Kart skin compatibility

This commit is contained in:
GenericHeroGuy 2025-01-25 23:52:53 +01:00
parent 7a6de57a99
commit 8cbacdeda7
7 changed files with 175 additions and 9 deletions

View file

@ -79,6 +79,7 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = {
0, // SPR2_SIGN
0, // SPR2_XTRA
0, // SPR2_KART
};
// Doesn't work with g++, needs actionf_p1 (don't modify this comment)

View file

@ -22,3 +22,5 @@ _(DEAD) // Dead
_(SIGN) // Finish signpost
_(XTRA) // Three Faces of Darkness
_(KART) // Extra frames from Kart skins

View file

@ -109,6 +109,9 @@ static void Sk_SetDefaultValue(skin_t *skin)
skin->flags = 0;
strcpy(skin->realname, "Someone");
strncpy(skin->facerank, "MISSING", 9);
strncpy(skin->facewant, "MISSING", 9);
strncpy(skin->facemmap, "MISSING", 9);
skin->starttranscolor = 96;
skin->prefcolor = SKINCOLOR_GREEN;
skin->supercolor = SKINCOLOR_SUPERGOLD1;
@ -396,6 +399,37 @@ static UINT16 W_CheckForPatchSkinMarkerInPwad(UINT16 wadid, UINT16 startlump)
return INT16_MAX; // not found
}
#define NUMKARTFRAMES 19
#define S(f, s) { f - 'A', SPR2_##s },
static UINT8 KART_TO_SPR2[][2] = {
S('A', STIN)
S('B', STIN)
S('C', STIL)
S('D', STIL)
S('E', STIR)
S('F', STIR)
S('J', SLWN)
S('G', SLWN)
S('K', SLWL)
S('H', SLWL)
S('L', SLWR)
S('I', SLWR)
S('A', FSTN)
S('J', FSTN)
S('C', FSTL)
S('K', FSTL)
S('E', FSTR)
S('L', FSTR)
S('M', DRLN)
S('N', DRLN)
S('O', DRRN)
S('P', DRRN)
S('Q', SPIN)
S('R', KART)
S('S', SIGN)
};
#undef S
static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, skin_t *skin)
{
UINT16 newlastlump;
@ -427,20 +461,88 @@ static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, ski
*lastlump = newlastlump; // okay, make the normal sprite set loading end there
}*/
// load all sprite sets we are aware of... for normal stuff.
for (sprite2 = 0; sprite2 < free_spr2; sprite2++)
R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[sprite2], wadnum, *lump, *lastlump);
if (!wadfiles[wadnum]->compatmode)
{
// load all sprite sets we are aware of... for normal stuff.
for (sprite2 = 0; sprite2 < free_spr2; sprite2++)
R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[sprite2], wadnum, *lump, *lastlump);
}
else
{
// okay, now we have to get fancy...
// first, just dump all the frames in a temporary def
size_t i;
spritedef_t *sd;
spriteframe_t *sf;
spritedef_t tmp = {};
const char *sprname = W_CheckNameForNumPwad(wadnum, *lump);
R_AddSingleSpriteDef(sprname, &tmp, wadnum, *lump, *lastlump);
if (tmp.numframes < NUMKARTFRAMES)
I_Error("R_LoadSkinSprites: too few frames for kart skin");
// now shuffle them around to fit the new SPR2 system
// iterate over KART_TO_SPR2, then add any excess frames to SPR2_KART
#define SPR2COUNT sizeof(KART_TO_SPR2)/sizeof(*KART_TO_SPR2)
for (i = 0; i < SPR2COUNT - NUMKARTFRAMES + tmp.numframes; i++)
{
boolean excess = i >= SPR2COUNT;
sf = &tmp.spriteframes[excess ? i - SPR2COUNT + NUMKARTFRAMES : KART_TO_SPR2[i][0]];
sd = &skin->sprites[excess ? SPR2_KART : KART_TO_SPR2[i][1]];
sd->spriteframes = Z_Realloc(sd->spriteframes, sizeof(*sd->spriteframes) * (sd->numframes+1), PU_STATIC, NULL);
sd->spriteframes[sd->numframes++] = *sf;
}
Z_Free(tmp.spriteframes);
#undef SPR2COUNT
// now we have to rotate the drift frames. i hate this.
sd = &skin->sprites[SPR2_DRRN];
for (i = 0; i < sd->numframes; i++)
{
sf = &sd->spriteframes[i];
if (sf->rotate != SRF_3D)
continue;
lumpnum_t lastpat = sf->lumppat[7];
size_t lastid = sf->lumpid[7];
for (int r = 7; r >= 1; r--)
{
sf->lumppat[r] = sf->lumppat[r-1];
sf->lumpid[r] = sf->lumpid[r-1];
}
sf->lumppat[0] = lastpat;
sf->lumpid[0] = lastid;
}
sd = &skin->sprites[SPR2_DRLN];
for (i = 0; i < sd->numframes; i++)
{
sf = &sd->spriteframes[i];
if (sf->rotate != SRF_3D)
continue;
lumpnum_t firstpat = sf->lumppat[0];
size_t firstid = sf->lumpid[0];
for (int r = 0; r < 8; r++)
{
sf->lumppat[r] = sf->lumppat[r+1];
sf->lumpid[r] = sf->lumpid[r+1];
}
sf->lumppat[7] = firstpat;
sf->lumpid[7] = firstid;
}
R_AddKartFaces(skin);
}
if (skin->sprites[0].numframes == 0)
I_Error("R_LoadSkinSprites: no frames found for sprite SPR2_%s\n", spr2names[0]);
}
#undef NUMKARTFRAMES
// returns whether found appropriate property
static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value, boolean compat)
{
// custom translation table
if (!stricmp(stoken, "startcolor"))
skin->starttranscolor = atoi(value);
skin->starttranscolor = compat ? R_GetPaletteRemap(atoi(value)) : atoi(value);
#define FULLPROCESS(field) else if (!stricmp(stoken, #field)) skin->field = get_number(value);
// character type identification
@ -492,6 +594,11 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
GETFLAG(MACHINE)
#undef GETFLAG
#define GETPATCH(field) else if (compat && !stricmp(stoken, #field)) strncpy(skin->field, value, 8);
GETPATCH(facerank)
GETPATCH(facewant)
GETPATCH(facemmap)
else // let's check if it's a sound, otherwise error out
{
boolean found = false;
@ -667,7 +774,7 @@ void R_AddSkins(UINT16 wadnum)
pos++;
}
}
else if (!R_ProcessPatchableFields(skin, stoken, value))
else if (!R_ProcessPatchableFields(skin, stoken, value, wadfiles[wadnum]->compatmode))
CONS_Debug(DBG_SETUP, "R_AddSkins: Unknown keyword '%s' in S_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename);
next_token:
@ -822,7 +929,7 @@ void R_PatchSkins(UINT16 wadnum)
pos++;
}
}
else if (!R_ProcessPatchableFields(skin, stoken, value))
else if (!R_ProcessPatchableFields(skin, stoken, value, wadfiles[wadnum]->compatmode))
CONS_Debug(DBG_SETUP, "R_PatchSkins: Unknown keyword '%s' in P_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename);
}

