Chee wanted paper sprites' code, so here it is for the public to see.

Note: Won't compile. Need to merge in the NAMEcLcR stuff first, let me do that.
This commit is contained in:
toasterbabe 2016-08-22 22:54:30 +01:00
parent e5c44de6ca
commit 2a74ea07ee
10 changed files with 160 additions and 74 deletions

View File

@ -6642,7 +6642,7 @@ static const char *const MOBJFLAG_LIST[] = {
"SHOOTABLE",
"NOSECTOR",
"NOBLOCKMAP",
"AMBUSH",
"PAPERCOLLISION",
"PUSHABLE",
"BOSS",
"SPAWNCEILING",
@ -6700,6 +6700,7 @@ static const char *const MOBJFLAG2_LIST[] = {
"BOSSNOTRAP", // No Egg Trap after boss
"BOSSFLEE", // Boss is fleeing!
"BOSSDEAD", // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.)
"AMBUSH", // Alternate behaviour typically set by MTF_AMBUSH
NULL
};
@ -6992,6 +6993,7 @@ struct {
// Frame settings
{"FF_FRAMEMASK",FF_FRAMEMASK},
{"FF_PAPERSPRITE",FF_PAPERSPRITE},
{"FF_ANIMATE",FF_ANIMATE},
{"FF_FULLBRIGHT",FF_FULLBRIGHT},
{"FF_TRANSMASK",FF_TRANSMASK},

View File

@ -1054,7 +1054,7 @@ void OP_NightsObjectplace(player_t *player)
if (!OP_HeightOkay(player, false))
return;
if (player->mo->target->flags & MF_AMBUSH)
if (player->mo->target->flags2 & MF2_AMBUSH)
angle = (UINT16)player->anotherflyangle;
else
{

View File

@ -2625,7 +2625,7 @@ for (i = cvar.value; i; --i) spawnchance[numchoices++] = type
newbox = spawnchance[P_RandomKey(numchoices)];
item = mobjinfo[newbox].damage;
remains->flags &= ~MF_AMBUSH;
remains->flags2 &= ~MF2_AMBUSH;
break;
}
default:
@ -3444,7 +3444,7 @@ void A_BubbleSpawn(mobj_t *actor)
}
actor->flags2 &= ~MF2_DONTDRAW;
if (!(actor->flags & MF_AMBUSH))
if (!(actor->flags2 & MF2_AMBUSH))
{
// Quick! Look through players!
// Don't spawn bubbles unless a player is relatively close by (var2).
@ -3492,7 +3492,7 @@ void A_FanBubbleSpawn(mobj_t *actor)
if (!(actor->eflags & MFE_UNDERWATER))
return;
if (!(actor->flags & MF_AMBUSH))
if (!(actor->flags2 & MF2_AMBUSH))
{
// Quick! Look through players!
// Don't spawn bubbles unless a player is relatively close by (var2).
@ -4038,7 +4038,7 @@ void A_JetChase(mobj_t *actor)
return;
#endif
if (actor->flags & MF_AMBUSH)
if (actor->flags2 & MF2_AMBUSH)
return;
if (actor->z >= actor->waterbottom && actor->watertop > actor->floorz
@ -4931,7 +4931,7 @@ void A_SlingAppear(mobj_t *actor)
if (firsttime)
{
// This is the outermost link in the chain
spawnee->flags |= MF_AMBUSH;
spawnee->flags2 |= MF2_AMBUSH;
firsttime = false;
}
@ -5916,7 +5916,7 @@ void A_Boss2Chase(mobj_t *actor)
{
actor->watertop = -actor->watertop;
actor->extravalue1 = 18;
if (actor->flags & MF_AMBUSH)
if (actor->flags2 & MF2_AMBUSH)
actor->extravalue1 -= (actor->info->spawnhealth - actor->health)*2;
actor->extravalue2 = actor->extravalue1;
}
@ -5942,7 +5942,7 @@ void A_Boss2Chase(mobj_t *actor)
else
{
// Only speed up if you have the 'Deaf' flag.
if (actor->flags & MF_AMBUSH)
if (actor->flags2 & MF2_AMBUSH)
speedvar = actor->health;
else
speedvar = actor->info->spawnhealth;
@ -6533,7 +6533,7 @@ void A_BuzzFly(mobj_t *actor)
if (LUA_CallAction("A_BuzzFly", actor))
return;
#endif
if (actor->flags & MF_AMBUSH)
if (actor->flags2 & MF2_AMBUSH)
return;
if (actor->reactiontime)
@ -6673,7 +6673,7 @@ void A_GuardChase(mobj_t *actor)
return; // got a new target
// chase towards player
if (--actor->movecount < 0 || !P_Move(actor, (actor->flags & MF_AMBUSH) ? actor->info->speed * 2 : actor->info->speed))
if (--actor->movecount < 0 || !P_Move(actor, (actor->flags2 & MF2_AMBUSH) ? actor->info->speed * 2 : actor->info->speed))
{
P_NewChaseDir(actor);
actor->movecount += 5; // Increase tics before change in direction allowed.

View File

@ -1327,7 +1327,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
case MT_SMALLMACECHAIN:
case MT_BIGMACECHAIN:
// Is this the last link in the chain?
if (toucher->momz > 0 || !(special->flags & MF_AMBUSH)
if (toucher->momz > 0 || !(special->flags2 & MF2_AMBUSH)
|| (player->pflags & PF_ITEMHANG) || (player->pflags & PF_MACESPIN))
return;

View File

@ -2466,7 +2466,7 @@ static boolean P_ZMovement(mobj_t *mo)
&& abs(mom.y) < FixedMul(STOPSPEED, mo->scale)
&& abs(mom.z) < FixedMul(STOPSPEED*3, mo->scale))
{
if (mo->flags & MF_AMBUSH)
if (mo->flags2 & MF2_AMBUSH)
{
// If deafed, give the tumbleweed another random kick if it runs out of steam.
mom.z += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale);
@ -6392,7 +6392,7 @@ void P_MobjThinker(mobj_t *mobj)
flame->angle = mobj->angle;
if (mobj->flags & MF_AMBUSH) // Wave up and down instead of side-to-side
if (mobj->flags2 & MF2_AMBUSH) // Wave up and down instead of side-to-side
flame->momz = mobj->fuse << (FRACBITS-2);
else
flame->angle += FixedAngle(mobj->fuse*FRACUNIT);
@ -6427,7 +6427,7 @@ void P_MobjThinker(mobj_t *mobj)
strength -= ((20*FRACUNIT)/16)*mobj->movedir;
// If deaf'd, the object spawns on the ceiling.
if (mobj->flags & MF_AMBUSH)
if (mobj->flags2 & MF2_AMBUSH)
{
mobj->z = mobj->ceilingz-mobj->height;
flame->momz = -strength;
@ -7283,7 +7283,7 @@ void P_MobjThinker(mobj_t *mobj)
case MT_EGGMANBOX: // Eggman box
case MT_GRAVITYBOX: // Gravity box
case MT_QUESTIONBOX:
if ((mobj->flags & MF_AMBUSH || mobj->flags2 & MF2_STRONGBOX) && mobj->type != MT_QUESTIONBOX)
if ((mobj->flags2 & MF2_AMBUSH || mobj->flags2 & MF2_STRONGBOX) && mobj->type != MT_QUESTIONBOX)
{
mobjtype_t spawnchance[64];
INT32 numchoices = 0, i = 0;
@ -7311,11 +7311,7 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
i = P_RandomKey(numchoices); // Gotta love those random numbers!
newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, spawnchance[i]);
// If the monitor respawns randomly, transfer the flag.
if (mobj->flags & MF_AMBUSH)
newmobj->flags |= MF_AMBUSH;
// Transfer flags2 (strongbox, objectflip)
// Transfer flags2 (strongbox, objectflip, ambush)
newmobj->flags2 = mobj->flags2;
}
else
@ -9132,7 +9128,7 @@ ML_NOCLIMB : Direction not controllable
if (firsttime)
{
// This is the outermost link in the chain
spawnee->flags |= MF_AMBUSH;
spawnee->flags2 |= MF2_AMBUSH;
firsttime = false;
}
@ -9204,7 +9200,7 @@ ML_NOCLIMB : Direction not controllable
{
// Inverted if uppermost bit is set
if (mthing->angle & 16384)
mobj->flags |= MF_AMBUSH;
mobj->flags2 |= MF2_AMBUSH;
if (mthing->angle > 0)
mobj->radius = (mthing->angle & 16383)*FRACUNIT;
@ -9381,7 +9377,7 @@ ML_NOCLIMB : Direction not controllable
mthing->type == mobjinfo[MT_YELLOWTV].doomednum || mthing->type == mobjinfo[MT_BLUETV].doomednum ||
mthing->type == mobjinfo[MT_BLACKTV].doomednum || mthing->type == mobjinfo[MT_PITYTV].doomednum ||
mthing->type == mobjinfo[MT_RECYCLETV].doomednum || mthing->type == mobjinfo[MT_MIXUPBOX].doomednum)
mobj->flags |= MF_AMBUSH;
mobj->flags2 |= MF2_AMBUSH;
}
else if (mthing->type != mobjinfo[MT_AXIS].doomednum &&
@ -9389,7 +9385,7 @@ ML_NOCLIMB : Direction not controllable
mthing->type != mobjinfo[MT_AXISTRANSFERLINE].doomednum &&
mthing->type != mobjinfo[MT_NIGHTSBUMPER].doomednum &&
mthing->type != mobjinfo[MT_STARPOST].doomednum)
mobj->flags |= MF_AMBUSH;
mobj->flags2 |= MF2_AMBUSH;
}
if (mthing->options & MTF_OBJECTSPECIAL)
@ -9728,7 +9724,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
P_SetMobjState(mobj, mobj->info->seestate);
mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
mobj->flags |= MF_AMBUSH;
mobj->flags2 |= MF2_AMBUSH;
mthing->mobj = mobj;
}
// All manners of rings and coins
@ -9802,7 +9798,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
}
mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
mobj->flags |= MF_AMBUSH;
mobj->flags2 |= MF2_AMBUSH;
mthing->mobj = mobj;
}
// ***
@ -9858,7 +9854,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
if (mthing->options & MTF_AMBUSH)
mobj->flags |= MF_AMBUSH;
mobj->flags2 |= MF2_AMBUSH;
}
}
// Diagonal rings (handles both types)
@ -9916,7 +9912,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
if (mthing->options & MTF_AMBUSH)
mobj->flags |= MF_AMBUSH;
mobj->flags2 |= MF2_AMBUSH;
}
}
// Rings of items (all six of them)

