icculus quake2 doxygen  1.0 dev
r_scan.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 
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.
8 
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.
12 
13 See the GNU General Public License for more details.
14 
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.
18 
19 */
20 // d_scan.c
21 //
22 // Portable C scan-level rasterization code, all pixel depths.
23 
24 #include "r_local.h"
25 
26 unsigned char *r_turb_pbase, *r_turb_pdest;
30 
31 void D_DrawTurbulent8Span (void);
32 
33 
34 /*
35 =============
36 D_WarpScreen
37 
38 this performs a slight compression of the screen at the same time as
39 the sine warp, to keep the edges from wrapping
40 =============
41 */
42 void D_WarpScreen (void)
43 {
44  int w, h;
45  int u,v, u2, v2;
46  byte *dest;
47  int *turb;
48  int *col;
49  byte **row;
50 
51  static int cached_width, cached_height;
52  static byte *rowptr[1200+AMP2*2];
53  static int column[1600+AMP2*2];
54 
55  //
56  // these are constant over resolutions, and can be saved
57  //
59  h = r_newrefdef.height;
60  if (w != cached_width || h != cached_height)
61  {
62  cached_width = w;
63  cached_height = h;
64  for (v=0 ; v<h+AMP2*2 ; v++)
65  {
66  v2 = (int)((float)v/(h + AMP2 * 2) * r_refdef.vrect.height);
67  rowptr[v] = r_warpbuffer + (WARP_WIDTH * v2);
68  }
69 
70  for (u=0 ; u<w+AMP2*2 ; u++)
71  {
72  u2 = (int)((float)u/(w + AMP2 * 2) * r_refdef.vrect.width);
73  column[u] = u2;
74  }
75  }
76 
77  turb = intsintable + ((int)(r_newrefdef.time*SPEED)&(CYCLE-1));
79 
80  for (v=0 ; v<h ; v++, dest += vid.rowbytes)
81  {
82  col = &column[turb[v]];
83  row = &rowptr[v];
84  for (u=0 ; u<w ; u+=4)
85  {
86  dest[u+0] = row[turb[u+0]][col[u+0]];
87  dest[u+1] = row[turb[u+1]][col[u+1]];
88  dest[u+2] = row[turb[u+2]][col[u+2]];
89  dest[u+3] = row[turb[u+3]][col[u+3]];
90  }
91  }
92 }
93 
94 
95 #if !id386
96 
97 /*
98 =============
99 D_DrawTurbulent8Span
100 =============
101 */
103 {
104  int sturb, tturb;
105 
106  do
107  {
108  sturb = ((r_turb_s + r_turb_turb[(r_turb_t>>16)&(CYCLE-1)])>>16)&63;
109  tturb = ((r_turb_t + r_turb_turb[(r_turb_s>>16)&(CYCLE-1)])>>16)&63;
110  *r_turb_pdest++ = *(r_turb_pbase + (tturb<<6) + sturb);
113  } while (--r_turb_spancount > 0);
114 }
115 
116 #endif // !id386
117 
118 
119 /*
120 =============
121 Turbulent8
122 =============
123 */
124 void Turbulent8 (espan_t *pspan)
125 {
126  int count;
127  fixed16_t snext, tnext;
128  float sdivz, tdivz, zi, z, du, dv, spancountminus1;
129  float sdivz16stepu, tdivz16stepu, zi16stepu;
130 
132 
133  r_turb_sstep = 0; // keep compiler happy
134  r_turb_tstep = 0; // ditto
135 
136  r_turb_pbase = (unsigned char *)cacheblock;
137 
138  sdivz16stepu = d_sdivzstepu * 16;
139  tdivz16stepu = d_tdivzstepu * 16;
140  zi16stepu = d_zistepu * 16;
141 
142  do
143  {
144  r_turb_pdest = (unsigned char *)((byte *)d_viewbuffer +
145  (r_screenwidth * pspan->v) + pspan->u);
146 
147  count = pspan->count;
148 
149  // calculate the initial s/z, t/z, 1/z, s, and t and clamp
150  du = (float)pspan->u;
151  dv = (float)pspan->v;
152 
153  sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
154  tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
155  zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
156  z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
157 
158  r_turb_s = (int)(sdivz * z) + sadjust;
159  if (r_turb_s > bbextents)
161  else if (r_turb_s < 0)
162  r_turb_s = 0;
163 
164  r_turb_t = (int)(tdivz * z) + tadjust;
165  if (r_turb_t > bbextentt)
167  else if (r_turb_t < 0)
168  r_turb_t = 0;
169 
170  do
171  {
172  // calculate s and t at the far end of the span
173  if (count >= 16)
174  r_turb_spancount = 16;
175  else
177 
179 
180  if (count)
181  {
182  // calculate s/z, t/z, zi->fixed s and t at far end of span,
183  // calculate s and t steps across span by shifting
184  sdivz += sdivz16stepu;
185  tdivz += tdivz16stepu;
186  zi += zi16stepu;
187  z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
188 
189  snext = (int)(sdivz * z) + sadjust;
190  if (snext > bbextents)
191  snext = bbextents;
192  else if (snext < 16)
193  snext = 16; // prevent round-off error on <0 steps from
194  // from causing overstepping & running off the
195  // edge of the texture
196 
197  tnext = (int)(tdivz * z) + tadjust;
198  if (tnext > bbextentt)
199  tnext = bbextentt;
200  else if (tnext < 16)
201  tnext = 16; // guard against round-off error on <0 steps
202 
203  r_turb_sstep = (snext - r_turb_s) >> 4;
204  r_turb_tstep = (tnext - r_turb_t) >> 4;
205  }
206  else
207  {
208  // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
209  // can't step off polygon), clamp, calculate s and t steps across
210  // span by division, biasing steps low so we don't run off the
211  // texture
212  spancountminus1 = (float)(r_turb_spancount - 1);
213  sdivz += d_sdivzstepu * spancountminus1;
214  tdivz += d_tdivzstepu * spancountminus1;
215  zi += d_zistepu * spancountminus1;
216  z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
217  snext = (int)(sdivz * z) + sadjust;
218  if (snext > bbextents)
219  snext = bbextents;
220  else if (snext < 16)
221  snext = 16; // prevent round-off error on <0 steps from
222  // from causing overstepping & running off the
223  // edge of the texture
224 
225  tnext = (int)(tdivz * z) + tadjust;
226  if (tnext > bbextentt)
227  tnext = bbextentt;
228  else if (tnext < 16)
229  tnext = 16; // guard against round-off error on <0 steps
230 
231  if (r_turb_spancount > 1)
232  {
233  r_turb_sstep = (snext - r_turb_s) / (r_turb_spancount - 1);
234  r_turb_tstep = (tnext - r_turb_t) / (r_turb_spancount - 1);
235  }
236  }
237 
238  r_turb_s = r_turb_s & ((CYCLE<<16)-1);
239  r_turb_t = r_turb_t & ((CYCLE<<16)-1);
240 
242 
243  r_turb_s = snext;
244  r_turb_t = tnext;
245 
246  } while (count > 0);
247 
248  } while ((pspan = pspan->pnext) != NULL);
249 }
250 
251 //====================
252 //PGM
253 /*
254 =============
255 NonTurbulent8 - this is for drawing scrolling textures. they're warping water textures
256  but the turbulence is automatically 0.
257 =============
258 */
259 void NonTurbulent8 (espan_t *pspan)
260 {
261  int count;
262  fixed16_t snext, tnext;
263  float sdivz, tdivz, zi, z, du, dv, spancountminus1;
264  float sdivz16stepu, tdivz16stepu, zi16stepu;
265 
266 // r_turb_turb = sintable + ((int)(r_newrefdef.time*SPEED)&(CYCLE-1));
268 
269  r_turb_sstep = 0; // keep compiler happy
270  r_turb_tstep = 0; // ditto
271 
272  r_turb_pbase = (unsigned char *)cacheblock;
273 
274  sdivz16stepu = d_sdivzstepu * 16;
275  tdivz16stepu = d_tdivzstepu * 16;
276  zi16stepu = d_zistepu * 16;
277 
278  do
279  {
280  r_turb_pdest = (unsigned char *)((byte *)d_viewbuffer +
281  (r_screenwidth * pspan->v) + pspan->u);
282 
283  count = pspan->count;
284 
285  // calculate the initial s/z, t/z, 1/z, s, and t and clamp
286  du = (float)pspan->u;
287  dv = (float)pspan->v;
288 
289  sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
290  tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
291  zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
292  z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
293 
294  r_turb_s = (int)(sdivz * z) + sadjust;
295  if (r_turb_s > bbextents)
297  else if (r_turb_s < 0)
298  r_turb_s = 0;
299 
300  r_turb_t = (int)(tdivz * z) + tadjust;
301  if (r_turb_t > bbextentt)
303  else if (r_turb_t < 0)
304  r_turb_t = 0;
305 
306  do
307  {
308  // calculate s and t at the far end of the span
309  if (count >= 16)
310  r_turb_spancount = 16;
311  else
313 
315 
316  if (count)
317  {
318  // calculate s/z, t/z, zi->fixed s and t at far end of span,
319  // calculate s and t steps across span by shifting
320  sdivz += sdivz16stepu;
321  tdivz += tdivz16stepu;
322  zi += zi16stepu;
323  z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
324 
325  snext = (int)(sdivz * z) + sadjust;
326  if (snext > bbextents)
327  snext = bbextents;
328  else if (snext < 16)
329  snext = 16; // prevent round-off error on <0 steps from
330  // from causing overstepping & running off the
331  // edge of the texture
332 
333  tnext = (int)(tdivz * z) + tadjust;
334  if (tnext > bbextentt)
335  tnext = bbextentt;
336  else if (tnext < 16)
337  tnext = 16; // guard against round-off error on <0 steps
338 
339  r_turb_sstep = (snext - r_turb_s) >> 4;
340  r_turb_tstep = (tnext - r_turb_t) >> 4;
341  }
342  else
343  {
344  // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
345  // can't step off polygon), clamp, calculate s and t steps across
346  // span by division, biasing steps low so we don't run off the
347  // texture
348  spancountminus1 = (float)(r_turb_spancount - 1);
349  sdivz += d_sdivzstepu * spancountminus1;
350  tdivz += d_tdivzstepu * spancountminus1;
351  zi += d_zistepu * spancountminus1;
352  z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
353  snext = (int)(sdivz * z) + sadjust;
354  if (snext > bbextents)
355  snext = bbextents;
356  else if (snext < 16)
357  snext = 16; // prevent round-off error on <0 steps from
358  // from causing overstepping & running off the
359  // edge of the texture
360 
361  tnext = (int)(tdivz * z) + tadjust;
362  if (tnext > bbextentt)
363  tnext = bbextentt;
364  else if (tnext < 16)
365  tnext = 16; // guard against round-off error on <0 steps
366 
367  if (r_turb_spancount > 1)
368  {
369  r_turb_sstep = (snext - r_turb_s) / (r_turb_spancount - 1);
370  r_turb_tstep = (tnext - r_turb_t) / (r_turb_spancount - 1);
371  }
372  }
373 
374  r_turb_s = r_turb_s & ((CYCLE<<16)-1);
375  r_turb_t = r_turb_t & ((CYCLE<<16)-1);
376 
378 
379  r_turb_s = snext;
380  r_turb_t = tnext;
381 
382  } while (count > 0);
383 
384  } while ((pspan = pspan->pnext) != NULL);
385 }
386 //PGM
387 //====================
388 
389 
390 #if !id386
391 
392 /*
393 =============
394 D_DrawSpans16
395 
396  FIXME: actually make this subdivide by 16 instead of 8!!!
397 =============
398 */
399 void D_DrawSpans16 (espan_t *pspan)
400 {
401  int count, spancount;
402  unsigned char *pbase, *pdest;
403  fixed16_t s, t, snext, tnext, sstep, tstep;
404  float sdivz, tdivz, zi, z, du, dv, spancountminus1;
405  float sdivz8stepu, tdivz8stepu, zi8stepu;
406 
407  sstep = 0; // keep compiler happy
408  tstep = 0; // ditto
409 
410  pbase = (unsigned char *)cacheblock;
411 
412  sdivz8stepu = d_sdivzstepu * 8;
413  tdivz8stepu = d_tdivzstepu * 8;
414  zi8stepu = d_zistepu * 8;
415 
416  do
417  {
418  pdest = (unsigned char *)((byte *)d_viewbuffer +
419  (r_screenwidth * pspan->v) + pspan->u);
420 
421  count = pspan->count;
422 
423  // calculate the initial s/z, t/z, 1/z, s, and t and clamp
424  du = (float)pspan->u;
425  dv = (float)pspan->v;
426 
427  sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
428  tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
429  zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
430  z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
431 
432  s = (int)(sdivz * z) + sadjust;
433  if (s > bbextents)
434  s = bbextents;
435  else if (s < 0)
436  s = 0;
437 
438  t = (int)(tdivz * z) + tadjust;
439  if (t > bbextentt)
440  t = bbextentt;
441  else if (t < 0)
442  t = 0;
443 
444  do
445  {
446  // calculate s and t at the far end of the span
447  if (count >= 8)
448  spancount = 8;
449  else
450  spancount = count;
451 
452  count -= spancount;
453 
454  if (count)
455  {
456  // calculate s/z, t/z, zi->fixed s and t at far end of span,
457  // calculate s and t steps across span by shifting
458  sdivz += sdivz8stepu;
459  tdivz += tdivz8stepu;
460  zi += zi8stepu;
461  z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
462 
463  snext = (int)(sdivz * z) + sadjust;
464  if (snext > bbextents)
465  snext = bbextents;
466  else if (snext < 8)
467  snext = 8; // prevent round-off error on <0 steps from
468  // from causing overstepping & running off the
469  // edge of the texture
470 
471  tnext = (int)(tdivz * z) + tadjust;
472  if (tnext > bbextentt)
473  tnext = bbextentt;
474  else if (tnext < 8)
475  tnext = 8; // guard against round-off error on <0 steps
476 
477  sstep = (snext - s) >> 3;
478  tstep = (tnext - t) >> 3;
479  }
480  else
481  {
482  // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
483  // can't step off polygon), clamp, calculate s and t steps across
484  // span by division, biasing steps low so we don't run off the
485  // texture
486  spancountminus1 = (float)(spancount - 1);
487  sdivz += d_sdivzstepu * spancountminus1;
488  tdivz += d_tdivzstepu * spancountminus1;
489  zi += d_zistepu * spancountminus1;
490  z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
491  snext = (int)(sdivz * z) + sadjust;
492  if (snext > bbextents)
493  snext = bbextents;
494  else if (snext < 8)
495  snext = 8; // prevent round-off error on <0 steps from
496  // from causing overstepping & running off the
497  // edge of the texture
498 
499  tnext = (int)(tdivz * z) + tadjust;
500  if (tnext > bbextentt)
501  tnext = bbextentt;
502  else if (tnext < 8)
503  tnext = 8; // guard against round-off error on <0 steps
504 
505  if (spancount > 1)
506  {
507  sstep = (snext - s) / (spancount - 1);
508  tstep = (tnext - t) / (spancount - 1);
509  }
510  }
511 
512  do
513  {
514  *pdest++ = *(pbase + (s >> 16) + (t >> 16) * cachewidth);
515  s += sstep;
516  t += tstep;
517  } while (--spancount > 0);
518 
519  s = snext;
520  t = tnext;
521 
522  } while (count > 0);
523 
524  } while ((pspan = pspan->pnext) != NULL);
525 }
526 
527 #endif
528 
529 
530 #if !id386
531 
532 /*
533 =============
534 D_DrawZSpans
535 =============
536 */
537 void D_DrawZSpans (espan_t *pspan)
538 {
539  int count, doublecount, izistep;
540  int izi;
541  short *pdest;
542  unsigned ltemp;
543  float zi;
544  float du, dv;
545 
546 // FIXME: check for clamping/range problems
547 // we count on FP exceptions being turned off to avoid range problems
548  izistep = (int)(d_zistepu * 0x8000 * 0x10000);
549 
550  do
551  {
552  pdest = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
553 
554  count = pspan->count;
555 
556  // calculate the initial 1/z
557  du = (float)pspan->u;
558  dv = (float)pspan->v;
559 
560  zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
561  // we count on FP exceptions being turned off to avoid range problems
562  izi = (int)(zi * 0x8000 * 0x10000);
563 
564  if ((long)pdest & 0x02)
565  {
566  *pdest++ = (short)(izi >> 16);
567  izi += izistep;
568  count--;
569  }
570 
571  if ((doublecount = count >> 1) > 0)
572  {
573  do
574  {
575  ltemp = izi >> 16;
576  izi += izistep;
577  ltemp |= izi & 0xFFFF0000;
578  izi += izistep;
579  *(int *)pdest = ltemp;
580  pdest += 2;
581  } while (--doublecount > 0);
582  }
583 
584  if (count & 1)
585  *pdest = (short)(izi >> 16);
586 
587  } while ((pspan = pspan->pnext) != NULL);
588 }
589 
590 #endif
591 
cachewidth
int cachewidth
Definition: r_main.c:180
espan_s
Definition: r_local.h:375
d_sdivzorigin
float d_sdivzorigin
Definition: r_main.c:175
r_turb_turb
int * r_turb_turb
Definition: r_scan.c:28
intsintable
int intsintable[1280]
Definition: r_rast.c:48
int
CONST PIXELFORMATDESCRIPTOR int
Definition: qgl_win.c:35
CYCLE
#define CYCLE
Definition: asm_draw.h:16
NonTurbulent8
void NonTurbulent8(espan_t *pspan)
Definition: r_scan.c:259
viddef_t::buffer
pixel_t * buffer
Definition: r_local.h:88
v
GLdouble v
Definition: qgl_win.c:143
d_tdivzstepv
float d_tdivzstepv
Definition: r_local.h:482
vrect_s::height
int height
Definition: vid.h:24
z
GLdouble GLdouble z
Definition: qgl_win.c:283
d_viewbuffer
pixel_t * d_viewbuffer
Definition: r_main.c:181
refdef_t::y
int y
Definition: ref.h:122
d_tdivzorigin
float d_tdivzorigin
Definition: r_local.h:483
espan_s::pnext
struct espan_s * pnext
Definition: r_local.h:378
SPEED
#define SPEED
Definition: r_local.h:233
Turbulent8
void Turbulent8(espan_t *pspan)
Definition: r_scan.c:124
r_local.h
r_turb_t
fixed16_t r_turb_t
Definition: r_scan.c:27
espan_s::count
int count
Definition: r_local.h:377
d_ziorigin
float d_ziorigin
Definition: r_local.h:483
viddef_t::rowbytes
int rowbytes
Definition: r_local.h:91
v2
GLdouble GLdouble GLint GLint GLdouble GLdouble v2
Definition: qgl_win.c:227
bbextentt
fixed16_t bbextentt
Definition: r_local.h:486
sintable
int sintable[1280]
Definition: r_rast.c:47
espan_s::v
int v
Definition: r_local.h:377
t
GLdouble t
Definition: qgl_win.c:328
r_turb_s
fixed16_t r_turb_s
Definition: r_scan.c:27
sadjust
fixed16_t sadjust
Definition: r_local.h:672
d_tdivzstepu
float d_tdivzstepu
Definition: r_local.h:481
r_newrefdef
refdef_t r_newrefdef
Definition: r_main.c:36
r_turb_pbase
unsigned char * r_turb_pbase
Definition: r_scan.c:26
espan_s::u
int u
Definition: r_local.h:377
NULL
#define NULL
Definition: q_shared.h:60
WARP_WIDTH
#define WARP_WIDTH
Definition: r_local.h:174
bbextents
fixed16_t bbextents
Definition: r_local.h:673
refdef_t::time
float time
Definition: ref.h:127
d_zistepv
float d_zistepv
Definition: r_local.h:482
r_turb_tstep
fixed16_t r_turb_tstep
Definition: r_scan.c:27
refdef_t::height
int height
Definition: ref.h:122
r_screenwidth
int r_screenwidth
Definition: r_main.c:81
d_zistepu
float d_zistepu
Definition: r_local.h:481
AMP2
#define AMP2
Definition: r_local.h:232
blanktable
int blanktable[1280]
Definition: r_rast.c:49
D_DrawZSpans
void D_DrawZSpans(espan_t *pspan)
Definition: r_scan.c:537
D_DrawTurbulent8Span
void D_DrawTurbulent8Span(void)
Definition: r_scan.c:102
oldrefdef_t::vrect
vrect_t vrect
Definition: r_local.h:112
r_warpbuffer
byte r_warpbuffer[WARP_WIDTH *WARP_HEIGHT]
Definition: r_main.c:41
fixed16_t
int fixed16_t
Definition: q_shared.h:132
vrect_s::width
int width
Definition: vid.h:24
u2
GLdouble GLdouble u2
Definition: qgl_win.c:225
d_zwidth
unsigned int d_zwidth
Definition: r_local.h:502
d_sdivzstepu
float d_sdivzstepu
Definition: r_main.c:173
r_turb_sstep
fixed16_t r_turb_sstep
Definition: r_scan.c:27
refdef_t::width
int width
Definition: ref.h:122
r_turb_pdest
unsigned char * r_turb_pdest
Definition: r_scan.c:26
w
GLdouble GLdouble GLdouble w
Definition: qgl_win.c:291
d_sdivzstepv
float d_sdivzstepv
Definition: r_main.c:174
refdef_t::x
int x
Definition: ref.h:122
cacheblock
pixel_t * cacheblock
Definition: r_main.c:179
d_pzbuffer
short * d_pzbuffer
Definition: r_main.c:182
tadjust
fixed16_t tadjust
Definition: r_local.h:485
D_WarpScreen
void D_WarpScreen(void)
Definition: r_scan.c:42
r_turb_spancount
int r_turb_spancount
Definition: r_scan.c:29
r_refdef
oldrefdef_t r_refdef
Definition: r_main.c:74
count
GLint GLsizei count
Definition: qgl_win.c:128
D_DrawSpans16
void D_DrawSpans16(espan_t *pspan)
Definition: r_scan.c:399
vid
viddef_t vid
Definition: r_main.c:24