Reformat all the things. Have fun with merge conflicts.

This commit is contained in:
Pierre Bourdon
2016-06-24 10:43:46 +02:00
parent 2115e8a4a6
commit 3570c7f03a
1116 changed files with 187405 additions and 180344 deletions

View File

@ -12,40 +12,40 @@
#include "Common/CommonTypes.h"
#include "Common/StringUtil.h"
#include "Core/PowerPC/PowerPC.h"
#include "DolphinWX/WxUtils.h"
#include "DolphinWX/Debugger/BreakpointDlg.h"
#include "DolphinWX/Debugger/BreakpointWindow.h"
#include "DolphinWX/WxUtils.h"
BreakPointDlg::BreakPointDlg(CBreakPointWindow *_Parent)
: wxDialog(_Parent, wxID_ANY, _("Add Breakpoint"))
, Parent(_Parent)
BreakPointDlg::BreakPointDlg(CBreakPointWindow* _Parent)
: wxDialog(_Parent, wxID_ANY, _("Add Breakpoint")), Parent(_Parent)
{
Bind(wxEVT_BUTTON, &BreakPointDlg::OnOK, this, wxID_OK);
Bind(wxEVT_BUTTON, &BreakPointDlg::OnOK, this, wxID_OK);
m_pEditAddress = new wxTextCtrl(this, wxID_ANY, "80000000");
m_pEditAddress = new wxTextCtrl(this, wxID_ANY, "80000000");
wxBoxSizer *sMainSizer = new wxBoxSizer(wxVERTICAL);
sMainSizer->Add(m_pEditAddress, 0, wxEXPAND | wxALL, 5);
sMainSizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxALL, 5);
wxBoxSizer* sMainSizer = new wxBoxSizer(wxVERTICAL);
sMainSizer->Add(m_pEditAddress, 0, wxEXPAND | wxALL, 5);
sMainSizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxALL, 5);
SetSizerAndFit(sMainSizer);
SetFocus();
SetSizerAndFit(sMainSizer);
SetFocus();
}
void BreakPointDlg::OnOK(wxCommandEvent& event)
{
wxString AddressString = m_pEditAddress->GetLineText(0);
u32 Address = 0;
if (AsciiToHex(WxStrToStr(AddressString), Address))
{
PowerPC::breakpoints.Add(Address);
Parent->NotifyUpdate();
Close();
}
else
{
WxUtils::ShowErrorDialog(wxString::Format(_("The address %s is invalid."), WxStrToStr(AddressString).c_str()));
}
wxString AddressString = m_pEditAddress->GetLineText(0);
u32 Address = 0;
if (AsciiToHex(WxStrToStr(AddressString), Address))
{
PowerPC::breakpoints.Add(Address);
Parent->NotifyUpdate();
Close();
}
else
{
WxUtils::ShowErrorDialog(
wxString::Format(_("The address %s is invalid."), WxStrToStr(AddressString).c_str()));
}
event.Skip();
event.Skip();
}

View File

@ -12,11 +12,11 @@ class wxTextCtrl;
class BreakPointDlg : public wxDialog
{
public:
BreakPointDlg(CBreakPointWindow *_Parent);
BreakPointDlg(CBreakPointWindow* _Parent);
private:
CBreakPointWindow *Parent;
wxTextCtrl *m_pEditAddress;
CBreakPointWindow* Parent;
wxTextCtrl* m_pEditAddress;
void OnOK(wxCommandEvent& event);
void OnOK(wxCommandEvent& event);
};

View File

@ -10,92 +10,94 @@
#include "Common/BreakPoints.h"
#include "Common/CommonTypes.h"
#include "Common/StringUtil.h"
#include "Core/PowerPC/PowerPC.h"
#include "Core/PowerPC/PPCSymbolDB.h"
#include "DolphinWX/WxUtils.h"
#include "Core/PowerPC/PowerPC.h"
#include "DolphinWX/Debugger/BreakpointView.h"
#include "DolphinWX/Debugger/DebuggerUIUtil.h"
#include "DolphinWX/WxUtils.h"
CBreakPointView::CBreakPointView(wxWindow* parent, const wxWindowID id)
: wxListCtrl(parent, id, wxDefaultPosition, wxDefaultSize,
wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT | wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING)
: wxListCtrl(parent, id, wxDefaultPosition, wxDefaultSize,
wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT | wxLC_SINGLE_SEL |
wxLC_SORT_ASCENDING)
{
SetFont(DebuggerFont);
Refresh();
SetFont(DebuggerFont);
Refresh();
}
void CBreakPointView::Update()
{
ClearAll();
ClearAll();
InsertColumn(0, _("Active"));
InsertColumn(1, _("Type"));
InsertColumn(2, _("Function"));
InsertColumn(3, _("Address"));
InsertColumn(4, _("Flags"));
InsertColumn(0, _("Active"));
InsertColumn(1, _("Type"));
InsertColumn(2, _("Function"));
InsertColumn(3, _("Address"));
InsertColumn(4, _("Flags"));
const BreakPoints::TBreakPoints& rBreakPoints = PowerPC::breakpoints.GetBreakPoints();
for (const auto& rBP : rBreakPoints)
{
if (!rBP.bTemporary)
{
wxString breakpoint_enabled_str = StrToWxStr(rBP.bOn ? "on" : " ");
int item = InsertItem(0, breakpoint_enabled_str);
SetItem(item, 1, StrToWxStr("BP"));
const BreakPoints::TBreakPoints& rBreakPoints = PowerPC::breakpoints.GetBreakPoints();
for (const auto& rBP : rBreakPoints)
{
if (!rBP.bTemporary)
{
wxString breakpoint_enabled_str = StrToWxStr(rBP.bOn ? "on" : " ");
int item = InsertItem(0, breakpoint_enabled_str);
SetItem(item, 1, StrToWxStr("BP"));
Symbol *symbol = g_symbolDB.GetSymbolFromAddr(rBP.iAddress);
if (symbol)
{
wxString symbol_description = StrToWxStr(g_symbolDB.GetDescription(rBP.iAddress));
SetItem(item, 2, symbol_description);
}
Symbol* symbol = g_symbolDB.GetSymbolFromAddr(rBP.iAddress);
if (symbol)
{
wxString symbol_description = StrToWxStr(g_symbolDB.GetDescription(rBP.iAddress));
SetItem(item, 2, symbol_description);
}
std::string address = StringFromFormat("%08x", rBP.iAddress);
SetItem(item, 3, StrToWxStr(address));
std::string address = StringFromFormat("%08x", rBP.iAddress);
SetItem(item, 3, StrToWxStr(address));
SetItemData(item, rBP.iAddress);
}
}
SetItemData(item, rBP.iAddress);
}
}
const MemChecks::TMemChecks& rMemChecks = PowerPC::memchecks.GetMemChecks();
for (const auto& rMemCheck : rMemChecks)
{
wxString memcheck_on_str = StrToWxStr((rMemCheck.Break || rMemCheck.Log) ? "on" : " ");
int item = InsertItem(0, memcheck_on_str);
SetItem(item, 1, StrToWxStr("MC"));
const MemChecks::TMemChecks& rMemChecks = PowerPC::memchecks.GetMemChecks();
for (const auto& rMemCheck : rMemChecks)
{
wxString memcheck_on_str = StrToWxStr((rMemCheck.Break || rMemCheck.Log) ? "on" : " ");
int item = InsertItem(0, memcheck_on_str);
SetItem(item, 1, StrToWxStr("MC"));
Symbol *symbol = g_symbolDB.GetSymbolFromAddr(rMemCheck.StartAddress);
if (symbol)
{
wxString memcheck_start_addr = StrToWxStr(g_symbolDB.GetDescription(rMemCheck.StartAddress));
SetItem(item, 2, memcheck_start_addr);
}
Symbol* symbol = g_symbolDB.GetSymbolFromAddr(rMemCheck.StartAddress);
if (symbol)
{
wxString memcheck_start_addr = StrToWxStr(g_symbolDB.GetDescription(rMemCheck.StartAddress));
SetItem(item, 2, memcheck_start_addr);
}
std::string address_range_str = StringFromFormat("%08x to %08x", rMemCheck.StartAddress, rMemCheck.EndAddress);
SetItem(item, 3, StrToWxStr(address_range_str));
std::string address_range_str =
StringFromFormat("%08x to %08x", rMemCheck.StartAddress, rMemCheck.EndAddress);
SetItem(item, 3, StrToWxStr(address_range_str));
std::string mode;
if (rMemCheck.OnRead)
mode += 'r';
if (rMemCheck.OnWrite)
mode += 'w';
std::string mode;
if (rMemCheck.OnRead)
mode += 'r';
if (rMemCheck.OnWrite)
mode += 'w';
SetItem(item, 4, StrToWxStr(mode));
SetItem(item, 4, StrToWxStr(mode));
SetItemData(item, rMemCheck.StartAddress);
}
SetItemData(item, rMemCheck.StartAddress);
}
Refresh();
Refresh();
}
void CBreakPointView::DeleteCurrentSelection()
{
int item = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
if (item >= 0)
{
u32 Address = (u32)GetItemData(item);
PowerPC::breakpoints.Remove(Address);
PowerPC::memchecks.Remove(Address);
Update();
}
int item = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
if (item >= 0)
{
u32 Address = (u32)GetItemData(item);
PowerPC::breakpoints.Remove(Address);
PowerPC::memchecks.Remove(Address);
Update();
}
}

View File

@ -9,8 +9,8 @@
class CBreakPointView : public wxListCtrl
{
public:
CBreakPointView(wxWindow* parent, const wxWindowID id);
CBreakPointView(wxWindow* parent, const wxWindowID id);
void Update() override;
void DeleteCurrentSelection();
void Update() override;
void DeleteCurrentSelection();
};

View File

@ -2,12 +2,12 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <wx/aui/auibar.h>
#include <wx/aui/framemanager.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/listbase.h>
#include <wx/panel.h>
#include <wx/aui/auibar.h>
#include <wx/aui/framemanager.h>
#include "Common/BreakPoints.h"
#include "Common/CommonTypes.h"
@ -16,189 +16,195 @@
#include "Core/ConfigManager.h"
#include "Core/HW/Memmap.h"
#include "Core/PowerPC/PowerPC.h"
#include "DolphinWX/WxUtils.h"
#include "DolphinWX/Debugger/BreakpointDlg.h"
#include "DolphinWX/Debugger/BreakpointView.h"
#include "DolphinWX/Debugger/BreakpointWindow.h"
#include "DolphinWX/Debugger/CodeWindow.h"
#include "DolphinWX/Debugger/MemoryCheckDlg.h"
#include "DolphinWX/WxUtils.h"
class CBreakPointBar : public wxAuiToolBar
{
public:
CBreakPointBar(CBreakPointWindow* parent, const wxWindowID id)
: wxAuiToolBar(parent, id, wxDefaultPosition, wxDefaultSize,
wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_TEXT)
{
SetToolBitmapSize(wxSize(24, 24));
CBreakPointBar(CBreakPointWindow* parent, const wxWindowID id)
: wxAuiToolBar(parent, id, wxDefaultPosition, wxDefaultSize,
wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_TEXT)
{
SetToolBitmapSize(wxSize(24, 24));
m_Bitmaps[Toolbar_Delete] = WxUtils::LoadResourceBitmap("toolbar_debugger_delete");
m_Bitmaps[Toolbar_Add_BP] = WxUtils::LoadResourceBitmap("toolbar_add_breakpoint");
m_Bitmaps[Toolbar_Add_MC] = WxUtils::LoadResourceBitmap("toolbar_add_memorycheck");
m_Bitmaps[Toolbar_Delete] = WxUtils::LoadResourceBitmap("toolbar_debugger_delete");
m_Bitmaps[Toolbar_Add_BP] = WxUtils::LoadResourceBitmap("toolbar_add_breakpoint");
m_Bitmaps[Toolbar_Add_MC] = WxUtils::LoadResourceBitmap("toolbar_add_memorycheck");
AddTool(ID_DELETE, _("Delete"), m_Bitmaps[Toolbar_Delete]);
Bind(wxEVT_TOOL, &CBreakPointWindow::OnDelete, parent, ID_DELETE);
AddTool(ID_DELETE, _("Delete"), m_Bitmaps[Toolbar_Delete]);
Bind(wxEVT_TOOL, &CBreakPointWindow::OnDelete, parent, ID_DELETE);
AddTool(ID_CLEAR, _("Clear"), m_Bitmaps[Toolbar_Delete]);
Bind(wxEVT_TOOL, &CBreakPointWindow::OnClear, parent, ID_CLEAR);
AddTool(ID_CLEAR, _("Clear"), m_Bitmaps[Toolbar_Delete]);
Bind(wxEVT_TOOL, &CBreakPointWindow::OnClear, parent, ID_CLEAR);
AddTool(ID_ADDBP, "+BP", m_Bitmaps[Toolbar_Add_BP]);
Bind(wxEVT_TOOL, &CBreakPointWindow::OnAddBreakPoint, parent, ID_ADDBP);
AddTool(ID_ADDBP, "+BP", m_Bitmaps[Toolbar_Add_BP]);
Bind(wxEVT_TOOL, &CBreakPointWindow::OnAddBreakPoint, parent, ID_ADDBP);
// Add memory breakpoints if you can use them
if (Memory::AreMemoryBreakpointsActivated())
{
AddTool(ID_ADDMC, "+MC", m_Bitmaps[Toolbar_Add_MC]);
Bind(wxEVT_TOOL, &CBreakPointWindow::OnAddMemoryCheck, parent, ID_ADDMC);
}
// Add memory breakpoints if you can use them
if (Memory::AreMemoryBreakpointsActivated())
{
AddTool(ID_ADDMC, "+MC", m_Bitmaps[Toolbar_Add_MC]);
Bind(wxEVT_TOOL, &CBreakPointWindow::OnAddMemoryCheck, parent, ID_ADDMC);
}
AddTool(ID_LOAD, _("Load"), m_Bitmaps[Toolbar_Delete]);
Bind(wxEVT_TOOL, &CBreakPointWindow::Event_LoadAll, parent, ID_LOAD);
AddTool(ID_LOAD, _("Load"), m_Bitmaps[Toolbar_Delete]);
Bind(wxEVT_TOOL, &CBreakPointWindow::Event_LoadAll, parent, ID_LOAD);
AddTool(ID_SAVE, _("Save"), m_Bitmaps[Toolbar_Delete]);
Bind(wxEVT_TOOL, &CBreakPointWindow::Event_SaveAll, parent, ID_SAVE);
}
AddTool(ID_SAVE, _("Save"), m_Bitmaps[Toolbar_Delete]);
Bind(wxEVT_TOOL, &CBreakPointWindow::Event_SaveAll, parent, ID_SAVE);
}
private:
enum
{
Toolbar_Delete,
Toolbar_Add_BP,
Toolbar_Add_MC,
Num_Bitmaps
};
enum
{
Toolbar_Delete,
Toolbar_Add_BP,
Toolbar_Add_MC,
Num_Bitmaps
};
enum
{
ID_DELETE = 2000,
ID_CLEAR,
ID_ADDBP,
ID_ADDMC,
ID_LOAD,
ID_SAVE
};
enum
{
ID_DELETE = 2000,
ID_CLEAR,
ID_ADDBP,
ID_ADDMC,
ID_LOAD,
ID_SAVE
};
wxBitmap m_Bitmaps[Num_Bitmaps];
wxBitmap m_Bitmaps[Num_Bitmaps];
};
CBreakPointWindow::CBreakPointWindow(CCodeWindow* _pCodeWindow, wxWindow* parent,
wxWindowID id, const wxString& title, const wxPoint& position,
const wxSize& size, long style)
: wxPanel(parent, id, position, size, style, title)
, m_pCodeWindow(_pCodeWindow)
CBreakPointWindow::CBreakPointWindow(CCodeWindow* _pCodeWindow, wxWindow* parent, wxWindowID id,
const wxString& title, const wxPoint& position,
const wxSize& size, long style)
: wxPanel(parent, id, position, size, style, title), m_pCodeWindow(_pCodeWindow)
{
Bind(wxEVT_CLOSE_WINDOW, &CBreakPointWindow::OnClose, this);
Bind(wxEVT_CLOSE_WINDOW, &CBreakPointWindow::OnClose, this);
m_mgr.SetManagedWindow(this);
m_mgr.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_LIVE_RESIZE);
m_mgr.SetManagedWindow(this);
m_mgr.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_LIVE_RESIZE);
m_BreakPointListView = new CBreakPointView(this, wxID_ANY);
m_BreakPointListView->Bind(wxEVT_LIST_ITEM_SELECTED, &CBreakPointWindow::OnSelectBP, this);
m_BreakPointListView = new CBreakPointView(this, wxID_ANY);
m_BreakPointListView->Bind(wxEVT_LIST_ITEM_SELECTED, &CBreakPointWindow::OnSelectBP, this);
m_mgr.AddPane(new CBreakPointBar(this, wxID_ANY), wxAuiPaneInfo().ToolbarPane().Top().
LeftDockable(true).RightDockable(true).BottomDockable(false).Floatable(false));
m_mgr.AddPane(m_BreakPointListView, wxAuiPaneInfo().CenterPane());
m_mgr.Update();
m_mgr.AddPane(new CBreakPointBar(this, wxID_ANY), wxAuiPaneInfo()
.ToolbarPane()
.Top()
.LeftDockable(true)
.RightDockable(true)
.BottomDockable(false)
.Floatable(false));
m_mgr.AddPane(m_BreakPointListView, wxAuiPaneInfo().CenterPane());
m_mgr.Update();
}
CBreakPointWindow::~CBreakPointWindow()
{
m_mgr.UnInit();
m_mgr.UnInit();
}
void CBreakPointWindow::OnClose(wxCloseEvent& event)
{
SaveAll();
event.Skip();
SaveAll();
event.Skip();
}
void CBreakPointWindow::NotifyUpdate()
{
m_BreakPointListView->Update();
m_BreakPointListView->Update();
}
void CBreakPointWindow::OnDelete(wxCommandEvent& WXUNUSED(event))
{
m_BreakPointListView->DeleteCurrentSelection();
m_BreakPointListView->DeleteCurrentSelection();
}
// jump to begin addr
void CBreakPointWindow::OnSelectBP(wxListEvent& event)
{
long Index = event.GetIndex();
if (Index >= 0)
{
u32 Address = (u32)m_BreakPointListView->GetItemData(Index);
if (m_pCodeWindow)
m_pCodeWindow->JumpToAddress(Address);
}
long Index = event.GetIndex();
if (Index >= 0)
{
u32 Address = (u32)m_BreakPointListView->GetItemData(Index);
if (m_pCodeWindow)
m_pCodeWindow->JumpToAddress(Address);
}
}
// Clear all breakpoints and memchecks
void CBreakPointWindow::OnClear(wxCommandEvent& WXUNUSED(event))
{
PowerPC::debug_interface.ClearAllBreakpoints();
PowerPC::debug_interface.ClearAllMemChecks();
PowerPC::debug_interface.ClearAllBreakpoints();
PowerPC::debug_interface.ClearAllMemChecks();
NotifyUpdate();
NotifyUpdate();
}
void CBreakPointWindow::OnAddBreakPoint(wxCommandEvent& WXUNUSED(event))
{
BreakPointDlg bpDlg(this);
bpDlg.ShowModal();
BreakPointDlg bpDlg(this);
bpDlg.ShowModal();
}
void CBreakPointWindow::OnAddMemoryCheck(wxCommandEvent& WXUNUSED(event))
{
MemoryCheckDlg memDlg(this);
memDlg.ShowModal();
MemoryCheckDlg memDlg(this);
memDlg.ShowModal();
}
void CBreakPointWindow::Event_SaveAll(wxCommandEvent& WXUNUSED(event))
{
SaveAll();
SaveAll();
}
void CBreakPointWindow::SaveAll()
{
// simply dump all to bp/mc files in a way we can read again
IniFile ini;
ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetUniqueID() + ".ini", false);
ini.SetLines("BreakPoints", PowerPC::breakpoints.GetStrings());
ini.SetLines("MemoryChecks", PowerPC::memchecks.GetStrings());
ini.Save(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetUniqueID() + ".ini");
// simply dump all to bp/mc files in a way we can read again
IniFile ini;
ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetUniqueID() + ".ini",
false);
ini.SetLines("BreakPoints", PowerPC::breakpoints.GetStrings());
ini.SetLines("MemoryChecks", PowerPC::memchecks.GetStrings());
ini.Save(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetUniqueID() + ".ini");
}
void CBreakPointWindow::Event_LoadAll(wxCommandEvent& WXUNUSED(event))
{
LoadAll();
return;
LoadAll();
return;
}
void CBreakPointWindow::LoadAll()
{
IniFile ini;
BreakPoints::TBreakPointsStr newbps;
MemChecks::TMemChecksStr newmcs;
IniFile ini;
BreakPoints::TBreakPointsStr newbps;
MemChecks::TMemChecksStr newmcs;
if (!ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetUniqueID() + ".ini", false))
{
return;
}
if (!ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetUniqueID() +
".ini",
false))
{
return;
}
if (ini.GetLines("BreakPoints", &newbps, false))
{
PowerPC::breakpoints.Clear();
PowerPC::breakpoints.AddFromStrings(newbps);
}
if (ini.GetLines("BreakPoints", &newbps, false))
{
PowerPC::breakpoints.Clear();
PowerPC::breakpoints.AddFromStrings(newbps);
}
if (ini.GetLines("MemoryChecks", &newmcs, false))
{
PowerPC::memchecks.Clear();
PowerPC::memchecks.AddFromStrings(newmcs);
}
if (ini.GetLines("MemoryChecks", &newmcs, false))
{
PowerPC::memchecks.Clear();
PowerPC::memchecks.AddFromStrings(newmcs);
}
NotifyUpdate();
NotifyUpdate();
}

View File

@ -4,8 +4,8 @@
#pragma once
#include <wx/panel.h>
#include <wx/aui/framemanager.h>
#include <wx/panel.h>
class CBreakPointView;
class CCodeWindow;
@ -14,32 +14,28 @@ class wxListEvent;
class CBreakPointWindow : public wxPanel
{
public:
CBreakPointWindow(CCodeWindow* _pCodeWindow, wxWindow* parent, wxWindowID id = wxID_ANY,
const wxString& title = _("Breakpoints"),
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
long style = wxTAB_TRAVERSAL | wxBORDER_NONE);
~CBreakPointWindow();
CBreakPointWindow(CCodeWindow* _pCodeWindow,
wxWindow* parent,
wxWindowID id = wxID_ANY,
const wxString& title = _("Breakpoints"),
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxTAB_TRAVERSAL | wxBORDER_NONE);
~CBreakPointWindow();
void NotifyUpdate();
void NotifyUpdate();
void OnDelete(wxCommandEvent& WXUNUSED(event));
void OnClear(wxCommandEvent& WXUNUSED(event));
void OnAddBreakPoint(wxCommandEvent& WXUNUSED(event));
void OnAddMemoryCheck(wxCommandEvent& WXUNUSED(event));
void Event_SaveAll(wxCommandEvent& WXUNUSED(event));
void SaveAll();
void Event_LoadAll(wxCommandEvent& WXUNUSED(event));
void LoadAll();
void OnDelete(wxCommandEvent& WXUNUSED(event));
void OnClear(wxCommandEvent& WXUNUSED(event));
void OnAddBreakPoint(wxCommandEvent& WXUNUSED(event));
void OnAddMemoryCheck(wxCommandEvent& WXUNUSED(event));
void Event_SaveAll(wxCommandEvent& WXUNUSED(event));
void SaveAll();
void Event_LoadAll(wxCommandEvent& WXUNUSED(event));
void LoadAll();
private:
wxAuiManager m_mgr;
CBreakPointView* m_BreakPointListView;
CCodeWindow* m_pCodeWindow;
wxAuiManager m_mgr;
CBreakPointView* m_BreakPointListView;
CCodeWindow* m_pCodeWindow;
void OnClose(wxCloseEvent& event);
void OnSelectBP(wxListEvent& event);
void OnClose(wxCloseEvent& event);
void OnSelectBP(wxListEvent& event);
};

File diff suppressed because it is too large Load Diff

View File

@ -24,72 +24,64 @@ class wxPaintDC;
class CCodeView : public wxControl
{
public:
CCodeView(DebugInterface* debuginterface, SymbolDB *symbol_db,
wxWindow* parent, wxWindowID Id = wxID_ANY);
CCodeView(DebugInterface* debuginterface, SymbolDB* symbol_db, wxWindow* parent,
wxWindowID Id = wxID_ANY);
void ToggleBreakpoint(u32 address);
void ToggleBreakpoint(u32 address);
u32 GetSelection() const
{
return m_selection;
}
void Center(u32 addr)
{
m_curAddress = addr;
m_selection = addr;
Refresh();
}
void SetPlain()
{
m_plain = true;
}
u32 GetSelection() const { return m_selection; }
void Center(u32 addr)
{
m_curAddress = addr;
m_selection = addr;
Refresh();
}
void SetPlain() { m_plain = true; }
private:
void OnPaint(wxPaintEvent& event);
void OnErase(wxEraseEvent& event);
void OnScrollWheel(wxMouseEvent& event);
void OnMouseDown(wxMouseEvent& event);
void OnMouseMove(wxMouseEvent& event);
void OnMouseUpL(wxMouseEvent& event);
void OnMouseUpR(wxMouseEvent& event);
void OnPopupMenu(wxCommandEvent& event);
void InsertBlrNop(int);
void OnPaint(wxPaintEvent& event);
void OnErase(wxEraseEvent& event);
void OnScrollWheel(wxMouseEvent& event);
void OnMouseDown(wxMouseEvent& event);
void OnMouseMove(wxMouseEvent& event);
void OnMouseUpL(wxMouseEvent& event);
void OnMouseUpR(wxMouseEvent& event);
void OnPopupMenu(wxCommandEvent& event);
void InsertBlrNop(int);
void RaiseEvent();
int YToAddress(int y);
void RaiseEvent();
int YToAddress(int y);
u32 AddrToBranch(u32 addr);
void OnResize(wxSizeEvent& event);
u32 AddrToBranch(u32 addr);
void OnResize(wxSizeEvent& event);
void MoveTo(int x, int y)
{
m_lx = x;
m_ly = y;
}
void MoveTo(int x, int y)
{
m_lx = x;
m_ly = y;
}
void LineTo(std::unique_ptr<wxGraphicsContext>& dc, int x, int y);
void LineTo(std::unique_ptr<wxGraphicsContext>& dc, int x, int y);
struct BlrStruct // for IDM_INSERTBLR
{
u32 address;
u32 oldValue;
};
std::vector<BlrStruct> m_blrList;
struct BlrStruct // for IDM_INSERTBLR
{
u32 address;
u32 oldValue;
};
std::vector<BlrStruct> m_blrList;
DebugInterface* m_debugger;
SymbolDB* m_symbol_db;
DebugInterface* m_debugger;
SymbolDB* m_symbol_db;
bool m_plain;
bool m_plain;
int m_curAddress;
int m_align;
int m_rowHeight;
int m_curAddress;
int m_align;
int m_rowHeight;
u32 m_selection;
u32 m_oldSelection;
bool m_selecting;
u32 m_selection;
u32 m_oldSelection;
bool m_selecting;
int m_lx, m_ly;
int m_lx, m_ly;
};

