Annotation of doom/r_things.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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