mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 09:11:48 +00:00
Do a bunch of stuff to the MD2/3 sprite2 support to get it back to feature parity with before, without going back to being hacky as fuck.
* Store the number of frames per sprite2 run in the spr2frames struct. * Reintroduce P_GetModelSprite2, to allow for the sprite2 defaulting system to be used to full advantage even in GL. * Instead of splitting the SUPER and normal SPR2 stuff within the same cell of the struct, have them exist in different cells just like in the "normal" sprite2 structs. * Allow for just providing spr2 frames in order without specifying which "normal" sprite2 frame it's supposed to replace. Also: * Fix FF_VERTICALFLIP-ignoring regression. * Fix whitespace adjustment in win_dll.c * Remove bracket in P_GetSkinSprite2 because I realised it was extraneous while making sure P_GetModelSprite2 worked with it.
This commit is contained in:
parent
7746767735
commit
417f17ebdd
5 changed files with 116 additions and 32 deletions
|
@ -848,6 +848,63 @@ static boolean HWR_CanInterpolateSprite2(modelspr2frames_t *spr2frame)
|
|||
return spr2frame->interpolate;
|
||||
}
|
||||
|
||||
//
|
||||
// P_GetModelSprite2 (see P_GetSkinSprite2)
|
||||
// For non-super players, tries each sprite2's immediate predecessor until it finds one with a number of frames or ends up at standing.
|
||||
// For super players, does the same as above - but tries the super equivalent for each sprite2 before the non-super version.
|
||||
//
|
||||
|
||||
static UINT8 P_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t *player)
|
||||
{
|
||||
UINT8 super = 0, i = 0;
|
||||
|
||||
if (!md2 || !md2->model || !md2->model->spr2frames || !skin)
|
||||
return 0;
|
||||
|
||||
if ((playersprite_t)(spr2 & ~FF_SPR2SUPER) >= free_spr2)
|
||||
return 0;
|
||||
|
||||
while (!md2->model->spr2frames[spr2].numframes
|
||||
&& spr2 != SPR2_STND
|
||||
&& ++i != 32) // recursion limiter
|
||||
{
|
||||
if (spr2 & FF_SPR2SUPER)
|
||||
{
|
||||
super = FF_SPR2SUPER;
|
||||
spr2 &= ~FF_SPR2SUPER;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(spr2)
|
||||
{
|
||||
// Normal special cases.
|
||||
case SPR2_JUMP:
|
||||
spr2 = ((player
|
||||
? player->charflags
|
||||
: skin->flags)
|
||||
& SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_ROLL;
|
||||
break;
|
||||
case SPR2_TIRE:
|
||||
spr2 = ((player
|
||||
? player->charability
|
||||
: skin->ability)
|
||||
== CA_SWIM) ? SPR2_SWIM : SPR2_FLY;
|
||||
break;
|
||||
// Use the handy list, that's what it's there for!
|
||||
default:
|
||||
spr2 = spr2defaults[spr2];
|
||||
break;
|
||||
}
|
||||
|
||||
spr2 |= super;
|
||||
}
|
||||
|
||||
if (i >= 32) // probably an infinite loop...
|
||||
return 0;
|
||||
|
||||
return spr2;
|
||||
}
|
||||
|
||||
void HWR_DrawMD2(gr_vissprite_t *spr)
|
||||
{
|
||||
FSurfaceInfo Surf;
|
||||
|
@ -906,9 +963,10 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
INT32 durs = spr->mobj->state->tics;
|
||||
INT32 tics = spr->mobj->tics;
|
||||
//mdlframe_t *next = NULL;
|
||||
const UINT8 flip = (UINT8)((spr->mobj->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP);
|
||||
const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !(spr->mobj->frame & FF_VERTICALFLIP));
|
||||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
INT32 mod;
|
||||
float finalscale;
|
||||
|
||||
// Apparently people don't like jump frames like that, so back it goes
|
||||
|
@ -1018,34 +1076,49 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
tics = spr->mobj->anim_duration;
|
||||
}
|
||||
|
||||
//FIXME: this is not yet correct
|
||||
if (spr->mobj->sprite2 && md2->model->spr2frames)
|
||||
frame = (spr->mobj->frame & FF_FRAMEMASK);
|
||||
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY && md2->model->spr2frames)
|
||||
{
|
||||
spr2 = (spr->mobj->sprite2 & ~FF_SPR2SUPER);
|
||||
frame = (spr->mobj->frame & FF_FRAMEMASK);
|
||||
if (spr->mobj->sprite2 & FF_SPR2SUPER)
|
||||
frame = md2->model->spr2frames[spr2].superframes[frame];
|
||||
spr2 = P_GetModelSprite2(md2, spr->mobj->skin, spr->mobj->sprite2, spr->mobj->player);
|
||||
mod = md2->model->spr2frames[spr2].numframes;
|
||||
#ifndef DONTHIDEDIFFANIMLENGTH // by default, different anim length is masked by the mod
|
||||
if (mod > (INT32)((skin_t *)spr->mobj->skin)->sprites[spr2].numframes)
|
||||
mod = ((skin_t *)spr->mobj->skin)->sprites[spr2].numframes;
|
||||
#endif
|
||||
if (mod)
|
||||
frame = md2->model->spr2frames[spr2].frames[frame%mod];
|
||||
else
|
||||
frame = md2->model->spr2frames[spr2].frames[frame];
|
||||
frame = 0;
|
||||
}
|
||||
else
|
||||
frame = (spr->mobj->frame & FF_FRAMEMASK);
|
||||
{
|
||||
mod = md2->model->meshes[0].numFrames;
|
||||
if (mod)
|
||||
frame %= mod;
|
||||
}
|
||||
|
||||
#ifdef USE_MODEL_NEXTFRAME
|
||||
if (cv_grmodels.value == 1 && tics <= durs)
|
||||
#define INTERPOLERATION_LIMIT TICRATE/4
|
||||
if (cv_grmodels.value == 1 && tics <= durs && tics <= INTERPOLERATION_LIMIT)
|
||||
{
|
||||
if (spr->mobj->sprite2 && md2->model->spr2frames)
|
||||
if (durs > INTERPOLERATION_LIMIT)
|
||||
durs = INTERPOLERATION_LIMIT;
|
||||
|
||||
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY && md2->model->spr2frames)
|
||||
{
|
||||
if (HWR_CanInterpolateSprite2(&md2->model->spr2frames[spr2]))
|
||||
if (mod && HWR_CanInterpolateSprite2(&md2->model->spr2frames[spr2])
|
||||
&& (spr->mobj->frame & FF_ANIMATE
|
||||
|| (spr->mobj->state->nextstate != S_NULL
|
||||
&& states[spr->mobj->state->nextstate].sprite == SPR_PLAY
|
||||
&& ((P_GetSkinSprite2(spr->mobj->skin, (((spr->mobj->player && spr->mobj->player->powers[pw_super]) ? FF_SPR2SUPER : 0)|states[spr->mobj->state->nextstate].frame) & FF_FRAMEMASK, spr->mobj->player) == spr->mobj->sprite2)))))
|
||||
{
|
||||
UINT32 framecount = (&((skin_t *)spr->mobj->skin)->sprites[spr->mobj->sprite2])->numframes;
|
||||
nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1;
|
||||
if (nextFrame >= framecount)
|
||||
if (nextFrame >= mod)
|
||||
nextFrame = 0;
|
||||
if (spr->mobj->sprite2 & FF_SPR2SUPER)
|
||||
nextFrame = md2->model->spr2frames[spr2].superframes[nextFrame];
|
||||
else
|
||||
if (frame || !(spr->mobj->state->frame & FF_SPR2ENDSTATE))
|
||||
nextFrame = md2->model->spr2frames[spr2].frames[nextFrame];
|
||||
else
|
||||
nextFrame = -1;
|
||||
}
|
||||
}
|
||||
else if (HWR_CanInterpolateModel(spr->mobj, md2->model))
|
||||
|
@ -1054,7 +1127,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
if (spr->mobj->frame & FF_ANIMATE)
|
||||
{
|
||||
nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1;
|
||||
if (nextFrame >= spr->mobj->state->var1)
|
||||
if (nextFrame >= (INT32)(spr->mobj->state->var1 + (spr->mobj->state->frame & FF_FRAMEMASK)))
|
||||
nextFrame = (spr->mobj->state->frame & FF_FRAMEMASK);
|
||||
//next = &md2->model->meshes[0].frames[nextFrame];
|
||||
}
|
||||
|
@ -1069,13 +1142,14 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
}
|
||||
}
|
||||
}
|
||||
#undef INTERPOLERATION_LIMIT
|
||||
#endif
|
||||
|
||||
//Hurdler: it seems there is still a small problem with mobj angle
|
||||
p.x = FIXED_TO_FLOAT(spr->mobj->x);
|
||||
p.y = FIXED_TO_FLOAT(spr->mobj->y)+md2->offset;
|
||||
|
||||
if (spr->mobj->eflags & MFE_VERTICALFLIP)
|
||||
if (flip)
|
||||
p.z = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height);
|
||||
else
|
||||
p.z = FIXED_TO_FLOAT(spr->mobj->z);
|
||||
|
|
|
@ -296,7 +296,7 @@ void LoadModelSprite2(model_t *model)
|
|||
char prefix[6];
|
||||
char name[5];
|
||||
char interpolation_flag[3];
|
||||
char framechar[4];
|
||||
char framechars[4];
|
||||
UINT8 frame = 0;
|
||||
UINT8 spr2idx;
|
||||
boolean interpolate = false;
|
||||
|
@ -304,10 +304,11 @@ void LoadModelSprite2(model_t *model)
|
|||
memset(&prefix, 0x00, 6);
|
||||
memset(&name, 0x00, 5);
|
||||
memset(&interpolation_flag, 0x00, 3);
|
||||
memset(&framechar, 0x00, 4);
|
||||
memset(&framechars, 0x00, 4);
|
||||
|
||||
if (strlen(framename) >= 9)
|
||||
{
|
||||
boolean super;
|
||||
char *modelframename = framename;
|
||||
memcpy(&prefix, modelframename, 5);
|
||||
modelframename += 5;
|
||||
|
@ -320,22 +321,31 @@ void LoadModelSprite2(model_t *model)
|
|||
interpolate = true;
|
||||
modelframename += 2;
|
||||
}
|
||||
memcpy(&framechar, modelframename, 3);
|
||||
frame = atoi(framechar);
|
||||
memcpy(&framechars, modelframename, 3);
|
||||
|
||||
if ((!memcmp(prefix, "SPR2_", 5)) || (!memcmp(prefix, "SUPER", 5)))
|
||||
if ((super = (!memcmp(prefix, "SUPER", 5))) || (!memcmp(prefix, "SPR2_", 5)))
|
||||
{
|
||||
spr2idx = 0;
|
||||
while (spr2idx < NUMPLAYERSPRITES)
|
||||
while (spr2idx < free_spr2)
|
||||
{
|
||||
if (!memcmp(spr2names[spr2idx], name, 4))
|
||||
{
|
||||
if (!spr2frames)
|
||||
spr2frames = (modelspr2frames_t*)Z_Calloc(sizeof(modelspr2frames_t)*NUMPLAYERSPRITES, PU_STATIC, NULL);
|
||||
if (!memcmp(prefix, "SUPER", 5))
|
||||
spr2frames[spr2idx].superframes[frame] = i;
|
||||
spr2frames = (modelspr2frames_t*)Z_Calloc(sizeof(modelspr2frames_t)*NUMPLAYERSPRITES*2, PU_STATIC, NULL);
|
||||
if (super)
|
||||
spr2idx |= FF_SPR2SUPER;
|
||||
if (framechars[0])
|
||||
{
|
||||
frame = atoi(framechars);
|
||||
if (spr2frames[spr2idx].numframes < frame+1)
|
||||
spr2frames[spr2idx].numframes = frame+1;
|
||||
}
|
||||
else
|
||||
spr2frames[spr2idx].frames[frame] = i;
|
||||
{
|
||||
frame = spr2frames[spr2idx].numframes;
|
||||
spr2frames[spr2idx].numframes++;
|
||||
}
|
||||
spr2frames[spr2idx].frames[frame] = i;
|
||||
spr2frames[spr2idx].interpolate = interpolate;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ typedef struct tag_s
|
|||
typedef struct
|
||||
{
|
||||
INT32 frames[256];
|
||||
INT32 superframes[256];
|
||||
UINT8 numframes;
|
||||
boolean interpolate;
|
||||
} modelspr2frames_t;
|
||||
|
||||
|
|
|
@ -2527,7 +2527,7 @@ UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player)
|
|||
if ((playersprite_t)(spr2 & ~FF_SPR2SUPER) >= free_spr2)
|
||||
return 0;
|
||||
|
||||
while (!(skin->sprites[spr2].numframes)
|
||||
while (!skin->sprites[spr2].numframes
|
||||
&& spr2 != SPR2_STND
|
||||
&& ++i < 32) // recursion limiter
|
||||
{
|
||||
|
|
|
@ -139,7 +139,7 @@ static loadfunc_t hwdFuncTable[] = {
|
|||
{"GClipRect", &hwdriver.pfnGClipRect},
|
||||
{"ClearMipMapCache", &hwdriver.pfnClearMipMapCache},
|
||||
{"SetSpecialState", &hwdriver.pfnSetSpecialState},
|
||||
{"DrawModel", &hwdriver.pfnDrawModel},
|
||||
{"DrawModel", &hwdriver.pfnDrawModel},
|
||||
{"SetTransform", &hwdriver.pfnSetTransform},
|
||||
{"GetTextureUsed", &hwdriver.pfnGetTextureUsed},
|
||||
{"GetRenderVersion", &hwdriver.pfnGetRenderVersion},
|
||||
|
|
Loading…
Reference in a new issue