forked from len0rd/rockbox
Patch #2969 - Doom! Currently only working on the H300.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9312 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
fff7d6157d
commit
47f4a458d6
130 changed files with 65584 additions and 1 deletions
843
apps/plugins/doom/r_segs.c
Normal file
843
apps/plugins/doom/r_segs.c
Normal file
|
@ -0,0 +1,843 @@
|
|||
/* Emacs style mode select -*- C++ -*-
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
*
|
||||
* PrBoom a Doom port merged with LxDoom and LSDLDoom
|
||||
* based on BOOM, a modified and improved DOOM engine
|
||||
* Copyright (C) 1999 by
|
||||
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
|
||||
* Copyright (C) 1999-2000 by
|
||||
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* All the clipping: columns, horizontal spans, sky columns.
|
||||
*
|
||||
*-----------------------------------------------------------------------------*/
|
||||
//
|
||||
// 4/25/98, 5/2/98 killough: reformatted, beautified
|
||||
|
||||
#include "doomstat.h"
|
||||
#include "r_main.h"
|
||||
#include "r_bsp.h"
|
||||
#include "r_plane.h"
|
||||
#include "r_things.h"
|
||||
#include "r_draw.h"
|
||||
#include "w_wad.h"
|
||||
//#include "lprintf.h"
|
||||
#include "rockmacros.h"
|
||||
|
||||
// OPTIMIZE: closed two sided lines as single sided
|
||||
|
||||
// killough 1/6/98: replaced globals with statics where appropriate
|
||||
|
||||
// True if any of the segs textures might be visible.
|
||||
boolean segtextured;
|
||||
boolean markfloor; // False if the back side is the same plane.
|
||||
boolean markceiling;
|
||||
static boolean maskedtexture;
|
||||
static int toptexture;
|
||||
static int bottomtexture;
|
||||
static int midtexture;
|
||||
|
||||
static fixed_t toptexheight, midtexheight, bottomtexheight; // cph
|
||||
|
||||
angle_t rw_normalangle;// angle to line origin
|
||||
int rw_angle1;
|
||||
fixed_t rw_distance;
|
||||
lighttable_t** walllights;
|
||||
|
||||
//
|
||||
// regular wall
|
||||
//
|
||||
int rw_x;
|
||||
int rw_stopx;
|
||||
static angle_t rw_centerangle;
|
||||
static fixed_t rw_offset;
|
||||
static fixed_t rw_scale;
|
||||
static fixed_t rw_scalestep;
|
||||
static fixed_t rw_midtexturemid;
|
||||
static fixed_t rw_toptexturemid;
|
||||
static fixed_t rw_bottomtexturemid;
|
||||
static int worldtop;
|
||||
static int worldbottom;
|
||||
static int worldhigh;
|
||||
static int worldlow;
|
||||
static fixed_t pixhigh;
|
||||
static fixed_t pixlow;
|
||||
static fixed_t pixhighstep;
|
||||
static fixed_t pixlowstep;
|
||||
static fixed_t topfrac;
|
||||
static fixed_t topstep;
|
||||
static fixed_t bottomfrac;
|
||||
static fixed_t bottomstep;
|
||||
static short *maskedtexturecol;
|
||||
|
||||
//
|
||||
// R_ScaleFromGlobalAngle
|
||||
// Returns the texture mapping scale
|
||||
// for the current line (horizontal span)
|
||||
// at the given angle.
|
||||
// rw_distance must be calculated first.
|
||||
//
|
||||
// killough 5/2/98: reformatted, cleaned up
|
||||
static fixed_t R_ScaleFromGlobalAngle (angle_t visangle)
|
||||
{
|
||||
int anglea = ANG90 + (visangle-viewangle);
|
||||
int angleb = ANG90 + (visangle-rw_normalangle);
|
||||
int sinea = finesine[anglea>>ANGLETOFINESHIFT];
|
||||
int sineb = finesine[angleb>>ANGLETOFINESHIFT];
|
||||
fixed_t num = FixedMul(projection,sineb);
|
||||
int den = FixedMul(rw_distance,sinea);
|
||||
|
||||
return den > num>>16 ? (num=FixedDiv (num, den)) > 64*FRACUNIT ?
|
||||
64*FRACUNIT : num < 256 ? 256 : num : 64*FRACUNIT ;
|
||||
}
|
||||
//
|
||||
// R_RenderMaskedSegRange
|
||||
//
|
||||
|
||||
int fake_contrast IBSS_ATTR;
|
||||
|
||||
void R_RenderMaskedSegRange(drawseg_t *ds, int x1, int x2)
|
||||
{
|
||||
column_t *col;
|
||||
int lightnum;
|
||||
int texnum;
|
||||
sector_t tempsec; // killough 4/13/98
|
||||
|
||||
// Calculate light table.
|
||||
// Use different light tables
|
||||
// for horizontal / vertical / diagonal. Diagonal?
|
||||
|
||||
curline = ds->curline; // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
|
||||
|
||||
// killough 4/11/98: draw translucent 2s normal textures
|
||||
|
||||
colfunc = R_DrawColumn;
|
||||
if (curline->linedef->tranlump >= 0 && general_translucency)
|
||||
{
|
||||
colfunc = R_DrawTLColumn;
|
||||
tranmap = main_tranmap;
|
||||
if (curline->linedef->tranlump > 0)
|
||||
tranmap = W_CacheLumpNum(curline->linedef->tranlump-1);
|
||||
}
|
||||
|
||||
// killough 4/11/98: end translucent 2s normal code
|
||||
|
||||
frontsector = curline->frontsector;
|
||||
backsector = curline->backsector;
|
||||
|
||||
texnum = texturetranslation[curline->sidedef->midtexture];
|
||||
|
||||
// killough 4/13/98: get correct lightlevel for 2s normal textures
|
||||
lightnum = (R_FakeFlat(frontsector, &tempsec, NULL, NULL, false)
|
||||
->lightlevel >> LIGHTSEGSHIFT)+extralight;
|
||||
|
||||
/* cph - ...what is this for? adding contrast to rooms?
|
||||
* It looks crap in outdoor areas */
|
||||
if (fake_contrast) {
|
||||
if (curline->v1->y == curline->v2->y)
|
||||
lightnum--;
|
||||
else
|
||||
if (curline->v1->x == curline->v2->x)
|
||||
lightnum++;
|
||||
}
|
||||
|
||||
walllights = lightnum >= LIGHTLEVELS ? scalelight[LIGHTLEVELS-1] :
|
||||
lightnum < 0 ? scalelight[0] : scalelight[lightnum];
|
||||
|
||||
maskedtexturecol = ds->maskedtexturecol;
|
||||
|
||||
rw_scalestep = ds->scalestep;
|
||||
spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
|
||||
mfloorclip = ds->sprbottomclip;
|
||||
mceilingclip = ds->sprtopclip;
|
||||
|
||||
// find positioning
|
||||
if (curline->linedef->flags & ML_DONTPEGBOTTOM)
|
||||
{
|
||||
dc_texturemid = frontsector->floorheight > backsector->floorheight
|
||||
? frontsector->floorheight : backsector->floorheight;
|
||||
dc_texturemid = dc_texturemid + textureheight[texnum] - viewz;
|
||||
}
|
||||
else
|
||||
{
|
||||
dc_texturemid =frontsector->ceilingheight<backsector->ceilingheight
|
||||
? frontsector->ceilingheight : backsector->ceilingheight;
|
||||
dc_texturemid = dc_texturemid - viewz;
|
||||
}
|
||||
|
||||
dc_texturemid += curline->sidedef->rowoffset;
|
||||
|
||||
if (fixedcolormap)
|
||||
dc_colormap = fixedcolormap;
|
||||
|
||||
// draw the columns
|
||||
for (dc_x = x1 ; dc_x <= x2 ; dc_x++, spryscale += rw_scalestep)
|
||||
if (maskedtexturecol[dc_x] != SHRT_MAX)
|
||||
{
|
||||
if (!fixedcolormap) // calculate lighting
|
||||
{
|
||||
unsigned index = spryscale>>LIGHTSCALESHIFT;
|
||||
|
||||
if (index >= MAXLIGHTSCALE )
|
||||
index = MAXLIGHTSCALE-1;
|
||||
|
||||
dc_colormap = walllights[index];
|
||||
}
|
||||
|
||||
// killough 3/2/98:
|
||||
//
|
||||
// This calculation used to overflow and cause crashes in Doom:
|
||||
//
|
||||
// sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
|
||||
//
|
||||
// This code fixes it, by using double-precision intermediate
|
||||
// arithmetic and by skipping the drawing of 2s normals whose
|
||||
// mapping to screen coordinates is totally out of range:
|
||||
|
||||
{
|
||||
int_64_t t = ((int_64_t) centeryfrac << FRACBITS) -
|
||||
(int_64_t) dc_texturemid * spryscale;
|
||||
if (t + (int_64_t) textureheight[texnum] * spryscale < 0 ||
|
||||
t > (int_64_t) SCREENHEIGHT << FRACBITS*2)
|
||||
continue; // skip if the texture is out of screen's range
|
||||
sprtopscreen = (long)(t >> FRACBITS);
|
||||
}
|
||||
|
||||
dc_iscale = 0xffffffffu / (unsigned) spryscale;
|
||||
|
||||
// killough 1/25/98: here's where Medusa came in, because
|
||||
// it implicitly assumed that the column was all one patch.
|
||||
// Originally, Doom did not construct complete columns for
|
||||
// multipatched textures, so there were no header or trailer
|
||||
// bytes in the column referred to below, which explains
|
||||
// the Medusa effect. The fix is to construct true columns
|
||||
// when forming multipatched textures (see r_data.c).
|
||||
|
||||
// draw the texture
|
||||
col = (column_t *)((byte *)
|
||||
R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3);
|
||||
R_DrawMaskedColumn (col);
|
||||
maskedtexturecol[dc_x] = SHRT_MAX;
|
||||
}
|
||||
|
||||
// Except for main_tranmap, mark others purgable at this point
|
||||
if (curline->linedef->tranlump > 0 && general_translucency)
|
||||
W_UnlockLumpNum(curline->linedef->tranlump-1); // cph - unlock it
|
||||
}
|
||||
|
||||
//
|
||||
// R_RenderSegLoop
|
||||
// Draws zero, one, or two textures (and possibly a masked texture) for walls.
|
||||
// Can draw or mark the starting pixel of floor and ceiling textures.
|
||||
// CALLED: CORE LOOPING ROUTINE.
|
||||
//
|
||||
|
||||
extern byte solidcol[SCREENWIDTH];
|
||||
#define HEIGHTBITS 12
|
||||
#define HEIGHTUNIT (1<<HEIGHTBITS)
|
||||
static int didsolidcol; /* True if at least one column was marked solid */
|
||||
|
||||
static void R_RenderSegLoop (void)
|
||||
{
|
||||
fixed_t texturecolumn = 0; // shut up compiler warning
|
||||
for ( ; rw_x < rw_stopx ; rw_x++)
|
||||
{
|
||||
|
||||
// mark floor / ceiling areas
|
||||
|
||||
int yh = bottomfrac>>HEIGHTBITS;
|
||||
int yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS;
|
||||
|
||||
// no space above wall?
|
||||
int bottom,top = ceilingclip[rw_x]+1;
|
||||
|
||||
if (yl < top)
|
||||
yl = top;
|
||||
|
||||
if (markceiling)
|
||||
{
|
||||
bottom = yl-1;
|
||||
|
||||
if (bottom >= floorclip[rw_x])
|
||||
bottom = floorclip[rw_x]-1;
|
||||
|
||||
if (top <= bottom)
|
||||
{
|
||||
ceilingplane->top[rw_x] = top;
|
||||
ceilingplane->bottom[rw_x] = bottom;
|
||||
}
|
||||
}
|
||||
|
||||
// yh = bottomfrac>>HEIGHTBITS;
|
||||
|
||||
bottom = floorclip[rw_x]-1;
|
||||
if (yh > bottom)
|
||||
yh = bottom;
|
||||
|
||||
if (markfloor)
|
||||
{
|
||||
|
||||
top = yh < ceilingclip[rw_x] ? ceilingclip[rw_x] : yh;
|
||||
|
||||
if (++top <= bottom)
|
||||
{
|
||||
floorplane->top[rw_x] = top;
|
||||
floorplane->bottom[rw_x] = bottom;
|
||||
}
|
||||
}
|
||||
|
||||
// texturecolumn and lighting are independent of wall tiers
|
||||
if (segtextured)
|
||||
{
|
||||
unsigned index;
|
||||
|
||||
// calculate texture offset
|
||||
angle_t angle =(rw_centerangle+xtoviewangle[rw_x])>>ANGLETOFINESHIFT;
|
||||
|
||||
texturecolumn = rw_offset-FixedMul(finetangent[angle],rw_distance);
|
||||
texturecolumn >>= FRACBITS;
|
||||
// calculate lighting
|
||||
index = rw_scale>>LIGHTSCALESHIFT;
|
||||
|
||||
if (index >= MAXLIGHTSCALE )
|
||||
index = MAXLIGHTSCALE-1;
|
||||
|
||||
dc_colormap = walllights[index];
|
||||
dc_x = rw_x;
|
||||
dc_iscale = 0xffffffffu / (unsigned)rw_scale;
|
||||
}
|
||||
|
||||
// draw the wall tiers
|
||||
if (midtexture)
|
||||
{
|
||||
|
||||
dc_yl = yl; // single sided line
|
||||
dc_yh = yh;
|
||||
dc_texturemid = rw_midtexturemid;
|
||||
dc_source = R_GetColumn(midtexture, texturecolumn);
|
||||
dc_texheight = midtexheight;
|
||||
colfunc ();
|
||||
ceilingclip[rw_x] = viewheight;
|
||||
floorclip[rw_x] = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// two sided line
|
||||
if (toptexture)
|
||||
{
|
||||
// top wall
|
||||
int mid = pixhigh>>HEIGHTBITS;
|
||||
pixhigh += pixhighstep;
|
||||
|
||||
if (mid >= floorclip[rw_x])
|
||||
mid = floorclip[rw_x]-1;
|
||||
|
||||
if (mid >= yl)
|
||||
{
|
||||
dc_yl = yl;
|
||||
dc_yh = mid;
|
||||
dc_texturemid = rw_toptexturemid;
|
||||
dc_source = R_GetColumn(toptexture,texturecolumn);
|
||||
dc_texheight = toptexheight;
|
||||
colfunc ();
|
||||
ceilingclip[rw_x] = mid;
|
||||
}
|
||||
else
|
||||
ceilingclip[rw_x] = yl-1;
|
||||
}
|
||||
else // no top wall
|
||||
{
|
||||
|
||||
if (markceiling)
|
||||
ceilingclip[rw_x] = yl-1;
|
||||
}
|
||||
|
||||
if (bottomtexture) // bottom wall
|
||||
{
|
||||
int mid = (pixlow+HEIGHTUNIT-1)>>HEIGHTBITS;
|
||||
pixlow += pixlowstep;
|
||||
|
||||
// no space above wall?
|
||||
if (mid <= ceilingclip[rw_x])
|
||||
mid = ceilingclip[rw_x]+1;
|
||||
|
||||
if (mid <= yh)
|
||||
{
|
||||
dc_yl = mid;
|
||||
dc_yh = yh;
|
||||
dc_texturemid = rw_bottomtexturemid;
|
||||
dc_source = R_GetColumn(bottomtexture,
|
||||
texturecolumn);
|
||||
dc_texheight = bottomtexheight;
|
||||
colfunc ();
|
||||
floorclip[rw_x] = mid;
|
||||
}
|
||||
else
|
||||
floorclip[rw_x] = yh+1;
|
||||
}
|
||||
else // no bottom wall
|
||||
{
|
||||
if (markfloor)
|
||||
floorclip[rw_x] = yh+1;
|
||||
}
|
||||
|
||||
// cph - if we completely blocked further sight through this column,
|
||||
// add this info to the solid columns array for r_bsp.c
|
||||
if ((markceiling || markfloor) &&
|
||||
(floorclip[rw_x] <= ceilingclip[rw_x] + 1)) {
|
||||
solidcol[rw_x] = 1; didsolidcol = 1;
|
||||
}
|
||||
|
||||
// save texturecol for backdrawing of masked mid texture
|
||||
if (maskedtexture)
|
||||
maskedtexturecol[rw_x] = texturecolumn;
|
||||
}
|
||||
|
||||
rw_scale += rw_scalestep;
|
||||
topfrac += topstep;
|
||||
bottomfrac += bottomstep;
|
||||
}
|
||||
}
|
||||
|
||||
// killough 5/2/98: move from r_main.c, made static, simplified
|
||||
|
||||
static fixed_t R_PointToDist(fixed_t x, fixed_t y)
|
||||
{
|
||||
fixed_t dx = D_abs(x - viewx);
|
||||
fixed_t dy = D_abs(y - viewy);
|
||||
|
||||
if (dy > dx)
|
||||
{
|
||||
fixed_t t = dx;
|
||||
dx = dy;
|
||||
dy = t;
|
||||
}
|
||||
|
||||
return FixedDiv(dx, finesine[(tantoangle[FixedDiv(dy,dx) >> DBITS]
|
||||
+ ANG90) >> ANGLETOFINESHIFT]);
|
||||
}
|
||||
|
||||
//
|
||||
// R_StoreWallRange
|
||||
// A wall segment will be drawn
|
||||
// between start and stop pixels (inclusive).
|
||||
//
|
||||
void R_StoreWallRange(const int start, const int stop)
|
||||
{
|
||||
fixed_t hyp;
|
||||
fixed_t sineval;
|
||||
angle_t distangle, offsetangle;
|
||||
|
||||
if (ds_p == drawsegs+maxdrawsegs) // killough 1/98 -- fix 2s line HOM
|
||||
{
|
||||
unsigned pos = ds_p - drawsegs; // jff 8/9/98 fix from ZDOOM1.14a
|
||||
unsigned newmax = maxdrawsegs ? maxdrawsegs*2 : 128; // killough
|
||||
drawsegs = realloc(drawsegs,newmax*sizeof(*drawsegs));
|
||||
ds_p = drawsegs + pos; // jff 8/9/98 fix from ZDOOM1.14a
|
||||
maxdrawsegs = newmax;
|
||||
}
|
||||
|
||||
if(curline->miniseg == false) // figgi -- skip minisegs
|
||||
curline->linedef->flags |= ML_MAPPED;
|
||||
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (start >=viewwidth || start > stop)
|
||||
I_Error ("Bad R_RenderWallRange: %i to %i", start , stop);
|
||||
#endif
|
||||
|
||||
sidedef = curline->sidedef;
|
||||
linedef = curline->linedef;
|
||||
|
||||
// mark the segment as visible for auto map
|
||||
linedef->flags |= ML_MAPPED;
|
||||
|
||||
// calculate rw_distance for scale calculation
|
||||
rw_normalangle = curline->angle + ANG90;
|
||||
|
||||
offsetangle = D_abs(rw_normalangle-rw_angle1);
|
||||
|
||||
if (offsetangle > ANG90)
|
||||
offsetangle = ANG90;
|
||||
|
||||
distangle = ANG90 - offsetangle;
|
||||
hyp = (viewx==curline->v1->x && viewy==curline->v1->y)?
|
||||
0 : R_PointToDist (curline->v1->x, curline->v1->y);
|
||||
sineval = finesine[distangle>>ANGLETOFINESHIFT];
|
||||
rw_distance = FixedMul(hyp, sineval);
|
||||
|
||||
ds_p->x1 = rw_x = start;
|
||||
ds_p->x2 = stop;
|
||||
ds_p->curline = curline;
|
||||
rw_stopx = stop+1;
|
||||
|
||||
{ // killough 1/6/98, 2/1/98: remove limit on openings
|
||||
extern short *openings;
|
||||
extern size_t maxopenings;
|
||||
size_t pos = lastopening - openings;
|
||||
size_t need = (rw_stopx - start)*4 + pos;
|
||||
if (need > maxopenings)
|
||||
{
|
||||
drawseg_t *ds; //jff 8/9/98 needed for fix from ZDoom
|
||||
short *oldopenings = openings;
|
||||
short *oldlast = lastopening;
|
||||
|
||||
do
|
||||
maxopenings = maxopenings ? maxopenings*2 : 16384;
|
||||
while (need > maxopenings);
|
||||
openings = realloc(openings, maxopenings * sizeof(*openings));
|
||||
lastopening = openings + pos;
|
||||
|
||||
// jff 8/9/98 borrowed fix for openings from ZDOOM1.14
|
||||
// [RH] We also need to adjust the openings pointers that
|
||||
// were already stored in drawsegs.
|
||||
for (ds = drawsegs; ds < ds_p; ds++)
|
||||
{
|
||||
#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast)\
|
||||
ds->p = ds->p - oldopenings + openings;
|
||||
ADJUST (maskedtexturecol);
|
||||
ADJUST (sprtopclip);
|
||||
ADJUST (sprbottomclip);
|
||||
}
|
||||
#undef ADJUST
|
||||
}
|
||||
} // killough: end of code to remove limits on openings
|
||||
|
||||
// calculate scale at both ends and step
|
||||
|
||||
ds_p->scale1 = rw_scale =
|
||||
R_ScaleFromGlobalAngle (viewangle + xtoviewangle[start]);
|
||||
|
||||
if (stop > start)
|
||||
{
|
||||
ds_p->scale2 = R_ScaleFromGlobalAngle (viewangle + xtoviewangle[stop]);
|
||||
ds_p->scalestep = rw_scalestep = (ds_p->scale2-rw_scale) / (stop-start);
|
||||
}
|
||||
else
|
||||
ds_p->scale2 = ds_p->scale1;
|
||||
|
||||
// calculate texture boundaries
|
||||
// and decide if floor / ceiling marks are needed
|
||||
|
||||
worldtop = frontsector->ceilingheight - viewz;
|
||||
worldbottom = frontsector->floorheight - viewz;
|
||||
|
||||
midtexture = toptexture = bottomtexture = maskedtexture = 0;
|
||||
ds_p->maskedtexturecol = NULL;
|
||||
|
||||
if (!backsector)
|
||||
{
|
||||
// single sided line
|
||||
midtexture = texturetranslation[sidedef->midtexture];
|
||||
midtexheight = (linedef->r_flags & RF_MID_TILE) ? 0 : textureheight[midtexture] >> FRACBITS;
|
||||
|
||||
// a single sided line is terminal, so it must mark ends
|
||||
markfloor = markceiling = true;
|
||||
|
||||
if (linedef->flags & ML_DONTPEGBOTTOM)
|
||||
{ // bottom of texture at bottom
|
||||
fixed_t vtop = frontsector->floorheight +
|
||||
textureheight[sidedef->midtexture];
|
||||
rw_midtexturemid = vtop - viewz;
|
||||
}
|
||||
else // top of texture at top
|
||||
rw_midtexturemid = worldtop;
|
||||
|
||||
rw_midtexturemid += FixedMod(sidedef->rowoffset, textureheight[midtexture]);
|
||||
|
||||
ds_p->silhouette = SIL_BOTH;
|
||||
ds_p->sprtopclip = screenheightarray;
|
||||
ds_p->sprbottomclip = negonearray;
|
||||
ds_p->bsilheight = INT_MAX;
|
||||
ds_p->tsilheight = INT_MIN;
|
||||
}
|
||||
else // two sided line
|
||||
{
|
||||
ds_p->sprtopclip = ds_p->sprbottomclip = NULL;
|
||||
ds_p->silhouette = 0;
|
||||
|
||||
if (linedef->r_flags & RF_CLOSED) { /* cph - closed 2S line e.g. door */
|
||||
// cph - killough's (outdated) comment follows - this deals with both
|
||||
// "automap fixes", his and mine
|
||||
// killough 1/17/98: this test is required if the fix
|
||||
// for the automap bug (r_bsp.c) is used, or else some
|
||||
// sprites will be displayed behind closed doors. That
|
||||
// fix prevents lines behind closed doors with dropoffs
|
||||
// from being displayed on the automap.
|
||||
|
||||
ds_p->silhouette = SIL_BOTH;
|
||||
ds_p->sprbottomclip = negonearray;
|
||||
ds_p->bsilheight = INT_MAX;
|
||||
ds_p->sprtopclip = screenheightarray;
|
||||
ds_p->tsilheight = INT_MIN;
|
||||
|
||||
} else { /* not solid - old code */
|
||||
|
||||
if (frontsector->floorheight > backsector->floorheight)
|
||||
{
|
||||
ds_p->silhouette = SIL_BOTTOM;
|
||||
ds_p->bsilheight = frontsector->floorheight;
|
||||
}
|
||||
else
|
||||
if (backsector->floorheight > viewz)
|
||||
{
|
||||
ds_p->silhouette = SIL_BOTTOM;
|
||||
ds_p->bsilheight = INT_MAX;
|
||||
}
|
||||
|
||||
if (frontsector->ceilingheight < backsector->ceilingheight)
|
||||
{
|
||||
ds_p->silhouette |= SIL_TOP;
|
||||
ds_p->tsilheight = frontsector->ceilingheight;
|
||||
}
|
||||
else
|
||||
if (backsector->ceilingheight < viewz)
|
||||
{
|
||||
ds_p->silhouette |= SIL_TOP;
|
||||
ds_p->tsilheight = INT_MIN;
|
||||
}
|
||||
}
|
||||
|
||||
worldhigh = backsector->ceilingheight - viewz;
|
||||
worldlow = backsector->floorheight - viewz;
|
||||
|
||||
// hack to allow height changes in outdoor areas
|
||||
if (frontsector->ceilingpic == skyflatnum
|
||||
&& backsector->ceilingpic == skyflatnum)
|
||||
worldtop = worldhigh;
|
||||
|
||||
markfloor = worldlow != worldbottom
|
||||
|| backsector->floorpic != frontsector->floorpic
|
||||
|| backsector->lightlevel != frontsector->lightlevel
|
||||
|
||||
// killough 3/7/98: Add checks for (x,y) offsets
|
||||
|| backsector->floor_xoffs != frontsector->floor_xoffs
|
||||
|| backsector->floor_yoffs != frontsector->floor_yoffs
|
||||
|
||||
// killough 4/15/98: prevent 2s normals
|
||||
// from bleeding through deep water
|
||||
|| frontsector->heightsec != -1
|
||||
|
||||
// killough 4/17/98: draw floors if different light levels
|
||||
|| backsector->floorlightsec != frontsector->floorlightsec
|
||||
;
|
||||
|
||||
markceiling = worldhigh != worldtop
|
||||
|| backsector->ceilingpic != frontsector->ceilingpic
|
||||
|| backsector->lightlevel != frontsector->lightlevel
|
||||
|
||||
// killough 3/7/98: Add checks for (x,y) offsets
|
||||
|| backsector->ceiling_xoffs != frontsector->ceiling_xoffs
|
||||
|| backsector->ceiling_yoffs != frontsector->ceiling_yoffs
|
||||
|
||||
// killough 4/15/98: prevent 2s normals
|
||||
// from bleeding through fake ceilings
|
||||
|| (frontsector->heightsec != -1 &&
|
||||
frontsector->ceilingpic!=skyflatnum)
|
||||
|
||||
// killough 4/17/98: draw ceilings if different light levels
|
||||
|| backsector->ceilinglightsec != frontsector->ceilinglightsec
|
||||
;
|
||||
|
||||
if (backsector->ceilingheight <= frontsector->floorheight
|
||||
|| backsector->floorheight >= frontsector->ceilingheight)
|
||||
markceiling = markfloor = true; // closed door
|
||||
|
||||
if (worldhigh < worldtop) // top texture
|
||||
{
|
||||
toptexture = texturetranslation[sidedef->toptexture];
|
||||
toptexheight = (linedef->r_flags & RF_TOP_TILE) ? 0 : textureheight[toptexture] >> FRACBITS;
|
||||
rw_toptexturemid = linedef->flags & ML_DONTPEGTOP ? worldtop :
|
||||
backsector->ceilingheight+textureheight[sidedef->toptexture]-viewz;
|
||||
rw_toptexturemid += FixedMod(sidedef->rowoffset, textureheight[toptexture]);
|
||||
}
|
||||
|
||||
if (worldlow > worldbottom) // bottom texture
|
||||
{
|
||||
bottomtexture = texturetranslation[sidedef->bottomtexture];
|
||||
bottomtexheight = (linedef->r_flags & RF_BOT_TILE) ? 0 : textureheight[bottomtexture] >> FRACBITS;
|
||||
rw_bottomtexturemid = linedef->flags & ML_DONTPEGBOTTOM ? worldtop :
|
||||
worldlow;
|
||||
rw_bottomtexturemid += FixedMod(sidedef->rowoffset, textureheight[bottomtexture]);
|
||||
}
|
||||
|
||||
// allocate space for masked texture tables
|
||||
if (sidedef->midtexture) // masked midtexture
|
||||
{
|
||||
maskedtexture = true;
|
||||
ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x;
|
||||
lastopening += rw_stopx - rw_x;
|
||||
}
|
||||
}
|
||||
|
||||
// calculate rw_offset (only needed for textured lines)
|
||||
segtextured = midtexture | toptexture | bottomtexture | maskedtexture;
|
||||
|
||||
if (segtextured)
|
||||
{
|
||||
offsetangle = rw_normalangle-rw_angle1;
|
||||
|
||||
if (offsetangle > ANG180)
|
||||
offsetangle = 0-offsetangle;
|
||||
|
||||
if (offsetangle > ANG90)
|
||||
offsetangle = ANG90;
|
||||
|
||||
sineval = finesine[offsetangle >>ANGLETOFINESHIFT];
|
||||
rw_offset = FixedMul (hyp, sineval);
|
||||
|
||||
if (rw_normalangle-rw_angle1 < ANG180)
|
||||
rw_offset = -rw_offset;
|
||||
|
||||
rw_offset += sidedef->textureoffset + curline->offset;
|
||||
|
||||
rw_centerangle = ANG90 + viewangle - rw_normalangle;
|
||||
|
||||
// calculate light table
|
||||
// use different light tables
|
||||
// for horizontal / vertical / diagonal
|
||||
// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
|
||||
if (!fixedcolormap)
|
||||
{
|
||||
int lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight;
|
||||
|
||||
/* cph - ...what is this for? adding contrast to rooms?
|
||||
* It looks crap in outdoor areas */
|
||||
if (fake_contrast) {
|
||||
if (curline->v1->y == curline->v2->y)
|
||||
lightnum--;
|
||||
else if (curline->v1->x == curline->v2->x)
|
||||
lightnum++;
|
||||
}
|
||||
|
||||
if (lightnum < 0)
|
||||
walllights = scalelight[0];
|
||||
else if (lightnum >= LIGHTLEVELS)
|
||||
walllights = scalelight[LIGHTLEVELS-1];
|
||||
else
|
||||
walllights = scalelight[lightnum];
|
||||
}
|
||||
}
|
||||
|
||||
// if a floor / ceiling plane is on the wrong side of the view
|
||||
// plane, it is definitely invisible and doesn't need to be marked.
|
||||
|
||||
// killough 3/7/98: add deep water check
|
||||
if (frontsector->heightsec == -1)
|
||||
{
|
||||
if (frontsector->floorheight >= viewz) // above view plane
|
||||
markfloor = false;
|
||||
if (frontsector->ceilingheight <= viewz &&
|
||||
frontsector->ceilingpic != skyflatnum) // below view plane
|
||||
markceiling = false;
|
||||
}
|
||||
|
||||
// calculate incremental stepping values for texture edges
|
||||
worldtop >>= 4;
|
||||
worldbottom >>= 4;
|
||||
|
||||
topstep = -FixedMul (rw_scalestep, worldtop);
|
||||
topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale);
|
||||
|
||||
bottomstep = -FixedMul (rw_scalestep,worldbottom);
|
||||
bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale);
|
||||
|
||||
if (backsector)
|
||||
{
|
||||
worldhigh >>= 4;
|
||||
worldlow >>= 4;
|
||||
|
||||
if (worldhigh < worldtop)
|
||||
{
|
||||
pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale);
|
||||
pixhighstep = -FixedMul (rw_scalestep,worldhigh);
|
||||
}
|
||||
if (worldlow > worldbottom)
|
||||
{
|
||||
pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale);
|
||||
pixlowstep = -FixedMul (rw_scalestep,worldlow);
|
||||
}
|
||||
}
|
||||
|
||||
// render it
|
||||
if (markceiling) {
|
||||
if (ceilingplane) // killough 4/11/98: add NULL ptr checks
|
||||
ceilingplane = R_CheckPlane (ceilingplane, rw_x, rw_stopx-1);
|
||||
else
|
||||
markceiling = 0;
|
||||
}
|
||||
|
||||
if (markfloor) {
|
||||
if (floorplane) // killough 4/11/98: add NULL ptr checks
|
||||
/* cph 2003/04/18 - ceilingplane and floorplane might be the same
|
||||
* visplane (e.g. if both skies); R_CheckPlane doesn't know about
|
||||
* modifications to the plane that might happen in parallel with the check
|
||||
* being made, so we have to override it and split them anyway if that is
|
||||
* a possibility, otherwise the floor marking would overwrite the ceiling
|
||||
* marking, resulting in HOM. */
|
||||
if (markceiling && ceilingplane == floorplane)
|
||||
floorplane = R_DupPlane (floorplane, rw_x, rw_stopx-1);
|
||||
else
|
||||
floorplane = R_CheckPlane (floorplane, rw_x, rw_stopx-1);
|
||||
else
|
||||
markfloor = 0;
|
||||
}
|
||||
|
||||
didsolidcol = 0;
|
||||
R_RenderSegLoop();
|
||||
|
||||
/* cph - if a column was made solid by this wall, we _must_ save full clipping info */
|
||||
if (backsector && didsolidcol) {
|
||||
if (!(ds_p->silhouette & SIL_BOTTOM)) {
|
||||
ds_p->silhouette |= SIL_BOTTOM;
|
||||
ds_p->bsilheight = backsector->floorheight;
|
||||
}
|
||||
if (!(ds_p->silhouette & SIL_TOP)) {
|
||||
ds_p->silhouette |= SIL_TOP;
|
||||
ds_p->tsilheight = backsector->ceilingheight;
|
||||
}
|
||||
}
|
||||
|
||||
// save sprite clipping info
|
||||
if ((ds_p->silhouette & SIL_TOP || maskedtexture) && !ds_p->sprtopclip)
|
||||
{
|
||||
memcpy (lastopening, ceilingclip+start, 2*(rw_stopx-start));
|
||||
ds_p->sprtopclip = lastopening - start;
|
||||
lastopening += rw_stopx - start;
|
||||
}
|
||||
if ((ds_p->silhouette & SIL_BOTTOM || maskedtexture) && !ds_p->sprbottomclip)
|
||||
{
|
||||
memcpy (lastopening, floorclip+start, 2*(rw_stopx-start));
|
||||
ds_p->sprbottomclip = lastopening - start;
|
||||
lastopening += rw_stopx - start;
|
||||
}
|
||||
if (maskedtexture && !(ds_p->silhouette & SIL_TOP))
|
||||
{
|
||||
ds_p->silhouette |= SIL_TOP;
|
||||
ds_p->tsilheight = INT_MIN;
|
||||
}
|
||||
if (maskedtexture && !(ds_p->silhouette & SIL_BOTTOM))
|
||||
{
|
||||
ds_p->silhouette |= SIL_BOTTOM;
|
||||
ds_p->bsilheight = INT_MAX;
|
||||
}
|
||||
ds_p++;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue