Merge branch 'raise-skin-limit' into 'next'

Raise the skin limit

See merge request STJr/SRB2!1466
This commit is contained in:
Logan Aerl Arias 2024-01-01 22:07:42 +00:00
commit dd8ae3db09
44 changed files with 565 additions and 625 deletions

View file

@ -2056,7 +2056,7 @@ static void CV_SetValueMaybeStealth(consvar_t *var, INT32 value, boolean stealth
if ((value < 0) || (value >= numskins))
tmpskin = "None";
else
tmpskin = skins[value].name;
tmpskin = skins[value]->name;
strncpy(val, tmpskin, SKINNAMESIZE);
}
else

View file

@ -1429,10 +1429,6 @@ void D_SRB2Main(void)
// Make backups of some SOCcable tables.
P_BackupTables();
// Setup character tables
// Have to be done here before files are loaded
M_InitCharacterTables();
mainwads = 3; // doesn't include music.dta
#ifdef USE_PATCH_DTA
mainwads++;

View file

@ -451,10 +451,10 @@ typedef struct player_s
UINT16 flashcount;
UINT16 flashpal;
// Player skin colorshift, 0-15 for which color to draw player.
// Player skin colorshift, which color to draw player.
UINT16 skincolor;
INT32 skin;
UINT8 skin;
UINT32 availabilities;
UINT32 score; // player score (total)

View file

@ -188,25 +188,22 @@ void clear_levels(void)
P_AllocMapHeader(gamemap-1);
}
static boolean findFreeSlot(INT32 *num)
static boolean findCharacterSlot(INT32 *num)
{
// Send the character select entry to a free slot.
while (*num < MAXSKINS && (description[*num].used))
*num = *num+1;
if (description)
{
// Send the character select entry to a free slot.
while (*num < numdescriptions && (description[*num].used))
(*num)++;
}
// No more free slots. :(
if (*num >= MAXSKINS)
// No more free slots.
if (*num >= MAXCHARACTERSLOTS)
return false;
else if (*num >= numdescriptions)
M_InitCharacterTables((*num) + 1);
// Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...)
description[*num].picname[0] = '\0';
description[*num].nametag[0] = '\0';
description[*num].displayname[0] = '\0';
description[*num].oppositecolor = SKINCOLOR_NONE;
description[*num].tagtextcolor = SKINCOLOR_NONE;
description[*num].tagoutlinecolor = SKINCOLOR_NONE;
// Found one! ^_^
// Found one!
return (description[*num].used = true);
}
@ -217,30 +214,43 @@ void readPlayer(MYFILE *f, INT32 num)
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
char *word;
char *word2;
char *displayname = ZZ_Alloc(MAXLINELEN+1);
INT32 i;
boolean slotfound = false;
boolean failure = false;
INT32 i;
if (num < 0 || num >= MAXCHARACTERSLOTS)
{
deh_warning("Character %d out of range (0 - %d)", num, MAXCHARACTERSLOTS-1);
failure = true;
}
#define FINDSLOT \
if (!failure && !slotfound && (slotfound = findCharacterSlot(&num)) == false) { \
failure = true; \
deh_warning("Too many characters, ignoring"); \
}
#define SLOTFOUND \
if (!slotfound && (slotfound = findFreeSlot(&num)) == false) \
goto done;
displayname[MAXLINELEN] = '\0';
FINDSLOT \
if (failure) \
continue;
do
{
if (myfgets(s, MAXLINELEN, f))
{
char stringvalue[MAXLINELEN];
if (s[0] == '\n')
break;
for (i = 0; i < MAXLINELEN-3; i++)
stringvalue[0] = '\0';
for (i = 0; i < MAXLINELEN-3 && !failure; i++)
{
char *tmp;
if (s[i] == '=')
{
tmp = &s[i+2];
strncpy(displayname, tmp, SKINNAMESIZE);
strlcpy(stringvalue, &s[i+2], sizeof stringvalue);
break;
}
}
@ -255,7 +265,13 @@ void readPlayer(MYFILE *f, INT32 num)
{
char *playertext = NULL;
SLOTFOUND
FINDSLOT
if (failure)
{
ignorelinesuntilhash(f);
continue;
}
// A friendly neighborhood alias for brevity's sake
#define NOTE_SIZE sizeof(description[num].notes)
@ -275,7 +291,7 @@ void readPlayer(MYFILE *f, INT32 num)
myhashfgets(playertext, NOTE_SIZE, f), NOTE_SIZE);
}
else
strcpy(description[num].notes, "");
description[num].notes[0] = '\0';
// For some reason, cutting the string did not work above. Most likely due to strcpy or strcat...
// It works down here, though.
@ -304,37 +320,32 @@ void readPlayer(MYFILE *f, INT32 num)
if (word2[strlen(word2)-1] == '\n')
word2[strlen(word2)-1] = '\0';
i = atoi(word2);
if (fastcmp(word, "PICNAME"))
{
SLOTFOUND
strncpy(description[num].picname, word2, 8);
}
// new character select
else if (fastcmp(word, "DISPLAYNAME"))
{
char *cur = NULL;
SLOTFOUND
// replace '#' with line breaks
// (also remove any '\n')
// Remove any line breaks
cur = strchr(stringvalue, '\n');
if (cur)
*cur = '\0';
// Turn '#' into line breaks
cur = strchr(stringvalue, '#');
while (cur)
{
char *cur = NULL;
// remove '\n'
cur = strchr(displayname, '\n');
if (cur)
*cur = '\0';
// turn '#' into '\n'
cur = strchr(displayname, '#');
while (cur)
{
*cur = '\n';
cur = strchr(cur, '#');
}
*cur = '\n';
cur = strchr(cur, '#');
}
// copy final string
strncpy(description[num].displayname, displayname, SKINNAMESIZE);
strlcpy(description[num].displayname, stringvalue, sizeof description[num].displayname);
}
else if (fastcmp(word, "OPPOSITECOLOR") || fastcmp(word, "OPPOSITECOLOUR"))
{
@ -365,10 +376,12 @@ void readPlayer(MYFILE *f, INT32 num)
Because of this, you are allowed to edit any previous entries you like, but only if you
signal that you are purposely doing so by disabling and then reenabling the slot.
*/
if (i && !slotfound && (slotfound = findFreeSlot(&num)) == false)
goto done;
i = atoi(word2);
if (i && !slotfound && (slotfound = findCharacterSlot(&num)) == false)
failure = true;
description[num].used = (!!i);
if (!failure)
description[num].used = (!!i);
}
else if (fastcmp(word, "SKINNAME"))
{
@ -377,13 +390,12 @@ void readPlayer(MYFILE *f, INT32 num)
strlcpy(description[num].skinname, word2, sizeof description[num].skinname);
strlwr(description[num].skinname);
}
else
else if (!failure)
deh_warning("readPlayer %d: unknown word '%s'", num, word);
}
} while (!myfeof(f)); // finish when the line is empty
#undef FINDSLOT
#undef SLOTFOUND
done:
Z_Free(displayname);
Z_Free(s);
}
@ -933,7 +945,7 @@ void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2)
INT32 value;
#endif
char *lastline;
INT32 skinnumbers[MAXSKINS];
UINT8 *skinnumbers = NULL;
INT32 foundskins = 0;
// allocate a spriteinfo
@ -1022,7 +1034,9 @@ void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2)
break;
}
skinnumbers[foundskins] = skinnum;
if (skinnumbers == NULL)
skinnumbers = Z_Malloc(sizeof(UINT8) * numskins, PU_STATIC, NULL);
skinnumbers[foundskins] = (UINT8)skinnum;
foundskins++;
}
else if (fastcmp(word, "DEFAULT"))
@ -1065,8 +1079,7 @@ void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2)
}
for (i = 0; i < foundskins; i++)
{
size_t skinnum = skinnumbers[i];
skin_t *skin = &skins[skinnum];
skin_t *skin = skins[skinnumbers[i]];
spriteinfo_t *sprinfo = skin->sprinfo;
M_Memcpy(&sprinfo[num], info, sizeof(spriteinfo_t));
}
@ -1085,6 +1098,8 @@ void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2)
Z_Free(s);
Z_Free(info);
if (skinnumbers)
Z_Free(skinnumbers);
}
void readsprite2(MYFILE *f, INT32 num)
@ -1130,7 +1145,6 @@ void readsprite2(MYFILE *f, INT32 num)
Z_Free(s);
}
// copypasted from readPlayer :]
void readgametype(MYFILE *f, char *gtname)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);

View file

@ -169,6 +169,20 @@ static void ignorelines(MYFILE *f)
Z_Free(s);
}
void ignorelinesuntilhash(MYFILE *f)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
do
{
if (myfgets(s, MAXLINELEN, f))
{
if (s[0] == '#')
break;
}
} while (!myfeof(f));
Z_Free(s);
}
static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
@ -226,13 +240,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
i = 0;
if (fastcmp(word, "CHARACTER"))
{
if (i >= 0 && i < 32)
readPlayer(f, i);
else
{
deh_warning("Character %d out of range (0 - 31)", i);
ignorelines(f);
}
readPlayer(f, i);
continue;
}
else if (fastcmp(word, "EMBLEM"))

View file

@ -61,4 +61,5 @@ typedef struct
#define myfeof(a) (a->data + a->size <= a->curpos)
char *myfgets(char *buf, size_t bufsize, MYFILE *f);
char *myhashfgets(char *buf, size_t bufsize, MYFILE *f);
void ignorelinesuntilhash(MYFILE *f);
#endif

View file

@ -233,9 +233,16 @@ extern char logfilename[1024];
// NOTE: it needs more than this to increase the number of players...
#define MAXPLAYERS 32
#define MAXSKINS 32
#define PLAYERSMASK (MAXPLAYERS-1)
#define MAXPLAYERNAME 21
#define PLAYERSMASK (MAXPLAYERS-1)
// Don't make MAXSKINS higher than 256, since skin numbers are used with an
// UINT8 in various parts of the codebase. If you do anyway, the data type
// of those variables will have to be changed into at least an UINT16.
// This change must affect code such as demo recording and playback,
// and the structure of some networking packets and commands.
#define MAXSKINS 256
#define MAXCHARACTERSLOTS (MAXSKINS * 3) // Should be higher than MAXSKINS.
#define COLORRAMPSIZE 16
#define MAXCOLORNAME 32

View file

@ -1603,9 +1603,9 @@ void F_GameEvaluationDrawer(void)
rtatext = (marathonmode & MA_INGAME) ? "In-game timer" : "RTA timer";
cuttext = (marathonmode & MA_NOCUTSCENES) ? "" : " w/ cutscenes";
if (botskin)
endingtext = va("%s & %s, %s%s", skins[players[consoleplayer].skin].realname, skins[botskin-1].realname, rtatext, cuttext);
endingtext = va("%s & %s, %s%s", skins[players[consoleplayer].skin]->realname, skins[botskin-1]->realname, rtatext, cuttext);
else
endingtext = va("%s, %s%s", skins[players[consoleplayer].skin].realname, rtatext, cuttext);
endingtext = va("%s, %s%s", skins[players[consoleplayer].skin]->realname, rtatext, cuttext);
V_DrawCenteredString(BASEVIDWIDTH/2, 182, V_SNAPTOBOTTOM|(ultimatemode ? V_REDMAP : V_YELLOWMAP), endingtext);
}
}
@ -1719,9 +1719,9 @@ static void F_CacheEnding(void)
UINT8 skinnum = players[consoleplayer].skin;
spritedef_t *sprdef;
spriteframe_t *sprframe;
if (skins[skinnum].sprites[SPR2_XTRA].numframes > (XTRA_ENDING+2))
if (skins[skinnum]->sprites[SPR2_XTRA].numframes > (XTRA_ENDING+2))
{
sprdef = &skins[skinnum].sprites[SPR2_XTRA];
sprdef = &skins[skinnum]->sprites[SPR2_XTRA];
// character head, skin specific
sprframe = &sprdef->spriteframes[XTRA_ENDING];
endfwrk[0] = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH_LOWPRIORITY);
@ -2167,7 +2167,7 @@ void F_EndingDrawer(void)
boolean donttouch = false;
const char *str;
if (goodending)
str = va("[S] %s: Engage.", skins[players[consoleplayer].skin].realname);
str = va("[S] %s: Engage.", skins[players[consoleplayer].skin]->realname);
else
str = "[S] Eggman: Abscond.";
@ -3554,7 +3554,7 @@ void F_StartContinue(void)
S_ChangeMusicInternal("_conti", false);
S_StopSounds();
contskins[0] = &skins[players[consoleplayer].skin];
contskins[0] = skins[players[consoleplayer].skin];
cont_spr2[0][0] = P_GetSkinSprite2(contskins[0], SPR2_CNT1, NULL);
cont_spr2[0][2] = contskins[0]->contangle & 7;
contcolormaps[0] = R_GetTranslationColormap(players[consoleplayer].skin, players[consoleplayer].skincolor, GTC_CACHE);
@ -3570,7 +3570,7 @@ void F_StartContinue(void)
else // HACK
secondplaya = 1;
contskins[1] = &skins[players[secondplaya].skin];
contskins[1] = skins[players[secondplaya].skin];
cont_spr2[1][0] = P_GetSkinSprite2(contskins[1], SPR2_CNT4, NULL);
cont_spr2[1][2] = (contskins[1]->contangle >> 3) & 7;
contcolormaps[1] = R_GetTranslationColormap(players[secondplaya].skin, players[secondplaya].skincolor, GTC_CACHE);

View file

