Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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.