Annotation of doom/r_things.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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