File diff suppressed because it is too large Load Diff

View File

@ -4,9 +4,9 @@
#pragma once
#include <wx/aui/framemanager.h>
#include <wx/bitmap.h>
#include <wx/panel.h>
#include <wx/aui/framemanager.h>
#include "Common/CommonTypes.h"
#include "Common/Event.h"
@ -32,101 +32,98 @@ class wxToolBar;
class CCodeWindow : public wxPanel
{
public:
CCodeWindow(const SConfig& _LocalCoreStartupParameter,
CFrame * parent,
wxWindowID id = wxID_ANY,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxTAB_TRAVERSAL | wxBORDER_NONE,
const wxString& name = _("Code"));
~CCodeWindow();
CCodeWindow(const SConfig& _LocalCoreStartupParameter, CFrame* parent, wxWindowID id = wxID_ANY,
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
long style = wxTAB_TRAVERSAL | wxBORDER_NONE, const wxString& name = _("Code"));
~CCodeWindow();
void Load();
void Save();
void Load();
void Save();
// Parent interaction
CFrame *Parent;
wxMenuBar * GetMenuBar();
wxToolBar * GetToolBar();
wxBitmap m_Bitmaps[Toolbar_Debug_Bitmap_Max];
// Parent interaction
CFrame* Parent;
wxMenuBar* GetMenuBar();
wxToolBar* GetToolBar();
wxBitmap m_Bitmaps[Toolbar_Debug_Bitmap_Max];
bool UseInterpreter();
bool BootToPause();
bool AutomaticStart();
bool JITNoBlockCache();
bool JITNoBlockLinking();
bool JumpToAddress(u32 address);
bool UseInterpreter();
bool BootToPause();
bool AutomaticStart();
bool JITNoBlockCache();
bool JITNoBlockLinking();
bool JumpToAddress(u32 address);
void Update() override;
void NotifyMapLoaded();
void CreateMenu(const SConfig& _LocalCoreStartupParameter, wxMenuBar *pMenuBar);
void CreateMenuOptions(wxMenu *pMenu);
void CreateMenuSymbols(wxMenuBar *pMenuBar);
void PopulateToolbar(wxToolBar* toolBar);
void UpdateButtonStates();
void OpenPages();
void Update() override;
void NotifyMapLoaded();
void CreateMenu(const SConfig& _LocalCoreStartupParameter, wxMenuBar* pMenuBar);
void CreateMenuOptions(wxMenu* pMenu);
void CreateMenuSymbols(wxMenuBar* pMenuBar);
void PopulateToolbar(wxToolBar* toolBar);
void UpdateButtonStates();
void OpenPages();
// Menu bar
void ToggleCodeWindow(bool bShow);
void ToggleRegisterWindow(bool bShow);
void ToggleWatchWindow(bool bShow);
void ToggleBreakPointWindow(bool bShow);
void ToggleMemoryWindow(bool bShow);
void ToggleJitWindow(bool bShow);
void ToggleSoundWindow(bool bShow);
void ToggleVideoWindow(bool bShow);
// Menu bar
void ToggleCodeWindow(bool bShow);
void ToggleRegisterWindow(bool bShow);
void ToggleWatchWindow(bool bShow);
void ToggleBreakPointWindow(bool bShow);
void ToggleMemoryWindow(bool bShow);
void ToggleJitWindow(bool bShow);
void ToggleSoundWindow(bool bShow);
void ToggleVideoWindow(bool bShow);
// Sub dialogs
CRegisterWindow* m_RegisterWindow;
CWatchWindow* m_WatchWindow;
CBreakPointWindow* m_BreakpointWindow;
CMemoryWindow* m_MemoryWindow;
CJitWindow* m_JitWindow;
DSPDebuggerLLE* m_SoundWindow;
GFXDebuggerPanel* m_VideoWindow;
// Sub dialogs
CRegisterWindow* m_RegisterWindow;
CWatchWindow* m_WatchWindow;
CBreakPointWindow* m_BreakpointWindow;
CMemoryWindow* m_MemoryWindow;
CJitWindow* m_JitWindow;
DSPDebuggerLLE* m_SoundWindow;
GFXDebuggerPanel* m_VideoWindow;
// Settings
bool bAutomaticStart; bool bBootToPause;
bool bShowOnStart[IDM_VIDEO_WINDOW - IDM_LOG_WINDOW + 1];
int iNbAffiliation[IDM_CODE_WINDOW - IDM_LOG_WINDOW + 1];
// Settings
bool bAutomaticStart;
bool bBootToPause;
bool bShowOnStart[IDM_VIDEO_WINDOW - IDM_LOG_WINDOW + 1];
int iNbAffiliation[IDM_CODE_WINDOW - IDM_LOG_WINDOW + 1];
private:
void OnCPUMode(wxCommandEvent& event);
void OnCPUMode(wxCommandEvent& event);
void OnChangeFont(wxCommandEvent& event);
void OnChangeFont(wxCommandEvent& event);
void OnCodeStep(wxCommandEvent& event);
void OnAddrBoxChange(wxCommandEvent& event);
void OnSymbolsMenu(wxCommandEvent& event);
void OnJitMenu(wxCommandEvent& event);
void OnProfilerMenu(wxCommandEvent& event);
void OnCodeStep(wxCommandEvent& event);
void OnAddrBoxChange(wxCommandEvent& event);
void OnSymbolsMenu(wxCommandEvent& event);
void OnJitMenu(wxCommandEvent& event);
void OnProfilerMenu(wxCommandEvent& event);
void OnSymbolListChange(wxCommandEvent& event);
void OnSymbolListContextMenu(wxContextMenuEvent& event);
void OnCallstackListChange(wxCommandEvent& event);
void OnCallersListChange(wxCommandEvent& event);
void OnCallsListChange(wxCommandEvent& event);
void OnCodeViewChange(wxCommandEvent &event);
void OnHostMessage(wxCommandEvent& event);
void OnSymbolListChange(wxCommandEvent& event);
void OnSymbolListContextMenu(wxContextMenuEvent& event);
void OnCallstackListChange(wxCommandEvent& event);
void OnCallersListChange(wxCommandEvent& event);
void OnCallsListChange(wxCommandEvent& event);
void OnCodeViewChange(wxCommandEvent& event);
void OnHostMessage(wxCommandEvent& event);
// Debugger functions
void SingleStep();
void StepOver();
void StepOut();
void ToggleBreakpoint();
// Debugger functions
void SingleStep();
void StepOver();
void StepOut();
void ToggleBreakpoint();
void UpdateLists();
void UpdateCallstack();
void UpdateLists();
void UpdateCallstack();
void InitBitmaps();
void InitBitmaps();
CCodeView* codeview;
wxListBox* callstack;
wxListBox* symbols;
wxListBox* callers;
wxListBox* calls;
Common::Event sync_event;
CCodeView* codeview;
wxListBox* callstack;
wxListBox* symbols;
wxListBox* callers;
wxListBox* calls;
Common::Event sync_event;
wxAuiManager m_aui_manager;
wxAuiToolBar* m_aui_toolbar;
wxAuiManager m_aui_manager;
wxAuiToolBar* m_aui_toolbar;
};

File diff suppressed because it is too large Load Diff

View File

@ -4,236 +4,232 @@
#include <cstdio>
#include <wx/artprov.h>
#include <wx/aui/auibar.h>
#include <wx/aui/auibook.h>
#include <wx/aui/framemanager.h>
#include <wx/listbox.h>
#include <wx/panel.h>
#include <wx/sizer.h>
#include <wx/textctrl.h>
#include <wx/thread.h>
#include <wx/aui/auibar.h>
#include <wx/aui/auibook.h>
#include <wx/aui/framemanager.h>
#include "Common/CommonTypes.h"
#include "Common/StringUtil.h"
#include "Common/SymbolDB.h"
#include "Core/Host.h"
#include "Core/DSP/DSPCore.h"
#include "Core/HW/DSPLLE/DSPDebugInterface.h"
#include "Core/HW/DSPLLE/DSPSymbols.h"
#include "DolphinWX/WxUtils.h"
#include "Core/Host.h"
#include "DolphinWX/Debugger/CodeView.h"
#include "DolphinWX/Debugger/DSPDebugWindow.h"
#include "DolphinWX/Debugger/DSPRegisterView.h"
#include "DolphinWX/Debugger/MemoryView.h"
#include "DolphinWX/WxUtils.h"
static DSPDebuggerLLE* m_DebuggerFrame = nullptr;
DSPDebuggerLLE::DSPDebuggerLLE(wxWindow* parent, wxWindowID id)
: wxPanel(parent, id, wxDefaultPosition, wxDefaultSize,
wxTAB_TRAVERSAL, _("DSP LLE Debugger"))
, m_CachedStepCounter(-1)
: wxPanel(parent, id, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _("DSP LLE Debugger")),
m_CachedStepCounter(-1)
{
Bind(wxEVT_CLOSE_WINDOW, &DSPDebuggerLLE::OnClose, this);
Bind(wxEVT_MENU, &DSPDebuggerLLE::OnChangeState, this, ID_RUNTOOL, ID_SHOWPCTOOL);
Bind(wxEVT_CLOSE_WINDOW, &DSPDebuggerLLE::OnClose, this);
Bind(wxEVT_MENU, &DSPDebuggerLLE::OnChangeState, this, ID_RUNTOOL, ID_SHOWPCTOOL);
m_DebuggerFrame = this;
m_DebuggerFrame = this;
// notify wxAUI which frame to use
m_mgr.SetManagedWindow(this);
m_mgr.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_LIVE_RESIZE);
// notify wxAUI which frame to use
m_mgr.SetManagedWindow(this);
m_mgr.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_LIVE_RESIZE);
m_Toolbar = new wxAuiToolBar(this, ID_TOOLBAR,
wxDefaultPosition, wxDefaultSize, wxAUI_TB_HORZ_TEXT);
m_Toolbar->AddTool(ID_RUNTOOL, _("Pause"),
wxArtProvider::GetBitmap(wxART_TICK_MARK, wxART_OTHER, wxSize(10,10)));
m_Toolbar->AddTool(ID_STEPTOOL, _("Step"),
wxArtProvider::GetBitmap(wxART_GO_DOWN, wxART_OTHER, wxSize(10,10)));
m_Toolbar->AddTool(ID_SHOWPCTOOL, _("Show PC"),
wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_OTHER, wxSize(10,10)));
m_Toolbar->AddSeparator();
m_Toolbar =
new wxAuiToolBar(this, ID_TOOLBAR, wxDefaultPosition, wxDefaultSize, wxAUI_TB_HORZ_TEXT);
m_Toolbar->AddTool(ID_RUNTOOL, _("Pause"),
wxArtProvider::GetBitmap(wxART_TICK_MARK, wxART_OTHER, wxSize(10, 10)));
m_Toolbar->AddTool(ID_STEPTOOL, _("Step"),
wxArtProvider::GetBitmap(wxART_GO_DOWN, wxART_OTHER, wxSize(10, 10)));
m_Toolbar->AddTool(ID_SHOWPCTOOL, _("Show PC"),
wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_OTHER, wxSize(10, 10)));
m_Toolbar->AddSeparator();
m_addr_txtctrl = new wxTextCtrl(m_Toolbar, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
m_addr_txtctrl->Bind(wxEVT_TEXT_ENTER, &DSPDebuggerLLE::OnAddrBoxChange, this);
m_addr_txtctrl = new wxTextCtrl(m_Toolbar, wxID_ANY, wxEmptyString, wxDefaultPosition,
wxDefaultSize, wxTE_PROCESS_ENTER);
m_addr_txtctrl->Bind(wxEVT_TEXT_ENTER, &DSPDebuggerLLE::OnAddrBoxChange, this);
m_Toolbar->AddControl(m_addr_txtctrl);
m_Toolbar->Realize();
m_Toolbar->AddControl(m_addr_txtctrl);
m_Toolbar->Realize();
m_SymbolList = new wxListBox(this, wxID_ANY, wxDefaultPosition,
wxSize(140, 100), 0, nullptr, wxLB_SORT);
m_SymbolList->Bind(wxEVT_LISTBOX, &DSPDebuggerLLE::OnSymbolListChange, this);
m_SymbolList =
new wxListBox(this, wxID_ANY, wxDefaultPosition, wxSize(140, 100), 0, nullptr, wxLB_SORT);
m_SymbolList->Bind(wxEVT_LISTBOX, &DSPDebuggerLLE::OnSymbolListChange, this);
m_MainNotebook = new wxAuiNotebook(this, wxID_ANY,
wxDefaultPosition, wxDefaultSize,
wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE);
m_MainNotebook = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE);
wxPanel *code_panel = new wxPanel(m_MainNotebook, wxID_ANY);
wxBoxSizer *code_sizer = new wxBoxSizer(wxVERTICAL);
m_CodeView = new CCodeView(&debug_interface, &DSPSymbols::g_dsp_symbol_db, code_panel);
m_CodeView->SetPlain();
code_sizer->Add(m_CodeView, 1, wxALL | wxEXPAND);
code_panel->SetSizer(code_sizer);
m_MainNotebook->AddPage(code_panel, _("Disassembly"), true);
wxPanel* code_panel = new wxPanel(m_MainNotebook, wxID_ANY);
wxBoxSizer* code_sizer = new wxBoxSizer(wxVERTICAL);
m_CodeView = new CCodeView(&debug_interface, &DSPSymbols::g_dsp_symbol_db, code_panel);
m_CodeView->SetPlain();
code_sizer->Add(m_CodeView, 1, wxALL | wxEXPAND);
code_panel->SetSizer(code_sizer);
m_MainNotebook->AddPage(code_panel, _("Disassembly"), true);
wxPanel *mem_panel = new wxPanel(m_MainNotebook, wxID_ANY);
wxBoxSizer *mem_sizer = new wxBoxSizer(wxVERTICAL);
// TODO insert memViewer class
m_MemView = new CMemoryView(&debug_interface, mem_panel);
mem_sizer->Add(m_MemView, 1, wxALL | wxEXPAND);
mem_panel->SetSizer(mem_sizer);
m_MainNotebook->AddPage(mem_panel, _("Memory"));
wxPanel* mem_panel = new wxPanel(m_MainNotebook, wxID_ANY);
wxBoxSizer* mem_sizer = new wxBoxSizer(wxVERTICAL);
// TODO insert memViewer class
m_MemView = new CMemoryView(&debug_interface, mem_panel);
mem_sizer->Add(m_MemView, 1, wxALL | wxEXPAND);
mem_panel->SetSizer(mem_sizer);
m_MainNotebook->AddPage(mem_panel, _("Memory"));
m_Regs = new DSPRegisterView(this);
m_Regs = new DSPRegisterView(this);
// add the panes to the manager
m_mgr.AddPane(m_Toolbar, wxAuiPaneInfo().
ToolbarPane().Top().
LeftDockable(false).RightDockable(false));
// add the panes to the manager
m_mgr.AddPane(m_Toolbar,
wxAuiPaneInfo().ToolbarPane().Top().LeftDockable(false).RightDockable(false));
m_mgr.AddPane(m_SymbolList, wxAuiPaneInfo().
Left().CloseButton(false).
Caption(_("Symbols")).Dockable(true));
m_mgr.AddPane(m_SymbolList,
wxAuiPaneInfo().Left().CloseButton(false).Caption(_("Symbols")).Dockable(true));
m_mgr.AddPane(m_MainNotebook, wxAuiPaneInfo().
Name("m_MainNotebook").Center().
CloseButton(false).MaximizeButton(true));
m_mgr.AddPane(
m_MainNotebook,
wxAuiPaneInfo().Name("m_MainNotebook").Center().CloseButton(false).MaximizeButton(true));
m_mgr.AddPane(m_Regs, wxAuiPaneInfo().Right().
CloseButton(false).Caption(_("Registers")).
Dockable(true));
m_mgr.AddPane(m_Regs,
wxAuiPaneInfo().Right().CloseButton(false).Caption(_("Registers")).Dockable(true));
UpdateState();
UpdateState();
m_mgr.Update();
m_mgr.Update();
}
DSPDebuggerLLE::~DSPDebuggerLLE()
{
m_mgr.UnInit();
m_DebuggerFrame = nullptr;
m_mgr.UnInit();
m_DebuggerFrame = nullptr;
}
void DSPDebuggerLLE::OnClose(wxCloseEvent& event)
{
event.Skip();
event.Skip();
}
void DSPDebuggerLLE::OnChangeState(wxCommandEvent& event)
{
if (DSPCore_GetState() == DSPCORE_STOP)
return;
if (DSPCore_GetState() == DSPCORE_STOP)
return;
switch (event.GetId())
{
case ID_RUNTOOL:
if (DSPCore_GetState() == DSPCORE_RUNNING)
DSPCore_SetState(DSPCORE_STEPPING);
else
DSPCore_SetState(DSPCORE_RUNNING);
break;
switch (event.GetId())
{
case ID_RUNTOOL:
if (DSPCore_GetState() == DSPCORE_RUNNING)
DSPCore_SetState(DSPCORE_STEPPING);
else
DSPCore_SetState(DSPCORE_RUNNING);
break;
case ID_STEPTOOL:
if (DSPCore_GetState() == DSPCORE_STEPPING)
{
DSPCore_Step();
Update();
}
break;
case ID_STEPTOOL:
if (DSPCore_GetState() == DSPCORE_STEPPING)
{
DSPCore_Step();
Update();
}
break;
case ID_SHOWPCTOOL:
FocusOnPC();
break;
}
case ID_SHOWPCTOOL:
FocusOnPC();
break;
}
UpdateState();
m_mgr.Update();
UpdateState();
m_mgr.Update();
}
void Host_RefreshDSPDebuggerWindow()
{
if (m_DebuggerFrame)
m_DebuggerFrame->Update();
if (m_DebuggerFrame)
m_DebuggerFrame->Update();
}
void DSPDebuggerLLE::Update()
{
#if defined __WXGTK__
if (!wxIsMainThread())
wxMutexGuiEnter();
if (!wxIsMainThread())
wxMutexGuiEnter();
#endif
UpdateSymbolMap();
UpdateDisAsmListView();
UpdateRegisterFlags();
UpdateState();
UpdateSymbolMap();
UpdateDisAsmListView();
UpdateRegisterFlags();
UpdateState();
#if defined __WXGTK__
if (!wxIsMainThread())
wxMutexGuiLeave();
if (!wxIsMainThread())
wxMutexGuiLeave();
#endif
}
void DSPDebuggerLLE::FocusOnPC()
{
JumpToAddress(g_dsp.pc);
JumpToAddress(g_dsp.pc);
}
void DSPDebuggerLLE::UpdateState()
{
if (DSPCore_GetState() == DSPCORE_RUNNING)
{
m_Toolbar->SetToolLabel(ID_RUNTOOL, _("Pause"));
m_Toolbar->SetToolBitmap(ID_RUNTOOL,
wxArtProvider::GetBitmap(wxART_TICK_MARK, wxART_OTHER, wxSize(10,10)));
m_Toolbar->EnableTool(ID_STEPTOOL, false);
}
else
{
m_Toolbar->SetToolLabel(ID_RUNTOOL, _("Run"));
m_Toolbar->SetToolBitmap(ID_RUNTOOL,
wxArtProvider::GetBitmap(wxART_GO_FORWARD, wxART_OTHER, wxSize(10,10)));
m_Toolbar->EnableTool(ID_STEPTOOL, true);
}
m_Toolbar->Realize();
if (DSPCore_GetState() == DSPCORE_RUNNING)
{
m_Toolbar->SetToolLabel(ID_RUNTOOL, _("Pause"));
m_Toolbar->SetToolBitmap(
ID_RUNTOOL, wxArtProvider::GetBitmap(wxART_TICK_MARK, wxART_OTHER, wxSize(10, 10)));
m_Toolbar->EnableTool(ID_STEPTOOL, false);
}
else
{
m_Toolbar->SetToolLabel(ID_RUNTOOL, _("Run"));
m_Toolbar->SetToolBitmap(
ID_RUNTOOL, wxArtProvider::GetBitmap(wxART_GO_FORWARD, wxART_OTHER, wxSize(10, 10)));
m_Toolbar->EnableTool(ID_STEPTOOL, true);
}
m_Toolbar->Realize();
}
void DSPDebuggerLLE::UpdateDisAsmListView()
{
if (m_CachedStepCounter == g_dsp.step_counter)
return;
if (m_CachedStepCounter == g_dsp.step_counter)
return;
// show PC
FocusOnPC();
m_CachedStepCounter = g_dsp.step_counter;
m_Regs->Update();
// show PC
FocusOnPC();
m_CachedStepCounter = g_dsp.step_counter;
m_Regs->Update();
}
void DSPDebuggerLLE::UpdateSymbolMap()
{
if (g_dsp.dram == nullptr)
return;
if (g_dsp.dram == nullptr)
return;
m_SymbolList->Freeze(); // HyperIris: wx style fast filling
m_SymbolList->Clear();
for (const auto& symbol : DSPSymbols::g_dsp_symbol_db.Symbols())
{
int idx = m_SymbolList->Append(StrToWxStr(symbol.second.name));
m_SymbolList->SetClientData(idx, (void*)&symbol.second);
}
m_SymbolList->Thaw();
m_SymbolList->Freeze(); // HyperIris: wx style fast filling
m_SymbolList->Clear();
for (const auto& symbol : DSPSymbols::g_dsp_symbol_db.Symbols())
{
int idx = m_SymbolList->Append(StrToWxStr(symbol.second.name));
m_SymbolList->SetClientData(idx, (void*)&symbol.second);
}
m_SymbolList->Thaw();
}
void DSPDebuggerLLE::OnSymbolListChange(wxCommandEvent& event)
{
int index = m_SymbolList->GetSelection();
if (index >= 0)
{
Symbol* pSymbol = static_cast<Symbol *>(m_SymbolList->GetClientData(index));
if (pSymbol != nullptr)
{
if (pSymbol->type == Symbol::SYMBOL_FUNCTION)
{
JumpToAddress(pSymbol->address);
}
}
}
int index = m_SymbolList->GetSelection();
if (index >= 0)
{
Symbol* pSymbol = static_cast<Symbol*>(m_SymbolList->GetClientData(index));
if (pSymbol != nullptr)
{
if (pSymbol->type == Symbol::SYMBOL_FUNCTION)
{
JumpToAddress(pSymbol->address);
}
}
}
}
void DSPDebuggerLLE::UpdateRegisterFlags()
@ -242,45 +238,44 @@ void DSPDebuggerLLE::UpdateRegisterFlags()
void DSPDebuggerLLE::OnAddrBoxChange(wxCommandEvent& event)
{
wxString txt = m_addr_txtctrl->GetValue();
wxString txt = m_addr_txtctrl->GetValue();
auto text = StripSpaces(WxStrToStr(txt));
if (text.size())
{
u32 addr;
sscanf(text.c_str(), "%04x", &addr);
if (JumpToAddress(addr))
m_addr_txtctrl->SetBackgroundColour(*wxWHITE);
else
m_addr_txtctrl->SetBackgroundColour(*wxRED);
}
event.Skip();
auto text = StripSpaces(WxStrToStr(txt));
if (text.size())
{
u32 addr;
sscanf(text.c_str(), "%04x", &addr);
if (JumpToAddress(addr))
m_addr_txtctrl->SetBackgroundColour(*wxWHITE);
else
m_addr_txtctrl->SetBackgroundColour(*wxRED);
}
event.Skip();
}
bool DSPDebuggerLLE::JumpToAddress(u16 addr)
{
int page = m_MainNotebook->GetSelection();
if (page == 0)
{
// Center on valid instruction in IRAM/IROM
int new_line = DSPSymbols::Addr2Line(addr);
if (new_line >= 0)
{
m_CodeView->Center(new_line);
return true;
}
}
else if (page == 1)
{
// Center on any location in any valid ROM/RAM
int seg = addr >> 12;
if (seg == 0 || seg == 1 ||
seg == 8 || seg == 0xf)
{
m_MemView->Center(addr);
return true;
}
}
int page = m_MainNotebook->GetSelection();
if (page == 0)
{
// Center on valid instruction in IRAM/IROM
int new_line = DSPSymbols::Addr2Line(addr);
if (new_line >= 0)
{
m_CodeView->Center(new_line);
return true;
}
}
else if (page == 1)
{
// Center on any location in any valid ROM/RAM
int seg = addr >> 12;
if (seg == 0 || seg == 1 || seg == 8 || seg == 0xf)
{
m_MemView->Center(addr);
return true;
}
}
return false;
return false;
}

View File

@ -4,8 +4,8 @@
#pragma once
#include <wx/panel.h>
#include <wx/aui/framemanager.h>
#include <wx/panel.h>
#include "Common/CommonTypes.h"
#include "Core/HW/DSPLLE/DSPDebugInterface.h"
@ -20,49 +20,48 @@ class wxListBox;
class DSPDebuggerLLE : public wxPanel
{
public:
DSPDebuggerLLE(wxWindow *parent, wxWindowID id = wxID_ANY);
virtual ~DSPDebuggerLLE();
DSPDebuggerLLE(wxWindow* parent, wxWindowID id = wxID_ANY);
virtual ~DSPDebuggerLLE();
void Update() override;
void Update() override;
private:
enum
{
ID_TOOLBAR = 1000,
ID_RUNTOOL,
ID_STEPTOOL,
ID_SHOWPCTOOL,
};
enum
{
ID_TOOLBAR = 1000,
ID_RUNTOOL,
ID_STEPTOOL,
ID_SHOWPCTOOL,
};
DSPDebugInterface debug_interface;
u64 m_CachedStepCounter;
DSPDebugInterface debug_interface;
u64 m_CachedStepCounter;
// GUI updaters
void UpdateDisAsmListView();
void UpdateRegisterFlags();
void UpdateSymbolMap();
void UpdateState();
// GUI updaters
void UpdateDisAsmListView();
void UpdateRegisterFlags();
void UpdateSymbolMap();
void UpdateState();
// GUI items
wxAuiManager m_mgr;
wxAuiToolBar* m_Toolbar;
CCodeView* m_CodeView;
CMemoryView* m_MemView;
DSPRegisterView* m_Regs;
wxListBox* m_SymbolList;
wxTextCtrl* m_addr_txtctrl;
wxAuiNotebook* m_MainNotebook;
// GUI items
wxAuiManager m_mgr;
wxAuiToolBar* m_Toolbar;
CCodeView* m_CodeView;
CMemoryView* m_MemView;
DSPRegisterView* m_Regs;
wxListBox* m_SymbolList;
wxTextCtrl* m_addr_txtctrl;
wxAuiNotebook* m_MainNotebook;
void OnClose(wxCloseEvent& event);
void OnChangeState(wxCommandEvent& event);
//void OnRightClick(wxListEvent& event);
//void OnDoubleClick(wxListEvent& event);
void OnAddrBoxChange(wxCommandEvent& event);
void OnSymbolListChange(wxCommandEvent& event);
void OnClose(wxCloseEvent& event);
void OnChangeState(wxCommandEvent& event);
// void OnRightClick(wxListEvent& event);
// void OnDoubleClick(wxListEvent& event);
void OnAddrBoxChange(wxCommandEvent& event);
void OnSymbolListChange(wxCommandEvent& event);
bool JumpToAddress(u16 addr);
bool JumpToAddress(u16 addr);
void FocusOnPC();
//void UnselectAll();
void FocusOnPC();
// void UnselectAll();
};

