|
|
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.