1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-25 12:12:50 +01:00

Experimental RSX Debugger & minor changes

RSX Debugger:
Currently, it can preview the color buffers while the RSX Thread is
running, view and modify the render flags, and act as a memory viewer in
the RSX command buffers (no disasm yet). You can press F5, to update the
information (buffers, memory, flags, etc.) of the frame. There are *a
lot* of TODO's here that will be done in the future.

Minor changes:
*Added /dev_flash/ to VFS (required for cellFont in the future).
*cellMsgDialogOpenErrorCode implemented using wxMessageBox. The
information for each error code comes from PSDevWiki. There are lots
error codes missing.
*Updated sys_memory_get_page_attribute

Happy new year to everyone! :-)
This commit is contained in:
Alexandro Sánchez Bach 2013-12-30 23:59:39 +01:00
parent 3858f5097e
commit d1a27748a3
9 changed files with 592 additions and 22 deletions

View File

@ -176,6 +176,11 @@ void VFS::SaveLoadDevices(Array<VFSManagerEntry>& res, bool is_load)
res[idx].mount = "/dev_hdd1/";
res[idx].device = vfsDevice_LocalFile;
idx = res.Move(new VFSManagerEntry());
res[idx].path = "$(EmulatorDir)\\dev_flash\\";
res[idx].mount = "/dev_flash/";
res[idx].device = vfsDevice_LocalFile;
idx = res.Move(new VFSManagerEntry());
res[idx].path = "$(EmulatorDir)\\dev_usb000\\";
res[idx].mount = "/dev_usb000/";

View File

