Annotation of doom/r_things.c, revision 1.1.1.5

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.