* remove EmuDirectory from the core

* rework OpenLocalFile(), make the code more elegant, also fixes #352
This commit is contained in:
Arisotura
2019-03-27 13:54:33 +01:00
parent f08b87b41f
commit 60a728283e
3 changed files with 83 additions and 110 deletions

View File

@ -23,8 +23,6 @@
#include "Platform.h" #include "Platform.h"
extern char* EmuDirectory;
namespace Config namespace Config
{ {
@ -111,20 +109,7 @@ void Load()
void Save() void Save()
{ {
FILE* f = Platform::OpenLocalFile(kConfigFile, "w"); FILE* f = Platform::OpenLocalFile(kConfigFile, "w");
if (!f)
{
int dirlen = strlen(EmuDirectory);
int filelen = strlen(kConfigFile);
char* path = new char[dirlen + 1 + filelen + 1];
strncpy(&path[0], EmuDirectory, dirlen);
path[dirlen] = '/';
strncpy(&path[dirlen+1], kConfigFile, filelen);
path[dirlen+1+filelen] = '\0';
f = Platform::OpenFile(path, "w");
delete[] path;
if (!f) return; if (!f) return;
}
ConfigEntry* entry = &ConfigFile[0]; ConfigEntry* entry = &ConfigFile[0];
int c = 0; int c = 0;

View File

@ -36,7 +36,8 @@ void StopEmu();
// * current working directory // * current working directory
// * emulator directory (essentially where the melonDS executable is) if supported // * emulator directory (essentially where the melonDS executable is) if supported
// * any platform-specific application data directories // * any platform-specific application data directories
// requires that the file already exist. // in create mode, if the file doesn't exist, it will be created in the emulator
// directory if supported, or in the current directory otherwise
FILE* OpenFile(const char* path, const char* mode, bool mustexist=false); FILE* OpenFile(const char* path, const char* mode, bool mustexist=false);
FILE* OpenLocalFile(const char* path, const char* mode); FILE* OpenLocalFile(const char* path, const char* mode);

View File

@ -138,49 +138,61 @@ FILE* OpenLocalFile(const char* path, const char* mode)
bool relpath = false; bool relpath = false;
int pathlen = strlen(path); int pathlen = strlen(path);
#ifdef __WIN32__
if (pathlen > 3)
{
if (path[1] == ':' && path[2] == '\\')
return OpenFile(path, mode);
}
#else
if (pathlen > 1)
{
if (path[0] == '/')
return OpenFile(path, mode);
}
#endif
if (pathlen >= 3) if (pathlen >= 3)
{ {
if (path[0] == '.' && path[1] == '.' && (path[2] == '/' || path[2] == '\\')) if (path[0] == '.' && path[1] == '.' && (path[2] == '/' || path[2] == '\\'))
relpath = true; relpath = true;
} }
#ifdef __WIN32__ int emudirlen = strlen(EmuDirectory);
char* emudirpath;
if (pathlen > 3) if (emudirlen)
{ {
if (path[1] == ':' && path[2] == '\\') int len = emudirlen + 1 + pathlen + 1;
return OpenFile(path, mode); emudirpath = new char[len];
strncpy(&emudirpath[0], EmuDirectory, emudirlen);
emudirpath[emudirlen] = '\\';
strncpy(&emudirpath[emudirlen+1], path, pathlen);
emudirpath[emudirlen+1+pathlen] = '\0';
}
else
{
emudirpath = new char[pathlen+1];
strncpy(&emudirpath[0], path, pathlen);
emudirpath[pathlen] = '\0';
} }
// Locations are application directory, and AppData/melonDS on windows // Locations are application directory, and AppData/melonDS on Windows or XDG_CONFIG_HOME/melonds on Linux
FILE* f; FILE* f;
// First check current working directory // First check current working directory
f = OpenFile(path, mode, true); f = OpenFile(path, mode, true);
if (f) return f; if (f) { delete[] emudirpath; return f; }
// then emu directory // then emu directory
{ f = OpenFile(emudirpath, mode, true);
int dirlen = strlen(EmuDirectory); if (f) { delete[] emudirpath; return f; }
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); #ifdef __WIN32__
delete[] tmp;
if (f) return f;
}
}
// a path relative to AppData wouldn't make much sense // a path relative to AppData wouldn't make much sense
if (relpath) return NULL; if (!relpath)
{
// Now check AppData // Now check AppData
PWSTR appDataPath = NULL; PWSTR appDataPath = NULL;
SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &appDataPath); SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &appDataPath);
@ -214,55 +226,30 @@ FILE* OpenLocalFile(const char* path, const char* mode)
if (f) f = _wfreopen(appDataPath, fatperm, f); if (f) f = _wfreopen(appDataPath, fatperm, f);
CoTaskMemFree(appDataPath); CoTaskMemFree(appDataPath);
delete[] wfileName; delete[] wfileName;
if (f) return f; if (f) { delete[] emudirpath; return f; }
}
return NULL;
#else #else
if (pathlen > 1) if (!relpath)
{ {
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 // Now check XDG_CONFIG_HOME
// TODO: check for memory leak there // TODO: check for memory leak there
std::string fullpath = std::string(g_get_user_config_dir()) + "/melonds/" + path; std::string fullpath = std::string(g_get_user_config_dir()) + "/melonds/" + path;
f = OpenFile(fullpath.c_str(), mode, true); f = OpenFile(fullpath.c_str(), mode, true);
if (f) return f; if (f) { delete[] emudirpath; return f; }
}
return NULL;
#endif #endif
if (mode[0] != 'r')
{
f = OpenFile(emudirpath, mode);
if (f) { delete[] emudirpath; return f; }
}
delete[] emudirpath;
return NULL;
} }