Clean up config code (#679)

* Clean up config code

* Export function

* Fix
This commit is contained in:
Christian Semmler 2025-08-15 09:56:36 -07:00 committed by GitHub
parent 94c2d16180
commit 73c6be7abf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 46 additions and 82 deletions

View File

@ -21,7 +21,6 @@ void Android_SetupDefaultConfigOverrides(dictionary* p_dictionary)
iniparser_set(p_dictionary, "isle:diskpath", data); iniparser_set(p_dictionary, "isle:diskpath", data);
iniparser_set(p_dictionary, "isle:cdpath", data); iniparser_set(p_dictionary, "isle:cdpath", data);
iniparser_set(p_dictionary, "isle:mediapath", data); iniparser_set(p_dictionary, "isle:mediapath", data);
iniparser_set(p_dictionary, "isle:savepath", savedata.GetData()); iniparser_set(p_dictionary, "isle:savepath", savedata.GetData());
// Default to Virtual Mouse // Default to Virtual Mouse

View File

@ -1,5 +1,7 @@
#include "config.h" #include "config.h"
#include "mxstring.h"
#include <SDL3/SDL_filesystem.h> #include <SDL3/SDL_filesystem.h>
#include <SDL3/SDL_log.h> #include <SDL3/SDL_log.h>
#include <iniparser.h> #include <iniparser.h>
@ -11,15 +13,13 @@ void IOS_SetupDefaultConfigOverrides(dictionary* p_dictionary)
// Use DevelopmentFiles path for disk and cd paths // Use DevelopmentFiles path for disk and cd paths
// It's good to use that path since user can easily // It's good to use that path since user can easily
// connect through SMB and copy the files // connect through SMB and copy the files
const char* documentFolder = SDL_GetUserFolder(SDL_FOLDER_DOCUMENTS); MxString documentFolder = SDL_GetUserFolder(SDL_FOLDER_DOCUMENTS);
char* diskPath = new char[strlen(documentFolder) + strlen("isle") + 1](); documentFolder += "isle";
strcpy(diskPath, documentFolder);
strcat(diskPath, "isle");
if (!SDL_GetPathInfo(diskPath, NULL)) { if (!SDL_GetPathInfo(documentFolder.GetData(), NULL)) {
SDL_CreateDirectory(diskPath); SDL_CreateDirectory(documentFolder.GetData());
} }
iniparser_set(p_dictionary, "isle:diskpath", diskPath); iniparser_set(p_dictionary, "isle:diskpath", documentFolder.GetData());
iniparser_set(p_dictionary, "isle:cdpath", diskPath); iniparser_set(p_dictionary, "isle:cdpath", documentFolder.GetData());
} }

View File

