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

Iskhodnyy_kod_Doom

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

numsprites = check-namelist;

if (!numsprites) return;

sprites = Z_Malloc(numsprites *sizeof(*sprites), PU_STATIC, NULL);

start = firstspritelump-1; end = lastspritelump+1;

//scan all the lump names for each of the names,

//noting the highest frame letter.

//Just compare 4 characters as ints

for (i=0 ; i<numsprites ; i++)

{

spritename = namelist[i];

memset (sprtemp,-1, sizeof(sprtemp));

maxframe = -1;

intname = *(int *)namelist[i];

//scan the lumps,

//filling in the frames for whatever is found for (l=start+1 ; l<end ; l++)

{

if (*(int *)lumpinfo[l].name == intname)

{

frame = lumpinfo[l].name[4] - ’A’; rotation = lumpinfo[l].name[5] - ’0’;

if (modifiedgame)

patched = W_GetNumForName (lumpinfo[l].name);

else

patched = l;

R_InstallSpriteLump (patched, frame, rotation, false);

if (lumpinfo[l].name[6])

{

frame = lumpinfo[l].name[6] - ’A’; rotation = lumpinfo[l].name[7] - ’0’;

R_InstallSpriteLump (l, frame, rotation, true);

}

}

}

// check the frames that were found for completeness if (maxframe == -1)

{

sprites[i].numframes = 0; continue;

}

maxframe++;

for (frame = 0 ; frame < maxframe ; frame++)

{

switch ((int)sprtemp[frame].rotate)

{

case -1:

// no rotations were found for that frame at all I_Error ("R_InitSprites: No patches found "

"for %s frame %c", namelist[i], frame+’A’);

break;

691

case 0:

// only the first rotation is needed break;

case 1:

// must have all 8 frames

for (rotation=0 ; rotation<8 ; rotation++) if (sprtemp[frame].lump[rotation] == -1)

I_Error ("R_InitSprites: Sprite %s frame %c " "is missing rotations",

namelist[i], frame+’A’);

break;

}

}

// allocate space for the frames present and copy sprtemp to it sprites[i].numframes = maxframe;

sprites[i].spriteframes =

Z_Malloc (maxframe * sizeof(spriteframe_t), PU_STATIC, NULL);

memcpy (sprites[i].spriteframes, sprtemp, maxframe*sizeof(spriteframe_t));

}

}

//

 

// GAME FUNCTIONS

 

//

 

vissprite_t

vissprites[MAXVISSPRITES];

vissprite_t*

vissprite_p;

int

newvissprite;

//

//R_InitSprites

//Called at program start.

void R_InitSprites (char** namelist)

{

int

i;

for (i=0 ; i<SCREENWIDTH ; i++)

{

negonearray[i] = -1;

}

R_InitSpriteDefs (namelist);

}

//

//R_ClearSprites

//Called at frame start.

void R_ClearSprites (void)

{

vissprite_p = vissprites;

}

//

692

mfloorclip;
mceilingclip;
spryscale;
sprtopscreen;

// R_NewVisSprite

//

vissprite_t overflowsprite;

vissprite_t* R_NewVisSprite (void)

{

if (vissprite_p == &vissprites[MAXVISSPRITES]) return &overflowsprite;

vissprite_p++;

return vissprite_p-1;

}

//

//R_DrawMaskedColumn

//Used for sprites and masked mid textures.

//Masked means: partly transparent, i.e. stored

//in posts/runs of opaque pixels.

//

short*

short*

fixed_t fixed_t

void R_DrawMaskedColumn (column_t* column)

