Implement relative and absolute sprite offsets for objects (mobjs)

Added RF_ABSOLUTEOFFSETS and RF_FLIPOFFSETS
This commit is contained in:
Jaime Passos 2020-10-13 12:57:36 -03:00
parent 87e5d63723
commit 4273896311
12 changed files with 134 additions and 38 deletions

View File

@ -643,6 +643,12 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->frame = LONG(players[i].mo->frame);
rsp->sprite2 = players[i].mo->sprite2;
rsp->anim_duration = SHORT(players[i].mo->anim_duration);
rsp->spritexscale = LONG(players[i].mo->spritexscale);
rsp->spriteyscale = LONG(players[i].mo->spriteyscale);
rsp->spritexoffset = LONG(players[i].mo->spritexoffset);
rsp->spriteyoffset = LONG(players[i].mo->spriteyoffset);
rsp->tics = LONG(players[i].mo->tics);
rsp->statenum = (statenum_t)LONG(players[i].mo->state-states); // :(
rsp->eflags = (UINT16)SHORT(players[i].mo->eflags);
@ -655,8 +661,6 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->scale = LONG(players[i].mo->scale);
rsp->destscale = LONG(players[i].mo->destscale);
rsp->scalespeed = LONG(players[i].mo->scalespeed);
rsp->spritexscale = LONG(players[i].mo->spritexscale);
rsp->spriteyscale = LONG(players[i].mo->spriteyscale);
}
static void resynch_read_player(resynch_pak *rsp)
@ -805,6 +809,12 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].mo->frame = LONG(rsp->frame);
players[i].mo->sprite2 = rsp->sprite2;
players[i].mo->anim_duration = SHORT(rsp->anim_duration);
players[i].mo->spritexscale = LONG(rsp->spritexscale);
players[i].mo->spriteyscale = LONG(rsp->spriteyscale);
players[i].mo->spritexoffset = LONG(rsp->spritexoffset);
players[i].mo->spriteyoffset = LONG(rsp->spriteyoffset);
players[i].mo->tics = LONG(rsp->tics);
players[i].mo->state = &states[LONG(rsp->statenum)];
@ -817,8 +827,6 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].mo->scale = LONG(rsp->scale);
players[i].mo->destscale = LONG(rsp->destscale);
players[i].mo->scalespeed = LONG(rsp->scalespeed);
players[i].mo->spritexscale = LONG(rsp->spritexscale);
players[i].mo->spriteyscale = LONG(rsp->spriteyscale);
// And finally, SET THE MOBJ SKIN damn it.
if ((players[i].powers[pw_carry] == CR_NIGHTSMODE) && (skins[players[i].skin].sprites[SPR2_NFLY].numframes == 0))

View File

@ -288,6 +288,12 @@ typedef struct
UINT32 frame;
UINT8 sprite2;
UINT16 anim_duration;
fixed_t spritexscale;
fixed_t spriteyscale;
fixed_t spritexoffset;
fixed_t spriteyoffset;
INT32 tics;
statenum_t statenum;
UINT32 flags;
@ -300,8 +306,6 @@ typedef struct
fixed_t scale;
fixed_t destscale;
fixed_t scalespeed;
fixed_t spritexscale;
fixed_t spriteyscale;
} ATTRPACK resynch_pak;
typedef struct

View File

