void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event)) { bool stopped = false; if(Emu.IsRunning()) { Emu.Pause(); stopped = true; } wxFileDialog ctrl (this, L"Select PKG", wxEmptyString, wxEmptyString, "PKG files (*.pkg)|*.pkg|All files (*.*)|*.*", wxFD_OPEN | wxFD_FILE_MUST_EXIST); if(ctrl.ShowModal() == wxID_CANCEL) { if(stopped) Emu.Resume(); return; } Emu.Stop(); // Open and install PKG file std::string filePath = ctrl.GetPath().ToStdString(); rFile pkg_f(filePath, rFile::read); // TODO: Use VFS to install PKG files if (pkg_f.IsOpened()) { PKGLoader pkg(pkg_f); pkg.Install("/dev_hdd0/game/"); pkg.Close(); // Refresh game list m_game_viewer->Refresh(); } }
void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event)) { bool stopped = false; if(Emu.IsRunning()) { Emu.Pause(); stopped = true; } wxFileDialog ctrl(this, L"Select PKG", wxEmptyString, wxEmptyString, "PKG files (*.pkg)|*.pkg|All files (*.*)|*.*", wxFD_OPEN | wxFD_FILE_MUST_EXIST); if(ctrl.ShowModal() == wxID_CANCEL) { if(stopped) Emu.Resume(); return; } Emu.Stop(); // Open and install PKG file fs::file pkg_f(ctrl.GetPath().ToStdString(), fom::read); if (pkg_f) { Emu.GetVFS().Init("/"); std::string local_path; Emu.GetVFS().GetDevice("/dev_hdd0/game/", local_path); PKGLoader::Install(pkg_f, local_path + "/"); // Refresh game list m_game_viewer->Refresh(); } }
void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event)) { const bool paused = Emu.Pause(); wxFileDialog ctrl(this, L"Select PKG", wxEmptyString, wxEmptyString, "PKG files (*.pkg)|*.pkg|All files (*.*)|*.*", wxFD_OPEN | wxFD_FILE_MUST_EXIST); if (ctrl.ShowModal() == wxID_CANCEL) { if (paused) Emu.Resume(); return; } Emu.Stop(); // Open PKG file fs::file pkg_f(ctrl.GetPath().ToStdString()); if (!pkg_f || pkg_f.size() < 64) { LOG_ERROR(LOADER, "PKG: Failed to open %s", ctrl.GetPath().ToStdString()); return; } // Get title ID std::vector<char> title_id(9); pkg_f.seek(55); pkg_f.read(title_id); pkg_f.seek(0); // Get full path const auto& local_path = Emu.GetGameDir() + std::string(std::begin(title_id), std::end(title_id)); if (!fs::create_dir(local_path)) { if (fs::is_dir(local_path)) { if (wxMessageDialog(this, "Another installation found. Do you want to overwrite it?", "PKG Decrypter / Installer", wxYES_NO | wxCENTRE).ShowModal() != wxID_YES) { LOG_ERROR(LOADER, "PKG: Cancelled installation to existing directory %s", local_path); return; } } else { LOG_ERROR(LOADER, "PKG: Could not create the installation directory %s", local_path); return; } } wxProgressDialog pdlg("PKG Installer", "Please wait, unpacking...", 1000, this, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT); // Synchronization variable atomic_t<double> progress(0.); { // Run PKG unpacking asynchronously scope_thread worker("PKG Installer", [&] { if (pkg_install(pkg_f, local_path + '/', progress)) { progress = 1.; return_; } // TODO: Ask user to delete files on cancellation/failure? progress = -1.; }); // Wait for the completion while (std::this_thread::sleep_for(5ms), std::abs(progress) < 1.) { // Update progress window if (!pdlg.Update(static_cast<int>(progress * pdlg.GetRange()))) { // Installation cancelled (signal with negative value) progress -= 1.; break; } } if (progress > 0.) { pdlg.Update(pdlg.GetRange()); std::this_thread::sleep_for(100ms); } } pdlg.Close(); if (progress >= 1.) { // Refresh game list m_game_viewer->Refresh(); } }
void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event)) { const bool was_running = Emu.Pause(); wxFileDialog ctrl(this, L"Select PKG", wxEmptyString, wxEmptyString, "PKG files (*.pkg)|*.pkg|All files (*.*)|*.*", wxFD_OPEN | wxFD_FILE_MUST_EXIST); if (ctrl.ShowModal() == wxID_CANCEL) { if (was_running) Emu.Resume(); return; } Emu.Stop(); Emu.GetVFS().Init("/"); std::string local_path; Emu.GetVFS().GetDevice("/dev_hdd0/game/", local_path); // Open PKG file fs::file pkg_f(ctrl.GetPath().ToStdString()); // Open file mapping (test) fs::file_ptr pkg_ptr(pkg_f); if (!pkg_f || !pkg_ptr) { LOG_ERROR(LOADER, "PKG: Failed to open %s", ctrl.GetPath().ToStdString()); return; } // Append title ID to the path local_path += '/'; local_path += { pkg_ptr + 55, 9 }; if (!fs::create_dir(local_path)) { if (fs::is_dir(local_path)) { if (wxMessageDialog(this, "Another installation found. Do you want to overwrite it?", "PKG Decrypter / Installer", wxYES_NO | wxCENTRE).ShowModal() != wxID_YES) { LOG_ERROR(LOADER, "PKG: Cancelled installation to existing directory %s", local_path); return; } } else { LOG_ERROR(LOADER, "PKG: Could not create the installation directory %s", local_path); return; } } wxProgressDialog pdlg("PKG Decrypter / Installer", "Please wait, unpacking...", 1000, this, wxPD_AUTO_HIDE | wxPD_APP_MODAL); volatile f64 progress = 0.0; // Run PKG unpacking asynchronously auto result = std::async(std::launch::async, WRAP_EXPR(pkg_install(pkg_f, local_path + "/", progress))); // Wait for the completion while (result.wait_for(15ms) != std::future_status::ready) { // Update progress window pdlg.Update(progress * pdlg.GetRange()); // Update main frame Update(); wxGetApp().ProcessPendingEvents(); } pdlg.Close(); if (result.get()) { LOG_SUCCESS(LOADER, "PKG: Package successfully installed in %s", local_path); // Refresh game list m_game_viewer->Refresh(); } }