r_plane.c
上传用户:xuyinpeng
上传日期:2021-05-12
资源大小:455k
文件大小:11k
源码类别:

射击游戏

开发平台:

Visual C++

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