i18n: English/German from Switch system language
- Add I18n module: German when system language is DE, else English (ENUS/ENGB or any other language). - Translate UI strings (tabs, settings, about, file browser, notifications, OC row titles, toggles Ein/Aus). - Keep toggle/frequency/voltage list rows without subtitle descriptions like before. Uses setGetSystemLanguage + setMakeLanguage; call I18n::init before Application::init. Made-with: Cursor
This commit is contained in:
264
src/i18n.cpp
Normal file
264
src/i18n.cpp
Normal file
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
SWR INI Tool - Switchroot INI Configuration Editor
|
||||
Copyright (C) 2026 Switchroot
|
||||
*/
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#include <switch.h>
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
bool gGerman = false;
|
||||
|
||||
#ifdef __SWITCH__
|
||||
void detectSystemLanguage()
|
||||
{
|
||||
gGerman = false;
|
||||
Result rc = setInitialize();
|
||||
if (!R_SUCCEEDED(rc))
|
||||
return;
|
||||
|
||||
u64 code = 0;
|
||||
SetLanguage lang = SetLanguage_ENUS;
|
||||
if (R_SUCCEEDED(setGetSystemLanguage(&code)) && R_SUCCEEDED(setMakeLanguage(code, &lang)))
|
||||
{
|
||||
if (lang == SetLanguage_DE)
|
||||
gGerman = true;
|
||||
}
|
||||
setExit();
|
||||
}
|
||||
#endif
|
||||
|
||||
struct Triple
|
||||
{
|
||||
const char* key;
|
||||
const char* en;
|
||||
const char* de;
|
||||
};
|
||||
|
||||
static const Triple OC_BOOL_LABEL[] = {
|
||||
{"oc", "Overclocking", "Übertaktung"},
|
||||
{"dvfsb", "CPU DVFS Boost", "CPU-DVFS-Boost"},
|
||||
{"gpu_dvfsc", "GPU DVFS Scaling", "GPU-DVFS-Skalierung"},
|
||||
{"usb3force", "Force USB 3.0", "USB 3.0 erzwingen"},
|
||||
{"ddr200_enable", "DDR200 Enable", "DDR200 aktivieren"},
|
||||
};
|
||||
|
||||
static const Triple OC_FREQ_LABEL[] = {
|
||||
{"max_cpu_freq", "Max CPU Frequency", "Max. CPU-Taktfrequenz"},
|
||||
{"max_gpu_freq", "Max GPU Frequency", "Max. GPU-Taktfrequenz"},
|
||||
{"ram_oc", "RAM Frequency", "RAM-Taktfrequenz"},
|
||||
};
|
||||
|
||||
static const Triple OC_VOLT_LABEL[] = {
|
||||
{"ram_oc_vdd2", "RAM VDD2 Voltage", "RAM VDD2-Spannung"},
|
||||
{"ram_oc_vddq", "RAM VDDQ Voltage", "RAM VDDQ-Spannung"},
|
||||
};
|
||||
|
||||
const char* lookup(const Triple* table, size_t n, const std::string& key, const char* fallback)
|
||||
{
|
||||
for (size_t i = 0; i < n; i++)
|
||||
{
|
||||
if (key == table[i].key)
|
||||
return gGerman ? table[i].de : table[i].en;
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace I18n
|
||||
{
|
||||
|
||||
void init()
|
||||
{
|
||||
#ifdef __SWITCH__
|
||||
detectSystemLanguage();
|
||||
#else
|
||||
gGerman = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isGerman()
|
||||
{
|
||||
return gGerman;
|
||||
}
|
||||
|
||||
const char* appTitle()
|
||||
{
|
||||
return gGerman ? "SWR INI-Tool" : "SWR INI Tool";
|
||||
}
|
||||
|
||||
const char* tabSettings()
|
||||
{
|
||||
return gGerman ? "Einstellungen" : "Settings";
|
||||
}
|
||||
|
||||
const char* tabAbout()
|
||||
{
|
||||
return gGerman ? "Über" : "About";
|
||||
}
|
||||
|
||||
const char* wordOn()
|
||||
{
|
||||
return gGerman ? "Ein" : "ON";
|
||||
}
|
||||
|
||||
const char* wordOff()
|
||||
{
|
||||
return gGerman ? "Aus" : "OFF";
|
||||
}
|
||||
|
||||
std::string sectionEditLine(const std::string& section, const std::string& path)
|
||||
{
|
||||
if (gGerman)
|
||||
return "Abschnitt [" + section + "] aus " + path;
|
||||
return "Editing section [" + section + "] from " + path;
|
||||
}
|
||||
|
||||
const char* headerToggleOptions()
|
||||
{
|
||||
return gGerman ? "Schalter" : "Toggle Options";
|
||||
}
|
||||
|
||||
const char* headerFrequencySettings()
|
||||
{
|
||||
return gGerman ? "Frequenz" : "Frequency Settings";
|
||||
}
|
||||
|
||||
const char* headerVoltageSettings()
|
||||
{
|
||||
return gGerman ? "Spannung" : "Voltage Settings";
|
||||
}
|
||||
|
||||
const char* headerOther()
|
||||
{
|
||||
return gGerman ? "Sonstiges" : "Other";
|
||||
}
|
||||
|
||||
const char* headerIniFilePaths()
|
||||
{
|
||||
return gGerman ? "INI-Dateipfade" : "INI File Paths";
|
||||
}
|
||||
|
||||
const char* headerLinksAndResources()
|
||||
{
|
||||
return gGerman ? "Links und Infos" : "Links and Resources";
|
||||
}
|
||||
|
||||
const char* errorListItemTitleIni()
|
||||
{
|
||||
return gGerman ? "\uE150 INI-Problem" : "\uE150 INI file not found";
|
||||
}
|
||||
|
||||
std::string iniLoadErrorBody(const std::string& path)
|
||||
{
|
||||
if (gGerman)
|
||||
return "Die Datei konnte nicht geladen werden:\n" + path + "\n\n"
|
||||
"Prüfen Sie den Pfad in den Einstellungen.";
|
||||
return "Could not load " + path + "\n\n"
|
||||
"Make sure the INI file exists at the expected path.\n"
|
||||
"You can configure paths in the Settings tab.";
|
||||
}
|
||||
|
||||
std::string iniSectionErrorBody(const std::string& path, const std::string& osName)
|
||||
{
|
||||
if (gGerman)
|
||||
return "Kein OS-Abschnitt in " + path + "\n\n"
|
||||
"Die INI sollte z. B. einen Abschnitt ["
|
||||
+ osName + " OC] enthalten.";
|
||||
return "No OS section found in " + path + "\n\n"
|
||||
"The INI file should contain a section like\n"
|
||||
"[" + osName + " OC] with your configuration.";
|
||||
}
|
||||
|
||||
const char* notifyConfigSaved()
|
||||
{
|
||||
return gGerman ? "\uE14B Konfiguration gespeichert" : "\uE14B Configuration saved";
|
||||
}
|
||||
|
||||
const char* notifyConfigSaveError()
|
||||
{
|
||||
return gGerman ? "\uE150 Fehler beim Speichern!" : "\uE150 Error saving configuration!";
|
||||
}
|
||||
|
||||
const char* notifyPathUpdated()
|
||||
{
|
||||
return gGerman ? "\uE14B Pfad aktualisiert" : "\uE14B Path updated";
|
||||
}
|
||||
|
||||
const char* settingsIntro()
|
||||
{
|
||||
return gGerman ? "Wählen Sie, welche INI-Datei jeder Reiter liest und schreibt.\n"
|
||||
"Änderungen gelten sofort."
|
||||
: "Select which INI file each OS tab reads and writes.\n"
|
||||
"Changes take effect immediately.";
|
||||
}
|
||||
|
||||
const char* pathListDescriptionLakka()
|
||||
{
|
||||
return gGerman ? "Tippen, um eine INI-Datei zu wählen" : "Tap to browse for an INI file";
|
||||
}
|
||||
|
||||
const char* fileBrowserTitlePrefix()
|
||||
{
|
||||
return gGerman ? "INI wählen \u2014 " : "Select INI \u2014 ";
|
||||
}
|
||||
|
||||
std::string fileBrowserNoIni(const std::string& dir)
|
||||
{
|
||||
if (gGerman)
|
||||
return "Keine .ini-Dateien in " + dir;
|
||||
return "No .ini files found in " + dir;
|
||||
}
|
||||
|
||||
const char* aboutSubtitle()
|
||||
{
|
||||
return gGerman ? "Switchroot INI-Konfiguration\n"
|
||||
"Linux-, Android- und Lakka-OC ohne PC bearbeiten!"
|
||||
: "Switchroot INI Configuration Editor\n"
|
||||
"Edit your Linux, Android and Lakka OC settings without a PC!";
|
||||
}
|
||||
|
||||
const char* aboutCopyright()
|
||||
{
|
||||
return gGerman ? "Lizenziert unter GPL-3.0\n"
|
||||
"UI: Borealis\n"
|
||||
"Basierend auf der Arbeit von Switchroot\n"
|
||||
"\u00A9 2026 NiklasCFW"
|
||||
: "Licensed under GPL-3.0\n"
|
||||
"Powered by Borealis UI framework\n"
|
||||
"Based on the work of Switchroot\n"
|
||||
"\u00A9 2026 NiklasCFW";
|
||||
}
|
||||
|
||||
const char* aboutLinks()
|
||||
{
|
||||
return gGerman ? "\uE016 NiklasCFW-Dokumentation: Anleitungen und Infos\n"
|
||||
"\uE016 NiklasCFW-Discord: Fragen und Community\n"
|
||||
"\uE016 Quellcode auf GitHub (OmniNX)"
|
||||
: "\uE016 NiklasCFW Docs for setup guides and documentation\n"
|
||||
"\uE016 NiklasCFW's Discord server for support and community\n"
|
||||
"\uE016 Source code available on the OmniNX GitHub";
|
||||
}
|
||||
|
||||
const char* ocBoolLabel(const std::string& key)
|
||||
{
|
||||
return lookup(OC_BOOL_LABEL, sizeof(OC_BOOL_LABEL) / sizeof(OC_BOOL_LABEL[0]), key, key.c_str());
|
||||
}
|
||||
|
||||
const char* ocFreqLabel(const std::string& key)
|
||||
{
|
||||
return lookup(OC_FREQ_LABEL, sizeof(OC_FREQ_LABEL) / sizeof(OC_FREQ_LABEL[0]), key, key.c_str());
|
||||
}
|
||||
|
||||
const char* ocVoltageLabel(const std::string& key)
|
||||
{
|
||||
return lookup(OC_VOLT_LABEL, sizeof(OC_VOLT_LABEL) / sizeof(OC_VOLT_LABEL[0]), key, key.c_str());
|
||||
}
|
||||
|
||||
} // namespace I18n
|
||||
Reference in New Issue
Block a user