{

int

topscreen;

int

bottomscreen;

fixed_t

basetexturemid;

basetexturemid = dc_texturemid;

for ( ; column->topdelta != 0xff ; )

{

//calculate unclipped screen coordinates

//for post

topscreen = sprtopscreen + spryscale*column->topdelta; bottomscreen = topscreen + spryscale*column->length;

dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS; dc_yh = (bottomscreen-1)>>FRACBITS;

if (dc_yh >= mfloorclip[dc_x]) dc_yh = mfloorclip[dc_x]-1;

if (dc_yl <= mceilingclip[dc_x]) dc_yl = mceilingclip[dc_x]+1;

if (dc_yl <= dc_yh)

{

dc_source = (byte *)column + 3;

dc_texturemid = basetexturemid - (column->topdelta<<FRACBITS);

//dc_source = (byte *)column + 3 - column->topdelta;

//Drawn by either R_DrawColumn

//or (SHADOW) R_DrawFuzzColumn.

colfunc ();

}

column = (column_t *)( (byte *)column + column->length + 4);

}

dc_texturemid = basetexturemid;

}

693

//

//R_DrawVisSprite

//mfloorclip and mceilingclip should also be set.

void R_DrawVisSprite

( vissprite_t*

vis,

int

x1,

int

x2 )

{

 

column_t*

column;

int

texturecolumn;

fixed_t

frac;

patch_t*

patch;

patch = W_CacheLumpNum (vis->patch+firstspritelump, PU_CACHE);

dc_colormap = vis->colormap;

if (!dc_colormap)

{

// NULL colormap = shadow draw colfunc = fuzzcolfunc;

}

else if (vis->mobjflags & MF_TRANSLATION)

{

colfunc = R_DrawTranslatedColumn; dc_translation = translationtables - 256 +

( (vis->mobjflags & MF_TRANSLATION) >> (MF_TRANSSHIFT-8) );

}

dc_iscale = abs(vis->xiscale)>>detailshift; dc_texturemid = vis->texturemid;

frac = vis->startfrac; spryscale = vis->scale;

sprtopscreen = centeryfrac - FixedMul(dc_texturemid,spryscale);

for (dc_x=vis->x1 ; dc_x<=vis->x2 ; dc_x++, frac += vis->xiscale)

{

texturecolumn = frac>>FRACBITS; #ifdef RANGECHECK

if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) I_Error ("R_DrawSpriteRange: bad texturecolumn");

#endif

column = (column_t *) ((byte *)patch + LONG(patch->columnofs[texturecolumn]));

R_DrawMaskedColumn (column);

}

colfunc = basecolfunc;

}

//

//R_ProjectSprite

//Generates a vissprite for a thing

//if it might be visible.

//

void R_ProjectSprite (mobj_t* thing)