View File

@ -8,81 +8,83 @@
#include "Common/CommonTypes.h"
#include "Core/DSP/DSPCore.h"
#include "Core/DSP/DSPTables.h"
#include "DolphinWX/WxUtils.h"
#include "DolphinWX/Debugger/DSPRegisterView.h"
#include "DolphinWX/WxUtils.h"
wxString CDSPRegTable::GetValue(int row, int col)
{
if (row < 32) // 32 "normal" regs
{
switch (col)
{
case 0: return StrToWxStr(pdregname(row));
case 1: return wxString::Format("0x%04x", DSPCore_ReadRegister(row));
default: return wxEmptyString;
}
}
return wxEmptyString;
if (row < 32) // 32 "normal" regs
{
switch (col)
{
case 0:
return StrToWxStr(pdregname(row));
case 1:
return wxString::Format("0x%04x", DSPCore_ReadRegister(row));
default:
return wxEmptyString;
}
}
return wxEmptyString;
}
void CDSPRegTable::SetValue(int, int, const wxString &)
void CDSPRegTable::SetValue(int, int, const wxString&)
{
}
void CDSPRegTable::UpdateCachedRegs()
{
if (m_CachedCounter == g_dsp.step_counter)
{
return;
}
if (m_CachedCounter == g_dsp.step_counter)
{
return;
}
m_CachedCounter = g_dsp.step_counter;
m_CachedCounter = g_dsp.step_counter;
for (int i = 0; i < 32; ++i)
{
m_CachedRegHasChanged[i] = (m_CachedRegs[i] != DSPCore_ReadRegister(i));
m_CachedRegs[i] = DSPCore_ReadRegister(i);
}
for (int i = 0; i < 32; ++i)
{
m_CachedRegHasChanged[i] = (m_CachedRegs[i] != DSPCore_ReadRegister(i));
m_CachedRegs[i] = DSPCore_ReadRegister(i);
}
}
wxGridCellAttr *CDSPRegTable::GetAttr(int row, int col, wxGridCellAttr::wxAttrKind)
wxGridCellAttr* CDSPRegTable::GetAttr(int row, int col, wxGridCellAttr::wxAttrKind)
{
wxGridCellAttr *attr = new wxGridCellAttr();
wxGridCellAttr* attr = new wxGridCellAttr();
attr->SetBackgroundColour(*wxWHITE);
attr->SetBackgroundColour(*wxWHITE);
switch (col)
{
case 1:
attr->SetAlignment(wxALIGN_CENTER, wxALIGN_CENTER);
break;
default:
attr->SetAlignment(wxALIGN_LEFT, wxALIGN_CENTER);
break;
}
switch (col)
{
case 1:
attr->SetAlignment(wxALIGN_CENTER, wxALIGN_CENTER);
break;
default:
attr->SetAlignment(wxALIGN_LEFT, wxALIGN_CENTER);
break;
}
if (col == 1)
attr->SetTextColour(m_CachedRegHasChanged[row] ? *wxRED : *wxBLACK);
if (col == 1)
attr->SetTextColour(m_CachedRegHasChanged[row] ? *wxRED : *wxBLACK);
return attr;
return attr;
}
DSPRegisterView::DSPRegisterView(wxWindow *parent, wxWindowID id)
: wxGrid(parent, id, wxDefaultPosition, wxSize(130, 120))
DSPRegisterView::DSPRegisterView(wxWindow* parent, wxWindowID id)
: wxGrid(parent, id, wxDefaultPosition, wxSize(130, 120))
{
m_register_table = new CDSPRegTable();
m_register_table = new CDSPRegTable();
SetTable(m_register_table, true);
SetRowLabelSize(0);
SetColLabelSize(0);
DisableDragRowSize();
SetTable(m_register_table, true);
SetRowLabelSize(0);
SetColLabelSize(0);
DisableDragRowSize();
AutoSizeColumns();
AutoSizeColumns();
}
void DSPRegisterView::Update()
{
m_register_table->UpdateCachedRegs();
ForceRefresh();
m_register_table->UpdateCachedRegs();
ForceRefresh();
}

View File

@ -12,35 +12,35 @@
class CDSPRegTable : public wxGridTableBase
{
private:
u64 m_CachedCounter;
u16 m_CachedRegs[32];
bool m_CachedRegHasChanged[32];
u64 m_CachedCounter;
u16 m_CachedRegs[32];
bool m_CachedRegHasChanged[32];
DECLARE_NO_COPY_CLASS(CDSPRegTable);
DECLARE_NO_COPY_CLASS(CDSPRegTable);
public:
CDSPRegTable()
{
memset(m_CachedRegs, 0, sizeof(m_CachedRegs));
memset(m_CachedRegHasChanged, 0, sizeof(m_CachedRegHasChanged));
}
CDSPRegTable()
{
memset(m_CachedRegs, 0, sizeof(m_CachedRegs));
memset(m_CachedRegHasChanged, 0, sizeof(m_CachedRegHasChanged));
}
int GetNumberCols() override { return 2; }
int GetNumberRows() override { return 32; }
bool IsEmptyCell(int row, int col) override { return false; }
wxString GetValue(int row, int col) override;
void SetValue(int row, int col, const wxString &) override;
wxGridCellAttr *GetAttr(int, int, wxGridCellAttr::wxAttrKind) override;
void UpdateCachedRegs();
int GetNumberCols() override { return 2; }
int GetNumberRows() override { return 32; }
bool IsEmptyCell(int row, int col) override { return false; }
wxString GetValue(int row, int col) override;
void SetValue(int row, int col, const wxString&) override;
wxGridCellAttr* GetAttr(int, int, wxGridCellAttr::wxAttrKind) override;
void UpdateCachedRegs();
};
class DSPRegisterView : public wxGrid
{
public:
DSPRegisterView(wxWindow* parent, wxWindowID id = wxID_ANY);
void Update() override;
DSPRegisterView(wxWindow* parent, wxWindowID id = wxID_ANY);
void Update() override;
private:
// Owned by wx. Deleted implicitly upon destruction.
CDSPRegTable* m_register_table;
// Owned by wx. Deleted implicitly upon destruction.
CDSPRegTable* m_register_table;
};

View File

@ -14,346 +14,360 @@
#include "Common/FileUtil.h"
#include "Common/IniFile.h"
#include "Core/ConfigManager.h"
#include "DolphinWX/WxUtils.h"
#include "DolphinWX/Debugger/DebuggerPanel.h"
#include "DolphinWX/WxUtils.h"
#include "VideoCommon/Debugger.h"
#include "VideoCommon/TextureCacheBase.h"
GFXDebuggerPanel::GFXDebuggerPanel(wxWindow *parent, wxWindowID id, const wxPoint &position,
const wxSize& size, long style, const wxString &title)
: wxPanel(parent, id, position, size, style, title)
GFXDebuggerPanel::GFXDebuggerPanel(wxWindow* parent, wxWindowID id, const wxPoint& position,
const wxSize& size, long style, const wxString& title)
: wxPanel(parent, id, position, size, style, title)
{
g_pdebugger = this;
g_pdebugger = this;
CreateGUIControls();
CreateGUIControls();
Bind(wxEVT_CLOSE_WINDOW, &GFXDebuggerPanel::OnClose, this);
Bind(wxEVT_CLOSE_WINDOW, &GFXDebuggerPanel::OnClose, this);
LoadSettings();
LoadSettings();
}
GFXDebuggerPanel::~GFXDebuggerPanel()
{
g_pdebugger = nullptr;
GFXDebuggerPauseFlag = false;
g_pdebugger = nullptr;
GFXDebuggerPauseFlag = false;
}
void GFXDebuggerPanel::OnClose(wxCloseEvent& event)
{
// save the window position when we hide the window
SaveSettings();
// save the window position when we hide the window
SaveSettings();
event.Skip();
event.Skip();
}
void GFXDebuggerPanel::SaveSettings() const
{
IniFile file;
file.Load(File::GetUserPath(F_DEBUGGERCONFIG_IDX));
IniFile file;
file.Load(File::GetUserPath(F_DEBUGGERCONFIG_IDX));
// TODO: make this work when we close the entire program too, currently on total close we get
// weird values, perhaps because of some conflict with the rendering window
// TODO: make this work when we close the entire program too, currently on total close we get
// weird values, perhaps because of some conflict with the rendering window
// TODO: get the screen resolution and make limits from that
if (GetPosition().x < 1000 &&
GetPosition().y < 1000 &&
GetSize().GetWidth() < 1000 &&
GetSize().GetHeight() < 1000)
{
IniFile::Section* video_window = file.GetOrCreateSection("VideoWindow");
video_window->Set("x", GetPosition().x);
video_window->Set("y", GetPosition().y);
video_window->Set("w", GetSize().GetWidth());
video_window->Set("h", GetSize().GetHeight());
}
// TODO: get the screen resolution and make limits from that
if (GetPosition().x < 1000 && GetPosition().y < 1000 && GetSize().GetWidth() < 1000 &&
GetSize().GetHeight() < 1000)
{
IniFile::Section* video_window = file.GetOrCreateSection("VideoWindow");
video_window->Set("x", GetPosition().x);
video_window->Set("y", GetPosition().y);
video_window->Set("w", GetSize().GetWidth());
video_window->Set("h", GetSize().GetHeight());
}
file.Save(File::GetUserPath(F_DEBUGGERCONFIG_IDX));
file.Save(File::GetUserPath(F_DEBUGGERCONFIG_IDX));
}
void GFXDebuggerPanel::LoadSettings()
{
IniFile file;
file.Load(File::GetUserPath(F_DEBUGGERCONFIG_IDX));
IniFile file;
file.Load(File::GetUserPath(F_DEBUGGERCONFIG_IDX));
int x = 100;
int y = 100;
int w = 100;
int h = 100;
int x = 100;
int y = 100;
int w = 100;
int h = 100;
IniFile::Section* video_window = file.GetOrCreateSection("VideoWindow");
video_window->Get("x", &x, GetPosition().x);
video_window->Get("y", &y, GetPosition().y);
video_window->Get("w", &w, GetSize().GetWidth());
video_window->Get("h", &h, GetSize().GetHeight());
IniFile::Section* video_window = file.GetOrCreateSection("VideoWindow");
video_window->Get("x", &x, GetPosition().x);
video_window->Get("y", &y, GetPosition().y);
video_window->Get("w", &w, GetSize().GetWidth());
video_window->Get("h", &h, GetSize().GetHeight());
SetSize(x, y, w, h);
SetSize(x, y, w, h);
}
struct PauseEventMap
{
PauseEvent event;
const wxString ListStr;
PauseEvent event;
const wxString ListStr;
};
static PauseEventMap* pauseEventMap;
void GFXDebuggerPanel::CreateGUIControls()
{
static PauseEventMap map[] = {
{NEXT_FRAME, _("Frame")},
{NEXT_FLUSH, _("Flush")},
static PauseEventMap map[] = {{NEXT_FRAME, _("Frame")},
{NEXT_FLUSH, _("Flush")},
{NEXT_PIXEL_SHADER_CHANGE, _("Pixel Shader")},
{NEXT_VERTEX_SHADER_CHANGE, _("Vertex Shader")},
{NEXT_TEXTURE_CHANGE, _("Texture")},
{NEXT_NEW_TEXTURE, _("New Texture")},
{NEXT_PIXEL_SHADER_CHANGE, _("Pixel Shader")},
{NEXT_VERTEX_SHADER_CHANGE, _("Vertex Shader")},
{NEXT_TEXTURE_CHANGE, _("Texture")},
{NEXT_NEW_TEXTURE, _("New Texture")},
{NEXT_XFB_CMD, _("XFB Cmd")},
{NEXT_EFB_CMD, _("EFB Cmd")},
{NEXT_XFB_CMD, _("XFB Cmd")},
{NEXT_EFB_CMD, _("EFB Cmd")},
{NEXT_MATRIX_CMD, _("Matrix Cmd")},
{NEXT_VERTEX_CMD, _("Vertex Cmd")},
{NEXT_TEXTURE_CMD, _("Texture Cmd")},
{NEXT_LIGHT_CMD, _("Light Cmd")},
{NEXT_FOG_CMD, _("Fog Cmd")},
{NEXT_MATRIX_CMD, _("Matrix Cmd")},
{NEXT_VERTEX_CMD, _("Vertex Cmd")},
{NEXT_TEXTURE_CMD, _("Texture Cmd")},
{NEXT_LIGHT_CMD, _("Light Cmd")},
{NEXT_FOG_CMD, _("Fog Cmd")},
{NEXT_SET_TLUT, _("TLUT Cmd")},
{NEXT_SET_TLUT, _("TLUT Cmd")},
{NEXT_ERROR, _("Error")}
};
pauseEventMap = map;
const int numPauseEventMap = sizeof(map)/sizeof(PauseEventMap);
{NEXT_ERROR, _("Error")}};
pauseEventMap = map;
const int numPauseEventMap = sizeof(map) / sizeof(PauseEventMap);
// Basic settings
CenterOnParent();
// Basic settings
CenterOnParent();
m_pButtonPause = new wxButton(this, wxID_ANY, _("Pause"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _("Pause"));
m_pButtonPause->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnPauseButton, this);
m_pButtonPause = new wxButton(this, wxID_ANY, _("Pause"), wxDefaultPosition, wxDefaultSize, 0,
wxDefaultValidator, _("Pause"));
m_pButtonPause->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnPauseButton, this);
m_pButtonPauseAtNext = new wxButton(this, wxID_ANY, _("Pause After"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _("Pause At Next"));
m_pButtonPauseAtNext->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnPauseAtNextButton, this);
m_pButtonPauseAtNext = new wxButton(this, wxID_ANY, _("Pause After"), wxDefaultPosition,
wxDefaultSize, 0, wxDefaultValidator, _("Pause At Next"));
m_pButtonPauseAtNext->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnPauseAtNextButton, this);
m_pButtonPauseAtNextFrame = new wxButton(this, wxID_ANY, _("Go to Next Frame"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _("Next Frame"));
m_pButtonPauseAtNextFrame->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnPauseAtNextFrameButton, this);
m_pButtonPauseAtNextFrame = new wxButton(this, wxID_ANY, _("Go to Next Frame"), wxDefaultPosition,
wxDefaultSize, 0, wxDefaultValidator, _("Next Frame"));
m_pButtonPauseAtNextFrame->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnPauseAtNextFrameButton, this);
m_pButtonCont = new wxButton(this, wxID_ANY, _("Continue"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _("Continue"));
m_pButtonCont->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnContButton, this);
m_pButtonCont = new wxButton(this, wxID_ANY, _("Continue"), wxDefaultPosition, wxDefaultSize, 0,
wxDefaultValidator, _("Continue"));
m_pButtonCont->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnContButton, this);
m_pCount = new wxTextCtrl(this, wxID_ANY, "1", wxDefaultPosition, wxSize(50,25), wxTE_RIGHT, wxDefaultValidator, _("Count"));
m_pCount = new wxTextCtrl(this, wxID_ANY, "1", wxDefaultPosition, wxSize(50, 25), wxTE_RIGHT,
wxDefaultValidator, _("Count"));
m_pPauseAtList = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxSize(100,25), 0, nullptr,0,wxDefaultValidator, _("PauseAtList"));
for (int i=0; i<numPauseEventMap; i++)
{
m_pPauseAtList->Append(pauseEventMap[i].ListStr);
}
m_pPauseAtList->SetSelection(0);
m_pPauseAtList = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxSize(100, 25), 0, nullptr, 0,
wxDefaultValidator, _("PauseAtList"));
for (int i = 0; i < numPauseEventMap; i++)
{
m_pPauseAtList->Append(pauseEventMap[i].ListStr);
}
m_pPauseAtList->SetSelection(0);
m_pButtonDump = new wxButton(this, wxID_ANY, _("Dump"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _("Dump"));
m_pButtonDump->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnDumpButton, this);
m_pButtonDump = new wxButton(this, wxID_ANY, _("Dump"), wxDefaultPosition, wxDefaultSize, 0,
wxDefaultValidator, _("Dump"));
m_pButtonDump->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnDumpButton, this);
m_pButtonUpdateScreen = new wxButton(this, wxID_ANY, _("Update Screen"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _("Update Screen"));
m_pButtonUpdateScreen->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnUpdateScreenButton, this);
m_pButtonUpdateScreen = new wxButton(this, wxID_ANY, _("Update Screen"), wxDefaultPosition,
wxDefaultSize, 0, wxDefaultValidator, _("Update Screen"));
m_pButtonUpdateScreen->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnUpdateScreenButton, this);
m_pButtonClearScreen = new wxButton(this, wxID_ANY, _("Clear Screen"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _("Clear Screen"));
m_pButtonClearScreen->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnClearScreenButton, this);
m_pButtonClearScreen = new wxButton(this, wxID_ANY, _("Clear Screen"), wxDefaultPosition,
wxDefaultSize, 0, wxDefaultValidator, _("Clear Screen"));
m_pButtonClearScreen->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnClearScreenButton, this);
m_pButtonClearTextureCache = new wxButton(this, wxID_ANY, _("Clear Textures"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _("Clear Textures"));
m_pButtonClearTextureCache->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnClearTextureCacheButton, this);
m_pButtonClearTextureCache =
new wxButton(this, wxID_ANY, _("Clear Textures"), wxDefaultPosition, wxDefaultSize, 0,
wxDefaultValidator, _("Clear Textures"));
m_pButtonClearTextureCache->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnClearTextureCacheButton,
this);
m_pButtonClearVertexShaderCache = new wxButton(this, wxID_ANY, _("Clear V Shaders"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _("Clear V Shaders"));
m_pButtonClearVertexShaderCache->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnClearVertexShaderCacheButton, this);
m_pButtonClearVertexShaderCache =
new wxButton(this, wxID_ANY, _("Clear V Shaders"), wxDefaultPosition, wxDefaultSize, 0,
wxDefaultValidator, _("Clear V Shaders"));
m_pButtonClearVertexShaderCache->Bind(wxEVT_BUTTON,
&GFXDebuggerPanel::OnClearVertexShaderCacheButton, this);
m_pButtonClearPixelShaderCache = new wxButton(this, wxID_ANY, _("Clear P Shaders"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _("Clear P Shaders"));
m_pButtonClearPixelShaderCache->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnClearPixelShaderCacheButton, this);
m_pButtonClearPixelShaderCache =
new wxButton(this, wxID_ANY, _("Clear P Shaders"), wxDefaultPosition, wxDefaultSize, 0,
wxDefaultValidator, _("Clear P Shaders"));
m_pButtonClearPixelShaderCache->Bind(wxEVT_BUTTON,
&GFXDebuggerPanel::OnClearPixelShaderCacheButton, this);
m_pDumpList = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxSize(120,25), 0, nullptr, 0 ,wxDefaultValidator, _("DumpList"));
m_pDumpList->Insert(_("Pixel Shader"),0);
m_pDumpList->Append(_("Vertex Shader"));
m_pDumpList->Append(_("Pixel Shader Constants"));
m_pDumpList->Append(_("Vertex Shader Constants"));
m_pDumpList->Append(_("Textures"));
m_pDumpList->Append(_("Frame Buffer"));
m_pDumpList->Append(_("Geometry data"));
m_pDumpList->Append(_("Vertex Description"));
m_pDumpList->Append(_("Vertex Matrices"));
m_pDumpList->Append(_("Statistics"));
m_pDumpList->SetSelection(0);
m_pDumpList = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxSize(120, 25), 0, nullptr, 0,
wxDefaultValidator, _("DumpList"));
m_pDumpList->Insert(_("Pixel Shader"), 0);
m_pDumpList->Append(_("Vertex Shader"));
m_pDumpList->Append(_("Pixel Shader Constants"));
m_pDumpList->Append(_("Vertex Shader Constants"));
m_pDumpList->Append(_("Textures"));
m_pDumpList->Append(_("Frame Buffer"));
m_pDumpList->Append(_("Geometry data"));
m_pDumpList->Append(_("Vertex Description"));
m_pDumpList->Append(_("Vertex Matrices"));
m_pDumpList->Append(_("Statistics"));
m_pDumpList->SetSelection(0);
wxBoxSizer *sMain = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* sMain = new wxBoxSizer(wxVERTICAL);
wxStaticBoxSizer* const pFlowCtrlBox = new wxStaticBoxSizer(wxVERTICAL, this, _("Flow Control"));
wxBoxSizer* const pPauseAtNextSzr = new wxBoxSizer(wxHORIZONTAL);
pFlowCtrlBox->Add(m_pButtonPause);
pPauseAtNextSzr->Add(m_pButtonPauseAtNext);
pPauseAtNextSzr->Add(m_pCount);
pPauseAtNextSzr->Add(m_pPauseAtList);
pFlowCtrlBox->Add(pPauseAtNextSzr);
pFlowCtrlBox->Add(m_pButtonPauseAtNextFrame);
pFlowCtrlBox->Add(m_pButtonCont);
wxStaticBoxSizer* const pFlowCtrlBox = new wxStaticBoxSizer(wxVERTICAL, this, _("Flow Control"));
wxBoxSizer* const pPauseAtNextSzr = new wxBoxSizer(wxHORIZONTAL);
pFlowCtrlBox->Add(m_pButtonPause);
pPauseAtNextSzr->Add(m_pButtonPauseAtNext);
pPauseAtNextSzr->Add(m_pCount);
pPauseAtNextSzr->Add(m_pPauseAtList);
pFlowCtrlBox->Add(pPauseAtNextSzr);
pFlowCtrlBox->Add(m_pButtonPauseAtNextFrame);
pFlowCtrlBox->Add(m_pButtonCont);
wxStaticBoxSizer* const pDebugBox = new wxStaticBoxSizer(wxVERTICAL, this, _("Debugging"));
wxBoxSizer* const pDumpSzr = new wxBoxSizer(wxHORIZONTAL);
pDumpSzr->Add(m_pButtonDump);
pDumpSzr->Add(m_pDumpList);
pDebugBox->Add(pDumpSzr);
wxGridSizer* const pDbgGrid = new wxGridSizer(2, 5, 5);
pDbgGrid->Add(m_pButtonUpdateScreen);
pDbgGrid->Add(m_pButtonClearScreen);
pDbgGrid->Add(m_pButtonClearTextureCache);
pDbgGrid->Add(m_pButtonClearVertexShaderCache);
pDbgGrid->Add(m_pButtonClearPixelShaderCache);
pDebugBox->Add(pDbgGrid);
wxStaticBoxSizer* const pDebugBox = new wxStaticBoxSizer(wxVERTICAL, this, _("Debugging"));
wxBoxSizer* const pDumpSzr = new wxBoxSizer(wxHORIZONTAL);
pDumpSzr->Add(m_pButtonDump);
pDumpSzr->Add(m_pDumpList);
pDebugBox->Add(pDumpSzr);
wxGridSizer* const pDbgGrid = new wxGridSizer(2, 5, 5);
pDbgGrid->Add(m_pButtonUpdateScreen);
pDbgGrid->Add(m_pButtonClearScreen);
pDbgGrid->Add(m_pButtonClearTextureCache);
pDbgGrid->Add(m_pButtonClearVertexShaderCache);
pDbgGrid->Add(m_pButtonClearPixelShaderCache);
pDebugBox->Add(pDbgGrid);
sMain->Add(pFlowCtrlBox, 0, 0, 5);
sMain->Add(pDebugBox, 0, 0, 5);
SetSizerAndFit(sMain);
sMain->Add(pFlowCtrlBox, 0, 0, 5);
sMain->Add(pDebugBox, 0, 0, 5);
SetSizerAndFit(sMain);
OnContinue();
OnContinue();
}
void GFXDebuggerPanel::OnPause()
{
m_pButtonDump->Enable();
m_pDumpList->Enable();
m_pButtonUpdateScreen->Enable();
m_pButtonClearScreen->Enable();
m_pButtonClearTextureCache->Enable();
m_pButtonClearVertexShaderCache->Enable();
m_pButtonClearPixelShaderCache->Enable();
m_pButtonDump->Enable();
m_pDumpList->Enable();
m_pButtonUpdateScreen->Enable();
m_pButtonClearScreen->Enable();
m_pButtonClearTextureCache->Enable();
m_pButtonClearVertexShaderCache->Enable();
m_pButtonClearPixelShaderCache->Enable();
}
void GFXDebuggerPanel::OnContinue()
{
m_pButtonDump->Disable();
m_pDumpList->Disable();
m_pButtonUpdateScreen->Disable();
m_pButtonClearScreen->Disable();
m_pButtonClearTextureCache->Disable();
m_pButtonClearVertexShaderCache->Disable();
m_pButtonClearPixelShaderCache->Disable();
m_pButtonDump->Disable();
m_pDumpList->Disable();
m_pButtonUpdateScreen->Disable();
m_pButtonClearScreen->Disable();
m_pButtonClearTextureCache->Disable();
m_pButtonClearVertexShaderCache->Disable();
m_pButtonClearPixelShaderCache->Disable();
}
// General settings
void GFXDebuggerPanel::GeneralSettings(wxCommandEvent& event)
{
SaveSettings();
SaveSettings();
}
void GFXDebuggerPanel::OnPauseButton(wxCommandEvent& event)
{
GFXDebuggerPauseFlag = true;
GFXDebuggerPauseFlag = true;
}
void GFXDebuggerPanel::OnPauseAtNextButton(wxCommandEvent& event)
{
GFXDebuggerPauseFlag = false;
GFXDebuggerToPauseAtNext = pauseEventMap[m_pPauseAtList->GetSelection()].event;
wxString val = m_pCount->GetValue();
long value;
if (val.ToLong(&value))
GFXDebuggerEventToPauseCount = value;
else
GFXDebuggerEventToPauseCount = 1;
GFXDebuggerPauseFlag = false;
GFXDebuggerToPauseAtNext = pauseEventMap[m_pPauseAtList->GetSelection()].event;
wxString val = m_pCount->GetValue();
long value;
if (val.ToLong(&value))
GFXDebuggerEventToPauseCount = value;
else
GFXDebuggerEventToPauseCount = 1;
}
void GFXDebuggerPanel::OnPauseAtNextFrameButton(wxCommandEvent& event)
{
GFXDebuggerPauseFlag = false;
GFXDebuggerToPauseAtNext = NEXT_FRAME;
GFXDebuggerEventToPauseCount = 1;
GFXDebuggerPauseFlag = false;
GFXDebuggerToPauseAtNext = NEXT_FRAME;
GFXDebuggerEventToPauseCount = 1;
}
void GFXDebuggerPanel::OnDumpButton(wxCommandEvent& event)
{
std::string dump_path = File::GetUserPath(D_DUMP_IDX) + "Debug/" +
SConfig::GetInstance().m_strUniqueID + "/";
if (!File::CreateFullPath(dump_path))
return;
std::string dump_path =
File::GetUserPath(D_DUMP_IDX) + "Debug/" + SConfig::GetInstance().m_strUniqueID + "/";
if (!File::CreateFullPath(dump_path))
return;
switch (m_pDumpList->GetSelection())
{
case 0: // Pixel Shader
DumpPixelShader(dump_path);
break;
switch (m_pDumpList->GetSelection())
{
case 0: // Pixel Shader
DumpPixelShader(dump_path);
break;
case 1: // Vertex Shader
DumpVertexShader(dump_path);
break;
case 1: // Vertex Shader
DumpVertexShader(dump_path);
break;
case 2: // Pixel Shader Constants
DumpPixelShaderConstants(dump_path);
WxUtils::ShowErrorDialog(_("Not implemented"));
break;
case 2: // Pixel Shader Constants
DumpPixelShaderConstants(dump_path);
WxUtils::ShowErrorDialog(_("Not implemented"));
break;
case 3: // Vertex Shader Constants
DumpVertexShaderConstants(dump_path);
WxUtils::ShowErrorDialog(_("Not implemented"));
break;
case 3: // Vertex Shader Constants
DumpVertexShaderConstants(dump_path);
WxUtils::ShowErrorDialog(_("Not implemented"));
break;
case 4: // Textures
DumpTextures(dump_path);
WxUtils::ShowErrorDialog(_("Not implemented"));
break;
case 4: // Textures
DumpTextures(dump_path);
WxUtils::ShowErrorDialog(_("Not implemented"));
break;
case 5: // Frame Buffer
DumpFrameBuffer(dump_path);
WxUtils::ShowErrorDialog(_("Not implemented"));
break;
case 5: // Frame Buffer
DumpFrameBuffer(dump_path);
WxUtils::ShowErrorDialog(_("Not implemented"));
break;
case 6: // Geometry
DumpGeometry(dump_path);
WxUtils::ShowErrorDialog(_("Not implemented"));
break;
case 6: // Geometry
DumpGeometry(dump_path);
WxUtils::ShowErrorDialog(_("Not implemented"));
break;
case 7: // Vertex Description
DumpVertexDecl(dump_path);
WxUtils::ShowErrorDialog(_("Not implemented"));
break;
case 7: // Vertex Description
DumpVertexDecl(dump_path);
WxUtils::ShowErrorDialog(_("Not implemented"));
break;
case 8: // Vertex Matrices
DumpMatrices(dump_path);
WxUtils::ShowErrorDialog(_("Not implemented"));
break;
case 8: // Vertex Matrices
DumpMatrices(dump_path);
WxUtils::ShowErrorDialog(_("Not implemented"));
break;
case 9: // Statistics
DumpStats(dump_path);
WxUtils::ShowErrorDialog(_("Not implemented"));
break;
}
case 9: // Statistics
DumpStats(dump_path);
WxUtils::ShowErrorDialog(_("Not implemented"));
break;
}
}
void GFXDebuggerPanel::OnContButton(wxCommandEvent& event)
{
GFXDebuggerToPauseAtNext = NOT_PAUSE;
GFXDebuggerPauseFlag = false;
GFXDebuggerToPauseAtNext = NOT_PAUSE;
GFXDebuggerPauseFlag = false;
}
void GFXDebuggerPanel::OnClearScreenButton(wxCommandEvent& event)
{
// TODO
WxUtils::ShowErrorDialog(_("Not implemented"));
// TODO
WxUtils::ShowErrorDialog(_("Not implemented"));
}
void GFXDebuggerPanel::OnClearTextureCacheButton(wxCommandEvent& event)
{
TextureCacheBase::Invalidate();
TextureCacheBase::Invalidate();
}
void GFXDebuggerPanel::OnClearVertexShaderCacheButton(wxCommandEvent& event)
{
// TODO
WxUtils::ShowErrorDialog(_("Not implemented"));
// TODO
WxUtils::ShowErrorDialog(_("Not implemented"));
}
void GFXDebuggerPanel::OnClearPixelShaderCacheButton(wxCommandEvent& event)
{
// TODO
WxUtils::ShowErrorDialog(_("Not implemented"));
// TODO
WxUtils::ShowErrorDialog(_("Not implemented"));
}
void GFXDebuggerPanel::OnUpdateScreenButton(wxCommandEvent& event)
{
WxUtils::ShowErrorDialog(_("Not implemented"));
GFXDebuggerUpdateScreen();
WxUtils::ShowErrorDialog(_("Not implemented"));
GFXDebuggerUpdateScreen();
}