View file

@ -42,6 +42,7 @@ struct skin_t
skinflags_t flags;
char realname[SKINNAMESIZE+1]; // Display name for level completion.
char facerank[9], facewant[9], facemmap[9]; // Arbitrarily named patch lumps
// SRB2kart
UINT8 kartspeed;

View file

@ -249,6 +249,30 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
sprtemp[frame].flip &= ~(1<<rotation);
}
#define NUMFACES 3
static size_t KART_FACES[NUMFACES] = {
offsetof(skin_t, facerank),
offsetof(skin_t, facewant),
offsetof(skin_t, facemmap),
};
void R_AddKartFaces(skin_t *skin)
{
memset(sprtemp, 0xff, sizeof(sprtemp));
spritedef_t *sd = &skin->sprites[SPR2_XTRA];
for (size_t f = 0; f < NUMFACES; f++)
{
lumpnum_t lumpnum = W_CheckNumForName(reinterpret_cast<char *>(skin) + KART_FACES[f]); // how do you do, fellow C++ers?
if (lumpnum == LUMPERROR)
I_Error("R_AddKartFaces: missing patch %s for skin %s", reinterpret_cast<char *>(skin) + KART_FACES[f], skin->name);
R_InstallSpriteLump(WADFILENUM(lumpnum), LUMPNUM(lumpnum), numspritelumps++, f, 0, 0);
}
sd->numframes = NUMFACES;
sd->spriteframes = static_cast<spriteframe_t*>(Z_Realloc(sd->spriteframes, sizeof(spriteframe_t)*NUMFACES, PU_STATIC, NULL));
M_Memcpy(sd->spriteframes, sprtemp, sizeof(spriteframe_t)*NUMFACES);
}
#undef NUMFACES
// Install a single sprite, given its identifying name (4 chars)
//
// (originally part of R_AddSpriteDefs)

View file

@ -31,6 +31,7 @@ extern "C" {
#define FEETADJUST (4<<FRACBITS) // R_AddSingleSpriteDef
void R_AddKartFaces(skin_t *skin);
boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 wadnum, UINT16 startlump, UINT16 endlump);
//faB: find sprites in wadfile, replace existing, add new ones

View file

@ -298,10 +298,40 @@ static inline boolean CheckCompatFilename(char *filename)
return toupper(basename ? basename[1] : filename[0]) == 'K';
}
static inline boolean CheckCompatSkins(UINT16 wadnum)
{
#if 0
UINT16 skin = W_CheckNumForNamePwad("S_SKIN", wadnum, 0);
if (skin == INT16_MAX)
return false;
// valid kart skins can only have one sprname for all frames
const char *firstsprname = W_CheckNameForNumPwad(wadnum, ++skin);
int maxframe = 0;
while (true)
{
const char *sprname = W_CheckNameForNumPwad(wadnum, ++skin);
if (!sprname)
break;
if (memcmp(sprname, firstsprname, 4))
break;
maxframe = max(maxframe, sprname[4]);
}
// how many frames does this first sprite name have?
// if there's at least 19 frames, this is a valid kart skin,
// so we need compatmode to load skins from this file!
return (maxframe - 'A') >= 18;
#else
return false;
#endif
}
// try to figure out if a PK3 file needs compatmode enabled (palette remap)
static inline boolean CheckCompatZip(UINT16 wadnum)
{
if (CheckCompatFilename(wadfiles[wadnum]->filename))
if (CheckCompatFilename(wadfiles[wadnum]->filename) || CheckCompatSkins(wadnum))
return true;
// assume RR/2.2 for PK3s so basegame assets work
@ -311,7 +341,7 @@ static inline boolean CheckCompatZip(UINT16 wadnum)
// ditto, but for WADs
static inline boolean CheckCompatWad(UINT16 wadnum)
{
if (CheckCompatFilename(wadfiles[wadnum]->filename))
if (CheckCompatFilename(wadfiles[wadnum]->filename) || CheckCompatSkins(wadnum))
return true;
// assume Kart/2.1 for WADs so basegame assets work