home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #2 / amigaacscoverdisc1998-021998.iso / games / doom / source / linuxdoom-1.10 / r_plane.c < prev    next >
C/C++ Source or Header  |  1997-12-22  |  8KB  |  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.