Annotation of doom/r_plane.c, revision 1.1.1.5

1.1.1.3   root        1: // Emacs style mode select   -*- C++ -*- 
                      2: //-----------------------------------------------------------------------------
                      3: //
                      4: // $Id:$
                      5: //
                      6: // Copyright (C) 1993-1996 by id Software, Inc.
                      7: //
1.1.1.5 ! root        8: // This source is available for distribution and/or modification
        !             9: // only under the terms of the DOOM Source Code License as
        !            10: // published by id Software. All rights reserved.
1.1.1.3   root       11: //
1.1.1.5 ! root       12: // The source is distributed in the hope that it will be useful,
1.1.1.3   root       13: // but WITHOUT ANY WARRANTY; without even the implied warranty of
1.1.1.5 ! root       14: // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
        !            15: // for more details.
1.1.1.3   root       16: //
                     17: // $Log:$
                     18: //
                     19: // DESCRIPTION:
                     20: //     Here is a core component: drawing the floors and ceilings,
                     21: //      while maintaining a per column clipping list only.
                     22: //     Moreover, the sky areas have to be determined.
                     23: //
                     24: //-----------------------------------------------------------------------------
1.1       root       25: 
                     26: 
1.1.1.3   root       27: static const char
                     28: rcsid[] = "$Id: r_plane.c,v 1.4 1997/02/03 16:47:55 b1 Exp $";
1.1       root       29: 
1.1.1.3   root       30: #include <stdlib.h>
1.1       root       31: 
1.1.1.3   root       32: #include "i_system.h"
                     33: #include "z_zone.h"
                     34: #include "w_wad.h"
1.1       root       35: 
1.1.1.3   root       36: #include "doomdef.h"
                     37: #include "doomstat.h"
1.1       root       38: 
1.1.1.3   root       39: #include "r_local.h"
                     40: #include "r_sky.h"
1.1       root       41: 
1.1.1.2   root       42: 
                     43: 
1.1.1.3   root       44: planefunction_t                floorfunc;
                     45: planefunction_t                ceilingfunc;
1.1.1.2   root       46: 
1.1.1.3   root       47: //
                     48: // opening
                     49: //
1.1.1.2   root       50: 
1.1.1.3   root       51: // Here comes the obnoxious "visplane".
                     52: #define MAXVISPLANES   128
                     53: visplane_t             visplanes[MAXVISPLANES];
                     54: visplane_t*            lastvisplane;
                     55: visplane_t*            floorplane;
                     56: visplane_t*            ceilingplane;
1.1.1.2   root       57: 
1.1.1.3   root       58: // ?
1.1.1.5 ! root       59: //#define MAXOPENINGS  SCREENWIDTH*64
        !            60: int MAXOPENINGS = 0;
        !            61: short          *openings;
        !            62: //short                        openings[MAXOPENINGS];
1.1.1.3   root       63: short*                 lastopening;
1.1.1.2   root       64: 
                     65: 
1.1.1.3   root       66: //
1.1.1.2   root       67: // Clip values are the solid pixel bounding the range.
1.1.1.3   root       68: //  floorclip starts out SCREENHEIGHT
                     69: //  ceilingclip starts out -1
1.1.1.2   root       70: //
1.1.1.5 ! root       71: short          *floorclip;
        !            72: short          *ceilingclip;
        !            73: 
        !            74: //short                        floorclip[SCREENWIDTH];
        !            75: //short                        ceilingclip[SCREENWIDTH];
1.1.1.3   root       76: 
1.1.1.2   root       77: //
1.1.1.3   root       78: // spanstart holds the start of a plane span
                     79: // initialized to 0 at start
1.1.1.2   root       80: //
1.1.1.5 ! root       81: int                    *spanstart;
        !            82: int                    *spanstop;
        !            83: //int                  spanstart[SCREENHEIGHT];
        !            84: //int                  spanstop[SCREENHEIGHT];
1.1       root       85: 
1.1.1.2   root       86: //
1.1.1.3   root       87: // texture mapping
1.1.1.2   root       88: //
1.1.1.3   root       89: lighttable_t**         planezlight;
                     90: fixed_t                        planeheight;
                     91: 
