From c9482ba86cf48f5f30c4a424313d5507e7257f35 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 1 Jun 2024 16:36:00 -0500 Subject: [PATCH] I HATE GLOBAL CONFIGS I HATE GLOBAL CONFIGS I HATE @tildearrow instead of this nonsense you could have just made a language menu in the interface settings --- CMakeLists.txt | 47 ++++++++++++++++++++--------------------- src/engine/engine.cpp | 23 ++++++++++++-------- src/engine/engine.h | 5 +++++ src/gui/gui.h | 4 +++- src/gui/settings.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 8 +++++-- src/momo/momo.c | 36 ++++++++++++++++++++++++++++--- 7 files changed, 133 insertions(+), 39 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 40c236a34..72fd82c99 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -182,30 +182,6 @@ if (WIN32) endif() endif() -if (WITH_LOCALE) - if (USE_MOMO) - add_library(momo STATIC src/momo/momo.c) - list(APPEND DEPENDENCIES_DEFINES HAVE_LOCALE) - list(APPEND DEPENDENCIES_DEFINES HAVE_MOMO) - list(APPEND DEPENDENCIES_INCLUDE_DIRS src/momo) - list(APPEND DEPENDENCIES_LIBRARIES momo) - message(STATUS "Using libintl (Momo)") - else() - if ("${CMAKE_VERSION}" VERSION_LESS "3.2") - message(FATAL_ERROR "CMake 3.2 or later required for locale support.") - else() - include(FindIntl) - if (NOT Intl_FOUND) - message(FATAL_ERROR "Could not find libintl! Try enabling USE_MOMO.") - endif() - list(APPEND DEPENDENCIES_DEFINES HAVE_LOCALE) - list(APPEND DEPENDENCIES_INCLUDE_DIRS ${Intl_INCLUDE_DIRS}) - list(APPEND DEPENDENCIES_LIBRARIES ${Intl_LIBRARIES}) - message(STATUS "Using libintl (system)") - endif() - endif() -endif() - if (SYSTEM_FFTW) find_package(PkgConfig REQUIRED) pkg_check_modules(FFTW REQUIRED fftw3>=3.3) @@ -1062,6 +1038,29 @@ if (NOT WIN32) endif() endif() +if (WITH_LOCALE) + if (USE_MOMO) + list(APPEND ENGINE_SOURCES src/momo/momo.c) + list(APPEND DEPENDENCIES_DEFINES HAVE_LOCALE) + list(APPEND DEPENDENCIES_DEFINES HAVE_MOMO) + list(APPEND DEPENDENCIES_INCLUDE_DIRS src/momo) + message(STATUS "Using libintl (Momo)") + else() + if ("${CMAKE_VERSION}" VERSION_LESS "3.2") + message(FATAL_ERROR "CMake 3.2 or later required for locale support.") + else() + include(FindIntl) + if (NOT Intl_FOUND) + message(FATAL_ERROR "Could not find libintl! Try enabling USE_MOMO.") + endif() + list(APPEND DEPENDENCIES_DEFINES HAVE_LOCALE) + list(APPEND DEPENDENCIES_INCLUDE_DIRS ${Intl_INCLUDE_DIRS}) + list(APPEND DEPENDENCIES_LIBRARIES ${Intl_LIBRARIES}) + message(STATUS "Using libintl (system)") + endif() + endif() +endif() + set(USED_SOURCES ${ENGINE_SOURCES} ${AUDIO_SOURCES} ${CLI_SOURCES} src/main.cpp) if (USE_BACKWARD) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index fe318f576..1d0cef2aa 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -3956,15 +3956,24 @@ bool DivEngine::deinitAudioBackend(bool dueToSwitchMaster) { return true; } -bool DivEngine::preInit(bool noSafeMode) { - bool wantSafe=false; - // register systems - if (!systemsRegistered) registerSystems(); - +bool DivEngine::prePreInit() { // init config initConfDir(); logD("config path: %s",configPath.c_str()); + configLoaded=true; + return loadConf(); +} + +bool DivEngine::preInit(bool noSafeMode) { + bool wantSafe=false; + if (!configLoaded) prePreInit(); + + logI("Furnace version " DIV_VERSION "."); + + // register systems + if (!systemsRegistered) registerSystems(); + // TODO: re-enable with a better approach // see issue #1581 /* @@ -3979,10 +3988,6 @@ bool DivEngine::preInit(bool noSafeMode) { String logPath=configPath+DIR_SEPARATOR_STR+"furnace.log"; startLogFile(logPath.c_str()); - logI("Furnace version " DIV_VERSION "."); - - loadConf(); - if (!conf.has("opn1Core")) { if (conf.has("opnCore")) { conf.set("opn1Core",conf.getString("opnCore","")); diff --git a/src/engine/engine.h b/src/engine/engine.h index 370de2a5f..0bbfaed79 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -430,6 +430,7 @@ class DivEngine { String exportPath; std::thread* exportThread; int chans; + bool configLoaded; bool active; bool lowQuality; bool dcHiPass; @@ -1295,6 +1296,9 @@ class DivEngine { // quit dispatch void quitDispatch(); + // pre-pre-initialize the engine. + bool prePreInit(); + // pre-initialize the engine. returns whether Furnace should run in safe mode. bool preInit(bool noSafeMode=true); @@ -1315,6 +1319,7 @@ class DivEngine { output(NULL), exportThread(NULL), chans(0), + configLoaded(false), active(false), lowQuality(false), dcHiPass(true), diff --git a/src/gui/gui.h b/src/gui/gui.h index 103108670..9e86f1e9f 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1956,6 +1956,7 @@ class FurnaceGUI { String emptyLabel2; String sdlAudioDriver; String defaultAuthorName; + String locale; DivConfig initialSys; Settings(): @@ -2210,7 +2211,8 @@ class FurnaceGUI { emptyLabel("..."), emptyLabel2(".."), sdlAudioDriver(""), - defaultAuthorName("") {} + defaultAuthorName(""), + locale("") {} } settings; struct Tutorial { diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 3412c5f5d..0d82c199a 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -68,6 +68,27 @@ #define SYS_FILE_DIALOG_DEFAULT 1 #endif +const char* locales[][2]={ + {"", ""}, + {"English", "en_US"}, + {"Deutsch", "de_DE"}, + {"Español", "es_ES"}, + {"Suomi", "fi_FI"}, + {"Français", "fr_FR"}, + {"Հայերեն", "hy_AM"}, + {"한국어", "ko_KR"}, + {"Nederlands", "nl_NL"}, + {"Polski", "pl_PL"}, + {"Português (Brasil)", "pt_BR"}, + {"Русский", "ru_RU"}, + {"Slovenčina", "sk_SK"}, + {"Svenska", "sv_SE"}, + {"ไทย", "th_TH"}, + {"Türkçe", "tr_TR"}, + {"Українська", "uk_UA"}, + {NULL, NULL} +}; + const char* fontBackends[]={ "stb_truetype", "FreeType" @@ -549,6 +570,30 @@ void FurnaceGUI::drawSettings() { CONFIG_SECTION(_("General")) { // SUBSECTION PROGRAM CONFIG_SUBSECTION(_("Program")); + + String curLocale=settings.locale; + if (curLocale=="") { + curLocale=""; + } else { + for (int i=1; locales[i][0]; i++) { + if (strcmp(curLocale.c_str(),locales[i][1])==0) { + curLocale=locales[i][0]; + break; + } + } + } + if (ImGui::BeginCombo(_("Language"),curLocale.c_str())) { + for (int i=0; locales[i][0]; i++) { + if (ImGui::Selectable(locales[i][0],strcmp(settings.locale.c_str(),locales[i][1])==0)) { + settings.locale=locales[i][1]; + } + } + ImGui::EndCombo(); + } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip(_("you may need to restart Furnace for this setting to take effect.")); + } + String curRenderBackend=settings.renderBackend.empty()?GUI_BACKEND_DEFAULT_NAME:settings.renderBackend; if (ImGui::BeginCombo(_("Render backend"),curRenderBackend.c_str())) { #ifdef HAVE_RENDER_SDL @@ -4671,6 +4716,8 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) { settings.backupMaxCopies=conf.getInt("backupMaxCopies",5); settings.autoFillSave=conf.getInt("autoFillSave",0); + + settings.locale=conf.getString("locale",""); } if (groups&GUI_SETTINGS_AUDIO) { @@ -5253,6 +5300,8 @@ void FurnaceGUI::writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups) { conf.set("backupMaxCopies",settings.backupMaxCopies); conf.set("autoFillSave",settings.autoFillSave); + + conf.set("locale",settings.locale); } // audio diff --git a/src/main.cpp b/src/main.cpp index 85bbebb75..17b5fb0f7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -506,14 +506,18 @@ int main(int argc, char** argv) { zsmOutName=""; cmdOutName=""; + // load config for locale + e.prePreInit(); + #ifdef HAVE_LOCALE + String reqLocale=e.getConfString("locale",""); const char* localeRet=NULL; - if ((localeRet=TA_SETLOCALE(LC_CTYPE,"pt_BR"))==NULL) { + if ((localeRet=TA_SETLOCALE(LC_CTYPE,reqLocale.c_str()))==NULL) { logE("could not set locale (CTYPE)!"); } else { logV("locale: %s",localeRet); } - if ((localeRet=TA_SETLOCALE(LC_MESSAGES,"pt_BR"))==NULL) { + if ((localeRet=TA_SETLOCALE(LC_MESSAGES,reqLocale.c_str()))==NULL) { logE("could not set locale (MESSAGES)!"); } else { logV("locale: %s",localeRet); diff --git a/src/momo/momo.c b/src/momo/momo.c index 477c4f383..d244d1c69 100644 --- a/src/momo/momo.c +++ b/src/momo/momo.c @@ -26,6 +26,13 @@ #include #include "momo.h" +#ifdef ANDROID +#include +#define MO_FREE SDL_free +#else +#define MO_FREE free +#endif + static char curLocale[64]; static char tempPath[4096]; @@ -171,6 +178,28 @@ const char* momo_bindtextdomain(const char* domainName, const char* dirName) { if (newDomain->mo==NULL) { snprintf(tempPath,4096,"%s/%s/LC_MESSAGES/%s.mo",newDomain->path,curLocale,newDomain->name); +#ifdef ANDROID + newDomain->mo=SDL_LoadFile(tempPath,&newDomain->moLen); + if (newDomain->mo==NULL) { + // try without country + char* cPos=strchr(curLocale,'_'); + if (cPos) { + *cPos=0; + } + snprintf(tempPath,4096,"%s/%s/LC_MESSAGES/%s.mo",newDomain->path,curLocale,newDomain->name); + newDomain->mo=SDL_LoadFile(tempPath,&newDomain->moLen); + if (newDomain->mo==NULL) { + // give up + if (found) { + if (newDomain==curDomain) curDomain=NULL; + domainsRemove(newDomain); + } + free(newDomain); + return NULL; + } + + } +#else FILE* f=fopen(tempPath,"rb"); if (f==NULL) { // try without country @@ -255,12 +284,13 @@ const char* momo_bindtextdomain(const char* domainName, const char* dirName) { return NULL; } fclose(f); +#endif // parse struct MOHeader* header=(struct MOHeader*)newDomain->mo; if (header->magic!=0x950412de) { // give up - free(newDomain->mo); + MO_FREE(newDomain->mo); if (found) { if (newDomain==curDomain) curDomain=NULL; domainsRemove(newDomain); @@ -273,7 +303,7 @@ const char* momo_bindtextdomain(const char* domainName, const char* dirName) { header->transPtr+(header->stringCount*8)>newDomain->moLen || header->hashPtr+(header->hashSize*4)>newDomain->moLen) { // give up - free(newDomain->mo); + MO_FREE(newDomain->mo); if (found) { if (newDomain==curDomain) curDomain=NULL; domainsRemove(newDomain); @@ -300,7 +330,7 @@ const char* momo_bindtextdomain(const char* domainName, const char* dirName) { // add to domain list if (!found) { if (!domainsInsert(newDomain)) { - if (newDomain->mo) free(newDomain->mo); + if (newDomain->mo) MO_FREE(newDomain->mo); free(newDomain); errno=ENOMEM; return NULL;