mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-20 18:01:16 +00:00
Implement relative and absolute sprite offsets for objects (mobjs)
Added RF_ABSOLUTEOFFSETS and RF_FLIPOFFSETS
This commit is contained in:
parent
87e5d63723
commit
4273896311
12 changed files with 134 additions and 38 deletions
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
10
src/p_mobj.h
10
src/p_mobj.h
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
10
src/r_defs.h
10
src/r_defs.h
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in a new issue