PageRenderTime 86ms CodeModel.GetById 44ms RepoModel.GetById 0ms app.codeStats 1ms

/src/r_segs.c

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

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