Skip to content

Commit 9b68381

Browse files
committed
[XAM] Implemented backend profile settings support
1 parent 805e83c commit 9b68381

26 files changed

+1210
-196
lines changed

src/xenia/app/gamerpic_browser.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,19 @@ void TitleGamerpicBrowser::UpdateGamerpicIfRequested(
926926
}
927927

928928
if (updated) {
929+
// XUIDs -> Title IDs -> Settings
930+
user_settingids_map settings = {};
931+
932+
settings[profile_->GetOnlineXUID()][xe::kernel::kDashboardID].push_back(
933+
kernel::xam::UserSettingId::XPROFILE_GAMERCARD_PICTURE_KEY);
934+
935+
// Profile settings are sent along with profile registration, therefore
936+
// it doesn't matter if this fails due to profile not existing on the
937+
// backend.
938+
if (!kernel::XLiveAPI::SetUsersSettings(settings)) {
939+
XELOGW("Updating Backend Gamerpic Setting Failed!");
940+
}
941+
929942
new_gamerpic_ = {};
930943
small_gamerpic_ = {};
931944

src/xenia/app/profile_dialogs.cc

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -115,23 +115,39 @@ void ProfileConfigDialog::LoadProfileIcon(const uint64_t xuid) {
115115
return;
116116
}
117117

118-
const auto profile_manager = emulator_window_->emulator()
119-
->kernel_state()
120-
->xam_state()
121-
->profile_manager();
118+
const auto xam_state =
119+
emulator_window_->emulator()->kernel_state()->xam_state();
120+
121+
const auto profile_manager = xam_state->profile_manager();
122+
const auto user_tracker = xam_state->user_tracker();
123+
122124
if (!profile_manager) {
123125
return;
124126
}
125127

128+
if (!user_tracker) {
129+
return;
130+
}
131+
126132
const auto profile = profile_manager->GetProfile(xuid);
127133

128134
if (!profile) {
129135
if (profile_icon_.contains(xuid)) {
130136
profile_icon_[xuid].release();
131137
}
138+
139+
if (profile_gamerpic_key_.contains(xuid)) {
140+
profile_gamerpic_key_.erase(xuid);
141+
}
132142
return;
133143
}
134144

145+
const auto gamerpic_key = user_tracker->GetUserGamerpicSetting(xuid);
146+
147+
if (gamerpic_key.has_value()) {
148+
profile_gamerpic_key_[xuid] = gamerpic_key.value();
149+
}
150+
135151
const auto profile_icon =
136152
profile->GetProfileIcon(kernel::xam::XTileType::kGamerTile);
137153
if (profile_icon.empty()) {
@@ -197,12 +213,32 @@ void ProfileConfigDialog::OnDraw(ImGuiIO& io) {
197213
const uint8_t user_index =
198214
profile_manager->GetUserIndexAssignedToProfile(xuid);
199215

200-
// Create ImmediateTexture of profile gamerpic every frame (Slow
201-
// Performance)
216+
// Detect the change because creating ImmediateTexture every frame will
217+
// impact performance.
202218
//
203219
// If dialog is open while Gamerpic Browser changes gamerpic then we want to
204220
// detect the change.
205-
LoadProfileIcon(xuid);
221+
const auto user_tracker = emulator_window_->emulator()
222+
->kernel_state()
223+
->xam_state()
224+
->user_tracker();
225+
226+
if (user_tracker && profile_gamerpic_key_.contains(xuid)) {
227+
const auto gamerpic_key = user_tracker->GetUserGamerpicSetting(xuid);
228+
229+
if (gamerpic_key.has_value()) {
230+
const kernel::xam::GamerPictureKey cached_gamerpic_key =
231+
profile_gamerpic_key_.at(xuid);
232+
const kernel::xam::GamerPictureKey current_gamerpic_key =
233+
gamerpic_key.value();
234+
235+
// Reload gamerpic icon if changed.
236+
if (memcmp(&cached_gamerpic_key, &current_gamerpic_key,
237+
sizeof(kernel::xam::GamerPictureKey)) != 0) {
238+
LoadProfileIcon(xuid);
239+
}
240+
}
241+
}
206242

207243
const auto profile_icon = profile_icon_.find(xuid) != profile_icon_.cend()
208244
? profile_icon_[xuid].get()
@@ -385,20 +421,10 @@ void ManagerDialog::Initalize(ui::ImGuiDrawer* imgui_drawer,
385421
return;
386422
}
387423

388-
friends_presence_ = RefreshFriendsPresence(profile);
389-
}
390-
391-
std::future<std::vector<kernel::FriendPresenceObjectJSON>>
392-
ManagerDialog::RefreshFriendsPresence(xe::kernel::xam::UserProfile* profile) {
393-
return std::async(std::launch::async, [profile, this]() {
394-
const uint8_t user_index =
395-
emulator_window_->emulator()
396-
->kernel_state()
397-
->xam_state()
398-
->GetUserIndexAssignedToProfileFromXUID(profile->xuid());
399-
400-
return kernel::XLiveAPI::GetAllFriendsPresence(user_index);
401-
});
424+
friends_presence_ =
425+
kernel::XLiveAPI::GetFriendsPresenceAsync(profile->xuid());
426+
immediate_gamerpics_ =
427+
kernel::XLiveAPI::GetFriendsGamerpicsAsync(profile->xuid(), imgui_drawer);
402428
}
403429

404430
void ManagerDialog::OnDraw(ImGuiIO& io) {
@@ -503,11 +529,21 @@ void ManagerDialog::OnDraw(ImGuiIO& io) {
503529
friends_presence_result_ = {};
504530
friends_args.refresh_presence = false;
505531

506-
friends_presence_ = RefreshFriendsPresence(profile);
532+
friends_presence_ =
533+
kernel::XLiveAPI::GetFriendsPresenceAsync(profile->xuid());
534+
immediate_gamerpics_ = kernel::XLiveAPI::GetFriendsGamerpicsAsync(
535+
profile->xuid(), imgui_drawer());
536+
}
537+
538+
if (immediate_gamerpics_.valid()) {
539+
if (immediate_gamerpics_.wait_for(0s) == std::future_status::ready) {
540+
immediate_gamerpics_result_.merge(immediate_gamerpics_.get());
541+
}
507542
}
508543

509544
xeDrawFriendsContent(imgui_drawer(), profile, friends_args,
510-
&friends_presence_result_);
545+
&friends_presence_result_,
546+
immediate_gamerpics_result_);
511547

512548
xeDrawSessionsContent(imgui_drawer(), profile, sessions_args, &sessions);
513549

src/xenia/app/profile_dialogs.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "xenia/kernel/xam/user_profile.h"
1919
#include "xenia/ui/imgui_dialog.h"
2020
#include "xenia/ui/imgui_drawer.h"
21+
#include "xenia/ui/immediate_drawer.h"
2122
#include "xenia/xbox.h"
2223

2324
namespace xe {
@@ -53,6 +54,7 @@ class ProfileConfigDialog final : public ui::ImGuiDialog {
5354
void LoadProfileIcon(const uint64_t xuid);
5455

5556
std::map<uint64_t, std::unique_ptr<ui::ImmediateTexture>> profile_icon_;
57+
std::map<uint64_t, kernel::xam::GamerPictureKey> profile_gamerpic_key_;
5658

5759
uint64_t selected_xuid_ = 0;
5860
EmulatorWindow* emulator_window_;
@@ -69,9 +71,6 @@ class ManagerDialog final : public ui::ImGuiDialog {
6971
void OnDraw(ImGuiIO& io) override;
7072
void Initalize(ui::ImGuiDrawer* imgui_drawer, uint32_t user_index);
7173

72-
std::future<std::vector<kernel::FriendPresenceObjectJSON>>
73-
RefreshFriendsPresence(xe::kernel::xam::UserProfile* profile);
74-
7574
private:
7675
bool manager_opened_ = false;
7776
uint64_t selected_xuid_ = 0;
@@ -86,6 +85,10 @@ class ManagerDialog final : public ui::ImGuiDialog {
8685
std::future<std::vector<xe::kernel::FriendPresenceObjectJSON>>
8786
friends_presence_;
8887
std::vector<xe::kernel::FriendPresenceObjectJSON> friends_presence_result_;
88+
std::future<std::map<uint64_t, std::shared_ptr<xe::ui::ImmediateTexture>>>
89+
immediate_gamerpics_;
90+
std::map<uint64_t, std::shared_ptr<xe::ui::ImmediateTexture>>
91+
immediate_gamerpics_result_;
8992
};
9093

9194
} // namespace app

0 commit comments

Comments
 (0)