* 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
This commit is contained in:
Arisotura
2019-03-27 13:34:26 +01:00
parent 6d7e80b677
commit f08b87b41f
11 changed files with 207 additions and 235 deletions

View File

@ -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;
return ret;
#else
return fopen(path, mode);
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
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
}

View File

@ -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;