From 5e1a958ee660b6ba2be6bd803cc3f457d462560d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandro=20S=C3=A1nchez=20Bach?= Date: Sat, 23 Nov 2013 05:47:19 +0100 Subject: [PATCH] New debugging features, cellGame & minor changes Two cellGame functions partially implemented: - cellGameGetParamInt - cellGameGetParamString New debugging features: - Call Stack viewer added - Memory Viewer rewritten (Not finished yet) Modified definition of UNIMPLEMENTED_FUNC to improve compatibility with other compilers: Thanks @krofna Replaced the "Compiler" menu entry with "Tools" and "Memory Viewer" entry added. NOTE: To "quickly" browse the memory using the Memory Viewer you can use the scrollbar. Notice the irony of the word 'quickly' since the memory viewer is actually slow as fuck. I will fix that soon. As you can see, I'd like to add a Raw image viewer in the future in order to "see" textures directly from memory. --- rpcs3/Emu/ARMv7/ARMv7Thread.cpp | 2 +- rpcs3/Emu/CPU/CPUThread.h | 9 + rpcs3/Emu/Cell/PPUInterpreter.h | 2 + rpcs3/Emu/Cell/PPUThread.h | 2 +- rpcs3/Emu/Cell/SPUThread.h | 2 +- rpcs3/Emu/SysCalls/Modules/cellGame.cpp | 117 +++++++++++- rpcs3/Emu/SysCalls/SysCalls.h | 2 +- rpcs3/Gui/InterpreterDisAsm.cpp | 29 ++- rpcs3/Gui/InterpreterDisAsm.h | 2 + rpcs3/Gui/MainFrame.cpp | 19 +- rpcs3/Gui/MainFrame.h | 1 + rpcs3/Gui/MemoryViewer.cpp | 230 ++++++++++++++++++------ rpcs3/Gui/MemoryViewer.h | 33 +++- rpcs3/rpcs3.vcxproj | 1 + rpcs3/rpcs3.vcxproj.filters | 3 + 15 files changed, 376 insertions(+), 78 deletions(-) diff --git a/rpcs3/Emu/ARMv7/ARMv7Thread.cpp b/rpcs3/Emu/ARMv7/ARMv7Thread.cpp index ee0b69a996..577c679ef9 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Thread.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Thread.cpp @@ -39,7 +39,7 @@ void ARMv7Thread::SetArg(const uint pos, const u64 arg) wxString ARMv7Thread::RegsToString() { - wxString result; + wxString result = "Registers:\n=========\n"; for(int i=0; i<15; ++i) { result += wxString::Format("%s\t= 0x%08x\n", g_arm_reg_name[i], GPR[i]); diff --git a/rpcs3/Emu/CPU/CPUThread.h b/rpcs3/Emu/CPU/CPUThread.h index fe171cd220..bc8d4a0cad 100644 --- a/rpcs3/Emu/CPU/CPUThread.h +++ b/rpcs3/Emu/CPU/CPUThread.h @@ -171,6 +171,15 @@ public: virtual void Exec(); void ExecOnce(); + Stack m_call_stack; + wxString CallStackToString() + { + wxString ret = "Call Stack:\n==========\n"; + for(uint i=0; i buf, u32 bufsize) { - UNIMPLEMENTED_FUNC(cellGame); + cellGame.Warning("cellGameGetParamString(id=%d, buf_addr=0x%x, bufsize=%d)", id, buf.GetAddr(), bufsize); + + if(!buf.IsGood()) + return CELL_GAME_ERROR_PARAM; + + // TODO: Locate the PARAM.SFO. The following path is in most cases wrong. + vfsStream* f = Emu.GetVFS().Open("/app_home/PARAM.SFO", vfsRead); + PSFLoader psf(*f); + if(!psf.Load(false)) + return CELL_GAME_ERROR_FAILURE; + psf.Close(); + + switch(id) + { + // WARNING: Is there any difference between all these "CELL_GAME_PARAMID_TITLE*" IDs? + case CELL_GAME_PARAMID_TITLE: + case CELL_GAME_PARAMID_TITLE_DEFAULT: + case CELL_GAME_PARAMID_TITLE_JAPANESE: + case CELL_GAME_PARAMID_TITLE_ENGLISH: + case CELL_GAME_PARAMID_TITLE_FRENCH: + case CELL_GAME_PARAMID_TITLE_SPANISH: + case CELL_GAME_PARAMID_TITLE_GERMAN: + case CELL_GAME_PARAMID_TITLE_ITALIAN: + case CELL_GAME_PARAMID_TITLE_DUTCH: + case CELL_GAME_PARAMID_TITLE_PORTUGUESE: + case CELL_GAME_PARAMID_TITLE_RUSSIAN: + case CELL_GAME_PARAMID_TITLE_KOREAN: + case CELL_GAME_PARAMID_TITLE_CHINESE_T: + case CELL_GAME_PARAMID_TITLE_CHINESE_S: + case CELL_GAME_PARAMID_TITLE_FINNISH: + case CELL_GAME_PARAMID_TITLE_SWEDISH: + case CELL_GAME_PARAMID_TITLE_DANISH: + case CELL_GAME_PARAMID_TITLE_NORWEGIAN: + case CELL_GAME_PARAMID_TITLE_POLISH: + case CELL_GAME_PARAMID_TITLE_PORTUGUESE_BRAZIL: + case CELL_GAME_PARAMID_TITLE_ENGLISH_UK: + Memory.WriteString(buf.GetAddr(), psf.m_info.name.Left(bufsize)); + break; + case CELL_GAME_PARAMID_TITLE_ID: + Memory.WriteString(buf.GetAddr(), psf.m_info.serial.Left(bufsize)); + break; + case CELL_GAME_PARAMID_VERSION: + Memory.WriteString(buf.GetAddr(), psf.m_info.fw.Left(bufsize)); + break; + case CELL_GAME_PARAMID_APP_VER: + Memory.WriteString(buf.GetAddr(), psf.m_info.app_ver.Left(bufsize)); + break; + + default: + return CELL_GAME_ERROR_INVALID_ID; + } + return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index b89954efcd..ea828897e3 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -324,7 +324,7 @@ extern int sys_rsx_device_map(mem32_t a1, mem32_t a2, u32 a3); extern int sys_rsx_device_unmap(); extern int sys_rsx_attribute(); -#define UNIMPLEMENTED_FUNC(module) module.Error("Unimplemented function: "__FUNCTION__) +#define UNIMPLEMENTED_FUNC(module) module.Error("Unimplemented function: %s", __FUNCTION__) #define SC_ARG_0 CPU.GPR[3] #define SC_ARG_1 CPU.GPR[4] diff --git a/rpcs3/Gui/InterpreterDisAsm.cpp b/rpcs3/Gui/InterpreterDisAsm.cpp index 0742d6ee41..cad576da6f 100644 --- a/rpcs3/Gui/InterpreterDisAsm.cpp +++ b/rpcs3/Gui/InterpreterDisAsm.cpp @@ -50,12 +50,20 @@ InterpreterDisAsmFrame::InterpreterDisAsmFrame(wxWindow* parent) m_regs->SetMinSize(wxSize(495, 100)); m_regs->SetEditable(false); - m_list->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL)); - m_regs->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL)); + //Call Stack + m_calls = new wxTextCtrl(this, wxID_ANY, wxEmptyString, + wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_DONTWRAP|wxNO_BORDER|wxTE_RICH2); + m_calls->SetMinSize(wxSize(495, 100)); + m_calls->SetEditable(false); + + m_list ->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL)); + m_regs ->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL)); + m_calls->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL)); wxBoxSizer& s_w_list = *new wxBoxSizer(wxHORIZONTAL); s_w_list.Add(m_list, 2, wxEXPAND | wxLEFT | wxDOWN, 5); s_w_list.Add(m_regs, 1, wxEXPAND | wxRIGHT | wxDOWN, 5); + s_w_list.Add(m_calls,1, wxEXPAND | wxRIGHT | wxDOWN, 5); s_p_main.Add(&s_b_main, 0, wxEXPAND | wxLEFT | wxRIGHT, 5); s_p_main.Add(&s_w_list, 1, wxEXPAND | wxDOWN, 5); @@ -216,6 +224,7 @@ void InterpreterDisAsmFrame::DoUpdate() { Show_PC(wxCommandEvent()); WriteRegs(); + WriteCallStack(); } void InterpreterDisAsmFrame::ShowAddr(const u64 addr) @@ -316,6 +325,22 @@ void InterpreterDisAsmFrame::WriteRegs() m_regs->Thaw(); } +void InterpreterDisAsmFrame::WriteCallStack() +{ + if(!CPU) + { + m_calls->Clear(); + return; + } + + const wxString data = CPU->CallStackToString(); + + m_calls->Freeze(); + m_calls->Clear(); + m_calls->WriteText(data); + m_calls->Thaw(); +} + void InterpreterDisAsmFrame::HandleCommand(wxCommandEvent& event) { CPUThread* thr = (CPUThread*)event.GetClientData(); diff --git a/rpcs3/Gui/InterpreterDisAsm.h b/rpcs3/Gui/InterpreterDisAsm.h index 807212e0e1..3069b5e730 100644 --- a/rpcs3/Gui/InterpreterDisAsm.h +++ b/rpcs3/Gui/InterpreterDisAsm.h @@ -11,6 +11,7 @@ class InterpreterDisAsmFrame : public wxPanel u64 PC; Array remove_markedPC; wxTextCtrl* m_regs; + wxTextCtrl* m_calls; wxButton* m_btn_step; wxButton* m_btn_run; wxButton* m_btn_pause; @@ -34,6 +35,7 @@ public: void DoUpdate(); void ShowAddr(const u64 addr); void WriteRegs(); + void WriteCallStack(); void HandleCommand(wxCommandEvent& event); void OnUpdate(wxCommandEvent& event); diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index 0510470a67..87e1d217e5 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "MainFrame.h" #include "CompilerELF.h" +#include "MemoryViewer.h" #include "git-version.h" #include "Emu/System.h" @@ -31,7 +32,8 @@ enum IDs id_config_emu, id_config_vfs_manager, id_config_vhdd_manager, - id_compiler, + id_tools_compiler, + id_tools_memory_viewer, id_help_about, id_update_dbg, }; @@ -60,13 +62,13 @@ MainFrame::MainFrame() wxMenu& menu_boot(*new wxMenu()); wxMenu& menu_sys(*new wxMenu()); wxMenu& menu_conf(*new wxMenu()); - wxMenu& menu_compiler(*new wxMenu()); + wxMenu& menu_tools(*new wxMenu()); wxMenu& menu_help(*new wxMenu()); menubar.Append(&menu_boot, "Boot"); menubar.Append(&menu_sys, "System"); menubar.Append(&menu_conf, "Config"); - menubar.Append(&menu_compiler, "Compiler"); + menubar.Append(&menu_tools, "Tools"); menubar.Append(&menu_help, "Help"); menu_boot.Append(id_boot_game, "Boot game"); @@ -86,7 +88,8 @@ MainFrame::MainFrame() menu_conf.Append(id_config_vfs_manager, "Virtual File System Manager"); menu_conf.Append(id_config_vhdd_manager, "Virtual HDD Manager"); - menu_compiler.Append(id_compiler, "ELF Compiler"); + menu_tools.Append(id_tools_compiler, "ELF Compiler"); + menu_tools.Append(id_tools_memory_viewer, "Memory Viewer"); menu_help.Append(id_help_about, "About..."); @@ -109,7 +112,8 @@ MainFrame::MainFrame() Connect( id_config_vfs_manager, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::ConfigVFS) ); Connect( id_config_vhdd_manager,wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::ConfigVHDD) ); - Connect( id_compiler, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OpenELFCompiler)); + Connect( id_tools_compiler, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OpenELFCompiler)); + Connect( id_tools_memory_viewer,wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OpenMemoryViewer)); Connect( id_help_about, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::AboutDialogHandler) ); @@ -490,6 +494,11 @@ void MainFrame::OpenELFCompiler(wxCommandEvent& WXUNUSED(event)) (new CompilerELF(this)) -> Show(); } +void MainFrame::OpenMemoryViewer(wxCommandEvent& WXUNUSED(event)) +{ + (new MemoryViewerPanel(this)) -> Show(); +} + void MainFrame::AboutDialogHandler(wxCommandEvent& WXUNUSED(event)) { AboutDialog(this).ShowModal(); diff --git a/rpcs3/Gui/MainFrame.h b/rpcs3/Gui/MainFrame.h index 0199875427..acb82de459 100644 --- a/rpcs3/Gui/MainFrame.h +++ b/rpcs3/Gui/MainFrame.h @@ -31,6 +31,7 @@ private: void ConfigVFS(wxCommandEvent& event); void ConfigVHDD(wxCommandEvent& event); void OpenELFCompiler(wxCommandEvent& evt); + void OpenMemoryViewer(wxCommandEvent& evt); void AboutDialogHandler(wxCommandEvent& event); void UpdateUI(wxCommandEvent& event); void OnKeyDown(wxKeyEvent& event); diff --git a/rpcs3/Gui/MemoryViewer.cpp b/rpcs3/Gui/MemoryViewer.cpp index 40a5904be3..5cbbbedd0d 100644 --- a/rpcs3/Gui/MemoryViewer.cpp +++ b/rpcs3/Gui/MemoryViewer.cpp @@ -3,94 +3,216 @@ #include "Emu/Memory/Memory.h" MemoryViewerPanel::MemoryViewerPanel(wxWindow* parent) - : FrameBase(parent, wxID_ANY, L"Memory Viewer", wxEmptyString, wxSize(700, 450), wxDefaultPosition, - wxSYSTEM_MENU | wxRESIZE_BORDER | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxCLOSE_BOX | wxCAPTION | wxCLIP_CHILDREN) + : wxFrame(parent, wxID_ANY, "Memory Viewer", wxDefaultPosition, wxSize(700, 450)) + //wxSYSTEM_MENU | wxRESIZE_BORDER | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxCLOSE_BOX | wxCAPTION | wxCLIP_CHILDREN) { exit = false; + m_addr = 0; + m_colcount = 16; + m_rowcount = 16; - m_PC = 0; + this->SetBackgroundColour(wxColour(240,240,240)); //This fix the ugly background color under Windows + wxBoxSizer& s_panel = *new wxBoxSizer(wxVERTICAL); - wxBoxSizer& s_panel( *new wxBoxSizer(wxVERTICAL) ); - wxBoxSizer& s_b_panel( *new wxBoxSizer(wxHORIZONTAL) ); + //Tools + wxBoxSizer& s_tools = *new wxBoxSizer(wxHORIZONTAL); - hex_wind = new wxListView(this); + //Tools: Memory Viewer Options + wxStaticBoxSizer& s_tools_mem = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Memory Viewer Options"); - for(uint i=0; iInsertColumn(i, wxString::Format("%d", i)); - hex_wind->SetColumnWidth(i, 28); - } + wxStaticBoxSizer& s_tools_mem_addr = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Address"); + t_addr = new wxTextCtrl(this, wxID_ANY, "00000000", wxDefaultPosition, wxSize(60,-1)); + t_addr->SetMaxLength(8); + s_tools_mem_addr.Add(t_addr); - hex_wind->InsertColumn(COL_COUNT, wxEmptyString); - hex_wind->SetColumnWidth(COL_COUNT, 20); + wxStaticBoxSizer& s_tools_mem_bytes = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Bytes"); + sc_bytes = new wxSpinCtrl(this, wxID_ANY, "16", wxDefaultPosition, wxSize(44,-1)); + sc_bytes->SetMax(16); + sc_bytes->SetMin(1); + s_tools_mem_bytes.Add(sc_bytes); - m_colsize = 0; + wxStaticBoxSizer& s_tools_mem_buttons = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Control"); + wxButton* b_fprev = new wxButton(this, wxID_ANY, "\u00AB", wxDefaultPosition, wxSize(21, 21)); + wxButton* b_prev = new wxButton(this, wxID_ANY, "<", wxDefaultPosition, wxSize(21, 21)); + wxButton* b_next = new wxButton(this, wxID_ANY, ">", wxDefaultPosition, wxSize(21, 21)); + wxButton* b_fnext = new wxButton(this, wxID_ANY, "\u00BB", wxDefaultPosition, wxSize(21, 21)); + s_tools_mem_buttons.Add(b_fprev); + s_tools_mem_buttons.Add(b_prev); + s_tools_mem_buttons.Add(b_next); + s_tools_mem_buttons.Add(b_fnext); - for(uint i=0; iGetColumnWidth(i); - } + s_tools_mem.Add(&s_tools_mem_addr); + s_tools_mem.Add(&s_tools_mem_bytes); + s_tools_mem.Add(&s_tools_mem_buttons); - SetMinSize(wxSize(m_colsize + hex_wind->GetColumnWidth(COL_COUNT), 50)); + //Tools: Raw Image Preview Options + wxStaticBoxSizer& s_tools_img = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Raw Image Preview"); - for(uint i=0; iInsertItem(i, -1); + wxStaticBoxSizer& s_tools_img_size = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Size"); + sc_img_size_x = new wxSpinCtrl(this, wxID_ANY, "256", wxDefaultPosition, wxSize(60,-1)); + sc_img_size_y = new wxSpinCtrl(this, wxID_ANY, "256", wxDefaultPosition, wxSize(60,-1)); + s_tools_img_size.Add(sc_img_size_x); + s_tools_img_size.Add(new wxStaticText(this, wxID_ANY, " x ")); + s_tools_img_size.Add(sc_img_size_y); - wxButton& b_fprev = *new wxButton(this, wxID_ANY, L"<<"); - wxButton& b_prev = *new wxButton(this, wxID_ANY, L"<"); - wxButton& b_next = *new wxButton(this, wxID_ANY, L">"); - wxButton& b_fnext = *new wxButton(this, wxID_ANY, L">>"); + wxStaticBoxSizer& s_tools_img_mode = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Mode"); + cbox_img_mode = new wxComboBox(this, wxID_ANY); + cbox_img_mode->Append("RGB"); + cbox_img_mode->Append("ARGB"); + cbox_img_mode->Append("RGBA"); + s_tools_img_mode.Add(cbox_img_mode); - s_b_panel.Add(&b_fprev); - s_b_panel.Add(&b_prev); - s_b_panel.AddSpacer(5); - s_b_panel.Add(&b_next); - s_b_panel.Add(&b_fnext); + s_tools_img.Add(&s_tools_img_size); + s_tools_img.Add(&s_tools_img_mode); - s_panel.Add(&s_b_panel); - s_panel.Add(hex_wind); + //Tools: Run tools + wxStaticBoxSizer& s_tools_buttons = *new wxStaticBoxSizer(wxVERTICAL, this, "Tools"); + wxButton* b_tools_img_view = new wxButton(this, wxID_ANY, "View\nimage", wxDefaultPosition, wxSize(52,-1)); + s_tools_buttons.Add(b_tools_img_view); - SetSizerAndFit( &s_panel ); + //Tools: Tools = Memory Viewer Options + Raw Image Preview Options + Buttons + s_tools.AddSpacer(10); + s_tools.Add(&s_tools_mem); + s_tools.AddSpacer(10); + s_tools.Add(&s_tools_img); + s_tools.AddSpacer(10); + s_tools.Add(&s_tools_buttons); + s_tools.AddSpacer(10); - Connect( wxEVT_SIZE, wxSizeEventHandler(MemoryViewerPanel::OnResize) ); + //Memory Panel + wxBoxSizer& s_mem_panel = *new wxBoxSizer(wxHORIZONTAL); + t_mem_addr = new wxTextCtrl(this, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxNO_BORDER|wxTE_READONLY); + t_mem_hex = new wxTextCtrl(this, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxNO_BORDER|wxTE_READONLY); + t_mem_ascii = new wxTextCtrl(this, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxNO_BORDER|wxTE_READONLY); + t_mem_addr->SetMinSize(wxSize(68, 228)); + t_mem_addr->SetForegroundColour(wxColour(75, 135, 150)); + + t_mem_addr->SetScrollbar(wxVERTICAL, 0, 0, 0); + t_mem_hex ->SetScrollbar(wxVERTICAL, 0, 0, 0); + t_mem_ascii->SetScrollbar(wxVERTICAL, 0, 0, 0); + t_mem_addr ->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL)); + t_mem_hex ->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL)); + t_mem_ascii->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL)); - Connect(b_prev.GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryViewerPanel::Prev)); - Connect(b_next.GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryViewerPanel::Next)); - Connect(b_fprev.GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryViewerPanel::fPrev)); - Connect(b_fnext.GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryViewerPanel::fNext)); + s_mem_panel.AddSpacer(10); + s_mem_panel.Add(t_mem_addr); + s_mem_panel.Add(t_mem_hex); + s_mem_panel.Add(t_mem_ascii); + s_mem_panel.AddSpacer(10); + + //Memory Panel: Set size of the wxTextCtrl's + int x, y; + t_mem_hex->GetTextExtent(wxT("T"), &x, &y); + t_mem_hex->SetMinSize(wxSize(x * 3*m_colcount + 6, 228)); + t_mem_hex->SetMaxSize(wxSize(x * 3*m_colcount + 6, 228)); + t_mem_ascii->SetMinSize(wxSize(x * m_colcount + 6, 228)); + t_mem_ascii->SetMaxSize(wxSize(x * m_colcount + 6, 228)); + + //Merge and display everything + s_panel.AddSpacer(10); + s_panel.Add(&s_tools); + s_panel.AddSpacer(10); + s_panel.Add(&s_mem_panel, 0, 0, 100); + s_panel.AddSpacer(10); + SetSizerAndFit(&s_panel); + + //Events + //Connect( wxEVT_SIZE, wxSizeEventHandler(MemoryViewerPanel::OnResize) ); + Connect(t_addr->GetId(), wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(MemoryViewerPanel::OnChangeToolsAddr) ); + Connect(sc_bytes->GetId(), wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(MemoryViewerPanel::OnChangeToolsBytes) ); + Connect(sc_bytes->GetId(), wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler(MemoryViewerPanel::OnChangeToolsBytes) ); + + Connect(b_prev->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryViewerPanel::Prev)); + Connect(b_next->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryViewerPanel::Next)); + Connect(b_fprev->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryViewerPanel::fPrev)); + Connect(b_fnext->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryViewerPanel::fNext)); + + t_mem_addr ->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(MemoryViewerPanel::OnScrollMemory), NULL, this); + t_mem_hex ->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(MemoryViewerPanel::OnScrollMemory), NULL, this); + t_mem_ascii->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(MemoryViewerPanel::OnScrollMemory), NULL, this); + + //Fill the wxTextCtrl's + ShowMemory(); }; -void MemoryViewerPanel::OnResize(wxSizeEvent& event) +/*void MemoryViewerPanel::OnResize(wxSizeEvent& event) { const wxSize size(GetClientSize()); hex_wind->SetSize( size.GetWidth(), size.GetHeight() - 25); - hex_wind->SetColumnWidth(COL_COUNT, size.GetWidth() - m_colsize - 4); + hex_wind->SetColumnWidth(COL_COUNT, size.GetWidth() - m_colcount - 4); + event.Skip(); +}*/ + +void MemoryViewerPanel::OnChangeToolsAddr(wxCommandEvent& event) +{ + t_addr->GetValue().ToULong((unsigned long *)&m_addr, 16); + t_addr->SetValue(wxString::Format("%08x", m_addr)); + ShowMemory(); event.Skip(); } -void MemoryViewerPanel::ShowPC() +void MemoryViewerPanel::OnChangeToolsBytes(wxCommandEvent& event) { - uint pc = m_PC; + m_colcount = sc_bytes->GetValue(); - for(uint line=0; line < LINE_COUNT; ++line) + int x, y; + t_mem_hex->GetTextExtent(wxT("T"), &x, &y); + t_mem_hex->SetMinSize(wxSize(x * 3*m_colcount + 6, 228)); + t_mem_hex->SetMaxSize(wxSize(x * 3*m_colcount + 6, 228)); + t_mem_ascii->SetMinSize(wxSize(x * m_colcount + 6, 228)); + t_mem_ascii->SetMaxSize(wxSize(x * m_colcount + 6, 228)); + this->Layout(); + ShowMemory(); + event.Skip(); +} + +void MemoryViewerPanel::OnScrollMemory(wxMouseEvent& event) +{ + if (event.GetWheelRotation() < 0) + m_addr += m_colcount; + else + m_addr -= m_colcount; + + t_addr->SetValue(wxString::Format("%08x", m_addr)); + ShowMemory(); + event.Skip(); +} + +void MemoryViewerPanel::ShowMemory() +{ + wxString t_mem_addr_str; + wxString t_mem_hex_str; + wxString t_mem_ascii_str; + + for(u32 addr = m_addr; addr != m_addr + m_rowcount * m_colcount; addr += m_colcount) { - wxString char_col = wxEmptyString; + t_mem_addr_str += wxString::Format("%08x ", addr); + } - for(uint item=0; item < COL_COUNT; ++item) + + for(u32 addr = m_addr; addr != m_addr + m_rowcount * m_colcount; addr++) + { + if (Memory.IsGoodAddr(addr)) { - const u8 rmem = Memory.Read8(pc++); - - hex_wind->SetItem(line, item, wxString::Format("%02X", rmem)); - + const u8 rmem = Memory.Read8(addr); + t_mem_hex_str += wxString::Format("%02x ", rmem); const wxString c_rmem = wxString::Format("%c", rmem); - char_col += c_rmem.IsEmpty() ? "." : c_rmem; + t_mem_ascii_str += c_rmem.IsEmpty() ? "." : c_rmem;; + } + else + { + t_mem_hex_str += "?? "; + t_mem_ascii_str += "?"; } - hex_wind->SetItem(line, COL_COUNT, char_col); + t_mem_addr->SetValue(t_mem_addr_str); + t_mem_hex->SetValue(t_mem_hex_str); + t_mem_ascii->SetValue(t_mem_ascii_str); } } -void MemoryViewerPanel::Next (wxCommandEvent& WXUNUSED(event)) { m_PC += COL_COUNT; ShowPC(); } -void MemoryViewerPanel::Prev (wxCommandEvent& WXUNUSED(event)) { m_PC -= COL_COUNT; ShowPC(); } -void MemoryViewerPanel::fNext(wxCommandEvent& WXUNUSED(event)) { m_PC += LINE_COUNT * COL_COUNT; ShowPC(); } -void MemoryViewerPanel::fPrev(wxCommandEvent& WXUNUSED(event)) { m_PC -= LINE_COUNT * COL_COUNT; ShowPC(); } \ No newline at end of file +void MemoryViewerPanel::Next (wxCommandEvent& WXUNUSED(event)) { m_addr += m_colcount; ShowMemory(); } +void MemoryViewerPanel::Prev (wxCommandEvent& WXUNUSED(event)) { m_addr -= m_colcount; ShowMemory(); } +void MemoryViewerPanel::fNext(wxCommandEvent& WXUNUSED(event)) { m_addr += m_rowcount * m_colcount; ShowMemory(); } +void MemoryViewerPanel::fPrev(wxCommandEvent& WXUNUSED(event)) { m_addr -= m_rowcount * m_colcount; ShowMemory(); } \ No newline at end of file diff --git a/rpcs3/Gui/MemoryViewer.h b/rpcs3/Gui/MemoryViewer.h index 1251b4089f..153987a22b 100644 --- a/rpcs3/Gui/MemoryViewer.h +++ b/rpcs3/Gui/MemoryViewer.h @@ -2,14 +2,26 @@ #include -class MemoryViewerPanel : public FrameBase +class MemoryViewerPanel : public wxFrame { - static const uint LINE_COUNT = 50; - static const uint COL_COUNT = 17; + //static const uint LINE_COUNT = 50; + //static const uint COL_COUNT = 17; - uint m_PC; - wxListView* hex_wind; - uint m_colsize; + u32 m_addr; + u32 m_colcount; + u32 m_rowcount; + //wxListView* hex_wind; + + wxTextCtrl* t_addr; + wxSpinCtrl* sc_bytes; + + wxSpinCtrl* sc_img_size_x; + wxSpinCtrl* sc_img_size_y; + wxComboBox* cbox_img_mode; + + wxTextCtrl* t_mem_addr; + wxTextCtrl* t_mem_hex; + wxTextCtrl* t_mem_ascii; public: bool exit; @@ -19,14 +31,17 @@ public: exit = true; } - virtual void OnResize(wxSizeEvent& event); + //virtual void OnResize(wxSizeEvent& event); + virtual void OnChangeToolsAddr(wxCommandEvent& event); + virtual void OnChangeToolsBytes(wxCommandEvent& event); + virtual void OnScrollMemory(wxMouseEvent& event); virtual void Next(wxCommandEvent& event); virtual void Prev(wxCommandEvent& event); virtual void fNext(wxCommandEvent& event); virtual void fPrev(wxCommandEvent& event); - virtual void ShowPC(); + virtual void ShowMemory(); - void SetPC(const uint pc) { m_PC = pc; } + void SetPC(const uint pc) { m_addr = pc; } }; \ No newline at end of file diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index a2d2b62d57..eb6546feb6 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -260,6 +260,7 @@ + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index e79c346fe6..2b31944bd9 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -337,6 +337,9 @@ Emu\GS\GL + + Emu\SysCalls\Modules +