@ -492,7 +492,7 @@ void G_WriteGhostTic(mobj_t *ghost)
if (ghost->player->followmobj->colorized)
followtic |= FZT_COLORIZED;
if (followtic & FZT_SKIN)
WRITEUINT8(demo_p,(UINT8)(((skin_t *)(ghost->player->followmobj->skin))-skins));
WRITEUINT8(demo_p,(UINT8)(((skin_t *)ghost->player->followmobj->skin)->skinnum));
oldghost.flags2 |= MF2_AMBUSH;
}
@ -761,7 +761,7 @@ void G_GhostTicker(void)
g->mo->color = SKINCOLOR_WHITE;
break;
case GHC_NIGHTSSKIN: // not actually a colour
g->mo->skin = &skins[DEFAULTNIGHTSSKIN];
g->mo->skin = skins[DEFAULTNIGHTSSKIN];
break;
}
}
@ -1387,7 +1387,7 @@ void G_WriteMetalTic(mobj_t *metal)
if (metal->player->followmobj->colorized)
followtic |= FZT_COLORIZED;
if (followtic & FZT_SKIN)
WRITEUINT8(demo_p,(UINT8)(((skin_t *)(metal->player->followmobj->skin))-skins));
WRITEUINT8(demo_p,(UINT8)(((skin_t *)metal->player->followmobj->skin)->skinnum));
oldmetal.flags2 |= MF2_AMBUSH;
}
@ -1540,7 +1540,7 @@ void G_BeginRecording(void)
demo_p += 16;
// Skin
const char *skinname = skins[players[0].skin].name;
const char *skinname = skins[players[0].skin]->name;
for (i = 0; i < 16 && skinname[i]; i++)
name[i] = skinname[i];
for (; i < 16; i++)
@ -2289,7 +2289,7 @@ void G_DoPlayDemo(char *defdemoname)
G_InitNew(false, G_BuildMapName(gamemap), true, true, false);
// Set color
players[0].skincolor = skins[players[0].skin].prefcolor;
players[0].skincolor = skins[players[0].skin]->prefcolor;
for (i = 0; i < numskincolors; i++)
if (!stricmp(skincolors[i].name,color))
{
@ -2609,11 +2609,11 @@ void G_AddGhost(char *defdemoname)
gh->oldmo.z = gh->mo->z;
// Set skin
gh->mo->skin = &skins[0];
gh->mo->skin = skins[0];
for (i = 0; i < numskins; i++)
if (!stricmp(skins[i].name,skin))
if (!stricmp(skins[i]->name,skin))
{
gh->mo->skin = &skins[i];
gh->mo->skin = skins[i];
break;
}
gh->oldmo.skin = gh->mo->skin;

View file

@ -588,14 +588,14 @@ static void G_SetMainRecords(gamedata_t *data, player_t *player)
I_Error("Out of memory for replay filepath\n");
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap));
snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, skins[cv_chooseskin.value-1].name);
snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, skins[cv_chooseskin.value-1]->name);
if (FIL_FileExists(lastdemo))
{
UINT8 *buf;
size_t len = FIL_ReadFile(lastdemo, &buf);
snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, skins[cv_chooseskin.value-1].name);
snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, skins[cv_chooseskin.value-1]->name);
if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & 1)
{ // Better time, save this demo.
if (FIL_FileExists(bestdemo))
@ -604,7 +604,7 @@ static void G_SetMainRecords(gamedata_t *data, player_t *player)
CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW RECORD TIME!"), M_GetText("Saved replay as"), bestdemo);
}
snprintf(bestdemo, 255, "%s-%s-score-best.lmp", gpath, skins[cv_chooseskin.value-1].name);
snprintf(bestdemo, 255, "%s-%s-score-best.lmp", gpath, skins[cv_chooseskin.value-1]->name);
if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<1)))
{ // Better score, save this demo.
if (FIL_FileExists(bestdemo))
@ -613,7 +613,7 @@ static void G_SetMainRecords(gamedata_t *data, player_t *player)
CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW HIGH SCORE!"), M_GetText("Saved replay as"), bestdemo);
}
snprintf(bestdemo, 255, "%s-%s-rings-best.lmp", gpath, skins[cv_chooseskin.value-1].name);
snprintf(bestdemo, 255, "%s-%s-rings-best.lmp", gpath, skins[cv_chooseskin.value-1]->name);
if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<2)))
{ // Better rings, save this demo.
if (FIL_FileExists(bestdemo))
@ -726,14 +726,14 @@ static void G_SetNightsRecords(gamedata_t *data, player_t *player)
I_Error("Out of memory for replay filepath\n");
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap));
snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, skins[cv_chooseskin.value-1].name);
snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, skins[cv_chooseskin.value-1]->name);
if (FIL_FileExists(lastdemo))
{
UINT8 *buf;
size_t len = FIL_ReadFile(lastdemo, &buf);
snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, skins[cv_chooseskin.value-1].name);;
snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, skins[cv_chooseskin.value-1]->name);
if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & 1)
{ // Better time, save this demo.
if (FIL_FileExists(bestdemo))
@ -742,7 +742,7 @@ static void G_SetNightsRecords(gamedata_t *data, player_t *player)
CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW RECORD TIME!"), M_GetText("Saved replay as"), bestdemo);
}
snprintf(bestdemo, 255, "%s-%s-score-best.lmp", gpath, skins[cv_chooseskin.value-1].name);
snprintf(bestdemo, 255, "%s-%s-score-best.lmp", gpath, skins[cv_chooseskin.value-1]->name);
if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<1)))
{ // Better score, save this demo.
if (FIL_FileExists(bestdemo))
@ -2598,7 +2598,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
UINT8 laps;
UINT8 mare;
UINT16 skincolor;
INT32 skin;
UINT8 skin;
UINT32 availabilities;
tic_t jointime;
tic_t quittime;
@ -5008,7 +5008,7 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 character, bo
if (savedata.lives > 0)
{
if ((botingame = ((botskin = savedata.botskin) != 0)))
botcolor = skins[botskin-1].prefcolor;
botcolor = skins[botskin-1]->prefcolor;
}
else if (splitscreen != SSSG)
{
@ -5138,7 +5138,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
players[consoleplayer].lives = savedata.lives;
players[consoleplayer].score = savedata.score;
if ((botingame = ((botskin = savedata.botskin) != 0)))
botcolor = skins[botskin-1].prefcolor;
botcolor = skins[botskin-1]->prefcolor;
emeralds = savedata.emeralds;
savedata.lives = 0;
}

View file

@ -4996,7 +4996,7 @@ static void HWR_DrawSprites(void)
if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
{
if (!cv_glmodels.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f)
if (!cv_glmodels.value || !md2_playermodels[((skin_t*)spr->mobj->skin)->skinnum].found || md2_playermodels[((skin_t*)spr->mobj->skin)->skinnum].scale < 0.0f)
HWR_DrawSprite(spr);
else
{
@ -5006,7 +5006,7 @@ static void HWR_DrawSprites(void)
}
else
{
if (!cv_glmodels.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f)
if (!cv_glmodels.value || !md2_models[spr->mobj->sprite].found || md2_models[spr->mobj->sprite].scale < 0.0f)
HWR_DrawSprite(spr);
else
{
@ -5183,11 +5183,11 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (cv_glmodels.value) //Yellow: Only MD2's dont disappear
{
if (thing->skin && thing->sprite == SPR_PLAY)
md2 = &md2_playermodels[( (skin_t *)thing->skin - skins )];
md2 = &md2_playermodels[((skin_t *)thing->skin)->skinnum];
else
md2 = &md2_models[thing->sprite];
if (md2->notfound || md2->scale < 0.0f)
if (!md2->found || md2->scale < 0.0f)
return;
}
else
@ -5576,8 +5576,8 @@ static void HWR_ProjectSprite(mobj_t *thing)
}
else if (thing->skin && thing->sprite == SPR_PLAY) // This thing is a player!
{
size_t skinnum = (skin_t*)thing->skin-skins;
vis->colormap = R_GetTranslationColormap((INT32)skinnum, vis->color, GTC_CACHE);
UINT8 skinnum = ((skin_t*)thing->skin)->skinnum;
vis->colormap = R_GetTranslationColormap(skinnum, vis->color, GTC_CACHE);
}
else
vis->colormap = R_GetTranslationColormap(TC_DEFAULT, vis->color ? vis->color : SKINCOLOR_CYAN, GTC_CACHE);

View file

@ -35,6 +35,7 @@
#include "../m_misc.h"
#include "../w_wad.h"
#include "../z_zone.h"
#include "../r_state.h"
#include "../r_things.h"
#include "../r_draw.h"
#include "../p_tick.h"
@ -72,7 +73,8 @@
#endif
md2_t md2_models[NUMSPRITES];
md2_t md2_playermodels[MAXSKINS];
md2_t *md2_playermodels = NULL;
size_t md2_numplayermodels = 0;
/*
@ -484,24 +486,7 @@ static boolean nomd2s = false;
void HWR_InitModels(void)
{
size_t i;
INT32 s;
FILE *f;
char name[26], filename[32];
float scale, offset;
size_t prefixlen;
CONS_Printf("HWR_InitModels()...\n");
for (s = 0; s < MAXSKINS; s++)
{
md2_playermodels[s].scale = -1.0f;
md2_playermodels[s].model = NULL;
md2_playermodels[s].grpatch = NULL;
md2_playermodels[s].notexturefile = false;
md2_playermodels[s].noblendfile = false;
md2_playermodels[s].skin = -1;
md2_playermodels[s].notfound = true;
md2_playermodels[s].error = false;
}
for (i = 0; i < NUMSPRITES; i++)
{
md2_models[i].scale = -1.0f;
@ -509,11 +494,48 @@ void HWR_InitModels(void)
md2_models[i].grpatch = NULL;
md2_models[i].notexturefile = false;
md2_models[i].noblendfile = false;
md2_models[i].skin = -1;
md2_models[i].notfound = true;
md2_models[i].found = false;
md2_models[i].error = false;
}
if (numsprites && numskins)
HWR_LoadModels();
}
void HWR_LoadModels(void)
{
size_t i;
INT32 s;
FILE *f;
char name[26], filename[32];
// name[24] is used to check for names in the models.dat file that match with sprites or player skins
// sprite names are always 4 characters long, and names is for player skins can be up to 19 characters long
// PLAYERMODELPREFIX is 6 characters long
float scale, offset;
size_t prefixlen;
if (nomd2s)
return;
// realloc player models table
if (numskins != (INT32)md2_numplayermodels)
{
md2_numplayermodels = (size_t)numskins;
md2_playermodels = Z_Realloc(md2_playermodels, sizeof(md2_t) * md2_numplayermodels, PU_STATIC, NULL);
for (s = 0; s < numskins; s++)
{
md2_playermodels[s].scale = -1.0f;
md2_playermodels[s].model = NULL;
md2_playermodels[s].grpatch = NULL;
md2_playermodels[s].notexturefile = false;
md2_playermodels[s].noblendfile = false;
md2_playermodels[s].found = false;
md2_playermodels[s].error = false;
}
}
// read the models.dat file
//Filename checking fixed ~Monster Iestyn and Golden
f = fopen(va("%s"PATHSEP"%s", srb2home, "models.dat"), "rt");
@ -537,23 +559,24 @@ void HWR_InitModels(void)
char *skinname = name;
size_t len = strlen(name);
// check for the player model prefix.
// Check for the player model prefix.
if (!strnicmp(name, PLAYERMODELPREFIX, prefixlen) && (len > prefixlen))
{
skinname += prefixlen;
goto addskinmodel;
}
// add sprite model
if (len == 4) // must be 4 characters long exactly. otherwise it's not a sprite name.
// Add sprite models.
// Must be 4 characters long exactly. Otherwise, it's not a sprite name.
if (len == 4)
{
for (i = 0; i < NUMSPRITES; i++)
for (i = 0; i < numsprites; i++)
{
if (stricmp(name, sprnames[i]) == 0)
{
md2_models[i].scale = scale;
md2_models[i].offset = offset;
md2_models[i].notfound = false;
md2_models[i].found = true;
strcpy(md2_models[i].filename, filename);
goto modelfound;
}
@ -561,137 +584,24 @@ void HWR_InitModels(void)
}
addskinmodel:
// add player model
for (s = 0; s < MAXSKINS; s++)
// Add player models.
for (s = 0; s < numskins; s++)
{
if (stricmp(skinname, skins[s].name) == 0)
if (stricmp(skinname, skins[s]->name) == 0)
{
md2_playermodels[s].skin = s;
md2_playermodels[s].scale = scale;
md2_playermodels[s].offset = offset;
md2_playermodels[s].notfound = false;
md2_playermodels[s].found = true;
strcpy(md2_playermodels[s].filename, filename);
goto modelfound;
}
}
modelfound:
// move on to next line...
// Move on to the next line...
continue;
}
fclose(f);
}
void HWR_AddPlayerModel(int skin) // For skins that were added after startup
{
FILE *f;
char name[26], filename[32];
float scale, offset;
size_t prefixlen;
if (nomd2s)
return;
//CONS_Printf("HWR_AddPlayerModel()...\n");
// read the models.dat file
//Filename checking fixed ~Monster Iestyn and Golden
f = fopen(va("%s"PATHSEP"%s", srb2home, "models.dat"), "rt");
if (!f)
{
f = fopen(va("%s"PATHSEP"%s", srb2path, "models.dat"), "rt");
if (!f)
{
CONS_Printf("%s %s\n", M_GetText("Error while loading models.dat:"), strerror(errno));
nomd2s = true;
return;
}
}
// length of the player model prefix
prefixlen = strlen(PLAYERMODELPREFIX);
// Check for any models that match the names of player skins!
while (fscanf(f, "%25s %31s %f %f", name, filename, &scale, &offset) == 4)
{
char *skinname = name;
size_t len = strlen(name);
// ignore the player model prefix.
if (!strnicmp(name, PLAYERMODELPREFIX, prefixlen) && (len > prefixlen))
skinname += prefixlen;
if (stricmp(skinname, skins[skin].name) == 0)
{
md2_playermodels[skin].skin = skin;
md2_playermodels[skin].scale = scale;
md2_playermodels[skin].offset = offset;
md2_playermodels[skin].notfound = false;
strcpy(md2_playermodels[skin].filename, filename);
goto playermodelfound;
}
}
md2_playermodels[skin].notfound = true;
playermodelfound:
fclose(f);
}
void HWR_AddSpriteModel(size_t spritenum) // For sprites that were added after startup
{
FILE *f;
// name[24] is used to check for names in the models.dat file that match with sprites or player skins
// sprite names are always 4 characters long, and names is for player skins can be up to 19 characters long
// PLAYERMODELPREFIX is 6 characters long
char name[26], filename[32];
float scale, offset;
if (nomd2s)
return;
if (spritenum == SPR_PLAY) // Handled already NEWMD2: Per sprite, per-skin check
return;
// Read the models.dat file
//Filename checking fixed ~Monster Iestyn and Golden
f = fopen(va("%s"PATHSEP"%s", srb2home, "models.dat"), "rt");
if (!f)
{
f = fopen(va("%s"PATHSEP"%s", srb2path, "models.dat"), "rt");
if (!f)
{
CONS_Printf("%s %s\n", M_GetText("Error while loading models.dat:"), strerror(errno));
nomd2s = true;
return;
}
}
// Check for any models that match the names of sprite names!
while (fscanf(f, "%25s %31s %f %f", name, filename, &scale, &offset) == 4)
{
// length of the sprite name
size_t len = strlen(name);
if (len != 4) // must be 4 characters long exactly. otherwise it's not a sprite name.
continue;
// check for the player model prefix.
if (!strnicmp(name, PLAYERMODELPREFIX, strlen(PLAYERMODELPREFIX)))
continue; // that's not a sprite...
if (stricmp(name, sprnames[spritenum]) == 0)
{
md2_models[spritenum].scale = scale;
md2_models[spritenum].offset = offset;
md2_models[spritenum].notfound = false;
strcpy(md2_models[spritenum].filename, filename);
goto spritemodelfound;
}
}
md2_models[spritenum].notfound = true;
spritemodelfound:
fclose(f);
}
@ -1380,8 +1290,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
// 2. draw model with correct position, rotation,...
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) // Use the player MD2 list if the mobj has a skin and is using the player sprites
{
md2 = &md2_playermodels[(skin_t*)spr->mobj->skin-skins];
md2->skin = (skin_t*)spr->mobj->skin-skins;
UINT8 skinnum = ((skin_t*)spr->mobj->skin)->skinnum;
md2 = &md2_playermodels[skinnum];
}
else
{
@ -1476,7 +1386,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
skinnum = TC_RAINBOW;
}
else if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
skinnum = (INT32)((skin_t*)spr->mobj->skin-skins);
skinnum = ((skin_t*)spr->mobj->skin)->skinnum;
else
skinnum = TC_DEFAULT;
}

View file

@ -31,17 +31,17 @@ typedef struct
boolean notexturefile; // true if texture file was not found
void *blendgrpatch;
boolean noblendfile; // true if blend texture file was not found
boolean notfound;
INT32 skin;
boolean found;
boolean error;
} md2_t;
extern md2_t md2_models[NUMSPRITES];
extern md2_t md2_playermodels[MAXSKINS];
extern md2_t *md2_playermodels;
extern size_t md2_numplayermodels;
void HWR_InitModels(void);
void HWR_AddPlayerModel(INT32 skin);
void HWR_AddSpriteModel(size_t spritenum);
void HWR_LoadModels(void);
boolean HWR_DrawModel(gl_vissprite_t *spr);
#define PLAYERMODELPREFIX "PLAYER"

View file

@ -328,8 +328,8 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat)
texcoords = (md2texcoord_t*)&buffer[header->offsetST];
frames = (md2frame_t*)&buffer[header->offsetFrames];
retModel->framenames = (char*)Z_Calloc(header->numFrames*16, ztag, 0);
fname = retModel->framenames;
retModel->frameNames = (char*)Z_Calloc(header->numFrames*16, ztag, 0);
fname = retModel->frameNames;
for (i = 0; i < header->numFrames; i++)
{
md2frame_t *fr = (md2frame_t*)&buffer[header->offsetFrames + foffset];

View file

@ -230,8 +230,8 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat)
retModel->meshes = (mesh_t*)Z_Calloc(sizeof(mesh_t)*retModel->numMeshes, ztag, 0);
frames = (md3Frame*)&buffer[mdh->offsetFrames];
retModel->framenames = (char*)Z_Calloc(mdh->numFrames*16, ztag, 0);
fname = retModel->framenames;
retModel->frameNames = (char*)Z_Calloc(mdh->numFrames*16, ztag, 0);
fname = retModel->frameNames;
for (i = 0; i < mdh->numFrames; i++)
{
memcpy(fname, frames->name, 16);

View file

@ -10,6 +10,8 @@
#include "../doomdef.h"
#include "../doomtype.h"
#include "../info.h"
#include "../r_skins.h"
#include "../r_state.h"
#include "../z_zone.h"
#include "hw_model.h"
#include "hw_md2load.h"
@ -141,9 +143,7 @@ tag_t *GetTagByName(model_t *model, char *name, int frame)
//
// LoadModel
//
// Load a model and
// convert it to the
// internal format.
// Load a model and convert it to the internal format.
//
model_t *LoadModel(const char *filename, int ztag)
{
@ -193,9 +193,6 @@ model_t *LoadModel(const char *filename, int ztag)
return NULL;
}
model->mdlFilename = (char*)Z_Malloc(strlen(filename)+1, ztag, 0);
strcpy(model->mdlFilename, filename);
Optimize(model);
GeneratePolygonNormals(model, ztag);
LoadModelSprite2(model);
@ -236,15 +233,16 @@ model_t *LoadModel(const char *filename, int ztag)
void HWR_ReloadModels(void)
{
size_t i;
INT32 s;
for (s = 0; s < MAXSKINS; s++)
HWR_LoadModels();
for (i = 0; i < md2_numplayermodels; i++)
{
if (md2_playermodels[s].model)
LoadModelSprite2(md2_playermodels[s].model);
if (md2_playermodels[i].model)
LoadModelSprite2(md2_playermodels[i].model);
}
for (i = 0; i < NUMSPRITES; i++)
for (i = 0; i < numsprites; i++)
{
if (md2_models[i].model)
LoadModelInterpolationSettings(md2_models[i].model);
@ -255,7 +253,7 @@ void LoadModelInterpolationSettings(model_t *model)
{
INT32 i;
INT32 numframes = model->meshes[0].numFrames;
char *framename = model->framenames;
char *framename = model->frameNames;
if (!framename)
return;
@ -295,7 +293,7 @@ void LoadModelSprite2(model_t *model)
INT32 i;
modelspr2frames_t *spr2frames = NULL;
INT32 numframes = model->meshes[0].numFrames;
char *framename = model->framenames;
char *framename = model->frameNames;
if (!framename)
return;

View file

@ -91,17 +91,14 @@ typedef struct model_s
{
int maxNumFrames;
int numMaterials;
material_t *materials;
int numMeshes;
mesh_t *meshes;
int numMaterials;
material_t *materials;
int numTags;
tag_t *tags;
char *mdlFilename;
boolean unloaded;
char *framenames;
char *frameNames;
boolean interpolate[256];
modelspr2frames_t *spr2frames;

View file

@ -2116,7 +2116,7 @@ void HU_Erase(void)
// IN-LEVEL MULTIPLAYER RANKINGS
//======================================================================
#define supercheckdef (!(players[tab[i].num].charflags & SF_NOSUPERSPRITES) && ((players[tab[i].num].powers[pw_super] && players[tab[i].num].mo && (players[tab[i].num].mo->state < &states[S_PLAY_SUPER_TRANS1] || players[tab[i].num].mo->state >= &states[S_PLAY_SUPER_TRANS6])) || (players[tab[i].num].powers[pw_carry] == CR_NIGHTSMODE && skins[players[tab[i].num].skin].flags & SF_SUPER)))
#define supercheckdef (!(players[tab[i].num].charflags & SF_NOSUPERSPRITES) && ((players[tab[i].num].powers[pw_super] && players[tab[i].num].mo && (players[tab[i].num].mo->state < &states[S_PLAY_SUPER_TRANS1] || players[tab[i].num].mo->state >= &states[S_PLAY_SUPER_TRANS6])) || (players[tab[i].num].powers[pw_carry] == CR_NIGHTSMODE && skins[players[tab[i].num].skin]->flags & SF_SUPER)))
#define greycheckdef (players[tab[i].num].spectator || players[tab[i].num].playerstate == PST_DEAD || (G_IsSpecialStage(gamemap) && players[tab[i].num].exiting))
//

View file

@ -3764,10 +3764,10 @@ static int lib_gAddPlayer(lua_State *L)
if (!lua_isnoneornil(L, 2))
newplayer->skincolor = R_GetColorByName(luaL_checkstring(L, 2));
else
newplayer->skincolor = skins[skinnum].prefcolor;
newplayer->skincolor = skins[skinnum]->prefcolor;
// Set the bot default name as the skin
strcpy(player_names[newplayernum], skins[skinnum].realname);
strcpy(player_names[newplayernum], skins[skinnum]->realname);
// Read the bot name, if given
if (!lua_isnoneornil(L, 3))

View file

@ -557,7 +557,7 @@ static int libd_getSprite2Patch(lua_State *L)
{
const char *name = luaL_checkstring(L, 1);
for (i = 0; i < numskins; i++)
if (fastcmp(skins[i].name, name))
if (fastcmp(skins[i]->name, name))
break;
if (i >= numskins)
return 0;
@ -599,9 +599,9 @@ static int libd_getSprite2Patch(lua_State *L)
if (super)
j |= FF_SPR2SUPER;
j = P_GetSkinSprite2(&skins[i], j, NULL); // feed skin and current sprite2 through to change sprite2 used if necessary
j = P_GetSkinSprite2(skins[i], j, NULL); // feed skin and current sprite2 through to change sprite2 used if necessary
sprdef = &skins[i].sprites[j];
sprdef = &skins[i]->sprites[j];
// set frame number
frame = luaL_optinteger(L, 2, 0);
@ -629,7 +629,7 @@ static int libd_getSprite2Patch(lua_State *L)
INT32 rot = R_GetRollAngle(rollangle);
if (rot) {
patch_t *rotsprite = Patch_GetRotatedSprite(sprframe, frame, angle, sprframe->flip & (1<<angle), &skins[i].sprinfo[j], rot);
patch_t *rotsprite = Patch_GetRotatedSprite(sprframe, frame, angle, sprframe->flip & (1<<angle), &skins[i]->sprinfo[j], rot);
LUA_PushUserdata(L, rotsprite, META_PATCH);
lua_pushboolean(L, false);
lua_pushboolean(L, true);

View file

@ -30,9 +30,6 @@
#include "lua_hud.h" // hud_running errors
#include "lua_hook.h" // hook_cmd_running errors
extern CV_PossibleValue_t Color_cons_t[];
extern UINT8 skincolor_modified[];
boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor);
state_t *astate;

View file

@ -679,10 +679,10 @@ static int mobj_set(lua_State *L)
strlcpy(skin, luaL_checkstring(L, 3), sizeof skin);
strlwr(skin); // all skin names are lowercase
for (i = 0; i < numskins; i++)
if (fastcmp(skins[i].name, skin))
if (fastcmp(skins[i]->name, skin))
{
if (!mo->player || R_SkinUsable(mo->player-players, i))
mo->skin = &skins[i];
mo->skin = skins[i];
return 0;
}
return luaL_error(L, "mobj.skin '%s' not found!", skin);

View file

@ -1396,7 +1396,7 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
{
skin_t *skin = *((skin_t **)lua_touserdata(gL, myindex));
WRITEUINT8(save_p, ARCH_SKIN);
WRITEUINT8(save_p, skin - skins); // UINT8 because MAXSKINS is only 32
WRITEUINT8(save_p, skin->skinnum); // UINT8 because MAXSKINS must be <= 256
break;
}
default:

View file

@ -234,7 +234,7 @@ static int skin_num(lua_State *L)
// skins are always valid, only added, never removed
I_Assert(skin != NULL);
lua_pushinteger(L, skin-skins);
lua_pushinteger(L, skin->skinnum);
return 1;
}
@ -253,14 +253,14 @@ static int lib_iterateSkins(lua_State *L)
lua_remove(L, 1); // state is unused.
if (!lua_isnil(L, 1))
i = (INT32)(*((skin_t **)luaL_checkudata(L, 1, META_SKIN)) - skins) + 1;
i = (INT32)((*((skin_t **)luaL_checkudata(L, 1, META_SKIN)))->skinnum) + 1;
else
i = 0;
// skins are always valid, only added, never removed
if (i < numskins)
{
LUA_PushUserdata(L, &skins[i], META_SKIN);
LUA_PushUserdata(L, skins[i], META_SKIN);
return 1;
}
@ -280,7 +280,7 @@ static int lib_getSkin(lua_State *L)
return luaL_error(L, "skins[] index %d out of range (0 - %d)", i, MAXSKINS-1);
if (i >= numskins)
return 0;
LUA_PushUserdata(L, &skins[i], META_SKIN);
LUA_PushUserdata(L, skins[i], META_SKIN);
return 1;
}
@ -295,9 +295,9 @@ static int lib_getSkin(lua_State *L)
// find skin by name
for (i = 0; i < numskins; i++)
if (fastcmp(skins[i].name, field))
if (fastcmp(skins[i]->name, field))
{
LUA_PushUserdata(L, &skins[i], META_SKIN);
LUA_PushUserdata(L, skins[i], META_SKIN);
return 1;
}

View file

@ -132,7 +132,9 @@ M_waiting_mode_t m_waiting_mode = M_NOT_WAITING;
const char *quitmsg[NUM_QUITMESSAGES];
// Stuff for customizing the player select screen Tails 09-22-2003
description_t description[MAXSKINS];
description_t *description = NULL;
INT32 numdescriptions = 0;
INT16 char_on = -1, startchar = 0;
static char *char_notes = NULL;
@ -258,7 +260,7 @@ static void M_ConfirmTeamScramble(INT32 choice);
static void M_ConfirmTeamChange(INT32 choice);
static void M_SecretsMenu(INT32 choice);
static void M_SetupChoosePlayer(INT32 choice);
static UINT8 M_SetupChoosePlayerDirect(INT32 choice);
static UINT16 M_SetupChoosePlayerDirect(INT32 choice);
static void M_QuitSRB2(INT32 choice);
menu_t SP_MainDef, OP_MainDef;
menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef;
@ -2258,7 +2260,7 @@ void Nextmap_OnChange(void)
SP_NightsAttackMenu[naghost].status = IT_DISABLED;
// Check if file exists, if not, disable REPLAY option
sprintf(tabase,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s",srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name);
sprintf(tabase,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s",srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1]->name);
#ifdef OLDNREPLAYNAME
sprintf(tabaseold,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s",srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value));
@ -2329,7 +2331,7 @@ void Nextmap_OnChange(void)
SP_TimeAttackMenu[taghost].status = IT_DISABLED;
// Check if file exists, if not, disable REPLAY option
sprintf(tabase,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s",srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name);
sprintf(tabase,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s",srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1]->name);
for (i = 0; i < 5; i++) {
SP_ReplayMenu[i].status = IT_DISABLED;
SP_GuestReplayMenu[i].status = IT_DISABLED;
@ -3029,7 +3031,7 @@ static void M_ChangeCvar(INT32 choice)
{
SINT8 skinno = R_SkinAvailable(cv_chooseskin.string);
if (skinno != -1)
CV_SetValue(cv,skins[skinno].prefcolor);
CV_SetValue(cv,skins[skinno]->prefcolor);
return;
}
CV_Set(cv,cv->defaultvalue);
@ -3936,24 +3938,32 @@ void M_Init(void)
CV_RegisterVar(&cv_serversort);
}
void M_InitCharacterTables(void)
static void M_InitCharacterDescription(INT32 i)
{
UINT8 i;
// Setup description table
for (i = 0; i < MAXSKINS; i++)
{
description[i].used = false;
strcpy(description[i].notes, "???");
strcpy(description[i].picname, "");
strcpy(description[i].nametag, "");
strcpy(description[i].skinname, "");
strcpy(description[i].displayname, "");
description[i].prev = description[i].next = 0;
description[i].charpic = NULL;
description[i].namepic = NULL;
description[i].oppositecolor = description[i].tagtextcolor = description[i].tagoutlinecolor = 0;
}
description_t *desc = &description[i];
desc->picname[0] = '\0';
desc->nametag[0] = '\0';
desc->skinname[0] = '\0';
desc->displayname[0] = '\0';
desc->prev = desc->next = 0;
desc->charpic = NULL;
desc->namepic = NULL;
desc->oppositecolor = SKINCOLOR_NONE;
desc->tagtextcolor = SKINCOLOR_NONE;
desc->tagoutlinecolor = SKINCOLOR_NONE;
strcpy(desc->notes, "???");
}
void M_InitCharacterTables(INT32 num)
{
INT32 i = numdescriptions;
description = Z_Realloc(description, sizeof(description_t) * num, PU_STATIC, NULL);
numdescriptions = num;
for (; i < numdescriptions; i++)
M_InitCharacterDescription(i);
}
// ==========================================================================
@ -5014,9 +5024,9 @@ static void M_PatchSkinNameTable(void)
for (j = 0; j < MAXSKINS; j++)
{
if (skins[j].name[0] != '\0' && R_SkinUsable(-1, j))
if (j < numskins && skins[j]->name[0] != '\0' && R_SkinUsable(-1, j))
{
skins_cons_t[j].strvalue = skins[j].realname;
skins_cons_t[j].strvalue = skins[j]->realname;
skins_cons_t[j].value = j+1;
}
else
@ -8492,7 +8502,7 @@ static void M_DrawLoadGameData(void)
savetodraw--;
if (savegameinfo[savetodraw].lives != 0)
charskin = &skins[savegameinfo[savetodraw].skinnum];
charskin = skins[savegameinfo[savetodraw].skinnum];
// signpost background
{
@ -8626,7 +8636,7 @@ static void M_DrawLoadGameData(void)
// botskin first
if (savegameinfo[savetodraw].botskin)
{
skin_t *charbotskin = &skins[savegameinfo[savetodraw].botskin-1];
skin_t *charbotskin = skins[savegameinfo[savetodraw].botskin-1];
sprdef = &charbotskin->sprites[SPR2_SIGN];
if (!sprdef->numframes)
goto skipbot;
@ -9205,9 +9215,9 @@ static void M_CacheCharacterSelectEntry(INT32 i, INT32 skinnum)
{
if (!(description[i].picname[0]))
{
if (skins[skinnum].sprites[SPR2_XTRA].numframes > XTRA_CHARSEL)
if (skins[skinnum]->sprites[SPR2_XTRA].numframes > XTRA_CHARSEL)
{
spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
spritedef_t *sprdef = &skins[skinnum]->sprites[SPR2_XTRA];
spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CHARSEL];
description[i].charpic = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH);
}
@ -9221,71 +9231,74 @@ static void M_CacheCharacterSelectEntry(INT32 i, INT32 skinnum)
description[i].namepic = W_CachePatchName(description[i].nametag, PU_PATCH);
}
static UINT8 M_SetupChoosePlayerDirect(INT32 choice)
static UINT16 M_SetupChoosePlayerDirect(INT32 choice)
{
INT32 skinnum, botskinnum;
UINT8 i;
UINT8 firstvalid = 255, lastvalid = 255;
UINT16 i;
INT32 firstvalid = INT32_MAX, lastvalid = INT32_MAX;
boolean allowed = false;
char *and;
(void)choice;
if (!mapheaderinfo[startmap-1] || mapheaderinfo[startmap-1]->forcecharacter[0] == '\0')
{
for (i = 0; i < MAXSKINS; i++) // Handle charsels, availability, and unlocks.
for (i = 0; i < numdescriptions; i++) // Handle charsels, availability, and unlocks.
{
if (description[i].used) // If the character's disabled through SOC, there's nothing we can do for it.
char *and;
// If the character's disabled through SOC, there's nothing we can do for it.
if (!description[i].used)
continue;
and = strchr(description[i].skinname, '&');
if (and)
{
and = strchr(description[i].skinname, '&');
if (and)
char firstskin[SKINNAMESIZE+1];
if (mapheaderinfo[startmap-1] && mapheaderinfo[startmap-1]->typeoflevel & TOL_NIGHTS) // skip tagteam characters for NiGHTS levels
continue;
strncpy(firstskin, description[i].skinname, (and - description[i].skinname));
firstskin[(and - description[i].skinname)] = '\0';
description[i].skinnum[0] = R_SkinAvailable(firstskin);
description[i].skinnum[1] = R_SkinAvailable(and+1);
}
else
{
description[i].skinnum[0] = R_SkinAvailable(description[i].skinname);
description[i].skinnum[1] = -1;
}
skinnum = description[i].skinnum[0];
if ((skinnum != -1) && (R_SkinUsable(-1, skinnum)))
{
botskinnum = description[i].skinnum[1];
if ((botskinnum != -1) && (!R_SkinUsable(-1, botskinnum)))
{
char firstskin[SKINNAMESIZE+1];
if (mapheaderinfo[startmap-1] && mapheaderinfo[startmap-1]->typeoflevel & TOL_NIGHTS) // skip tagteam characters for NiGHTS levels
continue;
strncpy(firstskin, description[i].skinname, (and - description[i].skinname));
firstskin[(and - description[i].skinname)] = '\0';
description[i].skinnum[0] = R_SkinAvailable(firstskin);
description[i].skinnum[1] = R_SkinAvailable(and+1);
// Bot skin isn't unlocked
continue;
}
// Handling order.
if (firstvalid == INT32_MAX)
firstvalid = i;
else
{
description[i].skinnum[0] = R_SkinAvailable(description[i].skinname);
description[i].skinnum[1] = -1;
description[i].prev = lastvalid;
description[lastvalid].next = i;
}
skinnum = description[i].skinnum[0];
if ((skinnum != -1) && (R_SkinUsable(-1, skinnum)))
{
botskinnum = description[i].skinnum[1];
if ((botskinnum != -1) && (!R_SkinUsable(-1, botskinnum)))
{
// Bot skin isn't unlocked
continue;
}
lastvalid = i;
// Handling order.
if (firstvalid == 255)
firstvalid = i;
else
{
description[i].prev = lastvalid;
description[lastvalid].next = i;
}
lastvalid = i;
if (i == char_on)
allowed = true;
if (i == char_on)
allowed = true;
M_CacheCharacterSelectEntry(i, skinnum);
}
// else -- Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them.
M_CacheCharacterSelectEntry(i, skinnum);
}
// else -- Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them.
}
}
if (firstvalid == lastvalid) // We're being forced into a specific character, so might as well just skip it.
{
return firstvalid;
}
// One last bit of order we can't do in the iteration above.
description[firstvalid].prev = lastvalid;
@ -9294,7 +9307,7 @@ static UINT8 M_SetupChoosePlayerDirect(INT32 choice)
if (!allowed)
{
char_on = firstvalid;
if (startchar > 0 && startchar < MAXSKINS)
if (startchar > 0 && startchar < numdescriptions)
{
INT16 workchar = startchar;
while (workchar--)
@ -9302,13 +9315,13 @@ static UINT8 M_SetupChoosePlayerDirect(INT32 choice)
}
}
return MAXSKINS;
return MAXCHARACTERSLOTS;
}
static void M_SetupChoosePlayer(INT32 choice)
{
UINT8 skinset = M_SetupChoosePlayerDirect(choice);
if (skinset != MAXSKINS)
UINT16 skinset = M_SetupChoosePlayerDirect(choice);
if (skinset != MAXCHARACTERSLOTS)
{
M_ChoosePlayer(skinset);
return;
@ -9419,7 +9432,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
{
const INT32 my = 16;
skin_t *charskin = &skins[0];
skin_t *charskin = skins[0];
INT32 skinnum = 0;
UINT16 col;
UINT8 *colormap = NULL;
@ -9451,7 +9464,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
// Find skin number from description[]
skinnum = description[char_on].skinnum[0];
charskin = &skins[skinnum];
charskin = skins[skinnum];
// Use the opposite of the character's skincolor
col = description[char_on].oppositecolor;
@ -9554,7 +9567,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
prevoutlinecolor = description[prev].tagoutlinecolor;
if (prevtext[0] == '\0')
prevpatch = description[prev].namepic;
charskin = &skins[description[prev].skinnum[0]];
charskin = skins[description[prev].skinnum[0]];
if (!prevtextcolor)
prevtextcolor = charskin->prefcolor;
if (!prevoutlinecolor)
@ -9584,7 +9597,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
nextoutlinecolor = description[next].tagoutlinecolor;
if (nexttext[0] == '\0')
nextpatch = description[next].namepic;
charskin = &skins[description[next].skinnum[0]];
charskin = skins[description[next].skinnum[0]];
if (!nexttextcolor)
nexttextcolor = charskin->prefcolor;
if (!nextoutlinecolor)
@ -9629,7 +9642,7 @@ static void M_ChoosePlayer(INT32 choice)
UINT8 skinnum;
// skip this if forcecharacter or no characters available
if (choice == 255)
if (choice == INT32_MAX)
{
skinnum = botskin = 0;
botingame = false;
@ -9642,7 +9655,7 @@ static void M_ChoosePlayer(INT32 choice)
if ((botingame = (description[choice].skinnum[1] != -1))) {
// this character has a second skin
botskin = (UINT8)(description[choice].skinnum[1]+1);
botcolor = skins[description[choice].skinnum[1]].prefcolor;
botcolor = skins[description[choice].skinnum[1]]->prefcolor;
}
else
botskin = botcolor = 0;
@ -9930,7 +9943,7 @@ void M_DrawTimeAttackMenu(void)
gamedata_t *data = clientGamedata;
INT32 i, x, y, empatx, empaty, cursory = 0;
UINT16 dispstatus;
patch_t *PictureOfUrFace; // my WHAT
patch_t *PictureOfUrFace;
patch_t *empatch;
M_SetMenuCurBackground("RECATKBG");
@ -9999,9 +10012,9 @@ void M_DrawTimeAttackMenu(void)
// Character face!
{
if (skins[cv_chooseskin.value-1].sprites[SPR2_XTRA].numframes > XTRA_CHARSEL)
if (skins[cv_chooseskin.value-1]->sprites[SPR2_XTRA].numframes > XTRA_CHARSEL)
{
spritedef_t *sprdef = &skins[cv_chooseskin.value-1].sprites[SPR2_XTRA];
spritedef_t *sprdef = &skins[cv_chooseskin.value-1]->sprites[SPR2_XTRA];
spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CHARSEL];
PictureOfUrFace = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH);
}
@ -10447,7 +10460,7 @@ static void M_ChooseNightsAttack(INT32 choice)
I_Error("Out of memory for replay filepath\n");
sprintf(gpath,"replay"PATHSEP"%s"PATHSEP"%s", timeattackfolder, G_BuildMapName(cv_nextmap.value));
snprintf(nameofdemo, sizeof nameofdemo, "%s-%s-last", gpath, skins[cv_chooseskin.value-1].name);
snprintf(nameofdemo, sizeof nameofdemo, "%s-%s-last", gpath, skins[cv_chooseskin.value-1]->name);
if (!cv_autorecord.value)
remove(va("%s"PATHSEP"%s.lmp", srb2home, nameofdemo));
@ -10476,7 +10489,7 @@ static void M_ChooseTimeAttack(INT32 choice)
I_Error("Out of memory for replay filepath\n");
sprintf(gpath,"replay"PATHSEP"%s"PATHSEP"%s", timeattackfolder, G_BuildMapName(cv_nextmap.value));
snprintf(nameofdemo, sizeof nameofdemo, "%s-%s-last", gpath, skins[cv_chooseskin.value-1].name);
snprintf(nameofdemo, sizeof nameofdemo, "%s-%s-last", gpath, skins[cv_chooseskin.value-1]->name);
if (!cv_autorecord.value)
remove(va("%s"PATHSEP"%s.lmp", srb2home, nameofdemo));
@ -10529,7 +10542,7 @@ static void M_ReplayTimeAttack(INT32 choice)
if (choice != 4)
{
// srb2/replay/main/map01-sonic-time-best.lmp
snprintf(ra_demoname, 1024, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which);
snprintf(ra_demoname, 1024, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1]->name, which);
}
}
else if (currentMenu == &SP_NightsReplayDef)
@ -10552,7 +10565,7 @@ static void M_ReplayTimeAttack(INT32 choice)
if (choice != 3)
{
snprintf(ra_demoname, 1024, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which);
snprintf(ra_demoname, 1024, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1]->name, which);
#ifdef OLDNREPLAYNAME // Check for old style named NiGHTS replay if a new style replay doesn't exist.
if (!FIL_FileExists(ra_demoname))
@ -10639,7 +10652,7 @@ static void M_OverwriteGuest(const char *which)
char *rguest = Z_StrDup(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)));
UINT8 *buf;
size_t len;
len = FIL_ReadFile(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which), &buf);
len = FIL_ReadFile(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1]->name, which), &buf);
if (!len) {
return;
@ -10781,7 +10794,7 @@ static void M_MarathonLiveEventBackup(INT32 choice)
// Going to Marathon menu...
static void M_Marathon(INT32 choice)
{
UINT8 skinset;
UINT16 skinset;
INT32 mapnum = 0;
if (choice != -1 && FIL_FileExists(liveeventbackup))
@ -10805,7 +10818,7 @@ static void M_Marathon(INT32 choice)
skinset = M_SetupChoosePlayerDirect(-1);
SP_MarathonMenu[marathonplayer].status = (skinset == MAXSKINS) ? IT_KEYHANDLER|IT_STRING : IT_NOTHING|IT_DISABLED;
SP_MarathonMenu[marathonplayer].status = (skinset == MAXCHARACTERSLOTS) ? IT_KEYHANDLER|IT_STRING : IT_NOTHING|IT_DISABLED;
while (mapnum < NUMMAPS)
{
@ -12248,11 +12261,11 @@ static void M_DrawSetupMultiPlayerMenu(void)
// draw skin string
V_DrawRightAlignedString(BASEVIDWIDTH - x, y,
((MP_PlayerSetupMenu[1].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|(itemOn == 1 ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE,
skins[setupm_fakeskin].realname);
skins[setupm_fakeskin]->realname);
if (itemOn == 1 && (MP_PlayerSetupMenu[1].status & IT_TYPE) != IT_SPACE)
{
V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(skins[setupm_fakeskin].realname, V_ALLOWLOWERCASE) - (skullAnimCounter/5), y,
V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(skins[setupm_fakeskin]->realname, V_ALLOWLOWERCASE) - (skullAnimCounter/5), y,
'\x1C' | V_YELLOWMAP, false);
V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y,
'\x1D' | V_YELLOWMAP, false);
@ -12275,7 +12288,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
V_DrawFill(x-(charw/2), y, charw, 84,
multi_invcolor ?skincolors[skincolors[setupm_fakecolor->color].invcolor].ramp[skincolors[setupm_fakecolor->color].invshade] : 159);
sprdef = &skins[setupm_fakeskin].sprites[multi_spr2];
sprdef = &skins[setupm_fakeskin]->sprites[multi_spr2];
if (!setupm_fakecolor->color || !sprdef->numframes) // should never happen but hey, who knows
goto faildraw;
@ -12296,7 +12309,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
V_DrawFixedPatch(
x<<FRACBITS,
chary<<FRACBITS,
FixedDiv(skins[setupm_fakeskin].highresscale, skins[setupm_fakeskin].shieldscale),
FixedDiv(skins[setupm_fakeskin]->highresscale, skins[setupm_fakeskin]->shieldscale),
flags, patch, colormap);
goto colordraw;
@ -12528,7 +12541,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
setupm_fakeskin = numskins-1;
}
while ((prev_setupm_fakeskin != setupm_fakeskin) && !(R_SkinUsable(-1, setupm_fakeskin)));
multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL);
multi_spr2 = P_GetSkinSprite2(skins[setupm_fakeskin], SPR2_WALK, NULL);
}
else if (itemOn == 2) // player color
{
@ -12544,7 +12557,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
{
S_StartSound(NULL,sfx_strpst);
// you know what? always putting these in the buffer won't hurt anything.
COM_BufAddText (va("%s \"%s\"\n",setupm_cvdefaultskin->name,skins[setupm_fakeskin].name));
COM_BufAddText (va("%s \"%s\"\n",setupm_cvdefaultskin->name,skins[setupm_fakeskin]->name));
COM_BufAddText (va("%s %d\n",setupm_cvdefaultcolor->name,setupm_fakecolor->color));
break;
}
@ -12568,7 +12581,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
setupm_fakeskin = 0;
}
while ((prev_setupm_fakeskin != setupm_fakeskin) && !(R_SkinUsable(-1, setupm_fakeskin)));
multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL);
multi_spr2 = P_GetSkinSprite2(skins[setupm_fakeskin], SPR2_WALK, NULL);
}
else if (itemOn == 2) // player color
{
@ -12624,7 +12637,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
}
else if (itemOn == 2)
{
UINT16 col = skins[setupm_fakeskin].prefcolor;
UINT16 col = skins[setupm_fakeskin]->prefcolor;
if ((setupm_fakecolor->color != col) && skincolors[col].accessible)
{
S_StartSound(NULL,sfx_menu1); // Tails
@ -12718,7 +12731,7 @@ static void M_SetupMultiPlayer(INT32 choice)
MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER|IT_STRING);
multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL);
multi_spr2 = P_GetSkinSprite2(skins[setupm_fakeskin], SPR2_WALK, NULL);
MP_PlayerSetupDef.prevMenu = currentMenu;
M_SetupNextMenu(&MP_PlayerSetupDef);
@ -12759,7 +12772,7 @@ static void M_SetupMultiPlayer2(INT32 choice)
MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER|IT_STRING);
multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL);
multi_spr2 = P_GetSkinSprite2(skins[setupm_fakeskin], SPR2_WALK, NULL);
MP_PlayerSetupDef.prevMenu = currentMenu;
M_SetupNextMenu(&MP_PlayerSetupDef);
@ -12777,7 +12790,7 @@ static boolean M_QuitMultiPlayerMenu(void)
setupm_name[l] =0;
COM_BufAddText (va("%s \"%s\"\n",setupm_cvname->name,setupm_name));
}
COM_BufAddText (va("%s \"%s\"\n",setupm_cvskin->name,skins[setupm_fakeskin].name));
COM_BufAddText (va("%s \"%s\"\n",setupm_cvskin->name,skins[setupm_fakeskin]->name));
// send color if changed
if (setupm_fakecolor->color != setupm_cvcolor->value)
COM_BufAddText (va("%s %d\n",setupm_cvcolor->name,setupm_fakecolor->color));

View file

@ -200,8 +200,8 @@ void M_Drawer(void);
// Called by D_SRB2Main, loads the config file.
void M_Init(void);
// Called by D_SRB2Main also, sets up the playermenu and description tables.
void M_InitCharacterTables(void);
// Called by deh_soc.c, sets up the playermenu and description tables.
void M_InitCharacterTables(INT32 num);
// Called by intro code to force menu up upon a keypress,
// does nothing if menu is already up.
@ -375,10 +375,8 @@ typedef struct
patch_t *charpic;
UINT8 prev;
UINT8 next;
// new character select
char displayname[SKINNAMESIZE+1];
SINT8 skinnum[2];
INT16 skinnum[2];
UINT16 oppositecolor;
char nametag[8];
patch_t *namepic;
@ -431,7 +429,8 @@ typedef struct
INT32 gamemap;
} saveinfo_t;
extern description_t description[MAXSKINS];
extern description_t *description;
extern INT32 numdescriptions;
extern consvar_t cv_showfocuslost;
extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort;

View file

@ -1259,8 +1259,8 @@ static void SendNameAndColor(void)
CV_StealthSetValue(&cv_playercolor, players[consoleplayer].skincolor);
else if (skincolors[atoi(cv_playercolor.defaultvalue)].accessible)
CV_StealthSet(&cv_playercolor, cv_playercolor.defaultvalue);
else if (skins[players[consoleplayer].skin].prefcolor && skincolors[skins[players[consoleplayer].skin].prefcolor].accessible)
CV_StealthSetValue(&cv_playercolor, skins[players[consoleplayer].skin].prefcolor);
else if (skins[players[consoleplayer].skin]->prefcolor && skincolors[skins[players[consoleplayer].skin]->prefcolor].accessible)
CV_StealthSetValue(&cv_playercolor, skins[players[consoleplayer].skin]->prefcolor);
else {
UINT16 i = 0;
while (i<numskincolors && !skincolors[i].accessible) i++;
@ -1270,7 +1270,7 @@ static void SendNameAndColor(void)
if (!strcmp(cv_playername.string, player_names[consoleplayer])
&& cv_playercolor.value == players[consoleplayer].skincolor
&& !strcmp(cv_skin.string, skins[players[consoleplayer].skin].name))
&& !strcmp(cv_skin.string, skins[players[consoleplayer].skin]->name))
return;
players[consoleplayer].availabilities = R_GetSkinAvailabilities();
@ -1313,7 +1313,7 @@ static void SendNameAndColor(void)
if ((cv_skin.value < 0) || !R_SkinUsable(consoleplayer, cv_skin.value))
{
INT32 defaultSkinNum = GetPlayerDefaultSkin(consoleplayer);
CV_StealthSet(&cv_skin, skins[defaultSkinNum].name);
CV_StealthSet(&cv_skin, skins[defaultSkinNum]->name);
cv_skin.value = defaultSkinNum;
}
@ -1344,8 +1344,8 @@ static void SendNameAndColor2(void)
CV_StealthSetValue(&cv_playercolor2, players[secondplaya].skincolor);
else if (skincolors[atoi(cv_playercolor2.defaultvalue)].accessible)
CV_StealthSet(&cv_playercolor, cv_playercolor2.defaultvalue);
else if (skins[players[secondplaya].skin].prefcolor && skincolors[skins[players[secondplaya].skin].prefcolor].accessible)
CV_StealthSetValue(&cv_playercolor2, skins[players[secondplaya].skin].prefcolor);
else if (skins[players[secondplaya].skin]->prefcolor && skincolors[skins[players[secondplaya].skin]->prefcolor].accessible)
CV_StealthSetValue(&cv_playercolor2, skins[players[secondplaya].skin]->prefcolor);
else {
UINT16 i = 0;
while (i<numskincolors && !skincolors[i].accessible) i++;
@ -2079,7 +2079,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
if (modeattacking)
{
SetPlayerSkinByNum(0, cv_chooseskin.value-1);
players[0].skincolor = skins[players[0].skin].prefcolor;
players[0].skincolor = skins[players[0].skin]->prefcolor;
}
mapnumber = M_MapNumber(mapname[3], mapname[4]);
@ -4743,7 +4743,7 @@ static void ForceSkin_OnChange(void)
}
else
{
CONS_Printf("The server is restricting all players to skin \"%s\".\n",skins[cv_forceskin.value].name);
CONS_Printf("The server is restricting all players to skin \"%s\".\n",skins[cv_forceskin.value]->name);
if (Playing())
ForceAllSkins(cv_forceskin.value);
}
@ -4789,7 +4789,7 @@ static void Skin_OnChange(void)
if (!(cv_debug || devparm)
&& (gamestate != GS_WAITINGPLAYERS)) // allows command line -warp x +skin y
{
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin]->name);
return;
}

View file

@ -3677,7 +3677,7 @@ void A_1upThinker(mobj_t *actor)
}
}
if (closestplayer == -1 || skins[players[closestplayer].skin].sprites[SPR2_LIFE].numframes == 0)
if (closestplayer == -1 || skins[players[closestplayer].skin]->sprites[SPR2_LIFE].numframes == 0)
{ // Closest player not found (no players in game?? may be empty dedicated server!), or does not have correct sprite.
if (actor->tracer)
{
@ -3698,7 +3698,7 @@ void A_1upThinker(mobj_t *actor)
return;
P_SetTarget(&actor->tracer->target, actor);
actor->tracer->skin = &skins[players[closestplayer].skin]; // required here to prevent spr2 default showing stand for a single frame
actor->tracer->skin = skins[players[closestplayer].skin]; // required here to prevent spr2 default showing stand for a single frame
P_SetMobjState(actor->tracer, actor->info->seestate);
// The overlay is going to be one tic early turning off and on
@ -3708,7 +3708,7 @@ void A_1upThinker(mobj_t *actor)
}
actor->tracer->color = players[closestplayer].mo->color;
actor->tracer->skin = &skins[players[closestplayer].skin];
actor->tracer->skin = skins[players[closestplayer].skin];
}
// Function: A_MonitorPop
@ -3769,6 +3769,7 @@ void A_MonitorPop(mobj_t *actor)
{
P_SetTarget(&newmobj->target, actor->target); // Transfer target
if (item == MT_1UP_ICON)
{
if (!newmobj->target
@ -3857,7 +3858,6 @@ void A_GoldMonitorPop(mobj_t *actor)
if (!P_MobjWasRemoved(newmobj))
{
P_SetTarget(&newmobj->target, actor->target); // Transfer target
if (item == MT_1UP_ICON)
{
if (actor->tracer) // Remove the old lives icon.
@ -5349,7 +5349,7 @@ void A_SignPlayer(mobj_t *actor)
if (!actor->target->player)
return;
skin = &skins[actor->target->player->skin];
skin = skins[actor->target->player->skin];
facecolor = P_GetPlayerColor(actor->target->player);
if (signcolor)
@ -5380,10 +5380,10 @@ void A_SignPlayer(mobj_t *actor)
if (!SignSkinCheck(player, skincount))
skinnum++;
}
skin = &skins[skinnum];
skin = skins[skinnum];
}
else // specific skin
skin = &skins[locvar1];
skin = skins[locvar1];
facecolor = skin->prefcolor;
if (signcolor)

View file

@ -212,7 +212,7 @@ static boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
return P_SetPlayerMobjState(mobj, S_PLAY_FALL);
// Catch swimming versus flying
if ((state == S_PLAY_FLY || (state == S_PLAY_GLIDE && skins[player->skin].sprites[SPR2_SWIM].numframes))
if ((state == S_PLAY_FLY || (state == S_PLAY_GLIDE && skins[player->skin]->sprites[SPR2_SWIM].numframes))
&& player->mo->eflags & MFE_UNDERWATER && !player->skidtime)
return P_SetPlayerMobjState(player->mo, S_PLAY_SWIM);
else if (state == S_PLAY_SWIM && !(player->mo->eflags & MFE_UNDERWATER))
@ -11086,10 +11086,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...)
nummaprings++;
break;
case MT_METALSONIC_RACE:
mobj->skin = &skins[5];
mobj->skin = skins[5];
/* FALLTHRU */
case MT_METALSONIC_BATTLE:
mobj->color = skins[5].prefcolor;
mobj->color = skins[5]->prefcolor;
sc = 5;
break;
case MT_FANG:
@ -11794,7 +11794,7 @@ void P_SpawnPlayer(INT32 playernum)
// set 'spritedef' override in mobj for player skins.. (see ProjectSprite)
// (usefulness: when body mobj is detached from player (who respawns),
// the dead body mobj retains the skin through the 'spritedef' override).
mobj->skin = &skins[p->skin];
mobj->skin = skins[p->skin];
P_SetupStateAnimation(mobj, mobj->state);
mobj->health = 1;
@ -11802,14 +11802,14 @@ void P_SpawnPlayer(INT32 playernum)
p->bonustime = false;
p->realtime = leveltime;
p->followitem = skins[p->skin].followitem;
p->followitem = skins[p->skin]->followitem;
// Make sure player's stats are reset if they were in dashmode!
if (p->dashmode)
{
p->dashmode = 0;
p->normalspeed = skins[p->skin].normalspeed;
p->jumpfactor = skins[p->skin].jumpfactor;
p->normalspeed = skins[p->skin]->normalspeed;
p->jumpfactor = skins[p->skin]->jumpfactor;
}
// Clear lastlinehit and lastsidehit
@ -11825,7 +11825,7 @@ void P_SpawnPlayer(INT32 playernum)
P_FlashPal(p, 0, 0); // Resets
// Set bounds accurately.
mobj->radius = FixedMul(skins[p->skin].radius, mobj->scale);
mobj->radius = FixedMul(skins[p->skin]->radius, mobj->scale);
mobj->height = P_GetPlayerHeight(p);
if (!leveltime && !p->spectator && ((maptol & TOL_NIGHTS) == TOL_NIGHTS) != (G_IsSpecialStage(gamemap))) // non-special NiGHTS stage or special non-NiGHTS stage

View file

@ -78,11 +78,11 @@ static inline void P_ArchivePlayer(void)
// Write skin names, so that loading skins in different orders
// doesn't change who the save file is for!
WRITESTRINGN(save_p, skins[player->skin].name, SKINNAMESIZE);
WRITESTRINGN(save_p, skins[player->skin]->name, SKINNAMESIZE);
if (botskin != 0)
{
WRITESTRINGN(save_p, skins[botskin-1].name, SKINNAMESIZE);
WRITESTRINGN(save_p, skins[botskin-1]->name, SKINNAMESIZE);
}
else
{
@ -2058,7 +2058,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
if (diff2 & MD2_CVMEM)
WRITEINT32(save_p, mobj->cvmem);
if (diff2 & MD2_SKIN)
WRITEUINT8(save_p, (UINT8)((skin_t *)mobj->skin - skins));
WRITEUINT8(save_p, (UINT8)(((skin_t *)mobj->skin)->skinnum));
if (diff2 & MD2_COLOR)
WRITEUINT16(save_p, mobj->color);
if (diff2 & MD2_EXTVAL1)
@ -3112,7 +3112,7 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
if (diff2 & MD2_CVMEM)
mobj->cvmem = READINT32(save_p);
if (diff2 & MD2_SKIN)
mobj->skin = &skins[READUINT8(save_p)];
mobj->skin = skins[READUINT8(save_p)];
if (diff2 & MD2_COLOR)
mobj->color = READUINT16(save_p);
if (diff2 & MD2_EXTVAL1)

View file

@ -7267,7 +7267,7 @@ static void P_ForceCharacter(const char *forcecharskin)
SetPlayerSkinByNum(i, skinnum);
if (!netgame)
players[i].skincolor = skins[skinnum].prefcolor;
players[i].skincolor = skins[skinnum]->prefcolor;
}
}
@ -7310,8 +7310,8 @@ static void P_LoadRecordGhosts(void)
if (cv_ghost_bestscore.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-score-best.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-score-best.lmp", gpath, skins[i].name));
if (FIL_FileExists(va("%s-%s-score-best.lmp", gpath, skins[i]->name)))
G_AddGhost(va("%s-%s-score-best.lmp", gpath, skins[i]->name));
}
}
@ -7323,8 +7323,8 @@ static void P_LoadRecordGhosts(void)
if (cv_ghost_besttime.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-time-best.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-time-best.lmp", gpath, skins[i].name));
if (FIL_FileExists(va("%s-%s-time-best.lmp", gpath, skins[i]->name)))
G_AddGhost(va("%s-%s-time-best.lmp", gpath, skins[i]->name));
}
}
@ -7336,8 +7336,8 @@ static void P_LoadRecordGhosts(void)
if (cv_ghost_bestrings.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-rings-best.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-rings-best.lmp", gpath, skins[i].name));
if (FIL_FileExists(va("%s-%s-rings-best.lmp", gpath, skins[i]->name)))
G_AddGhost(va("%s-%s-rings-best.lmp", gpath, skins[i]->name));
}
}
@ -7349,8 +7349,8 @@ static void P_LoadRecordGhosts(void)
if (cv_ghost_last.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-last.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-last.lmp", gpath, skins[i].name));
if (FIL_FileExists(va("%s-%s-last.lmp", gpath, skins[i]->name)))
G_AddGhost(va("%s-%s-last.lmp", gpath, skins[i]->name));
}
}
@ -7380,8 +7380,8 @@ static void P_LoadNightsGhosts(void)
if (cv_ghost_bestscore.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-score-best.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-score-best.lmp", gpath, skins[i].name));
if (FIL_FileExists(va("%s-%s-score-best.lmp", gpath, skins[i]->name)))
G_AddGhost(va("%s-%s-score-best.lmp", gpath, skins[i]->name));
}
}
@ -7393,8 +7393,8 @@ static void P_LoadNightsGhosts(void)
if (cv_ghost_besttime.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-time-best.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-time-best.lmp", gpath, skins[i].name));
if (FIL_FileExists(va("%s-%s-time-best.lmp", gpath, skins[i]->name)))
G_AddGhost(va("%s-%s-time-best.lmp", gpath, skins[i]->name));
}
}
@ -7406,8 +7406,8 @@ static void P_LoadNightsGhosts(void)
if (cv_ghost_last.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-last.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-last.lmp", gpath, skins[i].name));
if (FIL_FileExists(va("%s-%s-last.lmp", gpath, skins[i]->name)))
G_AddGhost(va("%s-%s-last.lmp", gpath, skins[i]->name));
}
}

