diff --git a/CMakeLists.txt b/CMakeLists.txt index 938f6a114..de7089a1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -524,6 +524,11 @@ if(NOT KYTY_CLANG_CL) endif() if(BUILD_TESTING) + add_test(NAME emulator_user_name_cli + COMMAND $ --help --user-name 1234567890123456) + add_test(NAME emulator_user_name_too_long + COMMAND $ --help --user-name 12345678901234567) + set_tests_properties(emulator_user_name_too_long PROPERTIES WILL_FAIL TRUE) add_test(NAME ime_dialog COMMAND $) add_test(NAME shader_cfg COMMAND $) add_test(NAME scalar_provenance COMMAND $) diff --git a/src/common/emulatorConfig.cpp b/src/common/emulatorConfig.cpp index ef0e8e1b2..290bf9cc0 100644 --- a/src/common/emulatorConfig.cpp +++ b/src/common/emulatorConfig.cpp @@ -21,6 +21,7 @@ void Shutdown() { void Load(const ConfigOptions& cfg) { EXIT_IF(g_config == nullptr); + EXIT_IF(cfg.user_name.empty() || cfg.user_name.size() > MAX_USER_NAME_LENGTH); *g_config = cfg; } @@ -33,6 +34,10 @@ uint32_t GetScreenHeight() { return g_config->screen_height; } +const std::string& GetUserName() { + return g_config->user_name; +} + bool FullscreenEnabled() { return g_config->fullscreen_enabled; } diff --git a/src/common/emulatorConfig.h b/src/common/emulatorConfig.h index 1dbf49f62..7de12efc7 100644 --- a/src/common/emulatorConfig.h +++ b/src/common/emulatorConfig.h @@ -3,6 +3,7 @@ #include "common/common.h" +#include #include #include #include @@ -30,10 +31,12 @@ using Keymap = std::vector; constexpr uint32_t DEFAULT_CONSOLE_LANGUAGE = 1; constexpr uint32_t MAX_CONSOLE_LANGUAGE = 29; +constexpr std::size_t MAX_USER_NAME_LENGTH = 16; struct ConfigOptions { uint32_t screen_width = 1280; uint32_t screen_height = 720; + std::string user_name = "Kyty"; bool fullscreen_enabled = false; uint32_t vblank_frequency = 60; uint32_t console_language = DEFAULT_CONSOLE_LANGUAGE; @@ -63,6 +66,7 @@ void Load(const ConfigOptions& cfg); uint32_t GetScreenWidth(); uint32_t GetScreenHeight(); +const std::string& GetUserName(); bool FullscreenEnabled(); uint32_t GetVblankFrequency(); uint32_t GetConsoleLanguage(); diff --git a/src/launcher/forms/configuration_edit_dialog.ui b/src/launcher/forms/configuration_edit_dialog.ui index 67deb7b11..27ab6f183 100644 --- a/src/launcher/forms/configuration_edit_dialog.ui +++ b/src/launcher/forms/configuration_edit_dialog.ui @@ -102,27 +102,44 @@ + + + User name: + + + + + + + Local user name exposed to games + + + true + + + + Screen resolution: - + Window resolution - + Vblank frequency: - + Virtual display refresh rate used for frame pacing @@ -138,56 +155,56 @@ - + 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 @@ -197,14 +214,14 @@ - + Command buffer dump folder: - + Specify directory to dump command buffers @@ -214,28 +231,28 @@ - + Printf direction: - + Print logs to file or console window. If enabled may decrease emulator performance - + Printf output file: - + Specify file to dump logs @@ -245,14 +262,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 c6cc7d303..fe6e3ced8 100644 --- a/src/launcher/include/configuration.h +++ b/src/launcher/include/configuration.h @@ -87,6 +87,7 @@ public: QString game_comment; Resolution screen_resolution = Resolution::R1280X720; + QString user_name = "Kyty"; bool fullscreen_enabled = false; int vblank_frequency = 60; int console_language = DEFAULT_CONSOLE_LANGUAGE; @@ -110,6 +111,7 @@ public: void CopyEmulatorSettingsFrom(const Configuration& other) { screen_resolution = other.screen_resolution; + user_name = other.user_name; fullscreen_enabled = other.fullscreen_enabled; vblank_frequency = other.vblank_frequency; console_language = other.console_language; @@ -150,6 +152,7 @@ public: KYTY_CFG_SET(game_path); KYTY_CFG_SET(custom_settings); KYTY_CFG_SET(screen_resolution); + KYTY_CFG_SET(user_name); KYTY_CFG_SET(fullscreen_enabled); KYTY_CFG_SET(vblank_frequency); KYTY_CFG_SET(console_language); @@ -177,6 +180,7 @@ public: KYTY_CFG_GET(game_path); KYTY_CFG_GET(custom_settings); KYTY_CFG_GET(screen_resolution); + user_name = s->value("user_name", user_name).toString(); KYTY_CFG_GET(fullscreen_enabled); vblank_frequency = s->value("vblank_frequency", vblank_frequency).toInt(); console_language = s->value("console_language", console_language).toInt(); diff --git a/src/launcher/src/configurationEditDialog.cpp b/src/launcher/src/configurationEditDialog.cpp index 470712ecf..bc12d57e8 100644 --- a/src/launcher/src/configurationEditDialog.cpp +++ b/src/launcher/src/configurationEditDialog.cpp @@ -1,5 +1,6 @@ #include "configurationEditDialog.h" +#include "common/emulatorConfig.h" #include "configuration.h" #include "mandatoryLineEdit.h" @@ -12,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -152,6 +154,8 @@ static void ListInit(QComboBox* combo, T value) { } void ConfigurationEditDialog::Init(const Configuration& info) { + m_ui->lineEdit_user_name->setMaxLength(static_cast(Config::MAX_USER_NAME_LENGTH)); + m_ui->lineEdit_user_name->setText(info.user_name); ListInit(m_ui->comboBox_screen_resolution, info.screen_resolution); m_ui->checkBox_fullscreen->setChecked(info.fullscreen_enabled); m_ui->spinBox_vblank_frequency->setValue(info.vblank_frequency); @@ -283,6 +287,7 @@ void ConfigurationEditDialog::moveEvent(QMoveEvent* event) { } static void UpdateInfo(Configuration& info, Ui::ConfigurationEditDialog& ui) { + info.user_name = ui.lineEdit_user_name->text().trimmed(); info.screen_resolution = TextToEnum(ui.comboBox_screen_resolution->currentText()); info.fullscreen_enabled = ui.checkBox_fullscreen->isChecked(); @@ -322,6 +327,14 @@ void ConfigurationEditDialog::save() { return; } + const auto user_name = m_ui->lineEdit_user_name->text().trimmed(); + if (user_name.isEmpty() || user_name.toUtf8().size() > Config::MAX_USER_NAME_LENGTH) { + QMessageBox::critical(this, tr("Save failed"), + tr("User name must contain 1-16 UTF-8 bytes")); + return; + } + m_ui->lineEdit_user_name->setText(user_name); + update_info(); emit accept(); diff --git a/src/launcher/src/mainDialog.cpp b/src/launcher/src/mainDialog.cpp index 8fe923a8e..245fb95c3 100644 --- a/src/launcher/src/mainDialog.cpp +++ b/src/launcher/src/mainDialog.cpp @@ -204,6 +204,7 @@ static QStringList CreateEmulatorArgs(const Configuration& info) { args << "--screen-width" << r.at(0); args << "--screen-height" << r.at(1); + args << "--user-name" << info.user_name; if (info.fullscreen_enabled) { args << "--fullscreen"; } diff --git a/src/libs/libUserService.cpp b/src/libs/libUserService.cpp index cfcb83e43..4093ef170 100644 --- a/src/libs/libUserService.cpp +++ b/src/libs/libUserService.cpp @@ -1,11 +1,10 @@ #include "common/abi.h" #include "common/assert.h" -#include "common/stringUtils.h" +#include "common/emulatorConfig.h" #include "libs/errno.h" #include "libs/libs.h" #include "loader/symbolDatabase.h" -#include #include #include @@ -96,7 +95,8 @@ static KYTY_SYSV_ABI int UserServiceGetUserName(int user_id, char* name, size_t EXIT_NOT_IMPLEMENTED(user_id != 1000); EXIT_NOT_IMPLEMENTED(size < 5); - int s = snprintf(name, size, "%s", "Kyty"); + const auto& user_name = Config::GetUserName(); + int s = snprintf(name, size, "%s", user_name.c_str()); EXIT_NOT_IMPLEMENTED(static_cast(s) >= size); diff --git a/src/main.cpp b/src/main.cpp index 21db25b1f..afff146b0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -47,6 +47,8 @@ static void PrintUsage() { " --game-patch Validated patch plan to apply before entry.\n"); ::printf(" --screen-width Window width. Default: 1280.\n"); ::printf(" --screen-height Window height. Default: 720.\n"); + ::printf( + " --user-name Local user name (1-16 bytes). Default: Kyty.\n"); ::printf(" --fullscreen Run in borderless desktop fullscreen.\n"); ::printf(" --vblank-frequency Virtual vblank frequency. Default: 60.\n"); ::printf(" --console-language <0-29> Console language. Default: 1 (English US).\n"); @@ -201,6 +203,13 @@ static bool ParseArgs(int argc, char* argv[], RunOptions& options, bool& show_he options.config.screen_width = static_cast(Common::ToInt32(value)); } else if (arg == "--screen-height") { options.config.screen_height = static_cast(Common::ToInt32(value)); + } else if (arg == "--user-name") { + if (value.empty() || value.size() > Config::MAX_USER_NAME_LENGTH) { + ::printf("invalid user name: must contain 1-%zu bytes\n", + Config::MAX_USER_NAME_LENGTH); + return false; + } + options.config.user_name = value; } else if (arg == "--vblank-frequency") { const int32_t vblank_frequency = Common::ToInt32(value); options.config.vblank_frequency =