{

694

fixed_t

tr_x;

fixed_t

tr_y;

fixed_t

gxt;

fixed_t

gyt;

fixed_t

tx;

fixed_t

tz;

fixed_t

xscale;

int

x1;

int

x2;

spritedef_t*

sprdef;

spriteframe_t*

sprframe;

int

lump;

unsigned

rot;

boolean

flip;

int

index;

vissprite_t*

vis;

angle_t

ang;

fixed_t

iscale;

// transform the origin point tr_x = thing->x - viewx; tr_y = thing->y - viewy;

gxt = FixedMul(tr_x,viewcos); gyt = -FixedMul(tr_y,viewsin);

tz = gxt-gyt;

// thing is behind view plane? if (tz < MINZ)

return;

xscale = FixedDiv(projection, tz);

gxt = -FixedMul(tr_x,viewsin); gyt = FixedMul(tr_y,viewcos); tx = -(gyt+gxt);

//too far off the side? if (abs(tx)>(tz<<2))

return;

//decide which patch to use for sprite relative to player #ifdef RANGECHECK

if ((unsigned)thing->sprite >= numsprites)

I_Error ("R_ProjectSprite: invalid sprite number %i ",

thing->sprite);

#endif

sprdef = &sprites[thing->sprite]; #ifdef RANGECHECK

if ( (thing->frame&FF_FRAMEMASK) >= sprdef->numframes ) I_Error ("R_ProjectSprite: invalid sprite frame %i : %i ",

thing->sprite, thing->frame);

#endif

sprframe = &sprdef->spriteframes[ thing->frame & FF_FRAMEMASK];

695

if (sprframe->rotate)

{

// choose a different rotation based on player view ang = R_PointToAngle (thing->x, thing->y);

rot = (ang-thing->angle+(unsigned)(ANG45/2)*9)>>29; lump = sprframe->lump[rot];

flip = (boolean)sprframe->flip[rot];

}

else

{

// use single rotation for all views lump = sprframe->lump[0];

flip = (boolean)sprframe->flip[0];

}

//calculate edges of the shape tx -= spriteoffset[lump];

x1 = (centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS;

//off the right side?

if (x1 > viewwidth) return;

tx += spritewidth[lump];

x2 = ((centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS) - 1;

//off the left side if (x2 < 0)

return;

//store information in a vissprite vis = R_NewVisSprite (); vis->mobjflags = thing->flags; vis->scale = xscale<<detailshift; vis->gx = thing->x;

vis->gy = thing->y; vis->gz = thing->z;

vis->gzt = thing->z + spritetopoffset[lump]; vis->texturemid = vis->gzt - viewz;

vis->x1 = x1 < 0 ? 0 : x1;

vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; iscale = FixedDiv (FRACUNIT, xscale);

if (flip)

{

vis->startfrac = spritewidth[lump]-1; vis->xiscale = -iscale;

}

else

{

vis->startfrac = 0; vis->xiscale = iscale;

}

if (vis->x1 > x1)

vis->startfrac += vis->xiscale*(vis->x1-x1); vis->patch = lump;

// get light level

if (thing->flags & MF_SHADOW)

{

// shadow draw vis->colormap = NULL;

}

else if (fixedcolormap)

696

{

// fixed map

vis->colormap = fixedcolormap;

}

else if (thing->frame & FF_FULLBRIGHT)

{

// full bright vis->colormap = colormaps;

}

else

{

// diminished light

index = xscale>>(LIGHTSCALESHIFT-detailshift);

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

vis->colormap = spritelights[index];

}

}

//

//R_AddSprites

//During BSP traversal, this adds sprites by sector.

void R_AddSprites (sector_t* sec)

{

mobj_t*

thing;

int

lightnum;

//BSP is traversed by subsector.

//A sector might have been split into several

//subsectors during BSP building.

//Thus we check whether its already added.

if (sec->validcount == validcount) return;

// Well, now it will be done. sec->validcount = validcount;

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

if (lightnum < 0)

spritelights = scalelight[0]; else if (lightnum >= LIGHTLEVELS)

spritelights = scalelight[LIGHTLEVELS-1];

else

spritelights = scalelight[lightnum];

// Handle all things in sector.

for (thing = sec->thinglist ; thing ; thing = thing->snext) R_ProjectSprite (thing);

}

//

// R_DrawPSprite

//

void R_DrawPSprite (pspdef_t* psp)

{

fixed_t

tx;

697

int

x1;

int

x2;

spritedef_t*

sprdef;

spriteframe_t*

sprframe;

int

lump;

boolean

flip;

vissprite_t*

vis;

vissprite_t

avis;

// decide which patch to use #ifdef RANGECHECK

if ( (unsigned)psp->state->sprite >= numsprites)

I_Error ("R_ProjectSprite: invalid sprite number %i ", psp->state->sprite);

#endif

sprdef = &sprites[psp->state->sprite]; #ifdef RANGECHECK

if ( (psp->state->frame & FF_FRAMEMASK) >= sprdef->numframes) I_Error ("R_ProjectSprite: invalid sprite frame %i : %i ",

psp->state->sprite, psp->state->frame);

#endif

sprframe = &sprdef->spriteframes[ psp->state->frame & FF_FRAMEMASK ];

lump = sprframe->lump[0];

flip = (boolean)sprframe->flip[0];

// calculate edges of the shape tx = psp->sx-160*FRACUNIT;

tx -= spriteoffset[lump];

x1 = (centerxfrac + FixedMul (tx,pspritescale) ) >>FRACBITS;

// off the right side if (x1 > viewwidth)

return;

tx += spritewidth[lump];

x2 = ((centerxfrac + FixedMul (tx, pspritescale) ) >>FRACBITS) - 1;

//off the left side if (x2 < 0)

return;

//store information in a vissprite vis = &avis;

vis->mobjflags = 0;

vis->texturemid = (BASEYCENTER<<FRACBITS)+FRACUNIT/2-(psp->sy-spritetopoffset[lump]); vis->x1 = x1 < 0 ? 0 : x1;

vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; vis->scale = pspritescale<<detailshift;

if (flip)

{

vis->xiscale = -pspriteiscale; vis->startfrac = spritewidth[lump]-1;

}

else

{

vis->xiscale = pspriteiscale; vis->startfrac = 0;

}

if (vis->x1 > x1)

vis->startfrac += vis->xiscale*(vis->x1-x1);

698

vis->patch = lump;

if (viewplayer->powers[pw_invisibility] > 4*32 || viewplayer->powers[pw_invisibility] & 8)

{

// shadow draw vis->colormap = NULL;

}

else if (fixedcolormap)

{

// fixed color

vis->colormap = fixedcolormap;

}

else if (psp->state->frame & FF_FULLBRIGHT)

{

// full bright vis->colormap = colormaps;

}

else

{

// local light

vis->colormap = spritelights[MAXLIGHTSCALE-1];

}

R_DrawVisSprite (vis, vis->x1, vis->x2);

}

//

// R_DrawPlayerSprites

//

void R_DrawPlayerSprites (void)

{

 

int

i;

int

lightnum;

pspdef_t*

psp;

// get light level lightnum =

(viewplayer->mo->subsector->sector->lightlevel >> LIGHTSEGSHIFT) +extralight;

if (lightnum < 0)

spritelights = scalelight[0]; else if (lightnum >= LIGHTLEVELS)

spritelights = scalelight[LIGHTLEVELS-1];

else

spritelights = scalelight[lightnum];

//clip to screen bounds mfloorclip = screenheightarray; mceilingclip = negonearray;

//add all active psprites

for (i=0, psp=viewplayer->psprites; i<NUMPSPRITES;

i++,psp++)

{

if (psp->state) R_DrawPSprite (psp);

}

}

699

//

// R_SortVisSprites

//

vissprite_t vsprsortedhead;

void R_SortVisSprites (void)

{

int

i;

int

count;

vissprite_t*

ds;

vissprite_t*

best;

vissprite_t

unsorted;

fixed_t

bestscale;

count = vissprite_p - vissprites;

unsorted.next = unsorted.prev = &unsorted;

if (!count) return;

for (ds=vissprites ; ds<vissprite_p ; ds++)

{

ds->next = ds+1; ds->prev = ds-1;

}

vissprites[0].prev = &unsorted; unsorted.next = &vissprites[0]; (vissprite_p-1)->next = &unsorted; unsorted.prev = vissprite_p-1;

// pull the vissprites out by scale

//best = 0; // shut up the compiler warning

vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead; for (i=0 ; i<count ; i++)

{

bestscale = MAXINT;

for (ds=unsorted.next ; ds!= &unsorted ; ds=ds->next)

{

if (ds->scale < bestscale)

{

bestscale = ds->scale; best = ds;

}

}

best->next->prev = best->prev; best->prev->next = best->next; best->next = &vsprsortedhead; best->prev = vsprsortedhead.prev; vsprsortedhead.prev->next = best; vsprsortedhead.prev = best;

}

}

//

// R_DrawSprite

//

void R_DrawSprite (vissprite_t* spr)

{

700

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