|
|
1.1.1.3 root 1: // Emacs style mode select -*- C++ -*-
2: //-----------------------------------------------------------------------------
3: //
4: // $Id:$
5: //
6: // Copyright (C) 1993-1996 by id Software, Inc.
7: //
1.1.1.4 ! root 8: // This program is free software; you can redistribute it and/or
! 9: // modify it under the terms of the GNU General Public License
! 10: // as published by the Free Software Foundation; either version 2
! 11: // of the License, or (at your option) any later version.
1.1.1.3 root 12: //
1.1.1.4 ! root 13: // This program is distributed in the hope that it will be useful,
1.1.1.3 root 14: // but WITHOUT ANY WARRANTY; without even the implied warranty of
1.1.1.4 ! root 15: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 16: // GNU General Public License for more details.
1.1.1.3 root 17: //
18: // $Log:$
19: //
20: // DESCRIPTION:
21: // Refresh of things, i.e. objects represented by sprites.
22: //
23: //-----------------------------------------------------------------------------
24:
25:
26: static const char
27: rcsid[] = "$Id: r_things.c,v 1.5 1997/02/03 16:47:56 b1 Exp $";
1.1.1.2 root 28:
29:
1.1 root 30: #include <stdio.h>
31: #include <stdlib.h>
32:
33:
1.1.1.3 root 34: #include "doomdef.h"
35: #include "m_swap.h"
1.1 root 36:
1.1.1.3 root 37: #include "i_system.h"
38: #include "z_zone.h"
39: #include "w_wad.h"
1.1 root 40:
1.1.1.3 root 41: #include "r_local.h"
1.1 root 42:
1.1.1.3 root 43: #include "doomstat.h"
1.1 root 44:
45:
46:
1.1.1.3 root 47: #define MINZ (FRACUNIT*4)
48: #define BASEYCENTER 100
1.1 root 49:
1.1.1.3 root 50: //void R_DrawColumn (void);
51: //void R_DrawFuzzColumn (void);
1.1 root 52:
53:
54:
1.1.1.3 root 55: typedef struct
56: {
57: int x1;
58: int x2;
59:
60: int column;
61: int topclip;
62: int bottomclip;
1.1 root 63:
1.1.1.3 root 64: } maskdraw_t;
1.1 root 65:
66:
67:
1.1.1.3 root 68: //
69: // Sprite rotation 0 is facing the viewer,
70: // rotation 1 is one angle turn CLOCKWISE around the axis.
71: // This is not the same as the angle,
72: // which increases counter clockwise (protractor).
73: // There was a lot of stuff grabbed wrong, so I changed it...
74: //
75: fixed_t pspritescale;
76: fixed_t pspriteiscale;
1.1 root 77:
1.1.1.3 root 78: lighttable_t** spritelights;
1.1 root 79:
1.1.1.3 root 80: // constant arrays
81: // used for psprite clipping and initializing clipping
82: short negonearray[SCREENWIDTH];
83: short screenheightarray[SCREENWIDTH];
1.1 root 84:
85:
1.1.1.3 root 86: //
87: // INITIALIZATION FUNCTIONS
88: //
1.1 root 89:
1.1.1.3 root 90: // variables used to look up
91: // and range check thing_t sprites patches
92: spritedef_t* sprites;
93: int numsprites;
1.1 root 94:
1.1.1.3 root 95: spriteframe_t sprtemp[29];
96: int maxframe;
97: char* spritename;
1.1 root 98:
99:
100:
101:
1.1.1.3 root 102: //
103: // R_InstallSpriteLump
104: // Local function for R_InitSprites.
105: //
106: void
107: R_InstallSpriteLump
108: ( int lump,
109: unsigned frame,
110: unsigned rotation,
111: boolean flipped )
112: {
113: int r;
114:
115: if (frame >= 29 || rotation > 8)
116: I_Error("R_InstallSpriteLump: "
117: "Bad frame characters in lump %i", lump);
118:
119: if ((int)frame > maxframe)
120: maxframe = frame;
121:
122: if (rotation == 0)
123: {
124: // the lump should be used for all rotations
125: if (sprtemp[frame].rotate == false)
126: I_Error ("R_InitSprites: Sprite %s frame %c has "
127: "multip rot=0 lump", spritename, 'A'+frame);
1.1 root 128:
1.1.1.3 root 129: if (sprtemp[frame].rotate == true)
130: I_Error ("R_InitSprites: Sprite %s frame %c has rotations "
131: "and a rot=0 lump", spritename, 'A'+frame);
132:
133: sprtemp[frame].rotate = false;
134: for (r=0 ; r<8 ; r++)
135: {
136: sprtemp[frame].lump[r] = lump - firstspritelump;
137: sprtemp[frame].flip[r] = (byte)flipped;
138: }
139: return;
140: }
141:
142: // the lump is only used for one rotation
143: if (sprtemp[frame].rotate == false)
144: I_Error ("R_InitSprites: Sprite %s frame %c has rotations "
145: "and a rot=0 lump", spritename, 'A'+frame);
146:
147: sprtemp[frame].rotate = true;
148:
149: // make 0 based
150: rotation--;
151: if (sprtemp[frame].lump[rotation] != -1)
152: I_Error ("R_InitSprites: Sprite %s : %c : %c "
153: "has two lumps mapped to it",
154: spritename, 'A'+frame, '1'+rotation);
155:
156: sprtemp[frame].lump[rotation] = lump - firstspritelump;
157: sprtemp[frame].flip[rotation] = (byte)flipped;
1.1 root 158: }
159:
160:
161:
162:
1.1.1.3 root 163: //
164: // R_InitSpriteDefs
165: // Pass a null terminated list of sprite names
166: // (4 chars exactly) to be used.
167: // Builds the sprite rotation matrixes to account
168: // for horizontally flipped sprites.
169: // Will report an error if the lumps are inconsistant.
170: // Only called at startup.
171: //
172: // Sprite lump names are 4 characters for the actor,
173: // a letter for the frame, and a number for the rotation.
174: // A sprite that is flippable will have an additional
175: // letter/number appended.
176: // The rotation character can be 0 to signify no rotations.
177: //
178: void R_InitSpriteDefs (char** namelist)
179: {
180: char** check;
181: int i;
182: int l;
183: int intname;
184: int frame;
185: int rotation;
186: int start;
187: int end;
188: int patched;
189:
190: // count the number of sprite names
191: check = namelist;
192: while (*check != NULL)
193: check++;
194:
195: numsprites = check-namelist;
196:
197: if (!numsprites)
198: return;
199:
200: sprites = Z_Malloc(numsprites *sizeof(*sprites), PU_STATIC, NULL);
201:
202: start = firstspritelump-1;
203: end = lastspritelump+1;
204:
205: // scan all the lump names for each of the names,
206: // noting the highest frame letter.
207: // Just compare 4 characters as ints
208: for (i=0 ; i<numsprites ; i++)
209: {
210: spritename = namelist[i];
211: memset (sprtemp,-1, sizeof(sprtemp));
212:
213: maxframe = -1;
214: intname = *(int *)namelist[i];
215:
216: // scan the lumps,
217: // filling in the frames for whatever is found
218: for (l=start+1 ; l<end ; l++)
219: {
220: if (*(int *)lumpinfo[l].name == intname)
221: {
222: frame = lumpinfo[l].name[4] - 'A';
223: rotation = lumpinfo[l].name[5] - '0';
224:
225: if (modifiedgame)
226: patched = W_GetNumForName (lumpinfo[l].name);
227: else
228: patched = l;
1.1 root 229:
1.1.1.3 root 230: R_InstallSpriteLump (patched, frame, rotation, false);
231:
232: if (lumpinfo[l].name[6])
1.1 root 233: {
1.1.1.3 root 234: frame = lumpinfo[l].name[6] - 'A';
235: rotation = lumpinfo[l].name[7] - '0';
236: R_InstallSpriteLump (l, frame, rotation, true);
1.1 root 237: }
1.1.1.3 root 238: }
239: }
240:
241: // check the frames that were found for completeness
242: if (maxframe == -1)
243: {
244: sprites[i].numframes = 0;
245: continue;
246: }
247:
248: maxframe++;
249:
250: for (frame = 0 ; frame < maxframe ; frame++)
251: {
252: switch ((int)sprtemp[frame].rotate)
253: {
254: case -1:
255: // no rotations were found for that frame at all
256: I_Error ("R_InitSprites: No patches found "
257: "for %s frame %c", namelist[i], frame+'A');
258: break;
259:
260: case 0:
261: // only the first rotation is needed
262: break;
263:
264: case 1:
265: // must have all 8 frames
266: for (rotation=0 ; rotation<8 ; rotation++)
267: if (sprtemp[frame].lump[rotation] == -1)
268: I_Error ("R_InitSprites: Sprite %s frame %c "
269: "is missing rotations",
270: namelist[i], frame+'A');
271: break;
272: }
1.1 root 273: }
1.1.1.3 root 274:
275: // allocate space for the frames present and copy sprtemp to it
276: sprites[i].numframes = maxframe;
277: sprites[i].spriteframes =
278: Z_Malloc (maxframe * sizeof(spriteframe_t), PU_STATIC, NULL);
279: memcpy (sprites[i].spriteframes, sprtemp, maxframe*sizeof(spriteframe_t));
280: }
1.1 root 281:
282: }
283:
284:
285:
286:
1.1.1.3 root 287: //
288: // GAME FUNCTIONS
289: //
290: vissprite_t vissprites[MAXVISSPRITES];
291: vissprite_t* vissprite_p;
292: int newvissprite;
1.1 root 293:
294:
295:
1.1.1.3 root 296: //
297: // R_InitSprites
298: // Called at program start.
299: //
300: void R_InitSprites (char** namelist)
1.1 root 301: {
1.1.1.3 root 302: int i;
303:
304: for (i=0 ; i<SCREENWIDTH ; i++)
305: {
306: negonearray[i] = -1;
307: }
308:
309: R_InitSpriteDefs (namelist);
1.1 root 310: }
311:
312:
313:
1.1.1.3 root 314: //
315: // R_ClearSprites
316: // Called at frame start.
317: //
1.1 root 318: void R_ClearSprites (void)
319: {
1.1.1.3 root 320: vissprite_p = vissprites;
1.1 root 321: }
322:
323:
1.1.1.3 root 324: //
325: // R_NewVisSprite
326: //
327: vissprite_t overflowsprite;
1.1 root 328:
1.1.1.3 root 329: vissprite_t* R_NewVisSprite (void)
1.1 root 330: {
1.1.1.3 root 331: if (vissprite_p == &vissprites[MAXVISSPRITES])
332: return &overflowsprite;
333:
334: vissprite_p++;
335: return vissprite_p-1;
1.1 root 336: }
337:
338:
339:
1.1.1.3 root 340: //
341: // R_DrawMaskedColumn
342: // Used for sprites and masked mid textures.
343: // Masked means: partly transparent, i.e. stored
344: // in posts/runs of opaque pixels.
345: //
346: short* mfloorclip;
347: short* mceilingclip;
348:
1.1 root 349: fixed_t spryscale;
350: fixed_t sprtopscreen;
351:
1.1.1.3 root 352: void R_DrawMaskedColumn (column_t* column)
1.1 root 353: {
1.1.1.3 root 354: int topscreen;
355: int bottomscreen;
356: fixed_t basetexturemid;
357:
358: basetexturemid = dc_texturemid;
359:
360: for ( ; column->topdelta != 0xff ; )
361: {
362: // calculate unclipped screen coordinates
363: // for post
364: topscreen = sprtopscreen + spryscale*column->topdelta;
365: bottomscreen = topscreen + spryscale*column->length;
366:
367: dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
368: dc_yh = (bottomscreen-1)>>FRACBITS;
369:
370: if (dc_yh >= mfloorclip[dc_x])
371: dc_yh = mfloorclip[dc_x]-1;
372: if (dc_yl <= mceilingclip[dc_x])
373: dc_yl = mceilingclip[dc_x]+1;
374:
375: if (dc_yl <= dc_yh)
376: {
377: dc_source = (byte *)column + 3;
378: dc_texturemid = basetexturemid - (column->topdelta<<FRACBITS);
379: // dc_source = (byte *)column + 3 - column->topdelta;
380:
381: // Drawn by either R_DrawColumn
382: // or (SHADOW) R_DrawFuzzColumn.
383: colfunc ();
1.1 root 384: }
1.1.1.3 root 385: column = (column_t *)( (byte *)column + column->length + 4);
386: }
387:
388: dc_texturemid = basetexturemid;
1.1 root 389: }
390:
391:
392:
1.1.1.3 root 393: //
394: // R_DrawVisSprite
395: // mfloorclip and mceilingclip should also be set.
396: //
397: void
398: R_DrawVisSprite
399: ( vissprite_t* vis,
400: int x1,
401: int x2 )
1.1 root 402: {
1.1.1.3 root 403: column_t* column;
404: int texturecolumn;
405: fixed_t frac;
406: patch_t* patch;
407:
408:
409: patch = W_CacheLumpNum (vis->patch+firstspritelump, PU_CACHE);
1.1 root 410:
1.1.1.3 root 411: dc_colormap = vis->colormap;
412:
413: if (!dc_colormap)
414: {
415: // NULL colormap = shadow draw
416: colfunc = fuzzcolfunc;
417: }
418: else if (vis->mobjflags & MF_TRANSLATION)
419: {
420: colfunc = R_DrawTranslatedColumn;
421: dc_translation = translationtables - 256 +
422: ( (vis->mobjflags & MF_TRANSLATION) >> (MF_TRANSSHIFT-8) );
423: }
424:
425: dc_iscale = abs(vis->xiscale)>>detailshift;
426: dc_texturemid = vis->texturemid;
427: frac = vis->startfrac;
428: spryscale = vis->scale;
429: sprtopscreen = centeryfrac - FixedMul(dc_texturemid,spryscale);
430:
431: for (dc_x=vis->x1 ; dc_x<=vis->x2 ; dc_x++, frac += vis->xiscale)
432: {
433: texturecolumn = frac>>FRACBITS;
1.1 root 434: #ifdef RANGECHECK
1.1.1.3 root 435: if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
436: I_Error ("R_DrawSpriteRange: bad texturecolumn");
1.1 root 437: #endif
1.1.1.3 root 438: column = (column_t *) ((byte *)patch +
439: LONG(patch->columnofs[texturecolumn]));
440: R_DrawMaskedColumn (column);
441: }
442:
443: colfunc = basecolfunc;
1.1 root 444: }
445:
446:
447:
448: //
1.1.1.3 root 449: // R_ProjectSprite
450: // Generates a vissprite for a thing
451: // if it might be visible.
452: //
453: void R_ProjectSprite (mobj_t* thing)
454: {
455: fixed_t tr_x;
456: fixed_t tr_y;
457:
458: fixed_t gxt;
459: fixed_t gyt;
460:
461: fixed_t tx;
462: fixed_t tz;
463:
464: fixed_t xscale;
465:
466: int x1;
467: int x2;
468:
469: spritedef_t* sprdef;
470: spriteframe_t* sprframe;
471: int lump;
472:
473: unsigned rot;
474: boolean flip;
475:
476: int index;
477:
478: vissprite_t* vis;
479:
480: angle_t ang;
481: fixed_t iscale;
482:
483: // transform the origin point
484: tr_x = thing->x - viewx;
485: tr_y = thing->y - viewy;
1.1 root 486:
1.1.1.3 root 487: gxt = FixedMul(tr_x,viewcos);
488: gyt = -FixedMul(tr_y,viewsin);
489:
490: tz = gxt-gyt;
491:
492: // thing is behind view plane?
493: if (tz < MINZ)
494: return;
495:
496: xscale = FixedDiv(projection, tz);
497:
498: gxt = -FixedMul(tr_x,viewsin);
499: gyt = FixedMul(tr_y,viewcos);
500: tx = -(gyt+gxt);
501:
502: // too far off the side?
503: if (abs(tx)>(tz<<2))
504: return;
505:
506: // decide which patch to use for sprite relative to player
1.1 root 507: #ifdef RANGECHECK
1.1.1.3 root 508: if ((unsigned)thing->sprite >= numsprites)
509: I_Error ("R_ProjectSprite: invalid sprite number %i ",
510: thing->sprite);
1.1 root 511: #endif
1.1.1.3 root 512: sprdef = &sprites[thing->sprite];
1.1 root 513: #ifdef RANGECHECK
1.1.1.3 root 514: if ( (thing->frame&FF_FRAMEMASK) >= sprdef->numframes )
515: I_Error ("R_ProjectSprite: invalid sprite frame %i : %i ",
516: thing->sprite, thing->frame);
1.1 root 517: #endif
1.1.1.3 root 518: sprframe = &sprdef->spriteframes[ thing->frame & FF_FRAMEMASK];
1.1 root 519:
1.1.1.3 root 520: if (sprframe->rotate)
521: {
522: // choose a different rotation based on player view
523: ang = R_PointToAngle (thing->x, thing->y);
524: rot = (ang-thing->angle+(unsigned)(ANG45/2)*9)>>29;
525: lump = sprframe->lump[rot];
526: flip = (boolean)sprframe->flip[rot];
527: }
528: else
529: {
530: // use single rotation for all views
531: lump = sprframe->lump[0];
532: flip = (boolean)sprframe->flip[0];
533: }
534:
535: // calculate edges of the shape
536: tx -= spriteoffset[lump];
537: x1 = (centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS;
538:
539: // off the right side?
540: if (x1 > viewwidth)
541: return;
542:
543: tx += spritewidth[lump];
544: x2 = ((centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS) - 1;
545:
546: // off the left side
547: if (x2 < 0)
548: return;
549:
550: // store information in a vissprite
551: vis = R_NewVisSprite ();
552: vis->mobjflags = thing->flags;
553: vis->scale = xscale<<detailshift;
554: vis->gx = thing->x;
555: vis->gy = thing->y;
556: vis->gz = thing->z;
557: vis->gzt = thing->z + spritetopoffset[lump];
558: vis->texturemid = vis->gzt - viewz;
559: vis->x1 = x1 < 0 ? 0 : x1;
560: vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
561: iscale = FixedDiv (FRACUNIT, xscale);
562:
563: if (flip)
564: {
565: vis->startfrac = spritewidth[lump]-1;
566: vis->xiscale = -iscale;
567: }
568: else
569: {
570: vis->startfrac = 0;
571: vis->xiscale = iscale;
572: }
573:
574: if (vis->x1 > x1)
575: vis->startfrac += vis->xiscale*(vis->x1-x1);
576: vis->patch = lump;
577:
578: // get light level
579: if (thing->flags & MF_SHADOW)
580: {
581: // shadow draw
582: vis->colormap = NULL;
583: }
584: else if (fixedcolormap)
585: {
586: // fixed map
587: vis->colormap = fixedcolormap;
588: }
589: else if (thing->frame & FF_FULLBRIGHT)
590: {
591: // full bright
592: vis->colormap = colormaps;
593: }
594:
595: else
596: {
597: // diminished light
598: index = xscale>>(LIGHTSCALESHIFT-detailshift);
599:
600: if (index >= MAXLIGHTSCALE)
601: index = MAXLIGHTSCALE-1;
602:
603: vis->colormap = spritelights[index];
604: }
1.1 root 605: }
606:
607:
608:
609:
1.1.1.3 root 610: //
611: // R_AddSprites
612: // During BSP traversal, this adds sprites by sector.
613: //
614: void R_AddSprites (sector_t* sec)
615: {
616: mobj_t* thing;
617: int lightnum;
618:
619: // BSP is traversed by subsector.
620: // A sector might have been split into several
621: // subsectors during BSP building.
622: // Thus we check whether its already added.
623: if (sec->validcount == validcount)
624: return;
1.1 root 625:
1.1.1.3 root 626: // Well, now it will be done.
627: sec->validcount = validcount;
628:
629: lightnum = (sec->lightlevel >> LIGHTSEGSHIFT)+extralight;
1.1 root 630:
1.1.1.3 root 631: if (lightnum < 0)
632: spritelights = scalelight[0];
633: else if (lightnum >= LIGHTLEVELS)
634: spritelights = scalelight[LIGHTLEVELS-1];
635: else
636: spritelights = scalelight[lightnum];
1.1 root 637:
1.1.1.3 root 638: // Handle all things in sector.
639: for (thing = sec->thinglist ; thing ; thing = thing->snext)
640: R_ProjectSprite (thing);
1.1 root 641: }
642:
643:
644: //
1.1.1.3 root 645: // R_DrawPSprite
1.1 root 646: //
1.1.1.3 root 647: void R_DrawPSprite (pspdef_t* psp)
648: {
649: fixed_t tx;
650: int x1;
651: int x2;
652: spritedef_t* sprdef;
653: spriteframe_t* sprframe;
654: int lump;
655: boolean flip;
656: vissprite_t* vis;
657: vissprite_t avis;
658:
659: // decide which patch to use
1.1 root 660: #ifdef RANGECHECK
1.1.1.3 root 661: if ( (unsigned)psp->state->sprite >= numsprites)
662: I_Error ("R_ProjectSprite: invalid sprite number %i ",
663: psp->state->sprite);
1.1 root 664: #endif
1.1.1.3 root 665: sprdef = &sprites[psp->state->sprite];
1.1 root 666: #ifdef RANGECHECK
1.1.1.3 root 667: if ( (psp->state->frame & FF_FRAMEMASK) >= sprdef->numframes)
668: I_Error ("R_ProjectSprite: invalid sprite frame %i : %i ",
669: psp->state->sprite, psp->state->frame);
1.1 root 670: #endif
1.1.1.3 root 671: sprframe = &sprdef->spriteframes[ psp->state->frame & FF_FRAMEMASK ];
1.1 root 672:
1.1.1.3 root 673: lump = sprframe->lump[0];
674: flip = (boolean)sprframe->flip[0];
675:
676: // calculate edges of the shape
677: tx = psp->sx-160*FRACUNIT;
678:
679: tx -= spriteoffset[lump];
680: x1 = (centerxfrac + FixedMul (tx,pspritescale) ) >>FRACBITS;
1.1 root 681:
1.1.1.3 root 682: // off the right side
683: if (x1 > viewwidth)
684: return;
685:
686: tx += spritewidth[lump];
687: x2 = ((centerxfrac + FixedMul (tx, pspritescale) ) >>FRACBITS) - 1;
688:
689: // off the left side
690: if (x2 < 0)
691: return;
692:
693: // store information in a vissprite
694: vis = &avis;
695: vis->mobjflags = 0;
696: vis->texturemid = (BASEYCENTER<<FRACBITS)+FRACUNIT/2-(psp->sy-spritetopoffset[lump]);
697: vis->x1 = x1 < 0 ? 0 : x1;
698: vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
699: vis->scale = pspritescale<<detailshift;
700:
701: if (flip)
702: {
703: vis->xiscale = -pspriteiscale;
704: vis->startfrac = spritewidth[lump]-1;
705: }
706: else
707: {
708: vis->xiscale = pspriteiscale;
709: vis->startfrac = 0;
710: }
711:
712: if (vis->x1 > x1)
713: vis->startfrac += vis->xiscale*(vis->x1-x1);
714:
715: vis->patch = lump;
716:
717: if (viewplayer->powers[pw_invisibility] > 4*32
718: || viewplayer->powers[pw_invisibility] & 8)
719: {
720: // shadow draw
721: vis->colormap = NULL;
722: }
723: else if (fixedcolormap)
724: {
725: // fixed color
726: vis->colormap = fixedcolormap;
727: }
728: else if (psp->state->frame & FF_FULLBRIGHT)
729: {
730: // full bright
731: vis->colormap = colormaps;
732: }
733: else
734: {
735: // local light
736: vis->colormap = spritelights[MAXLIGHTSCALE-1];
737: }
738:
739: R_DrawVisSprite (vis, vis->x1, vis->x2);
1.1 root 740: }
741:
742:
743:
744: //
1.1.1.3 root 745: // R_DrawPlayerSprites
1.1 root 746: //
1.1.1.3 root 747: void R_DrawPlayerSprites (void)
748: {
749: int i;
750: int lightnum;
751: pspdef_t* psp;
752:
753: // get light level
754: lightnum =
755: (viewplayer->mo->subsector->sector->lightlevel >> LIGHTSEGSHIFT)
756: +extralight;
757:
758: if (lightnum < 0)
759: spritelights = scalelight[0];
760: else if (lightnum >= LIGHTLEVELS)
761: spritelights = scalelight[LIGHTLEVELS-1];
762: else
763: spritelights = scalelight[lightnum];
764:
765: // clip to screen bounds
766: mfloorclip = screenheightarray;
767: mceilingclip = negonearray;
768:
769: // add all active psprites
770: for (i=0, psp=viewplayer->psprites;
771: i<NUMPSPRITES;
772: i++,psp++)
773: {
774: if (psp->state)
775: R_DrawPSprite (psp);
776: }
1.1 root 777: }
778:
779:
780:
781:
782: //
1.1.1.3 root 783: // R_SortVisSprites
1.1 root 784: //
1.1.1.3 root 785: vissprite_t vsprsortedhead;
1.1 root 786:
787:
1.1.1.3 root 788: void R_SortVisSprites (void)
1.1 root 789: {
1.1.1.3 root 790: int i;
791: int count;
792: vissprite_t* ds;
793: vissprite_t* best;
794: vissprite_t unsorted;
795: fixed_t bestscale;
1.1 root 796:
1.1.1.3 root 797: count = vissprite_p - vissprites;
798:
799: unsorted.next = unsorted.prev = &unsorted;
800:
801: if (!count)
802: return;
803:
804: for (ds=vissprites ; ds<vissprite_p ; ds++)
805: {
806: ds->next = ds+1;
807: ds->prev = ds-1;
808: }
809:
810: vissprites[0].prev = &unsorted;
811: unsorted.next = &vissprites[0];
812: (vissprite_p-1)->next = &unsorted;
813: unsorted.prev = vissprite_p-1;
814:
815: // pull the vissprites out by scale
816: //best = 0; // shut up the compiler warning
817: vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead;
818: for (i=0 ; i<count ; i++)
819: {
820: bestscale = MAXINT;
821: for (ds=unsorted.next ; ds!= &unsorted ; ds=ds->next)
822: {
823: if (ds->scale < bestscale)
824: {
825: bestscale = ds->scale;
826: best = ds;
827: }
828: }
829: best->next->prev = best->prev;
830: best->prev->next = best->next;
831: best->next = &vsprsortedhead;
832: best->prev = vsprsortedhead.prev;
833: vsprsortedhead.prev->next = best;
834: vsprsortedhead.prev = best;
835: }
836: }
1.1 root 837:
838:
839:
840: //
1.1.1.3 root 841: // R_DrawSprite
842: //
843: void R_DrawSprite (vissprite_t* spr)
844: {
845: drawseg_t* ds;
846: short clipbot[SCREENWIDTH];
847: short cliptop[SCREENWIDTH];
848: int x;
849: int r1;
850: int r2;
851: fixed_t scale;
852: fixed_t lowscale;
853: int silhouette;
854:
855: for (x = spr->x1 ; x<=spr->x2 ; x++)
856: clipbot[x] = cliptop[x] = -2;
857:
858: // Scan drawsegs from end to start for obscuring segs.
859: // The first drawseg that has a greater scale
860: // is the clip seg.
861: for (ds=ds_p-1 ; ds >= drawsegs ; ds--)
862: {
863: // determine if the drawseg obscures the sprite
864: if (ds->x1 > spr->x2
865: || ds->x2 < spr->x1
866: || (!ds->silhouette
867: && !ds->maskedtexturecol) )
868: {
869: // does not cover sprite
870: continue;
871: }
872:
873: r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1;
874: r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2;
1.1 root 875:
1.1.1.3 root 876: if (ds->scale1 > ds->scale2)
877: {
878: lowscale = ds->scale2;
879: scale = ds->scale1;
880: }
881: else
882: {
883: lowscale = ds->scale1;
884: scale = ds->scale2;
885: }
886:
887: if (scale < spr->scale
888: || ( lowscale < spr->scale
889: && !R_PointOnSegSide (spr->gx, spr->gy, ds->curline) ) )
890: {
891: // masked mid texture?
892: if (ds->maskedtexturecol)
893: R_RenderMaskedSegRange (ds, r1, r2);
894: // seg is behind sprite
895: continue;
1.1 root 896: }
897:
1.1.1.3 root 898:
899: // clip this piece of the sprite
900: silhouette = ds->silhouette;
901:
902: if (spr->gz >= ds->bsilheight)
903: silhouette &= ~SIL_BOTTOM;
1.1 root 904:
1.1.1.3 root 905: if (spr->gzt <= ds->tsilheight)
906: silhouette &= ~SIL_TOP;
907:
908: if (silhouette == 1)
1.1 root 909: {
1.1.1.3 root 910: // bottom sil
911: for (x=r1 ; x<=r2 ; x++)
1.1 root 912: if (clipbot[x] == -2)
1.1.1.3 root 913: clipbot[x] = ds->sprbottomclip[x];
914: }
915: else if (silhouette == 2)
916: {
917: // top sil
918: for (x=r1 ; x<=r2 ; x++)
1.1 root 919: if (cliptop[x] == -2)
1.1.1.3 root 920: cliptop[x] = ds->sprtopclip[x];
1.1 root 921: }
1.1.1.3 root 922: else if (silhouette == 3)
923: {
924: // both
925: for (x=r1 ; x<=r2 ; x++)
926: {
927: if (clipbot[x] == -2)
928: clipbot[x] = ds->sprbottomclip[x];
929: if (cliptop[x] == -2)
930: cliptop[x] = ds->sprtopclip[x];
931: }
932: }
933:
934: }
935:
936: // all clipping has been performed, so draw the sprite
1.1 root 937:
1.1.1.3 root 938: // check for unclipped columns
939: for (x = spr->x1 ; x<=spr->x2 ; x++)
940: {
941: if (clipbot[x] == -2)
942: clipbot[x] = viewheight;
1.1 root 943:
1.1.1.3 root 944: if (cliptop[x] == -2)
945: cliptop[x] = -1;
946: }
947:
948: mfloorclip = clipbot;
949: mceilingclip = cliptop;
950: R_DrawVisSprite (spr, spr->x1, spr->x2);
951: }
1.1 root 952:
953:
954:
955:
956: //
1.1.1.3 root 957: // R_DrawMasked
1.1 root 958: //
1.1.1.3 root 959: void R_DrawMasked (void)
960: {
961: vissprite_t* spr;
962: drawseg_t* ds;
963:
964: R_SortVisSprites ();
1.1 root 965:
1.1.1.3 root 966: if (vissprite_p > vissprites)
967: {
968: // draw all vissprites back to front
969: for (spr = vsprsortedhead.next ;
970: spr != &vsprsortedhead ;
971: spr=spr->next)
972: {
973:
974: R_DrawSprite (spr);
975: }
976: }
977:
978: // render any remaining masked mid textures
979: for (ds=ds_p-1 ; ds >= drawsegs ; ds--)
980: if (ds->maskedtexturecol)
981: R_RenderMaskedSegRange (ds, ds->x1, ds->x2);
982:
983: // draw the psprites on top of everything
984: // but does not draw on side views
985: if (!viewangleoffset)
986: R_DrawPlayerSprites ();
1.1 root 987: }
988:
989:
1.1.1.3 root 990:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.