Fix for the problem that SDL applications exited
[AROS-Contrib.git] / Games / Quake / d_scan.c
blob008c783be64e0c6e94c2efb641998626a6d9b45f
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 // d_scan.c
22 // Portable C scan-level rasterization code, all pixel depths.
24 #include "quakedef.h"
25 #include "r_local.h"
26 #include "d_local.h"
28 unsigned char *r_turb_pbase, *r_turb_pdest;
29 fixed16_t r_turb_s, r_turb_t, r_turb_sstep, r_turb_tstep;
30 int *r_turb_turb;
31 int r_turb_spancount;
33 void D_DrawTurbulent8Span (void);
37 =============
38 D_WarpScreen
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 =============
44 void D_WarpScreen (void)
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;
56 w = r_refdef.vrect.width;
57 h = r_refdef.vrect.height;
59 wratio = w / (float)scr_vrect.width;
60 hratio = h / (float)scr_vrect.height;
62 for (v=0 ; v<scr_vrect.height+AMP2*2 ; v++)
64 rowptr[v] = d_viewbuffer + (r_refdef.vrect.y * screenwidth) +
65 (screenwidth * (int)((float)v * hratio * h / (h + AMP2 * 2)));
68 for (u=0 ; u<scr_vrect.width+AMP2*2 ; u++)
70 column[u] = r_refdef.vrect.x +
71 (int)((float)u * wratio * w / (w + AMP2 * 2));
74 turb = intsintable + ((int)(cl.time*SPEED)&(CYCLE-1));
75 dest = vid.buffer + scr_vrect.y * vid.rowbytes + scr_vrect.x;
77 for (v=0 ; v<scr_vrect.height ; v++, dest += vid.rowbytes)
79 col = &column[turb[v]];
80 row = &rowptr[v];
82 for (u=0 ; u<scr_vrect.width ; u+=4)
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]];
93 #if !id386
96 =============
97 D_DrawTurbulent8Span
98 =============
100 void D_DrawTurbulent8Span (void)
102 int sturb, tturb;
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);
114 #endif // !id386
118 =============
119 Turbulent8
120 =============
122 void Turbulent8 (espan_t *pspan)
124 int count;
125 fixed16_t snext, tnext;
126 float sdivz, tdivz, zi, z, du, dv, spancountminus1;
127 float sdivz16stepu, tdivz16stepu, zi16stepu;
129 r_turb_turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1));
131 r_turb_sstep = 0; // keep compiler happy
132 r_turb_tstep = 0; // ditto
134 r_turb_pbase = (unsigned char *)cacheblock;
136 sdivz16stepu = d_sdivzstepu * 16;
137 tdivz16stepu = d_tdivzstepu * 16;
138 zi16stepu = d_zistepu * 16;
142 r_turb_pdest = (unsigned char *)((byte *)d_viewbuffer +
143 (screenwidth * pspan->v) + pspan->u);
145 count = pspan->count;
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;
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
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;
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;
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;
176 count -= r_turb_spancount;
178 if (count)
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
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
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
201 r_turb_sstep = (snext - r_turb_s) >> 4;
202 r_turb_tstep = (tnext - r_turb_t) >> 4;
204 else
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
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
229 if (r_turb_spancount > 1)
231 r_turb_sstep = (snext - r_turb_s) / (r_turb_spancount - 1);
232 r_turb_tstep = (tnext - r_turb_t) / (r_turb_spancount - 1);
236 r_turb_s = r_turb_s & ((CYCLE<<16)-1);
237 r_turb_t = r_turb_t & ((CYCLE<<16)-1);
239 D_DrawTurbulent8Span ();
241 r_turb_s = snext;
242 r_turb_t = tnext;
244 } while (count > 0);
246 } while ((pspan = pspan->pnext) != NULL);
250 #if !id386
253 =============
254 D_DrawSpans8
255 =============
257 void D_DrawSpans8 (espan_t *pspan)
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;
265 sstep = 0; // keep compiler happy
266 tstep = 0; // ditto
268 pbase = (unsigned char *)cacheblock;
270 sdivz8stepu = d_sdivzstepu * 8;
271 tdivz8stepu = d_tdivzstepu * 8;
272 zi8stepu = d_zistepu * 8;
276 pdest = (unsigned char *)((byte *)d_viewbuffer +
277 (screenwidth * pspan->v) + pspan->u);
279 count = pspan->count;
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;
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
290 s = (int)(sdivz * z) + sadjust;
291 if (s > bbextents)
292 s = bbextents;
293 else if (s < 0)
294 s = 0;
296 t = (int)(tdivz * z) + tadjust;
297 if (t > bbextentt)
298 t = bbextentt;
299 else if (t < 0)
300 t = 0;
304 // calculate s and t at the far end of the span
305 if (count >= 8)
306 spancount = 8;
307 else
308 spancount = count;
310 count -= spancount;
312 if (count)
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
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
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
335 sstep = (snext - s) >> 3;
336 tstep = (tnext - t) >> 3;
338 else
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
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
363 if (spancount > 1)
365 sstep = (snext - s) / (spancount - 1);
366 tstep = (tnext - t) / (spancount - 1);
372 *pdest++ = *(pbase + (s >> 16) + (t >> 16) * cachewidth);
373 s += sstep;
374 t += tstep;
375 } while (--spancount > 0);
377 s = snext;
378 t = tnext;
380 } while (count > 0);
382 } while ((pspan = pspan->pnext) != NULL);
385 #endif
388 #if !id386
391 =============
392 D_DrawZSpans
393 =============
395 void D_DrawZSpans (espan_t *pspan)
397 int count, doublecount, izistep;
398 int izi;
399 short *pdest;
400 unsigned ltemp;
401 double zi;
402 float du, dv;
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);
410 pdest = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
412 count = pspan->count;
414 // calculate the initial 1/z
415 du = (float)pspan->u;
416 dv = (float)pspan->v;
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);
422 if ((long)pdest & 0x02)
424 *pdest++ = (short)(izi >> 16);
425 izi += izistep;
426 count--;
429 if ((doublecount = count >> 1) > 0)
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);
442 if (count & 1)
443 *pdest = (short)(izi >> 16);
445 } while ((pspan = pspan->pnext) != NULL);
448 #endif