PageRenderTime 63ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/engine/src/r_segs.c

https://bitbucket.org/zturtleman/srb2ztm1094
C | 2107 lines | 1600 code | 307 blank | 200 comment | 521 complexity | 58ffafd80d7ab8cb8602e80b7fad4cd9 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. // Emacs style mode select -*- C++ -*-
  2. //-----------------------------------------------------------------------------
  3. //
  4. // Copyright (C) 1993-1996 by id Software, Inc.
  5. // Copyright (C) 1998-2000 by DooM Legacy Team.
  6. //
  7. // This program is free software; you can redistribute it and/or
  8. // modify it under the terms of the GNU General Public License
  9. // as published by the Free Software Foundation; either version 2
  10. // of the License, or (at your option) any later version.
  11. //
  12. // This program is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. // GNU General Public License for more details.
  16. //-----------------------------------------------------------------------------
  17. /// \file
  18. /// \brief All the clipping: columns, horizontal spans, sky columns
  19. #include "doomdef.h"
  20. #include "r_local.h"
  21. #include "r_sky.h"
  22. #include "r_splats.h"
  23. #include "w_wad.h"
  24. #include "z_zone.h"
  25. #include "d_netcmd.h"
  26. #include "m_misc.h"
  27. #include "p_local.h" // Camera...
  28. #include "console.h" // con_clipviewtop
  29. // OPTIMIZE: closed two sided lines as single sided
  30. // True if any of the segs textures might be visible.
  31. static boolean segtextured;
  32. static boolean markfloor; // False if the back side is the same plane.
  33. static boolean markceiling;
  34. static boolean maskedtexture;
  35. static long toptexture, bottomtexture, midtexture;
  36. static int numthicksides;
  37. angle_t rw_normalangle;
  38. // angle to line origin
  39. angle_t rw_angle1;
  40. fixed_t rw_distance;
  41. //
  42. // regular wall
  43. //
  44. static int rw_x, rw_stopx;
  45. static angle_t rw_centerangle;
  46. static fixed_t rw_offset;
  47. static fixed_t rw_offset2; // for splats
  48. static fixed_t rw_scale, rw_scalestep;
  49. static fixed_t rw_midtexturemid, rw_toptexturemid, rw_bottomtexturemid;
  50. static int worldtop, worldbottom, worldhigh, worldlow;
  51. static fixed_t pixhigh, pixlow, pixhighstep, pixlowstep;
  52. static fixed_t topfrac, topstep;
  53. static fixed_t bottomfrac, bottomstep;
  54. lighttable_t **walllights;
  55. static short *maskedtexturecol;
  56. // ==========================================================================
  57. // R_Splats Wall Splats Drawer
  58. // ==========================================================================
  59. #ifdef WALLSPLATS
  60. static short last_ceilingclip[MAXVIDWIDTH];
  61. static short last_floorclip[MAXVIDWIDTH];
  62. static void R_DrawSplatColumn(column_t *column)
  63. {
  64. int topscreen, bottomscreen;
  65. fixed_t basetexturemid;
  66. basetexturemid = dc_texturemid;
  67. for (; column->topdelta != 0xff ;)
  68. {
  69. // calculate unclipped screen coordinates for post
  70. topscreen = sprtopscreen + spryscale*column->topdelta;
  71. bottomscreen = topscreen + spryscale*column->length;
  72. dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
  73. dc_yh = (bottomscreen-1)>>FRACBITS;
  74. if (dc_yh >= last_floorclip[dc_x])
  75. dc_yh = last_floorclip[dc_x] - 1;
  76. if (dc_yl <= last_ceilingclip[dc_x])
  77. dc_yl = last_ceilingclip[dc_x] + 1;
  78. if (dc_yl <= dc_yh)
  79. {
  80. dc_source = (byte *)column + 3;
  81. dc_texturemid = basetexturemid - (column->topdelta<<FRACBITS);
  82. // Drawn by R_DrawColumn.
  83. colfunc();
  84. }
  85. column = (column_t *)((byte *)column + column->length + 4);
  86. }
  87. dc_texturemid = basetexturemid;
  88. }
  89. static void R_DrawWallSplats(void)
  90. {
  91. wallsplat_t *splat;
  92. seg_t *seg;
  93. angle_t angle, angle1, angle2;
  94. int x1, x2;
  95. size_t pindex;
  96. column_t *col;
  97. patch_t *patch;
  98. fixed_t texturecolumn;
  99. splat = (wallsplat_t *)linedef->splats;
  100. I_Assert(splat != NULL);
  101. seg = ds_p->curline;
  102. // draw all splats from the line that touches the range of the seg
  103. for (; splat; splat = splat->next)
  104. {
  105. angle1 = R_PointToAngle(splat->v1.x, splat->v1.y);
  106. angle2 = R_PointToAngle(splat->v2.x, splat->v2.y);
  107. angle1 = (angle1 - viewangle + ANG90)>>ANGLETOFINESHIFT;
  108. angle2 = (angle2 - viewangle + ANG90)>>ANGLETOFINESHIFT;
  109. // out of the viewangletox lut
  110. /// \todo clip it to the screen
  111. if (angle1 > FINEANGLES/2 || angle2 > FINEANGLES/2)
  112. continue;
  113. x1 = viewangletox[angle1];
  114. x2 = viewangletox[angle2];
  115. if (x1 >= x2)
  116. continue; // does not cross a pixel
  117. // splat is not in this seg range
  118. if (x2 < ds_p->x1 || x1 > ds_p->x2)
  119. continue;
  120. if (x1 < ds_p->x1)
  121. x1 = ds_p->x1;
  122. if (x2 > ds_p->x2)
  123. x2 = ds_p->x2;
  124. if (x2 <= x1)
  125. continue;
  126. // calculate incremental stepping values for texture edges
  127. rw_scalestep = ds_p->scalestep;
  128. spryscale = ds_p->scale1 + (x1 - ds_p->x1)*rw_scalestep;
  129. mfloorclip = floorclip;
  130. mceilingclip = ceilingclip;
  131. patch = W_CachePatchNum(splat->patch, PU_CACHE);
  132. dc_texturemid = splat->top + (patch->height<<(FRACBITS-1)) - viewz;
  133. if (splat->yoffset)
  134. dc_texturemid += *splat->yoffset;
  135. sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
  136. // set drawing mode
  137. switch (splat->flags & SPLATDRAWMODE_MASK)
  138. {
  139. case SPLATDRAWMODE_OPAQUE:
  140. colfunc = basecolfunc;
  141. break;
  142. case SPLATDRAWMODE_TRANS:
  143. if (!cv_translucency.value)
  144. colfunc = basecolfunc;
  145. else
  146. {
  147. dc_transmap = ((tr_transmed - 1)<<FF_TRANSSHIFT) + transtables;
  148. colfunc = fuzzcolfunc;
  149. }
  150. break;
  151. case SPLATDRAWMODE_SHADE:
  152. colfunc = shadecolfunc;
  153. break;
  154. }
  155. dc_texheight = 0;
  156. // draw the columns
  157. for (dc_x = x1; dc_x <= x2; dc_x++, spryscale += rw_scalestep)
  158. {
  159. pindex = spryscale>>LIGHTSCALESHIFT;
  160. if (pindex >= MAXLIGHTSCALE)
  161. pindex = MAXLIGHTSCALE - 1;
  162. dc_colormap = walllights[pindex];
  163. if (frontsector->extra_colormap)
  164. dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
  165. sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
  166. dc_iscale = 0xffffffffu / (unsigned)spryscale;
  167. // find column of patch, from perspective
  168. angle = (rw_centerangle + xtoviewangle[dc_x])>>ANGLETOFINESHIFT;
  169. texturecolumn = rw_offset2 - splat->offset
  170. - FixedMul(FINETANGENT(angle), rw_distance);
  171. // FIXME!
  172. texturecolumn >>= FRACBITS;
  173. if (texturecolumn < 0 || texturecolumn >= patch->width)
  174. continue;
  175. // draw the texture
  176. col = (column_t *)((byte *)patch + LONG(patch->columnofs[texturecolumn]));
  177. R_DrawSplatColumn(col);
  178. }
  179. } // next splat
  180. colfunc = basecolfunc;
  181. }
  182. #endif //WALLSPLATS
  183. // ==========================================================================
  184. // R_RenderMaskedSegRange
  185. // ==========================================================================
  186. // If we have a multi-patch texture on a 2sided wall (rare) then we draw
  187. // it using R_DrawColumn, else we draw it using R_DrawMaskedColumn, this
  188. // way we don't have to store extra post_t info with each column for
  189. // multi-patch textures. They are not normally needed as multi-patch
  190. // textures don't have holes in it. At least not for now.
  191. static int column2s_length; // column->length : for multi-patch on 2sided wall = texture->height
  192. static void R_Render2sidedMultiPatchColumn(column_t *column)
  193. {
  194. int topscreen, bottomscreen;
  195. topscreen = sprtopscreen; // + spryscale*column->topdelta; topdelta is 0 for the wall
  196. bottomscreen = topscreen + spryscale * column2s_length;
  197. dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS;
  198. dc_yh = (bottomscreen-1)>>FRACBITS;
  199. if (windowtop != MAXINT && windowbottom != MAXINT)
  200. {
  201. dc_yl = ((windowtop + FRACUNIT)>>FRACBITS);
  202. dc_yh = (windowbottom - 1)>>FRACBITS;
  203. }
  204. if (dc_yh >= mfloorclip[dc_x])
  205. dc_yh = mfloorclip[dc_x] - 1;
  206. if (dc_yl <= mceilingclip[dc_x])
  207. dc_yl = mceilingclip[dc_x] + 1;
  208. if (dc_yl >= vid.height || dc_yh < 0)
  209. return;
  210. if (dc_yl <= dc_yh)
  211. {
  212. dc_source = (byte *)column + 3;
  213. colfunc();
  214. }
  215. }
  216. void R_RenderMaskedSegRange(drawseg_t *ds, int x1, int x2)
  217. {
  218. size_t pindex;
  219. column_t *col;
  220. int lightnum, texnum, i;
  221. fixed_t height, realbot;
  222. lightlist_t *light;
  223. r_lightlist_t *rlight;
  224. void (*colfunc_2s)(column_t *);
  225. line_t *ldef;
  226. sector_t *front, *back;
  227. // Calculate light table.
  228. // Use different light tables
  229. // for horizontal / vertical / diagonal. Diagonal?
  230. // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
  231. curline = ds->curline;
  232. frontsector = curline->frontsector;
  233. backsector = curline->backsector;
  234. texnum = texturetranslation[curline->sidedef->midtexture];
  235. windowbottom = windowtop = sprbotscreen = MAXINT;
  236. // hack translucent linedef types (284-288 for transtables 1-5)
  237. ldef = curline->linedef;
  238. switch (ldef->special)
  239. {
  240. case 284:
  241. dc_transmap = ((tr_transmed)<<FF_TRANSSHIFT) - 0x10000 + transtables;
  242. colfunc = fuzzcolfunc;
  243. break;
  244. case 285:
  245. dc_transmap = ((tr_transmor)<<FF_TRANSSHIFT) - 0x10000 + transtables;
  246. colfunc = fuzzcolfunc;
  247. break;
  248. case 286:
  249. dc_transmap = ((tr_transhi)<<FF_TRANSSHIFT) - 0x10000 + transtables;
  250. colfunc = fuzzcolfunc;
  251. break;
  252. case 287:
  253. dc_transmap = ((tr_transfir)<<FF_TRANSSHIFT) - 0x10000 + transtables;
  254. colfunc = fuzzcolfunc;
  255. break;
  256. case 288:
  257. dc_transmap = ((tr_transfir)<<FF_TRANSSHIFT) - 0x10000 + transtables;
  258. colfunc = fuzzcolfunc;
  259. break;
  260. case 289:
  261. dc_transmap = transtables; // get first transtable 50/50
  262. colfunc = fuzzcolfunc;
  263. break;
  264. case 283:
  265. colfunc = R_DrawFogColumn_8;
  266. windowtop = frontsector->ceilingheight;
  267. windowbottom = frontsector->floorheight;
  268. break;
  269. default:
  270. colfunc = wallcolfunc;
  271. break;
  272. }
  273. rw_scalestep = ds->scalestep;
  274. spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
  275. // handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures
  276. // are not stored per-column with post info in SRB2
  277. if (textures[texnum]->patchcount == 1)
  278. colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture
  279. else
  280. {
  281. colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info)
  282. column2s_length = textures[texnum]->height;
  283. }
  284. // Setup lighting based on the presence/lack-of 3D floors.
  285. dc_numlights = 0;
  286. if (frontsector->numlights)
  287. {
  288. dc_numlights = frontsector->numlights;
  289. if (dc_numlights >= dc_maxlights)
  290. {
  291. dc_maxlights = dc_numlights;
  292. dc_lightlist = realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights);
  293. if (!dc_lightlist) I_Error("Out of Memory in R_RenderMaskedSegRange");
  294. }
  295. for (i = 0; i < dc_numlights; i++)
  296. {
  297. light = &frontsector->lightlist[i];
  298. rlight = &dc_lightlist[i];
  299. rlight->height = (centeryfrac) - FixedMul((light->height - viewz), spryscale);
  300. rlight->heightstep = -FixedMul(rw_scalestep, (light->height - viewz));
  301. rlight->lightlevel = *light->lightlevel;
  302. rlight->extra_colormap = light->extra_colormap;
  303. rlight->flags = light->flags;
  304. if (rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog))
  305. lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
  306. else if (colfunc == fuzzcolfunc)
  307. lightnum = LIGHTLEVELS - 1;
  308. else
  309. lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
  310. if (rlight->extra_colormap && rlight->extra_colormap->fog)
  311. ;
  312. else if (curline->v1->y == curline->v2->y)
  313. lightnum--;
  314. else if (curline->v1->x == curline->v2->x)
  315. lightnum++;
  316. rlight->lightnum = lightnum;
  317. }
  318. }
  319. else
  320. {
  321. if (colfunc == fuzzcolfunc)
  322. {
  323. if (frontsector->extra_colormap && frontsector->extra_colormap->fog)
  324. lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
  325. else
  326. lightnum = LIGHTLEVELS - 1;
  327. }
  328. else
  329. lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
  330. if (colfunc == R_DrawFogColumn_8
  331. || (frontsector->extra_colormap && frontsector->extra_colormap->fog))
  332. ;
  333. else if (curline->v1->y == curline->v2->y)
  334. lightnum--;
  335. else if (curline->v1->x == curline->v2->x)
  336. lightnum++;
  337. if (lightnum < 0)
  338. walllights = scalelight[0];
  339. else if (lightnum >= LIGHTLEVELS)
  340. walllights = scalelight[LIGHTLEVELS - 1];
  341. else
  342. walllights = scalelight[lightnum];
  343. }
  344. maskedtexturecol = ds->maskedtexturecol;
  345. mfloorclip = ds->sprbottomclip;
  346. mceilingclip = ds->sprtopclip;
  347. if (frontsector->heightsec != -1)
  348. front = &sectors[frontsector->heightsec];
  349. else
  350. front = frontsector;
  351. if (backsector->heightsec != -1)
  352. back = &sectors[backsector->heightsec];
  353. else
  354. back = backsector;
  355. if (curline->linedef->flags & ML_DONTPEGBOTTOM)
  356. {
  357. dc_texturemid = front->floorheight > back->floorheight
  358. ? front->floorheight : back->floorheight;
  359. dc_texturemid = dc_texturemid + textureheight[texnum] - viewz;
  360. }
  361. else
  362. {
  363. dc_texturemid = front->ceilingheight < back->ceilingheight
  364. ? front->ceilingheight : back->ceilingheight;
  365. dc_texturemid = dc_texturemid - viewz;
  366. }
  367. dc_texturemid += curline->sidedef->rowoffset;
  368. dc_texheight = textureheight[texnum]>>FRACBITS;
  369. // draw the columns
  370. for (dc_x = x1; dc_x <= x2; dc_x++)
  371. {
  372. // calculate lighting
  373. if (maskedtexturecol[dc_x] != MAXSHORT)
  374. {
  375. if (dc_numlights)
  376. {
  377. lighttable_t **xwalllights;
  378. sprbotscreen = MAXINT;
  379. // killough 3/2/98:
  380. //
  381. // This calculation used to overflow and cause crashes in Doom:
  382. //
  383. // sprtopscreen = centeryfrac - FixedMul(dcvars.texturemid, spryscale);
  384. //
  385. // This code fixes it, by using double-precision intermediate
  386. // arithmetic and by skipping the drawing of 2s normals whose
  387. // mapping to screen coordinates is totally out of range:
  388. {
  389. INT64 t = ((INT64) centeryfrac << FRACBITS) -
  390. (INT64) dc_texturemid * spryscale;
  391. if (t + (INT64) textureheight[texnum] * spryscale < 0 ||
  392. t > (INT64) MAXVIDHEIGHT << FRACBITS*2)
  393. continue; // skip if the texture is out of screen's range
  394. sprtopscreen = windowtop = (long)(t>>FRACBITS);
  395. }
  396. realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen;
  397. dc_iscale = 0xffffffffu / (unsigned)spryscale;
  398. // draw the texture
  399. col = (column_t *)((byte *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3);
  400. for (i = 0; i < dc_numlights; i++)
  401. {
  402. rlight = &dc_lightlist[i];
  403. if ((rlight->flags & FF_NOSHADE))
  404. continue;
  405. if (rlight->lightnum < 0)
  406. xwalllights = scalelight[0];
  407. else if (rlight->lightnum >= LIGHTLEVELS)
  408. xwalllights = scalelight[LIGHTLEVELS-1];
  409. else
  410. xwalllights = scalelight[rlight->lightnum];
  411. pindex = spryscale>>LIGHTSCALESHIFT;
  412. if (pindex >= MAXLIGHTSCALE)
  413. pindex = MAXLIGHTSCALE - 1;
  414. if (rlight->extra_colormap)
  415. rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps);
  416. else
  417. rlight->rcolormap = xwalllights[pindex];
  418. rlight->height += rlight->heightstep;
  419. height = rlight->height;
  420. if (height <= windowtop)
  421. {
  422. dc_colormap = rlight->rcolormap;
  423. continue;
  424. }
  425. windowbottom = height;
  426. if (windowbottom >= realbot)
  427. {
  428. windowbottom = realbot;
  429. colfunc_2s(col);
  430. for (i++; i < dc_numlights; i++)
  431. {
  432. rlight = &dc_lightlist[i];
  433. rlight->height += rlight->heightstep;
  434. }
  435. continue;
  436. }
  437. colfunc_2s(col);
  438. windowtop = windowbottom + 1;
  439. dc_colormap = rlight->rcolormap;
  440. }
  441. windowbottom = realbot;
  442. if (windowtop < windowbottom)
  443. colfunc_2s(col);
  444. spryscale += rw_scalestep;
  445. continue;
  446. }
  447. // calculate lighting
  448. pindex = spryscale>>LIGHTSCALESHIFT;
  449. if (pindex >= MAXLIGHTSCALE)
  450. pindex = MAXLIGHTSCALE - 1;
  451. dc_colormap = walllights[pindex];
  452. if (frontsector->extra_colormap)
  453. dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
  454. // killough 3/2/98:
  455. //
  456. // This calculation used to overflow and cause crashes in Doom:
  457. //
  458. // sprtopscreen = centeryfrac - FixedMul(dcvars.texturemid, spryscale);
  459. //
  460. // This code fixes it, by using double-precision intermediate
  461. // arithmetic and by skipping the drawing of 2s normals whose
  462. // mapping to screen coordinates is totally out of range:
  463. {
  464. INT64 t = ((INT64) centeryfrac << FRACBITS) -
  465. (INT64) dc_texturemid * spryscale;
  466. if (t + (INT64) textureheight[texnum] * spryscale < 0 ||
  467. t > (INT64) MAXVIDHEIGHT << FRACBITS*2)
  468. continue; // skip if the texture is out of screen's range
  469. sprtopscreen = (long)(t>>FRACBITS);
  470. }
  471. dc_iscale = 0xffffffffu / (unsigned)spryscale;
  472. // draw the texture
  473. col = (column_t *)((byte *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3);
  474. #ifdef POLYOBJECTS_PLANES
  475. if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES))
  476. {
  477. fixed_t my_topscreen;
  478. fixed_t my_bottomscreen;
  479. fixed_t my_yl, my_yh;
  480. my_topscreen = sprtopscreen + spryscale*col->topdelta;
  481. my_bottomscreen = sprbotscreen == MAXINT ? my_topscreen + spryscale*col->length
  482. : sprbotscreen + spryscale*col->length;
  483. my_yl = (my_topscreen+FRACUNIT-1)>>FRACBITS;
  484. my_yh = (my_bottomscreen-1)>>FRACBITS;
  485. // CONS_Printf("my_topscreen: %d\nmy_bottomscreen: %d\nmy_yl: %d\nmy_yh: %d\n", my_topscreen, my_bottomscreen, my_yl, my_yh);
  486. if (numffloors)
  487. {
  488. int top = my_yl;
  489. int bottom = my_yh;
  490. for (i = 0; i < numffloors; i++)
  491. {
  492. if (!ffloor[i].polyobj)
  493. continue;
  494. if (ffloor[i].height < viewz)
  495. {
  496. int top_w = ffloor[i].plane->top[dc_x];
  497. // CONS_Printf("Leveltime : %d\n", leveltime);
  498. // CONS_Printf("Top is %d, top_w is %d\n", top, top_w);
  499. if (top_w < top)
  500. {
  501. ffloor[i].plane->top[dc_x] = (short)top;
  502. ffloor[i].plane->picnum = 0;
  503. }
  504. // CONS_Printf("top_w is now %d\n", ffloor[i].plane->top[dc_x]);
  505. }
  506. else if (ffloor[i].height > viewz)
  507. {
  508. int bottom_w = ffloor[i].plane->bottom[dc_x];
  509. if (bottom_w > bottom)
  510. {
  511. ffloor[i].plane->bottom[dc_x] = (short)bottom;
  512. ffloor[i].plane->picnum = 0;
  513. }
  514. }
  515. }
  516. }
  517. }
  518. else
  519. #endif
  520. colfunc_2s(col);
  521. }
  522. spryscale += rw_scalestep;
  523. }
  524. colfunc = wallcolfunc;
  525. }
  526. //
  527. // R_RenderThickSideRange
  528. // Renders all the thick sides in the given range.
  529. void R_RenderThickSideRange(drawseg_t *ds, int x1, int x2, ffloor_t *pfloor)
  530. {
  531. size_t pindex;
  532. column_t * col;
  533. int lightnum;
  534. long texnum;
  535. sector_t tempsec;
  536. int templight;
  537. int i, p;
  538. fixed_t bottombounds = viewheight << FRACBITS;
  539. fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS;
  540. fixed_t offsetvalue = 0;
  541. lightlist_t *light;
  542. r_lightlist_t *rlight;
  543. fixed_t lheight;
  544. void (*colfunc_2s) (column_t *);
  545. // Calculate light table.
  546. // Use different light tables
  547. // for horizontal / vertical / diagonal. Diagonal?
  548. // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
  549. curline = ds->curline;
  550. backsector = pfloor->target;
  551. frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector;
  552. texnum = texturetranslation[sides[pfloor->master->sidenum[0]].midtexture];
  553. colfunc = wallcolfunc;
  554. if (pfloor->flags & FF_TRANSLUCENT)
  555. {
  556. boolean fuzzy = true;
  557. // Hacked up support for alpha value in software mode Tails 09-24-2002
  558. if (pfloor->alpha < 12)
  559. return; // Don't even draw it
  560. else if (pfloor->alpha < 64)
  561. dc_transmap = ((tr_transhi)<<FF_TRANSSHIFT) - 0x10000 + transtables; // Don't be so hard to see Tails 02-02-2002
  562. else if (pfloor->alpha < 128)
  563. dc_transmap = ((tr_transmor)<<FF_TRANSSHIFT) - 0x10000 + transtables; // Don't be so hard to see Tails 02-02-2002
  564. else if (pfloor->alpha < 192)
  565. dc_transmap = ((tr_transmed)<<FF_TRANSSHIFT) - 0x10000 + transtables; // Don't be so hard to see Tails 02-02-2002
  566. else
  567. fuzzy = false; // Opaque
  568. if (fuzzy)
  569. colfunc = fuzzcolfunc;
  570. }
  571. else if (pfloor->flags & FF_FOG)
  572. colfunc = R_DrawFogColumn_8;
  573. //SoM: Moved these up here so they are available for my lightlist calculations
  574. rw_scalestep = ds->scalestep;
  575. spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
  576. dc_numlights = 0;
  577. if (frontsector->numlights)
  578. {
  579. dc_numlights = frontsector->numlights;
  580. if (dc_numlights > dc_maxlights)
  581. {
  582. dc_maxlights = dc_numlights;
  583. dc_lightlist = realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights);
  584. if (!dc_lightlist) I_Error("Out of Memory in R_RenderThickSideRange");
  585. }
  586. for (i = p = 0; i < dc_numlights; i++)
  587. {
  588. light = &frontsector->lightlist[i];
  589. rlight = &dc_lightlist[p];
  590. if (light->height < *pfloor->bottomheight)
  591. continue;
  592. if (light->height > *pfloor->topheight && i+1 < dc_numlights && frontsector->lightlist[i+1].height > *pfloor->topheight)
  593. continue;
  594. lheight = light->height;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : light->height;
  595. rlight->heightstep = -FixedMul (rw_scalestep, (lheight - viewz));
  596. rlight->height = (centeryfrac) - FixedMul((lheight - viewz), spryscale) - rlight->heightstep;
  597. rlight->flags = light->flags;
  598. if (light->flags & FF_CUTLEVEL)
  599. {
  600. lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight;
  601. rlight->botheightstep = -FixedMul (rw_scalestep, (lheight - viewz));
  602. rlight->botheight = (centeryfrac) - FixedMul((lheight - viewz), spryscale) - rlight->botheightstep;
  603. }
  604. rlight->lightlevel = *light->lightlevel;
  605. rlight->extra_colormap = light->extra_colormap;
  606. // Check if the current light effects the colormap/lightlevel
  607. if (pfloor->flags & FF_FOG)
  608. rlight->lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT);
  609. else
  610. rlight->lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
  611. if (pfloor->flags & FF_FOG || rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog))
  612. ;
  613. else if (curline->v1->y == curline->v2->y)
  614. rlight->lightnum--;
  615. else if (curline->v1->x == curline->v2->x)
  616. rlight->lightnum++;
  617. p++;
  618. }
  619. dc_numlights = p;
  620. }
  621. else
  622. {
  623. // Get correct light level!
  624. if ((frontsector->extra_colormap && frontsector->extra_colormap->fog))
  625. lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
  626. else if (pfloor->flags & FF_FOG)
  627. lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT);
  628. else if (colfunc == fuzzcolfunc)
  629. lightnum = LIGHTLEVELS-1;
  630. else
  631. lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false)
  632. ->lightlevel >> LIGHTSEGSHIFT;
  633. if (pfloor->flags & FF_FOG || (frontsector->extra_colormap && frontsector->extra_colormap->fog));
  634. else if (curline->v1->y == curline->v2->y)
  635. lightnum--;
  636. else if (curline->v1->x == curline->v2->x)
  637. lightnum++;
  638. if (lightnum < 0)
  639. walllights = scalelight[0];
  640. else if (lightnum >= LIGHTLEVELS)
  641. walllights = scalelight[LIGHTLEVELS-1];
  642. else
  643. walllights = scalelight[lightnum];
  644. }
  645. maskedtexturecol = ds->thicksidecol;
  646. mfloorclip = ds->sprbottomclip;
  647. mceilingclip = ds->sprtopclip;
  648. dc_texheight = textureheight[texnum]>>FRACBITS;
  649. dc_texturemid = *pfloor->topheight - viewz;
  650. offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset;
  651. if (curline->linedef->flags & ML_DONTPEGBOTTOM)
  652. offsetvalue -= *pfloor->topheight - *pfloor->bottomheight;
  653. dc_texturemid += offsetvalue;
  654. //faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures
  655. // are not stored per-column with post info anymore in Doom Legacy
  656. if (textures[texnum]->patchcount == 1)
  657. colfunc_2s = R_DrawMaskedColumn; //render the usual 2sided single-patch packed texture
  658. else
  659. {
  660. colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info)
  661. column2s_length = textures[texnum]->height;
  662. }
  663. // draw the columns
  664. for (dc_x = x1; dc_x <= x2; dc_x++)
  665. {
  666. if (maskedtexturecol[dc_x] != MAXSHORT)
  667. {
  668. // SoM: New code does not rely on r_drawColumnShadowed_8 which
  669. // will (hopefully) put less strain on the stack.
  670. if (dc_numlights)
  671. {
  672. lighttable_t **xwalllights;
  673. fixed_t height;
  674. fixed_t bheight = 0;
  675. int solid = 0;
  676. int lighteffect = 0;
  677. sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale));
  678. sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen;
  679. // SoM: If column is out of range, why bother with it??
  680. if (windowbottom < topbounds || windowtop > bottombounds)
  681. {
  682. for (i = 0; i < dc_numlights; i++)
  683. {
  684. rlight = &dc_lightlist[i];
  685. rlight->height += rlight->heightstep;
  686. if (rlight->flags & FF_CUTLEVEL)
  687. rlight->botheight += rlight->botheightstep;
  688. }
  689. spryscale += rw_scalestep;
  690. continue;
  691. }
  692. dc_iscale = 0xffffffffu / (unsigned)spryscale;
  693. // draw the texture
  694. col = (column_t *)((byte *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3);
  695. for (i = 0; i < dc_numlights; i++)
  696. {
  697. // Check if the current light effects the colormap/lightlevel
  698. rlight = &dc_lightlist[i];
  699. lighteffect = !(dc_lightlist[i].flags & FF_NOSHADE);
  700. if (lighteffect)
  701. {
  702. lightnum = rlight->lightnum;
  703. if (lightnum < 0)
  704. xwalllights = scalelight[0];
  705. else if (lightnum >= LIGHTLEVELS)
  706. xwalllights = scalelight[LIGHTLEVELS-1];
  707. else
  708. xwalllights = scalelight[lightnum];
  709. pindex = spryscale>>LIGHTSCALESHIFT;
  710. if (pindex >= MAXLIGHTSCALE)
  711. pindex = MAXLIGHTSCALE-1;
  712. if (pfloor->flags & FF_FOG)
  713. {
  714. if (pfloor->master->frontsector->extra_colormap)
  715. rlight->rcolormap = pfloor->master->frontsector->extra_colormap->colormap + (xwalllights[pindex] - colormaps);
  716. else
  717. rlight->rcolormap = xwalllights[pindex];
  718. }
  719. else
  720. {
  721. if (rlight->extra_colormap)
  722. rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps);
  723. else
  724. rlight->rcolormap = xwalllights[pindex];
  725. }
  726. }
  727. // Check if the current light can cut the current 3D floor.
  728. if (rlight->flags & FF_CUTSOLIDS && !(pfloor->flags & FF_EXTRA))
  729. solid = 1;
  730. else if (rlight->flags & FF_CUTEXTRA && pfloor->flags & FF_EXTRA)
  731. {
  732. if (rlight->flags & FF_EXTRA)
  733. {
  734. // The light is from an extra 3D floor... Check the flags so
  735. // there are no undesired cuts.
  736. if (rlight->flags == pfloor->flags) // Only merge with your own kind
  737. solid = 1;
  738. }
  739. else
  740. solid = 1;
  741. }
  742. else
  743. solid = 0;
  744. rlight->height += rlight->heightstep;
  745. height = rlight->height;
  746. if (solid)
  747. {
  748. rlight->botheight += rlight->botheightstep;
  749. bheight = rlight->botheight - (FRACUNIT >> 1);
  750. }
  751. if (height <= windowtop)
  752. {
  753. if (lighteffect)
  754. dc_colormap = rlight->rcolormap;
  755. if (solid && windowtop < bheight)
  756. windowtop = bheight;
  757. continue;
  758. }
  759. windowbottom = height;
  760. if (windowbottom >= sprbotscreen)
  761. {
  762. windowbottom = sprbotscreen;
  763. colfunc_2s (col);
  764. for (i++; i < dc_numlights; i++)
  765. {
  766. rlight = &dc_lightlist[i];
  767. rlight->height += rlight->heightstep;
  768. if (rlight->flags & FF_CUTLEVEL)
  769. rlight->botheight += rlight->botheightstep;
  770. }
  771. continue;
  772. }
  773. colfunc_2s (col);
  774. if (solid)
  775. windowtop = bheight;
  776. else
  777. windowtop = windowbottom + 1;
  778. if (lighteffect)
  779. dc_colormap = rlight->rcolormap;
  780. }
  781. windowbottom = sprbotscreen;
  782. if (windowtop < windowbottom)
  783. colfunc_2s (col);
  784. spryscale += rw_scalestep;
  785. continue;
  786. }
  787. // calculate lighting
  788. pindex = spryscale>>LIGHTSCALESHIFT;
  789. if (pindex >= MAXLIGHTSCALE)
  790. pindex = MAXLIGHTSCALE - 1;
  791. dc_colormap = walllights[pindex];
  792. if (frontsector->extra_colormap)
  793. dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
  794. if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap)
  795. dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
  796. sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale));
  797. sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen;
  798. dc_iscale = 0xffffffffu / (unsigned)spryscale;
  799. // draw the texture
  800. col = (column_t *)((byte *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3);
  801. colfunc_2s (col);
  802. spryscale += rw_scalestep;
  803. }
  804. }
  805. colfunc = wallcolfunc;
  806. }
  807. //
  808. // R_RenderSegLoop
  809. // Draws zero, one, or two textures (and possibly a masked
  810. // texture) for walls.
  811. // Can draw or mark the starting pixel of floor and ceiling
  812. // textures.
  813. // CALLED: CORE LOOPING ROUTINE.
  814. //
  815. #define HEIGHTBITS 12
  816. #define HEIGHTUNIT (1<<HEIGHTBITS)
  817. //profile stuff ---------------------------------------------------------
  818. //#define TIMING
  819. #ifdef TIMING
  820. #include "p5prof.h"
  821. long long mycount;
  822. long long mytotal = 0;
  823. unsigned long nombre = 100000;
  824. //static char runtest[10][80];
  825. #endif
  826. //profile stuff ---------------------------------------------------------
  827. static void R_RenderSegLoop (void)
  828. {
  829. angle_t angle;
  830. size_t pindex;
  831. int yl;
  832. int yh;
  833. int mid;
  834. fixed_t texturecolumn = 0;
  835. int top;
  836. int bottom;
  837. int i;
  838. for (; rw_x < rw_stopx; rw_x++)
  839. {
  840. // mark floor / ceiling areas
  841. yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS;
  842. // no space above wall?
  843. top = ceilingclip[rw_x]+1;
  844. // no space above wall?
  845. if (yl < top)
  846. yl = top;
  847. if (markceiling)
  848. {
  849. bottom = yl-1;
  850. if (bottom >= floorclip[rw_x])
  851. bottom = floorclip[rw_x]-1;
  852. if (top <= bottom)
  853. {
  854. ceilingplane->top[rw_x] = (short)top;
  855. ceilingplane->bottom[rw_x] = (short)bottom;
  856. }
  857. }
  858. yh = bottomfrac>>HEIGHTBITS;
  859. bottom = floorclip[rw_x]-1;
  860. if (yh > bottom)
  861. yh = bottom;
  862. if (markfloor)
  863. {
  864. #if 0 // Old Doom Legacy code
  865. bottom = floorclip[rw_x]-1;
  866. if (top <= ceilingclip[rw_x])
  867. top = ceilingclip[rw_x]+1;
  868. if (top <= bottom && floorplane)
  869. {
  870. floorplane->top[rw_x] = (short)top;
  871. floorplane->bottom[rw_x] = (short)bottom;
  872. }
  873. #else // Spiffy new PRBoom code
  874. top = yh < ceilingclip[rw_x] ? ceilingclip[rw_x] : yh;
  875. if (++top <= bottom && floorplane)
  876. {
  877. floorplane->top[rw_x] = (short)top;
  878. floorplane->bottom[rw_x] = (short)bottom;
  879. }
  880. #endif
  881. }
  882. if (numffloors)
  883. {
  884. firstseg->frontscale[rw_x] = frontscale[rw_x];
  885. top = ceilingclip[rw_x]+1; // PRBoom
  886. bottom = floorclip[rw_x]-1; // PRBoom
  887. for (i = 0; i < numffloors; i++)
  888. {
  889. #ifdef POLYOBJECTS_PLANES
  890. if (curline->polyseg && !ffloor[i].polyobj)
  891. continue;
  892. #endif
  893. if (ffloor[i].height < viewz)
  894. {
  895. int top_w = (ffloor[i].f_frac >> HEIGHTBITS) + 1;
  896. int bottom_w = ffloor[i].f_clip[rw_x];
  897. if (top_w < top)
  898. top_w = top;
  899. if (bottom_w > bottom)
  900. bottom_w = bottom;
  901. if (top_w <= bottom_w)
  902. {
  903. ffloor[i].plane->top[rw_x] = (short)top_w;
  904. ffloor[i].plane->bottom[rw_x] = (short)bottom_w;
  905. }
  906. }
  907. else if (ffloor[i].height > viewz)
  908. {
  909. int top_w = ffloor[i].c_clip[rw_x] + 1;
  910. int bottom_w = (ffloor[i].f_frac >> HEIGHTBITS);
  911. if (top_w < top)
  912. top_w = top;
  913. if (bottom_w > bottom)
  914. bottom_w = bottom;
  915. if (top_w <= bottom_w)
  916. {
  917. ffloor[i].plane->top[rw_x] = (short)top_w;
  918. ffloor[i].plane->bottom[rw_x] = (short)bottom_w;
  919. }
  920. }
  921. }
  922. }
  923. //SoM: Calculate offsets for Thick fake floors.
  924. // calculate texture offset
  925. angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT;
  926. texturecolumn = rw_offset-FixedMul(FINETANGENT(angle),rw_distance);
  927. texturecolumn >>= FRACBITS;
  928. // texturecolumn and lighting are independent of wall tiers
  929. if (segtextured)
  930. {
  931. // calculate lighting
  932. pindex = rw_scale>>LIGHTSCALESHIFT;
  933. if (pindex >= MAXLIGHTSCALE)
  934. pindex = MAXLIGHTSCALE-1;
  935. dc_colormap = walllights[pindex];
  936. dc_x = rw_x;
  937. dc_iscale = 0xffffffffu / (unsigned)rw_scale;
  938. if (frontsector->extra_colormap)
  939. dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
  940. }
  941. if (dc_numlights)
  942. {
  943. lighttable_t **xwalllights;
  944. for (i = 0; i < dc_numlights; i++)
  945. {
  946. int lightnum;
  947. lightnum = (dc_lightlist[i].lightlevel >> LIGHTSEGSHIFT);
  948. if (dc_lightlist[i].extra_colormap)
  949. ;
  950. else if (curline->v1->y == curline->v2->y)
  951. lightnum--;
  952. else if (curline->v1->x == curline->v2->x)
  953. lightnum++;
  954. if (lightnum < 0)
  955. xwalllights = scalelight[0];
  956. else if (lightnum >= LIGHTLEVELS)
  957. xwalllights = scalelight[LIGHTLEVELS-1];
  958. else
  959. xwalllights = scalelight[lightnum];
  960. pindex = rw_scale>>LIGHTSCALESHIFT;
  961. if (pindex >= MAXLIGHTSCALE)
  962. pindex = MAXLIGHTSCALE-1;
  963. if (dc_lightlist[i].extra_colormap)
  964. dc_lightlist[i].rcolormap = dc_lightlist[i].extra_colormap->colormap + (xwalllights[pindex] - colormaps);
  965. else
  966. dc_lightlist[i].rcolormap = xwalllights[pindex];
  967. colfunc = R_DrawColumnShadowed_8;
  968. }
  969. }
  970. frontscale[rw_x] = rw_scale;
  971. // draw the wall tiers
  972. if (midtexture)
  973. {
  974. // single sided line
  975. dc_yl = yl;
  976. dc_yh = yh;
  977. dc_texturemid = rw_midtexturemid;
  978. dc_source = R_GetColumn(midtexture,texturecolumn);
  979. dc_texheight = textureheight[midtexture]>>FRACBITS;
  980. //profile stuff ---------------------------------------------------------
  981. #ifdef TIMING
  982. ProfZeroTimer();
  983. #endif
  984. colfunc();
  985. #ifdef TIMING
  986. RDMSR(0x10,&mycount);
  987. mytotal += mycount; //64bit add
  988. if (nombre--==0)
  989. I_Error("R_DrawColumn CPU Spy reports: 0x%d %d\n", *((int *)&mytotal+1),
  990. (int)mytotal);
  991. #endif
  992. //profile stuff ---------------------------------------------------------
  993. // dont draw anything more for this column, since
  994. // a midtexture blocks the view
  995. ceilingclip[rw_x] = (short)viewheight;
  996. floorclip[rw_x] = -1;
  997. }
  998. else
  999. {
  1000. // two sided line
  1001. if (toptexture)
  1002. {
  1003. // top wall
  1004. mid = pixhigh>>HEIGHTBITS;
  1005. pixhigh += pixhighstep;
  1006. if (mid >= floorclip[rw_x])
  1007. mid = floorclip[rw_x]-1;
  1008. if (mid >= yl)
  1009. {
  1010. dc_yl = yl;
  1011. dc_yh = mid;
  1012. dc_texturemid = rw_toptexturemid;
  1013. dc_source = R_GetColumn(toptexture,texturecolumn);
  1014. dc_texheight = textureheight[toptexture]>>FRACBITS;
  1015. colfunc();
  1016. ceilingclip[rw_x] = (short)mid;
  1017. }
  1018. else
  1019. ceilingclip[rw_x] = (short)((short)yl - 1);
  1020. }
  1021. else if (markceiling) // no top wall
  1022. ceilingclip[rw_x] = (short)((short)yl - 1);
  1023. if (bottomtexture)
  1024. {
  1025. // bottom wall
  1026. mid = (pixlow+HEIGHTUNIT-1)>>HEIGHTBITS;
  1027. pixlow += pixlowstep;
  1028. // no space above wall?
  1029. if (mid <= ceilingclip[rw_x])
  1030. mid = ceilingclip[rw_x]+1;
  1031. if (mid <= yh)
  1032. {
  1033. dc_yl = mid;
  1034. dc_yh = yh;
  1035. dc_texturemid = rw_bottomtexturemid;
  1036. dc_source = R_GetColumn(bottomtexture,
  1037. texturecolumn);
  1038. dc_texheight = textureheight[bottomtexture]>>FRACBITS;
  1039. colfunc();
  1040. floorclip[rw_x] = (short)mid;
  1041. }
  1042. else
  1043. floorclip[rw_x] = (short)((short)yh + 1);
  1044. }
  1045. else if (markfloor) // no bottom wall
  1046. floorclip[rw_x] = (short)((short)yh + 1);
  1047. }
  1048. if (maskedtexture || numthicksides)
  1049. {
  1050. // save texturecol
  1051. // for backdrawing of masked mid texture
  1052. maskedtexturecol[rw_x] = (short)texturecolumn;
  1053. }
  1054. if (dc_numlights)
  1055. {
  1056. for (i = 0; i < dc_numlights; i++)
  1057. {
  1058. dc_lightlist[i].height += dc_lightlist[i].heightstep;
  1059. if (dc_lightlist[i].flags & FF_SOLID)
  1060. dc_lightlist[i].botheight += dc_lightlist[i].botheightstep;
  1061. }
  1062. }
  1063. for (i = 0; i < MAXFFLOORS; i++)
  1064. {
  1065. #ifdef POLYOBJECTS_PLANES
  1066. if (curline->polyseg && !ffloor[i].polyobj)
  1067. continue;
  1068. #endif
  1069. if (ffloor[i].mark)
  1070. {
  1071. int y_w = ffloor[i].b_frac >> HEIGHTBITS;
  1072. ffloor[i].f_clip[rw_x] = ffloor[i].c_clip[rw_x] = (short)y_w;
  1073. ffloor[i].b_frac += ffloor[i].b_step;
  1074. }
  1075. ffloor[i].f_frac += ffloor[i].f_step;
  1076. }
  1077. rw_scale += rw_scalestep;
  1078. topfrac += topstep;
  1079. bottomfrac += bottomstep;
  1080. }
  1081. }
  1082. //
  1083. // R_StoreWallRange
  1084. // A wall segment will be drawn
  1085. // between start and stop pixels (inclusive).
  1086. //
  1087. void R_StoreWallRange(int start, int stop)
  1088. {
  1089. fixed_t hyp;
  1090. fixed_t sineval;
  1091. angle_t distangle, offsetangle;
  1092. fixed_t vtop;
  1093. int lightnum;
  1094. int i, p;
  1095. lightlist_t *light;
  1096. r_lightlist_t *rlight;
  1097. fixed_t lheight;
  1098. static size_t maxdrawsegs = 0;
  1099. if (ds_p == drawsegs+maxdrawsegs)
  1100. {
  1101. size_t pos = ds_p - drawsegs;
  1102. size_t pos2 = firstnewseg - drawsegs;
  1103. size_t newmax = maxdrawsegs ? maxdrawsegs*2 : 128;
  1104. if (firstseg)
  1105. firstseg = (drawseg_t *)(firstseg - drawsegs);
  1106. drawsegs = realloc(drawsegs,newmax*sizeof (*drawsegs));
  1107. if (!drawsegs) I_Error("Out of Memory in R_StoreWallRange");
  1108. ds_p = drawsegs + pos;
  1109. firstnewseg = drawsegs + pos2;
  1110. maxdrawsegs = newmax;
  1111. if (firstseg)
  1112. firstseg = drawsegs + (size_t)firstseg;
  1113. }
  1114. sidedef = curline->sidedef;
  1115. linedef = curline->linedef;
  1116. // calculate rw_distance for scale calculation
  1117. rw_normalangle = curline->angle + ANG90;
  1118. offsetangle = abs((int)(rw_normalangle-rw_angle1));
  1119. if (offsetangle > ANG90)
  1120. offsetangle = ANG90;
  1121. distangle = ANG90 - offsetangle;
  1122. hyp = R_PointToDist (curline->v1->x, curline->v1->y);
  1123. sineval = FINESINE(distangle>>ANGLETOFINESHIFT);
  1124. rw_distance = FixedMul (hyp, sineval);
  1125. ds_p->x1 = rw_x = start;
  1126. ds_p->x2 = stop;
  1127. ds_p->curline = curline;
  1128. rw_stopx = stop+1;
  1129. //SoM: Code to remove limits on openings.
  1130. {
  1131. size_t pos = lastopening - openings;
  1132. size_t need = (rw_stopx - start)*4 + pos;
  1133. if (need > maxopenings)
  1134. {
  1135. drawseg_t *ds; //needed for fix from *cough* zdoom *cough*
  1136. short *oldopenings = openings;
  1137. short *oldlast = lastopening;
  1138. do
  1139. maxopenings = maxopenings ? maxopenings*2 : 16384;
  1140. while (need > maxopenings);
  1141. openings = realloc(openings, maxopenings * sizeof (*openings));
  1142. if (!openings) I_Error("Out of Memory in R_StoreWallRange");
  1143. lastopening = openings + pos;
  1144. // borrowed fix from *cough* zdoom *cough*
  1145. // [RH] We also need to adjust the openings pointers that
  1146. // were already stored in drawsegs.
  1147. for (ds = drawsegs; ds < ds_p; ds++)
  1148. {
  1149. #define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast) ds->p = ds->p - oldopenings + openings;
  1150. ADJUST(maskedtexturecol);
  1151. ADJUST(sprtopclip);
  1152. ADJUST(sprbottomclip);
  1153. ADJUST(thicksidecol);
  1154. #undef ADJUST
  1155. }
  1156. }
  1157. } // end of code to remove limits on openings
  1158. // calculate scale at both ends and step
  1159. ds_p->scale1 = rw_scale = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[start]);
  1160. if (stop > start)
  1161. {
  1162. ds_p->scale2 = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[stop]);
  1163. ds_p->scalestep = rw_scalestep = (ds_p->scale2 - rw_scale) / (stop-start);
  1164. }
  1165. else
  1166. {
  1167. // UNUSED: try to fix the stretched line bug
  1168. #if 0
  1169. if (rw_distance < FRACUNIT/2)
  1170. {
  1171. fixed_t tr_x,tr_y;
  1172. fixed_t gxt,gyt;
  1173. CONS_Printf("TRYING TO FIX THE STRETCHED ETC\n");
  1174. tr_x = curline->v1->x - viewx;
  1175. tr_y = curline->v1->y - viewy;
  1176. gxt = FixedMul(tr_x, viewcos);
  1177. gyt = -FixedMul(tr_y, viewsin);
  1178. ds_p->scale1 = FixedDiv(projection, gxt - gyt);
  1179. }
  1180. #endif
  1181. ds_p->scale2 = ds_p->scale1;
  1182. }
  1183. // calculate texture boundaries
  1184. // and decide if floor / ceiling marks are needed
  1185. worldtop = frontsector->ceilingheight - viewz;
  1186. worldbottom = frontsector->floorheight - viewz;
  1187. midtexture = toptexture = bottomtexture = maskedtexture = 0;
  1188. ds_p->maskedtexturecol = NULL;
  1189. ds_p->numthicksides = numthicksides = 0;
  1190. ds_p->thicksidecol = NULL;
  1191. ds_p->tsilheight = 0;
  1192. for (i = 0; i < MAXFFLOORS; i++)
  1193. {
  1194. ffloor[i].mark = false;
  1195. ds_p->thicksides[i] = NULL;
  1196. }
  1197. if (numffloors)
  1198. {
  1199. for (i = 0; i < numffloors; i++)
  1200. {
  1201. #ifdef POLYOBJECTS_PLANES
  1202. if (ds_p->curline->polyseg && !ffloor[i].polyobj)
  1203. continue;
  1204. #endif
  1205. ffloor[i].f_pos = ffloor[i].height - viewz;
  1206. }
  1207. }
  1208. if (!backsector)
  1209. {
  1210. // single sided line
  1211. midtexture = texturetranslation[sidedef->midtexture];
  1212. // a single sided line is terminal, so it must mark ends
  1213. markfloor = markceiling = true;
  1214. if (linedef->flags & ML_DONTPEGBOTTOM)
  1215. {
  1216. vtop = frontsector->floorheight + textureheight[sidedef->midtexture];
  1217. // bottom of texture at bottom
  1218. rw_midtexturemid = vtop - viewz;
  1219. }
  1220. else
  1221. {
  1222. // top of texture at top
  1223. rw_midtexturemid = worldtop;
  1224. }
  1225. rw_midtexturemid += sidedef->rowoffset;
  1226. ds_p->silhouette = SIL_BOTH;
  1227. ds_p->sprtopclip = screenheightarray;
  1228. ds_p->sprbottomclip = negonearray;
  1229. ds_p->bsilheight = MAXINT;
  1230. ds_p->tsilheight = MININT;
  1231. }
  1232. else
  1233. {
  1234. // two sided line
  1235. ds_p->sprtopclip = ds_p->sprbottomclip = NULL;
  1236. ds_p->silhouette = 0;
  1237. if (frontsector->floorheight > backsector->floorheight)
  1238. {
  1239. ds_p->silhouette = SIL_BOTTOM;
  1240. ds_p->bsilheight = frontsector->floorheight;
  1241. }
  1242. else if (backsector->floorheight > viewz)
  1243. {
  1244. ds_p->silhouette = SIL_BOTTOM;
  1245. ds_p->bsilheight = MAXINT;
  1246. // ds_p->sprbottomclip = negonearray;
  1247. }
  1248. if (frontsector->ceilingheight < backsector->ceilingheight)
  1249. {
  1250. ds_p->silhouette |= SIL_TOP;
  1251. ds_p->tsilheight = frontsector->ceilingheight;
  1252. }
  1253. else if (backsector->ceilingheight < viewz)
  1254. {
  1255. ds_p->silhouette |= SIL_TOP;
  1256. ds_p->tsilheight = MININT;
  1257. // ds_p->sprtopclip = screenheightarray;
  1258. }
  1259. if (backsector->ceilingheight <= frontsector->floorheight)
  1260. {
  1261. ds_p->sprbottomclip = negonearray;
  1262. ds_p->bsilheight = MAXINT;
  1263. ds_p->silhouette |= SIL_BOTTOM;
  1264. }
  1265. if (backsector->floorheight >= frontsector->ceilingheight)
  1266. {
  1267. ds_p->sprtopclip = screenheightarray;
  1268. ds_p->tsilheight = MININT;
  1269. ds_p->silhouette |= SIL_TOP;
  1270. }
  1271. //SoM: 3/25/2000: This code fixes an automap bug that didn't check
  1272. // frontsector->ceiling and backsector->floor to see if a door was closed.
  1273. // Without the following code, sprites get displayed behind closed doors.
  1274. {
  1275. if (doorclosed || backsector->ceilingheight <= frontsector->floorheight)
  1276. {
  1277. ds_p->sprbottomclip = negonearray;
  1278. ds_p->bsilheight = MAXINT;
  1279. ds_p->silhouette |= SIL_BOTTOM;
  1280. }
  1281. if (doorclosed || backsector->floorheight >= frontsector->ceilingheight)
  1282. { // killough 1/17/98, 2/8/98
  1283. ds_p->sprtopclip = screenheightarray;
  1284. ds_p->tsilheight = MININT;
  1285. ds_p->silhouette |= SIL_TOP;
  1286. }
  1287. }
  1288. worldhigh = backsector->ceilingheight - viewz;
  1289. worldlow = backsector->floorheight - viewz;
  1290. // hack to allow height changes in outdoor areas
  1291. if (frontsector->ceilingpic == skyflatnum
  1292. && backsector->ceilingpic == skyflatnum)
  1293. {
  1294. worldtop = worldhigh;
  1295. }
  1296. if (worldlow != worldbottom
  1297. || backsector->floorpic != frontsector->floorpic
  1298. || backsector->lightlevel != frontsector->lightlevel
  1299. //SoM: 3/22/2000: Check floor x and y offsets.
  1300. || backsector->floor_xoffs != frontsector->floor_xoffs
  1301. || backsector->floor_yoffs != frontsector->floor_yoffs
  1302. || backsector->floorpic_angle != frontsector->floorpic_angle
  1303. //SoM: 3/22/2000: Prevents bleeding.
  1304. || frontsector->heightsec != -1
  1305. || backsector->floorlightsec != frontsector->floorlightsec
  1306. //SoM: 4/3/2000: Check for colormaps
  1307. || frontsector->extra_colormap != backsector->extra_colormap
  1308. || (frontsector->ffloors != backsector->ffloors && frontsector->tag != backsector->tag))
  1309. {
  1310. markfloor = true;
  1311. }
  1312. else
  1313. {
  1314. // same plane on both sides
  1315. markfloor = false;
  1316. }
  1317. if (worldhigh != worldtop
  1318. || backsector->ceilingpic != frontsector->ceilingpic
  1319. || backsector->lightlevel != frontsector->lightlevel
  1320. //SoM: 3/22/2000: Check floor x and y offsets.
  1321. || backsector->ceiling_xoffs != frontsector->ceiling_xoffs
  1322. || backsector->ceiling_yoffs != frontsector->ceiling_yoffs
  1323. || backsector->ceilingpic_angle != frontsector->ceilingpic_angle
  1324. //SoM: 3/22/2000: Prevents bleeding.
  1325. || (frontsector->heightsec != -1 && frontsector->ceilingpic != skyflatnum)
  1326. || backsector->floorlightsec != frontsector->floorlightsec
  1327. //SoM: 4/3/2000: Check for colormaps
  1328. || frontsector->extra_colormap != backsector->extra_colormap
  1329. || (frontsector->ffloors != backsector->ffloors && frontsector->tag != backsector->tag))
  1330. {
  1331. markceiling = true;
  1332. }
  1333. else
  1334. {
  1335. // same plane on both sides
  1336. markceiling = false;
  1337. }
  1338. if (backsector->ceilingheight <= frontsector->floorheight
  1339. || backsector->floorheight >= frontsector->ceilingheight)
  1340. {
  1341. // closed door
  1342. markceiling = markfloor = true;
  1343. }
  1344. // check TOP TEXTURE
  1345. if (worldhigh < worldtop)
  1346. {
  1347. // top texture
  1348. toptexture = texturetranslation[sidedef->toptexture];
  1349. if (linedef->flags & ML_DONTPEGTOP)
  1350. {
  1351. // top of texture at top
  1352. rw_toptexturemid = worldtop;
  1353. }
  1354. else
  1355. {
  1356. vtop = backsector->ceilingheight + textureheight[sidedef->toptexture];
  1357. // bottom of texture
  1358. rw_toptexturemid = vtop - viewz;
  1359. }
  1360. }
  1361. // check BOTTOM TEXTURE
  1362. if (worldlow > worldbottom) //seulement si VISIBLE!!!
  1363. {
  1364. // bottom texture
  1365. bottomtexture = texturetranslation[sidedef->bottomtexture];
  1366. if (linedef->flags & ML_DONTPEGBOTTOM)
  1367. {
  1368. // bottom of texture at bottom
  1369. // top of texture at top
  1370. rw_bottomtexturemid = worldtop;
  1371. }
  1372. else // top of texture at top
  1373. rw_bottomtexturemid = worldlow;
  1374. }
  1375. rw_toptexturemid += sidedef->rowoffset;
  1376. rw_bottomtexturemid += sidedef->rowoffset;
  1377. // allocate space for masked texture tables
  1378. if (frontsector && backsector && frontsector->tag != backsector->tag && (backsector->ffloors || frontsector->ffloors))
  1379. {
  1380. ffloor_t *rover;
  1381. ffloor_t *r2;
  1382. fixed_t lowcut, highcut;
  1383. //markceiling = markfloor = true;
  1384. maskedtexture = true;
  1385. ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x;
  1386. lastopening += rw_stopx - rw_x;
  1387. lowcut = frontsector->floorheight > backsector->floorheight ? frontsector->floorheight : backsector->floorheight;
  1388. highcut = frontsector->ceilingheight < backsector->ceilingheight ? frontsector->ceilingheight : backsector->ceilingheight;
  1389. if (frontsector->ffloors && backsector->ffloors)
  1390. {
  1391. i = 0;
  1392. for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next)
  1393. {
  1394. if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS))
  1395. continue;
  1396. if (rover->flags & FF_INVERTSIDES)
  1397. continue;
  1398. if (*rover->topheight < lowcut || *rover->bottomheight > highcut)
  1399. continue;
  1400. for (r2 = frontsector->ffloors; r2; r2 = r2->next)
  1401. {
  1402. if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)
  1403. || *r2->topheight < lowcut || *r2->bottomheight > highcut)
  1404. continue;
  1405. if (rover->flags & FF_EXTRA)
  1406. {
  1407. if (!(r2->flags & FF_CUTEXTRA))
  1408. continue;
  1409. if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG)))
  1410. continue;
  1411. }
  1412. else
  1413. {
  1414. if (!(r2->flags & FF_CUTSOLIDS))
  1415. continue;
  1416. }
  1417. if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight)
  1418. continue;
  1419. break;
  1420. }
  1421. if (r2)
  1422. continue;
  1423. ds_p->thicksides[i] = rover;
  1424. i++;
  1425. }
  1426. for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next)
  1427. {
  1428. if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS))
  1429. continue;
  1430. if (!(rover->flags & FF_ALLSIDES))
  1431. continue;
  1432. if (*rover->topheight < lowcut || *rover->bottomheight > highcut)
  1433. continue;
  1434. for (r2 = backsector->ffloors; r2; r2 = r2->next)
  1435. {
  1436. if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)
  1437. || *r2->topheight < lowcut || *r2->bottomheight > highcut)
  1438. continue;
  1439. if (rover->flags & FF_EXTRA)
  1440. {
  1441. if (!(r2->flags & FF_CUTEXTRA))
  1442. continue;
  1443. if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG)))
  1444. continue;
  1445. }
  1446. else
  1447. {
  1448. if (!(r2->flags & FF_CUTSOLIDS))
  1449. continue;
  1450. }
  1451. if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight)
  1452. continue;
  1453. break;
  1454. }
  1455. if (r2)
  1456. continue;
  1457. ds_p->thicksides[i] = rover;
  1458. i++;
  1459. }
  1460. }
  1461. else if (backsector->ffloors)
  1462. {
  1463. for (rover = backsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next)
  1464. {
  1465. if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || rover->flags & FF_INVERTSIDES)
  1466. continue;
  1467. if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight)
  1468. continue;
  1469. ds_p->thicksides[i] = rover;
  1470. i++;
  1471. }
  1472. }
  1473. else if (frontsector->ffloors)
  1474. {
  1475. for (rover = frontsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next)
  1476. {
  1477. if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_ALLSIDES))
  1478. continue;
  1479. if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight)
  1480. continue;
  1481. if (*rover->topheight <= backsector->floorheight || *rover->bottomheight >= backsector->ceilingheight)
  1482. continue;
  1483. ds_p->thicksides[i] = rover;
  1484. i++;
  1485. }
  1486. }
  1487. ds_p->numthicksides = numthicksides = i;
  1488. }
  1489. if (sidedef->midtexture)
  1490. {
  1491. // masked midtexture
  1492. if (!ds_p->thicksidecol)
  1493. {
  1494. ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x;
  1495. lastopening += rw_stopx - rw_x;
  1496. }
  1497. else
  1498. ds_p->maskedtexturecol = ds_p->thicksidecol;
  1499. maskedtexture = true;
  1500. }
  1501. }
  1502. // calculate rw_offset (only needed for textured lines)
  1503. segtextured = midtexture || toptexture || bottomtexture || maskedtexture || (numthicksides > 0);
  1504. if (segtextured)
  1505. {
  1506. offsetangle = rw_normalangle-rw_angle1;
  1507. if (offsetangle > ANG180)
  1508. offsetangle = -(signed)offsetangle;
  1509. if (offsetangle > ANG90)
  1510. offsetangle = ANG90;
  1511. sineval = FINESINE(offsetangle >>ANGLETOFINESHIFT);
  1512. rw_offset = FixedMul (hyp, sineval);
  1513. if (rw_normalangle-rw_angle1 < ANG180)
  1514. rw_offset = -rw_offset;
  1515. /// don't use texture offset for splats
  1516. rw_offset2 = rw_offset + curline->offset;
  1517. rw_offset += sidedef->textureoffset + curline->offset;
  1518. rw_centerangle = ANG90 + viewangle - rw_normalangle;
  1519. // calculate light table
  1520. // use different light tables
  1521. // for horizonta…

Large files files are truncated, but you can click here to view the full file