1.1.1.5 ! root       92: fixed_t        *yslope;
        !            93: fixed_t        *distscale;
        !            94: //fixed_t                      yslope[SCREENHEIGHT];
        !            95: //fixed_t                      distscale[SCREENWIDTH];
1.1.1.3   root       96: fixed_t                        basexscale;
                     97: fixed_t                        baseyscale;
                     98: 
1.1.1.5 ! root       99: fixed_t        *cachedheight;
        !           100: fixed_t        *cacheddistance;
        !           101: fixed_t        *cachedxstep;
        !           102: fixed_t        *cachedystep;
        !           103: //fixed_t                      cachedheight[SCREENHEIGHT];
        !           104: //fixed_t                      cacheddistance[SCREENHEIGHT];
        !           105: //fixed_t                      cachedxstep[SCREENHEIGHT];
        !           106: //fixed_t                      cachedystep[SCREENHEIGHT];
1.1.1.3   root      107: 
1.1       root      108: 
                    109: 
1.1.1.2   root      110: //
                    111: // R_InitPlanes
1.1.1.3   root      112: // Only at game startup.
1.1.1.2   root      113: //
1.1.1.3   root      114: void R_InitPlanes (void)
1.1.1.5 ! root      115:    {
        !           116:     int         i;
        !           117:     // Doh!
        !           118: 
        !           119:     MAXOPENINGS = SCREENWIDTH*64;
        !           120:     openings = (short *)calloc(MAXOPENINGS,sizeof(short));
        !           121:     for (i = 0; i < MAXVISPLANES; i++)
        !           122:        {
        !           123:         visplanes[i].topbase = (unsigned short *)calloc(SCREENWIDTH+2,sizeof(unsigned short));
        !           124:         visplanes[i].top = &visplanes[i].topbase[1];
        !           125:         visplanes[i].bottombase = (unsigned short *)calloc(SCREENWIDTH+2,sizeof(unsigned short));
        !           126:         visplanes[i].bottom = &visplanes[i].bottombase[1];
        !           127:        }
        !           128: 
        !           129:     floorclip = (short *)calloc(SCREENWIDTH,sizeof(short));
        !           130:     ceilingclip = (short *)calloc(SCREENWIDTH,sizeof(short));
        !           131: 
        !           132:     spanstart = (int *)calloc(SCREENHEIGHT,sizeof(int));
        !           133:     spanstop = (int*)calloc(SCREENHEIGHT,sizeof(int));
        !           134:     yslope = (fixed_t *)calloc(SCREENHEIGHT,sizeof(fixed_t));
        !           135:     distscale = (fixed_t *)calloc(SCREENWIDTH,sizeof(fixed_t));
        !           136: 
        !           137:     cachedheight = (fixed_t *)calloc(SCREENHEIGHT,sizeof(fixed_t));
        !           138:     cacheddistance = (fixed_t *)calloc(SCREENHEIGHT,sizeof(fixed_t));
        !           139:     cachedxstep = (fixed_t *)calloc(SCREENHEIGHT,sizeof(fixed_t));
        !           140:     cachedystep = (fixed_t *)calloc(SCREENHEIGHT,sizeof(fixed_t));
        !           141:    }
1.1       root      142: 
1.1.1.3   root      143: 
1.1.1.2   root      144: //
                    145: // R_MapPlane
                    146: //
1.1.1.3   root      147: // Uses global vars:
                    148: //  planeheight
                    149: //  ds_source
                    150: //  basexscale
                    151: //  baseyscale
                    152: //  viewx
                    153: //  viewy
                    154: //
                    155: // BASIC PRIMITIVE
                    156: //
                    157: void
                    158: R_MapPlane
                    159: ( int          y,
                    160:   int          x1,
                    161:   int          x2 )
