From f08b87b41f0ffaabd7928d68c41d704e824b5de3 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 27 Mar 2019 13:34:26 +0100 Subject: * move melon_fopen_local() to Platform.cpp * make it require that the file already exist (hopefully fixing config saving bug) * finally axe melon_fopen.cpp --- src/libui_sdl/Platform.cpp | 162 ++++++++++++++++++++++++++++++++++++++++++++- src/libui_sdl/main.cpp | 30 ++------- 2 files changed, 166 insertions(+), 26 deletions(-) (limited to 'src/libui_sdl') diff --git a/src/libui_sdl/Platform.cpp b/src/libui_sdl/Platform.cpp index a3619b5..3cf72bf 100644 --- a/src/libui_sdl/Platform.cpp +++ b/src/libui_sdl/Platform.cpp @@ -26,11 +26,17 @@ #include "LAN_PCap.h" #ifdef __WIN32__ + #define NTDDI_VERSION 0x06000000 // GROSS FUCKING HACK + #include + //#include // FUCK THAT SHIT + extern "C" const GUID DECLSPEC_SELECTANY FOLDERID_RoamingAppData = {0x3eb685db, 0x65f9, 0x4cf6, {0xa0, 0x3a, 0xe3, 0xef, 0x65, 0x72, 0x9f, 0x3d}}; + #include #include #include #define socket_t SOCKET #define sockaddr_t SOCKADDR #else + #include #include #include #include @@ -46,6 +52,8 @@ #endif +extern char* EmuDirectory; + void Stop(bool internal); @@ -81,8 +89,10 @@ void StopEmu() } -FILE* OpenFile(const char* path, const char* mode) +FILE* OpenFile(const char* path, const char* mode, bool mustexist) { + FILE* ret; + #ifdef __WIN32__ int len = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); @@ -98,13 +108,159 @@ FILE* OpenFile(const char* path, const char* mode) fatmode[2] = mode[2]; fatmode[3] = 0; - FILE* ret = _wfopen(fatpath, fatmode); + if (mustexist) + { + ret = _wfopen(fatpath, L"rb"); + if (ret) ret = _wfreopen(fatpath, fatmode, ret); + } + else + ret = _wfopen(fatpath, fatmode); + delete[] fatpath; + +#else + + if (mustexist) + { + ret = fopen(path, "rb"); + if (ret) ret = freopen(path, mode); + } + else + ret = fopen(path, mode); + +#endif + return ret; +} + +FILE* OpenLocalFile(const char* path, const char* mode) +{ + bool relpath = false; + int pathlen = strlen(path); + + if (pathlen >= 3) + { + if (path[0] == '.' && path[1] == '.' && (path[2] == '/' || path[2] == '\\')) + relpath = true; + } + +#ifdef __WIN32__ + + if (pathlen > 3) + { + if (path[1] == ':' && path[2] == '\\') + return OpenFile(path, mode); + } + + // Locations are application directory, and AppData/melonDS on windows + + FILE* f; + + // First check current working directory + f = OpenFile(path, mode, true); + if (f) return f; + + // then emu directory + { + int dirlen = strlen(EmuDirectory); + if (dirlen) + { + int len = dirlen + 1 + pathlen + 1; + char* tmp = new char[len]; + strncpy(&tmp[0], EmuDirectory, dirlen); + tmp[dirlen] = '\\'; + strncpy(&tmp[dirlen+1], path, pathlen); + tmp[dirlen+1+pathlen] = '\0'; + + f = OpenFile(tmp, mode, true); + delete[] tmp; + if (f) return f; + } + } + + // a path relative to AppData wouldn't make much sense + if (relpath) return NULL; + + // Now check AppData + PWSTR appDataPath = NULL; + SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &appDataPath); + if (!appDataPath) + return NULL; + + // this will be more than enough + WCHAR fatperm[4]; + fatperm[0] = mode[0]; + fatperm[1] = mode[1]; + fatperm[2] = mode[2]; + fatperm[3] = 0; + + int fnlen = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); + if (fnlen < 1) return NULL; + WCHAR* wfileName = new WCHAR[fnlen]; + int res = MultiByteToWideChar(CP_UTF8, 0, path, -1, wfileName, fnlen); + if (res != fnlen) { delete[] wfileName; return NULL; } // checkme? + + const WCHAR* appdir = L"\\melonDS\\"; + + int pos = wcslen(appDataPath); + void* ptr = CoTaskMemRealloc(appDataPath, (pos+wcslen(appdir)+fnlen+1)*sizeof(WCHAR)); + if (!ptr) { delete[] wfileName; return NULL; } // oh well + appDataPath = (PWSTR)ptr; + + wcscpy(&appDataPath[pos], appdir); pos += wcslen(appdir); + wcscpy(&appDataPath[pos], wfileName); + + f = _wfopen(appDataPath, L"rb"); + if (f) f = _wfreopen(appDataPath, fatperm, f); + CoTaskMemFree(appDataPath); + delete[] wfileName; + if (f) return f; + + return NULL; #else - return fopen(path, mode); + if (pathlen > 1) + { + if (path[0] == '/') + return OpenFile(path, mode); + } + + // Locations are application directory, and XDG_CONFIG_HOME/melonds + + FILE* f; + + // First check current working directory + f = OpenFile(path, mode, true); + if (f) return f; + + // then emu directory + { + int dirlen = strlen(EmuDirectory); + if (dirlen) + { + int len = dirlen + 1 + pathlen + 1; + char* tmp = new char[len]; + strncpy(&tmp[0], EmuDirectory, dirlen); + tmp[dirlen] = '/'; + strncpy(&tmp[dirlen+1], path, pathlen); + tmp[dirlen+1+pathlen] = '\0'; + + f = OpenFile(tmp, mode, true); + delete[] tmp; + if (f) return f; + } + } + + if (relpath) return NULL; + + // Now check XDG_CONFIG_HOME + // TODO: check for memory leak there + std::string fullpath = std::string(g_get_user_config_dir()) + "/melonds/" + path; + f = OpenFile(fullpath.c_str(), mode, true); + if (f) return f; + + return NULL; #endif } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 4fc6679..566b346 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -25,7 +25,6 @@ #include "libui/ui.h" #include "../types.h" -#include "../melon_fopen.h" #include "../version.h" #include "PlatformConfig.h" @@ -138,23 +137,6 @@ void GetSavestateName(int slot, char* filename, int len); -bool FileExists(const char* name) -{ - FILE* f = Platform::OpenFile(name, "rb"); - if (!f) return false; - fclose(f); - return true; -} - -bool LocalFileExists(const char* name) -{ - FILE* f = melon_fopen_local(name, "rb"); - if (!f) return false; - fclose(f); - return true; -} - - void MicLoadWav(char* name) { SDL_AudioSpec format; @@ -1077,8 +1059,8 @@ void Run() { char ssfile[1024]; GetSavestateName(i+1, ssfile, 1024); - if (FileExists(ssfile)) uiMenuItemEnable(MenuItem_LoadStateSlot[i]); - else uiMenuItemDisable(MenuItem_LoadStateSlot[i]); + if (Platform::FileExists(ssfile)) uiMenuItemEnable(MenuItem_LoadStateSlot[i]); + else uiMenuItemDisable(MenuItem_LoadStateSlot[i]); } for (int i = 0; i < 9; i++) uiMenuItemEnable(MenuItem_SaveStateSlot[i]); @@ -1210,7 +1192,7 @@ void LoadState(int slot) uiFreeText(file); } - if (!FileExists(filename)) + if (!Platform::FileExists(filename)) { EmuRunning = prevstatus; return; @@ -1752,7 +1734,9 @@ int main(int argc, char** argv) if (Config::AudioVolume < 0) Config::AudioVolume = 0; else if (Config::AudioVolume > 256) Config::AudioVolume = 256; - if (!LocalFileExists("bios7.bin") || !LocalFileExists("bios9.bin") || !LocalFileExists("firmware.bin")) + if (!Platform::LocalFileExists("bios7.bin") || + !Platform::LocalFileExists("bios9.bin") || + !Platform::LocalFileExists("firmware.bin")) { uiMsgBoxError( NULL, @@ -1770,7 +1754,7 @@ int main(int argc, char** argv) } { - FILE* f = melon_fopen_local("romlist.bin", "rb"); + FILE* f = Platform::OpenLocalFile("romlist.bin", "rb"); if (f) { u32 data; -- cgit v1.2.3