View file

@ -1836,7 +1836,7 @@ void P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller)
return;
if (!triggerline->stringargs[0])
return;
if (!(stricmp(triggerline->stringargs[0], skins[actor->player->skin].name) == 0) ^ !!(triggerline->args[1]))
if (!(stricmp(triggerline->stringargs[0], skins[actor->player->skin]->name) == 0) ^ !!(triggerline->args[1]))
return;
break;
case 334: // object dye

View file

@ -685,8 +685,8 @@ static void P_DeNightserizePlayer(player_t *player)
player->mo->flags &= ~MF_NOGRAVITY;
player->mo->skin = &skins[player->skin];
player->followitem = skins[player->skin].followitem;
player->mo->skin = skins[player->skin];
player->followitem = skins[player->skin]->followitem;
player->mo->color = P_GetPlayerColor(player);
G_GhostAddColor(GHC_RETURNSKIN);
@ -786,12 +786,12 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
player->mo->height = P_GetPlayerHeight(player); // Just to make sure jumping into the drone doesn't result in a squashed hitbox.
player->oldscale = player->mo->scale;
if (skins[player->skin].sprites[SPR2_NFLY].numframes == 0) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin.
if (skins[player->skin]->sprites[SPR2_NFLY].numframes == 0) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin.
{
player->mo->skin = &skins[DEFAULTNIGHTSSKIN];
player->mo->skin = skins[DEFAULTNIGHTSSKIN];
if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback))
player->mo->color = skins[DEFAULTNIGHTSSKIN].prefcolor;
player->followitem = skins[DEFAULTNIGHTSSKIN].followitem;
player->mo->color = skins[DEFAULTNIGHTSSKIN]->prefcolor;
player->followitem = skins[DEFAULTNIGHTSSKIN]->followitem;
G_GhostAddColor(GHC_NIGHTSSKIN);
}
}
@ -4417,7 +4417,7 @@ static void P_DoSuperStuff(player_t *player)
player->mo->color = (player->pflags & PF_GODMODE && cv_debug == 0)
? (SKINCOLOR_SUPERSILVER1 + 5*(((signed)leveltime >> 1) % 7)) // A wholesome easter egg.
: skins[player->skin].supercolor + abs( ( (player->powers[pw_super] >> 1) % 9) - 4); // This is where super flashing is handled.
: skins[player->skin]->supercolor + abs( ( (player->powers[pw_super] >> 1) % 9) - 4); // This is where super flashing is handled.
G_GhostAddColor(GHC_SUPER);
@ -11643,7 +11643,7 @@ void P_DoMetalJetFume(player_t *player, mobj_t *fume)
if (resetinterp) R_ResetMobjInterpolationState(fume);
// If dashmode is high enough, spawn a trail
if (player->normalspeed >= skins[player->skin].normalspeed*2)
if (player->normalspeed >= skins[player->skin]->normalspeed*2)
{
mobj_t *ghost = P_SpawnGhostMobj(fume);
if (!P_MobjWasRemoved(ghost))
@ -12517,25 +12517,25 @@ void P_PlayerThink(player_t *player)
{
if (prevdashmode >= DASHMODE_THRESHOLD)
{
player->normalspeed = skins[player->skin].normalspeed; // Reset to default if not capable of entering dash mode.
player->jumpfactor = skins[player->skin].jumpfactor;
player->normalspeed = skins[player->skin]->normalspeed; // Reset to default if not capable of entering dash mode.
player->jumpfactor = skins[player->skin]->jumpfactor;
if (player->powers[pw_strong] & STR_DASH)
player->powers[pw_strong] = STR_NONE;
}
}
else if (P_IsObjectOnGround(player->mo)) // Activate dash mode if we're on the ground.
{
if (player->normalspeed < skins[player->skin].normalspeed*2) // If the player normalspeed is not currently at normalspeed*2 in dash mode, add speed each tic
if (player->normalspeed < skins[player->skin]->normalspeed*2) // If the player normalspeed is not currently at normalspeed*2 in dash mode, add speed each tic
player->normalspeed += FRACUNIT/5; // Enter Dash Mode smoothly.
if (player->jumpfactor < FixedMul(skins[player->skin].jumpfactor, 5*FRACUNIT/4)) // Boost jump height.
if (player->jumpfactor < FixedMul(skins[player->skin]->jumpfactor, 5*FRACUNIT/4)) // Boost jump height.
player->jumpfactor += FRACUNIT/300;
if ((player->charflags & SF_MACHINE) && (!(player->powers[pw_strong] == STR_METAL)))
player->powers[pw_strong] = STR_METAL;
}
if (player->normalspeed >= skins[player->skin].normalspeed*2)
if (player->normalspeed >= skins[player->skin]->normalspeed*2)
{
mobj_t *ghost = P_SpawnGhostMobj(player->mo); // Spawns afterimages
if (!P_MobjWasRemoved(ghost))
@ -12550,8 +12550,8 @@ void P_PlayerThink(player_t *player)
{
if (dashmode >= DASHMODE_THRESHOLD) // catch getting the flag!
{
player->normalspeed = skins[player->skin].normalspeed;
player->jumpfactor = skins[player->skin].jumpfactor;
player->normalspeed = skins[player->skin]->normalspeed;
player->jumpfactor = skins[player->skin]->jumpfactor;
S_StartSound(player->mo, sfx_kc65);
if (player->powers[pw_strong] & STR_DASH)
player->powers[pw_strong] = STR_NONE;

View file

@ -121,52 +121,53 @@ float focallengthf, zeroheight;
UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask;
// =========================================================================
// TRANSLATION COLORMAP CODE
// TRANSLATION COLORMAP CODE
// =========================================================================
#define DEFAULT_TT_CACHE_INDEX MAXSKINS
#define BOSS_TT_CACHE_INDEX (MAXSKINS + 1)
#define METALSONIC_TT_CACHE_INDEX (MAXSKINS + 2)
#define ALLWHITE_TT_CACHE_INDEX (MAXSKINS + 3)
#define RAINBOW_TT_CACHE_INDEX (MAXSKINS + 4)
#define BLINK_TT_CACHE_INDEX (MAXSKINS + 5)
#define DASHMODE_TT_CACHE_INDEX (MAXSKINS + 6)
static UINT8 **translationtablecache[MAXSKINS + 7] = {NULL};
UINT8 skincolor_modified[MAXSKINCOLORS];
static INT32 SkinToCacheIndex(INT32 skinnum)
enum
{
switch (skinnum)
DEFAULT_TT_CACHE_INDEX,
BOSS_TT_CACHE_INDEX,
METALSONIC_TT_CACHE_INDEX,
ALLWHITE_TT_CACHE_INDEX,
RAINBOW_TT_CACHE_INDEX,
BLINK_TT_CACHE_INDEX,
DASHMODE_TT_CACHE_INDEX,
TT_CACHE_SIZE
};
static UINT8 **translationtablecache[TT_CACHE_SIZE] = {NULL};
static UINT8 **skintranslationcache[NUM_PALETTE_ENTRIES] = {NULL};
boolean skincolor_modified[MAXSKINCOLORS];
static INT32 TranslationToCacheIndex(INT32 translation)
{
switch (translation)
{
case TC_DEFAULT: return DEFAULT_TT_CACHE_INDEX;
case TC_BOSS: return BOSS_TT_CACHE_INDEX;
case TC_METALSONIC: return METALSONIC_TT_CACHE_INDEX;
case TC_ALLWHITE: return ALLWHITE_TT_CACHE_INDEX;
case TC_RAINBOW: return RAINBOW_TT_CACHE_INDEX;
case TC_BLINK: return BLINK_TT_CACHE_INDEX;
case TC_DASHMODE: return DASHMODE_TT_CACHE_INDEX;
default: break;
default: return DEFAULT_TT_CACHE_INDEX;
}
return skinnum;
}
static INT32 CacheIndexToSkin(INT32 ttc)
static INT32 CacheIndexToTranslation(INT32 index)
{
switch (ttc)
switch (index)
{
case DEFAULT_TT_CACHE_INDEX: return TC_DEFAULT;
case BOSS_TT_CACHE_INDEX: return TC_BOSS;
case METALSONIC_TT_CACHE_INDEX: return TC_METALSONIC;
case ALLWHITE_TT_CACHE_INDEX: return TC_ALLWHITE;
case RAINBOW_TT_CACHE_INDEX: return TC_RAINBOW;
case BLINK_TT_CACHE_INDEX: return TC_BLINK;
case DASHMODE_TT_CACHE_INDEX: return TC_DASHMODE;
default: break;
default: return TC_DEFAULT;
}
return ttc;
}
CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1];
@ -396,18 +397,18 @@ static void R_RainbowColormap(UINT8 *dest_colormap, UINT16 skincolor)
RGBA_t color;
UINT8 brightness;
INT32 j;
UINT8 colorbrightnesses[16];
UINT8 colorbrightnesses[COLORRAMPSIZE];
UINT16 brightdif;
INT32 temp;
// first generate the brightness of all the colours of that skincolour
for (i = 0; i < 16; i++)
for (i = 0; i < COLORRAMPSIZE; i++)
{
color = V_GetColor(skincolors[skincolor].ramp[i]);
SETBRIGHTNESS(colorbrightnesses[i], color.s.red, color.s.green, color.s.blue);
}
// next, for every colour in the palette, choose the transcolor that has the closest brightness
// next, for every colour in the palette, choose the translated colour that has the closest brightness
for (i = 0; i < NUM_PALETTE_ENTRIES; i++)
{
if (i == 0 || i == 31) // pure black and pure white don't change
@ -418,7 +419,7 @@ static void R_RainbowColormap(UINT8 *dest_colormap, UINT16 skincolor)
color = V_GetColor(i);
SETBRIGHTNESS(brightness, color.s.red, color.s.green, color.s.blue);
brightdif = 256;
for (j = 0; j < 16; j++)
for (j = 0; j < COLORRAMPSIZE; j++)
{
temp = abs((INT16)brightness - (INT16)colorbrightnesses[j]);
if (temp < brightdif)
@ -434,28 +435,29 @@ static void R_RainbowColormap(UINT8 *dest_colormap, UINT16 skincolor)
/** \brief Generates a translation colormap.
\param dest_colormap colormap to populate
\param skinnum skin number, or a translation mode
\param color translation color
\param dest_colormap colormap to populate
\param translation translation mode
\param color translation color
\param starttranscolor starting point of the translation
\return void
*/
static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, UINT16 color)
static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 translation, UINT16 color, INT32 starttranscolor)
{
INT32 i, starttranscolor, skinramplength;
INT32 i, skinramplength;
// Handle a couple of simple special cases
if (skinnum < TC_DEFAULT)
if (translation < TC_DEFAULT)
{
switch (skinnum)
switch (translation)
{
case TC_ALLWHITE:
memset(dest_colormap, 0, NUM_PALETTE_ENTRIES * sizeof(UINT8));
return;
case TC_RAINBOW:
if (color >= numskincolors)
I_Error("Invalid skin color #%hu.", (UINT16)color);
if (color != SKINCOLOR_NONE)
I_Error("Invalid skin color #%hu", (UINT16)color);
else if (color != SKINCOLOR_NONE)
{
R_RainbowColormap(dest_colormap, color);
return;
@ -463,8 +465,8 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
break;
case TC_BLINK:
if (color >= numskincolors)
I_Error("Invalid skin color #%hu.", (UINT16)color);
if (color != SKINCOLOR_NONE)
I_Error("Invalid skin color #%hu", (UINT16)color);
else if (color != SKINCOLOR_NONE)
{
memset(dest_colormap, skincolors[color].ramp[3], NUM_PALETTE_ENTRIES * sizeof(UINT8));
return;
@ -478,26 +480,28 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
dest_colormap[i] = (UINT8)i;
// White!
if (skinnum == TC_BOSS)
if (translation == TC_BOSS)
{
UINT8 *originalColormap = R_GetTranslationColormap(TC_DEFAULT, (skincolornum_t)color, GTC_CACHE);
for (i = 0; i < 16; i++)
if (starttranscolor >= NUM_PALETTE_ENTRIES)
I_Error("Invalid startcolor #%d", starttranscolor);
for (i = 0; i < COLORRAMPSIZE; i++)
{
dest_colormap[DEFAULT_STARTTRANSCOLOR + i] = originalColormap[DEFAULT_STARTTRANSCOLOR + i];
dest_colormap[starttranscolor + i] = originalColormap[starttranscolor + i];
dest_colormap[31-i] = i;
}
}
else if (skinnum == TC_METALSONIC)
else if (translation == TC_METALSONIC)
{
for (i = 0; i < 6; i++)
{
dest_colormap[skincolors[SKINCOLOR_BLUE].ramp[12-i]] = skincolors[SKINCOLOR_BLUE].ramp[i];
}
dest_colormap[159] = dest_colormap[253] = dest_colormap[254] = 0;
for (i = 0; i < 16; i++)
for (i = 0; i < COLORRAMPSIZE; i++)
dest_colormap[96+i] = dest_colormap[skincolors[SKINCOLOR_COBALT].ramp[i]];
}
else if (skinnum == TC_DASHMODE) // This is a long one, because MotorRoach basically hand-picked the indices
else if (translation == TC_DASHMODE) // This is a long one, because MotorRoach basically hand-picked the indices
{
// greens -> ketchups
dest_colormap[96] = dest_colormap[97] = 48;
@ -541,26 +545,21 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
}
if (color >= numskincolors)
I_Error("Invalid skin color #%hu.", (UINT16)color);
if (skinnum < 0 && skinnum > TC_DEFAULT)
I_Error("Invalid translation colormap index %d.", skinnum);
starttranscolor = (skinnum != TC_DEFAULT) ? skins[skinnum].starttranscolor : DEFAULT_STARTTRANSCOLOR;
I_Error("Invalid skin color #%hu", (UINT16)color);
if (starttranscolor >= NUM_PALETTE_ENTRIES)
I_Error("Invalid startcolor #%d.", starttranscolor);
I_Error("Invalid startcolor #%d", starttranscolor);
// Fill in the entries of the palette that are fixed
for (i = 0; i < starttranscolor; i++)
dest_colormap[i] = (UINT8)i;
i = starttranscolor + 16;
i = starttranscolor + COLORRAMPSIZE;
if (i < NUM_PALETTE_ENTRIES)
{
for (i = (UINT8)i; i < NUM_PALETTE_ENTRIES; i++)
dest_colormap[i] = (UINT8)i;
skinramplength = 16;
skinramplength = COLORRAMPSIZE;
}
else
skinramplength = i - NUM_PALETTE_ENTRIES; // shouldn't this be NUM_PALETTE_ENTRIES - starttranscolor?
@ -573,7 +572,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
/** \brief Retrieves a translation colormap from the cache.
\param skinnum number of skin, TC_DEFAULT or TC_BOSS
\param skinnum number of skin, or translation modes
\param color translation color
\param flags set GTC_CACHE to use the cache
@ -581,25 +580,47 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
*/
UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags)
{
UINT8* ret;
INT32 skintableindex = SkinToCacheIndex(skinnum); // Adjust if we want the default colormap
INT32 i;
UINT8 ***cache = NULL;
INT32 index, starttranscolor;
UINT8 *ret;
// Adjust if we want the default colormap
if (skinnum >= numskins)
I_Error("Invalid skin number %d", skinnum);
else if (skinnum >= 0)
{
cache = skintranslationcache;
starttranscolor = index = skins[skinnum]->starttranscolor;
}
else if (skinnum <= TC_DEFAULT)
{
cache = translationtablecache;
starttranscolor = DEFAULT_STARTTRANSCOLOR;
index = TranslationToCacheIndex(skinnum);
}
else
I_Error("Invalid translation %d", skinnum);
if (flags & GTC_CACHE)
{
// Allocate table for skin if necessary
if (!translationtablecache[skintableindex])
translationtablecache[skintableindex] = Z_Calloc(MAXSKINCOLORS * sizeof(UINT8**), PU_STATIC, NULL);
if (!cache[index])
cache[index] = Z_Calloc(MAXSKINCOLORS * sizeof(UINT8**), PU_STATIC, NULL);
// Get colormap
ret = translationtablecache[skintableindex][color];
ret = cache[index][color];
// Rebuild the cache if necessary
if (skincolor_modified[color])
{
for (i = 0; i < (INT32)(sizeof(translationtablecache) / sizeof(translationtablecache[0])); i++)
INT32 i;
for (i = 0; i < TT_CACHE_SIZE; i++)
if (translationtablecache[i] && translationtablecache[i][color])
R_GenerateTranslationColormap(translationtablecache[i][color], CacheIndexToSkin(i), color);
R_GenerateTranslationColormap(translationtablecache[i][color], CacheIndexToTranslation(i), color, starttranscolor);
for (i = 0; i < NUM_PALETTE_ENTRIES; i++)
if (skintranslationcache[i] && skintranslationcache[i][color])
R_GenerateTranslationColormap(skintranslationcache[i][color], 0, color, i);
skincolor_modified[color] = false;
}
@ -610,11 +631,11 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags
if (!ret)
{
ret = Z_MallocAlign(NUM_PALETTE_ENTRIES, (flags & GTC_CACHE) ? PU_LEVEL : PU_STATIC, NULL, 8);
R_GenerateTranslationColormap(ret, skinnum, color);
R_GenerateTranslationColormap(ret, skinnum, color, starttranscolor);
// Cache the colormap if desired
if (flags & GTC_CACHE)
translationtablecache[skintableindex][color] = ret;
cache[index][color] = ret;
}
return ret;
@ -632,9 +653,12 @@ void R_FlushTranslationColormapCache(void)
{
INT32 i;
for (i = 0; i < (INT32)(sizeof(translationtablecache) / sizeof(translationtablecache[0])); i++)
for (i = 0; i < TT_CACHE_SIZE; i++)
if (translationtablecache[i])
memset(translationtablecache[i], 0, MAXSKINCOLORS * sizeof(UINT8**));
for (i = 0; i < NUM_PALETTE_ENTRIES; i++)
if (skintranslationcache[i])
memset(skintranslationcache[i], 0, MAXSKINCOLORS * sizeof(UINT8**));
}
UINT16 R_GetColorByName(const char *name)

View file

@ -146,7 +146,7 @@ UINT8 *R_GetBlendTable(int style, INT32 alphalevel);
boolean R_BlendLevelVisible(INT32 blendmode, INT32 alphalevel);
// Color ramp modification should force a recache
extern UINT8 skincolor_modified[];
extern boolean skincolor_modified[];
void R_InitViewBuffer(INT32 width, INT32 height);
void R_InitViewBorder(void);

View file

@ -1489,7 +1489,7 @@ static void R_ParseSpriteInfo(boolean spr2)
spritenum_t sprnum = NUMSPRITES;
playersprite_t spr2num = NUMPLAYERSPRITES;
INT32 i;
INT32 skinnumbers[MAXSKINS];
UINT8 *skinnumbers = NULL;
INT32 foundskins = 0;
// Sprite name
@ -1587,7 +1587,9 @@ static void R_ParseSpriteInfo(boolean spr2)
if (skinnum == -1)
I_Error("Error parsing SPRTINFO lump: Unknown skin \"%s\"", skinName);
skinnumbers[foundskins] = skinnum;
if (skinnumbers == NULL)
skinnumbers = Z_Malloc(sizeof(UINT8) * numskins, PU_STATIC, NULL);
skinnumbers[foundskins] = (UINT8)skinnum;
foundskins++;
}
else if (stricmp(sprinfoToken, "FRAME")==0)
@ -1600,8 +1602,7 @@ static void R_ParseSpriteInfo(boolean spr2)
I_Error("Error parsing SPRTINFO lump: No skins specified in this sprite2 definition");
for (i = 0; i < foundskins; i++)
{
size_t skinnum = skinnumbers[i];
skin_t *skin = &skins[skinnum];
skin_t *skin = skins[skinnumbers[i]];
spriteinfo_t *sprinfo = skin->sprinfo;
M_Memcpy(&sprinfo[spr2num], info, sizeof(spriteinfo_t));
}
@ -1625,8 +1626,11 @@ static void R_ParseSpriteInfo(boolean spr2)
{
I_Error("Error parsing SPRTINFO lump: Expected \"{\" for sprite \"%s\", got \"%s\"",newSpriteName,sprinfoToken);
}
Z_Free(sprinfoToken);
Z_Free(info);
if (skinnumbers)
Z_Free(skinnumbers);
}
//

View file

@ -18,6 +18,7 @@
#include "st_stuff.h"
#include "w_wad.h"
#include "z_zone.h"
#include "m_menu.h"
#include "m_misc.h"
#include "info.h" // spr2names
#include "i_video.h" // rendermode
@ -32,13 +33,7 @@
#endif
INT32 numskins = 0;
skin_t skins[MAXSKINS];
// FIXTHIS: don't work because it must be inistilised before the config load
//#define SKINVALUES
#ifdef SKINVALUES
CV_PossibleValue_t skin_cons_t[MAXSKINS+1];
#endif
skin_t **skins = NULL;
//
// P_GetSkinSprite2
@ -105,7 +100,7 @@ static void Sk_SetDefaultValue(skin_t *skin)
//
memset(skin, 0, sizeof (skin_t));
snprintf(skin->name,
sizeof skin->name, "skin %u", (UINT32)(skin-skins));
sizeof skin->name, "skin %u", (UINT32)(skin->skinnum));
skin->name[sizeof skin->name - 1] = '\0';
skin->wadnum = INT16_MAX;
@ -159,16 +154,6 @@ static void Sk_SetDefaultValue(skin_t *skin)
//
void R_InitSkins(void)
{
#ifdef SKINVALUES
INT32 i;
for (i = 0; i <= MAXSKINS; i++)
{
skin_cons_t[i].value = 0;
skin_cons_t[i].strvalue = NULL;
}
#endif
// no default skin!
numskins = 0;
}
@ -291,7 +276,7 @@ boolean R_SkinUsable(INT32 playernum, INT32 skinnum)
}
}
// returns true if the skin name is found (loaded from pwad)
// returns the skin number if the skin name is found (loaded from pwad)
// warning return -1 if not found
INT32 R_SkinAvailable(const char *name)
{
@ -300,7 +285,7 @@ INT32 R_SkinAvailable(const char *name)
for (i = 0; i < numskins; i++)
{
// search in the skin list
if (stricmp(skins[i].name,name)==0)
if (!stricmp(skins[i]->name,name))
return i;
}
return -1;
@ -324,7 +309,7 @@ INT32 R_GetForcedSkin(INT32 playernum)
// Auxillary function that actually sets the skin
static void SetSkin(player_t *player, INT32 skinnum)
{
skin_t *skin = &skins[skinnum];
skin_t *skin = skins[skinnum];
UINT16 newcolor = 0;
player->skin = skinnum;
@ -381,7 +366,7 @@ static void SetSkin(player_t *player, INT32 skinnum)
fixed_t radius = FixedMul(skin->radius, player->mo->scale);
if ((player->powers[pw_carry] == CR_NIGHTSMODE) && (skin->sprites[SPR2_NFLY].numframes == 0)) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin.
{
skin = &skins[DEFAULTNIGHTSSKIN];
skin = skins[DEFAULTNIGHTSSKIN];
player->followitem = skin->followitem;
if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback))
newcolor = skin->prefcolor; // will be updated in thinker to flashing
@ -721,8 +706,10 @@ void R_AddSkins(UINT16 wadnum, boolean mainfile)
buf2[size] = '\0';
// set defaults
skin = &skins[numskins];
skins = Z_Realloc(skins, sizeof(skin_t*) * (numskins + 1), PU_STATIC, NULL);
skin = skins[numskins] = Z_Calloc(sizeof(skin_t), PU_STATIC, NULL);
Sk_SetDefaultValue(skin);
skin->skinnum = numskins;
skin->wadnum = wadnum;
hudname = realname = supername = false;
// parse
@ -836,15 +823,6 @@ next_token:
if (mainfile == false)
CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name);
#ifdef SKINVALUES
skin_cons_t[numskins].value = numskins;
skin_cons_t[numskins].strvalue = skin->name;
#endif
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_AddPlayerModel(numskins);
#endif
numskins++;
}
@ -915,7 +893,7 @@ void R_PatchSkins(UINT16 wadnum, boolean mainfile)
strlwr(value);
skinnum = R_SkinAvailable(value);
if (skinnum != -1)
skin = &skins[skinnum];
skin = skins[skinnum];
else
{
CONS_Debug(DBG_SETUP, "R_PatchSkins: unknown skin name in P_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename);
@ -1066,7 +1044,7 @@ static void R_RefreshSprite2ForWad(UINT16 wadnum, UINT8 start_spr2)
strlwr(value);
skinnum = R_SkinAvailable(value);
if (skinnum != -1)
skin = &skins[skinnum];
skin = skins[skinnum];
else
{
CONS_Debug(DBG_SETUP, "R_RefreshSprite2ForWad: unknown skin name in P_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename);

View file

@ -31,7 +31,8 @@
/// The skin_t struct
typedef struct
{
char name[SKINNAMESIZE+1]; // INT16 descriptive name of the skin
char name[SKINNAMESIZE+1]; // name of the skin
UINT8 skinnum;
UINT16 wadnum;
skinflags_t flags;
@ -85,7 +86,7 @@ typedef struct
/// Externs
extern INT32 numskins;
extern skin_t skins[MAXSKINS];
extern skin_t **skins;
/// Function prototypes
void R_InitSkins(void);

View file

@ -509,10 +509,6 @@ void R_AddSpriteDefs(UINT16 wadnum)
if (R_AddSingleSpriteDef(sprnames[i], &sprites[i], wadnum, start, end))
{
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_AddSpriteModel(i);
#endif
// if a new sprite was added (not just replaced)
addsprites++;
#ifndef ZDEBUG
@ -587,14 +583,10 @@ void R_InitSprites(void)
}
ST_ReloadSkinFaceGraphics();
//
// check if all sprites have frames
//
/*
for (i = 0; i < numsprites; i++)
if (sprites[i].numframes < 1)
CONS_Debug(DBG_SETUP, "R_InitSprites: sprite %s has no frames at all\n", sprnames[i]);
*/
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_LoadModels();
#endif
}
//
@ -806,8 +798,8 @@ UINT8 *R_GetSpriteTranslation(vissprite_t *vis)
}
else if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player!
{
size_t skinnum = (skin_t*)vis->mobj->skin-skins;
return R_GetTranslationColormap((INT32)skinnum, vis->color, GTC_CACHE);
UINT8 skinnum = ((skin_t*)vis->mobj->skin)->skinnum;
return R_GetTranslationColormap(skinnum, vis->color, GTC_CACHE);
}
else // Use the defaults
return R_GetTranslationColormap(TC_DEFAULT, vis->color, GTC_CACHE);

View file

@ -43,7 +43,7 @@ typedef enum
// free sfx for S_AddSoundFx()
#define NUMSFXFREESLOTS 1600 // Matches SOC Editor.
#define NUMSKINSFXSLOTS (MAXSKINS*NUMSKINSOUNDS)
#define NUMSKINSFXSLOTS (128*NUMSKINSOUNDS)
//
// SoundFX struct.
@ -874,7 +874,7 @@ typedef enum
// free slots for S_AddSoundFx() at run-time --------------------
sfx_freeslot0,
//
// ... 60 free sounds here ...
// ... 1600 free sounds here ...
//
sfx_lastfreeslot = sfx_freeslot0 + NUMSFXFREESLOTS-1,
// end of freeslots ---------------------------------------------

View file

@ -54,8 +54,8 @@ UINT16 objectsdrawn = 0;
// STATUS BAR DATA
//
patch_t *faceprefix[MAXSKINS]; // face status patches
patch_t *superprefix[MAXSKINS]; // super face status patches
patch_t **faceprefix; // face status patches
patch_t **superprefix; // super face status patches
// ------------------------------------------
// status bar overlay
@ -135,8 +135,6 @@ static patch_t *gotrflag;
static patch_t *gotbflag;
static patch_t *fnshico;
static boolean facefreed[MAXPLAYERS];
hudinfo_t hudinfo[NUMHUDITEMS] =
{
{ 16, 176, V_SNAPTOLEFT|V_SNAPTOBOTTOM}, // HUD_LIVES
@ -368,14 +366,14 @@ void ST_LoadGraphics(void)
// made separate so that skins code can reload custom face graphics
void ST_LoadFaceGraphics(INT32 skinnum)
{
if (skins[skinnum].sprites[SPR2_XTRA].numframes > XTRA_LIFEPIC)
if (skins[skinnum]->sprites[SPR2_XTRA].numframes > XTRA_LIFEPIC)
{
spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
spritedef_t *sprdef = &skins[skinnum]->sprites[SPR2_XTRA];
spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_LIFEPIC];
faceprefix[skinnum] = W_CachePatchNum(sprframe->lumppat[0], PU_HUDGFX);
if (skins[skinnum].sprites[(SPR2_XTRA|FF_SPR2SUPER)].numframes > XTRA_LIFEPIC)
if (skins[skinnum]->sprites[(SPR2_XTRA|FF_SPR2SUPER)].numframes > XTRA_LIFEPIC)
{
sprdef = &skins[skinnum].sprites[SPR2_XTRA|FF_SPR2SUPER];
sprdef = &skins[skinnum]->sprites[SPR2_XTRA|FF_SPR2SUPER];
sprframe = &sprdef->spriteframes[0];
superprefix[skinnum] = W_CachePatchNum(sprframe->lumppat[0], PU_HUDGFX);
}
@ -384,13 +382,21 @@ void ST_LoadFaceGraphics(INT32 skinnum)
}
else
faceprefix[skinnum] = superprefix[skinnum] = W_CachePatchName("MISSING", PU_HUDGFX); // ditto
facefreed[skinnum] = false;
}
void ST_ReloadSkinFaceGraphics(void)
{
INT32 i;
Z_Free(faceprefix);
Z_Free(superprefix);
if (!numskins)
return;
faceprefix = Z_Malloc(sizeof(patch_t *) * numskins, PU_STATIC, NULL);
superprefix = Z_Malloc(sizeof(patch_t *) * numskins, PU_STATIC, NULL);
for (i = 0; i < numskins; i++)
ST_LoadFaceGraphics(i);
}
@ -433,11 +439,6 @@ lumpnum_t st_borderpatchnum;
void ST_Init(void)
{
INT32 i;
for (i = 0; i < MAXPLAYERS; i++)
facefreed[i] = true;
if (dedicated)
return;
@ -997,14 +998,14 @@ static void ST_drawLivesArea(void)
// name
v_colmap |= (V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER);
if (strlen(skins[stplyr->skin].hudname) <= 5)
V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname);
else if (V_StringWidth(skins[stplyr->skin].hudname, v_colmap) <= 48)
V_DrawString(hudinfo[HUD_LIVES].x+18, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname);
else if (V_ThinStringWidth(skins[stplyr->skin].hudname, v_colmap) <= 40)
V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname);
if (strlen(skins[stplyr->skin]->hudname) <= 5)
V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin]->hudname);
else if (V_StringWidth(skins[stplyr->skin]->hudname, v_colmap) <= 48)
V_DrawString(hudinfo[HUD_LIVES].x+18, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin]->hudname);
else if (V_ThinStringWidth(skins[stplyr->skin]->hudname, v_colmap) <= 40)
V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin]->hudname);
else
V_DrawThinString(hudinfo[HUD_LIVES].x+18, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname);
V_DrawThinString(hudinfo[HUD_LIVES].x+18, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin]->hudname);
// Power Stones collected
if (G_RingSlingerGametype() && LUA_HudEnabled(hud_powerstones))