View File

@ -107,8 +107,8 @@ typedef enum
MF_NOSECTOR = 1<<3,
// Don't use the blocklinks (inert but displayable)
MF_NOBLOCKMAP = 1<<4,
// Not to be activated by sound, deaf monster.
MF_AMBUSH = 1<<5,
// Thin, paper-like collision bound (for visual equivalent, see FF_PAPERSPRITE)
MF_PAPERCOLLISION = 1<<5,
// You can push this object. It can activate switches and things by pushing it on top.
MF_PUSHABLE = 1<<6,
// Object is a boss.
@ -193,6 +193,7 @@ typedef enum
MF2_BOSSNOTRAP = 1<<25, // No Egg Trap after boss
MF2_BOSSFLEE = 1<<26, // Boss is fleeing!
MF2_BOSSDEAD = 1<<27, // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.)
MF2_AMBUSH = 1<<28, // Alternate behaviour typically set by MTF_AMBUSH
// free: to and including 1<<31
} mobjflag2_t;

View File

@ -36,7 +36,9 @@
#endif
/// \brief Frame flags: only the frame number
#define FF_FRAMEMASK 0x3fff
#define FF_FRAMEMASK 0x1ff
/// \brief Frame flags: Thin, paper-like sprite (for collision equivalent, see MF_PAPERCOLLISION)
#define FF_PAPERSPRITE 0x800
/// \brief Frame flags: Simple stateless animation
#define FF_ANIMATE 0x4000
/// \brief Frame flags: frame always appears full bright

