diff --git a/src/acs/call-funcs.cpp b/src/acs/call-funcs.cpp index 12b698540..36b40e14c 100644 --- a/src/acs/call-funcs.cpp +++ b/src/acs/call-funcs.cpp @@ -1645,7 +1645,7 @@ bool CallFunc_PlayerSkin(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM:: && (info->mo != NULL && P_MobjWasRemoved(info->mo) == false) && (info->mo->player != NULL)) { - UINT8 skin = info->mo->player->skin; + UINT16 skin = info->mo->player->skin; thread->dataStk.push(~env->getString( skins[skin]->name )->idx); return false; } diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 813bbb277..6bf0bb42c 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1208,7 +1208,7 @@ static void SV_SendPlayerInfo(INT32 node) netbuffer->u.playerinfo[i].score = LONG(players[i].score); netbuffer->u.playerinfo[i].timeinserver = SHORT((UINT16)(players[i].jointime / TICRATE)); - netbuffer->u.playerinfo[i].skin = (UINT8)(players[i].skin); + netbuffer->u.playerinfo[i].deprecated_skin = 0xFF; // Extra data netbuffer->u.playerinfo[i].data = 0; //players[i].skincolor; @@ -3863,7 +3863,7 @@ static void Got_RemovePlayer(const UINT8 **p, INT32 playernum) static void Got_AddBot(const UINT8 **p, INT32 playernum) { INT16 newplayernum; - UINT8 skinnum = 0; + UINT16 skinnum = 0; UINT8 difficulty = DIFFICULTBOT; botStyle_e style = BOT_STYLE_NORMAL; @@ -3879,7 +3879,7 @@ static void Got_AddBot(const UINT8 **p, INT32 playernum) } newplayernum = READUINT8(*p); - skinnum = READUINT8(*p); + skinnum = READUINT16(*p); difficulty = READUINT8(*p); style = READUINT8(*p); @@ -4050,11 +4050,11 @@ static boolean SV_AddWaitingPlayers(SINT8 node, UINT8 *availabilities, } /*-------------------------------------------------- - boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p) + boolean K_AddBotFromServer(UINT16 skin, UINT8 difficulty, botStyle_e style, UINT8 *p) See header file for description. --------------------------------------------------*/ -boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p) +boolean K_AddBotFromServer(UINT16 skin, UINT8 difficulty, botStyle_e style, UINT8 *p) { UINT8 newplayernum = *p; @@ -4095,7 +4095,7 @@ boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 if (server) { - UINT8 buf[4]; + UINT8 buf[5]; UINT8 *buf_p = buf; WRITEUINT8(buf_p, newplayernum); @@ -4105,7 +4105,7 @@ boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 skin = numskins; } - WRITEUINT8(buf_p, skin); + WRITEUINT16(buf_p, skin); if (difficulty < 1) { @@ -4555,8 +4555,7 @@ static void HandleConnect(SINT8 node) /// \todo fix this !!! return; // restart the while } - //if (gamestate != GS_LEVEL) // GS_INTERMISSION, etc? - // SV_SendPlayerConfigs(node); // send bare minimum player info + G_SetGamestate(backupstate); DEBFILE("new node joined\n"); } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index eb3861c55..47f11535b 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -348,23 +348,12 @@ struct plrinfo char name[MAXPLAYERNAME+1]; UINT8 address[4]; // sending another string would run us up against MAXPACKETLENGTH UINT8 team; - UINT8 skin; + UINT8 deprecated_skin; UINT8 data; // Color is first four bits, hasflag, isit and issuper have one bit each, the last is unused. UINT32 score; UINT16 timeinserver; // In seconds. } ATTRPACK; -// Shortest player information for join during intermission. -struct plrconfig -{ - char name[MAXPLAYERNAME+1]; - UINT8 skin; - UINT16 color; - UINT32 pflags; - UINT32 score; - UINT8 team; -} ATTRPACK; - struct filesneededconfig_pak { INT32 first; @@ -470,7 +459,6 @@ struct doomdata_t askinfo_pak askinfo; // 61 bytes msaskinfo_pak msaskinfo; // 22 bytes plrinfo playerinfo[MSCOMPAT_MAXPLAYERS];// 576 bytes(?) - plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?) INT32 filesneedednum; // 4 bytes filesneededconfig_pak filesneededcfg; // ??? bytes netinfo_pak netinfo; // Don't believe their lies @@ -634,7 +622,7 @@ void SV_StopServer(void); void SV_ResetServer(void); /*-------------------------------------------------- - boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *newplayernum); + boolean K_AddBotFromServer(UINT16 skin, UINT8 difficulty, botStyle_e style, UINT8 *newplayernum); Adds a new bot, using a server-sided packet sent to all clients. Using regular K_AddBot wherever possible is better, but this is kept @@ -651,7 +639,7 @@ void SV_ResetServer(void); true if a bot can be added via a packet later, otherwise false. --------------------------------------------------*/ -boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p); +boolean K_AddBotFromServer(UINT16 skin, UINT8 difficulty, botStyle_e style, UINT8 *p); void CL_AddSplitscreenPlayer(void); void CL_RemoveSplitscreenPlayer(UINT8 p); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 5d90aaa90..026189ad9 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1048,13 +1048,13 @@ static void SendNameAndColor(const UINT8 n) CleanupPlayerName(playernum, cv_playername[n].zstring); } - char buf[MAXPLAYERNAME+12]; + char buf[MAXPLAYERNAME+13]; char *p = buf; // Finally write out the complete packet and send it off. WRITESTRINGN(p, cv_playername[n].zstring, MAXPLAYERNAME); WRITEUINT16(p, sendColor); - WRITEUINT8(p, (UINT8)cv_skin[n].value); + WRITEUINT16(p, (UINT16)cv_skin[n].value); if (horngoner) { WRITEINT16(p, (-1)); @@ -1135,7 +1135,7 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum) player_t *p = &players[playernum]; char name[MAXPLAYERNAME+1]; UINT16 color, followercolor; - UINT8 skin; + UINT16 skin; INT16 follower; UINT8 i; @@ -1164,7 +1164,7 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum) READSTRINGN(*cp, name, MAXPLAYERNAME); color = READUINT16(*cp); - skin = READUINT8(*cp); + skin = READUINT16(*cp); follower = READINT16(*cp); followercolor = READUINT16(*cp); diff --git a/src/d_player.h b/src/d_player.h index 11e40c04e..553c2a422 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -694,8 +694,8 @@ struct player_t INT32 skin; UINT8 availabilities[MAXAVAILABILITY]; - UINT8 fakeskin; // ironman - UINT8 lastfakeskin; + UINT16 fakeskin; // ironman + UINT16 lastfakeskin; UINT8 kartspeed; // Kart speed stat between 1 and 9 UINT8 kartweight; // Kart weight stat between 1 and 9 diff --git a/src/doomdef.h b/src/doomdef.h index 2842e4d80..efb0364c5 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -170,9 +170,10 @@ extern char logfilename[1024]; #define MAXSPLITSCREENPLAYERS 4 // Max number of players on a single computer #define MAXGAMEPADS (MAXSPLITSCREENPLAYERS * 2) // Number of gamepads we'll be allowing -#define MAXSKINS UINT8_MAX +#define MAXSKINS 1024 #define SKINNAMESIZE 16 -#define MAXAVAILABILITY ((MAXSKINS + 7)/8) +#define MAXSKINUNAVAILABLE 128 +#define MAXAVAILABILITY (MAXSKINUNAVAILABLE / 8) #define COLORRAMPSIZE 16 #define MAXCOLORNAME 32 diff --git a/src/doomstat.h b/src/doomstat.h index 322e59bad..0d567c053 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -145,7 +145,7 @@ extern unloaded_skin_t *unloadedskins; struct skinreference_t { unloaded_skin_t *unloaded; - UINT8 id; + UINT16 id; }; // mapvisited is now a set of flags that says what we've done in the map. diff --git a/src/g_demo.cpp b/src/g_demo.cpp index feb35c5c8..c4ceaa65d 100644 --- a/src/g_demo.cpp +++ b/src/g_demo.cpp @@ -98,11 +98,15 @@ tic_t demostarttime; // for comparative timing purposes static constexpr DemoBufferSizes get_buffer_sizes(UINT16 version) { - // These sizes are compatible as of version 0x000A + if (version < 0x0010) + return {21, 16, 32, 32}; + + // These sizes are compatible as of version 0x0010 static_assert(MAXPLAYERNAME == 21); static_assert(SKINNAMESIZE == 16); static_assert(MAXCOLORNAME == 32); - return {21, 16, 32}; + static_assert(MAXAVAILABILITY == 16); + return {21, 16, 32, 16}; } static DemoBufferSizes g_buffer_sizes; @@ -138,7 +142,8 @@ static struct { INT32 health; // EZT_STATDATA - UINT8 skinid, kartspeed, kartweight; + UINT16 skinid; + UINT8 kartspeed, kartweight; UINT32 charflags; UINT8 desyncframes; // Don't try to resync unless we've been off for two frames, to monkeypatch a few trouble spots @@ -169,11 +174,14 @@ demoghost *ghosts = NULL; // - Slope physics changed with a scaling fix // - 0x000C (Ring Racers v2.2) // - 0x000D (Ring Racers v2.3) -// - 0x000E (Ring Racers v2.4 in-dev before DYNSLOPE thinker change) -// - 0x000F (Ring Racers v2.4) + +// Currently supported: +// - 0x000E (Ring Racers 2.4 staff ghosts part 1 - initial recordings) +// - 0x000F (Ring Racers 2.4 staff ghosts part 2 - dynslopes thinker fix) +// - 0x0010 (Ring Racers 2.4 staff ghosts part 3 - skinlimit raise. don't say we never did anythin for 'ya) #define MINDEMOVERSION 0x000E -#define DEMOVERSION 0x000F +#define DEMOVERSION 0x0010 boolean G_CompatLevel(UINT16 level) { @@ -330,6 +338,8 @@ void G_ReadDemoExtraData(void) { players[p].availabilities[i] = READUINT8(demobuf.p); } + if (g_buffer_sizes.availability > static_cast(i)) + demobuf.p += (g_buffer_sizes.availability - i); players[p].bot = !!(READUINT8(demobuf.p)); if (players[p].bot) @@ -389,13 +399,17 @@ void G_ReadDemoExtraData(void) } if (extradata & DXD_SKIN) { - UINT8 skinid; + UINT16 skinid; // Skin - skinid = READUINT8(demobuf.p); + if (demo.version >= 0x0010) + skinid = READUINT16(demobuf.p); + else + skinid = READUINT8(demobuf.p); if (skinid >= demo.numskins) skinid = 0; + ghostext[p].skinid = demo.currentskinid[p] = skinid; SetPlayerSkinByNum(p, skinid); @@ -537,7 +551,7 @@ void G_WriteDemoExtraData(void) if (demo_extradata[i] & DXD_SKIN) { // Skin - WRITEUINT8(demobuf.p, players[i].skin); + WRITEUINT16(demobuf.p, players[i].skin); } if (demo_extradata[i] & DXD_COLOR) { @@ -922,14 +936,14 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum) } if (ghost->player && ( - ghostext[playernum].skinid != (UINT8)(((skin_t *)ghost->skin)->skinnum) || + ghostext[playernum].skinid != (UINT16)(((skin_t *)ghost->skin)->skinnum) || ghostext[playernum].kartspeed != ghost->player->kartspeed || ghostext[playernum].kartweight != ghost->player->kartweight || ghostext[playernum].charflags != ghost->player->charflags )) { ghostext[playernum].flags |= EZT_STATDATA; - ghostext[playernum].skinid = (UINT8)(((skin_t *)ghost->skin)->skinnum); + ghostext[playernum].skinid = (UINT16)(((skin_t *)ghost->skin)->skinnum); ghostext[playernum].kartspeed = ghost->player->kartspeed; ghostext[playernum].kartweight = ghost->player->kartweight; ghostext[playernum].charflags = ghost->player->charflags; @@ -984,7 +998,7 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum) } if (ghostext[playernum].flags & EZT_STATDATA) { - WRITEUINT8(demobuf.p,ghostext[playernum].skinid); + WRITEUINT16(demobuf.p,ghostext[playernum].skinid); WRITEUINT8(demobuf.p,ghostext[playernum].kartspeed); WRITEUINT8(demobuf.p,ghostext[playernum].kartweight); WRITEUINT32(demobuf.p, ghostext[playernum].charflags); @@ -1013,7 +1027,7 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum) if (ghost->player->followmobj->colorized) followtic |= FZT_COLORIZED; if (followtic & FZT_SKIN) - WRITEUINT8(demobuf.p,(UINT8)(((skin_t *)(ghost->player->followmobj->skin))->skinnum)); + WRITEUINT16(demobuf.p,(UINT16)(((skin_t *)(ghost->player->followmobj->skin))->skinnum)); oldghost[playernum].flags2 |= MF2_AMBUSH; } @@ -1160,9 +1174,18 @@ void G_ConsGhostTic(INT32 playernum) } if (xziptic & EZT_STATDATA) { - ghostext[playernum].skinid = READUINT8(demobuf.p); - if (ghostext[playernum].skinid >= demo.numskins) - ghostext[playernum].skinid = 0; + UINT16 skinid; + + // Skin + + if (demo.version >= 0x0010) + skinid = READUINT16(demobuf.p); + else + skinid = READUINT8(demobuf.p); + if (skinid >= demo.numskins) + skinid = 0; + + ghostext[playernum].skinid = skinid; ghostext[playernum].kartspeed = READUINT8(demobuf.p); ghostext[playernum].kartweight = READUINT8(demobuf.p); ghostext[playernum].charflags = READUINT32(demobuf.p); @@ -1176,7 +1199,11 @@ void G_ConsGhostTic(INT32 playernum) { demobuf.p += sizeof(INT16); if (followtic & FZT_SKIN) + { demobuf.p++; + if (demo.version >= 0x0010) + demobuf.p++; + } } if (followtic & FZT_SCALE) demobuf.p += sizeof(fixed_t); @@ -1247,7 +1274,7 @@ void G_ConsGhostTic(INT32 playernum) if (players[playernum].kartspeed != ghostext[playernum].kartspeed || players[playernum].kartweight != ghostext[playernum].kartweight || players[playernum].charflags != ghostext[playernum].charflags || - demo.skinlist[ghostext[playernum].skinid].mapping != (UINT8)(((skin_t *)testmo->skin)->skinnum)) + demo.skinlist[ghostext[playernum].skinid].mapping != (UINT16)(((skin_t *)testmo->skin)->skinnum)) { if (demosynced) { @@ -1289,7 +1316,7 @@ void G_GhostTicker(void) continue; } // Pause jhosts that cross until the timer starts. - if (g->attackstart != INT32_MAX && leveltime < starttime && leveltime >= g->attackstart && G_TimeAttackStart()) + if (g->attackstart != UINT32_MAX && leveltime < starttime && leveltime >= g->attackstart && G_TimeAttackStart()) { continue; } @@ -1333,7 +1360,7 @@ fadeghost: ziptic = READUINT8(g->p); if (ziptic & DXD_JOINDATA) { - g->p += MAXAVAILABILITY; + g->p += g->sizes.availability; if (READUINT8(g->p) != 0) I_Error("Ghost is not a record attack ghost (bot JOINDATA)"); } @@ -1349,7 +1376,11 @@ fadeghost: } } if (ziptic & DXD_SKIN) + { g->p++; // We _could_ read this info, but it shouldn't change anything in record attack... + if (g->version >= 0x0010) + g->p++; + } if (ziptic & DXD_COLOR) g->p += g->sizes.color_name; // Same tbh if (ziptic & DXD_NAME) @@ -1511,9 +1542,17 @@ fadeghost: g->p += 1 + 1 + 4; // itemtype, itemamount, health if (xziptic & EZT_STATDATA) { - UINT8 skinid = READUINT8(g->p); + UINT16 skinid; + + // Skin + + if (g->version >= 0x0010) + skinid = READUINT16(g->p); + else + skinid = READUINT8(g->p); if (skinid >= g->numskins) skinid = 0; + g->mo->skin = skins[g->skinlist[skinid].mapping]; g->p += 6; // kartspeed, kartweight, charflags } @@ -1549,7 +1588,14 @@ fadeghost: follow->colorized = true; if (followtic & FZT_SKIN) - follow->skin = skins[READUINT8(g->p)]; + { + UINT16 id; + if (g->version >= 0x0010) + id = READUINT16(g->p); + else + id = READUINT8(g->p); + follow->skin = skins[id]; + } } if (follow) { @@ -1618,10 +1664,10 @@ skippedghosttic: I_Error("Ghost is not a record attack ghost GHOSTEND"); //@TODO lmao don't blow up like this // If the timer started, skip ahead until the ghost starts too. - if (!fastforward && attacktimingstarted && g->attackstart != INT32_MAX && leveltime < g->attackstart && G_TimeAttackStart()) + if (!fastforward && attacktimingstarted && g->attackstart != UINT32_MAX && leveltime < g->attackstart && G_TimeAttackStart()) { fastforward = g->attackstart - leveltime; - g->attackstart = INT32_MAX; + g->attackstart = UINT32_MAX; } if (fastforward) @@ -1871,10 +1917,10 @@ static UINT8 G_CheckDemoExtraFiles(savebuffer_t *info, boolean quick) static void G_SaveDemoSkins(UINT8 **pp, const DemoBufferSizes &psizes) { - UINT8 i; + UINT16 i; UINT8 *availabilitiesbuffer = R_GetSkinAvailabilities(true, -1); - WRITEUINT8((*pp), numskins); + WRITEUINT16((*pp), numskins); for (i = 0; i < numskins; i++) { // Skinname, for first attempt at identification. @@ -1892,9 +1938,10 @@ static void G_SaveDemoSkins(UINT8 **pp, const DemoBufferSizes &psizes) } } -static democharlist_t *G_LoadDemoSkins(const DemoBufferSizes &psizes, savebuffer_t *info, UINT8 *worknumskins, boolean getclosest) +static democharlist_t *G_LoadDemoSkins(const DemoBufferSizes &psizes, savebuffer_t *info, UINT16 *worknumskins, boolean getclosest) { - UINT8 i, byte, shif; + UINT16 i; + UINT8 byte, shif; democharlist_t *skinlist = NULL; if (P_SaveBufferRemaining(info) < 1) @@ -1902,7 +1949,11 @@ static democharlist_t *G_LoadDemoSkins(const DemoBufferSizes &psizes, savebuffer return NULL; } - (*worknumskins) = READUINT8(info->p); + if (psizes.availability == 32) // version isn't accessible here + (*worknumskins) = READUINT8(info->p); + else + (*worknumskins) = READUINT16(info->p); + if (!(*worknumskins)) return NULL; @@ -1943,18 +1994,18 @@ static democharlist_t *G_LoadDemoSkins(const DemoBufferSizes &psizes, savebuffer if (result != -1) { - skinlist[i].mapping = (UINT8)result; + skinlist[i].mapping = (UINT16)result; } } + if (P_SaveBufferRemaining(info) < psizes.availability) + { + Z_Free(skinlist); + return NULL; + } + for (byte = 0; byte < MAXAVAILABILITY; byte++) { - if (P_SaveBufferRemaining(info) < 1) - { - Z_Free(skinlist); - return NULL; - } - UINT8 availabilitiesbuffer = READUINT8(info->p); for (shif = 0; shif < 8; shif++) @@ -1971,15 +2022,22 @@ static democharlist_t *G_LoadDemoSkins(const DemoBufferSizes &psizes, savebuffer } } + if (psizes.availability > static_cast(byte)) + info->p += (psizes.availability - byte); + return skinlist; } static void G_SkipDemoSkins(UINT8 **pp, const DemoBufferSizes& psizes) { - UINT8 demonumskins; - UINT8 i; + UINT16 demonumskins; + UINT16 i; + + if (psizes.availability == 32) // version isn't accessible here + demonumskins = READUINT8((*pp)); + else + demonumskins = READUINT16((*pp)); - demonumskins = READUINT8((*pp)); for (i = 0; i < demonumskins; ++i) { (*pp) += psizes.skin_name; // name @@ -1988,7 +2046,7 @@ static void G_SkipDemoSkins(UINT8 **pp, const DemoBufferSizes& psizes) (*pp) += 4; // flags } - (*pp) += MAXAVAILABILITY; + (*pp) += psizes.availability; } void G_BeginRecording(void) @@ -2086,7 +2144,7 @@ void G_BeginRecording(void) // If special attack-start timing applies, we need to know where to skip the ghost to demoattack_p = demobuf.p; - WRITEUINT32(demobuf.p, INT32_MAX); + WRITEUINT32(demobuf.p, UINT32_MAX); demosplits_p = demobuf.p; for (i = 0; i < MAXSPLITS; i++) @@ -2164,8 +2222,8 @@ void G_BeginRecording(void) } // Skin (now index into demo.skinlist) - WRITEUINT8(demobuf.p, player->skin); - WRITEUINT8(demobuf.p, player->lastfakeskin); + WRITEUINT16(demobuf.p, player->skin); + WRITEUINT16(demobuf.p, player->lastfakeskin); WRITEUINT8(demobuf.p, player->team); @@ -2305,10 +2363,6 @@ void G_SetDemoCheckpointTiming(player_t *player, tic_t time, UINT8 checkpoint) if (points <= MAXSPLITS) endtime = g->splits[points-1]; - // Staff ghost oopsie. Fuckin, uh, - if (endtime == INT32_MAX) - endtime = UINT32_MAX; - if (lowestend > oldbest) // Not losing to any ghost { // Not currently losing to a ghost @@ -2488,15 +2542,10 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) } p += 12; // DEMOHEADER p++; // VERSION p++; // SUBVERSION - oldversion = READUINT16(p); - switch(oldversion) // demoversion + oldversion = READUINT16(p); // demoversion + if (oldversion < MINDEMOVERSION || oldversion > DEMOVERSION) { - case 0x000E: - /* fallthru */ - case DEMOVERSION: // latest always supported - break; - // too old, cannot support. - default: + // too old, cannot support. CONS_Alert(CONS_NOTICE, M_GetText("File '%s' invalid format. It will be overwritten.\n"), oldname); Z_Free(buffer); return UINT8_MAX; @@ -2601,7 +2650,8 @@ void G_LoadDemoInfo(menudemo_t *pdemo, boolean allownonmultiplayer) { savebuffer_t info = {0}; UINT8 *extrainfo_p; - UINT8 version, subversion, worknumskins; + UINT8 version, subversion; + UINT16 worknumskins; UINT16 pdemoflags; democharlist_t *skinlist = NULL; UINT16 pdemoversion, count; @@ -2639,27 +2689,22 @@ void G_LoadDemoInfo(menudemo_t *pdemo, boolean allownonmultiplayer) subversion = READUINT8(info.p); pdemoversion = READUINT16(info.p); - switch(pdemoversion) + if (pdemoversion < MINDEMOVERSION || pdemoversion > DEMOVERSION) { - case 0x000E: - /* fallthru */ - case DEMOVERSION: // latest always supported - if (P_SaveBufferRemaining(&info) < 64) - { - goto corrupt; - } - - // demo title - M_Memcpy(pdemo->title, info.p, 64); - info.p += 64; - - break; - // too old, cannot support. - default: + // too old, cannot support. CONS_Alert(CONS_ERROR, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemo->filepath); goto badreplay; } + if (P_SaveBufferRemaining(&info) < 64) + { + goto corrupt; + } + + // demo title + M_Memcpy(pdemo->title, info.p, 64); + info.p += 64; + if (version != VERSION || subversion != SUBVERSION) pdemo->type = MD_OUTDATED; @@ -2882,7 +2927,8 @@ void G_DoPlayDemoEx(const char *defdemoname, lumpnum_t deflumpnum) char msg[1024]; boolean spectator, bot; - UINT8 slots[MAXPLAYERS], lastfakeskin[MAXPLAYERS]; + UINT8 slots[MAXPLAYERS]; + UINT16 lastfakeskin[MAXPLAYERS]; #if defined(SKIPERRORS) && !defined(DEVELOP) // RR: Don't print warnings for staff ghosts, since they'll inevitably @@ -3038,14 +3084,9 @@ void G_DoPlayDemoEx(const char *defdemoname, lumpnum_t deflumpnum) version = READUINT8(demobuf.p); subversion = READUINT8(demobuf.p); demo.version = READUINT16(demobuf.p); - switch(demo.version) + if (demo.version < MINDEMOVERSION || demo.version > DEMOVERSION) { - case 0x000E: - /* fallthru */ - case DEMOVERSION: // latest always supported - break; - // too old, cannot support. - default: + // too old, cannot support. snprintf(msg, 1024, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname); CONS_Alert(CONS_ERROR, "%s", msg); M_StartMessage("Demo Playback", msg, NULL, MM_NOTHING, NULL, "Return to Menu"); @@ -3363,13 +3404,24 @@ void G_DoPlayDemoEx(const char *defdemoname, lumpnum_t deflumpnum) { availabilities[p][i] = READUINT8(demobuf.p); } + if (g_buffer_sizes.availability > static_cast(i)) + demobuf.p += (g_buffer_sizes.availability - i); // Skin - demo.currentskinid[p] = READUINT8(demobuf.p); + if (demo.version >= 0x0010) + { + demo.currentskinid[p] = READUINT16(demobuf.p); + lastfakeskin[p] = READUINT16(demobuf.p); + } + else + { + demo.currentskinid[p] = READUINT8(demobuf.p); + lastfakeskin[p] = READUINT8(demobuf.p); + } + if (demo.currentskinid[p] >= demo.numskins) demo.currentskinid[p] = 0; - lastfakeskin[p] = READUINT8(demobuf.p); players[p].team = READUINT8(demobuf.p); @@ -3510,7 +3562,7 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname) UINT16 initialskin = 0; UINT16 initialcolor = 0; skin_t *ghskin = skins[0]; - UINT8 worknumskins; + UINT16 worknumskins; UINT32 num_classes; democharlist_t *skinlist = NULL; @@ -3528,14 +3580,10 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname) p++; // SUBVERSION ghostversion = READUINT16(p); - switch(ghostversion) + + if (ghostversion < MINDEMOVERSION || ghostversion > DEMOVERSION) { - case 0x000E: - /* fallthru */ - case DEMOVERSION: // latest always supported - break; - // too old, cannot support. - default: + // too old, cannot support. CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Demo version incompatible.\n"), defdemoname); P_SaveBufferFree(buffer); return; @@ -3618,6 +3666,21 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname) splits[i] = READUINT32(p); } + if (ghostversion < 0x0010) + { + // Staff ghost oopsie. Fuckin, uh, + + if (attackstart == INT32_MAX) + attackstart = UINT32_MAX; + + for (i = 0; i < MAXSPLITS; i++) + { + if (splits[i] != INT32_MAX) + continue; + splits[i] = UINT32_MAX; + } + } + // net var data count = READUINT16(p); while (count--) @@ -3655,18 +3718,26 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname) // Player name (TODO: Display this somehow if it doesn't match cv_playername!) p += copy_fixed_buf(name, p, ghostsizes.player_name); - p += MAXAVAILABILITY; + p += ghostsizes.availability; // Skin - i = READUINT8(p); + if (ghostversion >= 0x0010) + { + i = READUINT16(p); + p += 2; // lastfakeskin + } + else + { + i = READUINT8(p); + p++; // lastfakeskin + } + if (i < worknumskins) { ghskin = skins[skinlist[i].mapping]; initialskin = skinlist[i].mapping; } - p++; // lastfakeskin - p++; // team // Color @@ -3794,7 +3865,7 @@ staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer) { UINT8 *p = buffer; UINT16 ghostversion; - UINT16 flags; + UINT16 flags, count; UINT32 num_classes; INT32 i; staffbrief_t temp = {0}; @@ -3814,16 +3885,10 @@ staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer) p++; // SUBVERSION ghostversion = READUINT16(p); - switch(ghostversion) + if (ghostversion < MINDEMOVERSION || ghostversion > DEMOVERSION) { - case 0x000E: - /* fallthru */ - case DEMOVERSION: // latest always supported - break; - // too old, cannot support. - default: - goto fail; + goto fail; } p += 64; // full demo title @@ -3867,9 +3932,8 @@ staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer) for (i = 0; i < MAXSPLITS; i++) p += 4; // splits - // Ehhhh don't need ghostversion here (?) so I'll reuse the var here - ghostversion = READUINT16(p); - while (ghostversion--) + count = READUINT16(p); + while (count--) { SKIPSTRING(p); SKIPSTRING(p); diff --git a/src/g_demo.h b/src/g_demo.h index 62d5577cb..8efcaa463 100644 --- a/src/g_demo.h +++ b/src/g_demo.h @@ -32,7 +32,7 @@ struct StandingJson { uint8_t ranking; String name; - uint8_t demoskin; + uint16_t demoskin; String skincolor; uint32_t timeorscore; @@ -71,7 +71,7 @@ extern tic_t demostarttime; struct democharlist_t { char name[SKINNAMESIZE+1]; UINT32 namehash; - UINT8 mapping; // No, this isn't about levels. It maps to loaded character ID. + UINT16 mapping; // No, this isn't about levels. It maps to loaded character ID. UINT8 kartspeed; UINT8 kartweight; UINT32 flags; @@ -97,9 +97,9 @@ struct demovars_s { boolean freecam; - UINT8 numskins; + UINT16 numskins; democharlist_t *skinlist; - UINT8 currentskinid[MAXPLAYERS]; + UINT16 currentskinid[MAXPLAYERS]; const savebuffer_t *buffer; // debug, valid only if recording or playback }; @@ -129,7 +129,7 @@ struct menudemo_t { struct { UINT8 ranking; char name[MAXPLAYERNAME+1]; - UINT8 skin, color; + UINT16 skin, color; UINT32 timeorscore; } standings[MAXPLAYERS]; }; @@ -194,6 +194,7 @@ struct DemoBufferSizes size_t player_name; size_t skin_name; size_t color_name; + size_t availability; }; // Your naming conventions are stupid and useless. @@ -205,7 +206,7 @@ struct demoghost { UINT16 initialcolor; UINT8 fadein; UINT16 version; - UINT8 numskins; + UINT16 numskins; tic_t attackstart; tic_t splits[MAXSPLITS]; boolean done; diff --git a/src/g_game.c b/src/g_game.c index 83985b51b..db732acc2 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2261,8 +2261,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) UINT16 skincolor; INT32 skin; UINT8 availabilities[MAXAVAILABILITY]; - UINT8 fakeskin; - UINT8 lastfakeskin; + UINT16 fakeskin; + UINT16 lastfakeskin; tic_t jointime; @@ -5229,7 +5229,7 @@ void G_DirtyGameData(void) // Can be called by the startup code or the menu task. // -#define SAV_VERSIONMINOR 6 +#define SAV_VERSIONMINOR 7 void G_LoadGame(void) { diff --git a/src/k_bot.cpp b/src/k_bot.cpp index 502f519a1..e1d59e4bf 100644 --- a/src/k_bot.cpp +++ b/src/k_bot.cpp @@ -49,7 +49,7 @@ extern "C" consvar_t cv_forcebots; /*-------------------------------------------------- - void K_SetNameForBot(UINT8 playerNum, UINT8 skinnum) + void K_SetNameForBot(UINT8 playerNum, const char *realname) See header file for description. --------------------------------------------------*/ @@ -102,11 +102,11 @@ void K_SetNameForBot(UINT8 newplayernum, const char *realname) } /*-------------------------------------------------- - void K_SetBot(UINT8 playerNum, UINT8 skinnum, UINT8 difficulty, botStyle_e style) + void K_SetBot(UINT8 playerNum, UINT16 skinnum, UINT8 difficulty, botStyle_e style) See header file for description. --------------------------------------------------*/ -void K_SetBot(UINT8 newplayernum, UINT8 skinnum, UINT8 difficulty, botStyle_e style) +void K_SetBot(UINT8 newplayernum, UINT16 skinnum, UINT8 difficulty, botStyle_e style) { CONS_Debug(DBG_NETPLAY, "addbot: %d\n", newplayernum); @@ -199,11 +199,11 @@ void K_SetBot(UINT8 newplayernum, UINT8 skinnum, UINT8 difficulty, botStyle_e st } /*-------------------------------------------------- - boolean K_AddBot(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p) + boolean K_AddBot(UINT16 skin, UINT8 difficulty, botStyle_e style, UINT8 *p) See header file for description. --------------------------------------------------*/ -boolean K_AddBot(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p) +boolean K_AddBot(UINT16 skin, UINT8 difficulty, botStyle_e style, UINT8 *p) { UINT8 newplayernum = *p; @@ -239,16 +239,16 @@ boolean K_AddBot(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p) --------------------------------------------------*/ void K_UpdateMatchRaceBots(void) { - const UINT8 defaultbotskin = R_BotDefaultSkin(); + const UINT16 defaultbotskin = R_BotDefaultSkin(); UINT8 difficulty; UINT8 pmax = (dedicated ? MAXPLAYERS-1 : MAXPLAYERS); UINT8 numplayers = 0; UINT8 numbots = 0; UINT8 numwaiting = 0; SINT8 wantedbots = 0; - UINT8 usableskins = 0, skincount = (demo.playback ? demo.numskins : numskins);; - UINT8 grabskins[MAXSKINS+1]; - UINT8 i; + UINT16 usableskins = 0, skincount = (demo.playback ? demo.numskins : numskins);; + UINT16 grabskins[MAXSKINS+1]; + UINT16 i; // Init usable bot skins list for (i = 0; i < skincount; i++) @@ -387,11 +387,11 @@ void K_UpdateMatchRaceBots(void) while (numbots < wantedbots) { - UINT8 skinnum = defaultbotskin; + UINT16 skinnum = defaultbotskin; if (usableskins > 0) { - UINT8 index = P_RandomKey(PR_BOTS, usableskins); + UINT16 index = P_RandomKey(PR_BOTS, usableskins); skinnum = grabskins[index]; grabskins[index] = grabskins[--usableskins]; } diff --git a/src/k_bot.h b/src/k_bot.h index 596894d2d..c050d1bfa 100644 --- a/src/k_bot.h +++ b/src/k_bot.h @@ -182,7 +182,7 @@ fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t /*-------------------------------------------------- - boolean K_AddBot(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p); + boolean K_AddBot(UINT16 skin, UINT8 difficulty, botStyle_e style, UINT8 *p); Adds a new bot, using code intended to run on all clients. @@ -197,7 +197,7 @@ fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t true if a bot was added, otherwise false. --------------------------------------------------*/ -boolean K_AddBot(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p); +boolean K_AddBot(UINT16 skin, UINT8 difficulty, botStyle_e style, UINT8 *p); // NOT AVAILABLE FOR LUA @@ -222,7 +222,7 @@ void K_SetNameForBot(UINT8 newplayernum, const char *realname); /*-------------------------------------------------- - void K_SetBot(UINT8 newplayernum, UINT8 skinnum, UINT8 difficulty, botStyle_e style); + void K_SetBot(UINT8 newplayernum, UINT16 skinnum, UINT8 difficulty, botStyle_e style); Sets a player ID to be a new bot directly. Invoked directly by K_AddBot, and indirectly by K_AddBotFromServer by sending @@ -238,7 +238,7 @@ void K_SetNameForBot(UINT8 newplayernum, const char *realname); None --------------------------------------------------*/ -void K_SetBot(UINT8 newplayernum, UINT8 skinnum, UINT8 difficulty, botStyle_e style); +void K_SetBot(UINT8 newplayernum, UINT16 skinnum, UINT8 difficulty, botStyle_e style); /*-------------------------------------------------- diff --git a/src/k_grandprix.cpp b/src/k_grandprix.cpp index 651f60742..85b7412ac 100644 --- a/src/k_grandprix.cpp +++ b/src/k_grandprix.cpp @@ -215,7 +215,7 @@ void K_AssignFoes(void) --------------------------------------------------*/ void K_InitGrandPrixBots(void) { - const UINT8 defaultbotskin = R_BotDefaultSkin(); + const UINT16 defaultbotskin = R_BotDefaultSkin(); const UINT8 startingdifficulty = K_BotStartingDifficulty(grandprixinfo.gamespeed); UINT8 difficultylevels[MAXPLAYERS]; @@ -226,14 +226,14 @@ void K_InitGrandPrixBots(void) UINT8 numplayers = 0; UINT8 competitors[MAXSPLITSCREENPLAYERS]; - UINT8 usableskins, skincount = (demo.playback ? demo.numskins : numskins);; - UINT8 grabskins[MAXSKINS+1]; + UINT16 usableskins, skincount = (demo.playback ? demo.numskins : numskins);; + UINT16 grabskins[MAXSKINS+1]; - UINT8 botskinlist[MAXPLAYERS]; + UINT16 botskinlist[MAXPLAYERS]; UINT8 botskinlistpos = 0; UINT8 newplayernum = 0; - UINT8 i, j; + UINT16 i, j; memset(competitors, MAXPLAYERS, sizeof (competitors)); memset(botskinlist, defaultbotskin, sizeof (botskinlist)); @@ -314,10 +314,10 @@ void K_InitGrandPrixBots(void) INT32 rivalnum = R_SkinAvailable(rivalname); // Intentionally referenced before (currently dummied out) unlock check. Such a tease! - if (rivalnum != -1 && grabskins[(UINT8)rivalnum] != MAXSKINS) + if (rivalnum != -1 && grabskins[(UINT16)rivalnum] != MAXSKINS) { botskinlist[botskinlistpos++] = (UINT8)rivalnum; - grabskins[(UINT8)rivalnum] = MAXSKINS; + grabskins[(UINT16)rivalnum] = MAXSKINS; } } } @@ -345,11 +345,11 @@ void K_InitGrandPrixBots(void) { while (botskinlistpos < wantedbots) { - UINT8 skinnum = defaultbotskin; + UINT16 skinnum = defaultbotskin; if (usableskins > 0) { - UINT8 index = P_RandomKey(PR_BOTS, usableskins); + UINT16 index = P_RandomKey(PR_BOTS, usableskins); skinnum = grabskins[index]; grabskins[index] = grabskins[--usableskins]; } @@ -781,7 +781,7 @@ static boolean CompareReplacements(player_t *a, player_t *b) --------------------------------------------------*/ void K_RetireBots(void) { - UINT8 i; + UINT16 i; if (grandprixinfo.gp == true && grandprixinfo.eventmode != GPEVENT_NONE) @@ -931,11 +931,11 @@ void K_RetireBots(void) // Okay, now this is essentially the original contents of K_RetireBots with cpp swag - const UINT8 defaultbotskin = R_BotDefaultSkin(); + const UINT16 defaultbotskin = R_BotDefaultSkin(); SINT8 newDifficulty; - UINT8 usableskins, skincount = (demo.playback ? demo.numskins : numskins); - UINT8 grabskins[MAXSKINS+1]; + UINT16 usableskins, skincount = (demo.playback ? demo.numskins : numskins); + UINT16 grabskins[MAXSKINS+1]; // Handle adjusting difficulty for new bots { @@ -1009,11 +1009,11 @@ void K_RetireBots(void) // Replace nocontested bots. for (player_t *bot : bots) { - UINT8 skinnum = defaultbotskin; + UINT16 skinnum = defaultbotskin; if (usableskins > 0) { - UINT8 index = P_RandomKey(PR_BOTS, usableskins); + UINT16 index = P_RandomKey(PR_BOTS, usableskins); skinnum = grabskins[index]; grabskins[index] = grabskins[--usableskins]; } diff --git a/src/k_hud.cpp b/src/k_hud.cpp index 1424d438d..e14d31342 100644 --- a/src/k_hud.cpp +++ b/src/k_hud.cpp @@ -2795,7 +2795,7 @@ void PositionFacesInfo::draw_1p() INT32 i, j; INT32 bumperx, emeraldx; INT32 xoff, yoff, flipflag = 0; - UINT8 workingskin; + UINT16 workingskin; UINT8 *colormap; UINT32 skinflags; @@ -3542,7 +3542,7 @@ static void K_drawKartDuelScores(void) // minirankings shamelessly copypasted because i know that shit works already // and SURELY we will never need to use this somewhere else, right? - UINT8 workingskin; + UINT16 workingskin; UINT8 *colormap; INT32 xoff, yoff, flipflag, skinflags; @@ -5957,7 +5957,7 @@ static void K_drawKartMinimap(void) INT32 minimaptrans; INT32 splitflags; - UINT8 skin = 0; + UINT16 skin = 0; UINT8 *colormap = NULL; SINT8 localplayers[MAXSPLITSCREENPLAYERS]; diff --git a/src/k_kart.c b/src/k_kart.c index 71d8e143d..4fdee3183 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2863,7 +2863,7 @@ static void K_RegularVoiceTimers(player_t *player) player->karthud[khud_tauntvoices] = 4*TICRATE; } -static UINT8 K_ObjectToSkinIDForSounds(mobj_t *source) +static UINT16 K_ObjectToSkinIDForSounds(mobj_t *source) { if (source->player) return source->player->skin; @@ -2876,7 +2876,7 @@ static UINT8 K_ObjectToSkinIDForSounds(mobj_t *source) static void K_PlayGenericTastefulTaunt(mobj_t *source, sfxenum_t sfx_id) { - UINT8 skinid = K_ObjectToSkinIDForSounds(source); + UINT16 skinid = K_ObjectToSkinIDForSounds(source); if (skinid >= numskins) return; @@ -2915,7 +2915,7 @@ void K_PlayBoostTaunt(mobj_t *source) void K_PlayOvertakeSound(mobj_t *source) { - UINT8 skinid = K_ObjectToSkinIDForSounds(source); + UINT16 skinid = K_ObjectToSkinIDForSounds(source); if (skinid >= numskins) return; @@ -2940,7 +2940,7 @@ void K_PlayOvertakeSound(mobj_t *source) static void K_PlayGenericCombatSound(mobj_t *source, mobj_t *other, sfxenum_t sfx_id) { - UINT8 skinid = K_ObjectToSkinIDForSounds(source); + UINT16 skinid = K_ObjectToSkinIDForSounds(source); if (skinid >= numskins) return; @@ -3010,7 +3010,7 @@ void K_TryHurtSoundExchange(mobj_t *victim, mobj_t *attacker) void K_PlayPowerGloatSound(mobj_t *source) { - UINT8 skinid = K_ObjectToSkinIDForSounds(source); + UINT16 skinid = K_ObjectToSkinIDForSounds(source); if (skinid >= numskins) return; @@ -3028,7 +3028,7 @@ void K_PlayPowerGloatSound(mobj_t *source) // MOVED so we don't have to extern K_ObjectToSkinID void P_PlayVictorySound(mobj_t *source) { - UINT8 skinid = K_ObjectToSkinIDForSounds(source); + UINT16 skinid = K_ObjectToSkinIDForSounds(source); if (skinid >= numskins) return; diff --git a/src/k_menu.h b/src/k_menu.h index a1fee8e37..f8207193d 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -793,7 +793,7 @@ UINT16 M_GetColorAfter(setup_player_colors_t *colors, UINT16 value, INT32 amount extern struct setup_chargrid_s { INT16 skinlist[MAXCLONES]; - UINT8 numskins; + UINT16 numskins; } setup_chargrid[9][9]; extern UINT8 setup_followercategories[MAXFOLLOWERCATEGORIES][2]; @@ -1512,7 +1512,7 @@ void M_Statistics(INT32 choice); void M_DrawStatistics(void); boolean M_StatisticsInputs(INT32 ch); -void M_DrawCharacterIconAndEngine(INT32 x, INT32 y, UINT8 skin, UINT8 *colormap, UINT8 baseskin); +void M_DrawCharacterIconAndEngine(INT32 x, INT32 y, UINT16 skin, UINT8 *colormap, UINT16 baseskin); fixed_t M_DrawCupWinData(INT32 rankx, INT32 ranky, cupheader_t *cup, UINT8 difficulty, boolean flash, boolean statsmode); #define MAXWRONGPLAYER MAXSPLITSCREENPLAYERS @@ -1523,7 +1523,7 @@ extern struct wrongwarp_s { tic_t delaytowrongplayer; struct wrongplayer_s { - UINT8 skin; + UINT16 skin; INT16 across; boolean spinout; } wrongplayers[MAXWRONGPLAYER]; diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 003fcbb44..b99196b3a 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -3057,7 +3057,7 @@ fixed_t M_DrawCupWinData(INT32 rankx, INT32 ranky, cupheader_t *cup, UINT8 diffi } else { - UINT8 skin = windata->best_skin.id; + UINT16 skin = windata->best_skin.id; colormap = R_GetTranslationColormap(skin, skins[skin]->prefcolor, GTC_MENUCACHE); @@ -7163,7 +7163,7 @@ drawborder: #define challengetransparentstrength 8 -void M_DrawCharacterIconAndEngine(INT32 x, INT32 y, UINT8 skin, UINT8 *colormap, UINT8 baseskin) +void M_DrawCharacterIconAndEngine(INT32 x, INT32 y, UINT16 skin, UINT8 *colormap, UINT16 baseskin) { V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT, diff --git a/src/k_rank.h b/src/k_rank.h index 943cb40c0..1c256996b 100644 --- a/src/k_rank.h +++ b/src/k_rank.h @@ -45,7 +45,7 @@ struct gpRank_t UINT8 totalPlayers; UINT8 position; - UINT8 skin; + UINT16 skin; UINT32 winPoints; UINT32 totalPoints; diff --git a/src/k_tally.cpp b/src/k_tally.cpp index 224c1111d..35af7b9ae 100644 --- a/src/k_tally.cpp +++ b/src/k_tally.cpp @@ -522,7 +522,7 @@ void level_tally_t::Init(player_t *player) // It'd be neat to add all of the grade sounds, // but not this close to release - UINT8 skinid = player->skin; + UINT16 skinid = player->skin; if (skinid >= numskins || R_CanShowSkinInDemo(skinid) == false) ; else if (rank < GRADE_C) diff --git a/src/m_cond.c b/src/m_cond.c index c1a4ffb9f..3032eed6c 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -3813,6 +3813,11 @@ INT32 M_UnlockableSkinNum(unlockable_t *unlock) skinnum = R_SkinAvailableEx(unlock->stringVar, false); if (skinnum != -1) { + if (skinnum >= MAXSKINUNAVAILABLE) + { + CONS_Alert(CONS_WARNING,"Unlockable ID %s: Skin %s (id %d) is greater than %u, and will not be locked in this session.", sizeu1((unlock-unlockables)+1), unlock->stringVar, skinnum, MAXSKINUNAVAILABLE); + } + unlock->stringVarCache = skinnum; return skinnum; } diff --git a/src/menus/play-char-select.c b/src/menus/play-char-select.c index 1a055a7b5..16685b29c 100644 --- a/src/menus/play-char-select.c +++ b/src/menus/play-char-select.c @@ -406,6 +406,8 @@ void M_CharacterSelect(INT32 choice) // Gets the selected follower's state for a given setup player. static void M_GetFollowerState(setup_player_t *p) { + if (p->followern < 0 || p->followern >= numfollowers) + return; p->follower_state = &states[followers[p->followern].followstate]; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index d1e0613f4..aee0a3fa4 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -175,7 +175,7 @@ static boolean P_UnArchivePlayer(savebuffer_t *save) memset(&savedata.bots, 0, sizeof(savedata.bots)); UINT8 pid; - const UINT8 defaultbotskin = R_BotDefaultSkin(); + const UINT16 defaultbotskin = R_BotDefaultSkin(); while ((pid = READUINT8(save->p)) < MAXPLAYERS) { @@ -260,8 +260,8 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, players[i].availabilities[j]); } - WRITEUINT8(save->p, players[i].fakeskin); - WRITEUINT8(save->p, players[i].lastfakeskin); + WRITEUINT16(save->p, players[i].fakeskin); + WRITEUINT16(save->p, players[i].lastfakeskin); WRITEUINT16(save->p, players[i].prefcolor); WRITEINT32(save->p, players[i].prefskin); @@ -988,8 +988,8 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].availabilities[j] = READUINT8(save->p); } - players[i].fakeskin = READUINT8(save->p); - players[i].lastfakeskin = READUINT8(save->p); + players[i].fakeskin = READUINT16(save->p); + players[i].lastfakeskin = READUINT16(save->p); players[i].prefcolor = READUINT16(save->p); players[i].prefskin = READINT32(save->p); @@ -3537,7 +3537,7 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 if (diff2 & MD2_CVMEM) WRITEINT32(save->p, mobj->cvmem); if (diff2 & MD2_SKIN) - WRITEUINT8(save->p, (UINT8)((skin_t *)mobj->skin)->skinnum); + WRITEUINT16(save->p, (UINT16)((skin_t *)mobj->skin)->skinnum); if (diff2 & MD2_COLOR) WRITEUINT16(save->p, mobj->color); if (diff2 & MD2_EXTVAL1) @@ -4836,7 +4836,7 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, 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[READUINT16(save->p)]; if (diff2 & MD2_COLOR) mobj->color = READUINT16(save->p); if (diff2 & MD2_EXTVAL1) @@ -6436,7 +6436,7 @@ static inline void P_ArchiveMisc(savebuffer_t *save) WRITEUINT8(save->p, rank->totalPlayers); WRITEUINT8(save->p, rank->position); - WRITEUINT8(save->p, rank->skin); + WRITEUINT16(save->p, rank->skin); WRITEUINT32(save->p, rank->winPoints); WRITEUINT32(save->p, rank->totalPoints); @@ -6702,7 +6702,7 @@ static boolean P_UnArchiveSPGame(savebuffer_t *save) rank->totalPlayers = READUINT8(save->p); rank->position = READUINT8(save->p); - rank->skin = READUINT8(save->p); + rank->skin = READUINT16(save->p); rank->winPoints = READUINT32(save->p); rank->totalPoints = READUINT32(save->p); diff --git a/src/p_saveg.h b/src/p_saveg.h index 1848550ad..1249630b5 100644 --- a/src/p_saveg.h +++ b/src/p_saveg.h @@ -43,7 +43,7 @@ mobj_t *P_FindNewPosition(UINT32 oldposition); struct savedata_bot_s { boolean valid; - UINT8 skin; + UINT16 skin; UINT8 difficulty; boolean rival; boolean foe; @@ -56,7 +56,7 @@ struct savedata_t SINT8 lives; UINT16 totalring; - UINT8 skin; + UINT16 skin; UINT16 skincolor; INT32 followerskin; UINT16 followercolor; diff --git a/src/r_skins.c b/src/r_skins.c index 553dd28f1..240a86a12 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -139,7 +139,7 @@ static void Sk_SetDefaultValue(skin_t *skin) // Grab the default skin #define DEFAULTBOTSKINNAME "eggrobo" -UINT8 R_BotDefaultSkin(void) +UINT16 R_BotDefaultSkin(void) { static INT32 defaultbotskin = -1; @@ -157,7 +157,7 @@ UINT8 R_BotDefaultSkin(void) } } - return (UINT8)defaultbotskin; + return (UINT16)defaultbotskin; } #undef DEFAULTBOTSKINNAME @@ -205,7 +205,7 @@ UINT8 *R_GetSkinAvailabilities(boolean demolock, INT32 botforcecharacter) skinid = M_UnlockableSkinNum(&unlockables[i]); - if (skinid < 0 || skinid >= MAXSKINS) + if (skinid < 0 || skinid >= MAXSKINUNAVAILABLE) continue; if ((forbots @@ -250,6 +250,12 @@ boolean R_SkinUsable(INT32 playernum, INT32 skinnum, boolean demoskins) return true; } + if (skinnum >= MAXSKINUNAVAILABLE) + { + // Keeping our packet size nice and sane in the wake of MAXSKINS increase + return true; + } + // Determine if this character is supposed to be unlockable or not if (useplayerstruct && demo.playback) { @@ -308,8 +314,8 @@ boolean R_CanShowSkinInDemo(INT32 skinnum) // Returns a random unlocked skin ID. UINT32 R_GetLocalRandomSkin(void) { - UINT8 i, usableskins = 0; - UINT8 grabskins[MAXSKINS]; + UINT16 i, usableskins = 0; + UINT16 grabskins[MAXSKINS]; for (i = 0; i < numskins; i++) { @@ -512,8 +518,8 @@ void SetFakePlayerSkin(player_t* player, INT32 skinid) void SetRandomFakePlayerSkin(player_t* player, boolean fast, boolean instant) { INT32 i; - UINT8 usableskins = 0, maxskinpick; - UINT8 grabskins[MAXSKINS]; + UINT16 usableskins = 0, maxskinpick; + UINT16 grabskins[MAXSKINS]; maxskinpick = (demo.playback ? demo.numskins : numskins); @@ -594,7 +600,7 @@ void SetRandomFakePlayerSkin(player_t* player, boolean fast, boolean instant) // Return to base skin from an SF_IRONMAN randomization void ClearFakePlayerSkin(player_t* player) { - UINT8 skinid; + UINT16 skinid; UINT32 flags; if (demo.playback) diff --git a/src/r_skins.h b/src/r_skins.h index 7ac74ef64..b075d8164 100644 --- a/src/r_skins.h +++ b/src/r_skins.h @@ -39,7 +39,7 @@ extern "C" { struct skin_t { char name[SKINNAMESIZE+1]; // name of skin - UINT8 skinnum; + UINT16 skinnum; UINT32 namehash; // quickncasehash(->name, SKINNAMESIZE) UINT16 wadnum; skinflags_t flags; @@ -125,7 +125,7 @@ void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002 // Set backup INT32 GetSkinNumClosestToStats(UINT8 kartspeed, UINT8 kartweight, UINT32 flags, boolean unlock); -UINT8 R_BotDefaultSkin(void); +UINT16 R_BotDefaultSkin(void); // Heavy Magician void SetFakePlayerSkin(player_t* player, INT32 skinnum); diff --git a/src/typedef.h b/src/typedef.h index d2eea64c4..d77aac7ee 100644 --- a/src/typedef.h +++ b/src/typedef.h @@ -73,7 +73,6 @@ TYPEDEF (serverrefuse_pak); TYPEDEF (askinfo_pak); TYPEDEF (msaskinfo_pak); TYPEDEF (plrinfo); -TYPEDEF (plrconfig); TYPEDEF (filesneededconfig_pak); TYPEDEF (doomdata_t); TYPEDEF (serverelem_t); diff --git a/src/y_inter.cpp b/src/y_inter.cpp index 883876f8e..1f3dffee9 100644 --- a/src/y_inter.cpp +++ b/src/y_inter.cpp @@ -1055,7 +1055,7 @@ void Y_RoundQueueDrawer(y_data_t *standings, INT32 offset, boolean doanimations, UINT8 *colormap = NULL, *oppositemap = NULL; fixed_t playerx = 0, playery = 0; - UINT8 pskin = MAXSKINS; + UINT16 pskin = MAXSKINS; UINT16 pcolor = SKINCOLOR_WHITE; if (standings->mainplayer == MAXPLAYERS)