View file

@ -42,7 +42,7 @@ void ST_UnloadGraphics(void);
void ST_LoadGraphics(void);
// face load graphics, called when skin changes
void ST_LoadFaceGraphics(INT32 playernum);
void ST_LoadFaceGraphics(INT32 skinnum);
void ST_ReloadSkinFaceGraphics(void);
void ST_doPaletteStuff(void);
@ -76,8 +76,8 @@ extern patch_t *sboscore;
extern patch_t *sbotime;
extern patch_t *sbocolon;
extern patch_t *sboperiod;
extern patch_t *faceprefix[MAXSKINS]; // face status patches
extern patch_t *superprefix[MAXSKINS]; // super face status patches
extern patch_t **faceprefix; // face status patches
extern patch_t **superprefix; // super face status patches
extern patch_t *livesback;
extern patch_t *stlivex;
extern patch_t *ngradeletters[7];

View file

@ -1060,9 +1060,9 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, IN
//
void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT16 skincolor)
{
if (skinnum >= 0 && skinnum < numskins && skins[skinnum].sprites[SPR2_XTRA].numframes > XTRA_CONTINUE)
if (skinnum >= 0 && skinnum < numskins && skins[skinnum]->sprites[SPR2_XTRA].numframes > XTRA_CONTINUE)
{
spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
spritedef_t *sprdef = &skins[skinnum]->sprites[SPR2_XTRA];
spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CONTINUE];
patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH);
const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE);

