* 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
|
@ -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);
|
if (mathlib) return luaL_error(L, "sprite '%s' could not be found.\n", word);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (fastncmp("SPR2_",word,4)) {
|
else if (fastncmp("SPR2_",word,5)) {
|
||||||
p = word+5;
|
p = word+5;
|
||||||
for (i = 0; i < (fixed_t)free_spr2; i++)
|
for (i = 0; i < (fixed_t)free_spr2; i++)
|
||||||
if (!spr2names[i][4])
|
if (!spr2names[i][4])
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include "../doomdef.h"
|
#include "../doomdef.h"
|
||||||
#include "../doomstat.h"
|
#include "../doomstat.h"
|
||||||
|
#include "../fastcmp.h"
|
||||||
|
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
#include "hw_drv.h"
|
#include "hw_drv.h"
|
||||||
|
@ -395,6 +396,29 @@ static md2_model_t *md2_readModel(const char *filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(model->frames[i].name, frame->name);
|
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++)
|
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];
|
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?
|
res?
|
||||||
run?
|
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 NORMALFOG 0x00000000
|
||||||
#define FADEFOG 0x19000000
|
#define FADEFOG 0x19000000
|
||||||
void HWR_DrawMD2(gr_vissprite_t *spr)
|
void HWR_DrawMD2(gr_vissprite_t *spr)
|
||||||
|
@ -1225,31 +1294,67 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
||||||
tics = spr->mobj->anim_duration;
|
tics = spr->mobj->anim_duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME: this is not yet correct
|
#define INTERPOLERATION_LIMIT TICRATE/4
|
||||||
frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames;
|
|
||||||
buff = md2->model->glCommandBuffer;
|
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
|
||||||
curr = &md2->model->frames[frame];
|
|
||||||
if (cv_grmd2.value == 1)
|
|
||||||
{
|
{
|
||||||
// frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation
|
UINT8 spr2 = P_GetModelSprite2(md2, spr->mobj->skin, spr->mobj->sprite2, spr->mobj->player);
|
||||||
if (spr->mobj->frame & FF_ANIMATE)
|
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 (durs > INTERPOLERATION_LIMIT)
|
||||||
if (nextframe >= (UINT32)spr->mobj->state->var1)
|
durs = INTERPOLERATION_LIMIT;
|
||||||
nextframe = (spr->mobj->state->frame & FF_FRAMEMASK);
|
|
||||||
nextframe %= md2->model->header.numFrames;
|
if (spr->mobj->frame & FF_ANIMATE
|
||||||
next = &md2->model->frames[nextframe];
|
|| (spr->mobj->state->nextstate != S_NULL
|
||||||
}
|
&& states[spr->mobj->state->nextstate].sprite == spr->mobj->sprite
|
||||||
else
|
&& (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) == spr->mobj->sprite2))
|
||||||
{
|
|
||||||
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]))
|
|
||||||
{
|
{
|
||||||
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];
|
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
|
//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);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#define _HW_MD2_H_
|
#define _HW_MD2_H_
|
||||||
|
|
||||||
#include "hw_glob.h"
|
#include "hw_glob.h"
|
||||||
|
#include "../info.h"
|
||||||
|
|
||||||
// magic number "IDP2" or 844121161
|
// magic number "IDP2" or 844121161
|
||||||
#define MD2_IDENT (INT32)(('2' << 24) + ('P' << 16) + ('D' << 8) + 'I')
|
#define MD2_IDENT (INT32)(('2' << 24) + ('P' << 16) + ('D' << 8) + 'I')
|
||||||
|
@ -111,7 +112,8 @@ typedef struct
|
||||||
md2_textureCoordinate_t *texCoords;
|
md2_textureCoordinate_t *texCoords;
|
||||||
md2_triangle_t *triangles;
|
md2_triangle_t *triangles;
|
||||||
md2_frame_t *frames;
|
md2_frame_t *frames;
|
||||||
INT32 *glCommandBuffer;
|
size_t spr2frames[2*NUMPLAYERSPRITES][2];
|
||||||
|
INT32 *glCommandBuffer;
|
||||||
} ATTRPACK md2_model_t;
|
} ATTRPACK md2_model_t;
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
|
|
@ -526,11 +526,11 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = {
|
||||||
|
|
||||||
0, // SPR2_TRNS,
|
0, // SPR2_TRNS,
|
||||||
|
|
||||||
0, // SPR2_NSTD,
|
FF_SPR2SUPER|SPR2_STND, // SPR2_NSTD,
|
||||||
0, // SPR2_NFLT,
|
FF_SPR2SUPER|SPR2_FLT , // SPR2_NFLT,
|
||||||
0, // SPR2_NSTN,
|
FF_SPR2SUPER|SPR2_STUN, // SPR2_NSTN,
|
||||||
SPR2_NSTN, // SPR2_NPUL,
|
SPR2_NSTN, // SPR2_NPUL,
|
||||||
0, // SPR2_NATK,
|
FF_SPR2SUPER|SPR2_ROLL, // SPR2_NATK,
|
||||||
|
|
||||||
0, // SPR2_NGT0, (should never be referenced)
|
0, // SPR2_NGT0, (should never be referenced)
|
||||||
SPR2_NGT0, // SPR2_NGT1,
|
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 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player)
|
||||||
{
|
{
|
||||||
UINT8 super = (spr2 & FF_SPR2SUPER), i = 0;
|
UINT8 super = 0, i = 0;
|
||||||
|
|
||||||
if (!skin)
|
if (!skin)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2442,6 +2442,7 @@ UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player)
|
||||||
{
|
{
|
||||||
if (spr2 & FF_SPR2SUPER)
|
if (spr2 & FF_SPR2SUPER)
|
||||||
{
|
{
|
||||||
|
super = FF_SPR2SUPER;
|
||||||
spr2 &= ~FF_SPR2SUPER;
|
spr2 &= ~FF_SPR2SUPER;
|
||||||
continue;
|
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;
|
spr2 = (player && player->charability == CA_SWIM) ? SPR2_SWIM : SPR2_FLY;
|
||||||
break;
|
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!
|
// Use the handy list, that's what it's there for!
|
||||||
default:
|
default:
|
||||||
spr2 = spr2defaults[spr2];
|
spr2 = spr2defaults[spr2];
|
||||||
|
|
Loading…
Reference in a new issue