[XConfig] Implementation of XConfig

This commit is contained in:
Gliniak
2026-05-17 21:30:10 +02:00
committed by Radosław Gliński
parent f88bfbe41e
commit 99ea6da18a
31 changed files with 2020 additions and 846 deletions

View File

@@ -169,6 +169,16 @@ X_HRESULT XamApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
args->unk1.get(), args->unk2.get(), args->unk3.get());
return X_E_SUCCESS;
}
// Causes dashboard to correctly process language/region change. It does not
// contain any buffer.
case 0x8000000D: {
const bool is_pc_enabled =
(kernel_state_->xconfig()->ReadSetting<uint8_t>(
XCONFIG_USER_CATEGORY, XCONFIG_USER_PC_FLAGS) &
X_PC_FLAGS::PCEnabled) != 0;
return is_pc_enabled ? X_E_ACCESS_DENIED : X_E_SUCCESS;
}
}
XELOGE(
"Unimplemented XAM message app={:08X}, msg={:08X}, arg1={:08X}, "

View File

@@ -349,7 +349,8 @@ void UserTracker::UpdateTitleGpdFile() {
}
auto user_language = spa_data_->GetExistingLanguage(
static_cast<XLanguage>(cvars::user_language));
static_cast<XLanguage>(kernel_state()->xconfig()->ReadSetting<uint32_t>(
kernel::XCONFIG_USER_CATEGORY, kernel::XCONFIG_USER_LANGUAGE)));
// First add achievements because of lowest ID
for (const auto& entry : spa_data_->GetAchievements()) {

View File

@@ -14,8 +14,8 @@
DEFINE_bool(allow_avatar_initialization, false,
"Enable Avatar Initialization\n"
" Only set true when testing Avatar games. Certain games may\n"
" require kinect implementation.",
"Only set true when testing Avatar games. Certain games may crash "
"due to requirement of full avatar implementation.",
"Kernel");
namespace xe {

View File

@@ -22,6 +22,7 @@
#include "xenia/kernel/xboxkrnl/xboxkrnl_memory.h"
#include "xenia/kernel/xboxkrnl/xboxkrnl_modules.h"
#include "xenia/kernel/xboxkrnl/xboxkrnl_threading.h"
#include "xenia/kernel/xconfig.h"
#include "xenia/kernel/xenumerator.h"
#include "xenia/kernel/xthread.h"
#include "xenia/ui/imgui_dialog.h"
@@ -45,8 +46,6 @@ DEFINE_int32(avpack, 8,
" 7 = TV PAL-60\n"
" 8 = HDMI (default)",
"Video");
DECLARE_uint32(audio_flag);
DEFINE_bool(staging_mode, 0,
"Enables preview mode in dashboards to render debug information.",
"Kernel");
@@ -605,11 +604,11 @@ dword_result_t XGetAudioFlags_entry() {
return 2;
}
if (!cvars::audio_flag) {
return 0x10000 | 0x1;
}
const auto audio_flags = kernel_state()->xconfig()->ReadSetting<uint32_t>(
XCONFIG_USER_CATEGORY,
XCONFIG_USER_CATEGORY_ENTRIES::XCONFIG_USER_AUDIO_FLAGS);
return cvars::audio_flag;
return audio_flags ? audio_flags : 0x10000 | 0x1;
}
DECLARE_XAM_EXPORT1(XGetAudioFlags, kNone, kImplemented);
@@ -764,6 +763,21 @@ void GetSystemTimeAsFileTime_entry(lpqword_t time_ptr,
}
DECLARE_XAM_EXPORT1(GetSystemTimeAsFileTime, kNone, kImplemented);
dword_result_t XamIsIptvEnabled_entry() {
const bool iptv_enabled =
kernel_state()->xconfig()->ReadSetting<uint32_t>(
X_CONFIG_CATEGORY::XCONFIG_USER_CATEGORY, XCONFIG_USER_RETAIL_FLAGS) &
X_RETAIL_FLAGS::IPTVEnabled;
return !iptv_enabled ? X_E_FAIL : X_ERROR_SUCCESS;
}
DECLARE_XAM_EXPORT1(XamIsIptvEnabled, kNone, kImplemented);
dword_result_t XamLookupCommonStringByIndex_entry(dword_t string_index) {
return 0;
}
DECLARE_XAM_EXPORT1(XamLookupCommonStringByIndex, kNone, kImplemented);
} // namespace xam
} // namespace kernel
} // namespace xe

View File