1.1       root      162: {
1.1.1.3   root      163:     angle_t    angle;
                    164:     fixed_t    distance;
                    165:     fixed_t    length;
                    166:     unsigned   index;
                    167:        
1.1       root      168: #ifdef RANGECHECK
1.1.1.3   root      169:     if (x2 < x1
                    170:        || x1<0
                    171:        || x2>=viewwidth
1.1.1.5 ! root      172:        || (unsigned)y>(unsigned)viewheight)
1.1.1.3   root      173:     {
                    174:        I_Error ("R_MapPlane: %i, %i at %i",x1,x2,y);
                    175:     }
1.1       root      176: #endif
                    177: 
1.1.1.3   root      178:     if (planeheight != cachedheight[y])
                    179:     {
                    180:        cachedheight[y] = planeheight;
                    181:        distance = cacheddistance[y] = FixedMul (planeheight, yslope[y]);
                    182:        ds_xstep = cachedxstep[y] = FixedMul (distance,basexscale);
                    183:        ds_ystep = cachedystep[y] = FixedMul (distance,baseyscale);
                    184:     }
                    185:     else
                    186:     {
                    187:        distance = cacheddistance[y];
                    188:        ds_xstep = cachedxstep[y];
                    189:        ds_ystep = cachedystep[y];
                    190:     }
1.1       root      191:        
1.1.1.3   root      192:     length = FixedMul (distance,distscale[x1]);
                    193:     angle = (viewangle + xtoviewangle[x1])>>ANGLETOFINESHIFT;
                    194:     ds_xfrac = viewx + FixedMul(finecosine[angle], length);
                    195:     ds_yfrac = -viewy - FixedMul(finesine[angle], length);
                    196: 
                    197:     if (fixedcolormap)
                    198:        ds_colormap = fixedcolormap;
                    199:     else
                    200:     {
                    201:        index = distance >> LIGHTZSHIFT;
                    202:        
                    203:        if (index >= MAXLIGHTZ )
                    204:            index = MAXLIGHTZ-1;
1.1.1.2   root      205: 
1.1.1.3   root      206:        ds_colormap = planezlight[index];
                    207:     }
                    208:        
                    209:     ds_y = y;
                    210:     ds_x1 = x1;
                    211:     ds_x2 = x2;
1.1       root      212: 
1.1.1.3   root      213:     // high or low detail
                    214:     spanfunc ();       
1.1.1.2   root      215: }
1.1       root      216: 
1.1.1.3   root      217: 
1.1.1.2   root      218: //
                    219: // R_ClearPlanes
1.1.1.3   root      220: // At begining of frame.
1.1.1.2   root      221: //
1.1.1.5 ! root      222: void R_ClearPlanes(void)
        !           223:    {
        !           224:     int     i;
1.1.1.3   root      225:     angle_t    angle;
                    226:     
                    227:     // opening / clipping determination
1.1.1.5 ! root      228:     for (i = 0; i < viewwidth; i++)
        !           229:        {
        !           230:         floorclip[i] = viewheight;
        !           231:         ceilingclip[i] = -1;
        !           232:        }
1.1.1.3   root      233: 
                    234:     lastvisplane = visplanes;
                    235:     lastopening = openings;
                    236:     
                    237:     // texture calculation
1.1.1.5 ! root      238:     memset (cachedheight, 0, (sizeof(fixed_t)*SCREENHEIGHT));
1.1.1.3   root      239: 
                    240:     // left to right mapping
                    241:     angle = (viewangle-ANG90)>>ANGLETOFINESHIFT;
                    242:        
                    243:     // scale will be unit scale at SCREENWIDTH/2 distance
                    244:     basexscale = FixedDiv (finecosine[angle],centerxfrac);
                    245:     baseyscale = -FixedDiv (finesine[angle],centerxfrac);
1.1.1.5 ! root      246:    }
1.1.1.2   root      247: 
1.1       root      248: 
                    249: 
                    250: 
1.1.1.2   root      251: //
                    252: // R_FindPlane
                    253: //
