aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArisotura <thetotalworm@gmail.com>2019-03-27 13:34:26 +0100
committerArisotura <thetotalworm@gmail.com>2019-03-27 13:34:26 +0100
commitf08b87b41f0ffaabd7928d68c41d704e824b5de3 (patch)
tree8a0548247fbd0a63d4a810d4c1c81bd8444681b3
parent6d7e80b67768d1c14792f5da5ff59b739e2109e6 (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.txt1
-rw-r--r--melonDS.cbp2
-rw-r--r--src/Config.cpp14
-rw-r--r--src/NDS.cpp5
-rw-r--r--src/NDSCart.cpp4
-rw-r--r--src/Platform.h31
-rw-r--r--src/SPI.cpp8
-rw-r--r--src/libui_sdl/Platform.cpp162
-rw-r--r--src/libui_sdl/main.cpp30
-rw-r--r--src/melon_fopen.cpp157
-rw-r--r--src/melon_fopen.h26
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