home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser-CD 2000 January / LCD_01_2000.iso / games / doom / pmdoom / src / r_plane.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-17  |  8.9 KB  |  454 lines

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