Read staff ghosts from pk3 directory

This commit is contained in:
Eidolon 2024-01-02 21:00:18 -06:00
parent 3d36f99609
commit 746da46321
8 changed files with 118 additions and 39 deletions

View file

@ -27,13 +27,19 @@ list(TRANSFORM SRB2_ASSETS_DOCS PREPEND "${SRB2_ASSET_DIRECTORY_ABSOLUTE}")
#################### ####################
set(SRB2_ASSETS_GAME set(SRB2_ASSETS_GAME
"main.kart" "bios.pk3"
"gfx.pk3" "gfx.pk3"
"textures.pk3" "textures_General.pk3"
"textures_OriginalZones.pk3"
"textures_SEGAZones.pk3"
"chars.pk3" "chars.pk3"
"maps.pk3" "maps.pk3"
"followers.pk3" "followers.pk3"
"patch.pk3" "patch.pk3"
"scripts.pk3"
"staffghosts.pk3"
"unlocks.pk3"
"shaders.pk3"
) )
list(TRANSFORM SRB2_ASSETS_GAME PREPEND "/") list(TRANSFORM SRB2_ASSETS_GAME PREPEND "/")
list(TRANSFORM SRB2_ASSETS_GAME PREPEND "${SRB2_ASSET_DIRECTORY_ABSOLUTE}") list(TRANSFORM SRB2_ASSETS_GAME PREPEND "${SRB2_ASSET_DIRECTORY_ABSOLUTE}")

View file

@ -116,6 +116,8 @@ extern "C" consvar_t cv_lua_profile;
#ifdef USE_PATCH_FILE #ifdef USE_PATCH_FILE
#define ASSET_HASH_PATCH_PK3 "00000000000000000000000000000000" #define ASSET_HASH_PATCH_PK3 "00000000000000000000000000000000"
#endif #endif
#define ASSET_HASH_STAFFGHOSTS_PK3 "00000000000000000000000000000000"
#define ASSET_HASH_SHADERS_PK3 "00000000000000000000000000000000"
// Version numbers for netplay :upside_down_face: // Version numbers for netplay :upside_down_face:
int VERSION; int VERSION;
@ -1258,6 +1260,7 @@ static void IdentifyVersion(void)
#if defined(DEVELOP) && defined(UNLOCKTESTING) #if defined(DEVELOP) && defined(UNLOCKTESTING)
D_AddFile(startupiwads, va(pandf,srb2waddir,"unlocks.pk3")); D_AddFile(startupiwads, va(pandf,srb2waddir,"unlocks.pk3"));
#endif #endif
D_AddFile(startupiwads, va(pandf,srb2waddir,"staffghosts.pk3"));
D_AddFile(startupiwads, va(pandf,srb2waddir,"shaders.pk3")); D_AddFile(startupiwads, va(pandf,srb2waddir,"shaders.pk3"));
#if !defined (HAVE_SDL) || defined (HAVE_MIXER) #if !defined (HAVE_SDL) || defined (HAVE_MIXER)
@ -1585,6 +1588,9 @@ void D_SRB2Main(void)
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_CHARS_PK3); // chars.pk3 mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_CHARS_PK3); // chars.pk3
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_FOLLOWERS_PK3); // followers.pk3 mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_FOLLOWERS_PK3); // followers.pk3
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_MAPS_PK3); // maps.pk3 mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_MAPS_PK3); // maps.pk3
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_UNLOCKS_PK3); // unlocks.pk3
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_STAFFGHOSTS_PK3); // staffghosts.pk3
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_SHADERS_PK3); // shaders.pk3
#else #else
#ifdef USE_PATCH_FILE #ifdef USE_PATCH_FILE
mainwads++; // scripts.pk3 mainwads++; // scripts.pk3
@ -1599,6 +1605,7 @@ void D_SRB2Main(void)
#ifdef UNLOCKTESTING #ifdef UNLOCKTESTING
mainwads++; // unlocks.pk3 mainwads++; // unlocks.pk3
#endif #endif
mainwads++; // staffghosts.pk3
#endif //ifndef DEVELOP #endif //ifndef DEVELOP
mainwads++; // shaders.pk3 mainwads++; // shaders.pk3

