Changed string paramaters for save functions to proper const pointer type.

Implemented subsectional saving (handled in the section's save function, and passed to the save function by & pointer). Default of "all" passed in from SaveFile for game saves.

Implemented subsectional saving for sohStats and entrances/scenes discovered.

Fixed check for game save registry by putting the check against the registry in the "all" section save code.
This commit is contained in:
Malkierian 2023-05-13 11:26:30 -07:00
parent 42b35634a5
commit dbe672444c
4 changed files with 86 additions and 61 deletions

View File

@ -233,47 +233,54 @@ void LoadStatsVersion1() {
[](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.sohStats.locationsSkipped[i]); });
}
void SaveStats(SaveContext* saveContext) {
SaveManager::Instance->SaveData("buildVersion", saveContext->sohStats.buildVersion);
SaveManager::Instance->SaveData("buildVersionMajor", saveContext->sohStats.buildVersionMajor);
SaveManager::Instance->SaveData("buildVersionMinor", saveContext->sohStats.buildVersionMinor);
SaveManager::Instance->SaveData("buildVersionPatch", saveContext->sohStats.buildVersionPatch);
void SaveStats(SaveContext* saveContext, const std::string& subSection) {
if (subSection == "all") {
SaveManager::Instance->SaveData("buildVersion", saveContext->sohStats.buildVersion);
SaveManager::Instance->SaveData("buildVersionMajor", saveContext->sohStats.buildVersionMajor);
SaveManager::Instance->SaveData("buildVersionMinor", saveContext->sohStats.buildVersionMinor);
SaveManager::Instance->SaveData("buildVersionPatch", saveContext->sohStats.buildVersionPatch);
SaveManager::Instance->SaveData("heartPieces", saveContext->sohStats.heartPieces);
SaveManager::Instance->SaveData("heartContainers", saveContext->sohStats.heartContainers);
SaveManager::Instance->SaveArray("dungeonKeys", ARRAY_COUNT(saveContext->sohStats.dungeonKeys), [&](size_t i) {
SaveManager::Instance->SaveData("", saveContext->sohStats.dungeonKeys[i]);
});
SaveManager::Instance->SaveData("playTimer", saveContext->sohStats.playTimer);
SaveManager::Instance->SaveData("pauseTimer", saveContext->sohStats.pauseTimer);
SaveManager::Instance->SaveArray(
"itemTimestamps", ARRAY_COUNT(saveContext->sohStats.itemTimestamp),
[&](size_t i) { SaveManager::Instance->SaveData("", saveContext->sohStats.itemTimestamp[i]); });
SaveManager::Instance->SaveArray(
"sceneTimestamps", ARRAY_COUNT(saveContext->sohStats.sceneTimestamps), [&](size_t i) {
if (saveContext->sohStats.sceneTimestamps[i].scene != 254 && saveContext->sohStats.sceneTimestamps[i].room != 254) {
SaveManager::Instance->SaveStruct("", [&]() {
SaveManager::Instance->SaveData("scene", saveContext->sohStats.sceneTimestamps[i].scene);
SaveManager::Instance->SaveData("room", saveContext->sohStats.sceneTimestamps[i].room);
SaveManager::Instance->SaveData("sceneTime", saveContext->sohStats.sceneTimestamps[i].sceneTime);
SaveManager::Instance->SaveData("roomTime", saveContext->sohStats.sceneTimestamps[i].roomTime);
SaveManager::Instance->SaveData("isRoom", saveContext->sohStats.sceneTimestamps[i].isRoom);
});
}
SaveManager::Instance->SaveData("heartPieces", saveContext->sohStats.heartPieces);
SaveManager::Instance->SaveData("heartContainers", saveContext->sohStats.heartContainers);
SaveManager::Instance->SaveArray("dungeonKeys", ARRAY_COUNT(saveContext->sohStats.dungeonKeys), [&](size_t i) {
SaveManager::Instance->SaveData("", saveContext->sohStats.dungeonKeys[i]);
});
SaveManager::Instance->SaveData("tsIdx", saveContext->sohStats.tsIdx);
SaveManager::Instance->SaveArray("counts", ARRAY_COUNT(saveContext->sohStats.count), [&](size_t i) {
SaveManager::Instance->SaveData("", saveContext->sohStats.count[i]);
});
SaveManager::Instance->SaveArray(
"scenesDiscovered", ARRAY_COUNT(saveContext->sohStats.scenesDiscovered),
[&](size_t i) { SaveManager::Instance->SaveData("", saveContext->sohStats.scenesDiscovered[i]); });
SaveManager::Instance->SaveArray(
"entrancesDiscovered", ARRAY_COUNT(saveContext->sohStats.entrancesDiscovered),
[&](size_t i) { SaveManager::Instance->SaveData("", saveContext->sohStats.entrancesDiscovered[i]); });
SaveManager::Instance->SaveArray(
"locationsSkipped", ARRAY_COUNT(saveContext->sohStats.locationsSkipped),
[&](size_t i) { SaveManager::Instance->SaveData("", saveContext->sohStats.locationsSkipped[i]); });
SaveManager::Instance->SaveData("playTimer", saveContext->sohStats.playTimer);
SaveManager::Instance->SaveData("pauseTimer", saveContext->sohStats.pauseTimer);
SaveManager::Instance->SaveArray(
"itemTimestamps", ARRAY_COUNT(saveContext->sohStats.itemTimestamp),
[&](size_t i) { SaveManager::Instance->SaveData("", saveContext->sohStats.itemTimestamp[i]); });
SaveManager::Instance->SaveArray(
"sceneTimestamps", ARRAY_COUNT(saveContext->sohStats.sceneTimestamps), [&](size_t i) {
if (saveContext->sohStats.sceneTimestamps[i].scene != 254 &&
saveContext->sohStats.sceneTimestamps[i].room != 254) {
SaveManager::Instance->SaveStruct("", [&]() {
SaveManager::Instance->SaveData("scene", saveContext->sohStats.sceneTimestamps[i].scene);
SaveManager::Instance->SaveData("room", saveContext->sohStats.sceneTimestamps[i].room);
SaveManager::Instance->SaveData("sceneTime", saveContext->sohStats.sceneTimestamps[i].sceneTime);
SaveManager::Instance->SaveData("roomTime", saveContext->sohStats.sceneTimestamps[i].roomTime);
SaveManager::Instance->SaveData("isRoom", saveContext->sohStats.sceneTimestamps[i].isRoom);
});
}
});
SaveManager::Instance->SaveData("tsIdx", saveContext->sohStats.tsIdx);
SaveManager::Instance->SaveArray("counts", ARRAY_COUNT(saveContext->sohStats.count), [&](size_t i) {
SaveManager::Instance->SaveData("", saveContext->sohStats.count[i]);
});
SaveManager::Instance->SaveArray(
"locationsSkipped", ARRAY_COUNT(saveContext->sohStats.locationsSkipped),
[&](size_t i) { SaveManager::Instance->SaveData("", saveContext->sohStats.locationsSkipped[i]); });
}
if (subSection == "entrances" || subSection == "all") {
SaveManager::Instance->SaveArray("entrancesDiscovered", ARRAY_COUNT(saveContext->sohStats.entrancesDiscovered), [&](size_t i) {
SaveManager::Instance->SaveData("", saveContext->sohStats.entrancesDiscovered[i]);
});
}
if (subSection == "scenes" || subSection == "all") {
SaveManager::Instance->SaveArray("scenesDiscovered", ARRAY_COUNT(saveContext->sohStats.scenesDiscovered), [&](size_t i) {
SaveManager::Instance->SaveData("", saveContext->sohStats.scenesDiscovered[i]);
});
}
}
void InitStats(bool isDebug) {

View File

@ -769,6 +769,7 @@ void Entrance_SetSceneDiscovered(u8 sceneNum) {
u32 sceneBit = 1 << (sceneNum - (idx * bitsPerIndex));
gSaveContext.sohStats.scenesDiscovered[idx] |= sceneBit;
}
Save_SaveSection("sohStats.scenes");
}
u8 Entrance_GetIsEntranceDiscovered(u16 entranceIndex) {
@ -801,4 +802,5 @@ void Entrance_SetEntranceDiscovered(u16 entranceIndex) {
}
}
}
Save_SaveSection("sohStats.entrances");
}

View File

@ -279,7 +279,7 @@ void SaveManager::LoadRandomizerVersion2() {
});
}
void SaveManager::SaveRandomizer(SaveContext* saveContext) {
void SaveManager::SaveRandomizer(SaveContext* saveContext, const std::string& subString) {
if (!saveContext->n64ddFlag)
return;
@ -709,26 +709,32 @@ void SaveManager::InitFileDebug() {
}
// Threaded SaveFile takes copy of gSaveContext for local unmodified storage
void SaveManager::SaveFileThreaded(int fileNum, SaveContext* saveContext, const std::string sectionString) {
/*nlohmann::json baseBlock;
baseBlock["version"] = 1;
baseBlock["sections"] = nlohmann::json::object();*/
void SaveManager::SaveFileThreaded(int fileNum, SaveContext* saveContext, const std::string& sectionString) {
saveBlock["version"] = 1;
size_t period = sectionString.find(".");
std::string section = sectionString;
std::string subsection = "";
if (period != std::string::npos) {
subsection = sectionString.substr(period + 1, std::string::npos);
section = sectionString.substr(0, sectionString.length() - (subsection.length() + 1));
}
if (sectionString == "all") {
for (auto& sectionHandler : sectionSaveHandlers) {
nlohmann::json& sectionBlock = saveBlock["sections"][sectionHandler.first];
sectionBlock["version"] = sectionHandler.second.first;
sectionBlock["data"] = nlohmann::json::object();
if (std::find(gameSaveRegistry.begin(), gameSaveRegistry.end(), sectionHandler.first) != gameSaveRegistry.end()) {
nlohmann::json& sectionBlock = saveBlock["sections"][sectionHandler.first];
sectionBlock["version"] = sectionHandler.second.first;
sectionBlock["data"] = nlohmann::json::object();
currentJsonContext = &sectionBlock["data"];
sectionHandler.second.second(saveContext);
currentJsonContext = &sectionBlock["data"];
sectionHandler.second.second(saveContext, "all");
}
}
} else if (sectionSaveHandlers.contains(sectionString) && std::find(gameSaveRegistry.begin(), gameSaveRegistry.end(), sectionString) != gameSaveRegistry.end()) {
SectionSaveHandler handler = sectionSaveHandlers.find(sectionString)->second;
nlohmann::json& sectionBlock = saveBlock["sections"][sectionString];
} else if (sectionSaveHandlers.contains(section)) {
SectionSaveHandler handler = sectionSaveHandlers.find(section)->second;
nlohmann::json& sectionBlock = saveBlock["sections"][section];
sectionBlock["version"] = handler.first;
currentJsonContext = &sectionBlock["data"];
handler.second(saveContext);
handler.second(saveContext, subsection);
} else {
return;
}
@ -748,14 +754,18 @@ void SaveManager::SaveFileThreaded(int fileNum, SaveContext* saveContext, const
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSaveFile>(fileNum);
}
void SaveManager::SaveFile(int fileNum) {
void SaveManager::SaveSection(int fileNum, const std::string& sectionString) {
if (fileNum == 0xFF) {
return;
}
// Can't think of any time the promise would be needed, so use push_task instead of submit
auto saveContext = new SaveContext;
memcpy(saveContext, &gSaveContext, sizeof(gSaveContext));
smThreadPool->push_task_back(&SaveManager::SaveFileThreaded, this, fileNum, saveContext, "all");
smThreadPool->push_task_back(&SaveManager::SaveFileThreaded, this, fileNum, saveContext, sectionString);
}
void SaveManager::SaveFile(int fileNum) {
SaveSection(fileNum, "all");
}
void SaveManager::SaveGlobal() {
@ -1616,7 +1626,7 @@ void SaveManager::LoadBaseVersion4() {
SaveManager::Instance->LoadData("dogParams", gSaveContext.dogParams);
}
void SaveManager::SaveBase(SaveContext* saveContext) {
void SaveManager::SaveBase(SaveContext* saveContext, const std::string& subString) {
SaveManager::Instance->SaveData("entranceIndex", saveContext->entranceIndex);
SaveManager::Instance->SaveData("linkAge", saveContext->linkAge);
SaveManager::Instance->SaveData("cutsceneIndex", saveContext->cutsceneIndex);
@ -2281,6 +2291,10 @@ extern "C" void Save_SaveFile(void) {
SaveManager::Instance->SaveFile(gSaveContext.fileNum);
}
extern "C" void Save_SaveSection(char* sectionString) {
SaveManager::Instance->SaveSection(gSaveContext.fileNum, sectionString);
}
extern "C" void Save_SaveGlobal(void) {
SaveManager::Instance->SaveGlobal();
}

View File

@ -45,7 +45,7 @@ public:
using InitFunc = void(*)(bool isDebug);
using LoadFunc = void(*)();
using SaveFunc = void(*)(SaveContext* saveContext);
using SaveFunc = void(*)(SaveContext* saveContext, const std::string& subSection);
using PostFunc = void(*)(int version);
SaveManager();
@ -53,6 +53,7 @@ public:
void Init();
void InitFile(bool isDebug);
void SaveFile(int fileNum);
void SaveSection(int fileNum, const std::string& sectionString);
void SaveGlobal();
void LoadFile(int fileNum);
bool SaveFile_Exist(int fileNum);
@ -128,7 +129,7 @@ public:
void ConvertFromUnversioned();
void CreateDefaultGlobal();
void SaveFileThreaded(int fileNum, SaveContext* saveContext, const std::string sectionString);
void SaveFileThreaded(int fileNum, SaveContext* saveContext, const std::string& sectionString);
void InitMeta(int slotNum);
static void InitFileImpl(bool isDebug);
@ -137,13 +138,13 @@ public:
static void LoadRandomizerVersion1();
static void LoadRandomizerVersion2();
static void SaveRandomizer(SaveContext* saveContext);
static void SaveRandomizer(SaveContext* saveContext, const std::string& subString);
static void LoadBaseVersion1();
static void LoadBaseVersion2();
static void LoadBaseVersion3();
static void LoadBaseVersion4();
static void SaveBase(SaveContext* saveContext);
static void SaveBase(SaveContext* saveContext, const std::string& subString);
std::vector<InitFunc> initFuncs;
@ -172,6 +173,7 @@ typedef void (*Save_SaveFunc)(const SaveContext* saveContext);
void Save_Init(void);
void Save_InitFile(int isDebug);
void Save_SaveFile(void);
void Save_SaveSection(char* sectionString);
void Save_SaveGlobal(void);
void Save_LoadGlobal(void);
void Save_AddLoadFunction(char* name, int version, Save_LoadFunc func);