From 99bf1c10e84db3527570e0b42b1b517aeedb5d0a Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 3 Feb 2023 00:55:34 +0000 Subject: [PATCH] staffbrief_t - Demos are VERY large and should not be cached for every map in the game all at once. - Instead, store a small amount of data related to staff ghosts for later reference. - best time (for use in Medals) - best lap (maybe use for Medals too) - player name (for use in Time Attack menu) --- src/doomstat.h | 12 ++++++++++++ src/g_demo.c | 28 ++++++++++++++++++---------- src/g_demo.h | 2 +- src/p_setup.c | 42 +++++++++++++++++++++++++++++++++++++----- src/typedef.h | 1 + 5 files changed, 69 insertions(+), 16 deletions(-) diff --git a/src/doomstat.h b/src/doomstat.h index 39b5a73da..fb62266a2 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -360,6 +360,14 @@ extern cupheader_t *kartcupheaders; // Start of cup linked list extern UINT16 numkartcupheaders; #define MAXMAPLUMPNAME 64 // includes \0, for cleaner savedata +#define MAXSTAFF 3 + +struct staffbrief_t +{ + char name[16]; + INT32 time; + INT32 lap; +}; /** Map header information. */ @@ -374,6 +382,10 @@ struct mapheader_t void *encoreLump; ///< Lump data for the Encore Mode remap. void *tweakLump; ///< Lump data for the palette tweak remap. + // Staff Ghost information + 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 diff --git a/src/g_demo.c b/src/g_demo.c index 286a4e965..17a8e4865 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -3711,14 +3711,17 @@ void G_FreeGhosts(void) } // A simplified version of G_AddGhost... -void G_UpdateStaffGhostName(lumpnum_t l) +staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer) { - UINT8 *buffer,*p; + UINT8 *p = buffer; UINT16 ghostversion; UINT8 flags; INT32 i; + staffbrief_t temp; + staffbrief_t *ret = NULL; - buffer = p = W_CacheLumpNum(l, PU_CACHE); + temp.name[0] = '\0'; + temp.time = temp.lap = UINT32_MAX; // read demo header if (memcmp(p, DEMOHEADER, 12)) @@ -3766,9 +3769,9 @@ void G_UpdateStaffGhostName(lumpnum_t l) G_SkipDemoSkins(&p); if (flags & ATTACKING_TIME) - p += 4; + temp.time = READUINT32(p); if (flags & ATTACKING_LAP) - p += 4; + temp.lap = READUINT32(p); for (i = 0; i < PRNUMCLASS; i++) { @@ -3781,7 +3784,7 @@ void G_UpdateStaffGhostName(lumpnum_t l) ghostversion = READUINT16(p); while (ghostversion--) { - p += 2; + SKIPSTRING(p); SKIPSTRING(p); p++; // stealth } @@ -3789,13 +3792,18 @@ void G_UpdateStaffGhostName(lumpnum_t l) // Assert first player is in and then read name if (READUINT8(p) != 0) goto fail; - M_Memcpy(dummystaffname, p,16); - dummystaffname[16] = '\0'; + if (READUINT8(p) & (DEMO_SPECTATOR|DEMO_BOT)) + goto fail; + + M_Memcpy(temp.name, p, 16); + + ret = Z_Malloc(sizeof(staffbrief_t), PU_STATIC, NULL); + if (ret) + M_Memcpy(ret, &temp, sizeof(staffbrief_t)); // Ok, no longer any reason to care, bye fail: - Z_Free(buffer); - return; + return ret; } // diff --git a/src/g_demo.h b/src/g_demo.h index a8c3f573c..d99b7a3ad 100644 --- a/src/g_demo.h +++ b/src/g_demo.h @@ -185,7 +185,7 @@ void G_DeferedPlayDemo(const char *demo); void G_DoPlayDemo(char *defdemoname); void G_TimeDemo(const char *name); void G_AddGhost(char *defdemoname); -void G_UpdateStaffGhostName(lumpnum_t l); +staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer); void G_FreeGhosts(void); void G_DoneLevelLoad(void); diff --git a/src/p_setup.c b/src/p_setup.c index e10f18a29..8381034a2 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -471,6 +471,7 @@ void P_AllocMapHeader(INT16 i) mapheaderinfo[i]->lumpname = NULL; mapheaderinfo[i]->thumbnailPic = NULL; mapheaderinfo[i]->minimapPic = NULL; + mapheaderinfo[i]->ghostCount = 0; mapheaderinfo[i]->cup = NULL; mapheaderinfo[i]->mainrecord = NULL; mapheaderinfo[i]->flickies = NULL; @@ -8018,11 +8019,13 @@ INT16 wadnamemap = 0; // gamemap based UINT8 P_InitMapData(boolean existingmapheaders) { UINT8 ret = 0; - INT32 i; + INT32 i, j; lumpnum_t maplump; virtres_t *virtmap; - virtlump_t *minimap, *thumbnailPic; + virtlump_t *minimap, *thumbnailPic, *ghost; char *name; + char buffer[9]; + sprintf(buffer, "GHOST_x"); for (i = 0; i < nummapheaders; ++i) { @@ -8034,7 +8037,6 @@ UINT8 P_InitMapData(boolean existingmapheaders) if (maplump != LUMPERROR || mapheaderinfo[i]->lumpnum != LUMPERROR) { cupheader_t *cup = kartcupheaders; - INT32 j; while (cup) { @@ -8116,16 +8118,46 @@ UINT8 P_InitMapData(boolean existingmapheaders) } // Now apply the new ones! - if (thumbnailPic) + if (thumbnailPic != NULL) { mapheaderinfo[i]->thumbnailPic = vres_GetPatch(thumbnailPic, PU_STATIC); } - if (minimap) + if (minimap != NULL) { mapheaderinfo[i]->minimapPic = vres_GetPatch(minimap, PU_STATIC); } + // Staff ghosts. + // The trouble with staff ghosts is that they're too large to cache. + // So we store extra information about them, and load later. + while (mapheaderinfo[i]->ghostCount > 0) + { + mapheaderinfo[i]->ghostCount--; + + Z_Free(mapheaderinfo[i]->ghostBrief[mapheaderinfo[i]->ghostCount]); + mapheaderinfo[i]->ghostBrief[mapheaderinfo[i]->ghostCount] = NULL; + } + + while (mapheaderinfo[i]->ghostCount < MAXSTAFF) + { + buffer[6] = '1' + mapheaderinfo[i]->ghostCount; + + ghost = vres_Find(virtmap, buffer); + if (ghost == NULL) + break; + + mapheaderinfo[i]->ghostBrief[mapheaderinfo[i]->ghostCount] = G_GetStaffGhostBrief(ghost->data); + if (mapheaderinfo[i]->ghostBrief[mapheaderinfo[i]->ghostCount] == NULL) + break; + /*CONS_Printf("name is %s, time is %d, lap is %d\n", + mapheaderinfo[i]->ghostBrief[mapheaderinfo[i]->ghostCount]->name, + mapheaderinfo[i]->ghostBrief[mapheaderinfo[i]->ghostCount]->time/TICRATE, + mapheaderinfo[i]->ghostBrief[mapheaderinfo[i]->ghostCount]->lap/TICRATE);*/ + + mapheaderinfo[i]->ghostCount++; + } + vres_Free(virtmap); } } diff --git a/src/typedef.h b/src/typedef.h index f33ee2f3b..a38b018a0 100644 --- a/src/typedef.h +++ b/src/typedef.h @@ -113,6 +113,7 @@ TYPEDEF (textprompt_t); TYPEDEF (mappoint_t); TYPEDEF (customoption_t); TYPEDEF (gametype_t); +TYPEDEF (staffbrief_t); TYPEDEF (mapheader_t); TYPEDEF (tolinfo_t); TYPEDEF (cupheader_t);