From 255570cfca8ac6a2700098036085a48a10a3a84b Mon Sep 17 00:00:00 2001 From: Eidolon Date: Fri, 1 Aug 2025 21:22:39 -0500 Subject: [PATCH] Dynamically allocate skins This avoids an issue where the skins array takes up a fixed, but large amount of memory at runtime. On x86_64 linux, that array is roughly 80 megabytes in memory, most of which is unused when the game is unmodded. Instead, we treat `skins` as a dynamically resizing array, and it is an array-of-pointers into separate allocated `skin_t`. This is based on Lactozilla's skin limit MR for SRB2, but I've rewritten it because RR has diverged quite a bit. This was verified to check every access of `skins` by using clangd's find-all-references function. However, I have only tested plain skins, not Lua addons, so that could afford some extra checking. --- src/acs/call-funcs.cpp | 6 +-- src/command.c | 2 +- src/d_main.cpp | 14 +++--- src/d_netcmd.c | 14 +++--- src/discord.c | 4 +- src/f_finale.c | 10 ++--- src/g_demo.cpp | 26 +++++------ src/g_game.c | 10 ++--- src/g_gamedata.cpp | 8 ++-- src/hardware/hw_main.c | 6 +-- src/hardware/hw_md2.c | 10 ++--- src/k_bot.cpp | 4 +- src/k_color.c | 6 +-- src/k_dialogue.cpp | 2 +- src/k_follower.c | 4 +- src/k_grandprix.c | 6 +-- src/k_hud.cpp | 12 +++--- src/k_kart.c | 12 +++--- src/k_menudraw.c | 74 ++++++++++++++++---------------- src/k_podium.cpp | 4 +- src/k_tally.cpp | 6 +-- src/lua_hudlib.c | 14 +++--- src/lua_mobjlib.c | 2 +- src/lua_skinlib.c | 12 +++--- src/m_cond.c | 20 ++++----- src/menus/extras-challenges.c | 4 +- src/menus/extras-statistics.cpp | 20 ++++----- src/menus/main-goner.cpp | 6 +-- src/menus/play-char-select.c | 32 +++++++------- src/menus/transient/cup-select.c | 2 +- src/objects/destroyed-kart.cpp | 6 +-- src/objects/ring-shooter.c | 6 +-- src/objects/ufo.c | 2 +- src/p_inter.c | 14 +++--- src/p_mobj.c | 20 ++++----- src/p_saveg.c | 10 ++--- src/p_setup.cpp | 6 +-- src/p_spec.c | 4 +- src/p_tick.c | 4 +- src/p_user.c | 6 +-- src/r_picformats.c | 2 +- src/r_skins.c | 49 ++++++++------------- src/r_skins.h | 7 +-- src/r_spritefx.cpp | 2 +- src/r_things.cpp | 2 +- src/s_sound.c | 4 +- src/st_stuff.c | 2 +- src/y_inter.cpp | 2 +- 48 files changed, 244 insertions(+), 256 deletions(-) diff --git a/src/acs/call-funcs.cpp b/src/acs/call-funcs.cpp index 303dcc07f..c74e18d6e 100644 --- a/src/acs/call-funcs.cpp +++ b/src/acs/call-funcs.cpp @@ -1646,7 +1646,7 @@ bool CallFunc_PlayerSkin(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM:: && (info->mo->player != NULL)) { UINT8 skin = info->mo->player->skin; - thread->dataStk.push(~env->getString( skins[skin].name )->idx); + thread->dataStk.push(~env->getString( skins[skin]->name )->idx); return false; } @@ -3698,11 +3698,11 @@ bool CallFunc_SetThingProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, A #define PROP_SKIN(x, y) \ case x: \ { \ - INT32 newSkin = (mobj->skin != NULL) ? (static_cast(mobj->skin)) - skins : -1; \ + INT32 newSkin = (mobj->skin != NULL) ? (static_cast(mobj->skin)->skinnum) : -1; \ bool success = ACS_GetSkinFromString(thread->scopeMap->getString( value )->str, &newSkin); \ if (success == true) \ { \ - mobj->y = (newSkin >= 0 && newSkin < numskins) ? &skins[ newSkin ] : NULL; \ + mobj->y = (newSkin >= 0 && newSkin < numskins) ? skins[ newSkin ] : NULL; \ } \ break; \ } diff --git a/src/command.c b/src/command.c index d1a985266..9096e5d1c 100644 --- a/src/command.c +++ b/src/command.c @@ -2126,7 +2126,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; strlcpy(val, tmpskin, SKINNAMESIZE+1); } else diff --git a/src/d_main.cpp b/src/d_main.cpp index 5ddd59326..bbf14f43e 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1793,15 +1793,15 @@ void D_SRB2Main(void) S_RegisterSoundStuff(); I_RegisterSysCommands(); - + CON_SetLoadingProgress(LOADED_HUINIT); - + CONS_Printf("W_InitMultipleFiles(): Adding external PWADs.\n"); - + // HACK: Refer to https://git.do.srb2.org/KartKrew/RingRacers/-/merge_requests/29#note_61574 partadd_earliestfile = numwadfiles; W_InitMultipleFiles(startuppwads, true); - + // Only search for pwad maps and reload graphics if we actually have a pwad added if (startuppwads[0] != NULL) { @@ -1811,7 +1811,7 @@ void D_SRB2Main(void) P_InitMapData(); HU_LoadGraphics(); } - + D_CleanFile(startuppwads); partadd_earliestfile = UINT16_MAX; @@ -2077,7 +2077,7 @@ void D_SRB2Main(void) INT32 importskin = R_SkinAvailableEx(pr->skinname, false); if (importskin != -1) { - skins[importskin].records.wins = pr->wins; + skins[importskin]->records.wins = pr->wins; cupheader_t *cup; for (cup = kartcupheaders; cup; cup = cup->next) @@ -2103,7 +2103,7 @@ void D_SRB2Main(void) } } - CONS_Printf(" Wins for profile \"%s\" imported onto character \"%s\"\n", pr->profilename, skins[importskin].name); + CONS_Printf(" Wins for profile \"%s\" imported onto character \"%s\"\n", pr->profilename, skins[importskin]->name); } } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index a91da5d27..102e886bb 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -881,7 +881,7 @@ static void ForceAllSkins(INT32 forcedskin) if (!playeringame[g_localplayers[i]]) continue; - CV_StealthSet(&cv_skin[i], skins[forcedskin].name); + CV_StealthSet(&cv_skin[i], skins[forcedskin]->name); } } @@ -975,7 +975,7 @@ static void SendNameAndColor(const UINT8 n) // Don't change skin if the server doesn't want you to. if (!CanChangeSkin(playernum)) { - CV_StealthSet(&cv_skin[n], skins[player->skin].name); + CV_StealthSet(&cv_skin[n], skins[player->skin]->name); } // check if player has the skin loaded (cv_skin may have @@ -996,7 +996,7 @@ static void SendNameAndColor(const UINT8 n) if (sendColor == SKINCOLOR_NONE) { - sendColor = skins[cv_skin[n].value].prefcolor; + sendColor = skins[cv_skin[n].value]->prefcolor; } if (sendFollowerColor == SKINCOLOR_NONE) @@ -1014,7 +1014,7 @@ static void SendNameAndColor(const UINT8 n) // Don't send if everything was identical. if (!strcmp(cv_playername[n].string, player_names[playernum]) && sendColor == player->skincolor - && !stricmp(cv_skin[n].string, skins[player->skin].name) + && !stricmp(cv_skin[n].string, skins[player->skin]->name) && !stricmp(cv_follower[n].string, (player->followerskin < 0 ? "None" : followers[player->followerskin].name)) && sendFollowerColor == player->followercolor) @@ -1194,7 +1194,7 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum) SetPlayerSkinByNum(playernum, forcedskin); if (localplayer != -1) - CV_StealthSet(&cv_skin[localplayer], skins[forcedskin].name); + CV_StealthSet(&cv_skin[localplayer], skins[forcedskin]->name); } else { @@ -7038,7 +7038,7 @@ static void Skin_OnChange(const UINT8 p) if (!CV_CheatsEnabled() && !(netgame || K_CanChangeRules(false)) && (gamestate != GS_WAITINGPLAYERS)) // allows command line -warp x +skin y { - CV_StealthSet(&cv_skin[p], skins[players[g_localplayers[p]].skin].name); + CV_StealthSet(&cv_skin[p], skins[players[g_localplayers[p]].skin]->name); return; } @@ -7049,7 +7049,7 @@ static void Skin_OnChange(const UINT8 p) else { CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n")); - CV_StealthSet(&cv_skin[p], skins[players[g_localplayers[p]].skin].name); + CV_StealthSet(&cv_skin[p], skins[players[g_localplayers[p]].skin]->name); } } diff --git a/src/discord.c b/src/discord.c index 808e54b89..768e15333 100644 --- a/src/discord.c +++ b/src/discord.c @@ -952,7 +952,7 @@ void DRPC_UpdatePresence(void) // Character image if ((unsigned)players[consoleplayer].skin < g_discord_skins) // Supported skins { - snprintf(charimg, 32, "char_%s", skins[ players[consoleplayer].skin ].name); + snprintf(charimg, 32, "char_%s", skins[ players[consoleplayer].skin ]->name); discordPresence.smallImageKey = charimg; } else @@ -961,7 +961,7 @@ void DRPC_UpdatePresence(void) discordPresence.smallImageKey = "custom_char"; } - snprintf(charname, 128, "Character: %s", skins[players[consoleplayer].skin].realname); + snprintf(charname, 128, "Character: %s", skins[players[consoleplayer].skin]->realname); discordPresence.smallImageText = charname; // Character name } } diff --git a/src/f_finale.c b/src/f_finale.c index 30652898c..15767bf7c 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1371,7 +1371,7 @@ void F_GameEvaluationDrawer(void) const char *rtatext, *cuttext; rtatext = (marathonmode & MA_INGAME) ? "In-game timer" : "RTA timer"; cuttext = (marathonmode & MA_NOCUTSCENES) ? "" : " w/ cutscenes"; - 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); } @@ -1886,13 +1886,13 @@ void F_TitleScreenDrawer(void) if (eggSkin != -1) { - eggColor = skins[eggSkin].prefcolor; + eggColor = skins[eggSkin]->prefcolor; } eggColormap = R_GetTranslationColormap(TC_DEFAULT, eggColor, GTC_MENUCACHE); if (tailsSkin != -1) { - tailsColor = skins[tailsSkin].prefcolor; + tailsColor = skins[tailsSkin]->prefcolor; } tailsColormap = R_GetTranslationColormap(TC_DEFAULT, tailsColor, GTC_MENUCACHE); @@ -2243,9 +2243,9 @@ void F_StartWaitingPlayers(void) if (waitcolormap) Z_Free(waitcolormap); - waitcolormap = R_GetTranslationColormap(randskin, skins[randskin].prefcolor, 0); + waitcolormap = R_GetTranslationColormap(randskin, skins[randskin]->prefcolor, 0); - sprdef = &skins[randskin].sprites[P_GetSkinSprite2(&skins[randskin], SPR2_FSTN, NULL)]; + sprdef = &skins[randskin]->sprites[P_GetSkinSprite2(skins[randskin], SPR2_FSTN, NULL)]; for (i = 0; i < 2; i++) { diff --git a/src/g_demo.cpp b/src/g_demo.cpp index 5fbdd382a..efd61bb9c 100644 --- a/src/g_demo.cpp +++ b/src/g_demo.cpp @@ -922,14 +922,14 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum) } if (ghost->player && ( - ghostext[playernum].skinid != (UINT8)(((skin_t *)ghost->skin)-skins) || + ghostext[playernum].skinid != (UINT8)(((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)-skins); + ghostext[playernum].skinid = (UINT8)(((skin_t *)ghost->skin)->skinnum); ghostext[playernum].kartspeed = ghost->player->kartspeed; ghostext[playernum].kartweight = ghost->player->kartweight; ghostext[playernum].charflags = ghost->player->charflags; @@ -1013,7 +1013,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))-skins)); + WRITEUINT8(demobuf.p,(UINT8)(((skin_t *)(ghost->player->followmobj->skin))->skinnum)); oldghost[playernum].flags2 |= MF2_AMBUSH; } @@ -1247,13 +1247,13 @@ 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)-skins)) + demo.skinlist[ghostext[playernum].skinid].mapping != (UINT8)(((skin_t *)testmo->skin)->skinnum)) { if (demosynced) CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced (Character/stats)!\n")); demosynced = false; - testmo->skin = &skins[demo.skinlist[ghostext[playernum].skinid].mapping]; + testmo->skin = skins[demo.skinlist[ghostext[playernum].skinid].mapping]; players[playernum].kartspeed = ghostext[playernum].kartspeed; players[playernum].kartweight = ghostext[playernum].kartweight; players[playernum].charflags = ghostext[playernum].charflags; @@ -1491,7 +1491,7 @@ readghosttic: UINT8 skinid = READUINT8(g->p); if (skinid >= g->numskins) skinid = 0; - g->mo->skin = &skins[g->skinlist[skinid].mapping]; + g->mo->skin = skins[g->skinlist[skinid].mapping]; g->p += 6; // kartspeed, kartweight, charflags } } @@ -1527,7 +1527,7 @@ readghosttic: follow->colorized = true; if (followtic & FZT_SKIN) - follow->skin = &skins[READUINT8(g->p)]; + follow->skin = skins[READUINT8(g->p)]; } if (follow) { @@ -2066,12 +2066,12 @@ static void G_SaveDemoSkins(UINT8 **pp, const DemoBufferSizes &psizes) for (i = 0; i < numskins; i++) { // Skinname, for first attempt at identification. - (*pp) += copy_fixed_buf((*pp), skins[i].name, psizes.skin_name); + (*pp) += copy_fixed_buf((*pp), skins[i]->name, psizes.skin_name); // Backup information for second pass. - WRITEUINT8((*pp), skins[i].kartspeed); - WRITEUINT8((*pp), skins[i].kartweight); - WRITEUINT32((*pp), skins[i].flags); + WRITEUINT8((*pp), skins[i]->kartspeed); + WRITEUINT8((*pp), skins[i]->kartweight); + WRITEUINT32((*pp), skins[i]->flags); } for (i = 0; i < MAXAVAILABILITY; i++) @@ -3552,7 +3552,7 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname) UINT8 *p; mapthing_t *mthing; UINT16 count, ghostversion; - skin_t *ghskin = &skins[0]; + skin_t *ghskin = skins[0]; UINT8 worknumskins; democharlist_t *skinlist = NULL; @@ -3705,7 +3705,7 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname) // Skin i = READUINT8(p); if (i < worknumskins) - ghskin = &skins[skinlist[i].mapping]; + ghskin = skins[skinlist[i].mapping]; p++; // lastfakeskin // Color diff --git a/src/g_game.c b/src/g_game.c index bfb58032b..b2f4d8b27 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2205,9 +2205,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) if (betweenmaps) { fakeskin = MAXSKINS; - kartspeed = skins[players[player].skin].kartspeed; - kartweight = skins[players[player].skin].kartweight; - charflags = skins[players[player].skin].flags; + kartspeed = skins[players[player].skin]->kartspeed; + kartweight = skins[players[player].skin]->kartweight; + charflags = skins[players[player].skin]->flags; for (i = 0; i < LAP__MAX; i++) { @@ -2218,7 +2218,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) { UINT32 skinflags = (demo.playback) ? demo.skinlist[demo.currentskinid[player]].flags - : skins[players[player].skin].flags; + : skins[players[player].skin]->flags; fakeskin = players[player].fakeskin; kartspeed = players[player].kartspeed; @@ -5179,7 +5179,7 @@ void G_DeferedInitNew(boolean pencoremode, INT32 map, INT32 pickedchar, UINT8 ss } SetPlayerSkinByNum(consoleplayer, pickedchar); - CV_StealthSet(&cv_skin[0], skins[pickedchar].name); + CV_StealthSet(&cv_skin[0], skins[pickedchar]->name); if (color != SKINCOLOR_NONE) { diff --git a/src/g_gamedata.cpp b/src/g_gamedata.cpp index 8eca0922c..f4ada91bf 100644 --- a/src/g_gamedata.cpp +++ b/src/g_gamedata.cpp @@ -118,7 +118,7 @@ void srb2::save_ng_gamedata() for (int i = 0; i < numskins; i++) { srb2::GamedataSkinJson skin {}; - skin_t& memskin = skins[i]; + skin_t& memskin = *skins[i]; std::string name = std::string(memskin.name); skin.records.wins = memskin.records.wins; @@ -239,7 +239,7 @@ void srb2::save_ng_gamedata() } else { - newrecords.bestskin = std::string(skins[skinref.id].name); + newrecords.bestskin = std::string(skins[skinref.id]->name); } newrecords.gotemerald = cup->windata[i].got_emerald; cupdata.records.emplace_back(std::move(newrecords)); @@ -266,7 +266,7 @@ void srb2::save_ng_gamedata() } else { - newrecords.bestskin = std::string(skins[skinref.id].name); + newrecords.bestskin = std::string(skins[skinref.id]->name); } newrecords.gotemerald = unloadedcup->windata[i].got_emerald; cupdata.records.emplace_back(std::move(newrecords)); @@ -591,7 +591,7 @@ void srb2::load_ng_gamedata() if (skin != -1) { - skins[skin].records = dummyrecord; + skins[skin]->records = dummyrecord; } else if (dummyrecord.wins) { diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index a9a90fbed..8175ca81a 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4512,7 +4512,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].notfound || md2_playermodels[((skin_t*)(spr->mobj->skin))->skinnum].scale < 0.0f) HWR_DrawSprite(spr); else { @@ -4725,7 +4725,7 @@ 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]; @@ -5077,7 +5077,7 @@ static void HWR_ProjectSprite(mobj_t *thing) if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player! { - skinnum = (skin_t*)vis->mobj->skin-skins; + skinnum = ((skin_t*)vis->mobj->skin)->skinnum; } // Hide not-yet-unlocked characters in replays from other people diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 7a49edcb8..3662a310e 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -632,7 +632,7 @@ void HWR_AddPlayerModel(INT32 skin) // For skins that were added after startup if (!strnicmp(name, PLAYERMODELPREFIX, prefixlen) && (len > prefixlen)) skinname += prefixlen; - if (stricmp(skinname, skins[skin].name) == 0) + if (stricmp(skinname, skins[skin]->name) == 0) { md2_playermodels[skin].skin = skin; md2_playermodels[skin].scale = scale; @@ -1448,10 +1448,10 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) // 1. load model+texture if not already loaded // 2. draw model with correct position, rotation,... - if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY && !md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound) // Use the player MD2 list if the mobj has a skin and is using the player sprites + if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY && !md2_playermodels[((skin_t*)spr->mobj->skin)->skinnum].notfound) // 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; + md2 = &md2_playermodels[((skin_t*)spr->mobj->skin)->skinnum]; + md2->skin = ((skin_t*)spr->mobj->skin)->skinnum; } else { @@ -1525,7 +1525,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) // This thing is a player! { - skinnum = (skin_t*)spr->mobj->skin-skins; + skinnum = ((skin_t*)spr->mobj->skin)->skinnum; } // Hide not-yet-unlocked characters in replays from other people diff --git a/src/k_bot.cpp b/src/k_bot.cpp index 601cba867..45220cd99 100644 --- a/src/k_bot.cpp +++ b/src/k_bot.cpp @@ -133,8 +133,8 @@ void K_SetBot(UINT8 newplayernum, UINT8 skinnum, UINT8 difficulty, botStyle_e st // For each subsequent round of GP, K_UpdateGrandPrixBots will handle this. players[newplayernum].spectator = grandprixinfo.gp && grandprixinfo.initalize && K_BotDefaultSpectator(); - skincolornum_t color = static_cast(skins[skinnum].prefcolor); - const char *realname = skins[skinnum].realname; + skincolornum_t color = static_cast(skins[skinnum]->prefcolor); + const char *realname = skins[skinnum]->realname; if (tutorialchallenge == TUTORIALSKIP_INPROGRESS) { // The ROYGBIV Rangers diff --git a/src/k_color.c b/src/k_color.c index 4355d607a..fc256725b 100644 --- a/src/k_color.c +++ b/src/k_color.c @@ -147,7 +147,7 @@ void K_HitlagColormap(UINT8 *dest_colormap) v = K_HitlagColorValue(color); // Convert raw brightness value to an offset from the greyscale palette line - offset = (255 - v) / 8; + offset = (255 - v) / 8; dest_colormap[i] = offset; // Starts from 0, add it if greyscale moves. } @@ -163,7 +163,7 @@ static void K_IntermissionColormap(UINT8 *dest_colormap) RGBA_t color; INT32 i; - // for every colour in the palette, check its + // for every colour in the palette, check its for (i = 0; i < NUM_PALETTE_ENTRIES; i++) { color = V_GetColor(i); @@ -264,7 +264,7 @@ void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, skincolornum_t return; } - starttranscolor = (skinnum != TC_DEFAULT) ? skins[skinnum].starttranscolor : DEFAULT_STARTTRANSCOLOR; + starttranscolor = (skinnum != TC_DEFAULT) ? skins[skinnum]->starttranscolor : DEFAULT_STARTTRANSCOLOR; // Fill in the entries of the palette that are fixed for (i = 0; i < starttranscolor; i++) diff --git a/src/k_dialogue.cpp b/src/k_dialogue.cpp index 64ba42097..149129031 100644 --- a/src/k_dialogue.cpp +++ b/src/k_dialogue.cpp @@ -187,7 +187,7 @@ void Dialogue::SetSpeaker(std::string skinName, int portraitID) if (skinID >= 0 && skinID < numskins) { - const skin_t *skin = &skins[skinID]; + const skin_t *skin = skins[skinID]; const spritedef_t *sprdef = &skin->sprites[SPR2_TALK]; if (sprdef->numframes > 0) diff --git a/src/k_follower.c b/src/k_follower.c index aee769b95..50b67a6b7 100644 --- a/src/k_follower.c +++ b/src/k_follower.c @@ -273,7 +273,7 @@ UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, follower_t *follower, U if (playerskin == NULL) { // Nothing from this line down is valid if playerskin is invalid, just guess Eggman? - playerskin = &skins[0]; + playerskin = skins[0]; } playercolor = playerskin->prefcolor; @@ -424,7 +424,7 @@ void K_HandleFollower(player_t *player) if (player->followerskin < 0) // using a fallback follower color = fl->defaultcolor; else - color = K_GetEffectiveFollowerColor(player->followercolor, fl, player->skincolor, &skins[player->skin]); + color = K_GetEffectiveFollowerColor(player->followercolor, fl, player->skincolor, skins[player->skin]); if (player->follower == NULL || P_MobjWasRemoved(player->follower)) // follower doesn't exist / isn't valid { diff --git a/src/k_grandprix.c b/src/k_grandprix.c index 4f10d4e29..289f84e4c 100644 --- a/src/k_grandprix.c +++ b/src/k_grandprix.c @@ -213,7 +213,7 @@ void K_InitGrandPrixBots(void) for (j = 0; j < numplayers; j++) { player_t *p = &players[competitors[j]]; - const char *rivalname = skins[p->skin].rivals[i]; + const char *rivalname = skins[p->skin]->rivals[i]; INT32 rivalnum = R_SkinAvailable(rivalname); // Intentionally referenced before (currently dummied out) unlock check. Such a tease! @@ -792,8 +792,8 @@ void K_RetireBots(void) bot->botvars.diffincrease = 0; SetPlayerSkinByNum(i, skinnum); - bot->skincolor = skins[skinnum].prefcolor; - K_SetNameForBot(i, skins[skinnum].realname); + bot->skincolor = skins[skinnum]->prefcolor; + K_SetNameForBot(i, skins[skinnum]->realname); bot->score = 0; bot->pflags &= ~PF_NOCONTEST; diff --git a/src/k_hud.cpp b/src/k_hud.cpp index 4e6adebaa..5ea4fb53b 100644 --- a/src/k_hud.cpp +++ b/src/k_hud.cpp @@ -2508,7 +2508,7 @@ void PositionFacesInfo::draw_1p() skinflags = (demo.playback) ? demo.skinlist[demo.currentskinid[rankplayer[i]]].flags - : skins[players[rankplayer[i]].skin].flags; + : skins[players[rankplayer[i]].skin]->flags; // Flip SF_IRONMAN portraits, but only if they're transformed if (skinflags & SF_IRONMAN @@ -2525,7 +2525,7 @@ void PositionFacesInfo::draw_1p() if (players[rankplayer[i]].mo->color) { if ((skin_t*)players[rankplayer[i]].mo->skin) - workingskin = (skin_t*)players[rankplayer[i]].mo->skin - skins; + workingskin = ((skin_t*)players[rankplayer[i]].mo->skin)->skinnum; else workingskin = players[rankplayer[i]].skin; @@ -4569,7 +4569,7 @@ static void K_drawKartMinimap(void) { if (g->mo && !P_MobjWasRemoved(g->mo) && g->mo->skin) { - skin = ((skin_t*)g->mo->skin)-skins; + skin = ((skin_t*)g->mo->skin)->skinnum; workingPic = R_CanShowSkinInDemo(skin) ? faceprefix[skin][FACE_MINIMAP] : kp_unknownminimap; @@ -4646,7 +4646,7 @@ static void K_drawKartMinimap(void) } else { - skin = ((skin_t*)mobj->skin)-skins; + skin = ((skin_t*)mobj->skin)->skinnum; workingPic = R_CanShowSkinInDemo(skin) ? faceprefix[skin][FACE_MINIMAP] : kp_unknownminimap; @@ -4846,7 +4846,7 @@ static void K_drawKartMinimap(void) } else { - skin = ((skin_t*)mobj->skin)-skins; + skin = ((skin_t*)mobj->skin)->skinnum; workingPic = R_CanShowSkinInDemo(skin) ? faceprefix[skin][FACE_MINIMAP] : kp_unknownminimap; @@ -4882,7 +4882,7 @@ static void K_drawKartMinimap(void) ang = ANGLE_180 - ang; if (skin && mobj->color && !mobj->colorized // relevant to redo - && skins[skin].starttranscolor != skins[0].starttranscolor) // redoing would have an affect + && skins[skin]->starttranscolor != skins[0]->starttranscolor) // redoing would have an affect { colormap = R_GetTranslationColormap(TC_DEFAULT, static_cast(mobj->color), GTC_CACHE); } diff --git a/src/k_kart.c b/src/k_kart.c index 7cb0c8d37..f2bd48348 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2738,7 +2738,7 @@ static UINT8 K_ObjectToSkinIDForSounds(mobj_t *source) if (!source->skin) return MAXSKINS; - return ((skin_t *)source->skin)-skins; + return ((skin_t *)source->skin)->skinnum; } static void K_PlayGenericTastefulTaunt(mobj_t *source, sfxenum_t sfx_id) @@ -2825,7 +2825,7 @@ static void K_PlayGenericCombatSound(mobj_t *source, mobj_t *other, sfxenum_t sf { S_StartSound( alwaysHear ? NULL : source, - skins[skinid].soundsid[S_sfx[sfx_id].skinsound] + skins[skinid]->soundsid[S_sfx[sfx_id].skinsound] ); } @@ -8316,7 +8316,7 @@ void K_KartPlayerHUDUpdate(player_t *player) if (player->skin >= 0 && player->skin < numskins) { skin_t *playerskin; - playerskin = &skins[player->skin]; + playerskin = skins[player->skin]; playerskin->records.tumbletime++; } } @@ -8648,13 +8648,13 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) for (doubler = 0; doubler < 2; doubler++) { fixed_t heightOffset = player->mo->height + (24*player->mo->scale); - if (P_IsObjectFlipped(player->mo)) + if (P_IsObjectFlipped(player->mo)) { // This counteracts the offset added by K_FlipFromObject so it looks seamless from non-flipped. heightOffset += player->mo->height - FixedMul(player->mo->scale, player->mo->height); heightOffset *= P_MobjFlip(player->mo); // Fleep. } - + mobj_t *debtflag = P_SpawnMobj(player->mo->x + player->mo->momx, player->mo->y + player->mo->momy, player->mo->z + P_GetMobjZMovement(player->mo) + heightOffset, MT_THOK); @@ -13285,7 +13285,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player->curshield != KSHIELD_BUBBLE) { mobj_t *shield = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BUBBLESHIELD); - // MT_BUBBLESHIELD doesn't have MF_NOBLOCKMAP so we need to remove this manually. + // MT_BUBBLESHIELD doesn't have MF_NOBLOCKMAP so we need to remove this manually. // Otherwise if you roll a bubble shield while flipped, the visuals look too mismatched. shield->eflags &= ~MFE_VERTICALFLIP; P_SetScale(shield, (shield->destscale = (5*shield->destscale)>>2)); diff --git a/src/k_menudraw.c b/src/k_menudraw.c index cadb433a8..ac09774a4 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -359,7 +359,7 @@ UINT16 M_GetCvPlayerColor(UINT8 pnum) if (skin == -1) return SKINCOLOR_NONE; - return skins[skin].prefcolor; + return skins[skin]->prefcolor; } static void M_DrawMenuParty(void) @@ -392,7 +392,7 @@ static void M_DrawMenuParty(void) if (skin == -1) \ skin = 0; \ if (color == SKINCOLOR_NONE) \ - color = skins[skin].prefcolor; \ + color = skins[skin]->prefcolor; \ colormap = R_GetTranslationColormap(skin, color, GTC_MENUCACHE); \ } @@ -1618,7 +1618,7 @@ static void M_DrawCharSelectCircle(setup_player_t *p, INT16 x, INT16 y) skin = setup_chargrid[p->gridx][p->gridy].skinlist[n]; patch = faceprefix[skin][FACE_RANK]; - colormap = R_GetTranslationColormap(skin, skins[skin].prefcolor, GTC_MENUCACHE); + colormap = R_GetTranslationColormap(skin, skins[skin]->prefcolor, GTC_MENUCACHE); radius = 24<width) << FRACBITS) >> 1; @@ -1643,7 +1643,7 @@ static void M_DrawCharSelectCircle(setup_player_t *p, INT16 x, INT16 y) n = r = M_GetColorAfter(&p->colors, r, 1); } - colormap = R_GetTranslationColormap(TC_DEFAULT, (n == SKINCOLOR_NONE) ? skins[p->skin].prefcolor : n, GTC_MENUCACHE); + colormap = R_GetTranslationColormap(TC_DEFAULT, (n == SKINCOLOR_NONE) ? skins[p->skin]->prefcolor : n, GTC_MENUCACHE); diff = (numoptions - i) / 2; // only 0 when i == numoptions-1 @@ -1742,7 +1742,7 @@ static void M_DrawCharSelectCircle(setup_player_t *p, INT16 x, INT16 y) patch = W_CachePatchName(fl->icon, PU_CACHE); colormap = R_GetTranslationColormap(TC_DEFAULT, - K_GetEffectiveFollowerColor(fl->defaultcolor, fl, p->color, &skins[p->skin]), + K_GetEffectiveFollowerColor(fl->defaultcolor, fl, p->color, skins[p->skin]), GTC_MENUCACHE ); } @@ -1772,7 +1772,7 @@ static void M_DrawCharSelectCircle(setup_player_t *p, INT16 x, INT16 y) n = r = M_GetColorAfter(&p->colors, r, 1); } - col = K_GetEffectiveFollowerColor(n, &followers[p->followern], p->color, &skins[p->skin]); + col = K_GetEffectiveFollowerColor(n, &followers[p->followern], p->color, skins[p->skin]); colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE); @@ -1826,8 +1826,8 @@ boolean M_DrawCharacterSprite(INT16 x, INT16 y, INT16 skin, UINT8 spr2, UINT8 ro spriteframe_t *sprframe; patch_t *sprpatch; - spr = P_GetSkinSprite2(&skins[skin], spr2, NULL); - sprdef = &skins[skin].sprites[spr]; + spr = P_GetSkinSprite2(skins[skin], spr2, NULL); + sprdef = &skins[skin]->sprites[spr]; if (!sprdef->numframes) // No frames ?? return false; // Can't render! @@ -1842,11 +1842,11 @@ boolean M_DrawCharacterSprite(INT16 x, INT16 y, INT16 skin, UINT8 spr2, UINT8 ro addflags ^= V_FLIP; // This sprite is left/right flipped! } - if (skins[skin].highresscale != FRACUNIT) + if (skins[skin]->highresscale != FRACUNIT) { V_DrawFixedPatch(x<highresscale, addflags, sprpatch, colormap); } else @@ -1914,7 +1914,7 @@ static boolean M_DrawFollowerSprite(INT16 x, INT16 y, INT32 num, boolean charfli (p->mdepth < CSSTEP_FOLLOWERCOLORS && p->mdepth != CSSTEP_ASKCHANGES) ? fl->defaultcolor : p->followercolor, fl, p->color, - &skins[p->skin] + skins[p->skin] ); sine = FixedMul(fl->bobamp, FINESINE(((FixedMul(4 * M_TAU_FIXED, fl->bobspeed) * p->follower_timer)>>ANGLETOFINESHIFT) & FINEMASK)); colormap = R_GetTranslationColormap(TC_DEFAULT, color, GTC_MENUCACHE); @@ -1938,7 +1938,7 @@ static void M_DrawCharSelectSprite(UINT8 num, INT16 x, INT16 y, boolean charflip if (p->mdepth < CSSTEP_COLORS && p->mdepth != CSSTEP_ASKCHANGES) { - color = skins[p->skin].prefcolor; + color = skins[p->skin]->prefcolor; } else { @@ -1947,7 +1947,7 @@ static void M_DrawCharSelectSprite(UINT8 num, INT16 x, INT16 y, boolean charflip if (color == SKINCOLOR_NONE) { - color = skins[p->skin].prefcolor; + color = skins[p->skin]->prefcolor; } colormap = R_GetTranslationColormap(p->skin, color, GTC_MENUCACHE); @@ -2130,8 +2130,8 @@ static void M_DrawCharSelectPreview(UINT8 num) && setup_chargrid[p->gridx][p->gridy].skinlist[p->clonenum] < numskins) { V_DrawThinString(x-3, y+12, 0, - skins[setup_chargrid[p->gridx][p->gridy].skinlist[p->clonenum]].name); - randomskin = (skins[setup_chargrid[p->gridx][p->gridy].skinlist[p->clonenum]].flags & SF_IRONMAN); + skins[setup_chargrid[p->gridx][p->gridy].skinlist[p->clonenum]]->name); + randomskin = (skins[setup_chargrid[p->gridx][p->gridy].skinlist[p->clonenum]]->flags & SF_IRONMAN); } else { @@ -2283,7 +2283,7 @@ static void M_DrawCharSelectCursor(UINT8 num) { if (p->skin >= 0) { - color = skins[p->skin].prefcolor; + color = skins[p->skin]->prefcolor; } else { @@ -2347,7 +2347,7 @@ void M_DrawProfileCard(INT32 x, INT32 y, boolean greyedout, profile_t *p) { if (skinnum >= 0) { - truecol = skins[skinnum].prefcolor; + truecol = skins[skinnum]->prefcolor; } else { @@ -2388,7 +2388,7 @@ void M_DrawProfileCard(INT32 x, INT32 y, boolean greyedout, profile_t *p) { if (M_DrawFollowerSprite(x-22 - 16, y+119, 0, false, 0, 0, sp)) { - UINT16 col = K_GetEffectiveFollowerColor(sp->followercolor, &followers[sp->followern], sp->color, &skins[sp->skin]); + UINT16 col = K_GetEffectiveFollowerColor(sp->followercolor, &followers[sp->followern], sp->color, skins[sp->skin]); patch_t *ico = W_CachePatchName(followers[sp->followern].icon, PU_CACHE); UINT8 *fcolormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE); V_DrawMappedPatch(x+14+18, y+66, 0, ico, fcolormap); @@ -2416,7 +2416,7 @@ void M_DrawProfileCard(INT32 x, INT32 y, boolean greyedout, profile_t *p) p->followercolor, &followers[fln], p->color, - &skins[skinnum] + skins[skinnum] ); UINT8 *fcolormap = R_GetTranslationColormap( (K_FollowerUsable(fln) ? TC_DEFAULT : TC_BLINK), @@ -2510,14 +2510,14 @@ void M_DrawCharacterSelect(void) // Draw the icons now for (i = 0; i < 9; i++) { - if ((forceskin == true) && (i != skins[cv_forceskin.value].kartspeed-1)) + if ((forceskin == true) && (i != skins[cv_forceskin.value]->kartspeed-1)) continue; for (j = 0; j < 9; j++) { if (forceskin == true) { - if (j != skins[cv_forceskin.value].kartweight-1) + if (j != skins[cv_forceskin.value]->kartweight-1) continue; skin = cv_forceskin.value; } @@ -2545,7 +2545,7 @@ void M_DrawCharacterSelect(void) if (k == setup_numplayers) colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_GREY, GTC_MENUCACHE); else - colormap = R_GetTranslationColormap(skin, skins[skin].prefcolor, GTC_MENUCACHE); + colormap = R_GetTranslationColormap(skin, skins[skin]->prefcolor, GTC_MENUCACHE); V_DrawMappedPatch(basex + 82 + (i*16) + quadx, 22 + (j*16) + quady, 0, faceprefix[skin][FACE_RANK], colormap); @@ -3063,7 +3063,7 @@ fixed_t M_DrawCupWinData(INT32 rankx, INT32 ranky, cupheader_t *cup, UINT8 diffi { UINT8 skin = windata->best_skin.id; - colormap = R_GetTranslationColormap(skin, skins[skin].prefcolor, GTC_MENUCACHE); + colormap = R_GetTranslationColormap(skin, skins[skin]->prefcolor, GTC_MENUCACHE); charPat = faceprefix[skin][FACE_MINIMAP]; } @@ -6648,7 +6648,7 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, UINT8 *flash INT32 skin = M_UnlockableSkinNum(ref); if (skin != -1) { - colormap = R_GetTranslationColormap(skin, skins[skin].prefcolor, GTC_MENUCACHE); + colormap = R_GetTranslationColormap(skin, skins[skin]->prefcolor, GTC_MENUCACHE); pat = faceprefix[skin][(ref->majorunlock) ? FACE_WANTED : FACE_RANK]; } break; @@ -6659,7 +6659,7 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, UINT8 *flash if (skin != -1) { INT32 psk = R_SkinAvailableEx(cv_skin[0].string, false); - UINT16 col = K_GetEffectiveFollowerColor(followers[skin].defaultcolor, &followers[skin], cv_playercolor[0].value, (psk != -1) ? &skins[psk] : &skins[0]); + UINT16 col = K_GetEffectiveFollowerColor(followers[skin].defaultcolor, &followers[skin], cv_playercolor[0].value, (psk != -1) ? skins[psk] : skins[0]); colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE); pat = W_CachePatchName(followers[skin].icon, PU_CACHE); } @@ -6846,7 +6846,7 @@ void M_DrawCharacterIconAndEngine(INT32 x, INT32 y, UINT8 skin, UINT8 *colormap, INT32 s, w; - if (skins[baseskin].flags & SF_IRONMAN) + if (skins[baseskin]->flags & SF_IRONMAN) { // this is the last thing i will do for rr pre-launhc ~toast 150424 // quoth tyron: "stat block rave holy shit" @@ -6879,8 +6879,8 @@ void M_DrawCharacterIconAndEngine(INT32 x, INT32 y, UINT8 skin, UINT8 *colormap, { // The following is a partial duplication of R_GetEngineClass - s = (skins[skin].kartspeed - 1)/3; - w = (skins[skin].kartweight - 1)/3; + s = (skins[skin]->kartspeed - 1)/3; + w = (skins[skin]->kartweight - 1)/3; #define LOCKSTAT(stat) \ if (stat < 0) { stat = 0; } \ @@ -6943,19 +6943,19 @@ static void M_DrawChallengePreview(INT32 x, INT32 y) // Draw our character! if (skin != -1) { - colormap = R_GetTranslationColormap(skin, skins[skin].prefcolor, GTC_MENUCACHE); + colormap = R_GetTranslationColormap(skin, skins[skin]->prefcolor, GTC_MENUCACHE); M_DrawCharacterSprite(x, y, skin, SPR2_STIN, 7, 0, 0, colormap); for (i = 0; i < skin; i++) { if (!R_SkinUsable(-1, i, false)) continue; - if (skins[i].kartspeed != skins[skin].kartspeed) + if (skins[i]->kartspeed != skins[skin]->kartspeed) continue; - if (skins[i].kartweight != skins[skin].kartweight) + if (skins[i]->kartweight != skins[skin]->kartweight) continue; - colormap = R_GetTranslationColormap(i, skins[i].prefcolor, GTC_MENUCACHE); + colormap = R_GetTranslationColormap(i, skins[i]->prefcolor, GTC_MENUCACHE); break; } @@ -6977,7 +6977,7 @@ static void M_DrawChallengePreview(INT32 x, INT32 y) // Draw follower next to them if (fskin != -1) { - UINT16 col = K_GetEffectiveFollowerColor(followers[fskin].defaultcolor, &followers[fskin], cv_playercolor[0].value, &skins[skin]); + UINT16 col = K_GetEffectiveFollowerColor(followers[fskin].defaultcolor, &followers[fskin], cv_playercolor[0].value, skins[skin]); colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE); M_DrawFollowerSprite(x - 16, y, fskin, false, 0, colormap, NULL); @@ -8366,14 +8366,14 @@ static void M_DrawStatsChars(void) } { - UINT8 *colormap = R_GetTranslationColormap(skin, skins[skin].prefcolor, GTC_MENUCACHE); + UINT8 *colormap = R_GetTranslationColormap(skin, skins[skin]->prefcolor, GTC_MENUCACHE); M_DrawCharacterIconAndEngine(24, y, skin, colormap, skin); } - V_DrawThinString(24+32+2, y+3, 0, skins[skin].realname); + V_DrawThinString(24+32+2, y+3, 0, skins[skin]->realname); - V_DrawRightAlignedThinString(BASEVIDWIDTH/2 + 30, y+3, 0, va("%d/%d", skins[skin].records.wins, skins[skin].records.rounds)); + V_DrawRightAlignedThinString(BASEVIDWIDTH/2 + 30, y+3, 0, va("%d/%d", skins[skin]->records.wins, skins[skin]->records.rounds)); y += STATSSTEP; @@ -8728,7 +8728,7 @@ static void M_DrawWrongPlayer(UINT8 i) if (wrongpl.skin >= numskins) return; - UINT8 *colormap = R_GetTranslationColormap(wrongpl.skin, skins[wrongpl.skin].prefcolor, GTC_MENUCACHE); + UINT8 *colormap = R_GetTranslationColormap(wrongpl.skin, skins[wrongpl.skin]->prefcolor, GTC_MENUCACHE); M_DrawCharacterSprite( wrongpl.across, diff --git a/src/k_podium.cpp b/src/k_podium.cpp index 29dd5ae4a..fc4df39d0 100644 --- a/src/k_podium.cpp +++ b/src/k_podium.cpp @@ -269,11 +269,11 @@ void podiumData_s::Init(void) // but not this close to release if (rank.position > RANK_NEUTRAL_POSITION || grade < GRADE_C) { - gradeVoice = skins[rank.skin].soundsid[S_sfx[sfx_klose].skinsound]; + gradeVoice = skins[rank.skin]->soundsid[S_sfx[sfx_klose].skinsound]; } else { - gradeVoice = skins[rank.skin].soundsid[S_sfx[sfx_kwin].skinsound]; + gradeVoice = skins[rank.skin]->soundsid[S_sfx[sfx_kwin].skinsound]; } } diff --git a/src/k_tally.cpp b/src/k_tally.cpp index 4e8d0cc74..db9f4c6e9 100644 --- a/src/k_tally.cpp +++ b/src/k_tally.cpp @@ -426,7 +426,7 @@ void level_tally_t::Init(player_t *player) { snprintf( header, sizeof header, - "%s", R_CanShowSkinInDemo(player->skin) ? skins[player->skin].realname : "???" + "%s", R_CanShowSkinInDemo(player->skin) ? skins[player->skin]->realname : "???" ); } @@ -524,11 +524,11 @@ void level_tally_t::Init(player_t *player) ; else if (rank < GRADE_C) { - gradeVoice = skins[skinid].soundsid[S_sfx[sfx_klose].skinsound]; + gradeVoice = skins[skinid]->soundsid[S_sfx[sfx_klose].skinsound]; } else { - gradeVoice = skins[skinid].soundsid[S_sfx[sfx_kwin].skinsound]; + gradeVoice = skins[skinid]->soundsid[S_sfx[sfx_kwin].skinsound]; } } diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 791348a27..5e6bfc42e 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -431,9 +431,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); @@ -461,7 +461,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<flip & (1<sprinfo[j], rot); LUA_PushUserdata(L, rotsprite, META_PATCH); lua_pushboolean(L, false); lua_pushboolean(L, true); @@ -604,7 +604,7 @@ static int libd_drawOnMinimap(lua_State *L) if (!lua_isnoneornil(L, 5)) colormap = *((UINT8 **)luaL_checkudata(L, 5, META_COLORMAP)); centered = lua_optboolean(L, 6); - + // Draw the HUD only when playing in a level. // hu_stuff needs this, unlike st_stuff. if (gamestate != GS_LEVEL) @@ -612,17 +612,17 @@ static int libd_drawOnMinimap(lua_State *L) if (R_GetViewNumber() != 0) return 0; - + AutomapPic = minimapinfo.minimap_pic; if (!AutomapPic) { return 0; // no pic, just get outta here } - + // Handle offsets and stuff. mm_x = MINI_X; mm_y = MINI_Y - SHORT(AutomapPic->topoffset); - + if (encoremode) { mm_x += SHORT(AutomapPic->leftoffset); diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 158909815..d673627b5 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -725,7 +725,7 @@ static int mobj_set(lua_State *L) { if (demo.playback) skin = demo.skinlist[skin].mapping; - mo->skin = &skins[skin]; + mo->skin = skins[skin]; } return 0; diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index 534249ad9..03b446234 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -93,7 +93,7 @@ static int skin_get(lua_State *L) case skin_kartweight: lua_pushinteger(L, skin->kartweight); break; - // + // case skin_followitem: lua_pushinteger(L, skin->followitem); break; @@ -137,7 +137,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; } @@ -156,14 +156,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; } @@ -183,7 +183,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; } @@ -200,7 +200,7 @@ static int lib_getSkin(lua_State *L) i = R_SkinAvailableEx(field, false); if (i != -1) { - LUA_PushUserdata(L, &skins[i], META_SKIN); + LUA_PushUserdata(L, skins[i], META_SKIN); return 1; } diff --git a/src/m_cond.c b/src/m_cond.c index 6399f0eac..bab0656ab 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -671,7 +671,7 @@ void M_ClearStats(void) for (i = 0; i < numskins; i++) { - memset(&skins[i].records, 0, sizeof(skins[i].records)); + memset(&skins[i]->records, 0, sizeof(skins[i]->records)); } unloaded_skin_t *unloadedskin, *nextunloadedskin = NULL; @@ -1553,7 +1553,7 @@ boolean M_CheckCondition(condition_t *cn, player_t *player) if (cn->requirement < 0) return false; - return (skins[cn->requirement].records.wins >= (UINT32)cn->extrainfo1); + return (skins[cn->requirement]->records.wins >= (UINT32)cn->extrainfo1); case UC_ALLCUPRECORDS: { @@ -1765,9 +1765,9 @@ boolean M_CheckCondition(condition_t *cn, player_t *player) return (player->roundconditions.switched_skin == false && player->skin < numskins && R_GetEngineClass( - skins[player->skin].kartspeed, - skins[player->skin].kartweight, - skins[player->skin].flags + skins[player->skin]->kartspeed, + skins[player->skin]->kartweight, + skins[player->skin]->flags ) == (unsigned)cn->requirement); case UCRP_HASFOLLOWER: return (cn->requirement != -1 && player->followerskin == cn->requirement); @@ -2184,7 +2184,7 @@ static const char *M_GetConditionCharacter(INT32 skin, boolean directlyrequires) for (j = 0; j < SKINRIVALS; j++) { - const char *rivalname = skins[i].rivals[j]; + const char *rivalname = skins[i]->rivals[j]; INT32 rivalnum = R_SkinAvailableEx(rivalname, false); if (rivalnum != skin) @@ -2207,7 +2207,7 @@ static const char *M_GetConditionCharacter(INT32 skin, boolean directlyrequires) } return (permitname) - ? skins[skin].realname + ? skins[skin]->realname : "???"; } @@ -2346,7 +2346,7 @@ static const char *M_GetConditionString(condition_t *cn) case UC_CHARACTERWINS: { - if (cn->requirement < 0 || !skins[cn->requirement].realname[0]) + if (cn->requirement < 0 || !skins[cn->requirement]->realname[0]) return va("INVALID CHAR CONDITION \"%d:%d:%d\"", cn->type, cn->requirement, cn->extrainfo1); work = M_GetConditionCharacter(cn->requirement, true); return va("win %d Round%s as %s", @@ -2667,7 +2667,7 @@ static const char *M_GetConditionString(condition_t *cn) Z_Free(title); return work; case UCRP_ISCHARACTER: - if (cn->requirement < 0 || !skins[cn->requirement].realname[0]) + if (cn->requirement < 0 || !skins[cn->requirement]->realname[0]) return va("INVALID CHAR CONDITION \"%d:%d\"", cn->type, cn->requirement); work = M_GetConditionCharacter(cn->requirement, true); return va("as %s", work); @@ -2800,7 +2800,7 @@ static const char *M_GetConditionString(condition_t *cn) case UCRP_MAKERETIRE: { - if (cn->requirement < 0 || !skins[cn->requirement].realname[0]) + if (cn->requirement < 0 || !skins[cn->requirement]->realname[0]) return va("INVALID CHAR CONDITION \"%d:%d\"", cn->type, cn->requirement); work = M_GetConditionCharacter(cn->requirement, false); diff --git a/src/menus/extras-challenges.c b/src/menus/extras-challenges.c index 905daeba9..828605c38 100644 --- a/src/menus/extras-challenges.c +++ b/src/menus/extras-challenges.c @@ -752,7 +752,7 @@ void M_ChallengesTick(void) INT32 skin = M_UnlockableSkinNum(ref); if (skin != -1) { - bombcolor = skins[skin].prefcolor; + bombcolor = skins[skin]->prefcolor; } break; } @@ -764,7 +764,7 @@ void M_ChallengesTick(void) INT32 psk = R_SkinAvailableEx(cv_skin[0].string, false); if (psk == -1) psk = 0; - bombcolor = K_GetEffectiveFollowerColor(followers[fskin].defaultcolor, &followers[fskin], cv_playercolor[0].value, &skins[psk]); + bombcolor = K_GetEffectiveFollowerColor(followers[fskin].defaultcolor, &followers[fskin], cv_playercolor[0].value, skins[psk]); } break; } diff --git a/src/menus/extras-statistics.cpp b/src/menus/extras-statistics.cpp index 5ae8832f0..6c80818fd 100644 --- a/src/menus/extras-statistics.cpp +++ b/src/menus/extras-statistics.cpp @@ -131,16 +131,16 @@ static void M_StatisticsChars(void) statisticsmenu.maplist[statisticsmenu.nummaps++] = i; - if (skins[i].records.wins == 0) + if (skins[i]->records.wins == 0) continue; // The following is a partial duplication of R_GetEngineClass { - if (skins[i].flags & SF_IRONMAN) + if (skins[i]->flags & SF_IRONMAN) continue; // does not add to any engine class - INT32 s = (skins[i].kartspeed - 1); - INT32 w = (skins[i].kartweight - 1); + INT32 s = (skins[i]->kartspeed - 1); + INT32 w = (skins[i]->kartweight - 1); #define LOCKSTAT(stat) \ if (stat < 0) { continue; } \ @@ -150,12 +150,12 @@ static void M_StatisticsChars(void) #undef LOCKSTAT if ( - statisticsmenu.statgridplayed[s][w] > skins[i].records.wins - && (UINT32_MAX - statisticsmenu.statgridplayed[s][w]) < skins[i].records.wins + statisticsmenu.statgridplayed[s][w] > skins[i]->records.wins + && (UINT32_MAX - statisticsmenu.statgridplayed[s][w]) < skins[i]->records.wins ) continue; // overflow protection - statisticsmenu.statgridplayed[s][w] += skins[i].records.wins; + statisticsmenu.statgridplayed[s][w] += skins[i]->records.wins; if (beststat >= statisticsmenu.statgridplayed[s][w]) continue; @@ -170,9 +170,9 @@ static void M_StatisticsChars(void) statisticsmenu.maplist, statisticsmenu.maplist + statisticsmenu.nummaps, [](UINT16 a, UINT16 b) { - if (skins[a].records.rounds > skins[b].records.rounds) + if (skins[a]->records.rounds > skins[b]->records.rounds) return true; - if (skins[a].records.rounds != skins[b].records.rounds) + if (skins[a]->records.rounds != skins[b]->records.rounds) return false; // Stable for skin ID return (a < b); @@ -260,7 +260,7 @@ static void M_StatisticsPageInit(void) M_StatisticsChars(); break; } - + case statisticspage_gp: { M_StatisticsGP(); diff --git a/src/menus/main-goner.cpp b/src/menus/main-goner.cpp index 52c936bd6..83c8b95a6 100644 --- a/src/menus/main-goner.cpp +++ b/src/menus/main-goner.cpp @@ -46,7 +46,7 @@ menuitem_t MAIN_Goner[] = {.routine = M_VideoOptions}, 0, 0}, {IT_STRING | IT_CALL, "SOUND OPTIONS", - "CALIBRATE AURAL DATASTREAM.", NULL, + "CALIBRATE AURAL DATASTREAM.", NULL, {.routine = M_SoundOptions}, 0, 0}, {IT_STRING | IT_CALL, "PROFILE SETUP", @@ -113,7 +113,7 @@ public: return sfx_ktalk; return skins[ skinID ] - .soundsid[ S_sfx[sfx_ktalk].skinsound ]; + ->soundsid[ S_sfx[sfx_ktalk].skinsound ]; }; int GetSkinID(void) @@ -1186,7 +1186,7 @@ static void M_GonerDrawer(void) { line = line .xy(-16, -2) - .colormap(skinID, static_cast(skins[skinID].prefcolor)); + .colormap(skinID, static_cast(skins[skinID]->prefcolor)); if (gamedata->gonerlevel > GDGONER_VIDEO) line.patch(faceprefix[skinID][FACE_MINIMAP]); else diff --git a/src/menus/play-char-select.c b/src/menus/play-char-select.c index c6265d422..92e00bd9b 100644 --- a/src/menus/play-char-select.c +++ b/src/menus/play-char-select.c @@ -235,12 +235,12 @@ static void M_SetupProfileGridPos(setup_player_t *p) if (!R_SkinUsable(g_localplayers[0], i, false)) { - i = GetSkinNumClosestToStats(skins[i].kartspeed, skins[i].kartweight, skins[i].flags, false); + i = GetSkinNumClosestToStats(skins[i]->kartspeed, skins[i]->kartweight, skins[i]->flags, false); } // Now position the grid for skin - p->gridx = skins[i].kartspeed-1; - p->gridy = skins[i].kartweight-1; + p->gridx = skins[i]->kartspeed-1; + p->gridy = skins[i]->kartweight-1; // Now this put our cursor on the good alt while (alt < setup_chargrid[p->gridx][p->gridy].numskins && setup_chargrid[p->gridx][p->gridy].skinlist[alt] != i) @@ -253,7 +253,7 @@ static void M_SetupProfileGridPos(setup_player_t *p) { p->color = SKINCOLOR_NONE; } - + } static void M_SetupMidGameGridPos(setup_player_t *p, UINT8 num) @@ -273,8 +273,8 @@ static void M_SetupMidGameGridPos(setup_player_t *p, UINT8 num) p->followern = -1; // Now position the grid for skin - p->gridx = skins[i].kartspeed-1; - p->gridy = skins[i].kartweight-1; + p->gridx = skins[i]->kartspeed-1; + p->gridy = skins[i]->kartweight-1; // Now this put our cursor on the good alt while (alt < setup_chargrid[p->gridx][p->gridy].numskins && setup_chargrid[p->gridx][p->gridy].skinlist[alt] != i) @@ -347,8 +347,8 @@ void M_CharacterSelectInit(void) for (i = 0; i < numskins; i++) { - UINT8 x = skins[i].kartspeed-1; - UINT8 y = skins[i].kartweight-1; + UINT8 x = skins[i]->kartspeed-1; + UINT8 y = skins[i]->kartweight-1; if (!R_SkinUsable(g_localplayers[0], i, false)) continue; @@ -778,7 +778,7 @@ static void M_HandleBeginningFollowers(setup_player_t *p) static void M_HandleBeginningColorsOrFollowers(setup_player_t *p) { if (p->skin != -1) - S_StartSound(NULL, skins[p->skin].soundsid[S_sfx[sfx_kattk1].skinsound]); + S_StartSound(NULL, skins[p->skin]->soundsid[S_sfx[sfx_kattk1].skinsound]); if (M_HandleBeginningColors(p)) S_StartSound(NULL, sfx_s3k63); else @@ -851,8 +851,8 @@ static boolean M_HandleCharacterGrid(setup_player_t *p, UINT8 num) { if (forceskin) { - if ((p->gridx != skins[cv_forceskin.value].kartspeed-1) - || (p->gridy != skins[cv_forceskin.value].kartweight-1)) + if ((p->gridx != skins[cv_forceskin.value]->kartspeed-1) + || (p->gridy != skins[cv_forceskin.value]->kartweight-1)) { S_StartSound(NULL, sfx_s3k7b); //sfx_s3kb2 } @@ -1332,8 +1332,8 @@ boolean M_CharacterSelectHandler(INT32 choice) // Just makes it easier to access later if (forceskin) { - if (p->gridx != skins[cv_forceskin.value].kartspeed-1 - || p->gridy != skins[cv_forceskin.value].kartweight-1) + if (p->gridx != skins[cv_forceskin.value]->kartspeed-1 + || p->gridy != skins[cv_forceskin.value]->kartweight-1) p->skin = -1; else p->skin = cv_forceskin.value; @@ -1386,7 +1386,7 @@ static void M_MPConfirmCharacterSelection(void) // finally, call the skin[x] console command. // This will call SendNameAndColor which will synch everything we sent here and apply the changes! - CV_StealthSet(&cv_skin[i], skins[setup_player[i].skin].name); + CV_StealthSet(&cv_skin[i], skins[setup_player[i].skin]->name); // ...actually, let's do this last - Skin_OnChange has some return-early occasions // follower color @@ -1440,7 +1440,7 @@ void M_CharacterSelectTick(void) if (optionsmenu.profile) { // save player - strcpy(optionsmenu.profile->skinname, skins[setup_player[0].skin].name); + strcpy(optionsmenu.profile->skinname, skins[setup_player[0].skin]->name); optionsmenu.profile->color = setup_player[0].color; // save follower @@ -1458,7 +1458,7 @@ void M_CharacterSelectTick(void) { for (i = 0; i < setup_numplayers; i++) { - CV_StealthSet(&cv_skin[i], skins[setup_player[i].skin].name); + CV_StealthSet(&cv_skin[i], skins[setup_player[i].skin]->name); CV_StealthSetValue(&cv_playercolor[i], setup_player[i].color); if (setup_player[i].followern < 0) diff --git a/src/menus/transient/cup-select.c b/src/menus/transient/cup-select.c index 8fa830094..b660cd674 100644 --- a/src/menus/transient/cup-select.c +++ b/src/menus/transient/cup-select.c @@ -119,7 +119,7 @@ static void M_StartCup(UINT8 entry) // finally, call the skin[x] console command. // This will call SendNameAndColor which will synch everything we sent here and apply the changes! - CV_StealthSet(&cv_skin[0], skins[savedata.skin].name); + CV_StealthSet(&cv_skin[0], skins[savedata.skin]->name); // ...actually, let's do this last - Skin_OnChange has some return-early occasions // follower color diff --git a/src/objects/destroyed-kart.cpp b/src/objects/destroyed-kart.cpp index c6a5a0946..069fe61c2 100644 --- a/src/objects/destroyed-kart.cpp +++ b/src/objects/destroyed-kart.cpp @@ -317,11 +317,11 @@ struct Kart : Mobj Mobj* p = player(); bool pValid = Mobj::valid(p) && p->player; - bool hasCustomHusk = pValid && skins[p->player->skin].sprites[SPR2_DKRT].numframes; + bool hasCustomHusk = pValid && skins[p->player->skin]->sprites[SPR2_DKRT].numframes; if(hasCustomHusk) { - skin = (void*)(&skins[p->player->skin]); + skin = (void*)(skins[p->player->skin]); frame = 0; } @@ -347,7 +347,7 @@ struct Kart : Mobj if(pValid) { - if((skins[p->player->skin].flags & SF_BADNIK)) + if((skins[p->player->skin]->flags & SF_BADNIK)) { P_SpawnBadnikExplosion(p); p->spritescale({2*FRACUNIT, 2*FRACUNIT}); diff --git a/src/objects/ring-shooter.c b/src/objects/ring-shooter.c index f3180fbd3..7d337b280 100644 --- a/src/objects/ring-shooter.c +++ b/src/objects/ring-shooter.c @@ -233,7 +233,7 @@ static void RingShooterCountdown(mobj_t *mo) if (playeringame[rs_base_playerface(mo)] == true) { player_t *player = &players[ rs_base_playerid(mo) ]; - part->skin = &skins[player->skin]; + part->skin = skins[player->skin]; } } @@ -779,9 +779,9 @@ void Obj_UpdateRingShooterFace(mobj_t *part) // it's a good idea to set the actor's skin *before* it uses this action, // but just in case, if it doesn't have the player's skin, set its skin then call the state again to get the correct sprite - if (part->skin != &skins[player->skin]) + if (part->skin != skins[player->skin]) { - part->skin = &skins[player->skin]; + part->skin = skins[player->skin]; P_SetMobjState(part, (statenum_t)(part->state - states)); return; } diff --git a/src/objects/ufo.c b/src/objects/ufo.c index 1b6bea5af..68476fe64 100644 --- a/src/objects/ufo.c +++ b/src/objects/ufo.c @@ -924,7 +924,7 @@ boolean Obj_SpecialUFODamage(mobj_t *ufo, mobj_t *inflictor, mobj_t *source, UIN { UINT32 skinflags = (demo.playback) ? demo.skinlist[demo.currentskinid[(source->player-players)]].flags - : skins[source->player->skin].flags; + : skins[source->player->skin]->flags; if (skinflags & SF_IRONMAN) SetRandomFakePlayerSkin(source->player, true, false); } diff --git a/src/p_inter.c b/src/p_inter.c index 1c696327a..a399c8681 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -643,7 +643,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) toucher->flags |= MF_NOGRAVITY; toucher->momz = (8*toucher->scale) * P_MobjFlip(toucher); toucher->player->carry = CR_TRAPBUBBLE; - P_SetTarget(&toucher->tracer, special); //use tracer to acces the object + P_SetTarget(&toucher->tracer, special); //use tracer to acces the object // Snap to the unfortunate player and quit moving laterally, or we can end up quite far away special->momx = 0; @@ -2576,7 +2576,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, { player->mo->health--; } - + } if (modeattacking & ATTACKING_SPB) @@ -2610,11 +2610,11 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, { UINT32 skinflags = (demo.playback) ? demo.skinlist[demo.currentskinid[(player-players)]].flags - : skins[player->skin].flags; + : skins[player->skin]->flags; if (skinflags & SF_IRONMAN) { - player->mo->skin = &skins[player->skin]; + player->mo->skin = skins[player->skin]; player->charflags = skinflags; K_SpawnMagicianParticles(player->mo, 5); S_StartSound(player->mo, sfx_slip); @@ -3234,7 +3234,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da UINT32 hurtskinflags = (demo.playback) ? demo.skinlist[demo.currentskinid[(player-players)]].flags - : skins[player->skin].flags; + : skins[player->skin]->flags; if (hurtskinflags & SF_IRONMAN) { if (gametyperules & GTR_BUMPERS) @@ -3249,11 +3249,11 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da { UINT32 skinflags = (demo.playback) ? demo.skinlist[demo.currentskinid[(player-players)]].flags - : skins[player->skin].flags; + : skins[player->skin]->flags; if (skinflags & SF_IRONMAN) { - player->mo->skin = &skins[player->skin]; + player->mo->skin = skins[player->skin]; player->charflags = skinflags; K_SpawnMagicianParticles(player->mo, 5); } diff --git a/src/p_mobj.c b/src/p_mobj.c index 4fe37026e..8c721ef5a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8351,7 +8351,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z + mobj->target->height/2); // Taken from K_FlipFromObject. We just want to flip the visual according to its target, but that's it. mobj->eflags = (mobj->eflags & ~MFE_VERTICALFLIP)|(mobj->target->eflags & MFE_VERTICALFLIP); - + break; } case MT_BUBBLESHIELD: @@ -8457,7 +8457,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->extravalue2 = mobj->target->player->bubbleblowup; P_SetScale(mobj, (mobj->destscale = scale)); - + // For some weird reason, the Bubble Shield is the exception flip-wise, it has the offset baked into the sprite. // So instead of simply flipping the object, we have to do a position offset. fixed_t positionOffset = 0; @@ -8881,7 +8881,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) UINT8 pnum = (newplayer-players); UINT32 skinflags = (demo.playback) ? demo.skinlist[demo.currentskinid[pnum]].flags - : skins[newplayer->skin].flags; + : skins[newplayer->skin]->flags; if (skinflags & SF_IRONMAN) { @@ -8932,15 +8932,15 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (newplayer != NULL) { - cur->skin = &skins[newplayer->skin]; + cur->skin = skins[newplayer->skin]; cur->color = newplayer->skincolor; - + // Even if we didn't have the Perfect Sign to consider, // it's still necessary to refresh SPR2 on skin changes. P_SetMobjState(cur, (newperfect == true) ? S_KART_SIGL : S_KART_SIGN); if (cv_shittysigns.value && cur->state != &states[S_KART_SIGL]) - cur->sprite2 = P_GetSkinSprite2(&skins[newplayer->skin], SPR2_SSIG, NULL);; + cur->sprite2 = P_GetSkinSprite2(skins[newplayer->skin], SPR2_SSIG, NULL);; } } else if (cur->state == &states[S_SIGN_ERROR]) @@ -9886,7 +9886,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) { return false; } - + break; } @@ -12102,7 +12102,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; @@ -12113,7 +12113,7 @@ void P_SpawnPlayer(INT32 playernum) p->realtime = leveltime; } - p->followitem = skins[p->skin].followitem; + p->followitem = skins[p->skin]->followitem; if (p->jointime <= 1 || leveltime <= 1) { @@ -13685,7 +13685,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj) if (!playeringame[i] || players[i].spectator == true) continue; - if (strcmp(skins[players[i].skin].name, "sakura") == 0) + if (strcmp(skins[players[i].skin]->name, "sakura") == 0) { state = mobj->info->spawnstate; break; diff --git a/src/p_saveg.c b/src/p_saveg.c index 03ef165a1..1c8936b1e 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -105,7 +105,7 @@ static inline void P_ArchivePlayer(savebuffer_t *save) if (skin > numskins) skin = 0; - WRITESTRINGN(save->p, skins[skin].name, SKINNAMESIZE); + WRITESTRINGN(save->p, skins[skin]->name, SKINNAMESIZE); if (player->followerskin < 0 || player->followerskin >= numfollowers) WRITESTRINGN(save->p, "None", SKINNAMESIZE); @@ -130,7 +130,7 @@ static inline void P_ArchivePlayer(savebuffer_t *save) if (skin > numskins) skin = 0; - WRITESTRINGN(save->p, skins[skin].name, SKINNAMESIZE); + WRITESTRINGN(save->p, skins[skin]->name, SKINNAMESIZE); WRITEUINT8(save->p, players[i].botvars.difficulty); WRITEUINT8(save->p, (UINT8)players[i].botvars.rival); @@ -183,7 +183,7 @@ static boolean P_UnArchivePlayer(savebuffer_t *save) { // It is not worth destroying an otherwise good savedata over extra added skins. // Let's just say they didn't show up to the rematch, so some Eggrobos subbed in. - CONS_Alert(CONS_WARNING, "P_UnArchivePlayer: Bot's character \"%s\" was not loaded, replacing with default \"%s\".\n", skinname, skins[defaultbotskin].name); + CONS_Alert(CONS_WARNING, "P_UnArchivePlayer: Bot's character \"%s\" was not loaded, replacing with default \"%s\".\n", skinname, skins[defaultbotskin]->name); skin = defaultbotskin; } @@ -3361,7 +3361,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 - skins)); + WRITEUINT8(save->p, (UINT8)((skin_t *)mobj->skin)->skinnum); if (diff2 & MD2_COLOR) WRITEUINT16(save->p, mobj->color); if (diff2 & MD2_EXTVAL1) @@ -4635,7 +4635,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[READUINT8(save->p)]; if (diff2 & MD2_COLOR) mobj->color = READUINT16(save->p); if (diff2 & MD2_EXTVAL1) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 06642755a..433450c7b 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -7882,7 +7882,7 @@ static void P_LoadRecordGhosts(void) if (allGhosts) { for (i = 0; i < numskins; ++i) - add_ghosts(fmt::format("{}-{}{}", gpath, skins[i].name, modeprefix), allGhosts); + add_ghosts(fmt::format("{}-{}{}", gpath, skins[i]->name, modeprefix), allGhosts); } if (sameGhosts) @@ -7890,7 +7890,7 @@ static void P_LoadRecordGhosts(void) INT32 skin = R_SkinAvailableEx(cv_skin[0].string, false); if (skin < 0 || !R_SkinUsable(-1, skin, false)) skin = 0; // use default skin - add_ghosts(fmt::format("{}-{}{}", gpath, skins[skin].name, modeprefix), sameGhosts); + add_ghosts(fmt::format("{}-{}{}", gpath, skins[skin]->name, modeprefix), sameGhosts); } // Guest ghost @@ -8026,7 +8026,7 @@ static void P_InitPlayers(void) if (skin != -1) { SetPlayerSkinByNum(i, skin); - players[i].skincolor = skins[skin].prefcolor; + players[i].skincolor = skins[skin]->prefcolor; players[i].followerskin = follower; if (follower != -1) diff --git a/src/p_spec.c b/src/p_spec.c index a499ae7bc..ad65a109d 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1586,7 +1586,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller return false; if (!triggerline->stringargs[0]) return false; - 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 false; break; case 334: // object dye @@ -2015,7 +2015,7 @@ static void K_HandleLapIncrement(player_t *player) { UINT32 skinflags = (demo.playback) ? demo.skinlist[demo.currentskinid[(player-players)]].flags - : skins[player->skin].flags; + : skins[player->skin]->flags; if (skinflags & SF_IRONMAN) { SetRandomFakePlayerSkin(player, true, false); diff --git a/src/p_tick.c b/src/p_tick.c index 3a85d40c2..c366a3b97 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -985,7 +985,7 @@ void P_Ticker(boolean run) continue; } - playerskin = &skins[players[i].skin]; + playerskin = skins[players[i].skin]; playerskin->records.timeplayed++; } @@ -1045,7 +1045,7 @@ void P_Ticker(boolean run) continue; } - playerskin = &skins[players[i].skin]; + playerskin = skins[players[i].skin]; playerskin->records.modetimeplayed[mode]++; } } diff --git a/src/p_user.c b/src/p_user.c index dfc87ecc7..88a3a3a71 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1335,7 +1335,7 @@ void P_DoPlayerExit(player_t *player, pflags_t flags) // Skin records (saved to gamedata) if (player->skin < numskins) { - skin_t *playerskin = &skins[player->skin]; + skin_t *playerskin = skins[player->skin]; if (!losing) { playerskin->records.wins++; @@ -4556,7 +4556,7 @@ void P_PlayerThink(player_t *player) player->mo->renderflags &= ~RF_DONTDRAW; player->mo->flags &= ~MF_NOCLIPTHING; } - + boolean deathcontrolled = (player->respawn.state != RESPAWNST_NONE && player->respawn.truedeath == true) || (player->pflags & PF_NOCONTEST) || (player->karmadelay); boolean powercontrolled = (player->hyudorotimer) || (player->growshrinktimer > 0); @@ -4584,7 +4584,7 @@ void P_PlayerThink(player_t *player) { UINT32 skinflags = (demo.playback) ? demo.skinlist[demo.currentskinid[playeri]].flags - : skins[player->skin].flags; + : skins[player->skin]->flags; if (skinflags & SF_IRONMAN) // we are Heavy Magician { diff --git a/src/r_picformats.c b/src/r_picformats.c index 14eaf01d7..aa3bf6620 100644 --- a/src/r_picformats.c +++ b/src/r_picformats.c @@ -1448,7 +1448,7 @@ static void R_ParseSpriteInfoSkin(struct ParseSpriteInfoState *parser) static void copy_to_skin (struct ParseSpriteInfoState *parser, INT32 skinnum) { - skin_t *skin = &skins[skinnum]; + skin_t *skin = skins[skinnum]; spriteinfo_t *sprinfo = skin->sprinfo; if (parser->any) diff --git a/src/r_skins.c b/src/r_skins.c index 994ce64fb..fb16314d3 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -42,7 +42,7 @@ #endif INT32 numskins = 0; -skin_t skins[MAXSKINS]; +skin_t **skins; unloaded_skin_t *unloadedskins = NULL; @@ -111,7 +111,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", skin->skinnum); skin->name[sizeof skin->name - 1] = '\0'; skin->wadnum = INT16_MAX; @@ -168,16 +168,6 @@ void R_InitSkins(void) { size_t i; - // it can be is do before loading config for skin cvar possible value - // (... what the fuck did you just say to me? "it can be is do"?) -#ifdef SKINVALUES - for (i = 0; i <= MAXSKINS; i++) - { - skin_cons_t[i].value = 0; - skin_cons_t[i].strvalue = NULL; - } -#endif - // no default skin! numskins = 0; @@ -334,7 +324,7 @@ UINT32 R_GetLocalRandomSkin(void) return grabskins[M_RandomKey(usableskins)]; } -// 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) { @@ -362,10 +352,10 @@ INT32 R_SkinAvailableEx(const char *name, boolean demoskins) for (i = 0; i < numskins; i++) { - if (skins[i].namehash != hash) + if (skins[i]->namehash != hash) continue; - if (stricmp(skins[i].name,name)!=0) + if (stricmp(skins[i]->name,name)!=0) continue; return i; @@ -398,7 +388,7 @@ static void SetSkin(player_t *player, INT32 skinnum) if (demo.playback) skinnum = demo.skinlist[skinnum].mapping; - skin_t *skin = &skins[skinnum]; + skin_t *skin = skins[skinnum]; player->skin = skinnum; @@ -523,9 +513,9 @@ void SetFakePlayerSkin(player_t* player, INT32 skinid) } else { - player->kartspeed = skins[skinid].kartspeed; - player->kartweight = skins[skinid].kartweight; - player->charflags = skins[skinid].flags; + player->kartspeed = skins[skinid]->kartspeed; + player->kartweight = skins[skinid]->kartweight; + player->charflags = skins[skinid]->flags; } player->mo->skin = &skins[skinid]; @@ -549,7 +539,7 @@ void SetRandomFakePlayerSkin(player_t* player, boolean fast, boolean instant) if (demo.skinlist[i].flags & SF_IRONMAN) continue; } - else if (skins[i].flags & SF_IRONMAN) + else if (skins[i]->flags & SF_IRONMAN) continue; if (!R_SkinUsable(player-players, i, true)) continue; @@ -628,7 +618,7 @@ void ClearFakePlayerSkin(player_t* player) else { skinid = player->skin; - flags = skins[player->skin].flags; + flags = skins[player->skin]->flags; } if ((flags & SF_IRONMAN) && !P_MobjWasRemoved(player->mo)) @@ -661,8 +651,8 @@ flaglessretry: { continue; } - stat_diff = abs(skins[i].kartspeed - kartspeed) + abs(skins[i].kartweight - kartweight); - if (doflagcheck && (skins[i].flags & flagcheck) != flagcheck) + stat_diff = abs(skins[i]->kartspeed - kartspeed) + abs(skins[i]->kartweight - kartweight); + if (doflagcheck && (skins[i]->flags & flagcheck) != flagcheck) { continue; } @@ -969,8 +959,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; realname = false; // parse @@ -1045,14 +1037,9 @@ 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 - // Update the forceskin possiblevalues Forceskin_cons_t[numskins+1].value = numskins; - Forceskin_cons_t[numskins+1].strvalue = skins[numskins].name; + Forceskin_cons_t[numskins+1].strvalue = skins[numskins]->name; #ifdef HWRENDER if (rendermode == render_opengl) @@ -1190,7 +1177,7 @@ void R_PatchSkins(UINT16 wadnum, boolean mainfile) strlwr(value); skinnum = R_SkinAvailableEx(value, false); 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); diff --git a/src/r_skins.h b/src/r_skins.h index 9a05129f9..85f401688 100644 --- a/src/r_skins.h +++ b/src/r_skins.h @@ -38,7 +38,8 @@ extern "C" { /// The skin_t struct struct skin_t { - char name[SKINNAMESIZE+1]; // descriptive name of the skin + char name[SKINNAMESIZE+1]; // name of skin + UINT8 skinnum; UINT32 namehash; // quickncasehash(->name, SKINNAMESIZE) UINT16 wadnum; skinflags_t flags; @@ -93,14 +94,14 @@ typedef enum { ENGINECLASS_I, ENGINECLASS_J - + } engineclass_t; engineclass_t R_GetEngineClass(SINT8 speed, SINT8 weight, skinflags_t flags); /// Externs extern INT32 numskins; -extern skin_t skins[MAXSKINS]; +extern skin_t **skins; extern CV_PossibleValue_t Forceskin_cons_t[]; diff --git a/src/r_spritefx.cpp b/src/r_spritefx.cpp index 03b2db6d6..dea525c11 100644 --- a/src/r_spritefx.cpp +++ b/src/r_spritefx.cpp @@ -45,7 +45,7 @@ INT32 R_ThingLightLevel(mobj_t* thing) lightlevel -= 255; } - if (!R_CanShowSkinInDemo((skin_t*)thing->skin-skins) + if (!R_CanShowSkinInDemo(((skin_t*)thing->skin)->skinnum) && !thing->colorized && !thing->hitlag) { diff --git a/src/r_things.cpp b/src/r_things.cpp index ac23b679c..af60a516b 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -848,7 +848,7 @@ UINT8 *R_GetSpriteTranslation(vissprite_t *vis) if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player! { - skinnum = (skin_t*)vis->mobj->skin-skins; + skinnum = ((skin_t*)vis->mobj->skin)->skinnum; // Hide not-yet-unlocked characters in replays from other people if (!R_CanShowSkinInDemo(skinnum)) diff --git a/src/s_sound.c b/src/s_sound.c index cef8df150..9768c4e9a 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -511,8 +511,8 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) if (sfx->skinsound != -1 && origin && (origin->player || origin->skin)) { // redirect player sound to the sound in the skin table - skin_t *skin = (origin->player ? &skins[origin->player->skin] : ((skin_t *)origin->skin)); - if (R_CanShowSkinInDemo(skin-skins) == false) + skin_t *skin = (origin->player ? skins[origin->player->skin] : ((skin_t *)origin->skin)); + if (R_CanShowSkinInDemo(skin->skinnum) == false) return; sfx_id = skin->soundsid[sfx->skinsound]; sfx = &S_sfx[sfx_id]; diff --git a/src/st_stuff.c b/src/st_stuff.c index 7349599d7..b5cd11d0d 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -181,7 +181,7 @@ void ST_LoadGraphics(void) void ST_LoadFaceGraphics(INT32 skinnum) { #define FACE_MAX (FACE_MINIMAP+1) - spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA]; + spritedef_t *sprdef = &skins[skinnum]->sprites[SPR2_XTRA]; spriteframe_t *sprframe; UINT8 i = 0, maxer = min(sprdef->numframes, FACE_MAX); while (i < maxer) diff --git a/src/y_inter.cpp b/src/y_inter.cpp index 8f14dea39..9a0214dfe 100644 --- a/src/y_inter.cpp +++ b/src/y_inter.cpp @@ -393,7 +393,7 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) snprintf(data.headerstring, sizeof data.headerstring, "%s", - R_CanShowSkinInDemo(players[i].skin) ? skins[players[i].skin].realname : "???"); + R_CanShowSkinInDemo(players[i].skin) ? skins[players[i].skin]->realname : "???"); } data.showroundnum = true;