From 0c7d66791bd993314300f8554d30f0c7d415c121 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 30 May 2023 21:08:29 +0100 Subject: [PATCH] Expand datatype for Unlockables, emblems (Medals + nonmedals), and Conditions. Made sure there is more than enough headroom for our current purposes. It should be easy to double again if necessary now that the datatypes have been increased... but that would be obscene at this point - 1024 Unlockables and 1024 Conditions (these were always tied together in slots) - 2048 emblems (Medals + nonmedals). If we ship with ~250 maps this permits 8 Medals per map - which is higher than we intend right now but could easily fill out in patches --- src/deh_soc.c | 6 ++-- src/g_game.c | 54 +++++++++++++++++++++++++---------- src/k_follower.c | 2 +- src/k_menu.h | 8 +++--- src/k_menudraw.c | 2 +- src/m_cheat.c | 4 +-- src/m_cond.c | 47 +++++++++++++++--------------- src/m_cond.h | 24 ++++++++-------- src/menus/extras-challenges.c | 10 +++---- src/r_skins.c | 5 ++-- 10 files changed, 94 insertions(+), 68 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index b7d54be2a..b466f1158 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -170,7 +170,7 @@ void clear_unlockables(void) void clear_conditionsets(void) { - UINT8 i; + UINT16 i; for (i = 0; i < MAXCONDITIONSETS; ++i) M_ClearConditionSet(i); } @@ -2317,9 +2317,9 @@ void readunlockable(MYFILE *f, INT32 num) strupr(word2); if (fastcmp(word, "CONDITIONSET")) - unlockables[num].conditionset = (UINT8)i; + unlockables[num].conditionset = (UINT16)i; else if (fastcmp(word, "MAJORUNLOCK")) - unlockables[num].majorunlock = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y'); + unlockables[num].majorunlock = (UINT8)(i != 0 || word2[0] == 'T' || word2[0] == 'Y'); else if (fastcmp(word, "TYPE")) { if (fastcmp(word2, "NONE")) diff --git a/src/g_game.c b/src/g_game.c index 9d14e0eb0..2f86dc500 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4793,6 +4793,11 @@ void G_LoadGameData(void) boolean gridunusable = false; savebuffer_t save = {0}; + UINT16 emblemreadcount = MAXEMBLEMS; + UINT16 unlockreadcount = MAXUNLOCKABLES; + UINT16 conditionreadcount = MAXCONDITIONSETS; + size_t unlockreadsize = sizeof(UINT16); + //For records UINT32 numgamedataskins; UINT32 numgamedatamapheaders; @@ -4897,32 +4902,39 @@ void G_LoadGameData(void) } } + if (versionMinor < 3) + { + emblemreadcount = 512; + unlockreadcount = conditionreadcount = UINT8_MAX; + unlockreadsize = sizeof(UINT8); + } + // To save space, use one bit per collected/achieved/unlocked flag - for (i = 0; i < MAXEMBLEMS;) + for (i = 0; i < emblemreadcount;) { rtemp = READUINT8(save.p); - for (j = 0; j < 8 && j+i < MAXEMBLEMS; ++j) + for (j = 0; j < 8 && j+i < emblemreadcount; ++j) gamedata->collected[j+i] = ((rtemp >> j) & 1); i += j; } - for (i = 0; i < MAXUNLOCKABLES;) + for (i = 0; i < unlockreadcount;) { rtemp = READUINT8(save.p); - for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j) + for (j = 0; j < 8 && j+i < unlockreadcount; ++j) gamedata->unlocked[j+i] = ((rtemp >> j) & 1); i += j; } - for (i = 0; i < MAXUNLOCKABLES;) + for (i = 0; i < unlockreadcount;) { rtemp = READUINT8(save.p); - for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j) + for (j = 0; j < 8 && j+i < unlockreadcount; ++j) gamedata->unlockpending[j+i] = ((rtemp >> j) & 1); i += j; } - for (i = 0; i < MAXCONDITIONSETS;) + for (i = 0; i < conditionreadcount;) { rtemp = READUINT8(save.p); - for (j = 0; j < 8 && j+i < MAXCONDITIONSETS; ++j) + for (j = 0; j < 8 && j+i < conditionreadcount; ++j) gamedata->achieved[j+i] = ((rtemp >> j) & 1); i += j; } @@ -4931,7 +4943,7 @@ void G_LoadGameData(void) { UINT16 burn = READUINT16(save.p); // Previous challengegridwidth UINT8 height = (versionMinor > 0) ? CHALLENGEGRIDHEIGHT : 5; - save.p += (burn * height * sizeof(UINT8)); // Step over previous grid data + save.p += (burn * height * unlockreadsize); // Step over previous grid data gamedata->challengegridwidth = 0; Z_Free(gamedata->challengegrid); @@ -4944,11 +4956,23 @@ void G_LoadGameData(void) if (gamedata->challengegridwidth) { gamedata->challengegrid = Z_Malloc( - (gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT * sizeof(UINT8)), + (gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT * sizeof(UINT16)), PU_STATIC, NULL); - for (i = 0; i < (gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT); i++) + if (unlockreadsize == sizeof(UINT8)) { - gamedata->challengegrid[i] = READUINT8(save.p); + for (i = 0; i < (gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT); i++) + { + gamedata->challengegrid[i] = READUINT8(save.p); + if (gamedata->challengegrid[i] == unlockreadcount) + gamedata->challengegrid[i] = MAXUNLOCKABLES; + } + } + else + { + for (i = 0; i < (gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT); i++) + { + gamedata->challengegrid[i] = READUINT16(save.p); + } } } else @@ -5261,7 +5285,7 @@ void G_SaveGameData(void) if (gamedata->challengegrid) { - length += gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT; + length += (gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT) * 2; } @@ -5434,12 +5458,12 @@ void G_SaveGameData(void) i += j; } - if (gamedata->challengegrid) // 2 + gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT + if (gamedata->challengegrid) // 2 + (gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT) * 2 { WRITEUINT16(save.p, gamedata->challengegridwidth); for (i = 0; i < (gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT); i++) { - WRITEUINT8(save.p, gamedata->challengegrid[i]); + WRITEUINT16(save.p, gamedata->challengegrid[i]); } } else // 2 diff --git a/src/k_follower.c b/src/k_follower.c index daa7b9d0d..48b9646e2 100644 --- a/src/k_follower.c +++ b/src/k_follower.c @@ -48,7 +48,7 @@ boolean K_FollowerUsable(INT32 skinnum) { // Unlike R_SkinUsable, not netsynced. // Solely used to prevent an invalid value being sent over the wire. - UINT8 i; + UINT16 i; INT32 fid; if (skinnum == -1 || demo.playback) diff --git a/src/k_menu.h b/src/k_menu.h index d461973b4..09cfbf772 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -1189,13 +1189,13 @@ extern struct challengesmenu_s { tic_t ticker; // How long the menu's been open for INT16 offset; // To make the icons move smoothly when we transition! - UINT8 currentunlock; + UINT16 currentunlock; char *unlockcondition; tic_t unlockanim; - SINT8 row, hilix, focusx; - UINT8 col, hiliy; + INT16 row, hilix, focusx; + UINT16 col, hiliy; challengegridextradata_t *extradata; @@ -1205,7 +1205,7 @@ extern struct challengesmenu_s { boolean requestflip; - UINT8 unlockcount[CC_MAX]; + UINT16 unlockcount[CC_MAX]; UINT8 fade; } challengesmenu; diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 70422ae13..19126e02e 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -4650,7 +4650,7 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, boolean hili patch_t *pat = missingpat; UINT8 *colormap = NULL, *bgmap = NULL; fixed_t siz, accordion; - UINT8 id, num; + UINT16 id, num; boolean unlockedyet; boolean categoryside; diff --git a/src/m_cheat.c b/src/m_cheat.c index e4aec3b41..72ffd6523 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -62,7 +62,7 @@ typedef struct // Cheat responders static UINT8 cheatf_warp(void) { - UINT8 i; + UINT16 i; boolean success = false; /*if (modifiedgame) @@ -98,7 +98,7 @@ static UINT8 cheatf_warp(void) #ifdef DEVELOP static UINT8 cheatf_devmode(void) { - UINT8 i; + UINT16 i; if (modifiedgame) return 0; diff --git a/src/m_cond.c b/src/m_cond.c index 2a016d30f..87bed8df0 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -60,7 +60,7 @@ void M_PopulateChallengeGrid(void) { UINT16 i, j; UINT16 numunlocks = 0, nummajorunlocks = 0, numempty = 0; - UINT8 selection[2][MAXUNLOCKABLES + (CHALLENGEGRIDHEIGHT-1)]; + UINT16 selection[2][MAXUNLOCKABLES + (CHALLENGEGRIDHEIGHT-1)]; UINT16 majorcompact = 2; if (gamedata->challengegrid != NULL) @@ -98,7 +98,7 @@ void M_PopulateChallengeGrid(void) if (nummajorunlocks) { // Getting the number of 2-highs you can fit into two adjacent columns. - UINT8 majorpad = (CHALLENGEGRIDHEIGHT/2); + UINT16 majorpad = (CHALLENGEGRIDHEIGHT/2); numempty = nummajorunlocks%majorpad; majorpad = (nummajorunlocks+(majorpad-1))/majorpad; @@ -128,7 +128,7 @@ void M_PopulateChallengeGrid(void) } gamedata->challengegrid = Z_Malloc( - (gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT * sizeof(UINT8)), + (gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT * sizeof(UINT16)), PU_STATIC, NULL); if (!gamedata->challengegrid) @@ -136,9 +136,10 @@ void M_PopulateChallengeGrid(void) I_Error("M_PopulateChallengeGrid: was not able to allocate grid"); } - memset(gamedata->challengegrid, - MAXUNLOCKABLES, - (gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT * sizeof(UINT8))); + for (i = 0; i < MAXUNLOCKABLES; ++i) + { + gamedata->challengegrid[i] = MAXUNLOCKABLES; + } // Attempt to place all large tiles first. if (nummajorunlocks) @@ -212,7 +213,7 @@ quickcheckagain: #if (CHALLENGEGRIDHEIGHT == 4) while (nummajorunlocks > 0) { - UINT8 unlocktomoveup = MAXUNLOCKABLES; + UINT16 unlocktomoveup = MAXUNLOCKABLES; j = gamedata->challengegridwidth-1; @@ -313,7 +314,7 @@ quickcheckagain: void M_UpdateChallengeGridExtraData(challengegridextradata_t *extradata) { - UINT8 i, j, num, id, tempid, work; + UINT16 i, j, num, id, tempid, work; boolean idchange; if (gamedata->challengegrid == NULL) @@ -478,7 +479,7 @@ void M_UpdateChallengeGridExtraData(challengegridextradata_t *extradata) } } -void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2, char *stringvar) +void M_AddRawCondition(UINT16 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2, char *stringvar) { condition_t *cond; UINT32 num, wnum; @@ -500,7 +501,7 @@ void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1 cond[wnum].stringvar = stringvar; } -void M_ClearConditionSet(UINT8 set) +void M_ClearConditionSet(UINT16 set) { if (conditionSets[set].numconditions) { @@ -1395,7 +1396,7 @@ static const char *M_GetConditionString(condition_t *cn) #undef BUILDCONDITIONTITLE } -char *M_BuildConditionSetString(UINT8 unlockid) +char *M_BuildConditionSetString(UINT16 unlockid) { conditionset_t *c = NULL; UINT32 lastID = 0; @@ -1651,7 +1652,7 @@ boolean M_UpdateUnlockablesAndExtraEmblems(boolean loud, boolean doall) UINT16 M_GetNextAchievedUnlock(void) { - UINT8 i; + UINT16 i; // Go through unlockables for (i = 0; i < MAXUNLOCKABLES; ++i) @@ -1683,14 +1684,14 @@ UINT16 M_GetNextAchievedUnlock(void) } // Emblem unlocking shit -UINT8 M_CheckLevelEmblems(void) +UINT16 M_CheckLevelEmblems(void) { INT32 i; INT32 valToReach; INT16 tag; INT16 levelnum; - UINT8 res; - UINT8 somethingUnlocked = 0; + boolean res; + UINT16 somethingUnlocked = 0; // Update Score, Time, Rings emblems for (i = 0; i < numemblems; ++i) @@ -1736,13 +1737,13 @@ UINT8 M_CheckLevelEmblems(void) return somethingUnlocked; } -UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separate print when awarding emblems and it's sorta different enough. +UINT16 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separate print when awarding emblems and it's sorta different enough. { INT32 i; INT32 embtype; INT16 levelnum; - UINT8 res; - UINT8 somethingUnlocked = 0; + boolean res; + UINT16 somethingUnlocked = 0; UINT8 flags; for (i = 0; i < numemblems; ++i) @@ -1781,7 +1782,7 @@ UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separa // Quick unlock checks // ------------------- -boolean M_CheckNetUnlockByID(UINT8 unlockid) +boolean M_CheckNetUnlockByID(UINT16 unlockid) { if (unlockid >= MAXUNLOCKABLES || !unlockables[unlockid].conditionset) @@ -1824,7 +1825,7 @@ boolean M_SecretUnlocked(INT32 type, boolean local) boolean M_CupLocked(cupheader_t *cup) { - UINT8 i; + UINT16 i; // Don't lock maps in dedicated servers. // That just makes hosts' lives hell. @@ -1852,7 +1853,7 @@ boolean M_CupLocked(cupheader_t *cup) boolean M_MapLocked(UINT16 mapnum) { - UINT8 i; + UINT16 i; // Don't lock maps in dedicated servers. // That just makes hosts' lives hell. @@ -1918,7 +1919,7 @@ INT32 M_CountMedals(boolean all, boolean extraonly) // Theoretically faster than using M_CountMedals() // Stops when it reaches the target number of medals. -UINT8 M_GotEnoughMedals(INT32 number) +boolean M_GotEnoughMedals(INT32 number) { INT32 i, gottenmedals = 0; for (i = 0; i < numemblems; ++i) @@ -1942,7 +1943,7 @@ UINT8 M_GotEnoughMedals(INT32 number) return false; } -UINT8 M_GotLowEnoughTime(INT32 tictime) +boolean M_GotLowEnoughTime(INT32 tictime) { INT32 curtics = 0; INT32 i; diff --git a/src/m_cond.h b/src/m_cond.h index a4fe978bd..08b3e28e0 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -159,7 +159,7 @@ struct unlockable_t char name[64]; char *icon; UINT16 color; - UINT8 conditionset; + UINT16 conditionset; INT16 type; INT16 variable; char *stringVar; @@ -206,8 +206,8 @@ typedef enum // If you have more secrets than these variables allow in your game, // you seriously need to get a life. -#define MAXCONDITIONSETS UINT8_MAX -#define MAXEMBLEMS 512 +#define MAXCONDITIONSETS 1024 +#define MAXEMBLEMS (MAXCONDITIONSETS*2) #define MAXUNLOCKABLES MAXCONDITIONSETS #define CHALLENGEGRIDHEIGHT 4 @@ -260,7 +260,7 @@ struct gamedata_t // CHALLENGE GRID UINT16 challengegridwidth; - UINT8 *challengegrid; + UINT16 *challengegrid; // # OF TIMES THE GAME HAS BEEN BEATEN UINT32 timesBeaten; @@ -317,15 +317,15 @@ void M_UpdateChallengeGridExtraData(challengegridextradata_t *extradata); #define CHE_CONNECTEDUP (1<<2) #define CHE_DONTDRAW (CHE_CONNECTEDLEFT|CHE_CONNECTEDUP) -char *M_BuildConditionSetString(UINT8 unlockid); +char *M_BuildConditionSetString(UINT16 unlockid); #define DESCRIPTIONWIDTH 170 // Condition set setup -void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2, char *stringvar); +void M_AddRawCondition(UINT16 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2, char *stringvar); void M_UpdateConditionSetsPending(void); // Clearing secrets -void M_ClearConditionSet(UINT8 set); +void M_ClearConditionSet(UINT16 set); void M_ClearSecrets(void); void M_ClearStats(void); @@ -338,11 +338,11 @@ boolean M_UpdateUnlockablesAndExtraEmblems(boolean loud, boolean doall); #define PENDING_CHAOKEYS (UINT16_MAX-1) UINT16 M_GetNextAchievedUnlock(void); -UINT8 M_CheckLevelEmblems(void); -UINT8 M_CompletionEmblems(void); +UINT16 M_CheckLevelEmblems(void); +UINT16 M_CompletionEmblems(void); // Checking unlockable status -boolean M_CheckNetUnlockByID(UINT8 unlockid); +boolean M_CheckNetUnlockByID(UINT16 unlockid); boolean M_SecretUnlocked(INT32 type, boolean local); boolean M_CupLocked(cupheader_t *cup); boolean M_MapLocked(UINT16 mapnum); @@ -356,8 +356,8 @@ const char *M_GetEmblemPatch(emblem_t *em, boolean big); // If you're looking to compare stats for unlocks or what not, use these // They stop checking upon reaching the target number so they // should be (theoretically?) slightly faster. -UINT8 M_GotEnoughMedals(INT32 number); -UINT8 M_GotLowEnoughTime(INT32 tictime); +boolean M_GotEnoughMedals(INT32 number); +boolean M_GotLowEnoughTime(INT32 tictime); INT32 M_UnlockableSkinNum(unlockable_t *unlock); INT32 M_UnlockableFollowerNum(unlockable_t *unlock); diff --git a/src/menus/extras-challenges.c b/src/menus/extras-challenges.c index c7d6674e1..eb49b762a 100644 --- a/src/menus/extras-challenges.c +++ b/src/menus/extras-challenges.c @@ -53,8 +53,8 @@ struct challengesmenu_s challengesmenu; static void M_ChallengesAutoFocus(UINT16 unlockid, boolean fresh) { - UINT8 i; - SINT8 work; + UINT16 i; + INT16 work; if (unlockid >= MAXUNLOCKABLES && gamedata->pendingkeyrounds > 0 && (gamedata->chaokeys < GDMAX_CHAOKEYS)) @@ -62,8 +62,8 @@ static void M_ChallengesAutoFocus(UINT16 unlockid, boolean fresh) if (fresh && unlockid >= MAXUNLOCKABLES) { - UINT8 selection[MAXUNLOCKABLES]; - UINT8 numunlocks = 0; + UINT16 selection[MAXUNLOCKABLES]; + UINT16 numunlocks = 0; // Get a random available unlockable. for (i = 0; i < MAXUNLOCKABLES; i++) @@ -512,7 +512,7 @@ void M_ChallengesTick(void) boolean M_ChallengesInputs(INT32 ch) { const UINT8 pid = 0; - UINT8 i; + UINT16 i; const boolean start = M_MenuButtonPressed(pid, MBT_START); const boolean move = (menucmd[pid].dpad_ud != 0 || menucmd[pid].dpad_lr != 0); (void) ch; diff --git a/src/r_skins.c b/src/r_skins.c index 94ac8bb03..30c4fa487 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -187,7 +187,8 @@ void R_InitSkins(void) UINT8 *R_GetSkinAvailabilities(boolean demolock, boolean forbots) { - UINT8 i, shif, byte; + UINT16 i; + UINT8 shif, byte; INT32 skinid; static UINT8 responsebuffer[MAXAVAILABILITY]; UINT8 defaultbotskin = R_BotDefaultSkin(); @@ -225,7 +226,7 @@ boolean R_SkinUsable(INT32 playernum, INT32 skinnum, boolean demoskins) { boolean needsunlocked = false; boolean useplayerstruct = (Playing() && playernum != -1); - UINT8 i; + UINT16 i; INT32 skinid; if (skinnum == -1)