@ -527,6 +527,109 @@ int cellMsgDialogOpen2(u32 type, char* msgString, u32 callback_addr, u32 userDat
return CELL_OK;
}
int cellMsgDialogOpenErrorCode(u32 errorCode, u32 callback_addr, u32 userData, u32 extParam)
{
cellSysutil.Warning("cellMsgDialogOpenErrorCode(errorCode=0x%x, callback_addr=0x%x, userData=%d, extParam=%d)",
errorCode, callback_addr, userData, extParam);
std::string errorMessage;
switch(errorCode)
{
// Generic errors
case 0x80010001: errorMessage = "The resource is temporarily unavailable."; break;
case 0x80010002: errorMessage = "Invalid argument or flag."; break;
case 0x80010003: errorMessage = "The feature is not yet implemented."; break;
case 0x80010004: errorMessage = "Memory allocation failed."; break;
case 0x80010005: errorMessage = "The resource with the specified identifier does not exist."; break;
case 0x80010006: errorMessage = "The file does not exist."; break;
case 0x80010007: errorMessage = "The file is in unrecognized format / The file is not a valid ELF file."; break;
case 0x80010008: errorMessage = "Resource deadlock is avoided."; break;
case 0x80010009: errorMessage = "Operation not permitted."; break;
case 0x8001000A: errorMessage = "The device or resource is bus."; break;
case 0x8001000B: errorMessage = "The operation is timed ou."; break;
case 0x8001000C: errorMessage = "The operation is aborte."; break;
case 0x8001000D: errorMessage = "Invalid memory access."; break;
case 0x8001000F: errorMessage = "State of the target thread is invalid."; break;
case 0x80010010: errorMessage = "Alignment is invalid."; break;
case 0x80010011: errorMessage = "Shortage of the kernel resources."; break;
case 0x80010012: errorMessage = "The file is a directory."; break;
case 0x80010013: errorMessage = "Operation canceled."; break;
case 0x80010014: errorMessage = "Entry already exists."; break;
case 0x80010015: errorMessage = "Port is already connected."; break;
case 0x80010016: errorMessage = "Port is not connected."; break;
case 0x80010017: errorMessage = "Failure in authorizing SELF. Program authentication fail."; break;
case 0x80010018: errorMessage = "The file is not MSELF."; break;
case 0x80010019: errorMessage = "System version error."; break;
case 0x8001001A: errorMessage = "Fatal system error occurred while authorizing SELF. SELF auth failure."; break;
case 0x8001001B: errorMessage = "Math domain violation."; break;
case 0x8001001C: errorMessage = "Math range violation."; break;
case 0x8001001D: errorMessage = "Illegal multi-byte sequence in input."; break;
case 0x8001001E: errorMessage = "File position error."; break;
case 0x8001001F: errorMessage = "Syscall was interrupted."; break;
case 0x80010020: errorMessage = "File too large."; break;
case 0x80010021: errorMessage = "Too many links."; break;
case 0x80010022: errorMessage = "File table overflow."; break;
case 0x80010023: errorMessage = "No space left on device."; break;
case 0x80010024: errorMessage = "Not a TTY."; break;
case 0x80010025: errorMessage = "Broken pipe."; break;
case 0x80010026: errorMessage = "Read-only filesystem."; break;
case 0x80010027: errorMessage = "Illegal seek."; break;
case 0x80010028: errorMessage = "Arg list too long."; break;
case 0x80010029: errorMessage = "Access violation."; break;
case 0x8001002A: errorMessage = "Invalid file descriptor."; break;
case 0x8001002B: errorMessage = "Filesystem mounting failed."; break;
case 0x8001002C: errorMessage = "Too many files open."; break;
case 0x8001002D: errorMessage = "No device."; break;
case 0x8001002E: errorMessage = "Not a directory."; break;
case 0x8001002F: errorMessage = "No such device or IO."; break;
case 0x80010030: errorMessage = "Cross-device link error."; break;
case 0x80010031: errorMessage = "Bad Message."; break;
case 0x80010032: errorMessage = "In progress."; break;
case 0x80010033: errorMessage = "Message size error."; break;
case 0x80010034: errorMessage = "Name too long."; break;
case 0x80010035: errorMessage = "No lock."; break;
case 0x80010036: errorMessage = "Not empty."; break;
case 0x80010037: errorMessage = "Not supported."; break;
case 0x80010038: errorMessage = "File-system specific error."; break;
case 0x80010039: errorMessage = "Overflow occured."; break;
case 0x8001003A: errorMessage = "Filesystem not mounted."; break;
case 0x8001003B: errorMessage = "Not SData."; break;
case 0x8001003C: errorMessage = "Incorrect version in sys_load_param."; break;
case 0x8001003D: errorMessage = "Pointer is null."; break;
case 0x8001003E: errorMessage = "Pointer is null."; break;
default: errorMessage = "An error has occurred."; break;
}
char errorCodeHex [9];
sprintf(errorCodeHex, "%08x", errorCode);
errorMessage.append("\n(");
errorMessage.append(errorCodeHex);
errorMessage.append(")\n");
u64 status;
int res = wxMessageBox(errorMessage, wxGetApp().GetAppName(), wxICON_ERROR | wxOK);
switch(res)
{
case wxOK: status = CELL_MSGDIALOG_BUTTON_OK; break;
default:
if(res)
{
status = CELL_MSGDIALOG_BUTTON_INVALID;
break;
}
status = CELL_MSGDIALOG_BUTTON_NONE;
break;
}
// TODO: The following lines produce an infinite loop of cellMsgDialogOpenErrorCode's
/*Callback2 callback(0, callback_addr, userData);
callback.Handle(status);
callback.Branch(true);*/
return CELL_OK;
}
int cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option)
{
@ -794,6 +897,7 @@ void cellSysutil_init()
cellSysutil.AddFunc(0x02ff3c1b, cellSysutilUnregisterCallback);
cellSysutil.AddFunc(0x7603d3db, cellMsgDialogOpen2);
cellSysutil.AddFunc(0x3e22cb4b, cellMsgDialogOpenErrorCode);
cellSysutil.AddFunc(0xf4e3caa0, cellAudioOutGetState);
cellSysutil.AddFunc(0x4692ab35, cellAudioOutConfigure);

View File

@ -161,14 +161,17 @@ int sys_memory_get_user_memory_size(u32 mem_info_addr)
return CELL_OK;
}
int sys_memory_get_page_attribute(u32 addr, mem_ptr_t<sys_page_attr_t> a)
int sys_memory_get_page_attribute(u32 addr, mem_ptr_t<sys_page_attr_t> attr)
{
sc_mem.Warning("sys_memory_get_page_attribute(addr=0x%x, attr=0x%x)", addr, a.GetAddr());
sc_mem.Warning("sys_memory_get_page_attribute(addr=0x%x, attr_addr=0x%x)", addr, attr.GetAddr());
a -> attribute = 0;
a -> page_size = 0;
a -> access_right = 0;
a -> pad = 0;
if (!attr.IsGood())
return CELL_EFAULT;
attr->attribute = 0;
attr->page_size = 0;
attr->access_right = 0;
attr->pad = 0;
return CELL_OK;
}