View File

@ -14,62 +14,60 @@ class wxTextCtrl;
class GFXDebuggerPanel : public wxPanel, public GFXDebuggerBase
{
public:
GFXDebuggerPanel(wxWindow* parent,
wxWindowID id = wxID_ANY,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxTAB_TRAVERSAL,
const wxString &title = _("GFX Debugger"));
GFXDebuggerPanel(wxWindow* parent, wxWindowID id = wxID_ANY,
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
long style = wxTAB_TRAVERSAL, const wxString& title = _("GFX Debugger"));
virtual ~GFXDebuggerPanel();
virtual ~GFXDebuggerPanel();
void SaveSettings() const;
void LoadSettings();
void SaveSettings() const;
void LoadSettings();
bool bInfoLog;
bool bPrimLog;
bool bSaveTextures;
bool bSaveTargets;
bool bSaveShaders;
bool bInfoLog;
bool bPrimLog;
bool bSaveTextures;
bool bSaveTargets;
bool bSaveShaders;
void OnPause() override;
void OnPause() override;
// Called from GFX thread once the GFXDebuggerPauseFlag spin lock has finished
void OnContinue() override;
// Called from GFX thread once the GFXDebuggerPauseFlag spin lock has finished
void OnContinue() override;
private:
wxButton* m_pButtonPause;
wxButton* m_pButtonPauseAtNext;
wxButton* m_pButtonPauseAtNextFrame;
wxButton* m_pButtonCont;
wxChoice* m_pPauseAtList;
wxButton* m_pButtonDump;
wxChoice* m_pDumpList;
wxButton* m_pButtonUpdateScreen;
wxButton* m_pButtonClearScreen;
wxButton* m_pButtonClearTextureCache;
wxButton* m_pButtonClearVertexShaderCache;
wxButton* m_pButtonClearPixelShaderCache;
wxTextCtrl* m_pCount;
wxButton* m_pButtonPause;
wxButton* m_pButtonPauseAtNext;
wxButton* m_pButtonPauseAtNextFrame;
wxButton* m_pButtonCont;
wxChoice* m_pPauseAtList;
wxButton* m_pButtonDump;
wxChoice* m_pDumpList;
wxButton* m_pButtonUpdateScreen;
wxButton* m_pButtonClearScreen;
wxButton* m_pButtonClearTextureCache;
wxButton* m_pButtonClearVertexShaderCache;
wxButton* m_pButtonClearPixelShaderCache;
wxTextCtrl* m_pCount;
void OnClose(wxCloseEvent& event);
void CreateGUIControls();
void OnClose(wxCloseEvent& event);
void CreateGUIControls();
void GeneralSettings(wxCommandEvent& event);
void GeneralSettings(wxCommandEvent& event);
// These set GFXDebuggerPauseFlag to true (either immediately or once the specified event has occurred)
void OnPauseButton(wxCommandEvent& event);
void OnPauseAtNextButton(wxCommandEvent& event);
// These set GFXDebuggerPauseFlag to true (either immediately or once the specified event has
// occurred)
void OnPauseButton(wxCommandEvent& event);
void OnPauseAtNextButton(wxCommandEvent& event);
void OnPauseAtNextFrameButton(wxCommandEvent& event);
void OnDumpButton(wxCommandEvent& event);
void OnPauseAtNextFrameButton(wxCommandEvent& event);
void OnDumpButton(wxCommandEvent& event);
// sets GFXDebuggerPauseFlag to false
void OnContButton(wxCommandEvent& event);
// sets GFXDebuggerPauseFlag to false
void OnContButton(wxCommandEvent& event);
void OnUpdateScreenButton(wxCommandEvent& event);
void OnClearScreenButton(wxCommandEvent& event);
void OnClearTextureCacheButton(wxCommandEvent& event);
void OnClearVertexShaderCacheButton(wxCommandEvent& event);
void OnClearPixelShaderCacheButton(wxCommandEvent& event);
void OnUpdateScreenButton(wxCommandEvent& event);
void OnClearScreenButton(wxCommandEvent& event);
void OnClearTextureCacheButton(wxCommandEvent& event);
void OnClearVertexShaderCacheButton(wxCommandEvent& event);
void OnClearPixelShaderCacheButton(wxCommandEvent& event);
};

View File

@ -2,9 +2,8 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <wx/font.h>
#include "DolphinWX/Debugger/DebuggerUIUtil.h"
#include <wx/font.h>
// The default font
wxFont DebuggerFont = wxFont(9, wxMODERN, wxNORMAL, wxNORMAL, false, "monospace");

View File

@ -4,7 +4,7 @@
#include <cstdio>
#include <cstring>
#include <disasm.h> // Bochs
#include <disasm.h> // Bochs
#include <sstream>
#include <wx/button.h>
@ -17,134 +17,136 @@
#include "Common/GekkoDisassembler.h"
#include "Core/PowerPC/Gekko.h"
#include "Core/PowerPC/PPCAnalyst.h"
#include "DolphinWX/Debugger/JitWindow.h"
#include "DolphinWX/Globals.h"
#include "DolphinWX/WxUtils.h"
#include "DolphinWX/Debugger/JitWindow.h"
#include "UICommon/Disassembler.h"
CJitWindow::CJitWindow(wxWindow* parent, wxWindowID id, const wxPoint& pos,
const wxSize& size, long style, const wxString& name)
: wxPanel(parent, id, pos, size, style, name)
CJitWindow::CJitWindow(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
long style, const wxString& name)
: wxPanel(parent, id, pos, size, style, name)
{
wxBoxSizer* sizerBig = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* sizerSplit = new wxBoxSizer(wxHORIZONTAL);
sizerSplit->Add(ppc_box = new wxTextCtrl(this, wxID_ANY, "(ppc)",
wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE), 1, wxEXPAND);
sizerSplit->Add(x86_box = new wxTextCtrl(this, wxID_ANY, "(x86)",
wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE), 1, wxEXPAND);
sizerBig->Add(block_list = new JitBlockList(this, wxID_ANY,
wxDefaultPosition, wxSize(100, 140),
wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT | wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING),
0, wxEXPAND);
sizerBig->Add(sizerSplit, 2, wxEXPAND);
wxBoxSizer* sizerBig = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* sizerSplit = new wxBoxSizer(wxHORIZONTAL);
sizerSplit->Add(ppc_box = new wxTextCtrl(this, wxID_ANY, "(ppc)", wxDefaultPosition,
wxDefaultSize, wxTE_MULTILINE),
1, wxEXPAND);
sizerSplit->Add(x86_box = new wxTextCtrl(this, wxID_ANY, "(x86)", wxDefaultPosition,
wxDefaultSize, wxTE_MULTILINE),
1, wxEXPAND);
sizerBig->Add(block_list = new JitBlockList(this, wxID_ANY, wxDefaultPosition, wxSize(100, 140),
wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT |
wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING),
0, wxEXPAND);
sizerBig->Add(sizerSplit, 2, wxEXPAND);
sizerBig->Add(button_refresh = new wxButton(this, wxID_ANY, _("&Refresh")));
button_refresh->Bind(wxEVT_BUTTON, &CJitWindow::OnRefresh, this);
sizerBig->Add(button_refresh = new wxButton(this, wxID_ANY, _("&Refresh")));
button_refresh->Bind(wxEVT_BUTTON, &CJitWindow::OnRefresh, this);
SetSizer(sizerBig);
SetSizer(sizerBig);
sizerSplit->Fit(this);
sizerBig->Fit(this);
sizerSplit->Fit(this);
sizerBig->Fit(this);
#if defined(_M_X86)
m_disassembler.reset(GetNewDisassembler("x86"));
m_disassembler.reset(GetNewDisassembler("x86"));
#elif defined(_M_ARM_64)
m_disassembler.reset(GetNewDisassembler("aarch64"));
m_disassembler.reset(GetNewDisassembler("aarch64"));
#else
m_disassembler.reset(GetNewDisassembler("UNK"));
m_disassembler.reset(GetNewDisassembler("UNK"));
#endif
}
void CJitWindow::OnRefresh(wxCommandEvent& /*event*/)
{
block_list->Update();
block_list->Update();
}
void CJitWindow::ViewAddr(u32 em_address)
{
Show(true);
Compare(em_address);
SetFocus();
Show(true);
Compare(em_address);
SetFocus();
}
void CJitWindow::Compare(u32 em_address)
{
// Get host side code disassembly
u32 host_instructions_count = 0;
u32 host_code_size = 0;
std::string host_instructions_disasm;
host_instructions_disasm = DisassembleBlock(m_disassembler.get(), &em_address, &host_instructions_count, &host_code_size);
// Get host side code disassembly
u32 host_instructions_count = 0;
u32 host_code_size = 0;
std::string host_instructions_disasm;
host_instructions_disasm = DisassembleBlock(m_disassembler.get(), &em_address,
&host_instructions_count, &host_code_size);
x86_box->SetValue(host_instructions_disasm);
x86_box->SetValue(host_instructions_disasm);
// == Fill in ppc box
u32 ppc_addr = em_address;
PPCAnalyst::CodeBuffer code_buffer(32000);
PPCAnalyst::BlockStats st;
PPCAnalyst::BlockRegStats gpa;
PPCAnalyst::BlockRegStats fpa;
PPCAnalyst::CodeBlock code_block;
PPCAnalyst::PPCAnalyzer analyzer;
analyzer.SetOption(PPCAnalyst::PPCAnalyzer::OPTION_CONDITIONAL_CONTINUE);
// == Fill in ppc box
u32 ppc_addr = em_address;
PPCAnalyst::CodeBuffer code_buffer(32000);
PPCAnalyst::BlockStats st;
PPCAnalyst::BlockRegStats gpa;
PPCAnalyst::BlockRegStats fpa;
PPCAnalyst::CodeBlock code_block;
PPCAnalyst::PPCAnalyzer analyzer;
analyzer.SetOption(PPCAnalyst::PPCAnalyzer::OPTION_CONDITIONAL_CONTINUE);
code_block.m_stats = &st;
code_block.m_gpa = &gpa;
code_block.m_fpa = &fpa;
code_block.m_stats = &st;
code_block.m_gpa = &gpa;
code_block.m_fpa = &fpa;
if (analyzer.Analyze(ppc_addr, &code_block, &code_buffer, 32000) != 0xFFFFFFFF)
{
std::ostringstream ppc_disasm;
for (u32 i = 0; i < code_block.m_num_instructions; i++)
{
const PPCAnalyst::CodeOp &op = code_buffer.codebuffer[i];
std::string opcode = GekkoDisassembler::Disassemble(op.inst.hex, op.address);
ppc_disasm << std::setfill('0') << std::setw(8) << std::hex << op.address;
ppc_disasm << " " << opcode << std::endl;
}
if (analyzer.Analyze(ppc_addr, &code_block, &code_buffer, 32000) != 0xFFFFFFFF)
{
std::ostringstream ppc_disasm;
for (u32 i = 0; i < code_block.m_num_instructions; i++)
{
const PPCAnalyst::CodeOp& op = code_buffer.codebuffer[i];
std::string opcode = GekkoDisassembler::Disassemble(op.inst.hex, op.address);
ppc_disasm << std::setfill('0') << std::setw(8) << std::hex << op.address;
ppc_disasm << " " << opcode << std::endl;
}
// Add stats to the end of the ppc box since it's generally the shortest.
ppc_disasm << std::dec << std::endl;
// Add stats to the end of the ppc box since it's generally the shortest.
ppc_disasm << std::dec << std::endl;
// Add some generic analysis
if (st.isFirstBlockOfFunction)
ppc_disasm << "(first block of function)" << std::endl;
if (st.isLastBlockOfFunction)
ppc_disasm << "(last block of function)" << std::endl;
// Add some generic analysis
if (st.isFirstBlockOfFunction)
ppc_disasm << "(first block of function)" << std::endl;
if (st.isLastBlockOfFunction)
ppc_disasm << "(last block of function)" << std::endl;
ppc_disasm << st.numCycles << " estimated cycles" << std::endl;
ppc_disasm << st.numCycles << " estimated cycles" << std::endl;
ppc_disasm << "Num instr: PPC: " << code_block.m_num_instructions
<< " x86: " << host_instructions_count
<< " (blowup: " << 100 * host_instructions_count / code_block.m_num_instructions - 100
<< "%)" << std::endl;
ppc_disasm << "Num instr: PPC: " << code_block.m_num_instructions
<< " x86: " << host_instructions_count << " (blowup: "
<< 100 * host_instructions_count / code_block.m_num_instructions - 100 << "%)"
<< std::endl;
ppc_disasm << "Num bytes: PPC: " << code_block.m_num_instructions * 4
<< " x86: " << host_code_size
<< " (blowup: " << 100 * host_code_size / (4 * code_block.m_num_instructions) - 100
<< "%)" << std::endl;
ppc_disasm << "Num bytes: PPC: " << code_block.m_num_instructions * 4
<< " x86: " << host_code_size
<< " (blowup: " << 100 * host_code_size / (4 * code_block.m_num_instructions) - 100
<< "%)" << std::endl;
ppc_box->SetValue(ppc_disasm.str());
}
else
{
ppc_box->SetValue(StringFromFormat("(non-code address: %08x)", em_address));
x86_box->SetValue("---");
}
ppc_box->SetValue(ppc_disasm.str());
}
else
{
ppc_box->SetValue(StringFromFormat("(non-code address: %08x)", em_address));
x86_box->SetValue("---");
}
}
void CJitWindow::Update()
{
}
void CJitWindow::OnHostMessage(wxCommandEvent& event)
{
switch (event.GetId())
{
case IDM_NOTIFY_MAP_LOADED:
//NotifyMapLoaded();
break;
}
switch (event.GetId())
{
case IDM_NOTIFY_MAP_LOADED:
// NotifyMapLoaded();
break;
}
}
// JitBlockList
@ -152,31 +154,31 @@ void CJitWindow::OnHostMessage(wxCommandEvent& event)
enum
{
COLUMN_ADDRESS,
COLUMN_PPCSIZE,
COLUMN_X86SIZE,
COLUMN_NAME,
COLUMN_FLAGS,
COLUMN_NUMEXEC,
COLUMN_COST, // (estimated as x86size * numexec)
COLUMN_ADDRESS,
COLUMN_PPCSIZE,
COLUMN_X86SIZE,
COLUMN_NAME,
COLUMN_FLAGS,
COLUMN_NUMEXEC,
COLUMN_COST, // (estimated as x86size * numexec)
};
JitBlockList::JitBlockList(wxWindow* parent, const wxWindowID id,
const wxPoint& pos, const wxSize& size, long style)
: wxListCtrl(parent, id, pos, size, style) // | wxLC_VIRTUAL)
JitBlockList::JitBlockList(wxWindow* parent, const wxWindowID id, const wxPoint& pos,
const wxSize& size, long style)
: wxListCtrl(parent, id, pos, size, style) // | wxLC_VIRTUAL)
{
Init();
Init();
}
void JitBlockList::Init()
{
InsertColumn(COLUMN_ADDRESS, _("Address"));
InsertColumn(COLUMN_PPCSIZE, _("PPC Size"));
InsertColumn(COLUMN_X86SIZE, _("x86 Size"));
InsertColumn(COLUMN_NAME, _("Symbol"));
InsertColumn(COLUMN_FLAGS, _("Flags"));
InsertColumn(COLUMN_NUMEXEC, _("NumExec"));
InsertColumn(COLUMN_COST, _("Cost"));
InsertColumn(COLUMN_ADDRESS, _("Address"));
InsertColumn(COLUMN_PPCSIZE, _("PPC Size"));
InsertColumn(COLUMN_X86SIZE, _("x86 Size"));
InsertColumn(COLUMN_NAME, _("Symbol"));
InsertColumn(COLUMN_FLAGS, _("Flags"));
InsertColumn(COLUMN_NUMEXEC, _("NumExec"));
InsertColumn(COLUMN_COST, _("Cost"));
}
void JitBlockList::Update()

View File

@ -19,33 +19,31 @@ class wxTextCtrl;
class JitBlockList : public wxListCtrl
{
public:
JitBlockList(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style);
void Init();
void Update() override;
JitBlockList(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size,
long style);
void Init();
void Update() override;
};
class CJitWindow : public wxPanel
{
public:
CJitWindow(wxWindow* parent,
wxWindowID id = wxID_ANY,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxTAB_TRAVERSAL | wxBORDER_NONE,
const wxString& name = _("JIT Block Viewer"));
CJitWindow(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL | wxBORDER_NONE,
const wxString& name = _("JIT Block Viewer"));
void ViewAddr(u32 em_address);
void Update() override;
void ViewAddr(u32 em_address);
void Update() override;
private:
void OnRefresh(wxCommandEvent& /*event*/);
void Compare(u32 em_address);
void OnRefresh(wxCommandEvent& /*event*/);
void Compare(u32 em_address);
JitBlockList* block_list;
std::unique_ptr<HostDisassembler> m_disassembler;
wxButton* button_refresh;
wxTextCtrl* ppc_box;
wxTextCtrl* x86_box;
JitBlockList* block_list;
std::unique_ptr<HostDisassembler> m_disassembler;
wxButton* button_refresh;
wxTextCtrl* ppc_box;
wxTextCtrl* x86_box;
void OnHostMessage(wxCommandEvent& event);
void OnHostMessage(wxCommandEvent& event);
};

View File