View file

@ -1438,6 +1438,7 @@ void PT_FileFragment(void)
|| !strcmp(filename, "scripts.pk3") || !strcmp(filename, "scripts.pk3")
|| !strcmp(filename, "sounds.pk3") || !strcmp(filename, "sounds.pk3")
|| !strcmp(filename, "music.pk3") || !strcmp(filename, "music.pk3")
|| !strcmp(filename, "staffghosts.pk3")
) )
{ {
I_Error("Tried to download \"%s\"", filename); I_Error("Tried to download \"%s\"", filename);

View file

@ -443,10 +443,11 @@ struct unloaded_cupheader_t
extern unloaded_cupheader_t *unloadedcupheaders; extern unloaded_cupheader_t *unloadedcupheaders;
#define MAXMAPLUMPNAME 64 // includes \0, for cleaner savedata #define MAXMAPLUMPNAME 64 // includes \0, for cleaner savedata
#define MAXSTAFF 3
struct staffbrief_t struct staffbrief_t
{ {
UINT16 wad;
UINT16 lump;
char name[16]; char name[16];
tic_t time; tic_t time;
tic_t lap; tic_t lap;
@ -480,7 +481,8 @@ struct mapheader_t
// Staff Ghost information // Staff Ghost information
UINT8 ghostCount; ///< Count of valid staff ghosts UINT8 ghostCount; ///< Count of valid staff ghosts
staffbrief_t *ghostBrief[MAXSTAFF]; ///< Mallocated array of names for each staff ghost UINT32 ghostBriefSize; ///< Size of ghostBrief vector allocation
staffbrief_t **ghostBrief; ///< Valid staff ghosts, pointers are owned
recorddata_t records; ///< Stores completion/record attack data recorddata_t records; ///< Stores completion/record attack data

View file

@ -3908,7 +3908,7 @@ staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer)
UINT16 ghostversion; UINT16 ghostversion;
UINT8 flags; UINT8 flags;
INT32 i; INT32 i;
staffbrief_t temp; staffbrief_t temp = {0};
staffbrief_t *ret = NULL; staffbrief_t *ret = NULL;
temp.name[0] = '\0'; temp.name[0] = '\0';

View file

@ -57,7 +57,7 @@ static boolean noFurtherInput = false;
// CONSOLE VARIABLES AND THEIR POSSIBLE VALUES GO HERE. // CONSOLE VARIABLES AND THEIR POSSIBLE VALUES GO HERE.
// ========================================================================== // ==========================================================================
CV_PossibleValue_t dummystaff_cons_t[] = {{0, "MIN"}, {MAXSTAFF-1, "MAX"}, {0, NULL}}; CV_PossibleValue_t dummystaff_cons_t[] = {{0, "MIN"}, {999, "MAX"}, {0, NULL}};
// ========================================================================== // ==========================================================================
// CVAR ONCHANGE EVENTS GO HERE // CVAR ONCHANGE EVENTS GO HERE

View file

@ -335,13 +335,21 @@ void M_HandleStaffReplay(INT32 choice)
{ {
if (choice == 2) if (choice == 2)
{ {
mapheader_t *mapheader;
staffbrief_t *staffbrief;
const char* lumpname = NULL;
restoreMenu = &PLAY_TimeAttackDef; restoreMenu = &PLAY_TimeAttackDef;
M_ClearMenus(true); M_ClearMenus(true);
demo.loadfiles = false; demo.loadfiles = false;
demo.ignorefiles = true; // Just assume that record attack replays have the files needed demo.ignorefiles = true; // Just assume that record attack replays have the files needed
G_DoPlayDemo(va("%s/GHOST_%u", mapheaderinfo[levellist.choosemap]->lumpname, cv_dummystaff.value+1)); mapheader = mapheaderinfo[levellist.choosemap];
staffbrief = mapheader->ghostBrief[cv_dummystaff.value];
lumpname = W_CheckNameForNumPwad(staffbrief->wad, staffbrief->lump);
G_DoPlayDemo(lumpname);
return; return;
} }

View file

@ -12,6 +12,11 @@
/// \brief Do all the WAD I/O, get map description, set up initial state and misc. LUTs /// \brief Do all the WAD I/O, get map description, set up initial state and misc. LUTs
#include <algorithm> #include <algorithm>
#include <string>
#include <fmt/format.h>
#include "cxxutil.hpp"
#include "doomdef.h" #include "doomdef.h"
#include "d_main.h" #include "d_main.h"
@ -475,6 +480,18 @@ static void P_ClearSingleMapHeaderInfo(INT16 num)
mapheaderinfo[num]->customopts = NULL; mapheaderinfo[num]->customopts = NULL;
mapheaderinfo[num]->numCustomOptions = 0; mapheaderinfo[num]->numCustomOptions = 0;
if (mapheaderinfo[num]->ghostBrief != NULL)
{
for (int i = 0; i < mapheaderinfo[num]->ghostCount; i++)
{
Z_Free(mapheaderinfo[num]->ghostBrief[i]);
}
Z_Free(mapheaderinfo[num]->ghostBrief);
}
mapheaderinfo[num]->ghostBrief = NULL;
mapheaderinfo[num]->ghostCount = 0;
mapheaderinfo[num]->ghostBriefSize = 0;
} }
/** Allocates a new map-header structure. /** Allocates a new map-header structure.
@ -525,6 +542,8 @@ void P_AllocMapHeader(INT16 i)
mapheaderinfo[i]->thumbnailPic = NULL; mapheaderinfo[i]->thumbnailPic = NULL;
mapheaderinfo[i]->minimapPic = NULL; mapheaderinfo[i]->minimapPic = NULL;
mapheaderinfo[i]->ghostCount = 0; mapheaderinfo[i]->ghostCount = 0;
mapheaderinfo[i]->ghostBriefSize = 0;
mapheaderinfo[i]->ghostBrief = NULL;
mapheaderinfo[i]->cup = NULL; mapheaderinfo[i]->cup = NULL;
mapheaderinfo[i]->followers = NULL; mapheaderinfo[i]->followers = NULL;
nummapheaders++; nummapheaders++;
@ -7806,24 +7825,30 @@ static void P_LoadRecordGhosts(void)
// Staff Attack ghosts // Staff Attack ghosts
if (cv_ghost_staff.value) if (cv_ghost_staff.value)
{ {
char *defdemoname;
virtlump_t *vLump;
for (i = mapheaderinfo[gamemap-1]->ghostCount; i > 0; i--) for (i = mapheaderinfo[gamemap-1]->ghostCount; i > 0; i--)
{ {
savebuffer_t buf = {0}; savebuffer_t buf = {0};
defdemoname = va("GHOST_%u", i); staffbrief_t* ghostbrief = mapheaderinfo[gamemap-1]->ghostBrief[i - 1];
vLump = vres_Find(curmapvirt, defdemoname); const char* lumpname = W_CheckNameForNumPwad(ghostbrief->wad, ghostbrief->lump);
if (vLump == NULL) size_t lumplength = W_LumpLengthPwad(ghostbrief->wad, ghostbrief->lump);
if (lumplength == 0)
{ {
CONS_Alert(CONS_ERROR, M_GetText("Failed to read virtlump '%s'.\n"), defdemoname); if (lumpname)
{
CONS_Alert(CONS_ERROR, M_GetText("Failed to read staff ghost lump '%s'.\n"), lumpname);
}
else
{
CONS_Alert(CONS_ERROR, M_GetText("Failed to read staff ghost lump for map '%s'.\n"), mapheaderinfo[gamemap-1]->lumpname);
}
continue; continue;
} }
P_SaveBufferZAlloc(&buf, vLump->size, PU_LEVEL, NULL); P_SaveBufferZAlloc(&buf, lumplength, PU_LEVEL, NULL);
memcpy(buf.buffer, vLump->data, vLump->size); W_ReadLumpPwad(ghostbrief->wad, ghostbrief->lump, buf.buffer);
G_AddGhost(&buf, defdemoname); G_AddGhost(&buf, (char*)lumpname);
} }
} }
@ -8833,10 +8858,8 @@ UINT8 P_InitMapData(void)
INT32 i, j; INT32 i, j;
lumpnum_t maplump; lumpnum_t maplump;
virtres_t *virtmap; virtres_t *virtmap;
virtlump_t *minimap, *thumbnailPic, *ghost; virtlump_t *minimap, *thumbnailPic;
char *name; char *name;
char buffer[9];
sprintf(buffer, "GHOST_x");
for (i = 0; i < nummapheaders; ++i) for (i = 0; i < nummapheaders; ++i)
{ {
@ -8950,23 +8973,55 @@ UINT8 P_InitMapData(void)
mapheaderinfo[i]->ghostBrief[mapheaderinfo[i]->ghostCount] = NULL; mapheaderinfo[i]->ghostBrief[mapheaderinfo[i]->ghostCount] = NULL;
} }
while (mapheaderinfo[i]->ghostCount < MAXSTAFF) for (INT32 wadindex = 0; wadindex < numwadfiles; wadindex++)
{ {
buffer[6] = '1' + mapheaderinfo[i]->ghostCount; if (wadfiles[wadindex]->type != RET_PK3)
{
continue;
}
std::string ghostdirname = fmt::format("staffghosts/{}/", mapheaderinfo[i]->lumpname);
ghost = vres_Find(virtmap, buffer); UINT16 lumpstart = W_CheckNumForFolderStartPK3(ghostdirname.c_str(), wadindex, 0);
if (ghost == NULL) if (lumpstart == INT16_MAX)
break; {
continue;
}
UINT16 lumpend = W_CheckNumForFolderEndPK3(ghostdirname.c_str(), wadindex, lumpstart);
if (lumpend == INT16_MAX)
{
continue;
}
mapheaderinfo[i]->ghostBrief[mapheaderinfo[i]->ghostCount] = G_GetStaffGhostBrief(ghost->data); for (UINT16 lumpnum = lumpstart; lumpnum < lumpend; lumpnum++)
if (mapheaderinfo[i]->ghostBrief[mapheaderinfo[i]->ghostCount] == NULL) {
break; if (W_IsLumpFolder(wadindex, lumpnum))
/*CONS_Printf("name is %s, time is %d, lap is %d\n", {
mapheaderinfo[i]->ghostBrief[mapheaderinfo[i]->ghostCount]->name, continue;
mapheaderinfo[i]->ghostBrief[mapheaderinfo[i]->ghostCount]->time/TICRATE, }
mapheaderinfo[i]->ghostBrief[mapheaderinfo[i]->ghostCount]->lap/TICRATE);*/
mapheaderinfo[i]->ghostCount++; size_t lumplength = W_LumpLengthPwad(wadindex, lumpnum);
UINT8* ghostdata = static_cast<UINT8*>(Z_Malloc(lumplength, PU_STATIC, nullptr));
auto ghostdata_finalizer = srb2::finally([=]() { Z_Free(ghostdata); });
W_ReadLumpPwad(wadindex, lumpnum, ghostdata);
staffbrief_t* briefghost = G_GetStaffGhostBrief(ghostdata);
if (briefghost == nullptr)
{
continue;
}
briefghost->wad = wadindex;
briefghost->lump = lumpnum;
// Resize ghostBrief if needed
if (mapheaderinfo[i]->ghostBriefSize < static_cast<UINT32>(mapheaderinfo[i]->ghostCount + 1))
{
UINT32 newsize = mapheaderinfo[i]->ghostBriefSize + 4;
mapheaderinfo[i]->ghostBrief = static_cast<staffbrief_t**>(Z_Realloc(mapheaderinfo[i]->ghostBrief, sizeof(staffbrief_t*) * newsize, PU_STATIC, NULL));
mapheaderinfo[i]->ghostBriefSize = newsize;
}
mapheaderinfo[i]->ghostBrief[mapheaderinfo[i]->ghostCount] = briefghost;
mapheaderinfo[i]->ghostCount++;
}
} }
vres_Free(virtmap); vres_Free(virtmap);