mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 17:22:12 +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;
|
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)
|
void HWR_DrawMD2(gr_vissprite_t *spr)
|
||||||
{
|
{
|
||||||
FSurfaceInfo Surf;
|
FSurfaceInfo Surf;
|
||||||
|
@ -906,9 +963,10 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
||||||
INT32 durs = spr->mobj->state->tics;
|
INT32 durs = spr->mobj->state->tics;
|
||||||
INT32 tics = spr->mobj->tics;
|
INT32 tics = spr->mobj->tics;
|
||||||
//mdlframe_t *next = NULL;
|
//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;
|
spritedef_t *sprdef;
|
||||||
spriteframe_t *sprframe;
|
spriteframe_t *sprframe;
|
||||||
|
INT32 mod;
|
||||||
float finalscale;
|
float finalscale;
|
||||||
|
|
||||||
// Apparently people don't like jump frames like that, so back it goes
|
// 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;
|
tics = spr->mobj->anim_duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME: this is not yet correct
|
frame = (spr->mobj->frame & FF_FRAMEMASK);
|
||||||
if (spr->mobj->sprite2 && md2->model->spr2frames)
|
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY && md2->model->spr2frames)
|
||||||
{
|
{
|
||||||
spr2 = (spr->mobj->sprite2 & ~FF_SPR2SUPER);
|
spr2 = P_GetModelSprite2(md2, spr->mobj->skin, spr->mobj->sprite2, spr->mobj->player);
|
||||||
frame = (spr->mobj->frame & FF_FRAMEMASK);
|
mod = md2->model->spr2frames[spr2].numframes;
|
||||||
if (spr->mobj->sprite2 & FF_SPR2SUPER)
|
#ifndef DONTHIDEDIFFANIMLENGTH // by default, different anim length is masked by the mod
|
||||||
frame = md2->model->spr2frames[spr2].superframes[frame];
|
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
|
else
|
||||||
frame = md2->model->spr2frames[spr2].frames[frame];
|
frame = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
frame = (spr->mobj->frame & FF_FRAMEMASK);
|
{
|
||||||
|
mod = md2->model->meshes[0].numFrames;
|
||||||
|
if (mod)
|
||||||
|
frame %= mod;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_MODEL_NEXTFRAME
|
#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;
|
nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1;
|
||||||
if (nextFrame >= framecount)
|
if (nextFrame >= mod)
|
||||||
nextFrame = 0;
|
nextFrame = 0;
|
||||||
if (spr->mobj->sprite2 & FF_SPR2SUPER)
|
if (frame || !(spr->mobj->state->frame & FF_SPR2ENDSTATE))
|
||||||
nextFrame = md2->model->spr2frames[spr2].superframes[nextFrame];
|
|
||||||
else
|
|
||||||
nextFrame = md2->model->spr2frames[spr2].frames[nextFrame];
|
nextFrame = md2->model->spr2frames[spr2].frames[nextFrame];
|
||||||
|
else
|
||||||
|
nextFrame = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (HWR_CanInterpolateModel(spr->mobj, md2->model))
|
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)
|
if (spr->mobj->frame & FF_ANIMATE)
|
||||||
{
|
{
|
||||||
nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1;
|
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);
|
nextFrame = (spr->mobj->state->frame & FF_FRAMEMASK);
|
||||||
//next = &md2->model->meshes[0].frames[nextFrame];
|
//next = &md2->model->meshes[0].frames[nextFrame];
|
||||||
}
|
}
|
||||||
|
@ -1069,13 +1142,14 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#undef INTERPOLERATION_LIMIT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Hurdler: it seems there is still a small problem with mobj angle
|
//Hurdler: it seems there is still a small problem with mobj angle
|
||||||
p.x = FIXED_TO_FLOAT(spr->mobj->x);
|
p.x = FIXED_TO_FLOAT(spr->mobj->x);
|
||||||
p.y = FIXED_TO_FLOAT(spr->mobj->y)+md2->offset;
|
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);
|
p.z = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height);
|
||||||
else
|
else
|
||||||
p.z = FIXED_TO_FLOAT(spr->mobj->z);
|
p.z = FIXED_TO_FLOAT(spr->mobj->z);
|
||||||
|
|
|
@ -296,7 +296,7 @@ void LoadModelSprite2(model_t *model)
|
||||||
char prefix[6];
|
char prefix[6];
|
||||||
char name[5];
|
char name[5];
|
||||||
char interpolation_flag[3];
|
char interpolation_flag[3];
|
||||||
char framechar[4];
|
char framechars[4];
|
||||||
UINT8 frame = 0;
|
UINT8 frame = 0;
|
||||||
UINT8 spr2idx;
|
UINT8 spr2idx;
|
||||||
boolean interpolate = false;
|
boolean interpolate = false;
|
||||||
|
@ -304,10 +304,11 @@ void LoadModelSprite2(model_t *model)
|
||||||
memset(&prefix, 0x00, 6);
|
memset(&prefix, 0x00, 6);
|
||||||
memset(&name, 0x00, 5);
|
memset(&name, 0x00, 5);
|
||||||
memset(&interpolation_flag, 0x00, 3);
|
memset(&interpolation_flag, 0x00, 3);
|
||||||
memset(&framechar, 0x00, 4);
|
memset(&framechars, 0x00, 4);
|
||||||
|
|
||||||
if (strlen(framename) >= 9)
|
if (strlen(framename) >= 9)
|
||||||
{
|
{
|
||||||
|
boolean super;
|
||||||
char *modelframename = framename;
|
char *modelframename = framename;
|
||||||
memcpy(&prefix, modelframename, 5);
|
memcpy(&prefix, modelframename, 5);
|
||||||
modelframename += 5;
|
modelframename += 5;
|
||||||
|
@ -320,22 +321,31 @@ void LoadModelSprite2(model_t *model)
|
||||||
interpolate = true;
|
interpolate = true;
|
||||||
modelframename += 2;
|
modelframename += 2;
|
||||||
}
|
}
|
||||||
memcpy(&framechar, modelframename, 3);
|
memcpy(&framechars, modelframename, 3);
|
||||||
frame = atoi(framechar);
|
|
||||||
|
|
||||||
if ((!memcmp(prefix, "SPR2_", 5)) || (!memcmp(prefix, "SUPER", 5)))
|
if ((super = (!memcmp(prefix, "SUPER", 5))) || (!memcmp(prefix, "SPR2_", 5)))
|
||||||
{
|
{
|
||||||
spr2idx = 0;
|
spr2idx = 0;
|
||||||
while (spr2idx < NUMPLAYERSPRITES)
|
while (spr2idx < free_spr2)
|
||||||
{
|
{
|
||||||
if (!memcmp(spr2names[spr2idx], name, 4))
|
if (!memcmp(spr2names[spr2idx], name, 4))
|
||||||
{
|
{
|
||||||
if (!spr2frames)
|
if (!spr2frames)
|
||||||
spr2frames = (modelspr2frames_t*)Z_Calloc(sizeof(modelspr2frames_t)*NUMPLAYERSPRITES, PU_STATIC, NULL);
|
spr2frames = (modelspr2frames_t*)Z_Calloc(sizeof(modelspr2frames_t)*NUMPLAYERSPRITES*2, PU_STATIC, NULL);
|
||||||
if (!memcmp(prefix, "SUPER", 5))
|
if (super)
|
||||||
spr2frames[spr2idx].superframes[frame] = i;
|
spr2idx |= FF_SPR2SUPER;
|
||||||
|
if (framechars[0])
|
||||||
|
{
|
||||||
|
frame = atoi(framechars);
|
||||||
|
if (spr2frames[spr2idx].numframes < frame+1)
|
||||||
|
spr2frames[spr2idx].numframes = frame+1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
spr2frames[spr2idx].frames[frame] = i;
|
{
|
||||||
|
frame = spr2frames[spr2idx].numframes;
|
||||||
|
spr2frames[spr2idx].numframes++;
|
||||||
|
}
|
||||||
|
spr2frames[spr2idx].frames[frame] = i;
|
||||||
spr2frames[spr2idx].interpolate = interpolate;
|
spr2frames[spr2idx].interpolate = interpolate;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ typedef struct tag_s
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
INT32 frames[256];
|
INT32 frames[256];
|
||||||
INT32 superframes[256];
|
UINT8 numframes;
|
||||||
boolean interpolate;
|
boolean interpolate;
|
||||||
} modelspr2frames_t;
|
} 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)
|
if ((playersprite_t)(spr2 & ~FF_SPR2SUPER) >= free_spr2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
while (!(skin->sprites[spr2].numframes)
|
while (!skin->sprites[spr2].numframes
|
||||||
&& spr2 != SPR2_STND
|
&& spr2 != SPR2_STND
|
||||||
&& ++i < 32) // recursion limiter
|
&& ++i < 32) // recursion limiter
|
||||||
{
|
{
|
||||||
|
|
|
@ -139,7 +139,7 @@ static loadfunc_t hwdFuncTable[] = {
|
||||||
{"GClipRect", &hwdriver.pfnGClipRect},
|
{"GClipRect", &hwdriver.pfnGClipRect},
|
||||||
{"ClearMipMapCache", &hwdriver.pfnClearMipMapCache},
|
{"ClearMipMapCache", &hwdriver.pfnClearMipMapCache},
|
||||||
{"SetSpecialState", &hwdriver.pfnSetSpecialState},
|
{"SetSpecialState", &hwdriver.pfnSetSpecialState},
|
||||||
{"DrawModel", &hwdriver.pfnDrawModel},
|
{"DrawModel", &hwdriver.pfnDrawModel},
|
||||||
{"SetTransform", &hwdriver.pfnSetTransform},
|
{"SetTransform", &hwdriver.pfnSetTransform},
|
||||||
{"GetTextureUsed", &hwdriver.pfnGetTextureUsed},
|
{"GetTextureUsed", &hwdriver.pfnGetTextureUsed},
|
||||||
{"GetRenderVersion", &hwdriver.pfnGetRenderVersion},
|
{"GetRenderVersion", &hwdriver.pfnGetRenderVersion},
|
||||||
|
|
Loading…
Reference in a new issue