diff --git a/source/common/initfs.cpp b/source/common/initfs.cpp index d4dfecd96..2d0c6192c 100644 --- a/source/common/initfs.cpp +++ b/source/common/initfs.cpp @@ -157,9 +157,9 @@ void D_AddWildFile (TArray &wadfiles, const char *value) { return; } - const char *wadfile = BaseFileSearch (value, ".wad", false); + FString wadfile = BaseFileSearch (value, ".wad", false); - if (wadfile != NULL) + if (wadfile.Len() != 0) { D_AddFile (wadfiles, wadfile); } diff --git a/source/duke3d/src/demo.cpp b/source/duke3d/src/demo.cpp index 82ce7a1d7..2e1ebf159 100644 --- a/source/duke3d/src/demo.cpp +++ b/source/duke3d/src/demo.cpp @@ -65,7 +65,6 @@ static void Demo_RestoreModes(int32_t menu) g_player[myconnectindex].ps->gm |= MODE_DEMO; } -// This is utterly gross. Global configuration should not be manipulated like this. void Demo_PrepareWarp(void) { if (!g_demo_paused) @@ -279,10 +278,7 @@ void G_CloseDemoWrite(void) g_demo_filePtr->Write("EnD!", 4); // lastly, we need to write the number of written recsyncs to the demo file - if (g_demo_filePtr->Write(g_demo_filePtr, offsetof(savehead_t, reccnt))) - Printf("G_CloseDemoWrite: final fseek\n"); - else - g_demo_filePtr->Write(&g_demo_cnt, sizeof(g_demo_cnt)); + g_demo_filePtr->Write(&g_demo_cnt, sizeof(g_demo_cnt)); ud.recstat = ud.m_recstat = 0; delete g_demo_filePtr; @@ -418,7 +414,8 @@ static void Demo_FinishProfile(void) dn, gms, (gms*1000.0)/nt); } - if (nf > 0) { + if (nf > 0) + { OSD_Printf("== demo %d: %d frames (%d frames/gametic)\n", dn, nf, g_demo_profile-1); OSD_Printf("== demo %d drawrooms times: %.03f s (%.03f ms/frame)\n", dn, dms1/1000.0, dms1/nf); diff --git a/source/duke3d/src/savegame.cpp b/source/duke3d/src/savegame.cpp index 090447874..a4b9ab68c 100644 --- a/source/duke3d/src/savegame.cpp +++ b/source/duke3d/src/savegame.cpp @@ -206,7 +206,7 @@ static void ReadSaveGameHeaders_CACHE1D(TArray &saves) static void ReadSaveGameHeaders_Internal(void) { - FString pattern = M_GetSavegamesPath() + "*.esv"; + FString pattern = M_GetSavegamesPath() + "*.bsv"; TArray saves; D_AddWildFile(saves, pattern); // potentially overallocating but programmatically simple @@ -750,7 +750,7 @@ int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave) } else { - static char const SaveName[] = "save0000.svz"; + static char const SaveName[] = "save0000.bsv"; fn.Format("%s%s", M_GetSavegamesPath().GetChars(), SaveName); auto fnp = fn.LockBuffer(); @@ -1002,7 +1002,7 @@ static int32_t readspecdata(const dataspec_t *spec, FileReader *fil, uint8_t **d if (!ptr || !cnt) continue; - if (fil != nullptr) + if (fil != nullptr && fil->isOpen()) { auto const mem = (dump && (spec->flags & DS_NOCHK) == 0) ? dump : (uint8_t *)ptr; int const siz = cnt * spec->size; @@ -1376,11 +1376,6 @@ static const dataspec_t svgm_udnetw[] = { 0, connectpoint2, sizeof(connectpoint2), 1 }, { 0, &randomseed, sizeof(randomseed), 1 }, { 0, &g_globalRandom, sizeof(g_globalRandom), 1 }, -#ifdef LUNATIC - // Save game tic count for Lunatic because it is exposed to userland. See - // test/helixspawner.lua for an example. - { 0, &g_moveThingsCount, sizeof(g_moveThingsCount), 1 }, -#endif // { 0, &lockclock_dummy, sizeof(lockclock), 1 }, { DS_END, 0, 0, 0 } }; @@ -1695,7 +1690,7 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i } else { - int v = 64000; + int v = 0; fil.Write(&v, 4); } @@ -1810,7 +1805,7 @@ int32_t sv_loadsnapshot(FileReader &fil, int32_t spot, savehead_t *h) } if (i > 0) { - if (fil.Seek(i, FileReader::SeekSet) != i) + if (fil.Seek(i, FileReader::SeekCur) < 0) { OSD_Printf("sv_snapshot: failed skipping over the screenshot.\n"); return 8; @@ -2185,13 +2180,6 @@ static int32_t doloadplayer2(FileReader &fil, uint8_t **memptr) PRINTSIZE("ud"); if (readspecdata(svgm_secwsp, &fil, &mem)) return -4; PRINTSIZE("sws"); -#ifdef LUNATIC - { - int32_t ret = El_ReadSaveCode(fil); - if (ret < 0) - return ret; - } -#endif if (readspecdata(svgm_script, &fil, &mem)) return -5; PRINTSIZE("script"); if (readspecdata(svgm_anmisc, &fil, &mem)) return -6; diff --git a/source/rr/src/demo.cpp b/source/rr/src/demo.cpp index 9cf547c5d..15ff12524 100644 --- a/source/rr/src/demo.cpp +++ b/source/rr/src/demo.cpp @@ -37,8 +37,8 @@ BEGIN_RR_NS char g_firstDemoFile[BMAX_PATH]; -buildvfs_FILE g_demo_filePtr{}; // write -FileReader g_demo_recFilePtr; +FileWriter *g_demo_filePtr{}; // write +FileReader g_demo_recFilePtr; // read int32_t g_demo_cnt; int32_t g_demo_goalCnt=0; @@ -156,7 +156,7 @@ void G_OpenDemoWrite(void) if (demonum == MAXDEMOS) return; - if (snprintf(demofn, sizeof(demofn), "%s" DEMOFN_FMT, M_GetSavegamesPath().GetChars(), demonum)) + if (snprintf(demofn, sizeof(demofn), "%s" DEMOFN_FMT, M_GetDemoPath().GetChars(), demonum)) { initprintf("Couldn't start demo writing: INTERNAL ERROR: file name too long\n"); goto error_wopen_demo; @@ -164,25 +164,26 @@ void G_OpenDemoWrite(void) demonum++; - g_demo_filePtr = buildvfs_fopen_read(demofn); + g_demo_filePtr = FileWriter::Open(demofn); if (g_demo_filePtr == NULL) break; - MAYBE_FCLOSE_AND_NULL(g_demo_filePtr); + delete g_demo_filePtr; } while (1); - g_demo_filePtr = buildvfs_fopen_write(demofn); + g_demo_filePtr = FileWriter::Open(demofn); if (g_demo_filePtr == NULL) return; - i=sv_saveandmakesnapshot(g_demo_filePtr, nullptr, -1, demorec_diffs_cvar, demorec_diffcompress_cvar, + i=sv_saveandmakesnapshot(*g_demo_filePtr, nullptr, -1, demorec_diffs_cvar, demorec_diffcompress_cvar, (demorec_seeds_cvar<<1)); if (i) { - MAYBE_FCLOSE_AND_NULL(g_demo_filePtr); + delete g_demo_filePtr; + g_demo_filePtr = nullptr; error_wopen_demo: - Bstrcpy(apStrings[QUOTE_RESERVED4], "FAILED STARTING DEMO RECORDING. SEE OSD FOR DETAILS."); + Bstrcpy(apStrings[QUOTE_RESERVED4], "FAILED STARTING DEMO RECORDING. SEE CONSOLE FOR DETAILS."); P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps); ud.recstat = ud.m_recstat = 0; return; @@ -233,13 +234,13 @@ static void Demo_WriteSync() { int16_t tmpreccnt; - buildvfs_fwrite("sYnC", 4, 1, g_demo_filePtr); + g_demo_filePtr->Write("sYnC", 4); tmpreccnt = (int16_t)ud.reccnt; - buildvfs_fwrite(&tmpreccnt, sizeof(int16_t), 1, g_demo_filePtr); + g_demo_filePtr->Write(&tmpreccnt, sizeof(int16_t)); if (demorec_seeds) - buildvfs_fwrite(g_demo_seedbuf, 1, ud.reccnt, g_demo_filePtr); + g_demo_filePtr->Write(g_demo_seedbuf, ud.reccnt); - buildvfs_fwrite(recsync, sizeof(input_t), ud.reccnt, g_demo_filePtr); + g_demo_filePtr->Write(recsync, sizeof(input_t)* ud.reccnt); ud.reccnt = 0; } @@ -276,16 +277,14 @@ void G_CloseDemoWrite(void) if (ud.reccnt > 0) Demo_WriteSync(); - buildvfs_fwrite("EnD!", 4, 1, g_demo_filePtr); + g_demo_filePtr->Write("EnD!", 4); // lastly, we need to write the number of written recsyncs to the demo file - if (buildvfs_fseek_abs(g_demo_filePtr, offsetof(savehead_t, reccnt))) - perror("G_CloseDemoWrite: final fseek"); - else - buildvfs_fwrite(&g_demo_cnt, sizeof(g_demo_cnt), 1, g_demo_filePtr); + g_demo_filePtr->Write(&g_demo_cnt, sizeof(g_demo_cnt)); ud.recstat = ud.m_recstat = 0; - MAYBE_FCLOSE_AND_NULL(g_demo_filePtr); + delete g_demo_filePtr; + g_demo_filePtr = nullptr; sv_freemem(); diff --git a/source/rr/src/demo.h b/source/rr/src/demo.h index fafeea1c7..372b842fa 100644 --- a/source/rr/src/demo.h +++ b/source/rr/src/demo.h @@ -33,7 +33,7 @@ BEGIN_RR_NS #define LDEMOFN_FMT "demo%d.dmo" #define MAXDEMOS 1000 -extern FILE *g_demo_filePtr; +extern FileWriter * g_demo_filePtr; extern char g_firstDemoFile[BMAX_PATH]; extern int32_t g_demo_cnt; diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index ac77c66a2..ad1961488 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -361,8 +361,11 @@ void G_GameExit(const char *msg) if (ud.recstat == 1) G_CloseDemoWrite(); - else if (ud.recstat == 2) - MAYBE_FCLOSE_AND_NULL(g_demo_filePtr); + else if (ud.recstat == 2) + { + delete g_demo_filePtr; + g_demo_filePtr = nullptr; + } // JBF: fixes crash on demo playback // PK: modified from original diff --git a/source/rr/src/savegame.cpp b/source/rr/src/savegame.cpp index 868f42f23..52f7f3961 100644 --- a/source/rr/src/savegame.cpp +++ b/source/rr/src/savegame.cpp @@ -186,7 +186,7 @@ static void ReadSaveGameHeaders_CACHE1D(TArray& saves) static void ReadSaveGameHeaders_Internal(void) { - FString pattern = M_GetSavegamesPath() + "*.esv"; + FString pattern = M_GetSavegamesPath() + "*.bsv"; TArray saves; D_AddWildFile(saves, pattern); @@ -480,55 +480,52 @@ int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave) Net_WaitForEverybody(); ready2send = 0; - char temp[BMAX_PATH]; + FString fn; - errno = 0; - FILE *fil; + errno = 0; + buildvfs_FILE fil; - if (sv.isValid()) - { - if (snprintf(temp, sizeof(temp), "%s%s", M_GetSavegamesPath().GetChars(), sv.path)) - { - OSD_Printf("G_SavePlayer: file name \"%s\" too long\n", sv.path); - goto saveproblem; - } - fil = fopen(temp, "wb"); - } - else - { - static char const SaveName[] = "save0000.esv"; - int const len = snprintf(temp, ARRAY_SIZE(temp), "%s%s", M_GetSavegamesPath().GetChars(), SaveName); - if (len >= ARRAY_SSIZE(temp)-1) - { - OSD_Printf("G_SavePlayer: could not form automatic save path\n"); - goto saveproblem; - } - char * zeros = temp + (len-8); - fil = savecounter.opennextfile(temp, zeros); - savecounter.count++; - // don't copy the mod dir into sv.path - Bstrcpy(sv.path, temp + (len-(ARRAY_SIZE(SaveName)-1))); - } + if (sv.isValid()) + { + fn.Format("%s%s", M_GetSavegamesPath().GetChars(), sv.path); + fil = fopen(fn, "wb"); + } + else + { + static char const SaveName[] = "save0000.bsv"; + fn.Format("%s%s", M_GetSavegamesPath().GetChars(), SaveName); - if (!fil) - { - OSD_Printf("G_SavePlayer: failed opening \"%s\" for writing: %s\n", - temp, strerror(errno)); - goto saveproblem; - } + auto fnp = fn.LockBuffer(); + char* zeros = fnp + (fn.Len() - 8); + fil = savecounter.opennextfile(fnp, zeros); + fn.UnlockBuffer(); + savecounter.count++; + // don't copy the mod dir into sv.path + Bstrcpy(sv.path, fn + (fn.Len() - (ARRAY_SIZE(SaveName) - 1))); + } - // temporary hack - ud.user_map = G_HaveUserMap(); + FileWriter fw(fil); + if (!fil) + { + OSD_Printf("G_SavePlayer: failed opening \"%s\" for writing: %s\n", + fn, strerror(errno)); + ready2send = 1; + Net_WaitForEverybody(); -#ifdef POLYMER - if (videoGetRenderMode() == REND_POLYMER) - polymer_resetlights(); -#endif + G_RestoreTimers(); + ototalclock = totalclock; + return -1; + } + else + { + // temporary hack + ud.user_map = G_HaveUserMap(); - // SAVE! - sv_saveandmakesnapshot(fil, sv.name, 0, 0, 0, 0, isAutoSave); - fclose(fil); + // SAVE! + sv_saveandmakesnapshot(fw, sv.name, 0, 0, 0, 0, isAutoSave); + + fw.Close(); if (!g_netServer && ud.multimode < 2) { @@ -543,15 +540,7 @@ int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave) ototalclock = totalclock; return 0; - -saveproblem: - ready2send = 1; - Net_WaitForEverybody(); - - G_RestoreTimers(); - ototalclock = totalclock; - - return -1; + } } int32_t G_LoadPlayerMaybeMulti(savebrief_t & sv) @@ -637,7 +626,7 @@ static inline void ds_get(const dataspec_t *spec, void **ptr, int32_t *cnt) } // write state to file and/or to dump -static uint8_t *writespecdata(const dataspec_t *spec, FILE *fil, uint8_t *dump) +static uint8_t *writespecdata(const dataspec_t *spec, FileWriter *fil, uint8_t *dump) { for (; spec->flags != DS_END; spec++) { @@ -652,7 +641,7 @@ static uint8_t *writespecdata(const dataspec_t *spec, FILE *fil, uint8_t *dump) continue; else if (spec->flags & DS_STRING) { - fwrite(spec->ptr, Bstrlen((const char *)spec->ptr), 1, fil); // not null-terminated! + fil->Write(spec->ptr, Bstrlen((const char *)spec->ptr)); // not null-terminated! continue; } @@ -672,7 +661,7 @@ static uint8_t *writespecdata(const dataspec_t *spec, FILE *fil, uint8_t *dump) if (fil) { - fwrite(ptr, spec->size, cnt, fil); + fil->Write(ptr, spec->size * cnt); } if (dump && (spec->flags & (DS_NOCHK|DS_CMP)) == 0) @@ -739,7 +728,7 @@ static int32_t readspecdata(const dataspec_t *spec, FileReader *fil, uint8_t **d if (!ptr || !cnt) continue; - if (fil->isOpen()) + if (fil != nullptr && fil->isOpen()) { auto const mem = (dump && (spec->flags & DS_NOCHK) == 0) ? dump : (uint8_t *)ptr; int const siz = cnt * spec->size; @@ -1267,7 +1256,7 @@ static const dataspec_t svgm_anmisc[] = { DS_END, 0, 0, 0 } }; -static uint8_t *dosaveplayer2(FILE *fil, uint8_t *mem); +static uint8_t *dosaveplayer2(FileWriter *fil, uint8_t *mem); static int32_t doloadplayer2(FileReader &fil, uint8_t **memptr); static void postloadplayer(int32_t savegamep); @@ -1299,7 +1288,7 @@ static void SV_AllocSnap(int32_t allocinit) } // make snapshot only if spot < 0 (demo) -int32_t sv_saveandmakesnapshot(FILE *fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress, bool isAutoSave) +int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress, bool isAutoSave) { savehead_t h; @@ -1347,10 +1336,6 @@ int32_t sv_saveandmakesnapshot(FILE *fil, char const *name, int8_t spot, int8_t { // savegame Bstrncpyz(h.savename, name, sizeof(h.savename)); -#ifdef __ANDROID__ - Bstrncpyz(h.volname, g_volumeNames[ud.volume_number], sizeof(h.volname)); - Bstrncpyz(h.skillname, g_skillNames[ud.player_skill], sizeof(h.skillname)); -#endif } else { @@ -1367,40 +1352,37 @@ int32_t sv_saveandmakesnapshot(FILE *fil, char const *name, int8_t spot, int8_t // write header - fwrite(&h, sizeof(savehead_t), 1, fil); + fil.Write(&h, sizeof(savehead_t)); // for savegames, the file offset after the screenshot goes here; // for demos, we keep it 0 to signify that we didn't save one - fwrite("\0\0\0\0", 4, 1, fil); if (spot >= 0 && tileData(TILE_SAVESHOT)) { - int32_t ofs; - + + int v = 64000; + fil.Write(&v, 4); // write the screenshot compressed - fwrite(tileData(TILE_SAVESHOT), 320, 200, fil); + fil.Write(tileData(TILE_SAVESHOT), 320*200); - // write the current file offset right after the header - ofs = ftell(fil); - fseek(fil, sizeof(savehead_t), SEEK_SET); - fwrite(&ofs, 4, 1, fil); - fseek(fil, ofs, SEEK_SET); } + else + { + int v = 0; + fil.Write(&v, 4); + } -#ifdef DEBUGGINGAIDS - OSD_Printf("sv_saveandmakesnapshot: snapshot size: %d bytes.\n", svsnapsiz); -#endif if (spot >= 0) { // savegame - dosaveplayer2(fil, NULL); + dosaveplayer2(&fil, NULL); } else { // demo SV_AllocSnap(0); - uint8_t * const p = dosaveplayer2(fil, svsnapshot); + uint8_t * const p = dosaveplayer2(&fil, svsnapshot); if (p != svsnapshot+svsnapsiz) { @@ -1441,7 +1423,7 @@ int32_t sv_loadheader(FileReader &fil, int32_t spot, savehead_t *h) #ifndef DEBUGGINGAIDS if (havedemo) #endif - OSD_Printf("Incompatible file version. Expected %d.%d.%d.%d.%0x, found %d.%d.%d.%d.%0x\n", SV_MAJOR_VER, SV_MINOR_VER, BYTEVERSION, + OSD_Printf("Incompatible savegame. Expected version %d.%d.%d.%d.%0x, found %d.%d.%d.%d.%0x\n", SV_MAJOR_VER, SV_MINOR_VER, BYTEVERSION, ud.userbytever, g_scriptcrc, h->majorver, h->minorver, h->bytever, h->userbytever, h->scriptcrc); if (h->majorver == SV_MAJOR_VER && h->minorver == SV_MINOR_VER) @@ -1500,8 +1482,8 @@ int32_t sv_loadsnapshot(FileReader &fil, int32_t spot, savehead_t *h) } if (i > 0) { - if (fil.Seek(i, FileReader::SeekSet) != i) - { + if (fil.Seek(i, FileReader::SeekCur) < 0) + { OSD_Printf("sv_snapshot: failed skipping over the screenshot.\n"); return 8; } @@ -1554,7 +1536,7 @@ int32_t sv_loadsnapshot(FileReader &fil, int32_t spot, savehead_t *h) } -uint32_t sv_writediff(FILE *fil) +uint32_t sv_writediff(FileWriter *fil) { uint8_t *p = svsnapshot; uint8_t *d = svdiff; @@ -1569,10 +1551,10 @@ uint32_t sv_writediff(FILE *fil) uint32_t const diffsiz = d - svdiff; - fwrite("dIfF",4,1,fil); - fwrite(&diffsiz, sizeof(diffsiz), 1, fil); + fil->Write("dIfF",4); + fil->Write(&diffsiz, sizeof(diffsiz)); - fwrite(svdiff, 1, diffsiz, fil); + fil->Write(svdiff, diffsiz); return diffsiz; } @@ -1746,7 +1728,7 @@ static void sv_restload() # define PRINTSIZE(name) do { } while (0) #endif -static uint8_t *dosaveplayer2(FILE *fil, uint8_t *mem) +static uint8_t *dosaveplayer2(FileWriter *fil, uint8_t *mem) { #ifdef DEBUGGINGAIDS uint8_t *tmem = mem; diff --git a/source/rr/src/savegame.h b/source/rr/src/savegame.h index 4aadb3fbf..d4f912af6 100644 --- a/source/rr/src/savegame.h +++ b/source/rr/src/savegame.h @@ -111,11 +111,11 @@ extern menusave_t * g_menusaves; extern uint16_t g_nummenusaves; int32_t sv_updatestate(int32_t frominit); -int32_t sv_readdiff(FileReader &fil); -uint32_t sv_writediff(FILE *fil); -int32_t sv_loadheader(FileReader& fil, int32_t spot, savehead_t* h); -int32_t sv_loadsnapshot(FileReader& fil, int32_t spot, savehead_t* h); -int32_t sv_saveandmakesnapshot(FILE *fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress, bool isAutoSave = false); +int32_t sv_readdiff(FileReader& fil); +uint32_t sv_writediff(FileWriter *fil); +int32_t sv_loadheader(FileReader &fil, int32_t spot, savehead_t *h); +int32_t sv_loadsnapshot(FileReader &fil, int32_t spot, savehead_t *h); +int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress, bool isAutoSave = false); void sv_freemem(); void G_DeleteSave(savebrief_t const & sv); void G_DeleteOldSaves(void);