From 1cc870485dd93445bb4933be98dc58b1cdafee5b Mon Sep 17 00:00:00 2001 From: spherallic Date: Tue, 15 Mar 2022 20:35:06 +0100 Subject: [PATCH 1/3] Increase unlockable limits: - MAXUNLOCKABLES from 32 to 80 - MAXEXTRAEMBLEMS from 16 to 48 - COMPAT_GAMEDATA_ID is used to account for the old values to prevent losing records. - Also fixes linedef actions 319/320. --- src/g_game.c | 32 +++++++++++++++++++++++--------- src/m_cond.h | 4 ++-- src/m_menu.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/r_skins.c | 3 ++- 4 files changed, 75 insertions(+), 12 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index b23980044..47e670bfe 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4309,6 +4309,12 @@ void G_LoadGameData(gamedata_t *data) // Stop saving, until we successfully load it again. data->loaded = false; + // Backwards compat stuff + INT32 max_emblems = MAXEMBLEMS; + INT32 max_extraemblems = MAXEXTRAEMBLEMS; + INT32 max_unlockables = MAXUNLOCKABLES; + INT32 max_conditionsets = MAXCONDITIONSETS; + // Clear things so previously read gamedata doesn't transfer // to new gamedata G_ClearRecords(data); // main and nights records @@ -4325,7 +4331,7 @@ void G_LoadGameData(gamedata_t *data) { // Don't load, but do save. (essentially, reset) data->loaded = true; - return; + return; } length = FIL_ReadFile(va(pandf, srb2home, gamedatafilename), &savebuffer); @@ -4355,6 +4361,14 @@ void G_LoadGameData(gamedata_t *data) I_Error("Game data is from another version of SRB2.\nDelete %s(maybe in %s) and try again.", gamedatafilename, gdfolder); } +#ifdef COMPAT_GAMEDATA_ID // Account for lower MAXUNLOCKABLES and MAXEXTRAEMBLEMS from older versions + if (versionID == COMPAT_GAMEDATA_ID) + { + max_extraemblems = 16; + max_unlockables = 32; + } +#endif + data->totalplaytime = READUINT32(save_p); #ifdef COMPAT_GAMEDATA_ID @@ -4393,31 +4407,31 @@ void G_LoadGameData(gamedata_t *data) goto datacorrupt; // To save space, use one bit per collected/achieved/unlocked flag - for (i = 0; i < MAXEMBLEMS;) + for (i = 0; i < max_emblems;) { rtemp = READUINT8(save_p); - for (j = 0; j < 8 && j+i < MAXEMBLEMS; ++j) + for (j = 0; j < 8 && j+i < max_emblems; ++j) data->collected[j+i] = ((rtemp >> j) & 1); i += j; } - for (i = 0; i < MAXEXTRAEMBLEMS;) + for (i = 0; i < max_extraemblems;) { rtemp = READUINT8(save_p); - for (j = 0; j < 8 && j+i < MAXEXTRAEMBLEMS; ++j) + for (j = 0; j < 8 && j+i < max_extraemblems; ++j) data->extraCollected[j+i] = ((rtemp >> j) & 1); i += j; } - for (i = 0; i < MAXUNLOCKABLES;) + for (i = 0; i < max_unlockables;) { rtemp = READUINT8(save_p); - for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j) + for (j = 0; j < 8 && j+i < max_unlockables; ++j) data->unlocked[j+i] = ((rtemp >> j) & 1); i += j; } - for (i = 0; i < MAXCONDITIONSETS;) + for (i = 0; i < max_conditionsets;) { rtemp = READUINT8(save_p); - for (j = 0; j < 8 && j+i < MAXCONDITIONSETS; ++j) + for (j = 0; j < 8 && j+i < max_conditionsets; ++j) data->achieved[j+i] = ((rtemp >> j) & 1); i += j; } diff --git a/src/m_cond.h b/src/m_cond.h index 6a3da79ec..95c3e1ebe 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -139,8 +139,8 @@ typedef struct // you seriously need to get a life. #define MAXCONDITIONSETS 128 #define MAXEMBLEMS 512 -#define MAXEXTRAEMBLEMS 16 -#define MAXUNLOCKABLES 32 +#define MAXEXTRAEMBLEMS 48 +#define MAXUNLOCKABLES 80 /** Time attack information, currently a very small structure. */ diff --git a/src/m_menu.c b/src/m_menu.c index f9f52335d..1c064d228 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -728,6 +728,54 @@ static menuitem_t SR_MainMenu[] = {IT_DISABLED, NULL, "", NULL, 0}, // Custom30 {IT_DISABLED, NULL, "", NULL, 0}, // Custom31 {IT_DISABLED, NULL, "", NULL, 0}, // Custom32 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom33 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom34 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom35 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom36 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom37 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom38 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom39 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom40 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom41 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom42 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom43 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom44 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom45 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom46 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom47 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom48 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom49 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom50 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom51 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom52 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom53 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom54 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom55 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom56 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom57 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom58 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom59 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom60 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom61 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom62 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom63 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom64 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom65 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom66 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom67 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom68 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom69 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom70 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom71 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom72 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom73 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom74 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom75 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom76 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom77 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom78 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom79 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom80 }; diff --git a/src/r_skins.c b/src/r_skins.c index 2c031ee85..5bcde27b1 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -190,7 +190,8 @@ UINT32 R_GetSkinAvailabilities(void) // This crash is impossible to trigger as is, // but it could happen if MAXUNLOCKABLES is ever made higher than 32, // and someone makes a mod that has 33+ unlockable characters. :V - I_Error("Too many unlockable characters\n"); + // 2022/03/15: MAXUNLOCKABLES is now higher than 32 + I_Error("Too many unlockable characters! (maximum is 32)\n"); return 0; } From 99f09339866e3fc30d100d7353d0866a41ed0981 Mon Sep 17 00:00:00 2001 From: spherallic Date: Sun, 20 Mar 2022 14:10:18 +0100 Subject: [PATCH 2/3] Change how SR_MainMenu is initialized. --- src/m_menu.c | 93 ++++------------------------------------------------ 1 file changed, 7 insertions(+), 86 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 1c064d228..51f5b7173 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -693,90 +693,10 @@ static menuitem_t SR_PandorasBox[] = }; // Sky Room Custom Unlocks -static menuitem_t SR_MainMenu[] = +static menuitem_t SR_MainMenu[MAXUNLOCKABLES+1] = { {IT_STRING|IT_SUBMENU,NULL, "Extras Checklist", &SR_UnlockChecklistDef, 0}, - {IT_DISABLED, NULL, "", NULL, 0}, // Custom1 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom2 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom3 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom4 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom5 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom6 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom7 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom8 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom9 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom10 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom11 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom12 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom13 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom14 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom15 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom16 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom17 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom18 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom19 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom20 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom21 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom22 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom23 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom24 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom25 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom26 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom27 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom28 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom29 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom30 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom31 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom32 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom33 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom34 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom35 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom36 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom37 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom38 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom39 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom40 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom41 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom42 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom43 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom44 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom45 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom46 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom47 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom48 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom49 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom50 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom51 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom52 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom53 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom54 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom55 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom56 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom57 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom58 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom59 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom60 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom61 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom62 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom63 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom64 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom65 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom66 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom67 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom68 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom69 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom70 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom71 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom72 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom73 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom74 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom75 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom76 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom77 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom78 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom79 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom80 - + // The remaining (MAXUNLOCKABLES) items are now initialized in M_SecretsMenu }; static menuitem_t SR_LevelSelectMenu[] = @@ -8177,14 +8097,15 @@ static void M_SecretsMenu(INT32 choice) (void)choice; - // Clear all before starting - for (i = 1; i < MAXUNLOCKABLES+1; ++i) - SR_MainMenu[i].status = IT_DISABLED; + // Initialize array with placeholder entries + menuitem_t placeholder = {IT_DISABLED, NULL, "", NULL, 0}; + for (i = 1; i <= MAXUNLOCKABLES; ++i) + SR_MainMenu[i] = placeholder; memset(skyRoomMenuTranslations, 0, sizeof(skyRoomMenuTranslations)); memset(done, 0, sizeof(done)); - for (i = 1; i < MAXUNLOCKABLES+1; ++i) + for (i = 1; i <= MAXUNLOCKABLES; ++i) { curheight = UINT16_MAX; ul = -1; From d9937953ad1d1e57c08da5f684c7021dcd5a5663 Mon Sep 17 00:00:00 2001 From: spherallic Date: Wed, 24 May 2023 12:54:19 +0200 Subject: [PATCH 3/3] Fix linedef type 319/320 again --- src/p_spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index 71ea145b9..d1973d951 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1808,7 +1808,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller { // An unlockable itself must be unlocked! INT32 unlockid = triggerline->args[1]; - if (unlockid < 0 || unlockid >= MAXUNLOCKABLES) // limited by unlockable count + if (unlockid <= 0 || unlockid > MAXUNLOCKABLES) // limited by unlockable count { CONS_Debug(DBG_GAMELOGIC, "Unlockable check (sidedef %hu): bad unlockable ID %d\n", triggerline->sidenum[0], unlockid); return false;