@ -13,88 +13,87 @@
#include "Common/CommonTypes.h"
#include "Common/StringUtil.h"
#include "Core/PowerPC/PowerPC.h"
#include "DolphinWX/WxUtils.h"
#include "DolphinWX/Debugger/BreakpointWindow.h"
#include "DolphinWX/Debugger/MemoryCheckDlg.h"
#include "DolphinWX/WxUtils.h"
#define TEXT_BOX(text) new wxStaticText(this, wxID_ANY, _(text))
MemoryCheckDlg::MemoryCheckDlg(CBreakPointWindow *parent)
: wxDialog(parent, wxID_ANY, _("Memory Check"))
, m_parent(parent)
MemoryCheckDlg::MemoryCheckDlg(CBreakPointWindow* parent)
: wxDialog(parent, wxID_ANY, _("Memory Check")), m_parent(parent)
{
Bind(wxEVT_BUTTON, &MemoryCheckDlg::OnOK, this, wxID_OK);
Bind(wxEVT_BUTTON, &MemoryCheckDlg::OnOK, this, wxID_OK);
m_pEditStartAddress = new wxTextCtrl(this, wxID_ANY, "");
m_pEditEndAddress = new wxTextCtrl(this, wxID_ANY, "");
m_pWriteFlag = new wxCheckBox(this, wxID_ANY, _("Write"));
m_pWriteFlag->SetValue(true);
m_pReadFlag = new wxCheckBox(this, wxID_ANY, _("Read"));
m_pEditStartAddress = new wxTextCtrl(this, wxID_ANY, "");
m_pEditEndAddress = new wxTextCtrl(this, wxID_ANY, "");
m_pWriteFlag = new wxCheckBox(this, wxID_ANY, _("Write"));
m_pWriteFlag->SetValue(true);
m_pReadFlag = new wxCheckBox(this, wxID_ANY, _("Read"));
m_log_flag = new wxCheckBox(this, wxID_ANY, _("Log"));
m_log_flag->SetValue(true);
m_break_flag = new wxCheckBox(this, wxID_ANY, _("Break"));
m_log_flag = new wxCheckBox(this, wxID_ANY, _("Log"));
m_log_flag->SetValue(true);
m_break_flag = new wxCheckBox(this, wxID_ANY, _("Break"));
wxStaticBoxSizer *sAddressRangeBox = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Address Range"));
sAddressRangeBox->Add(TEXT_BOX("Start"), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
sAddressRangeBox->Add(m_pEditStartAddress, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT, 10);
sAddressRangeBox->Add(TEXT_BOX("End"), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
sAddressRangeBox->Add(m_pEditEndAddress, 1, wxALIGN_CENTER_VERTICAL);
wxStaticBoxSizer* sAddressRangeBox = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Address Range"));
sAddressRangeBox->Add(TEXT_BOX("Start"), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
sAddressRangeBox->Add(m_pEditStartAddress, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT, 10);
sAddressRangeBox->Add(TEXT_BOX("End"), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
sAddressRangeBox->Add(m_pEditEndAddress, 1, wxALIGN_CENTER_VERTICAL);
wxStaticBoxSizer *sActionBox = new wxStaticBoxSizer(wxVERTICAL, this, _("Action"));
sActionBox->Add(m_pWriteFlag);
sActionBox->Add(m_pReadFlag);
wxStaticBoxSizer* sActionBox = new wxStaticBoxSizer(wxVERTICAL, this, _("Action"));
sActionBox->Add(m_pWriteFlag);
sActionBox->Add(m_pReadFlag);
wxBoxSizer* sFlags = new wxStaticBoxSizer(wxVERTICAL, this, _("Flags"));
sFlags->Add(m_log_flag);
sFlags->Add(m_break_flag);
wxBoxSizer* sFlags = new wxStaticBoxSizer(wxVERTICAL, this, _("Flags"));
sFlags->Add(m_log_flag);
sFlags->Add(m_break_flag);
wxBoxSizer *sControls = new wxBoxSizer(wxHORIZONTAL);
sControls->Add(sAddressRangeBox, 0, wxEXPAND);
sControls->Add(sActionBox, 0, wxEXPAND);
sControls->Add(sFlags, 0, wxEXPAND);
wxBoxSizer* sControls = new wxBoxSizer(wxHORIZONTAL);
sControls->Add(sAddressRangeBox, 0, wxEXPAND);
sControls->Add(sActionBox, 0, wxEXPAND);
sControls->Add(sFlags, 0, wxEXPAND);
wxBoxSizer *sMainSizer = new wxBoxSizer(wxVERTICAL);
sMainSizer->Add(sControls, 0, wxEXPAND | wxALL, 5);
sMainSizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
wxBoxSizer* sMainSizer = new wxBoxSizer(wxVERTICAL);
sMainSizer->Add(sControls, 0, wxEXPAND | wxALL, 5);
sMainSizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
SetSizerAndFit(sMainSizer);
SetFocus();
SetSizerAndFit(sMainSizer);
SetFocus();
}
void MemoryCheckDlg::OnOK(wxCommandEvent& event)
{
wxString StartAddressString = m_pEditStartAddress->GetLineText(0);
wxString EndAddressString = m_pEditEndAddress->GetLineText(0);
bool OnRead = m_pReadFlag->GetValue();
bool OnWrite = m_pWriteFlag->GetValue();
bool Log = m_log_flag->GetValue();
bool Break = m_break_flag->GetValue();
wxString StartAddressString = m_pEditStartAddress->GetLineText(0);
wxString EndAddressString = m_pEditEndAddress->GetLineText(0);
bool OnRead = m_pReadFlag->GetValue();
bool OnWrite = m_pWriteFlag->GetValue();
bool Log = m_log_flag->GetValue();
bool Break = m_break_flag->GetValue();
u32 StartAddress, EndAddress;
bool EndAddressOK = EndAddressString.Len() &&
AsciiToHex(WxStrToStr(EndAddressString), EndAddress);
u32 StartAddress, EndAddress;
bool EndAddressOK =
EndAddressString.Len() && AsciiToHex(WxStrToStr(EndAddressString), EndAddress);
if (AsciiToHex(WxStrToStr(StartAddressString), StartAddress) &&
(OnRead || OnWrite) && (Log || Break))
{
TMemCheck MemCheck;
if (AsciiToHex(WxStrToStr(StartAddressString), StartAddress) && (OnRead || OnWrite) &&
(Log || Break))
{
TMemCheck MemCheck;
if (!EndAddressOK)
EndAddress = StartAddress;
if (!EndAddressOK)
EndAddress = StartAddress;
MemCheck.StartAddress = StartAddress;
MemCheck.EndAddress = EndAddress;
MemCheck.bRange = StartAddress != EndAddress;
MemCheck.OnRead = OnRead;
MemCheck.OnWrite = OnWrite;
MemCheck.Log = Log;
MemCheck.Break = Break;
MemCheck.StartAddress = StartAddress;
MemCheck.EndAddress = EndAddress;
MemCheck.bRange = StartAddress != EndAddress;
MemCheck.OnRead = OnRead;
MemCheck.OnWrite = OnWrite;
MemCheck.Log = Log;
MemCheck.Break = Break;
PowerPC::memchecks.Add(MemCheck);
m_parent->NotifyUpdate();
Close();
}
PowerPC::memchecks.Add(MemCheck);
m_parent->NotifyUpdate();
Close();
}
event.Skip();
event.Skip();
}

View File

@ -13,16 +13,16 @@ class wxTextCtrl;
class MemoryCheckDlg : public wxDialog
{
public:
MemoryCheckDlg(CBreakPointWindow *parent);
MemoryCheckDlg(CBreakPointWindow* parent);
private:
CBreakPointWindow *m_parent;
wxCheckBox* m_pReadFlag;
wxCheckBox* m_pWriteFlag;
wxCheckBox* m_log_flag;
wxCheckBox* m_break_flag;
wxTextCtrl* m_pEditEndAddress;
wxTextCtrl* m_pEditStartAddress;
CBreakPointWindow* m_parent;
wxCheckBox* m_pReadFlag;
wxCheckBox* m_pWriteFlag;
wxCheckBox* m_log_flag;
wxCheckBox* m_break_flag;
wxTextCtrl* m_pEditEndAddress;
wxTextCtrl* m_pEditStartAddress;
void OnOK(wxCommandEvent& event);
void OnOK(wxCommandEvent& event);
};

View File

@ -18,407 +18,388 @@
#include "Common/DebugInterface.h"
#include "Common/StringUtil.h"
#include "Core/PowerPC/PowerPC.h"
#include "DolphinWX/Frame.h"
#include "DolphinWX/Globals.h"
#include "DolphinWX/WxUtils.h"
#include "DolphinWX/Debugger/CodeWindow.h"
#include "DolphinWX/Debugger/DebuggerUIUtil.h"
#include "DolphinWX/Debugger/MemoryView.h"
#include "DolphinWX/Debugger/WatchWindow.h"
#include "DolphinWX/Frame.h"
#include "DolphinWX/Globals.h"
#include "DolphinWX/WxUtils.h"
enum
{
IDM_GOTOINMEMVIEW = 12000,
IDM_COPYADDRESS,
IDM_COPYHEX,
IDM_COPYCODE,
IDM_RUNTOHERE,
IDM_DYNARECRESULTS,
IDM_WATCHADDRESS,
IDM_TOGGLEMEMORY,
IDM_VIEWASFP,
IDM_VIEWASASCII,
IDM_VIEWASHEX,
IDM_GOTOINMEMVIEW = 12000,
IDM_COPYADDRESS,
IDM_COPYHEX,
IDM_COPYCODE,
IDM_RUNTOHERE,
IDM_DYNARECRESULTS,
IDM_WATCHADDRESS,
IDM_TOGGLEMEMORY,
IDM_VIEWASFP,
IDM_VIEWASASCII,
IDM_VIEWASHEX,
};
CMemoryView::CMemoryView(DebugInterface* debuginterface, wxWindow* parent)
: wxControl(parent, wxID_ANY)
, debugger(debuginterface)
, align(debuginterface->GetInstructionSize(0))
, rowHeight(13)
, selection(0)
, oldSelection(0)
, selecting(false)
, memory(0)
, curAddress(debuginterface->GetPC())
, dataType(MemoryDataType::U8)
, viewAsType(VIEWAS_FP)
: wxControl(parent, wxID_ANY), debugger(debuginterface),
align(debuginterface->GetInstructionSize(0)), rowHeight(13), selection(0), oldSelection(0),
selecting(false), memory(0), curAddress(debuginterface->GetPC()),
dataType(MemoryDataType::U8), viewAsType(VIEWAS_FP)
{
Bind(wxEVT_PAINT, &CMemoryView::OnPaint, this);
Bind(wxEVT_LEFT_DOWN, &CMemoryView::OnMouseDownL, this);
Bind(wxEVT_LEFT_UP, &CMemoryView::OnMouseUpL, this);
Bind(wxEVT_MOTION, &CMemoryView::OnMouseMove, this);
Bind(wxEVT_RIGHT_DOWN, &CMemoryView::OnMouseDownR, this);
Bind(wxEVT_MOUSEWHEEL, &CMemoryView::OnScrollWheel, this);
Bind(wxEVT_MENU, &CMemoryView::OnPopupMenu, this);
Bind(wxEVT_SIZE, &CMemoryView::OnResize, this);
Bind(wxEVT_PAINT, &CMemoryView::OnPaint, this);
Bind(wxEVT_LEFT_DOWN, &CMemoryView::OnMouseDownL, this);
Bind(wxEVT_LEFT_UP, &CMemoryView::OnMouseUpL, this);
Bind(wxEVT_MOTION, &CMemoryView::OnMouseMove, this);
Bind(wxEVT_RIGHT_DOWN, &CMemoryView::OnMouseDownR, this);
Bind(wxEVT_MOUSEWHEEL, &CMemoryView::OnScrollWheel, this);
Bind(wxEVT_MENU, &CMemoryView::OnPopupMenu, this);
Bind(wxEVT_SIZE, &CMemoryView::OnResize, this);
}
int CMemoryView::YToAddress(int y)
{
wxRect rc = GetClientRect();
int ydiff = y - rc.height / 2 - rowHeight / 2;
ydiff = (int)(floorf((float)ydiff / (float)rowHeight)) + 1;
return curAddress + ydiff * align;
wxRect rc = GetClientRect();
int ydiff = y - rc.height / 2 - rowHeight / 2;
ydiff = (int)(floorf((float)ydiff / (float)rowHeight)) + 1;
return curAddress + ydiff * align;
}
void CMemoryView::OnMouseDownL(wxMouseEvent& event)
{
int x = event.m_x;
int y = event.m_y;
int x = event.m_x;
int y = event.m_y;
if (x > 16)
{
oldSelection = selection;
selection = YToAddress(y);
bool oldselecting = selecting;
selecting = true;
if (x > 16)
{
oldSelection = selection;
selection = YToAddress(y);
bool oldselecting = selecting;
selecting = true;
if (!oldselecting || (selection != oldSelection))
Refresh();
}
else
{
debugger->ToggleMemCheck(YToAddress(y));
if (!oldselecting || (selection != oldSelection))
Refresh();
}
else
{
debugger->ToggleMemCheck(YToAddress(y));
Refresh();
Refresh();
// Propagate back to the parent window to update the breakpoint list.
wxCommandEvent evt(wxEVT_HOST_COMMAND, IDM_UPDATE_BREAKPOINTS);
GetEventHandler()->AddPendingEvent(evt);
}
// Propagate back to the parent window to update the breakpoint list.
wxCommandEvent evt(wxEVT_HOST_COMMAND, IDM_UPDATE_BREAKPOINTS);
GetEventHandler()->AddPendingEvent(evt);
}
event.Skip();
event.Skip();
}
void CMemoryView::OnMouseMove(wxMouseEvent& event)
{
wxRect rc = GetClientRect();
wxRect rc = GetClientRect();
if (event.m_leftDown && event.m_x > 16)
{
if (event.m_y < 0)
{
curAddress -= align;
Refresh();
}
else if (event.m_y > rc.height)
{
curAddress += align;
Refresh();
}
else
OnMouseDownL(event);
}
if (event.m_leftDown && event.m_x > 16)
{
if (event.m_y < 0)
{
curAddress -= align;
Refresh();
}
else if (event.m_y > rc.height)
{
curAddress += align;
Refresh();
}
else
OnMouseDownL(event);
}
event.Skip();
event.Skip();
}
void CMemoryView::OnMouseUpL(wxMouseEvent& event)
{
if (event.m_x > 16)
{
curAddress = YToAddress(event.m_y);
selecting = false;
Refresh();
}
if (event.m_x > 16)
{
curAddress = YToAddress(event.m_y);
selecting = false;
Refresh();
}
event.Skip();
event.Skip();
}
void CMemoryView::OnScrollWheel(wxMouseEvent& event)
{
const bool scroll_down = (event.GetWheelRotation() < 0);
const int num_lines = event.GetLinesPerAction();
const bool scroll_down = (event.GetWheelRotation() < 0);
const int num_lines = event.GetLinesPerAction();
if (scroll_down)
{
curAddress += num_lines * 4;
}
else
{
curAddress -= num_lines * 4;
}
if (scroll_down)
{
curAddress += num_lines * 4;
}
else
{
curAddress -= num_lines * 4;
}
Refresh();
event.Skip();
Refresh();
event.Skip();
}
void CMemoryView::OnPopupMenu(wxCommandEvent& event)
{
CFrame* main_frame = static_cast<CFrame*>(GetGrandParent()->GetParent());
CCodeWindow* code_window = main_frame->g_pCodeWindow;
CWatchWindow* watch_window = code_window->m_WatchWindow;
CFrame* main_frame = static_cast<CFrame*>(GetGrandParent()->GetParent());
CCodeWindow* code_window = main_frame->g_pCodeWindow;
CWatchWindow* watch_window = code_window->m_WatchWindow;
#if wxUSE_CLIPBOARD
wxTheClipboard->Open();
wxTheClipboard->Open();
#endif
switch (event.GetId())
{
switch (event.GetId())
{
#if wxUSE_CLIPBOARD
case IDM_COPYADDRESS:
wxTheClipboard->SetData(new wxTextDataObject(wxString::Format("%08x", selection)));
break;
case IDM_COPYADDRESS:
wxTheClipboard->SetData(new wxTextDataObject(wxString::Format("%08x", selection)));
break;
case IDM_COPYHEX:
{
std::string temp = StringFromFormat("%08x", debugger->ReadExtraMemory(memory, selection));
wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(temp)));
}
break;
case IDM_COPYHEX:
{
std::string temp = StringFromFormat("%08x", debugger->ReadExtraMemory(memory, selection));
wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(temp)));
}
break;
#endif
case IDM_WATCHADDRESS:
debugger->AddWatch(selection);
if (watch_window)
watch_window->NotifyUpdate();
Refresh();
break;
case IDM_WATCHADDRESS:
debugger->AddWatch(selection);
if (watch_window)
watch_window->NotifyUpdate();
Refresh();
break;
case IDM_TOGGLEMEMORY:
memory ^= 1;
Refresh();
break;
case IDM_TOGGLEMEMORY:
memory ^= 1;
Refresh();
break;
case IDM_VIEWASFP:
viewAsType = VIEWAS_FP;
Refresh();
break;
case IDM_VIEWASFP:
viewAsType = VIEWAS_FP;
Refresh();
break;
case IDM_VIEWASASCII:
viewAsType = VIEWAS_ASCII;
Refresh();
break;
case IDM_VIEWASHEX:
viewAsType = VIEWAS_HEX;
Refresh();
break;
}
case IDM_VIEWASASCII:
viewAsType = VIEWAS_ASCII;
Refresh();
break;
case IDM_VIEWASHEX:
viewAsType = VIEWAS_HEX;
Refresh();
break;
}
#if wxUSE_CLIPBOARD
wxTheClipboard->Close();
wxTheClipboard->Close();
#endif
event.Skip();
event.Skip();
}
void CMemoryView::OnMouseDownR(wxMouseEvent& event)
{
// popup menu
wxMenu menu;
//menu.Append(IDM_GOTOINMEMVIEW, _("&Goto in mem view"));
// popup menu
wxMenu menu;
// menu.Append(IDM_GOTOINMEMVIEW, _("&Goto in mem view"));
#if wxUSE_CLIPBOARD
menu.Append(IDM_COPYADDRESS, _("Copy &address"));
menu.Append(IDM_COPYHEX, _("Copy &hex"));
menu.Append(IDM_COPYADDRESS, _("Copy &address"));
menu.Append(IDM_COPYHEX, _("Copy &hex"));
#endif
menu.Append(IDM_WATCHADDRESS, _("Add to &watch"));
menu.Append(IDM_TOGGLEMEMORY, _("Toggle &memory"));
menu.Append(IDM_WATCHADDRESS, _("Add to &watch"));
menu.Append(IDM_TOGGLEMEMORY, _("Toggle &memory"));
wxMenu* viewAsSubMenu = new wxMenu;
viewAsSubMenu->Append(IDM_VIEWASFP, _("FP value"));
viewAsSubMenu->Append(IDM_VIEWASASCII, "ASCII");
viewAsSubMenu->Append(IDM_VIEWASHEX, _("Hex"));
menu.AppendSubMenu(viewAsSubMenu, _("View As:"));
wxMenu* viewAsSubMenu = new wxMenu;
viewAsSubMenu->Append(IDM_VIEWASFP, _("FP value"));
viewAsSubMenu->Append(IDM_VIEWASASCII, "ASCII");
viewAsSubMenu->Append(IDM_VIEWASHEX, _("Hex"));
menu.AppendSubMenu(viewAsSubMenu, _("View As:"));
PopupMenu(&menu);
PopupMenu(&menu);
}
void CMemoryView::OnPaint(wxPaintEvent& event)
{
wxPaintDC dc(this);
wxRect rc = GetClientRect();
wxFont hFont("Courier");
hFont.SetFamily(wxFONTFAMILY_TELETYPE);
wxPaintDC dc(this);
wxRect rc = GetClientRect();
wxFont hFont("Courier");
hFont.SetFamily(wxFONTFAMILY_TELETYPE);
wxCoord w,h;
dc.GetTextExtent("0WJyq", &w, &h, nullptr, nullptr, &hFont);
if (h > rowHeight)
rowHeight = h;
dc.GetTextExtent("0WJyq", &w, &h, nullptr, nullptr, &DebuggerFont);
if (h > rowHeight)
rowHeight = h;
wxCoord w, h;
dc.GetTextExtent("0WJyq", &w, &h, nullptr, nullptr, &hFont);
if (h > rowHeight)
rowHeight = h;
dc.GetTextExtent("0WJyq", &w, &h, nullptr, nullptr, &DebuggerFont);
if (h > rowHeight)
rowHeight = h;
if (viewAsType==VIEWAS_HEX)
dc.SetFont(hFont);
else
dc.SetFont(DebuggerFont);
if (viewAsType == VIEWAS_HEX)
dc.SetFont(hFont);
else
dc.SetFont(DebuggerFont);
dc.GetTextExtent("W", &w, &h);
int fontSize = w;
int textPlacement = 17 + 9 * fontSize;
dc.GetTextExtent("W", &w, &h);
int fontSize = w;
int textPlacement = 17 + 9 * fontSize;
// TODO: Add any drawing code here...
int width = rc.width;
int numRows = (rc.height / rowHeight) / 2 + 2;
dc.SetBackgroundMode(wxTRANSPARENT);
const wxColour bgColor = *wxWHITE;
wxPen nullPen(bgColor);
wxPen currentPen(*wxBLACK_PEN);
wxPen selPen(*wxGREY_PEN);
nullPen.SetStyle(wxTRANSPARENT);
// TODO: Add any drawing code here...
int width = rc.width;
int numRows = (rc.height / rowHeight) / 2 + 2;
dc.SetBackgroundMode(wxTRANSPARENT);
const wxColour bgColor = *wxWHITE;
wxPen nullPen(bgColor);
wxPen currentPen(*wxBLACK_PEN);
wxPen selPen(*wxGREY_PEN);
nullPen.SetStyle(wxTRANSPARENT);
wxBrush currentBrush(*wxLIGHT_GREY_BRUSH);
wxBrush pcBrush(*wxGREEN_BRUSH);
wxBrush mcBrush(*wxBLUE_BRUSH);
wxBrush bgBrush(bgColor);
wxBrush nullBrush(bgColor);
nullBrush.SetStyle(wxTRANSPARENT);
wxBrush currentBrush(*wxLIGHT_GREY_BRUSH);
wxBrush pcBrush(*wxGREEN_BRUSH);
wxBrush mcBrush(*wxBLUE_BRUSH);
wxBrush bgBrush(bgColor);
wxBrush nullBrush(bgColor);
nullBrush.SetStyle(wxTRANSPARENT);
dc.SetPen(nullPen);
dc.SetBrush(bgBrush);
dc.DrawRectangle(0, 0, 16, rc.height);
dc.DrawRectangle(0, 0, rc.width, 5+8);
dc.SetPen(nullPen);
dc.SetBrush(bgBrush);
dc.DrawRectangle(0, 0, 16, rc.height);
dc.DrawRectangle(0, 0, rc.width, 5 + 8);
// TODO - clean up this freaking mess!!!!!
for (int row = -numRows; row <= numRows; row++)
{
unsigned int address = curAddress + row * align;
// TODO - clean up this freaking mess!!!!!
for (int row = -numRows; row <= numRows; row++)
{
unsigned int address = curAddress + row * align;
int rowY1 = rc.height / 2 + rowHeight * row - rowHeight / 2;
int rowY2 = rc.height / 2 + rowHeight * row + rowHeight / 2;
int rowY1 = rc.height / 2 + rowHeight * row - rowHeight / 2;
int rowY2 = rc.height / 2 + rowHeight * row + rowHeight / 2;
wxString temp = wxString::Format("%08x", address);
u32 col = debugger->GetColor(address);
wxBrush rowBrush(wxColour(col >> 16, col >> 8, col));
dc.SetBrush(nullBrush);
dc.SetPen(nullPen);
dc.DrawRectangle(0, rowY1, 16, rowY2);
wxString temp = wxString::Format("%08x", address);
u32 col = debugger->GetColor(address);
wxBrush rowBrush(wxColour(col >> 16, col >> 8, col));
dc.SetBrush(nullBrush);
dc.SetPen(nullPen);
dc.DrawRectangle(0, rowY1, 16, rowY2);
if (selecting && (address == selection))
dc.SetPen(selPen);
else
dc.SetPen(row == 0 ? currentPen : nullPen);
if (selecting && (address == selection))
dc.SetPen(selPen);
else
dc.SetPen(row == 0 ? currentPen : nullPen);
if (address == debugger->GetPC())
dc.SetBrush(pcBrush);
else
dc.SetBrush(rowBrush);
if (address == debugger->GetPC())
dc.SetBrush(pcBrush);
else
dc.SetBrush(rowBrush);
dc.DrawRectangle(16, rowY1, width, rowY2 - 1);
dc.SetBrush(currentBrush);
dc.SetTextForeground("#600000"); // Dark red
dc.DrawText(temp, 17, rowY1);
dc.DrawRectangle(16, rowY1, width, rowY2 - 1);
dc.SetBrush(currentBrush);
dc.SetTextForeground("#600000"); // Dark red
dc.DrawText(temp, 17, rowY1);
if (viewAsType != VIEWAS_HEX)
{
char mem[256];
debugger->GetRawMemoryString(memory, address, mem, 256);
dc.SetTextForeground(wxTheColourDatabase->Find("NAVY"));
dc.DrawText(StrToWxStr(mem), 17+fontSize*(8), rowY1);
dc.SetTextForeground(*wxBLACK);
}
if (viewAsType != VIEWAS_HEX)
{
char mem[256];
debugger->GetRawMemoryString(memory, address, mem, 256);
dc.SetTextForeground(wxTheColourDatabase->Find("NAVY"));
dc.DrawText(StrToWxStr(mem), 17 + fontSize * (8), rowY1);
dc.SetTextForeground(*wxBLACK);
}
if (!PowerPC::HostIsRAMAddress(address))
continue;
if (!PowerPC::HostIsRAMAddress(address))
continue;
if (debugger->IsAlive())
{
std::string dis;
u32 mem_data = debugger->ReadExtraMemory(memory, address);
if (debugger->IsAlive())
{
std::string dis;
u32 mem_data = debugger->ReadExtraMemory(memory, address);
if (viewAsType == VIEWAS_FP)
{
float flt = *(float *)(&mem_data);
dis = StringFromFormat("f: %f", flt);
}
else if (viewAsType == VIEWAS_ASCII)
{
u32 a[4] = {
(mem_data & 0xff000000) >> 24,
(mem_data & 0xff0000) >> 16,
(mem_data & 0xff00) >> 8,
(mem_data & 0xff)
};
if (viewAsType == VIEWAS_FP)
{
float flt = *(float*)(&mem_data);
dis = StringFromFormat("f: %f", flt);
}
else if (viewAsType == VIEWAS_ASCII)
{
u32 a[4] = {(mem_data & 0xff000000) >> 24, (mem_data & 0xff0000) >> 16,
(mem_data & 0xff00) >> 8, (mem_data & 0xff)};
for (auto& word : a)
{
if (word == '\0')
word = ' ';
}
for (auto& word : a)
{
if (word == '\0')
word = ' ';
}
dis = StringFromFormat("%c%c%c%c", a[0], a[1], a[2], a[3]);
}
else if (viewAsType == VIEWAS_HEX)
{
u32 mema[8] = {
debugger->ReadExtraMemory(memory, address),
debugger->ReadExtraMemory(memory, address+4),
debugger->ReadExtraMemory(memory, address+8),
debugger->ReadExtraMemory(memory, address+12),
debugger->ReadExtraMemory(memory, address+16),
debugger->ReadExtraMemory(memory, address+20),
debugger->ReadExtraMemory(memory, address+24),
debugger->ReadExtraMemory(memory, address+28)
};
dis = StringFromFormat("%c%c%c%c", a[0], a[1], a[2], a[3]);
}
else if (viewAsType == VIEWAS_HEX)
{
u32 mema[8] = {debugger->ReadExtraMemory(memory, address),
debugger->ReadExtraMemory(memory, address + 4),
debugger->ReadExtraMemory(memory, address + 8),
debugger->ReadExtraMemory(memory, address + 12),
debugger->ReadExtraMemory(memory, address + 16),
debugger->ReadExtraMemory(memory, address + 20),
debugger->ReadExtraMemory(memory, address + 24),
debugger->ReadExtraMemory(memory, address + 28)};
for (auto& word : mema)
{
switch (dataType)
{
case MemoryDataType::U8:
dis += StringFromFormat(" %02X %02X %02X %02X",
((word & 0xff000000) >> 24) & 0xFF,
((word & 0xff0000) >> 16) & 0xFF,
((word & 0xff00) >> 8) & 0xFF,
word & 0xff);
break;
case MemoryDataType::U16:
dis += StringFromFormat(" %02X%02X %02X%02X",
((word & 0xff000000) >> 24) & 0xFF,
((word & 0xff0000) >> 16) & 0xFF,
((word & 0xff00) >> 8) & 0xFF,
word & 0xff);
break;
case MemoryDataType::U32:
dis += StringFromFormat(" %02X%02X%02X%02X",
((word & 0xff000000) >> 24) & 0xFF,
((word & 0xff0000) >> 16) & 0xFF,
((word & 0xff00) >> 8) & 0xFF,
word & 0xff);
break;
}
}
}
else
{
dis = "INVALID VIEWAS TYPE";
}
for (auto& word : mema)
{
switch (dataType)
{
case MemoryDataType::U8:
dis += StringFromFormat(" %02X %02X %02X %02X", ((word & 0xff000000) >> 24) & 0xFF,
((word & 0xff0000) >> 16) & 0xFF, ((word & 0xff00) >> 8) & 0xFF,
word & 0xff);
break;
case MemoryDataType::U16:
dis += StringFromFormat(" %02X%02X %02X%02X", ((word & 0xff000000) >> 24) & 0xFF,
((word & 0xff0000) >> 16) & 0xFF, ((word & 0xff00) >> 8) & 0xFF,
word & 0xff);
break;
case MemoryDataType::U32:
dis += StringFromFormat(" %02X%02X%02X%02X", ((word & 0xff000000) >> 24) & 0xFF,
((word & 0xff0000) >> 16) & 0xFF, ((word & 0xff00) >> 8) & 0xFF,
word & 0xff);
break;
}
}
}
else
{
dis = "INVALID VIEWAS TYPE";
}
if (viewAsType != VIEWAS_HEX)
dc.DrawText(StrToWxStr(dis), textPlacement + fontSize*(8 + 8), rowY1);
else
dc.DrawText(StrToWxStr(dis), textPlacement, rowY1);
if (viewAsType != VIEWAS_HEX)
dc.DrawText(StrToWxStr(dis), textPlacement + fontSize * (8 + 8), rowY1);
else
dc.DrawText(StrToWxStr(dis), textPlacement, rowY1);
dc.SetTextForeground(*wxBLUE);
dc.SetTextForeground(*wxBLUE);
std::string desc = debugger->GetDescription(address);
if (!desc.empty())
dc.DrawText(StrToWxStr(desc), 17+fontSize*((8+8+8+30)*2), rowY1);
std::string desc = debugger->GetDescription(address);
if (!desc.empty())
dc.DrawText(StrToWxStr(desc), 17 + fontSize * ((8 + 8 + 8 + 30) * 2), rowY1);
// Show blue memory check dot
if (debugger->IsMemCheck(address))
{
dc.SetBrush(mcBrush);
dc.DrawRectangle(8, rowY1 + 1, 11, 11);
}
}
}
// Show blue memory check dot
if (debugger->IsMemCheck(address))
{
dc.SetBrush(mcBrush);
dc.DrawRectangle(8, rowY1 + 1, 11, 11);
}
}
}
dc.SetPen(currentPen);
dc.SetPen(currentPen);
}
void CMemoryView::OnResize(wxSizeEvent& event)
{
Refresh();
event.Skip();
Refresh();
event.Skip();
}

