Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make system language configurable #682

Merged
merged 1 commit into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "audio/dsp_core.hpp"
#include "frontend_settings.hpp"
#include "renderer.hpp"
#include "services/region_codes.hpp"

struct AudioDeviceConfig {
// Audio curve to use for volumes between 0-100
Expand Down Expand Up @@ -77,6 +78,8 @@ struct EmulatorConfig {
// Default to 3% battery to make users suffer
int batteryPercentage = 3;

LanguageCodes systemLanguage = LanguageCodes::English;

// Default ROM path to open in Qt and misc frontends
std::filesystem::path defaultRomPath = "";
std::filesystem::path filePath;
Expand Down Expand Up @@ -104,4 +107,7 @@ struct EmulatorConfig {
EmulatorConfig(const std::filesystem::path& path);
void load();
void save();

static LanguageCodes languageCodeFromString(std::string inString);
static const char* languageCodeToString(LanguageCodes code);
};
5 changes: 4 additions & 1 deletion include/services/cfg.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once
#include <cstring>

#include "config.hpp"
#include "helpers.hpp"
#include "logger.hpp"
#include "memory.hpp"
Expand All @@ -11,6 +12,8 @@ class CFGService {
using Handle = HorizonHandle;

Memory& mem;
const EmulatorConfig& settings;

CountryCodes country = CountryCodes::US; // Default to USA
MAKE_LOG_FUNCTION(log, cfgLogger)

Expand Down Expand Up @@ -45,7 +48,7 @@ class CFGService {
NOR, // cfg:nor
};

CFGService(Memory& mem) : mem(mem) {}
CFGService(Memory& mem, const EmulatorConfig& settings) : mem(mem), settings(settings) {}
void reset();
void handleSyncRequest(u32 messagePointer, Type type);
};
33 changes: 33 additions & 0 deletions src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <fstream>
#include <map>
#include <string>
#include <unordered_map>

#include "helpers.hpp"
#include "toml.hpp"
Expand Down Expand Up @@ -45,6 +46,7 @@ void EmulatorConfig::load() {
defaultRomPath = toml::find_or<std::string>(general, "DefaultRomPath", "");

printAppVersion = toml::find_or<toml::boolean>(general, "PrintAppVersion", true);
systemLanguage = languageCodeFromString(toml::find_or<std::string>(general, "SystemLanguage", "en"));
}
}

Expand Down Expand Up @@ -169,6 +171,7 @@ void EmulatorConfig::save() {
data["General"]["UsePortableBuild"] = usePortableBuild;
data["General"]["DefaultRomPath"] = defaultRomPath.string();
data["General"]["PrintAppVersion"] = printAppVersion;
data["General"]["SystemLanguage"] = languageCodeToString(systemLanguage);

data["Window"]["AppVersionOnWindow"] = windowSettings.showAppVersion;
data["Window"]["RememberWindowPosition"] = windowSettings.rememberPosition;
Expand Down Expand Up @@ -231,4 +234,34 @@ const char* AudioDeviceConfig::volumeCurveToString(AudioDeviceConfig::VolumeCurv
case VolumeCurve::Cubic:
default: return "cubic";
}
}

LanguageCodes EmulatorConfig::languageCodeFromString(std::string inString) { // Transform to lower-case to make the setting case-insensitive
std::transform(inString.begin(), inString.end(), inString.begin(), [](unsigned char c) { return std::tolower(c); });

static const std::unordered_map<std::string, LanguageCodes> map = {
{"ja", LanguageCodes::Japanese}, {"en", LanguageCodes::English}, {"fr", LanguageCodes::French}, {"de", LanguageCodes::German},
{"it", LanguageCodes::Italian}, {"es", LanguageCodes::Spanish}, {"zh", LanguageCodes::Chinese}, {"ko", LanguageCodes::Korean},
{"nl", LanguageCodes::Dutch}, {"pt", LanguageCodes::Portuguese}, {"ru", LanguageCodes::Russian}, {"tw", LanguageCodes::Taiwanese},
};

if (auto search = map.find(inString); search != map.end()) {
return search->second;
}

// Default to English if no language code in our map matches
return LanguageCodes::English;
}

const char* EmulatorConfig::languageCodeToString(LanguageCodes code) {
static constexpr std::array<const char*, 12> codes = {
"ja", "en", "fr", "de", "it", "es", "zh", "ko", "nl", "pt", "ru", "tw",
};

// Invalid country code, return english
if (static_cast<u32>(code) > static_cast<u32>(LanguageCodes::Taiwanese)) {
return "en";
} else {
return codes[static_cast<u32>(code)];
}
}
2 changes: 1 addition & 1 deletion src/core/services/cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ void CFGService::getConfigInfo(u32 output, u32 blockID, u32 size, u32 permission
if (size == 1 && blockID == 0x70001) { // Sound output mode
mem.write8(output, static_cast<u8>(DSPService::SoundOutputMode::Stereo));
} else if (size == 1 && blockID == 0xA0002) { // System language
mem.write8(output, static_cast<u8>(LanguageCodes::English));
mem.write8(output, static_cast<u8>(settings.systemLanguage));
} else if (size == 4 && blockID == 0xB0000) { // Country info
mem.write8(output, 0); // Unknown
mem.write8(output + 1, 0); // Unknown
Expand Down
4 changes: 2 additions & 2 deletions src/core/services/service_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
#include "kernel.hpp"

ServiceManager::ServiceManager(std::span<u32, 16> regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel, const EmulatorConfig& config)
: regs(regs), mem(mem), kernel(kernel), ac(mem), am(mem), boss(mem), act(mem), apt(mem, kernel), cam(mem, kernel), cecd(mem, kernel), cfg(mem),
csnd(mem, kernel), dlp_srvr(mem), dsp(mem, kernel, config), hid(mem, kernel), http(mem), ir_user(mem, kernel), frd(mem),
: regs(regs), mem(mem), kernel(kernel), ac(mem), am(mem), boss(mem), act(mem), apt(mem, kernel), cam(mem, kernel), cecd(mem, kernel),
cfg(mem, config), csnd(mem, kernel), dlp_srvr(mem), dsp(mem, kernel, config), hid(mem, kernel), http(mem), ir_user(mem, kernel), frd(mem),
fs(mem, kernel, config), gsp_gpu(mem, gpu, kernel, currentPID), gsp_lcd(mem), ldr(mem, kernel), mcu_hwc(mem, config), mic(mem, kernel),
nfc(mem, kernel), nim(mem), ndm(mem), news_u(mem), ns(mem), nwm_uds(mem, kernel), ptm(mem, config), soc(mem), ssl(mem), y2r(mem, kernel) {}

Expand Down
27 changes: 24 additions & 3 deletions src/panda_qt/config_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,27 @@ ConfigWindow::ConfigWindow(ConfigCallback configCallback, MainWindowCallback win
romLayout->addWidget(browseRomPath);
genLayout->addRow(tr("Default ROMs path"), romLayout);

QComboBox* systemLanguage = new QComboBox();
systemLanguage->addItem(tr("Japanese"));
systemLanguage->addItem(tr("English"));
systemLanguage->addItem(tr("French"));
systemLanguage->addItem(tr("German"));
systemLanguage->addItem(tr("Italian"));
systemLanguage->addItem(tr("Spanish"));
systemLanguage->addItem(tr("Chinese"));
systemLanguage->addItem(tr("Korean"));
systemLanguage->addItem(tr("Dutch"));
systemLanguage->addItem(tr("Portuguese"));
systemLanguage->addItem(tr("Russian"));
systemLanguage->addItem(tr("Taiwanese"));

systemLanguage->setCurrentIndex(static_cast<int>(config.systemLanguage));
connect(systemLanguage, &QComboBox::currentIndexChanged, this, [&](int index) {
config.systemLanguage = static_cast<LanguageCodes>(index);
updateConfig();
});
genLayout->addRow(tr("System language"), systemLanguage);

QCheckBox* discordRpcEnabled = new QCheckBox(tr("Enable Discord RPC"));
connectCheckbox(discordRpcEnabled, config.discordRpcEnabled);
genLayout->addRow(discordRpcEnabled);
Expand All @@ -163,7 +184,7 @@ ConfigWindow::ConfigWindow(ConfigCallback configCallback, MainWindowCallback win
gpuLayout->setHorizontalSpacing(20);
gpuLayout->setVerticalSpacing(10);

QComboBox* rendererType = new QComboBox;
QComboBox* rendererType = new QComboBox();
rendererType->addItem(tr("Null"));
rendererType->addItem(tr("OpenGL"));
rendererType->addItem(tr("Vulkan"));
Expand Down Expand Up @@ -217,7 +238,7 @@ ConfigWindow::ConfigWindow(ConfigCallback configCallback, MainWindowCallback win
audioLayout->setHorizontalSpacing(20);
audioLayout->setVerticalSpacing(10);

QComboBox* dspType = new QComboBox;
QComboBox* dspType = new QComboBox();
dspType->addItem(tr("Null"));
dspType->addItem(tr("LLE"));
dspType->addItem(tr("HLE"));
Expand All @@ -244,7 +265,7 @@ ConfigWindow::ConfigWindow(ConfigCallback configCallback, MainWindowCallback win
connectCheckbox(muteAudio, config.audioDeviceConfig.muteAudio);
audioLayout->addRow(muteAudio);

QComboBox* volumeCurveType = new QComboBox;
QComboBox* volumeCurveType = new QComboBox();
volumeCurveType->addItem(tr("Cubic"));
volumeCurveType->addItem(tr("Linear"));
volumeCurveType->setCurrentIndex(static_cast<int>(config.audioDeviceConfig.volumeCurve));
Expand Down
Loading