Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Iskhodnyy_kod_Doom

.pdf
Скачиваний:
7
Добавлен:
13.02.2015
Размер:
1.01 Mб
Скачать

extern short

floorclip[SCREENWIDTH];

extern short

ceilingclip[SCREENWIDTH];

extern

fixed_t

yslope[SCREENHEIGHT];

extern

fixed_t

distscale[SCREENWIDTH];

void R_InitPlanes (void); void R_ClearPlanes (void);

void

 

R_MapPlane

 

( int

y,

int

x1,

int

x2 );

void

 

R_MakeSpans

 

( int

x,

int

t1,

int

b1,

int

t2,

int

b2 );

void R_DrawPlanes (void);

visplane_t*

 

R_FindPlane

 

( fixed_t

height,

int

picnum,

int

lightlevel );

visplane_t*

 

R_CheckPlane

 

( visplane_t*

pl,

int

start,

int

stop );

#endif //-----------------------------------------------------------------------------

//

// $Log:$

//

//-----------------------------------------------------------------------------

10.13 r segs.c

// Emacs style mode select -*- C++ -*- //-----------------------------------------------------------------------------

//

//$Id:$

//Copyright (C) 1993-1996 by id Software, Inc.

//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.

//

671

//$Log:$

//DESCRIPTION:

//All the clipping: columns, horizontal spans, sky columns.

//-----------------------------------------------------------------------------

static const char

rcsid[] = "$Id: r_segs.c,v 1.3 1997/01/29 20:10:19 b1 Exp $";

#include <stdlib.h>

#include "i_system.h"

#include "doomdef.h" #include "doomstat.h"

#include "r_local.h" #include "r_sky.h"

//OPTIMIZE: closed two sided lines as single sided

//True if any of the segs textures might be visible.

boolean segtextured;

// False if the back side is the same plane.

boolean

markfloor;

boolean

markceiling;

boolean

maskedtexture;

int

toptexture;

int

bottomtexture;

int

midtexture;

angle_t

rw_normalangle;

// angle to line origin

int

rw_angle1;

//

 

// regular wall

 

//

 

int

rw_x;

int

rw_stopx;

angle_t

rw_centerangle;

fixed_t

rw_offset;

fixed_t

rw_distance;

fixed_t

rw_scale;

fixed_t

rw_scalestep;

fixed_t

rw_midtexturemid;

fixed_t

rw_toptexturemid;

fixed_t

rw_bottomtexturemid;

int

worldtop;

int

worldbottom;

int

worldhigh;

int

worldlow;

fixed_t

pixhigh;

672

fixed_t

pixlow;

fixed_t

pixhighstep;

fixed_t

pixlowstep;

fixed_t

topfrac;

fixed_t

topstep;

fixed_t

bottomfrac;

fixed_t

bottomstep;

lighttable_t**

walllights;

short*

maskedtexturecol;

//

// R_RenderMaskedSegRange

//

void R_RenderMaskedSegRange

( drawseg_t*

ds,

int

x1,

int

x2 )

{

 

unsigned

index;

column_t*

col;

int

lightnum;

int

texnum;

//Calculate light table.

//Use different light tables

//for horizontal / vertical / diagonal. Diagonal?

//OPTIMIZE: get rid of LIGHTSEGSHIFT globally curline = ds->curline;

frontsector = curline->frontsector; backsector = curline->backsector;

texnum = texturetranslation[curline->sidedef->midtexture];

lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight;

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];

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

673

? 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++)

{

// calculate lighting

if (maskedtexturecol[dc_x] != MAXSHORT)

{

if (!fixedcolormap)

{

index = spryscale>>LIGHTSCALESHIFT;

if (index >= MAXLIGHTSCALE ) index = MAXLIGHTSCALE-1;

dc_colormap = walllights[index];

}

sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); dc_iscale = 0xffffffffu / (unsigned)spryscale;

// draw the texture col = (column_t *)(

(byte *)R_GetColumn(texnum,maskedtexturecol[dc_x]) -3);

R_DrawMaskedColumn (col); maskedtexturecol[dc_x] = MAXSHORT;

}

spryscale += rw_scalestep;

}

}

//

//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.

//

 

#define HEIGHTBITS

12

#define HEIGHTUNIT

(1<<HEIGHTBITS)

void R_RenderSegLoop (void)

 