View File

@ -2,6 +2,7 @@
#include "MainFrame.h"
#include "CompilerELF.h"
#include "MemoryViewer.h"
#include "RSXDebugger.h"
#include "git-version.h"
#include "Emu/System.h"
@ -33,6 +34,7 @@ enum IDs
id_config_vhdd_manager,
id_tools_compiler,
id_tools_memory_viewer,
id_tools_rsx_debugger,
id_help_about,
id_update_dbg,
};
@ -150,6 +152,7 @@ MainFrame::MainFrame()
menu_tools.Append(id_tools_compiler, "ELF Compiler");
menu_tools.Append(id_tools_memory_viewer, "Memory Viewer");
menu_tools.Append(id_tools_rsx_debugger, "RSX Debugger");
menu_help.Append(id_help_about, "About...");
@ -158,26 +161,27 @@ MainFrame::MainFrame()
m_game_viewer = new GameViewer(this);
AddPane(m_game_viewer, "Game List", wxAUI_DOCK_BOTTOM);
Connect( id_boot_game, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootGame) );
Connect( id_install_pkg, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::InstallPkg) );
Connect( id_boot_elf, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootElf) );
Connect( id_boot_game, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootGame) );
Connect( id_install_pkg, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::InstallPkg) );
Connect( id_boot_elf, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootElf) );
Connect( id_sys_pause, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Pause) );
Connect( id_sys_stop, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Stop) );
Connect( id_sys_send_open_menu, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::SendOpenCloseSysMenu) );
Connect( id_sys_send_exit, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::SendExit) );
Connect( id_sys_pause, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Pause) );
Connect( id_sys_stop, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Stop) );
Connect( id_sys_send_open_menu, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::SendOpenCloseSysMenu) );
Connect( id_sys_send_exit, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::SendExit) );
Connect( id_config_emu, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Config) );
Connect( id_config_pad, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::ConfigPad) );
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_config_emu, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Config) );
Connect( id_config_pad, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::ConfigPad) );
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_tools_compiler, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OpenELFCompiler));
Connect( id_tools_memory_viewer,wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OpenMemoryViewer));
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_tools_rsx_debugger, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OpenRSXDebugger));
Connect( id_help_about, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::AboutDialogHandler) );
Connect( id_help_about, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::AboutDialogHandler) );
Connect( id_update_dbg, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::UpdateUI) );
Connect( id_update_dbg, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::UpdateUI) );
m_app_connector.Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainFrame::OnKeyDown), (wxObject*)0, this);
m_app_connector.Connect(wxEVT_DBG_COMMAND, wxCommandEventHandler(MainFrame::UpdateUI), (wxObject*)0, this);
@ -739,6 +743,11 @@ void MainFrame::OpenMemoryViewer(wxCommandEvent& WXUNUSED(event))
(new MemoryViewerPanel(this)) -> Show();
}
void MainFrame::OpenRSXDebugger(wxCommandEvent& WXUNUSED(event))
{
(new RSXDebugger(this)) -> Show();
}
void MainFrame::AboutDialogHandler(wxCommandEvent& WXUNUSED(event))
{
AboutDialog(this).ShowModal();

View File

@ -32,6 +32,7 @@ private:
void ConfigVHDD(wxCommandEvent& event);
void OpenELFCompiler(wxCommandEvent& evt);
void OpenMemoryViewer(wxCommandEvent& evt);
void OpenRSXDebugger(wxCommandEvent& evt);
void AboutDialogHandler(wxCommandEvent& event);
void UpdateUI(wxCommandEvent& event);
void OnKeyDown(wxKeyEvent& event);

385
rpcs3/Gui/RSXDebugger.cpp Normal file
View File

@ -0,0 +1,385 @@
#include "stdafx.h"
#include "RSXDebugger.h"
#include "Emu/Memory/Memory.h"
#include "Emu/GS/sysutil_video.h"
const char* s_rsx_flags [] = {
"Alpha test",
"Blend",
"Cull face",
"Depth bounds test",
"Depth test",
"Dither",
"Line smooth",
"Logic op",
"Poly smooth",
"Poly offset fill",
"Poly offset line",
"Poly offset point",
"Stencil test",
};
RSXDebugger::RSXDebugger(wxWindow* parent)
: wxFrame(parent, wxID_ANY, "RSX Debugger", wxDefaultPosition, wxSize(700, 450))
, m_item_count(23)
{
exit = false;
m_addr = 0x0;
m_colcount = 16;
this->SetBackgroundColour(wxColour(240,240,240)); //This fix the ugly background color under Windows
wxBoxSizer& s_panel = *new wxBoxSizer(wxHORIZONTAL);
//Tools
wxBoxSizer& s_tools = *new wxBoxSizer(wxVERTICAL);
//Controls: Memory Viewer Options
wxStaticBoxSizer& s_controls = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Memory Viewer Options");
wxStaticBoxSizer& s_controls_addr = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Address:");
t_addr = new wxTextCtrl(this, wxID_ANY, "00000000", wxDefaultPosition, wxSize(60,-1));
t_addr->SetMaxLength(8);
s_controls_addr.Add(t_addr);
wxStaticBoxSizer& s_controls_goto = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Go to:");
wxButton* b_goto_get = new wxButton(this, wxID_ANY, "Get", wxDefaultPosition, wxSize(40,-1));
wxButton* b_goto_put = new wxButton(this, wxID_ANY, "Put", wxDefaultPosition, wxSize(40,-1));
s_controls_goto.Add(b_goto_get);
s_controls_goto.Add(b_goto_put);
//Controls: Breaks
wxStaticBoxSizer& s_controls_breaks = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Break on:");
wxButton* b_break_frame = new wxButton(this, wxID_ANY, "Frame", wxDefaultPosition, wxSize(60,-1));
wxButton* b_break_text = new wxButton(this, wxID_ANY, "Texture", wxDefaultPosition, wxSize(60,-1));
wxButton* b_break_draw = new wxButton(this, wxID_ANY, "Draw", wxDefaultPosition, wxSize(60,-1));
wxButton* b_break_prim = new wxButton(this, wxID_ANY, "Primitive", wxDefaultPosition, wxSize(60,-1));
wxButton* b_break_inst = new wxButton(this, wxID_ANY, "Command", wxDefaultPosition, wxSize(60,-1));
s_controls_breaks.Add(b_break_frame);
s_controls_breaks.Add(b_break_text);
s_controls_breaks.Add(b_break_draw);
s_controls_breaks.Add(b_break_prim);
s_controls_breaks.Add(b_break_inst);
// TODO: This feature is not yet implemented
b_break_frame->Disable();
b_break_text->Disable();
b_break_draw->Disable();
b_break_prim->Disable();
b_break_inst->Disable();
s_controls.Add(&s_controls_addr);
s_controls.Add(&s_controls_goto);
s_controls.Add(&s_controls_breaks);
//Tabs
wxNotebook* nb_rsx = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxSize(482,475));
wxPanel* p_commands = new wxPanel(nb_rsx, wxID_ANY);
wxPanel* p_flags = new wxPanel(nb_rsx, wxID_ANY);
wxPanel* p_lightning = new wxPanel(nb_rsx, wxID_ANY);
wxPanel* p_texture = new wxPanel(nb_rsx, wxID_ANY);
wxPanel* p_settings = new wxPanel(nb_rsx, wxID_ANY);
nb_rsx->AddPage(p_commands, wxT("RSX Commands"));
nb_rsx->AddPage(p_flags, wxT("Flags"));
nb_rsx->AddPage(p_lightning, wxT("Lightning"));
nb_rsx->AddPage(p_texture, wxT("Texture"));
nb_rsx->AddPage(p_settings, wxT("Settings"));
//Tabs: Lists
m_list_commands = new wxListView(p_commands, wxID_ANY, wxPoint(1,3), wxSize(470,444));
m_list_flags = new wxListView(p_flags, wxID_ANY, wxPoint(1,3), wxSize(470,444));
m_list_lightning = new wxListView(p_lightning, wxID_ANY, wxPoint(1,3), wxSize(470,444));
m_list_texture = new wxListView(p_texture, wxID_ANY, wxPoint(1,3), wxSize(470,444));
m_list_settings = new wxListView(p_settings, wxID_ANY, wxPoint(1,3), wxSize(470,444));
//Tabs: List Style
m_list_commands ->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
m_list_flags ->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
m_list_lightning->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
m_list_texture ->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
m_list_settings ->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
//Tabs: List Columns
m_list_commands->InsertColumn(0, "Address", 0, 100);
m_list_commands->InsertColumn(1, "Value", 0, 100);
m_list_commands->InsertColumn(2, "Command", 0, 250);
m_list_flags->InsertColumn(0, "Name", 0, 150);
m_list_flags->InsertColumn(1, "Value", 0, 300);
m_list_lightning->InsertColumn(0, "Name");
m_list_lightning->InsertColumn(1, "Value");
m_list_texture->InsertColumn(0, "Name");
m_list_texture->InsertColumn(1, "Value");
m_list_settings->InsertColumn(0, "Name");
m_list_settings->InsertColumn(1, "Value");
for(u32 i=0; i<m_item_count; i++)
{
m_list_commands->InsertItem(m_list_commands->GetItemCount(), wxEmptyString);
}
for(u32 i=0; i < sizeof(s_rsx_flags)/sizeof(s_rsx_flags[0]); i++)
{
m_list_flags->InsertItem(m_list_flags->GetItemCount(), s_rsx_flags[i]);
}
//Tools: Tools = Memory Viewer Options + Raw Image Preview Options + Buttons
s_tools.AddSpacer(10);
s_tools.Add(&s_controls);
s_tools.AddSpacer(10);
s_tools.Add(nb_rsx);
s_tools.AddSpacer(10);
//Buffers
wxBoxSizer& s_buffers1 = *new wxBoxSizer(wxVERTICAL);
wxBoxSizer& s_buffers2 = *new wxBoxSizer(wxVERTICAL);
wxStaticBoxSizer& s_buffers_colorA = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Color Buffer A");
wxStaticBoxSizer& s_buffers_colorB = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Color Buffer B");
wxStaticBoxSizer& s_buffers_colorC = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Color Buffer C");
wxStaticBoxSizer& s_buffers_colorD = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Color Buffer D");
wxStaticBoxSizer& s_buffers_depth = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Depth Buffer");
wxStaticBoxSizer& s_buffers_stencil = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Stencil Buffer");
wxStaticBoxSizer& s_buffers_text = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Texture");
//Buffers and textures
CellVideoOutResolution res = ResolutionTable[ResolutionIdToNum(Ini.GSResolution.GetValue())];
m_buffers_width = res.width;
m_buffers_height = res.height;
m_panel_width = (m_buffers_width*108)/m_buffers_height;
m_panel_height = 108;
m_text_width = 108;
m_text_height = 108;
//Panels for displaying the buffers
p_buffer_colorA = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(m_panel_width, m_panel_height));
p_buffer_colorB = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(m_panel_width, m_panel_height));
p_buffer_colorC = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(m_panel_width, m_panel_height));
p_buffer_colorD = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(m_panel_width, m_panel_height));
p_buffer_depth = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(m_panel_width, m_panel_height));
p_buffer_stencil = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(m_panel_width, m_panel_height));
p_buffer_text = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(m_text_width, m_text_height));
s_buffers_colorA.Add(p_buffer_colorA);
s_buffers_colorB.Add(p_buffer_colorB);
s_buffers_colorC.Add(p_buffer_colorC);
s_buffers_colorD.Add(p_buffer_colorD);
s_buffers_depth.Add(p_buffer_depth);
s_buffers_stencil.Add(p_buffer_stencil);
s_buffers_text.Add(p_buffer_text);
//Merge and display everything
s_buffers1.AddSpacer(10);
s_buffers1.Add(&s_buffers_colorA);
s_buffers1.AddSpacer(10);
s_buffers1.Add(&s_buffers_colorC);
s_buffers1.AddSpacer(10);
s_buffers1.Add(&s_buffers_depth);
s_buffers1.AddSpacer(10);
s_buffers1.Add(&s_buffers_text);
s_buffers1.AddSpacer(10);
s_buffers2.AddSpacer(10);
s_buffers2.Add(&s_buffers_colorB);
s_buffers2.AddSpacer(10);
s_buffers2.Add(&s_buffers_colorD);
s_buffers2.AddSpacer(10);
s_buffers2.Add(&s_buffers_stencil);
s_buffers2.AddSpacer(10);
s_panel.AddSpacer(10);
s_panel.Add(&s_tools);
s_panel.AddSpacer(10);
s_panel.Add(&s_buffers1);
s_panel.AddSpacer(10);
s_panel.Add(&s_buffers2);
s_panel.AddSpacer(10);
SetSizerAndFit(&s_panel);
//Events
Connect(wxID_ANY, wxEVT_KEY_DOWN, wxKeyEventHandler(RSXDebugger::OnKeyDown), NULL, this);
Connect(t_addr->GetId(), wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(RSXDebugger::OnChangeToolsAddr));
Connect(b_goto_get->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RSXDebugger::GoToGet));
Connect(b_goto_put->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RSXDebugger::GoToPut));
m_list_commands->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(RSXDebugger::OnScrollMemory), NULL, this);
m_list_flags->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(RSXDebugger::ModifyFlags), NULL, this);
//Fill the frame
UpdateInformation();
};
void RSXDebugger::OnKeyDown(wxKeyEvent& event)
{
switch(event.GetKeyCode())
{
case WXK_F5: UpdateInformation(); break;
}
}
void RSXDebugger::OnChangeToolsAddr(wxCommandEvent& event)
{
t_addr->GetValue().ToULong((unsigned long *)&m_addr, 16);
t_addr->SetValue(wxString::Format("%08x", m_addr));
UpdateInformation();
event.Skip();
}
void RSXDebugger::OnScrollMemory(wxMouseEvent& event)
{
m_addr -= (event.ControlDown() ? m_item_count : 1) * 4 * (event.GetWheelRotation() / event.GetWheelDelta());
t_addr->SetValue(wxString::Format("%08x", m_addr));
UpdateInformation();
event.Skip();
}
void RSXDebugger::GoToGet(wxCommandEvent& event)
{
if (!RSXReady()) return;
CellGcmControl* ctrl = (CellGcmControl*)&Memory[Emu.GetGSManager().GetRender().m_ctrlAddress];
m_addr = Emu.GetGSManager().GetRender().m_ioAddress + re(ctrl->get);
t_addr->SetValue(wxString::Format("%08x", m_addr));
UpdateInformation();
event.Skip();
}
void RSXDebugger::GoToPut(wxCommandEvent& event)
{
if (!RSXReady()) return;
CellGcmControl* ctrl = (CellGcmControl*)&Memory[Emu.GetGSManager().GetRender().m_ctrlAddress];
m_addr = Emu.GetGSManager().GetRender().m_ioAddress + re(ctrl->put);
t_addr->SetValue(wxString::Format("%08x", m_addr));
UpdateInformation();
event.Skip();
}
void RSXDebugger::UpdateInformation()
{
ShowMemory();
ShowBuffers();
ShowFlags();
this->SetFocus();
}
void RSXDebugger::ShowMemory()
{
for(u32 i=0; i<m_item_count; i++)
{
u32 addr = m_addr + 4*i;
m_list_commands->SetItem(i, 0, wxString::Format("%08x", addr));
if (Memory.IsGoodAddr(addr))
{
u32 cmd = Memory.Read32(addr);
m_list_commands->SetItem(i, 1, wxString::Format("%08x", cmd));
}
else
{
m_list_commands->SetItem(i, 1, "????????");
}
}
}
void RSXDebugger::ShowBuffers()
{
// TODO: This is a *very* ugly way of checking if m_render was initialized. It throws an error while debugging with VS
const GSRender& render = Emu.GetGSManager().GetRender();
if (!&render)
return;
// TODO: Currently it only supports color buffers
for (u32 bufferId=0; bufferId < render.m_gcm_buffers_count; bufferId++)
{
gcmBuffer* buffers = (gcmBuffer*)Memory.GetMemFromAddr(render.m_gcm_buffers_addr);
u32 RSXbuffer_addr = render.m_local_mem_addr + re(buffers[bufferId].offset);
unsigned char* RSXbuffer = (unsigned char*)Memory.VirtualToRealAddr(RSXbuffer_addr);
u32 width = re(buffers[bufferId].width);
u32 height = re(buffers[bufferId].height);
unsigned char* buffer = (unsigned char*)malloc(width * height * 3);
//ABGR to RGB and flip vertically
for (u32 y=0; y<height; y++){
for (u32 i=0, j=0; j<width*4; i+=3, j+=4)
{
buffer[i+0 + y*width*3] = RSXbuffer[j+3 + (height-y-1)*width*4];
buffer[i+1 + y*width*3] = RSXbuffer[j+2 + (height-y-1)*width*4];
buffer[i+2 + y*width*3] = RSXbuffer[j+1 + (height-y-1)*width*4];
}
}
// TODO: Is there any better way to clasify the color buffers? How can we include the depth and stencil buffers?
wxPanel* pnl;
switch(bufferId)
{
case 0: pnl = p_buffer_colorA; break;
case 1: pnl = p_buffer_colorB; break;
case 2: pnl = p_buffer_colorC; break;
default: pnl = p_buffer_colorD; break;
}
wxImage img(m_buffers_width, m_buffers_height, buffer);
wxClientDC dc_canvas(pnl);
dc_canvas.DrawBitmap(img.Scale(m_panel_width, m_panel_height), 0, 0, false);
}
}
void RSXDebugger::ShowFlags()
{
if (!RSXReady())
{
for (u32 i=0; i<m_list_flags->GetItemCount(); i++)
{
m_list_flags->SetItem(i, 1, "N/A");
}
return;
}
const GSRender& render = Emu.GetGSManager().GetRender();
int i=0;
m_list_flags->SetItem(i++, 1, render.m_set_alpha_test ? "Enabled" : "Disabled");
m_list_flags->SetItem(i++, 1, render.m_set_blend ? "Enabled" : "Disabled");
m_list_flags->SetItem(i++, 1, render.m_set_cull_face_enable ? "Enabled" : "Disabled");
m_list_flags->SetItem(i++, 1, render.m_set_depth_bounds_test ? "Enabled" : "Disabled");
m_list_flags->SetItem(i++, 1, render.m_depth_test_enable ? "Enabled" : "Disabled");
m_list_flags->SetItem(i++, 1, render.m_set_dither ? "Enabled" : "Disabled");
m_list_flags->SetItem(i++, 1, render.m_set_line_smooth ? "Enabled" : "Disabled");
m_list_flags->SetItem(i++, 1, render.m_set_logic_op ? "Enabled" : "Disabled");
m_list_flags->SetItem(i++, 1, render.m_set_poly_smooth ? "Enabled" : "Disabled");
m_list_flags->SetItem(i++, 1, render.m_set_poly_offset_fill ? "Enabled" : "Disabled");
m_list_flags->SetItem(i++, 1, render.m_set_poly_offset_line ? "Enabled" : "Disabled");
m_list_flags->SetItem(i++, 1, render.m_set_poly_offset_point ? "Enabled" : "Disabled");
m_list_flags->SetItem(i++, 1, render.m_set_stencil_test ? "Enabled" : "Disabled");
}
void RSXDebugger::ModifyFlags(wxListEvent& event)
{
if (!RSXReady()) return;
GSRender& render = Emu.GetGSManager().GetRender();
switch(event.m_itemIndex)
{
case 0: render.m_set_alpha_test ^= true; break;
case 1: render.m_set_blend ^= true; break;
case 2: render.m_set_cull_face_enable ^= true; break;
case 3: render.m_set_depth_bounds_test ^= true; break;
case 4: render.m_depth_test_enable ^= true; break;
case 5: render.m_set_dither ^= true; break;
case 6: render.m_set_line_smooth ^= true; break;
case 7: render.m_set_logic_op ^= true; break;
case 8: render.m_set_poly_smooth ^= true; break;
case 9: render.m_set_poly_offset_fill ^= true; break;
case 10: render.m_set_poly_offset_line ^= true; break;
case 11: render.m_set_poly_offset_point ^= true; break;
case 12: render.m_set_stencil_test ^= true; break;
}
UpdateInformation();
}
bool RSXDebugger::RSXReady()
{
// TODO: This is a *very* ugly way of checking if m_render was initialized. It throws an error while debugging in VS
const GSRender& render = Emu.GetGSManager().GetRender();
if (!&render)
{
return false;
}
return true;
}

