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.
22 // Portable C scan-level rasterization code, all pixel depths.
28 unsigned char *r_turb_pbase
, *r_turb_pdest
;
29 fixed16_t r_turb_s
, r_turb_t
, r_turb_sstep
, r_turb_tstep
;
33 void D_DrawTurbulent8Span (void);
40 // this performs a slight compression of the screen at the same time as
41 // the sine warp, to keep the edges from wrapping
44 void D_WarpScreen (void)
52 byte
*rowptr
[MAXHEIGHT
+(AMP2
*2)];
53 int column
[MAXWIDTH
+(AMP2
*2)];
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
]];
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]];
100 void D_DrawTurbulent8Span (void)
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);
122 void Turbulent8 (espan_t
*pspan
)
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)
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)
170 // calculate s and t at the far end of the span
172 r_turb_spancount
= 16;
174 r_turb_spancount
= count
;
176 count
-= r_turb_spancount
;
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
;
185 z
= (float)0x10000 / zi
; // prescale to 16.16 fixed-point
187 snext
= (int)(sdivz
* z
) + sadjust
;
188 if (snext
> bbextents
)
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
)
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;
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
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
)
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
)
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 ();
246 } while ((pspan
= pspan
->pnext
) != NULL
);
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
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
;
296 t
= (int)(tdivz
* z
) + tadjust
;
304 // calculate s and t at the far end of the span
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
;
319 z
= (float)0x10000 / zi
; // prescale to 16.16 fixed-point
321 snext
= (int)(sdivz
* z
) + sadjust
;
322 if (snext
> bbextents
)
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
)
333 tnext
= 8; // guard against round-off error on <0 steps
335 sstep
= (snext
- s
) >> 3;
336 tstep
= (tnext
- t
) >> 3;
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
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
)
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
)
361 tnext
= 8; // guard against round-off error on <0 steps
365 sstep
= (snext
- s
) / (spancount
- 1);
366 tstep
= (tnext
- t
) / (spancount
- 1);
372 *pdest
++ = *(pbase
+ (s
>> 16) + (t
>> 16) * cachewidth
);
375 } while (--spancount
> 0);
382 } while ((pspan
= pspan
->pnext
) != NULL
);
395 void D_DrawZSpans (espan_t
*pspan
)
397 int count
, doublecount
, izistep
;
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);
429 if ((doublecount
= count
>> 1) > 0)
435 ltemp
|= izi
& 0xFFFF0000;
437 *(int *)pdest
= ltemp
;
439 } while (--doublecount
> 0);
443 *pdest
= (short)(izi
>> 16);
445 } while ((pspan
= pspan
->pnext
) != NULL
);