set the include directory
[AROS-Contrib.git] / Games / Doom / r_things.c
blob5635cabd0911df8c818191643daa4e8f9ba9fb21
1 // Emacs style mode select -*- C++ -*-
2 //-----------------------------------------------------------------------------
3 //
4 // $Id$
5 //
6 // Copyright (C) 1993-1996 by id Software, Inc.
7 //
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.
12 // The source is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
15 // for more details.
17 // $Log$
18 // Revision 1.1 2000/02/29 18:21:05 stegerg
19 // Doom port based on ADoomPPC. Read README.AROS!
22 // DESCRIPTION:
23 // Refresh of things, i.e. objects represented by sprites.
25 //-----------------------------------------------------------------------------
28 static const char
29 rcsid[] = "$Id$";
32 #include <stdio.h>
33 #include <stdlib.h>
36 #include "doomdef.h"
37 #include "m_swap.h"
39 #include "i_system.h"
40 #include "z_zone.h"
41 #include "w_wad.h"
43 #include "r_local.h"
45 #include "doomstat.h"
49 #define MINZ (FRACUNIT*4)
50 //#define BASEYCENTER 100
51 #define BASEYCENTER ((weirdaspect==1)?100:75)
53 //void R_DrawColumn (void);
54 //void R_DrawFuzzColumn (void);
58 typedef struct
60 int x1;
61 int x2;
63 int column;
64 int topclip;
65 int bottomclip;
67 } maskdraw_t;
72 // Sprite rotation 0 is facing the viewer,
73 // rotation 1 is one angle turn CLOCKWISE around the axis.
74 // This is not the same as the angle,
75 // which increases counter clockwise (protractor).
76 // There was a lot of stuff grabbed wrong, so I changed it...
78 fixed_t pspritescale;
79 fixed_t pspriteiscale;
80 //fixed_t pspritescale2;
81 fixed_t pspriteiscale2;
83 lighttable_t** spritelights;
85 // constant arrays
86 // used for psprite clipping and initializing clipping
87 //short negonearray[SCREENWIDTH];
88 //short screenheightarray[SCREENWIDTH];
89 short *negonearray;
90 short *screenheightarray;
94 // INITIALIZATION FUNCTIONS
97 // variables used to look up
98 // and range check thing_t sprites patches
99 spritedef_t* sprites;
100 int numsprites;
102 FAR spriteframe_t sprtemp[29];
103 int maxframe;
104 char* spritename;
110 // R_InstallSpriteLump
111 // Local function for R_InitSprites.
113 void
114 R_InstallSpriteLump
115 ( int lump,
116 unsigned frame,
117 unsigned rotation,
118 boolean flipped )
120 int r;
122 if (frame >= 29 || rotation > 8)
123 I_Error("R_InstallSpriteLump: "
124 "Bad frame characters in lump %i", lump);
126 if ((int)frame > maxframe)
127 maxframe = frame;
129 if (rotation == 0)
131 // the lump should be used for all rotations
132 if (sprtemp[frame].rotate == false)
133 I_Error ("R_InitSprites: Sprite %s frame %c has "
134 "multip rot=0 lump", spritename, 'A'+frame);
136 if (sprtemp[frame].rotate == true)
137 I_Error ("R_InitSprites: Sprite %s frame %c has rotations "
138 "and a rot=0 lump", spritename, 'A'+frame);
140 sprtemp[frame].rotate = false;
141 for (r=0 ; r<8 ; r++)
143 sprtemp[frame].lump[r] = lump - firstspritelump;
144 sprtemp[frame].flip[r] = (byte)flipped;
146 return;
149 // the lump is only used for one rotation
150 if (sprtemp[frame].rotate == false)
151 I_Error ("R_InitSprites: Sprite %s frame %c has rotations "
152 "and a rot=0 lump", spritename, 'A'+frame);
154 sprtemp[frame].rotate = true;
156 // make 0 based
157 rotation--;
158 if (sprtemp[frame].lump[rotation] != -1)
159 I_Error ("R_InitSprites: Sprite %s : %c : %c "
160 "has two lumps mapped to it",
161 spritename, 'A'+frame, '1'+rotation);
163 sprtemp[frame].lump[rotation] = lump - firstspritelump;
164 sprtemp[frame].flip[rotation] = (byte)flipped;
171 // R_InitSpriteDefs
172 // Pass a null terminated list of sprite names
173 // (4 chars exactly) to be used.
174 // Builds the sprite rotation matrixes to account
175 // for horizontally flipped sprites.
176 // Will report an error if the lumps are inconsistant.
177 // Only called at startup.
179 // Sprite lump names are 4 characters for the actor,
180 // a letter for the frame, and a number for the rotation.
181 // A sprite that is flippable will have an additional
182 // letter/number appended.
183 // The rotation character can be 0 to signify no rotations.
185 void R_InitSpriteDefs (char** namelist)
187 char** check;
188 int i;
189 int l;
190 int intname;
191 int frame;
192 int rotation;
193 int start;
194 int end;
195 int patched;
197 // count the number of sprite names
198 check = namelist;
199 while (*check != NULL)
200 check++;
202 numsprites = check-namelist;
204 if (!numsprites)
205 return;
207 sprites = Z_Malloc(numsprites *sizeof(*sprites), PU_STATIC, NULL);
209 start = firstspritelump-1;
210 end = lastspritelump+1;
212 // scan all the lump names for each of the names,
213 // noting the highest frame letter.
214 // Just compare 4 characters as ints
215 for (i=0 ; i<numsprites ; i++)
217 spritename = namelist[i];
218 memset (sprtemp,-1, sizeof(sprtemp));
220 maxframe = -1;
221 intname = *(int *)namelist[i];
223 // scan the lumps,
224 // filling in the frames for whatever is found
225 for (l=start+1 ; l<end ; l++)
227 if (*(int *)lumpinfo[l].name == intname)
229 frame = lumpinfo[l].name[4] - 'A';
230 rotation = lumpinfo[l].name[5] - '0';
232 if (modifiedgame)
233 patched = W_GetNumForName (lumpinfo[l].name);
234 else
235 patched = l;
237 R_InstallSpriteLump (patched, frame, rotation, false);
239 if (lumpinfo[l].name[6])
241 frame = lumpinfo[l].name[6] - 'A';
242 rotation = lumpinfo[l].name[7] - '0';
243 R_InstallSpriteLump (l, frame, rotation, true);
248 // check the frames that were found for completeness
249 if (maxframe == -1)
251 sprites[i].numframes = 0;
252 continue;
255 maxframe++;
257 for (frame = 0 ; frame < maxframe ; frame++)
259 switch ((int)sprtemp[frame].rotate)
261 case -1:
262 // no rotations were found for that frame at all
263 I_Error ("R_InitSprites: No patches found "
264 "for %s frame %c", namelist[i], frame+'A');
265 break;
267 case 0:
268 // only the first rotation is needed
269 break;
271 case 1:
272 // must have all 8 frames
273 for (rotation=0 ; rotation<8 ; rotation++)
274 if (sprtemp[frame].lump[rotation] == -1)
275 I_Error ("R_InitSprites: Sprite %s frame %c "
276 "is missing rotations",
277 namelist[i], frame+'A');
278 break;
282 // allocate space for the frames present and copy sprtemp to it
283 sprites[i].numframes = maxframe;
284 sprites[i].spriteframes =
285 Z_Malloc (maxframe * sizeof(spriteframe_t), PU_STATIC, NULL);
286 memcpy (sprites[i].spriteframes, sprtemp, maxframe*sizeof(spriteframe_t));
295 // GAME FUNCTIONS
297 FAR vissprite_t vissprites[MAXVISSPRITES];
298 vissprite_t* vissprite_p;
299 int newvissprite;
304 // R_InitSprites
305 // Called at program start.
307 void R_InitSprites (char** namelist)
309 int i;
311 for (i=0 ; i<SCREENWIDTH ; i++)
313 negonearray[i] = -1;
316 R_InitSpriteDefs (namelist);
322 // R_ClearSprites
323 // Called at frame start.
325 void R_ClearSprites (void)
327 vissprite_p = vissprites;
332 // R_NewVisSprite
334 vissprite_t overflowsprite;
336 vissprite_t* R_NewVisSprite (void)
338 if (vissprite_p == &vissprites[MAXVISSPRITES])
339 return &overflowsprite;
341 vissprite_p++;
342 return vissprite_p-1;
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.
353 short* mfloorclip;
354 short* mceilingclip;
356 fixed_t spryscale;
357 fixed_t sprtopscreen;
359 void R_DrawMaskedColumn (column_t* column)
361 int topscreen;
362 int bottomscreen;
363 fixed_t basetexturemid;
365 basetexturemid = dc_texturemid;
367 for ( ; column->topdelta != 0xff ; )
369 // calculate unclipped screen coordinates
370 // for post
371 topscreen = sprtopscreen + spryscale*column->topdelta;
372 bottomscreen = topscreen + spryscale*column->length;
374 dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
375 dc_yh = (bottomscreen-1)>>FRACBITS;
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;
382 if (dc_yl <= dc_yh)
384 dc_source = (byte *)column + 3;
385 dc_texturemid = basetexturemid - (column->topdelta<<FRACBITS);
386 // dc_source = (byte *)column + 3 - column->topdelta;
388 // Drawn by either R_DrawColumn
389 // or (SHADOW) R_DrawFuzzColumn.
390 colfunc ();
392 column = (column_t *)( (byte *)column + column->length + 4);
395 dc_texturemid = basetexturemid;
401 // R_DrawVisSprite
402 // mfloorclip and mceilingclip should also be set.
404 void
405 R_DrawVisSprite
406 ( vissprite_t* vis,
407 int x1,
408 int x2 )
410 column_t* column;
411 int texturecolumn;
412 fixed_t frac;
413 patch_t* patch;
416 patch = W_CacheLumpNum (vis->patch+firstspritelump, PU_CACHE);
418 dc_colormap = vis->colormap;
420 if (!dc_colormap)
422 // NULL colormap = shadow draw
423 colfunc = fuzzcolfunc;
425 else if (vis->mobjflags & MF_TRANSLATION)
427 colfunc = transcolfunc;
428 dc_translation = translationtables - 256 +
429 ( (vis->mobjflags & MF_TRANSLATION) >> (MF_TRANSSHIFT-8) );
432 dc_iscale = iabs(vis->xiscale)>>detailshift;
433 dc_texturemid = vis->texturemid;
434 frac = vis->startfrac;
435 spryscale = vis->scale;
436 sprtopscreen = centeryfrac - FixedMul(dc_texturemid,spryscale);
438 for (dc_x=vis->x1 ; dc_x<=vis->x2 ; dc_x++, frac += vis->xiscale)
440 texturecolumn = frac>>FRACBITS;
441 #ifdef RANGECHECK
442 if (texturecolumn < 0 || texturecolumn >= SWAPSHORT(patch->width))
443 I_Error ("R_DrawSpriteRange: bad texturecolumn");
444 #endif
445 column = (column_t *) ((byte *)patch +
446 SWAPLONG(patch->columnofs[texturecolumn]));
448 R_DrawMaskedColumn (column);
451 colfunc = basecolfunc;
457 // R_ProjectSprite
458 // Generates a vissprite for a thing
459 // if it might be visible.
461 void R_ProjectSprite (mobj_t* thing)
463 fixed_t tr_x;
464 fixed_t tr_y;
466 fixed_t gxt;
467 fixed_t gyt;
469 fixed_t tx;
470 fixed_t tz;
472 fixed_t xscale;
474 int x1;
475 int x2;
477 spritedef_t* sprdef;
478 spriteframe_t* sprframe;
479 int lump;
481 unsigned rot;
482 boolean flip;
484 int index;
486 vissprite_t* vis;
488 angle_t ang;
489 fixed_t iscale;
491 // transform the origin point
492 tr_x = thing->x - viewx;
493 tr_y = thing->y - viewy;
495 gxt = FixedMul(tr_x,viewcos);
496 gyt = -FixedMul(tr_y,viewsin);
498 tz = gxt-gyt;
500 // thing is behind view plane?
501 if (tz < MINZ)
502 return;
504 xscale = FixedDiv(projection, tz);
506 gxt = -FixedMul(tr_x,viewsin);
507 gyt = FixedMul(tr_y,viewcos);
508 tx = -(gyt+gxt);
510 // too far off the side?
511 if (iabs(tx)>(tz<<2))
512 return;
514 // decide which patch to use for sprite relative to player
515 #ifdef RANGECHECK
516 if ((unsigned)thing->sprite >= numsprites)
517 I_Error ("R_ProjectSprite: invalid sprite number %i ",
518 thing->sprite);
519 #endif
520 sprdef = &sprites[thing->sprite];
521 #ifdef RANGECHECK
522 if ( (thing->frame&FF_FRAMEMASK) >= sprdef->numframes )
523 I_Error ("R_ProjectSprite: invalid sprite frame %i : %i ",
524 thing->sprite, thing->frame);
525 #endif
526 sprframe = &sprdef->spriteframes[ thing->frame & FF_FRAMEMASK];
528 if (sprframe->rotate)
530 // choose a different rotation based on player view
531 ang = R_PointToAngle (thing->x, thing->y);
532 rot = (ang-thing->angle+(unsigned)(ANG45/2)*9)>>29;
533 lump = sprframe->lump[rot];
534 flip = (boolean)sprframe->flip[rot];
536 else
538 // use single rotation for all views
539 lump = sprframe->lump[0];
540 flip = (boolean)sprframe->flip[0];
543 // calculate edges of the shape
544 tx -= spriteoffset[lump];
545 x1 = (centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS;
547 // off the right side?
548 if (x1 > viewwidth)
549 return;
551 tx += spritewidth[lump];
552 x2 = ((centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS) - 1;
554 // off the left side
555 if (x2 < 0)
556 return;
558 // store information in a vissprite
559 vis = R_NewVisSprite ();
560 vis->mobjflags = thing->flags;
561 vis->scale = xscale<<detailshift;
562 vis->gx = thing->x;
563 vis->gy = thing->y;
564 vis->gz = thing->z;
565 vis->gzt = thing->z + spritetopoffset[lump];
566 vis->texturemid = vis->gzt - viewz;
567 vis->x1 = x1 < 0 ? 0 : x1;
568 vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
569 iscale = FixedDiv (FRACUNIT, xscale);
571 if (flip)
573 vis->startfrac = spritewidth[lump]-1;
574 vis->xiscale = -iscale;
576 else
578 vis->startfrac = 0;
579 vis->xiscale = iscale;
582 if (vis->x1 > x1)
583 vis->startfrac += vis->xiscale*(vis->x1-x1);
584 vis->patch = lump;
586 // get light level
587 if (thing->flags & MF_SHADOW)
589 // shadow draw
590 vis->colormap = NULL;
592 else if (fixedcolormap)
594 // fixed map
595 vis->colormap = fixedcolormap;
597 else if (thing->frame & FF_FULLBRIGHT)
599 // full bright
600 vis->colormap = colormaps;
603 else
605 // diminished light
606 index = xscale>>(LIGHTSCALESHIFT-detailshift);
608 if (index >= MAXLIGHTSCALE)
609 index = MAXLIGHTSCALE-1;
611 vis->colormap = spritelights[index];
619 // R_AddSprites
620 // During BSP traversal, this adds sprites by sector.
622 void R_AddSprites (sector_t* sec)
624 mobj_t* thing;
625 int lightnum;
627 // BSP is traversed by subsector.
628 // A sector might have been split into several
629 // subsectors during BSP building.
630 // Thus we check whether its already added.
631 if (sec->validcount == validcount)
632 return;
634 // Well, now it will be done.
635 sec->validcount = validcount;
637 lightnum = (sec->lightlevel >> LIGHTSEGSHIFT)+extralight;
639 if (lightnum < 0)
640 spritelights = scalelight[0];
641 else if (lightnum >= LIGHTLEVELS)
642 spritelights = scalelight[LIGHTLEVELS-1];
643 else
644 spritelights = scalelight[lightnum];
646 // Handle all things in sector.
647 for (thing = sec->thinglist ; thing ; thing = thing->snext)
648 R_ProjectSprite (thing);
653 // R_DrawPSprite
655 void R_DrawPSprite (pspdef_t* psp)
657 fixed_t tx;
658 int x1;
659 int x2;
660 spritedef_t* sprdef;
661 spriteframe_t* sprframe;
662 int lump;
663 boolean flip;
664 vissprite_t* vis;
665 vissprite_t avis;
667 // decide which patch to use
668 #ifdef RANGECHECK
669 if ( (unsigned)psp->state->sprite >= numsprites)
670 I_Error ("R_ProjectSprite: invalid sprite number %i ",
671 psp->state->sprite);
672 #endif
673 sprdef = &sprites[psp->state->sprite];
674 #ifdef RANGECHECK
675 if ( (psp->state->frame & FF_FRAMEMASK) >= sprdef->numframes)
676 I_Error ("R_ProjectSprite: invalid sprite frame %i : %i ",
677 psp->state->sprite, psp->state->frame);
678 #endif
679 sprframe = &sprdef->spriteframes[ psp->state->frame & FF_FRAMEMASK ];
681 lump = sprframe->lump[0];
682 flip = (boolean)sprframe->flip[0];
684 // calculate edges of the shape
685 tx = psp->sx-160*FRACUNIT;
687 tx -= spriteoffset[lump];
688 x1 = (centerxfrac + FixedMul (tx,pspritescale) ) >>FRACBITS;
690 // off the right side
691 if (x1 > viewwidth)
692 return;
694 tx += spritewidth[lump];
695 x2 = ((centerxfrac + FixedMul (tx, pspritescale) ) >>FRACBITS) - 1;
697 // off the left side
698 if (x2 < 0)
699 return;
701 // store information in a vissprite
702 vis = &avis;
703 vis->mobjflags = 0;
704 vis->texturemid = (BASEYCENTER<<FRACBITS)+FRACUNIT/2-(psp->sy-spritetopoffset[lump]);
705 vis->x1 = x1 < 0 ? 0 : x1;
706 vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
707 vis->scale = pspritescale<<detailshift;
709 if (flip)
711 vis->xiscale = -pspriteiscale;
712 vis->startfrac = spritewidth[lump]-1;
714 else
716 vis->xiscale = pspriteiscale;
717 vis->startfrac = 0;
720 if (vis->x1 > x1)
721 vis->startfrac += vis->xiscale*(vis->x1-x1);
723 vis->patch = lump;
725 if (viewplayer->powers[pw_invisibility] > 4*32
726 || viewplayer->powers[pw_invisibility] & 8)
728 // shadow draw
729 vis->colormap = NULL;
731 else if (fixedcolormap)
733 // fixed color
734 vis->colormap = fixedcolormap;
736 else if (psp->state->frame & FF_FULLBRIGHT)
738 // full bright
739 vis->colormap = colormaps;
741 else
743 // local light
744 vis->colormap = spritelights[MAXLIGHTSCALE-1];
747 R_DrawVisSprite (vis, vis->x1, vis->x2);
753 // R_DrawPlayerSprites
755 void R_DrawPlayerSprites (void)
757 int i;
758 int lightnum;
759 pspdef_t* psp;
761 // get light level
762 lightnum =
763 (viewplayer->mo->subsector->sector->lightlevel >> LIGHTSEGSHIFT)
764 +extralight;
766 if (lightnum < 0)
767 spritelights = scalelight[0];
768 else if (lightnum >= LIGHTLEVELS)
769 spritelights = scalelight[LIGHTLEVELS-1];
770 else
771 spritelights = scalelight[lightnum];
773 // clip to screen bounds
774 mfloorclip = screenheightarray;
775 mceilingclip = negonearray;
777 // add all active psprites
778 for (i=0, psp=viewplayer->psprites;
779 i<NUMPSPRITES;
780 i++,psp++)
782 if (psp->state)
783 R_DrawPSprite (psp);
788 vissprite_t vsprsortedhead;
791 // R_SortVisSprites
793 void R_SortVisSprites (void)
795 int i;
796 int count;
797 vissprite_t* ds;
798 vissprite_t* best;
799 vissprite_t unsorted;
800 fixed_t bestscale;
802 count = vissprite_p - vissprites;
804 unsorted.next = unsorted.prev = &unsorted;
806 if (!count)
807 return;
809 for (ds=vissprites ; ds<vissprite_p ; ds++)
811 ds->next = ds+1;
812 ds->prev = ds-1;
815 vissprites[0].prev = &unsorted;
816 unsorted.next = &vissprites[0];
817 (vissprite_p-1)->next = &unsorted;
818 unsorted.prev = vissprite_p-1;
820 // pull the vissprites out by scale
821 //best = 0; // shut up the compiler warning
822 vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead;
823 for (i=0 ; i<count ; i++)
825 bestscale = MAXINT;
826 for (ds=unsorted.next,best=ds ; ds!= &unsorted ; ds=ds->next)
828 if (ds->scale < bestscale)
830 bestscale = ds->scale;
831 best = ds;
834 best->next->prev = best->prev;
835 best->prev->next = best->next;
836 best->next = &vsprsortedhead;
837 best->prev = vsprsortedhead.prev;
838 vsprsortedhead.prev->next = best;
839 vsprsortedhead.prev = best;
846 // R_DrawSprite
848 void R_DrawSprite (vissprite_t* spr)
850 drawseg_t* ds;
851 // short clipbot[SCREENWIDTH];
852 // short cliptop[SCREENWIDTH];
853 static short clipbot[MAXSCREENWIDTH];
854 static short cliptop[MAXSCREENWIDTH];
855 int x;
856 int r1;
857 int r2;
858 fixed_t scale;
859 fixed_t lowscale;
860 int silhouette;
862 // clipbot = I_malloc (SCREENWIDTH * sizeof(short));
863 // cliptop = I_malloc (SCREENWIDTH * sizeof(short));
865 for (x = spr->x1 ; x<=spr->x2 ; x++)
866 clipbot[x] = cliptop[x] = -2;
868 // Scan drawsegs from end to start for obscuring segs.
869 // The first drawseg that has a greater scale
870 // is the clip seg.
871 for (ds=ds_p-1 ; ds >= drawsegs ; ds--)
873 // determine if the drawseg obscures the sprite
874 if (ds->x1 > spr->x2
875 || ds->x2 < spr->x1
876 || (!ds->silhouette
877 && !ds->maskedtexturecol) )
879 // does not cover sprite
880 continue;
883 r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1;
884 r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2;
886 if (ds->scale1 > ds->scale2)
888 lowscale = ds->scale2;
889 scale = ds->scale1;
891 else
893 lowscale = ds->scale1;
894 scale = ds->scale2;
897 if (scale < spr->scale
898 || ( lowscale < spr->scale
899 && !R_PointOnSegSide (spr->gx, spr->gy, ds->curline) ) )
901 // masked mid texture?
902 if (ds->maskedtexturecol)
903 R_RenderMaskedSegRange (ds, r1, r2);
904 // seg is behind sprite
905 continue;
909 // clip this piece of the sprite
910 silhouette = ds->silhouette;
912 if (spr->gz >= ds->bsilheight)
913 silhouette &= ~SIL_BOTTOM;
915 if (spr->gzt <= ds->tsilheight)
916 silhouette &= ~SIL_TOP;
918 if (silhouette == 1)
920 // bottom sil
921 for (x=r1 ; x<=r2 ; x++)
922 if (clipbot[x] == -2)
923 clipbot[x] = ds->sprbottomclip[x];
925 else if (silhouette == 2)
927 // top sil
928 for (x=r1 ; x<=r2 ; x++)
929 if (cliptop[x] == -2)
930 cliptop[x] = ds->sprtopclip[x];
932 else if (silhouette == 3)
934 // both
935 for (x=r1 ; x<=r2 ; x++)
937 if (clipbot[x] == -2)
938 clipbot[x] = ds->sprbottomclip[x];
939 if (cliptop[x] == -2)
940 cliptop[x] = ds->sprtopclip[x];
946 // all clipping has been performed, so draw the sprite
948 // check for unclipped columns
949 for (x = spr->x1 ; x<=spr->x2 ; x++)
951 if (clipbot[x] == -2)
952 clipbot[x] = viewheight;
954 if (cliptop[x] == -2)
955 cliptop[x] = -1;
958 mfloorclip = clipbot;
959 mceilingclip = cliptop;
960 R_DrawVisSprite (spr, spr->x1, spr->x2);
962 // free (clipbot);
963 // free (cliptop);
970 // R_DrawMasked
972 void R_DrawMasked (void)
974 vissprite_t* spr;
975 drawseg_t* ds;
977 R_SortVisSprites ();
979 if (vissprite_p > vissprites)
981 // draw all vissprites back to front
982 for (spr = vsprsortedhead.next ;
983 spr != &vsprsortedhead ;
984 spr=spr->next)
987 R_DrawSprite (spr);
991 // render any remaining masked mid textures
992 for (ds=ds_p-1 ; ds >= drawsegs ; ds--)
993 if (ds->maskedtexturecol)
994 R_RenderMaskedSegRange (ds, ds->x1, ds->x2);
996 // draw the psprites on top of everything
997 // but does not draw on side views
998 if (!viewangleoffset)
999 R_DrawPlayerSprites ();