59
rpcs3/Gui/RSXDebugger.h Normal file
View File

@ -0,0 +1,59 @@
#pragma once
#include <wx/listctrl.h>
class RSXDebugger : public wxFrame
{
u32 m_addr;
u32 m_colcount;
u32 m_rowcount;
u32 m_buffers_width;
u32 m_buffers_height;
u32 m_panel_width;
u32 m_panel_height;
u32 m_text_width;
u32 m_text_height;
wxTextCtrl* t_addr;
u32 m_item_count;
wxListView* m_list_commands;
wxListView* m_list_flags;
wxListView* m_list_lightning;
wxListView* m_list_texture;
wxListView* m_list_settings;
wxPanel* p_buffer_colorA;
wxPanel* p_buffer_colorB;
wxPanel* p_buffer_colorC;
wxPanel* p_buffer_colorD;
wxPanel* p_buffer_depth;
wxPanel* p_buffer_stencil;
wxPanel* p_buffer_text;
public:
bool exit;
RSXDebugger(wxWindow* parent);
~RSXDebugger()
{
exit = true;
}
virtual void OnKeyDown(wxKeyEvent& event);
virtual void OnChangeToolsAddr(wxCommandEvent& event);
virtual void OnScrollMemory(wxMouseEvent& event);
virtual void GoToGet(wxCommandEvent& event);
virtual void GoToPut(wxCommandEvent& event);
virtual void UpdateInformation();
virtual void ShowMemory();
virtual void ShowBuffers();
virtual void ShowFlags();
virtual void ModifyFlags(wxListEvent& event);
bool RSXReady();
void SetPC(const uint pc) { m_addr = pc; }
};

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@ -291,6 +291,7 @@
<ClCompile Include="Gui\InterpreterDisAsm.cpp" />
<ClCompile Include="Gui\MainFrame.cpp" />
<ClCompile Include="Gui\MemoryViewer.cpp" />
<ClCompile Include="Gui\RSXDebugger.cpp" />
<ClCompile Include="Gui\TextInputDialog.cpp" />
<ClCompile Include="Gui\VFSManager.cpp" />
<ClCompile Include="Gui\VHDDManager.cpp" />

View File

@ -358,6 +358,9 @@
<ClCompile Include="Emu\Audio\AudioManager.cpp">
<Filter>Emu\Audio</Filter>
</ClCompile>
<ClCompile Include="Gui\RSXDebugger.cpp">
<Filter>Gui</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="rpcs3.rc" />