From 39d8b77b0254138913daac7b4bd39702bc558b85 Mon Sep 17 00:00:00 2001 From: Ian Drake Date: Mon, 20 Jun 2022 13:54:44 -0400 Subject: [PATCH] Added save filename and path to config file (#130) * Added save filename and path to config file Closes #110 * Moved FileIO to libultraship * Moved OOT Specific Code to OTRGlobals and made libultraship for general file IO. Combined config options. * Moved filesystem include into GlobalCtx2.h --- libultraship/libultraship/ConfigFile.cpp | 2 + libultraship/libultraship/GlobalCtx2.cpp | 21 ++++++++ libultraship/libultraship/GlobalCtx2.h | 4 ++ soh/soh/OTRGlobals.cpp | 68 ++++++++++++++++++++++++ soh/soh/OTRGlobals.h | 8 ++- soh/src/code/z_ss_sram.c | 31 ++--------- 6 files changed, 105 insertions(+), 29 deletions(-) diff --git a/libultraship/libultraship/ConfigFile.cpp b/libultraship/libultraship/ConfigFile.cpp index 8a079464380..984bd34eacf 100644 --- a/libultraship/libultraship/ConfigFile.cpp +++ b/libultraship/libultraship/ConfigFile.cpp @@ -59,6 +59,8 @@ namespace Ship { (*this)["ARCHIVE"]["Main Archive"] = "oot.otr"; (*this)["ARCHIVE"]["Patches Directory"] = ""; + (*this)["SAVE"]["Save Filename"] = "oot_save.sav"; + (*this)["CONTROLLERS"]["CONTROLLER 1"] = "Auto"; (*this)["CONTROLLERS"]["CONTROLLER 2"] = "Unplugged"; (*this)["CONTROLLERS"]["CONTROLLER 3"] = "Unplugged"; diff --git a/libultraship/libultraship/GlobalCtx2.cpp b/libultraship/libultraship/GlobalCtx2.cpp index 5ce59f5abca..6da7412834d 100644 --- a/libultraship/libultraship/GlobalCtx2.cpp +++ b/libultraship/libultraship/GlobalCtx2.cpp @@ -86,4 +86,25 @@ namespace Ship { std::cout << "Log initialization failed: " << ex.what() << std::endl; } } + + void GlobalCtx2::WriteSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size) { + std::ofstream saveFile = std::ofstream(savePath, std::fstream::in | std::fstream::out | std::fstream::binary); + saveFile.seekp(addr); + saveFile.write((char*)dramAddr, size); + saveFile.close(); + } + + void GlobalCtx2::ReadSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size) { + std::ifstream saveFile = std::ifstream(savePath, std::fstream::in | std::fstream::out | std::fstream::binary); + + // If the file doesn't exist, initialize DRAM + if (saveFile.good()) { + saveFile.seekg(addr); + saveFile.read((char*)dramAddr, size); + } else { + memset(dramAddr, 0, size); + } + + saveFile.close(); + } } \ No newline at end of file diff --git a/libultraship/libultraship/GlobalCtx2.h b/libultraship/libultraship/GlobalCtx2.h index 1ed512347e8..4a7502393a3 100644 --- a/libultraship/libultraship/GlobalCtx2.h +++ b/libultraship/libultraship/GlobalCtx2.h @@ -4,6 +4,7 @@ #pragma once #ifdef __cplusplus +#include #include #include "spdlog/spdlog.h" #include "ConfigFile.h" @@ -23,6 +24,9 @@ namespace Ship { std::shared_ptr GetLogger() { return Logger; } std::shared_ptr GetConfig() { return Config; } + void WriteSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size); + void ReadSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size); + GlobalCtx2(const std::string& Name); ~GlobalCtx2(); diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index a77df5c84d1..7dc6ed444d9 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -1,6 +1,7 @@ #include "OTRGlobals.h" #include "OTRAudio.h" #include +#include #include #include #include "GlobalCtx2.h" @@ -46,6 +47,7 @@ OTRGlobals::OTRGlobals() { context = Ship::GlobalCtx2::CreateInstance("Ship of Harkinian"); gSaveStateMgr = std::make_shared(); context->GetWindow()->Init(); + CheckSaveFile(SRAM_SIZE); } OTRGlobals::~OTRGlobals() { @@ -840,6 +842,7 @@ extern "C" AnimationHeaderCommon* ResourceMgr_LoadAnimByName(const char* path) { for (int i = 0; i < res->rotationValues.size(); i++) animNormal->frameData[i] = res->rotationValues[i]; + animNormal->jointIndices = (JointIndex*)malloc(res->rotationIndices.size() * sizeof(Vec3s)); for (int i = 0; i < res->rotationIndices.size(); i++) { @@ -1084,6 +1087,71 @@ extern "C" s32* ResourceMgr_LoadCSByName(const char* path) return (s32*)res->commands.data(); } +std::filesystem::path GetSaveFile(Ship::ConfigFile& Conf) { + std::string fileName = Conf.get("SAVE").get("Save Filename"); + + if (fileName.empty()) { + Conf["SAVE"]["Save Filename"] = "oot_save.sav"; + Conf.Save(); + } + std::filesystem::path saveFile = std::filesystem::absolute(fileName); + + if (!std::filesystem::exists(saveFile.parent_path())) { + std::filesystem::create_directories(saveFile.parent_path()); + } + + return saveFile; +} + +std::filesystem::path GetSaveFile() { + std::shared_ptr pConf = OTRGlobals::Instance->context->GetConfig(); + Ship::ConfigFile& Conf = *pConf.get(); + + return GetSaveFile(Conf); +} + +void OTRGlobals::CheckSaveFile(size_t sramSize) { + std::shared_ptr pConf = context->GetConfig(); + Ship::ConfigFile& Conf = *pConf.get(); + + std::filesystem::path savePath = GetSaveFile(Conf); + std::fstream saveFile(savePath, std::fstream::in | std::fstream::out | std::fstream::binary); + if (saveFile.fail()) { + saveFile.open(savePath, std::fstream::in | std::fstream::out | std::fstream::binary | std::fstream::app); + for (int i = 0; i < sramSize; ++i) { + saveFile.write("\0", 1); + } + } + saveFile.close(); +} + +extern "C" void Ctx_ReadSaveFile(uintptr_t addr, void* dramAddr, size_t size) { + OTRGlobals::Instance->context->ReadSaveFile(GetSaveFile(), addr, dramAddr, size); +} + +extern "C" void Ctx_WriteSaveFile(uintptr_t addr, void* dramAddr, size_t size) { + OTRGlobals::Instance->context->WriteSaveFile(GetSaveFile(), addr, dramAddr, size); +} + +/* Remember to free after use of value */ +extern "C" char* Config_getValue(char* category, char* key) { + std::shared_ptr pConf = OTRGlobals::Instance->context->GetConfig(); + Ship::ConfigFile& Conf = *pConf.get(); + + std::string data = Conf.get(std::string(category)).get(std::string(key)); + char* retval = (char*)malloc(data.length()+1); + strcpy(retval, data.c_str()); + + return retval; +} + +extern "C" bool Config_setValue(char* category, char* key, char* value) { + std::shared_ptr pConf = OTRGlobals::Instance->context->GetConfig(); + Ship::ConfigFile& Conf = *pConf.get(); + Conf[std::string(category)][std::string(key)] = std::string(value); + return Conf.Save(); +} + std::wstring StringToU16(const std::string& s) { std::vector result; size_t i = 0; diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index ff9e4f24dca..31ec4522794 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -20,7 +20,7 @@ class OTRGlobals ~OTRGlobals(); private: - + void CheckSaveFile(size_t sramSize); }; #endif @@ -47,11 +47,17 @@ Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc); Gfx* ResourceMgr_LoadGfxByName(const char* path); Gfx* ResourceMgr_PatchGfxByName(const char* path, int size); Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc); + Vtx* ResourceMgr_LoadVtxByName(const char* path); SoundFont* ResourceMgr_LoadAudioSoundFont(const char* path); SequenceData ResourceMgr_LoadSeqByName(const char* path); SoundFontSample* ResourceMgr_LoadAudioSample(const char* path); CollisionHeader* ResourceMgr_LoadColByName(const char* path); +void Ctx_ReadSaveFile(uintptr_t addr, void* dramAddr, size_t size); +void Ctx_WriteSaveFile(uintptr_t addr, void* dramAddr, size_t size); +char* Config_getValue(char* category, char* key); +bool Config_setValue(char* category, char* key, char* value); + uint64_t GetPerfCounter(); struct SkeletonHeader* ResourceMgr_LoadSkeletonByName(const char* path); int ResourceMgr_OTRSigCheck(char* imgData); diff --git a/soh/src/code/z_ss_sram.c b/soh/src/code/z_ss_sram.c index 6b4ea50ca2d..8be84e07b48 100644 --- a/soh/src/code/z_ss_sram.c +++ b/soh/src/code/z_ss_sram.c @@ -58,38 +58,13 @@ void SsSram_Dma(void* dramAddr, size_t size, s32 direction) { void SsSram_ReadWrite(uintptr_t addr, void* dramAddr, size_t size, s32 direction) { osSyncPrintf("ssSRAMReadWrite:%08x %08x %08x %d\n", addr, (uintptr_t)dramAddr, size, direction); - //Check to see if the file exists - FILE* saveFile; - saveFile = fopen("oot_save.sav", "rb"); - - if (saveFile == NULL) { - - saveFile = fopen("oot_save.sav", "wb"); - fseek(saveFile, 0, SEEK_SET); - assert(saveFile != NULL); // OTRTODO LOG - uint8_t zero = 0; - - for (uint32_t i = 0; i < SRAM_SIZE; i++) { - fwrite(&zero, 1, 1, saveFile); - } - fclose(saveFile); - } else { - fclose(saveFile); - } + switch (direction) { case OS_WRITE: { - saveFile = fopen("oot_save.sav", "r+b"); - rewind(saveFile); - fseek(saveFile, addr, SEEK_SET); - fwrite(dramAddr, size, 1, saveFile); - fclose(saveFile); + Ctx_WriteSaveFile(addr, dramAddr, size); } break; case OS_READ: { - saveFile = fopen("oot_save.sav", "rb+"); - rewind(saveFile); - fseek(saveFile, addr, SEEK_SET); - fread(dramAddr, size, 1, saveFile); - fclose(saveFile); + Ctx_ReadSaveFile(addr, dramAddr, size); } break; } //SsSram_Init(addr, DEVICE_TYPE_SRAM, PI_DOMAIN2, 5, 0xD, 2, 0xC, 0);