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