@@ -21,8 +21,6 @@
#include "third_party/fmt/include/fmt/format.h"
#include "third_party/fmt/include/fmt/xchar.h"
DECLARE_int32(user_country);
DECLARE_int32(user_language);
// TODO(gibbed): put these forward decls in a header somewhere.
namespace xe {
@@ -205,17 +203,14 @@ uint8_t xeXamGetLocaleFromCountry(uint8_t id) {
// Helpers.
uint8_t xeXamGetLocaleEx(uint8_t max_country_id, uint8_t max_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))) {*/
uint8_t country_id = kernel_state()->xconfig()->ReadSetting<uint8_t>(
XCONFIG_USER_CATEGORY, XCONFIG_USER_COUNTRY);
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();
@@ -529,7 +524,9 @@ uint32_t xeXGetGameRegion() {
0x02FEu, 0x03FFu, 0x02FEu, 0x03FFu, 0x02FEu, 0x02FEu, 0xFFFFu, 0x03FFu,
0x03FFu, 0x03FFu, 0x03FFu, 0x02FEu, 0x03FFu, 0x03FFu, 0x02FEu, 0x00FFu,
0x03FFu, 0x03FFu, 0x03FFu, 0x03FFu, 0x03FFu, 0x03FFu, 0x03FFu};
auto country = static_cast<uint8_t>(cvars::user_country);
auto country = kernel_state()->xconfig()->ReadSetting<uint8_t>(
XCONFIG_USER_CATEGORY,
XCONFIG_USER_CATEGORY_ENTRIES::XCONFIG_USER_COUNTRY);
return country < xe::countof(table) ? table[country] : 0xFFFFu;
}
@@ -537,7 +534,11 @@ dword_result_t XGetGameRegion_entry() { return xeXGetGameRegion(); }
DECLARE_XAM_EXPORT1(XGetGameRegion, kNone, kStub);
XLanguage xeGetLanguage(bool extended_languages_support) {
auto desired_language = static_cast<XLanguage>(cvars::user_language);
auto desired_language =
static_cast<XLanguage>(kernel_state()->xconfig()->ReadSetting<uint32_t>(
XCONFIG_USER_CATEGORY,
XCONFIG_USER_CATEGORY_ENTRIES::XCONFIG_USER_LANGUAGE));
uint32_t region = xeXGetGameRegion();
auto max_languages = extended_languages_support ? XLanguage::kMaxLanguages
: XLanguage::kSChinese;
@@ -599,6 +600,24 @@ pointer_result_t XamGetLanguageTypefacePatch_entry(dword_t language) {
}
DECLARE_XAM_EXPORT1(XamGetLanguageTypefacePatch, kNone, kStub);
dword_result_t XamGetCountry_entry() {
return kernel_state()->xconfig()->ReadSetting<uint32_t>(
XCONFIG_USER_CATEGORY,
XCONFIG_USER_CATEGORY_ENTRIES::XCONFIG_USER_COUNTRY);
}
DECLARE_XAM_EXPORT1(XamGetCountry, kNone, kSketchy);
dword_result_t XamSetCountry_entry(dword_t country) {
const uint8_t country_real = country;
kernel_state()->xconfig()->WriteSetting(
XCONFIG_USER_CATEGORY,
XCONFIG_USER_CATEGORY_ENTRIES::XCONFIG_USER_COUNTRY, &country_real);
return 0;
}
DECLARE_XAM_EXPORT1(XamSetCountry, kNone, kSketchy);
} // namespace xam
} // namespace kernel
} // namespace xe

View File

@@ -19,12 +19,6 @@
#include "xenia/ui/windowed_app_context.h"
#include "xenia/xbox.h"
DEFINE_bool(allow_nui_initialization, false,
"Enable NUI initialization\n"
" Only set true when testing kinect games. Certain games may\n"
" require avatar implementation.",
"Kernel");
namespace xe {
namespace kernel {
namespace xam {
@@ -69,8 +63,14 @@ dword_result_t XamNuiGetDeviceStatus_entry(
*/
status_ptr.Zero();
status_ptr->status = cvars::allow_nui_initialization;
return cvars::allow_nui_initialization ? X_ERROR_SUCCESS : 0xC0050006;
const bool kinect_initialized =
kernel_state()->xconfig()->ReadSetting<uint32_t>(
X_CONFIG_CATEGORY::XCONFIG_USER_CATEGORY, XCONFIG_USER_RETAIL_FLAGS) &
X_RETAIL_FLAGS::KinectInitialized;
status_ptr->status = kinect_initialized;
return kinect_initialized ? X_ERROR_SUCCESS : 0xC0050006;
}
DECLARE_XAM_EXPORT1(XamNuiGetDeviceStatus, kNone, kStub);
@@ -195,8 +195,12 @@ dword_result_t XamNuiIsDeviceReady_entry() {
- 0x0004
- 0x0040
*/
uint16_t device_state = cvars::allow_nui_initialization ? 1 : 0;
return device_state >> 1 & 1;
const bool kinect_initialized =
kernel_state()->xconfig()->ReadSetting<uint32_t>(
X_CONFIG_CATEGORY::XCONFIG_USER_CATEGORY, XCONFIG_USER_RETAIL_FLAGS) &
X_RETAIL_FLAGS::KinectInitialized;
return kinect_initialized >> 1 & 1;
}
DECLARE_XAM_EXPORT1(XamNuiIsDeviceReady, kNone, kImplemented);

View File

@@ -988,7 +988,8 @@ DECLARE_XAM_EXPORT1(XamUserGetUserFlagsFromXUID, kUserProfiles, kImplemented);
dword_result_t XamUserGetOnlineLanguageFromXUID_entry(qword_t xuid) {
const auto& user = kernel_state()->xam_state()->GetUserProfile(xuid);
if (!user) {
return cvars::user_language;
return kernel_state()->xconfig()->ReadSetting<uint32_t>(
XCONFIG_USER_CATEGORY, XCONFIG_USER_LANGUAGE);
}
return user->GetLanguage();
}
@@ -998,7 +999,8 @@ DECLARE_XAM_EXPORT1(XamUserGetOnlineLanguageFromXUID, kUserProfiles,
dword_result_t XamUserGetOnlineCountryFromXUID_entry(qword_t xuid) {
const auto& user = kernel_state()->xam_state()->GetUserProfile(xuid);
if (!user) {
return cvars::user_country;
return kernel_state()->xconfig()->ReadSetting<uint8_t>(
XCONFIG_USER_CATEGORY, XCONFIG_USER_COUNTRY);
}
return user->GetCountry();
}