home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #2 / amigaacscoverdisc1998-021998.iso / games / doom / source / linuxdoom-1.10 / r_things.c < prev    next >
C/C++ Source or Header  |  1997-12-22  |  21KB  |  990 lines

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