1.1.1.5 ! root      254: visplane_t *R_FindPlane( fixed_t height, int picnum, int lightlevel )
        !           255:    {
1.1.1.3   root      256:     visplane_t*        check;
                    257:        
                    258:     if (picnum == skyflatnum)
1.1.1.5 ! root      259:        {
        !           260:         height = 0;                    // all skys map together
        !           261:         lightlevel = 0;
        !           262:        }
1.1.1.3   root      263:        
                    264:     for (check=visplanes; check<lastvisplane; check++)
1.1.1.5 ! root      265:         {
        !           266:          if (height == check->height && picnum == check->picnum && lightlevel == check->lightlevel)
        !           267:             {
        !           268:              break;
        !           269:             }
        !           270:         }
1.1.1.3   root      271:     
                    272:                        
                    273:     if (check < lastvisplane)
1.1.1.5 ! root      274:         return check;
1.1.1.3   root      275:                
                    276:     if (lastvisplane - visplanes == MAXVISPLANES)
1.1.1.5 ! root      277:         I_Error ("R_FindPlane: no more visplanes");
1.1.1.3   root      278:                
                    279:     lastvisplane++;
                    280: 
                    281:     check->height = height;
                    282:     check->picnum = picnum;
                    283:     check->lightlevel = lightlevel;
                    284:     check->minx = SCREENWIDTH;
                    285:     check->maxx = -1;
                    286:     
1.1.1.5 ! root      287:     memset (check->topbase,0xffff,sizeof(unsigned short)*(SCREENWIDTH+2)); // HIRES
1.1.1.3   root      288:                
                    289:     return check;
1.1.1.5 ! root      290:    }
1.1       root      291: 
1.1.1.3   root      292: 
1.1.1.2   root      293: //
                    294: // R_CheckPlane
                    295: //
1.1.1.3   root      296: visplane_t*
                    297: R_CheckPlane
                    298: ( visplane_t*  pl,
                    299:   int          start,
                    300:   int          stop )
1.1       root      301: {
1.1.1.3   root      302:     int                intrl;
                    303:     int                intrh;
                    304:     int                unionl;
                    305:     int                unionh;
                    306:     int                x;
                    307:        
                    308:     if (start < pl->minx)
                    309:     {
                    310:        intrl = pl->minx;
                    311:        unionl = start;
                    312:     }
                    313:     else
                    314:     {
                    315:        unionl = pl->minx;
                    316:        intrl = start;
                    317:     }
                    318:        
                    319:     if (stop > pl->maxx)
                    320:     {
                    321:        intrh = pl->maxx;
                    322:        unionh = stop;
                    323:     }
                    324:     else
                    325:     {
                    326:        unionh = pl->maxx;
                    327:        intrh = stop;
                    328:     }
                    329: 
                    330:     for (x=intrl ; x<= intrh ; x++)
1.1.1.5 ! root      331:        if (pl->top[x] != 0xffff) // HIRES
1.1.1.3   root      332:            break;
                    333: 
                    334:     if (x > intrh)
                    335:     {
                    336:        pl->minx = unionl;
                    337:        pl->maxx = unionh;
                    338: 
                    339:        // use the same one
                    340:        return pl;              
                    341:     }
                    342:        
                    343:     // make a new visplane
                    344:     lastvisplane->height = pl->height;
                    345:     lastvisplane->picnum = pl->picnum;
                    346:     lastvisplane->lightlevel = pl->lightlevel;
                    347:     
                    348:     pl = lastvisplane++;
                    349:     pl->minx = start;
                    350:     pl->maxx = stop;
                    351: 
1.1.1.5 ! root      352:     memset (pl->topbase,0xffff,sizeof(unsigned short)*(SCREENWIDTH+2)); // HIRES
1.1.1.3   root      353:                
                    354:     return pl;
1.1       root      355: }
                    356: 
1.1.1.3   root      357: 
1.1.1.2   root      358: //
                    359: // R_MakeSpans
                    360: //
1.1.1.3   root      361: void
                    362: R_MakeSpans
                    363: ( int          x,
                    364:   int          t1,
                    365:   int          b1,
                    366:   int          t2,
                    367:   int          b2 )
1.1       root      368: {
1.1.1.3   root      369:     while (t1 < t2 && t1<=b1)
                    370:     {
                    371:        R_MapPlane (t1,spanstart[t1],x-1);
                    372:        t1++;
                    373:     }
                    374:     while (b1 > b2 && b1>=t1)
                    375:     {
                    376:        R_MapPlane (b1,spanstart[b1],x-1);
                    377:        b1--;
                    378:     }
                    379:        
                    380:     while (t2 < t1 && t2<=b2)
                    381:     {
                    382:        spanstart[t2] = x;
                    383:        t2++;
                    384:     }
                    385:     while (b2 > b1 && b2>=t2)
                    386:     {
                    387:        spanstart[b2] = x;
                    388:        b2--;
                    389:     }
1.1       root      390: }
                    391: 
1.1.1.3   root      392: 
                    393: 
1.1.1.2   root      394: //
                    395: // R_DrawPlanes
