diff options
author | Arisotura <thetotalworm@gmail.com> | 2019-03-27 13:34:26 +0100 |
---|---|---|
committer | Arisotura <thetotalworm@gmail.com> | 2019-03-27 13:34:26 +0100 |
commit | f08b87b41f0ffaabd7928d68c41d704e824b5de3 (patch) | |
tree | 8a0548247fbd0a63d4a810d4c1c81bd8444681b3 | |
parent | 6d7e80b67768d1c14792f5da5ff59b739e2109e6 (diff) |
* 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
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | melonDS.cbp | 2 | ||||
-rw-r--r-- | src/Config.cpp | 14 | ||||
-rw-r--r-- | src/NDS.cpp | 5 | ||||
-rw-r--r-- | src/NDSCart.cpp | 4 | ||||
-rw-r--r-- | src/Platform.h | 31 | ||||
-rw-r--r-- | src/SPI.cpp | 8 | ||||
-rw-r--r-- | src/libui_sdl/Platform.cpp | 162 | ||||
-rw-r--r-- | src/libui_sdl/main.cpp | 30 | ||||
-rw-r--r-- | src/melon_fopen.cpp | 157 | ||||
-rw-r--r-- | src/melon_fopen.h | 26 |
11 files changed, 206 insertions, 234 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 0dbf043..8abe112 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,6 @@ SET(SOURCES src/GPU2D.cpp src/GPU3D.cpp src/GPU3D_Soft.cpp - src/melon_fopen.cpp src/NDS.cpp src/NDSCart.cpp src/RTC.cpp diff --git a/melonDS.cbp b/melonDS.cbp index 5bc0ff6..fc5f8df 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -253,8 +253,6 @@ <Unit filename="src/libui_sdl/libui/windows/winpublic.cpp" /> <Unit filename="src/libui_sdl/libui/windows/winutil.cpp" /> <Unit filename="src/libui_sdl/main.cpp" /> - <Unit filename="src/melon_fopen.cpp" /> - <Unit filename="src/melon_fopen.h" /> <Unit filename="src/pcap/bluetooth.h" /> <Unit filename="src/pcap/bpf.h" /> <Unit filename="src/pcap/can_socketcan.h" /> diff --git a/src/Config.cpp b/src/Config.cpp index 760ad3b..deddc58 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -21,10 +21,8 @@ #include <stdlib.h> #include "Config.h" #include "Platform.h" -#include "melon_fopen.h" -bool LocalFileExists(const char* name); extern char* EmuDirectory; namespace Config @@ -69,7 +67,7 @@ void Load() entry++; } - FILE* f = melon_fopen_local(kConfigFile, "r"); + FILE* f = Platform::OpenLocalFile(kConfigFile, "r"); if (!f) return; char linebuf[1024]; @@ -112,14 +110,8 @@ void Load() void Save() { - // TODO not make path search shit tself and pick the wrong ath every damn tiem!!!!! - FILE* f; - if (LocalFileExists(kConfigFile)) - { - f = melon_fopen_local(kConfigFile, "w"); - if (!f) return; - } - else + FILE* f = Platform::OpenLocalFile(kConfigFile, "w"); + if (!f) { int dirlen = strlen(EmuDirectory); int filelen = strlen(kConfigFile); diff --git a/src/NDS.cpp b/src/NDS.cpp index d0b04c4..dac1773 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -30,7 +30,6 @@ #include "RTC.h" #include "Wifi.h" #include "Platform.h" -#include "melon_fopen.h" namespace NDS @@ -388,7 +387,7 @@ void Reset() LastSysClockCycles = 0; - f = melon_fopen_local("bios9.bin", "rb"); + f = Platform::OpenLocalFile("bios9.bin", "rb"); if (!f) { printf("ARM9 BIOS not found\n"); @@ -405,7 +404,7 @@ void Reset() fclose(f); } - f = melon_fopen_local("bios7.bin", "rb"); + f = Platform::OpenLocalFile("bios7.bin", "rb"); if (!f) { printf("ARM7 BIOS not found\n"); diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index 7856bc9..0ecd304 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -22,8 +22,6 @@ #include "NDSCart.h" #include "ARM.h" #include "CRC32.h" - -#include "melon_fopen.h" #include "Platform.h" @@ -817,7 +815,7 @@ bool ReadROMParams(u32 gamecode, u32* params) // [gamecode] [ROM size] [save type] [reserved] // list must be sorted by gamecode - FILE* f = melon_fopen_local("romlist.bin", "rb"); + FILE* f = Platform::OpenLocalFile("romlist.bin", "rb"); if (!f) return false; fseek(f, 0, SEEK_END); diff --git a/src/Platform.h b/src/Platform.h index 6adc2a2..9b801ef 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -26,7 +26,36 @@ namespace Platform void StopEmu(); -FILE* OpenFile(const char* path, const char* mode); +// fopen() wrappers +// * OpenFile(): +// simple fopen() wrapper that supports UTF8. +// can be optionally restricted to only opening a file that already exists. +// * OpenLocalFile(): +// opens files local to the emulator (melonDS.ini, BIOS, firmware, ...) +// checks, by order of priority: +// * current working directory +// * emulator directory (essentially where the melonDS executable is) if supported +// * any platform-specific application data directories +// requires that the file already exist. + +FILE* OpenFile(const char* path, const char* mode, bool mustexist=false); +FILE* OpenLocalFile(const char* path, const char* mode); + +inline bool FileExists(const char* name) +{ + FILE* f = OpenFile(name, "rb"); + if (!f) return false; + fclose(f); + return true; +} + +inline bool LocalFileExists(const char* name) +{ + FILE* f = OpenLocalFile(name, "rb"); + if (!f) return false; + fclose(f); + return true; +} void* Thread_Create(void (*func)()); void Thread_Free(void* thread); diff --git a/src/SPI.cpp b/src/SPI.cpp index 5ed9890..6224338 100644 --- a/src/SPI.cpp +++ b/src/SPI.cpp @@ -22,7 +22,7 @@ #include "Config.h" #include "NDS.h" #include "SPI.h" -#include "melon_fopen.h" +#include "Platform.h" namespace SPI_Firmware @@ -90,7 +90,7 @@ void Reset() if (Firmware) delete[] Firmware; Firmware = NULL; - FILE* f = melon_fopen_local("firmware.bin", "rb"); + FILE* f = Platform::OpenLocalFile("firmware.bin", "rb"); if (!f) { printf("firmware.bin not found\n"); @@ -130,7 +130,7 @@ void Reset() // take a backup char* firmbkp = "firmware.bin.bak"; - f = melon_fopen_local(firmbkp, "rb"); + f = fopen(firmbkp, "rb"); if (f) fclose(f); else { @@ -325,7 +325,7 @@ void Write(u8 val, u32 hold) if (!hold && (CurCmd == 0x02 || CurCmd == 0x0A)) { - FILE* f = melon_fopen_local("firmware.bin", "r+b"); + FILE* f = Platform::OpenLocalFile("firmware.bin", "r+b"); if (f) { u32 cutoff = 0x7FA00 & FirmwareMask; 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 <windows.h> + //#include <knownfolders.h> // FUCK THAT SHIT + extern "C" const GUID DECLSPEC_SELECTANY FOLDERID_RoamingAppData = {0x3eb685db, 0x65f9, 0x4cf6, {0xa0, 0x3a, 0xe3, 0xef, 0x65, 0x72, 0x9f, 0x3d}}; + #include <shlobj.h> #include <winsock2.h> #include <ws2tcpip.h> #define socket_t SOCKET #define sockaddr_t SOCKADDR #else + #include <glib.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> @@ -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; diff --git a/src/melon_fopen.cpp b/src/melon_fopen.cpp deleted file mode 100644 index 5e0d03f..0000000 --- a/src/melon_fopen.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* - Copyright 2016-2019 Arisotura - - This file is part of melonDS. - - melonDS is free software: you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) - any later version. - - melonDS is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with melonDS. If not, see http://www.gnu.org/licenses/. -*/ - -// TODO: all this should ideally go in Platform.cpp - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <string> -#ifdef _WIN32 -#define NTDDI_VERSION 0x06000000 // GROSS FUCKING HACK -#include <windows.h> -//#include <knownfolders.h> // FUCK THAT SHIT -extern "C" const GUID DECLSPEC_SELECTANY FOLDERID_RoamingAppData = {0x3eb685db, 0x65f9, 0x4cf6, {0xa0, 0x3a, 0xe3, 0xef, 0x65, 0x72, 0x9f, 0x3d}}; -#include <shlobj.h> -#else -#include <glib.h> -#endif - -#include "Platform.h" -extern char* EmuDirectory; - - -#ifdef __WIN32__ - - - -FILE* melon_fopen_local(const char* fileName, const char* permissions) -{ - // Locations are application directory, and AppData/melonDS on windows - - FILE* f; - - // First check current working directory - f = fopen(fileName, permissions); - if (f) return f; - - // then emu directory - { - int dirlen = strlen(EmuDirectory); - if (dirlen) - { - int filelen = strlen(fileName); - int len = dirlen + 1 + filelen + 1; - char* tmp = new char[len]; - strncpy(&tmp[0], EmuDirectory, dirlen); - tmp[dirlen] = '\\'; - strncpy(&tmp[dirlen+1], fileName, filelen); - tmp[dirlen+1+filelen] = '\0'; - - f = Platform::OpenFile(tmp, permissions); - delete[] tmp; - if (f) return f; - } - } - - // 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] = permissions[0]; - fatperm[1] = permissions[1]; - fatperm[2] = permissions[2]; - fatperm[3] = 0; - - int fnlen = MultiByteToWideChar(CP_UTF8, 0, fileName, -1, NULL, 0); - if (fnlen < 1) return NULL; - WCHAR* wfileName = new WCHAR[fnlen]; - int res = MultiByteToWideChar(CP_UTF8, 0, fileName, -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, fatperm); - CoTaskMemFree(appDataPath); - delete[] wfileName; - if (f) return f; - - return NULL; - -} - - - -#else - - - -FILE* melon_fopen_local(const char* fileName, const char* permissions) -{ - // Locations are application directory, and XDG_CONFIG_HOME/melonds - - FILE* f; - - // First check current working directory - f = fopen(fileName, permissions); - if (f) return f; - - // then emu directory - { - int dirlen = strlen(EmuDirectory); - if (dirlen) - { - int filelen = strlen(fileName); - int len = dirlen + 1 + filelen + 1; - char* tmp = new char[len]; - strncpy(&tmp[0], EmuDirectory, dirlen); - tmp[dirlen] = '/'; - strncpy(&tmp[dirlen+1], fileName, filelen); - tmp[dirlen+1+filelen] = '\0'; - - f = fopen(tmp, permissions); - delete[] tmp; - if (f) return f; - } - } - - // Now check XDG_CONFIG_HOME - // TODO: check for memory leak there - std::string path = std::string(g_get_user_config_dir()) + "/melonds/" + fileName; - f = fopen(path.c_str(), permissions); - if (f) return f; - - return NULL; - -} - - - -#endif diff --git a/src/melon_fopen.h b/src/melon_fopen.h deleted file mode 100644 index 4de11e0..0000000 --- a/src/melon_fopen.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - Copyright 2016-2019 Arisotura - - This file is part of melonDS. - - melonDS is free software: you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) - any later version. - - melonDS is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with melonDS. If not, see http://www.gnu.org/licenses/. -*/ - -#ifndef MELON_FOPEN_H -#define MELON_FOPEN_H - - -FILE* melon_fopen_local(const char* filename, const char* perm); - - -#endif // MELON_FOPEN_H |