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
"main.kart"
"bios.pk3"
"gfx.pk3"
"textures.pk3"
"textures_General.pk3"
"textures_OriginalZones.pk3"
"textures_SEGAZones.pk3"
"chars.pk3"
"maps.pk3"
"followers.pk3"
"patch.pk3"
"scripts.pk3"
"staffghosts.pk3"
"unlocks.pk3"
"shaders.pk3"
)
list(TRANSFORM SRB2_ASSETS_GAME PREPEND "/")
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
#define ASSET_HASH_PATCH_PK3 "00000000000000000000000000000000"
#endif
#define ASSET_HASH_STAFFGHOSTS_PK3 "00000000000000000000000000000000"
#define ASSET_HASH_SHADERS_PK3 "00000000000000000000000000000000"
// Version numbers for netplay :upside_down_face:
int VERSION;
@ -989,7 +991,7 @@ void D_SRB2Loop(void)
// Fully completed frame made.
finishprecise = I_GetPreciseTime();
// Use the time before sleep for frameskip calculations:
// Use the time before sleep for frameskip calculations:
// post-sleep time is literally being intentionally wasted
deltasecs = (double)((INT64)(finishprecise - enterprecise)) / I_GetPrecisePrecision();
deltatics = deltasecs * NEWTICRATE;
@ -1258,6 +1260,7 @@ static void IdentifyVersion(void)
#if defined(DEVELOP) && defined(UNLOCKTESTING)
D_AddFile(startupiwads, va(pandf,srb2waddir,"unlocks.pk3"));
#endif
D_AddFile(startupiwads, va(pandf,srb2waddir,"staffghosts.pk3"));
D_AddFile(startupiwads, va(pandf,srb2waddir,"shaders.pk3"));
#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_FOLLOWERS_PK3); // followers.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
#ifdef USE_PATCH_FILE
mainwads++; // scripts.pk3
@ -1599,6 +1605,7 @@ void D_SRB2Main(void)
#ifdef UNLOCKTESTING
mainwads++; // unlocks.pk3
#endif
mainwads++; // staffghosts.pk3
#endif //ifndef DEVELOP
mainwads++; // shaders.pk3

View file

@ -592,13 +592,13 @@ INT32 CL_CheckFiles(void)
{
if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD || fileneeded[i].status == FS_FALLBACK)
downloadrequired = true;
if (fileneeded[i].status != FS_OPEN)
filestoload++;
if (fileneeded[i].status != FS_NOTCHECKED) //since we're running this over multiple tics now, its possible for us to come across files checked in previous tics
continue;
CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename);
// Check in already loaded files
@ -1438,6 +1438,7 @@ void PT_FileFragment(void)
|| !strcmp(filename, "scripts.pk3")
|| !strcmp(filename, "sounds.pk3")
|| !strcmp(filename, "music.pk3")
|| !strcmp(filename, "staffghosts.pk3")
)
{
I_Error("Tried to download \"%s\"", filename);

View file

@ -443,10 +443,11 @@ struct unloaded_cupheader_t
extern unloaded_cupheader_t *unloadedcupheaders;
#define MAXMAPLUMPNAME 64 // includes \0, for cleaner savedata
#define MAXSTAFF 3
struct staffbrief_t
{
UINT16 wad;
UINT16 lump;
char name[16];
tic_t time;
tic_t lap;
@ -480,7 +481,8 @@ struct mapheader_t
// Staff Ghost information
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

View file

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

View file

@ -57,7 +57,7 @@ static boolean noFurtherInput = false;
// 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
@ -436,8 +436,8 @@ void M_PlayMenuJam(void)
const boolean trulystarted = M_GameTrulyStarted();
const boolean profilemode = (
trulystarted
&& optionsmenu.profilemenu
trulystarted
&& optionsmenu.profilemenu
&& !optionsmenu.resetprofilemenu
);
@ -487,7 +487,7 @@ void M_PlayMenuJam(void)
"KEYGEN",
"LOSERC",
};
if (refMenu != NULL && NotCurrentlyPlaying(overridetotrack[override - 1]))
{
Music_Remap("menu", overridetotrack[override - 1]);

View file

@ -335,13 +335,21 @@ void M_HandleStaffReplay(INT32 choice)
{
if (choice == 2)
{
mapheader_t *mapheader;
staffbrief_t *staffbrief;
const char* lumpname = NULL;
restoreMenu = &PLAY_TimeAttackDef;
M_ClearMenus(true);
demo.loadfiles = false;
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;
}

View file

@ -12,6 +12,11 @@
/// \brief Do all the WAD I/O, get map description, set up initial state and misc. LUTs
#include <algorithm>
#include <string>
#include <fmt/format.h>
#include "cxxutil.hpp"
#include "doomdef.h"
#include "d_main.h"
@ -475,6 +480,18 @@ static void P_ClearSingleMapHeaderInfo(INT16 num)
mapheaderinfo[num]->customopts = NULL;
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.
@ -525,6 +542,8 @@ void P_AllocMapHeader(INT16 i)
mapheaderinfo[i]->thumbnailPic = NULL;
mapheaderinfo[i]->minimapPic = NULL;
mapheaderinfo[i]->ghostCount = 0;
mapheaderinfo[i]->ghostBriefSize = 0;
mapheaderinfo[i]->ghostBrief = NULL;
mapheaderinfo[i]->cup = NULL;
mapheaderinfo[i]->followers = NULL;
nummapheaders++;
@ -7806,24 +7825,30 @@ static void P_LoadRecordGhosts(void)
// Staff Attack ghosts
if (cv_ghost_staff.value)
{
char *defdemoname;
virtlump_t *vLump;
for (i = mapheaderinfo[gamemap-1]->ghostCount; i > 0; i--)
{
savebuffer_t buf = {0};
defdemoname = va("GHOST_%u", i);
vLump = vres_Find(curmapvirt, defdemoname);
if (vLump == NULL)
staffbrief_t* ghostbrief = mapheaderinfo[gamemap-1]->ghostBrief[i - 1];
const char* lumpname = W_CheckNameForNumPwad(ghostbrief->wad, ghostbrief->lump);
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;
}
P_SaveBufferZAlloc(&buf, vLump->size, PU_LEVEL, NULL);
memcpy(buf.buffer, vLump->data, vLump->size);
G_AddGhost(&buf, defdemoname);
P_SaveBufferZAlloc(&buf, lumplength, PU_LEVEL, NULL);
W_ReadLumpPwad(ghostbrief->wad, ghostbrief->lump, buf.buffer);
G_AddGhost(&buf, (char*)lumpname);
}
}
@ -8833,10 +8858,8 @@ UINT8 P_InitMapData(void)
INT32 i, j;
lumpnum_t maplump;
virtres_t *virtmap;
virtlump_t *minimap, *thumbnailPic, *ghost;
virtlump_t *minimap, *thumbnailPic;
char *name;
char buffer[9];
sprintf(buffer, "GHOST_x");
for (i = 0; i < nummapheaders; ++i)
{
@ -8950,23 +8973,55 @@ UINT8 P_InitMapData(void)
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);
if (ghost == NULL)
break;
UINT16 lumpstart = W_CheckNumForFolderStartPK3(ghostdirname.c_str(), wadindex, 0);
if (lumpstart == INT16_MAX)
{
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);
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);*/
for (UINT16 lumpnum = lumpstart; lumpnum < lumpend; lumpnum++)
{
if (W_IsLumpFolder(wadindex, lumpnum))
{
continue;
}
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);