From 4c34d04f8ae681c1d690d7102db70c63dd01d7f3 Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 24 May 2023 00:18:12 +0100 Subject: [PATCH] recorddata_t handling adjustments Preperatory work for the next feature on my agenda. - No longer independently allocated. - This was a byproduct of the previous NUMMAPS-based implementation. It's just cleaner to have it live directly on the mapheader_t, no caveats about it. - Now contains mapvisited bitflag array. - Now all to-gamedata properties on a mapheader's struct are grouped together. - I was of two minds about it, but decided that this would have cleaner guarantees for compartmentalisation, saving, and loading. - They can still be wiped independently (G_ClearRecords for time/lap and M_ClearSecrets for mapvisited). --- src/deh_soc.c | 2 - src/doomstat.h | 22 +++++----- src/g_game.c | 68 +++++++++--------------------- src/g_game.h | 1 - src/k_menudraw.c | 11 ++--- src/m_cond.c | 12 +++--- src/menus/extras-statistics.c | 2 +- src/menus/transient/level-select.c | 2 +- src/p_setup.c | 7 +-- src/s_sound.c | 2 +- 10 files changed, 46 insertions(+), 83 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index 2bd662828..d5fb03cd3 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -192,8 +192,6 @@ void clear_levels(void) P_DeleteHeaderFollowers(nummapheaders); - Z_Free(mapheaderinfo[nummapheaders]->mainrecord); - Patch_Free(mapheaderinfo[nummapheaders]->thumbnailPic); Patch_Free(mapheaderinfo[nummapheaders]->minimapPic); diff --git a/src/doomstat.h b/src/doomstat.h index ab73c70dc..4983442c2 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -112,12 +112,19 @@ extern preciptype_t curWeather; /** Time attack information, currently a very small structure. */ + +// mapvisited is now a set of flags that says what we've done in the map. +#define MV_VISITED (1) +#define MV_BEATEN (1<<1) +#define MV_ENCORE (1<<2) +#define MV_SPBATTACK (1<<3) +#define MV_MAX (MV_VISITED|MV_BEATEN|MV_ENCORE|MV_SPBATTACK) + struct recorddata_t { + UINT8 mapvisited; tic_t time; ///< Time in which the level was finished. tic_t lap; ///< Best lap time for this level. - //UINT32 score; ///< Score when the level was finished. - //UINT16 rings; ///< Rings when the level was finished. }; #define KARTSPEED_AUTO -1 @@ -144,14 +151,6 @@ struct cupwindata_t boolean got_emerald; }; -// mapvisited is now a set of flags that says what we've done in the map. -#define MV_VISITED (1) -#define MV_BEATEN (1<<1) -#define MV_ENCORE (1<<2) -#define MV_SPBATTACK (1<<3) -#define MV_MAX (MV_VISITED|MV_BEATEN|MV_ENCORE|MV_SPBATTACK) -#define MV_MP ((MV_MAX+1)<<1) - // Set if homebrew PWAD stuff has been added. extern boolean modifiedgame; extern boolean majormods; @@ -417,8 +416,7 @@ struct mapheader_t UINT8 ghostCount; ///< Count of valid staff ghosts staffbrief_t *ghostBrief[MAXSTAFF]; ///< Mallocated array of names for each staff ghost - UINT8 mapvisited; ///< A set of flags that says what we've done in the map. - recorddata_t *mainrecord; ///< Stores best time attack data + recorddata_t records; ///< Stores completion/record attack data cupheader_t *cup; ///< Cached cup diff --git a/src/g_game.c b/src/g_game.c index cf2e4b184..bf4537fa7 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -444,16 +444,6 @@ consvar_t cv_rumble[MAXSPLITSCREENPLAYERS] = { char player_names[MAXPLAYERS][MAXPLAYERNAME+1]; INT32 player_name_changes[MAXPLAYERS]; -// Allocation for time and nights data -void G_AllocMainRecordData(INT16 i) -{ - if (i > nummapheaders || !mapheaderinfo[i]) - I_Error("G_AllocMainRecordData: Internal map ID %d not found (nummapheaders = %d)\n", i, nummapheaders); - if (!mapheaderinfo[i]->mainrecord) - mapheaderinfo[i]->mainrecord = Z_Malloc(sizeof(recorddata_t), PU_STATIC, NULL); - memset(mapheaderinfo[i]->mainrecord, 0, sizeof(recorddata_t)); -} - // MAKE SURE YOU SAVE DATA BEFORE CALLING THIS void G_ClearRecords(void) { @@ -462,11 +452,8 @@ void G_ClearRecords(void) for (i = 0; i < nummapheaders; ++i) { - if (mapheaderinfo[i]->mainrecord) - { - Z_Free(mapheaderinfo[i]->mainrecord); - mapheaderinfo[i]->mainrecord = NULL; - } + mapheaderinfo[i]->records.time = 0; + mapheaderinfo[i]->records.lap = 0; } for (cup = kartcupheaders; cup; cup = cup->next) @@ -478,10 +465,10 @@ void G_ClearRecords(void) // For easy retrieval of records tic_t G_GetBestTime(INT16 map) { - if (!mapheaderinfo[map] || !mapheaderinfo[map]->mainrecord || mapheaderinfo[map]->mainrecord->time <= 0) + if (!mapheaderinfo[map] || mapheaderinfo[map]->records.time <= 0) return (tic_t)UINT32_MAX; - return mapheaderinfo[map]->mainrecord->time; + return mapheaderinfo[map]->records.time; } // BE RIGHT BACK @@ -490,10 +477,10 @@ tic_t G_GetBestTime(INT16 map) /* tic_t G_GetBestLap(INT16 map) { - if (!mapheaderinfo[map] || !mapheaderinfo[map]->mainrecord || mapheaderinfo[map]->mainrecord->lap <= 0) + if (!mapheaderinfo[map] || mapheaderinfo[map]->records.lap <= 0) return (tic_t)UINT32_MAX; - return mapheaderinfo[map]->mainrecord->lap; + return mapheaderinfo[map]->records.lap; } */ @@ -621,32 +608,28 @@ void G_UpdateRecords(void) { UINT8 earnedEmblems; - // Record new best time - if (!mapheaderinfo[gamemap-1]->mainrecord) - G_AllocMainRecordData(gamemap-1); - if (modeattacking & ATTACKING_TIME) { tic_t time = players[consoleplayer].realtime; if (players[consoleplayer].pflags & PF_NOCONTEST) time = UINT32_MAX; - if (((mapheaderinfo[gamemap-1]->mainrecord->time == 0) || (time < mapheaderinfo[gamemap-1]->mainrecord->time)) + if (((mapheaderinfo[gamemap-1]->records.time == 0) || (time < mapheaderinfo[gamemap-1]->records.time)) && (time < UINT32_MAX)) // DNF - mapheaderinfo[gamemap-1]->mainrecord->time = time; + mapheaderinfo[gamemap-1]->records.time = time; } else { - mapheaderinfo[gamemap-1]->mainrecord->time = 0; + mapheaderinfo[gamemap-1]->records.time = 0; } if (modeattacking & ATTACKING_LAP) { - if ((mapheaderinfo[gamemap-1]->mainrecord->lap == 0) || (bestlap < mapheaderinfo[gamemap-1]->mainrecord->lap)) - mapheaderinfo[gamemap-1]->mainrecord->lap = bestlap; + if ((mapheaderinfo[gamemap-1]->records.lap == 0) || (bestlap < mapheaderinfo[gamemap-1]->records.lap)) + mapheaderinfo[gamemap-1]->records.lap = bestlap; } else { - mapheaderinfo[gamemap-1]->mainrecord->lap = 0; + mapheaderinfo[gamemap-1]->records.lap = 0; } // Check emblems when level data is updated @@ -3986,16 +3969,16 @@ static void G_UpdateVisited(void) return; // Update visitation flags - mapheaderinfo[prevmap]->mapvisited |= MV_BEATEN; + mapheaderinfo[prevmap]->records.mapvisited |= MV_BEATEN; if (encoremode == true) { - mapheaderinfo[prevmap]->mapvisited |= MV_ENCORE; + mapheaderinfo[prevmap]->records.mapvisited |= MV_ENCORE; } if (modeattacking & ATTACKING_SPB) { - mapheaderinfo[prevmap]->mapvisited |= MV_SPBATTACK; + mapheaderinfo[prevmap]->records.mapvisited |= MV_SPBATTACK; } if (modeattacking) @@ -4959,14 +4942,13 @@ void G_LoadGameData(void) { // Valid mapheader, time to populate with record data. - if ((mapheaderinfo[mapnum]->mapvisited = rtemp) & ~MV_MAX) + if ((mapheaderinfo[mapnum]->records.mapvisited = rtemp) & ~MV_MAX) goto datacorrupt; if (rectime || reclap) { - G_AllocMainRecordData((INT16)i); - mapheaderinfo[i]->mainrecord->time = rectime; - mapheaderinfo[i]->mainrecord->lap = reclap; + mapheaderinfo[i]->records.time = rectime; + mapheaderinfo[i]->records.lap = reclap; //CONS_Printf("ID %d, Time = %d, Lap = %d\n", i, rectime/35, reclap/35); } } @@ -5219,18 +5201,10 @@ void G_SaveGameData(void) // For figuring out which header to assign it to on load WRITESTRINGN(save.p, mapheaderinfo[i]->lumpname, MAXMAPLUMPNAME); - WRITEUINT8(save.p, (mapheaderinfo[i]->mapvisited & MV_MAX)); + WRITEUINT8(save.p, (mapheaderinfo[i]->records.mapvisited & MV_MAX)); - if (mapheaderinfo[i]->mainrecord) - { - WRITEUINT32(save.p, mapheaderinfo[i]->mainrecord->time); - WRITEUINT32(save.p, mapheaderinfo[i]->mainrecord->lap); - } - else - { - WRITEUINT32(save.p, 0); - WRITEUINT32(save.p, 0); - } + WRITEUINT32(save.p, mapheaderinfo[i]->records.time); + WRITEUINT32(save.p, mapheaderinfo[i]->records.lap); } WRITEUINT32(save.p, numcups); // 4 diff --git a/src/g_game.h b/src/g_game.h index e7e028250..2f498134e 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -264,7 +264,6 @@ void G_SetGameModified(boolean silent, boolean major); void G_SetUsedCheats(void); // Gamedata record shit -void G_AllocMainRecordData(INT16 i); void G_ClearRecords(void); tic_t G_GetBestTime(INT16 map); diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 8c99f5e31..49b9c4f67 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -2640,11 +2640,8 @@ void M_DrawTimeAttack(void) if ((minimap = mapheaderinfo[map]->minimapPic)) V_DrawScaledPatch(24-t, 82, 0, minimap); - if (mapheaderinfo[map]->mainrecord) - { - timerec = mapheaderinfo[map]->mainrecord->time; - laprec = mapheaderinfo[map]->mainrecord->lap; - } + timerec = mapheaderinfo[map]->records.time; + laprec = mapheaderinfo[map]->records.lap; if ((gametypes[levellist.newgametype]->rules & GTR_CIRCUIT) && (mapheaderinfo[map]->numlaps != 1)) @@ -5779,13 +5776,13 @@ void M_DrawStatistics(void) if (!mapheaderinfo[i] || (mapheaderinfo[i]->menuflags & (LF2_NOTIMEATTACK|LF2_HIDEINSTATS|LF2_HIDEINMENU))) continue; - if (!mapheaderinfo[i]->mainrecord || mapheaderinfo[i]->mainrecord->time <= 0) + if (mapheaderinfo[i]->records.time <= 0) { mapsunfinished++; continue; } - besttime += mapheaderinfo[i]->mainrecord->time; + besttime += mapheaderinfo[i]->records.time; } V_DrawThinString(20, 60, V_6WIDTHSPACE|V_ALLOWLOWERCASE, "Combined time records:"); diff --git a/src/m_cond.c b/src/m_cond.c index 41510210c..4e64e6c43 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -539,7 +539,7 @@ void M_ClearSecrets(void) for (i = 0; i < nummapheaders; ++i) { - mapheaderinfo[i]->mapvisited = 0; + mapheaderinfo[i]->records.mapvisited = 0; } for (i = 0; i < MAXEMBLEMS; ++i) @@ -702,7 +702,7 @@ boolean M_CheckCondition(condition_t *cn, player_t *player) return ((cn->requirement < nummapheaders) && (mapheaderinfo[cn->requirement]) - && ((mapheaderinfo[cn->requirement]->mapvisited & mvtype) == mvtype)); + && ((mapheaderinfo[cn->requirement]->records.mapvisited & mvtype) == mvtype)); } case UC_MAPTIME: // Requires time on map <= x return (G_GetBestTime(cn->extrainfo1) <= (unsigned)cn->requirement); @@ -932,7 +932,7 @@ static char *M_BuildConditionTitle(UINT16 map) if (((mapheaderinfo[map]->menuflags & LF2_FINISHNEEDED) // the following is intentionally not MV_BEATEN, just in case the title is for "Finish a round on X" - && !(mapheaderinfo[map]->mapvisited & MV_VISITED)) + && !(mapheaderinfo[map]->records.mapvisited & MV_VISITED)) || M_MapLocked(map+1)) return Z_StrDup("???"); @@ -1770,7 +1770,7 @@ UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separa if (embtype & ME_SPBATTACK) flags |= MV_SPBATTACK; - res = ((mapheaderinfo[levelnum]->mapvisited & flags) == flags); + res = ((mapheaderinfo[levelnum]->records.mapvisited & flags) == flags); gamedata->collected[i] = res; if (res) @@ -1955,9 +1955,9 @@ UINT8 M_GotLowEnoughTime(INT32 tictime) if (!mapheaderinfo[i] || (mapheaderinfo[i]->menuflags & LF2_NOTIMEATTACK)) continue; - if (!mapheaderinfo[i]->mainrecord || !mapheaderinfo[i]->mainrecord->time) + if (!mapheaderinfo[i]->records.time) return false; - else if ((curtics += mapheaderinfo[i]->mainrecord->time) > tictime) + if ((curtics += mapheaderinfo[i]->records.time) > tictime) return false; } return true; diff --git a/src/menus/extras-statistics.c b/src/menus/extras-statistics.c index 356bf46b2..bc4843b27 100644 --- a/src/menus/extras-statistics.c +++ b/src/menus/extras-statistics.c @@ -26,7 +26,7 @@ static boolean M_StatisticsAddMap(UINT16 map, cupheader_t *cup, boolean *headere // Check for completion if ((mapheaderinfo[map]->menuflags & LF2_FINISHNEEDED) - && !(mapheaderinfo[map]->mapvisited & MV_BEATEN)) + && !(mapheaderinfo[map]->records.mapvisited & MV_BEATEN)) return false; // Check for unlock diff --git a/src/menus/transient/level-select.c b/src/menus/transient/level-select.c index db6e257bb..2aeb50f55 100644 --- a/src/menus/transient/level-select.c +++ b/src/menus/transient/level-select.c @@ -88,7 +88,7 @@ boolean M_CanShowLevelInList(INT16 mapnum, levelsearch_t *levelsearch) { // Check for completion if ((mapheaderinfo[mapnum]->menuflags & LF2_FINISHNEEDED) - && !(mapheaderinfo[mapnum]->mapvisited & MV_BEATEN)) + && !(mapheaderinfo[mapnum]->records.mapvisited & MV_BEATEN)) return false; // Check for unlock diff --git a/src/p_setup.c b/src/p_setup.c index 4153f889a..1542eed02 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -446,9 +446,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 num) P_DeleteHeaderFollowers(num); #endif - mapheaderinfo[num]->mapvisited = 0; - Z_Free(mapheaderinfo[num]->mainrecord); - mapheaderinfo[num]->mainrecord = NULL; + memset(&mapheaderinfo[num]->records, 0, sizeof(recorddata_t)); mapheaderinfo[num]->justPlayed = 0; mapheaderinfo[num]->anger = 0; @@ -506,7 +504,6 @@ void P_AllocMapHeader(INT16 i) mapheaderinfo[i]->minimapPic = NULL; mapheaderinfo[i]->ghostCount = 0; mapheaderinfo[i]->cup = NULL; - mapheaderinfo[i]->mainrecord = NULL; mapheaderinfo[i]->followers = NULL; nummapheaders++; } @@ -8312,7 +8309,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) if (!demo.playback) { - mapheaderinfo[gamemap-1]->mapvisited |= MV_VISITED; + mapheaderinfo[gamemap-1]->records.mapvisited |= MV_VISITED; M_UpdateUnlockablesAndExtraEmblems(true, true); G_SaveGameData(); diff --git a/src/s_sound.c b/src/s_sound.c index 9f04c82e9..9a2fbe466 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1534,7 +1534,7 @@ static boolean S_SoundTestDefLocked(musicdef_t *def) // Is the level tied to SP progression? if ((mapheaderinfo[def->sequence.map]->menuflags & LF2_FINISHNEEDED) - && !(mapheaderinfo[def->sequence.map]->mapvisited & MV_BEATEN)) + && !(mapheaderinfo[def->sequence.map]->records.mapvisited & MV_BEATEN)) return true; // Finally, do a full-fat map check.