View File

@ -11,60 +11,61 @@ class DebugInterface;
enum class MemoryDataType
{
U8, U16, U32
U8,
U16,
U32
};
class CMemoryView : public wxControl
{
public:
CMemoryView(DebugInterface* debuginterface, wxWindow* parent);
CMemoryView(DebugInterface* debuginterface, wxWindow* parent);
u32 GetSelection() const { return selection ; }
int GetMemoryType() const { return memory; }
u32 GetSelection() const { return selection; }
int GetMemoryType() const { return memory; }
void Center(u32 addr)
{
curAddress = addr;
Refresh();
}
void Center(u32 addr)
{
curAddress = addr;
Refresh();
}
void SetDataType(MemoryDataType data_type)
{
dataType = data_type;
Refresh();
}
void SetDataType(MemoryDataType data_type)
{
dataType = data_type;
Refresh();
}
private:
void OnPaint(wxPaintEvent& event);
void OnMouseDownL(wxMouseEvent& event);
void OnMouseMove(wxMouseEvent& event);
void OnMouseUpL(wxMouseEvent& event);
void OnMouseDownR(wxMouseEvent& event);
void OnScrollWheel(wxMouseEvent& event);
void OnPopupMenu(wxCommandEvent& event);
void OnPaint(wxPaintEvent& event);
void OnMouseDownL(wxMouseEvent& event);
void OnMouseMove(wxMouseEvent& event);
void OnMouseUpL(wxMouseEvent& event);
void OnMouseDownR(wxMouseEvent& event);
void OnScrollWheel(wxMouseEvent& event);
void OnPopupMenu(wxCommandEvent& event);
int YToAddress(int y);
void OnResize(wxSizeEvent& event);
int YToAddress(int y);
void OnResize(wxSizeEvent& event);
DebugInterface* debugger;
DebugInterface* debugger;
int align;
int rowHeight;
int align;
int rowHeight;
u32 selection;
u32 oldSelection;
bool selecting;
u32 selection;
u32 oldSelection;
bool selecting;
int memory;
int curAddress;
MemoryDataType dataType;
int memory;
int curAddress;
MemoryDataType dataType;
enum EViewAsType
{
VIEWAS_ASCII = 0,
VIEWAS_FP,
VIEWAS_HEX,
};
enum EViewAsType
{
VIEWAS_ASCII = 0,
VIEWAS_FP,
VIEWAS_HEX,
};
EViewAsType viewAsType;
EViewAsType viewAsType;
};

View File

