DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

r_segs.cpp (19699B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
     10 it under the terms of the GNU General Public License as published by
     11 the Free Software Foundation, either version 3 of the License, or
     12 (at your option) any later version.
     13 
     14 Doom 3 BFG Edition Source Code 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 You should have received a copy of the GNU General Public License
     20 along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code.  If not, please request a copy in writing from id Software at the address below.
     23 
     24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
     25 
     26 ===========================================================================
     27 */
     28 
     29 #include "Precompiled.h"
     30 #include "globaldata.h"
     31 
     32 
     33 
     34 
     35 
     36 #include <stdlib.h>
     37 
     38 #include "i_system.h"
     39 
     40 #include "doomdef.h"
     41 #include "doomstat.h"
     42 
     43 #include "r_local.h"
     44 #include "r_sky.h"
     45 
     46 
     47 // OPTIMIZE: closed two sided ::g->lines as single sided
     48 
     49 // True if any of the ::g->segs textures might be visible.
     50 
     51 // False if the back side is the same plane.
     52 
     53 
     54 
     55 // angle to line origin
     56 
     57 //
     58 // regular wall
     59 //
     60 
     61 
     62 
     63 
     64 
     65 
     66 
     67 
     68 
     69 
     70 //
     71 // R_RenderMaskedSegRange
     72 //
     73 void
     74 R_RenderMaskedSegRange
     75 ( drawseg_t*	ds,
     76   int		x1,
     77   int		x2 )
     78 {
     79     unsigned		index;
     80     postColumn_t*	col;
     81     int				lightnum;
     82     int				texnum;
     83     
     84     // Calculate light table.
     85     // Use different light tables
     86     //   for horizontal / vertical / diagonal. Diagonal?
     87     // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
     88     ::g->curline = ds->curline;
     89     ::g->frontsector = ::g->curline->frontsector;
     90     ::g->backsector = ::g->curline->backsector;
     91     texnum = ::g->texturetranslation[::g->curline->sidedef->midtexture];
     92 	
     93     lightnum = (::g->frontsector->lightlevel >> LIGHTSEGSHIFT)+::g->extralight;
     94 
     95     if (::g->curline->v1->y == ::g->curline->v2->y)
     96 	lightnum--;
     97     else if (::g->curline->v1->x == ::g->curline->v2->x)
     98 	lightnum++;
     99 
    100     if (lightnum < 0)		
    101 	::g->walllights = ::g->scalelight[0];
    102     else if (lightnum >= LIGHTLEVELS)
    103 	::g->walllights = ::g->scalelight[LIGHTLEVELS-1];
    104     else
    105 	::g->walllights = ::g->scalelight[lightnum];
    106 
    107     ::g->maskedtexturecol = ds->maskedtexturecol;
    108 
    109     ::g->rw_scalestep = ds->scalestep;		
    110     ::g->spryscale = ds->scale1 + (x1 - ds->x1)*::g->rw_scalestep;
    111     ::g->mfloorclip = ds->sprbottomclip;
    112     ::g->mceilingclip = ds->sprtopclip;
    113     
    114     // find positioning
    115     if (::g->curline->linedef->flags & ML_DONTPEGBOTTOM)
    116     {
    117 	::g->dc_texturemid = ::g->frontsector->floorheight > ::g->backsector->floorheight
    118 	    ? ::g->frontsector->floorheight : ::g->backsector->floorheight;
    119 	::g->dc_texturemid = ::g->dc_texturemid + ::g->s_textureheight[texnum] - ::g->viewz;
    120     }
    121     else
    122     {
    123 	::g->dc_texturemid =::g->frontsector->ceilingheight < ::g->backsector->ceilingheight
    124 	    ? ::g->frontsector->ceilingheight : ::g->backsector->ceilingheight;
    125 	::g->dc_texturemid = ::g->dc_texturemid - ::g->viewz;
    126     }
    127     ::g->dc_texturemid += ::g->curline->sidedef->rowoffset;
    128 			
    129     if (::g->fixedcolormap)
    130 	::g->dc_colormap = ::g->fixedcolormap;
    131     
    132     // draw the columns
    133     for (::g->dc_x = x1 ; ::g->dc_x <= x2 ; ::g->dc_x++)
    134     {
    135 	// calculate lighting
    136 	if (::g->maskedtexturecol[::g->dc_x] != SHRT_MAX)
    137 	{
    138 	    if (!::g->fixedcolormap)
    139 	    {
    140 		index = ::g->spryscale>>LIGHTSCALESHIFT;
    141 
    142 		if (index >=  MAXLIGHTSCALE )
    143 		    index = MAXLIGHTSCALE-1;
    144 
    145 		::g->dc_colormap = ::g->walllights[index];
    146 	    }
    147 			
    148 	    ::g->sprtopscreen = ::g->centeryfrac - FixedMul(::g->dc_texturemid, ::g->spryscale);
    149 	    ::g->dc_iscale = 0xffffffffu / (unsigned)::g->spryscale;
    150 	    
    151 	    // draw the texture
    152 	    col = (postColumn_t *)( 
    153 		(byte *)R_GetColumn(texnum,::g->maskedtexturecol[::g->dc_x]) -3);
    154 			
    155 	    R_DrawMaskedColumn (col);
    156 	    ::g->maskedtexturecol[::g->dc_x] = SHRT_MAX;
    157 	}
    158 	::g->spryscale += ::g->rw_scalestep;
    159     }
    160 	
    161 }
    162 
    163 
    164 
    165 
    166 //
    167 // R_RenderSegLoop
    168 // Draws zero, one, or two textures (and possibly a masked
    169 //  texture) for walls.
    170 // Can draw or mark the starting pixel of floor and ceiling
    171 //  textures.
    172 // CALLED: CORE LOOPING ROUTINE.
    173 //
    174 
    175 void R_RenderSegLoop (void)
    176 {
    177     angle_t		angle;
    178     unsigned		index;
    179     int			yl;
    180     int			yh;
    181     int			mid;
    182     fixed_t		texturecolumn;
    183     int			top;
    184     int			bottom;
    185 
    186     texturecolumn = 0;				// shut up compiler warning
    187 	
    188     for ( ; ::g->rw_x < ::g->rw_stopx ; ::g->rw_x++)
    189     {
    190 		// mark floor / ceiling areas
    191 		yl = (::g->topfrac+HEIGHTUNIT-1)>>HEIGHTBITS;
    192 
    193 		// no space above wall?
    194 		if (yl < ::g->ceilingclip[::g->rw_x]+1)
    195 			yl = ::g->ceilingclip[::g->rw_x]+1;
    196 		
    197 		if (::g->markceiling)
    198 		{
    199 			top = ::g->ceilingclip[::g->rw_x]+1;
    200 			bottom = yl-1;
    201 
    202 			if (bottom >= ::g->floorclip[::g->rw_x])
    203 				bottom = ::g->floorclip[::g->rw_x]-1;
    204 
    205 			if (top <= bottom)
    206 			{
    207 				::g->ceilingplane->top[::g->rw_x] = top;
    208 				::g->ceilingplane->bottom[::g->rw_x] = bottom;
    209 			}
    210 		}
    211 		
    212 		yh = ::g->bottomfrac>>HEIGHTBITS;
    213 
    214 		if (yh >= ::g->floorclip[::g->rw_x])
    215 			yh = ::g->floorclip[::g->rw_x]-1;
    216 
    217 		if (::g->markfloor)
    218 		{
    219 			top = yh+1;
    220 			bottom = ::g->floorclip[::g->rw_x]-1;
    221 			if (top <= ::g->ceilingclip[::g->rw_x])
    222 				top = ::g->ceilingclip[::g->rw_x]+1;
    223 			if (top <= bottom)
    224 			{
    225 				::g->floorplane->top[::g->rw_x] = top;
    226 				::g->floorplane->bottom[::g->rw_x] = bottom;
    227 			}
    228 		}
    229 		
    230 	// texturecolumn and lighting are independent of wall tiers
    231 	if (::g->segtextured)
    232 	{
    233 	    // calculate texture offset
    234 	    angle = (::g->rw_centerangle + ::g->xtoviewangle[::g->rw_x])>>ANGLETOFINESHIFT;
    235 	    texturecolumn = ::g->rw_offset-FixedMul(finetangent[angle],::g->rw_distance);
    236 	    texturecolumn >>= FRACBITS;
    237 	    // calculate lighting
    238 	    index = ::g->rw_scale>>LIGHTSCALESHIFT;
    239 
    240 	    if (index >=  MAXLIGHTSCALE )
    241 			index = MAXLIGHTSCALE-1;
    242 
    243 	    ::g->dc_colormap = ::g->walllights[index];
    244 	    ::g->dc_x = ::g->rw_x;
    245 	    ::g->dc_iscale = 0xffffffffu / (unsigned)::g->rw_scale;
    246 	}
    247 	
    248 	// draw the wall tiers
    249 	if (::g->midtexture)
    250 	{
    251 	    // single sided line
    252 	    ::g->dc_yl = yl;
    253 	    ::g->dc_yh = yh;
    254 	    ::g->dc_texturemid = ::g->rw_midtexturemid;
    255 	    ::g->dc_source = R_GetColumn(::g->midtexture,texturecolumn);
    256 	    colfunc ( ::g->dc_colormap, ::g->dc_source );
    257 	    ::g->ceilingclip[::g->rw_x] = ::g->viewheight;
    258 	    ::g->floorclip[::g->rw_x] = -1;
    259 	}
    260 	else
    261 	{
    262 	    // two sided line
    263 	    if (::g->toptexture)
    264 	    {
    265 			// top wall
    266 			mid = ::g->pixhigh>>HEIGHTBITS;
    267 			::g->pixhigh += ::g->pixhighstep;
    268 
    269 			if (mid >= ::g->floorclip[::g->rw_x])
    270 				mid = ::g->floorclip[::g->rw_x]-1;
    271 
    272 			if (mid >= yl)
    273 			{
    274 				::g->dc_yl = yl;
    275 				::g->dc_yh = mid;
    276 				::g->dc_texturemid = ::g->rw_toptexturemid;
    277 				::g->dc_source = R_GetColumn(::g->toptexture,texturecolumn);
    278 				colfunc ( ::g->dc_colormap, ::g->dc_source );
    279 				::g->ceilingclip[::g->rw_x] = mid;
    280 			}
    281 			else
    282 				::g->ceilingclip[::g->rw_x] = yl-1;
    283 		}
    284 	    else
    285 	    {
    286 			// no top wall
    287 			if (::g->markceiling)
    288 				::g->ceilingclip[::g->rw_x] = yl-1;
    289 		}
    290 			
    291 	    if (::g->bottomtexture)
    292 	    {
    293 			// bottom wall
    294 			mid = (::g->pixlow+HEIGHTUNIT-1)>>HEIGHTBITS;
    295 			::g->pixlow += ::g->pixlowstep;
    296 
    297 			// no space above wall?
    298 			if (mid <= ::g->ceilingclip[::g->rw_x])
    299 				mid = ::g->ceilingclip[::g->rw_x]+1;
    300 			
    301 			if (mid <= yh)
    302 			{
    303 				::g->dc_yl = mid;
    304 				::g->dc_yh = yh;
    305 				::g->dc_texturemid = ::g->rw_bottomtexturemid;
    306 				::g->dc_source = R_GetColumn(::g->bottomtexture,
    307 							texturecolumn);
    308 				colfunc ( ::g->dc_colormap, ::g->dc_source );
    309 				::g->floorclip[::g->rw_x] = mid;
    310 			}
    311 			else
    312 				::g->floorclip[::g->rw_x] = yh+1;
    313 	    }
    314 	    else
    315 	    {
    316 			// no bottom wall
    317 			if (::g->markfloor)
    318 				::g->floorclip[::g->rw_x] = yh+1;
    319 			}
    320 			
    321 			if (::g->maskedtexture)
    322 			{
    323 				// save texturecol
    324 				//  for backdrawing of masked mid texture
    325 				::g->maskedtexturecol[::g->rw_x] = texturecolumn;
    326 			}
    327 		}
    328 		
    329 		::g->rw_scale += ::g->rw_scalestep;
    330 		::g->topfrac += ::g->topstep;
    331 		::g->bottomfrac += ::g->bottomstep;
    332     }
    333 }
    334 
    335 
    336 
    337 
    338 //
    339 // R_StoreWallRange
    340 // A wall segment will be drawn
    341 //  between start and stop pixels (inclusive).
    342 //
    343 void
    344 R_StoreWallRange
    345 ( int	start,
    346   int	stop )
    347 {
    348     fixed_t		hyp;
    349     fixed_t		sineval;
    350     angle_t		distangle, offsetangle;
    351     fixed_t		vtop;
    352     int			lightnum;
    353 
    354     // don't overflow and crash
    355     if (::g->ds_p == &::g->drawsegs[MAXDRAWSEGS])
    356 	return;		
    357 		
    358 #ifdef RANGECHECK
    359     if (start >=::g->viewwidth || start > stop)
    360 	I_Error ("Bad R_RenderWallRange: %i to %i", start , stop);
    361 #endif
    362     
    363     ::g->sidedef = ::g->curline->sidedef;
    364     ::g->linedef = ::g->curline->linedef;
    365 
    366     // mark the segment as visible for auto map
    367     ::g->linedef->flags |= ML_MAPPED;
    368     
    369     // calculate ::g->rw_distance for scale calculation
    370     ::g->rw_normalangle = ::g->curline->angle + ANG90;
    371 	offsetangle = abs((long)(::g->rw_normalangle-::g->rw_angle1));
    372     
    373     if (offsetangle > ANG90)
    374 	offsetangle = ANG90;
    375 
    376     distangle = ANG90 - offsetangle;
    377     hyp = R_PointToDist (::g->curline->v1->x, ::g->curline->v1->y);
    378     sineval = finesine[distangle>>ANGLETOFINESHIFT];
    379     ::g->rw_distance = FixedMul (hyp, sineval);
    380 		
    381 	
    382     ::g->ds_p->x1 = ::g->rw_x = start;
    383     ::g->ds_p->x2 = stop;
    384     ::g->ds_p->curline = ::g->curline;
    385     ::g->rw_stopx = stop+1;
    386     
    387     // calculate scale at both ends and step
    388 	extern angle_t GetViewAngle();
    389     ::g->ds_p->scale1 = ::g->rw_scale = 
    390 	R_ScaleFromGlobalAngle (GetViewAngle() + ::g->xtoviewangle[start]);
    391     
    392     if (stop > start )
    393     {
    394 	::g->ds_p->scale2 = R_ScaleFromGlobalAngle (GetViewAngle() + ::g->xtoviewangle[stop]);
    395 	::g->ds_p->scalestep = ::g->rw_scalestep = 
    396 	    (::g->ds_p->scale2 - ::g->rw_scale) / (stop-start);
    397     }
    398     else
    399     {
    400 	// UNUSED: try to fix the stretched line bug
    401 #if 0
    402 	if (::g->rw_distance < FRACUNIT/2)
    403 	{
    404 	    fixed_t		trx,try;
    405 	    fixed_t		gxt,gyt;
    406 
    407 	extern fixed_t GetViewX(); extern fixed_t GetViewY(); 
    408 	    trx = ::g->curline->v1->x - GetViewX();
    409 	    try = ::g->curline->v1->y - GetVewY();
    410 			
    411 	    gxt = FixedMul(trx,::g->viewcos); 
    412 	    gyt = -FixedMul(try,::g->viewsin); 
    413 	    ::g->ds_p->scale1 = FixedDiv(::g->projection, gxt-gyt) << ::g->detailshift;
    414 	}
    415 #endif
    416 	::g->ds_p->scale2 = ::g->ds_p->scale1;
    417     }
    418     
    419     // calculate texture boundaries
    420     //  and decide if floor / ceiling marks are needed
    421     ::g->worldtop = ::g->frontsector->ceilingheight - ::g->viewz;
    422     ::g->worldbottom = ::g->frontsector->floorheight - ::g->viewz;
    423 	
    424     ::g->midtexture = ::g->toptexture = ::g->bottomtexture = ::g->maskedtexture = 0;
    425     ::g->ds_p->maskedtexturecol = NULL;
    426 	
    427     if (!::g->backsector)
    428     {
    429 	// single sided line
    430 	::g->midtexture = ::g->texturetranslation[::g->sidedef->midtexture];
    431 	// a single sided line is terminal, so it must mark ends
    432 	::g->markfloor = ::g->markceiling = true;
    433 	if (::g->linedef->flags & ML_DONTPEGBOTTOM)
    434 	{
    435 	    vtop = ::g->frontsector->floorheight +
    436 		::g->s_textureheight[::g->sidedef->midtexture];
    437 	    // bottom of texture at bottom
    438 	    ::g->rw_midtexturemid = vtop - ::g->viewz;	
    439 	}
    440 	else
    441 	{
    442 	    // top of texture at top
    443 	    ::g->rw_midtexturemid = ::g->worldtop;
    444 	}
    445 	::g->rw_midtexturemid += ::g->sidedef->rowoffset;
    446 
    447 	::g->ds_p->silhouette = SIL_BOTH;
    448 	::g->ds_p->sprtopclip = ::g->screenheightarray;
    449 	::g->ds_p->sprbottomclip = ::g->negonearray;
    450 	::g->ds_p->bsilheight = MAXINT;
    451 	::g->ds_p->tsilheight = MININT;
    452     }
    453     else
    454     {
    455 	// two sided line
    456 	::g->ds_p->sprtopclip = ::g->ds_p->sprbottomclip = NULL;
    457 	::g->ds_p->silhouette = 0;
    458 	
    459 	if (::g->frontsector->floorheight > ::g->backsector->floorheight)
    460 	{
    461 	    ::g->ds_p->silhouette = SIL_BOTTOM;
    462 	    ::g->ds_p->bsilheight = ::g->frontsector->floorheight;
    463 	}
    464 	else if (::g->backsector->floorheight > ::g->viewz)
    465 	{
    466 	    ::g->ds_p->silhouette = SIL_BOTTOM;
    467 	    ::g->ds_p->bsilheight = MAXINT;
    468 	    // ::g->ds_p->sprbottomclip = ::g->negonearray;
    469 	}
    470 	
    471 	if (::g->frontsector->ceilingheight < ::g->backsector->ceilingheight)
    472 	{
    473 	    ::g->ds_p->silhouette |= SIL_TOP;
    474 	    ::g->ds_p->tsilheight = ::g->frontsector->ceilingheight;
    475 	}
    476 	else if (::g->backsector->ceilingheight < ::g->viewz)
    477 	{
    478 	    ::g->ds_p->silhouette |= SIL_TOP;
    479 	    ::g->ds_p->tsilheight = MININT;
    480 	    // ::g->ds_p->sprtopclip = ::g->screenheightarray;
    481 	}
    482 		
    483 	if (::g->backsector->ceilingheight <= ::g->frontsector->floorheight)
    484 	{
    485 	    ::g->ds_p->sprbottomclip = ::g->negonearray;
    486 	    ::g->ds_p->bsilheight = MAXINT;
    487 	    ::g->ds_p->silhouette |= SIL_BOTTOM;
    488 	}
    489 	
    490 	if (::g->backsector->floorheight >= ::g->frontsector->ceilingheight)
    491 	{
    492 	    ::g->ds_p->sprtopclip = ::g->screenheightarray;
    493 	    ::g->ds_p->tsilheight = MININT;
    494 	    ::g->ds_p->silhouette |= SIL_TOP;
    495 	}
    496 	
    497 	::g->worldhigh = ::g->backsector->ceilingheight - ::g->viewz;
    498 	::g->worldlow = ::g->backsector->floorheight - ::g->viewz;
    499 		
    500 	// hack to allow height changes in outdoor areas
    501 	if (::g->frontsector->ceilingpic == ::g->skyflatnum 
    502 	    && ::g->backsector->ceilingpic == ::g->skyflatnum)
    503 	{
    504 	    ::g->worldtop = ::g->worldhigh;
    505 	}
    506 	
    507 			
    508 	if (::g->worldlow != ::g->worldbottom 
    509 	    || ::g->backsector->floorpic != ::g->frontsector->floorpic
    510 	    || ::g->backsector->lightlevel != ::g->frontsector->lightlevel)
    511 	{
    512 	    ::g->markfloor = true;
    513 	}
    514 	else
    515 	{
    516 	    // same plane on both ::g->sides
    517 	    ::g->markfloor = false;
    518 	}
    519 	
    520 			
    521 	if (::g->worldhigh != ::g->worldtop 
    522 	    || ::g->backsector->ceilingpic != ::g->frontsector->ceilingpic
    523 	    || ::g->backsector->lightlevel != ::g->frontsector->lightlevel)
    524 	{
    525 	    ::g->markceiling = true;
    526 	}
    527 	else
    528 	{
    529 	    // same plane on both ::g->sides
    530 	    ::g->markceiling = false;
    531 	}
    532 	
    533 	if (::g->backsector->ceilingheight <= ::g->frontsector->floorheight
    534 	    || ::g->backsector->floorheight >= ::g->frontsector->ceilingheight)
    535 	{
    536 	    // closed door
    537 	    ::g->markceiling = ::g->markfloor = true;
    538 	}
    539 	
    540 
    541 	if (::g->worldhigh < ::g->worldtop)
    542 	{
    543 	    // top texture
    544 	    ::g->toptexture = ::g->texturetranslation[::g->sidedef->toptexture];
    545 	    if (::g->linedef->flags & ML_DONTPEGTOP)
    546 	    {
    547 		// top of texture at top
    548 		::g->rw_toptexturemid = ::g->worldtop;
    549 	    }
    550 	    else
    551 	    {
    552 		vtop =
    553 		    ::g->backsector->ceilingheight
    554 		    + ::g->s_textureheight[::g->sidedef->toptexture];
    555 		
    556 		// bottom of texture
    557 		::g->rw_toptexturemid = vtop - ::g->viewz;	
    558 	    }
    559 	}
    560 	if (::g->worldlow > ::g->worldbottom)
    561 	{
    562 	    // bottom texture
    563 	    ::g->bottomtexture = ::g->texturetranslation[::g->sidedef->bottomtexture];
    564 
    565 	    if (::g->linedef->flags & ML_DONTPEGBOTTOM )
    566 	    {
    567 		// bottom of texture at bottom
    568 		// top of texture at top
    569 		::g->rw_bottomtexturemid = ::g->worldtop;
    570 	    }
    571 	    else	// top of texture at top
    572 		::g->rw_bottomtexturemid = ::g->worldlow;
    573 	}
    574 	::g->rw_toptexturemid += ::g->sidedef->rowoffset;
    575 	::g->rw_bottomtexturemid += ::g->sidedef->rowoffset;
    576 	
    577 	// allocate space for masked texture tables
    578 	if (::g->sidedef->midtexture)
    579 	{
    580 	    // masked ::g->midtexture
    581 	    ::g->maskedtexture = true;
    582 	    ::g->ds_p->maskedtexturecol = ::g->maskedtexturecol = ::g->lastopening - ::g->rw_x;
    583 	    ::g->lastopening += ::g->rw_stopx - ::g->rw_x;
    584 	}
    585     }
    586     
    587     // calculate ::g->rw_offset (only needed for textured ::g->lines)
    588     ::g->segtextured = ::g->midtexture | ::g->toptexture | ::g->bottomtexture | ::g->maskedtexture;
    589 
    590     if (::g->segtextured)
    591     {
    592 		offsetangle = ::g->rw_normalangle-::g->rw_angle1;
    593 		
    594 		if (offsetangle > ANG180)
    595 			offsetangle = -offsetangle; // ALANHACK UNSIGNED
    596 
    597 		if (offsetangle > ANG90)
    598 			offsetangle = ANG90;
    599 
    600 		sineval = finesine[offsetangle >>ANGLETOFINESHIFT];
    601 		::g->rw_offset = FixedMul (hyp, sineval);
    602 
    603 		if (::g->rw_normalangle-::g->rw_angle1 < ANG180)
    604 			::g->rw_offset = -::g->rw_offset;
    605 
    606 		::g->rw_offset += ::g->sidedef->textureoffset + ::g->curline->offset;
    607 		::g->rw_centerangle = ANG90 + GetViewAngle() - ::g->rw_normalangle;
    608 		
    609 		// calculate light table
    610 		//  use different light tables
    611 		//  for horizontal / vertical / diagonal
    612 		// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
    613 		if (!::g->fixedcolormap)
    614 		{
    615 			lightnum = (::g->frontsector->lightlevel >> LIGHTSEGSHIFT)+::g->extralight;
    616 
    617 			if (::g->curline->v1->y == ::g->curline->v2->y)
    618 			lightnum--;
    619 			else if (::g->curline->v1->x == ::g->curline->v2->x)
    620 			lightnum++;
    621 
    622 			if (lightnum < 0)		
    623 			::g->walllights = ::g->scalelight[0];
    624 			else if (lightnum >= LIGHTLEVELS)
    625 			::g->walllights = ::g->scalelight[LIGHTLEVELS-1];
    626 			else
    627 			::g->walllights = ::g->scalelight[lightnum];
    628 		}
    629     }
    630     
    631     // if a floor / ceiling plane is on the wrong side
    632     //  of the view plane, it is definitely invisible
    633     //  and doesn't need to be marked.
    634     
    635   
    636     if (::g->frontsector->floorheight >= ::g->viewz)
    637     {
    638 	// above view plane
    639 	::g->markfloor = false;
    640     }
    641     
    642     if (::g->frontsector->ceilingheight <= ::g->viewz 
    643 	&& ::g->frontsector->ceilingpic != ::g->skyflatnum)
    644     {
    645 	// below view plane
    646 	::g->markceiling = false;
    647     }
    648 
    649     
    650     // calculate incremental stepping values for texture edges
    651     ::g->worldtop >>= 4;
    652     ::g->worldbottom >>= 4;
    653 	
    654     ::g->topstep = -FixedMul (::g->rw_scalestep, ::g->worldtop);
    655     ::g->topfrac = (::g->centeryfrac>>4) - FixedMul (::g->worldtop, ::g->rw_scale);
    656 
    657     ::g->bottomstep = -FixedMul (::g->rw_scalestep,::g->worldbottom);
    658     ::g->bottomfrac = (::g->centeryfrac>>4) - FixedMul (::g->worldbottom, ::g->rw_scale);
    659 	
    660     if (::g->backsector)
    661     {	
    662 	::g->worldhigh >>= 4;
    663 	::g->worldlow >>= 4;
    664 
    665 	if (::g->worldhigh < ::g->worldtop)
    666 	{
    667 	    ::g->pixhigh = (::g->centeryfrac>>4) - FixedMul (::g->worldhigh, ::g->rw_scale);
    668 	    ::g->pixhighstep = -FixedMul (::g->rw_scalestep,::g->worldhigh);
    669 	}
    670 	
    671 	if (::g->worldlow > ::g->worldbottom)
    672 	{
    673 	    ::g->pixlow = (::g->centeryfrac>>4) - FixedMul (::g->worldlow, ::g->rw_scale);
    674 	    ::g->pixlowstep = -FixedMul (::g->rw_scalestep,::g->worldlow);
    675 	}
    676     }
    677     
    678     // render it
    679 	 if (::g->markceiling)
    680 		 ::g->ceilingplane = R_CheckPlane (::g->ceilingplane, ::g->rw_x, ::g->rw_stopx-1);
    681 
    682 	 if (::g->markfloor)
    683 		 ::g->floorplane = R_CheckPlane (::g->floorplane, ::g->rw_x, ::g->rw_stopx-1);
    684 
    685     R_RenderSegLoop ();
    686 
    687     
    688     // save sprite clipping info
    689     if ( ((::g->ds_p->silhouette & SIL_TOP) || ::g->maskedtexture)
    690 	 && !::g->ds_p->sprtopclip)
    691     {
    692 	memcpy (::g->lastopening, ::g->ceilingclip+start, 2*(::g->rw_stopx-start));
    693 	::g->ds_p->sprtopclip = ::g->lastopening - start;
    694 	::g->lastopening += ::g->rw_stopx - start;
    695     }
    696     
    697     if ( ((::g->ds_p->silhouette & SIL_BOTTOM) || ::g->maskedtexture)
    698 	 && !::g->ds_p->sprbottomclip)
    699     {
    700 	memcpy (::g->lastopening, ::g->floorclip+start, 2*(::g->rw_stopx-start));
    701 	::g->ds_p->sprbottomclip = ::g->lastopening - start;
    702 	::g->lastopening += ::g->rw_stopx - start;	
    703     }
    704 
    705     if (::g->maskedtexture && !(::g->ds_p->silhouette&SIL_TOP))
    706     {
    707 	::g->ds_p->silhouette |= SIL_TOP;
    708 	::g->ds_p->tsilheight = MININT;
    709     }
    710     if (::g->maskedtexture && !(::g->ds_p->silhouette&SIL_BOTTOM))
    711     {
    712 	::g->ds_p->silhouette |= SIL_BOTTOM;
    713 	::g->ds_p->bsilheight = MAXINT;
    714     }
    715     ::g->ds_p++;
    716 }
    717 
    718