r_plane.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /*
  2. ===========================================================================
  3. Doom 3 BFG Edition GPL Source Code
  4. Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
  6. Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "Precompiled.h"
  21. #include "globaldata.h"
  22. #include <stdlib.h>
  23. #include "i_system.h"
  24. #include "z_zone.h"
  25. #include "w_wad.h"
  26. #include "doomdef.h"
  27. #include "doomstat.h"
  28. #include "r_local.h"
  29. #include "r_sky.h"
  30. //
  31. // opening
  32. //
  33. // Here comes the obnoxious "visplane".
  34. //
  35. // Clip values are the solid pixel bounding the range.
  36. // ::g->floorclip starts out SCREENHEIGHT
  37. // ::g->ceilingclip starts out -1
  38. //
  39. //
  40. // ::g->spanstart holds the start of a plane span
  41. // initialized to 0 at start
  42. //
  43. //
  44. // texture mapping
  45. //
  46. //
  47. // R_InitPlanes
  48. // Only at game startup.
  49. //
  50. void R_InitPlanes (void)
  51. {
  52. // Doh!
  53. }
  54. //
  55. // R_MapPlane
  56. //
  57. // Uses global vars:
  58. // ::g->planeheight
  59. // ::g->ds_source
  60. // ::g->basexscale
  61. // ::g->baseyscale
  62. // ::g->viewx
  63. // ::g->viewy
  64. //
  65. // BASIC PRIMITIVE
  66. //
  67. void
  68. R_MapPlane
  69. ( int y,
  70. int x1,
  71. int x2 )
  72. {
  73. angle_t angle;
  74. fixed_t distance;
  75. fixed_t length;
  76. unsigned index;
  77. //#ifdef RANGECHECK
  78. if ( x2 < x1 || x1<0 || x2>=::g->viewwidth || y>::g->viewheight )
  79. {
  80. //I_Error ("R_MapPlane: %i, %i at %i",x1,x2,y);
  81. return;
  82. }
  83. //#endif
  84. if (::g->planeheight != ::g->cachedheight[y])
  85. {
  86. ::g->cachedheight[y] = ::g->planeheight;
  87. distance = ::g->cacheddistance[y] = FixedMul (::g->planeheight, ::g->yslope[y]);
  88. ::g->ds_xstep = ::g->cachedxstep[y] = FixedMul (distance,::g->basexscale);
  89. ::g->ds_ystep = ::g->cachedystep[y] = FixedMul (distance,::g->baseyscale);
  90. }
  91. else
  92. {
  93. distance = ::g->cacheddistance[y];
  94. ::g->ds_xstep = ::g->cachedxstep[y];
  95. ::g->ds_ystep = ::g->cachedystep[y];
  96. }
  97. extern angle_t GetViewAngle();
  98. length = FixedMul (distance,::g->distscale[x1]);
  99. angle = (GetViewAngle() + ::g->xtoviewangle[x1])>>ANGLETOFINESHIFT;
  100. extern fixed_t GetViewX(); extern fixed_t GetViewY();
  101. ::g->ds_xfrac = GetViewX() + FixedMul(finecosine[angle], length);
  102. ::g->ds_yfrac = -GetViewY() - FixedMul(finesine[angle], length);
  103. if (::g->fixedcolormap)
  104. ::g->ds_colormap = ::g->fixedcolormap;
  105. else
  106. {
  107. index = distance >> LIGHTZSHIFT;
  108. if (index >= MAXLIGHTZ )
  109. index = MAXLIGHTZ-1;
  110. ::g->ds_colormap = ::g->planezlight[index];
  111. }
  112. ::g->ds_y = y;
  113. ::g->ds_x1 = x1;
  114. ::g->ds_x2 = x2;
  115. // high or low detail
  116. spanfunc (
  117. ::g->ds_xfrac,
  118. ::g->ds_yfrac,
  119. ::g->ds_y,
  120. ::g->ds_x1,
  121. ::g->ds_x2,
  122. ::g->ds_xstep,
  123. ::g->ds_ystep,
  124. ::g->ds_colormap,
  125. ::g->ds_source );
  126. }
  127. //
  128. // R_ClearPlanes
  129. // At begining of frame.
  130. //
  131. void R_ClearPlanes (void)
  132. {
  133. int i;
  134. angle_t angle;
  135. // opening / clipping determination
  136. for (i=0 ; i < ::g->viewwidth ; i++)
  137. {
  138. ::g->floorclip[i] = ::g->viewheight;
  139. ::g->ceilingclip[i] = -1;
  140. }
  141. ::g->lastvisplane = ::g->visplanes;
  142. ::g->lastopening = ::g->openings;
  143. // texture calculation
  144. memset (::g->cachedheight, 0, sizeof(::g->cachedheight));
  145. // left to right mapping
  146. extern angle_t GetViewAngle();
  147. angle = (GetViewAngle()-ANG90)>>ANGLETOFINESHIFT;
  148. // scale will be unit scale at SCREENWIDTH/2 distance
  149. ::g->basexscale = FixedDiv (finecosine[angle],::g->centerxfrac);
  150. ::g->baseyscale = -FixedDiv (finesine[angle],::g->centerxfrac);
  151. }
  152. //
  153. // R_FindPlane
  154. //
  155. visplane_t* R_FindPlane( fixed_t height, int picnum, int lightlevel ) {
  156. visplane_t* check;
  157. if (picnum == ::g->skyflatnum) {
  158. height = 0; // all skys map together
  159. lightlevel = 0;
  160. }
  161. for (check=::g->visplanes; check < ::g->lastvisplane; check++) {
  162. if (height == check->height && picnum == check->picnum && lightlevel == check->lightlevel) {
  163. break;
  164. }
  165. }
  166. if (check < ::g->lastvisplane)
  167. return check;
  168. //if (::g->lastvisplane - ::g->visplanes == MAXVISPLANES)
  169. //I_Error ("R_FindPlane: no more visplanes");
  170. if ( ::g->lastvisplane - ::g->visplanes == MAXVISPLANES ) {
  171. check = ::g->visplanes;
  172. return check;
  173. }
  174. ::g->lastvisplane++;
  175. check->height = height;
  176. check->picnum = picnum;
  177. check->lightlevel = lightlevel;
  178. check->minx = SCREENWIDTH;
  179. check->maxx = -1;
  180. memset(check->top,0xff,sizeof(check->top));
  181. return check;
  182. }
  183. //
  184. // R_CheckPlane
  185. //
  186. visplane_t*
  187. R_CheckPlane
  188. ( visplane_t* pl,
  189. int start,
  190. int stop )
  191. {
  192. int intrl;
  193. int intrh;
  194. int unionl;
  195. int unionh;
  196. int x;
  197. if (start < pl->minx)
  198. {
  199. intrl = pl->minx;
  200. unionl = start;
  201. }
  202. else
  203. {
  204. unionl = pl->minx;
  205. intrl = start;
  206. }
  207. if (stop > pl->maxx)
  208. {
  209. intrh = pl->maxx;
  210. unionh = stop;
  211. }
  212. else
  213. {
  214. unionh = pl->maxx;
  215. intrh = stop;
  216. }
  217. for (x=intrl ; x<= intrh ; x++)
  218. if (pl->top[x] != 0xffff)
  219. break;
  220. if (x > intrh)
  221. {
  222. pl->minx = unionl;
  223. pl->maxx = unionh;
  224. // use the same one
  225. return pl;
  226. }
  227. if ( ::g->lastvisplane - ::g->visplanes == MAXVISPLANES ) {
  228. return pl;
  229. }
  230. // make a new visplane
  231. ::g->lastvisplane->height = pl->height;
  232. ::g->lastvisplane->picnum = pl->picnum;
  233. ::g->lastvisplane->lightlevel = pl->lightlevel;
  234. pl = ::g->lastvisplane++;
  235. pl->minx = start;
  236. pl->maxx = stop;
  237. memset(pl->top,0xff,sizeof(pl->top));
  238. return pl;
  239. }
  240. //
  241. // R_MakeSpans
  242. //
  243. void
  244. R_MakeSpans
  245. ( int x,
  246. int t1,
  247. int b1,
  248. int t2,
  249. int b2 )
  250. {
  251. while (t1 < t2 && t1<=b1)
  252. {
  253. R_MapPlane (t1,::g->spanstart[t1],x-1);
  254. t1++;
  255. }
  256. while (b1 > b2 && b1>=t1)
  257. {
  258. R_MapPlane (b1,::g->spanstart[b1],x-1);
  259. b1--;
  260. }
  261. while (t2 < t1 && t2<=b2)
  262. {
  263. ::g->spanstart[t2] = x;
  264. t2++;
  265. }
  266. while (b2 > b1 && b2>=t2)
  267. {
  268. ::g->spanstart[b2] = x;
  269. b2--;
  270. }
  271. }
  272. //
  273. // R_DrawPlanes
  274. // At the end of each frame.
  275. //
  276. void R_DrawPlanes (void)
  277. {
  278. visplane_t* pl;
  279. int light;
  280. int x;
  281. int stop;
  282. int angle;
  283. #ifdef RANGECHECK
  284. if (::g->ds_p - ::g->drawsegs > MAXDRAWSEGS)
  285. I_Error ("R_DrawPlanes: ::g->drawsegs overflow (%i)",
  286. ::g->ds_p - ::g->drawsegs);
  287. if (::g->lastvisplane - ::g->visplanes > MAXVISPLANES)
  288. I_Error ("R_DrawPlanes: visplane overflow (%i)",
  289. ::g->lastvisplane - ::g->visplanes);
  290. if (::g->lastopening - ::g->openings > MAXOPENINGS)
  291. I_Error ("R_DrawPlanes: opening overflow (%i)",
  292. ::g->lastopening - ::g->openings);
  293. #endif
  294. for (pl = ::g->visplanes ; pl < ::g->lastvisplane ; pl++)
  295. {
  296. if (pl->minx > pl->maxx)
  297. continue;
  298. // sky flat
  299. if (pl->picnum == ::g->skyflatnum)
  300. {
  301. ::g->dc_iscale = ::g->pspriteiscale>>::g->detailshift;
  302. // Sky is allways drawn full bright,
  303. // i.e. ::g->colormaps[0] is used.
  304. // Because of this hack, sky is not affected
  305. // by INVUL inverse mapping.
  306. ::g->dc_colormap = ::g->colormaps;
  307. ::g->dc_texturemid = ::g->skytexturemid;
  308. for (x=pl->minx ; x <= pl->maxx ; x++)
  309. {
  310. ::g->dc_yl = pl->top[x];
  311. ::g->dc_yh = pl->bottom[x];
  312. if (::g->dc_yl <= ::g->dc_yh)
  313. {
  314. extern angle_t GetViewAngle();
  315. angle = (GetViewAngle() + ::g->xtoviewangle[x])>>ANGLETOSKYSHIFT;
  316. ::g->dc_x = x;
  317. ::g->dc_source = R_GetColumn(::g->skytexture, angle);
  318. colfunc ( ::g->dc_colormap, ::g->dc_source );
  319. }
  320. }
  321. continue;
  322. }
  323. // regular flat
  324. ::g->ds_source = (byte*)W_CacheLumpNum(::g->firstflat +
  325. ::g->flattranslation[pl->picnum],
  326. PU_CACHE_SHARED);
  327. ::g->planeheight = abs(pl->height-::g->viewz);
  328. light = (pl->lightlevel >> LIGHTSEGSHIFT)+::g->extralight;
  329. if (light >= LIGHTLEVELS)
  330. light = LIGHTLEVELS-1;
  331. if (light < 0)
  332. light = 0;
  333. ::g->planezlight = ::g->zlight[light];
  334. pl->top[pl->maxx+1] = 0xffff;
  335. pl->top[pl->minx-1] = 0xffff;
  336. stop = pl->maxx + 1;
  337. for (x=pl->minx ; x<= stop ; x++)
  338. {
  339. R_MakeSpans(x,pl->top[x-1],
  340. pl->bottom[x-1],
  341. pl->top[x],
  342. pl->bottom[x]);
  343. }
  344. }
  345. }