1.1.1.3   root      396: // At the end of each frame.
1.1.1.2   root      397: //
1.1.1.5 ! root      398: void R_DrawPlanes(void)
1.1       root      399: {
1.1.1.5 ! root      400:     visplane_t *pl;
        !           401:     int         light;
        !           402:     int         x;
        !           403:     int         stop;
        !           404:     int         angle;
1.1.1.3   root      405:                                
1.1       root      406: #ifdef RANGECHECK
1.1.1.5 ! root      407:     if(ds_p - drawsegs > MAXDRAWSEGS)
        !           408:                I_Error("R_DrawPlanes: drawsegs overflow (%i)", ds_p - drawsegs);
        !           409:     if(lastvisplane - visplanes > MAXVISPLANES)
        !           410:                I_Error("R_DrawPlanes: visplane overflow (%i)", lastvisplane - visplanes);    
        !           411:     if(lastopening - openings > MAXOPENINGS)
        !           412:                I_Error ("R_DrawPlanes: opening overflow (%i)", lastopening - openings);
1.1       root      413: #endif
                    414: 
1.1.1.5 ! root      415:     for(pl = visplanes; pl < lastvisplane; pl++)
1.1       root      416:        {
1.1.1.5 ! root      417:         if(pl->minx > pl->maxx)
        !           418:             continue;
        !           419:        
        !           420:         // sky flat
        !           421:         if(pl->picnum == skyflatnum)
1.1.1.2   root      422:                {
1.1.1.5 ! root      423:             //11.8.98 dlw-since detail/detailshift are always
        !           424:                        // zero in this thing...
        !           425:                        //dc_iscale = pspriteiscale>>detailshift;
        !           426:                        dc_iscale = pspriteiscale;
        !           427: 
        !           428:             // Sky is allways drawn full bright,
        !           429:             //  i.e. colormaps[0] is used.
        !           430:             // Because of this hack, sky is not affected
        !           431:             //  by INVUL inverse mapping.
        !           432:             dc_colormap = colormaps;
        !           433:             dc_texturemid = skytexturemid;
        !           434:             for(x = pl->minx; x <= pl->maxx; x++)
        !           435:                        {
        !           436:                 dc_yl = pl->top[x];
        !           437:                 dc_yh = pl->bottom[x];
        !           438:                 if(dc_yl <= dc_yh)
        !           439:                                {
        !           440:                     angle = (viewangle + xtoviewangle[x]) >> ANGLETOSKYSHIFT;
        !           441:                     dc_x = x;
        !           442:                     dc_source = R_GetColumn(skytexture, angle);
        !           443:                     colfunc();
        !           444:                                }
        !           445:                        }
        !           446:             continue;
1.1.1.2   root      447:                }
1.1.1.3   root      448:        
1.1.1.5 ! root      449:         // regular flat
        !           450:         ds_source = W_CacheLumpNum(firstflat + flattranslation[pl->picnum], PU_STATIC);
1.1.1.3   root      451:        
1.1.1.5 ! root      452:         planeheight = abs(pl->height-viewz);
        !           453:         light = (pl->lightlevel >> LIGHTSEGSHIFT)+extralight;
1.1       root      454: 
1.1.1.5 ! root      455:         if (light >= LIGHTLEVELS)
        !           456:             light = LIGHTLEVELS-1;
1.1.1.2   root      457: 
1.1.1.5 ! root      458:         if (light < 0)
        !           459:             light = 0;
1.1.1.3   root      460: 
1.1.1.5 ! root      461:         planezlight = zlight[light];
1.1.1.3   root      462: 
1.1.1.5 ! root      463:         pl->top[pl->maxx+1] = 0xffff;
        !           464:         pl->top[pl->minx-1] = 0xffff;
1.1.1.3   root      465:                
1.1.1.5 ! root      466:         stop = pl->maxx + 1;
1.1.1.3   root      467: 
1.1.1.5 ! root      468:         for (x = pl->minx; x <= stop; x++)
        !           469:            {
        !           470:             R_MakeSpans(x,pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]);
        !           471:            }
        !           472:                Z_ChangeTag (ds_source, PU_CACHE);
        !           473:        }
        !           474:    }

unix.superglobalmegacorp.com

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