all repos — mgba @ f1592d350f1ebe0b90eb293541a198b0434e2278

mGBA Game Boy Advance Emulator

Core: Clean up and extend config saving/loading
Vicki Pfau vi@endrift.com
Tue, 08 Dec 2020 19:31:01 -0800
commit

f1592d350f1ebe0b90eb293541a198b0434e2278

parent

67f8197493dd3f978b96f69ad1eabfc1d674de69

M include/mgba-util/configuration.hinclude/mgba-util/configuration.h

@@ -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);
M include/mgba/core/config.hinclude/mgba/core/config.h

@@ -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);
M src/core/config.csrc/core/config.c

@@ -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 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 @@ snprintf(out, outLength, "%s/.config/%s", home, binaryName);

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) {
M src/platform/qt/ConfigController.cppsrc/platform/qt/ConfigController.cpp

@@ -297,6 +297,10 @@ delete m_settings;

m_settings = settings2; } +bool ConfigController::isPortable() { + return mCoreConfigIsPortable(); +} + const QString& ConfigController::configDir() { if (s_configDir.isNull()) { char path[PATH_MAX];
M src/platform/qt/ConfigController.hsrc/platform/qt/ConfigController.h

@@ -91,6 +91,7 @@ const mCoreConfig* config() const { return &m_config; }

mCoreConfig* config() { return &m_config; } static const QString& configDir(); + static bool isPortable(); public slots: void setOption(const char* key, bool value);
M src/util/configuration.csrc/util/configuration.c

@@ -177,9 +177,14 @@ struct VFile* vf = VFileOpen(path, O_WRONLY | O_CREAT | O_TRUNC);

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