[APP] Create and Extract Zarchive packages

This commit is contained in:
Adrian
2024-04-10 15:57:15 +01:00
committed by Radosław Gliński
parent 06d7a5f0a3
commit 0fcdc12cb9
7 changed files with 389 additions and 34 deletions

View File

@@ -553,17 +553,26 @@ bool EmulatorWindow::Initialize() {
auto main_menu = MenuItem::Create(MenuItem::Type::kNormal);
auto file_menu = MenuItem::Create(MenuItem::Type::kPopup, "&File");
auto recent_menu = MenuItem::Create(MenuItem::Type::kPopup, "&Open Recent");
auto zar_menu = MenuItem::Create(MenuItem::Type::kPopup, "&Zar Package");
FillRecentlyLaunchedTitlesMenu(recent_menu.get());
{
file_menu->AddChild(
MenuItem::Create(MenuItem::Type::kString, "&Open...", "Ctrl+O",
std::bind(&EmulatorWindow::FileOpen, this)));
file_menu->AddChild(std::move(recent_menu));
file_menu->AddChild(MenuItem::Create(MenuItem::Type::kSeparator));
file_menu->AddChild(
MenuItem::Create(MenuItem::Type::kString, "Install Content...",
std::bind(&EmulatorWindow::InstallContent, this)));
zar_menu->AddChild(
MenuItem::Create(MenuItem::Type::kString, "Create",
std::bind(&EmulatorWindow::CreateZarchive, this)));
zar_menu->AddChild(
MenuItem::Create(MenuItem::Type::kString, "Extract",
std::bind(&EmulatorWindow::ExtractZarchive, this)));
file_menu->AddChild(std::move(zar_menu));
#ifdef DEBUG
file_menu->AddChild(MenuItem::Create(MenuItem::Type::kSeparator));
file_menu->AddChild(
MenuItem::Create(MenuItem::Type::kString, "Close",
std::bind(&EmulatorWindow::FileClose, this)));
@@ -958,20 +967,158 @@ void EmulatorWindow::InstallContent() {
paths = file_picker->selected_files();
}
if (!paths.empty()) {
for (auto path : paths) {
// Normalize the path and make absolute.
auto abs_path = std::filesystem::absolute(path);
auto result = emulator_->InstallContentPackage(abs_path);
if (paths.empty()) {
return;
}
if (result != X_STATUS_SUCCESS) {
XELOGE("Failed to install content! Error code: {:08X}", result);
for (auto path : paths) {
// Normalize the path and make absolute.
auto abs_path = std::filesystem::absolute(path);
auto result = emulator_->InstallContentPackage(abs_path);
xe::ui::ImGuiDialog::ShowMessageBox(
imgui_drawer_.get(), "Failed to install content!",
"Failed to install content!\n\nCheck xenia.log for technical "
"details.");
}
if (result != X_STATUS_SUCCESS) {
XELOGE("Failed to install content! Error code: {:08X}", result);
xe::ui::ImGuiDialog::ShowMessageBox(
imgui_drawer_.get(), "Failed to install content!",
"Failed to install content!\n\nCheck xenia.log for technical "
"details.");
}
}
}
void EmulatorWindow::ExtractZarchive() {
std::vector<std::filesystem::path> zarchive_files;
std::filesystem::path extract_dir;
auto file_picker = xe::ui::FilePicker::Create();
file_picker->set_mode(ui::FilePicker::Mode::kOpen);
file_picker->set_type(ui::FilePicker::Type::kFile);
file_picker->set_multi_selection(true);
file_picker->set_title("Select Zar Package");
file_picker->set_extensions({
{"Zarchive Files (*.zar)", "*.zar"},
});
if (file_picker->Show(window_.get())) {
zarchive_files = file_picker->selected_files();
}
if (zarchive_files.empty()) {
return;
}
file_picker->set_type(ui::FilePicker::Type::kDirectory);
file_picker->set_title("Select Directory to Extract");
if (file_picker->Show(window_.get())) {
extract_dir = file_picker->selected_files().front();
}
if (extract_dir.empty()) {
return;
}
for (auto& zarchive_file_path : zarchive_files) {
// Normalize the path and make absolute.
auto abs_path = std::filesystem::absolute(zarchive_file_path);
std::filesystem::path abs_extract_dir;
if (zarchive_files.size() > 1) {
abs_extract_dir =
std::filesystem::absolute((extract_dir / abs_path.stem()));
} else {
abs_extract_dir = std::filesystem::absolute(extract_dir);
}
XELOGI("Extracting zar package: {}\n",
zarchive_file_path.filename().string());
auto result = emulator_->ExtractZarchivePackage(abs_path, abs_extract_dir);
if (result != X_STATUS_SUCCESS) {
std::error_code ec;
// delete incomplete output file
std::filesystem::remove(abs_extract_dir, ec);
XELOGE("Failed to extract Zarchive package.", result);
xe::ui::ImGuiDialog::ShowMessageBox(
imgui_drawer_.get(), "Failed to extract Zarchive package.",
"Failed to extract Zarchive package.");
}
}
}
void EmulatorWindow::CreateZarchive() {
std::vector<std::filesystem::path> content_dirs;
std::filesystem::path zarchive_dir;
auto file_picker = xe::ui::FilePicker::Create();
file_picker->set_mode(ui::FilePicker::Mode::kOpen);
file_picker->set_type(ui::FilePicker::Type::kDirectory);
file_picker->set_multi_selection(true);
file_picker->set_title("Select Contents");
if (file_picker->Show(window_.get())) {
content_dirs = file_picker->selected_files();
}
if (content_dirs.empty()) {
return;
}
if (content_dirs.size() == 1) {
file_picker->set_mode(ui::FilePicker::Mode::kSave);
file_picker->set_type(ui::FilePicker::Type::kFile);
file_picker->set_multi_selection(false);
file_picker->set_file_name(content_dirs.front().stem().string());
file_picker->set_default_extension("zar");
file_picker->set_title("Zarchive File");
file_picker->set_extensions({
{"Zarchive File (*.zar)", "*.zar"},
});
} else {
file_picker->set_title("Output Directory");
}
if (file_picker->Show(window_.get())) {
zarchive_dir = file_picker->selected_files().front();
}
if (zarchive_dir.empty()) {
return;
}
for (auto& content_path : content_dirs) {
// Normalize the path and make absolute.
auto abs_content_dir = std::filesystem::absolute(content_path);
std::filesystem::path abs_zarchive_file;
if (content_dirs.size() > 1) {
abs_zarchive_file = std::filesystem::absolute(
(zarchive_dir / abs_content_dir.stem()).replace_extension("zar"));
} else {
abs_zarchive_file = std::filesystem::absolute(zarchive_dir);
}
XELOGI("Creating zar package: {}\n", abs_zarchive_file.filename().string());
auto result =
emulator_->CreateZarchivePackage(abs_content_dir, abs_zarchive_file);
if (result != X_ERROR_SUCCESS) {
std::error_code ec;
// delete incomplete output file
std::filesystem::remove(abs_zarchive_file, ec);
XELOGE("Failed to create Zarchive package.", result);
xe::ui::ImGuiDialog::ShowMessageBox(imgui_drawer_.get(),
"Failed to create Zarchive package.",
"Failed to create Zarchive package.");
}
}
}

View File

@@ -206,6 +206,8 @@ class EmulatorWindow {
void FileOpen();
void FileClose();
void InstallContent();
void ExtractZarchive();
void CreateZarchive();
void ShowContentDirectory();
void CpuTimeScalarReset();
void CpuTimeScalarSetHalf();