Annotation of doom/r_things.c, revision 1.1.1.4

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

unix.superglobalmegacorp.com

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