PageRenderTime 29ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/legacy/trunk/video/r_segs.cpp

#
C++ | 2154 lines | 1542 code | 353 blank | 259 comment | 520 complexity | c6d0a1409b06ea63bd825b224856eeb5 MD5 | raw file
Possible License(s): GPL-2.0
  1. // Emacs style mode select -*- C++ -*-
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id: r_segs.cpp 482 2007-07-21 17:19:52Z smite-meister $
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. // Copyright (C) 1998-2007 by DooM Legacy Team.
  8. //
  9. // This program is free software; you can redistribute it and/or
  10. // modify it under the terms of the GNU General Public License
  11. // as published by the Free Software Foundation; either version 2
  12. // of the License, or (at your option) any later version.
  13. //
  14. // This program is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. // GNU General Public License for more details.
  18. //
  19. //-----------------------------------------------------------------------------
  20. /// \file
  21. /// \brief
  22. /// All the clipping: columns, horizontal spans, sky columns.
  23. /// Rendering of vertical surfaces.
  24. #include "doomdef.h"
  25. #include "command.h"
  26. #include "cvars.h"
  27. #include "console.h" //Con_clipviewtop
  28. #include "r_render.h"
  29. #include "r_data.h"
  30. #include "r_bsp.h"
  31. #include "r_draw.h"
  32. #include "r_plane.h"
  33. #include "r_sky.h"
  34. #include "r_splats.h"
  35. #include "r_things.h"
  36. #include "p_spec.h" // linedef special types
  37. #include "w_wad.h"
  38. #include "z_zone.h"
  39. #ifdef OLDWATER
  40. extern fixed_t waterheight;
  41. static bool markwater;
  42. static fixed_t waterz;
  43. static fixed_t waterfrac;
  44. static fixed_t waterstep;
  45. #endif
  46. // FIXME HACK
  47. #define FixedMul(x,y) ((x)*(y))
  48. // OPTIMIZE: closed two sided lines as single sided
  49. // True if any of the segs textures might be visible.
  50. static bool segtextured;
  51. static bool markfloor; // False if the back side is the same plane.
  52. static bool markceiling;
  53. static bool maskedtexture;
  54. static Material* toptexture;
  55. static Material* bottomtexture;
  56. static Material* midtexture;
  57. static int numthicksides;
  58. //static short* thicksidecol;
  59. angle_t rw_normalangle; // normal angle for the current segment
  60. // angle to line origin
  61. int rw_angle1;
  62. fixed_t rw_distance;
  63. //
  64. // regular wall
  65. //
  66. static int rw_x;
  67. static int rw_stopx;
  68. static angle_t rw_centerangle;
  69. static fixed_t rw_offset;
  70. static fixed_t rw_offset2; // for splats
  71. static fixed_t rw_scale;
  72. static fixed_t rw_scalestep;
  73. /// these are in world coordinates
  74. static fixed_t rw_midtexturemid;
  75. static fixed_t rw_toptexturemid;
  76. static fixed_t rw_bottomtexturemid;
  77. static fixed_t worldtop;
  78. static fixed_t worldbottom;
  79. static fixed_t worldhigh;
  80. static fixed_t worldlow;
  81. static fixed_t pixhigh;
  82. static fixed_t pixlow;
  83. static fixed_t pixhighstep;
  84. static fixed_t pixlowstep;
  85. static fixed_t topfrac;
  86. static fixed_t topstep;
  87. static fixed_t bottomfrac;
  88. static fixed_t bottomstep;
  89. int *walllights;
  90. short* maskedtexturecol;
  91. // ==========================================================================
  92. // R_Splats Wall Splats Drawer
  93. // ==========================================================================
  94. #define BORIS_FIX
  95. #ifdef BORIS_FIX
  96. static short last_ceilingclip[MAXVIDWIDTH];
  97. static short last_floorclip[MAXVIDWIDTH];
  98. #endif
  99. static void R_DrawSplatColumn (column_t* column)
  100. {
  101. fixed_t topscreen, bottomscreen;
  102. fixed_t basetexturemid = dc_texturemid;
  103. for ( ; column->topdelta != 0xff ; )
  104. {
  105. // calculate unclipped screen coordinates
  106. // for post
  107. topscreen = sprtopscreen + spryscale*column->topdelta;
  108. bottomscreen = topscreen + spryscale*column->length;
  109. dc_yl = (topscreen + 1 - fixed_epsilon).floor();
  110. dc_yh = (bottomscreen - fixed_epsilon).floor();
  111. #ifndef BORIS_FIX
  112. if (dc_yh >= mfloorclip[dc_x])
  113. dc_yh = mfloorclip[dc_x] - 1;
  114. if (dc_yl < mceilingclip[dc_x])
  115. dc_yl = mceilingclip[dc_x] + 1;
  116. #else
  117. if (dc_yh >= last_floorclip[dc_x])
  118. dc_yh = last_floorclip[dc_x]-1;
  119. if (dc_yl <= last_ceilingclip[dc_x])
  120. dc_yl = last_ceilingclip[dc_x]+1;
  121. #endif
  122. if (dc_yl <= dc_yh)
  123. {
  124. dc_source = (byte *)column + 3;
  125. dc_texturemid = basetexturemid - column->topdelta;
  126. //CONS_Printf("l %d h %d %d\n",dc_yl,dc_yh, column->length);
  127. // Drawn by either R_DrawColumn
  128. // or (SHADOW) R_DrawFuzzColumn.
  129. colfunc ();
  130. }
  131. column = (column_t *)( (byte *)column + column->length + 4);
  132. }
  133. dc_texturemid = basetexturemid;
  134. }
  135. void Rend::R_DrawWallSplats()
  136. {
  137. wallsplat_t *splat = linedef->splats;
  138. #ifdef PARANOIA
  139. if (!splat)
  140. I_Error ("R_DrawWallSplats: splat is NULL");
  141. #endif
  142. //seg_t *seg = ds_p->curline;
  143. // draw all splats from the line that touches the range of the seg
  144. for ( ; splat ; splat=splat->next)
  145. {
  146. angle_t angle1 = R_PointToAngle (splat->v1.x, splat->v1.y);
  147. angle_t angle2 = R_PointToAngle (splat->v2.x, splat->v2.y);
  148. angle1 = (angle1-viewangle+ANG90)>>ANGLETOFINESHIFT;
  149. angle2 = (angle2-viewangle+ANG90)>>ANGLETOFINESHIFT;
  150. #if 0
  151. if (angle1>clipangle)
  152. angle1=clipangle;
  153. if (angle2>clipangle)
  154. angle2=clipangle;
  155. if ((int)angle1<-(int)clipangle)
  156. angle1=-clipangle;
  157. if ((int)angle2<-(int)clipangle)
  158. angle2=-clipangle;
  159. #else
  160. // BP: out of the viewangletox lut, TODO clip it to the screen
  161. if( angle1 > FINEANGLES/2 || angle2 > FINEANGLES/2)
  162. continue;
  163. #endif
  164. int x1 = viewangletox[angle1];
  165. int x2 = viewangletox[angle2];
  166. if (x1 >= x2)
  167. continue; // does not cross a pixel
  168. // splat is not in this seg range
  169. if (x2 < ds_p->x1 || x1 > ds_p->x2)
  170. continue;
  171. if (x1 < ds_p->x1)
  172. x1 = ds_p->x1;
  173. if (x2 > ds_p->x2)
  174. x2 = ds_p->x2;
  175. if( x2<=x1 )
  176. continue;
  177. // calculate incremental stepping values for texture edges
  178. rw_scalestep = ds_p->scalestep;
  179. spryscale = ds_p->scale1 + (x1 - ds_p->x1)*rw_scalestep;
  180. mfloorclip = floorclip;
  181. mceilingclip = ceilingclip;
  182. // clip splat range to seg range left
  183. /*if (x1 < ds_p->x1)
  184. {
  185. spryscale += (rw_scalestep * (ds_p->x1 - x1));
  186. x1 = ds_p->x1;
  187. }*/
  188. // clip splat range to seg range right
  189. // SoM: This is set allready. THIS IS WHAT WAS CAUSING PROBLEMS WITH
  190. // BOOM WATER!
  191. // frontsector = ds_p->curline->frontsector;
  192. Material *mat = splat->mat;
  193. Material::TextureRef &tr = mat->tex[0];
  194. fixed_t world_texturemid = splat->top + (0.5 * tr.worldheight) - viewz;
  195. if (splat->yoffset)
  196. world_texturemid += *splat->yoffset;
  197. sprtopscreen = centeryfrac - (world_texturemid * spryscale);
  198. // set drawing mode
  199. switch (splat->flags & SPLATDRAWMODE_MASK)
  200. {
  201. case SPLATDRAWMODE_OPAQUE:
  202. colfunc = basecolfunc;
  203. break;
  204. case SPLATDRAWMODE_TRANS:
  205. if( cv_translucency.value == 0 )
  206. colfunc = basecolfunc;
  207. else
  208. {
  209. dc_transmap = transtables[tr_transmed-1];
  210. colfunc = fuzzcolfunc;
  211. }
  212. break;
  213. case SPLATDRAWMODE_SHADE:
  214. colfunc = shadecolfunc;
  215. break;
  216. }
  217. if (fixedcolormap)
  218. dc_colormap = base_colormap + fixedcolormap;
  219. dc_texheight = 0;
  220. dc_texturemid = world_texturemid * tr.yscale;
  221. // draw the columns
  222. for (dc_x = x1 ; dc_x <= x2 ; dc_x++,spryscale += rw_scalestep)
  223. {
  224. dc_iscale.setvalue(0xffffffffu / unsigned(spryscale.value()));
  225. dc_iscale *= tr.yscale;
  226. if (!fixedcolormap)
  227. {
  228. if (frontsector->extra_colormap)
  229. dc_colormap = frontsector->extra_colormap->colormap;
  230. else
  231. dc_colormap = base_colormap;
  232. unsigned index = (spryscale << LIGHTSCALESHIFT).floor();
  233. if (index >= MAXLIGHTSCALE )
  234. index = MAXLIGHTSCALE-1;
  235. dc_colormap += walllights[index];
  236. }
  237. sprtopscreen = centeryfrac - (world_texturemid * spryscale);
  238. // find column of tex, from perspective
  239. int angle = (rw_centerangle + xtoviewangle[dc_x])>>ANGLETOFINESHIFT;
  240. fixed_t texturecolumn = rw_offset2 - splat->offset - (finetangent[angle] * rw_distance);
  241. //texturecolumn &= 7;
  242. //DEBUG
  243. // FIXME !
  244. // CONS_Printf ("%.2f width %d, %d[x], %.1f[off]-%.1f[soff]-tg(%d)=%.1f*%.1f[d] = %.1f\n",
  245. // FIXED_TO_FLOAT(texturecolumn), tex->width,
  246. // dc_x,FIXED_TO_FLOAT(rw_offset2),FIXED_TO_FLOAT(splat->offset),angle,FIXED_TO_FLOAT(finetangent[angle]),FIXED_TO_FLOAT(rw_distance),FIXED_TO_FLOAT(FixedMul(finetangent[angle],rw_distance)));
  247. if (texturecolumn < 0 || texturecolumn >= tr.worldwidth)
  248. continue;
  249. // draw the texture
  250. column_t *col = mat->GetMaskedColumn(texturecolumn);
  251. R_DrawSplatColumn(col);
  252. }
  253. } // next splat
  254. colfunc = basecolfunc;
  255. }
  256. // ==========================================================================
  257. // R_RenderMaskedSegRange
  258. // ==========================================================================
  259. // If we have a multi-patch texture on a 2sided wall (rare) then we draw
  260. // it using R_DrawColumn, else we draw it using R_DrawMaskedColumn, this
  261. // way we don't have to store extra post_t info with each column for
  262. // multi-patch textures. They are not normally needed as multi-patch
  263. // textures don't have holes in it. At least not for now.
  264. static int column2s_length; // column->length : for multi-patch on 2sided wall = texture->height
  265. void R_Render2sidedMultiPatchColumn(column_t *column)
  266. {
  267. fixed_t topscreen = sprtopscreen; // + column->topdelta / dc_iscale; topdelta is 0 for the wall
  268. fixed_t bottomscreen = topscreen + column2s_length / dc_iscale;
  269. dc_yl = 1 + (topscreen - fixed_epsilon).floor();
  270. dc_yh = (bottomscreen - fixed_epsilon).floor();
  271. if (windowtop != fixed_t::FMAX && windowbottom != fixed_t::FMAX)
  272. {
  273. dc_yl = windowtop.floor() + 1;
  274. dc_yh = (windowbottom - fixed_epsilon).floor();
  275. }
  276. {
  277. if (dc_yh >= mfloorclip[dc_x])
  278. dc_yh = mfloorclip[dc_x]-1;
  279. if (dc_yl <= mceilingclip[dc_x])
  280. dc_yl = mceilingclip[dc_x]+1;
  281. }
  282. if (dc_yl >= vid.height || dc_yh < 0)
  283. return;
  284. if (dc_yl <= dc_yh)
  285. {
  286. dc_source = (byte *)column;
  287. colfunc();
  288. }
  289. }
  290. void Rend::R_RenderMaskedSegRange(drawseg_t *ds, int x1, int x2)
  291. {
  292. int i;
  293. void (*colfunc_2s) (column_t*);
  294. // Calculate light table.
  295. // Use different light tables
  296. // for horizontal / vertical / diagonal. Diagonal?
  297. // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
  298. curline = ds->curline;
  299. frontsector = curline->frontsector;
  300. backsector = curline->backsector;
  301. windowbottom = windowtop = sprbotscreen = fixed_t::FMAX;
  302. // translucent?
  303. line_t *ldef = curline->linedef;
  304. if (ldef->transmap != -1)
  305. {
  306. dc_transmap = transtables[ldef->transmap];
  307. colfunc = fuzzcolfunc;
  308. }
  309. else if (ldef->special == LINE_LEGACY_EXT && ldef->args[0] == LINE_LEGACY_RENDERER) // HACK fog sheet
  310. {
  311. colfunc = R_DrawFogColumn_8;
  312. windowtop = frontsector->ceilingheight;
  313. windowbottom = frontsector->floorheight;
  314. }
  315. else
  316. colfunc = basecolfunc;
  317. //SoM: Moved these up here so they are available for my lightlist calculations
  318. rw_scalestep = ds->scalestep;
  319. spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
  320. Material *mat = curline->sidedef->midtexture;
  321. Material::TextureRef &tr = mat->tex[0];
  322. //faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures
  323. // are not stored per-column with post info anymore in Doom Legacy
  324. bool masked = tr.t->Masked();
  325. if (masked)
  326. colfunc_2s = R_DrawMaskedColumn; //render the usual 2sided single-patch packed texture
  327. else
  328. {
  329. colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info)
  330. column2s_length = tr.t->height;
  331. }
  332. dc_numlights = 0;
  333. int lightnum;
  334. if(frontsector->numlights)
  335. {
  336. dc_numlights = frontsector->numlights;
  337. if(dc_numlights >= dc_maxlights)
  338. {
  339. dc_maxlights = dc_numlights;
  340. dc_lightlist = (r_lightlist_t *)realloc(dc_lightlist, sizeof(r_lightlist_t) * dc_maxlights);
  341. }
  342. for(i = 0; i < dc_numlights; i++)
  343. {
  344. dc_lightlist[i].height = (centeryfrac) - FixedMul((frontsector->lightlist[i].height - viewz), spryscale);
  345. dc_lightlist[i].heightstep = -(rw_scalestep * (frontsector->lightlist[i].height - viewz));
  346. dc_lightlist[i].lightlevel = *frontsector->lightlist[i].lightlevel;
  347. dc_lightlist[i].extra_colormap = frontsector->lightlist[i].extra_colormap;
  348. dc_lightlist[i].flags = frontsector->lightlist[i].caster ? frontsector->lightlist[i].caster->flags : 0;
  349. }
  350. }
  351. else
  352. {
  353. if(colfunc == fuzzcolfunc)
  354. {
  355. if(frontsector->extra_colormap && frontsector->extra_colormap->fog)
  356. lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
  357. else
  358. lightnum = LIGHTLEVELS-1;
  359. }
  360. else if(colfunc == R_DrawFogColumn_8)
  361. lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
  362. else
  363. lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight;
  364. if (colfunc == R_DrawFogColumn_8 || (frontsector->extra_colormap && frontsector->extra_colormap->fog));
  365. else if (curline->v1->y == curline->v2->y)
  366. lightnum--;
  367. else if (curline->v1->x == curline->v2->x)
  368. lightnum++;
  369. if (lightnum < 0)
  370. walllights = scalelight[0];
  371. else if (lightnum >= LIGHTLEVELS)
  372. walllights = scalelight[LIGHTLEVELS-1];
  373. else
  374. walllights = scalelight[lightnum];
  375. }
  376. maskedtexturecol = ds->maskedtexturecol;
  377. mfloorclip = ds->sprbottomclip;
  378. mceilingclip = ds->sprtopclip;
  379. dc_texheight = tr.t->height;
  380. fixed_t world_texturemid;
  381. if (curline->linedef->flags & ML_DONTPEGBOTTOM)
  382. {
  383. world_texturemid = frontsector->floorheight > backsector->floorheight
  384. ? frontsector->floorheight : backsector->floorheight;
  385. world_texturemid += tr.worldheight;
  386. }
  387. else
  388. {
  389. world_texturemid =frontsector->ceilingheight<backsector->ceilingheight
  390. ? frontsector->ceilingheight : backsector->ceilingheight;
  391. }
  392. world_texturemid += -viewz + curline->sidedef->rowoffset;
  393. dc_texturemid = world_texturemid * tr.yscale;
  394. if (fixedcolormap)
  395. dc_colormap = base_colormap + fixedcolormap;
  396. // draw the columns
  397. for (dc_x = x1 ; dc_x <= x2 ; dc_x++)
  398. {
  399. // calculate lighting
  400. if (maskedtexturecol[dc_x] != MAXSHORT)
  401. {
  402. dc_iscale.setvalue(0xffffffffu / unsigned(spryscale.value()));
  403. dc_iscale *= tr.yscale;
  404. // draw the texture
  405. column_t *col;
  406. if (masked)
  407. col = mat->GetMaskedColumn(maskedtexturecol[dc_x]);
  408. else
  409. col = (column_t *)mat->GetColumn(maskedtexturecol[dc_x]); // HACK
  410. #warning GetColumn should get a fixed_t param
  411. unsigned index;
  412. if(dc_numlights)
  413. {
  414. sprbotscreen = fixed_t::FMAX;
  415. sprtopscreen = windowtop = centeryfrac - (world_texturemid * spryscale);
  416. fixed_t realbot = windowbottom = tr.worldheight*spryscale + sprtopscreen;
  417. for(i = 0; i < dc_numlights; i++)
  418. {
  419. int lightnum;
  420. if(dc_lightlist[i].flags & FF_FOG || (dc_lightlist[i].extra_colormap && dc_lightlist[i].extra_colormap->fog))
  421. lightnum = (dc_lightlist[i].lightlevel >> LIGHTSEGSHIFT);
  422. else if(colfunc == fuzzcolfunc)
  423. lightnum = LIGHTLEVELS-1;
  424. else
  425. lightnum = (dc_lightlist[i].lightlevel >> LIGHTSEGSHIFT)+extralight;
  426. if((dc_lightlist[i].flags & FF_NOSHADE))
  427. continue;
  428. if (dc_lightlist[i].extra_colormap && dc_lightlist[i].extra_colormap->fog);
  429. else if (curline->v1->y == curline->v2->y)
  430. lightnum--;
  431. else if (curline->v1->x == curline->v2->x)
  432. lightnum++;
  433. int *xwalllights;
  434. if (lightnum < 0)
  435. xwalllights = scalelight[0];
  436. else if (lightnum >= LIGHTLEVELS)
  437. xwalllights = scalelight[LIGHTLEVELS-1];
  438. else
  439. xwalllights = scalelight[lightnum];
  440. index = (spryscale << LIGHTSCALESHIFT).floor();
  441. if (index >= MAXLIGHTSCALE )
  442. index = MAXLIGHTSCALE-1;
  443. if(dc_lightlist[i].extra_colormap && !fixedcolormap)
  444. dc_lightlist[i].rcolormap = dc_lightlist[i].extra_colormap->colormap + xwalllights[index];
  445. else if (!fixedcolormap)
  446. dc_lightlist[i].rcolormap = base_colormap + xwalllights[index];
  447. else
  448. dc_lightlist[i].rcolormap = base_colormap + fixedcolormap;
  449. dc_lightlist[i].height += dc_lightlist[i].heightstep;
  450. fixed_t height = dc_lightlist[i].height;
  451. if(height <= windowtop)
  452. {
  453. dc_colormap = dc_lightlist[i].rcolormap;
  454. continue;
  455. }
  456. windowbottom = height;
  457. if(windowbottom >= realbot)
  458. {
  459. windowbottom = realbot;
  460. colfunc_2s (col);
  461. for(i++ ; i < dc_numlights; i++)
  462. dc_lightlist[i].height += dc_lightlist[i].heightstep;
  463. continue;
  464. }
  465. colfunc_2s (col);
  466. windowtop = windowbottom + 1;
  467. dc_colormap = dc_lightlist[i].rcolormap;
  468. }
  469. windowbottom = realbot;
  470. if(windowtop < windowbottom)
  471. colfunc_2s (col);
  472. spryscale += rw_scalestep;
  473. continue;
  474. }
  475. // calculate lighting
  476. if (!fixedcolormap)
  477. {
  478. if (frontsector->extra_colormap)
  479. dc_colormap = frontsector->extra_colormap->colormap;
  480. else
  481. dc_colormap = base_colormap;
  482. index = (spryscale << LIGHTSCALESHIFT).floor();
  483. if (index >= MAXLIGHTSCALE )
  484. index = MAXLIGHTSCALE-1;
  485. dc_colormap += walllights[index];
  486. }
  487. sprtopscreen = centeryfrac - (world_texturemid * spryscale);
  488. // draw the texture
  489. colfunc_2s(col);
  490. }
  491. spryscale += rw_scalestep;
  492. }
  493. colfunc = basecolfunc;
  494. }
  495. //
  496. // R_RenderThickSideRange
  497. // Renders all the thick sides in the given range.
  498. void Rend::R_RenderThickSideRange(drawseg_t *ds, int x1, int x2, ffloor_t *ffloor)
  499. {
  500. unsigned index;
  501. int i;
  502. fixed_t bottombounds = viewheight;
  503. fixed_t topbounds = con_clipviewtop - 1;
  504. void (*colfunc_2s) (column_t*);
  505. Material *mat = ffloor->master->sideptr[0]->midtexture;
  506. Material::TextureRef &tr = mat->tex[0];
  507. // Calculate light table.
  508. // Use different light tables
  509. // for horizontal / vertical / diagonal. Diagonal?
  510. // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
  511. curline = ds->curline;
  512. backsector = ffloor->target;
  513. frontsector = curline->frontsector == ffloor->target ? curline->backsector : curline->frontsector;
  514. colfunc = basecolfunc;
  515. if (ffloor->flags & FF_TRANSLUCENT)
  516. {
  517. dc_transmap = transtables[0]; // get first transtable 50/50
  518. colfunc = fuzzcolfunc;
  519. }
  520. else if(ffloor->flags & FF_FOG)
  521. colfunc = R_DrawFogColumn_8;
  522. //SoM: Moved these up here so they are available for my lightlist calculations
  523. rw_scalestep = ds->scalestep;
  524. spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
  525. dc_numlights = 0;
  526. if(frontsector->numlights && frontsector == curline->backsector)
  527. {
  528. dc_numlights = frontsector->numlights;
  529. if(dc_numlights > dc_maxlights)
  530. {
  531. dc_maxlights = dc_numlights;
  532. dc_lightlist = (r_lightlist_t *)realloc(dc_lightlist, sizeof(r_lightlist_t) * dc_maxlights);
  533. }
  534. for(i = 0; i < dc_numlights; i++)
  535. {
  536. dc_lightlist[i].heightstep = -FixedMul (rw_scalestep, (frontsector->lightlist[i].height - viewz));
  537. dc_lightlist[i].height = (centeryfrac) - FixedMul((frontsector->lightlist[i].height - viewz), spryscale) - dc_lightlist[i].heightstep;
  538. if(frontsector->lightlist[i].caster)
  539. {
  540. if(frontsector->lightlist[i].caster->flags & FF_CUTLEVEL)
  541. {
  542. dc_lightlist[i].botheightstep = -FixedMul (rw_scalestep, (*frontsector->lightlist[i].caster->bottomheight - viewz));
  543. dc_lightlist[i].botheight = (centeryfrac) - FixedMul((*frontsector->lightlist[i].caster->bottomheight - viewz), spryscale) - dc_lightlist[i].botheightstep;
  544. }
  545. dc_lightlist[i].flags = frontsector->lightlist[i].caster->flags;
  546. }
  547. else
  548. dc_lightlist[i].flags = 0;
  549. dc_lightlist[i].lightlevel = *frontsector->lightlist[i].lightlevel;
  550. dc_lightlist[i].extra_colormap = frontsector->lightlist[i].extra_colormap;
  551. }
  552. }
  553. else if(frontsector == curline->frontsector && curline->numlights)
  554. {
  555. dc_numlights = curline->numlights;
  556. if(dc_numlights > dc_maxlights)
  557. {
  558. dc_maxlights = dc_numlights;
  559. dc_lightlist = (r_lightlist_t *)realloc(dc_lightlist, sizeof(r_lightlist_t) * dc_maxlights);
  560. }
  561. memcpy(dc_lightlist, curline->rlights, sizeof(r_lightlist_t) * dc_numlights);
  562. }
  563. else
  564. {
  565. int lightnum, templight;
  566. sector_t tempsec;
  567. //SoM: Get correct light level!
  568. if((frontsector->extra_colormap && frontsector->extra_colormap->fog))
  569. lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
  570. else if(ffloor->flags & FF_FOG)
  571. lightnum = (ffloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT);
  572. else if(colfunc == fuzzcolfunc)
  573. lightnum = LIGHTLEVELS-1;
  574. else
  575. lightnum = (R_FakeFlat(frontsector, &tempsec, &templight, &templight, false)
  576. ->lightlevel >> LIGHTSEGSHIFT)+extralight;
  577. if (ffloor->flags & FF_FOG || (frontsector->extra_colormap && frontsector->extra_colormap->fog));
  578. else if (curline->v1->y == curline->v2->y)
  579. lightnum--;
  580. else if (curline->v1->x == curline->v2->x)
  581. lightnum++;
  582. if (lightnum < 0)
  583. walllights = scalelight[0];
  584. else if (lightnum >= LIGHTLEVELS)
  585. walllights = scalelight[LIGHTLEVELS-1];
  586. else
  587. walllights = scalelight[lightnum];
  588. }
  589. maskedtexturecol = ds->thicksidecol;
  590. mfloorclip = ds->sprbottomclip;
  591. mceilingclip = ds->sprtopclip;
  592. fixed_t world_texturemid = *ffloor->topheight - viewz;
  593. fixed_t offsetvalue = ffloor->master->sideptr[0]->rowoffset;
  594. if(curline->linedef->flags & ML_DONTPEGBOTTOM)
  595. offsetvalue -= *ffloor->topheight - *ffloor->bottomheight;
  596. dc_texturemid = (world_texturemid + offsetvalue) * tr.yscale;
  597. dc_texheight = tr.t->height;
  598. if (fixedcolormap)
  599. dc_colormap = base_colormap + fixedcolormap;
  600. //faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures
  601. // are not stored per-column with post info anymore in Doom Legacy
  602. bool masked = tr.t->Masked();
  603. if (masked)
  604. colfunc_2s = R_DrawMaskedColumn; //render the usual 2sided single-patch packed texture
  605. else
  606. {
  607. colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info)
  608. column2s_length = tr.t->height;
  609. }
  610. // draw the columns
  611. for (dc_x = x1 ; dc_x <= x2 ; dc_x++)
  612. {
  613. if(maskedtexturecol[dc_x] != MAXSHORT)
  614. {
  615. dc_iscale.setvalue(0xffffffffu / unsigned(spryscale.value()));
  616. dc_iscale *= tr.yscale;
  617. column_t *col;
  618. if (masked)
  619. col = mat->GetMaskedColumn(maskedtexturecol[dc_x]);
  620. else
  621. col = (column_t *)mat->GetColumn(maskedtexturecol[dc_x]); // HACK
  622. #warning GetColumn should get a fixed_t param
  623. // SoM: New code does not rely on r_drawColumnShadowed_8 which
  624. // will (hopefully) put less strain on the stack.
  625. if (dc_numlights)
  626. {
  627. int *xwalllights;
  628. fixed_t height;
  629. fixed_t bheight = 0;
  630. int solid = 0;
  631. int lighteffect = 0;
  632. sprtopscreen = windowtop = (centeryfrac - FixedMul(world_texturemid, spryscale));
  633. sprbotscreen = windowbottom = FixedMul(*ffloor->topheight - *ffloor->bottomheight, spryscale) + sprtopscreen;
  634. // SoM: If column is out of range, why bother with it??
  635. if(windowbottom < topbounds || windowtop > bottombounds)
  636. {
  637. for(i = 0; i < dc_numlights; i++)
  638. {
  639. dc_lightlist[i].height += dc_lightlist[i].heightstep;
  640. if(dc_lightlist[i].flags & FF_CUTLEVEL)
  641. dc_lightlist[i].botheight += dc_lightlist[i].botheightstep;
  642. }
  643. spryscale += rw_scalestep;
  644. continue;
  645. }
  646. // draw the texture
  647. for(i = 0; i < dc_numlights; i++)
  648. {
  649. int lightnum;
  650. // Check if the current light effects the colormap/lightlevel
  651. lighteffect = !(dc_lightlist[i].flags & FF_NOSHADE);
  652. if(lighteffect)
  653. {
  654. if(ffloor->flags & FF_FOG || dc_lightlist[i].flags & FF_FOG || (dc_lightlist[i].extra_colormap && dc_lightlist[i].extra_colormap->fog))
  655. lightnum = (ffloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT);
  656. else
  657. lightnum = (dc_lightlist[i].lightlevel >> LIGHTSEGSHIFT)+extralight;
  658. if(ffloor->flags & FF_FOG || dc_lightlist[i].flags & FF_FOG || (dc_lightlist[i].extra_colormap && dc_lightlist[i].extra_colormap->fog));
  659. else if (curline->v1->y == curline->v2->y)
  660. lightnum--;
  661. else if (curline->v1->x == curline->v2->x)
  662. lightnum++;
  663. if (lightnum < 0)
  664. xwalllights = scalelight[0];
  665. else if (lightnum >= LIGHTLEVELS)
  666. xwalllights = scalelight[LIGHTLEVELS-1];
  667. else
  668. xwalllights = scalelight[lightnum];
  669. index = (spryscale << LIGHTSCALESHIFT).floor();
  670. if (index >= MAXLIGHTSCALE )
  671. index = MAXLIGHTSCALE-1;
  672. if (fixedcolormap)
  673. {
  674. dc_lightlist[i].rcolormap = base_colormap + fixedcolormap;
  675. }
  676. else if (ffloor->flags & FF_FOG)
  677. {
  678. if(ffloor->master->frontsector->extra_colormap)
  679. dc_lightlist[i].rcolormap = ffloor->master->frontsector->extra_colormap->colormap + xwalllights[index];
  680. else
  681. dc_lightlist[i].rcolormap = base_colormap + xwalllights[index];
  682. }
  683. else
  684. {
  685. if(dc_lightlist[i].extra_colormap)
  686. dc_lightlist[i].rcolormap = dc_lightlist[i].extra_colormap->colormap + xwalllights[index];
  687. else
  688. dc_lightlist[i].rcolormap = base_colormap + xwalllights[index];
  689. }
  690. }
  691. // Check if the current light can cut the current 3D floor.
  692. if(dc_lightlist[i].flags & FF_CUTSOLIDS && !(ffloor->flags & FF_EXTRA))
  693. solid = 1;
  694. else if(dc_lightlist[i].flags & FF_CUTEXTRA && ffloor->flags & FF_EXTRA)
  695. {
  696. if(dc_lightlist[i].flags & FF_EXTRA)
  697. {
  698. // The light is from an extra 3D floor... Check the flags so
  699. // there are no undesired cuts.
  700. if((dc_lightlist[i].flags & (FF_TRANSLUCENT|FF_FOG)) == (ffloor->flags & (FF_TRANSLUCENT|FF_FOG)))
  701. solid = 1;
  702. }
  703. else
  704. solid = 1;
  705. }
  706. else
  707. solid = 0;
  708. dc_lightlist[i].height += dc_lightlist[i].heightstep;
  709. height = dc_lightlist[i].height;
  710. if(solid)
  711. {
  712. dc_lightlist[i].botheight += dc_lightlist[i].botheightstep;
  713. bheight = dc_lightlist[i].botheight - 0.5f;
  714. }
  715. if(height <= windowtop)
  716. {
  717. if(lighteffect)
  718. dc_colormap = dc_lightlist[i].rcolormap;
  719. if(solid && windowtop < bheight)
  720. windowtop = bheight;
  721. continue;
  722. }
  723. windowbottom = height;
  724. if(windowbottom >= sprbotscreen)
  725. {
  726. windowbottom = sprbotscreen;
  727. colfunc_2s (col);
  728. for(i++ ; i < dc_numlights; i++)
  729. {
  730. dc_lightlist[i].height += dc_lightlist[i].heightstep;
  731. if(dc_lightlist[i].flags & FF_CUTLEVEL)
  732. dc_lightlist[i].botheight += dc_lightlist[i].botheightstep;
  733. }
  734. continue;
  735. }
  736. colfunc_2s (col);
  737. if(solid)
  738. windowtop = bheight;
  739. else
  740. windowtop = windowbottom + 1;
  741. if(lighteffect)
  742. dc_colormap = dc_lightlist[i].rcolormap;
  743. }
  744. windowbottom = sprbotscreen;
  745. if(windowtop < windowbottom)
  746. colfunc_2s (col);
  747. spryscale += rw_scalestep;
  748. continue;
  749. }
  750. // calculate lighting
  751. if (!fixedcolormap)
  752. {
  753. if (ffloor->flags & FF_FOG && ffloor->master->frontsector->extra_colormap)
  754. dc_colormap = ffloor->master->frontsector->extra_colormap->colormap;
  755. else if (frontsector->extra_colormap)
  756. dc_colormap = frontsector->extra_colormap->colormap;
  757. else
  758. dc_colormap = base_colormap;
  759. index = (spryscale << LIGHTSCALESHIFT).floor();
  760. if (index >= MAXLIGHTSCALE )
  761. index = MAXLIGHTSCALE-1;
  762. dc_colormap += walllights[index];
  763. }
  764. sprtopscreen = windowtop = (centeryfrac - (world_texturemid * spryscale));
  765. sprbotscreen = windowbottom = ((*ffloor->topheight - *ffloor->bottomheight) * spryscale) + sprtopscreen;
  766. // draw the texture
  767. colfunc_2s (col);
  768. spryscale += rw_scalestep;
  769. }
  770. }
  771. colfunc = basecolfunc;
  772. }
  773. //
  774. // R_RenderSegLoop
  775. // Draws zero, one, or two textures (and possibly a masked
  776. // texture) for walls.
  777. // Can draw or mark the starting pixel of floor and ceiling
  778. // textures.
  779. // CALLED: CORE LOOPING ROUTINE.
  780. //
  781. #define HEIGHTBITS 12
  782. #define HEIGHTUNIT (1<<HEIGHTBITS)
  783. void Rend::R_RenderSegLoop()
  784. {
  785. int i;
  786. for ( ; rw_x < rw_stopx ; rw_x++)
  787. {
  788. // mark floor / ceiling areas
  789. int yl = (topfrac.value() + HEIGHTUNIT-1)>>HEIGHTBITS;
  790. int bottom, top = ceilingclip[rw_x]+1;
  791. // no space above wall?
  792. if (yl < top)
  793. yl = top;
  794. if (markceiling)
  795. {
  796. bottom = yl-1;
  797. if (bottom >= floorclip[rw_x])
  798. bottom = floorclip[rw_x]-1;
  799. if (top <= bottom)
  800. {
  801. ceilingplane->top[rw_x] = top;
  802. ceilingplane->bottom[rw_x] = bottom;
  803. }
  804. }
  805. int yh = bottomfrac.value() >>HEIGHTBITS;
  806. bottom = floorclip[rw_x]-1;
  807. if (yh > bottom)
  808. yh = bottom;
  809. if (markfloor)
  810. {
  811. top = yh+1;
  812. if (top <= ceilingclip[rw_x])
  813. top = ceilingclip[rw_x]+1;
  814. if (top <= bottom && floorplane)
  815. {
  816. floorplane->top[rw_x] = top;
  817. floorplane->bottom[rw_x] = bottom;
  818. }
  819. }
  820. /*if (frontsector->ceilingportal)
  821. {
  822. top = ceilingclip[rw_x]+1;
  823. bottom = yl-1;
  824. if (bottom >= floorclip[rw_x])
  825. bottom = floorclip[rw_x]-1;
  826. if (top <= bottom)
  827. {
  828. dc_x = rw_x;
  829. dc_yl = top;
  830. dc_yh = bottom;
  831. dc_portal = frontsector->ceilingportal;
  832. R_StorePortalRange();
  833. }
  834. }*/
  835. #ifdef OLDWATER
  836. if (markwater)
  837. {
  838. //added:18-02-98:WATER!
  839. int yw = waterfrac>>HEIGHTBITS;
  840. // the markwater stuff...
  841. if (waterplane->height<viewz)
  842. {
  843. top = yw;
  844. bottom = waterclip[rw_x]-1;
  845. if (top <= ceilingclip[rw_x])
  846. top = ceilingclip[rw_x]+1;
  847. }
  848. else //view from under
  849. {
  850. top = waterclip[rw_x]+1;
  851. bottom = yw;
  852. if (bottom >= floorclip[rw_x])
  853. bottom = floorclip[rw_x]-1;
  854. }
  855. if (top <= bottom)
  856. {
  857. waterplane->top[rw_x] = top;
  858. waterplane->bottom[rw_x] = bottom;
  859. }
  860. // do it only if markwater else not needed!
  861. waterfrac += waterstep; //added:18-02-98:WATER!
  862. //dc_wcolormap = colormaps+(32<<8);
  863. }
  864. #endif
  865. if (numffloors)
  866. {
  867. firstseg->frontscale[rw_x] = frontscale[rw_x];
  868. for(i = 0; i < numffloors; i++)
  869. {
  870. if(ffloor[i].height < viewz)
  871. {
  872. int top_w = (ffloor[i].f_frac.value() >> HEIGHTBITS) + 1;
  873. int bottom_w = ffloor[i].f_clip[rw_x];
  874. if(top_w < ceilingclip[rw_x] + 1)
  875. top_w = ceilingclip[rw_x] + 1;
  876. if (bottom_w > floorclip[rw_x] - 1)
  877. bottom_w = floorclip[rw_x] - 1;
  878. if (top_w <= bottom_w)
  879. {
  880. ffloor[i].plane->top[rw_x] = top_w;
  881. ffloor[i].plane->bottom[rw_x] = bottom_w;
  882. }
  883. }
  884. else if (ffloor[i].height > viewz)
  885. {
  886. int top_w = ffloor[i].c_clip[rw_x] + 1;
  887. int bottom_w = (ffloor[i].f_frac.value() >> HEIGHTBITS);
  888. if (top_w < ceilingclip[rw_x] + 1)
  889. top_w = ceilingclip[rw_x] + 1;
  890. if (bottom_w > floorclip[rw_x] - 1)
  891. bottom_w = floorclip[rw_x] - 1;
  892. if (top_w <= bottom_w)
  893. {
  894. ffloor[i].plane->top[rw_x] = top_w;
  895. ffloor[i].plane->bottom[rw_x] = bottom_w;
  896. }
  897. }
  898. }
  899. }
  900. //SoM: Calculate offsets for Thick fake floors.
  901. // calculate texture offset
  902. int angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT;
  903. fixed_t texturecolumn = rw_offset - (finetangent[angle] * rw_distance);
  904. fixed_t base_iscale = 0;
  905. // texturecolumn and lighting are independent of wall tiers
  906. if (segtextured)
  907. {
  908. if (frontsector->extra_colormap && !fixedcolormap)
  909. dc_colormap = frontsector->extra_colormap->colormap;
  910. else
  911. dc_colormap = base_colormap;
  912. // calculate lighting
  913. int index = (rw_scale << LIGHTSCALESHIFT).floor();
  914. if (index >= MAXLIGHTSCALE )
  915. index = MAXLIGHTSCALE-1;
  916. dc_colormap += walllights[index];
  917. dc_x = rw_x;
  918. base_iscale.setvalue(0xffffffffu / unsigned(rw_scale.value()));
  919. }
  920. for (i = 0; i < dc_numlights; i++)
  921. {
  922. int lightnum;
  923. if((frontsector->lightlist[i].caster && frontsector->lightlist[i].caster->flags & FF_FOG && frontsector->lightlist[i].height != *frontsector->lightlist[i].caster->bottomheight) || (dc_lightlist[i].extra_colormap && dc_lightlist[i].extra_colormap->fog))
  924. lightnum = (dc_lightlist[i].lightlevel >> LIGHTSEGSHIFT);
  925. else
  926. lightnum = (dc_lightlist[i].lightlevel >> LIGHTSEGSHIFT)+extralight;
  927. if (dc_lightlist[i].extra_colormap);
  928. else if (curline->v1->y == curline->v2->y)
  929. lightnum--;
  930. else if (curline->v1->x == curline->v2->x)
  931. lightnum++;
  932. int *xwalllights;
  933. if (lightnum < 0)
  934. xwalllights = scalelight[0];
  935. else if (lightnum >= LIGHTLEVELS)
  936. xwalllights = scalelight[LIGHTLEVELS-1];
  937. else
  938. xwalllights = scalelight[lightnum];
  939. int index = (rw_scale << LIGHTSCALESHIFT).floor();
  940. if (index >= MAXLIGHTSCALE )
  941. index = MAXLIGHTSCALE-1;
  942. if(dc_lightlist[i].extra_colormap && !fixedcolormap)
  943. dc_lightlist[i].rcolormap = dc_lightlist[i].extra_colormap->colormap + xwalllights[index];
  944. else if(!fixedcolormap)
  945. dc_lightlist[i].rcolormap = base_colormap + xwalllights[index];
  946. else
  947. dc_lightlist[i].rcolormap = base_colormap + fixedcolormap;
  948. colfunc = R_DrawColumnShadowed_8;
  949. }
  950. /*if(dc_wallportals)
  951. colfunc = R_DrawPortalColumn_8;*/
  952. frontscale[rw_x] = rw_scale;
  953. // draw the wall tiers
  954. if (midtexture)
  955. {
  956. Material::TextureRef &tr = midtexture->tex[0];
  957. // single sided line
  958. dc_yl = yl;
  959. dc_yh = yh;
  960. dc_texturemid = rw_midtexturemid * tr.yscale;
  961. dc_iscale = base_iscale * tr.yscale;
  962. dc_source = midtexture->GetColumn(texturecolumn);
  963. dc_texheight = tr.t->height;
  964. colfunc();
  965. // dont draw anything more for this column, since
  966. // a midtexture blocks the view
  967. ceilingclip[rw_x] = viewheight;
  968. floorclip[rw_x] = -1;
  969. }
  970. else
  971. {
  972. int mid;
  973. // two sided line
  974. if (toptexture)
  975. {
  976. // top wall
  977. mid = pixhigh.value() >> HEIGHTBITS;
  978. pixhigh += pixhighstep;
  979. if (mid >= floorclip[rw_x])
  980. mid = floorclip[rw_x]-1;
  981. if (mid >= yl)
  982. {
  983. Material::TextureRef &tr = toptexture->tex[0];
  984. dc_yl = yl;
  985. dc_yh = mid;
  986. dc_texturemid = rw_toptexturemid * tr.yscale;
  987. dc_iscale = base_iscale * tr.yscale;
  988. dc_source = toptexture->GetColumn(texturecolumn);
  989. dc_texheight = tr.t->height;
  990. colfunc();
  991. ceilingclip[rw_x] = mid;
  992. }
  993. else
  994. ceilingclip[rw_x] = yl-1;
  995. }
  996. else
  997. {
  998. // no top wall
  999. if (markceiling)
  1000. {
  1001. ceilingclip[rw_x] = yl-1;
  1002. #ifdef OLDWATER
  1003. if (!waterplane || markwater)
  1004. waterclip[rw_x] = yl-1;
  1005. #endif
  1006. }
  1007. }
  1008. if (bottomtexture)
  1009. {
  1010. // bottom wall
  1011. mid = (pixlow.value() + HEIGHTUNIT-1)>>HEIGHTBITS;
  1012. pixlow += pixlowstep;
  1013. // no space above wall?
  1014. if (mid <= ceilingclip[rw_x])
  1015. mid = ceilingclip[rw_x]+1;
  1016. if (mid <= yh)
  1017. {
  1018. Material::TextureRef &tr = bottomtexture->tex[0];
  1019. dc_yl = mid;
  1020. dc_yh = yh;
  1021. dc_texturemid = rw_bottomtexturemid * tr.yscale;
  1022. dc_iscale = base_iscale * tr.yscale;
  1023. dc_source = bottomtexture->GetColumn(texturecolumn);
  1024. dc_texheight = tr.t->height;
  1025. colfunc();
  1026. floorclip[rw_x] = mid;
  1027. #ifdef OLDWATER
  1028. if (waterplane && waterz<worldlow)
  1029. waterclip[rw_x] = mid;
  1030. #endif
  1031. }
  1032. else
  1033. {
  1034. floorclip[rw_x] = yh+1;
  1035. }
  1036. }
  1037. else
  1038. {
  1039. // no bottom wall
  1040. if (markfloor)
  1041. {
  1042. floorclip[rw_x] = yh+1;
  1043. #ifdef OLDWATER
  1044. if (!waterplane || markwater)
  1045. waterclip[rw_x] = yh+1;
  1046. #endif
  1047. }
  1048. }
  1049. }
  1050. if (maskedtexture || numthicksides)
  1051. {
  1052. // save texturecol
  1053. // for backdrawing of masked mid texture
  1054. maskedtexturecol[rw_x] = texturecolumn.floor();
  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. /*if(dc_wallportals)
  1063. {
  1064. wallportal_t* wpr;
  1065. for(wpr = dc_wallportals; wpr; wpr = wpr->next)
  1066. {
  1067. wpr->top += wpr->topstep;
  1068. wpr->bottom += wpr->bottomstep;
  1069. }
  1070. }*/
  1071. for(i = 0; i < MAXFFLOORS; i++)
  1072. {
  1073. if (ffloor[i].mark)
  1074. {
  1075. int y_w = ffloor[i].b_frac.value() >> HEIGHTBITS;
  1076. ffloor[i].f_clip[rw_x] = ffloor[i].c_clip[rw_x] = y_w;
  1077. ffloor[i].b_frac += ffloor[i].b_step;
  1078. }
  1079. ffloor[i].f_frac += ffloor[i].f_step;
  1080. }
  1081. rw_scale += rw_scalestep;
  1082. topfrac += topstep;
  1083. bottomfrac += bottomstep;
  1084. }
  1085. }
  1086. //
  1087. // R_StoreWallRange
  1088. // A wall segment will be drawn
  1089. // between start and stop pixels (inclusive).
  1090. //
  1091. void Rend::R_StoreWallRange(int start, int stop)
  1092. {
  1093. int i;
  1094. //SoM: 3/26/2000: Use Boom limit removal and see if it works better.
  1095. //SoM: Boom code:
  1096. if (ds_p == drawsegs + maxdrawsegs)
  1097. {
  1098. unsigned pos_ds_p = ds_p - drawsegs;
  1099. unsigned pos_firstnewseg = firstnewseg - drawsegs;
  1100. unsigned pos_firstseg = firstseg - drawsegs;
  1101. maxdrawsegs = maxdrawsegs ? maxdrawsegs*2 : 128;
  1102. drawsegs = (drawseg_t *)realloc(drawsegs, maxdrawsegs*sizeof(*drawsegs));
  1103. ds_p = drawsegs + pos_ds_p;
  1104. firstnewseg = drawsegs + pos_firstnewseg;
  1105. if (firstseg)
  1106. firstseg = drawsegs + pos_firstseg; // if NULL, let it remain NULL
  1107. }
  1108. #ifdef RANGECHECK
  1109. if (start >=viewwidth || start > stop)
  1110. I_Error ("Bad R_RenderWallRange: %i to %i", start , stop);
  1111. #endif
  1112. sidedef = curline->sidedef;
  1113. linedef = curline->linedef;
  1114. // mark the segment as visible for auto map
  1115. linedef->flags |= ML_MAPPED;
  1116. // calculate rw_distance for scale calculation
  1117. rw_normalangle = curline->angle + ANG90;
  1118. angle_t offsetangle = abs(int(rw_normalangle)-rw_angle1);
  1119. if (offsetangle > ANG90)
  1120. offsetangle = ANG90;
  1121. angle_t distangle = ANG90 - offsetangle;
  1122. fixed_t hyp = R_PointToDist(curline->v1->x, curline->v1->y);
  1123. fixed_t sineval = finesine[distangle>>ANGLETOFINESHIFT];
  1124. rw_distance = 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. extern short *openings;
  1132. extern size_t maxopenings;
  1133. size_t pos = lastopening - openings;
  1134. size_t need = (rw_stopx - start)*4 + pos;
  1135. if (need > maxopenings)
  1136. {
  1137. drawseg_t *ds; //needed for fix from *cough* zdoom *cough*
  1138. short *oldopenings = openings;
  1139. short *oldlast = lastopening;
  1140. do
  1141. maxopenings = maxopenings ? maxopenings*2 : 16384;
  1142. while (need > maxopenings);
  1143. openings = (short int *)realloc(openings, maxopenings * sizeof(*openings));
  1144. lastopening = openings + pos;
  1145. // borrowed fix from *cough* zdoom *cough*
  1146. // [RH] We also need to adjust the openings pointers that
  1147. // were already stored in drawsegs.
  1148. for (ds = drawsegs; ds < ds_p; ds++)
  1149. {
  1150. #define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast)\
  1151. ds->p = ds->p - oldopenings + openings;
  1152. ADJUST (maskedtexturecol);
  1153. ADJUST (sprtopclip);
  1154. ADJUST (sprbottomclip);
  1155. ADJUST (thicksidecol);
  1156. }
  1157. #undef ADJUST
  1158. }
  1159. } // end of code to remove limits on openings
  1160. // calculate scale at both ends and step
  1161. ds_p->scale1 = rw_scale =
  1162. R_ScaleFromGlobalAngle (viewangle + xtoviewangle[start]);
  1163. if (stop > start)
  1164. {
  1165. ds_p->scale2 = R_ScaleFromGlobalAngle (viewangle + xtoviewangle[stop]);
  1166. ds_p->scalestep = rw_scalestep = (ds_p->scale2 - rw_scale) / (stop-start);
  1167. }
  1168. else
  1169. {
  1170. // UNUSED: try to fix the stretched line bug
  1171. #if 0
  1172. if (rw_distance < FRACUNIT/2)
  1173. {
  1174. fixed_t trx,try;
  1175. fixed_t gxt,gyt;
  1176. trx = curline->v1->x - viewx;
  1177. try = curline->v1->y - viewy;
  1178. gxt = FixedMul(trx,viewcos);
  1179. gyt = -FixedMul(try,viewsin);
  1180. ds_p->scale1 = FixedDiv(projection, gxt-gyt);
  1181. }
  1182. #endif
  1183. ds_p->scale2 = ds_p->scale1;
  1184. }
  1185. // calculate texture boundaries
  1186. // and decide if floor / ceiling marks are needed
  1187. worldtop = frontsector->ceilingheight - viewz;
  1188. worldbottom = frontsector->floorheight - viewz;
  1189. #ifdef OLDWATER
  1190. //added:18-02-98:WATER!
  1191. if (waterplane)
  1192. {
  1193. waterz = waterplane->height - viewz;
  1194. if (waterplane->height >= frontsector->ceilingheight)
  1195. I_Error("eau plus haut que plafond");
  1196. }
  1197. #endif
  1198. midtexture = toptexture = bottomtexture = 0;
  1199. maskedtexture = false;
  1200. ds_p->maskedtexturecol = NULL;
  1201. ds_p->numthicksides = numthicksides = 0;
  1202. ds_p->thicksidecol = NULL;
  1203. for(i = 0; i < MAXFFLOORS; i++)
  1204. {
  1205. ffloor[i].mark = false;
  1206. ds_p->thicksides[i] = NULL;
  1207. }
  1208. if(numffloors)
  1209. {
  1210. for(i = 0; i < numffloors; i++)
  1211. ffloor[i].f_pos = ffloor[i].height - viewz;
  1212. }
  1213. ds_p->bsilheight = fixed_t::FMAX;
  1214. ds_p->tsilheight = fixed_t::FMIN;
  1215. if (!backsector)
  1216. {
  1217. // single sided line
  1218. midtexture = sidedef->midtexture;
  1219. // a single sided line is terminal, so it must mark ends
  1220. markfloor = markceiling = true;
  1221. #ifdef OLDWATER
  1222. //added:18-02-98:WATER! onesided marque toujours l'eau si ya dlo
  1223. if (waterplane)
  1224. markwater = true;
  1225. else
  1226. markwater = false;
  1227. #endif
  1228. if (linedef->flags & ML_DONTPEGBOTTOM && midtexture) // FIXME correct?
  1229. {
  1230. // bottom of texture at bottom
  1231. rw_midtexturemid = frontsector->floorheight - viewz;
  1232. }
  1233. else
  1234. {
  1235. // top of texture at top
  1236. rw_midtexturemid = worldtop;
  1237. }
  1238. rw_midtexturemid += sidedef->rowoffset;
  1239. ds_p->silhouette = SIL_BOTH;
  1240. ds_p->sprtopclip = screenheightarray;
  1241. ds_p->sprbottomclip = negonearray;
  1242. }
  1243. else
  1244. {
  1245. // two sided line
  1246. ds_p->sprtopclip = ds_p->sprbottomclip = NULL;
  1247. ds_p->silhouette = 0;
  1248. if (frontsector->floorheight > backsector->floorheight)
  1249. {
  1250. ds_p->silhouette = SIL_BOTTOM;
  1251. ds_p->bsilheight = frontsector->floorheight;
  1252. }
  1253. else if (backsector->floorheight > viewz)
  1254. {
  1255. ds_p->silhouette = SIL_BOTTOM;
  1256. ds_p->bsilheight = fixed_t::FMAX;
  1257. // ds_p->sprbottomclip = negonearray;
  1258. }
  1259. if (frontsector->ceilingheight < backsector->ceilingheight)
  1260. {
  1261. ds_p->silhouette |= SIL_TOP;
  1262. ds_p->tsilheight = frontsector->ceilingheight;
  1263. }
  1264. else if (backsector->ceilingheight < viewz)
  1265. {
  1266. ds_p->silhouette |= SIL_TOP;
  1267. ds_p->tsilheight = fixed_t::FMIN;
  1268. // ds_p->sprtopclip = screenheightarray;
  1269. }
  1270. if (backsector->ceilingheight <= frontsector->floorheight)
  1271. {
  1272. ds_p->sprbottomclip = negonearray;
  1273. ds_p->bsilheight = fixed_t::FMAX;
  1274. ds_p->silhouette |= SIL_BOTTOM;
  1275. }
  1276. if (backsector->floorheight >= frontsector->ceilingheight)
  1277. {
  1278. ds_p->sprtopclip = screenheightarray;
  1279. ds_p->tsilheight = fixed_t::FMIN;
  1280. ds_p->silhouette |= SIL_TOP;
  1281. }
  1282. //SoM: 3/25/2000: This code fixes an automap bug that didn't check
  1283. // frontsector->ceiling and backsector->floor to see if a door was closed.
  1284. // Without the following code, sprites get displayed behind closed doors.
  1285. {
  1286. extern int doorclosed; // killough 1/17/98, 2/8/98, 4/7/98
  1287. if (doorclosed || backsector->ceilingheight<=frontsector->floorheight)
  1288. {
  1289. ds_p->sprbottomclip = negonearray;
  1290. ds_p->bsilheight = fixed_t::FMAX;
  1291. ds_p->silhouette |= SIL_BOTTOM;
  1292. }
  1293. if (doorclosed || backsector->floorheight>=frontsector->ceilingheight)
  1294. { // killough 1/17/98, 2/8/98
  1295. ds_p->sprtopclip = screenheightarray;
  1296. ds_p->tsilheight = fixed_t::FMIN;
  1297. ds_p->silhouette |= SIL_TOP;
  1298. }
  1299. }
  1300. worldhigh = backsector->ceilingheight - viewz;
  1301. worldlow = backsector->floorheight - viewz;
  1302. // hack to allow height changes in outdoor areas
  1303. if (frontsector->SkyCeiling() && backsector->SkyCeiling())
  1304. {
  1305. worldtop = worldhigh;
  1306. }
  1307. if (worldlow != worldbottom
  1308. || backsector->floorpic != frontsector->floorpic
  1309. || backsector->lightlevel != frontsector->lightlevel
  1310. //SoM: 3/22/2000: Check floor x and y offsets.
  1311. || backsector->floor_xoffs != frontsector->floor_xoffs
  1312. || backsector->floor_yoffs != frontsector->floor_yoffs
  1313. //SoM: 3/22/2000: Prevents bleeding.
  1314. || frontsector->heightsec != -1
  1315. || backsector->floorlightsec != frontsector->floorlightsec
  1316. //SoM: 4/3/2000: Check for colormaps
  1317. || frontsector->extra_colormap != backsector->extra_colormap
  1318. || (frontsector->ffloors != backsector->ffloors && frontsector->tag != backsector->tag))
  1319. {
  1320. markfloor = true;
  1321. }
  1322. else
  1323. {
  1324. // same plane on both sides
  1325. markfloor = false;
  1326. }
  1327. if (worldhigh != worldtop
  1328. || backsector->ceilingpic != frontsector->ceilingpic
  1329. || backsector->lightlevel != frontsector->lightlevel
  1330. //SoM: 3/22/2000: Check floor x and y offsets.
  1331. || backsector->ceiling_xoffs != frontsector->ceiling_xoffs
  1332. || backsector->ceiling_yoffs != frontsector->ceiling_yoffs
  1333. //SoM: 3/22/2000: Prevents bleeding.
  1334. || (frontsector->heightsec != -1 && !frontsector->SkyCeiling())
  1335. || backsector->floorlightsec != frontsector->floorlightsec
  1336. //SoM: 4/3/2000: Check for colormaps
  1337. || frontsector->extra_colormap != backsector->extra_colormap
  1338. || (frontsector->ffloors != backsector->ffloors && frontsector->tag != backsector->tag))
  1339. {
  1340. markceiling = true;
  1341. }
  1342. else
  1343. {
  1344. // same plane on both sides
  1345. markceiling = false;
  1346. }
  1347. if (backsector->ceilingheight <= frontsector->floorheight
  1348. || backsector->floorheight >= frontsector->ceilingheight)
  1349. {
  1350. // closed door
  1351. markceiling = markfloor = true;
  1352. }
  1353. #ifdef OLDWATER
  1354. //added:18-02-98: WATER! jamais mark si l'eau ne touche pas
  1355. // d'upper et de bottom
  1356. // (on s'en fout des differences de hauteur de plafond et
  1357. // de sol, tant que ca n'interrompt pas la surface de l'eau)
  1358. markwater = false;
  1359. #endif
  1360. // check TOP TEXTURE
  1361. if (worldhigh < worldtop)
  1362. {
  1363. #ifdef OLDWATER
  1364. //added:18-02-98:WATER! toptexture, check si ca touche watersurf
  1365. if (waterplane &&
  1366. waterz > worldhigh &&
  1367. waterz < worldtop)
  1368. markwater = true;
  1369. #endif
  1370. // top texture
  1371. toptexture = sidedef->toptexture;
  1372. if (linedef->flags & ML_DONTPEGTOP || !toptexture) // FIXME correct?
  1373. {
  1374. // top of texture at top
  1375. rw_toptexturemid = worldtop;
  1376. }
  1377. else
  1378. {
  1379. // bottom of texture
  1380. rw_toptexturemid = backsector->ceilingheight - viewz;
  1381. }
  1382. }
  1383. // check BOTTOM TEXTURE
  1384. if (worldlow > worldbottom) //seulement si VISIBLE!!!
  1385. {
  1386. #ifdef OLDWATER
  1387. //added:18-02-98:WATER! bottomtexture, check si ca touche watersurf
  1388. if (waterplane &&
  1389. waterz < worldlow &&
  1390. waterz > worldbottom)
  1391. markwater = true;
  1392. #endif
  1393. // bottom texture
  1394. bottomtexture = sidedef->bottomtexture;
  1395. if (linedef->flags & ML_DONTPEGBOTTOM )
  1396. {
  1397. // bottom of texture at bottom
  1398. // top of texture at top
  1399. rw_bottomtexturemid = worldtop;
  1400. }
  1401. else // top of texture at top
  1402. rw_bottomtexturemid = worldlow;
  1403. }
  1404. rw_toptexturemid += sidedef->rowoffset;
  1405. rw_bottomtexturemid += sidedef->rowoffset;
  1406. // allocate space for masked texture tables
  1407. if (frontsector && backsector && frontsector->tag != backsector->tag && (backsector->ffloors || frontsector->ffloors))
  1408. {
  1409. ffloor_t* rover;
  1410. ffloor_t* r2;
  1411. fixed_t lowcut, highcut;
  1412. //markceiling = markfloor = true;
  1413. maskedtexture = true;
  1414. ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x;
  1415. lastopening += rw_stopx - rw_x;
  1416. lowcut = frontsector->floorheight > backsector->floorheight ? frontsector->floorheight : backsector->floorheight;
  1417. highcut = frontsector->ceilingheight < backsector->ceilingheight ? frontsector->ceilingheight : backsector->ceilingheight;
  1418. if(frontsector->ffloors && backsector->ffloors)
  1419. {
  1420. i = 0;
  1421. for(rover = backsector->ffloors; rover != NULL && i < MAXFFLOORS; rover = rover->next)
  1422. {
  1423. if(!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS))
  1424. continue;
  1425. if(rover->flags & FF_INVERTSIDES)
  1426. continue;
  1427. if(*rover->topheight < lowcut || *rover->bottomheight > highcut)
  1428. continue;
  1429. for(r2 = frontsector->ffloors; r2; r2 = r2->next)
  1430. {
  1431. if(!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)
  1432. || *r2->topheight < lowcut || *r2->bottomheight > highcut)
  1433. continue;
  1434. if(rover->flags & FF_EXTRA)
  1435. {
  1436. if(!(r2->flags & FF_CUTEXTRA))
  1437. continue;
  1438. if(r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG)))
  1439. continue;
  1440. }
  1441. else
  1442. {
  1443. if(!(r2->flags & FF_CUTSOLIDS))
  1444. continue;
  1445. }
  1446. if(*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight)
  1447. continue;
  1448. break;
  1449. }
  1450. if(r2)
  1451. continue;
  1452. ds_p->thicksides[i] = rover;
  1453. i++;
  1454. }
  1455. for(rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next)
  1456. {
  1457. if(!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS))
  1458. continue;
  1459. if(!(rover->flags & FF_ALLSIDES))
  1460. continue;
  1461. if(*rover->topheight < lowcut || *rover->bottomheight > highcut)
  1462. continue;
  1463. for(r2 = backsector->ffloors; r2; r2 = r2->next)
  1464. {
  1465. if(!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)
  1466. || *r2->topheight < lowcut || *r2->bottomheight > highcut)
  1467. continue;
  1468. if(rover->flags & FF_EXTRA)
  1469. {
  1470. if(!(r2->flags & FF_CUTEXTRA))
  1471. continue;
  1472. if(r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG)))
  1473. continue;
  1474. }
  1475. else
  1476. {
  1477. if(!(r2->flags & FF_CUTSOLIDS))
  1478. continue;
  1479. }
  1480. if(*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight)
  1481. continue;
  1482. break;
  1483. }
  1484. if(r2)
  1485. continue;
  1486. ds_p->thicksides[i] = rover;
  1487. i++;
  1488. }
  1489. }
  1490. else if(backsector->ffloors)
  1491. {
  1492. for(rover = backsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next)
  1493. {
  1494. if(!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || rover->flags & FF_INVERTSIDES)
  1495. continue;
  1496. if(*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight)
  1497. continue;
  1498. ds_p->thicksides[i] = rover;
  1499. i++;
  1500. }
  1501. }
  1502. else if(frontsector->ffloors)
  1503. {
  1504. for(rover = frontsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next)
  1505. {
  1506. if(!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_ALLSIDES))
  1507. continue;
  1508. if(*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight)
  1509. continue;
  1510. if(*rover->topheight <= backsector->floorheight || *rover->bottomheight >= backsector->ceilingheight)
  1511. continue;
  1512. ds_p->thicksides[i] = rover;
  1513. i++;
  1514. }
  1515. }
  1516. ds_p->numthicksides = numthicksides = i;
  1517. }
  1518. if (sidedef->midtexture)
  1519. {
  1520. // masked midtexture
  1521. if(!ds_p->thicksidecol)
  1522. {
  1523. ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x;
  1524. lastopening += rw_stopx - rw_x;
  1525. }
  1526. else
  1527. ds_p->maskedtexturecol = ds_p->thicksidecol;
  1528. maskedtexture = true;
  1529. }
  1530. }
  1531. // calculate rw_offset (only needed for textured lines)
  1532. segtextured = midtexture || toptexture || bottomtexture || maskedtexture || (numthicksides > 0);
  1533. if (segtextured)
  1534. {
  1535. offsetangle = rw_normalangle-rw_angle1;
  1536. if (offsetangle > ANG180)
  1537. offsetangle = -offsetangle;
  1538. if (offsetangle > ANG90)
  1539. offsetangle = ANG90;
  1540. sineval = finesine[offsetangle >>ANGLETOFINESHIFT];
  1541. rw_offset = FixedMul (hyp, sineval);
  1542. if (rw_normalangle-rw_angle1 < ANG180)
  1543. rw_offset = -rw_offset;
  1544. /// don't use texture offset for splats
  1545. rw_offset2 = rw_offset + curline->offset;
  1546. rw_offset += sidedef->textureoffset + curline->offset;
  1547. rw_centerangle = ANG90 + viewangle - rw_normalangle;
  1548. // calculate light table
  1549. // use different light tables
  1550. // for horizontal / vertical / diagonal
  1551. // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
  1552. if (!fixedcolormap)
  1553. {
  1554. int lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight;
  1555. if (curline->v1->y == curline->v2->y)
  1556. lightnum--;
  1557. else if (curline->v1->x == curline->v2->x)
  1558. lightnum++;
  1559. if (lightnum < 0)
  1560. walllights = scalelight[0];
  1561. else if (lightnum >= LIGHTLEVELS)
  1562. walllights = scalelight[LIGHTLEVELS-1];
  1563. else
  1564. walllights = scalelight[lightnum];
  1565. }
  1566. }
  1567. // if a floor / ceiling plane is on the wrong side
  1568. // of the view plane, it is definitely invisible
  1569. // and doesn't need to be marked.
  1570. //added:18-02-98: WATER! cacher ici dans certaines conditions?
  1571. // la surface eau est visible de dessous et dessus...
  1572. if (frontsector->heightsec == -1)
  1573. {
  1574. if (frontsector->floorheight >= viewz)
  1575. {
  1576. // above view plane
  1577. markfloor = false;
  1578. }
  1579. if (frontsector->ceilingheight <= viewz && !frontsector->SkyCeiling())
  1580. {
  1581. // below view plane
  1582. markceiling = false;
  1583. }
  1584. }
  1585. // calculate incremental stepping values for texture edges
  1586. worldtop >>= 4;
  1587. worldbottom >>= 4;
  1588. topstep = -FixedMul (rw_scalestep, worldtop);
  1589. topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale);
  1590. #ifdef OLDWATER
  1591. //added:18-02-98:WATER!
  1592. waterz >>= 4;
  1593. if (markwater)
  1594. {
  1595. if (waterplane==NULL)
  1596. I_Error("fuck no waterplane!");
  1597. waterstep = -FixedMul (rw_scalestep, waterz);
  1598. waterfrac = (centeryfrac>>4) - FixedMul (waterz, rw_scale);
  1599. }
  1600. #endif
  1601. bottomstep = -FixedMul (rw_scalestep,worldbottom);
  1602. bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale);
  1603. dc_numlights = curline->numlights = 0;
  1604. if(frontsector->numlights)
  1605. {
  1606. dc_numlights = frontsector->numlights;
  1607. if(dc_numlights >= dc_maxlights)
  1608. {
  1609. dc_maxlights = dc_numlights;
  1610. dc_lightlist = (r_lightlist_t *)realloc(dc_lightlist, sizeof(r_lightlist_t) * dc_maxlights);
  1611. }
  1612. for(i = 0; i < dc_numlights; i++)
  1613. {
  1614. dc_lightlist[i].height = (centeryfrac) - FixedMul((frontsector->lightlist[i].height - viewz), rw_scale);
  1615. dc_lightlist[i].heightstep = -FixedMul (rw_scalestep, (frontsector->lightlist[i].height - viewz));
  1616. if(frontsector->lightlist[i].caster && frontsector->lightlist[i].caster->flags & FF_SOLID)
  1617. {
  1618. dc_lightlist[i].botheight = (centeryfrac) - FixedMul((*frontsector->lightlist[i].caster->bottomheight - viewz), rw_scale);
  1619. dc_lightlist[i].botheightstep = -FixedMul (rw_scalestep, (*frontsector->lightlist[i].caster->bottomheight - viewz));
  1620. dc_lightlist[i].flags = frontsector->lightlist[i].caster->flags;
  1621. }
  1622. else
  1623. dc_lightlist[i].flags = 0;
  1624. //Hurdler: it seems to crash here with phobia (lightlevel pointer is not valid)
  1625. if (frontsector->lightlist[i].lightlevel)
  1626. dc_lightlist[i].lightlevel = *frontsector->lightlist[i].lightlevel;
  1627. else
  1628. dc_lightlist[i].lightlevel = *frontsector->lightlist->lightlevel;
  1629. dc_lightlist[i].extra_colormap = frontsector->lightlist[i].extra_colormap;
  1630. }
  1631. if(curline->numlights < dc_numlights)
  1632. {
  1633. if(curline->rlights)
  1634. Z_Free(curline->rlights);
  1635. curline->rlights = (r_lightlist_t *)Z_Malloc(sizeof(r_lightlist_t) * dc_numlights, PU_LEVEL, 0);
  1636. memcpy(curline->rlights, dc_lightlist, sizeof(r_lightlist_t) * dc_numlights);
  1637. }
  1638. curline->numlights = dc_numlights;
  1639. }
  1640. /*if(linedef->wallportals)
  1641. {
  1642. wallportal_t* wpr;
  1643. dc_wallportals = linedef->wallportals;
  1644. for(wpr = dc_wallportals; wpr; wpr = wpr->next)
  1645. {
  1646. wpr->top = (centeryfrac) - FixedMul((*wpr->topheight - viewz), rw_scale) + FRACUNIT;
  1647. wpr->topstep = -FixedMul (rw_scalestep, (*wpr->topheight - viewz));
  1648. wpr->bottom = (centeryfrac) - FixedMul((*wpr->bottomheight - viewz), rw_scale);
  1649. wpr->bottomstep = -FixedMul (rw_scalestep, (*wpr->bottomheight - viewz));
  1650. }
  1651. }
  1652. else
  1653. dc_wallportals = NULL;*/
  1654. if(numffloors)
  1655. {
  1656. for(i = 0; i < numffloors; i++)
  1657. {
  1658. ffloor[i].f_pos >>= 4;
  1659. ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos);
  1660. ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale);
  1661. }
  1662. }
  1663. if (backsector)
  1664. {
  1665. worldhigh >>= 4;
  1666. worldlow >>= 4;
  1667. if (worldhigh < worldtop)
  1668. {
  1669. pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale);
  1670. pixhighstep = -FixedMul (rw_scalestep,worldhigh);
  1671. }
  1672. if (worldlow > worldbottom)
  1673. {
  1674. pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale);
  1675. pixlowstep = -FixedMul (rw_scalestep,worldlow);
  1676. }
  1677. {
  1678. ffloor_t* rover;
  1679. i = 0;
  1680. if(backsector->ffloors)
  1681. {
  1682. for(rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next)
  1683. {
  1684. if(!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES))
  1685. continue;
  1686. if(*rover->bottomheight <= backsector->ceilingheight &&
  1687. *rover->bottomheight >= backsector->floorheight &&
  1688. ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) ||
  1689. (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES))))
  1690. {
  1691. ffloor[i].mark = true;
  1692. ffloor[i].b_pos = *rover->bottomheight;
  1693. ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4;
  1694. ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos);
  1695. ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
  1696. i++;
  1697. }
  1698. if(i >= MAXFFLOORS)
  1699. break;
  1700. if(*rover->topheight >= backsector->floorheight &&
  1701. *rover->topheight <= backsector->ceilingheight &&
  1702. ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) ||
  1703. (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES))))
  1704. {
  1705. ffloor[i].mark = true;
  1706. ffloor[i].b_pos = *rover->topheight;
  1707. ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4;
  1708. ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos);
  1709. ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
  1710. i++;
  1711. }
  1712. }
  1713. }
  1714. else if(frontsector && frontsector->ffloors)
  1715. {
  1716. for(rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next)
  1717. {
  1718. if(!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES))
  1719. continue;
  1720. if(*rover->bottomheight <= frontsector->ceilingheight &&
  1721. *rover->bottomheight >= frontsector->floorheight &&
  1722. ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) ||
  1723. (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES))))
  1724. {
  1725. ffloor[i].mark = true;
  1726. ffloor[i].b_pos = *rover->bottomheight;
  1727. ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4;
  1728. ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos);
  1729. ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
  1730. i++;
  1731. }
  1732. if(i >= MAXFFLOORS)
  1733. break;
  1734. if(*rover->topheight >= frontsector->floorheight &&
  1735. *rover->topheight <= frontsector->ceilingheight &&
  1736. ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) ||
  1737. (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES))))
  1738. {
  1739. ffloor[i].mark = true;
  1740. ffloor[i].b_pos = *rover->topheight;
  1741. ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4;
  1742. ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos);
  1743. ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
  1744. i++;
  1745. }
  1746. }
  1747. }
  1748. }
  1749. }
  1750. // get a new or use the same visplane
  1751. if (markceiling)
  1752. {
  1753. if(ceilingplane) //SoM: 3/29/2000: Check for null ceiling planes
  1754. ceilingplane = R_CheckPlane (ceilingplane, rw_x, rw_stopx-1);
  1755. else
  1756. markceiling = false; // was 0
  1757. }
  1758. // get a new or use the same visplane
  1759. if (markfloor)
  1760. {
  1761. if(floorplane) //SoM: 3/29/2000: Check for null planes
  1762. floorplane = R_CheckPlane (floorplane, rw_x, rw_stopx-1);
  1763. else
  1764. markfloor = false; // was 0
  1765. }
  1766. #ifdef OLDWATER
  1767. //added:18-02-98: il me faut un visplane pour l'eau...WATER!
  1768. if (markwater)
  1769. {
  1770. if (waterplane==NULL)
  1771. I_Error("pas de waterplane avec markwater!?");
  1772. waterplane = R_CheckPlane (waterplane, rw_x, rw_stopx-1);
  1773. }
  1774. // render it
  1775. //added:24-02-98:WATER! unused now, trying something neater
  1776. if (markwater)
  1777. colfunc = R_DrawWaterColumn;
  1778. #endif
  1779. ds_p->numffloorplanes = 0;
  1780. if(numffloors)
  1781. {
  1782. if(firstseg == NULL)
  1783. {
  1784. for(i = 0; i < numffloors; i++)
  1785. ds_p->ffloorplanes[i] = ffloor[i].plane = R_CheckPlane(ffloor[i].plane, rw_x, rw_stopx - 1);
  1786. ds_p->numffloorplanes = numffloors;
  1787. firstseg = ds_p;
  1788. }
  1789. else
  1790. {
  1791. for(i = 0; i < numffloors; i++)
  1792. R_ExpandPlane(ffloor[i].plane, rw_x, rw_stopx - 1);
  1793. }
  1794. }
  1795. #ifdef BORIS_FIX
  1796. if (linedef->splats && cv_splats.value)
  1797. {
  1798. // SoM: