mirror of
https://github.com/RPCSX/rpcsx.git
synced 2025-12-06 07:12:14 +01:00
* Add PUP loader * Add .tar loader and update .pup loader * Add extract method + offset to TAR loader Also adds error checking + operator bool overload * Add firmware decryption keys to key vault * Initial seperation of SELFDecrypter This seperates SELFDecrypter into itself and SCEDecrypter. SCEDecrypter contains the logic to decrypt any file with an SCE Header. SELFDecrypter inherits from SCEDecrypter and contains the code specifically to do with ELF. DecryptData could be deduplicated more. * Add "Install Firmware" option to tools menu * SCEDecrypter: put each segment in own file Also, const-correctness, adjusted buffer size and better error handling * More SELFDecrypter refactoring * Compile fix * Add messageboxes to firmware install * Add progress bar to firmware install
673 lines
19 KiB
C++
673 lines
19 KiB
C++
#include "stdafx.h"
|
|
#include "stdafx_gui.h"
|
|
#include "rpcs3.h"
|
|
#include "MainFrame.h"
|
|
|
|
#include "Emu/Memory/Memory.h"
|
|
#include "Emu/System.h"
|
|
|
|
#include "Gui/PADManager.h"
|
|
#include "Gui/AboutDialog.h"
|
|
#include "Gui/GameViewer.h"
|
|
#include "Gui/AutoPauseManager.h"
|
|
#include "Gui/SaveDataUtility.h"
|
|
#include "Gui/KernelExplorer.h"
|
|
#include "Gui/MemoryViewer.h"
|
|
#include "Gui/RSXDebugger.h"
|
|
#include "Gui/SettingsDialog.h"
|
|
#include "Gui/MemoryStringSearcher.h"
|
|
#include "Gui/CgDisasm.h"
|
|
|
|
#include "Crypto/unpkg.h"
|
|
#include "Crypto/unself.h"
|
|
|
|
#include "Loader/PUP.h"
|
|
#include "Loader/TAR.h"
|
|
|
|
#include "Utilities/Thread.h"
|
|
#include "Utilities/StrUtil.h"
|
|
|
|
#include <thread>
|
|
|
|
#ifndef _WIN32
|
|
#include "frame_icon.xpm"
|
|
#endif
|
|
|
|
enum IDs
|
|
{
|
|
id_boot_elf = 0x555,
|
|
id_boot_game,
|
|
id_boot_install_pkg,
|
|
id_boot_exit,
|
|
id_sys_pause,
|
|
id_sys_stop,
|
|
id_sys_send_open_menu,
|
|
id_sys_send_exit,
|
|
id_config_emu,
|
|
id_config_pad,
|
|
id_config_vfs_manager,
|
|
id_config_vhdd_manager,
|
|
id_config_autopause_manager,
|
|
id_config_savedata_manager,
|
|
id_tools_compiler,
|
|
id_tools_kernel_explorer,
|
|
id_tools_memory_viewer,
|
|
id_tools_rsx_debugger,
|
|
id_tools_string_search,
|
|
id_tools_decrypt_sprx_libraries,
|
|
id_tools_install_firmware,
|
|
id_tools_cg_disasm,
|
|
id_help_about,
|
|
id_update_dbg
|
|
};
|
|
|
|
wxString GetPaneName()
|
|
{
|
|
static int pane_num = 0;
|
|
return wxString::Format("Pane_%d", pane_num++);
|
|
}
|
|
|
|
MainFrame::MainFrame()
|
|
: FrameBase(nullptr, wxID_ANY, "", "MainFrame", wxSize(900, 600))
|
|
, m_timer(this, id_update_dbg)
|
|
, m_aui_mgr(this)
|
|
, m_sys_menu_opened(false)
|
|
{
|
|
|
|
SetLabel("RPCS3 v" + rpcs3::version.to_string());
|
|
|
|
wxMenuBar* menubar = new wxMenuBar();
|
|
|
|
wxMenu* menu_boot = new wxMenu();
|
|
menubar->Append(menu_boot, "&Boot");
|
|
menu_boot->Append(id_boot_elf, "Boot &ELF / SELF file");
|
|
menu_boot->Append(id_boot_game, "Boot &game");
|
|
menu_boot->AppendSeparator();
|
|
menu_boot->Append(id_boot_install_pkg, "&Install PKG");
|
|
menu_boot->AppendSeparator();
|
|
menu_boot->Append(id_boot_exit, "&Exit");
|
|
|
|
wxMenu* menu_sys = new wxMenu();
|
|
menubar->Append(menu_sys, "&System");
|
|
menu_sys->Append(id_sys_pause, "&Pause")->Enable(false);
|
|
menu_sys->Append(id_sys_stop, "&Stop\tCtrl + S")->Enable(false);
|
|
menu_sys->AppendSeparator();
|
|
menu_sys->Append(id_sys_send_open_menu, "Send &open system menu cmd")->Enable(false);
|
|
menu_sys->Append(id_sys_send_exit, "Send &exit cmd")->Enable(false);
|
|
|
|
wxMenu* menu_conf = new wxMenu();
|
|
menubar->Append(menu_conf, "&Config");
|
|
menu_conf->Append(id_config_emu, "&Settings");
|
|
menu_conf->Append(id_config_pad, "&PAD Settings");
|
|
menu_conf->AppendSeparator();
|
|
menu_conf->Append(id_config_autopause_manager, "&Auto Pause Settings");
|
|
//menu_conf->AppendSeparator();
|
|
//menu_conf->Append(id_config_vfs_manager, "Virtual &File System Manager");
|
|
//menu_conf->Append(id_config_vhdd_manager, "Virtual &HDD Manager");
|
|
//menu_conf->Append(id_config_savedata_manager, "Save &Data Utility");
|
|
|
|
wxMenu* menu_tools = new wxMenu();
|
|
menubar->Append(menu_tools, "&Tools");
|
|
//menu_tools->Append(id_tools_compiler, "&ELF Compiler");
|
|
menu_tools->Append(id_tools_cg_disasm, "&Cg Disasm")->Enable();
|
|
menu_tools->Append(id_tools_kernel_explorer, "&Kernel Explorer")->Enable(false);
|
|
menu_tools->Append(id_tools_memory_viewer, "&Memory Viewer")->Enable(false);
|
|
menu_tools->Append(id_tools_rsx_debugger, "&RSX Debugger")->Enable(false);
|
|
menu_tools->Append(id_tools_string_search, "&String Search")->Enable(false);
|
|
menu_tools->AppendSeparator();
|
|
menu_tools->Append(id_tools_decrypt_sprx_libraries, "&Decrypt SPRX libraries");
|
|
menu_tools->Append(id_tools_install_firmware, "&Install Firmware");
|
|
|
|
wxMenu* menu_help = new wxMenu();
|
|
menubar->Append(menu_help, "&Help");
|
|
menu_help->Append(id_help_about, "&About...");
|
|
|
|
SetMenuBar(menubar);
|
|
SetIcon(wxICON(frame_icon));
|
|
|
|
// Panels
|
|
m_log_frame = new LogFrame(this);
|
|
m_game_viewer = new GameViewer(this);
|
|
m_debugger_frame = new DebuggerPanel(this);
|
|
|
|
AddPane(m_game_viewer, "Game List", wxAUI_DOCK_CENTRE);
|
|
AddPane(m_log_frame, "Log", wxAUI_DOCK_BOTTOM);
|
|
AddPane(m_debugger_frame, "Debugger", wxAUI_DOCK_RIGHT);
|
|
|
|
// Events
|
|
Bind(wxEVT_MENU, &MainFrame::BootElf, this, id_boot_elf);
|
|
Bind(wxEVT_MENU, &MainFrame::BootGame, this, id_boot_game);
|
|
Bind(wxEVT_MENU, &MainFrame::InstallPkg, this, id_boot_install_pkg);
|
|
Bind(wxEVT_MENU, [](wxCommandEvent&){ wxGetApp().Exit(); }, id_boot_exit);
|
|
|
|
Bind(wxEVT_MENU, &MainFrame::Pause, this, id_sys_pause);
|
|
Bind(wxEVT_MENU, &MainFrame::Stop, this, id_sys_stop);
|
|
Bind(wxEVT_MENU, &MainFrame::SendOpenCloseSysMenu, this, id_sys_send_open_menu);
|
|
Bind(wxEVT_MENU, &MainFrame::SendExit, this, id_sys_send_exit);
|
|
|
|
Bind(wxEVT_MENU, &MainFrame::Config, this, id_config_emu);
|
|
Bind(wxEVT_MENU, &MainFrame::ConfigPad, this, id_config_pad);
|
|
Bind(wxEVT_MENU, &MainFrame::ConfigAutoPause, this, id_config_autopause_manager);
|
|
Bind(wxEVT_MENU, &MainFrame::ConfigVFS, this, id_config_vfs_manager);
|
|
Bind(wxEVT_MENU, &MainFrame::ConfigVHDD, this, id_config_vhdd_manager);
|
|
Bind(wxEVT_MENU, &MainFrame::ConfigSaveData, this, id_config_savedata_manager);
|
|
Bind(wxEVT_MENU, &MainFrame::DecryptSPRXLibraries, this, id_tools_decrypt_sprx_libraries);
|
|
Bind(wxEVT_MENU, &MainFrame::InstallFirmware, this, id_tools_install_firmware);
|
|
|
|
|
|
Bind(wxEVT_MENU, &MainFrame::OpenELFCompiler, this, id_tools_compiler);
|
|
Bind(wxEVT_MENU, &MainFrame::OpenKernelExplorer, this, id_tools_kernel_explorer);
|
|
Bind(wxEVT_MENU, &MainFrame::OpenMemoryViewer, this, id_tools_memory_viewer);
|
|
Bind(wxEVT_MENU, &MainFrame::OpenRSXDebugger, this, id_tools_rsx_debugger);
|
|
Bind(wxEVT_MENU, &MainFrame::OpenStringSearch, this, id_tools_string_search);
|
|
Bind(wxEVT_MENU, &MainFrame::OpenCgDisasm, this, id_tools_cg_disasm);
|
|
|
|
Bind(wxEVT_MENU, &MainFrame::AboutDialogHandler, this, id_help_about);
|
|
|
|
Bind(wxEVT_MENU, &MainFrame::UpdateUI, this, id_update_dbg);
|
|
Bind(wxEVT_TIMER, &MainFrame::UpdateUI, this, id_update_dbg);
|
|
Bind(wxEVT_CLOSE_WINDOW, [&](wxCloseEvent&)
|
|
{
|
|
DoSettings(false);
|
|
TheApp->Exit();
|
|
});
|
|
|
|
wxGetApp().Bind(wxEVT_KEY_DOWN, &MainFrame::OnKeyDown, this);
|
|
|
|
// Check for updates every ~10 ms
|
|
m_timer.Start(10);
|
|
}
|
|
|
|
MainFrame::~MainFrame()
|
|
{
|
|
m_aui_mgr.UnInit();
|
|
}
|
|
|
|
void MainFrame::AddPane(wxWindow* wind, const wxString& caption, int flags)
|
|
{
|
|
wind->SetSize(-1, 300);
|
|
m_aui_mgr.AddPane(wind, wxAuiPaneInfo().Name(GetPaneName()).Caption(caption).Direction(flags).CloseButton(false).MaximizeButton());
|
|
}
|
|
|
|
void MainFrame::DoSettings(bool load)
|
|
{
|
|
auto&& cfg = g_gui_cfg[ini_name]["aui"];
|
|
|
|
if (load)
|
|
{
|
|
const auto& perspective = fmt::FromUTF8(cfg.Scalar());
|
|
|
|
m_aui_mgr.LoadPerspective(perspective.empty() ? m_aui_mgr.SavePerspective() : perspective);
|
|
}
|
|
else
|
|
{
|
|
cfg = fmt::ToUTF8(m_aui_mgr.SavePerspective());
|
|
save_gui_cfg();
|
|
}
|
|
}
|
|
|
|
void MainFrame::BootGame(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
bool stopped = false;
|
|
|
|
if(Emu.IsRunning())
|
|
{
|
|
Emu.Pause();
|
|
stopped = true;
|
|
}
|
|
|
|
wxDirDialog ctrl(this, L"Select game folder", wxEmptyString);
|
|
|
|
if(ctrl.ShowModal() == wxID_CANCEL)
|
|
{
|
|
if(stopped) Emu.Resume();
|
|
return;
|
|
}
|
|
|
|
Emu.Stop();
|
|
|
|
if(!Emu.BootGame(ctrl.GetPath().ToStdString()))
|
|
{
|
|
LOG_ERROR(GENERAL, "PS3 executable not found in selected folder (%s)", fmt::ToUTF8(ctrl.GetPath())); // passing std::string (test)
|
|
}
|
|
}
|
|
|
|
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::BootElf(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
bool stopped = false;
|
|
|
|
if(Emu.IsRunning())
|
|
{
|
|
Emu.Pause();
|
|
stopped = true;
|
|
}
|
|
|
|
wxFileDialog ctrl(this, L"Select (S)ELF", wxEmptyString, wxEmptyString,
|
|
"(S)ELF files (*BOOT.BIN;*.elf;*.self)|*BOOT.BIN;*.elf;*.self"
|
|
"|ELF files (BOOT.BIN;*.elf)|BOOT.BIN;*.elf"
|
|
"|SELF files (EBOOT.BIN;*.self)|EBOOT.BIN;*.self"
|
|
"|BOOT files (*BOOT.BIN)|*BOOT.BIN"
|
|
"|BIN files (*.bin)|*.bin"
|
|
"|All files (*.*)|*.*",
|
|
wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
|
|
|
if(ctrl.ShowModal() == wxID_CANCEL)
|
|
{
|
|
if(stopped) Emu.Resume();
|
|
return;
|
|
}
|
|
|
|
LOG_NOTICE(LOADER, "(S)ELF: booting...");
|
|
|
|
Emu.Stop();
|
|
Emu.SetPath(fmt::ToUTF8(ctrl.GetPath()));
|
|
Emu.Load();
|
|
|
|
LOG_SUCCESS(LOADER, "(S)ELF: boot done.");
|
|
}
|
|
|
|
void MainFrame::DecryptSPRXLibraries(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxFileDialog ctrl(this, L"Select SPRX files", wxEmptyString, wxEmptyString,
|
|
"SPRX files (*.sprx)|*sprx",
|
|
wxFD_OPEN | wxFD_MULTIPLE);
|
|
|
|
if (ctrl.ShowModal() == wxID_CANCEL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
wxArrayString modules;
|
|
ctrl.GetPaths(modules);
|
|
|
|
LOG_NOTICE(GENERAL, "Decrypting SPRX libraries...");
|
|
|
|
for (const wxString& module : modules)
|
|
{
|
|
std::string prx_path = fmt::ToUTF8(module);
|
|
const std::string& prx_dir = fs::get_parent_dir(prx_path);
|
|
|
|
fs::file elf_file(prx_path);
|
|
|
|
if (elf_file && elf_file.size() >= 4 && elf_file.read<u32>() == "SCE\0"_u32)
|
|
{
|
|
const std::size_t prx_ext_pos = prx_path.find_last_of('.');
|
|
const std::string& prx_ext = fmt::to_upper(prx_path.substr(prx_ext_pos != -1 ? prx_ext_pos : prx_path.size()));
|
|
const std::string& prx_name = prx_path.substr(prx_dir.size());
|
|
|
|
elf_file = decrypt_self(std::move(elf_file));
|
|
|
|
prx_path.erase(prx_path.size() - 4, 1); // change *.sprx to *.prx
|
|
|
|
if (elf_file)
|
|
{
|
|
if (fs::file new_file{prx_path, fs::rewrite})
|
|
{
|
|
new_file.write(elf_file.to_string());
|
|
LOG_SUCCESS(GENERAL, "Decrypted %s", prx_dir + prx_name);
|
|
}
|
|
else
|
|
{
|
|
LOG_ERROR(GENERAL, "Failed to create %s", prx_path);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LOG_ERROR(GENERAL, "Failed to decrypt %s", prx_dir + prx_name);
|
|
}
|
|
}
|
|
}
|
|
|
|
LOG_NOTICE(GENERAL, "Finished decrypting all SPRX libraries.");
|
|
}
|
|
|
|
void MainFrame::InstallFirmware(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxFileDialog ctrl(this, L"Select PS3UPDAT.PUP file", wxEmptyString, wxEmptyString,
|
|
"PS3 update file (PS3UPDAT.PUP)|PS3UPDAT.PUP",
|
|
wxFD_OPEN);
|
|
|
|
if (ctrl.ShowModal() == wxID_CANCEL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
fs::file pup_f(ctrl.GetPath().ToStdString());
|
|
pup_object pup(pup_f);
|
|
if (!pup) {
|
|
LOG_ERROR(GENERAL, "Error while installing firmware: PUP file is invalid.");
|
|
wxMessageBox("Error while installing firmware: PUP file is invalid.", "Failure!", wxOK | wxICON_ERROR, this);
|
|
return;
|
|
}
|
|
|
|
fs::file update_files_f = pup.get_file(0x300);
|
|
tar_object update_files(update_files_f);
|
|
auto updatefilenames = update_files.get_filenames();
|
|
|
|
updatefilenames.erase(std::remove_if(
|
|
updatefilenames.begin(), updatefilenames.end(), [](std::string s) {return s.find("dev_flash_") == std::string::npos; }),
|
|
updatefilenames.end());
|
|
|
|
wxProgressDialog pdlg("Firmware Installer", "Please wait, unpacking...", updatefilenames.size(), this, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
|
|
|
|
// Synchronization variable
|
|
atomic_t<int> progress(0);
|
|
{
|
|
// Run asynchronously
|
|
scope_thread worker("Firmware Installer", [&]
|
|
{
|
|
for (auto updatefilename : updatefilenames)
|
|
{
|
|
if (progress == -1) break;
|
|
|
|
fs::file updatefile = update_files.get_file(updatefilename);
|
|
|
|
SCEDecrypter self_dec(updatefile);
|
|
self_dec.LoadHeaders();
|
|
self_dec.LoadMetadata(SCEPKG_ERK, SCEPKG_RIV);
|
|
self_dec.DecryptData();
|
|
|
|
auto dev_flash_tar_f = self_dec.MakeFile();
|
|
if (dev_flash_tar_f.size() < 3) {
|
|
LOG_ERROR(GENERAL, "Error while installing firmware: PUP contents are invalid.");
|
|
wxMessageBox("Error while installing firmware: PUP contents are invalid.", "Failure!", wxOK | wxICON_ERROR, this);
|
|
progress = -1;
|
|
}
|
|
|
|
tar_object dev_flash_tar(dev_flash_tar_f[2]);
|
|
if (!dev_flash_tar.extract(fs::get_executable_dir()))
|
|
{
|
|
LOG_ERROR(GENERAL, "Error while installing firmware: TAR contents are invalid.");
|
|
wxMessageBox("Error while installing firmware: TAR contents are invalid.", "Failure!", wxOK | wxICON_ERROR, this);
|
|
progress = -1;
|
|
}
|
|
|
|
if(progress >= 0)
|
|
progress += 1;
|
|
}
|
|
});
|
|
|
|
// Wait for the completion
|
|
while (std::this_thread::sleep_for(5ms), std::abs(progress) < pdlg.GetRange())
|
|
{
|
|
// Update progress window
|
|
if (!pdlg.Update(static_cast<int>(progress)))
|
|
{
|
|
// Installation cancelled (signal with negative value)
|
|
progress = -1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
update_files_f.close();
|
|
pup_f.close();
|
|
|
|
if (progress > 0)
|
|
{
|
|
pdlg.Update(pdlg.GetRange());
|
|
std::this_thread::sleep_for(100ms);
|
|
}
|
|
}
|
|
pdlg.Close();
|
|
|
|
if (progress > 0)
|
|
{
|
|
LOG_SUCCESS(GENERAL, "Successfully installed PS3 firmware.");
|
|
wxMessageBox("Successfully installed PS3 firmware and LLE Modules!", "Success!", wxOK, this);
|
|
}
|
|
}
|
|
|
|
void MainFrame::Pause(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
if(Emu.IsReady())
|
|
{
|
|
Emu.Run();
|
|
}
|
|
else if(Emu.IsPaused())
|
|
{
|
|
Emu.Resume();
|
|
}
|
|
else if(Emu.IsRunning())
|
|
{
|
|
Emu.Pause();
|
|
}
|
|
}
|
|
|
|
void MainFrame::Stop(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
Emu.Stop();
|
|
}
|
|
|
|
// This is ugly, but PS3 headers shall not be included there.
|
|
extern void sysutil_send_system_cmd(u64 status, u64 param);
|
|
|
|
void MainFrame::SendExit(wxCommandEvent& event)
|
|
{
|
|
sysutil_send_system_cmd(0x0101 /* CELL_SYSUTIL_REQUEST_EXITGAME */, 0);
|
|
}
|
|
|
|
void MainFrame::SendOpenCloseSysMenu(wxCommandEvent& event)
|
|
{
|
|
sysutil_send_system_cmd(m_sys_menu_opened ? 0x0132 /* CELL_SYSUTIL_SYSTEM_MENU_CLOSE */ : 0x0131 /* CELL_SYSUTIL_SYSTEM_MENU_OPEN */, 0);
|
|
m_sys_menu_opened = !m_sys_menu_opened;
|
|
wxCommandEvent ce;
|
|
UpdateUI(ce);
|
|
}
|
|
|
|
void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
SettingsDialog(this);
|
|
}
|
|
|
|
void MainFrame::ConfigPad(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
PADManager(this).ShowModal();
|
|
}
|
|
|
|
void MainFrame::ConfigVFS(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
//VFSManagerDialog(this).ShowModal();
|
|
}
|
|
|
|
void MainFrame::ConfigVHDD(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
//VHDDManagerDialog(this).ShowModal();
|
|
}
|
|
|
|
void MainFrame::ConfigAutoPause(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
AutoPauseManagerDialog(this).ShowModal();
|
|
}
|
|
|
|
void MainFrame::ConfigSaveData(wxCommandEvent& event)
|
|
{
|
|
SaveDataListDialog(this, true).ShowModal();
|
|
}
|
|
|
|
void MainFrame::OpenELFCompiler(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
//(new CompilerELF(this))->Show();
|
|
}
|
|
|
|
void MainFrame::OpenKernelExplorer(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
(new KernelExplorer(this))->Show();
|
|
}
|
|
|
|
void MainFrame::OpenMemoryViewer(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
(new MemoryViewerPanel(this))->Show();
|
|
}
|
|
|
|
void MainFrame::OpenRSXDebugger(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
(new RSXDebugger(this))->Show();
|
|
}
|
|
|
|
void MainFrame::OpenStringSearch(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
(new MemoryStringSearcher(this))->Show();
|
|
}
|
|
|
|
void MainFrame::OpenCgDisasm(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
(new CgDisasm(this))->Show();
|
|
}
|
|
|
|
void MainFrame::AboutDialogHandler(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
AboutDialog(this).ShowModal();
|
|
}
|
|
|
|
void MainFrame::UpdateUI(wxEvent& event)
|
|
{
|
|
const bool is_running = Emu.IsRunning();
|
|
const bool is_stopped = Emu.IsStopped();
|
|
const bool is_ready = Emu.IsReady();
|
|
|
|
// Update menu items based on the state of the emulator
|
|
wxMenuBar& menubar( *GetMenuBar() );
|
|
|
|
// Emulation
|
|
wxMenuItem& pause = *menubar.FindItem(id_sys_pause);
|
|
wxMenuItem& stop = *menubar.FindItem(id_sys_stop);
|
|
pause.SetItemLabel(is_running ? "&Pause\tCtrl + P" : is_ready ? "&Start\tCtrl + E" : "&Resume\tCtrl + E");
|
|
pause.Enable(!is_stopped);
|
|
stop.Enable(!is_stopped);
|
|
|
|
// PS3 Commands
|
|
wxMenuItem& send_exit = *menubar.FindItem(id_sys_send_exit);
|
|
wxMenuItem& send_open_menu = *menubar.FindItem(id_sys_send_open_menu);
|
|
bool enable_commands = !is_stopped;
|
|
send_open_menu.SetItemLabel(wxString::Format("Send &%s system menu cmd", (m_sys_menu_opened ? "close" : "open")));
|
|
send_open_menu.Enable(enable_commands);
|
|
send_exit.Enable(enable_commands);
|
|
|
|
// Tools
|
|
wxMenuItem& kernel_explorer = *menubar.FindItem(id_tools_kernel_explorer);
|
|
wxMenuItem& memory_viewer = *menubar.FindItem(id_tools_memory_viewer);
|
|
wxMenuItem& rsx_debugger = *menubar.FindItem(id_tools_rsx_debugger);
|
|
wxMenuItem& string_search = *menubar.FindItem(id_tools_string_search);
|
|
kernel_explorer.Enable(!is_stopped);
|
|
memory_viewer.Enable(!is_stopped);
|
|
rsx_debugger.Enable(!is_stopped);
|
|
string_search.Enable(!is_stopped);
|
|
|
|
// Debugger
|
|
m_debugger_frame->UpdateUI();
|
|
|
|
// Logs
|
|
m_log_frame->UpdateUI();
|
|
}
|
|
|
|
void MainFrame::OnKeyDown(wxKeyEvent& event)
|
|
{
|
|
if(wxGetActiveWindow() /*== this*/ && event.ControlDown())
|
|
{
|
|
switch(event.GetKeyCode())
|
|
{
|
|
case 'E': case 'e': if(Emu.IsPaused()) Emu.Resume(); else if(Emu.IsReady()) Emu.Run(); return;
|
|
case 'P': case 'p': if(Emu.IsRunning()) Emu.Pause(); return;
|
|
case 'S': case 's': if(!Emu.IsStopped()) Emu.Stop(); return;
|
|
case 'R': case 'r': if(!Emu.GetPath().empty()) {Emu.Stop(); Emu.Run();} return;
|
|
}
|
|
}
|
|
|
|
event.Skip();
|
|
}
|