[UI] Added modify profile UI

- Changed default icons size from 75x75 to 64x64 to match console icons size
- Added png_utils
- Removed all dialogs from xam_ui.cc into separate entities under xam/ui
- Added option to return INT32 and WSTRING type settings to host
- Added multiple enums related to user settings
- Added code to handle changing user pfp
- Fixed bug with system app being added to GPD played list
- Changed logic in: XamUserGetUserFlagsFromXUID
- Implemented: XamUserIsOnlineEnabled
- Implemented: XamUserGetMembershipTier
- Implemented: XamUserGetMembershipTierFromXUID
- Implemented: XamUserGetUserTenure
- Partially Implemented: XamUserGetSubscriptionType
This commit is contained in:
Gliniak
2025-05-10 12:52:05 +02:00
committed by Radosław Gliński
parent 270e88a7a7
commit e601b5ab87
30 changed files with 2904 additions and 1404 deletions

View File

@@ -7,82 +7,24 @@
******************************************************************************
*/
#include "xenia/app/profile_dialogs.h"
#include <algorithm>
#include "xenia/app/emulator_window.h"
#include "xenia/app/profile_dialogs.h"
#include "xenia/base/png_utils.h"
#include "xenia/base/system.h"
#include "xenia/kernel/util/shim_utils.h"
#include "xenia/kernel/xam/xam_ui.h"
#include "xenia/ui/file_picker.h"
#include "xenia/kernel/xam/ui/create_profile_ui.h"
#include "xenia/kernel/xam/ui/gamercard_ui.h"
#include "xenia/kernel/xam/ui/signin_ui.h"
#include "xenia/kernel/xam/ui/title_info_ui.h"
namespace xe {
namespace kernel {
namespace xam {
extern bool xeDrawProfileContent(ui::ImGuiDrawer* imgui_drawer,
const uint64_t xuid, const uint8_t user_index,
const X_XAMACCOUNTINFO* account,
uint64_t* selected_xuid);
}
} // namespace kernel
namespace app {
void CreateProfileDialog::OnDraw(ImGuiIO& io) {
if (!has_opened_) {
ImGui::OpenPopup("Create Profile");
has_opened_ = true;
}
auto profile_manager = emulator_window_->emulator()
->kernel_state()
->xam_state()
->profile_manager();
bool dialog_open = true;
if (!ImGui::BeginPopupModal("Create Profile", &dialog_open,
ImGuiWindowFlags_NoCollapse |
ImGuiWindowFlags_AlwaysAutoResize |
ImGuiWindowFlags_HorizontalScrollbar)) {
Close();
return;
}
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) &&
!ImGui::IsAnyItemActive() && !ImGui::IsMouseClicked(0)) {
ImGui::SetKeyboardFocusHere(0);
}
ImGui::TextUnformatted("Gamertag:");
ImGui::InputText("##Gamertag", gamertag_, sizeof(gamertag_));
const std::string gamertag_string = std::string(gamertag_);
bool valid = profile_manager->IsGamertagValid(gamertag_string);
ImGui::BeginDisabled(!valid);
if (ImGui::Button("Create")) {
bool autologin = (profile_manager->GetAccountCount() == 0);
if (profile_manager->CreateProfile(gamertag_string, autologin,
migration_) &&
migration_) {
emulator_window_->emulator()->DataMigration(0xB13EBABEBABEBABE);
}
std::fill(std::begin(gamertag_), std::end(gamertag_), '\0');
dialog_open = false;
}
ImGui::EndDisabled();
ImGui::SameLine();
if (ImGui::Button("Cancel")) {
std::fill(std::begin(gamertag_), std::end(gamertag_), '\0');
dialog_open = false;
}
if (!dialog_open) {
ImGui::CloseCurrentPopup();
Close();
ImGui::EndPopup();
return;
}
ImGui::EndPopup();
}
void NoProfileDialog::OnDraw(ImGuiIO& io) {
auto profile_manager = emulator_window_->emulator()
->kernel_state()
@@ -124,13 +66,13 @@ void NoProfileDialog::OnDraw(ImGuiIO& io) {
if (content_files.empty()) {
if (ImGui::Button("Create Profile")) {
new CreateProfileDialog(emulator_window_->imgui_drawer(),
emulator_window_);
new kernel::xam::ui::CreateProfileUI(emulator_window_->imgui_drawer(),
emulator_window_->emulator());
}
} else {
if (ImGui::Button("Create profile & migrate data")) {
new CreateProfileDialog(emulator_window_->imgui_drawer(),
emulator_window_, true);
new kernel::xam::ui::CreateProfileUI(emulator_window_->imgui_drawer(),
emulator_window_->emulator(), true);
}
}
@@ -149,6 +91,57 @@ void NoProfileDialog::OnDraw(ImGuiIO& io) {
ImGui::End();
}
void ProfileConfigDialog::LoadProfileIcon() {
if (!emulator_window_) {
return;
}
for (uint8_t user_index = 0; user_index < XUserMaxUserCount; user_index++) {
const auto profile = emulator_window_->emulator()
->kernel_state()
->xam_state()
->profile_manager()
->GetProfile(user_index);
if (!profile) {
continue;
}
LoadProfileIcon(profile->xuid());
}
}
void ProfileConfigDialog::LoadProfileIcon(const uint64_t xuid) {
if (!emulator_window_) {
return;
}
const auto profile_manager = emulator_window_->emulator()
->kernel_state()
->xam_state()
->profile_manager();
if (!profile_manager) {
return;
}
const auto profile = profile_manager->GetProfile(xuid);
if (!profile) {
if (profile_icon_.contains(xuid)) {
profile_icon_[xuid].release();
}
return;
}
const auto profile_icon =
profile->GetProfileIcon(kernel::xam::XTileType::kGamerTile);
if (profile_icon.empty()) {
return;
}
profile_icon_[xuid].release();
profile_icon_[xuid] = imgui_drawer()->LoadImGuiIcon(profile_icon);
}
void ProfileConfigDialog::OnDraw(ImGuiIO& io) {
if (!emulator_window_->emulator() ||
!emulator_window_->emulator()->kernel_state() ||
@@ -184,28 +177,120 @@ void ProfileConfigDialog::OnDraw(ImGuiIO& io) {
ImGui::Separator();
}
const ImVec2 next_window_position =
ImVec2(ImGui::GetWindowPos().x + ImGui::GetWindowSize().x + 20.f,
ImGui::GetWindowPos().y);
for (auto& [xuid, account] : *profiles) {
ImGui::PushID(static_cast<int>(xuid));
const uint8_t user_index =
profile_manager->GetUserIndexAssignedToProfile(xuid);
if (!kernel::xam::xeDrawProfileContent(imgui_drawer(), xuid, user_index,
&account, &selected_xuid_)) {
const auto profile_icon = profile_icon_.find(xuid) != profile_icon_.cend()
? profile_icon_[xuid].get()
: nullptr;
auto context_menu_fun = [=, this]() -> bool {
if (ImGui::BeginPopupContextItem("Profile Menu")) {
//*selected_xuid = xuid;
if (user_index == XUserIndexAny) {
if (ImGui::MenuItem("Login")) {
profile_manager->Login(xuid);
if (!profile_manager->GetProfile(xuid)
->GetProfileIcon(kernel::xam::XTileType::kGamerTile)
.empty()) {
LoadProfileIcon(xuid);
}
}
if (ImGui::BeginMenu("Login to slot:")) {
for (uint8_t i = 1; i <= XUserMaxUserCount; i++) {
if (ImGui::MenuItem(fmt::format("slot {}", i).c_str())) {
profile_manager->Login(xuid, i - 1);
}
}
ImGui::EndMenu();
}
} else {
if (ImGui::MenuItem("Logout")) {
profile_manager->Logout(user_index);
LoadProfileIcon(xuid);
}
}
if (ImGui::MenuItem("Modify")) {
new kernel::xam::ui::GamercardUI(
emulator_window_->window(), emulator_window_->imgui_drawer(),
emulator_window_->emulator()->kernel_state(), xuid);
}
const bool is_signedin = profile_manager->GetProfile(xuid) != nullptr;
ImGui::BeginDisabled(!is_signedin);
if (ImGui::MenuItem("Show Played Titles")) {
new kernel::xam::ui::TitleListUI(
emulator_window_->imgui_drawer(), next_window_position,
profile_manager->GetProfile(user_index));
}
ImGui::EndDisabled();
if (ImGui::MenuItem("Show Content Directory")) {
const auto path = profile_manager->GetProfileContentPath(
xuid, emulator_window_->emulator()->kernel_state()->title_id());
if (!std::filesystem::exists(path)) {
std::filesystem::create_directories(path);
}
std::thread path_open(LaunchFileExplorer, path);
path_open.detach();
}
if (!emulator_window_->emulator()->is_title_open()) {
ImGui::Separator();
if (ImGui::BeginMenu("Delete Profile")) {
ImGui::BeginTooltip();
ImGui::TextUnformatted(
fmt::format(
"You're about to delete profile: {} (XUID: {:016X}). "
"This will remove all data assigned to this profile "
"including savefiles. Are you sure?",
account.GetGamertagString(), xuid)
.c_str());
ImGui::EndTooltip();
if (ImGui::MenuItem("Yes, delete it!")) {
profile_manager->DeleteProfile(xuid);
ImGui::EndMenu();
ImGui::EndPopup();
return false;
}
ImGui::EndMenu();
}
}
ImGui::EndPopup();
}
return true;
};
if (!kernel::xam::xeDrawProfileContent(
imgui_drawer(), xuid, user_index, &account, profile_icon,
context_menu_fun, [=, this]() { LoadProfileIcon(xuid); },
&selected_xuid_)) {
ImGui::PopID();
ImGui::End();
return;
}
ImGui::PopID();
ImGui::Spacing();
ImGui::Separator();
}
ImGui::Spacing();
if (ImGui::Button("Create Profile")) {
new CreateProfileDialog(emulator_window_->imgui_drawer(), emulator_window_);
new kernel::xam::ui::CreateProfileUI(emulator_window_->imgui_drawer(),
emulator_window_->emulator());
}
ImGui::End();