فهرست منبع

CFG:U: Store country codes as u16 instead of char pointers, and return the correct error in GetCountryCodeID.

Emmanuel Gil Peyrot 11 سال پیش
والد
کامیت
5a3b1b5f44
1فایلهای تغییر یافته به همراه48 افزوده شده و 44 حذف شده
  1. 48 44
      src/core/hle/service/cfg_u.cpp

+ 48 - 44
src/core/hle/service/cfg_u.cpp

@@ -11,33 +11,38 @@
 
 namespace CFG_U {
 
-static const std::array<const char*, 187> country_codes = { 
-    nullptr, "JP", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,    // 0-7
-    "AI", "AG", "AR", "AW", "BS", "BB", "BZ", "BO",                         // 8-15
-    "BR", "VG", "CA", "KY", "CL", "CO", "CR", "DM",                         // 16-23
-    "DO", "EC", "SV", "GF", "GD", "GP", "GT", "GY",                         // 24-31
-    "HT", "HN", "JM", "MQ", "MX", "MS", "AN", "NI",                         // 32-39
-    "PA", "PY", "PE", "KN", "LC", "VC", "SR", "TT",                         // 40-47
-    "TC", "US", "UY", "VI", "VE", nullptr, nullptr, nullptr,                // 48-55
-    nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // 56-63
-    "AL", "AU", "AT", "BE", "BA", "BW", "BG", "HR",                         // 64-71
-    "CY", "CZ", "DK", "EE", "FI", "FR", "DE", "GR",                         // 72-79
-    "HU", "IS", "IE", "IT", "LV", "LS", "LI", "LT",                         // 80-87
-    "LU", "MK", "MT", "ME", "MZ", "NA", "NL", "NZ",                         // 88-95
-    "NO", "PL", "PT", "RO", "RU", "RS", "SK", "SI",                         // 96-103
-    "ZA", "ES", "SZ", "SE", "CH", "TR", "GB", "ZM",                         // 104-111
-    "ZW", "AZ", "MR", "ML", "NE", "TD", "SD", "ER",                         // 112-119
-    "DJ", "SO", "AD", "GI", "GG", "IM", "JE", "MC",                         // 120-127
-    "TW", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,    // 128-135
-    "KR", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,    // 136-143
-    "HK", "MO", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,       // 144-151
-    "ID", "SG", "TH", "PH", "MY", nullptr, nullptr, nullptr,                // 152-159
-    "CN", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,    // 160-167
-    "AE", "IN", "EG", "OM", "QA", "KW", "SA", "SY",                         // 168-175
-    "BH", "JO", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,       // 176-183
-    "SM", "VA", "BM",                                                       // 184-186
+// TODO(Link Mauve): use a constexpr once MSVC starts supporting it.
+#define C(code) ((code)[0] | ((code)[1] << 8))
+
+static const std::array<u16, 187> country_codes = {
+    0,       C("JP"), 0,       0,       0,       0,       0,       0,       // 0-7
+    C("AI"), C("AG"), C("AR"), C("AW"), C("BS"), C("BB"), C("BZ"), C("BO"), // 8-15
+    C("BR"), C("VG"), C("CA"), C("KY"), C("CL"), C("CO"), C("CR"), C("DM"), // 16-23
+    C("DO"), C("EC"), C("SV"), C("GF"), C("GD"), C("GP"), C("GT"), C("GY"), // 24-31
+    C("HT"), C("HN"), C("JM"), C("MQ"), C("MX"), C("MS"), C("AN"), C("NI"), // 32-39
+    C("PA"), C("PY"), C("PE"), C("KN"), C("LC"), C("VC"), C("SR"), C("TT"), // 40-47
+    C("TC"), C("US"), C("UY"), C("VI"), C("VE"), 0,       0,       0,       // 48-55
+    0,       0,       0,       0,       0,       0,       0,       0,       // 56-63
+    C("AL"), C("AU"), C("AT"), C("BE"), C("BA"), C("BW"), C("BG"), C("HR"), // 64-71
+    C("CY"), C("CZ"), C("DK"), C("EE"), C("FI"), C("FR"), C("DE"), C("GR"), // 72-79
+    C("HU"), C("IS"), C("IE"), C("IT"), C("LV"), C("LS"), C("LI"), C("LT"), // 80-87
+    C("LU"), C("MK"), C("MT"), C("ME"), C("MZ"), C("NA"), C("NL"), C("NZ"), // 88-95
+    C("NO"), C("PL"), C("PT"), C("RO"), C("RU"), C("RS"), C("SK"), C("SI"), // 96-103
+    C("ZA"), C("ES"), C("SZ"), C("SE"), C("CH"), C("TR"), C("GB"), C("ZM"), // 104-111
+    C("ZW"), C("AZ"), C("MR"), C("ML"), C("NE"), C("TD"), C("SD"), C("ER"), // 112-119
+    C("DJ"), C("SO"), C("AD"), C("GI"), C("GG"), C("IM"), C("JE"), C("MC"), // 120-127
+    C("TW"), 0,       0,       0,       0,       0,       0,       0,       // 128-135
+    C("KR"), 0,       0,       0,       0,       0,       0,       0,       // 136-143
+    C("HK"), C("MO"), 0,       0,       0,       0,       0,       0,       // 144-151
+    C("ID"), C("SG"), C("TH"), C("PH"), C("MY"), 0,       0,       0,       // 152-159
+    C("CN"), 0,       0,       0,       0,       0,       0,       0,       // 160-167
+    C("AE"), C("IN"), C("EG"), C("OM"), C("QA"), C("KW"), C("SA"), C("SY"), // 168-175
+    C("BH"), C("JO"), 0,       0,       0,       0,       0,       0,       // 176-183
+    C("SM"), C("VA"), C("BM")                                               // 184-186
 };
 
+#undef C
+
 /**
  * CFG_User::GetCountryCodeString service function
  *  Inputs:
@@ -50,20 +55,14 @@ static void GetCountryCodeString(Service::Interface* self) {
     u32* cmd_buffer = Service::GetCommandBuffer();
     u32 country_code_id = cmd_buffer[1];
 
-    if (country_code_id >= country_codes.size()) {
+    if (country_code_id >= country_codes.size() || 0 == country_codes[country_code_id]) {
         ERROR_LOG(KERNEL, "requested country code id=%d is invalid", country_code_id);
         cmd_buffer[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw;
         return;
     }
-    
-    const char* code = country_codes[country_code_id];
-    if (code != nullptr) {
-        cmd_buffer[1] = 0;
-        cmd_buffer[2] = code[0] | (code[1] << 8);
-    } else {
-        cmd_buffer[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw;
-        DEBUG_LOG(KERNEL, "requested country code id=%d is not set", country_code_id);
-    }
+
+    cmd_buffer[1] = 0;
+    cmd_buffer[2] = country_codes[country_code_id];
 }
 
 /**
@@ -77,20 +76,25 @@ static void GetCountryCodeString(Service::Interface* self) {
 static void GetCountryCodeID(Service::Interface* self) {
     u32* cmd_buffer = Service::GetCommandBuffer();
     u16 country_code = cmd_buffer[1];
-    u16 country_code_id = -1;
+    u16 country_code_id = 0;
 
-    for (u32 i = 0; i < country_codes.size(); ++i) {
-        const char* code_string = country_codes[i];
+    // The following algorithm will fail if the first country code isn't 0.
+    _dbg_assert_(HLE, country_codes[0] == 0);
 
-        if (code_string != nullptr) {
-            u16 code = code_string[0] | (code_string[1] << 8);
-            if (code == country_code) {
-                country_code_id = i;
-                break;
-            }
+    for (size_t id = 0; id < country_codes.size(); ++id) {
+        if (country_codes[id] == country_code) {
+            country_code_id = id;
+            break;
         }
     }
 
+    if (0 == country_code_id) {
+        ERROR_LOG(KERNEL, "requested country code name=%c%c is invalid", country_code & 0xff, country_code >> 8);
+        cmd_buffer[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw;
+        cmd_buffer[2] = 0xFFFF;
+        return;
+    }
+
     cmd_buffer[1] = 0;
     cmd_buffer[2] = country_code_id;
 }