@ -9583,10 +9583,12 @@ struct {
// Render flags
{"RF_HORIZONTALFLIP",RF_HORIZONTALFLIP},
{"RF_VERTICALFLIP",RF_VERTICALFLIP},
{"RF_ONESIDED",RF_ONESIDED},
{"RF_ABSOLUTEOFFSETS",RF_ABSOLUTEOFFSETS},
{"RF_FLIPOFFSETS",RF_FLIPOFFSETS},
{"RF_SLOPESPLAT",RF_SLOPESPLAT},
{"RF_NOSPLATBILLBOARD",RF_NOSPLATBILLBOARD},
{"RF_NOSPLATROLLANGLE",RF_NOSPLATROLLANGLE},
{"RF_BLENDMASK",RF_BLENDMASK},
{"RF_FULLBRIGHT",RF_FULLBRIGHT},
{"RF_FULLDARK",RF_FULLDARK},
{"RF_SPRITETYPEMASK",RF_SPRITETYPEMASK},

View File

@ -69,9 +69,11 @@ typedef struct gl_vissprite_s
float tracertz; // for MF2_LINKDRAW sprites, this contains tracer's tz for use in sorting
float scale;
float spritexscale, spriteyscale;
float shadowheight, shadowscale;
float spritexscale, spriteyscale;
float spritexoffset, spriteyoffset;
UINT32 renderflags;
UINT8 rotateflags;

View File

@ -3966,8 +3966,8 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
angle = -angle;
angle += ANGLE_90;
topoffset = (float)gpatch->topoffset;
leftoffset = (float)gpatch->leftoffset;
topoffset = spr->spriteyoffset;
leftoffset = spr->spritexoffset;
if (spr->flip)
leftoffset = ((float)gpatch->width - leftoffset);
@ -4979,6 +4979,22 @@ static void HWR_ProjectSprite(mobj_t *thing)
}
#endif
if (thing->renderflags & RF_ABSOLUTEOFFSETS)
{
spr_offset = thing->spritexoffset;
spr_topoffset = thing->spriteyoffset;
}
else
{
SINT8 flipoffset = 1;
if ((thing->renderflags & RF_FLIPOFFSETS) && flip)
flipoffset = -1;
spr_offset += thing->spritexoffset * flipoffset;
spr_topoffset += thing->spriteyoffset * flipoffset;
}
if (papersprite)
{
rightsin = FIXED_TO_FLOAT(FINESINE((mobjangle)>>ANGLETOFINESHIFT));
@ -5123,6 +5139,8 @@ static void HWR_ProjectSprite(mobj_t *thing)
vis->scale = this_scale;
vis->spritexscale = spritexscale;
vis->spriteyscale = spriteyscale;
vis->spritexoffset = FIXED_TO_FLOAT(spr_offset);
vis->spriteyoffset = FIXED_TO_FLOAT(spr_topoffset);
vis->rotated = false;

View File

@ -39,6 +39,10 @@ enum mobj_e {
mobj_frame,
mobj_sprite2,
mobj_anim_duration,
mobj_spritexscale,
mobj_spriteyscale,
mobj_spritexoffset,
mobj_spriteyoffset,
mobj_touching_sectorlist,
mobj_subsector,
mobj_floorz,
@ -84,8 +88,6 @@ enum mobj_e {
mobj_scale,
mobj_destscale,
mobj_scalespeed,
mobj_spritexscale,
mobj_spriteyscale,
mobj_extravalue1,
mobj_extravalue2,
mobj_cusval,
@ -111,6 +113,10 @@ static const char *const mobj_opt[] = {
"frame",
"sprite2",
"anim_duration",
"spritexscale",
"spriteyscale",
"spritexoffset",
"spriteyoffset",
"touching_sectorlist",
"subsector",
"floorz",
@ -156,8 +162,6 @@ static const char *const mobj_opt[] = {
"scale",
"destscale",
"scalespeed",
"spritexscale",
"spriteyscale",
"extravalue1",
"extravalue2",
"cusval",
@ -233,6 +237,18 @@ static int mobj_get(lua_State *L)
case mobj_anim_duration:
lua_pushinteger(L, mo->anim_duration);
break;
case mobj_spritexscale:
lua_pushfixed(L, mo->spritexscale);
break;
case mobj_spriteyscale:
lua_pushfixed(L, mo->spriteyscale);
break;
case mobj_spritexoffset:
lua_pushfixed(L, mo->spritexoffset);
break;
case mobj_spriteyoffset:
lua_pushfixed(L, mo->spriteyoffset);
break;
case mobj_touching_sectorlist:
return UNIMPLEMENTED;
case mobj_subsector:
@ -390,12 +406,6 @@ static int mobj_get(lua_State *L)
case mobj_scalespeed:
lua_pushfixed(L, mo->scalespeed);
break;
case mobj_spritexscale:
lua_pushfixed(L, mo->spritexscale);
break;
case mobj_spriteyscale:
lua_pushfixed(L, mo->spriteyscale);
break;
case mobj_extravalue1:
lua_pushinteger(L, mo->extravalue1);
break;
@ -507,6 +517,18 @@ static int mobj_set(lua_State *L)
case mobj_anim_duration:
mo->anim_duration = (UINT16)luaL_checkinteger(L, 3);
break;
case mobj_spritexscale:
mo->spritexscale = luaL_checkfixed(L, 3);
break;
case mobj_spriteyscale:
mo->spriteyscale = luaL_checkfixed(L, 3);
break;
case mobj_spritexoffset:
mo->spritexoffset = luaL_checkfixed(L, 3);
break;
case mobj_spriteyoffset:
mo->spriteyoffset = luaL_checkfixed(L, 3);
break;
case mobj_touching_sectorlist:
return UNIMPLEMENTED;
case mobj_subsector:
@ -739,12 +761,6 @@ static int mobj_set(lua_State *L)
case mobj_scalespeed:
mo->scalespeed = luaL_checkfixed(L, 3);
break;
case mobj_spritexscale:
mo->spritexscale = luaL_checkfixed(L, 3);
break;
case mobj_spriteyscale:
mo->spriteyscale = luaL_checkfixed(L, 3);
break;
case mobj_extravalue1:
mo->extravalue1 = luaL_checkinteger(L, 3);
break;

View File

@ -10465,12 +10465,15 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
mobj->scale = FRACUNIT;
mobj->destscale = mobj->scale;
mobj->scalespeed = FRACUNIT/12;
mobj->spritexscale = mobj->spriteyscale = mobj->scale;
// TODO: Make this a special map header
if ((maptol & TOL_ERZ3) && !(mobj->type == MT_BLACKEGGMAN))
mobj->destscale = FRACUNIT/2;
// Sprite rendering
mobj->spritexscale = mobj->spriteyscale = mobj->scale;
mobj->spritexoffset = mobj->spriteyoffset = 0;
// set subsector and/or block links
P_SetThingPosition(mobj);
I_Assert(mobj->subsector != NULL);

View File

@ -286,6 +286,10 @@ typedef struct mobj_s
UINT8 sprite2; // player sprites
UINT16 anim_duration; // for FF_ANIMATE states
UINT32 renderflags; // render flags
fixed_t spritexscale, spriteyscale;
fixed_t spritexoffset, spriteyoffset;
struct msecnode_s *touching_sectorlist; // a linked list of sectors where this object appears
struct subsector_s *subsector; // Subsector the mobj resides in.
@ -309,7 +313,6 @@ typedef struct mobj_s
UINT32 flags; // flags from mobjinfo tables
UINT32 flags2; // MF2_ flags
UINT16 eflags; // extra flags
UINT32 renderflags; // render flags
void *skin; // overrides 'sprite' when non-NULL (for player bodies to 'remember' the skin)
// Player and mobj sprites in multiplayer modes are modified
@ -362,7 +365,6 @@ typedef struct mobj_s
fixed_t scale;
fixed_t destscale;
fixed_t scalespeed;
fixed_t spritexscale, spriteyscale;
// Extra values are for internal use for whatever you want
INT32 extravalue1;
@ -409,6 +411,10 @@ typedef struct precipmobj_s
UINT8 sprite2; // player sprites
UINT16 anim_duration; // for FF_ANIMATE states
UINT32 renderflags; // render flags
fixed_t spritexscale, spriteyscale;
fixed_t spritexoffset, spriteyoffset;
struct mprecipsecnode_s *touching_sectorlist; // a linked list of sectors where this object appears
struct subsector_s *subsector; // Subsector the mobj resides in.

View File

@ -1395,8 +1395,10 @@ typedef enum
MD2_ROLLANGLE = 1<<14,
MD2_SPRITEXSCALE = 1<<15,
MD2_SPRITEYSCALE = 1<<16,
MD2_SHADOWSCALE = 1<<17,
MD2_RENDERFLAGS = 1<<18,
MD2_SPRITEXOFFSET = 1<<17,
MD2_SPRITEYOFFSET = 1<<18,
MD2_SHADOWSCALE = 1<<19,
MD2_RENDERFLAGS = 1<<20,
} mobj_diff2_t;
typedef enum
@ -1611,6 +1613,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 |= MD2_SPRITEXSCALE;
if (mobj->spriteyscale != FRACUNIT)
diff2 |= MD2_SPRITEYSCALE;
if (mobj->spritexoffset)
diff2 |= MD2_SPRITEXOFFSET;
if (mobj->spriteyoffset)
diff2 |= MD2_SPRITEYOFFSET;
if (mobj->shadowscale)
diff2 |= MD2_SHADOWSCALE;
if (mobj->renderflags)
@ -1759,6 +1765,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEFIXED(save_p, mobj->spritexscale);
if (diff2 & MD2_SPRITEYSCALE)
WRITEFIXED(save_p, mobj->spriteyscale);
if (diff2 & MD2_SPRITEXOFFSET)
WRITEFIXED(save_p, mobj->spritexoffset);
if (diff2 & MD2_SPRITEYOFFSET)
WRITEFIXED(save_p, mobj->spriteyoffset);
if (diff2 & MD2_SHADOWSCALE)
WRITEFIXED(save_p, mobj->shadowscale);
if (diff2 & MD2_RENDERFLAGS)
@ -2774,6 +2784,10 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
mobj->spritexscale = READFIXED(save_p);
if (diff2 & MD2_SPRITEYSCALE)
mobj->spriteyscale = READFIXED(save_p);
if (diff2 & MD2_SPRITEXOFFSET)
mobj->spritexoffset = READFIXED(save_p);
if (diff2 & MD2_SPRITEYOFFSET)
mobj->spriteyoffset = READFIXED(save_p);
if (diff2 & MD2_SHADOWSCALE)
mobj->shadowscale = READFIXED(save_p);
if (diff2 & MD2_RENDERFLAGS)

View File

@ -717,10 +717,12 @@ typedef enum
{
RF_HORIZONTALFLIP = 0x0001, // Flip sprite horizontally
RF_VERTICALFLIP = 0x0002, // Flip sprite vertically
RF_ONESIDED = 0x0004, // Wall/floor sprite is visible from front only
RF_SLOPESPLAT = 0x0008, // Rotate floor sprites by the object's standing slope
RF_NOSPLATBILLBOARD = 0x0010, // Don't billboard floor sprites (faces forward from the view angle)
RF_NOSPLATROLLANGLE = 0x0020, // Don't rotate floor sprites by the object's rollangle (uses rotated patches instead)
RF_ABSOLUTEOFFSETS = 0x0004, // Sprite uses the object's offsets absolutely, instead of relatively
RF_FLIPOFFSETS = 0x0008, // Relative object offsets are flipped with the sprite
RF_SLOPESPLAT = 0x0010, // Rotate floor sprites by the object's standing slope
RF_NOSPLATBILLBOARD = 0x0020, // Don't billboard floor sprites (faces forward from the view angle)
RF_NOSPLATROLLANGLE = 0x0040, // Don't rotate floor sprites by the object's rollangle (uses rotated patches instead)
RF_BLENDMASK = 0x0F00, // --Blending modes
RF_FULLBRIGHT = 0x0100, // Sprite is drawn at full brightness

View File

@ -1632,6 +1632,22 @@ static void R_ProjectSprite(mobj_t *thing)
if (spritexscale < 1 || spriteyscale < 1)
return;
if (thing->renderflags & RF_ABSOLUTEOFFSETS)
{
spr_offset = thing->spritexoffset;
spr_topoffset = thing->spriteyoffset;
}
else
{
SINT8 flipoffset = 1;
if ((thing->renderflags & RF_FLIPOFFSETS) && flip)
flipoffset = -1;
spr_offset += thing->spritexoffset * flipoffset;
spr_topoffset += thing->spriteyoffset * flipoffset;
}
if (flip)
offset = spr_offset - spr_width;
else
@ -1981,7 +1997,8 @@ static void R_ProjectSprite(mobj_t *thing)
vis->spritexscale = spritexscale;
vis->spriteyscale = spriteyscale;
vis->shadowscale = shadowscale;
vis->spritexoffset = spr_offset;
vis->spriteyoffset = spr_topoffset;
if (shadowdraw || shadoweffects)
{
@ -1992,6 +2009,8 @@ static void R_ProjectSprite(mobj_t *thing)
else
iscale = FixedDiv(FRACUNIT, vis->xscale);
vis->shadowscale = shadowscale;
if (flip)
{
vis->startfrac = spr_width-1;
@ -2818,8 +2837,8 @@ static void R_DrawVisSplat(vissprite_t *spr)
splat.angle = -splatangle;
splat.angle += ANGLE_90;
topoffset = (spr->patch->topoffset * FRACUNIT);
leftoffset = (spr->patch->leftoffset * FRACUNIT);
topoffset = spr->spriteyoffset;
leftoffset = spr->spritexoffset;
if (hflip)
leftoffset = ((splat.width * FRACUNIT) - leftoffset);

View File

@ -195,6 +195,8 @@ typedef struct vissprite_s
UINT8 rotateflags;
fixed_t spritexscale, spriteyscale;
fixed_t spritexoffset, spriteyoffset;
fixed_t shadowscale;
INT16 clipbot[MAXVIDWIDTH], cliptop[MAXVIDWIDTH];