mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-26 04:30:55 +00:00
* Added support for sprite2s to MD2s!
- Name each frame either SPR2_**** or SUPER**** (where **** is the 4-character name) - If the name is 3 characters, '.' is accepted as a substitute for the '_', but a space/absent isn't (for tool-related reasons). - Adds a big sprite2 index array to all models, even non-player ones. Sorry! * Made MD2 frame interpoleration only work across the same spriteset (and sprite2set). * Made MD2 frame interpoleration happen when there's less than a quarter of a second between frames, as opposed to the hardcoded specific animation disabling. * Fixed sprite2-related typo in dehacked.c.
This commit is contained in:
parent
4da6169892
commit
76300026f8
5 changed files with 133 additions and 43 deletions
|
@ -7982,7 +7982,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
if (mathlib) return luaL_error(L, "sprite '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("SPR2_",word,4)) {
|
||||
else if (fastncmp("SPR2_",word,5)) {
|
||||
p = word+5;
|
||||
for (i = 0; i < (fixed_t)free_spr2; i++)
|
||||
if (!spr2names[i][4])
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "../doomdef.h"
|
||||
#include "../doomstat.h"
|
||||
#include "../fastcmp.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hw_drv.h"
|
||||
|
@ -395,6 +396,29 @@ static md2_model_t *md2_readModel(const char *filename)
|
|||
}
|
||||
|
||||
strcpy(model->frames[i].name, frame->name);
|
||||
if (frame->name[0] == 'S')
|
||||
{
|
||||
boolean super;
|
||||
if ((super = (fastncmp("UPER", frame->name+1, 4))) // SUPER
|
||||
|| fastncmp("PR2_", frame->name+1, 4)) // SPR2_
|
||||
{
|
||||
UINT8 spr2;
|
||||
for (spr2 = 0; spr2 < free_spr2; spr2++)
|
||||
if (fastncmp(frame->name+5,spr2names[spr2],3)
|
||||
&& ((frame->name[8] == spr2names[spr2][3])
|
||||
|| (frame->name[8] == '.' && spr2names[spr2][3] == '_')))
|
||||
break;
|
||||
|
||||
if (spr2 < free_spr2)
|
||||
{
|
||||
if (super)
|
||||
spr2 |= FF_SPR2SUPER;
|
||||
if (model->spr2frames[spr2][1]++ == 0) // numspr2frames
|
||||
model->spr2frames[spr2][0] = i; // starting frame
|
||||
CONS_Debug(DBG_RENDER, "frame %s, sprite2 %s - starting frame %d, number of frames %d\n", frame->name, spr2names[spr2 & ~FF_SPR2SUPER], model->spr2frames[spr2][0], model->spr2frames[spr2][1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (j = 0; j < model->header.numVertices; j++)
|
||||
{
|
||||
model->frames[i].vertices[j].vertex[0] = (float) ((INT32) frame->alias_vertices[j].vertex[0]) * frame->scale[0] + frame->translate[0];
|
||||
|
@ -1078,6 +1102,51 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, con
|
|||
res?
|
||||
run?
|
||||
*/
|
||||
|
||||
static UINT8 P_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t *player)
|
||||
{
|
||||
UINT8 super = 0, i = 0;
|
||||
|
||||
if (!md2 || !skin)
|
||||
return 0;
|
||||
|
||||
while (!(md2->model->spr2frames[spr2][1])
|
||||
&& 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 == 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;
|
||||
}
|
||||
|
||||
return spr2;
|
||||
}
|
||||
|
||||
#define NORMALFOG 0x00000000
|
||||
#define FADEFOG 0x19000000
|
||||
void HWR_DrawMD2(gr_vissprite_t *spr)
|
||||
|
@ -1225,31 +1294,67 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
tics = spr->mobj->anim_duration;
|
||||
}
|
||||
|
||||
//FIXME: this is not yet correct
|
||||
frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames;
|
||||
buff = md2->model->glCommandBuffer;
|
||||
curr = &md2->model->frames[frame];
|
||||
if (cv_grmd2.value == 1)
|
||||
#define INTERPOLERATION_LIMIT TICRATE/4
|
||||
|
||||
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
|
||||
{
|
||||
// frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation
|
||||
if (spr->mobj->frame & FF_ANIMATE)
|
||||
UINT8 spr2 = P_GetModelSprite2(md2, spr->mobj->skin, spr->mobj->sprite2, spr->mobj->player);
|
||||
UINT8 mod = md2->model->spr2frames[spr2][1] ? md2->model->spr2frames[spr2][1] : md2->model->header.numFrames;
|
||||
//FIXME: this is not yet correct
|
||||
frame = md2->model->spr2frames[spr2][0] + ((spr->mobj->frame & FF_FRAMEMASK) % mod);
|
||||
buff = md2->model->glCommandBuffer;
|
||||
curr = &md2->model->frames[frame];
|
||||
if (cv_grmd2.value == 1 && tics <= INTERPOLERATION_LIMIT)
|
||||
{
|
||||
UINT32 nextframe = (spr->mobj->frame & FF_FRAMEMASK) + 1;
|
||||
if (nextframe >= (UINT32)spr->mobj->state->var1)
|
||||
nextframe = (spr->mobj->state->frame & FF_FRAMEMASK);
|
||||
nextframe %= md2->model->header.numFrames;
|
||||
next = &md2->model->frames[nextframe];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL
|
||||
&& !(spr->mobj->player && spr->mobj->state->nextstate == S_PLAY_WAIT && spr->mobj->state == &states[S_PLAY_STND]))
|
||||
if (durs > INTERPOLERATION_LIMIT)
|
||||
durs = INTERPOLERATION_LIMIT;
|
||||
|
||||
if (spr->mobj->frame & FF_ANIMATE
|
||||
|| (spr->mobj->state->nextstate != S_NULL
|
||||
&& states[spr->mobj->state->nextstate].sprite == spr->mobj->sprite
|
||||
&& (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) == spr->mobj->sprite2))
|
||||
{
|
||||
const UINT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames;
|
||||
UINT32 nextframe = (spr->mobj->frame & FF_FRAMEMASK) + 1;
|
||||
if (nextframe >= (UINT32)((skin_t*)spr->mobj->skin)->sprites[spr->mobj->sprite2].numframes)
|
||||
nextframe = 0;
|
||||
nextframe = md2->model->spr2frames[spr2][0] + (nextframe % md2->model->spr2frames[spr2][1]);
|
||||
next = &md2->model->frames[nextframe];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//FIXME: this is not yet correct
|
||||
frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames;
|
||||
buff = md2->model->glCommandBuffer;
|
||||
curr = &md2->model->frames[frame];
|
||||
if (cv_grmd2.value == 1 && tics <= INTERPOLERATION_LIMIT)
|
||||
{
|
||||
if (durs > INTERPOLERATION_LIMIT)
|
||||
durs = INTERPOLERATION_LIMIT;
|
||||
|
||||
// frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation
|
||||
if (spr->mobj->frame & FF_ANIMATE)
|
||||
{
|
||||
UINT32 nextframe = (spr->mobj->frame & FF_FRAMEMASK) + 1;
|
||||
if (nextframe >= (UINT32)spr->mobj->state->var1)
|
||||
nextframe = (spr->mobj->state->frame & FF_FRAMEMASK);
|
||||
nextframe %= md2->model->header.numFrames;
|
||||
next = &md2->model->frames[nextframe];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (spr->mobj->state->nextstate != S_NULL
|
||||
&& states[spr->mobj->state->nextstate].sprite == spr->mobj->sprite)
|
||||
{
|
||||
const UINT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames;
|
||||
next = &md2->model->frames[nextframe];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef INTERPOLERATION_LIMIT
|
||||
|
||||
//Hurdler: it seems there is still a small problem with mobj angle
|
||||
p.x = FIXED_TO_FLOAT(spr->mobj->x);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define _HW_MD2_H_
|
||||
|
||||
#include "hw_glob.h"
|
||||
#include "../info.h"
|
||||
|
||||
// magic number "IDP2" or 844121161
|
||||
#define MD2_IDENT (INT32)(('2' << 24) + ('P' << 16) + ('D' << 8) + 'I')
|
||||
|
@ -111,7 +112,8 @@ typedef struct
|
|||
md2_textureCoordinate_t *texCoords;
|
||||
md2_triangle_t *triangles;
|
||||
md2_frame_t *frames;
|
||||
INT32 *glCommandBuffer;
|
||||
size_t spr2frames[2*NUMPLAYERSPRITES][2];
|
||||
INT32 *glCommandBuffer;
|
||||
} ATTRPACK md2_model_t;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
|
|
@ -526,11 +526,11 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = {
|
|||
|
||||
0, // SPR2_TRNS,
|
||||
|
||||
0, // SPR2_NSTD,
|
||||
0, // SPR2_NFLT,
|
||||
0, // SPR2_NSTN,
|
||||
FF_SPR2SUPER|SPR2_STND, // SPR2_NSTD,
|
||||
FF_SPR2SUPER|SPR2_FLT , // SPR2_NFLT,
|
||||
FF_SPR2SUPER|SPR2_STUN, // SPR2_NSTN,
|
||||
SPR2_NSTN, // SPR2_NPUL,
|
||||
0, // SPR2_NATK,
|
||||
FF_SPR2SUPER|SPR2_ROLL, // SPR2_NATK,
|
||||
|
||||
0, // SPR2_NGT0, (should never be referenced)
|
||||
SPR2_NGT0, // SPR2_NGT1,
|
||||
|
|
|
@ -2431,7 +2431,7 @@ CV_PossibleValue_t skin_cons_t[MAXSKINS+1];
|
|||
|
||||
UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player)
|
||||
{
|
||||
UINT8 super = (spr2 & FF_SPR2SUPER), i = 0;
|
||||
UINT8 super = 0, i = 0;
|
||||
|
||||
if (!skin)
|
||||
return 0;
|
||||
|
@ -2442,6 +2442,7 @@ UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player)
|
|||
{
|
||||
if (spr2 & FF_SPR2SUPER)
|
||||
{
|
||||
super = FF_SPR2SUPER;
|
||||
spr2 &= ~FF_SPR2SUPER;
|
||||
continue;
|
||||
}
|
||||
|
@ -2460,24 +2461,6 @@ UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player)
|
|||
spr2 = (player && player->charability == CA_SWIM) ? SPR2_SWIM : SPR2_FLY;
|
||||
break;
|
||||
|
||||
// NiGHTS sprites.
|
||||
case SPR2_NSTD:
|
||||
spr2 = SPR2_STND;
|
||||
super = FF_SPR2SUPER;
|
||||
break;
|
||||
case SPR2_NFLT:
|
||||
spr2 = SPR2_FLT ;
|
||||
super = FF_SPR2SUPER;
|
||||
break;
|
||||
case SPR2_NSTN:
|
||||
spr2 = SPR2_STUN;
|
||||
super = FF_SPR2SUPER;
|
||||
break;
|
||||
case SPR2_NATK:
|
||||
spr2 = SPR2_ROLL;
|
||||
super = FF_SPR2SUPER;
|
||||
break;
|
||||
|
||||
// Use the handy list, that's what it's there for!
|
||||
default:
|
||||
spr2 = spr2defaults[spr2];
|
||||
|
|
Loading…
Reference in a new issue