R_PLANE.C 8.4 KB

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