From 8197881803443714134eedbf2ff1f1425073b411 Mon Sep 17 00:00:00 2001 From: Gliniak Date: Sat, 19 Apr 2025 21:13:46 +0200 Subject: [PATCH] [UI] Added detailed installation state to "Install Content" option --- src/xenia/app/emulator_window.cc | 17 ++++++++++------- src/xenia/emulator.cc | 10 ++++++++++ src/xenia/emulator.h | 15 ++++++++++++++- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/xenia/app/emulator_window.cc b/src/xenia/app/emulator_window.cc index 15aa29daa..b222f7668 100644 --- a/src/xenia/app/emulator_window.cc +++ b/src/xenia/app/emulator_window.cc @@ -611,14 +611,17 @@ void EmulatorWindow::ContentInstallDialog::OnDraw(ImGuiIO& io) { XContentTypeMap.at(entry.content_type_).c_str()); } - if (entry.installation_result_ != X_ERROR_SUCCESS) { - ImGui::Text("Status: %s (0x%08X)", - entry.installation_error_message_.c_str(), - entry.installation_result_); - } else if (entry.currently_installed_size_ == entry.content_size_ && - entry.installation_result_ == X_ERROR_SUCCESS) { - ImGui::Text("Status: Success"); + std::string result = fmt::format( + "Status: {}", xe::Emulator::installStateStringName[static_cast( + entry.installation_state_)]); + + if (entry.installation_state_ == xe::Emulator::InstallState::failed) { + result += fmt::format(" - {} ({:08X})", + entry.installation_error_message_.c_str(), + entry.installation_result_); } + + ImGui::Text("%s", result.c_str()); ImGui::EndTable(); if (entry.content_size_ > 0) { diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index b5720e562..c5af4e017 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -794,6 +794,7 @@ X_STATUS Emulator::ProcessContentPackageHeader( const auto header = vfs::XContentContainerDevice::ReadContainerHeader(path); if (!header || !header->content_header.is_magic_valid()) { + installation_info.installation_state_ = InstallState::failed; installation_info.installation_result_ = X_STATUS_INVALID_PARAMETER; installation_info.installation_error_message_ = "Invalid Package Type!"; XELOGE("Failed to initialize device"); @@ -828,6 +829,7 @@ X_STATUS Emulator::ProcessContentPackageHeader( installation_info.content_type_ = static_cast(header->content_metadata.content_type); installation_info.content_size_ = header->content_metadata.content_size; + installation_info.installation_state_ = InstallState::pending; installation_info.icon_ = imgui_drawer_->LoadImGuiIcon( std::span(header->content_metadata.title_thumbnail, @@ -837,6 +839,8 @@ X_STATUS Emulator::ProcessContentPackageHeader( X_STATUS Emulator::InstallContentPackage( const std::filesystem::path& path, ContentInstallEntry& installation_info) { + installation_info.installation_state_ = InstallState::preparing; + std::unique_ptr device = vfs::XContentContainerDevice::CreateContentDevice("", path); @@ -854,6 +858,7 @@ X_STATUS Emulator::InstallContentPackage( if (!std::filesystem::exists(content_root())) { const std::error_code ec = xe::filesystem::CreateFolder(content_root()); if (ec) { + installation_info.installation_state_ = InstallState::failed; installation_info.installation_error_message_ = ec.message(); installation_info.installation_result_ = X_STATUS_ACCESS_DENIED; return X_STATUS_ACCESS_DENIED; @@ -862,6 +867,7 @@ X_STATUS Emulator::InstallContentPackage( const auto disk_space = std::filesystem::space(content_root()); if (disk_space.available < installation_info.content_size_ * 1.1f) { + installation_info.installation_state_ = InstallState::failed; installation_info.installation_error_message_ = "Insufficient disk space!"; installation_info.installation_result_ = X_STATUS_DISK_FULL; return X_STATUS_DISK_FULL; @@ -874,6 +880,7 @@ X_STATUS Emulator::InstallContentPackage( std::error_code error_code; std::filesystem::create_directories(installation_path, error_code); if (error_code) { + installation_info.installation_state_ = InstallState::failed; installation_info.installation_error_message_ = "Cannot Create Content Directory!"; installation_info.installation_result_ = error_code.value(); @@ -882,6 +889,7 @@ X_STATUS Emulator::InstallContentPackage( } installation_info.content_size_ = device->data_size(); + installation_info.installation_state_ = InstallState::installing; vfs::VirtualFileSystem::ExtractContentHeader(device.get(), header_path); @@ -889,9 +897,11 @@ X_STATUS Emulator::InstallContentPackage( device.get(), installation_path, installation_info.currently_installed_size_); if (error_code != X_ERROR_SUCCESS) { + installation_info.installation_state_ = InstallState::failed; return error_code; } + installation_info.installation_state_ = InstallState::installed; installation_info.currently_installed_size_ = installation_info.content_size_; kernel_state()->BroadcastNotification(kXNotificationLiveContentInstalled, 0); diff --git a/src/xenia/emulator.h b/src/xenia/emulator.h index c19328c7c..c98440daf 100644 --- a/src/xenia/emulator.h +++ b/src/xenia/emulator.h @@ -235,6 +235,17 @@ class Emulator { X_STATUS LaunchDefaultModule(const std::filesystem::path& path); + enum class InstallState : uint8_t { + preparing, + pending, + installing, + installed, + failed + }; + + constexpr static std::string_view installStateStringName[5] = { + "Preparing", "Pending", "Installing", "Success", "Failed"}; + struct ContentInstallEntry { ContentInstallEntry(std::filesystem::path path) : path_(path) {}; @@ -245,9 +256,11 @@ class Emulator { uint64_t content_size_ = 0; uint64_t currently_installed_size_ = 0; + XContentType content_type_{}; + + InstallState installation_state_{}; X_STATUS installation_result_{}; std::string installation_error_message_{}; - XContentType content_type_{}; std::unique_ptr icon_; };