mirror of https://github.com/mgba-emu/mgba.git
Core: Clean up and extend config saving/loading
This commit is contained in:
parent
67f8197493
commit
f1592d350f
|
@ -36,6 +36,7 @@ bool ConfigurationRead(struct Configuration*, const char* path);
|
|||
bool ConfigurationReadVFile(struct Configuration*, struct VFile* vf);
|
||||
bool ConfigurationWrite(const struct Configuration*, const char* path);
|
||||
bool ConfigurationWriteSection(const struct Configuration*, const char* path, const char* section);
|
||||
bool ConfigurationWriteVFile(const struct Configuration*, struct VFile* vf);
|
||||
|
||||
void ConfigurationEnumerateSections(const struct Configuration* configuration, void (*handler)(const char* sectionName, void* user), void* user);
|
||||
void ConfigurationEnumerate(const struct Configuration* configuration, const char* section, void (*handler)(const char* key, const char* value, void* user), void* user);
|
||||
|
|
|
@ -68,9 +68,13 @@ bool mCoreConfigLoad(struct mCoreConfig*);
|
|||
bool mCoreConfigSave(const struct mCoreConfig*);
|
||||
bool mCoreConfigLoadPath(struct mCoreConfig*, const char* path);
|
||||
bool mCoreConfigSavePath(const struct mCoreConfig*, const char* path);
|
||||
bool mCoreConfigLoadVFile(struct mCoreConfig*, struct VFile* vf);
|
||||
bool mCoreConfigSaveVFile(const struct mCoreConfig*, struct VFile* vf);
|
||||
|
||||
void mCoreConfigMakePortable(const struct mCoreConfig*);
|
||||
void mCoreConfigDirectory(char* out, size_t outLength);
|
||||
void mCoreConfigPortablePath(char* out, size_t outLength);
|
||||
bool mCoreConfigIsPortable(void);
|
||||
#endif
|
||||
|
||||
const char* mCoreConfigGetValue(const struct mCoreConfig*, const char* key);
|
||||
|
|
|
@ -170,27 +170,23 @@ bool mCoreConfigSavePath(const struct mCoreConfig* config, const char* path) {
|
|||
return ConfigurationWrite(&config->configTable, path);
|
||||
}
|
||||
|
||||
bool mCoreConfigLoadVFile(struct mCoreConfig* config, struct VFile* vf) {
|
||||
return ConfigurationReadVFile(&config->configTable, vf);
|
||||
}
|
||||
|
||||
bool mCoreConfigSaveVFile(const struct mCoreConfig* config, struct VFile* vf) {
|
||||
return ConfigurationWriteVFile(&config->configTable, vf);
|
||||
}
|
||||
|
||||
void mCoreConfigMakePortable(const struct mCoreConfig* config) {
|
||||
struct VFile* portable = 0;
|
||||
#ifdef _WIN32
|
||||
char out[MAX_PATH];
|
||||
wchar_t wpath[MAX_PATH];
|
||||
wchar_t wprojectName[MAX_PATH];
|
||||
MultiByteToWideChar(CP_UTF8, 0, projectName, -1, wprojectName, MAX_PATH);
|
||||
HMODULE hModule = GetModuleHandleW(NULL);
|
||||
GetModuleFileNameW(hModule, wpath, MAX_PATH);
|
||||
PathRemoveFileSpecW(wpath);
|
||||
WideCharToMultiByte(CP_UTF8, 0, wpath, -1, out, MAX_PATH, 0, 0);
|
||||
StringCchCatA(out, MAX_PATH, "\\portable.ini");
|
||||
portable = VFileOpen(out, O_WRONLY | O_CREAT);
|
||||
#elif defined(PSP2) || defined(_3DS) || defined(__SWITCH__) || defined(GEKKO)
|
||||
// Already portable
|
||||
#else
|
||||
struct VFile* portable = NULL;
|
||||
char out[PATH_MAX];
|
||||
getcwd(out, PATH_MAX);
|
||||
strncat(out, PATH_SEP "portable.ini", PATH_MAX - strlen(out));
|
||||
mCoreConfigPortablePath(out, sizeof(out));
|
||||
if (!out[0]) {
|
||||
// Cannot be made portable
|
||||
return;
|
||||
}
|
||||
portable = VFileOpen(out, O_WRONLY | O_CREAT);
|
||||
#endif
|
||||
if (portable) {
|
||||
portable->close(portable);
|
||||
mCoreConfigSave(config);
|
||||
|
@ -199,62 +195,44 @@ void mCoreConfigMakePortable(const struct mCoreConfig* config) {
|
|||
|
||||
void mCoreConfigDirectory(char* out, size_t outLength) {
|
||||
struct VFile* portable;
|
||||
char portableDir[PATH_MAX];
|
||||
mCoreConfigPortablePath(portableDir, sizeof(portableDir));
|
||||
if (portableDir[0]) {
|
||||
portable = VFileOpen(portableDir, O_RDONLY);
|
||||
if (portable) {
|
||||
portable->close(portable);
|
||||
if (outLength < PATH_MAX) {
|
||||
char outTmp[PATH_MAX];
|
||||
separatePath(portableDir, outTmp, NULL, NULL);
|
||||
strlcpy(out, outTmp, outLength);
|
||||
} else {
|
||||
separatePath(portableDir, out, NULL, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
#ifdef _WIN32
|
||||
wchar_t wpath[MAX_PATH];
|
||||
wchar_t wprojectName[MAX_PATH];
|
||||
MultiByteToWideChar(CP_UTF8, 0, projectName, -1, wprojectName, MAX_PATH);
|
||||
HMODULE hModule = GetModuleHandleW(NULL);
|
||||
GetModuleFileNameW(hModule, wpath, MAX_PATH);
|
||||
PathRemoveFileSpecW(wpath);
|
||||
WideCharToMultiByte(CP_UTF8, 0, wpath, -1, out, outLength, 0, 0);
|
||||
StringCchCatA(out, outLength, "\\portable.ini");
|
||||
portable = VFileOpen(out, O_RDONLY);
|
||||
if (portable) {
|
||||
portable->close(portable);
|
||||
} else {
|
||||
wchar_t* home;
|
||||
SHGetKnownFolderPath(&FOLDERID_RoamingAppData, 0, NULL, &home);
|
||||
StringCchPrintfW(wpath, MAX_PATH, L"%ws\\%ws", home, wprojectName);
|
||||
CoTaskMemFree(home);
|
||||
CreateDirectoryW(wpath, NULL);
|
||||
}
|
||||
WideCharToMultiByte(CP_UTF8, 0, wpath, -1, out, outLength, 0, 0);
|
||||
wchar_t* home;
|
||||
SHGetKnownFolderPath(&FOLDERID_RoamingAppData, 0, NULL, &home);
|
||||
StringCchPrintfW(wpath, MAX_PATH, L"%ws\\%ws", home, wprojectName);
|
||||
CoTaskMemFree(home);
|
||||
CreateDirectoryW(wpath, NULL);
|
||||
#elif defined(PSP2)
|
||||
UNUSED(portable);
|
||||
snprintf(out, outLength, "ux0:data/%s", projectName);
|
||||
sceIoMkdir(out, 0777);
|
||||
#elif defined(GEKKO) || defined(__SWITCH__)
|
||||
UNUSED(portable);
|
||||
snprintf(out, outLength, "/%s", projectName);
|
||||
mkdir(out, 0777);
|
||||
#elif defined(_3DS)
|
||||
UNUSED(portable);
|
||||
snprintf(out, outLength, "/%s", projectName);
|
||||
FSUSER_CreateDirectory(sdmcArchive, fsMakePath(PATH_ASCII, out), 0);
|
||||
#elif defined(__HAIKU__)
|
||||
getcwd(out, outLength);
|
||||
strncat(out, PATH_SEP "portable.ini", outLength - strlen(out));
|
||||
portable = VFileOpen(out, O_RDONLY);
|
||||
if (portable) {
|
||||
getcwd(out, outLength);
|
||||
portable->close(portable);
|
||||
return;
|
||||
}
|
||||
|
||||
char path[B_PATH_NAME_LENGTH];
|
||||
find_directory(B_USER_SETTINGS_DIRECTORY, 0, false, path, B_PATH_NAME_LENGTH);
|
||||
snprintf(out, outLength, "%s/%s", path, binaryName);
|
||||
mkdir(out, 0755);
|
||||
#else
|
||||
getcwd(out, outLength);
|
||||
strncat(out, PATH_SEP "portable.ini", outLength - strlen(out));
|
||||
portable = VFileOpen(out, O_RDONLY);
|
||||
if (portable) {
|
||||
getcwd(out, outLength);
|
||||
portable->close(portable);
|
||||
return;
|
||||
}
|
||||
|
||||
char* xdgConfigHome = getenv("XDG_CONFIG_HOME");
|
||||
if (xdgConfigHome && xdgConfigHome[0] == '/') {
|
||||
snprintf(out, outLength, "%s/%s", xdgConfigHome, binaryName);
|
||||
|
@ -268,6 +246,39 @@ void mCoreConfigDirectory(char* out, size_t outLength) {
|
|||
mkdir(out, 0755);
|
||||
#endif
|
||||
}
|
||||
|
||||
void mCoreConfigPortablePath(char* out, size_t outLength) {
|
||||
#ifdef _WIN32
|
||||
wchar_t wpath[MAX_PATH];
|
||||
wchar_t wprojectName[MAX_PATH];
|
||||
MultiByteToWideChar(CP_UTF8, 0, projectName, -1, wprojectName, MAX_PATH);
|
||||
HMODULE hModule = GetModuleHandleW(NULL);
|
||||
GetModuleFileNameW(hModule, wpath, MAX_PATH);
|
||||
PathRemoveFileSpecW(wpath);
|
||||
WideCharToMultiByte(CP_UTF8, 0, wpath, -1, out, outLength, 0, 0);
|
||||
StringCchCatA(out, outLength, "\\portable.ini");
|
||||
#elif defined(PSP2) || defined(GEKKO) || defined(__SWITCH__) || defined(_3DS)
|
||||
out[0] = '\0';
|
||||
#else
|
||||
getcwd(out, outLength);
|
||||
strncat(out, PATH_SEP "portable.ini", outLength - strlen(out));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool mCoreConfigIsPortable(void) {
|
||||
struct VFile* portable;
|
||||
char portableDir[PATH_MAX];
|
||||
mCoreConfigPortablePath(portableDir, sizeof(portableDir));
|
||||
if (portableDir[0]) {
|
||||
portable = VFileOpen(portableDir, O_RDONLY);
|
||||
if (portable) {
|
||||
portable->close(portable);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
const char* mCoreConfigGetValue(const struct mCoreConfig* config, const char* key) {
|
||||
|
|
|
@ -297,6 +297,10 @@ void ConfigController::makePortable() {
|
|||
m_settings = settings2;
|
||||
}
|
||||
|
||||
bool ConfigController::isPortable() {
|
||||
return mCoreConfigIsPortable();
|
||||
}
|
||||
|
||||
const QString& ConfigController::configDir() {
|
||||
if (s_configDir.isNull()) {
|
||||
char path[PATH_MAX];
|
||||
|
|
|
@ -91,6 +91,7 @@ public:
|
|||
mCoreConfig* config() { return &m_config; }
|
||||
|
||||
static const QString& configDir();
|
||||
static bool isPortable();
|
||||
|
||||
public slots:
|
||||
void setOption(const char* key, bool value);
|
||||
|
|
|
@ -177,9 +177,14 @@ bool ConfigurationWrite(const struct Configuration* configuration, const char* p
|
|||
if (!vf) {
|
||||
return false;
|
||||
}
|
||||
bool res = ConfigurationWriteVFile(configuration, vf);
|
||||
vf->close(vf);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConfigurationWriteVFile(const struct Configuration* configuration, struct VFile* vf) {
|
||||
HashTableEnumerate(&configuration->root, _keyHandler, vf);
|
||||
HashTableEnumerate(&configuration->sections, _sectionHandler, vf);
|
||||
vf->close(vf);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue