From 7b04f6788483923a5e43ac05d86542783296a380 Mon Sep 17 00:00:00 2001 From: David Chavez Date: Wed, 13 Jul 2022 06:19:07 +0200 Subject: [PATCH] Introduce App Directory Path (#572) * Introduce app directory path concept * macos: Remove hacky way of using applicaiton directory * Update the new SaveManager * Address stack user after return * Remove unecessary property * Use std::string for filepath * Improve clang specific detections * Use new path system for imgui files * Improve helper for getting relative paths --- BUILDING.md | 5 +- ZAPDTR/Makefile | 2 +- libultraship/Makefile | 37 +++++++++--- libultraship/libultraship/ConfigFile.cpp | 4 +- libultraship/libultraship/GlobalCtx2.cpp | 30 ++++++++-- libultraship/libultraship/GlobalCtx2.h | 3 + libultraship/libultraship/ImGuiImpl.cpp | 5 ++ libultraship/libultraship/OSXFolderManager.h | 60 +++++++++++++++++++ libultraship/libultraship/OSXFolderManager.mm | 37 ++++++++++++ soh/Makefile | 8 +-- soh/macosx/Info.plist | 2 +- soh/macosx/appsupport.m | 26 -------- soh/macosx/launcher.sh | 9 --- soh/soh/Enhancements/debugconsole.cpp | 9 ++- soh/soh/OTRGlobals.cpp | 3 +- soh/soh/SaveManager.cpp | 16 +++-- 16 files changed, 186 insertions(+), 70 deletions(-) create mode 100644 libultraship/libultraship/OSXFolderManager.h create mode 100644 libultraship/libultraship/OSXFolderManager.mm delete mode 100644 soh/macosx/appsupport.m delete mode 100755 soh/macosx/launcher.sh diff --git a/BUILDING.md b/BUILDING.md index 08ea20b35..5999f1eb9 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -63,9 +63,10 @@ make setup -j8 DEBUG=0 # Compile the code (watch the -j parameter as above) make -j8 DEBUG=0 # Create macOS app bundle -make filledappbundle +make appbundle ``` -9. Launch soh app in the soh folder! +9. Copy your OTR file to ~/Library/Application\ Support/com.shipofharkinian.soh +10. Launch soh app in the soh folder! # Compatible Roms ``` diff --git a/ZAPDTR/Makefile b/ZAPDTR/Makefile index d9a85b6db..755fd931a 100644 --- a/ZAPDTR/Makefile +++ b/ZAPDTR/Makefile @@ -49,7 +49,7 @@ LDFLAGS := -lm -ldl \ -L../StormLib/build -L../libultraship -lbz2 -pthread -lultraship -lstorm ifeq ($(UNAME), Darwin) - LDFLAGS += $(shell pkg-config --libs glew libpng zlib) $(shell sdl2-config --libs) -framework OpenGL + LDFLAGS += $(shell pkg-config --libs glew libpng zlib) $(shell sdl2-config --libs) -framework OpenGL -framework Foundation INC += $(shell pkg-config --cflags libpng) else LDFLAGS += -lpng -lGL -lGLEW -lX11 -lz -lSDL2 -lpulse diff --git a/libultraship/Makefile b/libultraship/Makefile index b3b7d2836..819acce9f 100644 --- a/libultraship/Makefile +++ b/libultraship/Makefile @@ -2,7 +2,7 @@ CXX ?= g++ CC ?= gcc -AR := ar +AR := ar FORMAT := clang-format-11 UNAME := $(shell uname) @@ -11,6 +11,15 @@ DEBUG ?= 1 OPTFLAGS ?= -O0 LTO ?= 0 +# flag to save whether the compiler being used is clang or gcc by checking CXX --version +CXX_IS_CLANG ?= $(shell $(CXX) --version | grep -c clang) +ifeq ($(CXX_IS_CLANG),1) + MXX := $(CXX) +else + MXX ?= clang++ +endif + + WARN := -Wall -Wextra -Werror \ -Wno-unused-variable \ -Wno-unused-parameter \ @@ -29,8 +38,7 @@ WARN := -Wall -Wextra -Werror \ CWARN := CXXWARN := -Wno-deprecated-enum-enum-conversion -Wno-deprecated-copy -COMPILER_VERSION := $(shell $(CXX) --version) -ifneq '' '$(findstring g++,$(COMPILER_VERSION))' +ifneq ($(CXX_IS_CLANG),1) WARN += -Wno-error=stringop-overflow CXXWARN += -Wno-error=maybe-uninitialized endif @@ -39,12 +47,17 @@ CXXFLAGS := $(WARN) $(CXXWARN) -std=c++20 -D_GNU_SOURCE -DENABLE_OPENGL -DSPDLOG CFLAGS := $(WARN) $(CWARN) -std=c99 -D_GNU_SOURCE -DENABLE_OPENGL -DSPDLOG_ACTIVE_LEVEL=0 CPPFLAGS := -MMD -ifeq ($(UNAME), Darwin) #APPLE - CPPFLAGS += $(shell pkg-config --cflags sdl2 glew) -framework OpenGL +MMFLAGS := -Wno-deprecated-declarations -ObjC++ -fobjc-weak -fobjc-arc + +# if not using clang, ask clang to use gcc standard library +ifneq ($(CXX_IS_CLANG),1) + STD_ISYSTEM=$(shell ${CXX} -xc++ -E -v - < /dev/null 2>&1 | grep "> search starts here" -A2 | tail -n 2 | head -n 1) + CXX_ISYSTEM=$(shell ${CXX} -xc++ -E -v - < /dev/null 2>&1 | grep "> search starts here" -A2 | tail -n 2 | tail -n 1) + MMFLAGS += -stdlib++-isystem ${STD_ISYSTEM} -cxx-isystem ${CXX_ISYSTEM} endif -ifeq ($(UNAME), Linux) - WARN += -Wno-error=stringop-overflow # This is required with clang on Linux. +ifeq ($(UNAME), Darwin) #APPLE + CPPFLAGS += $(shell pkg-config --cflags sdl2 glew) -framework OpenGL -framework Foundation endif ifneq ($(DEBUG),0) @@ -78,12 +91,19 @@ C_FILES := \ libultraship/mixer.c \ libultraship/Lib/stb/stb_impl.c +MM_FILES := \ + libultraship/OSXFolderManager.mm + FMT_FILES := $(shell find libultraship/ -type f \( -name "*.cpp" -o -name "*.h" \) -a -not -path "libultraship/Lib/*") O_FILES := \ $(CXX_FILES:%.cpp=build/%.o) \ $(C_FILES:%.c=build/%.o) +ifeq ($(UNAME), Darwin) #APPLE + O_FILES += $(MM_FILES:%.mm=build/%.o) +endif + D_FILES := $(O_FILES:%.o=%.d) LIB := libultraship.a @@ -117,6 +137,9 @@ build/%.o: %.cpp build/%.o: %.c $(CC) $(CFLAGS) $(CPPFLAGS) $(OPTFLAGS) $(INC_DIRS) -c $< -o $@ +build/%.o: %.mm + $(MXX) $(MMFLAGS) $(CXXFLAGS) $(OPTFLAGS) $(INC_DIRS) -c $< -o $@ + $(LIB): $(O_FILES) $(AR) rcs $@ $^ diff --git a/libultraship/libultraship/ConfigFile.cpp b/libultraship/libultraship/ConfigFile.cpp index 43dde4d8a..e8a52d881 100644 --- a/libultraship/libultraship/ConfigFile.cpp +++ b/libultraship/libultraship/ConfigFile.cpp @@ -56,10 +56,10 @@ namespace Ship { } bool ConfigFile::CreateDefaultConfig() { - (*this)["ARCHIVE"]["Main Archive"] = "oot.otr"; + (*this)["ARCHIVE"]["Main Archive"] = ""; (*this)["ARCHIVE"]["Patches Directory"] = ""; - (*this)["SAVE"]["Save Filename"] = "oot_save.sav"; + (*this)["SAVE"]["Save Filename"] = ""; (*this)["CONTROLLERS"]["CONTROLLER 1"] = "Auto"; (*this)["CONTROLLERS"]["CONTROLLER 2"] = "Unplugged"; diff --git a/libultraship/libultraship/GlobalCtx2.cpp b/libultraship/libultraship/GlobalCtx2.cpp index 6da741283..54e64e0ce 100644 --- a/libultraship/libultraship/GlobalCtx2.cpp +++ b/libultraship/libultraship/GlobalCtx2.cpp @@ -8,10 +8,14 @@ #include "spdlog/sinks/stdout_color_sinks.h" #include "spdlog/sinks/sohconsole_sink.h" #include "ModManager.h" +#ifdef __APPLE__ +#include "OSXFolderManager.h" +#endif namespace Ship { std::weak_ptr GlobalCtx2::Context; ModManager* INSTANCE; + std::shared_ptr GlobalCtx2::GetInstance() { return Context.lock(); } @@ -29,6 +33,22 @@ namespace Ship { return GetInstance(); } + std::string GlobalCtx2::GetAppDirectoryPath() { + #ifdef __APPLE__ + FolderManager folderManager; + std::string fpath = std::string(folderManager.pathForDirectory(NSApplicationSupportDirectory, NSUserDomainMask)); + fpath.append("/com.shipofharkinian.soh"); + return fpath; + #endif + + return "."; + + } + + std::string GlobalCtx2::GetPathRelativeToAppDirectory(const char* path) { + return GlobalCtx2::GetAppDirectoryPath() + "/" + path; + } + GlobalCtx2::GlobalCtx2(const std::string& Name) : Name(Name), MainPath(""), PatchesPath("") { } @@ -40,14 +60,14 @@ namespace Ship { void GlobalCtx2::InitWindow() { InitLogging(); - Config = std::make_shared(GlobalCtx2::GetInstance(), "shipofharkinian.ini"); + Config = std::make_shared(GlobalCtx2::GetInstance(), GetPathRelativeToAppDirectory("shipofharkinian.ini")); MainPath = (*Config)["ARCHIVE"]["Main Archive"]; if (MainPath.empty()) { - MainPath = "oot.otr"; + MainPath = GetPathRelativeToAppDirectory("oot.otr"); } PatchesPath = (*Config)["ARCHIVE"]["Patches Directory"]; if (PatchesPath.empty()) { - PatchesPath = "./"; + PatchesPath = GetAppDirectoryPath() + "/"; } ResMan = std::make_shared(GlobalCtx2::GetInstance(), MainPath, PatchesPath); Win = std::make_shared(GlobalCtx2::GetInstance()); @@ -67,11 +87,13 @@ namespace Ship { void GlobalCtx2::InitLogging() { try { + auto logPath = GetPathRelativeToAppDirectory(("logs/" + GetName() + ".log").c_str()); + // Setup Logging spdlog::init_thread_pool(8192, 1); auto SohConsoleSink = std::make_shared(); auto ConsoleSink = std::make_shared(); - auto FileSink = std::make_shared("logs/" + GetName() + ".log", 1024 * 1024 * 10, 10); + auto FileSink = std::make_shared(logPath, 1024 * 1024 * 10, 10); SohConsoleSink->set_level(spdlog::level::trace); ConsoleSink->set_level(spdlog::level::trace); FileSink->set_level(spdlog::level::trace); diff --git a/libultraship/libultraship/GlobalCtx2.h b/libultraship/libultraship/GlobalCtx2.h index 4a7502393..5736e2b66 100644 --- a/libultraship/libultraship/GlobalCtx2.h +++ b/libultraship/libultraship/GlobalCtx2.h @@ -24,6 +24,9 @@ namespace Ship { std::shared_ptr GetLogger() { return Logger; } std::shared_ptr GetConfig() { return Config; } + static std::string GetAppDirectoryPath(); + static std::string GetPathRelativeToAppDirectory(const char* path); + 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); diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index ba51c1e99..ebc15ace8 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -304,6 +304,11 @@ namespace SohImGui { SohImGui::overlay->TextDrawNotification(30.0f, true, "Press F1 to access enhancements menu"); } + auto imguiIniPath = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("imgui.ini"); + auto imguiLogPath = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("imgui_log.txt"); + io->IniFilename = strcpy(new char[imguiIniPath.length() + 1], imguiIniPath.c_str()); + io->LogFilename = strcpy(new char[imguiLogPath.length() + 1], imguiLogPath.c_str()); + if (UseViewports()) { io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; } diff --git a/libultraship/libultraship/OSXFolderManager.h b/libultraship/libultraship/OSXFolderManager.h new file mode 100644 index 000000000..476b78d3c --- /dev/null +++ b/libultraship/libultraship/OSXFolderManager.h @@ -0,0 +1,60 @@ +// +// OSXFolderManager.h +// libultraship +// +// Created by David Chavez on 28.06.22. +// + +#ifndef OSXFolderManager_h +#define OSXFolderManager_h + +#include +namespace Ship { + enum { + NSApplicationDirectory = 1, + NSDemoApplicationDirectory, + NSDeveloperApplicationDirectory, + NSAdminApplicationDirectory, + NSLibraryDirectory, + NSDeveloperDirectory, + NSUserDirectory, + NSDocumentationDirectory, + NSDocumentDirectory, + NSCoreServiceDirectory, + NSAutosavedInformationDirectory = 11, + NSDesktopDirectory = 12, + NSCachesDirectory = 13, + NSApplicationSupportDirectory = 14, + NSDownloadsDirectory = 15, + NSInputMethodsDirectory = 16, + NSMoviesDirectory = 17, + NSMusicDirectory = 18, + NSPicturesDirectory = 19, + NSPrinterDescriptionDirectory = 20, + NSSharedPublicDirectory = 21, + NSPreferencePanesDirectory = 22, + NSApplicationScriptsDirectory = 23, + NSItemReplacementDirectory = 99, + NSAllApplicationsDirectory = 100, + NSAllLibrariesDirectory = 101, + NSTrashDirectory = 102 + }; + typedef unsigned long SearchPathDirectory; + + enum { + NSUserDomainMask = 1, // user's home directory --- place to install user's personal items (~) + NSLocalDomainMask = 2, // local to the current machine --- place to install items available to everyone on this machine (/Library) + NSNetworkDomainMask = 4, // publically available location in the local area network --- place to install items available on the network (/Network) + NSSystemDomainMask = 8, // provided by Apple, unmodifiable (/System) + NSAllDomainsMask = 0x0ffff // all domains: all of the above and future items + }; + typedef unsigned long SearchPathDomainMask; + + class FolderManager { + public: + const char *pathForDirectory(SearchPathDirectory directory, SearchPathDomainMask domainMask); + const char *pathForDirectoryAppropriateForItemAtPath(SearchPathDirectory directory, SearchPathDomainMask domainMask, const char *itemPath, bool create = false); + }; +}; + +#endif /* OSXFolderManager_h */ diff --git a/libultraship/libultraship/OSXFolderManager.mm b/libultraship/libultraship/OSXFolderManager.mm new file mode 100644 index 000000000..85bfb20a8 --- /dev/null +++ b/libultraship/libultraship/OSXFolderManager.mm @@ -0,0 +1,37 @@ +// +// OSXFolderManager.m +// libultraship +// +// Created by David Chavez on 28.06.22. +// + +#include "OSXFolderManager.h" +#import + +using namespace Ship; + +const char * FolderManager::pathForDirectory(SearchPathDirectory directory, SearchPathDomainMask domainMask) { + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSArray *URLs = [fileManager URLsForDirectory:(NSSearchPathDirectory)directory inDomains:domainMask]; + if (URLs.count == 0) return NULL; + + NSURL *URL = [URLs objectAtIndex:0]; + NSString *path = URL.path; + + // `fileSystemRepresentation` on an `NSString` gives a path suitable for POSIX APIs + return path.fileSystemRepresentation; +} + +const char * FolderManager::pathForDirectoryAppropriateForItemAtPath(SearchPathDirectory directory, + SearchPathDomainMask domainMask, const char *itemPath, bool create) { + + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSString *nsPath = [fileManager stringWithFileSystemRepresentation:itemPath length:strlen(itemPath)]; + NSURL *itemURL = (nsPath ? [NSURL fileURLWithPath:nsPath] : nil); + + NSURL *URL = [fileManager URLForDirectory:(NSSearchPathDirectory)directory + inDomain:domainMask + appropriateForURL:itemURL + create:create error:NULL]; + return URL.path.fileSystemRepresentation; +} diff --git a/soh/Makefile b/soh/Makefile index 14bb46827..b05321a60 100644 --- a/soh/Makefile +++ b/soh/Makefile @@ -120,6 +120,7 @@ ifeq ($(UNAME), Darwin) #APPLE LDLIBS += \ $(addprefix -framework , \ OpenGL \ + Foundation \ ) \ $(shell sdl2-config --libs) $(shell pkg-config --libs glew) endif @@ -224,9 +225,6 @@ appbundle: macosx/$(APPNAME).icns cp macosx/PkgInfo $(APPBUNDLECONTENTS)/ cp macosx/$(APPNAME).icns $(APPBUNDLEICON)/ cp $(TARGET) $(APPBUNDLEEXE)/soh - cp macosx/launcher.sh $(APPBUNDLEEXE)/launcher.sh - clang -ObjC macosx/appsupport.m -arch arm64 -arch x86_64 -framework Foundation -o macosx/appsupport - cp macosx/appsupport $(APPBUNDLEEXE)/appsupport otool -l $(TARGET) | grep -A 2 LC_RPATH | tail -n 1 | awk '{print $2}' | dylibbundler -od -b -x $(APPBUNDLEEXE)/soh -d $(APPBUNDLECONTENTS)/libs macosx/$(APPNAME).icns: macosx/$(APPNAME)Icon.png @@ -244,7 +242,3 @@ macosx/$(APPNAME).icns: macosx/$(APPNAME)Icon.png cp macosx/$(APPNAME)Icon.png macosx/$(APPNAME).iconset/icon_512x512@2x.png iconutil -c icns -o macosx/$(APPNAME).icns macosx/$(APPNAME).iconset rm -r macosx/$(APPNAME).iconset - -filledappbundle: appbundle - cp ./oot.otr $(APPBUNDLEEXE)/oot.otr - diff --git a/soh/macosx/Info.plist b/soh/macosx/Info.plist index af3ea4de5..f657ef657 100644 --- a/soh/macosx/Info.plist +++ b/soh/macosx/Info.plist @@ -7,7 +7,7 @@ CFBundleName Ship of Harkinian CFBundleExecutable - launcher.sh + soh CFBundleGetInfoString 2.0.0 CFBundleIconFile diff --git a/soh/macosx/appsupport.m b/soh/macosx/appsupport.m deleted file mode 100644 index a7df45e67..000000000 --- a/soh/macosx/appsupport.m +++ /dev/null @@ -1,26 +0,0 @@ -#import -int main(void) { - NSString *appSupportDir = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject]; - //If there isn't an App Support Directory yet ... - if (![[NSFileManager defaultManager] fileExistsAtPath:appSupportDir isDirectory:NULL]) { - NSError *error = nil; - //Create one - if (![[NSFileManager defaultManager] createDirectoryAtPath:appSupportDir withIntermediateDirectories:YES attributes:nil error:&error]) { - NSLog(@"%@", error.localizedDescription); - } - else { - // *** OPTIONAL *** Mark the directory as excluded from iCloud backups - NSURL *url = [NSURL fileURLWithPath:appSupportDir]; - if (![url setResourceValue:@YES - forKey:NSURLIsExcludedFromBackupKey - error:&error]) - { - NSLog(@"Error excluding %@ from backup %@", url.lastPathComponent, error.localizedDescription); - } - else { - NSLog(@"Yay"); - } - } - } - printf("%s\n", [appSupportDir UTF8String]); -} diff --git a/soh/macosx/launcher.sh b/soh/macosx/launcher.sh deleted file mode 100755 index ef22983de..000000000 --- a/soh/macosx/launcher.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -APPPATH="${0%/*}" -cd "${APPPATH}" -APPPATH=$(pwd) -APPSUPPORT=$(./appsupport) -mkdir -p "${APPSUPPORT}/com.shipofharkinian.soh" -cd "${APPSUPPORT}/com.shipofharkinian.soh" -cp "${APPPATH}/oot.otr" . -${APPPATH}/soh diff --git a/soh/soh/Enhancements/debugconsole.cpp b/soh/soh/Enhancements/debugconsole.cpp index 445134f2a..b2981d361 100644 --- a/soh/soh/Enhancements/debugconsole.cpp +++ b/soh/soh/Enhancements/debugconsole.cpp @@ -500,8 +500,9 @@ template bool is_number(const std::string& s) { void DebugConsole_LoadCVars() { - if (File::Exists("cvars.cfg")) { - const auto lines = File::ReadAllLines("cvars.cfg"); + auto cvarsConfig = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("cvars.cfg"); + if (File::Exists(cvarsConfig)) { + const auto lines = File::ReadAllLines(cvarsConfig); for (const std::string& line : lines) { std::vector cfg = StringHelper::Split(line, " = "); @@ -535,5 +536,7 @@ void DebugConsole_SaveCVars() output += StringHelper::Sprintf("%s = %f\n", cvar.first.c_str(), cvar.second->value.valueFloat); } - File::WriteAllText("cvars.cfg", output); + + auto cvarsConfig = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("cvars.cfg"); + File::WriteAllText(cvarsConfig, output); } diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 042a4b5e9..3a862d58a 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -57,7 +57,6 @@ OTRGlobals* OTRGlobals::Instance; SaveManager* SaveManager::Instance; OTRGlobals::OTRGlobals() { - context = Ship::GlobalCtx2::CreateInstance("Ship of Harkinian"); gSaveStateMgr = std::make_shared(); gRandomizer = std::make_shared(); @@ -1158,7 +1157,7 @@ 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"]["Save Filename"] = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("oot_save.sav"); Conf.Save(); } std::filesystem::path saveFile = std::filesystem::absolute(fileName); diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 1bbbd3a1c..cbe4315d3 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -1,4 +1,5 @@ #include "SaveManager.h" +#include "OTRGlobals.h" #include "z64.h" #include "functions.h" @@ -14,11 +15,9 @@ extern "C" SaveContext gSaveContext; -static const std::filesystem::path sSavePath("Save"); // TODO maybe let this be user-configurable? -static const std::filesystem::path sGlobalPath = sSavePath / "global.sav"; - std::filesystem::path SaveManager::GetFileName(int fileNum) { - return sSavePath / (std::string("file") + std::to_string(fileNum + 1) + ".sav"); + const std::filesystem::path sSavePath(Ship::GlobalCtx2::GetPathRelativeToAppDirectory("Save")); + return sSavePath / ("file" + std::to_string(fileNum + 1) + ".sav"); } SaveManager::SaveManager() { @@ -128,15 +127,20 @@ void SaveManager::SaveRandomizer() { } void SaveManager::Init() { + const std::filesystem::path sSavePath(Ship::GlobalCtx2::GetPathRelativeToAppDirectory("Save")); + const std::filesystem::path sGlobalPath = sSavePath / std::string("global.sav"); + auto sOldSavePath = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("oot_save.sav"); + auto sOldBackupSavePath = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("oot_save.bak"); + // If the save directory does not exist, create it if (!std::filesystem::exists(sSavePath)) { std::filesystem::create_directory(sSavePath); } // If there is a lingering unversioned save, convert it - if (std::filesystem::exists("oot_save.sav")) { + if (std::filesystem::exists(sOldSavePath)) { ConvertFromUnversioned(); - std::filesystem::rename("oot_save.sav", "oot_save.bak"); + std::filesystem::rename(sOldSavePath, sOldBackupSavePath); } // If the global save file exist, load it. Otherwise, create it.