From 7d84d084a44f9a13aa3262822de7f3bce0b20142 Mon Sep 17 00:00:00 2001 From: Ninetime Date: Sat, 10 Aug 2024 16:33:38 -0400 Subject: [PATCH] Enable user to change country code (#15884) --- rpcs3/Emu/CMakeLists.txt | 1 + rpcs3/Emu/Cell/Modules/sceNp.cpp | 7 +-- rpcs3/Emu/NP/np_handler.cpp | 6 +-- rpcs3/Emu/NP/rpcn_countries.cpp | 82 +++++++++++++++++++++++++++++++ rpcs3/Emu/NP/rpcn_countries.h | 15 ++++++ rpcs3/Emu/system_config.h | 1 + rpcs3/emucore.vcxproj | 2 + rpcs3/emucore.vcxproj.filters | 6 +++ rpcs3/rpcs3qt/emu_settings_type.h | 2 + rpcs3/rpcs3qt/settings_dialog.cpp | 32 ++++++++++++ rpcs3/rpcs3qt/settings_dialog.h | 3 ++ rpcs3/rpcs3qt/settings_dialog.ui | 12 +++++ rpcs3/rpcs3qt/tooltips.h | 1 + 13 files changed, 164 insertions(+), 6 deletions(-) create mode 100644 rpcs3/Emu/NP/rpcn_countries.cpp create mode 100644 rpcs3/Emu/NP/rpcn_countries.h diff --git a/rpcs3/Emu/CMakeLists.txt b/rpcs3/Emu/CMakeLists.txt index 90149137c5..36c81a73ec 100644 --- a/rpcs3/Emu/CMakeLists.txt +++ b/rpcs3/Emu/CMakeLists.txt @@ -449,6 +449,7 @@ target_sources(rpcs3_emu PRIVATE NP/np_structs_extra.cpp NP/rpcn_client.cpp NP/rpcn_config.cpp + NP/rpcn_countries.cpp NP/upnp_config.cpp NP/upnp_handler.cpp ) diff --git a/rpcs3/Emu/Cell/Modules/sceNp.cpp b/rpcs3/Emu/Cell/Modules/sceNp.cpp index a3fa20b4ba..8e2f962866 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp.cpp @@ -3956,9 +3956,10 @@ error_code sceNpManagerGetAccountRegion(vm::ptr countryCode, v return SCE_NP_ERROR_INVALID_STATE; } - memset(countryCode.get_ptr(), 0, sizeof(SceNpCountryCode)); - countryCode->data[0] = 'u'; - countryCode->data[1] = 's'; + const std::string ccode = g_cfg.net.country.to_string(); + std::memset(countryCode.get_ptr(), 0, sizeof(countryCode)); + ensure(ccode.size() == sizeof(SceNpCountryCode::data)); + std::memcpy(countryCode->data, ccode.data(), sizeof(SceNpCountryCode::data)); *language = CELL_SYSUTIL_LANG_ENGLISH_US; diff --git a/rpcs3/Emu/NP/np_handler.cpp b/rpcs3/Emu/NP/np_handler.cpp index 923babde59..499b6b9171 100644 --- a/rpcs3/Emu/NP/np_handler.cpp +++ b/rpcs3/Emu/NP/np_handler.cpp @@ -761,9 +761,9 @@ namespace np np_memory.setup(poolptr, poolsize); } - memset(&npid, 0, sizeof(npid)); - memset(&online_name, 0, sizeof(online_name)); - memset(&avatar_url, 0, sizeof(avatar_url)); + std::memset(&npid, 0, sizeof(npid)); + std::memset(&online_name, 0, sizeof(online_name)); + std::memset(&avatar_url, 0, sizeof(avatar_url)); if (g_cfg.net.psn_status >= np_psn_status::psn_fake) { diff --git a/rpcs3/Emu/NP/rpcn_countries.cpp b/rpcs3/Emu/NP/rpcn_countries.cpp new file mode 100644 index 0000000000..9d841d9dfd --- /dev/null +++ b/rpcs3/Emu/NP/rpcn_countries.cpp @@ -0,0 +1,82 @@ +#include "stdafx.h" +#include "rpcn_countries.h" + +namespace countries +{ + const std::array g_countries = + { + country_code{"Japan", "jp"}, + country_code{"United States", "us"}, + country_code{"Argentina", "ar"}, + country_code{"Australia", "au"}, + country_code{"Austria", "at"}, + country_code{"Bahrain", "bh"}, + country_code{"Belgium", "be"}, + country_code{"Bolivia", "bo"}, + country_code{"Brazil", "br"}, + country_code{"Bulgaria", "bg"}, + country_code{"Canada", "ca"}, + country_code{"Chile", "cl"}, + country_code{"China", "cn"}, + country_code{"Colombia", "co"}, + country_code{"Costa Rica", "cr"}, + country_code{"Croatia", "hr"}, + country_code{"Cyprus", "cy"}, + country_code{"Czech Republic", "cz"}, + country_code{"Denmark", "dk"}, + country_code{"Ecuador", "ec"}, + country_code{"El Salvador", "sv"}, + country_code{"Finland", "fi"}, + country_code{"France", "fr"}, + country_code{"Germany", "de"}, + country_code{"Greece", "gr"}, + country_code{"Guatemala", "gt"}, + country_code{"Honduras", "hn"}, + country_code{"Hong Kong", "hk"}, + country_code{"Hungary", "hu"}, + country_code{"Iceland", "is"}, + country_code{"India", "in"}, + country_code{"Indonesia", "id"}, + country_code{"Ireland", "ie"}, + country_code{"Israel", "il"}, + country_code{"Italy", "it"}, + country_code{"Korea", "kr"}, + country_code{"Kuwait", "kw"}, + country_code{"Lebanon", "lb"}, + country_code{"Luxembourg", "lu"}, + country_code{"Malaysia", "my"}, + country_code{"Malta", "mt"}, + country_code{"Mexico", "mx"}, + country_code{"Netherlands", "nl"}, + country_code{"New Zealand", "nz"}, + country_code{"Nicaragua", "ni"}, + country_code{"Norway", "no"}, + country_code{"Oman", "om"}, + country_code{"Panama", "pa"}, + country_code{"Paraguay", "py"}, + country_code{"Peru", "pe"}, + country_code{"Philippines", "ph"}, + country_code{"Poland", "pl"}, + country_code{"Portugal", "pt"}, + country_code{"Qatar", "qa"}, + country_code{"Romania", "ro"}, + country_code{"Russia", "ru"}, + country_code{"Saudi Arabia", "sa"}, + country_code{"Serbia", "rs"}, + country_code{"Singapore", "sg"}, + country_code{"Slovakia", "sk"}, + country_code{"South Africa", "za"}, + country_code{"Spain", "es"}, + country_code{"Sweden", "se"}, + country_code{"Switzerland", "ch"}, + country_code{"Taiwan", "tw"}, + country_code{"Thailand", "th"}, + country_code{"Turkey", "tr"}, + country_code{"Ukraine", "ua"}, + country_code{"United Arab Emirates", "ae"}, + country_code{"United Kingdom", "gb"}, + country_code{"Uruguay", "uy"}, + country_code{"Vietnam", "vn"} + }; +} // namespace countries + diff --git a/rpcs3/Emu/NP/rpcn_countries.h b/rpcs3/Emu/NP/rpcn_countries.h new file mode 100644 index 0000000000..2551ced9c1 --- /dev/null +++ b/rpcs3/Emu/NP/rpcn_countries.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +namespace countries +{ + struct country_code + { + std::string_view name; + std::string_view ccode; + }; + extern const std::array g_countries; +} // namespace countries + diff --git a/rpcs3/Emu/system_config.h b/rpcs3/Emu/system_config.h index b7d15da534..a3926102ad 100644 --- a/rpcs3/Emu/system_config.h +++ b/rpcs3/Emu/system_config.h @@ -314,6 +314,7 @@ struct cfg_root : cfg::node cfg::_bool upnp_enabled{this, "UPNP Enabled", false}; cfg::_enum psn_status{this, "PSN status", np_psn_status::disabled}; + cfg::string country{this, "PSN Country", "us"}; } net{this}; struct node_savestate : cfg::node diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index 14b28d0838..b1e96181b5 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -98,6 +98,7 @@ + @@ -578,6 +579,7 @@ + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 860a8d83ed..b2b5e82239 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -1264,6 +1264,9 @@ Emu\Io + + Emu\NP + @@ -2569,6 +2572,9 @@ Emu\CPU + + Emu\NP + diff --git a/rpcs3/rpcs3qt/emu_settings_type.h b/rpcs3/rpcs3qt/emu_settings_type.h index 59820995ec..c283065513 100644 --- a/rpcs3/rpcs3qt/emu_settings_type.h +++ b/rpcs3/rpcs3qt/emu_settings_type.h @@ -185,6 +185,7 @@ enum class emu_settings_type PSNStatus, BindAddress, EnableUpnp, + PSNCountry, // System LicenseArea, @@ -376,6 +377,7 @@ inline static const QMap settings_location = { emu_settings_type::PSNStatus, { "Net", "PSN status"}}, { emu_settings_type::BindAddress, { "Net", "Bind address"}}, { emu_settings_type::EnableUpnp, { "Net", "UPNP Enabled"}}, + { emu_settings_type::PSNCountry, { "Net", "PSN Country"}}, // System { emu_settings_type::LicenseArea, { "System", "License Area"}}, diff --git a/rpcs3/rpcs3qt/settings_dialog.cpp b/rpcs3/rpcs3qt/settings_dialog.cpp index 7edce0cad8..14836e7fc4 100644 --- a/rpcs3/rpcs3qt/settings_dialog.cpp +++ b/rpcs3/rpcs3qt/settings_dialog.cpp @@ -24,6 +24,7 @@ #include "emu_settings_type.h" #include "render_creator.h" #include "microphone_creator.h" +#include "Emu/NP/rpcn_countries.h" #include "Emu/GameInfo.h" #include "Emu/System.h" @@ -1468,6 +1469,22 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std m_emu_settings->EnhanceComboBox(ui->psnStatusBox, emu_settings_type::PSNStatus); SubscribeTooltip(ui->gb_psnStatusBox, tooltips.settings.psn_status); + settings_dialog::refresh_countrybox(); + connect(ui->psnCountryBox, QOverload::of(&QComboBox::currentIndexChanged), this, [this](int index) + { + if (index < 0) + return; + + const QVariant country_code = ui->psnCountryBox->itemData(index); + + if (!country_code.isValid() || !country_code.canConvert()) + return; + + m_emu_settings->SetSetting(emu_settings_type::PSNCountry, country_code.toString().toStdString()); + }); + + SubscribeTooltip(ui->gb_psnCountryBox, tooltips.settings.psn_country); + if (!game) { remove_item(ui->psnStatusBox, static_cast(np_psn_status::psn_fake), static_cast(g_cfg.net.psn_status.def)); @@ -2433,6 +2450,21 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std } } +void settings_dialog::refresh_countrybox() +{ + const auto& vec_countries = countries::g_countries; + const std::string cur_country = m_emu_settings->GetSetting(emu_settings_type::PSNCountry); + + ui->psnCountryBox->clear(); + + for (const auto& [cnty, code] : vec_countries) + { + ui->psnCountryBox->addItem(QString::fromUtf8(cnty.data(), static_cast(cnty.size())), QString::fromUtf8(code.data(), static_cast(code.size()))); + } + ui->psnCountryBox->setCurrentIndex(ui->psnCountryBox->findData(QString::fromStdString(cur_country))); + ui->psnCountryBox->model()->sort(0, Qt::AscendingOrder); +} + void settings_dialog::closeEvent([[maybe_unused]] QCloseEvent* event) { m_gui_settings->SetValue(gui::cfg_geometry, saveGeometry()); diff --git a/rpcs3/rpcs3qt/settings_dialog.h b/rpcs3/rpcs3qt/settings_dialog.h index 3c539e26ac..ce0696e57d 100644 --- a/rpcs3/rpcs3qt/settings_dialog.h +++ b/rpcs3/rpcs3qt/settings_dialog.h @@ -68,4 +68,7 @@ private: void SubscribeTooltip(QObject* object, const QString& tooltip); bool eventFilter(QObject* object, QEvent* event) override; void closeEvent(QCloseEvent* event) override; + + // Countries + void refresh_countrybox(); }; diff --git a/rpcs3/rpcs3qt/settings_dialog.ui b/rpcs3/rpcs3qt/settings_dialog.ui index fc9f33fde3..13bff3c435 100644 --- a/rpcs3/rpcs3qt/settings_dialog.ui +++ b/rpcs3/rpcs3qt/settings_dialog.ui @@ -2276,6 +2276,18 @@ + + + Country + + + + + + + + + Qt::Vertical diff --git a/rpcs3/rpcs3qt/tooltips.h b/rpcs3/rpcs3qt/tooltips.h index ba2fce2487..e06f6231a2 100644 --- a/rpcs3/rpcs3qt/tooltips.h +++ b/rpcs3/rpcs3qt/tooltips.h @@ -247,6 +247,7 @@ public: const QString dns_swap = tr("DNS Swap List.\nOnly available in custom configurations."); const QString bind = tr("Interface IP Address to bind to.\nOnly available in custom configurations."); const QString enable_upnp = tr("Enable UPNP.\nThis will automatically forward ports bound on 0.0.0.0 if your router has UPNP enabled."); + const QString psn_country = tr("Changes the RPCN country."); // system