|
|
1.1 root 1: /*
2: Copyright (C) 1996-1997 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 "quakedef.h"
25: #include "r_local.h"
26: #include "d_local.h"
27:
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;
32:
33: void D_DrawTurbulent8Span (void);
34:
35:
36: /*
37: =============
38: D_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: */
44: void 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[1024];
53: int column[1280];
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: for (u=0 ; u<scr_vrect.width ; u+=4)
82: {
83: dest[u+0] = row[turb[u+0]][col[u+0]];
84: dest[u+1] = row[turb[u+1]][col[u+1]];
85: dest[u+2] = row[turb[u+2]][col[u+2]];
86: dest[u+3] = row[turb[u+3]][col[u+3]];
87: }
88: }
89: }
90:
91:
92: #if !id386
93:
94: /*
95: =============
96: D_DrawTurbulent8Span
97: =============
98: */
99: void D_DrawTurbulent8Span (void)
100: {
101: int sturb, tturb;
102:
103: do
104: {
105: sturb = ((r_turb_s + r_turb_turb[(r_turb_t>>16)&(CYCLE-1)])>>16)&63;
106: tturb = ((r_turb_t + r_turb_turb[(r_turb_s>>16)&(CYCLE-1)])>>16)&63;
107: *r_turb_pdest++ = *(r_turb_pbase + (tturb<<6) + sturb);
108: r_turb_s += r_turb_sstep;
109: r_turb_t += r_turb_tstep;
110: } while (--r_turb_spancount > 0);
111: }
112:
113: #endif // !id386
114:
115: /*
116: =============
117: Turbulent8
118: =============
119: */
120: void Turbulent8 (espan_t *pspan)
121: {
122: int count;
123: fixed16_t snext, tnext;
124: float sdivz, tdivz, zi, z, du, dv, spancountminus1;
125: float sdivz16stepu, tdivz16stepu, zi16stepu;
126:
127: r_turb_turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1));
128:
129: r_turb_sstep = 0; // keep compiler happy
130: r_turb_tstep = 0; // ditto
131:
132: r_turb_pbase = (unsigned char *)cacheblock;
133:
134: sdivz16stepu = d_sdivzstepu * 16;
135: tdivz16stepu = d_tdivzstepu * 16;
136: zi16stepu = d_zistepu * 16;
137:
138: do
139: {
140: r_turb_pdest = (unsigned char *)((byte *)d_viewbuffer +
141: (screenwidth * pspan->v) + pspan->u);
142:
143: count = pspan->count;
144:
145: // calculate the initial s/z, t/z, 1/z, s, and t and clamp
146: du = (float)pspan->u;
147: dv = (float)pspan->v;
148:
149: sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
150: tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
151: zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
152: z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
153:
154: r_turb_s = (int)(sdivz * z) + sadjust;
155: if (r_turb_s > bbextents)
156: r_turb_s = bbextents;
157: else if (r_turb_s < 0)
158: r_turb_s = 0;
159:
160: r_turb_t = (int)(tdivz * z) + tadjust;
161: if (r_turb_t > bbextentt)
162: r_turb_t = bbextentt;
163: else if (r_turb_t < 0)
164: r_turb_t = 0;
165:
166: do
167: {
168: // calculate s and t at the far end of the span
169: if (count >= 16)
170: r_turb_spancount = 16;
171: else
172: r_turb_spancount = count;
173:
174: count -= r_turb_spancount;
175:
176: if (count)
177: {
178: // calculate s/z, t/z, zi->fixed s and t at far end of span,
179: // calculate s and t steps across span by shifting
180: sdivz += sdivz16stepu;
181: tdivz += tdivz16stepu;
182: zi += zi16stepu;
183: z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
184:
185: snext = (int)(sdivz * z) + sadjust;
186: if (snext > bbextents)
187: snext = bbextents;
188: else if (snext < 16)
189: snext = 16; // prevent round-off error on <0 steps from
190: // from causing overstepping & running off the
191: // edge of the texture
192:
193: tnext = (int)(tdivz * z) + tadjust;
194: if (tnext > bbextentt)
195: tnext = bbextentt;
196: else if (tnext < 16)
197: tnext = 16; // guard against round-off error on <0 steps
198:
199: r_turb_sstep = (snext - r_turb_s) >> 4;
200: r_turb_tstep = (tnext - r_turb_t) >> 4;
201: }
202: else
203: {
204: // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
205: // can't step off polygon), clamp, calculate s and t steps across
206: // span by division, biasing steps low so we don't run off the
207: // texture
208: spancountminus1 = (float)(r_turb_spancount - 1);
209: sdivz += d_sdivzstepu * spancountminus1;
210: tdivz += d_tdivzstepu * spancountminus1;
211: zi += d_zistepu * spancountminus1;
212: z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
213: snext = (int)(sdivz * z) + sadjust;
214: if (snext > bbextents)
215: snext = bbextents;
216: else if (snext < 16)
217: snext = 16; // prevent round-off error on <0 steps from
218: // from causing overstepping & running off the
219: // edge of the texture
220:
221: tnext = (int)(tdivz * z) + tadjust;
222: if (tnext > bbextentt)
223: tnext = bbextentt;
224: else if (tnext < 16)
225: tnext = 16; // guard against round-off error on <0 steps
226:
227: if (r_turb_spancount > 1)
228: {
229: r_turb_sstep = (snext - r_turb_s) / (r_turb_spancount - 1);
230: r_turb_tstep = (tnext - r_turb_t) / (r_turb_spancount - 1);
231: }
232: }
233:
234: r_turb_s = r_turb_s & ((CYCLE<<16)-1);
235: r_turb_t = r_turb_t & ((CYCLE<<16)-1);
236:
237: D_DrawTurbulent8Span ();
238:
239: r_turb_s = snext;
240: r_turb_t = tnext;
241:
242: } while (count > 0);
243:
244: } while ((pspan = pspan->pnext) != NULL);
245: }
246:
247:
248: #if !id386
249:
250: /*
251: =============
252: D_DrawSpans8
253: =============
254: */
255: void D_DrawSpans8 (espan_t *pspan)
256: {
257: int count, spancount;
258: unsigned char *pbase, *pdest;
259: fixed16_t s, t, snext, tnext, sstep, tstep;
260: float sdivz, tdivz, zi, z, du, dv, spancountminus1;
261: float sdivz8stepu, tdivz8stepu, zi8stepu;
262:
263: sstep = 0; // keep compiler happy
264: tstep = 0; // ditto
265:
266: pbase = (unsigned char *)cacheblock;
267:
268: sdivz8stepu = d_sdivzstepu * 8;
269: tdivz8stepu = d_tdivzstepu * 8;
270: zi8stepu = d_zistepu * 8;
271:
272: do
273: {
274: pdest = (unsigned char *)((byte *)d_viewbuffer +
275: (screenwidth * pspan->v) + pspan->u);
276:
277: count = pspan->count;
278:
279: // calculate the initial s/z, t/z, 1/z, s, and t and clamp
280: du = (float)pspan->u;
281: dv = (float)pspan->v;
282:
283: sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
284: tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
285: zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
286: z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
287:
288: s = (int)(sdivz * z) + sadjust;
289: if (s > bbextents)
290: s = bbextents;
291: else if (s < 0)
292: s = 0;
293:
294: t = (int)(tdivz * z) + tadjust;
295: if (t > bbextentt)
296: t = bbextentt;
297: else if (t < 0)
298: t = 0;
299:
300: do
301: {
302: // calculate s and t at the far end of the span
303: if (count >= 8)
304: spancount = 8;
305: else
306: spancount = count;
307:
308: count -= spancount;
309:
310: if (count)
311: {
312: // calculate s/z, t/z, zi->fixed s and t at far end of span,
313: // calculate s and t steps across span by shifting
314: sdivz += sdivz8stepu;
315: tdivz += tdivz8stepu;
316: zi += zi8stepu;
317: z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
318:
319: snext = (int)(sdivz * z) + sadjust;
320: if (snext > bbextents)
321: snext = bbextents;
322: else if (snext < 8)
323: snext = 8; // prevent round-off error on <0 steps from
324: // from causing overstepping & running off the
325: // edge of the texture
326:
327: tnext = (int)(tdivz * z) + tadjust;
328: if (tnext > bbextentt)
329: tnext = bbextentt;
330: else if (tnext < 8)
331: tnext = 8; // guard against round-off error on <0 steps
332:
333: sstep = (snext - s) >> 3;
334: tstep = (tnext - t) >> 3;
335: }
336: else
337: {
338: // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
339: // can't step off polygon), clamp, calculate s and t steps across
340: // span by division, biasing steps low so we don't run off the
341: // texture
342: spancountminus1 = (float)(spancount - 1);
343: sdivz += d_sdivzstepu * spancountminus1;
344: tdivz += d_tdivzstepu * spancountminus1;
345: zi += d_zistepu * spancountminus1;
346: z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
347: snext = (int)(sdivz * z) + sadjust;
348: if (snext > bbextents)
349: snext = bbextents;
350: else if (snext < 8)
351: snext = 8; // prevent round-off error on <0 steps from
352: // from causing overstepping & running off the
353: // edge of the texture
354:
355: tnext = (int)(tdivz * z) + tadjust;
356: if (tnext > bbextentt)
357: tnext = bbextentt;
358: else if (tnext < 8)
359: tnext = 8; // guard against round-off error on <0 steps
360:
361: if (spancount > 1)
362: {
363: sstep = (snext - s) / (spancount - 1);
364: tstep = (tnext - t) / (spancount - 1);
365: }
366: }
367:
368: do
369: {
370: *pdest++ = *(pbase + (s >> 16) + (t >> 16) * cachewidth);
371: s += sstep;
372: t += tstep;
373: } while (--spancount > 0);
374:
375: s = snext;
376: t = tnext;
377:
378: } while (count > 0);
379:
380: } while ((pspan = pspan->pnext) != NULL);
381: }
382:
383: #endif
384:
385:
386: #if !id386
387:
388: /*
389: =============
390: D_DrawZSpans
391: =============
392: */
393: void D_DrawZSpans (espan_t *pspan)
394: {
395: int count, doublecount, izistep;
396: int izi;
397: short *pdest;
398: unsigned ltemp;
399: double zi;
400: float du, dv;
401:
402: // FIXME: check for clamping/range problems
403: // we count on FP exceptions being turned off to avoid range problems
404: izistep = (int)(d_zistepu * 0x8000 * 0x10000);
405:
406: do
407: {
408: pdest = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
409:
410: count = pspan->count;
411:
412: // calculate the initial 1/z
413: du = (float)pspan->u;
414: dv = (float)pspan->v;
415:
416: zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
417: // we count on FP exceptions being turned off to avoid range problems
418: izi = (int)(zi * 0x8000 * 0x10000);
419:
420: if ((long)pdest & 0x02)
421: {
422: *pdest++ = (short)(izi >> 16);
423: izi += izistep;
424: count--;
425: }
426:
427: if ((doublecount = count >> 1) > 0)
428: {
429: do
430: {
431: ltemp = izi >> 16;
432: izi += izistep;
433: ltemp |= izi & 0xFFFF0000;
434: izi += izistep;
435: *(int *)pdest = ltemp;
436: pdest += 2;
437: } while (--doublecount > 0);
438: }
439:
440: if (count & 1)
441: *pdest = (short)(izi >> 16);
442:
443: } while ((pspan = pspan->pnext) != NULL);
444: }
445:
446: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.