diff --git a/src/common/emulatorConfig.cpp b/src/common/emulatorConfig.cpp
index b376d7979..128b6f7f4 100644
--- a/src/common/emulatorConfig.cpp
+++ b/src/common/emulatorConfig.cpp
@@ -37,6 +37,10 @@ uint32_t GetVblankFrequency() {
return std::clamp(g_config->vblank_frequency, 30u, 360u);
}
+uint32_t GetConsoleLanguage() {
+ return g_config->console_language;
+}
+
bool VulkanValidationEnabled() {
return g_config->vulkan_validation_enabled;
}
diff --git a/src/common/emulatorConfig.h b/src/common/emulatorConfig.h
index 2e54604cc..4e7c40b1b 100644
--- a/src/common/emulatorConfig.h
+++ b/src/common/emulatorConfig.h
@@ -18,10 +18,14 @@ enum class ProfilerDirection { None, Network };
enum class OutputDirection { Silent, Console, File };
+constexpr uint32_t DEFAULT_CONSOLE_LANGUAGE = 1;
+constexpr uint32_t MAX_CONSOLE_LANGUAGE = 29;
+
struct ConfigOptions {
uint32_t screen_width = 1280;
uint32_t screen_height = 720;
uint32_t vblank_frequency = 60;
+ uint32_t console_language = DEFAULT_CONSOLE_LANGUAGE;
bool vulkan_validation_enabled = false;
bool shader_validation_enabled = false;
ShaderOptimizationType shader_optimization_type = ShaderOptimizationType::None;
@@ -43,6 +47,7 @@ void Load(const ConfigOptions& cfg);
uint32_t GetScreenWidth();
uint32_t GetScreenHeight();
uint32_t GetVblankFrequency();
+uint32_t GetConsoleLanguage();
bool VulkanValidationEnabled();
bool ShaderValidationEnabled();
diff --git a/src/launcher/forms/configuration_edit_dialog.ui b/src/launcher/forms/configuration_edit_dialog.ui
index d9a40745c..6fa5d0ca7 100644
--- a/src/launcher/forms/configuration_edit_dialog.ui
+++ b/src/launcher/forms/configuration_edit_dialog.ui
@@ -7,7 +7,7 @@
0
0
560
- 420
+ 450
@@ -119,41 +119,55 @@
-
+
+
+ Console language:
+
+
+
+ -
+
+
+ Language
+
+
+
+ -
Shader optimization type:
- -
+
-
Optimize shaders for code size or performance
- -
+
-
Shader log direction:
- -
+
-
Dump shaders to file or console window. If enabled may decrease emulator performance
- -
+
-
Shader log folder:
- -
+
-
Specify directory to dump shaders
@@ -163,14 +177,14 @@
- -
+
-
Command buffer dump folder:
- -
+
-
Specify directory to dump command buffers
@@ -180,28 +194,28 @@
- -
+
-
Printf direction:
- -
+
-
Print logs to file or console window. If enabled may decrease emulator performance
- -
+
-
Printf output file:
- -
+
-
Specify file to dump logs
@@ -211,14 +225,14 @@
- -
+
-
Profiler direction:
- -
+
-
Enable or disable profiler. If enabled may decrease emulator performance
diff --git a/src/launcher/include/configuration.h b/src/launcher/include/configuration.h
index 232149892..5a997bd4c 100644
--- a/src/launcher/include/configuration.h
+++ b/src/launcher/include/configuration.h
@@ -48,6 +48,9 @@ class Configuration: public QObject {
Q_OBJECT
public:
+ static constexpr int DEFAULT_CONSOLE_LANGUAGE = 1;
+ static constexpr int MAX_CONSOLE_LANGUAGE = 29;
+
enum class Resolution {
R1280X720,
R1920X1080,
@@ -83,6 +86,7 @@ public:
Resolution screen_resolution = Resolution::R1280X720;
int vblank_frequency = 60;
+ int console_language = DEFAULT_CONSOLE_LANGUAGE;
bool vulkan_validation_enabled = true;
bool shader_validation_enabled = true;
ShaderOptimizationType shader_optimization_type = ShaderOptimizationType::Performance;
@@ -100,6 +104,7 @@ public:
void CopyEmulatorSettingsFrom(const Configuration& other) {
screen_resolution = other.screen_resolution;
vblank_frequency = other.vblank_frequency;
+ console_language = other.console_language;
vulkan_validation_enabled = other.vulkan_validation_enabled;
shader_validation_enabled = other.shader_validation_enabled;
shader_optimization_type = other.shader_optimization_type;
@@ -134,6 +139,7 @@ public:
KYTY_CFG_SET(custom_settings);
KYTY_CFG_SET(screen_resolution);
KYTY_CFG_SET(vblank_frequency);
+ KYTY_CFG_SET(console_language);
KYTY_CFG_SET(vulkan_validation_enabled);
KYTY_CFG_SET(shader_validation_enabled);
KYTY_CFG_SET(shader_optimization_type);
@@ -155,6 +161,10 @@ public:
KYTY_CFG_GET(custom_settings);
KYTY_CFG_GET(screen_resolution);
vblank_frequency = s->value("vblank_frequency", vblank_frequency).toInt();
+ console_language = s->value("console_language", console_language).toInt();
+ if (console_language < 0 || console_language > MAX_CONSOLE_LANGUAGE) {
+ console_language = DEFAULT_CONSOLE_LANGUAGE;
+ }
KYTY_CFG_GET(vulkan_validation_enabled);
KYTY_CFG_GET(shader_validation_enabled);
KYTY_CFG_GET(shader_optimization_type);
diff --git a/src/launcher/src/configurationEditDialog.cpp b/src/launcher/src/configurationEditDialog.cpp
index 6aea1ae4d..2b28c3c8f 100644
--- a/src/launcher/src/configurationEditDialog.cpp
+++ b/src/launcher/src/configurationEditDialog.cpp
@@ -30,6 +30,39 @@ constexpr char SETTINGS_CFG_DIALOG[] = "ConfigurationEditDialog";
constexpr char SETTINGS_CFG_LAST_GEOMETRY[] = "geometry";
constexpr int GLOBAL_SETTINGS_GAME_DIRS_MIN_WIDTH = 560;
+const QStringList CONSOLE_LANGUAGE_NAMES = {
+ "Japanese",
+ "English (United States)",
+ "French (France)",
+ "Spanish (Spain)",
+ "German",
+ "Italian",
+ "Dutch",
+ "Portuguese (Portugal)",
+ "Russian",
+ "Korean",
+ "Chinese (Traditional)",
+ "Chinese (Simplified)",
+ "Finnish",
+ "Swedish",
+ "Danish",
+ "Norwegian",
+ "Polish",
+ "Portuguese (Brazil)",
+ "English (United Kingdom)",
+ "Turkish",
+ "Spanish (Latin America)",
+ "Arabic",
+ "French (Canada)",
+ "Czech",
+ "Hungarian",
+ "Greek",
+ "Romanian",
+ "Thai",
+ "Vietnamese",
+ "Indonesian",
+};
+
static QString NormalizeGameDirectory(const QString& dir) {
const auto trimmed = dir.trimmed();
if (trimmed.isEmpty()) {
@@ -121,6 +154,12 @@ static void ListInit(QComboBox* combo, T value) {
void ConfigurationEditDialog::Init(const Configuration& info) {
ListInit(m_ui->comboBox_screen_resolution, info.screen_resolution);
m_ui->spinBox_vblank_frequency->setValue(info.vblank_frequency);
+ m_ui->comboBox_console_language->clear();
+ m_ui->comboBox_console_language->addItems(CONSOLE_LANGUAGE_NAMES);
+ m_ui->comboBox_console_language->setCurrentIndex(
+ info.console_language >= 0 && info.console_language < CONSOLE_LANGUAGE_NAMES.size()
+ ? info.console_language
+ : Configuration::DEFAULT_CONSOLE_LANGUAGE);
m_ui->checkBox_shader_validation->setChecked(info.shader_validation_enabled);
m_ui->checkBox_vulkan_validation->setChecked(info.vulkan_validation_enabled);
m_ui->checkBox_renderdoc_capture->setChecked(info.renderdoc_enabled);
@@ -241,6 +280,7 @@ static void UpdateInfo(Configuration& info, Ui::ConfigurationEditDialog& ui) {
info.screen_resolution =
TextToEnum(ui.comboBox_screen_resolution->currentText());
info.vblank_frequency = ui.spinBox_vblank_frequency->value();
+ info.console_language = ui.comboBox_console_language->currentIndex();
info.vulkan_validation_enabled = ui.checkBox_vulkan_validation->isChecked();
info.shader_validation_enabled = ui.checkBox_shader_validation->isChecked();
info.renderdoc_enabled = ui.checkBox_renderdoc_capture->isChecked();
diff --git a/src/launcher/src/mainDialog.cpp b/src/launcher/src/mainDialog.cpp
index fa3c9b28a..0f236be92 100644
--- a/src/launcher/src/mainDialog.cpp
+++ b/src/launcher/src/mainDialog.cpp
@@ -205,6 +205,7 @@ static QStringList CreateEmulatorArgs(const Configuration& info) {
args << "--screen-width" << r.at(0);
args << "--screen-height" << r.at(1);
args << "--vblank-frequency" << QString::number(info.vblank_frequency);
+ args << "--console-language" << QString::number(info.console_language);
args << "--vulkan-validation" << BoolArg(info.vulkan_validation_enabled);
args << "--shader-validation" << BoolArg(info.shader_validation_enabled);
args << "--shader-optimization-type" << EnumToText(info.shader_optimization_type);
diff --git a/src/libs/libSystemService.cpp b/src/libs/libSystemService.cpp
index 7dbd05e7f..381814354 100644
--- a/src/libs/libSystemService.cpp
+++ b/src/libs/libSystemService.cpp
@@ -1,6 +1,7 @@
#include "common/abi.h"
#include "common/assert.h"
#include "common/common.h"
+#include "common/emulatorConfig.h"
#include "common/logging/log.h"
#include "common/stringUtils.h"
#include "libs/errno.h"
@@ -25,37 +26,6 @@ namespace SystemService {
[[maybe_unused]] constexpr int PARAM_ID_SCREEN_READER = 208;
[[maybe_unused]] constexpr int PARAM_ID_ENTER_BUTTON_ASSIGN = 1000;
-[[maybe_unused]] constexpr int PARAM_LANG_JAPANESE = 0;
-[[maybe_unused]] constexpr int PARAM_LANG_ENGLISH_US = 1;
-[[maybe_unused]] constexpr int PARAM_LANG_FRENCH = 2;
-[[maybe_unused]] constexpr int PARAM_LANG_SPANISH = 3;
-[[maybe_unused]] constexpr int PARAM_LANG_GERMAN = 4;
-[[maybe_unused]] constexpr int PARAM_LANG_ITALIAN = 5;
-[[maybe_unused]] constexpr int PARAM_LANG_DUTCH = 6;
-[[maybe_unused]] constexpr int PARAM_LANG_PORTUGUESE_PT = 7;
-[[maybe_unused]] constexpr int PARAM_LANG_RUSSIAN = 8;
-[[maybe_unused]] constexpr int PARAM_LANG_KOREAN = 9;
-[[maybe_unused]] constexpr int PARAM_LANG_CHINESE_T = 10;
-[[maybe_unused]] constexpr int PARAM_LANG_CHINESE_S = 11;
-[[maybe_unused]] constexpr int PARAM_LANG_FINNISH = 12;
-[[maybe_unused]] constexpr int PARAM_LANG_SWEDISH = 13;
-[[maybe_unused]] constexpr int PARAM_LANG_DANISH = 14;
-[[maybe_unused]] constexpr int PARAM_LANG_NORWEGIAN = 15;
-[[maybe_unused]] constexpr int PARAM_LANG_POLISH = 16;
-[[maybe_unused]] constexpr int PARAM_LANG_PORTUGUESE_BR = 17;
-[[maybe_unused]] constexpr int PARAM_LANG_ENGLISH_GB = 18;
-[[maybe_unused]] constexpr int PARAM_LANG_TURKISH = 19;
-[[maybe_unused]] constexpr int PARAM_LANG_SPANISH_LA = 20;
-[[maybe_unused]] constexpr int PARAM_LANG_ARABIC = 21;
-[[maybe_unused]] constexpr int PARAM_LANG_FRENCH_CA = 22;
-[[maybe_unused]] constexpr int PARAM_LANG_CZECH = 23;
-[[maybe_unused]] constexpr int PARAM_LANG_HUNGARIAN = 24;
-[[maybe_unused]] constexpr int PARAM_LANG_GREEK = 25;
-[[maybe_unused]] constexpr int PARAM_LANG_ROMANIAN = 26;
-[[maybe_unused]] constexpr int PARAM_LANG_THAI = 27;
-[[maybe_unused]] constexpr int PARAM_LANG_VIETNAMESE = 28;
-[[maybe_unused]] constexpr int PARAM_LANG_INDONESIAN = 29;
-
[[maybe_unused]] constexpr int PARAM_DATE_FORMAT_YYYYMMDD = 0;
[[maybe_unused]] constexpr int PARAM_DATE_FORMAT_DDMMYYYY = 1;
[[maybe_unused]] constexpr int PARAM_DATE_FORMAT_MMDDYYYY = 2;
@@ -121,7 +91,7 @@ static int KYTY_SYSV_ABI SystemServiceParamGetInt(int param_id, int* value) {
int v = 0;
switch (param_id) {
- case PARAM_ID_LANG: v = PARAM_LANG_ENGLISH_US; break;
+ case PARAM_ID_LANG: v = static_cast(Config::GetConsoleLanguage()); break;
case PARAM_ID_DATE_FORMAT: v = PARAM_DATE_FORMAT_DDMMYYYY; break;
case PARAM_ID_TIME_FORMAT: v = PARAM_TIME_FORMAT_24HOUR; break;
case PARAM_ID_TIME_ZONE: v = +180; break;
diff --git a/src/main.cpp b/src/main.cpp
index 124d77b0b..157de8f14 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -10,6 +10,7 @@
#include "emulator.h"
#include "kytyGitVersion.h"
+#include
#include
#include
@@ -47,6 +48,7 @@ static void PrintUsage() {
::printf(" --screen-width Window width. Default: 1280.\n");
::printf(" --screen-height Window height. Default: 720.\n");
::printf(" --vblank-frequency Virtual vblank frequency. Default: 60.\n");
+ ::printf(" --console-language <0-29> Console language. Default: 1 (English US).\n");
::printf(" --vulkan-validation Enable Vulkan validation.\n");
::printf(" --shader-validation Enable shader validation.\n");
::printf(" --shader-optimization-type None, Size, or Performance.\n");
@@ -101,6 +103,17 @@ static bool ParseEnum(const std::string& value, E& out) {
return true;
}
+static bool ParseConsoleLanguage(const std::string& value, uint32_t& out) {
+ uint32_t language = 0;
+ auto [end, error] = std::from_chars(value.data(), value.data() + value.size(), language);
+ if (error != std::errc {} || end != value.data() + value.size() ||
+ language > Config::MAX_CONSOLE_LANGUAGE) {
+ return false;
+ }
+ out = language;
+ return true;
+}
+
static bool ParseArgs(int argc, char* argv[], RunOptions& options, bool& show_help) {
show_help = false;
@@ -167,6 +180,11 @@ static bool ParseArgs(int argc, char* argv[], RunOptions& options, bool& show_he
const int32_t vblank_frequency = Common::ToInt32(value);
options.config.vblank_frequency =
static_cast(vblank_frequency < 0 ? 0 : vblank_frequency);
+ } else if (arg == "--console-language") {
+ if (!ParseConsoleLanguage(value, options.config.console_language)) {
+ ::printf("invalid console language: %s\n", value.c_str());
+ return false;
+ }
} else if (arg == "--vulkan-validation") {
if (!ParseBool(value, options.config.vulkan_validation_enabled)) {
::printf("invalid boolean for %s: %s\n", arg.c_str(), value.c_str());