Merge branch 'master' of https://github.com/xenia-project/xenia into canary
# Conflicts: # src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc - resolved in xboxkrnl_xconfig.cc?
This commit is contained in:
commit
25df5a6e94
|
@ -17,15 +17,12 @@
|
|||
#include "xenia/kernel/xthread.h"
|
||||
#include "xenia/xbox.h"
|
||||
|
||||
DECLARE_int32(user_country);
|
||||
|
||||
// TODO(gibbed): put these forward decls in a header somewhere.
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
X_STATUS xeExGetXConfigSetting(uint16_t category, uint16_t setting,
|
||||
void* buffer, uint16_t buffer_size,
|
||||
uint16_t* required_size);
|
||||
} // namespace xboxkrnl
|
||||
namespace xam {
|
||||
uint32_t xeXGetGameRegion();
|
||||
} // namespace xam
|
||||
|
@ -75,7 +72,8 @@ const wchar_t* xeXamGetOnlineCountryString(uint8_t id) {
|
|||
L"PG", L"PN", L"RE", L"RW", L"WS", L"SM", L"ST", L"SN", L"RS",
|
||||
L"SC", L"SL", L"SB", L"SO", L"LK", L"SH", L"KN", L"LC", L"PM",
|
||||
L"VC", L"SR", L"SZ", L"TJ", L"TZ", L"TL", L"TG", L"TK", L"TO",
|
||||
L"TM", L"TC", L"TV", L"UG",
|
||||
L"TM", L"TC", L"TV", L"UG", L"VU", L"VA", nullptr, L"VG", L"WF",
|
||||
L"EH", L"ZM", L"ZZ",
|
||||
};
|
||||
#pragma warning(suppress : 6385)
|
||||
return id < xe::countof(table) ? table[id] : nullptr;
|
||||
|
@ -94,6 +92,7 @@ const wchar_t* xeXamGetCountryString(uint8_t id) {
|
|||
L"PH", L"PK", L"PL", L"PR", L"PT", L"PY", L"QA", L"RO", L"RU", L"SA",
|
||||
L"SE", L"SG", L"SI", L"SK", nullptr, L"SV", L"SY", L"TH", L"TN", L"TR",
|
||||
L"TT", L"TW", L"UA", L"US", L"UY", L"UZ", L"VE", L"VN", L"YE", L"ZA",
|
||||
L"ZW", L"ZZ",
|
||||
};
|
||||
#pragma warning(suppress : 6385)
|
||||
return id < xe::countof(table) ? table[id] : nullptr;
|
||||
|
@ -102,7 +101,7 @@ const wchar_t* xeXamGetCountryString(uint8_t id) {
|
|||
const wchar_t* xeXamGetLanguageString(uint8_t id) {
|
||||
static const wchar_t* const table[] = {
|
||||
L"zz", L"en", L"ja", L"de", L"fr", L"es", L"it", L"ko", L"zh",
|
||||
L"pt", nullptr, L"pl", L"ru", L"sv", L"tr", L"nb", L"nl",
|
||||
L"pt", nullptr, L"pl", L"ru", L"sv", L"tr", L"nb", L"nl", L"zh",
|
||||
};
|
||||
#pragma warning(suppress : 6385)
|
||||
return id < xe::countof(table) ? table[id] : nullptr;
|
||||
|
@ -122,9 +121,19 @@ const wchar_t* xeXamGetLocaleString(uint8_t id) {
|
|||
|
||||
uint8_t xeXamGetLocaleFromOnlineCountry(uint8_t id) {
|
||||
static uint8_t const table[] = {
|
||||
0, 43, 0, 0, 40, 2, 1, 0, 3, 0, 0, 0, 0, 4, 0,
|
||||
0, 5, 0, 33, 6, 7, 8, 0, 9, 13, 10, 0, 0, 0, 0,
|
||||
0, 31, 11, 0, 12, 35, 0, 14, 0, 15, 0, 0, 16,
|
||||
0, 43, 0, 0, 40, 2, 1, 0, 3, 0, 0, 0, 0, 4, 0, 0, 5, 0, 33,
|
||||
6, 7, 8, 0, 9, 13, 10, 0, 0, 0, 0, 0, 31, 11, 0, 12, 35, 0, 14,
|
||||
0, 15, 0, 0, 16, 0, 18, 42, 17, 0, 0, 0, 19, 0, 0, 20, 0, 0, 21,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 23, 25,
|
||||
24, 0, 0, 0, 0, 0, 26, 0, 27, 0, 0, 0, 37, 41, 32, 28, 0, 29, 0,
|
||||
0, 0, 0, 0, 39, 0, 34, 0, 36, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 38,
|
||||
};
|
||||
#pragma warning(suppress : 6385)
|
||||
return id < xe::countof(table) ? table[id] : 0;
|
||||
|
@ -132,9 +141,9 @@ uint8_t xeXamGetLocaleFromOnlineCountry(uint8_t id) {
|
|||
|
||||
uint8_t xeXamGetLanguageFromOnlineLanguage(uint8_t id) {
|
||||
static uint8_t const table[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 17, 11, 12, 1, 1, 15, 16, 13, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 17, 11, 12, 1, 1, 15, 16, 13, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
};
|
||||
#pragma warning(suppress : 6385)
|
||||
return id < xe::countof(table) ? table[id] : 0;
|
||||
|
@ -156,13 +165,21 @@ const wchar_t* xeXamGetOnlineLanguageString(uint8_t id) {
|
|||
|
||||
uint8_t xeXamGetCountryFromOnlineCountry(uint8_t id) {
|
||||
static uint8_t const table[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 0, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 95,
|
||||
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 0, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 0, 95,
|
||||
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111,
|
||||
};
|
||||
#pragma warning(suppress : 6385)
|
||||
return id < xe::countof(table) ? table[id] : 0;
|
||||
|
@ -170,9 +187,12 @@ uint8_t xeXamGetCountryFromOnlineCountry(uint8_t id) {
|
|||
|
||||
uint8_t xeXamGetLocaleFromCountry(uint8_t id) {
|
||||
static uint8_t const table[] = {
|
||||
0, 43, 0, 0, 40, 2, 1, 0, 3, 0, 0, 0, 0, 4, 0,
|
||||
0, 5, 0, 33, 6, 7, 8, 0, 9, 13, 10, 0, 0, 0, 0,
|
||||
0, 31, 11, 0, 12, 35, 0, 14, 0, 15, 0, 0, 16,
|
||||
0, 43, 0, 0, 40, 2, 1, 0, 3, 0, 0, 0, 0, 4, 0, 0, 5, 0, 33,
|
||||
6, 7, 8, 0, 9, 13, 10, 0, 0, 0, 0, 0, 31, 11, 0, 12, 35, 0, 14,
|
||||
0, 15, 0, 0, 16, 0, 18, 42, 17, 0, 0, 0, 19, 0, 0, 20, 0, 0, 21,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 23, 25,
|
||||
24, 0, 0, 0, 0, 0, 26, 0, 27, 0, 0, 0, 37, 41, 32, 28, 0, 29, 0,
|
||||
0, 0, 0, 0, 39, 0, 34, 0, 36, 0, 0, 0, 0, 0, 30, 0, 38,
|
||||
};
|
||||
#pragma warning(suppress : 6385)
|
||||
return id < xe::countof(table) ? table[id] : 0;
|
||||
|
@ -181,16 +201,17 @@ uint8_t xeXamGetLocaleFromCountry(uint8_t id) {
|
|||
// Helpers.
|
||||
|
||||
uint8_t xeXamGetLocaleEx(uint8_t max_country_id, uint8_t max_locale_id) {
|
||||
uint8_t country_id;
|
||||
if (XSUCCEEDED(xboxkrnl::xeExGetXConfigSetting(
|
||||
3, 14, &country_id, sizeof(country_id), nullptr))) {
|
||||
if (country_id <= max_country_id) {
|
||||
uint8_t locale_id = xeXamGetLocaleFromCountry(country_id);
|
||||
if (locale_id <= max_locale_id) {
|
||||
return locale_id;
|
||||
}
|
||||
// TODO(gibbed): rework when XConfig is cleanly implemented.
|
||||
uint8_t country_id = static_cast<uint8_t>(cvars::user_country);
|
||||
/*if (XSUCCEEDED(xboxkrnl::xeExGetXConfigSetting(
|
||||
3, 14, &country_id, sizeof(country_id), nullptr))) {*/
|
||||
if (country_id <= max_country_id) {
|
||||
uint8_t locale_id = xeXamGetLocaleFromCountry(country_id);
|
||||
if (locale_id <= max_locale_id) {
|
||||
return locale_id;
|
||||
}
|
||||
}
|
||||
/*}*/
|
||||
|
||||
// couldn't find locale, fallback from game region.
|
||||
auto game_region = xeXGetGameRegion();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
@ -96,6 +96,7 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
|
|||
RegisterThreadingExports(export_resolver_, kernel_state_);
|
||||
RegisterUsbcamExports(export_resolver_, kernel_state_);
|
||||
RegisterVideoExports(export_resolver_, kernel_state_);
|
||||
RegisterXConfigExports(export_resolver_, kernel_state_);
|
||||
|
||||
// KeDebugMonitorData (?*)
|
||||
// Set to a valid value when a remote debugger is attached.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
@ -14,133 +14,11 @@
|
|||
#include "xenia/kernel/util/shim_utils.h"
|
||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_private.h"
|
||||
#include "xenia/xbox.h"
|
||||
#include "xenia/base/cvar.h"
|
||||
|
||||
DEFINE_bool(xconfig_initial_setup, false,
|
||||
"Enable the dashboard initial setup/OOBE", "Kernel");
|
||||
|
||||
DEFINE_int32(game_language, 1,
|
||||
"The language for the game to run in. 1=EN / 2=JP / 3=DE / 4=FR / "
|
||||
"5=ES / 6=IT / 7=KR / 8=CN",
|
||||
"General");
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
X_STATUS xeExGetXConfigSetting(uint16_t category, uint16_t setting,
|
||||
void* buffer, uint16_t buffer_size,
|
||||
uint16_t* required_size) {
|
||||
uint16_t setting_size = 0;
|
||||
alignas(uint32_t) uint8_t value[4];
|
||||
|
||||
// TODO(benvanik): have real structs here that just get copied from.
|
||||
// https://free60project.github.io/wiki/XConfig.html
|
||||
// https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/Generic/ExConfig.h
|
||||
switch (category) {
|
||||
case 0x0002:
|
||||
// XCONFIG_SECURED_CATEGORY
|
||||
switch (setting) {
|
||||
case 0x0001: // XCONFIG_SECURED_MAC_ADDRESS (6 bytes)
|
||||
return X_STATUS_SUCCESS; // Just return, easier than setting up code
|
||||
// for different size configs
|
||||
case 0x0002: // XCONFIG_SECURED_AV_REGION
|
||||
setting_size = 4;
|
||||
xe::store_and_swap<uint32_t>(value, 0x00001000); // USA/Canada
|
||||
break;
|
||||
default:
|
||||
assert_unhandled_case(setting);
|
||||
return X_STATUS_INVALID_PARAMETER_2;
|
||||
}
|
||||
break;
|
||||
case 0x0003:
|
||||
// XCONFIG_USER_CATEGORY
|
||||
switch (setting) {
|
||||
case 0x0001: // XCONFIG_USER_TIME_ZONE_BIAS
|
||||
case 0x0002: // XCONFIG_USER_TIME_ZONE_STD_NAME
|
||||
case 0x0003: // XCONFIG_USER_TIME_ZONE_DLT_NAME
|
||||
case 0x0004: // XCONFIG_USER_TIME_ZONE_STD_DATE
|
||||
case 0x0005: // XCONFIG_USER_TIME_ZONE_DLT_DATE
|
||||
case 0x0006: // XCONFIG_USER_TIME_ZONE_STD_BIAS
|
||||
case 0x0007: // XCONFIG_USER_TIME_ZONE_DLT_BIAS
|
||||
setting_size = 4;
|
||||
// TODO(benvanik): get this value.
|
||||
xe::store_and_swap<uint32_t>(value, 0);
|
||||
break;
|
||||
case 0x0009: // XCONFIG_USER_LANGUAGE
|
||||
setting_size = 4;
|
||||
xe::store_and_swap<uint32_t>(value, cvars::game_language); // English
|
||||
break;
|
||||
case 0x000A: // XCONFIG_USER_VIDEO_FLAGS
|
||||
setting_size = 4;
|
||||
xe::store_and_swap<uint32_t>(value, 0x00040000);
|
||||
break;
|
||||
case 0x000C: // XCONFIG_USER_RETAIL_FLAGS
|
||||
setting_size = 4;
|
||||
// TODO(benvanik): get this value.
|
||||
|
||||
// 0x40 = dashboard initial setup complete
|
||||
xe::store_and_swap<uint32_t>(value,
|
||||
cvars::xconfig_initial_setup ? 0 : 0x40);
|
||||
break;
|
||||
case 0x000E: // XCONFIG_USER_COUNTRY
|
||||
// Halo: Reach sub_82804888 - min 0x5, max 0x6E.
|
||||
setting_size = 1;
|
||||
// TODO(benvanik): get this value.
|
||||
value[0] = 5;
|
||||
break;
|
||||
case 0x000F: // XCONFIG_USER_PC_FLAGS (parental control?)
|
||||
setting_size = 1;
|
||||
xe::store_and_swap<uint32_t>(value, 0);
|
||||
break;
|
||||
case 0x0010: // XCONFIG_USER_SMB_CONFIG (0x100 byte string)
|
||||
// Just set the start of the buffer to 0 so that callers
|
||||
// don't error from an un-inited buffer
|
||||
setting_size = 4;
|
||||
xe::store_and_swap<uint32_t>(value, 0);
|
||||
break;
|
||||
default:
|
||||
assert_unhandled_case(setting);
|
||||
return X_STATUS_INVALID_PARAMETER_2;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert_unhandled_case(category);
|
||||
return X_STATUS_INVALID_PARAMETER_1;
|
||||
}
|
||||
|
||||
if (buffer) {
|
||||
if (buffer_size < setting_size) {
|
||||
return X_STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
std::memcpy(buffer, value, setting_size);
|
||||
} else {
|
||||
if (buffer_size) {
|
||||
return X_STATUS_INVALID_PARAMETER_3;
|
||||
}
|
||||
}
|
||||
if (required_size) {
|
||||
*required_size = setting_size;
|
||||
}
|
||||
|
||||
return X_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
dword_result_t ExGetXConfigSetting(word_t category, word_t setting,
|
||||
lpdword_t buffer_ptr, word_t buffer_size,
|
||||
lpword_t required_size_ptr) {
|
||||
uint16_t required_size = 0;
|
||||
X_STATUS result = xeExGetXConfigSetting(category, setting, buffer_ptr,
|
||||
buffer_size, &required_size);
|
||||
|
||||
if (required_size_ptr) {
|
||||
*required_size_ptr = required_size;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(ExGetXConfigSetting, kModules, kImplemented);
|
||||
|
||||
dword_result_t XexCheckExecutablePrivilege(dword_t privilege) {
|
||||
// BOOL
|
||||
// DWORD Privilege
|
||||
|
|
|
@ -21,40 +21,28 @@ namespace xboxkrnl {
|
|||
xe::cpu::Export* RegisterExport_xboxkrnl(xe::cpu::Export* export_entry);
|
||||
|
||||
// Registration functions, one per file.
|
||||
void RegisterAudioExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state);
|
||||
void RegisterAudioXmaExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state);
|
||||
void RegisterCryptExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state);
|
||||
void RegisterDebugExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state);
|
||||
void RegisterErrorExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state);
|
||||
void RegisterHalExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state);
|
||||
void RegisterHidExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state);
|
||||
void RegisterIoExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state);
|
||||
void RegisterMemoryExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state);
|
||||
void RegisterMiscExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state);
|
||||
void RegisterModuleExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state);
|
||||
void RegisterObExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state);
|
||||
void RegisterRtlExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state);
|
||||
void RegisterStringExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state);
|
||||
void RegisterThreadingExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state);
|
||||
void RegisterUsbcamExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state);
|
||||
void RegisterVideoExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state);
|
||||
#define DECLARE_REGISTER_EXPORTS(n) \
|
||||
void Register##n##Exports(xe::cpu::ExportResolver* export_resolver, \
|
||||
KernelState* kernel_state)
|
||||
DECLARE_REGISTER_EXPORTS(Audio);
|
||||
DECLARE_REGISTER_EXPORTS(AudioXma);
|
||||
DECLARE_REGISTER_EXPORTS(Crypt);
|
||||
DECLARE_REGISTER_EXPORTS(Debug);
|
||||
DECLARE_REGISTER_EXPORTS(Error);
|
||||
DECLARE_REGISTER_EXPORTS(Hal);
|
||||
DECLARE_REGISTER_EXPORTS(Hid);
|
||||
DECLARE_REGISTER_EXPORTS(Io);
|
||||
DECLARE_REGISTER_EXPORTS(Memory);
|
||||
DECLARE_REGISTER_EXPORTS(Misc);
|
||||
DECLARE_REGISTER_EXPORTS(Module);
|
||||
DECLARE_REGISTER_EXPORTS(Ob);
|
||||
DECLARE_REGISTER_EXPORTS(Rtl);
|
||||
DECLARE_REGISTER_EXPORTS(String);
|
||||
DECLARE_REGISTER_EXPORTS(Threading);
|
||||
DECLARE_REGISTER_EXPORTS(Usbcam);
|
||||
DECLARE_REGISTER_EXPORTS(Video);
|
||||
DECLARE_REGISTER_EXPORTS(XConfig);
|
||||
#undef DECLARE_REGISTER_EXPORTS
|
||||
|
||||
} // namespace xboxkrnl
|
||||
} // namespace kernel
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/cpu/processor.h"
|
||||
#include "xenia/kernel/kernel_state.h"
|
||||
#include "xenia/kernel/user_module.h"
|
||||
#include "xenia/kernel/util/shim_utils.h"
|
||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_private.h"
|
||||
#include "xenia/xbox.h"
|
||||
|
||||
DEFINE_bool(xconfig_initial_setup, false,
|
||||
"Enable the dashboard initial setup/OOBE", "Kernel");
|
||||
|
||||
DEFINE_int32(user_language, 1,
|
||||
"User language ID. "
|
||||
"1=en / 2=ja / 3=de / 4=fr / 5=es / 6=it / 7=ko / 8=zh / 9=pt / "
|
||||
"11=pl / 12=ru / 13=sv / 14=tr / 15=nb / 16=nl / 17=zh",
|
||||
"XConfig");
|
||||
|
||||
// TODO(gibbed): The description is very long. Newline support?
|
||||
DEFINE_int32(
|
||||
user_country, 103,
|
||||
"User country ID. "
|
||||
"1=AE / 2=AL / 3=AM / 4=AR / 5=AT / 6=AU / 7=AZ / 8=BE / 9=BG / 10=BH / "
|
||||
"11=BN / 12=BO / 13=BR / 14=BY / 15=BZ / 16=CA / 18=CH / 19=CL / 20=CN / "
|
||||
"21=CO / 22=CR / 23=CZ / 24=DE / 25=DK / 26=DO / 27=DZ / 28=EC / 29=EE / "
|
||||
"30=EG / 31=ES / 32=FI / 33=FO / 34=FR / 35=GB / 36=GE / 37=GR / 38=GT / "
|
||||
"39=HK / 40=HN / 41=HR / 42=HU / 43=ID / 44=IE / 45=IL / 46=IN / 47=IQ / "
|
||||
"48=IR / 49=IS / 50=IT / 51=JM / 52=JO / 53=JP / 54=KE / 55=KG / 56=KR / "
|
||||
"57=KW / 58=KZ / 59=LB / 60=LI / 61=LT / 62=LU / 63=LV / 64=LY / 65=MA / "
|
||||
"66=MC / 67=MK / 68=MN / 69=MO / 70=MV / 71=MX / 72=MY / 73=NI / 74=NL / "
|
||||
"75=NO / 76=NZ / 77=OM / 78=PA / 79=PE / 80=PH / 81=PK / 82=PL / 83=PR / "
|
||||
"84=PT / 85=PY / 86=QA / 87=RO / 88=RU / 89=SA / 90=SE / 91=SG / 92=SI / "
|
||||
"93=SK / 95=SV / 96=SY / 97=TH / 98=TN / 99=TR / 100=TT / 101=TW / "
|
||||
"102=UA / 103=US / 104=UY / 105=UZ / 106=VE / 107=VN / 108=YE / 109=ZA",
|
||||
"XConfig");
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
X_STATUS xeExGetXConfigSetting(uint16_t category, uint16_t setting,
|
||||
void* buffer, uint16_t buffer_size,
|
||||
uint16_t* required_size) {
|
||||
uint16_t setting_size = 0;
|
||||
alignas(uint32_t) uint8_t value[4];
|
||||
|
||||
// TODO(benvanik): have real structs here that just get copied from.
|
||||
// https://free60project.github.io/wiki/XConfig.html
|
||||
// https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/Generic/ExConfig.h
|
||||
switch (category) {
|
||||
case 0x0002:
|
||||
// XCONFIG_SECURED_CATEGORY
|
||||
switch (setting) {
|
||||
case 0x0001: // XCONFIG_SECURED_MAC_ADDRESS (6 bytes)
|
||||
return X_STATUS_SUCCESS; // Just return, easier than setting up code
|
||||
// for different size configs
|
||||
case 0x0002: // XCONFIG_SECURED_AV_REGION
|
||||
setting_size = 4;
|
||||
xe::store_and_swap<uint32_t>(value, 0x00001000); // USA/Canada
|
||||
break;
|
||||
default:
|
||||
assert_unhandled_case(setting);
|
||||
return X_STATUS_INVALID_PARAMETER_2;
|
||||
}
|
||||
break;
|
||||
case 0x0003:
|
||||
// XCONFIG_USER_CATEGORY
|
||||
switch (setting) {
|
||||
case 0x0001: // XCONFIG_USER_TIME_ZONE_BIAS
|
||||
case 0x0002: // XCONFIG_USER_TIME_ZONE_STD_NAME
|
||||
case 0x0003: // XCONFIG_USER_TIME_ZONE_DLT_NAME
|
||||
case 0x0004: // XCONFIG_USER_TIME_ZONE_STD_DATE
|
||||
case 0x0005: // XCONFIG_USER_TIME_ZONE_DLT_DATE
|
||||
case 0x0006: // XCONFIG_USER_TIME_ZONE_STD_BIAS
|
||||
case 0x0007: // XCONFIG_USER_TIME_ZONE_DLT_BIAS
|
||||
setting_size = 4;
|
||||
// TODO(benvanik): get this value.
|
||||
xe::store_and_swap<uint32_t>(value, 0);
|
||||
break;
|
||||
case 0x0009: // XCONFIG_USER_LANGUAGE
|
||||
setting_size = 4;
|
||||
xe::store_and_swap<uint32_t>(value, cvars::user_language);
|
||||
break;
|
||||
case 0x000A: // XCONFIG_USER_VIDEO_FLAGS
|
||||
setting_size = 4;
|
||||
xe::store_and_swap<uint32_t>(value, 0x00040000);
|
||||
break;
|
||||
case 0x000C: // XCONFIG_USER_RETAIL_FLAGS
|
||||
setting_size = 4;
|
||||
// TODO(benvanik): get this value.
|
||||
// 0x40 = dashboard initial setup complete
|
||||
xe::store_and_swap<uint32_t>(value,
|
||||
cvars::xconfig_initial_setup ? 0 : 0x40);
|
||||
break;
|
||||
case 0x000E: // XCONFIG_USER_COUNTRY
|
||||
setting_size = 1;
|
||||
value[0] = static_cast<uint8_t>(cvars::user_country);
|
||||
break;
|
||||
case 0x000F: // XCONFIG_USER_PC_FLAGS (parental control?)
|
||||
setting_size = 1;
|
||||
xe::store_and_swap<uint32_t>(value, 0); // value[0]?
|
||||
break;
|
||||
case 0x0010: // XCONFIG_USER_SMB_CONFIG (0x100 byte string)
|
||||
// Just set the start of the buffer to 0 so that callers
|
||||
// don't error from an un-inited buffer
|
||||
setting_size = 4;
|
||||
xe::store_and_swap<uint32_t>(value, 0);
|
||||
break;
|
||||
default:
|
||||
assert_unhandled_case(setting);
|
||||
return X_STATUS_INVALID_PARAMETER_2;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert_unhandled_case(category);
|
||||
return X_STATUS_INVALID_PARAMETER_1;
|
||||
}
|
||||
|
||||
if (buffer) {
|
||||
if (buffer_size < setting_size) {
|
||||
return X_STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
std::memcpy(buffer, value, setting_size);
|
||||
} else {
|
||||
if (buffer_size) {
|
||||
return X_STATUS_INVALID_PARAMETER_3;
|
||||
}
|
||||
}
|
||||
|
||||
if (required_size) {
|
||||
*required_size = setting_size;
|
||||
}
|
||||
|
||||
return X_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
dword_result_t ExGetXConfigSetting(word_t category, word_t setting,
|
||||
lpdword_t buffer_ptr, word_t buffer_size,
|
||||
lpword_t required_size_ptr) {
|
||||
uint16_t required_size = 0;
|
||||
X_STATUS result = xeExGetXConfigSetting(category, setting, buffer_ptr,
|
||||
buffer_size, &required_size);
|
||||
|
||||
if (required_size_ptr) {
|
||||
*required_size_ptr = required_size;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(ExGetXConfigSetting, kModules, kImplemented);
|
||||
|
||||
void RegisterXConfigExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state) {}
|
||||
|
||||
} // namespace xboxkrnl
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
Loading…
Reference in New Issue