@ -26,418 +26,420 @@
#include "Core/HW/DSP.h"
#include "Core/HW/Memmap.h"
#include "Core/PowerPC/PowerPC.h"
#include "DolphinWX/Globals.h"
#include "DolphinWX/WxUtils.h"
#include "DolphinWX/Debugger/MemoryView.h"
#include "DolphinWX/Debugger/MemoryWindow.h"
#include "DolphinWX/Globals.h"
#include "DolphinWX/WxUtils.h"
enum
{
IDM_MEM_ADDRBOX,
IDM_SYMBOLLIST,
IDM_SETVALBUTTON,
IDM_DUMP_MEMORY,
IDM_DUMP_MEM2,
IDM_DUMP_FAKEVMEM,
IDM_VALBOX,
IDM_U8,
IDM_U16,
IDM_U32,
IDM_SEARCH,
IDM_ASCII,
IDM_HEX
IDM_MEM_ADDRBOX,
IDM_SYMBOLLIST,
IDM_SETVALBUTTON,
IDM_DUMP_MEMORY,
IDM_DUMP_MEM2,
IDM_DUMP_FAKEVMEM,
IDM_VALBOX,
IDM_U8,
IDM_U16,
IDM_U32,
IDM_SEARCH,
IDM_ASCII,
IDM_HEX
};
BEGIN_EVENT_TABLE(CMemoryWindow, wxPanel)
EVT_LISTBOX(IDM_SYMBOLLIST, CMemoryWindow::OnSymbolListChange)
EVT_HOST_COMMAND(wxID_ANY, CMemoryWindow::OnHostMessage)
EVT_BUTTON(IDM_SETVALBUTTON, CMemoryWindow::SetMemoryValue)
EVT_BUTTON(IDM_DUMP_MEMORY, CMemoryWindow::OnDumpMemory)
EVT_BUTTON(IDM_DUMP_MEM2, CMemoryWindow::OnDumpMem2)
EVT_BUTTON(IDM_DUMP_FAKEVMEM, CMemoryWindow::OnDumpFakeVMEM)
EVT_CHECKBOX(IDM_U8, CMemoryWindow::U8)
EVT_CHECKBOX(IDM_U16, CMemoryWindow::U16)
EVT_CHECKBOX(IDM_U32, CMemoryWindow::U32)
EVT_BUTTON(IDM_SEARCH, CMemoryWindow::onSearch)
EVT_CHECKBOX(IDM_ASCII, CMemoryWindow::onAscii)
EVT_CHECKBOX(IDM_HEX, CMemoryWindow::onHex)
EVT_LISTBOX(IDM_SYMBOLLIST, CMemoryWindow::OnSymbolListChange)
EVT_HOST_COMMAND(wxID_ANY, CMemoryWindow::OnHostMessage)
EVT_BUTTON(IDM_SETVALBUTTON, CMemoryWindow::SetMemoryValue)
EVT_BUTTON(IDM_DUMP_MEMORY, CMemoryWindow::OnDumpMemory)
EVT_BUTTON(IDM_DUMP_MEM2, CMemoryWindow::OnDumpMem2)
EVT_BUTTON(IDM_DUMP_FAKEVMEM, CMemoryWindow::OnDumpFakeVMEM)
EVT_CHECKBOX(IDM_U8, CMemoryWindow::U8)
EVT_CHECKBOX(IDM_U16, CMemoryWindow::U16)
EVT_CHECKBOX(IDM_U32, CMemoryWindow::U32)
EVT_BUTTON(IDM_SEARCH, CMemoryWindow::onSearch)
EVT_CHECKBOX(IDM_ASCII, CMemoryWindow::onAscii)
EVT_CHECKBOX(IDM_HEX, CMemoryWindow::onHex)
END_EVENT_TABLE()
CMemoryWindow::CMemoryWindow(wxWindow* parent, wxWindowID id,
const wxPoint& pos, const wxSize& size, long style, const wxString& name)
: wxPanel(parent, id, pos, size, style, name)
CMemoryWindow::CMemoryWindow(wxWindow* parent, wxWindowID id, const wxPoint& pos,
const wxSize& size, long style, const wxString& name)
: wxPanel(parent, id, pos, size, style, name)
{
DebugInterface* di = &PowerPC::debug_interface;
DebugInterface* di = &PowerPC::debug_interface;
memview = new CMemoryView(di, this);
memview = new CMemoryView(di, this);
addrbox = new wxSearchCtrl(this, IDM_MEM_ADDRBOX);
addrbox->Bind(wxEVT_TEXT, &CMemoryWindow::OnAddrBoxChange, this);
addrbox->SetDescriptiveText(_("Search Address"));
addrbox = new wxSearchCtrl(this, IDM_MEM_ADDRBOX);
addrbox->Bind(wxEVT_TEXT, &CMemoryWindow::OnAddrBoxChange, this);
addrbox->SetDescriptiveText(_("Search Address"));
valbox = new wxTextCtrl(this, IDM_VALBOX, "", wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
valbox->Bind(wxEVT_TEXT_ENTER, &CMemoryWindow::SetMemoryValueFromValBox, this);
valbox =
new wxTextCtrl(this, IDM_VALBOX, "", wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
valbox->Bind(wxEVT_TEXT_ENTER, &CMemoryWindow::SetMemoryValueFromValBox, this);
wxGridSizer* const search_sizer = new wxGridSizer(1);
search_sizer->Add(addrbox);
search_sizer->Add(valbox, 0, wxEXPAND);
search_sizer->Add(new wxButton(this, IDM_SETVALBUTTON, _("Set Value")));
wxGridSizer* const search_sizer = new wxGridSizer(1);
search_sizer->Add(addrbox);
search_sizer->Add(valbox, 0, wxEXPAND);
search_sizer->Add(new wxButton(this, IDM_SETVALBUTTON, _("Set Value")));
wxGridSizer* const dump_sizer = new wxGridSizer(1);
dump_sizer->Add(new wxButton(this, IDM_DUMP_MEMORY, _("Dump MRAM")), 0, wxEXPAND);
dump_sizer->Add(new wxButton(this, IDM_DUMP_MEM2, _("Dump EXRAM")), 0, wxEXPAND);
if (!SConfig::GetInstance().bMMU)
dump_sizer->Add(new wxButton(this, IDM_DUMP_FAKEVMEM, _("Dump FakeVMEM")), 0, wxEXPAND);
wxGridSizer* const dump_sizer = new wxGridSizer(1);
dump_sizer->Add(new wxButton(this, IDM_DUMP_MEMORY, _("Dump MRAM")), 0, wxEXPAND);
dump_sizer->Add(new wxButton(this, IDM_DUMP_MEM2, _("Dump EXRAM")), 0, wxEXPAND);
if (!SConfig::GetInstance().bMMU)
dump_sizer->Add(new wxButton(this, IDM_DUMP_FAKEVMEM, _("Dump FakeVMEM")), 0, wxEXPAND);
wxStaticBoxSizer* const sizerSearchType = new wxStaticBoxSizer(wxVERTICAL, this, _("Search"));
sizerSearchType->Add(btnSearch = new wxButton(this, IDM_SEARCH, _("Search")));
sizerSearchType->Add(chkAscii = new wxCheckBox(this, IDM_ASCII, "Ascii "));
sizerSearchType->Add(chkHex = new wxCheckBox(this, IDM_HEX, _("Hex")));
wxStaticBoxSizer* const sizerSearchType = new wxStaticBoxSizer(wxVERTICAL, this, _("Search"));
sizerSearchType->Add(btnSearch = new wxButton(this, IDM_SEARCH, _("Search")));
sizerSearchType->Add(chkAscii = new wxCheckBox(this, IDM_ASCII, "Ascii "));
sizerSearchType->Add(chkHex = new wxCheckBox(this, IDM_HEX, _("Hex")));
wxStaticBoxSizer* const sizerDataTypes = new wxStaticBoxSizer(wxVERTICAL, this, _("Data Type"));
sizerDataTypes->SetMinSize(74, 40);
sizerDataTypes->Add(chk8 = new wxCheckBox(this, IDM_U8, "U8"));
sizerDataTypes->Add(chk16 = new wxCheckBox(this, IDM_U16, "U16"));
sizerDataTypes->Add(chk32 = new wxCheckBox(this, IDM_U32, "U32"));
wxStaticBoxSizer* const sizerDataTypes = new wxStaticBoxSizer(wxVERTICAL, this, _("Data Type"));
sizerDataTypes->SetMinSize(74, 40);
sizerDataTypes->Add(chk8 = new wxCheckBox(this, IDM_U8, "U8"));
sizerDataTypes->Add(chk16 = new wxCheckBox(this, IDM_U16, "U16"));
sizerDataTypes->Add(chk32 = new wxCheckBox(this, IDM_U32, "U32"));
wxBoxSizer* const sizerRight = new wxBoxSizer(wxVERTICAL);
sizerRight->Add(search_sizer);
sizerRight->AddSpacer(5);
sizerRight->Add(dump_sizer);
sizerRight->Add(sizerSearchType);
sizerRight->Add(sizerDataTypes);
wxBoxSizer* const sizerRight = new wxBoxSizer(wxVERTICAL);
sizerRight->Add(search_sizer);
sizerRight->AddSpacer(5);
sizerRight->Add(dump_sizer);
sizerRight->Add(sizerSearchType);
sizerRight->Add(sizerDataTypes);
wxBoxSizer* const sizerBig = new wxBoxSizer(wxHORIZONTAL);
sizerBig->Add(memview, 20, wxEXPAND);
sizerBig->Add(sizerRight, 0, wxEXPAND | wxALL, 3);
wxBoxSizer* const sizerBig = new wxBoxSizer(wxHORIZONTAL);
sizerBig->Add(memview, 20, wxEXPAND);
sizerBig->Add(sizerRight, 0, wxEXPAND | wxALL, 3);
SetSizer(sizerBig);
chkHex->SetValue(1); //Set defaults
chk8->SetValue(1);
SetSizer(sizerBig);
chkHex->SetValue(1); // Set defaults
chk8->SetValue(1);
sizerRight->Fit(this);
sizerBig->Fit(this);
sizerRight->Fit(this);
sizerBig->Fit(this);
}
void CMemoryWindow::Save(IniFile& ini) const
{
// Prevent these bad values that can happen after a crash or hanging
if (GetPosition().x != -32000 && GetPosition().y != -32000)
{
IniFile::Section* mem_window = ini.GetOrCreateSection("MemoryWindow");
mem_window->Set("x", GetPosition().x);
mem_window->Set("y", GetPosition().y);
mem_window->Set("w", GetSize().GetWidth());
mem_window->Set("h", GetSize().GetHeight());
}
// Prevent these bad values that can happen after a crash or hanging
if (GetPosition().x != -32000 && GetPosition().y != -32000)
{
IniFile::Section* mem_window = ini.GetOrCreateSection("MemoryWindow");
mem_window->Set("x", GetPosition().x);
mem_window->Set("y", GetPosition().y);
mem_window->Set("w", GetSize().GetWidth());
mem_window->Set("h", GetSize().GetHeight());
}
}
void CMemoryWindow::Load(IniFile& ini)
{
int x, y, w, h;
int x, y, w, h;
IniFile::Section* mem_window = ini.GetOrCreateSection("MemoryWindow");
mem_window->Get("x", &x, GetPosition().x);
mem_window->Get("y", &y, GetPosition().y);
mem_window->Get("w", &w, GetSize().GetWidth());
mem_window->Get("h", &h, GetSize().GetHeight());
IniFile::Section* mem_window = ini.GetOrCreateSection("MemoryWindow");
mem_window->Get("x", &x, GetPosition().x);
mem_window->Get("y", &y, GetPosition().y);
mem_window->Get("w", &w, GetSize().GetWidth());
mem_window->Get("h", &h, GetSize().GetHeight());
SetSize(x, y, w, h);
SetSize(x, y, w, h);
}
void CMemoryWindow::JumpToAddress(u32 _Address)
{
memview->Center(_Address);
memview->Center(_Address);
}
void CMemoryWindow::SetMemoryValueFromValBox(wxCommandEvent& event)
{
SetMemoryValue(event);
valbox->SetFocus();
SetMemoryValue(event);
valbox->SetFocus();
}
void CMemoryWindow::SetMemoryValue(wxCommandEvent& event)
{
if (!Memory::IsInitialized())
{
WxUtils::ShowErrorDialog(_("Cannot set uninitialized memory."));
return;
}
if (!Memory::IsInitialized())
{
WxUtils::ShowErrorDialog(_("Cannot set uninitialized memory."));
return;
}
std::string str_addr = WxStrToStr(addrbox->GetValue());
std::string str_val = WxStrToStr(valbox->GetValue());
u32 addr;
u32 val;
std::string str_addr = WxStrToStr(addrbox->GetValue());
std::string str_val = WxStrToStr(valbox->GetValue());
u32 addr;
u32 val;
if (!TryParse(std::string("0x") + str_addr, &addr))
{
WxUtils::ShowErrorDialog(wxString::Format(_("Invalid address: %s"), str_addr.c_str()));
return;
}
if (!TryParse(std::string("0x") + str_addr, &addr))
{
WxUtils::ShowErrorDialog(wxString::Format(_("Invalid address: %s"), str_addr.c_str()));
return;
}
if (!TryParse(std::string("0x") + str_val, &val))
{
WxUtils::ShowErrorDialog(wxString::Format(_("Invalid value: %s"), str_val.c_str()));
return;
}
if (!TryParse(std::string("0x") + str_val, &val))
{
WxUtils::ShowErrorDialog(wxString::Format(_("Invalid value: %s"), str_val.c_str()));
return;
}
PowerPC::HostWrite_U32(val, addr);
memview->Refresh();
PowerPC::HostWrite_U32(val, addr);
memview->Refresh();
}
void CMemoryWindow::OnAddrBoxChange(wxCommandEvent& event)
{
wxString txt = addrbox->GetValue();
if (txt.size())
{
u32 addr;
sscanf(WxStrToStr(txt).c_str(), "%08x", &addr);
memview->Center(addr & ~3);
}
wxString txt = addrbox->GetValue();
if (txt.size())
{
u32 addr;
sscanf(WxStrToStr(txt).c_str(), "%08x", &addr);
memview->Center(addr & ~3);
}
event.Skip();
event.Skip();
}
void CMemoryWindow::Update()
{
memview->Refresh();
memview->Center(PC);
memview->Refresh();
memview->Center(PC);
}
void CMemoryWindow::NotifyMapLoaded()
{
symbols->Show(false); // hide it for faster filling
symbols->Clear();
symbols->Show(false); // hide it for faster filling
symbols->Clear();
#if 0
#ifdef _WIN32
#ifdef _WIN32
const FunctionDB::XFuncMap &syms = g_symbolDB.Symbols();
for (FuntionDB::XFuncMap::iterator iter = syms.begin(); iter != syms.end(); ++iter)
{
int idx = symbols->Append(iter->second.name.c_str());
symbols->SetClientData(idx, (void*)&iter->second);
}
#endif
#endif
symbols->Show(true);
Update();
#endif
symbols->Show(true);
Update();
}
void CMemoryWindow::OnSymbolListChange(wxCommandEvent& event)
{
int index = symbols->GetSelection();
if (index >= 0)
{
Symbol* pSymbol = static_cast<Symbol *>(symbols->GetClientData(index));
if (pSymbol != nullptr)
{
memview->Center(pSymbol->address);
}
}
int index = symbols->GetSelection();
if (index >= 0)
{
Symbol* pSymbol = static_cast<Symbol*>(symbols->GetClientData(index));
if (pSymbol != nullptr)
{
memview->Center(pSymbol->address);
}
}
}
void CMemoryWindow::OnHostMessage(wxCommandEvent& event)
{
switch (event.GetId())
{
case IDM_NOTIFY_MAP_LOADED:
NotifyMapLoaded();
break;
}
switch (event.GetId())
{
case IDM_NOTIFY_MAP_LOADED:
NotifyMapLoaded();
break;
}
}
static void DumpArray(const std::string& filename, const u8* data, size_t length)
{
if (data)
{
File::IOFile f(filename, "wb");
f.WriteBytes(data, length);
}
if (data)
{
File::IOFile f(filename, "wb");
f.WriteBytes(data, length);
}
}
// Write mram to file
void CMemoryWindow::OnDumpMemory( wxCommandEvent& event )
void CMemoryWindow::OnDumpMemory(wxCommandEvent& event)
{
DumpArray(File::GetUserPath(F_RAMDUMP_IDX), Memory::m_pRAM, Memory::REALRAM_SIZE);
DumpArray(File::GetUserPath(F_RAMDUMP_IDX), Memory::m_pRAM, Memory::REALRAM_SIZE);
}
// Write exram (aram or mem2) to file
void CMemoryWindow::OnDumpMem2( wxCommandEvent& event )
void CMemoryWindow::OnDumpMem2(wxCommandEvent& event)
{
if (SConfig::GetInstance().bWii)
{
DumpArray(File::GetUserPath(F_ARAMDUMP_IDX), Memory::m_pEXRAM, Memory::EXRAM_SIZE);
}
else
{
DumpArray(File::GetUserPath(F_ARAMDUMP_IDX), DSP::GetARAMPtr(), DSP::ARAM_SIZE);
}
if (SConfig::GetInstance().bWii)
{
DumpArray(File::GetUserPath(F_ARAMDUMP_IDX), Memory::m_pEXRAM, Memory::EXRAM_SIZE);
}
else
{
DumpArray(File::GetUserPath(F_ARAMDUMP_IDX), DSP::GetARAMPtr(), DSP::ARAM_SIZE);
}
}
// Write fake vmem to file
void CMemoryWindow::OnDumpFakeVMEM( wxCommandEvent& event )
void CMemoryWindow::OnDumpFakeVMEM(wxCommandEvent& event)
{
DumpArray(File::GetUserPath(F_FAKEVMEMDUMP_IDX), Memory::m_pFakeVMEM, Memory::FAKEVMEM_SIZE);
DumpArray(File::GetUserPath(F_FAKEVMEMDUMP_IDX), Memory::m_pFakeVMEM, Memory::FAKEVMEM_SIZE);
}
void CMemoryWindow::U8(wxCommandEvent& event)
{
chk16->SetValue(0);
chk32->SetValue(0);
memview->SetDataType(MemoryDataType::U8);
chk16->SetValue(0);
chk32->SetValue(0);
memview->SetDataType(MemoryDataType::U8);
}
void CMemoryWindow::U16(wxCommandEvent& event)
{
chk8->SetValue(0);
chk32->SetValue(0);
memview->SetDataType(MemoryDataType::U16);
chk8->SetValue(0);
chk32->SetValue(0);
memview->SetDataType(MemoryDataType::U16);
}
void CMemoryWindow::U32(wxCommandEvent& event)
{
chk16->SetValue(0);
chk8->SetValue(0);
memview->SetDataType(MemoryDataType::U32);
chk16->SetValue(0);
chk8->SetValue(0);
memview->SetDataType(MemoryDataType::U32);
}
void CMemoryWindow::onSearch(wxCommandEvent& event)
{
u8* TheRAM = nullptr;
u32 szRAM = 0;
switch (memview->GetMemoryType())
{
case 0:
default:
if (Memory::m_pRAM)
{
TheRAM = Memory::m_pRAM;
szRAM = Memory::REALRAM_SIZE;
}
break;
case 1:
{
u8* aram = DSP::GetARAMPtr();
if (aram)
{
TheRAM = aram;
szRAM = DSP::ARAM_SIZE;
}
}
break;
}
//Now we have memory to look in
//Are we looking for ASCII string, or hex?
//memview->cu
wxString rawData = valbox->GetValue();
std::vector<u8> Dest; //May need a better name
u32 size = 0;
int pad = rawData.size()%2; //If it's uneven
unsigned int i = 0;
long count = 0;
char copy[3] = {0};
long newsize = 0;
unsigned char *tmp2 = nullptr;
char* tmpstr = nullptr;
u8* TheRAM = nullptr;
u32 szRAM = 0;
switch (memview->GetMemoryType())
{
case 0:
default:
if (Memory::m_pRAM)
{
TheRAM = Memory::m_pRAM;
szRAM = Memory::REALRAM_SIZE;
}
break;
case 1:
{
u8* aram = DSP::GetARAMPtr();
if (aram)
{
TheRAM = aram;
szRAM = DSP::ARAM_SIZE;
}
}
break;
}
// Now we have memory to look in
// Are we looking for ASCII string, or hex?
// memview->cu
wxString rawData = valbox->GetValue();
std::vector<u8> Dest; // May need a better name
u32 size = 0;
int pad = rawData.size() % 2; // If it's uneven
unsigned int i = 0;
long count = 0;
char copy[3] = {0};
long newsize = 0;
unsigned char* tmp2 = nullptr;
char* tmpstr = nullptr;
if (chkHex->GetValue())
{
//We are looking for hex
//If it's uneven
size = (rawData.size()/2) + pad;
Dest.resize(size+32);
newsize = rawData.size();
if (chkHex->GetValue())
{
// We are looking for hex
// If it's uneven
size = (rawData.size() / 2) + pad;
Dest.resize(size + 32);
newsize = rawData.size();
if (pad)
{
tmpstr = new char[newsize + 2];
memset(tmpstr, 0, newsize + 2);
tmpstr[0] = '0';
}
else
{
tmpstr = new char[newsize + 1];
memset(tmpstr, 0, newsize + 1);
}
strcat(tmpstr, WxStrToStr(rawData).c_str());
tmp2 = &Dest.front();
count = 0;
for (i = 0; i < strlen(tmpstr); i++)
{
copy[0] = tmpstr[i];
copy[1] = tmpstr[i+1];
copy[2] = 0;
int tmpint;
sscanf(copy, "%02x", &tmpint);
tmp2[count++] = tmpint;
// Dest[count] should now be the hex of what the two chars were!
// Also should add a check to make sure it's A-F only
//sscanf(copy, "%02x", &tmp2[count++]);
i += 1;
}
delete[] tmpstr;
}
else
{
//Looking for an ascii string
size = rawData.size();
Dest.resize(size+1);
tmpstr = new char[size+1];
if (pad)
{
tmpstr = new char[newsize + 2];
memset(tmpstr, 0, newsize + 2);
tmpstr[0] = '0';
}
else
{
tmpstr = new char[newsize + 1];
memset(tmpstr, 0, newsize + 1);
}
strcat(tmpstr, WxStrToStr(rawData).c_str());
tmp2 = &Dest.front();
count = 0;
for (i = 0; i < strlen(tmpstr); i++)
{
copy[0] = tmpstr[i];
copy[1] = tmpstr[i + 1];
copy[2] = 0;
int tmpint;
sscanf(copy, "%02x", &tmpint);
tmp2[count++] = tmpint;
// Dest[count] should now be the hex of what the two chars were!
// Also should add a check to make sure it's A-F only
// sscanf(copy, "%02x", &tmp2[count++]);
i += 1;
}
delete[] tmpstr;
}
else
{
// Looking for an ascii string
size = rawData.size();
Dest.resize(size + 1);
tmpstr = new char[size + 1];
tmp2 = &Dest.front();
sprintf(tmpstr, "%s", WxStrToStr(rawData).c_str());
tmp2 = &Dest.front();
sprintf(tmpstr, "%s", WxStrToStr(rawData).c_str());
for (i = 0; i < size; i++)
tmp2[i] = tmpstr[i];
for (i = 0; i < size; i++)
tmp2[i] = tmpstr[i];
delete[] tmpstr;
}
delete[] tmpstr;
}
if (size)
{
unsigned char* pnt = &Dest.front();
unsigned int k = 0;
//grab
wxString txt = addrbox->GetValue();
u32 addr = 0;
if (txt.size())
{
sscanf(WxStrToStr(txt).c_str(), "%08x", &addr);
}
i = addr+4;
for ( ; i < szRAM; ++i)
{
for (k = 0; k < size; ++k)
{
if (i + k > szRAM) break;
if (k > size) break;
if (pnt[k] != TheRAM[i+k])
{
k = 0;
break;
}
}
if (k == size)
{
//Match was found
wxMessageBox(_("A match was found. Placing viewer at the offset."));
addrbox->SetValue(wxString::Format("%08x", i));
//memview->curAddress = i;
//memview->Refresh();
OnAddrBoxChange(event);
return;
}
}
wxMessageBox(_("No match was found."));
}
if (size)
{
unsigned char* pnt = &Dest.front();
unsigned int k = 0;
// grab
wxString txt = addrbox->GetValue();
u32 addr = 0;
if (txt.size())
{
sscanf(WxStrToStr(txt).c_str(), "%08x", &addr);
}
i = addr + 4;
for (; i < szRAM; ++i)
{
for (k = 0; k < size; ++k)
{
if (i + k > szRAM)
break;
if (k > size)
break;
if (pnt[k] != TheRAM[i + k])
{
k = 0;
break;
}
}
if (k == size)
{
// Match was found
wxMessageBox(_("A match was found. Placing viewer at the offset."));
addrbox->SetValue(wxString::Format("%08x", i));
// memview->curAddress = i;
// memview->Refresh();
OnAddrBoxChange(event);
return;
}
}
wxMessageBox(_("No match was found."));
}
}
void CMemoryWindow::onAscii(wxCommandEvent& event)
{
chkHex->SetValue(0);
chkHex->SetValue(0);
}
void CMemoryWindow::onHex(wxCommandEvent& event)
{
chkAscii->SetValue(0);
chkAscii->SetValue(0);
}

View File

@ -18,49 +18,46 @@ class wxTextCtrl;
class CMemoryWindow : public wxPanel
{
public:
CMemoryWindow(wxWindow* parent,
wxWindowID id = wxID_ANY,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxTAB_TRAVERSAL | wxBORDER_NONE,
const wxString& name = _("Memory"));
CMemoryWindow(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL | wxBORDER_NONE,
const wxString& name = _("Memory"));
void Save(IniFile& _IniFile) const;
void Load(IniFile& _IniFile);
void Save(IniFile& _IniFile) const;
void Load(IniFile& _IniFile);
void Update() override;
void NotifyMapLoaded();
void Update() override;
void NotifyMapLoaded();
void JumpToAddress(u32 _Address);
void JumpToAddress(u32 _Address);
private:
DECLARE_EVENT_TABLE()
DECLARE_EVENT_TABLE()
void U8(wxCommandEvent& event);
void U16(wxCommandEvent& event);
void U32(wxCommandEvent& event);
void onSearch(wxCommandEvent& event);
void onAscii(wxCommandEvent& event);
void onHex(wxCommandEvent& event);
void OnSymbolListChange(wxCommandEvent& event);
void OnAddrBoxChange(wxCommandEvent& event);
void OnHostMessage(wxCommandEvent& event);
void SetMemoryValueFromValBox(wxCommandEvent& event);
void SetMemoryValue(wxCommandEvent& event);
void OnDumpMemory(wxCommandEvent& event);
void OnDumpMem2(wxCommandEvent& event);
void OnDumpFakeVMEM(wxCommandEvent& event);
void U8(wxCommandEvent& event);
void U16(wxCommandEvent& event);
void U32(wxCommandEvent& event);
void onSearch(wxCommandEvent& event);
void onAscii(wxCommandEvent& event);
void onHex(wxCommandEvent& event);
void OnSymbolListChange(wxCommandEvent& event);
void OnAddrBoxChange(wxCommandEvent& event);
void OnHostMessage(wxCommandEvent& event);
void SetMemoryValueFromValBox(wxCommandEvent& event);
void SetMemoryValue(wxCommandEvent& event);
void OnDumpMemory(wxCommandEvent& event);
void OnDumpMem2(wxCommandEvent& event);
void OnDumpFakeVMEM(wxCommandEvent& event);
wxCheckBox* chk8;
wxCheckBox* chk16;
wxCheckBox* chk32;
wxButton* btnSearch;
wxCheckBox* chkAscii;
wxCheckBox* chkHex;
wxCheckBox* chk8;
wxCheckBox* chk16;
wxCheckBox* chk32;
wxButton* btnSearch;
wxCheckBox* chkAscii;
wxCheckBox* chkHex;
CMemoryView* memview;
wxListBox* symbols;
CMemoryView* memview;
wxListBox* symbols;
wxSearchCtrl* addrbox;
wxTextCtrl* valbox;
wxSearchCtrl* addrbox;
wxTextCtrl* valbox;
};

View File

@ -12,291 +12,349 @@
#include "Core/HW/ProcessorInterface.h"
#include "Core/PowerPC/Gekko.h"
#include "Core/PowerPC/PowerPC.h"
#include "DolphinWX/Frame.h"
#include "DolphinWX/Globals.h"
#include "DolphinWX/WxUtils.h"
#include "DolphinWX/Debugger/CodeWindow.h"
#include "DolphinWX/Debugger/DebuggerUIUtil.h"
#include "DolphinWX/Debugger/MemoryWindow.h"
#include "DolphinWX/Debugger/RegisterView.h"
#include "DolphinWX/Debugger/WatchWindow.h"
#include "DolphinWX/Frame.h"
#include "DolphinWX/Globals.h"
#include "DolphinWX/WxUtils.h"
// F-zero 80005e60 wtf??
enum
{
IDM_WATCHADDRESS,
IDM_VIEWMEMORY,
IDM_VIEWCODE
IDM_WATCHADDRESS,
IDM_VIEWMEMORY,
IDM_VIEWCODE
};
static const char *special_reg_names[] = {
"PC", "LR", "CTR", "CR", "FPSCR", "MSR", "SRR0", "SRR1", "Exceptions", "Int Mask", "Int Cause", "DSISR", "DAR", "PT hashmask"
};
static const char* special_reg_names[] = {"PC", "LR", "CTR", "CR", "FPSCR",
"MSR", "SRR0", "SRR1", "Exceptions", "Int Mask",
"Int Cause", "DSISR", "DAR", "PT hashmask"};
static u32 GetSpecialRegValue(int reg)
{
switch (reg)
{
case 0: return PowerPC::ppcState.pc;
case 1: return PowerPC::ppcState.spr[SPR_LR];
case 2: return PowerPC::ppcState.spr[SPR_CTR];
case 3: return GetCR();
case 4: return PowerPC::ppcState.fpscr;
case 5: return PowerPC::ppcState.msr;
case 6: return PowerPC::ppcState.spr[SPR_SRR0];
case 7: return PowerPC::ppcState.spr[SPR_SRR1];
case 8: return PowerPC::ppcState.Exceptions;
case 9: return ProcessorInterface::GetMask();
case 10: return ProcessorInterface::GetCause();
case 11: return PowerPC::ppcState.spr[SPR_DSISR];
case 12: return PowerPC::ppcState.spr[SPR_DAR];
case 13: return (PowerPC::ppcState.pagetable_hashmask << 6) | PowerPC::ppcState.pagetable_base;
default: return 0;
}
switch (reg)
{
case 0:
return PowerPC::ppcState.pc;
case 1:
return PowerPC::ppcState.spr[SPR_LR];
case 2:
return PowerPC::ppcState.spr[SPR_CTR];
case 3:
return GetCR();
case 4:
return PowerPC::ppcState.fpscr;
case 5:
return PowerPC::ppcState.msr;
case 6:
return PowerPC::ppcState.spr[SPR_SRR0];
case 7:
return PowerPC::ppcState.spr[SPR_SRR1];
case 8:
return PowerPC::ppcState.Exceptions;
case 9:
return ProcessorInterface::GetMask();
case 10:
return ProcessorInterface::GetCause();
case 11:
return PowerPC::ppcState.spr[SPR_DSISR];
case 12:
return PowerPC::ppcState.spr[SPR_DAR];
case 13:
return (PowerPC::ppcState.pagetable_hashmask << 6) | PowerPC::ppcState.pagetable_base;
default:
return 0;
}
}
static wxString GetValueByRowCol(int row, int col)
{
if (row < 32)
{
switch (col)
{
case 0: return StrToWxStr(GekkoDisassembler::GetGPRName(row));
case 1: return wxString::Format("%08x", GPR(row));
case 2: return StrToWxStr(GekkoDisassembler::GetFPRName(row));
case 3: return wxString::Format("%016llx", riPS0(row));
case 4: return wxString::Format("%016llx", riPS1(row));
case 5:
{
if (row < 4)
return wxString::Format("DBAT%01d", row);
if (row < 32)
{
switch (col)
{
case 0:
return StrToWxStr(GekkoDisassembler::GetGPRName(row));
case 1:
return wxString::Format("%08x", GPR(row));
case 2:
return StrToWxStr(GekkoDisassembler::GetFPRName(row));
case 3:
return wxString::Format("%016llx", riPS0(row));
case 4:
return wxString::Format("%016llx", riPS1(row));
case 5:
{
if (row < 4)
return wxString::Format("DBAT%01d", row);
if (row < 8)
return wxString::Format("IBAT%01d", row - 4);
if (row < 8)
return wxString::Format("IBAT%01d", row - 4);
if (row < 12)
return wxString::Format("DBAT%01d", row - 4);
if (row < 12)
return wxString::Format("DBAT%01d", row - 4);
if (row < 16)
return wxString::Format("IBAT%01d", row - 8);
if (row < 16)
return wxString::Format("IBAT%01d", row - 8);
break;
}
case 6:
{
if (row < 4)
return wxString::Format("%016llx", (u64)PowerPC::ppcState.spr[SPR_DBAT0U + row * 2] << 32 | PowerPC::ppcState.spr[SPR_DBAT0L + row * 2]);
break;
}
case 6:
{
if (row < 4)
return wxString::Format("%016llx", (u64)PowerPC::ppcState.spr[SPR_DBAT0U + row * 2] << 32 |
PowerPC::ppcState.spr[SPR_DBAT0L + row * 2]);
if (row < 8)
return wxString::Format("%016llx", (u64)PowerPC::ppcState.spr[SPR_IBAT0U + (row - 4) * 2] << 32 | PowerPC::ppcState.spr[SPR_IBAT0L + (row - 4) * 2]);
if (row < 8)
return wxString::Format("%016llx", (u64)PowerPC::ppcState.spr[SPR_IBAT0U + (row - 4) * 2]
<< 32 |
PowerPC::ppcState.spr[SPR_IBAT0L + (row - 4) * 2]);
if (row < 12)
return wxString::Format("%016llx", (u64)PowerPC::ppcState.spr[SPR_DBAT4U + (row - 12) * 2] << 32 | PowerPC::ppcState.spr[SPR_DBAT4L + (row - 12) * 2]);
if (row < 12)
return wxString::Format("%016llx", (u64)PowerPC::ppcState.spr[SPR_DBAT4U + (row - 12) * 2]
<< 32 |
PowerPC::ppcState.spr[SPR_DBAT4L + (row - 12) * 2]);
if (row < 16)
return wxString::Format("%016llx", (u64)PowerPC::ppcState.spr[SPR_IBAT4U + (row - 16) * 2] << 32 | PowerPC::ppcState.spr[SPR_IBAT4L + (row - 16) * 2]);
if (row < 16)
return wxString::Format("%016llx", (u64)PowerPC::ppcState.spr[SPR_IBAT4U + (row - 16) * 2]
<< 32 |
PowerPC::ppcState.spr[SPR_IBAT4L + (row - 16) * 2]);
break;
}
case 7:
{
if (row < 16)
return wxString::Format("SR%02d", row);
break;
}
case 7:
{
if (row < 16)
return wxString::Format("SR%02d", row);
break;
}
case 8:
{
if (row < 16)
return wxString::Format("%08x", PowerPC::ppcState.sr[row]);
break;
}
case 8:
{
if (row < 16)
return wxString::Format("%08x", PowerPC::ppcState.sr[row]);
break;
}
default: return wxEmptyString;
}
}
else
{
if (row - 32 < NUM_SPECIALS)
{
switch (col)
{
case 0: return StrToWxStr(special_reg_names[row - 32]);
case 1: return wxString::Format("%08x", GetSpecialRegValue(row - 32));
default: return wxEmptyString;
}
}
}
return wxEmptyString;
break;
}
default:
return wxEmptyString;
}
}
else
{
if (row - 32 < NUM_SPECIALS)
{
switch (col)
{
case 0:
return StrToWxStr(special_reg_names[row - 32]);
case 1:
return wxString::Format("%08x", GetSpecialRegValue(row - 32));
default:
return wxEmptyString;
}
}
}
return wxEmptyString;
}
wxString CRegTable::GetValue(int row, int col)
{
return GetValueByRowCol(row, col);
return GetValueByRowCol(row, col);
}
static void SetSpecialRegValue(int reg, u32 value)
{
switch (reg)
{
case 0: PowerPC::ppcState.pc = value; break;
case 1: PowerPC::ppcState.spr[SPR_LR] = value; break;
case 2: PowerPC::ppcState.spr[SPR_CTR] = value; break;
case 3: SetCR(value); break;
case 4: PowerPC::ppcState.fpscr = value; break;
case 5: PowerPC::ppcState.msr = value; break;
case 6: PowerPC::ppcState.spr[SPR_SRR0] = value; break;
case 7: PowerPC::ppcState.spr[SPR_SRR1] = value; break;
case 8: PowerPC::ppcState.Exceptions = value; break;
// Should we just change the value, or use ProcessorInterface::SetInterrupt() to make the system aware?
// case 9: return ProcessorInterface::GetMask();
// case 10: return ProcessorInterface::GetCause();
case 11: PowerPC::ppcState.spr[SPR_DSISR] = value; break;
case 12: PowerPC::ppcState.spr[SPR_DAR] = value; break;
//case 13: (PowerPC::ppcState.pagetable_hashmask << 6) | PowerPC::ppcState.pagetable_base;
default: return;
}
switch (reg)
{
case 0:
PowerPC::ppcState.pc = value;
break;
case 1:
PowerPC::ppcState.spr[SPR_LR] = value;
break;
case 2:
PowerPC::ppcState.spr[SPR_CTR] = value;
break;
case 3:
SetCR(value);
break;
case 4:
PowerPC::ppcState.fpscr = value;
break;
case 5:
PowerPC::ppcState.msr = value;
break;
case 6:
PowerPC::ppcState.spr[SPR_SRR0] = value;
break;
case 7:
PowerPC::ppcState.spr[SPR_SRR1] = value;
break;
case 8:
PowerPC::ppcState.Exceptions = value;
break;
// Should we just change the value, or use ProcessorInterface::SetInterrupt() to make the system
// aware?
// case 9: return ProcessorInterface::GetMask();
// case 10: return ProcessorInterface::GetCause();
case 11:
PowerPC::ppcState.spr[SPR_DSISR] = value;
break;
case 12:
PowerPC::ppcState.spr[SPR_DAR] = value;
break;
// case 13: (PowerPC::ppcState.pagetable_hashmask << 6) | PowerPC::ppcState.pagetable_base;
default:
return;
}
}
void CRegTable::SetValue(int row, int col, const wxString& strNewVal)
{
u32 newVal = 0;
if (TryParse("0x" + WxStrToStr(strNewVal), &newVal))
{
if (row < 32)
{
if (col == 1)
GPR(row) = newVal;
else if (col == 3)
riPS0(row) = newVal;
else if (col == 4)
riPS1(row) = newVal;
}
else
{
if ((row - 32 < NUM_SPECIALS) && (col == 1))
{
SetSpecialRegValue(row - 32, newVal);
}
}
}
u32 newVal = 0;
if (TryParse("0x" + WxStrToStr(strNewVal), &newVal))
{
if (row < 32)
{
if (col == 1)
GPR(row) = newVal;
else if (col == 3)
riPS0(row) = newVal;
else if (col == 4)
riPS1(row) = newVal;
}
else
{
if ((row - 32 < NUM_SPECIALS) && (col == 1))
{
SetSpecialRegValue(row - 32, newVal);
}
}
}
}
void CRegTable::UpdateCachedRegs()
{
for (int i = 0; i < 32; ++i)
{
m_CachedRegHasChanged[i] = (m_CachedRegs[i] != GPR(i));
m_CachedRegs[i] = GPR(i);
for (int i = 0; i < 32; ++i)
{
m_CachedRegHasChanged[i] = (m_CachedRegs[i] != GPR(i));
m_CachedRegs[i] = GPR(i);
m_CachedFRegHasChanged[i][0] = (m_CachedFRegs[i][0] != riPS0(i));
m_CachedFRegs[i][0] = riPS0(i);
m_CachedFRegHasChanged[i][1] = (m_CachedFRegs[i][1] != riPS1(i));
m_CachedFRegs[i][1] = riPS1(i);
}
for (int i = 0; i < NUM_SPECIALS; ++i)
{
m_CachedSpecialRegHasChanged[i] = (m_CachedSpecialRegs[i] != GetSpecialRegValue(i));
m_CachedSpecialRegs[i] = GetSpecialRegValue(i);
}
m_CachedFRegHasChanged[i][0] = (m_CachedFRegs[i][0] != riPS0(i));
m_CachedFRegs[i][0] = riPS0(i);
m_CachedFRegHasChanged[i][1] = (m_CachedFRegs[i][1] != riPS1(i));
m_CachedFRegs[i][1] = riPS1(i);
}
for (int i = 0; i < NUM_SPECIALS; ++i)
{
m_CachedSpecialRegHasChanged[i] = (m_CachedSpecialRegs[i] != GetSpecialRegValue(i));
m_CachedSpecialRegs[i] = GetSpecialRegValue(i);
}
}
wxGridCellAttr *CRegTable::GetAttr(int row, int col, wxGridCellAttr::wxAttrKind)
wxGridCellAttr* CRegTable::GetAttr(int row, int col, wxGridCellAttr::wxAttrKind)
{
wxGridCellAttr *attr = new wxGridCellAttr();
wxGridCellAttr* attr = new wxGridCellAttr();
attr->SetBackgroundColour(*wxWHITE);
attr->SetFont(DebuggerFont);
attr->SetBackgroundColour(*wxWHITE);
attr->SetFont(DebuggerFont);
switch (col)
{
case 1:
attr->SetAlignment(wxALIGN_CENTER, wxALIGN_CENTER);
break;
case 3:
case 4:
attr->SetAlignment(wxALIGN_RIGHT, wxALIGN_CENTER);
break;
default:
attr->SetAlignment(wxALIGN_LEFT, wxALIGN_CENTER);
break;
}
switch (col)
{
case 1:
attr->SetAlignment(wxALIGN_CENTER, wxALIGN_CENTER);
break;
case 3:
case 4:
attr->SetAlignment(wxALIGN_RIGHT, wxALIGN_CENTER);
break;
default:
attr->SetAlignment(wxALIGN_LEFT, wxALIGN_CENTER);
break;
}
bool red = false;
switch (col)
{
case 1: red = row < 32 ? m_CachedRegHasChanged[row] : m_CachedSpecialRegHasChanged[row-32]; break;
case 3:
case 4: red = row < 32 ? m_CachedFRegHasChanged[row][col-3] : false; break;
}
bool red = false;
switch (col)
{
case 1:
red = row < 32 ? m_CachedRegHasChanged[row] : m_CachedSpecialRegHasChanged[row - 32];
break;
case 3:
case 4:
red = row < 32 ? m_CachedFRegHasChanged[row][col - 3] : false;
break;
}
attr->SetTextColour(red ? *wxRED : *wxBLACK);
return attr;
attr->SetTextColour(red ? *wxRED : *wxBLACK);
return attr;
}
CRegisterView::CRegisterView(wxWindow *parent, wxWindowID id)
: wxGrid(parent, id)
CRegisterView::CRegisterView(wxWindow* parent, wxWindowID id) : wxGrid(parent, id)
{
m_register_table = new CRegTable();
m_register_table = new CRegTable();
SetTable(m_register_table, true);
SetRowLabelSize(0);
SetColLabelSize(0);
DisableDragRowSize();
SetTable(m_register_table, true);
SetRowLabelSize(0);
SetColLabelSize(0);
DisableDragRowSize();
Bind(wxEVT_GRID_CELL_RIGHT_CLICK, &CRegisterView::OnMouseDownR, this);
Bind(wxEVT_MENU, &CRegisterView::OnPopupMenu, this);
Bind(wxEVT_GRID_CELL_RIGHT_CLICK, &CRegisterView::OnMouseDownR, this);
Bind(wxEVT_MENU, &CRegisterView::OnPopupMenu, this);
AutoSizeColumns();
AutoSizeColumns();
}
void CRegisterView::Update()
{
m_register_table->UpdateCachedRegs();
ForceRefresh();
m_register_table->UpdateCachedRegs();
ForceRefresh();
}
void CRegisterView::OnMouseDownR(wxGridEvent& event)
{
// popup menu
int row = event.GetRow();
int col = event.GetCol();
// popup menu
int row = event.GetRow();
int col = event.GetCol();
wxString strNewVal = GetValueByRowCol(row, col);
TryParse("0x" + WxStrToStr(strNewVal), &m_selectedAddress);
wxString strNewVal = GetValueByRowCol(row, col);
TryParse("0x" + WxStrToStr(strNewVal), &m_selectedAddress);
wxMenu menu;
menu.Append(IDM_WATCHADDRESS, _("Add to &watch"));
menu.Append(IDM_VIEWMEMORY, _("View &memory"));
menu.Append(IDM_VIEWCODE, _("View &code"));
PopupMenu(&menu);
wxMenu menu;
menu.Append(IDM_WATCHADDRESS, _("Add to &watch"));
menu.Append(IDM_VIEWMEMORY, _("View &memory"));
menu.Append(IDM_VIEWCODE, _("View &code"));
PopupMenu(&menu);
}
void CRegisterView::OnPopupMenu(wxCommandEvent& event)
{
CFrame* main_frame = static_cast<CFrame*>(GetGrandParent()->GetParent());
CCodeWindow* code_window = main_frame->g_pCodeWindow;
CWatchWindow* watch_window = code_window->m_WatchWindow;
CMemoryWindow* memory_window = code_window->m_MemoryWindow;
CFrame* main_frame = static_cast<CFrame*>(GetGrandParent()->GetParent());
CCodeWindow* code_window = main_frame->g_pCodeWindow;
CWatchWindow* watch_window = code_window->m_WatchWindow;
CMemoryWindow* memory_window = code_window->m_MemoryWindow;
switch (event.GetId())
{
case IDM_WATCHADDRESS:
PowerPC::watches.Add(m_selectedAddress);
if (watch_window)
watch_window->NotifyUpdate();
Refresh();
break;
case IDM_VIEWMEMORY:
if (memory_window)
memory_window->JumpToAddress(m_selectedAddress);
Refresh();
break;
case IDM_VIEWCODE:
code_window->JumpToAddress(m_selectedAddress);
Refresh();
break;
}
event.Skip();
switch (event.GetId())
{
case IDM_WATCHADDRESS:
PowerPC::watches.Add(m_selectedAddress);
if (watch_window)
watch_window->NotifyUpdate();
Refresh();
break;
case IDM_VIEWMEMORY:
if (memory_window)
memory_window->JumpToAddress(m_selectedAddress);
Refresh();
break;
case IDM_VIEWCODE:
code_window->JumpToAddress(m_selectedAddress);
Refresh();
break;
}
event.Skip();
}

View File

@ -29,50 +29,48 @@
class CRegTable : public wxGridTableBase
{
public:
CRegTable()
{
memset(m_CachedRegs, 0, sizeof(m_CachedRegs));
memset(m_CachedSpecialRegs, 0, sizeof(m_CachedSpecialRegs));
memset(m_CachedFRegs, 0, sizeof(m_CachedFRegs));
memset(m_CachedRegHasChanged, 0, sizeof(m_CachedRegHasChanged));
memset(m_CachedSpecialRegHasChanged, 0, sizeof(m_CachedSpecialRegHasChanged));
memset(m_CachedFRegHasChanged, 0, sizeof(m_CachedFRegHasChanged));
}
CRegTable()
{
memset(m_CachedRegs, 0, sizeof(m_CachedRegs));
memset(m_CachedSpecialRegs, 0, sizeof(m_CachedSpecialRegs));
memset(m_CachedFRegs, 0, sizeof(m_CachedFRegs));
memset(m_CachedRegHasChanged, 0, sizeof(m_CachedRegHasChanged));
memset(m_CachedSpecialRegHasChanged, 0, sizeof(m_CachedSpecialRegHasChanged));
memset(m_CachedFRegHasChanged, 0, sizeof(m_CachedFRegHasChanged));
}
int GetNumberCols() override { return 9; }
int GetNumberRows() override { return 32 + NUM_SPECIALS; }
bool IsEmptyCell(int row, int col) override { return row > 31 && col > 2; }
wxString GetValue(int row, int col) override;
void SetValue(int row, int col, const wxString &) override;
wxGridCellAttr *GetAttr(int, int, wxGridCellAttr::wxAttrKind) override;
void UpdateCachedRegs();
int GetNumberCols() override { return 9; }
int GetNumberRows() override { return 32 + NUM_SPECIALS; }
bool IsEmptyCell(int row, int col) override { return row > 31 && col > 2; }
wxString GetValue(int row, int col) override;
void SetValue(int row, int col, const wxString&) override;
wxGridCellAttr* GetAttr(int, int, wxGridCellAttr::wxAttrKind) override;
void UpdateCachedRegs();
private:
u32 m_CachedRegs[32];
u32 m_CachedSpecialRegs[NUM_SPECIALS];
u64 m_CachedFRegs[32][2];
bool m_CachedRegHasChanged[32];
bool m_CachedSpecialRegHasChanged[NUM_SPECIALS];
bool m_CachedFRegHasChanged[32][2];
u32 m_CachedRegs[32];
u32 m_CachedSpecialRegs[NUM_SPECIALS];
u64 m_CachedFRegs[32][2];
bool m_CachedRegHasChanged[32];
bool m_CachedSpecialRegHasChanged[NUM_SPECIALS];
bool m_CachedFRegHasChanged[32][2];
DECLARE_NO_COPY_CLASS(CRegTable);
DECLARE_NO_COPY_CLASS(CRegTable);
};
class CRegisterView : public wxGrid
{
public:
CRegisterView(wxWindow* parent, wxWindowID id = wxID_ANY);
void Update() override;
CRegisterView(wxWindow* parent, wxWindowID id = wxID_ANY);
void Update() override;
private:
void OnMouseDownR(wxGridEvent& event);
void OnPopupMenu(wxCommandEvent& event);
void OnMouseDownR(wxGridEvent& event);
void OnPopupMenu(wxCommandEvent& event);
u32 m_selectedAddress = 0;
u32 m_selectedAddress = 0;
// Owned by wx. Deleted implicitly upon destruction.
CRegTable* m_register_table;
// Owned by wx. Deleted implicitly upon destruction.
CRegTable* m_register_table;
};

View File

@ -10,27 +10,25 @@
#include "DolphinWX/Debugger/RegisterView.h"
#include "DolphinWX/Debugger/RegisterWindow.h"
CRegisterWindow::CRegisterWindow(wxWindow* parent, wxWindowID id,
const wxPoint& position, const wxSize& size,
long style, const wxString& name)
: wxPanel(parent, id, position, size, style, name)
, m_GPRGridView(nullptr)
CRegisterWindow::CRegisterWindow(wxWindow* parent, wxWindowID id, const wxPoint& position,
const wxSize& size, long style, const wxString& name)
: wxPanel(parent, id, position, size, style, name), m_GPRGridView(nullptr)
{
CreateGUIControls();
CreateGUIControls();
}
void CRegisterWindow::CreateGUIControls()
{
wxBoxSizer *sGrid = new wxBoxSizer(wxVERTICAL);
m_GPRGridView = new CRegisterView(this);
sGrid->Add(m_GPRGridView, 1, wxGROW);
SetSizer(sGrid);
wxBoxSizer* sGrid = new wxBoxSizer(wxVERTICAL);
m_GPRGridView = new CRegisterView(this);
sGrid->Add(m_GPRGridView, 1, wxGROW);
SetSizer(sGrid);
NotifyUpdate();
NotifyUpdate();
}
void CRegisterWindow::NotifyUpdate()
{
if (m_GPRGridView != nullptr)
m_GPRGridView->Update();
if (m_GPRGridView != nullptr)
m_GPRGridView->Update();
}

View File

@ -11,16 +11,14 @@ class CRegisterView;
class CRegisterWindow : public wxPanel
{
public:
CRegisterWindow(wxWindow* parent,
wxWindowID id = wxID_ANY,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxTAB_TRAVERSAL | wxNO_BORDER,
const wxString& name = _("Registers"));
CRegisterWindow(wxWindow* parent, wxWindowID id = wxID_ANY,
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
long style = wxTAB_TRAVERSAL | wxNO_BORDER,
const wxString& name = _("Registers"));
void NotifyUpdate();
void NotifyUpdate();
private:
CRegisterView* m_GPRGridView;
void CreateGUIControls();
CRegisterView* m_GPRGridView;
void CreateGUIControls();
};

View File

@ -10,8 +10,6 @@
#include "Core/Core.h"
#include "Core/HW/Memmap.h"
#include "Core/PowerPC/PowerPC.h"
#include "DolphinWX/Frame.h"
#include "DolphinWX/WxUtils.h"
#include "DolphinWX/Debugger/BreakpointWindow.h"
#include "DolphinWX/Debugger/CodeWindow.h"
#include "DolphinWX/Debugger/DebuggerUIUtil.h"
@ -19,289 +17,300 @@
#include "DolphinWX/Debugger/RegisterView.h"
#include "DolphinWX/Debugger/WatchView.h"
#include "DolphinWX/Debugger/WatchWindow.h"
#include "DolphinWX/Frame.h"
#include "DolphinWX/WxUtils.h"
enum
{
IDM_DELETEWATCH = 1,
IDM_ADDMEMCHECK,
IDM_VIEWMEMORY,
IDM_DELETEWATCH = 1,
IDM_ADDMEMCHECK,
IDM_VIEWMEMORY,
};
static std::string GetWatchName(int count)
{
return PowerPC::watches.GetWatches().at(count - 1).name;
return PowerPC::watches.GetWatches().at(count - 1).name;
}
static u32 GetWatchAddr(int count)
{
return PowerPC::watches.GetWatches().at(count - 1).iAddress;
return PowerPC::watches.GetWatches().at(count - 1).iAddress;
}
static u32 GetWatchValue(int count)
{
return PowerPC::HostRead_U32(GetWatchAddr(count));
return PowerPC::HostRead_U32(GetWatchAddr(count));
}
static void AddWatchAddr(int count, u32 value)
{
PowerPC::watches.Add(value);
PowerPC::watches.Add(value);
}
static void UpdateWatchAddr(int count, u32 value)
{
PowerPC::watches.Update(count - 1, value);
PowerPC::watches.Update(count - 1, value);
}
static void SetWatchName(int count, const std::string& value)
{
if ((count - 1) < (int)PowerPC::watches.GetWatches().size())
{
PowerPC::watches.UpdateName(count - 1, value);
}
else
{
PowerPC::watches.Add(0);
PowerPC::watches.UpdateName(PowerPC::watches.GetWatches().size() - 1, value);
}
if ((count - 1) < (int)PowerPC::watches.GetWatches().size())
{
PowerPC::watches.UpdateName(count - 1, value);
}
else
{
PowerPC::watches.Add(0);
PowerPC::watches.UpdateName(PowerPC::watches.GetWatches().size() - 1, value);
}
}
static void SetWatchValue(int count, u32 value)
{
PowerPC::HostWrite_U32(value, GetWatchAddr(count));
PowerPC::HostWrite_U32(value, GetWatchAddr(count));
}
static wxString GetValueByRowCol(int row, int col)
{
if (row == 0)
{
// Column Labels
switch (col)
{
case 0: return _("Label");
case 1: return _("Address");
case 2: return _("Hexadecimal");
case 3: return _("Decimal");
case 4: return _("String");
default: return wxEmptyString;
}
}
else if (row <= (int)PowerPC::watches.GetWatches().size())
{
if (Core::IsRunning())
{
switch (col)
{
case 0: return wxString::Format("%s", GetWatchName(row));
case 1: return wxString::Format("%08x", GetWatchAddr(row));
case 2: return wxString::Format("%08x", GetWatchValue(row));
case 3: return wxString::Format("%u", GetWatchValue(row));
case 4:
{
u32 addr = GetWatchAddr(row);
if (PowerPC::HostIsRAMAddress(addr))
return PowerPC::HostGetString(addr, 32).c_str();
else
return wxEmptyString;
}
default: return wxEmptyString;
}
}
}
return wxEmptyString;
if (row == 0)
{
// Column Labels
switch (col)
{
case 0:
return _("Label");
case 1:
return _("Address");
case 2:
return _("Hexadecimal");
case 3:
return _("Decimal");
case 4:
return _("String");
default:
return wxEmptyString;
}
}
else if (row <= (int)PowerPC::watches.GetWatches().size())
{
if (Core::IsRunning())
{
switch (col)
{
case 0:
return wxString::Format("%s", GetWatchName(row));
case 1:
return wxString::Format("%08x", GetWatchAddr(row));
case 2:
return wxString::Format("%08x", GetWatchValue(row));
case 3:
return wxString::Format("%u", GetWatchValue(row));
case 4:
{
u32 addr = GetWatchAddr(row);
if (PowerPC::HostIsRAMAddress(addr))
return PowerPC::HostGetString(addr, 32).c_str();
else
return wxEmptyString;
}
default:
return wxEmptyString;
}
}
}
return wxEmptyString;
}
wxString CWatchTable::GetValue(int row, int col)
{
return GetValueByRowCol(row, col);
return GetValueByRowCol(row, col);
}
void CWatchTable::SetValue(int row, int col, const wxString& strNewVal)
{
u32 newVal = 0;
if (col == 0 || TryParse("0x" + WxStrToStr(strNewVal), &newVal))
{
if (row > 0)
{
switch (col)
{
case 0:
{
SetWatchName(row, std::string(WxStrToStr(strNewVal)));
break;
}
case 1:
{
if (row > (int)PowerPC::watches.GetWatches().size())
{
AddWatchAddr(row, newVal);
row = (int)PowerPC::watches.GetWatches().size();
}
else
{
UpdateWatchAddr(row, newVal);
}
break;
}
case 2:
{
SetWatchValue(row, newVal);
break;
}
default:
break;
}
}
}
u32 newVal = 0;
if (col == 0 || TryParse("0x" + WxStrToStr(strNewVal), &newVal))
{
if (row > 0)
{
switch (col)
{
case 0:
{
SetWatchName(row, std::string(WxStrToStr(strNewVal)));
break;
}
case 1:
{
if (row > (int)PowerPC::watches.GetWatches().size())
{
AddWatchAddr(row, newVal);
row = (int)PowerPC::watches.GetWatches().size();
}
else
{
UpdateWatchAddr(row, newVal);
}
break;
}
case 2:
{
SetWatchValue(row, newVal);
break;
}
default:
break;
}
}
}
}
void CWatchTable::UpdateWatch()
{
for (int i = 0; i < (int)PowerPC::watches.GetWatches().size(); ++i)
{
m_CachedWatchHasChanged[i] = (m_CachedWatch[i] != GetWatchValue(i + 1));
m_CachedWatch[i] = GetWatchValue(i + 1);
}
for (int i = 0; i < (int)PowerPC::watches.GetWatches().size(); ++i)
{
m_CachedWatchHasChanged[i] = (m_CachedWatch[i] != GetWatchValue(i + 1));
m_CachedWatch[i] = GetWatchValue(i + 1);
}
}
wxGridCellAttr* CWatchTable::GetAttr(int row, int col, wxGridCellAttr::wxAttrKind)
{
wxGridCellAttr* attr = new wxGridCellAttr();
wxGridCellAttr* attr = new wxGridCellAttr();
attr->SetBackgroundColour(*wxWHITE);
attr->SetFont(DebuggerFont);
attr->SetBackgroundColour(*wxWHITE);
attr->SetFont(DebuggerFont);
switch (col)
{
case 1:
attr->SetAlignment(wxALIGN_LEFT, wxALIGN_CENTER);
break;
case 3:
case 4:
attr->SetAlignment(wxALIGN_LEFT, wxALIGN_CENTER);
break;
default:
attr->SetAlignment(wxALIGN_LEFT, wxALIGN_CENTER);
break;
}
switch (col)
{
case 1:
attr->SetAlignment(wxALIGN_LEFT, wxALIGN_CENTER);
break;
case 3:
case 4:
attr->SetAlignment(wxALIGN_LEFT, wxALIGN_CENTER);
break;
default:
attr->SetAlignment(wxALIGN_LEFT, wxALIGN_CENTER);
break;
}
if (row == 0)
{
attr->SetReadOnly(true);
attr->SetBackgroundColour(*wxBLACK);
attr->SetTextColour(*wxWHITE);
}
else
{
bool red = false;
if (col == 1)
red = m_CachedWatchHasChanged[row];
if (row == 0)
{
attr->SetReadOnly(true);
attr->SetBackgroundColour(*wxBLACK);
attr->SetTextColour(*wxWHITE);
}
else
{
bool red = false;
if (col == 1)
red = m_CachedWatchHasChanged[row];
attr->SetTextColour(red ? *wxRED : *wxBLACK);
attr->SetTextColour(red ? *wxRED : *wxBLACK);
if (row > (int)(PowerPC::watches.GetWatches().size() + 1) || !Core::IsRunning())
{
attr->SetReadOnly(true);
attr->SetBackgroundColour(*wxLIGHT_GREY);
}
}
if (row > (int)(PowerPC::watches.GetWatches().size() + 1) || !Core::IsRunning())
{
attr->SetReadOnly(true);
attr->SetBackgroundColour(*wxLIGHT_GREY);
}
}
return attr;
return attr;
}
CWatchView::CWatchView(wxWindow* parent, wxWindowID id)
: wxGrid(parent, id)
CWatchView::CWatchView(wxWindow* parent, wxWindowID id) : wxGrid(parent, id)
{
m_watch_table = new CWatchTable();
m_watch_table = new CWatchTable();
SetTable(m_watch_table, true);
SetRowLabelSize(0);
SetColLabelSize(0);
DisableDragRowSize();
SetTable(m_watch_table, true);
SetRowLabelSize(0);
SetColLabelSize(0);
DisableDragRowSize();
Bind(wxEVT_GRID_CELL_RIGHT_CLICK, &CWatchView::OnMouseDownR, this);
Bind(wxEVT_MENU, &CWatchView::OnPopupMenu, this);
Bind(wxEVT_GRID_CELL_RIGHT_CLICK, &CWatchView::OnMouseDownR, this);
Bind(wxEVT_MENU, &CWatchView::OnPopupMenu, this);
}
void CWatchView::Update()
{
if (Core::IsRunning())
{
m_watch_table->UpdateWatch();
ForceRefresh();
}
if (Core::IsRunning())
{
m_watch_table->UpdateWatch();
ForceRefresh();
}
}
void CWatchView::OnMouseDownR(wxGridEvent& event)
{
// popup menu
int row = event.GetRow();
int col = event.GetCol();
// popup menu
int row = event.GetRow();
int col = event.GetCol();
m_selectedRow = row;
m_selectedRow = row;
if (col == 1 || col == 2)
{
wxString strNewVal = GetValueByRowCol(row, col);
TryParse("0x" + WxStrToStr(strNewVal), &m_selectedAddress);
}
if (col == 1 || col == 2)
{
wxString strNewVal = GetValueByRowCol(row, col);
TryParse("0x" + WxStrToStr(strNewVal), &m_selectedAddress);
}
wxMenu menu;
if (row != 0 && row != (int)(PowerPC::watches.GetWatches().size() + 1))
menu.Append(IDM_DELETEWATCH, _("&Delete watch"));
wxMenu menu;
if (row != 0 && row != (int)(PowerPC::watches.GetWatches().size() + 1))
menu.Append(IDM_DELETEWATCH, _("&Delete watch"));
if (row != 0 && row != (int)(PowerPC::watches.GetWatches().size() + 1) && (col == 1 || col == 2))
{
if (row != 0 && row != (int)(PowerPC::watches.GetWatches().size() + 1) && (col == 1 || col == 2))
{
#ifdef ENABLE_MEM_CHECK
menu.Append(IDM_ADDMEMCHECK, _("Add memory &breakpoint"));
menu.Append(IDM_ADDMEMCHECK, _("Add memory &breakpoint"));
#endif
menu.Append(IDM_VIEWMEMORY, _("View &memory"));
}
PopupMenu(&menu);
menu.Append(IDM_VIEWMEMORY, _("View &memory"));
}
PopupMenu(&menu);
}
void CWatchView::OnPopupMenu(wxCommandEvent& event)
{
CFrame* main_frame = static_cast<CFrame*>(GetGrandParent()->GetParent());
CCodeWindow* code_window = main_frame->g_pCodeWindow;
CWatchWindow* watch_window = code_window->m_WatchWindow;
CMemoryWindow* memory_window = code_window->m_MemoryWindow;
CBreakPointWindow* breakpoint_window = code_window->m_BreakpointWindow;
CFrame* main_frame = static_cast<CFrame*>(GetGrandParent()->GetParent());
CCodeWindow* code_window = main_frame->g_pCodeWindow;
CWatchWindow* watch_window = code_window->m_WatchWindow;
CMemoryWindow* memory_window = code_window->m_MemoryWindow;
CBreakPointWindow* breakpoint_window = code_window->m_BreakpointWindow;
wxString strNewVal;
TMemCheck MemCheck;
wxString strNewVal;
TMemCheck MemCheck;
switch (event.GetId())
{
case IDM_DELETEWATCH:
strNewVal = GetValueByRowCol(m_selectedRow, 1);
if (TryParse("0x" + WxStrToStr(strNewVal), &m_selectedAddress))
{
PowerPC::watches.Remove(m_selectedAddress);
if (watch_window)
watch_window->NotifyUpdate();
Refresh();
}
break;
case IDM_ADDMEMCHECK:
MemCheck.StartAddress = m_selectedAddress;
MemCheck.EndAddress = m_selectedAddress;
MemCheck.bRange = false;
MemCheck.OnRead = true;
MemCheck.OnWrite = true;
MemCheck.Log = true;
MemCheck.Break = true;
PowerPC::memchecks.Add(MemCheck);
switch (event.GetId())
{
case IDM_DELETEWATCH:
strNewVal = GetValueByRowCol(m_selectedRow, 1);
if (TryParse("0x" + WxStrToStr(strNewVal), &m_selectedAddress))
{
PowerPC::watches.Remove(m_selectedAddress);
if (watch_window)
watch_window->NotifyUpdate();
Refresh();
}
break;
case IDM_ADDMEMCHECK:
MemCheck.StartAddress = m_selectedAddress;
MemCheck.EndAddress = m_selectedAddress;
MemCheck.bRange = false;
MemCheck.OnRead = true;
MemCheck.OnWrite = true;
MemCheck.Log = true;
MemCheck.Break = true;
PowerPC::memchecks.Add(MemCheck);
if (breakpoint_window)
breakpoint_window->NotifyUpdate();
Refresh();
break;
case IDM_VIEWMEMORY:
if (memory_window)
memory_window->JumpToAddress(m_selectedAddress);
Refresh();
break;
}
event.Skip();
if (breakpoint_window)
breakpoint_window->NotifyUpdate();
Refresh();
break;
case IDM_VIEWMEMORY:
if (memory_window)
memory_window->JumpToAddress(m_selectedAddress);
Refresh();
break;
}
event.Skip();
}

View File

@ -12,41 +12,38 @@
class CWatchTable : public wxGridTableBase
{
enum
{
MAX_SPECIALS = 256,
};
enum
{
MAX_SPECIALS = 256,
};
public:
CWatchTable()
{
}
int GetNumberCols() override { return 5; }
int GetNumberRows() override { return MAX_SPECIALS; }
wxString GetValue(int row, int col) override;
void SetValue(int row, int col, const wxString&) override;
wxGridCellAttr* GetAttr(int, int, wxGridCellAttr::wxAttrKind) override;
void UpdateWatch();
CWatchTable() {}
int GetNumberCols() override { return 5; }
int GetNumberRows() override { return MAX_SPECIALS; }
wxString GetValue(int row, int col) override;
void SetValue(int row, int col, const wxString&) override;
wxGridCellAttr* GetAttr(int, int, wxGridCellAttr::wxAttrKind) override;
void UpdateWatch();
private:
std::array<u32, MAX_SPECIALS> m_CachedWatch;
std::array<bool, MAX_SPECIALS> m_CachedWatchHasChanged;
std::array<u32, MAX_SPECIALS> m_CachedWatch;
std::array<bool, MAX_SPECIALS> m_CachedWatchHasChanged;
DECLARE_NO_COPY_CLASS(CWatchTable);
DECLARE_NO_COPY_CLASS(CWatchTable);
};
class CWatchView : public wxGrid
{
public:
CWatchView(wxWindow* parent, wxWindowID id = wxID_ANY);
void Update() override;
CWatchView(wxWindow* parent, wxWindowID id = wxID_ANY);
void Update() override;
private:
void OnMouseDownR(wxGridEvent& event);
void OnPopupMenu(wxCommandEvent& event);
void OnMouseDownR(wxGridEvent& event);
void OnPopupMenu(wxCommandEvent& event);
u32 m_selectedAddress = 0;
u32 m_selectedRow = 0;
CWatchTable* m_watch_table;
u32 m_selectedAddress = 0;
u32 m_selectedRow = 0;
CWatchTable* m_watch_table;
};

View File

@ -4,114 +4,119 @@
#include <cstddef>
#include <wx/aui/auibar.h>
#include <wx/bitmap.h>
#include <wx/panel.h>
#include <wx/aui/auibar.h>
#include "Common/FileUtil.h"
#include "Common/IniFile.h"
#include "Core/ConfigManager.h"
#include "Core/PowerPC/PowerPC.h"
#include "DolphinWX/WxUtils.h"
#include "DolphinWX/Debugger/WatchView.h"
#include "DolphinWX/Debugger/WatchWindow.h"
#include "DolphinWX/WxUtils.h"
class CWatchToolbar : public wxAuiToolBar
{
public:
CWatchToolbar(CWatchWindow* parent, const wxWindowID id)
: wxAuiToolBar(parent, id, wxDefaultPosition, wxDefaultSize,
wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_TEXT)
{
SetToolBitmapSize(wxSize(16, 16));
CWatchToolbar(CWatchWindow* parent, const wxWindowID id)
: wxAuiToolBar(parent, id, wxDefaultPosition, wxDefaultSize,
wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_TEXT)
{
SetToolBitmapSize(wxSize(16, 16));
m_Bitmaps[Toolbar_File] = WxUtils::LoadResourceBitmap("toolbar_debugger_delete");
m_Bitmaps[Toolbar_File] = WxUtils::LoadResourceBitmap("toolbar_debugger_delete");
AddTool(ID_LOAD, _("Load"), m_Bitmaps[Toolbar_File]);
Bind(wxEVT_TOOL, &CWatchWindow::Event_LoadAll, parent, ID_LOAD);
AddTool(ID_LOAD, _("Load"), m_Bitmaps[Toolbar_File]);
Bind(wxEVT_TOOL, &CWatchWindow::Event_LoadAll, parent, ID_LOAD);
AddTool(ID_SAVE, _("Save"), m_Bitmaps[Toolbar_File]);
Bind(wxEVT_TOOL, &CWatchWindow::Event_SaveAll, parent, ID_SAVE);
}
AddTool(ID_SAVE, _("Save"), m_Bitmaps[Toolbar_File]);
Bind(wxEVT_TOOL, &CWatchWindow::Event_SaveAll, parent, ID_SAVE);
}
private:
enum
{
Toolbar_File,
Num_Bitmaps
};
enum
{
Toolbar_File,
Num_Bitmaps
};
enum
{
ID_LOAD,
ID_SAVE
};
enum
{
ID_LOAD,
ID_SAVE
};
wxBitmap m_Bitmaps[Num_Bitmaps];
wxBitmap m_Bitmaps[Num_Bitmaps];
};
CWatchWindow::CWatchWindow(wxWindow* parent, wxWindowID id,
const wxPoint& position, const wxSize& size,
long style, const wxString& name)
: wxPanel(parent, id, position, size, style, name)
, m_GPRGridView(nullptr)
CWatchWindow::CWatchWindow(wxWindow* parent, wxWindowID id, const wxPoint& position,
const wxSize& size, long style, const wxString& name)
: wxPanel(parent, id, position, size, style, name), m_GPRGridView(nullptr)
{
m_mgr.SetManagedWindow(this);
m_mgr.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_LIVE_RESIZE);
m_mgr.SetManagedWindow(this);
m_mgr.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_LIVE_RESIZE);
m_GPRGridView = new CWatchView(this);
m_GPRGridView = new CWatchView(this);
m_mgr.AddPane(new CWatchToolbar(this, wxID_ANY), wxAuiPaneInfo().ToolbarPane().Top().
LeftDockable(true).RightDockable(true).BottomDockable(false).Floatable(false));
m_mgr.AddPane(m_GPRGridView, wxAuiPaneInfo().CenterPane());
m_mgr.Update();
m_mgr.AddPane(new CWatchToolbar(this, wxID_ANY), wxAuiPaneInfo()
.ToolbarPane()
.Top()
.LeftDockable(true)
.RightDockable(true)
.BottomDockable(false)
.Floatable(false));
m_mgr.AddPane(m_GPRGridView, wxAuiPaneInfo().CenterPane());
m_mgr.Update();
}
CWatchWindow::~CWatchWindow()
{
m_mgr.UnInit();
m_mgr.UnInit();
}
void CWatchWindow::NotifyUpdate()
{
if (m_GPRGridView != nullptr)
m_GPRGridView->Update();
if (m_GPRGridView != nullptr)
m_GPRGridView->Update();
}
void CWatchWindow::Event_SaveAll(wxCommandEvent& WXUNUSED(event))
{
SaveAll();
SaveAll();
}
void CWatchWindow::SaveAll()
{
IniFile ini;
ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetUniqueID() + ".ini", false);
ini.SetLines("Watches", PowerPC::watches.GetStrings());
ini.Save(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetUniqueID() + ".ini");
IniFile ini;
ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetUniqueID() + ".ini",
false);
ini.SetLines("Watches", PowerPC::watches.GetStrings());
ini.Save(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetUniqueID() + ".ini");
}
void CWatchWindow::Event_LoadAll(wxCommandEvent& WXUNUSED(event))
{
LoadAll();
LoadAll();
}
void CWatchWindow::LoadAll()
{
IniFile ini;
Watches::TWatchesStr watches;
IniFile ini;
Watches::TWatchesStr watches;
if (!ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetUniqueID() + ".ini", false))
{
return;
}
if (!ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetUniqueID() +
".ini",
false))
{
return;
}
if (ini.GetLines("Watches", &watches, false))
{
PowerPC::watches.Clear();
PowerPC::watches.AddFromStrings(watches);
}
if (ini.GetLines("Watches", &watches, false))
{
PowerPC::watches.Clear();
PowerPC::watches.AddFromStrings(watches);
}
NotifyUpdate();
NotifyUpdate();
}

View File

@ -4,31 +4,28 @@
#pragma once
#include <wx/panel.h>
#include <wx/aui/framemanager.h>
#include <wx/panel.h>
class CWatchView;
class CWatchWindow : public wxPanel
{
public:
CWatchWindow(wxWindow* parent,
wxWindowID id = wxID_ANY,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxTAB_TRAVERSAL | wxNO_BORDER,
const wxString& name = _("Watch"));
~CWatchWindow();
CWatchWindow(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL | wxNO_BORDER,
const wxString& name = _("Watch"));
~CWatchWindow();
void NotifyUpdate();
void Event_SaveAll(wxCommandEvent& WXUNUSED(event));
void SaveAll();
void Event_LoadAll(wxCommandEvent& WXUNUSED(event));
void LoadAll();
void NotifyUpdate();
void Event_SaveAll(wxCommandEvent& WXUNUSED(event));
void SaveAll();
void Event_LoadAll(wxCommandEvent& WXUNUSED(event));
void LoadAll();
private:
wxAuiManager m_mgr;
wxAuiManager m_mgr;
// Owned by wx. Deleted implicitly upon destruction.
CWatchView* m_GPRGridView;
// Owned by wx. Deleted implicitly upon destruction.
CWatchView* m_GPRGridView;
};