View File

@ -629,7 +629,7 @@ static void P_DeNightserizePlayer(player_t *player)
if (!(mo2->type == MT_NIGHTSDRONE))
continue;
if (mo2->flags & MF_AMBUSH)
if (mo2->flags2 & MF2_AMBUSH)
P_DamageMobj(player->mo, NULL, NULL, 10000);
break;
@ -4931,7 +4931,7 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad
boolean transfer1last = false;
boolean transfer2last = false;
vertex_t vertices[4];
fixed_t truexspeed = xspeed*(!(player->pflags & PF_TRANSFERTOCLOSEST) && player->mo->target->flags & MF_AMBUSH ? -1 : 1);
fixed_t truexspeed = xspeed*(!(player->pflags & PF_TRANSFERTOCLOSEST) && player->mo->target->flags2 & MF2_AMBUSH ? -1 : 1);
// Find next waypoint
for (th = thinkercap.next; th != &thinkercap; th = th->next)
@ -5596,7 +5596,7 @@ static void P_NiGHTSMovement(player_t *player)
// The 'ambush' flag says you should rotate
// the other way around the axis.
if (player->mo->target->flags & MF_AMBUSH)
if (player->mo->target->flags2 & MF2_AMBUSH)
backwardaxis = true;
player->angle_pos = R_PointToAngle2(player->mo->target->x, player->mo->target->y, player->mo->x, player->mo->y);
@ -7931,7 +7931,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
}
else if (player->mo->target)
{
if (player->mo->target->flags & MF_AMBUSH)
if (player->mo->target->flags2 & MF2_AMBUSH)
angle = R_PointToAngle2(player->mo->target->x, player->mo->target->y, player->mo->x, player->mo->y);
else
angle = R_PointToAngle2(player->mo->x, player->mo->y, player->mo->target->x, player->mo->target->y);

View File

@ -754,11 +754,18 @@ static void R_DrawVisSprite(vissprite_t *vis)
if (overflow_test < 0) overflow_test = -overflow_test;
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // fixed point mult would overflow
if (vis->scalestep) // handles right edge too
{
overflow_test = (INT64)centeryfrac - (((INT64)vis->texturemid*(vis->scale + (vis->scalestep*(vis->x2 - vis->x1))))>>FRACBITS);
if (overflow_test < 0) overflow_test = -overflow_test;
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // ditto
}
colfunc = basecolfunc; // hack: this isn't resetting properly somewhere.
dc_colormap = vis->colormap;
if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
{
// translate green skin to another color
// translate certain pixels to white
colfunc = transcolfunc;
if (vis->mobj->type == MT_CYBRAKDEMON)
dc_translation = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE);
@ -814,13 +821,10 @@ static void R_DrawVisSprite(vissprite_t *vis)
if (!dc_colormap)
dc_colormap = colormaps;
dc_iscale = FixedDiv(FRACUNIT, vis->scale);
dc_texturemid = vis->texturemid;
dc_texheight = 0;
frac = vis->startfrac;
spryscale = vis->scale;
sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
windowtop = windowbottom = sprbotscreen = INT32_MAX;
if (vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES)
@ -832,28 +836,29 @@ static void R_DrawVisSprite(vissprite_t *vis)
if (!vis->isScaled)
{
vis->scale = FixedMul(vis->scale, this_scale);
spryscale = vis->scale;
dc_iscale = FixedDiv(FRACUNIT, vis->scale);
vis->scalestep = FixedMul(vis->scalestep, this_scale);
vis->xiscale = FixedDiv(vis->xiscale,this_scale);
vis->isScaled = true;
}
dc_texturemid = FixedDiv(dc_texturemid,this_scale);
}
//Oh lordy, mercy me. Don't freak out if sprites go offscreen!
/*if (vis->xiscale > 0)
frac = FixedDiv(frac, this_scale);
else if (vis->x1 <= 0)
frac = (vis->x1 - vis->x2) * vis->xiscale;*/
spryscale = vis->scale;
if (!(vis->scalestep))
{
sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
//dc_hires = 1;
dc_iscale = FixedDiv(FRACUNIT, vis->scale);
}
x1 = vis->x1;
x2 = vis->x2;
if (vis->x1 < 0)
{
spryscale += vis->scalestep*(-vis->x1);
vis->x1 = 0;
}
if (vis->x2 >= vid.width)
vis->x2 = vid.width-1;
@ -869,10 +874,16 @@ static void R_DrawVisSprite(vissprite_t *vis)
#else
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS]));
#endif
if (vis->scalestep)
{
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
dc_iscale = (0xffffffffu / (unsigned)spryscale);
}
if (vis->vflip)
R_DrawFlippedMaskedColumn(column, patch->height);
else
R_DrawMaskedColumn(column);
spryscale += vis->scalestep;
}
colfunc = basecolfunc;
@ -967,7 +978,7 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
if (testheight <= sprite->gz)
return;
cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewz, sprite->scale))>>FRACBITS);
cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewz, sprite->sortscale))>>FRACBITS);
if (cutfrac < 0)
continue;
if (cutfrac > viewheight)
@ -1040,7 +1051,7 @@ static void R_ProjectSprite(mobj_t *thing)
fixed_t tr_x, tr_y;
fixed_t gxt, gyt;
fixed_t tx, tz;
fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!!
fixed_t xscale, yscale, sortscale; //added : 02-02-98 : aaargll..if I were a math-guy!!!
INT32 x1, x2;
@ -1057,6 +1068,9 @@ static void R_ProjectSprite(mobj_t *thing)
angle_t ang;
fixed_t iscale;
fixed_t scalestep; // toast '16
fixed_t offset, offset2;
boolean papersprite = (thing->frame & FF_PAPERSPRITE);
//SoM: 3/17/2000
fixed_t gz, gzt;
@ -1064,6 +1078,8 @@ static void R_ProjectSprite(mobj_t *thing)
INT32 light = 0;
fixed_t this_scale = thing->scale;
fixed_t ang_scale = FRACUNIT;
// transform the origin point
tr_x = thing->x - viewx;
tr_y = thing->y - viewy;
@ -1074,7 +1090,7 @@ static void R_ProjectSprite(mobj_t *thing)
tz = gxt-gyt;
// thing is behind view plane?
if (tz < FixedMul(MINZ, this_scale))
if (!(papersprite) && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later
return;
gxt = -FixedMul(tr_x, viewsin);
@ -1087,7 +1103,7 @@ static void R_ProjectSprite(mobj_t *thing)
// aspect ratio stuff
xscale = FixedDiv(projection, tz);
yscale = FixedDiv(projectiony, tz);
sortscale = FixedDiv(projectiony, tz);
// decide which patch to use for sprite relative to player
#ifdef RANGECHECK
@ -1129,10 +1145,17 @@ static void R_ProjectSprite(mobj_t *thing)
I_Error("R_ProjectSprite: sprframes NULL for sprite %d\n", thing->sprite);
#endif
if (sprframe->rotate != SRF_SINGLE || papersprite)
{
ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
if (papersprite)
ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT));
}
if (sprframe->rotate)
{
// choose a different rotation based on player view
ang = R_PointToAngle (thing->x, thing->y);
//ang = R_PointToAngle (thing->x, thing->y);
rot = (ang-thing->angle+ANGLE_202h)>>29;
//Fab: lumpid is the index for spritewidth,spriteoffset... tables
lump = sprframe->lumpid[rot];
@ -1153,22 +1176,77 @@ static void R_ProjectSprite(mobj_t *thing)
// calculate edges of the shape
if (flip)
tx -= FixedMul(spritecachedinfo[lump].width-spritecachedinfo[lump].offset, this_scale);
offset = spritecachedinfo[lump].offset - spritecachedinfo[lump].width;
else
tx -= FixedMul(spritecachedinfo[lump].offset, this_scale);
offset = -spritecachedinfo[lump].offset;
offset = FixedMul(offset, this_scale);
tx += FixedMul(offset, ang_scale);
x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS;
// off the right side?
if (x1 > viewwidth)
return;
tx += FixedMul(spritecachedinfo[lump].width, this_scale);
offset2 = FixedMul(spritecachedinfo[lump].width, this_scale);
tx += FixedMul(offset2, ang_scale);
x2 = ((centerxfrac + FixedMul (tx,xscale)) >>FRACBITS) - 1;
// off the left side
if (x2 < 0)
return;
if (papersprite)
{
fixed_t yscale2, cosmul, sinmul, tz2;
INT32 range;
if (ang >= ANGLE_180)
{
offset *= -1;
offset2 *= -1;
}
cosmul = FINECOSINE(thing->angle>>ANGLETOFINESHIFT);
sinmul = FINESINE(thing->angle>>ANGLETOFINESHIFT);
tr_x += FixedMul(offset, cosmul);
tr_y += FixedMul(offset, sinmul);
gxt = FixedMul(tr_x, viewcos);
gyt = -FixedMul(tr_y, viewsin);
tz = gxt-gyt;
yscale = FixedDiv(projectiony, tz);
if (yscale < 64) return; // Fix some funky visuals
tr_x += FixedMul(offset2, cosmul);
tr_y += FixedMul(offset2, sinmul);
gxt = FixedMul(tr_x, viewcos);
gyt = -FixedMul(tr_y, viewsin);
tz2 = gxt-gyt;
yscale2 = FixedDiv(projectiony, tz2);
if (yscale2 < 64) return; // ditto
if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier
return;
if (x2 > x1)
range = (x2 - x1);
else
range = 1;
scalestep = (yscale2 - yscale)/range;
// The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2?
// sortscale = max(yscale, yscale2);
// sortscale = min(yscale, yscale2);
}
else
{
scalestep = 0;
yscale = sortscale;
}
xscale = FixedMul(xscale, ang_scale);
// PORTAL SPRITE CLIPPING
if (portalrender)
{
@ -1250,6 +1328,7 @@ static void R_ProjectSprite(mobj_t *thing)
vis->heightsec = heightsec; //SoM: 3/17/2000
vis->mobjflags = thing->flags;
vis->scale = yscale; //<<detailshift;
vis->sortscale = sortscale;
vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15
vis->gx = thing->x;
vis->gy = thing->y;
@ -1259,6 +1338,7 @@ static void R_ProjectSprite(mobj_t *thing)
vis->pz = thing->z;
vis->pzt = vis->pz + vis->thingheight;
vis->texturemid = vis->gzt - viewz;
vis->scalestep = scalestep;
vis->mobj = thing; // Easy access! Tails 06-07-2002
@ -1276,8 +1356,8 @@ static void R_ProjectSprite(mobj_t *thing)
vis->xscale = xscale; //SoM: 4/17/2000
vis->sector = thing->subsector->sector;
vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, yscale))>>FRACBITS);
vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, yscale))>>FRACBITS);
vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, sortscale))>>FRACBITS);
vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, sortscale))>>FRACBITS);
vis->cut = SC_NONE;
if (thing->subsector->sector->numlights)
vis->extra_colormap = thing->subsector->sector->lightlist[light].extra_colormap;
@ -1298,7 +1378,10 @@ static void R_ProjectSprite(mobj_t *thing)
}
if (vis->x1 > x1)
{
vis->startfrac += FixedDiv(vis->xiscale, this_scale)*(vis->x1-x1);
vis->scale += scalestep*(vis->x1 - x1);
}
//Fab: lumppat is the lump number of the patch to use, this is different
// than lumpid for sprites-in-pwad : the graphics are patched
@ -1457,7 +1540,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
// store information in a vissprite
vis = R_NewVisSprite();
vis->scale = yscale; //<<detailshift;
vis->scale = vis->sortscale = yscale; //<<detailshift;
vis->dispoffset = 0; // Monster Iestyn: 23/11/15
vis->gx = thing->x;
vis->gy = thing->y;
@ -1467,6 +1550,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
vis->pz = thing->z;
vis->pzt = vis->pz + vis->thingheight;
vis->texturemid = vis->gzt - viewz;
vis->scalestep = 0;
vis->x1 = x1 < 0 ? 0 : x1;
vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
@ -1645,14 +1729,14 @@ void R_SortVisSprites(void)
bestscale = bestdispoffset = INT32_MAX;
for (ds = unsorted.next; ds != &unsorted; ds = ds->next)
{
if (ds->scale < bestscale)
if (ds->sortscale < bestscale)
{
bestscale = ds->scale;
bestscale = ds->sortscale;
bestdispoffset = ds->dispoffset;
best = ds;
}
// order visprites of same scale by dispoffset, smallest first
else if (ds->scale == bestscale && ds->dispoffset < bestdispoffset)
else if (ds->sortscale == bestscale && ds->dispoffset < bestdispoffset)
{
bestdispoffset = ds->dispoffset;
best = ds;
@ -1814,7 +1898,7 @@ static void R_CreateDrawNodes(void)
for (i = x1; i <= x2; i++)
{
if (r2->seg->frontscale[i] > rover->scale)
if (r2->seg->frontscale[i] > rover->sortscale)
break;
}
if (i > x2)
@ -1833,10 +1917,10 @@ static void R_CreateDrawNodes(void)
continue;
scale = r2->thickseg->scale1 > r2->thickseg->scale2 ? r2->thickseg->scale1 : r2->thickseg->scale2;
if (scale <= rover->scale)
if (scale <= rover->sortscale)
continue;
scale = r2->thickseg->scale1 + (r2->thickseg->scalestep * (sintersect - r2->thickseg->x1));
if (scale <= rover->scale)
if (scale <= rover->sortscale)
continue;
#ifdef ESLOPE
@ -1886,11 +1970,11 @@ static void R_CreateDrawNodes(void)
continue;
scale = r2->seg->scale1 > r2->seg->scale2 ? r2->seg->scale1 : r2->seg->scale2;
if (scale <= rover->scale)
if (scale <= rover->sortscale)
continue;
scale = r2->seg->scale1 + (r2->seg->scalestep * (sintersect - r2->seg->x1));
if (rover->scale < scale)
if (rover->sortscale < scale)
{
entry = R_CreateDrawNode(NULL);
(entry->prev = r2->prev)->next = entry;
@ -1906,8 +1990,8 @@ static void R_CreateDrawNodes(void)
if (r2->sprite->szt > rover->sz || r2->sprite->sz < rover->szt)
continue;
if (r2->sprite->scale > rover->scale
|| (r2->sprite->scale == rover->scale && r2->sprite->dispoffset > rover->dispoffset))
if (r2->sprite->sortscale > rover->sortscale
|| (r2->sprite->sortscale == rover->sortscale && r2->sprite->dispoffset > rover->dispoffset))
{
entry = R_CreateDrawNode(NULL);
(entry->prev = r2->prev)->next = entry;
@ -2060,8 +2144,8 @@ void R_ClipSprites(void)
scale = ds->scale2;
}
if (scale < spr->scale ||
(lowscale < spr->scale &&
if (scale < spr->sortscale ||
(lowscale < spr->sortscale &&
!R_PointOnSegSide (spr->gx, spr->gy, ds->curline)))
{
// masked mid texture?
@ -2112,7 +2196,7 @@ void R_ClipSprites(void)
fixed_t mh, h;
INT32 phs = viewplayer->mo->subsector->sector->heightsec;
if ((mh = sectors[spr->heightsec].floorheight) > spr->gz &&
(h = centeryfrac - FixedMul(mh -= viewz, spr->scale)) >= 0 &&
(h = centeryfrac - FixedMul(mh -= viewz, spr->sortscale)) >= 0 &&
(h >>= FRACBITS) < viewheight)
{
if (mh <= 0 || (phs != -1 && viewz > sectors[phs].floorheight))
@ -2130,7 +2214,7 @@ void R_ClipSprites(void)
}
if ((mh = sectors[spr->heightsec].ceilingheight) < spr->gzt &&
(h = centeryfrac - FixedMul(mh-viewz, spr->scale)) >= 0 &&
(h = centeryfrac - FixedMul(mh-viewz, spr->sortscale)) >= 0 &&
(h >>= FRACBITS) < viewheight)
{
if (phs != -1 && viewz >= sectors[phs].ceilingheight)

View File

@ -131,7 +131,8 @@ typedef struct vissprite_s
fixed_t pz, pzt; // physical bottom/top for sorting with 3D floors
fixed_t startfrac; // horizontal position of x1
fixed_t scale;
fixed_t scale, sortscale; // sortscale only differs from scale for flat sprites
fixed_t scalestep; // only for flat sprites, 0 otherwise
fixed_t xiscale; // negative if flipped
fixed_t texturemid;