diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index 8a34237c6..31858e8a8 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp @@ -602,6 +602,43 @@ void Module::Interface::GetModelNintendo2DS(Kernel::HLERequestContext& ctx) { rb.Push(model != Service::CFG::NINTENDO_2DS); } +void Module::Interface::TranslateCountryInfo(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx); + ConsoleCountryInfo country_info = rp.PopRaw(); + u8 translate_direction = rp.Pop(); + + // Translation table, left is version A and right is version B. + static constexpr std::array, 5> translations = + {{ + {{{0x00, 0x00}, 0x03, 0x6E}, {{0x00, 0x00}, 0x04, 0x6E}}, + {{{0x00, 0x00}, 0x04, 0x6E}, {{0x00, 0x00}, 0x05, 0x6E}}, + {{{0x00, 0x00}, 0x05, 0x6E}, {{0x00, 0x00}, 0x06, 0x6E}}, + {{{0x00, 0x00}, 0x06, 0x6E}, {{0x00, 0x00}, 0x07, 0x6E}}, + {{{0x00, 0x00}, 0x07, 0x6E}, {{0x00, 0x00}, 0x03, 0x6E}}, + }}; + + ConsoleCountryInfo final_info = country_info; + if (translate_direction == 0) { + for (const auto& [vA, vB] : translations) { + if (country_info == vB) { + final_info = vA; + break; + } + } + } else if (translate_direction == 1) { + for (const auto& [vA, vB] : translations) { + if (country_info == vA) { + final_info = vB; + break; + } + } + } + + IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); + rb.Push(ResultSuccess); + rb.PushRaw(final_info); +} + void Module::Interface::GetConfig(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx); u32 size = rp.Pop(); diff --git a/src/core/hle/service/cfg/cfg.h b/src/core/hle/service/cfg/cfg.h index 8b02d6f8e..0464af042 100644 --- a/src/core/hle/service/cfg/cfg.h +++ b/src/core/hle/service/cfg/cfg.h @@ -152,6 +152,15 @@ struct ConsoleCountryInfo { std::array unknown; ///< Unknown data u8 state_code; ///< The state or province code. u8 country_code; ///< The country code of the console + + bool operator==(const ConsoleCountryInfo& other) const { + return unknown == other.unknown && state_code == other.state_code && + country_code == other.country_code; + } + + bool operator!=(const ConsoleCountryInfo& other) const { + return !(*this == other); + } }; static_assert(sizeof(ConsoleCountryInfo) == 4, "ConsoleCountryInfo must be exactly 4 bytes"); @@ -315,6 +324,8 @@ public: */ void GetModelNintendo2DS(Kernel::HLERequestContext& ctx); + void TranslateCountryInfo(Kernel::HLERequestContext& ctx); + /** * CFG::GetConfig service function * Inputs: diff --git a/src/core/hle/service/cfg/cfg_i.cpp b/src/core/hle/service/cfg/cfg_i.cpp index aa7c17c3b..7cd8adaee 100644 --- a/src/core/hle/service/cfg/cfg_i.cpp +++ b/src/core/hle/service/cfg/cfg_i.cpp @@ -1,4 +1,4 @@ -// Copyright 2014 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -20,7 +20,7 @@ CFG_I::CFG_I(std::shared_ptr cfg) : Module::Interface(std::move(cfg), "c {0x0005, &CFG_I::GetSystemModel, "GetSystemModel"}, {0x0006, &CFG_I::GetModelNintendo2DS, "GetModelNintendo2DS"}, {0x0007, nullptr, "WriteToFirstByteCfgSavegame"}, - {0x0008, nullptr, "TranslateCountryInfo"}, + {0x0008, &CFG_I::TranslateCountryInfo, "TranslateCountryInfo"}, {0x0009, &CFG_I::GetCountryCodeString, "GetCountryCodeString"}, {0x000A, &CFG_I::GetCountryCodeID, "GetCountryCodeID"}, {0x000B, nullptr, "IsFangateSupported"}, diff --git a/src/core/hle/service/cfg/cfg_s.cpp b/src/core/hle/service/cfg/cfg_s.cpp index 81aa5f487..a918fd946 100644 --- a/src/core/hle/service/cfg/cfg_s.cpp +++ b/src/core/hle/service/cfg/cfg_s.cpp @@ -1,4 +1,4 @@ -// Copyright 2015 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -20,7 +20,7 @@ CFG_S::CFG_S(std::shared_ptr cfg) : Module::Interface(std::move(cfg), "c {0x0005, &CFG_S::GetSystemModel, "GetSystemModel"}, {0x0006, &CFG_S::GetModelNintendo2DS, "GetModelNintendo2DS"}, {0x0007, nullptr, "WriteToFirstByteCfgSavegame"}, - {0x0008, nullptr, "TranslateCountryInfo"}, + {0x0008, &CFG_S::TranslateCountryInfo, "TranslateCountryInfo"}, {0x0009, &CFG_S::GetCountryCodeString, "GetCountryCodeString"}, {0x000A, &CFG_S::GetCountryCodeID, "GetCountryCodeID"}, {0x000B, nullptr, "IsFangateSupported"}, diff --git a/src/core/hle/service/cfg/cfg_u.cpp b/src/core/hle/service/cfg/cfg_u.cpp index 57db9d45a..301daf05f 100644 --- a/src/core/hle/service/cfg/cfg_u.cpp +++ b/src/core/hle/service/cfg/cfg_u.cpp @@ -1,4 +1,4 @@ -// Copyright 2014 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -20,7 +20,7 @@ CFG_U::CFG_U(std::shared_ptr cfg) : Module::Interface(std::move(cfg), "c {0x0005, &CFG_U::GetSystemModel, "GetSystemModel"}, {0x0006, &CFG_U::GetModelNintendo2DS, "GetModelNintendo2DS"}, {0x0007, nullptr, "WriteToFirstByteCfgSavegame"}, - {0x0008, nullptr, "TranslateCountryInfo"}, + {0x0008, &CFG_U::TranslateCountryInfo, "TranslateCountryInfo"}, {0x0009, &CFG_U::GetCountryCodeString, "GetCountryCodeString"}, {0x000A, &CFG_U::GetCountryCodeID, "GetCountryCodeID"}, {0x000B, nullptr, "IsFangateSupported"},