summaryrefslogtreecommitdiff
path: root/apps/plugins/doom/r_segs.c
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2006-03-28 15:44:01 +0000
committerDave Chapman <dave@dchapman.com>2006-03-28 15:44:01 +0000
commit47f4a458d636a889e955e68f896708f1276febc0 (patch)
tree99f770c02ef606f0abbdcd332ac39e69830d8007 /apps/plugins/doom/r_segs.c
parentfff7d6157d56f233cad5c2003475e47a5ff809a7 (diff)
downloadrockbox-47f4a458d636a889e955e68f896708f1276febc0.tar.gz
rockbox-47f4a458d636a889e955e68f896708f1276febc0.zip
Patch #2969 - Doom! Currently only working on the H300.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9312 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/doom/r_segs.c')
-rw-r--r--apps/plugins/doom/r_segs.c843
1 files changed, 843 insertions, 0 deletions
diff --git a/apps/plugins/doom/r_segs.c b/apps/plugins/doom/r_segs.c
new file mode 100644
index 0000000000..4771132c77
--- /dev/null
+++ b/apps/plugins/doom/r_segs.c
@@ -0,0 +1,843 @@
1/* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
3 *
4 *
5 * PrBoom a Doom port merged with LxDoom and LSDLDoom
6 * based on BOOM, a modified and improved DOOM engine
7 * Copyright (C) 1999 by
8 * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
9 * Copyright (C) 1999-2000 by
10 * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 * 02111-1307, USA.
26 *
27 * DESCRIPTION:
28 * All the clipping: columns, horizontal spans, sky columns.
29 *
30 *-----------------------------------------------------------------------------*/
31//
32// 4/25/98, 5/2/98 killough: reformatted, beautified
33
34#include "doomstat.h"
35#include "r_main.h"
36#include "r_bsp.h"
37#include "r_plane.h"
38#include "r_things.h"
39#include "r_draw.h"
40#include "w_wad.h"
41//#include "lprintf.h"
42#include "rockmacros.h"
43
44// OPTIMIZE: closed two sided lines as single sided
45
46// killough 1/6/98: replaced globals with statics where appropriate
47
48// True if any of the segs textures might be visible.
49boolean segtextured;
50boolean markfloor; // False if the back side is the same plane.
51boolean markceiling;
52static boolean maskedtexture;
53static int toptexture;
54static int bottomtexture;
55static int midtexture;
56
57static fixed_t toptexheight, midtexheight, bottomtexheight; // cph
58
59angle_t rw_normalangle;// angle to line origin
60int rw_angle1;
61fixed_t rw_distance;
62lighttable_t** walllights;
63
64//
65// regular wall
66//
67int rw_x;
68int rw_stopx;
69static angle_t rw_centerangle;
70static fixed_t rw_offset;
71static fixed_t rw_scale;
72static fixed_t rw_scalestep;
73static fixed_t rw_midtexturemid;
74static fixed_t rw_toptexturemid;
75static fixed_t rw_bottomtexturemid;
76static int worldtop;
77static int worldbottom;
78static int worldhigh;
79static int worldlow;
80static fixed_t pixhigh;
81static fixed_t pixlow;
82static fixed_t pixhighstep;
83static fixed_t pixlowstep;
84static fixed_t topfrac;
85static fixed_t topstep;
86static fixed_t bottomfrac;
87static fixed_t bottomstep;
88static short *maskedtexturecol;
89
90//
91// R_ScaleFromGlobalAngle
92// Returns the texture mapping scale
93// for the current line (horizontal span)
94// at the given angle.
95// rw_distance must be calculated first.
96//
97// killough 5/2/98: reformatted, cleaned up
98static fixed_t R_ScaleFromGlobalAngle (angle_t visangle)
99{
100 int anglea = ANG90 + (visangle-viewangle);
101 int angleb = ANG90 + (visangle-rw_normalangle);
102 int sinea = finesine[anglea>>ANGLETOFINESHIFT];
103 int sineb = finesine[angleb>>ANGLETOFINESHIFT];
104 fixed_t num = FixedMul(projection,sineb);
105 int den = FixedMul(rw_distance,sinea);
106
107 return den > num>>16 ? (num=FixedDiv (num, den)) > 64*FRACUNIT ?
108 64*FRACUNIT : num < 256 ? 256 : num : 64*FRACUNIT ;
109}
110//
111// R_RenderMaskedSegRange
112//
113
114int fake_contrast IBSS_ATTR;
115
116void R_RenderMaskedSegRange(drawseg_t *ds, int x1, int x2)
117{
118 column_t *col;
119 int lightnum;
120 int texnum;
121 sector_t tempsec; // killough 4/13/98
122
123 // Calculate light table.
124 // Use different light tables
125 // for horizontal / vertical / diagonal. Diagonal?
126
127 curline = ds->curline; // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
128
129 // killough 4/11/98: draw translucent 2s normal textures
130
131 colfunc = R_DrawColumn;
132 if (curline->linedef->tranlump >= 0 && general_translucency)
133 {
134 colfunc = R_DrawTLColumn;
135 tranmap = main_tranmap;
136 if (curline->linedef->tranlump > 0)
137 tranmap = W_CacheLumpNum(curline->linedef->tranlump-1);
138 }
139
140 // killough 4/11/98: end translucent 2s normal code
141
142 frontsector = curline->frontsector;
143 backsector = curline->backsector;
144
145 texnum = texturetranslation[curline->sidedef->midtexture];
146
147 // killough 4/13/98: get correct lightlevel for 2s normal textures
148 lightnum = (R_FakeFlat(frontsector, &tempsec, NULL, NULL, false)
149 ->lightlevel >> LIGHTSEGSHIFT)+extralight;
150
151 /* cph - ...what is this for? adding contrast to rooms?
152 * It looks crap in outdoor areas */
153 if (fake_contrast) {
154 if (curline->v1->y == curline->v2->y)
155 lightnum--;
156 else
157 if (curline->v1->x == curline->v2->x)
158 lightnum++;
159 }
160
161 walllights = lightnum >= LIGHTLEVELS ? scalelight[LIGHTLEVELS-1] :
162 lightnum < 0 ? scalelight[0] : scalelight[lightnum];
163
164 maskedtexturecol = ds->maskedtexturecol;
165
166 rw_scalestep = ds->scalestep;
167 spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
168 mfloorclip = ds->sprbottomclip;
169 mceilingclip = ds->sprtopclip;
170
171 // find positioning
172 if (curline->linedef->flags & ML_DONTPEGBOTTOM)
173 {
174 dc_texturemid = frontsector->floorheight > backsector->floorheight
175 ? frontsector->floorheight : backsector->floorheight;
176 dc_texturemid = dc_texturemid + textureheight[texnum] - viewz;
177 }
178 else
179 {
180 dc_texturemid =frontsector->ceilingheight<backsector->ceilingheight
181 ? frontsector->ceilingheight : backsector->ceilingheight;
182 dc_texturemid = dc_texturemid - viewz;
183 }
184
185 dc_texturemid += curline->sidedef->rowoffset;
186
187 if (fixedcolormap)
188 dc_colormap = fixedcolormap;
189
190 // draw the columns
191 for (dc_x = x1 ; dc_x <= x2 ; dc_x++, spryscale += rw_scalestep)
192 if (maskedtexturecol[dc_x] != SHRT_MAX)
193 {
194 if (!fixedcolormap) // calculate lighting
195 {
196 unsigned index = spryscale>>LIGHTSCALESHIFT;
197
198 if (index >= MAXLIGHTSCALE )
199 index = MAXLIGHTSCALE-1;
200
201 dc_colormap = walllights[index];
202 }
203
204 // killough 3/2/98:
205 //
206 // This calculation used to overflow and cause crashes in Doom:
207 //
208 // sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
209 //
210 // This code fixes it, by using double-precision intermediate
211 // arithmetic and by skipping the drawing of 2s normals whose
212 // mapping to screen coordinates is totally out of range:
213
214 {
215 int_64_t t = ((int_64_t) centeryfrac << FRACBITS) -
216 (int_64_t) dc_texturemid * spryscale;
217 if (t + (int_64_t) textureheight[texnum] * spryscale < 0 ||
218 t > (int_64_t) SCREENHEIGHT << FRACBITS*2)
219 continue; // skip if the texture is out of screen's range
220 sprtopscreen = (long)(t >> FRACBITS);
221 }
222
223 dc_iscale = 0xffffffffu / (unsigned) spryscale;
224
225 // killough 1/25/98: here's where Medusa came in, because
226 // it implicitly assumed that the column was all one patch.
227 // Originally, Doom did not construct complete columns for
228 // multipatched textures, so there were no header or trailer
229 // bytes in the column referred to below, which explains
230 // the Medusa effect. The fix is to construct true columns
231 // when forming multipatched textures (see r_data.c).
232
233 // draw the texture
234 col = (column_t *)((byte *)
235 R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3);
236 R_DrawMaskedColumn (col);
237 maskedtexturecol[dc_x] = SHRT_MAX;
238 }
239
240 // Except for main_tranmap, mark others purgable at this point
241 if (curline->linedef->tranlump > 0 && general_translucency)
242 W_UnlockLumpNum(curline->linedef->tranlump-1); // cph - unlock it
243}
244
245//
246// R_RenderSegLoop
247// Draws zero, one, or two textures (and possibly a masked texture) for walls.
248// Can draw or mark the starting pixel of floor and ceiling textures.
249// CALLED: CORE LOOPING ROUTINE.
250//
251
252extern byte solidcol[SCREENWIDTH];
253#define HEIGHTBITS 12
254#define HEIGHTUNIT (1<<HEIGHTBITS)
255static int didsolidcol; /* True if at least one column was marked solid */
256
257static void R_RenderSegLoop (void)
258{
259 fixed_t texturecolumn = 0; // shut up compiler warning
260 for ( ; rw_x < rw_stopx ; rw_x++)
261 {
262
263 // mark floor / ceiling areas
264
265 int yh = bottomfrac>>HEIGHTBITS;
266 int yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS;
267
268 // no space above wall?
269 int bottom,top = ceilingclip[rw_x]+1;
270
271 if (yl < top)
272 yl = top;
273
274 if (markceiling)
275 {
276 bottom = yl-1;
277
278 if (bottom >= floorclip[rw_x])
279 bottom = floorclip[rw_x]-1;
280
281 if (top <= bottom)
282 {
283 ceilingplane->top[rw_x] = top;
284 ceilingplane->bottom[rw_x] = bottom;
285 }
286 }
287
288 // yh = bottomfrac>>HEIGHTBITS;
289
290 bottom = floorclip[rw_x]-1;
291 if (yh > bottom)
292 yh = bottom;
293
294 if (markfloor)
295 {
296
297 top = yh < ceilingclip[rw_x] ? ceilingclip[rw_x] : yh;
298
299 if (++top <= bottom)
300 {
301 floorplane->top[rw_x] = top;
302 floorplane->bottom[rw_x] = bottom;
303 }
304 }
305
306 // texturecolumn and lighting are independent of wall tiers
307 if (segtextured)
308 {
309 unsigned index;
310
311 // calculate texture offset
312 angle_t angle =(rw_centerangle+xtoviewangle[rw_x])>>ANGLETOFINESHIFT;
313
314 texturecolumn = rw_offset-FixedMul(finetangent[angle],rw_distance);
315 texturecolumn >>= FRACBITS;
316 // calculate lighting
317 index = rw_scale>>LIGHTSCALESHIFT;
318
319 if (index >= MAXLIGHTSCALE )
320 index = MAXLIGHTSCALE-1;
321
322 dc_colormap = walllights[index];
323 dc_x = rw_x;
324 dc_iscale = 0xffffffffu / (unsigned)rw_scale;
325 }
326
327 // draw the wall tiers
328 if (midtexture)
329 {
330
331 dc_yl = yl; // single sided line
332 dc_yh = yh;
333 dc_texturemid = rw_midtexturemid;
334 dc_source = R_GetColumn(midtexture, texturecolumn);
335 dc_texheight = midtexheight;
336 colfunc ();
337 ceilingclip[rw_x] = viewheight;
338 floorclip[rw_x] = -1;
339 }
340 else
341 {
342
343 // two sided line
344 if (toptexture)
345 {
346 // top wall
347 int mid = pixhigh>>HEIGHTBITS;
348 pixhigh += pixhighstep;
349
350 if (mid >= floorclip[rw_x])
351 mid = floorclip[rw_x]-1;
352
353 if (mid >= yl)
354 {
355 dc_yl = yl;
356 dc_yh = mid;
357 dc_texturemid = rw_toptexturemid;
358 dc_source = R_GetColumn(toptexture,texturecolumn);
359 dc_texheight = toptexheight;
360 colfunc ();
361 ceilingclip[rw_x] = mid;
362 }
363 else
364 ceilingclip[rw_x] = yl-1;
365 }
366 else // no top wall
367 {
368
369 if (markceiling)
370 ceilingclip[rw_x] = yl-1;
371 }
372
373 if (bottomtexture) // bottom wall
374 {
375 int mid = (pixlow+HEIGHTUNIT-1)>>HEIGHTBITS;
376 pixlow += pixlowstep;
377
378 // no space above wall?
379 if (mid <= ceilingclip[rw_x])
380 mid = ceilingclip[rw_x]+1;
381
382 if (mid <= yh)
383 {
384 dc_yl = mid;
385 dc_yh = yh;
386 dc_texturemid = rw_bottomtexturemid;
387 dc_source = R_GetColumn(bottomtexture,
388 texturecolumn);
389 dc_texheight = bottomtexheight;
390 colfunc ();
391 floorclip[rw_x] = mid;
392 }
393 else
394 floorclip[rw_x] = yh+1;
395 }
396 else // no bottom wall
397 {
398 if (markfloor)
399 floorclip[rw_x] = yh+1;
400 }
401
402 // cph - if we completely blocked further sight through this column,
403 // add this info to the solid columns array for r_bsp.c
404 if ((markceiling || markfloor) &&
405 (floorclip[rw_x] <= ceilingclip[rw_x] + 1)) {
406 solidcol[rw_x] = 1; didsolidcol = 1;
407 }
408
409 // save texturecol for backdrawing of masked mid texture
410 if (maskedtexture)
411 maskedtexturecol[rw_x] = texturecolumn;
412 }
413
414 rw_scale += rw_scalestep;
415 topfrac += topstep;
416 bottomfrac += bottomstep;
417 }
418}
419
420// killough 5/2/98: move from r_main.c, made static, simplified
421
422static fixed_t R_PointToDist(fixed_t x, fixed_t y)
423{
424 fixed_t dx = D_abs(x - viewx);
425 fixed_t dy = D_abs(y - viewy);
426
427 if (dy > dx)
428 {
429 fixed_t t = dx;
430 dx = dy;
431 dy = t;
432 }
433
434 return FixedDiv(dx, finesine[(tantoangle[FixedDiv(dy,dx) >> DBITS]
435 + ANG90) >> ANGLETOFINESHIFT]);
436}
437
438//
439// R_StoreWallRange
440// A wall segment will be drawn
441// between start and stop pixels (inclusive).
442//
443void R_StoreWallRange(const int start, const int stop)
444{
445 fixed_t hyp;
446 fixed_t sineval;
447 angle_t distangle, offsetangle;
448
449 if (ds_p == drawsegs+maxdrawsegs) // killough 1/98 -- fix 2s line HOM
450 {
451 unsigned pos = ds_p - drawsegs; // jff 8/9/98 fix from ZDOOM1.14a
452 unsigned newmax = maxdrawsegs ? maxdrawsegs*2 : 128; // killough
453 drawsegs = realloc(drawsegs,newmax*sizeof(*drawsegs));
454 ds_p = drawsegs + pos; // jff 8/9/98 fix from ZDOOM1.14a
455 maxdrawsegs = newmax;
456 }
457
458 if(curline->miniseg == false) // figgi -- skip minisegs
459 curline->linedef->flags |= ML_MAPPED;
460
461
462#ifdef RANGECHECK
463 if (start >=viewwidth || start > stop)
464 I_Error ("Bad R_RenderWallRange: %i to %i", start , stop);
465#endif
466
467 sidedef = curline->sidedef;
468 linedef = curline->linedef;
469
470 // mark the segment as visible for auto map
471 linedef->flags |= ML_MAPPED;
472
473 // calculate rw_distance for scale calculation
474 rw_normalangle = curline->angle + ANG90;
475
476 offsetangle = D_abs(rw_normalangle-rw_angle1);
477
478 if (offsetangle > ANG90)
479 offsetangle = ANG90;
480
481 distangle = ANG90 - offsetangle;
482 hyp = (viewx==curline->v1->x && viewy==curline->v1->y)?
483 0 : R_PointToDist (curline->v1->x, curline->v1->y);
484 sineval = finesine[distangle>>ANGLETOFINESHIFT];
485 rw_distance = FixedMul(hyp, sineval);
486
487 ds_p->x1 = rw_x = start;
488 ds_p->x2 = stop;
489 ds_p->curline = curline;
490 rw_stopx = stop+1;
491
492 { // killough 1/6/98, 2/1/98: remove limit on openings
493 extern short *openings;
494 extern size_t maxopenings;
495 size_t pos = lastopening - openings;
496 size_t need = (rw_stopx - start)*4 + pos;
497 if (need > maxopenings)
498 {
499 drawseg_t *ds; //jff 8/9/98 needed for fix from ZDoom
500 short *oldopenings = openings;
501 short *oldlast = lastopening;
502
503 do
504 maxopenings = maxopenings ? maxopenings*2 : 16384;
505 while (need > maxopenings);
506 openings = realloc(openings, maxopenings * sizeof(*openings));
507 lastopening = openings + pos;
508
509 // jff 8/9/98 borrowed fix for openings from ZDOOM1.14
510 // [RH] We also need to adjust the openings pointers that
511 // were already stored in drawsegs.
512 for (ds = drawsegs; ds < ds_p; ds++)
513 {
514#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast)\
515 ds->p = ds->p - oldopenings + openings;
516 ADJUST (maskedtexturecol);
517 ADJUST (sprtopclip);
518 ADJUST (sprbottomclip);
519 }
520#undef ADJUST
521 }
522 } // killough: end of code to remove limits on openings
523
524 // calculate scale at both ends and step
525
526 ds_p->scale1 = rw_scale =
527 R_ScaleFromGlobalAngle (viewangle + xtoviewangle[start]);
528
529 if (stop > start)
530 {
531 ds_p->scale2 = R_ScaleFromGlobalAngle (viewangle + xtoviewangle[stop]);
532 ds_p->scalestep = rw_scalestep = (ds_p->scale2-rw_scale) / (stop-start);
533 }
534 else
535 ds_p->scale2 = ds_p->scale1;
536
537 // calculate texture boundaries
538 // and decide if floor / ceiling marks are needed
539
540 worldtop = frontsector->ceilingheight - viewz;
541 worldbottom = frontsector->floorheight - viewz;
542
543 midtexture = toptexture = bottomtexture = maskedtexture = 0;
544 ds_p->maskedtexturecol = NULL;
545
546 if (!backsector)
547 {
548 // single sided line
549 midtexture = texturetranslation[sidedef->midtexture];
550 midtexheight = (linedef->r_flags & RF_MID_TILE) ? 0 : textureheight[midtexture] >> FRACBITS;
551
552 // a single sided line is terminal, so it must mark ends
553 markfloor = markceiling = true;
554
555 if (linedef->flags & ML_DONTPEGBOTTOM)
556 { // bottom of texture at bottom
557 fixed_t vtop = frontsector->floorheight +
558 textureheight[sidedef->midtexture];
559 rw_midtexturemid = vtop - viewz;
560 }
561 else // top of texture at top
562 rw_midtexturemid = worldtop;
563
564 rw_midtexturemid += FixedMod(sidedef->rowoffset, textureheight[midtexture]);
565
566 ds_p->silhouette = SIL_BOTH;
567 ds_p->sprtopclip = screenheightarray;
568 ds_p->sprbottomclip = negonearray;
569 ds_p->bsilheight = INT_MAX;
570 ds_p->tsilheight = INT_MIN;
571 }
572 else // two sided line
573 {
574 ds_p->sprtopclip = ds_p->sprbottomclip = NULL;
575 ds_p->silhouette = 0;
576
577 if (linedef->r_flags & RF_CLOSED) { /* cph - closed 2S line e.g. door */
578 // cph - killough's (outdated) comment follows - this deals with both
579 // "automap fixes", his and mine
580 // killough 1/17/98: this test is required if the fix
581 // for the automap bug (r_bsp.c) is used, or else some
582 // sprites will be displayed behind closed doors. That
583 // fix prevents lines behind closed doors with dropoffs
584 // from being displayed on the automap.
585
586 ds_p->silhouette = SIL_BOTH;
587 ds_p->sprbottomclip = negonearray;
588 ds_p->bsilheight = INT_MAX;
589 ds_p->sprtopclip = screenheightarray;
590 ds_p->tsilheight = INT_MIN;
591
592 } else { /* not solid - old code */
593
594 if (frontsector->floorheight > backsector->floorheight)
595 {
596 ds_p->silhouette = SIL_BOTTOM;
597 ds_p->bsilheight = frontsector->floorheight;
598 }
599 else
600 if (backsector->floorheight > viewz)
601 {
602 ds_p->silhouette = SIL_BOTTOM;
603 ds_p->bsilheight = INT_MAX;
604 }
605
606 if (frontsector->ceilingheight < backsector->ceilingheight)
607 {
608 ds_p->silhouette |= SIL_TOP;
609 ds_p->tsilheight = frontsector->ceilingheight;
610 }
611 else
612 if (backsector->ceilingheight < viewz)
613 {
614 ds_p->silhouette |= SIL_TOP;
615 ds_p->tsilheight = INT_MIN;
616 }
617 }
618
619 worldhigh = backsector->ceilingheight - viewz;
620 worldlow = backsector->floorheight - viewz;
621
622 // hack to allow height changes in outdoor areas
623 if (frontsector->ceilingpic == skyflatnum
624 && backsector->ceilingpic == skyflatnum)
625 worldtop = worldhigh;
626
627 markfloor = worldlow != worldbottom
628 || backsector->floorpic != frontsector->floorpic
629 || backsector->lightlevel != frontsector->lightlevel
630
631 // killough 3/7/98: Add checks for (x,y) offsets
632 || backsector->floor_xoffs != frontsector->floor_xoffs
633 || backsector->floor_yoffs != frontsector->floor_yoffs
634
635 // killough 4/15/98: prevent 2s normals
636 // from bleeding through deep water
637 || frontsector->heightsec != -1
638
639 // killough 4/17/98: draw floors if different light levels
640 || backsector->floorlightsec != frontsector->floorlightsec
641 ;
642
643 markceiling = worldhigh != worldtop
644 || backsector->ceilingpic != frontsector->ceilingpic
645 || backsector->lightlevel != frontsector->lightlevel
646
647 // killough 3/7/98: Add checks for (x,y) offsets
648 || backsector->ceiling_xoffs != frontsector->ceiling_xoffs
649 || backsector->ceiling_yoffs != frontsector->ceiling_yoffs
650
651 // killough 4/15/98: prevent 2s normals
652 // from bleeding through fake ceilings
653 || (frontsector->heightsec != -1 &&
654 frontsector->ceilingpic!=skyflatnum)
655
656 // killough 4/17/98: draw ceilings if different light levels
657 || backsector->ceilinglightsec != frontsector->ceilinglightsec
658 ;
659
660 if (backsector->ceilingheight <= frontsector->floorheight
661 || backsector->floorheight >= frontsector->ceilingheight)
662 markceiling = markfloor = true; // closed door
663
664 if (worldhigh < worldtop) // top texture
665 {
666 toptexture = texturetranslation[sidedef->toptexture];
667 toptexheight = (linedef->r_flags & RF_TOP_TILE) ? 0 : textureheight[toptexture] >> FRACBITS;
668 rw_toptexturemid = linedef->flags & ML_DONTPEGTOP ? worldtop :
669 backsector->ceilingheight+textureheight[sidedef->toptexture]-viewz;
670 rw_toptexturemid += FixedMod(sidedef->rowoffset, textureheight[toptexture]);
671 }
672
673 if (worldlow > worldbottom) // bottom texture
674 {
675 bottomtexture = texturetranslation[sidedef->bottomtexture];
676 bottomtexheight = (linedef->r_flags & RF_BOT_TILE) ? 0 : textureheight[bottomtexture] >> FRACBITS;
677 rw_bottomtexturemid = linedef->flags & ML_DONTPEGBOTTOM ? worldtop :
678 worldlow;
679 rw_bottomtexturemid += FixedMod(sidedef->rowoffset, textureheight[bottomtexture]);
680 }
681
682 // allocate space for masked texture tables
683 if (sidedef->midtexture) // masked midtexture
684 {
685 maskedtexture = true;
686 ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x;
687 lastopening += rw_stopx - rw_x;
688 }
689 }
690
691 // calculate rw_offset (only needed for textured lines)
692 segtextured = midtexture | toptexture | bottomtexture | maskedtexture;
693
694 if (segtextured)
695 {
696 offsetangle = rw_normalangle-rw_angle1;
697
698 if (offsetangle > ANG180)
699 offsetangle = 0-offsetangle;
700
701 if (offsetangle > ANG90)
702 offsetangle = ANG90;
703
704 sineval = finesine[offsetangle >>ANGLETOFINESHIFT];
705 rw_offset = FixedMul (hyp, sineval);
706
707 if (rw_normalangle-rw_angle1 < ANG180)
708 rw_offset = -rw_offset;
709
710 rw_offset += sidedef->textureoffset + curline->offset;
711
712 rw_centerangle = ANG90 + viewangle - rw_normalangle;
713
714 // calculate light table
715 // use different light tables
716 // for horizontal / vertical / diagonal
717 // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
718 if (!fixedcolormap)
719 {
720 int lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight;
721
722 /* cph - ...what is this for? adding contrast to rooms?
723 * It looks crap in outdoor areas */
724 if (fake_contrast) {
725 if (curline->v1->y == curline->v2->y)
726 lightnum--;
727 else if (curline->v1->x == curline->v2->x)
728 lightnum++;
729 }
730
731 if (lightnum < 0)
732 walllights = scalelight[0];
733 else if (lightnum >= LIGHTLEVELS)
734 walllights = scalelight[LIGHTLEVELS-1];
735 else
736 walllights = scalelight[lightnum];
737 }
738 }
739
740 // if a floor / ceiling plane is on the wrong side of the view
741 // plane, it is definitely invisible and doesn't need to be marked.
742
743 // killough 3/7/98: add deep water check
744 if (frontsector->heightsec == -1)
745 {
746 if (frontsector->floorheight >= viewz) // above view plane
747 markfloor = false;
748 if (frontsector->ceilingheight <= viewz &&
749 frontsector->ceilingpic != skyflatnum) // below view plane
750 markceiling = false;
751 }
752
753 // calculate incremental stepping values for texture edges
754 worldtop >>= 4;
755 worldbottom >>= 4;
756
757 topstep = -FixedMul (rw_scalestep, worldtop);
758 topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale);
759
760 bottomstep = -FixedMul (rw_scalestep,worldbottom);
761 bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale);
762
763 if (backsector)
764 {
765 worldhigh >>= 4;
766 worldlow >>= 4;
767
768 if (worldhigh < worldtop)
769 {
770 pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale);
771 pixhighstep = -FixedMul (rw_scalestep,worldhigh);
772 }
773 if (worldlow > worldbottom)
774 {
775 pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale);
776 pixlowstep = -FixedMul (rw_scalestep,worldlow);
777 }
778 }
779
780 // render it
781 if (markceiling) {
782 if (ceilingplane) // killough 4/11/98: add NULL ptr checks
783 ceilingplane = R_CheckPlane (ceilingplane, rw_x, rw_stopx-1);
784 else
785 markceiling = 0;
786 }
787
788 if (markfloor) {
789 if (floorplane) // killough 4/11/98: add NULL ptr checks
790 /* cph 2003/04/18 - ceilingplane and floorplane might be the same
791 * visplane (e.g. if both skies); R_CheckPlane doesn't know about
792 * modifications to the plane that might happen in parallel with the check
793 * being made, so we have to override it and split them anyway if that is
794 * a possibility, otherwise the floor marking would overwrite the ceiling
795 * marking, resulting in HOM. */
796 if (markceiling && ceilingplane == floorplane)
797 floorplane = R_DupPlane (floorplane, rw_x, rw_stopx-1);
798 else
799 floorplane = R_CheckPlane (floorplane, rw_x, rw_stopx-1);
800 else
801 markfloor = 0;
802 }
803
804 didsolidcol = 0;
805 R_RenderSegLoop();
806
807 /* cph - if a column was made solid by this wall, we _must_ save full clipping info */
808 if (backsector && didsolidcol) {
809 if (!(ds_p->silhouette & SIL_BOTTOM)) {
810 ds_p->silhouette |= SIL_BOTTOM;
811 ds_p->bsilheight = backsector->floorheight;
812 }
813 if (!(ds_p->silhouette & SIL_TOP)) {
814 ds_p->silhouette |= SIL_TOP;
815 ds_p->tsilheight = backsector->ceilingheight;
816 }
817 }
818
819 // save sprite clipping info
820 if ((ds_p->silhouette & SIL_TOP || maskedtexture) && !ds_p->sprtopclip)
821 {
822 memcpy (lastopening, ceilingclip+start, 2*(rw_stopx-start));
823 ds_p->sprtopclip = lastopening - start;
824 lastopening += rw_stopx - start;
825 }
826 if ((ds_p->silhouette & SIL_BOTTOM || maskedtexture) && !ds_p->sprbottomclip)
827 {
828 memcpy (lastopening, floorclip+start, 2*(rw_stopx-start));
829 ds_p->sprbottomclip = lastopening - start;
830 lastopening += rw_stopx - start;
831 }
832 if (maskedtexture && !(ds_p->silhouette & SIL_TOP))
833 {
834 ds_p->silhouette |= SIL_TOP;
835 ds_p->tsilheight = INT_MIN;
836 }
837 if (maskedtexture && !(ds_p->silhouette & SIL_BOTTOM))
838 {
839 ds_p->silhouette |= SIL_BOTTOM;
840 ds_p->bsilheight = INT_MAX;
841 }
842 ds_p++;
843}