View file

@ -97,7 +97,7 @@ typedef union
// Continues
UINT8 continues;
patch_t *pcontinues;
INT32 *playerchar; // Continue HUD
UINT8 *playerchar; // Continue HUD
UINT16 *playercolor;
UINT8 gotlife; // Number of extra lives obtained
@ -108,7 +108,7 @@ typedef union
UINT32 scores[MAXPLAYERS]; // Winner's score
UINT16 *color[MAXPLAYERS]; // Winner's color #
boolean spectator[MAXPLAYERS]; // Spectator list
INT32 *character[MAXPLAYERS]; // Winner's character #
UINT8 *character[MAXPLAYERS]; // Winner's character #
INT32 num[MAXPLAYERS]; // Winner's player #
char *name[MAXPLAYERS]; // Winner's name
patch_t *result; // RESULT
@ -121,7 +121,7 @@ typedef union
struct
{
UINT16 *color[MAXPLAYERS]; // Winner's color #
INT32 *character[MAXPLAYERS]; // Winner's character #
UINT8 *character[MAXPLAYERS]; // Winner's character #
INT32 num[MAXPLAYERS]; // Winner's player #
char name[MAXPLAYERS][9]; // Winner's name
UINT32 times[MAXPLAYERS];
@ -1382,22 +1382,22 @@ void Y_StartIntermission(void)
else
{
// too long so just show "YOU GOT THROUGH THE ACT"
if (strlen(skins[players[consoleplayer].skin].realname) > 13)
if (strlen(skins[players[consoleplayer].skin]->realname) > 13)
{
strcpy(data.coop.passed1, "you got");
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "through act" : "through the act");
}
// long enough that "X GOT" won't fit so use "X PASSED THE ACT"
else if (strlen(skins[players[consoleplayer].skin].realname) > 8)
else if (strlen(skins[players[consoleplayer].skin]->realname) > 8)
{
strcpy(data.coop.passed1, skins[players[consoleplayer].skin].realname);
strcpy(data.coop.passed1, skins[players[consoleplayer].skin]->realname);
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "passed act" : "passed the act");
}
// length is okay for normal use
else
{
snprintf(data.coop.passed1, sizeof data.coop.passed1, "%s got",
skins[players[consoleplayer].skin].realname);
skins[players[consoleplayer].skin]->realname);
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "through act" : "through the act");
}
}
@ -1469,26 +1469,26 @@ void Y_StartIntermission(void)
{
snprintf(data.spec.passed1,
sizeof data.spec.passed1, "%s",
skins[players[consoleplayer].skin].realname);
skins[players[consoleplayer].skin]->realname);
data.spec.passed1[sizeof data.spec.passed1 - 1] = '\0';
strcpy(data.spec.passed2, "got them all!");
if (players[consoleplayer].charflags & SF_SUPER)
{
strcpy(data.spec.passed3, "can now become");
if (strlen(skins[players[consoleplayer].skin].supername) > 20) //too long, use generic
if (strlen(skins[players[consoleplayer].skin]->supername) > 20) //too long, use generic
strcpy(data.spec.passed4, "their super form");
else
strcpy(data.spec.passed4, skins[players[consoleplayer].skin].supername);
strcpy(data.spec.passed4, skins[players[consoleplayer].skin]->supername);
}
}
else
{
if (strlen(skins[players[consoleplayer].skin].realname) <= SKINNAMESIZE-5)
if (strlen(skins[players[consoleplayer].skin]->realname) <= SKINNAMESIZE-5)
{
snprintf(data.spec.passed1,
sizeof data.spec.passed1, "%s got",
skins[players[consoleplayer].skin].realname);
skins[players[consoleplayer].skin]->realname);
data.spec.passed1[sizeof data.spec.passed1 - 1] = '\0';
}
else