You've already forked 2ship2harkinian-Android
mirror of
https://github.com/izzy2lost/2ship2harkinian-Android.git
synced 2026-03-10 11:20:47 -07:00
Rework save files organization (#445)
This commit is contained in:
@@ -9,6 +9,7 @@ shipofharkinian.json
|
||||
*.sav
|
||||
.envrc
|
||||
imgui.ini
|
||||
saves/*
|
||||
|
||||
mm/libultraship/extern/Debug/ImGui.lib
|
||||
|
||||
|
||||
@@ -696,11 +696,11 @@ bool BinarySaveConverter_HandleFileDropped(std::string filePath) {
|
||||
reader->Seek(saveOffsets[0] - 0x24, Ship::SeekOffsetType::Start);
|
||||
BinarySaveConverter_ReadBufferToSave(&saveContext, reader);
|
||||
nlohmann::json j;
|
||||
std::string fileName = "save_" + std::to_string(saveSlot) + ".sav";
|
||||
std::string fileName = SaveManager_GetFileName(saveSlot);
|
||||
|
||||
j["save"] = saveContext.save;
|
||||
|
||||
SaveManager_WriteSaveFile(fileName, j);
|
||||
j["newCycleSave"]["save"] = saveContext.save;
|
||||
j["type"] = "2S2H_SAVE";
|
||||
j["version"] = 4;
|
||||
|
||||
// Based on where the save was found, determine if the two possible owl save offsets are in the list of save
|
||||
// offsets. If they are, we can assume that the save is the owl save associated with the other file above
|
||||
@@ -716,14 +716,12 @@ bool BinarySaveConverter_HandleFileDropped(std::string filePath) {
|
||||
if (foundOwlSave) {
|
||||
memset(&saveContext, 0, sizeof(Legacy_SaveContext));
|
||||
BinarySaveConverter_ReadBufferToSave(&saveContext, reader);
|
||||
fileName = "save_" + std::to_string(saveSlot + 4) + ".sav";
|
||||
nlohmann::json j2;
|
||||
|
||||
j2 = saveContext;
|
||||
|
||||
SaveManager_WriteSaveFile(fileName, j2);
|
||||
j["owlSave"] = saveContext;
|
||||
}
|
||||
|
||||
SaveManager_WriteSaveFile(fileName, j);
|
||||
|
||||
if (gFileSelectState != NULL) {
|
||||
func_801457CC(&gFileSelectState->state, &gFileSelectState->sramCtx);
|
||||
if (gFileSelectState->menuMode == FS_MENU_MODE_CONFIG && gFileSelectState->configMode == CM_MAIN_MENU) {
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "2s2h/SaveManager/SaveManager.h"
|
||||
#include "z64.h"
|
||||
|
||||
// Final legacy migration, prior to merging owl saves into main save file.
|
||||
void SaveManager_Migration_4(nlohmann::json& j) {
|
||||
nlohmann::json rootSave;
|
||||
rootSave["newCycleSave"] = j;
|
||||
|
||||
j = rootSave;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "2s2h/SaveManager/SaveManager.h"
|
||||
#include "z64.h"
|
||||
|
||||
// This is the base migration, binary saves are imported as this version.
|
||||
void SaveManager_Migration_5(nlohmann::json& j) {
|
||||
nlohmann::json dpadEquips;
|
||||
for (int i = 0; i < EQUIP_SLOT_D_MAX; i++) {
|
||||
for (int j = 0; j < EQUIP_SLOT_D_MAX; j++) {
|
||||
dpadEquips["dpadItems"][i][j] = ITEM_NONE;
|
||||
dpadEquips["dpadSlots"][i][j] = SLOT_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
// if shipSaveInfo doesn't exist, create it
|
||||
if (!j["save"].contains("shipSaveInfo")) {
|
||||
j["save"]["shipSaveInfo"]["dpadEquips"] = dpadEquips;
|
||||
j["save"]["shipSaveInfo"]["pauseSaveEntrance"] = -1;
|
||||
}
|
||||
}
|
||||
+235
-117
@@ -34,7 +34,7 @@ typedef enum FlashSlotFile {
|
||||
((GET_NEWF(save, 0) == 'Z') && (GET_NEWF(save, 1) == 'E') && (GET_NEWF(save, 2) == 'L') && \
|
||||
(GET_NEWF(save, 3) == 'D') && (GET_NEWF(save, 4) == 'A') && (GET_NEWF(save, 5) == '3'))
|
||||
|
||||
const std::filesystem::path savesFolderPath(Ship::Context::GetPathRelativeToAppDirectory("Save"));
|
||||
const std::filesystem::path savesFolderPath(Ship::Context::GetPathRelativeToAppDirectory("saves"));
|
||||
|
||||
// Migrations
|
||||
// The idea here is that we can read in any version of the save as generic JSON, then apply migrations
|
||||
@@ -46,28 +46,60 @@ const std::filesystem::path savesFolderPath(Ship::Context::GetPathRelativeToAppD
|
||||
// - Create the migration file in the Migrations folder with the name `{CURRENT_SAVE_VERSION}.cpp`
|
||||
// - Add the migration function definition below and add it to the `migrations` map with the key being the previous
|
||||
// version
|
||||
const uint32_t CURRENT_SAVE_VERSION = 3;
|
||||
const uint32_t CURRENT_SAVE_VERSION = 5;
|
||||
|
||||
void SaveManager_Migration_1(nlohmann::json& j);
|
||||
void SaveManager_Migration_2(nlohmann::json& j);
|
||||
void SaveManager_Migration_3(nlohmann::json& j);
|
||||
void SaveManager_Migration_4(nlohmann::json& j);
|
||||
void SaveManager_Migration_5(nlohmann::json& j);
|
||||
|
||||
const std::unordered_map<uint32_t, std::function<void(nlohmann::json&)>> migrations = {
|
||||
// Pre-1.0.0 Migrations, deprecated
|
||||
{ 0, SaveManager_Migration_1 },
|
||||
{ 1, SaveManager_Migration_2 },
|
||||
{ 2, SaveManager_Migration_3 },
|
||||
{ 3, SaveManager_Migration_4 },
|
||||
// Base Migration
|
||||
{ 4, SaveManager_Migration_5 },
|
||||
};
|
||||
|
||||
void SaveManager_MigrateSave(nlohmann::json& j) {
|
||||
int SaveManager_MigrateSave(nlohmann::json& j) {
|
||||
int version = j.value("version", 0);
|
||||
|
||||
// BENTODO: what should we do if the version number is greater?
|
||||
while (version < CURRENT_SAVE_VERSION) {
|
||||
if (migrations.contains(version)) {
|
||||
auto migration = migrations.at(version);
|
||||
migration(j);
|
||||
if (version > CURRENT_SAVE_VERSION) {
|
||||
SPDLOG_ERROR("Save version is greater than current version");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (version >= 4 && !j.contains("newCycleSave") && !j.contains("owlSave")) {
|
||||
SPDLOG_ERROR("Save file is missing newCycleSave and owlSave");
|
||||
return -1;
|
||||
}
|
||||
|
||||
try {
|
||||
while (version < CURRENT_SAVE_VERSION) {
|
||||
if (migrations.contains(version)) {
|
||||
auto migration = migrations.at(version);
|
||||
if (version < 4) {
|
||||
migration(j); // Pre-1.0.0 Migrations, deprecated
|
||||
} else {
|
||||
// In the case of copying files, the owl save is copied first, so the new cycle may not exist yet.
|
||||
if (j.contains("newCycleSave")) {
|
||||
migration(j["newCycleSave"]);
|
||||
}
|
||||
// Only migrate the owl save if it exists
|
||||
if (j.contains("owlSave")) {
|
||||
migration(j["owlSave"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
version = j["version"] = version + 1;
|
||||
}
|
||||
version = j["version"] = version + 1;
|
||||
return 0;
|
||||
} catch (...) {
|
||||
SPDLOG_ERROR("Failed to migrate save file");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,17 +110,21 @@ void SaveManager_WriteSaveFile(std::filesystem::path fileName, nlohmann::json j)
|
||||
std::filesystem::create_directory(savesFolderPath);
|
||||
}
|
||||
|
||||
std::ofstream o(filePath);
|
||||
o << std::setw(4) << j << std::endl;
|
||||
o.close();
|
||||
try {
|
||||
std::ofstream o(filePath);
|
||||
o << std::setw(4) << j << std::endl;
|
||||
o.close();
|
||||
} catch (...) { SPDLOG_ERROR("Failed to write save file"); }
|
||||
}
|
||||
|
||||
void SaveManager_DeleteSaveFile(std::filesystem::path fileName) {
|
||||
const std::filesystem::path filePath = savesFolderPath / fileName;
|
||||
|
||||
if (std::filesystem::exists(filePath)) {
|
||||
std::filesystem::remove(filePath);
|
||||
}
|
||||
try {
|
||||
if (std::filesystem::exists(filePath)) {
|
||||
std::filesystem::remove(filePath);
|
||||
}
|
||||
} catch (...) { SPDLOG_ERROR("Failed to delete save file"); }
|
||||
}
|
||||
|
||||
int SaveManager_ReadSaveFile(std::filesystem::path fileName, nlohmann::json& j) {
|
||||
@@ -98,19 +134,39 @@ int SaveManager_ReadSaveFile(std::filesystem::path fileName, nlohmann::json& j)
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::ifstream i(filePath);
|
||||
i >> j;
|
||||
i.close();
|
||||
return 0;
|
||||
try {
|
||||
std::ifstream i(filePath);
|
||||
i >> j;
|
||||
i.close();
|
||||
return 0;
|
||||
} catch (...) {
|
||||
SPDLOG_ERROR("Failed to read save file");
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
void SaveManager_MoveInvalidSaveFile(std::filesystem::path fileName, std::string message) {
|
||||
const std::filesystem::path filePath = savesFolderPath / fileName;
|
||||
const std::filesystem::path backupFilePath =
|
||||
savesFolderPath / (fileName.stem().string() + "_invalid_" + std::to_string(std::time(nullptr)) + ".json");
|
||||
|
||||
try {
|
||||
if (std::filesystem::exists(filePath)) {
|
||||
std::filesystem::rename(filePath, backupFilePath);
|
||||
}
|
||||
|
||||
auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui();
|
||||
gui->GetGameOverlay()->TextDrawNotification(30.0f, true, message.c_str());
|
||||
} catch (...) { SPDLOG_ERROR("Failed to move invalid save file"); }
|
||||
}
|
||||
|
||||
int SaveManager_GetOpenFileSlot() {
|
||||
std::string fileName = "save_0.sav";
|
||||
std::string fileName = "file1.json";
|
||||
if (!std::filesystem::exists(savesFolderPath / fileName)) {
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
fileName = "save_2.sav";
|
||||
fileName = "file2.json";
|
||||
if (!std::filesystem::exists(savesFolderPath / fileName)) {
|
||||
return 2;
|
||||
}
|
||||
@@ -118,6 +174,50 @@ int SaveManager_GetOpenFileSlot() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
FlashSlotFile SaveManager_GetFlashSlotFileFromPages(u32 pageNum, u32 pageCount) {
|
||||
FlashSlotFile flashSlotFile = FLASH_SLOT_FILE_UNAVAILABLE;
|
||||
|
||||
for (u32 i = 0; i < ARRAY_COUNT(gFlashSaveStartPages) - 1; i++) {
|
||||
// Verify that the requested pages align with expected values
|
||||
if (pageNum == (u32)gFlashSaveStartPages[i] &&
|
||||
(pageCount == (u32)gFlashSaveNumPages[i] || pageCount == (u32)gFlashSpecialSaveNumPages[i])) {
|
||||
flashSlotFile = static_cast<FlashSlotFile>(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return flashSlotFile;
|
||||
}
|
||||
|
||||
std::string SaveManager_GetFileName(int fileNum, bool isBackup) {
|
||||
return "file" + std::to_string(fileNum) + (isBackup ? "backup" : "") + ".json";
|
||||
}
|
||||
|
||||
std::string SaveManager_GetFileNameFromFlashSlotFile(FlashSlotFile flashSlotFile) {
|
||||
if (flashSlotFile == FLASH_SLOT_FILE_UNAVAILABLE)
|
||||
return "invalid";
|
||||
|
||||
if (flashSlotFile == FLASH_SLOT_FILE_SRAM_HEADER || flashSlotFile == FLASH_SLOT_FILE_SRAM_HEADER_BACKUP) {
|
||||
return "global.json";
|
||||
}
|
||||
|
||||
bool isBackup =
|
||||
flashSlotFile == FLASH_SLOT_FILE_1_NEW_CYCLE_BACKUP || flashSlotFile == FLASH_SLOT_FILE_2_NEW_CYCLE_BACKUP ||
|
||||
flashSlotFile == FLASH_SLOT_FILE_1_OWL_SAVE_BACKUP || flashSlotFile == FLASH_SLOT_FILE_2_OWL_SAVE_BACKUP;
|
||||
|
||||
int fileNum =
|
||||
(flashSlotFile == FLASH_SLOT_FILE_1_NEW_CYCLE_BACKUP || flashSlotFile == FLASH_SLOT_FILE_1_NEW_CYCLE ||
|
||||
flashSlotFile == FLASH_SLOT_FILE_1_OWL_SAVE_BACKUP || flashSlotFile == FLASH_SLOT_FILE_1_OWL_SAVE)
|
||||
? 1
|
||||
: 2;
|
||||
|
||||
bool isOwlSave =
|
||||
(flashSlotFile == FLASH_SLOT_FILE_1_OWL_SAVE || flashSlotFile == FLASH_SLOT_FILE_1_OWL_SAVE_BACKUP ||
|
||||
flashSlotFile == FLASH_SLOT_FILE_2_OWL_SAVE || flashSlotFile == FLASH_SLOT_FILE_2_OWL_SAVE_BACKUP);
|
||||
|
||||
return "file" + std::to_string(fileNum) + (isBackup ? "backup" : "") + ".json";
|
||||
}
|
||||
|
||||
bool SaveManager_HandleFileDropped(std::string filePath) {
|
||||
try {
|
||||
std::ifstream fileStream(filePath);
|
||||
@@ -134,13 +234,9 @@ bool SaveManager_HandleFileDropped(std::string filePath) {
|
||||
nlohmann::json j;
|
||||
try {
|
||||
fileStream >> j;
|
||||
} catch (nlohmann::json::parse_error& e) {
|
||||
SPDLOG_ERROR("Failed to parse JSON: {}", e.what());
|
||||
return false;
|
||||
}
|
||||
} catch (nlohmann::json::parse_error& e) { return false; }
|
||||
|
||||
if (!j.contains("type") || j["type"] != "2S2H_SAVE") {
|
||||
SPDLOG_ERROR("Invalid save file type");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -152,7 +248,7 @@ bool SaveManager_HandleFileDropped(std::string filePath) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string fileName = "save_" + std::to_string(saveSlot) + ".sav";
|
||||
std::string fileName = SaveManager_GetFileName(saveSlot);
|
||||
|
||||
SaveManager_WriteSaveFile(fileName, j);
|
||||
|
||||
@@ -178,20 +274,24 @@ bool SaveManager_HandleFileDropped(std::string filePath) {
|
||||
}
|
||||
|
||||
extern "C" void SaveManager_SysFlashrom_WriteData(u8* saveBuffer, u32 pageNum, u32 pageCount) {
|
||||
FlashSlotFile flashSlotFile = FLASH_SLOT_FILE_UNAVAILABLE;
|
||||
FlashSlotFile flashSlotFile = SaveManager_GetFlashSlotFileFromPages(pageNum, pageCount);
|
||||
std::string fileName = SaveManager_GetFileNameFromFlashSlotFile(flashSlotFile);
|
||||
|
||||
bool isBackup = false;
|
||||
for (u32 i = 0; i < ARRAY_COUNT(gFlashSaveStartPages) - 1; i++) {
|
||||
// Verify that the requested pages align with expected values
|
||||
if (pageNum == (u32)gFlashSaveStartPages[i] &&
|
||||
(pageCount == (u32)gFlashSaveNumPages[i] || pageCount == (u32)gFlashSpecialSaveNumPages[i])) {
|
||||
flashSlotFile = static_cast<FlashSlotFile>(i);
|
||||
break;
|
||||
}
|
||||
|
||||
if (flashSlotFile == FLASH_SLOT_FILE_UNAVAILABLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (flashSlotFile == FLASH_SLOT_FILE_SRAM_HEADER || flashSlotFile == FLASH_SLOT_FILE_SRAM_HEADER_BACKUP) {
|
||||
SaveOptions saveOptions;
|
||||
memcpy(&saveOptions, saveBuffer, sizeof(SaveOptions));
|
||||
|
||||
SaveManager_WriteSaveFile(fileName, saveOptions);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (flashSlotFile) {
|
||||
case FLASH_SLOT_FILE_UNAVAILABLE:
|
||||
return;
|
||||
case FLASH_SLOT_FILE_1_NEW_CYCLE_BACKUP:
|
||||
case FLASH_SLOT_FILE_2_NEW_CYCLE_BACKUP:
|
||||
isBackup = true;
|
||||
@@ -201,19 +301,32 @@ extern "C" void SaveManager_SysFlashrom_WriteData(u8* saveBuffer, u32 pageNum, u
|
||||
Save save;
|
||||
memcpy(&save, saveBuffer, sizeof(Save));
|
||||
|
||||
std::string fileName = "save_" + std::to_string(flashSlotFile) + ".sav";
|
||||
if (isBackup)
|
||||
fileName += ".bak";
|
||||
|
||||
if (IS_VALID_FILE(save)) {
|
||||
nlohmann::json j;
|
||||
|
||||
j["save"] = save;
|
||||
// Read the existing save file to preserve the owl save
|
||||
int result = SaveManager_ReadSaveFile(fileName, j);
|
||||
if (result == -2) {
|
||||
SaveManager_MoveInvalidSaveFile(
|
||||
fileName,
|
||||
"Something went wrong trying to preserve the owl save. Original save file has been backed up.");
|
||||
} else if (result == 0) {
|
||||
result = SaveManager_MigrateSave(j);
|
||||
|
||||
if (result != 0) {
|
||||
SaveManager_MoveInvalidSaveFile(
|
||||
fileName, "Failed to migrate owl save. Original save file has been backed up.");
|
||||
}
|
||||
}
|
||||
|
||||
j["newCycleSave"]["save"] = save;
|
||||
j["version"] = CURRENT_SAVE_VERSION;
|
||||
j["type"] = "2S2H_SAVE";
|
||||
|
||||
SaveManager_WriteSaveFile(fileName, j);
|
||||
} else {
|
||||
// If IS_VALID_FILE fails, we should delete the save file, even if there is an owl save in it, because
|
||||
// they just deleted the new cycle save
|
||||
SaveManager_DeleteSaveFile(fileName);
|
||||
}
|
||||
break;
|
||||
@@ -227,106 +340,111 @@ extern "C" void SaveManager_SysFlashrom_WriteData(u8* saveBuffer, u32 pageNum, u
|
||||
SaveContext saveContext;
|
||||
memcpy(&saveContext, saveBuffer, offsetof(SaveContext, fileNum));
|
||||
|
||||
std::string fileName = "save_" + std::to_string(flashSlotFile) + ".sav";
|
||||
if (isBackup)
|
||||
fileName += ".bak";
|
||||
nlohmann::json j;
|
||||
// Read the existing save file to preserve the new cycle save
|
||||
int result = SaveManager_ReadSaveFile(fileName, j);
|
||||
if (result == -2) {
|
||||
SaveManager_MoveInvalidSaveFile(fileName, "Something went wrong trying to preserve the new cycle save. "
|
||||
"Original save file has been backed up.");
|
||||
} else if (result == 0) {
|
||||
result = SaveManager_MigrateSave(j);
|
||||
|
||||
if (result != 0) {
|
||||
SaveManager_MoveInvalidSaveFile(
|
||||
fileName, "Failed to migrate new cycle save. Original save file has been backed up.");
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_VALID_FILE(saveContext.save)) {
|
||||
nlohmann::json j = saveContext;
|
||||
|
||||
j["owlSave"] = saveContext;
|
||||
j["version"] = CURRENT_SAVE_VERSION;
|
||||
j["type"] = "2S2H_SAVE";
|
||||
|
||||
SaveManager_WriteSaveFile(fileName, j);
|
||||
} else {
|
||||
SaveManager_DeleteSaveFile(fileName);
|
||||
// If IS_VALID_FILE fails, and there is still a new cycle save present, we just want to only remove the
|
||||
// owl save and write the new cycle save back
|
||||
if (j.contains("newCycleSave")) {
|
||||
if (j.contains("owlSave")) {
|
||||
j.erase("owlSave");
|
||||
}
|
||||
j["version"] = CURRENT_SAVE_VERSION;
|
||||
j["type"] = "2S2H_SAVE";
|
||||
SaveManager_WriteSaveFile(fileName, j);
|
||||
// If there is no new cycle save, we should just delete the save file
|
||||
} else {
|
||||
SaveManager_DeleteSaveFile(fileName);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FLASH_SLOT_FILE_SRAM_HEADER_BACKUP:
|
||||
case FLASH_SLOT_FILE_SRAM_HEADER: {
|
||||
SaveOptions saveOptions;
|
||||
memcpy(&saveOptions, saveBuffer, sizeof(SaveOptions));
|
||||
|
||||
std::string fileName = "global.sav";
|
||||
SaveManager_WriteSaveFile(fileName, saveOptions);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" s32 SaveManager_SysFlashrom_ReadData(void* saveBuffer, u32 pageNum, u32 pageCount) {
|
||||
FlashSlotFile flashSlotFile = FLASH_SLOT_FILE_UNAVAILABLE;
|
||||
bool isBackup = false;
|
||||
for (u32 i = 0; i < ARRAY_COUNT(gFlashSaveStartPages) - 1; i++) {
|
||||
// Verify that the requested pages align with expected values
|
||||
if (pageNum == (u32)gFlashSaveStartPages[i] &&
|
||||
(pageCount == (u32)gFlashSaveNumPages[i] || pageCount == (u32)gFlashSpecialSaveNumPages[i])) {
|
||||
flashSlotFile = static_cast<FlashSlotFile>(i);
|
||||
break;
|
||||
}
|
||||
FlashSlotFile flashSlotFile = SaveManager_GetFlashSlotFileFromPages(pageNum, pageCount);
|
||||
std::string fileName = SaveManager_GetFileNameFromFlashSlotFile(flashSlotFile);
|
||||
|
||||
if (flashSlotFile == FLASH_SLOT_FILE_UNAVAILABLE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (flashSlotFile) {
|
||||
case FLASH_SLOT_FILE_UNAVAILABLE:
|
||||
if (flashSlotFile == FLASH_SLOT_FILE_SRAM_HEADER || flashSlotFile == FLASH_SLOT_FILE_SRAM_HEADER_BACKUP) {
|
||||
nlohmann::json j;
|
||||
int result = SaveManager_ReadSaveFile(fileName, j);
|
||||
if (result == -2) {
|
||||
SaveManager_MoveInvalidSaveFile(
|
||||
fileName,
|
||||
"Something went wrong trying to read global save file, the original file has been backed up.");
|
||||
return -1;
|
||||
case FLASH_SLOT_FILE_1_NEW_CYCLE_BACKUP:
|
||||
case FLASH_SLOT_FILE_2_NEW_CYCLE_BACKUP:
|
||||
isBackup = true;
|
||||
// fallthrough
|
||||
case FLASH_SLOT_FILE_1_NEW_CYCLE:
|
||||
case FLASH_SLOT_FILE_2_NEW_CYCLE: {
|
||||
std::string fileName = "save_" + std::to_string(flashSlotFile) + ".sav";
|
||||
if (isBackup)
|
||||
fileName += ".bak";
|
||||
|
||||
nlohmann::json j;
|
||||
int result = SaveManager_ReadSaveFile(fileName, j);
|
||||
if (result != 0)
|
||||
return result;
|
||||
|
||||
SaveManager_MigrateSave(j);
|
||||
|
||||
Save save = j["save"];
|
||||
|
||||
memcpy(saveBuffer, &save, sizeof(Save));
|
||||
} else if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
case FLASH_SLOT_FILE_1_OWL_SAVE_BACKUP:
|
||||
case FLASH_SLOT_FILE_2_OWL_SAVE_BACKUP:
|
||||
isBackup = true;
|
||||
// fallthrough
|
||||
case FLASH_SLOT_FILE_1_OWL_SAVE:
|
||||
case FLASH_SLOT_FILE_2_OWL_SAVE: {
|
||||
std::string fileName = "save_" + std::to_string(flashSlotFile) + ".sav";
|
||||
if (isBackup)
|
||||
fileName += ".bak";
|
||||
|
||||
nlohmann::json j;
|
||||
int result = SaveManager_ReadSaveFile(fileName, j);
|
||||
if (result != 0)
|
||||
return result;
|
||||
SaveOptions saveOptions = j;
|
||||
|
||||
SaveManager_MigrateSave(j);
|
||||
memcpy(saveBuffer, &saveOptions, sizeof(SaveOptions));
|
||||
return 0;
|
||||
}
|
||||
|
||||
SaveContext saveContext = j;
|
||||
bool isOwlSave =
|
||||
(flashSlotFile == FLASH_SLOT_FILE_1_OWL_SAVE || flashSlotFile == FLASH_SLOT_FILE_1_OWL_SAVE_BACKUP ||
|
||||
flashSlotFile == FLASH_SLOT_FILE_2_OWL_SAVE || flashSlotFile == FLASH_SLOT_FILE_2_OWL_SAVE_BACKUP);
|
||||
|
||||
memcpy(saveBuffer, &saveContext, offsetof(SaveContext, fileNum));
|
||||
return result;
|
||||
nlohmann::json j;
|
||||
int result = SaveManager_ReadSaveFile(fileName, j);
|
||||
if (result == -2) {
|
||||
SaveManager_MoveInvalidSaveFile(
|
||||
fileName, "Something went wrong trying to read save file, the original file has been backed up.");
|
||||
return -1;
|
||||
} else if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = SaveManager_MigrateSave(j);
|
||||
|
||||
if (result != 0) {
|
||||
SaveManager_MoveInvalidSaveFile(fileName, "Failed to migrate save file, the original file has been backed up.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (isOwlSave) {
|
||||
if (!j.contains("owlSave")) {
|
||||
return -1;
|
||||
}
|
||||
case FLASH_SLOT_FILE_SRAM_HEADER:
|
||||
case FLASH_SLOT_FILE_SRAM_HEADER_BACKUP: {
|
||||
std::string fileName = "global.sav";
|
||||
|
||||
nlohmann::json j;
|
||||
int result = SaveManager_ReadSaveFile(fileName, j);
|
||||
if (result != 0)
|
||||
return result;
|
||||
SaveContext saveContext = j["owlSave"];
|
||||
|
||||
SaveOptions saveOptions = j;
|
||||
|
||||
memcpy(saveBuffer, &saveOptions, sizeof(SaveOptions));
|
||||
return 0;
|
||||
memcpy(saveBuffer, &saveContext, offsetof(SaveContext, fileNum));
|
||||
return 0;
|
||||
} else {
|
||||
if (!j.contains("newCycleSave")) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Save save = j["newCycleSave"]["save"];
|
||||
|
||||
memcpy(saveBuffer, &save, sizeof(Save));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
std::string SaveManager_GetFileName(int fileNum, bool isBackup = false);
|
||||
bool SaveManager_HandleFileDropped(std::string filePath);
|
||||
bool BinarySaveConverter_HandleFileDropped(std::string filePath);
|
||||
int SaveManager_GetOpenFileSlot();
|
||||
|
||||
Reference in New Issue
Block a user