@ -40,6 +40,7 @@
#include <array> #include <array>
#include <extensions/extensions.h> #include <extensions/extensions.h>
#include <miniwin/miniwindevice.h> #include <miniwin/miniwindevice.h>
#include <type_traits>
#include <vec.h> #include <vec.h>
#define SDL_MAIN_USE_CALLBACKS #define SDL_MAIN_USE_CALLBACKS
@ -172,6 +173,7 @@ IsleApp::IsleApp()
LegoOmni::CreateInstance(); LegoOmni::CreateInstance();
m_mediaPath = NULL;
m_iniPath = NULL; m_iniPath = NULL;
m_maxLod = RealtimeView::GetUserMaxLOD(); m_maxLod = RealtimeView::GetUserMaxLOD();
m_maxAllowedExtras = m_islandQuality <= 1 ? 10 : 20; m_maxAllowedExtras = m_islandQuality <= 1 ? 10 : 20;
@ -198,25 +200,11 @@ IsleApp::~IsleApp()
MxOmni::DestroyInstance(); MxOmni::DestroyInstance();
} }
if (m_hdPath) { SDL_free(m_hdPath);
delete[] m_hdPath; SDL_free(m_cdPath);
} SDL_free(m_deviceId);
SDL_free(m_savePath);
if (m_cdPath) { SDL_free(m_mediaPath);
delete[] m_cdPath;
}
if (m_deviceId) {
delete[] m_deviceId;
}
if (m_savePath) {
delete[] m_savePath;
}
if (m_mediaPath) {
delete[] m_mediaPath;
}
} }
// FUNCTION: ISLE 0x401260 // FUNCTION: ISLE 0x401260
@ -1032,39 +1020,32 @@ bool IsleApp::LoadConfig()
#ifdef IOS #ifdef IOS
const char* prefPath = SDL_GetUserFolder(SDL_FOLDER_DOCUMENTS); const char* prefPath = SDL_GetUserFolder(SDL_FOLDER_DOCUMENTS);
#elif defined(ANDROID) #elif defined(ANDROID)
// SDL_GetAndroidExternalStoragePath() returns without a trailing / resulting in "filesisle.ini" :( MxString androidPath = MxString(SDL_GetAndroidExternalStoragePath()) + "/";
const char* androidPath = SDL_GetAndroidExternalStoragePath(); const char* prefPath = androidPath.GetData();
size_t len = SDL_strlen(androidPath) + 2; #elif defined(EMSCRIPTEN)
char* prefPath = new char[len];
SDL_strlcpy(prefPath, androidPath, len);
SDL_strlcat(prefPath, "/", len);
#else
char* prefPath = SDL_GetPrefPath("isledecomp", "isle");
#endif
char* iniConfig;
#ifdef __EMSCRIPTEN__
if (m_iniPath && !Emscripten_SetupConfig(m_iniPath)) { if (m_iniPath && !Emscripten_SetupConfig(m_iniPath)) {
m_iniPath = NULL; m_iniPath = NULL;
} }
char* prefPath = SDL_GetPrefPath("isledecomp", "isle");
#else
char* prefPath = SDL_GetPrefPath("isledecomp", "isle");
#endif #endif
MxString iniConfig;
if (m_iniPath) { if (m_iniPath) {
iniConfig = new char[strlen(m_iniPath) + 1]; iniConfig = m_iniPath;
strcpy(iniConfig, m_iniPath);
} }
else if (prefPath) { else if (prefPath) {
iniConfig = new char[strlen(prefPath) + strlen("isle.ini") + 1](); iniConfig = prefPath;
strcat(iniConfig, prefPath); iniConfig += "isle.ini";
strcat(iniConfig, "isle.ini");
} }
else { else {
iniConfig = new char[strlen("isle.ini") + 1]; iniConfig = "isle.ini";
strcpy(iniConfig, "isle.ini");
} }
SDL_Log("Reading configuration from \"%s\"", iniConfig);
dictionary* dict = iniparser_load(iniConfig); SDL_Log("Reading configuration from \"%s\"", iniConfig.GetData());
dictionary* dict = iniparser_load(iniConfig.GetData());
// [library:config] // [library:config]
// Load sane defaults if dictionary failed to load // Load sane defaults if dictionary failed to load
@ -1075,20 +1056,20 @@ bool IsleApp::LoadConfig()
} }
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Loading sane defaults"); SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Loading sane defaults");
FILE* iniFP = fopen(iniConfig, "wb"); FILE* iniFP = fopen(iniConfig.GetData(), "wb");
if (!iniFP) { if (!iniFP) {
SDL_LogError( SDL_LogError(
SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_CATEGORY_APPLICATION,
"Failed to write config at '%s': %s", "Failed to write config at '%s': %s",
iniConfig, iniConfig.GetData(),
strerror(errno) strerror(errno)
); );
return false; return false;
} }
char buf[32]; char buf[32];
dict = iniparser_load(iniConfig); dict = iniparser_load(iniConfig.GetData());
iniparser_set(dict, "isle", NULL); iniparser_set(dict, "isle", NULL);
iniparser_set(dict, "isle:diskpath", SDL_GetBasePath()); iniparser_set(dict, "isle:diskpath", SDL_GetBasePath());
@ -1143,8 +1124,9 @@ bool IsleApp::LoadConfig()
#ifdef ANDROID #ifdef ANDROID
Android_SetupDefaultConfigOverrides(dict); Android_SetupDefaultConfigOverrides(dict);
#endif #endif
iniparser_dump_ini(dict, iniFP); iniparser_dump_ini(dict, iniFP);
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "New config written at '%s'", iniConfig); SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "New config written at '%s'", iniConfig.GetData());
fclose(iniFP); fclose(iniFP);
} }
@ -1152,20 +1134,10 @@ bool IsleApp::LoadConfig()
Emscripten_SetupDefaultConfigOverrides(dict); Emscripten_SetupDefaultConfigOverrides(dict);
#endif #endif
const char* hdPath = iniparser_getstring(dict, "isle:diskpath", SDL_GetBasePath()); MxOmni::SetHD((m_hdPath = SDL_strdup(iniparser_getstring(dict, "isle:diskpath", SDL_GetBasePath()))));
m_hdPath = new char[strlen(hdPath) + 1]; MxOmni::SetCD((m_cdPath = SDL_strdup(iniparser_getstring(dict, "isle:cdpath", MxOmni::GetCD()))));
strcpy(m_hdPath, hdPath); m_savePath = SDL_strdup(iniparser_getstring(dict, "isle:savepath", prefPath));
MxOmni::SetHD(m_hdPath); m_mediaPath = SDL_strdup(iniparser_getstring(dict, "isle:mediapath", m_hdPath));
const char* cdPath = iniparser_getstring(dict, "isle:cdpath", MxOmni::GetCD());
m_cdPath = new char[strlen(cdPath) + 1];
strcpy(m_cdPath, cdPath);
MxOmni::SetCD(m_cdPath);
const char* mediaPath = iniparser_getstring(dict, "isle:mediapath", hdPath);
m_mediaPath = new char[strlen(mediaPath) + 1];
strcpy(m_mediaPath, mediaPath);
m_flipSurfaces = iniparser_getboolean(dict, "isle:Flip Surfaces", m_flipSurfaces); m_flipSurfaces = iniparser_getboolean(dict, "isle:Flip Surfaces", m_flipSurfaces);
m_fullScreen = iniparser_getboolean(dict, "isle:Full Screen", m_fullScreen); m_fullScreen = iniparser_getboolean(dict, "isle:Full Screen", m_fullScreen);
m_exclusiveFullScreen = iniparser_getboolean(dict, "isle:Exclusive Full Screen", m_exclusiveFullScreen); m_exclusiveFullScreen = iniparser_getboolean(dict, "isle:Exclusive Full Screen", m_exclusiveFullScreen);
@ -1212,17 +1184,9 @@ bool IsleApp::LoadConfig()
const char* deviceId = iniparser_getstring(dict, "isle:3D Device ID", NULL); const char* deviceId = iniparser_getstring(dict, "isle:3D Device ID", NULL);
if (deviceId != NULL) { if (deviceId != NULL) {
m_deviceId = new char[strlen(deviceId) + 1]; m_deviceId = SDL_strdup(deviceId);
strcpy(m_deviceId, deviceId);
} }
// [library:config]
// The original game does not save any data if no savepath is given.
// Instead, we use SDLs prefPath as a default fallback and always save data.
const char* savePath = iniparser_getstring(dict, "isle:savepath", prefPath);
m_savePath = new char[strlen(savePath) + 1];
strcpy(m_savePath, savePath);
#ifdef EXTENSIONS #ifdef EXTENSIONS
for (const char* key : Extensions::availableExtensions) { for (const char* key : Extensions::availableExtensions) {
if (iniparser_getboolean(dict, key, 0)) { if (iniparser_getboolean(dict, key, 0)) {
@ -1242,11 +1206,12 @@ bool IsleApp::LoadConfig()
#endif #endif
iniparser_freedict(dict); iniparser_freedict(dict);
delete[] iniConfig;
#ifndef IOS
SDL_free(prefPath);
#endif
[](auto path) {
if constexpr (std::is_same_v<decltype(path), char*>) {
SDL_free(path);
}
}(prefPath);
return true; return true;
} }

View File

@ -101,7 +101,7 @@ class IsleApp {
MxFloat m_cursorSensitivity; MxFloat m_cursorSensitivity;
void DisplayArgumentHelp(const char* p_execName); void DisplayArgumentHelp(const char* p_execName);
char* m_iniPath; const char* m_iniPath;
MxFloat m_maxLod; MxFloat m_maxLod;
MxU32 m_maxAllowedExtras; MxU32 m_maxAllowedExtras;
MxTransitionManager::TransitionType m_transitionType; MxTransitionManager::TransitionType m_transitionType;

View File

@ -9,7 +9,7 @@
// SIZE 0x10 // SIZE 0x10
class MxString : public MxCore { class MxString : public MxCore {
public: public:
MxString(); LEGO1_EXPORT MxString();
MxString(const MxString& p_str); MxString(const MxString& p_str);
LEGO1_EXPORT MxString(const char* p_str); LEGO1_EXPORT MxString(const char* p_str);
MxString(const char* p_str, MxU16 p_maxlen); MxString(const char* p_str, MxU16 p_maxlen);