diff --git a/src/xenia/kernel/xam/user_profile.h b/src/xenia/kernel/xam/user_profile.h index d2d5a4ea5..a288dacd9 100644 --- a/src/xenia/kernel/xam/user_profile.h +++ b/src/xenia/kernel/xam/user_profile.h @@ -95,10 +95,23 @@ class UserProfile { uint32_t signin_state() const { return 1; } uint32_t type() const { return 1 | 2; /* local | online profile? */ } + uint32_t GetReservedFlags() const { + return account_info_.GetReservedFlags(); + }; uint32_t GetCachedFlags() const { return account_info_.GetCachedFlags(); }; + uint32_t GetCountry() const { + return static_cast(account_info_.GetCountry()); + }; uint32_t GetSubscriptionTier() const { return account_info_.GetSubscriptionTier(); } + uint32_t GetLanguage() const { + return static_cast(account_info_.GetLanguage()); + }; + + bool IsParentalControlled() const { + return account_info_.IsParentalControlled(); + }; bool IsLiveEnabled() const { return account_info_.IsLiveEnabled(); } std::span GetProfileIcon(XTileType icon_type) { diff --git a/src/xenia/kernel/xam/xam_info.cc b/src/xenia/kernel/xam/xam_info.cc index c33a55b9e..391f820c8 100644 --- a/src/xenia/kernel/xam/xam_info.cc +++ b/src/xenia/kernel/xam/xam_info.cc @@ -733,6 +733,18 @@ dword_result_t XamIsXbox1TitleId_entry(dword_t title_id) { } DECLARE_XAM_EXPORT1(XamIsXbox1TitleId, kNone, kImplemented); +dword_result_t XamIsChildAccountSignedIn_entry() { + for (uint32_t i = 0; i < XUserMaxUserCount; i++) { + const auto& profile = kernel_state()->xam_state()->GetUserProfile(i); + if (profile && profile->IsParentalControlled()) { + return true; + } + } + + return false; +} +DECLARE_XAM_EXPORT1(XamIsChildAccountSignedIn, kNone, kImplemented); + void XamSetActiveDashAppInfo_entry(pointer_t dash_app) { if (!dash_app) { kernel_state()->dash_app_info_ = {}; diff --git a/src/xenia/kernel/xam/xam_user.cc b/src/xenia/kernel/xam/xam_user.cc index 7ee1a9e58..2dd35663c 100644 --- a/src/xenia/kernel/xam/xam_user.cc +++ b/src/xenia/kernel/xam/xam_user.cc @@ -19,6 +19,7 @@ #include "third_party/stb/stb_image.h" DECLARE_int32(user_language); +DECLARE_int32(user_country); namespace xe { namespace kernel { @@ -913,6 +914,18 @@ dword_result_t XamUserGetSubscriptionType_entry(dword_t user_index, } DECLARE_XAM_EXPORT1(XamUserGetSubscriptionType, kUserProfiles, kStub); +dword_result_t XamUserGetCachedUserFlags_entry(dword_t user_index) { + if (!kernel_state()->xam_state()->IsUserSignedIn(user_index)) { + return 0; + } + + const auto& user_profile = + kernel_state()->xam_state()->GetUserProfile(user_index); + + return user_profile->GetCachedFlags(); +} +DECLARE_XAM_EXPORT1(XamUserGetCachedUserFlags, kUserProfiles, kImplemented); + dword_result_t XamUserGetUserFlags_entry(dword_t user_index) { if (!kernel_state()->xam_state()->IsUserSignedIn(user_index)) { return 0; @@ -936,16 +949,24 @@ dword_result_t XamUserGetUserFlagsFromXUID_entry(qword_t xuid) { DECLARE_XAM_EXPORT1(XamUserGetUserFlagsFromXUID, kUserProfiles, kImplemented); dword_result_t XamUserGetOnlineLanguageFromXUID_entry(qword_t xuid) { - /* Notes: - - Calls XamUserGetUserFlagsFromXUID and returns (ulonglong)(cached_flag << - 0x20) >> 0x39 & 0x1f; - - XamUserGetMembershipTierFromXUID and XamUserGetOnlineCountryFromXUID also - call it - - Removed in metro - */ - return cvars::user_language; + const auto& user = kernel_state()->xam_state()->GetUserProfile(xuid); + if (!user) { + return cvars::user_language; + } + return user->GetLanguage(); } -DECLARE_XAM_EXPORT1(XamUserGetOnlineLanguageFromXUID, kUserProfiles, kStub); +DECLARE_XAM_EXPORT1(XamUserGetOnlineLanguageFromXUID, kUserProfiles, + kImplemented); + +dword_result_t XamUserGetOnlineCountryFromXUID_entry(qword_t xuid) { + const auto& user = kernel_state()->xam_state()->GetUserProfile(xuid); + if (!user) { + return cvars::user_country; + } + return user->GetCountry(); +} +DECLARE_XAM_EXPORT1(XamUserGetOnlineCountryFromXUID, kUserProfiles, + kImplemented); constexpr uint8_t kStatsMaxAmount = 64; diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index 6beae4688..01900e7f4 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -812,6 +812,7 @@ struct X_XAMACCOUNTINFO { return std::string_view(online_domain); } + uint32_t GetReservedFlags() const { return reserved_flags; }; uint32_t GetCachedFlags() const { return cached_user_flags; }; XOnlineCountry GetCountry() const { @@ -823,6 +824,10 @@ struct X_XAMACCOUNTINFO { (cached_user_flags & kSubscriptionTierMask) >> 20); } + bool IsParentalControlled() const { + return static_cast((cached_user_flags & kLanguageMask) >> 24); + } + XLanguage GetLanguage() const { return static_cast((cached_user_flags & kLanguageMask) >> 25); }