summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/quake/d_scan.c
diff options
context:
space:
mode:
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