[XAM] Implementation of: Profile Manager & Profiles Support
Thanks Emoose for Account Encrypt/Decrypt code!
This commit is contained in:
committed by
Radosław Gliński
parent
9ba0f18c82
commit
9bdd07590c
@@ -36,7 +36,9 @@
|
||||
#include "xenia/gpu/d3d12/d3d12_command_processor.h"
|
||||
#include "xenia/gpu/graphics_system.h"
|
||||
#include "xenia/hid/input_system.h"
|
||||
#include "xenia/kernel/xam/profile_manager.h"
|
||||
#include "xenia/kernel/xam/xam_module.h"
|
||||
#include "xenia/kernel/xam/xam_state.h"
|
||||
#include "xenia/ui/file_picker.h"
|
||||
#include "xenia/ui/graphics_provider.h"
|
||||
#include "xenia/ui/imgui_dialog.h"
|
||||
@@ -147,6 +149,14 @@ DEFINE_int32(recent_titles_entry_amount, 10,
|
||||
"recently played titles.",
|
||||
"General");
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xam {
|
||||
extern std::atomic<int> xam_dialogs_shown_;
|
||||
}
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
namespace xe {
|
||||
namespace app {
|
||||
|
||||
@@ -250,6 +260,14 @@ void EmulatorWindow::ShutdownGraphicsSystemPresenterPainting() {
|
||||
}
|
||||
|
||||
void EmulatorWindow::OnEmulatorInitialized() {
|
||||
if (!emulator_->kernel_state()
|
||||
->xam_state()
|
||||
->profile_manager()
|
||||
->GetProfilesCount()) {
|
||||
new NoProfileDialog(imgui_drawer_.get(), this);
|
||||
disable_hotkeys_ = true;
|
||||
}
|
||||
|
||||
emulator_initialized_ = true;
|
||||
window_->SetMainMenuEnabled(true);
|
||||
// When the user can see that the emulator isn't initializing anymore (the
|
||||
@@ -593,6 +611,15 @@ bool EmulatorWindow::Initialize() {
|
||||
}
|
||||
main_menu->AddChild(std::move(file_menu));
|
||||
|
||||
// Profile Menu
|
||||
auto profile_menu = MenuItem::Create(MenuItem::Type::kPopup, "&Profile");
|
||||
{
|
||||
profile_menu->AddChild(MenuItem::Create(
|
||||
MenuItem::Type::kString, "&Show Profile Menu", "",
|
||||
std::bind(&EmulatorWindow::ToggleProfilesConfigDialog, this)));
|
||||
}
|
||||
main_menu->AddChild(std::move(profile_menu));
|
||||
|
||||
// CPU menu.
|
||||
auto cpu_menu = MenuItem::Create(MenuItem::Type::kPopup, "&CPU");
|
||||
{
|
||||
@@ -1104,6 +1131,10 @@ void EmulatorWindow::InstallContent() {
|
||||
summary += "\n";
|
||||
}
|
||||
|
||||
if (content_installation_details.count(XContentType::kProfile)) {
|
||||
emulator_->kernel_state()->xam_state()->profile_manager()->ReloadProfiles();
|
||||
}
|
||||
|
||||
xe::ui::ImGuiDialog::ShowMessageBox(imgui_drawer_.get(),
|
||||
"Content Installation Summary", summary);
|
||||
}
|
||||
@@ -1296,24 +1327,13 @@ void EmulatorWindow::CreateZarchive() {
|
||||
}
|
||||
|
||||
void EmulatorWindow::ShowContentDirectory() {
|
||||
std::filesystem::path target_path;
|
||||
|
||||
auto content_root = emulator_->content_root();
|
||||
if (!emulator_->is_title_open() || !emulator_->kernel_state()) {
|
||||
target_path = content_root;
|
||||
} else {
|
||||
// TODO(gibbed): expose this via ContentManager?
|
||||
auto title_id =
|
||||
fmt::format("{:08X}", emulator_->kernel_state()->title_id());
|
||||
auto package_root = content_root / title_id;
|
||||
target_path = package_root;
|
||||
|
||||
if (!std::filesystem::exists(content_root)) {
|
||||
std::filesystem::create_directories(content_root);
|
||||
}
|
||||
|
||||
if (!std::filesystem::exists(target_path)) {
|
||||
std::filesystem::create_directories(target_path);
|
||||
}
|
||||
|
||||
LaunchFileExplorer(target_path);
|
||||
LaunchFileExplorer(content_root);
|
||||
}
|
||||
|
||||
void EmulatorWindow::CpuTimeScalarReset() {
|
||||
@@ -1382,6 +1402,23 @@ void EmulatorWindow::ToggleDisplayConfigDialog() {
|
||||
}
|
||||
}
|
||||
|
||||
void EmulatorWindow::ToggleProfilesConfigDialog() {
|
||||
if (!profile_config_dialog_) {
|
||||
disable_hotkeys_ = true;
|
||||
emulator_->kernel_state()->BroadcastNotification(kXNotificationIDSystemUI,
|
||||
1);
|
||||
profile_config_dialog_ =
|
||||
std::make_unique<ProfileConfigDialog>(imgui_drawer_.get(), this);
|
||||
kernel::xam::xam_dialogs_shown_++;
|
||||
} else {
|
||||
disable_hotkeys_ = false;
|
||||
emulator_->kernel_state()->BroadcastNotification(kXNotificationIDSystemUI,
|
||||
0);
|
||||
profile_config_dialog_.reset();
|
||||
kernel::xam::xam_dialogs_shown_--;
|
||||
}
|
||||
}
|
||||
|
||||
void EmulatorWindow::ToggleControllerVibration() {
|
||||
auto input_sys = emulator()->input_system();
|
||||
if (input_sys) {
|
||||
@@ -1579,7 +1616,13 @@ EmulatorWindow::ControllerHotKey EmulatorWindow::ProcessControllerHotkey(
|
||||
// Default return value
|
||||
EmulatorWindow::ControllerHotKey Unknown_hotkey = {};
|
||||
|
||||
if (buttons == 0) return Unknown_hotkey;
|
||||
if (buttons == 0) {
|
||||
return Unknown_hotkey;
|
||||
}
|
||||
|
||||
if (disable_hotkeys_.load()) {
|
||||
return Unknown_hotkey;
|
||||
}
|
||||
|
||||
// Hotkey cool-down to prevent toggling too fast
|
||||
const std::chrono::milliseconds delay(75);
|
||||
@@ -1790,7 +1833,8 @@ void EmulatorWindow::GamepadHotKeys() {
|
||||
while (true) {
|
||||
auto input_lock = input_sys->lock();
|
||||
|
||||
for (uint32_t user_index = 0; user_index < MAX_USERS; ++user_index) {
|
||||
for (uint32_t user_index = 0; user_index < XUserMaxUserCount;
|
||||
++user_index) {
|
||||
X_RESULT result = input_sys->GetState(user_index, &state);
|
||||
|
||||
// Release the lock before processing the hotkey
|
||||
@@ -1962,6 +2006,17 @@ xe::X_STATUS EmulatorWindow::RunTitle(
|
||||
|
||||
auto result = emulator_->LaunchPath(abs_path);
|
||||
|
||||
disable_hotkeys_ = false;
|
||||
|
||||
if (profile_config_dialog_) {
|
||||
profile_config_dialog_.reset();
|
||||
kernel::xam::xam_dialogs_shown_--;
|
||||
}
|
||||
|
||||
if (display_config_dialog_) {
|
||||
display_config_dialog_.reset();
|
||||
}
|
||||
|
||||
imgui_drawer_.get()->ClearDialogs();
|
||||
|
||||
if (result) {
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "xenia/ui/windowed_app_context.h"
|
||||
#include "xenia/xbox.h"
|
||||
|
||||
#define MAX_USERS 4
|
||||
#include "xenia/app/profile_dialogs.h"
|
||||
|
||||
namespace xe {
|
||||
namespace app {
|
||||
@@ -93,6 +93,12 @@ class EmulatorWindow {
|
||||
void SaveImage(const std::filesystem::path& path,
|
||||
const xe::ui::RawImage& image);
|
||||
|
||||
void ToggleProfilesConfigDialog();
|
||||
void SetHotkeysState(bool enabled) { disable_hotkeys_ = !enabled; }
|
||||
// We need to store it somewhere so there will be no situation when there are
|
||||
// multiple instances opened.
|
||||
std::unique_ptr<CreateProfileDialog> profile_creation_dialog_;
|
||||
|
||||
// Types of button functions for hotkeys.
|
||||
enum class ButtonFunctions {
|
||||
ToggleFullscreen,
|
||||
@@ -257,12 +263,17 @@ class EmulatorWindow {
|
||||
std::unique_ptr<ui::ImmediateDrawer> immediate_drawer_;
|
||||
|
||||
bool emulator_initialized_ = false;
|
||||
std::atomic<bool> disable_hotkeys_ = false;
|
||||
|
||||
std::string base_title_;
|
||||
bool initializing_shader_storage_ = false;
|
||||
|
||||
std::unique_ptr<DisplayConfigDialog> display_config_dialog_;
|
||||
|
||||
// Storing pointers and toggling dialog state is useful for broadcasting
|
||||
// messages back to guest.
|
||||
std::unique_ptr<ProfileConfigDialog> profile_config_dialog_;
|
||||
|
||||
std::vector<RecentTitleEntry> recently_launched_titles_;
|
||||
};
|
||||
|
||||
|
||||
333
src/xenia/app/profile_dialogs.cc
Normal file
333
src/xenia/app/profile_dialogs.cc
Normal file
@@ -0,0 +1,333 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2024 Xenia Canary. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "xenia/app/profile_dialogs.h"
|
||||
#include <algorithm>
|
||||
#include "xenia/app/emulator_window.h"
|
||||
#include "xenia/base/system.h"
|
||||
|
||||
namespace xe {
|
||||
namespace app {
|
||||
|
||||
void CreateProfileDialog::OnDraw(ImGuiIO& io) {
|
||||
auto profile_manager = emulator_window_->emulator()
|
||||
->kernel_state()
|
||||
->xam_state()
|
||||
->profile_manager();
|
||||
|
||||
const auto window_position =
|
||||
ImVec2(GetIO().DisplaySize.x * 0.40f, GetIO().DisplaySize.y * 0.44f);
|
||||
|
||||
ImGui::SetNextWindowPos(window_position, ImGuiCond_FirstUseEver);
|
||||
ImGui::SetNextWindowBgAlpha(1.0f);
|
||||
|
||||
bool dialog_open = true;
|
||||
if (!ImGui::Begin("Create Profile", &dialog_open,
|
||||
ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_AlwaysAutoResize |
|
||||
ImGuiWindowFlags_HorizontalScrollbar)) {
|
||||
ImGui::End();
|
||||
emulator_window_->profile_creation_dialog_.reset();
|
||||
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);
|
||||
|
||||
if (profile_manager->IsGamertagValid(gamertag_string)) {
|
||||
if (ImGui::Button("Create")) {
|
||||
if (profile_manager->CreateProfile(gamertag_string, migration) &&
|
||||
migration) {
|
||||
emulator_window_->emulator()->DataMigration(0xB13EBABEBABEBABE);
|
||||
}
|
||||
std::fill(std::begin(gamertag), std::end(gamertag), '\0');
|
||||
dialog_open = false;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
if (ImGui::Button("Cancel")) {
|
||||
std::fill(std::begin(gamertag), std::end(gamertag), '\0');
|
||||
dialog_open = false;
|
||||
}
|
||||
|
||||
if (!dialog_open) {
|
||||
ImGui::End();
|
||||
emulator_window_->profile_creation_dialog_.reset();
|
||||
return;
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void NoProfileDialog::OnDraw(ImGuiIO& io) {
|
||||
auto profile_manager = emulator_window_->emulator()
|
||||
->kernel_state()
|
||||
->xam_state()
|
||||
->profile_manager();
|
||||
|
||||
if (profile_manager->GetProfilesCount()) {
|
||||
delete this;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto window_position =
|
||||
ImVec2(GetIO().DisplaySize.x * 0.35f, GetIO().DisplaySize.y * 0.4f);
|
||||
|
||||
ImGui::SetNextWindowPos(window_position, ImGuiCond_FirstUseEver);
|
||||
ImGui::SetNextWindowBgAlpha(1.0f);
|
||||
|
||||
bool dialog_open = true;
|
||||
if (!ImGui::Begin("No Profiles Found", &dialog_open,
|
||||
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize |
|
||||
ImGuiWindowFlags_AlwaysAutoResize |
|
||||
ImGuiWindowFlags_HorizontalScrollbar)) {
|
||||
ImGui::End();
|
||||
delete this;
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string message =
|
||||
"There is no profile available! You will not be able to save without "
|
||||
"one.\n\nWould you like to create one?";
|
||||
|
||||
ImGui::TextUnformatted(message.c_str());
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::NewLine();
|
||||
|
||||
const auto content_files = xe::filesystem::ListDirectories(
|
||||
emulator_window_->emulator()->content_root());
|
||||
|
||||
if (content_files.empty()) {
|
||||
if (ImGui::Button("Create Profile") &&
|
||||
!emulator_window_->profile_creation_dialog_) {
|
||||
emulator_window_->profile_creation_dialog_ =
|
||||
std::make_unique<CreateProfileDialog>(
|
||||
emulator_window_->imgui_drawer(), emulator_window_);
|
||||
}
|
||||
} else {
|
||||
if (ImGui::Button("Create profile & migrate data") &&
|
||||
!emulator_window_->profile_creation_dialog_) {
|
||||
emulator_window_->profile_creation_dialog_ =
|
||||
std::make_unique<CreateProfileDialog>(
|
||||
emulator_window_->imgui_drawer(), emulator_window_, true);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Open profile menu")) {
|
||||
emulator_window_->ToggleProfilesConfigDialog();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Close") || !dialog_open) {
|
||||
emulator_window_->SetHotkeysState(true);
|
||||
ImGui::End();
|
||||
delete this;
|
||||
return;
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void ProfileConfigDialog::OnDraw(ImGuiIO& io) {
|
||||
if (!emulator_window_->emulator() ||
|
||||
!emulator_window_->emulator()->kernel_state() ||
|
||||
!emulator_window_->emulator()->kernel_state()->xam_state()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto profile_manager = emulator_window_->emulator()
|
||||
->kernel_state()
|
||||
->xam_state()
|
||||
->profile_manager();
|
||||
if (!profile_manager) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto profiles = profile_manager->GetProfiles();
|
||||
|
||||
ImGui::SetNextWindowPos(ImVec2(40, 40), ImGuiCond_FirstUseEver);
|
||||
ImGui::SetNextWindowBgAlpha(0.8f);
|
||||
|
||||
bool dialog_open = true;
|
||||
if (!ImGui::Begin("Profiles Menu", &dialog_open,
|
||||
ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_AlwaysAutoResize |
|
||||
ImGuiWindowFlags_HorizontalScrollbar)) {
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
||||
if (profiles->empty()) {
|
||||
ImGui::TextUnformatted("No profiles found!");
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
for (auto& [xuid, account] : *profiles) {
|
||||
ImGui::PushID(static_cast<int>(xuid));
|
||||
|
||||
const uint8_t user_index =
|
||||
profile_manager->GetUserIndexAssignedToProfile(xuid);
|
||||
|
||||
DrawProfileContent(xuid, user_index, &account);
|
||||
|
||||
ImGui::PopID();
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
if (ImGui::Button("Create Profile") &&
|
||||
!emulator_window_->profile_creation_dialog_) {
|
||||
emulator_window_->profile_creation_dialog_ =
|
||||
std::make_unique<CreateProfileDialog>(emulator_window_->imgui_drawer(),
|
||||
emulator_window_);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
||||
if (!dialog_open) {
|
||||
emulator_window_->ToggleProfilesConfigDialog();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool ProfileConfigDialog::DrawProfileContent(const uint64_t xuid,
|
||||
const uint8_t user_index,
|
||||
const X_XAMACCOUNTINFO* account) {
|
||||
auto profile_manager = emulator_window_->emulator()
|
||||
->kernel_state()
|
||||
->xam_state()
|
||||
->profile_manager();
|
||||
|
||||
const float default_image_size = 75.0f;
|
||||
auto position = ImGui::GetCursorPos();
|
||||
const float selectable_height =
|
||||
ImGui::GetTextLineHeight() *
|
||||
5; // 3 is for amount of lines of text behind image/object.
|
||||
const auto font = emulator_window_->imgui_drawer()->GetIO().Fonts->Fonts[0];
|
||||
|
||||
const auto text_size = font->CalcTextSizeA(
|
||||
font->FontSize, FLT_MAX, -1.0f,
|
||||
fmt::format("XUID: {:016X}\n", 0xB13EBABEBABEBABE).c_str());
|
||||
|
||||
const auto image_scale = selectable_height / default_image_size;
|
||||
const auto image_size = ImVec2(default_image_size * image_scale,
|
||||
default_image_size * image_scale);
|
||||
// This includes 10% to include empty spaces between border and elements.
|
||||
auto selectable_region_size =
|
||||
ImVec2((image_size.x + text_size.x) * 1.10f, selectable_height);
|
||||
|
||||
if (ImGui::Selectable("##Selectable", selected_xuid_ == xuid,
|
||||
ImGuiSelectableFlags_SpanAllColumns,
|
||||
selectable_region_size)) {
|
||||
selected_xuid_ = xuid;
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopupContextItem("Profile Menu")) {
|
||||
if (user_index == static_cast<uint8_t>(-1)) {
|
||||
if (ImGui::MenuItem("Login")) {
|
||||
profile_manager->Login(xuid);
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Login to slot:")) {
|
||||
for (uint8_t i = 0; i < XUserMaxUserCount; i++) {
|
||||
if (ImGui::MenuItem(fmt::format("slot {}", i).c_str())) {
|
||||
profile_manager->Login(xuid, i);
|
||||
}
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
} else {
|
||||
if (ImGui::MenuItem("Logout")) {
|
||||
profile_manager->Logout(user_index);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::MenuItem("Modify (unsupported)");
|
||||
ImGui::MenuItem("Show Achievements (unsupported)");
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPos(position);
|
||||
|
||||
// In the future it can be replaced with profile icon.
|
||||
ImGui::Image(user_index < XUserMaxUserCount
|
||||
? imgui_drawer()->GetNotificationIcon(user_index)
|
||||
: nullptr,
|
||||
ImVec2(default_image_size * image_scale,
|
||||
default_image_size * image_scale));
|
||||
|
||||
ImGui::SameLine();
|
||||
position = ImGui::GetCursorPos();
|
||||
ImGui::TextUnformatted(
|
||||
fmt::format("User: {}\n", account->GetGamertagString()).c_str());
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPos(position);
|
||||
ImGui::SetCursorPosY(position.y + ImGui::GetTextLineHeight());
|
||||
ImGui::TextUnformatted(fmt::format("XUID: {:016X}\n", xuid).c_str());
|
||||
|
||||
if (user_index != static_cast<uint8_t>(-1)) {
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPos(position);
|
||||
ImGui::SetCursorPosY(position.y + 2 * ImGui::GetTextLineHeight());
|
||||
ImGui::TextUnformatted(
|
||||
fmt::format("Assigned to slot: {}\n", user_index).c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
} // namespace xe
|
||||
76
src/xenia/app/profile_dialogs.h
Normal file
76
src/xenia/app/profile_dialogs.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2024 Xenia Canary. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_APP_PROFILE_DIALOGS_H_
|
||||
#define XENIA_APP_PROFILE_DIALOGS_H_
|
||||
|
||||
#include "xenia/ui/imgui_dialog.h"
|
||||
#include "xenia/ui/imgui_drawer.h"
|
||||
#include "xenia/xbox.h"
|
||||
|
||||
namespace xe {
|
||||
namespace app {
|
||||
|
||||
class EmulatorWindow;
|
||||
|
||||
class CreateProfileDialog final : public ui::ImGuiDialog {
|
||||
public:
|
||||
CreateProfileDialog(ui::ImGuiDrawer* imgui_drawer,
|
||||
EmulatorWindow* emulator_window,
|
||||
bool with_migration = false)
|
||||
: ui::ImGuiDialog(imgui_drawer),
|
||||
emulator_window_(emulator_window),
|
||||
migration(with_migration) {
|
||||
memset(gamertag, 0, sizeof(gamertag));
|
||||
}
|
||||
|
||||
protected:
|
||||
void OnDraw(ImGuiIO& io) override;
|
||||
|
||||
bool migration = false;
|
||||
char gamertag[16] = "";
|
||||
EmulatorWindow* emulator_window_;
|
||||
};
|
||||
|
||||
class NoProfileDialog final : public ui::ImGuiDialog {
|
||||
public:
|
||||
NoProfileDialog(ui::ImGuiDrawer* imgui_drawer,
|
||||
EmulatorWindow* emulator_window)
|
||||
: ui::ImGuiDialog(imgui_drawer), emulator_window_(emulator_window) {}
|
||||
|
||||
protected:
|
||||
void OnDraw(ImGuiIO& io) override;
|
||||
|
||||
EmulatorWindow* emulator_window_;
|
||||
};
|
||||
|
||||
class ProfileConfigDialog final : public ui::ImGuiDialog {
|
||||
public:
|
||||
ProfileConfigDialog(ui::ImGuiDrawer* imgui_drawer,
|
||||
EmulatorWindow* emulator_window)
|
||||
: ui::ImGuiDialog(imgui_drawer), emulator_window_(emulator_window) {
|
||||
memset(gamertag, 0, sizeof(gamertag));
|
||||
}
|
||||
|
||||
protected:
|
||||
void OnDraw(ImGuiIO& io) override;
|
||||
|
||||
private:
|
||||
bool DrawProfileContent(const uint64_t xuid, const uint8_t user_index,
|
||||
const X_XAMACCOUNTINFO* account);
|
||||
|
||||
uint64_t selected_xuid_ = 0;
|
||||
char gamertag[16] = "";
|
||||
EmulatorWindow* emulator_window_;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
} // namespace xe
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user