summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/quake/d_scan.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2018-02-11 15:34:30 -0500
committerFranklin Wei <git@fwei.tk>2019-07-19 22:37:40 -0400
commit5d05b9d3e920a6aa5fcb553758e98ed0da8c91e4 (patch)
tree84406e21639529a185556a33e5de7f43cffc277b /apps/plugins/sdl/progs/quake/d_scan.c
parentb70fecf21ddc21877ec1ae7888d9c18a979e37ad (diff)
downloadrockbox-5d05b9d3e920a6aa5fcb553758e98ed0da8c91e4.tar.gz
rockbox-5d05b9d3e920a6aa5fcb553758e98ed0da8c91e4.zip
Quake!
This ports id Software's Quake to run on the SDL plugin runtime. The source code originated from id under the GPLv2 license. I used https://github.com/ahefner/sdlquake as the base of my port. Performance is, unsurprisingly, not on par with what you're probably used to on PC. I average about 10FPS on ipod6g, but it's still playable. Sound works well enough, but in-game music is not supported. I've written ARM assembly routines for the inner sound loop. Make sure you turn the "brightness" all the way down, or colors will look funky. To run, extract Quake's data files to /.rockbox/quake. Have fun! Change-Id: I4285036e967d7f0722802d43cf2096c808ca5799
Diffstat (limited to 'apps/plugins/sdl/progs/quake/d_scan.c')
-rw-r--r--apps/plugins/sdl/progs/quake/d_scan.c449
1 files changed, 449 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/quake/d_scan.c b/apps/plugins/sdl/progs/quake/d_scan.c
new file mode 100644
index 0000000000..008c783be6
--- /dev/null
+++ b/apps/plugins/sdl/progs/quake/d_scan.c
@@ -0,0 +1,449 @@
1/*
2Copyright (C) 1996-1997 Id Software, Inc.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20// d_scan.c
21//
22// Portable C scan-level rasterization code, all pixel depths.
23
24#include "quakedef.h"
25#include "r_local.h"
26#include "d_local.h"
27
28unsigned char *r_turb_pbase, *r_turb_pdest;
29fixed16_t r_turb_s, r_turb_t, r_turb_sstep, r_turb_tstep;
30int *r_turb_turb;
31int r_turb_spancount;
32
33void D_DrawTurbulent8Span (void);
34
35
36/*
37=============
38D_WarpScreen
39
40// this performs a slight compression of the screen at the same time as
41// the sine warp, to keep the edges from wrapping
42=============
43*/
44void D_WarpScreen (void)
45{
46 int w, h;
47 int u,v;
48 byte *dest;
49 int *turb;
50 int *col;
51 byte **row;
52 byte *rowptr[MAXHEIGHT+(AMP2*2)];
53 int column[MAXWIDTH+(AMP2*2)];
54 float wratio, hratio;
55
56 w = r_refdef.vrect.width;
57 h = r_refdef.vrect.height;
58
59 wratio = w / (float)scr_vrect.width;
60 hratio = h / (float)scr_vrect.height;
61
62 for (v=0 ; v<scr_vrect.height+AMP2*2 ; v++)
63 {
64 rowptr[v] = d_viewbuffer + (r_refdef.vrect.y * screenwidth) +
65 (screenwidth * (int)((float)v * hratio * h / (h + AMP2 * 2)));
66 }
67
68 for (u=0 ; u<scr_vrect.width+AMP2*2 ; u++)
69 {
70 column[u] = r_refdef.vrect.x +
71 (int)((float)u * wratio * w / (w + AMP2 * 2));
72 }
73
74 turb = intsintable + ((int)(cl.time*SPEED)&(CYCLE-1));
75 dest = vid.buffer + scr_vrect.y * vid.rowbytes + scr_vrect.x;
76
77 for (v=0 ; v<scr_vrect.height ; v++, dest += vid.rowbytes)
78 {
79 col = &column[turb[v]];
80 row = &rowptr[v];
81
82 for (u=0 ; u<scr_vrect.width ; u+=4)
83 {
84 dest[u+0] = row[turb[u+0]][col[u+0]];
85 dest[u+1] = row[turb[u+1]][col[u+1]];
86 dest[u+2] = row[turb[u+2]][col[u+2]];
87 dest[u+3] = row[turb[u+3]][col[u+3]];
88 }
89 }
90}
91
92
93#if !id386
94
95/*
96=============
97D_DrawTurbulent8Span
98=============
99*/
100void D_DrawTurbulent8Span (void)
101{
102 int sturb, tturb;
103
104 do
105 {
106 sturb = ((r_turb_s + r_turb_turb[(r_turb_t>>16)&(CYCLE-1)])>>16)&63;
107 tturb = ((r_turb_t + r_turb_turb[(r_turb_s>>16)&(CYCLE-1)])>>16)&63;
108 *r_turb_pdest++ = *(r_turb_pbase + (tturb<<6) + sturb);
109 r_turb_s += r_turb_sstep;
110 r_turb_t += r_turb_tstep;
111 } while (--r_turb_spancount > 0);
112}
113
114#endif // !id386
115
116
117/*
118=============
119Turbulent8
120=============
121*/
122void Turbulent8 (espan_t *pspan)
123{
124 int count;
125 fixed16_t snext, tnext;
126 float sdivz, tdivz, zi, z, du, dv, spancountminus1;
127 float sdivz16stepu, tdivz16stepu, zi16stepu;
128
129 r_turb_turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1));
130
131 r_turb_sstep = 0; // keep compiler happy
132 r_turb_tstep = 0; // ditto
133
134 r_turb_pbase = (unsigned char *)cacheblock;
135
136 sdivz16stepu = d_sdivzstepu * 16;
137 tdivz16stepu = d_tdivzstepu * 16;
138 zi16stepu = d_zistepu * 16;
139
140 do
141 {
142 r_turb_pdest = (unsigned char *)((byte *)d_viewbuffer +
143 (screenwidth * pspan->v) + pspan->u);
144
145 count = pspan->count;
146
147 // calculate the initial s/z, t/z, 1/z, s, and t and clamp
148 du = (float)pspan->u;
149 dv = (float)pspan->v;
150
151 sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
152 tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
153 zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
154 z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
155
156 r_turb_s = (int)(sdivz * z) + sadjust;
157 if (r_turb_s > bbextents)
158 r_turb_s = bbextents;
159 else if (r_turb_s < 0)
160 r_turb_s = 0;
161
162 r_turb_t = (int)(tdivz * z) + tadjust;
163 if (r_turb_t > bbextentt)
164 r_turb_t = bbextentt;
165 else if (r_turb_t < 0)
166 r_turb_t = 0;
167
168 do
169 {
170 // calculate s and t at the far end of the span
171 if (count >= 16)
172 r_turb_spancount = 16;
173 else
174 r_turb_spancount = count;
175
176 count -= r_turb_spancount;
177
178 if (count)
179 {
180 // calculate s/z, t/z, zi->fixed s and t at far end of span,
181 // calculate s and t steps across span by shifting
182 sdivz += sdivz16stepu;
183 tdivz += tdivz16stepu;
184 zi += zi16stepu;
185 z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
186
187 snext = (int)(sdivz * z) + sadjust;
188 if (snext > bbextents)
189 snext = bbextents;
190 else if (snext < 16)
191 snext = 16; // prevent round-off error on <0 steps from
192 // from causing overstepping & running off the
193 // edge of the texture
194
195 tnext = (int)(tdivz * z) + tadjust;
196 if (tnext > bbextentt)
197 tnext = bbextentt;
198 else if (tnext < 16)
199 tnext = 16; // guard against round-off error on <0 steps
200
201 r_turb_sstep = (snext - r_turb_s) >> 4;
202 r_turb_tstep = (tnext - r_turb_t) >> 4;
203 }
204 else
205 {
206 // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
207 // can't step off polygon), clamp, calculate s and t steps across
208 // span by division, biasing steps low so we don't run off the
209 // texture
210 spancountminus1 = (float)(r_turb_spancount - 1);
211 sdivz += d_sdivzstepu * spancountminus1;
212 tdivz += d_tdivzstepu * spancountminus1;
213 zi += d_zistepu * spancountminus1;
214 z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
215 snext = (int)(sdivz * z) + sadjust;
216 if (snext > bbextents)
217 snext = bbextents;
218 else if (snext < 16)
219 snext = 16; // prevent round-off error on <0 steps from
220 // from causing overstepping & running off the
221 // edge of the texture
222
223 tnext = (int)(tdivz * z) + tadjust;
224 if (tnext > bbextentt)
225 tnext = bbextentt;
226 else if (tnext < 16)
227 tnext = 16; // guard against round-off error on <0 steps
228
229 if (r_turb_spancount > 1)
230 {
231 r_turb_sstep = (snext - r_turb_s) / (r_turb_spancount - 1);
232 r_turb_tstep = (tnext - r_turb_t) / (r_turb_spancount - 1);
233 }
234 }
235
236 r_turb_s = r_turb_s & ((CYCLE<<16)-1);
237 r_turb_t = r_turb_t & ((CYCLE<<16)-1);
238
239 D_DrawTurbulent8Span ();
240
241 r_turb_s = snext;
242 r_turb_t = tnext;
243
244 } while (count > 0);
245
246 } while ((pspan = pspan->pnext) != NULL);
247}
248
249
250#if !id386
251
252/*
253=============
254D_DrawSpans8
255=============
256*/
257void D_DrawSpans8 (espan_t *pspan)
258{
259 int count, spancount;
260 unsigned char *pbase, *pdest;
261 fixed16_t s, t, snext, tnext, sstep, tstep;
262 float sdivz, tdivz, zi, z, du, dv, spancountminus1;
263 float sdivz8stepu, tdivz8stepu, zi8stepu;
264
265 sstep = 0; // keep compiler happy
266 tstep = 0; // ditto
267
268 pbase = (unsigned char *)cacheblock;
269
270 sdivz8stepu = d_sdivzstepu * 8;
271 tdivz8stepu = d_tdivzstepu * 8;
272 zi8stepu = d_zistepu * 8;
273
274 do
275 {
276 pdest = (unsigned char *)((byte *)d_viewbuffer +
277 (screenwidth * pspan->v) + pspan->u);
278
279 count = pspan->count;
280
281 // calculate the initial s/z, t/z, 1/z, s, and t and clamp
282 du = (float)pspan->u;
283 dv = (float)pspan->v;
284
285 sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
286 tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
287 zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
288 z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
289
290 s = (int)(sdivz * z) + sadjust;
291 if (s > bbextents)
292 s = bbextents;
293 else if (s < 0)
294 s = 0;
295
296 t = (int)(tdivz * z) + tadjust;
297 if (t > bbextentt)
298 t = bbextentt;
299 else if (t < 0)
300 t = 0;
301
302 do
303 {
304 // calculate s and t at the far end of the span
305 if (count >= 8)
306 spancount = 8;
307 else
308 spancount = count;
309
310 count -= spancount;
311
312 if (count)
313 {
314 // calculate s/z, t/z, zi->fixed s and t at far end of span,
315 // calculate s and t steps across span by shifting
316 sdivz += sdivz8stepu;
317 tdivz += tdivz8stepu;
318 zi += zi8stepu;
319 z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
320
321 snext = (int)(sdivz * z) + sadjust;
322 if (snext > bbextents)
323 snext = bbextents;
324 else if (snext < 8)
325 snext = 8; // prevent round-off error on <0 steps from
326 // from causing overstepping & running off the
327 // edge of the texture
328
329 tnext = (int)(tdivz * z) + tadjust;
330 if (tnext > bbextentt)
331 tnext = bbextentt;
332 else if (tnext < 8)
333 tnext = 8; // guard against round-off error on <0 steps
334
335 sstep = (snext - s) >> 3;
336 tstep = (tnext - t) >> 3;
337 }
338 else
339 {
340 // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
341 // can't step off polygon), clamp, calculate s and t steps across
342 // span by division, biasing steps low so we don't run off the
343 // texture
344 spancountminus1 = (float)(spancount - 1);
345 sdivz += d_sdivzstepu * spancountminus1;
346 tdivz += d_tdivzstepu * spancountminus1;
347 zi += d_zistepu * spancountminus1;
348 z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
349 snext = (int)(sdivz * z) + sadjust;
350 if (snext > bbextents)
351 snext = bbextents;
352 else if (snext < 8)
353 snext = 8; // prevent round-off error on <0 steps from
354 // from causing overstepping & running off the
355 // edge of the texture
356
357 tnext = (int)(tdivz * z) + tadjust;
358 if (tnext > bbextentt)
359 tnext = bbextentt;
360 else if (tnext < 8)
361 tnext = 8; // guard against round-off error on <0 steps
362
363 if (spancount > 1)
364 {
365 sstep = (snext - s) / (spancount - 1);
366 tstep = (tnext - t) / (spancount - 1);
367 }
368 }
369
370 do
371 {
372 *pdest++ = *(pbase + (s >> 16) + (t >> 16) * cachewidth);
373 s += sstep;
374 t += tstep;
375 } while (--spancount > 0);
376
377 s = snext;
378 t = tnext;
379
380 } while (count > 0);
381
382 } while ((pspan = pspan->pnext) != NULL);
383}
384
385#endif
386
387
388#if !id386
389
390/*
391=============
392D_DrawZSpans
393=============
394*/
395void D_DrawZSpans (espan_t *pspan)
396{
397 int count, doublecount, izistep;
398 int izi;
399 short *pdest;
400 unsigned ltemp;
401 double zi;
402 float du, dv;
403
404// FIXME: check for clamping/range problems
405// we count on FP exceptions being turned off to avoid range problems
406 izistep = (int)(d_zistepu * 0x8000 * 0x10000);
407
408 do
409 {
410 pdest = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
411
412 count = pspan->count;
413
414 // calculate the initial 1/z
415 du = (float)pspan->u;
416 dv = (float)pspan->v;
417
418 zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
419 // we count on FP exceptions being turned off to avoid range problems
420 izi = (int)(zi * 0x8000 * 0x10000);
421
422 if ((long)pdest & 0x02)
423 {
424 *pdest++ = (short)(izi >> 16);
425 izi += izistep;
426 count--;
427 }
428
429 if ((doublecount = count >> 1) > 0)
430 {
431 do
432 {
433 ltemp = izi >> 16;
434 izi += izistep;
435 ltemp |= izi & 0xFFFF0000;
436 izi += izistep;
437 *(int *)pdest = ltemp;
438 pdest += 2;
439 } while (--doublecount > 0);
440 }
441
442 if (count & 1)
443 *pdest = (short)(izi >> 16);
444
445 } while ((pspan = pspan->pnext) != NULL);
446}
447
448#endif
449