{

 

angle_t

angle;

unsigned

index;

int

yl;

int

yh;

674

int

mid;

fixed_t

texturecolumn;

int

top;

int

bottom;

//texturecolumn = 0;

// shut up compiler warning

for ( ; rw_x < rw_stopx ; rw_x++)

{

// mark floor / ceiling areas

yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS;

// no space above wall?

if (yl < ceilingclip[rw_x]+1) yl = ceilingclip[rw_x]+1;

if (markceiling)

{

top = ceilingclip[rw_x]+1; 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;

if (yh >= floorclip[rw_x]) yh = floorclip[rw_x]-1;

if (markfloor)

{

top = yh+1;

bottom = floorclip[rw_x]-1; if (top <= ceilingclip[rw_x])

top = ceilingclip[rw_x]+1; if (top <= bottom)

{

floorplane->top[rw_x] = top; floorplane->bottom[rw_x] = bottom;

}

}

// texturecolumn and lighting are independent of wall tiers if (segtextured)

{

// calculate texture offset

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;

675

}

// draw the wall tiers if (midtexture)

{

// single sided line dc_yl = yl;

dc_yh = yh;

dc_texturemid = rw_midtexturemid;

dc_source = R_GetColumn(midtexture,texturecolumn); colfunc ();

ceilingclip[rw_x] = viewheight; floorclip[rw_x] = -1;

}

else

{

// two sided line if (toptexture)

{

// top wall

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); 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

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);

colfunc (); floorclip[rw_x] = mid;

}

676

else

floorclip[rw_x] = yh+1;

}

else

{

// no bottom wall if (markfloor)

floorclip[rw_x] = yh+1;

}

if (maskedtexture)

{

//save texturecol

//for backdrawing of masked mid texture maskedtexturecol[rw_x] = texturecolumn;

}

}

rw_scale += rw_scalestep; topfrac += topstep; bottomfrac += bottomstep;

}

}

//

//R_StoreWallRange

//A wall segment will be drawn

//between start and stop pixels (inclusive).

void R_StoreWallRange

( int

start,

int

stop )

{

 

fixed_t

hyp;

fixed_t

sineval;

angle_t

distangle, offsetangle;

fixed_t

vtop;

int

lightnum;

// don’t overflow and crash

if (ds_p == &drawsegs[MAXDRAWSEGS]) return;

#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 = abs(rw_normalangle-rw_angle1);

if (offsetangle > ANG90) offsetangle = ANG90;

677

distangle = ANG90 - offsetangle;

hyp = 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;

// 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

{

// UNUSED: try to fix the stretched line bug

#if 0

if (rw_distance < FRACUNIT/2)

{

fixed_t

trx,try;

fixed_t

gxt,gyt;

trx = curline->v1->x - viewx; try = curline->v1->y - viewy;

gxt = FixedMul(trx,viewcos); gyt = -FixedMul(try,viewsin);

ds_p->scale1 = FixedDiv(projection, gxt-gyt)<<detailshift;

}

#endif

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];

// a single sided line is terminal, so it must mark ends markfloor = markceiling = true;

if (linedef->flags & ML_DONTPEGBOTTOM)

{

vtop = frontsector->floorheight + textureheight[sidedef->midtexture];

// bottom of texture at bottom rw_midtexturemid = vtop - viewz;

}

else

{

// top of texture at top

678

rw_midtexturemid = worldtop;

}

rw_midtexturemid += sidedef->rowoffset;

ds_p->silhouette = SIL_BOTH; ds_p->sprtopclip = screenheightarray; ds_p->sprbottomclip = negonearray; ds_p->bsilheight = MAXINT; ds_p->tsilheight = MININT;

}

else

{

// two sided line

ds_p->sprtopclip = ds_p->sprbottomclip = NULL; ds_p->silhouette = 0;

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 = MAXINT;

// ds_p->sprbottomclip = negonearray;

}

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 = MININT;

// ds_p->sprtopclip = screenheightarray;

}

if (backsector->ceilingheight <= frontsector->floorheight)

{

ds_p->sprbottomclip = negonearray; ds_p->bsilheight = MAXINT; ds_p->silhouette |= SIL_BOTTOM;

}

if (backsector->floorheight >= frontsector->ceilingheight)

{

ds_p->sprtopclip = screenheightarray; ds_p->tsilheight = MININT; ds_p->silhouette |= SIL_TOP;

}

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;

}

679

if (worldlow != worldbottom

||backsector->floorpic != frontsector->floorpic

||backsector->lightlevel != frontsector->lightlevel)

{

markfloor = true;

}

else

{

// same plane on both sides markfloor = false;

}

if (worldhigh != worldtop

||backsector->ceilingpic != frontsector->ceilingpic

||backsector->lightlevel != frontsector->lightlevel)

{

markceiling = true;

}

else

{

// same plane on both sides markceiling = false;

}

if (backsector->ceilingheight <= frontsector->floorheight

|| backsector->floorheight >= frontsector->ceilingheight)

{

// closed door

markceiling = markfloor = true;

}

if (worldhigh < worldtop)

{

// top texture

toptexture = texturetranslation[sidedef->toptexture]; if (linedef->flags & ML_DONTPEGTOP)

{

// top of texture at top rw_toptexturemid = worldtop;

}

else

{

vtop = backsector->ceilingheight

+textureheight[sidedef->toptexture];

//bottom of texture

rw_toptexturemid = vtop - viewz;

}

}

if (worldlow > worldbottom)

{

// bottom texture

bottomtexture = texturetranslation[sidedef->bottomtexture];

if (linedef->flags & ML_DONTPEGBOTTOM )

{

//bottom of texture at bottom

//top of texture at top

rw_bottomtexturemid = worldtop;

}

else // top of texture at top rw_bottomtexturemid = worldlow;

680

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]