WX: HiDPI: FrameAUI / Debugger
Changes: - MemoryWindow was cleaned up and gives more feedback on searches. Some bugs were fixed as well: - A complex bug that allowed tearing off tabs and opening multiple copies of a debug panel which lead to segfaults - Another segfault related to right-click menus on code/memory views when those tools were floating in their own window.
This commit is contained in:
parent
f39c301579
commit
27d295ec7e
|
@ -23,11 +23,15 @@ BreakPointDlg::BreakPointDlg(CBreakPointWindow* _Parent)
|
||||||
|
|
||||||
m_pEditAddress = new wxTextCtrl(this, wxID_ANY, "80000000");
|
m_pEditAddress = new wxTextCtrl(this, wxID_ANY, "80000000");
|
||||||
|
|
||||||
wxBoxSizer* sMainSizer = new wxBoxSizer(wxVERTICAL);
|
const int space5 = FromDIP(5);
|
||||||
sMainSizer->Add(m_pEditAddress, 0, wxEXPAND | wxALL, 5);
|
wxBoxSizer* main_szr = new wxBoxSizer(wxVERTICAL);
|
||||||
sMainSizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxALL, 5);
|
main_szr->AddSpacer(space5);
|
||||||
|
main_szr->Add(m_pEditAddress, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
|
||||||
|
main_szr->AddSpacer(space5);
|
||||||
|
main_szr->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
|
||||||
|
main_szr->AddSpacer(space5);
|
||||||
|
|
||||||
SetSizerAndFit(sMainSizer);
|
SetSizerAndFit(main_szr);
|
||||||
SetFocus();
|
SetFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ CBreakPointView::CBreakPointView(wxWindow* parent, const wxWindowID id)
|
||||||
Refresh();
|
Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBreakPointView::Update()
|
void CBreakPointView::Repopulate()
|
||||||
{
|
{
|
||||||
ClearAll();
|
ClearAll();
|
||||||
|
|
||||||
|
@ -98,6 +98,6 @@ void CBreakPointView::DeleteCurrentSelection()
|
||||||
u32 Address = (u32)GetItemData(item);
|
u32 Address = (u32)GetItemData(item);
|
||||||
PowerPC::breakpoints.Remove(Address);
|
PowerPC::breakpoints.Remove(Address);
|
||||||
PowerPC::memchecks.Remove(Address);
|
PowerPC::memchecks.Remove(Address);
|
||||||
Update();
|
Repopulate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,6 @@ class CBreakPointView : public wxListCtrl
|
||||||
public:
|
public:
|
||||||
CBreakPointView(wxWindow* parent, const wxWindowID id);
|
CBreakPointView(wxWindow* parent, const wxWindowID id);
|
||||||
|
|
||||||
void Update() override;
|
void Repopulate();
|
||||||
void DeleteCurrentSelection();
|
void DeleteCurrentSelection();
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
// Licensed under GPLv2+
|
// Licensed under GPLv2+
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#include <wx/bitmap.h>
|
#include <wx/bitmap.h>
|
||||||
#include <wx/aui/framemanager.h>
|
#include <wx/aui/framemanager.h>
|
||||||
|
@ -32,11 +34,15 @@ public:
|
||||||
: DolphinAuiToolBar(parent, id, wxDefaultPosition, wxDefaultSize,
|
: DolphinAuiToolBar(parent, id, wxDefaultPosition, wxDefaultSize,
|
||||||
wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_TEXT)
|
wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_TEXT)
|
||||||
{
|
{
|
||||||
SetToolBitmapSize(wxSize(24, 24));
|
wxSize bitmap_size = FromDIP(wxSize(24, 24));
|
||||||
|
SetToolBitmapSize(bitmap_size);
|
||||||
|
|
||||||
m_Bitmaps[Toolbar_Delete] = WxUtils::LoadResourceBitmap("toolbar_debugger_delete");
|
static const std::array<const char* const, Num_Bitmaps> image_names{
|
||||||
m_Bitmaps[Toolbar_Add_BP] = WxUtils::LoadResourceBitmap("toolbar_add_breakpoint");
|
{"toolbar_debugger_delete", "toolbar_add_breakpoint", "toolbar_add_memorycheck"}};
|
||||||
m_Bitmaps[Toolbar_Add_MC] = WxUtils::LoadResourceBitmap("toolbar_add_memorycheck");
|
for (std::size_t i = 0; i < image_names.size(); ++i)
|
||||||
|
m_Bitmaps[i] =
|
||||||
|
WxUtils::LoadScaledResourceBitmap(image_names[i], this, bitmap_size, wxDefaultSize,
|
||||||
|
WxUtils::LSI_SCALE_DOWN | WxUtils::LSI_ALIGN_CENTER);
|
||||||
|
|
||||||
AddTool(ID_DELETE, _("Delete"), m_Bitmaps[Toolbar_Delete]);
|
AddTool(ID_DELETE, _("Delete"), m_Bitmaps[Toolbar_Delete]);
|
||||||
Bind(wxEVT_TOOL, &CBreakPointWindow::OnDelete, parent, ID_DELETE);
|
Bind(wxEVT_TOOL, &CBreakPointWindow::OnDelete, parent, ID_DELETE);
|
||||||
|
@ -84,8 +90,6 @@ CBreakPointWindow::CBreakPointWindow(CCodeWindow* _pCodeWindow, wxWindow* parent
|
||||||
const wxSize& size, long style)
|
const wxSize& size, long style)
|
||||||
: wxPanel(parent, id, position, size, style, title), m_pCodeWindow(_pCodeWindow)
|
: wxPanel(parent, id, position, size, style, title), m_pCodeWindow(_pCodeWindow)
|
||||||
{
|
{
|
||||||
Bind(wxEVT_CLOSE_WINDOW, &CBreakPointWindow::OnClose, this);
|
|
||||||
|
|
||||||
m_mgr.SetManagedWindow(this);
|
m_mgr.SetManagedWindow(this);
|
||||||
m_mgr.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_LIVE_RESIZE);
|
m_mgr.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_LIVE_RESIZE);
|
||||||
|
|
||||||
|
@ -108,15 +112,9 @@ CBreakPointWindow::~CBreakPointWindow()
|
||||||
m_mgr.UnInit();
|
m_mgr.UnInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBreakPointWindow::OnClose(wxCloseEvent& event)
|
|
||||||
{
|
|
||||||
SaveAll();
|
|
||||||
event.Skip();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CBreakPointWindow::NotifyUpdate()
|
void CBreakPointWindow::NotifyUpdate()
|
||||||
{
|
{
|
||||||
m_BreakPointListView->Update();
|
m_BreakPointListView->Repopulate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBreakPointWindow::OnDelete(wxCommandEvent& WXUNUSED(event))
|
void CBreakPointWindow::OnDelete(wxCommandEvent& WXUNUSED(event))
|
||||||
|
|
|
@ -21,21 +21,21 @@ public:
|
||||||
~CBreakPointWindow();
|
~CBreakPointWindow();
|
||||||
|
|
||||||
void NotifyUpdate();
|
void NotifyUpdate();
|
||||||
|
void SaveAll();
|
||||||
|
void LoadAll();
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class CBreakPointBar;
|
||||||
|
|
||||||
void OnDelete(wxCommandEvent& WXUNUSED(event));
|
void OnDelete(wxCommandEvent& WXUNUSED(event));
|
||||||
void OnClear(wxCommandEvent& WXUNUSED(event));
|
void OnClear(wxCommandEvent& WXUNUSED(event));
|
||||||
void OnAddBreakPoint(wxCommandEvent& WXUNUSED(event));
|
void OnAddBreakPoint(wxCommandEvent& WXUNUSED(event));
|
||||||
void OnAddMemoryCheck(wxCommandEvent& WXUNUSED(event));
|
void OnAddMemoryCheck(wxCommandEvent& WXUNUSED(event));
|
||||||
void Event_SaveAll(wxCommandEvent& WXUNUSED(event));
|
void Event_SaveAll(wxCommandEvent& WXUNUSED(event));
|
||||||
void SaveAll();
|
|
||||||
void Event_LoadAll(wxCommandEvent& WXUNUSED(event));
|
void Event_LoadAll(wxCommandEvent& WXUNUSED(event));
|
||||||
void LoadAll();
|
void OnSelectBP(wxListEvent& event);
|
||||||
|
|
||||||
private:
|
|
||||||
wxAuiManager m_mgr;
|
wxAuiManager m_mgr;
|
||||||
CBreakPointView* m_BreakPointListView;
|
CBreakPointView* m_BreakPointListView;
|
||||||
CCodeWindow* m_pCodeWindow;
|
CCodeWindow* m_pCodeWindow;
|
||||||
|
|
||||||
void OnClose(wxCloseEvent& event);
|
|
||||||
void OnSelectBP(wxListEvent& event);
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -53,9 +53,9 @@ CCodeView::CCodeView(DebugInterface* debuginterface, SymbolDB* symboldb, wxWindo
|
||||||
wxWindowID Id)
|
wxWindowID Id)
|
||||||
: wxControl(parent, Id), m_debugger(debuginterface), m_symbol_db(symboldb), m_plain(false),
|
: wxControl(parent, Id), m_debugger(debuginterface), m_symbol_db(symboldb), m_plain(false),
|
||||||
m_curAddress(debuginterface->GetPC()), m_align(debuginterface->GetInstructionSize(0)),
|
m_curAddress(debuginterface->GetPC()), m_align(debuginterface->GetInstructionSize(0)),
|
||||||
m_rowHeight(13), m_selection(0), m_oldSelection(0), m_selecting(false), m_lx(-1), m_ly(-1)
|
m_rowHeight(FromDIP(13)), m_left_col_width(FromDIP(LEFT_COL_WIDTH)), m_selection(0),
|
||||||
|
m_oldSelection(0), m_selecting(false)
|
||||||
{
|
{
|
||||||
Bind(wxEVT_ERASE_BACKGROUND, &CCodeView::OnErase, this);
|
|
||||||
Bind(wxEVT_PAINT, &CCodeView::OnPaint, this);
|
Bind(wxEVT_PAINT, &CCodeView::OnPaint, this);
|
||||||
Bind(wxEVT_MOUSEWHEEL, &CCodeView::OnScrollWheel, this);
|
Bind(wxEVT_MOUSEWHEEL, &CCodeView::OnScrollWheel, this);
|
||||||
Bind(wxEVT_LEFT_DOWN, &CCodeView::OnMouseDown, this);
|
Bind(wxEVT_LEFT_DOWN, &CCodeView::OnMouseDown, this);
|
||||||
|
@ -65,6 +65,13 @@ CCodeView::CCodeView(DebugInterface* debuginterface, SymbolDB* symboldb, wxWindo
|
||||||
Bind(wxEVT_RIGHT_UP, &CCodeView::OnMouseUpR, this);
|
Bind(wxEVT_RIGHT_UP, &CCodeView::OnMouseUpR, this);
|
||||||
Bind(wxEVT_MENU, &CCodeView::OnPopupMenu, this);
|
Bind(wxEVT_MENU, &CCodeView::OnPopupMenu, this);
|
||||||
Bind(wxEVT_SIZE, &CCodeView::OnResize, this);
|
Bind(wxEVT_SIZE, &CCodeView::OnResize, this);
|
||||||
|
|
||||||
|
// Disable the erase event, the entire window is being painted so the erase
|
||||||
|
// event will just cause unnecessary flicker.
|
||||||
|
SetBackgroundStyle(wxBG_STYLE_PAINT);
|
||||||
|
#if defined(__WXMSW__) || defined(__WXGTK__)
|
||||||
|
SetDoubleBuffered(true);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int CCodeView::YToAddress(int y)
|
int CCodeView::YToAddress(int y)
|
||||||
|
@ -80,7 +87,7 @@ void CCodeView::OnMouseDown(wxMouseEvent& event)
|
||||||
int x = event.m_x;
|
int x = event.m_x;
|
||||||
int y = event.m_y;
|
int y = event.m_y;
|
||||||
|
|
||||||
if (x > 16)
|
if (x > m_left_col_width)
|
||||||
{
|
{
|
||||||
m_oldSelection = m_selection;
|
m_oldSelection = m_selection;
|
||||||
m_selection = YToAddress(y);
|
m_selection = YToAddress(y);
|
||||||
|
@ -131,7 +138,7 @@ void CCodeView::OnMouseMove(wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
wxRect rc = GetClientRect();
|
wxRect rc = GetClientRect();
|
||||||
|
|
||||||
if (event.m_leftDown && event.m_x > 16)
|
if (event.m_leftDown && event.m_x > m_left_col_width)
|
||||||
{
|
{
|
||||||
if (event.m_y < 0)
|
if (event.m_y < 0)
|
||||||
{
|
{
|
||||||
|
@ -162,7 +169,7 @@ void CCodeView::RaiseEvent()
|
||||||
|
|
||||||
void CCodeView::OnMouseUpL(wxMouseEvent& event)
|
void CCodeView::OnMouseUpL(wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
if (event.m_x > 16)
|
if (event.m_x > m_left_col_width)
|
||||||
{
|
{
|
||||||
m_curAddress = YToAddress(event.m_y);
|
m_curAddress = YToAddress(event.m_y);
|
||||||
m_selecting = false;
|
m_selecting = false;
|
||||||
|
@ -222,10 +229,6 @@ void CCodeView::InsertBlrNop(int Blr)
|
||||||
|
|
||||||
void CCodeView::OnPopupMenu(wxCommandEvent& event)
|
void CCodeView::OnPopupMenu(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
#if wxUSE_CLIPBOARD
|
|
||||||
wxTheClipboard->Open();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (event.GetId())
|
switch (event.GetId())
|
||||||
{
|
{
|
||||||
case IDM_GOTOINMEMVIEW:
|
case IDM_GOTOINMEMVIEW:
|
||||||
|
@ -234,11 +237,15 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event)
|
||||||
|
|
||||||
#if wxUSE_CLIPBOARD
|
#if wxUSE_CLIPBOARD
|
||||||
case IDM_COPYADDRESS:
|
case IDM_COPYADDRESS:
|
||||||
|
{
|
||||||
|
wxClipboardLocker locker;
|
||||||
wxTheClipboard->SetData(new wxTextDataObject(wxString::Format("%08x", m_selection)));
|
wxTheClipboard->SetData(new wxTextDataObject(wxString::Format("%08x", m_selection)));
|
||||||
break;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case IDM_COPYCODE:
|
case IDM_COPYCODE:
|
||||||
{
|
{
|
||||||
|
wxClipboardLocker locker;
|
||||||
std::string disasm = m_debugger->Disassemble(m_selection);
|
std::string disasm = m_debugger->Disassemble(m_selection);
|
||||||
wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(disasm)));
|
wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(disasm)));
|
||||||
}
|
}
|
||||||
|
@ -246,8 +253,9 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event)
|
||||||
|
|
||||||
case IDM_COPYHEX:
|
case IDM_COPYHEX:
|
||||||
{
|
{
|
||||||
std::string temp = StringFromFormat("%08x", m_debugger->ReadInstruction(m_selection));
|
wxClipboardLocker locker;
|
||||||
wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(temp)));
|
wxTheClipboard->SetData(
|
||||||
|
new wxTextDataObject(wxString::Format("%08x", m_debugger->ReadInstruction(m_selection))));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -266,6 +274,7 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event)
|
||||||
std::string disasm = m_debugger->Disassemble(addr);
|
std::string disasm = m_debugger->Disassemble(addr);
|
||||||
text += StringFromFormat("%08x: ", addr) + disasm + "\r\n";
|
text += StringFromFormat("%08x: ", addr) + disasm + "\r\n";
|
||||||
}
|
}
|
||||||
|
wxClipboardLocker locker;
|
||||||
wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(text)));
|
wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(text)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,6 +292,7 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event)
|
||||||
InsertBlrNop(0);
|
InsertBlrNop(0);
|
||||||
Refresh();
|
Refresh();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDM_INSERTNOP:
|
case IDM_INSERTNOP:
|
||||||
InsertBlrNop(1);
|
InsertBlrNop(1);
|
||||||
Refresh();
|
Refresh();
|
||||||
|
@ -332,12 +342,11 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event)
|
||||||
|
|
||||||
case IDM_PATCHALERT:
|
case IDM_PATCHALERT:
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
#if wxUSE_CLIPBOARD
|
default:
|
||||||
wxTheClipboard->Close();
|
event.Skip();
|
||||||
#endif
|
break;
|
||||||
event.Skip();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCodeView::OnMouseUpR(wxMouseEvent& event)
|
void CCodeView::OnMouseUpR(wxMouseEvent& event)
|
||||||
|
@ -363,104 +372,112 @@ void CCodeView::OnMouseUpR(wxMouseEvent& event)
|
||||||
menu.Append(IDM_JITRESULTS, _("PPC vs X86"))->Enable(Core::IsRunning());
|
menu.Append(IDM_JITRESULTS, _("PPC vs X86"))->Enable(Core::IsRunning());
|
||||||
menu.Append(IDM_INSERTBLR, _("Insert &blr"))->Enable(Core::IsRunning());
|
menu.Append(IDM_INSERTBLR, _("Insert &blr"))->Enable(Core::IsRunning());
|
||||||
menu.Append(IDM_INSERTNOP, _("Insert &nop"))->Enable(Core::IsRunning());
|
menu.Append(IDM_INSERTNOP, _("Insert &nop"))->Enable(Core::IsRunning());
|
||||||
menu.Append(IDM_PATCHALERT, _("Patch alert"))->Enable(Core::IsRunning());
|
// menu.Append(IDM_PATCHALERT, _("Patch alert"))->Enable(Core::IsRunning());
|
||||||
PopupMenu(&menu);
|
PopupMenu(&menu);
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCodeView::OnErase(wxEraseEvent& event)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCodeView::OnPaint(wxPaintEvent& event)
|
void CCodeView::OnPaint(wxPaintEvent& event)
|
||||||
{
|
{
|
||||||
// -------------------------
|
// -------------------------
|
||||||
// General settings
|
// General settings
|
||||||
// -------------------------
|
// -------------------------
|
||||||
std::unique_ptr<wxGraphicsContext> ctx(wxGraphicsContext::Create(wxPaintDC(this)));
|
wxPaintDC paint_dc(this);
|
||||||
wxRect rc = GetClientRect();
|
wxRect rc = GetClientRect();
|
||||||
|
int char_width;
|
||||||
|
|
||||||
|
paint_dc.SetFont(DebuggerFont);
|
||||||
|
{
|
||||||
|
wxFontMetrics metrics = paint_dc.GetFontMetrics();
|
||||||
|
char_width = metrics.averageWidth;
|
||||||
|
if (metrics.height > m_rowHeight)
|
||||||
|
m_rowHeight = metrics.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<wxGraphicsContext> ctx(wxGraphicsContext::Create(paint_dc));
|
||||||
|
ctx->DisableOffset(); // Incompatible with matrix transforms
|
||||||
ctx->SetFont(DebuggerFont, *wxBLACK);
|
ctx->SetFont(DebuggerFont, *wxBLACK);
|
||||||
|
|
||||||
wxDouble w, h;
|
struct Branch
|
||||||
ctx->GetTextExtent("0WJyq", &w, &h);
|
|
||||||
|
|
||||||
if (h > m_rowHeight)
|
|
||||||
m_rowHeight = h;
|
|
||||||
|
|
||||||
ctx->GetTextExtent("W", &w, &h);
|
|
||||||
int charWidth = w;
|
|
||||||
|
|
||||||
struct branch
|
|
||||||
{
|
{
|
||||||
int src, dst, srcAddr;
|
int src, dst, srcAddr;
|
||||||
};
|
};
|
||||||
|
|
||||||
branch branches[256];
|
Branch branches[256];
|
||||||
int numBranches = 0;
|
int num_branches = 0;
|
||||||
// TODO: Add any drawing code here...
|
const int num_rows = ((rc.height / m_rowHeight) / 2) + 2;
|
||||||
int width = rc.width;
|
|
||||||
int numRows = ((rc.height / m_rowHeight) / 2) + 2;
|
const double scale = FromDIP(1024) / 1024.0;
|
||||||
|
const int pen_width = static_cast<int>(std::ceil(scale));
|
||||||
|
const int col_width = rc.width - m_left_col_width;
|
||||||
|
const int text_col = m_left_col_width + pen_width / 2 + 1; // 1 unscaled pixel
|
||||||
|
const int bp_offset_x = FromDIP(LEFT_COL_WIDTH / 8);
|
||||||
|
const wxSize bp_size = FromDIP(wxSize(LEFT_COL_WIDTH * 3 / 4, LEFT_COL_WIDTH * 3 / 4));
|
||||||
|
const int bp_offset_y = (m_rowHeight - bp_size.GetHeight()) / 2;
|
||||||
// ------------
|
// ------------
|
||||||
|
|
||||||
// -------------------------
|
// -------------------------
|
||||||
// Colors and brushes
|
// Colors and brushes
|
||||||
// -------------------------
|
// -------------------------
|
||||||
|
|
||||||
const wxColour bgColor = *wxWHITE;
|
wxColour branch_color = wxTheColourDatabase->Find("PURPLE");
|
||||||
wxPen nullPen(bgColor);
|
wxColour blr_color = wxTheColourDatabase->Find("DARK GREEN");
|
||||||
wxPen currentPen(*wxBLACK_PEN);
|
wxColour instr_color = wxTheColourDatabase->Find("VIOLET");
|
||||||
wxPen selPen(*wxGREY_PEN);
|
wxGraphicsPen null_pen = ctx->CreatePen(*wxTRANSPARENT_PEN);
|
||||||
nullPen.SetStyle(wxPENSTYLE_TRANSPARENT);
|
wxGraphicsPen focus_pen = ctx->CreatePen(wxPen(*wxBLACK, pen_width));
|
||||||
currentPen.SetStyle(wxPENSTYLE_SOLID);
|
wxGraphicsPen selection_pen = ctx->CreatePen(wxPen("GREY", pen_width));
|
||||||
wxBrush currentBrush(*wxLIGHT_GREY_BRUSH);
|
wxGraphicsBrush pc_brush = ctx->CreateBrush(*wxGREEN_BRUSH);
|
||||||
wxBrush pcBrush(*wxGREEN_BRUSH);
|
wxGraphicsBrush bp_brush = ctx->CreateBrush(*wxRED_BRUSH);
|
||||||
wxBrush bpBrush(*wxRED_BRUSH);
|
wxGraphicsBrush back_brush = ctx->CreateBrush(*wxWHITE_BRUSH);
|
||||||
|
wxGraphicsBrush null_brush = ctx->CreateBrush(*wxTRANSPARENT_BRUSH);
|
||||||
|
|
||||||
wxBrush bgBrush(bgColor);
|
|
||||||
wxBrush nullBrush(bgColor);
|
|
||||||
nullBrush.SetStyle(wxBRUSHSTYLE_TRANSPARENT);
|
|
||||||
|
|
||||||
ctx->SetPen(nullPen);
|
|
||||||
ctx->SetBrush(bgBrush);
|
|
||||||
ctx->DrawRectangle(0, 0, 16, rc.height);
|
|
||||||
ctx->DrawRectangle(0, 0, rc.width, 5);
|
|
||||||
// ------------
|
// ------------
|
||||||
|
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
// Walk through all visible rows
|
// Walk through all visible rows
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
for (int i = -numRows; i <= numRows; i++)
|
for (int i = -num_rows; i <= num_rows; i++)
|
||||||
{
|
{
|
||||||
unsigned int address = m_curAddress + (i * m_align);
|
unsigned int address = m_curAddress + (i * m_align);
|
||||||
|
|
||||||
int rowY1 = (rc.height / 2) + (m_rowHeight * i) - (m_rowHeight / 2);
|
int row_y = (rc.height / 2) + (m_rowHeight * i) - (m_rowHeight / 2);
|
||||||
int rowY2 = (rc.height / 2) + (m_rowHeight * i) + (m_rowHeight / 2);
|
|
||||||
|
|
||||||
wxString temp = wxString::Format("%08x", address);
|
wxString temp = wxString::Format("%08x", address);
|
||||||
u32 color = m_debugger->GetColor(address);
|
u32 color = m_debugger->GetColor(address);
|
||||||
wxBrush rowBrush(wxColour(color >> 16, color >> 8, color));
|
wxBrush row_brush(wxColour(color >> 16, color >> 8, color));
|
||||||
ctx->SetBrush(nullBrush);
|
ctx->SetBrush(back_brush);
|
||||||
ctx->SetPen(nullPen);
|
ctx->SetPen(null_pen);
|
||||||
ctx->DrawRectangle(0, rowY1, 16, rowY2 - rowY1 + 2);
|
ctx->DrawRectangle(0, row_y, m_left_col_width, m_rowHeight);
|
||||||
|
|
||||||
if (m_selecting && (address == m_selection))
|
|
||||||
ctx->SetPen(selPen);
|
|
||||||
else
|
|
||||||
ctx->SetPen(i == 0 ? currentPen : nullPen);
|
|
||||||
|
|
||||||
if (address == m_debugger->GetPC())
|
if (address == m_debugger->GetPC())
|
||||||
ctx->SetBrush(pcBrush);
|
ctx->SetBrush(pc_brush);
|
||||||
else
|
else
|
||||||
ctx->SetBrush(rowBrush);
|
ctx->SetBrush(row_brush);
|
||||||
|
|
||||||
|
ctx->SetPen(null_pen);
|
||||||
|
ctx->DrawRectangle(m_left_col_width, row_y, col_width, m_rowHeight);
|
||||||
|
if (i == 0 || (m_selecting && address == m_selection))
|
||||||
|
{
|
||||||
|
if (m_selecting && address == m_selection)
|
||||||
|
ctx->SetPen(selection_pen);
|
||||||
|
else
|
||||||
|
ctx->SetPen(focus_pen);
|
||||||
|
ctx->SetBrush(null_brush);
|
||||||
|
// In a graphics context, the border of a rectangle is drawn along the edge,
|
||||||
|
// it does not count towards the width of the rectangle (i.e. drawn right on
|
||||||
|
// the pixel boundary of the fill area, half inside, half outside. For example
|
||||||
|
// a rect with a 1px pen at (5,5)->(10,10) will have an actual screen size of
|
||||||
|
// (4.5,4.5)->(10.5,10.5) with the line being aliased on the half-pixels)
|
||||||
|
double offset = pen_width / 2.0;
|
||||||
|
ctx->DrawRectangle(m_left_col_width + offset, row_y + offset, col_width - pen_width,
|
||||||
|
m_rowHeight - pen_width);
|
||||||
|
}
|
||||||
|
|
||||||
ctx->DrawRectangle(16, rowY1, width, rowY2 - rowY1 + 1);
|
|
||||||
ctx->SetBrush(currentBrush);
|
|
||||||
if (!m_plain)
|
if (!m_plain)
|
||||||
{
|
{
|
||||||
// the address text is dark red
|
// the address text is dark red
|
||||||
ctx->SetFont(DebuggerFont, wxColour("#600000"));
|
ctx->SetFont(DebuggerFont, wxColour(0x60, 0x00, 0x00));
|
||||||
ctx->DrawText(temp, 17, rowY1);
|
ctx->DrawText(temp, text_col, row_y);
|
||||||
ctx->SetFont(DebuggerFont, *wxBLACK);
|
ctx->SetFont(DebuggerFont, *wxBLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,31 +505,32 @@ void CCodeView::OnPaint(wxPaintEvent& event)
|
||||||
{
|
{
|
||||||
u32 offs = std::stoul(hex_str, nullptr, 16);
|
u32 offs = std::stoul(hex_str, nullptr, 16);
|
||||||
|
|
||||||
branches[numBranches].src = rowY1 + (m_rowHeight / 2);
|
branches[num_branches].src = row_y + (m_rowHeight / 2);
|
||||||
branches[numBranches].srcAddr = (address / m_align);
|
branches[num_branches].srcAddr = (address / m_align);
|
||||||
branches[numBranches++].dst =
|
branches[num_branches++].dst =
|
||||||
(int)(rowY1 + ((s64)(u32)offs - (s64)(u32)address) * m_rowHeight / m_align +
|
(int)(row_y + ((s64)(u32)offs - (s64)(u32)address) * m_rowHeight / m_align +
|
||||||
m_rowHeight / 2);
|
m_rowHeight / 2);
|
||||||
desc = StringFromFormat("-->%s", m_debugger->GetDescription(offs).c_str());
|
desc = StringFromFormat("-->%s", m_debugger->GetDescription(offs).c_str());
|
||||||
|
|
||||||
// the -> arrow illustrations are purple
|
// the -> arrow illustrations are purple
|
||||||
ctx->SetFont(DebuggerFont, wxTheColourDatabase->Find("PURPLE"));
|
ctx->SetFont(DebuggerFont, branch_color);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ctx->SetFont(DebuggerFont, *wxBLACK);
|
ctx->SetFont(DebuggerFont, *wxBLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->DrawText(StrToWxStr(operands), 17 + 17 * charWidth, rowY1);
|
ctx->DrawText(StrToWxStr(operands), text_col + 17 * char_width, row_y);
|
||||||
// ------------
|
// ------------
|
||||||
|
|
||||||
// Show blr as its' own color
|
// Show blr as its' own color
|
||||||
if (opcode == "blr")
|
if (opcode == "blr")
|
||||||
ctx->SetFont(DebuggerFont, wxTheColourDatabase->Find("DARK GREEN"));
|
ctx->SetFont(DebuggerFont, blr_color);
|
||||||
else
|
else
|
||||||
ctx->SetFont(DebuggerFont, wxTheColourDatabase->Find("VIOLET"));
|
ctx->SetFont(DebuggerFont, instr_color);
|
||||||
|
|
||||||
ctx->DrawText(StrToWxStr(opcode), 17 + (m_plain ? 1 * charWidth : 9 * charWidth), rowY1);
|
ctx->DrawText(StrToWxStr(opcode), text_col + (m_plain ? 1 * char_width : 9 * char_width),
|
||||||
|
row_y);
|
||||||
|
|
||||||
if (desc.empty())
|
if (desc.empty())
|
||||||
{
|
{
|
||||||
|
@ -527,15 +545,16 @@ void CCodeView::OnPaint(wxPaintEvent& event)
|
||||||
// UnDecorateSymbolName(desc,temp,255,UNDNAME_COMPLETE);
|
// UnDecorateSymbolName(desc,temp,255,UNDNAME_COMPLETE);
|
||||||
if (!desc.empty())
|
if (!desc.empty())
|
||||||
{
|
{
|
||||||
ctx->DrawText(StrToWxStr(desc), 17 + 35 * charWidth, rowY1);
|
ctx->DrawText(StrToWxStr(desc), text_col + 45 * char_width, row_y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show red breakpoint dot
|
// Show red breakpoint dot
|
||||||
if (m_debugger->IsBreakpoint(address))
|
if (m_debugger->IsBreakpoint(address))
|
||||||
{
|
{
|
||||||
ctx->SetBrush(bpBrush);
|
ctx->SetPen(null_pen);
|
||||||
ctx->DrawRectangle(2, rowY1 + 1, 11, 11);
|
ctx->SetBrush(bp_brush);
|
||||||
|
ctx->DrawEllipse(bp_offset_x, row_y + bp_offset_y, bp_size.GetWidth(), bp_size.GetHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // end of for
|
} // end of for
|
||||||
|
@ -544,22 +563,24 @@ void CCodeView::OnPaint(wxPaintEvent& event)
|
||||||
// -------------------------
|
// -------------------------
|
||||||
// Colors and brushes
|
// Colors and brushes
|
||||||
// -------------------------
|
// -------------------------
|
||||||
ctx->SetPen(currentPen);
|
ctx->SetPen(focus_pen);
|
||||||
|
|
||||||
for (int i = 0; i < numBranches; i++)
|
wxGraphicsPath branch_path = ctx->CreatePath();
|
||||||
|
|
||||||
|
for (int i = 0; i < num_branches; ++i)
|
||||||
{
|
{
|
||||||
int x = 17 + 49 * charWidth + (branches[i].srcAddr % 9) * 8;
|
int x = text_col + 52 * char_width + (branches[i].srcAddr % 9) * 8;
|
||||||
MoveTo(x - 2, branches[i].src);
|
branch_path.MoveToPoint(x - 2 * scale, branches[i].src);
|
||||||
|
|
||||||
if (branches[i].dst < rc.height + 400 && branches[i].dst > -400)
|
if (branches[i].dst < rc.height + 400 && branches[i].dst > -400)
|
||||||
{
|
{
|
||||||
LineTo(ctx, x + 2, branches[i].src);
|
branch_path.AddLineToPoint(x + 2 * scale, branches[i].src);
|
||||||
LineTo(ctx, x + 2, branches[i].dst);
|
branch_path.AddLineToPoint(x + 2 * scale, branches[i].dst);
|
||||||
LineTo(ctx, x - 4, branches[i].dst);
|
branch_path.AddLineToPoint(x - 4 * scale, branches[i].dst);
|
||||||
|
|
||||||
MoveTo(x, branches[i].dst - 4);
|
branch_path.MoveToPoint(x, branches[i].dst - 4 * scale);
|
||||||
LineTo(ctx, x - 4, branches[i].dst);
|
branch_path.AddLineToPoint(x - 4 * scale, branches[i].dst);
|
||||||
LineTo(ctx, x + 1, branches[i].dst + 5);
|
branch_path.AddLineToPoint(x + 1 * scale, branches[i].dst + 5 * scale);
|
||||||
}
|
}
|
||||||
// else
|
// else
|
||||||
//{
|
//{
|
||||||
|
@ -575,18 +596,19 @@ void CCodeView::OnPaint(wxPaintEvent& event)
|
||||||
// LineTo(ctx, x, branches[i].dst+4);
|
// LineTo(ctx, x, branches[i].dst+4);
|
||||||
// LineTo(ctx, x-2, branches[i].dst);
|
// LineTo(ctx, x-2, branches[i].dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the pen width is odd then we need to offset the path so that lines are drawn in
|
||||||
|
// the middle of pixels instead of the edge so we don't get aliasing.
|
||||||
|
if (pen_width & 1)
|
||||||
|
{
|
||||||
|
wxGraphicsMatrix matrix = ctx->CreateMatrix();
|
||||||
|
matrix.Translate(0.5, 0.5);
|
||||||
|
branch_path.Transform(matrix);
|
||||||
|
}
|
||||||
|
ctx->StrokePath(branch_path);
|
||||||
// ------------
|
// ------------
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCodeView::LineTo(std::unique_ptr<wxGraphicsContext>& ctx, int x, int y)
|
|
||||||
{
|
|
||||||
std::vector<wxPoint2DDouble> points{wxPoint2DDouble(m_lx, m_ly), wxPoint2DDouble(x, y)};
|
|
||||||
|
|
||||||
ctx->DrawLines(points.size(), points.data());
|
|
||||||
m_lx = x;
|
|
||||||
m_ly = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCodeView::OnResize(wxSizeEvent& event)
|
void CCodeView::OnResize(wxSizeEvent& event)
|
||||||
{
|
{
|
||||||
Refresh();
|
Refresh();
|
||||||
|
|
|
@ -40,7 +40,6 @@ public:
|
||||||
void SetPlain() { m_plain = true; }
|
void SetPlain() { m_plain = true; }
|
||||||
private:
|
private:
|
||||||
void OnPaint(wxPaintEvent& event);
|
void OnPaint(wxPaintEvent& event);
|
||||||
void OnErase(wxEraseEvent& event);
|
|
||||||
void OnScrollWheel(wxMouseEvent& event);
|
void OnScrollWheel(wxMouseEvent& event);
|
||||||
void OnMouseDown(wxMouseEvent& event);
|
void OnMouseDown(wxMouseEvent& event);
|
||||||
void OnMouseMove(wxMouseEvent& event);
|
void OnMouseMove(wxMouseEvent& event);
|
||||||
|
@ -55,14 +54,6 @@ private:
|
||||||
u32 AddrToBranch(u32 addr);
|
u32 AddrToBranch(u32 addr);
|
||||||
void OnResize(wxSizeEvent& event);
|
void OnResize(wxSizeEvent& event);
|
||||||
|
|
||||||
void MoveTo(int x, int y)
|
|
||||||
{
|
|
||||||
m_lx = x;
|
|
||||||
m_ly = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LineTo(std::unique_ptr<wxGraphicsContext>& dc, int x, int y);
|
|
||||||
|
|
||||||
struct BlrStruct // for IDM_INSERTBLR
|
struct BlrStruct // for IDM_INSERTBLR
|
||||||
{
|
{
|
||||||
u32 address;
|
u32 address;
|
||||||
|
@ -70,6 +61,8 @@ private:
|
||||||
};
|
};
|
||||||
std::vector<BlrStruct> m_blrList;
|
std::vector<BlrStruct> m_blrList;
|
||||||
|
|
||||||
|
static constexpr int LEFT_COL_WIDTH = 16;
|
||||||
|
|
||||||
DebugInterface* m_debugger;
|
DebugInterface* m_debugger;
|
||||||
SymbolDB* m_symbol_db;
|
SymbolDB* m_symbol_db;
|
||||||
|
|
||||||
|
@ -78,10 +71,9 @@ private:
|
||||||
int m_curAddress;
|
int m_curAddress;
|
||||||
int m_align;
|
int m_align;
|
||||||
int m_rowHeight;
|
int m_rowHeight;
|
||||||
|
int m_left_col_width;
|
||||||
|
|
||||||
u32 m_selection;
|
u32 m_selection;
|
||||||
u32 m_oldSelection;
|
u32 m_oldSelection;
|
||||||
bool m_selecting;
|
bool m_selecting;
|
||||||
|
|
||||||
int m_lx, m_ly;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "DolphinWX/Debugger/CodeWindow.h"
|
#include "DolphinWX/Debugger/CodeWindow.h"
|
||||||
#include "DolphinWX/Debugger/DebuggerUIUtil.h"
|
#include "DolphinWX/Debugger/DebuggerUIUtil.h"
|
||||||
#include "DolphinWX/Debugger/JitWindow.h"
|
#include "DolphinWX/Debugger/JitWindow.h"
|
||||||
|
#include "DolphinWX/Debugger/MemoryWindow.h"
|
||||||
#include "DolphinWX/Debugger/RegisterWindow.h"
|
#include "DolphinWX/Debugger/RegisterWindow.h"
|
||||||
#include "DolphinWX/Debugger/WatchWindow.h"
|
#include "DolphinWX/Debugger/WatchWindow.h"
|
||||||
#include "DolphinWX/AuiToolBar.h"
|
#include "DolphinWX/AuiToolBar.h"
|
||||||
|
@ -54,9 +55,8 @@
|
||||||
CCodeWindow::CCodeWindow(const SConfig& _LocalCoreStartupParameter, CFrame* parent, wxWindowID id,
|
CCodeWindow::CCodeWindow(const SConfig& _LocalCoreStartupParameter, CFrame* parent, wxWindowID id,
|
||||||
const wxPoint& position, const wxSize& size, long style,
|
const wxPoint& position, const wxSize& size, long style,
|
||||||
const wxString& name)
|
const wxString& name)
|
||||||
: wxPanel(parent, id, position, size, style, name), Parent(parent), m_RegisterWindow(nullptr),
|
: wxPanel(parent, id, position, size, style, name), m_sibling_panels(), Parent(parent),
|
||||||
m_WatchWindow(nullptr), m_BreakpointWindow(nullptr), m_MemoryWindow(nullptr),
|
codeview(nullptr)
|
||||||
m_JitWindow(nullptr), m_SoundWindow(nullptr), m_VideoWindow(nullptr), codeview(nullptr)
|
|
||||||
{
|
{
|
||||||
InitBitmaps();
|
InitBitmaps();
|
||||||
|
|
||||||
|
@ -88,21 +88,31 @@ CCodeWindow::CCodeWindow(const SConfig& _LocalCoreStartupParameter, CFrame* pare
|
||||||
|
|
||||||
m_aui_manager.SetManagedWindow(this);
|
m_aui_manager.SetManagedWindow(this);
|
||||||
m_aui_manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_LIVE_RESIZE);
|
m_aui_manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_LIVE_RESIZE);
|
||||||
m_aui_manager.AddPane(m_aui_toolbar,
|
m_aui_manager.AddPane(m_aui_toolbar, wxAuiPaneInfo().ToolbarPane().Top().Floatable(false));
|
||||||
wxAuiPaneInfo().MinSize(150, -1).ToolbarPane().Top().Floatable(false));
|
m_aui_manager.AddPane(callstack, wxAuiPaneInfo()
|
||||||
m_aui_manager.AddPane(
|
.MinSize(FromDIP(wxSize(150, 100)))
|
||||||
callstack,
|
.Left()
|
||||||
wxAuiPaneInfo().MinSize(150, 100).Left().CloseButton(false).Floatable(false).Caption(
|
.CloseButton(false)
|
||||||
_("Callstack")));
|
.Floatable(false)
|
||||||
m_aui_manager.AddPane(
|
.Caption(_("Callstack")));
|
||||||
symbols, wxAuiPaneInfo().MinSize(150, 100).Left().CloseButton(false).Floatable(false).Caption(
|
m_aui_manager.AddPane(symbols, wxAuiPaneInfo()
|
||||||
_("Symbols")));
|
.MinSize(FromDIP(wxSize(150, 100)))
|
||||||
m_aui_manager.AddPane(
|
.Left()
|
||||||
calls, wxAuiPaneInfo().MinSize(150, 100).Left().CloseButton(false).Floatable(false).Caption(
|
.CloseButton(false)
|
||||||
_("Function calls")));
|
.Floatable(false)
|
||||||
m_aui_manager.AddPane(
|
.Caption(_("Symbols")));
|
||||||
callers, wxAuiPaneInfo().MinSize(150, 100).Left().CloseButton(false).Floatable(false).Caption(
|
m_aui_manager.AddPane(calls, wxAuiPaneInfo()
|
||||||
_("Function callers")));
|
.MinSize(FromDIP(wxSize(150, 100)))
|
||||||
|
.Left()
|
||||||
|
.CloseButton(false)
|
||||||
|
.Floatable(false)
|
||||||
|
.Caption(_("Function calls")));
|
||||||
|
m_aui_manager.AddPane(callers, wxAuiPaneInfo()
|
||||||
|
.MinSize(FromDIP(wxSize(150, 100)))
|
||||||
|
.Left()
|
||||||
|
.CloseButton(false)
|
||||||
|
.Floatable(false)
|
||||||
|
.Caption(_("Function callers")));
|
||||||
m_aui_manager.AddPane(codeview, wxAuiPaneInfo().CenterPane().CloseButton(false).Floatable(false));
|
m_aui_manager.AddPane(codeview, wxAuiPaneInfo().CenterPane().CloseButton(false).Floatable(false));
|
||||||
m_aui_manager.Update();
|
m_aui_manager.Update();
|
||||||
|
|
||||||
|
@ -144,30 +154,30 @@ void CCodeWindow::OnHostMessage(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
case IDM_NOTIFY_MAP_LOADED:
|
case IDM_NOTIFY_MAP_LOADED:
|
||||||
NotifyMapLoaded();
|
NotifyMapLoaded();
|
||||||
if (m_BreakpointWindow)
|
if (HasPanel<CBreakPointWindow>())
|
||||||
m_BreakpointWindow->NotifyUpdate();
|
GetPanel<CBreakPointWindow>()->NotifyUpdate();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDM_UPDATE_DISASM_DIALOG:
|
case IDM_UPDATE_DISASM_DIALOG:
|
||||||
Update();
|
Repopulate();
|
||||||
if (CPU::IsStepping())
|
if (HasPanel<CRegisterWindow>())
|
||||||
Parent->UpdateGUI();
|
GetPanel<CRegisterWindow>()->NotifyUpdate();
|
||||||
if (m_RegisterWindow)
|
if (HasPanel<CWatchWindow>())
|
||||||
m_RegisterWindow->NotifyUpdate();
|
GetPanel<CWatchWindow>()->NotifyUpdate();
|
||||||
if (m_WatchWindow)
|
if (HasPanel<CMemoryWindow>())
|
||||||
m_WatchWindow->NotifyUpdate();
|
GetPanel<CMemoryWindow>()->Refresh();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDM_UPDATE_BREAKPOINTS:
|
case IDM_UPDATE_BREAKPOINTS:
|
||||||
if (m_BreakpointWindow)
|
Repopulate();
|
||||||
m_BreakpointWindow->NotifyUpdate();
|
if (HasPanel<CBreakPointWindow>())
|
||||||
|
GetPanel<CBreakPointWindow>()->NotifyUpdate();
|
||||||
|
if (HasPanel<CMemoryWindow>())
|
||||||
|
GetPanel<CMemoryWindow>()->Refresh();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDM_UPDATE_JIT_PANE:
|
case IDM_UPDATE_JIT_PANE:
|
||||||
// Check if the JIT pane is in the AUI notebook. If not, add it and switch to it.
|
RequirePanel<CJitWindow>()->ViewAddr(codeview->GetSelection());
|
||||||
if (!m_JitWindow)
|
|
||||||
ToggleJitWindow(true);
|
|
||||||
m_JitWindow->ViewAddr(codeview->GetSelection());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,12 +205,12 @@ void CCodeWindow::OnCodeStep(wxCommandEvent& event)
|
||||||
|
|
||||||
case IDM_SKIP:
|
case IDM_SKIP:
|
||||||
PC += 4;
|
PC += 4;
|
||||||
Update();
|
Repopulate();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDM_SETPC:
|
case IDM_SETPC:
|
||||||
PC = codeview->GetSelection();
|
PC = codeview->GetSelection();
|
||||||
Update();
|
Repopulate();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDM_GOTOPC:
|
case IDM_GOTOPC:
|
||||||
|
@ -373,8 +383,12 @@ void CCodeWindow::StepOut()
|
||||||
PowerPC::SetMode(old_mode);
|
PowerPC::SetMode(old_mode);
|
||||||
CPU::PauseAndLock(false, false);
|
CPU::PauseAndLock(false, false);
|
||||||
|
|
||||||
Host_UpdateDisasmDialog();
|
JumpToAddress(PC);
|
||||||
UpdateButtonStates();
|
{
|
||||||
|
wxCommandEvent ev(wxEVT_HOST_COMMAND, IDM_UPDATE_DISASM_DIALOG);
|
||||||
|
GetEventHandler()->ProcessEvent(ev);
|
||||||
|
}
|
||||||
|
|
||||||
// Update all toolbars in the aui manager
|
// Update all toolbars in the aui manager
|
||||||
Parent->UpdateGUI();
|
Parent->UpdateGUI();
|
||||||
}
|
}
|
||||||
|
@ -386,7 +400,7 @@ void CCodeWindow::ToggleBreakpoint()
|
||||||
{
|
{
|
||||||
if (codeview)
|
if (codeview)
|
||||||
codeview->ToggleBreakpoint(codeview->GetSelection());
|
codeview->ToggleBreakpoint(codeview->GetSelection());
|
||||||
Update();
|
Repopulate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,7 +709,7 @@ void CCodeWindow::PopulateToolbar(wxToolBar* toolBar)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update GUI
|
// Update GUI
|
||||||
void CCodeWindow::Update()
|
void CCodeWindow::Repopulate()
|
||||||
{
|
{
|
||||||
if (!codeview)
|
if (!codeview)
|
||||||
return;
|
return;
|
||||||
|
@ -714,41 +728,28 @@ void CCodeWindow::UpdateButtonStates()
|
||||||
bool Initialized = (Core::GetState() != Core::CORE_UNINITIALIZED);
|
bool Initialized = (Core::GetState() != Core::CORE_UNINITIALIZED);
|
||||||
bool Pause = (Core::GetState() == Core::CORE_PAUSE);
|
bool Pause = (Core::GetState() == Core::CORE_PAUSE);
|
||||||
bool Stepping = CPU::IsStepping();
|
bool Stepping = CPU::IsStepping();
|
||||||
|
bool can_step = Initialized && Stepping;
|
||||||
wxToolBar* ToolBar = GetToolBar();
|
wxToolBar* ToolBar = GetToolBar();
|
||||||
|
|
||||||
// Toolbar
|
// Toolbar
|
||||||
if (!ToolBar)
|
if (!ToolBar)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!Initialized)
|
ToolBar->EnableTool(IDM_STEP, can_step);
|
||||||
{
|
ToolBar->EnableTool(IDM_STEPOVER, can_step);
|
||||||
ToolBar->EnableTool(IDM_STEPOVER, false);
|
ToolBar->EnableTool(IDM_STEPOUT, can_step);
|
||||||
ToolBar->EnableTool(IDM_STEPOUT, false);
|
ToolBar->EnableTool(IDM_SKIP, can_step);
|
||||||
ToolBar->EnableTool(IDM_SKIP, false);
|
ToolBar->EnableTool(IDM_SETPC, Pause);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!Stepping)
|
|
||||||
{
|
|
||||||
ToolBar->EnableTool(IDM_STEPOVER, false);
|
|
||||||
ToolBar->EnableTool(IDM_STEPOUT, false);
|
|
||||||
ToolBar->EnableTool(IDM_SKIP, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ToolBar->EnableTool(IDM_STEPOVER, true);
|
|
||||||
ToolBar->EnableTool(IDM_STEPOUT, true);
|
|
||||||
ToolBar->EnableTool(IDM_SKIP, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ToolBar->EnableTool(IDM_STEP, Initialized && Stepping);
|
|
||||||
ToolBar->Realize();
|
ToolBar->Realize();
|
||||||
|
|
||||||
// Menu bar
|
// Menu bar
|
||||||
// ------------------
|
// ------------------
|
||||||
GetMenuBar()->Enable(IDM_INTERPRETER, Pause); // CPU Mode
|
GetMenuBar()->Enable(IDM_INTERPRETER, Pause); // CPU Mode
|
||||||
|
|
||||||
|
GetMenuBar()->Enable(IDM_STEP, can_step);
|
||||||
|
GetMenuBar()->Enable(IDM_STEPOVER, can_step);
|
||||||
|
GetMenuBar()->Enable(IDM_STEPOUT, can_step);
|
||||||
|
|
||||||
GetMenuBar()->Enable(IDM_JIT_NO_BLOCK_CACHE, !Initialized);
|
GetMenuBar()->Enable(IDM_JIT_NO_BLOCK_CACHE, !Initialized);
|
||||||
|
|
||||||
GetMenuBar()->Enable(IDM_JIT_OFF, Pause);
|
GetMenuBar()->Enable(IDM_JIT_OFF, Pause);
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include <wx/aui/framemanager.h>
|
#include <wx/aui/framemanager.h>
|
||||||
#include <wx/bitmap.h>
|
#include <wx/bitmap.h>
|
||||||
#include <wx/panel.h>
|
#include <wx/panel.h>
|
||||||
|
@ -12,16 +14,16 @@
|
||||||
#include "Common/Event.h"
|
#include "Common/Event.h"
|
||||||
#include "DolphinWX/Globals.h"
|
#include "DolphinWX/Globals.h"
|
||||||
|
|
||||||
|
class CCodeView;
|
||||||
class CFrame;
|
class CFrame;
|
||||||
|
struct SConfig;
|
||||||
|
class CBreakPointWindow;
|
||||||
class CRegisterWindow;
|
class CRegisterWindow;
|
||||||
class CWatchWindow;
|
class CWatchWindow;
|
||||||
class CBreakPointWindow;
|
|
||||||
class CMemoryWindow;
|
class CMemoryWindow;
|
||||||
class CJitWindow;
|
class CJitWindow;
|
||||||
class CCodeView;
|
|
||||||
class DSPDebuggerLLE;
|
class DSPDebuggerLLE;
|
||||||
class GFXDebuggerPanel;
|
class GFXDebuggerPanel;
|
||||||
struct SConfig;
|
|
||||||
|
|
||||||
class DolphinAuiToolBar;
|
class DolphinAuiToolBar;
|
||||||
class wxListBox;
|
class wxListBox;
|
||||||
|
@ -29,6 +31,48 @@ class wxMenu;
|
||||||
class wxMenuBar;
|
class wxMenuBar;
|
||||||
class wxToolBar;
|
class wxToolBar;
|
||||||
|
|
||||||
|
namespace Details
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
struct DebugPanelToID;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct DebugPanelToID<CBreakPointWindow>
|
||||||
|
{
|
||||||
|
static constexpr int ID = IDM_BREAKPOINT_WINDOW;
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct DebugPanelToID<CRegisterWindow>
|
||||||
|
{
|
||||||
|
static constexpr int ID = IDM_REGISTER_WINDOW;
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct DebugPanelToID<CWatchWindow>
|
||||||
|
{
|
||||||
|
static constexpr int ID = IDM_WATCH_WINDOW;
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct DebugPanelToID<CMemoryWindow>
|
||||||
|
{
|
||||||
|
static constexpr int ID = IDM_MEMORY_WINDOW;
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct DebugPanelToID<CJitWindow>
|
||||||
|
{
|
||||||
|
static constexpr int ID = IDM_JIT_WINDOW;
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct DebugPanelToID<DSPDebuggerLLE>
|
||||||
|
{
|
||||||
|
static constexpr int ID = IDM_SOUND_WINDOW;
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct DebugPanelToID<GFXDebuggerPanel>
|
||||||
|
{
|
||||||
|
static constexpr int ID = IDM_VIDEO_WINDOW;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
class CCodeWindow : public wxPanel
|
class CCodeWindow : public wxPanel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -41,10 +85,8 @@ public:
|
||||||
void Save();
|
void Save();
|
||||||
|
|
||||||
// Parent interaction
|
// Parent interaction
|
||||||
CFrame* Parent;
|
|
||||||
wxMenuBar* GetMenuBar();
|
wxMenuBar* GetMenuBar();
|
||||||
wxToolBar* GetToolBar();
|
wxToolBar* GetToolBar();
|
||||||
wxBitmap m_Bitmaps[Toolbar_Debug_Bitmap_Max];
|
|
||||||
|
|
||||||
bool UseInterpreter();
|
bool UseInterpreter();
|
||||||
bool BootToPause();
|
bool BootToPause();
|
||||||
|
@ -53,7 +95,7 @@ public:
|
||||||
bool JITNoBlockLinking();
|
bool JITNoBlockLinking();
|
||||||
bool JumpToAddress(u32 address);
|
bool JumpToAddress(u32 address);
|
||||||
|
|
||||||
void Update() override;
|
void Repopulate();
|
||||||
void NotifyMapLoaded();
|
void NotifyMapLoaded();
|
||||||
void CreateMenu(const SConfig& _LocalCoreStartupParameter, wxMenuBar* pMenuBar);
|
void CreateMenu(const SConfig& _LocalCoreStartupParameter, wxMenuBar* pMenuBar);
|
||||||
void CreateMenuOptions(wxMenu* pMenu);
|
void CreateMenuOptions(wxMenu* pMenu);
|
||||||
|
@ -63,29 +105,35 @@ public:
|
||||||
void OpenPages();
|
void OpenPages();
|
||||||
|
|
||||||
// Menu bar
|
// Menu bar
|
||||||
void ToggleCodeWindow(bool bShow);
|
// FIXME: This belongs in a separate class.
|
||||||
void ToggleRegisterWindow(bool bShow);
|
void TogglePanel(int id, bool show);
|
||||||
void ToggleWatchWindow(bool bShow);
|
wxPanel* GetUntypedPanel(int id) const;
|
||||||
void ToggleBreakPointWindow(bool bShow);
|
bool HasUntypedPanel(int id) const { return GetUntypedPanel(id) != nullptr; }
|
||||||
void ToggleMemoryWindow(bool bShow);
|
template <class T>
|
||||||
void ToggleJitWindow(bool bShow);
|
T* GetPanel() const
|
||||||
void ToggleSoundWindow(bool bShow);
|
{
|
||||||
void ToggleVideoWindow(bool bShow);
|
return static_cast<T*>(GetUntypedPanel(Details::DebugPanelToID<T>::ID));
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
bool HasPanel() const
|
||||||
|
{
|
||||||
|
return HasUntypedPanel(Details::DebugPanelToID<T>::ID);
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
T* RequirePanel()
|
||||||
|
{
|
||||||
|
if (T* p = GetPanel<T>())
|
||||||
|
return p;
|
||||||
|
|
||||||
// Sub dialogs
|
TogglePanel(Details::DebugPanelToID<T>::ID, true);
|
||||||
CRegisterWindow* m_RegisterWindow;
|
return GetPanel<T>();
|
||||||
CWatchWindow* m_WatchWindow;
|
}
|
||||||
CBreakPointWindow* m_BreakpointWindow;
|
|
||||||
CMemoryWindow* m_MemoryWindow;
|
|
||||||
CJitWindow* m_JitWindow;
|
|
||||||
DSPDebuggerLLE* m_SoundWindow;
|
|
||||||
GFXDebuggerPanel* m_VideoWindow;
|
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
bool bAutomaticStart;
|
bool bAutomaticStart;
|
||||||
bool bBootToPause;
|
bool bBootToPause;
|
||||||
bool bShowOnStart[IDM_VIDEO_WINDOW - IDM_LOG_WINDOW + 1];
|
bool bShowOnStart[IDM_DEBUG_WINDOW_LIST_END - IDM_DEBUG_WINDOW_LIST_START];
|
||||||
int iNbAffiliation[IDM_CODE_WINDOW - IDM_LOG_WINDOW + 1];
|
int iNbAffiliation[IDM_DEBUG_WINDOW_LIST_END - IDM_DEBUG_WINDOW_LIST_START];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void OnCPUMode(wxCommandEvent& event);
|
void OnCPUMode(wxCommandEvent& event);
|
||||||
|
@ -99,7 +147,6 @@ private:
|
||||||
void OnProfilerMenu(wxCommandEvent& event);
|
void OnProfilerMenu(wxCommandEvent& event);
|
||||||
|
|
||||||
void OnSymbolListChange(wxCommandEvent& event);
|
void OnSymbolListChange(wxCommandEvent& event);
|
||||||
void OnSymbolListContextMenu(wxContextMenuEvent& event);
|
|
||||||
void OnCallstackListChange(wxCommandEvent& event);
|
void OnCallstackListChange(wxCommandEvent& event);
|
||||||
void OnCallersListChange(wxCommandEvent& event);
|
void OnCallersListChange(wxCommandEvent& event);
|
||||||
void OnCallsListChange(wxCommandEvent& event);
|
void OnCallsListChange(wxCommandEvent& event);
|
||||||
|
@ -116,7 +163,15 @@ private:
|
||||||
void UpdateCallstack();
|
void UpdateCallstack();
|
||||||
|
|
||||||
void InitBitmaps();
|
void InitBitmaps();
|
||||||
|
wxPanel* CreateSiblingPanel(int id);
|
||||||
|
|
||||||
|
wxBitmap m_Bitmaps[Toolbar_Debug_Bitmap_Max];
|
||||||
|
|
||||||
|
// Sibling debugger panels
|
||||||
|
// FIXME: This obviously belongs in some manager class above this one.
|
||||||
|
std::array<wxPanel*, IDM_DEBUG_WINDOW_LIST_END - IDM_DEBUG_WINDOW_LIST_START> m_sibling_panels;
|
||||||
|
|
||||||
|
CFrame* Parent;
|
||||||
CCodeView* codeview;
|
CCodeView* codeview;
|
||||||
wxListBox* callstack;
|
wxListBox* callstack;
|
||||||
wxListBox* symbols;
|
wxListBox* symbols;
|
||||||
|
|
|
@ -453,7 +453,7 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
|
||||||
break;
|
break;
|
||||||
case IDM_PATCH_HLE_FUNCTIONS:
|
case IDM_PATCH_HLE_FUNCTIONS:
|
||||||
HLE::PatchFunctions();
|
HLE::PatchFunctions();
|
||||||
Update();
|
Repopulate();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -464,7 +464,6 @@ void CCodeWindow::NotifyMapLoaded()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_symbolDB.FillInCallers();
|
g_symbolDB.FillInCallers();
|
||||||
// symbols->Show(false); // hide it for faster filling
|
|
||||||
symbols->Freeze(); // HyperIris: wx style fast filling
|
symbols->Freeze(); // HyperIris: wx style fast filling
|
||||||
symbols->Clear();
|
symbols->Clear();
|
||||||
for (const auto& symbol : g_symbolDB.Symbols())
|
for (const auto& symbol : g_symbolDB.Symbols())
|
||||||
|
@ -473,8 +472,7 @@ void CCodeWindow::NotifyMapLoaded()
|
||||||
symbols->SetClientData(idx, (void*)&symbol.second);
|
symbols->SetClientData(idx, (void*)&symbol.second);
|
||||||
}
|
}
|
||||||
symbols->Thaw();
|
symbols->Thaw();
|
||||||
// symbols->Show(true);
|
Repopulate();
|
||||||
Update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCodeWindow::OnSymbolListChange(wxCommandEvent& event)
|
void CCodeWindow::OnSymbolListChange(wxCommandEvent& event)
|
||||||
|
@ -487,8 +485,9 @@ void CCodeWindow::OnSymbolListChange(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
if (pSymbol->type == Symbol::Type::Data)
|
if (pSymbol->type == Symbol::Type::Data)
|
||||||
{
|
{
|
||||||
if (m_MemoryWindow) // && m_MemoryWindow->IsVisible())
|
CMemoryWindow* memory = GetPanel<CMemoryWindow>();
|
||||||
m_MemoryWindow->JumpToAddress(pSymbol->address);
|
if (memory)
|
||||||
|
memory->JumpToAddress(pSymbol->address);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -498,10 +497,6 @@ void CCodeWindow::OnSymbolListChange(wxCommandEvent& event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCodeWindow::OnSymbolListContextMenu(wxContextMenuEvent& event)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change the global DebuggerFont
|
// Change the global DebuggerFont
|
||||||
void CCodeWindow::OnChangeFont(wxCommandEvent& event)
|
void CCodeWindow::OnChangeFont(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
|
@ -511,157 +506,104 @@ void CCodeWindow::OnChangeFont(wxCommandEvent& event)
|
||||||
wxFontDialog dialog(this, data);
|
wxFontDialog dialog(this, data);
|
||||||
if (dialog.ShowModal() == wxID_OK)
|
if (dialog.ShowModal() == wxID_OK)
|
||||||
DebuggerFont = dialog.GetFontData().GetChosenFont();
|
DebuggerFont = dialog.GetFontData().GetChosenFont();
|
||||||
|
|
||||||
|
// TODO: Send event to all panels that tells them to reload the font when it changes.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle windows
|
// Toggle windows
|
||||||
|
|
||||||
|
wxPanel* CCodeWindow::GetUntypedPanel(int id) const
|
||||||
|
{
|
||||||
|
wxASSERT_MSG(id >= IDM_DEBUG_WINDOW_LIST_START && id < IDM_DEBUG_WINDOW_LIST_END,
|
||||||
|
"ID out of range");
|
||||||
|
wxASSERT_MSG(id != IDM_LOG_WINDOW && id != IDM_LOG_CONFIG_WINDOW,
|
||||||
|
"Log windows are managed separately");
|
||||||
|
return m_sibling_panels.at(id - IDM_DEBUG_WINDOW_LIST_START);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCodeWindow::TogglePanel(int id, bool show)
|
||||||
|
{
|
||||||
|
wxPanel* panel = GetUntypedPanel(id);
|
||||||
|
|
||||||
|
// Not all the panels (i.e. CodeWindow) have corresponding menu options.
|
||||||
|
wxMenuItem* item = GetMenuBar()->FindItem(id);
|
||||||
|
if (item)
|
||||||
|
item->Check(show);
|
||||||
|
|
||||||
|
if (show)
|
||||||
|
{
|
||||||
|
if (!panel)
|
||||||
|
{
|
||||||
|
panel = CreateSiblingPanel(id);
|
||||||
|
}
|
||||||
|
Parent->DoAddPage(panel, iNbAffiliation[id - IDM_DEBUG_WINDOW_LIST_START],
|
||||||
|
Parent->bFloatWindow[id - IDM_DEBUG_WINDOW_LIST_START]);
|
||||||
|
}
|
||||||
|
else if (panel) // Close
|
||||||
|
{
|
||||||
|
Parent->DoRemovePage(panel, panel == this);
|
||||||
|
m_sibling_panels[id - IDM_DEBUG_WINDOW_LIST_START] = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wxPanel* CCodeWindow::CreateSiblingPanel(int id)
|
||||||
|
{
|
||||||
|
// Includes range check inside the get call
|
||||||
|
wxASSERT_MSG(!GetUntypedPanel(id), "Panel must not already exist");
|
||||||
|
|
||||||
|
wxPanel* panel = nullptr;
|
||||||
|
switch (id)
|
||||||
|
{
|
||||||
|
// case IDM_LOG_WINDOW: // These exist separately in CFrame.
|
||||||
|
// case IDM_LOG_CONFIG_WINDOW:
|
||||||
|
case IDM_REGISTER_WINDOW:
|
||||||
|
panel = new CRegisterWindow(Parent, IDM_REGISTER_WINDOW);
|
||||||
|
break;
|
||||||
|
case IDM_WATCH_WINDOW:
|
||||||
|
panel = new CWatchWindow(Parent, IDM_WATCH_WINDOW);
|
||||||
|
break;
|
||||||
|
case IDM_BREAKPOINT_WINDOW:
|
||||||
|
panel = new CBreakPointWindow(this, Parent, IDM_BREAKPOINT_WINDOW);
|
||||||
|
break;
|
||||||
|
case IDM_MEMORY_WINDOW:
|
||||||
|
panel = new CMemoryWindow(Parent, IDM_MEMORY_WINDOW);
|
||||||
|
break;
|
||||||
|
case IDM_JIT_WINDOW:
|
||||||
|
panel = new CJitWindow(Parent, IDM_JIT_WINDOW);
|
||||||
|
break;
|
||||||
|
case IDM_SOUND_WINDOW:
|
||||||
|
panel = new DSPDebuggerLLE(Parent, IDM_SOUND_WINDOW);
|
||||||
|
break;
|
||||||
|
case IDM_VIDEO_WINDOW:
|
||||||
|
panel = new GFXDebuggerPanel(Parent, IDM_VIDEO_WINDOW);
|
||||||
|
break;
|
||||||
|
case IDM_CODE_WINDOW:
|
||||||
|
panel = this;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
wxTrap();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_sibling_panels[id - IDM_DEBUG_WINDOW_LIST_START] = panel;
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
void CCodeWindow::OpenPages()
|
void CCodeWindow::OpenPages()
|
||||||
{
|
{
|
||||||
ToggleCodeWindow(true);
|
// This is forced, and should always be placed as the first tab in the notebook.
|
||||||
if (bShowOnStart[0])
|
TogglePanel(IDM_CODE_WINDOW, true);
|
||||||
|
|
||||||
|
// These panels are managed separately by CFrame
|
||||||
|
if (bShowOnStart[IDM_LOG_WINDOW - IDM_DEBUG_WINDOW_LIST_START])
|
||||||
Parent->ToggleLogWindow(true);
|
Parent->ToggleLogWindow(true);
|
||||||
if (bShowOnStart[IDM_LOG_CONFIG_WINDOW - IDM_LOG_WINDOW])
|
if (bShowOnStart[IDM_LOG_CONFIG_WINDOW - IDM_DEBUG_WINDOW_LIST_START])
|
||||||
Parent->ToggleLogConfigWindow(true);
|
Parent->ToggleLogConfigWindow(true);
|
||||||
if (bShowOnStart[IDM_REGISTER_WINDOW - IDM_LOG_WINDOW])
|
|
||||||
ToggleRegisterWindow(true);
|
|
||||||
if (bShowOnStart[IDM_WATCH_WINDOW - IDM_LOG_WINDOW])
|
|
||||||
ToggleWatchWindow(true);
|
|
||||||
if (bShowOnStart[IDM_BREAKPOINT_WINDOW - IDM_LOG_WINDOW])
|
|
||||||
ToggleBreakPointWindow(true);
|
|
||||||
if (bShowOnStart[IDM_MEMORY_WINDOW - IDM_LOG_WINDOW])
|
|
||||||
ToggleMemoryWindow(true);
|
|
||||||
if (bShowOnStart[IDM_JIT_WINDOW - IDM_LOG_WINDOW])
|
|
||||||
ToggleJitWindow(true);
|
|
||||||
if (bShowOnStart[IDM_SOUND_WINDOW - IDM_LOG_WINDOW])
|
|
||||||
ToggleSoundWindow(true);
|
|
||||||
if (bShowOnStart[IDM_VIDEO_WINDOW - IDM_LOG_WINDOW])
|
|
||||||
ToggleVideoWindow(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCodeWindow::ToggleCodeWindow(bool bShow)
|
// Iterate normal panels that don't have weird rules.
|
||||||
{
|
for (int i = IDM_REGISTER_WINDOW; i < IDM_CODE_WINDOW; ++i)
|
||||||
if (bShow)
|
|
||||||
Parent->DoAddPage(this, iNbAffiliation[IDM_CODE_WINDOW - IDM_LOG_WINDOW],
|
|
||||||
Parent->bFloatWindow[IDM_CODE_WINDOW - IDM_LOG_WINDOW]);
|
|
||||||
else // Hide
|
|
||||||
Parent->DoRemovePage(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCodeWindow::ToggleRegisterWindow(bool bShow)
|
|
||||||
{
|
|
||||||
GetMenuBar()->FindItem(IDM_REGISTER_WINDOW)->Check(bShow);
|
|
||||||
if (bShow)
|
|
||||||
{
|
{
|
||||||
if (!m_RegisterWindow)
|
if (bShowOnStart[i - IDM_DEBUG_WINDOW_LIST_START])
|
||||||
m_RegisterWindow = new CRegisterWindow(Parent, IDM_REGISTER_WINDOW);
|
TogglePanel(i, true);
|
||||||
Parent->DoAddPage(m_RegisterWindow, iNbAffiliation[IDM_REGISTER_WINDOW - IDM_LOG_WINDOW],
|
|
||||||
Parent->bFloatWindow[IDM_REGISTER_WINDOW - IDM_LOG_WINDOW]);
|
|
||||||
}
|
|
||||||
else // Close
|
|
||||||
{
|
|
||||||
Parent->DoRemovePage(m_RegisterWindow, false);
|
|
||||||
m_RegisterWindow = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCodeWindow::ToggleWatchWindow(bool bShow)
|
|
||||||
{
|
|
||||||
GetMenuBar()->FindItem(IDM_WATCH_WINDOW)->Check(bShow);
|
|
||||||
if (bShow)
|
|
||||||
{
|
|
||||||
if (!m_WatchWindow)
|
|
||||||
m_WatchWindow = new CWatchWindow(Parent, IDM_WATCH_WINDOW);
|
|
||||||
Parent->DoAddPage(m_WatchWindow, iNbAffiliation[IDM_WATCH_WINDOW - IDM_LOG_WINDOW],
|
|
||||||
Parent->bFloatWindow[IDM_WATCH_WINDOW - IDM_LOG_WINDOW]);
|
|
||||||
}
|
|
||||||
else // Close
|
|
||||||
{
|
|
||||||
Parent->DoRemovePage(m_WatchWindow, false);
|
|
||||||
m_WatchWindow = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCodeWindow::ToggleBreakPointWindow(bool bShow)
|
|
||||||
{
|
|
||||||
GetMenuBar()->FindItem(IDM_BREAKPOINT_WINDOW)->Check(bShow);
|
|
||||||
if (bShow)
|
|
||||||
{
|
|
||||||
if (!m_BreakpointWindow)
|
|
||||||
m_BreakpointWindow = new CBreakPointWindow(this, Parent, IDM_BREAKPOINT_WINDOW);
|
|
||||||
Parent->DoAddPage(m_BreakpointWindow, iNbAffiliation[IDM_BREAKPOINT_WINDOW - IDM_LOG_WINDOW],
|
|
||||||
Parent->bFloatWindow[IDM_BREAKPOINT_WINDOW - IDM_LOG_WINDOW]);
|
|
||||||
}
|
|
||||||
else // Close
|
|
||||||
{
|
|
||||||
Parent->DoRemovePage(m_BreakpointWindow, false);
|
|
||||||
m_BreakpointWindow = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCodeWindow::ToggleMemoryWindow(bool bShow)
|
|
||||||
{
|
|
||||||
GetMenuBar()->FindItem(IDM_MEMORY_WINDOW)->Check(bShow);
|
|
||||||
if (bShow)
|
|
||||||
{
|
|
||||||
if (!m_MemoryWindow)
|
|
||||||
m_MemoryWindow = new CMemoryWindow(this, Parent, IDM_MEMORY_WINDOW);
|
|
||||||
Parent->DoAddPage(m_MemoryWindow, iNbAffiliation[IDM_MEMORY_WINDOW - IDM_LOG_WINDOW],
|
|
||||||
Parent->bFloatWindow[IDM_MEMORY_WINDOW - IDM_LOG_WINDOW]);
|
|
||||||
}
|
|
||||||
else // Close
|
|
||||||
{
|
|
||||||
Parent->DoRemovePage(m_MemoryWindow, false);
|
|
||||||
m_MemoryWindow = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCodeWindow::ToggleJitWindow(bool bShow)
|
|
||||||
{
|
|
||||||
GetMenuBar()->FindItem(IDM_JIT_WINDOW)->Check(bShow);
|
|
||||||
if (bShow)
|
|
||||||
{
|
|
||||||
if (!m_JitWindow)
|
|
||||||
m_JitWindow = new CJitWindow(Parent, IDM_JIT_WINDOW);
|
|
||||||
Parent->DoAddPage(m_JitWindow, iNbAffiliation[IDM_JIT_WINDOW - IDM_LOG_WINDOW],
|
|
||||||
Parent->bFloatWindow[IDM_JIT_WINDOW - IDM_LOG_WINDOW]);
|
|
||||||
}
|
|
||||||
else // Close
|
|
||||||
{
|
|
||||||
Parent->DoRemovePage(m_JitWindow, false);
|
|
||||||
m_JitWindow = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCodeWindow::ToggleSoundWindow(bool bShow)
|
|
||||||
{
|
|
||||||
GetMenuBar()->FindItem(IDM_SOUND_WINDOW)->Check(bShow);
|
|
||||||
if (bShow)
|
|
||||||
{
|
|
||||||
if (!m_SoundWindow)
|
|
||||||
m_SoundWindow = new DSPDebuggerLLE(Parent, IDM_SOUND_WINDOW);
|
|
||||||
Parent->DoAddPage(m_SoundWindow, iNbAffiliation[IDM_SOUND_WINDOW - IDM_LOG_WINDOW],
|
|
||||||
Parent->bFloatWindow[IDM_SOUND_WINDOW - IDM_LOG_WINDOW]);
|
|
||||||
}
|
|
||||||
else // Close
|
|
||||||
{
|
|
||||||
Parent->DoRemovePage(m_SoundWindow, false);
|
|
||||||
m_SoundWindow = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCodeWindow::ToggleVideoWindow(bool bShow)
|
|
||||||
{
|
|
||||||
GetMenuBar()->FindItem(IDM_VIDEO_WINDOW)->Check(bShow);
|
|
||||||
if (bShow)
|
|
||||||
{
|
|
||||||
if (!m_VideoWindow)
|
|
||||||
m_VideoWindow = new GFXDebuggerPanel(Parent, IDM_VIDEO_WINDOW);
|
|
||||||
Parent->DoAddPage(m_VideoWindow, iNbAffiliation[IDM_VIDEO_WINDOW - IDM_LOG_WINDOW],
|
|
||||||
Parent->bFloatWindow[IDM_VIDEO_WINDOW - IDM_LOG_WINDOW]);
|
|
||||||
}
|
|
||||||
else // Close
|
|
||||||
{
|
|
||||||
Parent->DoRemovePage(m_VideoWindow, false);
|
|
||||||
m_VideoWindow = nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,9 +32,8 @@ static DSPDebuggerLLE* m_DebuggerFrame = nullptr;
|
||||||
|
|
||||||
DSPDebuggerLLE::DSPDebuggerLLE(wxWindow* parent, wxWindowID id)
|
DSPDebuggerLLE::DSPDebuggerLLE(wxWindow* parent, wxWindowID id)
|
||||||
: wxPanel(parent, id, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _("DSP LLE Debugger")),
|
: wxPanel(parent, id, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _("DSP LLE Debugger")),
|
||||||
m_CachedStepCounter(-1)
|
m_CachedStepCounter(-1), m_toolbar_item_size(FromDIP(wxSize(16, 16)))
|
||||||
{
|
{
|
||||||
Bind(wxEVT_CLOSE_WINDOW, &DSPDebuggerLLE::OnClose, this);
|
|
||||||
Bind(wxEVT_MENU, &DSPDebuggerLLE::OnChangeState, this, ID_RUNTOOL, ID_SHOWPCTOOL);
|
Bind(wxEVT_MENU, &DSPDebuggerLLE::OnChangeState, this, ID_RUNTOOL, ID_SHOWPCTOOL);
|
||||||
|
|
||||||
m_DebuggerFrame = this;
|
m_DebuggerFrame = this;
|
||||||
|
@ -46,11 +45,12 @@ DSPDebuggerLLE::DSPDebuggerLLE(wxWindow* parent, wxWindowID id)
|
||||||
m_Toolbar =
|
m_Toolbar =
|
||||||
new DolphinAuiToolBar(this, ID_TOOLBAR, wxDefaultPosition, wxDefaultSize, wxAUI_TB_HORZ_TEXT);
|
new DolphinAuiToolBar(this, ID_TOOLBAR, wxDefaultPosition, wxDefaultSize, wxAUI_TB_HORZ_TEXT);
|
||||||
m_Toolbar->AddTool(ID_RUNTOOL, _("Pause"),
|
m_Toolbar->AddTool(ID_RUNTOOL, _("Pause"),
|
||||||
wxArtProvider::GetBitmap(wxART_TICK_MARK, wxART_OTHER, wxSize(10, 10)));
|
wxArtProvider::GetBitmap(wxART_TICK_MARK, wxART_OTHER, m_toolbar_item_size));
|
||||||
m_Toolbar->AddTool(ID_STEPTOOL, _("Step"),
|
m_Toolbar->AddTool(ID_STEPTOOL, _("Step"),
|
||||||
wxArtProvider::GetBitmap(wxART_GO_DOWN, wxART_OTHER, wxSize(10, 10)));
|
wxArtProvider::GetBitmap(wxART_GO_DOWN, wxART_OTHER, m_toolbar_item_size));
|
||||||
m_Toolbar->AddTool(ID_SHOWPCTOOL, _("Show PC"),
|
m_Toolbar->AddTool(
|
||||||
wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_OTHER, wxSize(10, 10)));
|
ID_SHOWPCTOOL, _("Show PC"),
|
||||||
|
wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_OTHER, m_toolbar_item_size));
|
||||||
m_Toolbar->AddSeparator();
|
m_Toolbar->AddSeparator();
|
||||||
|
|
||||||
m_addr_txtctrl = new wxTextCtrl(m_Toolbar, wxID_ANY, wxEmptyString, wxDefaultPosition,
|
m_addr_txtctrl = new wxTextCtrl(m_Toolbar, wxID_ANY, wxEmptyString, wxDefaultPosition,
|
||||||
|
@ -60,8 +60,8 @@ DSPDebuggerLLE::DSPDebuggerLLE(wxWindow* parent, wxWindowID id)
|
||||||
m_Toolbar->AddControl(m_addr_txtctrl);
|
m_Toolbar->AddControl(m_addr_txtctrl);
|
||||||
m_Toolbar->Realize();
|
m_Toolbar->Realize();
|
||||||
|
|
||||||
m_SymbolList =
|
m_SymbolList = new wxListBox(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(100, 80)),
|
||||||
new wxListBox(this, wxID_ANY, wxDefaultPosition, wxSize(140, 100), 0, nullptr, wxLB_SORT);
|
0, nullptr, wxLB_SORT);
|
||||||
m_SymbolList->Bind(wxEVT_LISTBOX, &DSPDebuggerLLE::OnSymbolListChange, this);
|
m_SymbolList->Bind(wxEVT_LISTBOX, &DSPDebuggerLLE::OnSymbolListChange, this);
|
||||||
|
|
||||||
m_MainNotebook = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
|
m_MainNotebook = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
|
||||||
|
@ -71,15 +71,14 @@ DSPDebuggerLLE::DSPDebuggerLLE(wxWindow* parent, wxWindowID id)
|
||||||
wxBoxSizer* code_sizer = new wxBoxSizer(wxVERTICAL);
|
wxBoxSizer* code_sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
m_CodeView = new CCodeView(&debug_interface, &DSPSymbols::g_dsp_symbol_db, code_panel);
|
m_CodeView = new CCodeView(&debug_interface, &DSPSymbols::g_dsp_symbol_db, code_panel);
|
||||||
m_CodeView->SetPlain();
|
m_CodeView->SetPlain();
|
||||||
code_sizer->Add(m_CodeView, 1, wxALL | wxEXPAND);
|
code_sizer->Add(m_CodeView, 1, wxEXPAND);
|
||||||
code_panel->SetSizer(code_sizer);
|
code_panel->SetSizer(code_sizer);
|
||||||
m_MainNotebook->AddPage(code_panel, _("Disassembly"), true);
|
m_MainNotebook->AddPage(code_panel, _("Disassembly"), true);
|
||||||
|
|
||||||
wxPanel* mem_panel = new wxPanel(m_MainNotebook, wxID_ANY);
|
wxPanel* mem_panel = new wxPanel(m_MainNotebook, wxID_ANY);
|
||||||
wxBoxSizer* mem_sizer = new wxBoxSizer(wxVERTICAL);
|
wxBoxSizer* mem_sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
// TODO insert memViewer class
|
|
||||||
m_MemView = new CMemoryView(&debug_interface, mem_panel);
|
m_MemView = new CMemoryView(&debug_interface, mem_panel);
|
||||||
mem_sizer->Add(m_MemView, 1, wxALL | wxEXPAND);
|
mem_sizer->Add(m_MemView, 1, wxEXPAND);
|
||||||
mem_panel->SetSizer(mem_sizer);
|
mem_panel->SetSizer(mem_sizer);
|
||||||
m_MainNotebook->AddPage(mem_panel, _("Memory"));
|
m_MainNotebook->AddPage(mem_panel, _("Memory"));
|
||||||
|
|
||||||
|
@ -111,11 +110,6 @@ DSPDebuggerLLE::~DSPDebuggerLLE()
|
||||||
m_DebuggerFrame = nullptr;
|
m_DebuggerFrame = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPDebuggerLLE::OnClose(wxCloseEvent& event)
|
|
||||||
{
|
|
||||||
event.Skip();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DSPDebuggerLLE::OnChangeState(wxCommandEvent& event)
|
void DSPDebuggerLLE::OnChangeState(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
if (DSPCore_GetState() == DSPCORE_STOP)
|
if (DSPCore_GetState() == DSPCORE_STOP)
|
||||||
|
@ -134,7 +128,7 @@ void DSPDebuggerLLE::OnChangeState(wxCommandEvent& event)
|
||||||
if (DSPCore_GetState() == DSPCORE_STEPPING)
|
if (DSPCore_GetState() == DSPCORE_STEPPING)
|
||||||
{
|
{
|
||||||
DSPCore_Step();
|
DSPCore_Step();
|
||||||
Update();
|
Repopulate();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -149,24 +143,24 @@ void DSPDebuggerLLE::OnChangeState(wxCommandEvent& event)
|
||||||
|
|
||||||
void Host_RefreshDSPDebuggerWindow()
|
void Host_RefreshDSPDebuggerWindow()
|
||||||
{
|
{
|
||||||
|
// FIXME: This should use QueueEvent to post the update request to the UI thread.
|
||||||
|
// Need to check if this can safely be performed asynchronously or if it races.
|
||||||
|
// FIXME: This probably belongs in Main.cpp with the other host functions.
|
||||||
|
// NOTE: The DSP never tells us when it shuts down. It probably should.
|
||||||
if (m_DebuggerFrame)
|
if (m_DebuggerFrame)
|
||||||
m_DebuggerFrame->Update();
|
m_DebuggerFrame->Repopulate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPDebuggerLLE::Update()
|
void DSPDebuggerLLE::Repopulate()
|
||||||
{
|
{
|
||||||
#if defined __WXGTK__
|
|
||||||
if (!wxIsMainThread())
|
if (!wxIsMainThread())
|
||||||
wxMutexGuiEnter();
|
wxMutexGuiEnter();
|
||||||
#endif
|
|
||||||
UpdateSymbolMap();
|
UpdateSymbolMap();
|
||||||
UpdateDisAsmListView();
|
UpdateDisAsmListView();
|
||||||
UpdateRegisterFlags();
|
UpdateRegisterFlags();
|
||||||
UpdateState();
|
UpdateState();
|
||||||
#if defined __WXGTK__
|
|
||||||
if (!wxIsMainThread())
|
if (!wxIsMainThread())
|
||||||
wxMutexGuiLeave();
|
wxMutexGuiLeave();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPDebuggerLLE::FocusOnPC()
|
void DSPDebuggerLLE::FocusOnPC()
|
||||||
|
@ -180,14 +174,14 @@ void DSPDebuggerLLE::UpdateState()
|
||||||
{
|
{
|
||||||
m_Toolbar->SetToolLabel(ID_RUNTOOL, _("Pause"));
|
m_Toolbar->SetToolLabel(ID_RUNTOOL, _("Pause"));
|
||||||
m_Toolbar->SetToolBitmap(
|
m_Toolbar->SetToolBitmap(
|
||||||
ID_RUNTOOL, wxArtProvider::GetBitmap(wxART_TICK_MARK, wxART_OTHER, wxSize(10, 10)));
|
ID_RUNTOOL, wxArtProvider::GetBitmap(wxART_TICK_MARK, wxART_OTHER, m_toolbar_item_size));
|
||||||
m_Toolbar->EnableTool(ID_STEPTOOL, false);
|
m_Toolbar->EnableTool(ID_STEPTOOL, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_Toolbar->SetToolLabel(ID_RUNTOOL, _("Run"));
|
m_Toolbar->SetToolLabel(ID_RUNTOOL, _("Run"));
|
||||||
m_Toolbar->SetToolBitmap(
|
m_Toolbar->SetToolBitmap(
|
||||||
ID_RUNTOOL, wxArtProvider::GetBitmap(wxART_GO_FORWARD, wxART_OTHER, wxSize(10, 10)));
|
ID_RUNTOOL, wxArtProvider::GetBitmap(wxART_GO_FORWARD, wxART_OTHER, m_toolbar_item_size));
|
||||||
m_Toolbar->EnableTool(ID_STEPTOOL, true);
|
m_Toolbar->EnableTool(ID_STEPTOOL, true);
|
||||||
}
|
}
|
||||||
m_Toolbar->Realize();
|
m_Toolbar->Realize();
|
||||||
|
@ -201,7 +195,7 @@ void DSPDebuggerLLE::UpdateDisAsmListView()
|
||||||
// show PC
|
// show PC
|
||||||
FocusOnPC();
|
FocusOnPC();
|
||||||
m_CachedStepCounter = g_dsp.step_counter;
|
m_CachedStepCounter = g_dsp.step_counter;
|
||||||
m_Regs->Update();
|
m_Regs->Repopulate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPDebuggerLLE::UpdateSymbolMap()
|
void DSPDebuggerLLE::UpdateSymbolMap()
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
DSPDebuggerLLE(wxWindow* parent, wxWindowID id = wxID_ANY);
|
DSPDebuggerLLE(wxWindow* parent, wxWindowID id = wxID_ANY);
|
||||||
virtual ~DSPDebuggerLLE();
|
virtual ~DSPDebuggerLLE();
|
||||||
|
|
||||||
void Update() override;
|
void Repopulate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum
|
enum
|
||||||
|
@ -52,8 +52,8 @@ private:
|
||||||
wxListBox* m_SymbolList;
|
wxListBox* m_SymbolList;
|
||||||
wxTextCtrl* m_addr_txtctrl;
|
wxTextCtrl* m_addr_txtctrl;
|
||||||
wxAuiNotebook* m_MainNotebook;
|
wxAuiNotebook* m_MainNotebook;
|
||||||
|
wxSize m_toolbar_item_size;
|
||||||
|
|
||||||
void OnClose(wxCloseEvent& event);
|
|
||||||
void OnChangeState(wxCommandEvent& event);
|
void OnChangeState(wxCommandEvent& event);
|
||||||
// void OnRightClick(wxListEvent& event);
|
// void OnRightClick(wxListEvent& event);
|
||||||
// void OnDoubleClick(wxListEvent& event);
|
// void OnDoubleClick(wxListEvent& event);
|
||||||
|
|
|
@ -71,7 +71,7 @@ wxGridCellAttr* CDSPRegTable::GetAttr(int row, int col, wxGridCellAttr::wxAttrKi
|
||||||
}
|
}
|
||||||
|
|
||||||
DSPRegisterView::DSPRegisterView(wxWindow* parent, wxWindowID id)
|
DSPRegisterView::DSPRegisterView(wxWindow* parent, wxWindowID id)
|
||||||
: wxGrid(parent, id, wxDefaultPosition, wxSize(130, 120))
|
: wxGrid(parent, id, wxDefaultPosition, wxDLG_UNIT(parent, wxSize(100, 80)))
|
||||||
{
|
{
|
||||||
m_register_table = new CDSPRegTable();
|
m_register_table = new CDSPRegTable();
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ DSPRegisterView::DSPRegisterView(wxWindow* parent, wxWindowID id)
|
||||||
AutoSizeColumns();
|
AutoSizeColumns();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPRegisterView::Update()
|
void DSPRegisterView::Repopulate()
|
||||||
{
|
{
|
||||||
m_register_table->UpdateCachedRegs();
|
m_register_table->UpdateCachedRegs();
|
||||||
ForceRefresh();
|
ForceRefresh();
|
||||||
|
|
|
@ -38,7 +38,7 @@ class DSPRegisterView : public wxGrid
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DSPRegisterView(wxWindow* parent, wxWindowID id = wxID_ANY);
|
DSPRegisterView(wxWindow* parent, wxWindowID id = wxID_ANY);
|
||||||
void Update() override;
|
void Repopulate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Owned by wx. Deleted implicitly upon destruction.
|
// Owned by wx. Deleted implicitly upon destruction.
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <wx/sizer.h>
|
#include <wx/sizer.h>
|
||||||
#include <wx/textctrl.h>
|
#include <wx/textctrl.h>
|
||||||
|
|
||||||
|
#include "Common/CommonFuncs.h"
|
||||||
#include "Common/FileUtil.h"
|
#include "Common/FileUtil.h"
|
||||||
#include "Common/IniFile.h"
|
#include "Common/IniFile.h"
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
|
@ -26,10 +27,6 @@ GFXDebuggerPanel::GFXDebuggerPanel(wxWindow* parent, wxWindowID id, const wxPoin
|
||||||
g_pdebugger = this;
|
g_pdebugger = this;
|
||||||
|
|
||||||
CreateGUIControls();
|
CreateGUIControls();
|
||||||
|
|
||||||
Bind(wxEVT_CLOSE_WINDOW, &GFXDebuggerPanel::OnClose, this);
|
|
||||||
|
|
||||||
LoadSettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GFXDebuggerPanel::~GFXDebuggerPanel()
|
GFXDebuggerPanel::~GFXDebuggerPanel()
|
||||||
|
@ -38,55 +35,6 @@ GFXDebuggerPanel::~GFXDebuggerPanel()
|
||||||
GFXDebuggerPauseFlag = false;
|
GFXDebuggerPauseFlag = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GFXDebuggerPanel::OnClose(wxCloseEvent& event)
|
|
||||||
{
|
|
||||||
// save the window position when we hide the window
|
|
||||||
SaveSettings();
|
|
||||||
|
|
||||||
event.Skip();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GFXDebuggerPanel::SaveSettings() const
|
|
||||||
{
|
|
||||||
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: 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
void GFXDebuggerPanel::LoadSettings()
|
|
||||||
{
|
|
||||||
IniFile file;
|
|
||||||
file.Load(File::GetUserPath(F_DEBUGGERCONFIG_IDX));
|
|
||||||
|
|
||||||
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());
|
|
||||||
|
|
||||||
SetSize(x, y, w, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PauseEventMap
|
struct PauseEventMap
|
||||||
{
|
{
|
||||||
PauseEvent event;
|
PauseEvent event;
|
||||||
|
@ -118,10 +66,9 @@ void GFXDebuggerPanel::CreateGUIControls()
|
||||||
|
|
||||||
{NEXT_ERROR, _("Error")}};
|
{NEXT_ERROR, _("Error")}};
|
||||||
pauseEventMap = map;
|
pauseEventMap = map;
|
||||||
const int numPauseEventMap = sizeof(map) / sizeof(PauseEventMap);
|
static constexpr int numPauseEventMap = ArraySize(map);
|
||||||
|
|
||||||
// Basic settings
|
const int space3 = FromDIP(3);
|
||||||
CenterOnParent();
|
|
||||||
|
|
||||||
m_pButtonPause = new wxButton(this, wxID_ANY, _("Pause"), wxDefaultPosition, wxDefaultSize, 0,
|
m_pButtonPause = new wxButton(this, wxID_ANY, _("Pause"), wxDefaultPosition, wxDefaultSize, 0,
|
||||||
wxDefaultValidator, _("Pause"));
|
wxDefaultValidator, _("Pause"));
|
||||||
|
@ -139,10 +86,11 @@ void GFXDebuggerPanel::CreateGUIControls()
|
||||||
wxDefaultValidator, _("Continue"));
|
wxDefaultValidator, _("Continue"));
|
||||||
m_pButtonCont->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnContButton, this);
|
m_pButtonCont->Bind(wxEVT_BUTTON, &GFXDebuggerPanel::OnContButton, this);
|
||||||
|
|
||||||
m_pCount = new wxTextCtrl(this, wxID_ANY, "1", wxDefaultPosition, wxSize(50, 25), wxTE_RIGHT,
|
m_pCount = new wxTextCtrl(this, wxID_ANY, "1", wxDefaultPosition, wxDefaultSize, wxTE_RIGHT,
|
||||||
wxDefaultValidator, _("Count"));
|
wxDefaultValidator, _("Count"));
|
||||||
|
m_pCount->SetMinSize(WxUtils::GetTextWidgetMinSize(m_pCount, 10000));
|
||||||
|
|
||||||
m_pPauseAtList = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxSize(100, 25), 0, nullptr, 0,
|
m_pPauseAtList = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, nullptr, 0,
|
||||||
wxDefaultValidator, _("PauseAtList"));
|
wxDefaultValidator, _("PauseAtList"));
|
||||||
for (int i = 0; i < numPauseEventMap; i++)
|
for (int i = 0; i < numPauseEventMap; i++)
|
||||||
{
|
{
|
||||||
|
@ -180,7 +128,7 @@ void GFXDebuggerPanel::CreateGUIControls()
|
||||||
m_pButtonClearPixelShaderCache->Bind(wxEVT_BUTTON,
|
m_pButtonClearPixelShaderCache->Bind(wxEVT_BUTTON,
|
||||||
&GFXDebuggerPanel::OnClearPixelShaderCacheButton, this);
|
&GFXDebuggerPanel::OnClearPixelShaderCacheButton, this);
|
||||||
|
|
||||||
m_pDumpList = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxSize(120, 25), 0, nullptr, 0,
|
m_pDumpList = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, nullptr, 0,
|
||||||
wxDefaultValidator, _("DumpList"));
|
wxDefaultValidator, _("DumpList"));
|
||||||
m_pDumpList->Insert(_("Pixel Shader"), 0);
|
m_pDumpList->Insert(_("Pixel Shader"), 0);
|
||||||
m_pDumpList->Append(_("Vertex Shader"));
|
m_pDumpList->Append(_("Vertex Shader"));
|
||||||
|
@ -196,31 +144,40 @@ void GFXDebuggerPanel::CreateGUIControls()
|
||||||
|
|
||||||
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);
|
wxBoxSizer* const pPauseAtNextSzr = new wxBoxSizer(wxHORIZONTAL);
|
||||||
pFlowCtrlBox->Add(m_pButtonPause);
|
pPauseAtNextSzr->Add(m_pCount, 0, wxALIGN_CENTER_VERTICAL);
|
||||||
pPauseAtNextSzr->Add(m_pButtonPauseAtNext);
|
pPauseAtNextSzr->Add(m_pPauseAtList, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, space3);
|
||||||
pPauseAtNextSzr->Add(m_pCount);
|
|
||||||
pPauseAtNextSzr->Add(m_pPauseAtList);
|
wxFlexGridSizer* const flow_szr = new wxFlexGridSizer(2, space3, space3);
|
||||||
pFlowCtrlBox->Add(pPauseAtNextSzr);
|
flow_szr->Add(m_pButtonPause, 0, wxEXPAND);
|
||||||
pFlowCtrlBox->Add(m_pButtonPauseAtNextFrame);
|
flow_szr->AddSpacer(1);
|
||||||
pFlowCtrlBox->Add(m_pButtonCont);
|
flow_szr->Add(m_pButtonPauseAtNext, 0, wxEXPAND);
|
||||||
|
flow_szr->Add(pPauseAtNextSzr, 0, wxEXPAND);
|
||||||
|
flow_szr->Add(m_pButtonPauseAtNextFrame, 0, wxEXPAND);
|
||||||
|
flow_szr->AddSpacer(1);
|
||||||
|
flow_szr->Add(m_pButtonCont, 0, wxEXPAND);
|
||||||
|
flow_szr->AddSpacer(1);
|
||||||
|
|
||||||
|
wxStaticBoxSizer* const pFlowCtrlBox = new wxStaticBoxSizer(wxVERTICAL, this, _("Flow Control"));
|
||||||
|
pFlowCtrlBox->Add(flow_szr, 1, wxEXPAND);
|
||||||
|
|
||||||
|
wxBoxSizer* const pDumpSzr = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
pDumpSzr->Add(m_pButtonDump, 0, wxALIGN_CENTER_VERTICAL);
|
||||||
|
pDumpSzr->Add(m_pDumpList, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, space3);
|
||||||
|
|
||||||
|
wxGridSizer* const pDbgGrid = new wxGridSizer(2, space3, space3);
|
||||||
|
pDbgGrid->Add(m_pButtonUpdateScreen, 0, wxEXPAND);
|
||||||
|
pDbgGrid->Add(m_pButtonClearScreen, 0, wxEXPAND);
|
||||||
|
pDbgGrid->Add(m_pButtonClearTextureCache, 0, wxEXPAND);
|
||||||
|
pDbgGrid->Add(m_pButtonClearVertexShaderCache, 0, wxEXPAND);
|
||||||
|
pDbgGrid->Add(m_pButtonClearPixelShaderCache, 0, wxEXPAND);
|
||||||
|
|
||||||
wxStaticBoxSizer* const pDebugBox = new wxStaticBoxSizer(wxVERTICAL, this, _("Debugging"));
|
wxStaticBoxSizer* const pDebugBox = new wxStaticBoxSizer(wxVERTICAL, this, _("Debugging"));
|
||||||
wxBoxSizer* const pDumpSzr = new wxBoxSizer(wxHORIZONTAL);
|
pDebugBox->Add(pDumpSzr, 0, wxEXPAND);
|
||||||
pDumpSzr->Add(m_pButtonDump);
|
pDebugBox->Add(pDbgGrid, 1, wxTOP, space3);
|
||||||
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(pFlowCtrlBox);
|
||||||
sMain->Add(pDebugBox, 0, 0, 5);
|
sMain->Add(pDebugBox);
|
||||||
SetSizerAndFit(sMain);
|
SetSizerAndFit(sMain);
|
||||||
|
|
||||||
OnContinue();
|
OnContinue();
|
||||||
|
@ -248,12 +205,6 @@ void GFXDebuggerPanel::OnContinue()
|
||||||
m_pButtonClearPixelShaderCache->Disable();
|
m_pButtonClearPixelShaderCache->Disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
// General settings
|
|
||||||
void GFXDebuggerPanel::GeneralSettings(wxCommandEvent& event)
|
|
||||||
{
|
|
||||||
SaveSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GFXDebuggerPanel::OnPauseButton(wxCommandEvent& event)
|
void GFXDebuggerPanel::OnPauseButton(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
GFXDebuggerPauseFlag = true;
|
GFXDebuggerPauseFlag = true;
|
||||||
|
|
|
@ -20,9 +20,6 @@ public:
|
||||||
|
|
||||||
virtual ~GFXDebuggerPanel();
|
virtual ~GFXDebuggerPanel();
|
||||||
|
|
||||||
void SaveSettings() const;
|
|
||||||
void LoadSettings();
|
|
||||||
|
|
||||||
bool bInfoLog;
|
bool bInfoLog;
|
||||||
bool bPrimLog;
|
bool bPrimLog;
|
||||||
bool bSaveTextures;
|
bool bSaveTextures;
|
||||||
|
@ -49,11 +46,8 @@ private:
|
||||||
wxButton* m_pButtonClearPixelShaderCache;
|
wxButton* m_pButtonClearPixelShaderCache;
|
||||||
wxTextCtrl* m_pCount;
|
wxTextCtrl* m_pCount;
|
||||||
|
|
||||||
void OnClose(wxCloseEvent& event);
|
|
||||||
void CreateGUIControls();
|
void CreateGUIControls();
|
||||||
|
|
||||||
void GeneralSettings(wxCommandEvent& event);
|
|
||||||
|
|
||||||
// These set GFXDebuggerPauseFlag to true (either immediately or once the specified event has
|
// These set GFXDebuggerPauseFlag to true (either immediately or once the specified event has
|
||||||
// occurred)
|
// occurred)
|
||||||
void OnPauseButton(wxCommandEvent& event);
|
void OnPauseButton(wxCommandEvent& event);
|
||||||
|
|
|
@ -34,7 +34,8 @@ CJitWindow::CJitWindow(wxWindow* parent, wxWindowID id, const wxPoint& pos, cons
|
||||||
sizerSplit->Add(x86_box = new wxTextCtrl(this, wxID_ANY, "(x86)", wxDefaultPosition,
|
sizerSplit->Add(x86_box = new wxTextCtrl(this, wxID_ANY, "(x86)", wxDefaultPosition,
|
||||||
wxDefaultSize, wxTE_MULTILINE),
|
wxDefaultSize, wxTE_MULTILINE),
|
||||||
1, wxEXPAND);
|
1, wxEXPAND);
|
||||||
sizerBig->Add(block_list = new JitBlockList(this, wxID_ANY, wxDefaultPosition, wxSize(100, 140),
|
sizerBig->Add(block_list = new JitBlockList(this, wxID_ANY, wxDefaultPosition,
|
||||||
|
wxDLG_UNIT(this, wxSize(80, 96)),
|
||||||
wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT |
|
wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT |
|
||||||
wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING),
|
wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING),
|
||||||
0, wxEXPAND);
|
0, wxEXPAND);
|
||||||
|
@ -43,10 +44,7 @@ CJitWindow::CJitWindow(wxWindow* parent, wxWindowID id, const wxPoint& pos, cons
|
||||||
sizerBig->Add(button_refresh = new wxButton(this, wxID_ANY, _("&Refresh")));
|
sizerBig->Add(button_refresh = new wxButton(this, wxID_ANY, _("&Refresh")));
|
||||||
button_refresh->Bind(wxEVT_BUTTON, &CJitWindow::OnRefresh, this);
|
button_refresh->Bind(wxEVT_BUTTON, &CJitWindow::OnRefresh, this);
|
||||||
|
|
||||||
SetSizer(sizerBig);
|
SetSizerAndFit(sizerBig);
|
||||||
|
|
||||||
sizerSplit->Fit(this);
|
|
||||||
sizerBig->Fit(this);
|
|
||||||
|
|
||||||
#if defined(_M_X86)
|
#if defined(_M_X86)
|
||||||
m_disassembler.reset(GetNewDisassembler("x86"));
|
m_disassembler.reset(GetNewDisassembler("x86"));
|
||||||
|
@ -59,7 +57,7 @@ CJitWindow::CJitWindow(wxWindow* parent, wxWindowID id, const wxPoint& pos, cons
|
||||||
|
|
||||||
void CJitWindow::OnRefresh(wxCommandEvent& /*event*/)
|
void CJitWindow::OnRefresh(wxCommandEvent& /*event*/)
|
||||||
{
|
{
|
||||||
block_list->Update();
|
block_list->Repopulate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CJitWindow::ViewAddr(u32 em_address)
|
void CJitWindow::ViewAddr(u32 em_address)
|
||||||
|
@ -135,7 +133,7 @@ void CJitWindow::Compare(u32 em_address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CJitWindow::Update()
|
void CJitWindow::Repopulate()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,6 +179,6 @@ void JitBlockList::Init()
|
||||||
InsertColumn(COLUMN_COST, _("Cost"));
|
InsertColumn(COLUMN_COST, _("Cost"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitBlockList::Update()
|
void JitBlockList::Repopulate()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ public:
|
||||||
JitBlockList(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size,
|
JitBlockList(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size,
|
||||||
long style);
|
long style);
|
||||||
void Init();
|
void Init();
|
||||||
void Update() override;
|
void Repopulate();
|
||||||
};
|
};
|
||||||
|
|
||||||
class CJitWindow : public wxPanel
|
class CJitWindow : public wxPanel
|
||||||
|
@ -33,7 +33,7 @@ public:
|
||||||
const wxString& name = _("JIT Block Viewer"));
|
const wxString& name = _("JIT Block Viewer"));
|
||||||
|
|
||||||
void ViewAddr(u32 em_address);
|
void ViewAddr(u32 em_address);
|
||||||
void Update() override;
|
void Repopulate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void OnRefresh(wxCommandEvent& /*event*/);
|
void OnRefresh(wxCommandEvent& /*event*/);
|
||||||
|
|
|
@ -22,6 +22,8 @@ MemoryCheckDlg::MemoryCheckDlg(CBreakPointWindow* parent)
|
||||||
Bind(wxEVT_BUTTON, &MemoryCheckDlg::OnOK, this, wxID_OK);
|
Bind(wxEVT_BUTTON, &MemoryCheckDlg::OnOK, this, wxID_OK);
|
||||||
Bind(wxEVT_RADIOBUTTON, &MemoryCheckDlg::OnRadioButtonClick, this);
|
Bind(wxEVT_RADIOBUTTON, &MemoryCheckDlg::OnRadioButtonClick, this);
|
||||||
|
|
||||||
|
const int space5 = FromDIP(5);
|
||||||
|
|
||||||
m_textAddress = new wxStaticText(this, wxID_ANY, _("Address"));
|
m_textAddress = new wxStaticText(this, wxID_ANY, _("Address"));
|
||||||
m_textStartAddress = new wxStaticText(this, wxID_ANY, _("Start"));
|
m_textStartAddress = new wxStaticText(this, wxID_ANY, _("Start"));
|
||||||
m_textStartAddress->Disable();
|
m_textStartAddress->Disable();
|
||||||
|
@ -46,14 +48,22 @@ MemoryCheckDlg::MemoryCheckDlg(CBreakPointWindow* parent)
|
||||||
m_radioBreakLog->SetValue(true);
|
m_radioBreakLog->SetValue(true);
|
||||||
|
|
||||||
auto* sAddressBox = new wxBoxSizer(wxHORIZONTAL);
|
auto* sAddressBox = new wxBoxSizer(wxHORIZONTAL);
|
||||||
sAddressBox->Add(m_textAddress, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
|
sAddressBox->AddSpacer(space5);
|
||||||
sAddressBox->Add(m_pEditAddress, 1, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM, 10);
|
sAddressBox->Add(m_textAddress, 0, wxALIGN_CENTER_VERTICAL);
|
||||||
|
sAddressBox->AddSpacer(space5);
|
||||||
|
sAddressBox->Add(m_pEditAddress, 1, wxALIGN_CENTER_VERTICAL);
|
||||||
|
sAddressBox->AddSpacer(space5);
|
||||||
|
|
||||||
auto* sAddressRangeBox = new wxBoxSizer(wxHORIZONTAL);
|
auto* sAddressRangeBox = new wxBoxSizer(wxHORIZONTAL);
|
||||||
sAddressRangeBox->Add(m_textStartAddress, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
|
sAddressRangeBox->AddSpacer(space5);
|
||||||
sAddressRangeBox->Add(m_pEditStartAddress, 1, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM, 10);
|
sAddressRangeBox->Add(m_textStartAddress, 0, wxALIGN_CENTER_VERTICAL);
|
||||||
sAddressRangeBox->Add(m_textEndAddress, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
|
sAddressRangeBox->AddSpacer(space5);
|
||||||
sAddressRangeBox->Add(m_pEditEndAddress, 1, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM, 5);
|
sAddressRangeBox->Add(m_pEditStartAddress, 1, wxALIGN_CENTER_VERTICAL);
|
||||||
|
sAddressRangeBox->AddSpacer(space5);
|
||||||
|
sAddressRangeBox->Add(m_textEndAddress, 0, wxALIGN_CENTER_VERTICAL);
|
||||||
|
sAddressRangeBox->AddSpacer(space5);
|
||||||
|
sAddressRangeBox->Add(m_pEditEndAddress, 1, wxALIGN_CENTER_VERTICAL);
|
||||||
|
sAddressRangeBox->AddSpacer(space5);
|
||||||
|
|
||||||
auto* sActions = new wxStaticBoxSizer(wxVERTICAL, this, _("Action"));
|
auto* sActions = new wxStaticBoxSizer(wxVERTICAL, this, _("Action"));
|
||||||
sActions->Add(m_radioRead, 0, wxEXPAND);
|
sActions->Add(m_radioRead, 0, wxEXPAND);
|
||||||
|
@ -67,19 +77,26 @@ MemoryCheckDlg::MemoryCheckDlg(CBreakPointWindow* parent)
|
||||||
sFlags->Add(m_radioBreakLog);
|
sFlags->Add(m_radioBreakLog);
|
||||||
|
|
||||||
auto* sOptionsBox = new wxBoxSizer(wxHORIZONTAL);
|
auto* sOptionsBox = new wxBoxSizer(wxHORIZONTAL);
|
||||||
sOptionsBox->Add(sActions, 1, wxEXPAND | wxRIGHT | wxTOP | wxBOTTOM, 5);
|
sOptionsBox->Add(sActions, 1, wxEXPAND, space5);
|
||||||
sOptionsBox->Add(sFlags, 1, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 5);
|
sOptionsBox->Add(sFlags, 1, wxEXPAND | wxLEFT, space5);
|
||||||
|
|
||||||
auto* sControls = new wxBoxSizer(wxVERTICAL);
|
auto* sControls = new wxBoxSizer(wxVERTICAL);
|
||||||
sControls->Add(m_radioAddress, 0, wxEXPAND);
|
sControls->Add(m_radioAddress, 0, wxEXPAND);
|
||||||
|
sControls->AddSpacer(5);
|
||||||
sControls->Add(sAddressBox, 0, wxEXPAND);
|
sControls->Add(sAddressBox, 0, wxEXPAND);
|
||||||
|
sControls->AddSpacer(5);
|
||||||
sControls->Add(m_radioRange, 0, wxEXPAND);
|
sControls->Add(m_radioRange, 0, wxEXPAND);
|
||||||
|
sControls->AddSpacer(5);
|
||||||
sControls->Add(sAddressRangeBox, 0, wxEXPAND);
|
sControls->Add(sAddressRangeBox, 0, wxEXPAND);
|
||||||
|
sControls->AddSpacer(5);
|
||||||
sControls->Add(sOptionsBox, 0, wxEXPAND);
|
sControls->Add(sOptionsBox, 0, wxEXPAND);
|
||||||
|
|
||||||
auto* sMainSizer = new wxBoxSizer(wxVERTICAL);
|
auto* sMainSizer = new wxBoxSizer(wxVERTICAL);
|
||||||
sMainSizer->Add(sControls, 0, wxEXPAND | wxTOP | wxRIGHT | wxLEFT, 5);
|
sMainSizer->AddSpacer(space5);
|
||||||
sMainSizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
sMainSizer->Add(sControls, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
|
||||||
|
sMainSizer->AddSpacer(space5);
|
||||||
|
sMainSizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
|
||||||
|
sMainSizer->AddSpacer(space5);
|
||||||
|
|
||||||
SetSizerAndFit(sMainSizer);
|
SetSizerAndFit(sMainSizer);
|
||||||
SetFocus();
|
SetFocus();
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
// Licensed under GPLv2+
|
// Licensed under GPLv2+
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cctype>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <wx/brush.h>
|
#include <wx/brush.h>
|
||||||
|
@ -17,6 +19,7 @@
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/DebugInterface.h"
|
#include "Common/DebugInterface.h"
|
||||||
#include "Common/StringUtil.h"
|
#include "Common/StringUtil.h"
|
||||||
|
#include "Core/HW/Memmap.h"
|
||||||
#include "Core/PowerPC/PPCSymbolDB.h"
|
#include "Core/PowerPC/PPCSymbolDB.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
#include "DolphinWX/Debugger/CodeWindow.h"
|
#include "DolphinWX/Debugger/CodeWindow.h"
|
||||||
|
@ -25,6 +28,7 @@
|
||||||
#include "DolphinWX/Debugger/WatchWindow.h"
|
#include "DolphinWX/Debugger/WatchWindow.h"
|
||||||
#include "DolphinWX/Frame.h"
|
#include "DolphinWX/Frame.h"
|
||||||
#include "DolphinWX/Globals.h"
|
#include "DolphinWX/Globals.h"
|
||||||
|
#include "DolphinWX/Main.h"
|
||||||
#include "DolphinWX/WxUtils.h"
|
#include "DolphinWX/WxUtils.h"
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -42,11 +46,12 @@ enum
|
||||||
IDM_VIEWASHEX,
|
IDM_VIEWASHEX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
wxDEFINE_EVENT(DOLPHIN_EVT_MEMORY_VIEW_DATA_TYPE_CHANGED, wxCommandEvent);
|
||||||
|
|
||||||
CMemoryView::CMemoryView(DebugInterface* debuginterface, wxWindow* parent)
|
CMemoryView::CMemoryView(DebugInterface* debuginterface, wxWindow* parent)
|
||||||
: wxControl(parent, wxID_ANY), debugger(debuginterface),
|
: wxControl(parent, wxID_ANY), debugger(debuginterface), align(0), rowHeight(FromDIP(13)),
|
||||||
align(debuginterface->GetInstructionSize(0)), rowHeight(13), selection(0), oldSelection(0),
|
m_left_col_width(FromDIP(LEFT_COL_WIDTH)), selection(0), oldSelection(0), selecting(false),
|
||||||
selecting(false), memory(0), curAddress(debuginterface->GetPC()),
|
memory(0), curAddress(debuginterface->GetPC()), m_data_type(MemoryDataType::U8)
|
||||||
dataType(MemoryDataType::U8), viewAsType(VIEWAS_FP)
|
|
||||||
{
|
{
|
||||||
Bind(wxEVT_PAINT, &CMemoryView::OnPaint, this);
|
Bind(wxEVT_PAINT, &CMemoryView::OnPaint, this);
|
||||||
Bind(wxEVT_LEFT_DOWN, &CMemoryView::OnMouseDownL, this);
|
Bind(wxEVT_LEFT_DOWN, &CMemoryView::OnMouseDownL, this);
|
||||||
|
@ -56,6 +61,38 @@ CMemoryView::CMemoryView(DebugInterface* debuginterface, wxWindow* parent)
|
||||||
Bind(wxEVT_MOUSEWHEEL, &CMemoryView::OnScrollWheel, this);
|
Bind(wxEVT_MOUSEWHEEL, &CMemoryView::OnScrollWheel, this);
|
||||||
Bind(wxEVT_MENU, &CMemoryView::OnPopupMenu, this);
|
Bind(wxEVT_MENU, &CMemoryView::OnPopupMenu, this);
|
||||||
Bind(wxEVT_SIZE, &CMemoryView::OnResize, this);
|
Bind(wxEVT_SIZE, &CMemoryView::OnResize, this);
|
||||||
|
|
||||||
|
SetDataType(MemoryDataType::FloatingPoint);
|
||||||
|
|
||||||
|
// Every pixel will be drawn over in the paint event so erasing will just cause flickering.
|
||||||
|
SetBackgroundStyle(wxBG_STYLE_PAINT);
|
||||||
|
#if defined(__WXMSW__) || defined(__WXGTK__)
|
||||||
|
SetDoubleBuffered(true);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMemoryView::SetDataType(MemoryDataType data_type)
|
||||||
|
{
|
||||||
|
if (m_data_type == data_type)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_data_type = data_type;
|
||||||
|
switch (data_type)
|
||||||
|
{
|
||||||
|
case MemoryDataType::FloatingPoint:
|
||||||
|
case MemoryDataType::ASCII:
|
||||||
|
align = 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
align = 16;
|
||||||
|
m_last_hex_type = data_type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Refresh();
|
||||||
|
|
||||||
|
wxCommandEvent ev(DOLPHIN_EVT_MEMORY_VIEW_DATA_TYPE_CHANGED, GetId());
|
||||||
|
ev.SetInt(static_cast<int>(data_type));
|
||||||
|
GetEventHandler()->ProcessEvent(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CMemoryView::YToAddress(int y)
|
int CMemoryView::YToAddress(int y)
|
||||||
|
@ -68,10 +105,10 @@ int CMemoryView::YToAddress(int y)
|
||||||
|
|
||||||
void CMemoryView::OnMouseDownL(wxMouseEvent& event)
|
void CMemoryView::OnMouseDownL(wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
int x = event.m_x;
|
int x = event.GetX();
|
||||||
int y = event.m_y;
|
int y = event.GetY();
|
||||||
|
|
||||||
if (x > 16)
|
if (x > m_left_col_width)
|
||||||
{
|
{
|
||||||
oldSelection = selection;
|
oldSelection = selection;
|
||||||
selection = YToAddress(y);
|
selection = YToAddress(y);
|
||||||
|
@ -99,7 +136,7 @@ void CMemoryView::OnMouseMove(wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
wxRect rc = GetClientRect();
|
wxRect rc = GetClientRect();
|
||||||
|
|
||||||
if (event.m_leftDown && event.m_x > 16)
|
if (event.m_leftDown && event.m_x > m_left_col_width)
|
||||||
{
|
{
|
||||||
if (event.m_y < 0)
|
if (event.m_y < 0)
|
||||||
{
|
{
|
||||||
|
@ -120,7 +157,7 @@ void CMemoryView::OnMouseMove(wxMouseEvent& event)
|
||||||
|
|
||||||
void CMemoryView::OnMouseUpL(wxMouseEvent& event)
|
void CMemoryView::OnMouseUpL(wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
if (event.m_x > 16)
|
if (event.m_x > m_left_col_width)
|
||||||
{
|
{
|
||||||
curAddress = YToAddress(event.m_y);
|
curAddress = YToAddress(event.m_y);
|
||||||
selecting = false;
|
selecting = false;
|
||||||
|
@ -137,11 +174,11 @@ void CMemoryView::OnScrollWheel(wxMouseEvent& event)
|
||||||
|
|
||||||
if (scroll_down)
|
if (scroll_down)
|
||||||
{
|
{
|
||||||
curAddress += num_lines * 4;
|
curAddress += num_lines * align;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
curAddress -= num_lines * 4;
|
curAddress -= num_lines * align;
|
||||||
}
|
}
|
||||||
|
|
||||||
Refresh();
|
Refresh();
|
||||||
|
@ -150,25 +187,26 @@ void CMemoryView::OnScrollWheel(wxMouseEvent& event)
|
||||||
|
|
||||||
void CMemoryView::OnPopupMenu(wxCommandEvent& event)
|
void CMemoryView::OnPopupMenu(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
CFrame* main_frame = static_cast<CFrame*>(GetGrandParent()->GetParent());
|
// FIXME: This is terrible. Generate events instead.
|
||||||
CCodeWindow* code_window = main_frame->g_pCodeWindow;
|
CFrame* cframe = wxGetApp().GetCFrame();
|
||||||
CWatchWindow* watch_window = code_window->m_WatchWindow;
|
CCodeWindow* code_window = cframe->g_pCodeWindow;
|
||||||
|
CWatchWindow* watch_window = code_window->GetPanel<CWatchWindow>();
|
||||||
#if wxUSE_CLIPBOARD
|
|
||||||
wxTheClipboard->Open();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (event.GetId())
|
switch (event.GetId())
|
||||||
{
|
{
|
||||||
#if wxUSE_CLIPBOARD
|
#if wxUSE_CLIPBOARD
|
||||||
case IDM_COPYADDRESS:
|
case IDM_COPYADDRESS:
|
||||||
|
{
|
||||||
|
wxClipboardLocker clipboard_lock;
|
||||||
wxTheClipboard->SetData(new wxTextDataObject(wxString::Format("%08x", selection)));
|
wxTheClipboard->SetData(new wxTextDataObject(wxString::Format("%08x", selection)));
|
||||||
break;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case IDM_COPYHEX:
|
case IDM_COPYHEX:
|
||||||
{
|
{
|
||||||
std::string temp = StringFromFormat("%08x", debugger->ReadExtraMemory(memory, selection));
|
wxClipboardLocker clipboard_lock;
|
||||||
wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(temp)));
|
wxTheClipboard->SetData(new wxTextDataObject(
|
||||||
|
wxString::Format("%08x", debugger->ReadExtraMemory(memory, selection))));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
@ -186,24 +224,21 @@ void CMemoryView::OnPopupMenu(wxCommandEvent& event)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDM_VIEWASFP:
|
case IDM_VIEWASFP:
|
||||||
viewAsType = VIEWAS_FP;
|
SetDataType(MemoryDataType::FloatingPoint);
|
||||||
Refresh();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDM_VIEWASASCII:
|
case IDM_VIEWASASCII:
|
||||||
viewAsType = VIEWAS_ASCII;
|
SetDataType(MemoryDataType::ASCII);
|
||||||
Refresh();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDM_VIEWASHEX:
|
case IDM_VIEWASHEX:
|
||||||
viewAsType = VIEWAS_HEX;
|
SetDataType(m_last_hex_type);
|
||||||
Refresh();
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
event.Skip();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if wxUSE_CLIPBOARD
|
|
||||||
wxTheClipboard->Close();
|
|
||||||
#endif
|
|
||||||
event.Skip();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMemoryView::OnMouseDownR(wxMouseEvent& event)
|
void CMemoryView::OnMouseDownR(wxMouseEvent& event)
|
||||||
|
@ -216,12 +251,14 @@ void CMemoryView::OnMouseDownR(wxMouseEvent& event)
|
||||||
menu.Append(IDM_COPYHEX, _("Copy &hex"));
|
menu.Append(IDM_COPYHEX, _("Copy &hex"));
|
||||||
#endif
|
#endif
|
||||||
menu.Append(IDM_WATCHADDRESS, _("Add to &watch"));
|
menu.Append(IDM_WATCHADDRESS, _("Add to &watch"));
|
||||||
menu.Append(IDM_TOGGLEMEMORY, _("Toggle &memory"));
|
menu.AppendCheckItem(IDM_TOGGLEMEMORY, _("Toggle &memory"))->Check(memory != 0);
|
||||||
|
|
||||||
wxMenu* viewAsSubMenu = new wxMenu;
|
wxMenu* viewAsSubMenu = new wxMenu;
|
||||||
viewAsSubMenu->Append(IDM_VIEWASFP, _("FP value"));
|
viewAsSubMenu->AppendRadioItem(IDM_VIEWASFP, _("FP value"))
|
||||||
viewAsSubMenu->Append(IDM_VIEWASASCII, "ASCII");
|
->Check(m_data_type == MemoryDataType::FloatingPoint);
|
||||||
viewAsSubMenu->Append(IDM_VIEWASHEX, _("Hex"));
|
viewAsSubMenu->AppendRadioItem(IDM_VIEWASASCII, "ASCII")
|
||||||
|
->Check(m_data_type == MemoryDataType::ASCII);
|
||||||
|
viewAsSubMenu->AppendRadioItem(IDM_VIEWASHEX, _("Hex"))->Check(IsHexMode());
|
||||||
menu.AppendSubMenu(viewAsSubMenu, _("View As:"));
|
menu.AppendSubMenu(viewAsSubMenu, _("View As:"));
|
||||||
|
|
||||||
PopupMenu(&menu);
|
PopupMenu(&menu);
|
||||||
|
@ -231,176 +268,160 @@ void CMemoryView::OnPaint(wxPaintEvent& event)
|
||||||
{
|
{
|
||||||
wxPaintDC dc(this);
|
wxPaintDC dc(this);
|
||||||
wxRect rc = GetClientRect();
|
wxRect rc = GetClientRect();
|
||||||
wxFont hFont("Courier");
|
|
||||||
hFont.SetFamily(wxFONTFAMILY_TELETYPE);
|
|
||||||
|
|
||||||
wxCoord w, h;
|
if (DebuggerFont.IsFixedWidth())
|
||||||
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);
|
dc.SetFont(DebuggerFont);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dc.SetFont(wxFont(DebuggerFont.GetPointSize(), wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL,
|
||||||
|
wxFONTWEIGHT_NORMAL, false, "Courier"));
|
||||||
|
}
|
||||||
|
|
||||||
dc.GetTextExtent("W", &w, &h);
|
int font_width;
|
||||||
int fontSize = w;
|
{
|
||||||
int textPlacement = 17 + 9 * fontSize;
|
wxFontMetrics metrics = dc.GetFontMetrics();
|
||||||
|
font_width = metrics.averageWidth;
|
||||||
|
if (metrics.height > rowHeight)
|
||||||
|
rowHeight = metrics.height;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Add any drawing code here...
|
const int row_start_x = m_left_col_width + 1;
|
||||||
int width = rc.width;
|
const int mchk_x = FromDIP(LEFT_COL_WIDTH / 8);
|
||||||
int numRows = (rc.height / rowHeight) / 2 + 2;
|
const wxSize mchk_size = FromDIP(wxSize(LEFT_COL_WIDTH * 3 / 4, LEFT_COL_WIDTH * 3 / 4));
|
||||||
dc.SetBackgroundMode(wxPENSTYLE_TRANSPARENT);
|
const int mchk_offset_y = (rowHeight - mchk_size.GetHeight()) / 2;
|
||||||
const wxColour bgColor = *wxWHITE;
|
|
||||||
wxPen nullPen(bgColor);
|
|
||||||
wxPen currentPen(*wxBLACK_PEN);
|
|
||||||
wxPen selPen(*wxGREY_PEN);
|
|
||||||
nullPen.SetStyle(wxPENSTYLE_TRANSPARENT);
|
|
||||||
|
|
||||||
wxBrush currentBrush(*wxLIGHT_GREY_BRUSH);
|
int col_width = rc.width - m_left_col_width;
|
||||||
wxBrush pcBrush(*wxGREEN_BRUSH);
|
int num_rows = (rc.height / rowHeight) / 2 + 2;
|
||||||
wxBrush mcBrush(*wxBLUE_BRUSH);
|
const wxColour navy_color = wxTheColourDatabase->Find("NAVY");
|
||||||
wxBrush bgBrush(bgColor);
|
|
||||||
wxBrush nullBrush(bgColor);
|
|
||||||
nullBrush.SetStyle(wxBRUSHSTYLE_TRANSPARENT);
|
|
||||||
|
|
||||||
dc.SetPen(nullPen);
|
const int pen_width = FromDIP(1);
|
||||||
dc.SetBrush(bgBrush);
|
wxPen focus_pen(*wxBLACK, pen_width);
|
||||||
dc.DrawRectangle(0, 0, 16, rc.height);
|
wxPen selection_pen(*wxLIGHT_GREY, pen_width);
|
||||||
dc.DrawRectangle(0, 0, rc.width, 5 + 8);
|
wxBrush pc_brush(*wxGREEN_BRUSH);
|
||||||
|
wxBrush mc_brush(*wxBLUE_BRUSH);
|
||||||
|
wxBrush bg_brush(*wxWHITE_BRUSH);
|
||||||
|
|
||||||
// TODO - clean up this freaking mess!!!!!
|
// TODO - clean up this freaking mess!!!!!
|
||||||
for (int row = -numRows; row <= numRows; row++)
|
for (int row = -num_rows; row <= num_rows; ++row)
|
||||||
{
|
{
|
||||||
unsigned int address = curAddress + row * align;
|
u32 address = curAddress + row * align;
|
||||||
|
|
||||||
int rowY1 = rc.height / 2 + rowHeight * row - rowHeight / 2;
|
int row_y = rc.height / 2 + rowHeight * row - rowHeight / 2;
|
||||||
int rowY2 = rc.height / 2 + rowHeight * row + rowHeight / 2;
|
int row_x = row_start_x;
|
||||||
|
|
||||||
|
auto draw_text = [&](const wxString& s, int offset_chars = 0, int min_length = 0) -> void {
|
||||||
|
dc.DrawText(s, row_x + font_width * offset_chars, row_y);
|
||||||
|
row_x += font_width * (std::max(static_cast<int>(s.size()), min_length) + offset_chars);
|
||||||
|
};
|
||||||
|
|
||||||
wxString temp = wxString::Format("%08x", address);
|
wxString temp = wxString::Format("%08x", address);
|
||||||
u32 col = debugger->GetColor(address);
|
u32 col = debugger->GetColor(address);
|
||||||
wxBrush rowBrush(wxColour(col >> 16, col >> 8, col));
|
wxBrush rowBrush(wxColour(col >> 16, col >> 8, col));
|
||||||
dc.SetBrush(nullBrush);
|
dc.SetBrush(bg_brush);
|
||||||
dc.SetPen(nullPen);
|
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||||
dc.DrawRectangle(0, rowY1, 16, rowY2);
|
dc.DrawRectangle(0, row_y, m_left_col_width, rowHeight);
|
||||||
|
|
||||||
if (selecting && (address == selection))
|
if (selecting && (address == selection))
|
||||||
dc.SetPen(selPen);
|
dc.SetPen(selection_pen);
|
||||||
else
|
else
|
||||||
dc.SetPen(row == 0 ? currentPen : nullPen);
|
dc.SetPen(row == 0 ? focus_pen : *wxTRANSPARENT_PEN);
|
||||||
|
|
||||||
if (address == debugger->GetPC())
|
if (address == debugger->GetPC())
|
||||||
dc.SetBrush(pcBrush);
|
dc.SetBrush(pc_brush);
|
||||||
else
|
else
|
||||||
dc.SetBrush(rowBrush);
|
dc.SetBrush(rowBrush);
|
||||||
|
|
||||||
dc.DrawRectangle(16, rowY1, width, rowY2 - 1);
|
dc.DrawRectangle(m_left_col_width, row_y, col_width, rowHeight);
|
||||||
dc.SetBrush(currentBrush);
|
dc.SetTextForeground(wxColour(0x60, 0x00, 0x00)); // Dark red
|
||||||
dc.SetTextForeground("#600000"); // Dark red
|
draw_text(temp);
|
||||||
dc.DrawText(temp, 17, rowY1);
|
|
||||||
|
|
||||||
if (viewAsType != VIEWAS_HEX)
|
if (!IsHexMode())
|
||||||
{
|
{
|
||||||
char mem[256];
|
char mem[256];
|
||||||
debugger->GetRawMemoryString(memory, address, mem, 256);
|
debugger->GetRawMemoryString(memory, address, mem, 256);
|
||||||
dc.SetTextForeground(wxTheColourDatabase->Find("NAVY"));
|
dc.SetTextForeground(navy_color);
|
||||||
dc.DrawText(StrToWxStr(mem), 17 + fontSize * (8), rowY1);
|
draw_text(StrToWxStr(mem), 2);
|
||||||
dc.SetTextForeground(*wxBLACK);
|
}
|
||||||
|
dc.SetTextForeground(*wxBLACK);
|
||||||
|
|
||||||
|
// NOTE: We can trigger a segfault inside HostIsRAMAddress (nullptr) during shutdown
|
||||||
|
// because we still get paint events even though the core is being deleted so we
|
||||||
|
// need to make sure the Memory still exists.
|
||||||
|
// FIXME: This isn't relevant to the DSP Memory View
|
||||||
|
if (!debugger->IsAlive() || !Memory::IsInitialized() || !PowerPC::HostIsRAMAddress(address))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
std::string dis;
|
||||||
|
// FIXME: This doesn't work with the DSP Debugger
|
||||||
|
u32 mem_data = debugger->ReadExtraMemory(memory, address);
|
||||||
|
|
||||||
|
if (m_data_type == MemoryDataType::FloatingPoint)
|
||||||
|
{
|
||||||
|
float& flt = reinterpret_cast<float&>(mem_data);
|
||||||
|
dis = StringFromFormat("f: %f", flt);
|
||||||
|
}
|
||||||
|
else if (m_data_type == MemoryDataType::ASCII)
|
||||||
|
{
|
||||||
|
dis.reserve(4);
|
||||||
|
for (unsigned int i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
u8 byte = static_cast<u8>(mem_data >> (24 - i * 8));
|
||||||
|
if (std::isprint(byte))
|
||||||
|
dis += static_cast<char>(byte);
|
||||||
|
else
|
||||||
|
dis += ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
Symbol* sym = g_symbolDB.GetSymbolFromAddr(mem_data);
|
||||||
|
if (sym)
|
||||||
|
{
|
||||||
|
dis += StringFromFormat(" # -> %s", sym->name.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dis.reserve(48);
|
||||||
|
for (unsigned int i = 0; i < align; i += sizeof(u32))
|
||||||
|
{
|
||||||
|
if (!PowerPC::HostIsRAMAddress(address + i))
|
||||||
|
break;
|
||||||
|
u32 word = debugger->ReadExtraMemory(memory, address + i);
|
||||||
|
switch (m_data_type)
|
||||||
|
{
|
||||||
|
case MemoryDataType::U8:
|
||||||
|
default:
|
||||||
|
dis += StringFromFormat(" %02X %02X %02X %02X", (word >> 24) & 0xFF, (word >> 16) & 0xFF,
|
||||||
|
(word >> 8) & 0xFF, word & 0xFF);
|
||||||
|
break;
|
||||||
|
case MemoryDataType::U16:
|
||||||
|
dis += StringFromFormat(" %04X %04X", (word >> 16) & 0xFFFF, word & 0xFFFF);
|
||||||
|
break;
|
||||||
|
case MemoryDataType::U32:
|
||||||
|
dis += StringFromFormat(" %08X", word);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debugger->IsAlive())
|
// Pad to a minimum of 48 characters for full fixed point float width
|
||||||
|
draw_text(StrToWxStr(dis), 2, 48);
|
||||||
|
|
||||||
|
dc.SetTextForeground(*wxBLUE);
|
||||||
|
|
||||||
|
std::string desc = debugger->GetDescription(address);
|
||||||
|
if (!desc.empty())
|
||||||
|
draw_text(StrToWxStr(desc), 2);
|
||||||
|
|
||||||
|
// Show blue memory check dot
|
||||||
|
if (debugger->IsMemCheck(address))
|
||||||
{
|
{
|
||||||
if (!PowerPC::HostIsRAMAddress(address))
|
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||||
continue;
|
dc.SetBrush(mc_brush);
|
||||||
|
dc.DrawEllipse(mchk_x, row_y + mchk_offset_y, mchk_size.GetWidth(), mchk_size.GetHeight());
|
||||||
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)};
|
|
||||||
|
|
||||||
for (auto& word : a)
|
|
||||||
{
|
|
||||||
if (word == '\0')
|
|
||||||
word = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
Symbol* sym = g_symbolDB.GetSymbolFromAddr(mem_data);
|
|
||||||
if (sym == nullptr)
|
|
||||||
dis = StringFromFormat("%c%c%c%c", a[0], a[1], a[2], a[3]);
|
|
||||||
else
|
|
||||||
dis = StringFromFormat("# -> %s", sym->name.c_str());
|
|
||||||
}
|
|
||||||
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";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (viewAsType != VIEWAS_HEX)
|
|
||||||
dc.DrawText(StrToWxStr(dis), textPlacement + fontSize * (8 + 8), rowY1);
|
|
||||||
else
|
|
||||||
dc.DrawText(StrToWxStr(dis), textPlacement, rowY1);
|
|
||||||
|
|
||||||
dc.SetTextForeground(*wxBLUE);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dc.SetPen(currentPen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMemoryView::OnResize(wxSizeEvent& event)
|
void CMemoryView::OnResize(wxSizeEvent& event)
|
||||||
|
|
|
@ -13,9 +13,13 @@ enum class MemoryDataType
|
||||||
{
|
{
|
||||||
U8,
|
U8,
|
||||||
U16,
|
U16,
|
||||||
U32
|
U32,
|
||||||
|
ASCII,
|
||||||
|
FloatingPoint
|
||||||
};
|
};
|
||||||
|
|
||||||
|
wxDECLARE_EVENT(DOLPHIN_EVT_MEMORY_VIEW_DATA_TYPE_CHANGED, wxCommandEvent);
|
||||||
|
|
||||||
class CMemoryView : public wxControl
|
class CMemoryView : public wxControl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -29,12 +33,8 @@ public:
|
||||||
Refresh();
|
Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetDataType(MemoryDataType data_type)
|
void SetDataType(MemoryDataType data_type);
|
||||||
{
|
MemoryDataType GetDataType() const { return m_data_type; }
|
||||||
dataType = data_type;
|
|
||||||
Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetMemCheckOptions(bool read, bool write, bool log)
|
void SetMemCheckOptions(bool read, bool write, bool log)
|
||||||
{
|
{
|
||||||
memCheckRead = read;
|
memCheckRead = read;
|
||||||
|
@ -43,6 +43,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int YToAddress(int y);
|
||||||
|
bool IsHexMode() const
|
||||||
|
{
|
||||||
|
return m_data_type != MemoryDataType::ASCII && m_data_type != MemoryDataType::FloatingPoint;
|
||||||
|
}
|
||||||
|
|
||||||
void OnPaint(wxPaintEvent& event);
|
void OnPaint(wxPaintEvent& event);
|
||||||
void OnMouseDownL(wxMouseEvent& event);
|
void OnMouseDownL(wxMouseEvent& event);
|
||||||
void OnMouseMove(wxMouseEvent& event);
|
void OnMouseMove(wxMouseEvent& event);
|
||||||
|
@ -50,14 +56,15 @@ private:
|
||||||
void OnMouseDownR(wxMouseEvent& event);
|
void OnMouseDownR(wxMouseEvent& event);
|
||||||
void OnScrollWheel(wxMouseEvent& event);
|
void OnScrollWheel(wxMouseEvent& event);
|
||||||
void OnPopupMenu(wxCommandEvent& event);
|
void OnPopupMenu(wxCommandEvent& event);
|
||||||
|
|
||||||
int YToAddress(int y);
|
|
||||||
void OnResize(wxSizeEvent& event);
|
void OnResize(wxSizeEvent& event);
|
||||||
|
|
||||||
|
static constexpr int LEFT_COL_WIDTH = 16;
|
||||||
|
|
||||||
DebugInterface* debugger;
|
DebugInterface* debugger;
|
||||||
|
|
||||||
int align;
|
unsigned int align;
|
||||||
int rowHeight;
|
int rowHeight;
|
||||||
|
int m_left_col_width;
|
||||||
|
|
||||||
u32 selection;
|
u32 selection;
|
||||||
u32 oldSelection;
|
u32 oldSelection;
|
||||||
|
@ -65,18 +72,11 @@ private:
|
||||||
|
|
||||||
int memory;
|
int memory;
|
||||||
int curAddress;
|
int curAddress;
|
||||||
MemoryDataType dataType;
|
|
||||||
|
|
||||||
bool memCheckRead;
|
bool memCheckRead;
|
||||||
bool memCheckWrite;
|
bool memCheckWrite;
|
||||||
bool memCheckLog;
|
bool memCheckLog;
|
||||||
|
|
||||||
enum EViewAsType
|
MemoryDataType m_data_type;
|
||||||
{
|
MemoryDataType m_last_hex_type = MemoryDataType::U8;
|
||||||
VIEWAS_ASCII = 0,
|
|
||||||
VIEWAS_FP,
|
|
||||||
VIEWAS_HEX,
|
|
||||||
};
|
|
||||||
|
|
||||||
EViewAsType viewAsType;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
// Licensed under GPLv2+
|
// Licensed under GPLv2+
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <wx/button.h>
|
#include <wx/button.h>
|
||||||
|
@ -12,10 +13,13 @@
|
||||||
#include <wx/listbox.h>
|
#include <wx/listbox.h>
|
||||||
#include <wx/msgdlg.h>
|
#include <wx/msgdlg.h>
|
||||||
#include <wx/panel.h>
|
#include <wx/panel.h>
|
||||||
|
#include <wx/radiobox.h>
|
||||||
#include <wx/radiobut.h>
|
#include <wx/radiobut.h>
|
||||||
#include <wx/sizer.h>
|
#include <wx/sizer.h>
|
||||||
#include <wx/srchctrl.h>
|
#include <wx/srchctrl.h>
|
||||||
|
#include <wx/stattext.h>
|
||||||
#include <wx/textctrl.h>
|
#include <wx/textctrl.h>
|
||||||
|
#include <wx/utils.h>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/FileUtil.h"
|
#include "Common/FileUtil.h"
|
||||||
|
@ -43,9 +47,7 @@ enum
|
||||||
IDM_DUMP_MEM2,
|
IDM_DUMP_MEM2,
|
||||||
IDM_DUMP_FAKEVMEM,
|
IDM_DUMP_FAKEVMEM,
|
||||||
IDM_VALBOX,
|
IDM_VALBOX,
|
||||||
IDM_U8,
|
IDM_DATA_TYPE_RBOX,
|
||||||
IDM_U16,
|
|
||||||
IDM_U32,
|
|
||||||
IDM_SEARCH,
|
IDM_SEARCH,
|
||||||
IDM_ASCII,
|
IDM_ASCII,
|
||||||
IDM_HEX,
|
IDM_HEX,
|
||||||
|
@ -53,30 +55,24 @@ enum
|
||||||
};
|
};
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(CMemoryWindow, wxPanel)
|
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_SETVALBUTTON, CMemoryWindow::SetMemoryValue)
|
||||||
EVT_BUTTON(IDM_DUMP_MEMORY, CMemoryWindow::OnDumpMemory)
|
EVT_BUTTON(IDM_DUMP_MEMORY, CMemoryWindow::OnDumpMemory)
|
||||||
EVT_BUTTON(IDM_DUMP_MEM2, CMemoryWindow::OnDumpMem2)
|
EVT_BUTTON(IDM_DUMP_MEM2, CMemoryWindow::OnDumpMem2)
|
||||||
EVT_BUTTON(IDM_DUMP_FAKEVMEM, CMemoryWindow::OnDumpFakeVMEM)
|
EVT_BUTTON(IDM_DUMP_FAKEVMEM, CMemoryWindow::OnDumpFakeVMEM)
|
||||||
EVT_CHECKBOX(IDM_U8, CMemoryWindow::U8)
|
EVT_RADIOBOX(IDM_DATA_TYPE_RBOX, CMemoryWindow::OnDataTypeChanged)
|
||||||
EVT_CHECKBOX(IDM_U16, CMemoryWindow::U16)
|
EVT_BUTTON(IDM_SEARCH, CMemoryWindow::OnSearch)
|
||||||
EVT_CHECKBOX(IDM_U32, CMemoryWindow::U32)
|
EVT_RADIOBUTTON(IDM_MEMCHECK_OPTIONS_CHANGE, CMemoryWindow::OnMemCheckOptionChange)
|
||||||
EVT_BUTTON(IDM_SEARCH, CMemoryWindow::onSearch)
|
EVT_CHECKBOX(IDM_MEMCHECK_OPTIONS_CHANGE, CMemoryWindow::OnMemCheckOptionChange)
|
||||||
EVT_CHECKBOX(IDM_ASCII, CMemoryWindow::onAscii)
|
|
||||||
EVT_CHECKBOX(IDM_HEX, CMemoryWindow::onHex)
|
|
||||||
EVT_RADIOBUTTON(IDM_MEMCHECK_OPTIONS_CHANGE, CMemoryWindow::onMemCheckOptionChange)
|
|
||||||
EVT_CHECKBOX(IDM_MEMCHECK_OPTIONS_CHANGE, CMemoryWindow::onMemCheckOptionChange)
|
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
CMemoryWindow::CMemoryWindow(CCodeWindow* code_window, wxWindow* parent, wxWindowID id,
|
CMemoryWindow::CMemoryWindow(wxWindow* parent, wxWindowID id, const wxPoint& pos,
|
||||||
const wxPoint& pos, const wxSize& size, long style,
|
const wxSize& size, long style, const wxString& name)
|
||||||
const wxString& name)
|
: wxPanel(parent, id, pos, size, style, name)
|
||||||
: wxPanel(parent, id, pos, size, style, name), m_code_window(code_window)
|
|
||||||
{
|
{
|
||||||
DebugInterface* di = &PowerPC::debug_interface;
|
DebugInterface* di = &PowerPC::debug_interface;
|
||||||
|
|
||||||
memview = new CMemoryView(di, this);
|
memview = new CMemoryView(di, this);
|
||||||
|
memview->Bind(DOLPHIN_EVT_MEMORY_VIEW_DATA_TYPE_CHANGED, &CMemoryWindow::OnDataTypeChanged, this);
|
||||||
|
|
||||||
addrbox = new wxSearchCtrl(this, IDM_MEM_ADDRBOX);
|
addrbox = new wxSearchCtrl(this, IDM_MEM_ADDRBOX);
|
||||||
addrbox->Bind(wxEVT_TEXT, &CMemoryWindow::OnAddrBoxChange, this);
|
addrbox->Bind(wxEVT_TEXT, &CMemoryWindow::OnAddrBoxChange, this);
|
||||||
|
@ -85,13 +81,17 @@ CMemoryWindow::CMemoryWindow(CCodeWindow* code_window, wxWindow* parent, wxWindo
|
||||||
valbox =
|
valbox =
|
||||||
new wxTextCtrl(this, IDM_VALBOX, "", wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
|
new wxTextCtrl(this, IDM_VALBOX, "", wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
|
||||||
valbox->Bind(wxEVT_TEXT_ENTER, &CMemoryWindow::SetMemoryValueFromValBox, this);
|
valbox->Bind(wxEVT_TEXT_ENTER, &CMemoryWindow::SetMemoryValueFromValBox, this);
|
||||||
|
valbox->Bind(wxEVT_TEXT, &CMemoryWindow::OnValueChanged, this);
|
||||||
|
|
||||||
wxGridSizer* const search_sizer = new wxGridSizer(1);
|
const int space3 = FromDIP(3);
|
||||||
search_sizer->Add(addrbox);
|
const int space5 = FromDIP(5);
|
||||||
|
|
||||||
|
wxBoxSizer* const search_sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
|
search_sizer->Add(addrbox, 0, wxEXPAND);
|
||||||
search_sizer->Add(valbox, 0, wxEXPAND);
|
search_sizer->Add(valbox, 0, wxEXPAND);
|
||||||
search_sizer->Add(new wxButton(this, IDM_SETVALBUTTON, _("Set Value")));
|
search_sizer->Add(new wxButton(this, IDM_SETVALBUTTON, _("Set Value")));
|
||||||
|
|
||||||
wxGridSizer* const dump_sizer = new wxGridSizer(1);
|
wxBoxSizer* const dump_sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
dump_sizer->Add(new wxButton(this, IDM_DUMP_MEMORY, _("Dump MRAM")), 0, wxEXPAND);
|
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);
|
dump_sizer->Add(new wxButton(this, IDM_DUMP_MEM2, _("Dump EXRAM")), 0, wxEXPAND);
|
||||||
if (!SConfig::GetInstance().bMMU)
|
if (!SConfig::GetInstance().bMMU)
|
||||||
|
@ -99,73 +99,57 @@ CMemoryWindow::CMemoryWindow(CCodeWindow* code_window, wxWindow* parent, wxWindo
|
||||||
|
|
||||||
wxStaticBoxSizer* const sizerSearchType = new wxStaticBoxSizer(wxVERTICAL, this, _("Search"));
|
wxStaticBoxSizer* const sizerSearchType = new wxStaticBoxSizer(wxVERTICAL, this, _("Search"));
|
||||||
sizerSearchType->Add(btnSearch = new wxButton(this, IDM_SEARCH, _("Search")));
|
sizerSearchType->Add(btnSearch = new wxButton(this, IDM_SEARCH, _("Search")));
|
||||||
sizerSearchType->Add(chkAscii = new wxCheckBox(this, IDM_ASCII, "Ascii "));
|
sizerSearchType->Add(m_rb_ascii = new wxRadioButton(this, IDM_ASCII, "Ascii", wxDefaultPosition,
|
||||||
sizerSearchType->Add(chkHex = new wxCheckBox(this, IDM_HEX, _("Hex")));
|
wxDefaultSize, wxRB_GROUP));
|
||||||
|
sizerSearchType->Add(m_rb_hex = new wxRadioButton(this, IDM_HEX, _("Hex")));
|
||||||
|
m_search_result_msg =
|
||||||
|
new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
|
||||||
|
wxST_NO_AUTORESIZE | wxALIGN_CENTER_HORIZONTAL);
|
||||||
|
sizerSearchType->Add(m_search_result_msg, 0, wxEXPAND);
|
||||||
|
|
||||||
wxStaticBoxSizer* const sizerDataTypes = new wxStaticBoxSizer(wxVERTICAL, this, _("Data Type"));
|
wxArrayString data_type_options;
|
||||||
sizerDataTypes->SetMinSize(74, 40);
|
data_type_options.Add("U8");
|
||||||
sizerDataTypes->Add(chk8 = new wxCheckBox(this, IDM_U8, "U8"));
|
data_type_options.Add("U16");
|
||||||
sizerDataTypes->Add(chk16 = new wxCheckBox(this, IDM_U16, "U16"));
|
data_type_options.Add("U32");
|
||||||
sizerDataTypes->Add(chk32 = new wxCheckBox(this, IDM_U32, "U32"));
|
data_type_options.Add("ASCII");
|
||||||
|
data_type_options.Add("Float32");
|
||||||
|
m_rbox_data_type = new wxRadioBox(this, IDM_DATA_TYPE_RBOX, _("Data Type"), wxDefaultPosition,
|
||||||
|
wxDefaultSize, data_type_options, 1);
|
||||||
|
|
||||||
wxStaticBoxSizer* const sizerMemCheckOptions =
|
wxStaticBoxSizer* const memcheck_options_sizer =
|
||||||
new wxStaticBoxSizer(wxVERTICAL, this, "Memory check options");
|
new wxStaticBoxSizer(wxVERTICAL, this, "Memory check options");
|
||||||
sizerMemCheckOptions->Add(rdbReadWrite = new wxRadioButton(this, IDM_MEMCHECK_OPTIONS_CHANGE,
|
memcheck_options_sizer->Add(rdbReadWrite = new wxRadioButton(this, IDM_MEMCHECK_OPTIONS_CHANGE,
|
||||||
"Read and Write", wxDefaultPosition,
|
"Read and Write", wxDefaultPosition,
|
||||||
wxDefaultSize, wxRB_GROUP));
|
wxDefaultSize, wxRB_GROUP));
|
||||||
sizerMemCheckOptions->Add(rdbRead =
|
memcheck_options_sizer->Add(
|
||||||
new wxRadioButton(this, IDM_MEMCHECK_OPTIONS_CHANGE, "Read only"));
|
rdbRead = new wxRadioButton(this, IDM_MEMCHECK_OPTIONS_CHANGE, "Read only"));
|
||||||
sizerMemCheckOptions->Add(rdbWrite =
|
memcheck_options_sizer->Add(
|
||||||
new wxRadioButton(this, IDM_MEMCHECK_OPTIONS_CHANGE, "Write only"));
|
rdbWrite = new wxRadioButton(this, IDM_MEMCHECK_OPTIONS_CHANGE, "Write only"));
|
||||||
sizerMemCheckOptions->Add(chkLog = new wxCheckBox(this, IDM_MEMCHECK_OPTIONS_CHANGE, "Log"));
|
memcheck_options_sizer->Add(chkLog = new wxCheckBox(this, IDM_MEMCHECK_OPTIONS_CHANGE, "Log"));
|
||||||
|
|
||||||
wxBoxSizer* const sizerRight = new wxBoxSizer(wxVERTICAL);
|
wxBoxSizer* const sizerRight = new wxBoxSizer(wxVERTICAL);
|
||||||
sizerRight->Add(search_sizer);
|
sizerRight->Add(search_sizer);
|
||||||
sizerRight->AddSpacer(5);
|
sizerRight->AddSpacer(space5);
|
||||||
sizerRight->Add(dump_sizer);
|
sizerRight->Add(dump_sizer, 0, wxEXPAND);
|
||||||
sizerRight->Add(sizerSearchType);
|
sizerRight->Add(sizerSearchType, 0, wxEXPAND);
|
||||||
sizerRight->Add(sizerDataTypes);
|
sizerRight->Add(m_rbox_data_type, 0, wxEXPAND);
|
||||||
sizerRight->Add(sizerMemCheckOptions);
|
sizerRight->Add(memcheck_options_sizer, 0, wxEXPAND);
|
||||||
|
|
||||||
wxBoxSizer* const sizerBig = new wxBoxSizer(wxHORIZONTAL);
|
wxBoxSizer* const sizerBig = new wxBoxSizer(wxHORIZONTAL);
|
||||||
sizerBig->Add(memview, 20, wxEXPAND);
|
sizerBig->Add(memview, 20, wxEXPAND);
|
||||||
sizerBig->Add(sizerRight, 0, wxEXPAND | wxALL, 3);
|
sizerBig->AddSpacer(space3);
|
||||||
|
sizerBig->Add(sizerRight, 0, wxEXPAND | wxTOP | wxBOTTOM, space3);
|
||||||
|
sizerBig->AddSpacer(space3);
|
||||||
|
|
||||||
SetSizer(sizerBig);
|
SetSizer(sizerBig);
|
||||||
chkHex->SetValue(1); // Set defaults
|
m_rb_hex->SetValue(true); // Set defaults
|
||||||
chk8->SetValue(1);
|
chkLog->SetValue(true);
|
||||||
chkLog->SetValue(1);
|
m_rbox_data_type->SetSelection(static_cast<int>(memview->GetDataType()));
|
||||||
|
|
||||||
sizerRight->Fit(this);
|
sizerRight->Fit(this);
|
||||||
sizerBig->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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMemoryWindow::Load(IniFile& ini)
|
|
||||||
{
|
|
||||||
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());
|
|
||||||
|
|
||||||
SetSize(x, y, w, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMemoryWindow::JumpToAddress(u32 _Address)
|
void CMemoryWindow::JumpToAddress(u32 _Address)
|
||||||
{
|
{
|
||||||
memview->Center(_Address);
|
memview->Center(_Address);
|
||||||
|
@ -219,55 +203,14 @@ void CMemoryWindow::OnAddrBoxChange(wxCommandEvent& event)
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMemoryWindow::Update()
|
void CMemoryWindow::Repopulate()
|
||||||
{
|
{
|
||||||
memview->Refresh();
|
|
||||||
memview->Center(PC);
|
memview->Center(PC);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMemoryWindow::NotifyMapLoaded()
|
void CMemoryWindow::OnValueChanged(wxCommandEvent&)
|
||||||
{
|
{
|
||||||
symbols->Show(false); // hide it for faster filling
|
m_continue_search = false;
|
||||||
symbols->Clear();
|
|
||||||
#if 0
|
|
||||||
#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();
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMemoryWindow::OnHostMessage(wxCommandEvent& event)
|
|
||||||
{
|
|
||||||
switch (event.GetId())
|
|
||||||
{
|
|
||||||
case IDM_NOTIFY_MAP_LOADED:
|
|
||||||
NotifyMapLoaded();
|
|
||||||
break;
|
|
||||||
case IDM_UPDATE_BREAKPOINTS:
|
|
||||||
if (m_code_window->m_BreakpointWindow)
|
|
||||||
m_code_window->m_BreakpointWindow->NotifyUpdate();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DumpArray(const std::string& filename, const u8* data, size_t length)
|
static void DumpArray(const std::string& filename, const u8* data, size_t length)
|
||||||
|
@ -304,39 +247,40 @@ 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)
|
void CMemoryWindow::OnDataTypeChanged(wxCommandEvent& ev)
|
||||||
{
|
{
|
||||||
chk16->SetValue(0);
|
static constexpr std::array<MemoryDataType, 5> map{{MemoryDataType::U8, MemoryDataType::U16,
|
||||||
chk32->SetValue(0);
|
MemoryDataType::U32, MemoryDataType::ASCII,
|
||||||
memview->SetDataType(MemoryDataType::U8);
|
MemoryDataType::FloatingPoint}};
|
||||||
|
if (ev.GetId() == IDM_DATA_TYPE_RBOX)
|
||||||
|
{
|
||||||
|
memview->SetDataType(map.at(ev.GetSelection()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Event from the CMemoryView indicating type was changed.
|
||||||
|
auto itr = std::find(map.begin(), map.end(), static_cast<MemoryDataType>(ev.GetInt()));
|
||||||
|
int idx = -1;
|
||||||
|
if (itr != map.end())
|
||||||
|
idx = static_cast<int>(itr - map.begin());
|
||||||
|
m_rbox_data_type->SetSelection(idx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMemoryWindow::U16(wxCommandEvent& event)
|
void CMemoryWindow::OnSearch(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
chk8->SetValue(0);
|
wxBusyCursor hourglass_cursor;
|
||||||
chk32->SetValue(0);
|
u8* ram_ptr = nullptr;
|
||||||
memview->SetDataType(MemoryDataType::U16);
|
u32 ram_size = 0;
|
||||||
}
|
// NOTE: We're assuming the base address is zero.
|
||||||
|
|
||||||
void CMemoryWindow::U32(wxCommandEvent& event)
|
|
||||||
{
|
|
||||||
chk16->SetValue(0);
|
|
||||||
chk8->SetValue(0);
|
|
||||||
memview->SetDataType(MemoryDataType::U32);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMemoryWindow::onSearch(wxCommandEvent& event)
|
|
||||||
{
|
|
||||||
u8* TheRAM = nullptr;
|
|
||||||
u32 szRAM = 0;
|
|
||||||
switch (memview->GetMemoryType())
|
switch (memview->GetMemoryType())
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
default:
|
default:
|
||||||
if (Memory::m_pRAM)
|
if (Memory::m_pRAM)
|
||||||
{
|
{
|
||||||
TheRAM = Memory::m_pRAM;
|
ram_ptr = Memory::m_pRAM;
|
||||||
szRAM = Memory::REALRAM_SIZE;
|
ram_size = Memory::REALRAM_SIZE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -344,131 +288,115 @@ void CMemoryWindow::onSearch(wxCommandEvent& event)
|
||||||
u8* aram = DSP::GetARAMPtr();
|
u8* aram = DSP::GetARAMPtr();
|
||||||
if (aram)
|
if (aram)
|
||||||
{
|
{
|
||||||
TheRAM = aram;
|
ram_ptr = aram;
|
||||||
szRAM = DSP::ARAM_SIZE;
|
ram_size = DSP::ARAM_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Now we have memory to look in
|
if (!ram_ptr)
|
||||||
// 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
|
m_search_result_msg->SetLabel(_("Memory Not Ready"));
|
||||||
// If it's uneven
|
return;
|
||||||
size = (rawData.size() / 2) + pad;
|
}
|
||||||
Dest.resize(size + 32);
|
|
||||||
newsize = rawData.size();
|
|
||||||
|
|
||||||
if (pad)
|
std::vector<u8> search_bytes;
|
||||||
|
wxString search_val = valbox->GetValue();
|
||||||
|
|
||||||
|
if (m_rb_hex->GetValue())
|
||||||
|
{
|
||||||
|
search_val.Trim(true).Trim(false);
|
||||||
|
// If there's a trailing nybble, stick a zero in front to make it a byte
|
||||||
|
if (search_val.size() & 1)
|
||||||
|
search_val.insert(0, 1, '0');
|
||||||
|
search_bytes.reserve(search_val.size() / 2);
|
||||||
|
|
||||||
|
wxString conversion_buffer(2, ' ');
|
||||||
|
for (std::size_t i = 0; i < search_val.size(); i += 2)
|
||||||
{
|
{
|
||||||
tmpstr = new char[newsize + 2];
|
unsigned long byte = 0;
|
||||||
memset(tmpstr, 0, newsize + 2);
|
conversion_buffer[0] = search_val[i];
|
||||||
tmpstr[0] = '0';
|
conversion_buffer[1] = search_val[i + 1];
|
||||||
|
if (!conversion_buffer.ToULong(&byte, 16))
|
||||||
|
{
|
||||||
|
m_search_result_msg->SetLabel(_("Not Valid Hex"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
search_bytes.push_back(static_cast<u8>(byte));
|
||||||
}
|
}
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
// Looking for an ascii string
|
const auto& bytes = search_val.ToUTF8();
|
||||||
size = rawData.size();
|
search_bytes.assign(bytes.data(), bytes.data() + bytes.length());
|
||||||
Dest.resize(size + 1);
|
|
||||||
tmpstr = new char[size + 1];
|
|
||||||
|
|
||||||
tmp2 = &Dest.front();
|
|
||||||
sprintf(tmpstr, "%s", WxStrToStr(rawData).c_str());
|
|
||||||
|
|
||||||
for (i = 0; i < size; i++)
|
|
||||||
tmp2[i] = tmpstr[i];
|
|
||||||
|
|
||||||
delete[] tmpstr;
|
|
||||||
}
|
}
|
||||||
|
search_val.Clear();
|
||||||
|
|
||||||
if (size)
|
// For completeness
|
||||||
|
if (search_bytes.size() > ram_size)
|
||||||
{
|
{
|
||||||
unsigned char* pnt = &Dest.front();
|
m_search_result_msg->SetLabel(_("Value Too Large"));
|
||||||
unsigned int k = 0;
|
return;
|
||||||
// grab
|
}
|
||||||
wxString txt = addrbox->GetValue();
|
|
||||||
u32 addr = 0;
|
if (search_bytes.empty())
|
||||||
if (txt.size())
|
{
|
||||||
|
m_search_result_msg->SetLabel(_("No Value Given"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search starting from specified address if there is one.
|
||||||
|
u32 addr = 0; // Base address
|
||||||
|
{
|
||||||
|
wxString addr_val = addrbox->GetValue();
|
||||||
|
addr_val.Trim(true).Trim(false);
|
||||||
|
if (!addr_val.empty())
|
||||||
{
|
{
|
||||||
sscanf(WxStrToStr(txt).c_str(), "%08x", &addr);
|
unsigned long addr_ul = 0;
|
||||||
}
|
if (addr_val.ToULong(&addr_ul, 16))
|
||||||
i = addr + 4;
|
|
||||||
for (; i < szRAM; ++i)
|
|
||||||
{
|
|
||||||
for (k = 0; k < size; ++k)
|
|
||||||
{
|
{
|
||||||
if (i + k > szRAM)
|
addr = static_cast<u32>(addr_ul);
|
||||||
break;
|
// Don't find the result we're already looking at
|
||||||
if (k > size)
|
if (m_continue_search && addr == m_last_search_address)
|
||||||
break;
|
addr += 1;
|
||||||
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 the current address doesn't leave enough bytes to search then we're done.
|
||||||
|
if (addr >= ram_size - search_bytes.size())
|
||||||
|
{
|
||||||
|
m_search_result_msg->SetLabel(_("Address Out of Range"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8* end = &ram_ptr[ram_size - search_bytes.size() + 1];
|
||||||
|
u8* ptr = &ram_ptr[addr];
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
ptr = std::find(ptr, end, search_bytes[0]);
|
||||||
|
if (ptr == end)
|
||||||
|
{
|
||||||
|
m_search_result_msg->SetLabel(_("No Match"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::equal(search_bytes.begin(), search_bytes.end(), ptr))
|
||||||
|
{
|
||||||
|
m_search_result_msg->SetLabel(_("Match Found"));
|
||||||
|
u32 offset = static_cast<u32>(ptr - ram_ptr);
|
||||||
|
// NOTE: SetValue() generates a synthetic wxEVT_TEXT
|
||||||
|
addrbox->SetValue(wxString::Format("%08x", offset));
|
||||||
|
m_last_search_address = offset;
|
||||||
|
m_continue_search = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++ptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMemoryWindow::onAscii(wxCommandEvent& event)
|
void CMemoryWindow::OnMemCheckOptionChange(wxCommandEvent& event)
|
||||||
{
|
|
||||||
chkHex->SetValue(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMemoryWindow::onHex(wxCommandEvent& event)
|
|
||||||
{
|
|
||||||
chkAscii->SetValue(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMemoryWindow::onMemCheckOptionChange(wxCommandEvent& event)
|
|
||||||
{
|
{
|
||||||
if (rdbReadWrite->GetValue())
|
if (rdbReadWrite->GetValue())
|
||||||
memview->SetMemCheckOptions(true, true, chkLog->GetValue());
|
memview->SetMemCheckOptions(true, true, chkLog->GetValue());
|
||||||
|
|
|
@ -12,51 +12,46 @@ class CCodeWindow;
|
||||||
class IniFile;
|
class IniFile;
|
||||||
class wxButton;
|
class wxButton;
|
||||||
class wxCheckBox;
|
class wxCheckBox;
|
||||||
|
class wxRadioBox;
|
||||||
|
class wxRadioButton;
|
||||||
class wxListBox;
|
class wxListBox;
|
||||||
class wxSearchCtrl;
|
class wxSearchCtrl;
|
||||||
|
class wxStaticText;
|
||||||
class wxTextCtrl;
|
class wxTextCtrl;
|
||||||
class wxRadioButton;
|
class wxRadioButton;
|
||||||
|
|
||||||
class CMemoryWindow : public wxPanel
|
class CMemoryWindow : public wxPanel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CMemoryWindow(CCodeWindow* code_window, wxWindow* parent, wxWindowID id = wxID_ANY,
|
CMemoryWindow(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
|
||||||
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
|
const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL | wxBORDER_NONE,
|
||||||
long style = wxTAB_TRAVERSAL | wxBORDER_NONE, const wxString& name = _("Memory"));
|
const wxString& name = _("Memory"));
|
||||||
|
|
||||||
void Save(IniFile& _IniFile) const;
|
void Repopulate();
|
||||||
void Load(IniFile& _IniFile);
|
|
||||||
|
|
||||||
void Update() override;
|
|
||||||
void NotifyMapLoaded();
|
|
||||||
|
|
||||||
void JumpToAddress(u32 _Address);
|
void JumpToAddress(u32 _Address);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
|
|
||||||
void U8(wxCommandEvent& event);
|
void OnDataTypeChanged(wxCommandEvent& event);
|
||||||
void U16(wxCommandEvent& event);
|
void OnSearch(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 OnAddrBoxChange(wxCommandEvent& event);
|
||||||
void OnHostMessage(wxCommandEvent& event);
|
void OnValueChanged(wxCommandEvent&);
|
||||||
void SetMemoryValueFromValBox(wxCommandEvent& event);
|
void SetMemoryValueFromValBox(wxCommandEvent& event);
|
||||||
void SetMemoryValue(wxCommandEvent& event);
|
void SetMemoryValue(wxCommandEvent& event);
|
||||||
void OnDumpMemory(wxCommandEvent& event);
|
void OnDumpMemory(wxCommandEvent& event);
|
||||||
void OnDumpMem2(wxCommandEvent& event);
|
void OnDumpMem2(wxCommandEvent& event);
|
||||||
void OnDumpFakeVMEM(wxCommandEvent& event);
|
void OnDumpFakeVMEM(wxCommandEvent& event);
|
||||||
void onMemCheckOptionChange(wxCommandEvent& event);
|
void OnMemCheckOptionChange(wxCommandEvent& event);
|
||||||
|
|
||||||
wxCheckBox* chk8;
|
|
||||||
wxCheckBox* chk16;
|
|
||||||
wxCheckBox* chk32;
|
|
||||||
wxButton* btnSearch;
|
wxButton* btnSearch;
|
||||||
wxCheckBox* chkAscii;
|
wxRadioButton* m_rb_ascii;
|
||||||
wxCheckBox* chkHex;
|
wxRadioButton* m_rb_hex;
|
||||||
|
|
||||||
|
wxRadioBox* m_rbox_data_type;
|
||||||
|
wxStaticText* m_search_result_msg;
|
||||||
|
|
||||||
wxCheckBox* chkLog;
|
wxCheckBox* chkLog;
|
||||||
wxRadioButton* rdbRead;
|
wxRadioButton* rdbRead;
|
||||||
wxRadioButton* rdbWrite;
|
wxRadioButton* rdbWrite;
|
||||||
|
@ -65,8 +60,10 @@ private:
|
||||||
CCodeWindow* m_code_window;
|
CCodeWindow* m_code_window;
|
||||||
|
|
||||||
CMemoryView* memview;
|
CMemoryView* memview;
|
||||||
wxListBox* symbols;
|
|
||||||
|
|
||||||
wxSearchCtrl* addrbox;
|
wxSearchCtrl* addrbox;
|
||||||
wxTextCtrl* valbox;
|
wxTextCtrl* valbox;
|
||||||
|
|
||||||
|
u32 m_last_search_address = 0;
|
||||||
|
bool m_continue_search = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "DolphinWX/Debugger/WatchWindow.h"
|
#include "DolphinWX/Debugger/WatchWindow.h"
|
||||||
#include "DolphinWX/Frame.h"
|
#include "DolphinWX/Frame.h"
|
||||||
#include "DolphinWX/Globals.h"
|
#include "DolphinWX/Globals.h"
|
||||||
|
#include "DolphinWX/Main.h"
|
||||||
#include "DolphinWX/WxUtils.h"
|
#include "DolphinWX/WxUtils.h"
|
||||||
|
|
||||||
// F-zero 80005e60 wtf??
|
// F-zero 80005e60 wtf??
|
||||||
|
@ -466,7 +467,7 @@ CRegisterView::CRegisterView(wxWindow* parent, wxWindowID id) : wxGrid(parent, i
|
||||||
AutoSizeColumns();
|
AutoSizeColumns();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRegisterView::Update()
|
void CRegisterView::Repopulate()
|
||||||
{
|
{
|
||||||
m_register_table->UpdateCachedRegs();
|
m_register_table->UpdateCachedRegs();
|
||||||
ForceRefresh();
|
ForceRefresh();
|
||||||
|
@ -507,10 +508,11 @@ void CRegisterView::OnMouseDownR(wxGridEvent& event)
|
||||||
|
|
||||||
void CRegisterView::OnPopupMenu(wxCommandEvent& event)
|
void CRegisterView::OnPopupMenu(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
CFrame* main_frame = static_cast<CFrame*>(GetGrandParent()->GetParent());
|
// FIXME: This is terrible. Generate events instead.
|
||||||
CCodeWindow* code_window = main_frame->g_pCodeWindow;
|
CFrame* cframe = wxGetApp().GetCFrame();
|
||||||
CWatchWindow* watch_window = code_window->m_WatchWindow;
|
CCodeWindow* code_window = cframe->g_pCodeWindow;
|
||||||
CMemoryWindow* memory_window = code_window->m_MemoryWindow;
|
CWatchWindow* watch_window = code_window->GetPanel<CWatchWindow>();
|
||||||
|
CMemoryWindow* memory_window = code_window->GetPanel<CMemoryWindow>();
|
||||||
|
|
||||||
switch (event.GetId())
|
switch (event.GetId())
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
void UpdateCachedRegs();
|
void UpdateCachedRegs();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr size_t NUM_SPECIALS = 14;
|
static constexpr int NUM_SPECIALS = 14;
|
||||||
|
|
||||||
std::array<u32, 32> m_CachedRegs{};
|
std::array<u32, 32> m_CachedRegs{};
|
||||||
std::array<u32, NUM_SPECIALS> m_CachedSpecialRegs{};
|
std::array<u32, NUM_SPECIALS> m_CachedSpecialRegs{};
|
||||||
|
@ -72,7 +72,7 @@ class CRegisterView : public wxGrid
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CRegisterView(wxWindow* parent, wxWindowID id = wxID_ANY);
|
CRegisterView(wxWindow* parent, wxWindowID id = wxID_ANY);
|
||||||
void Update() override;
|
void Repopulate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void OnMouseDownR(wxGridEvent& event);
|
void OnMouseDownR(wxGridEvent& event);
|
||||||
|
|
|
@ -21,7 +21,7 @@ void CRegisterWindow::CreateGUIControls()
|
||||||
{
|
{
|
||||||
wxBoxSizer* sGrid = new wxBoxSizer(wxVERTICAL);
|
wxBoxSizer* sGrid = new wxBoxSizer(wxVERTICAL);
|
||||||
m_GPRGridView = new CRegisterView(this);
|
m_GPRGridView = new CRegisterView(this);
|
||||||
sGrid->Add(m_GPRGridView, 1, wxGROW);
|
sGrid->Add(m_GPRGridView, 1, wxEXPAND);
|
||||||
SetSizer(sGrid);
|
SetSizer(sGrid);
|
||||||
|
|
||||||
NotifyUpdate();
|
NotifyUpdate();
|
||||||
|
@ -30,5 +30,5 @@ void CRegisterWindow::CreateGUIControls()
|
||||||
void CRegisterWindow::NotifyUpdate()
|
void CRegisterWindow::NotifyUpdate()
|
||||||
{
|
{
|
||||||
if (m_GPRGridView != nullptr)
|
if (m_GPRGridView != nullptr)
|
||||||
m_GPRGridView->Update();
|
m_GPRGridView->Repopulate();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "DolphinWX/Debugger/WatchView.h"
|
#include "DolphinWX/Debugger/WatchView.h"
|
||||||
#include "DolphinWX/Debugger/WatchWindow.h"
|
#include "DolphinWX/Debugger/WatchWindow.h"
|
||||||
#include "DolphinWX/Frame.h"
|
#include "DolphinWX/Frame.h"
|
||||||
|
#include "DolphinWX/Main.h"
|
||||||
#include "DolphinWX/WxUtils.h"
|
#include "DolphinWX/WxUtils.h"
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -232,7 +233,7 @@ CWatchView::CWatchView(wxWindow* parent, wxWindowID id) : wxGrid(parent, id)
|
||||||
Bind(wxEVT_MENU, &CWatchView::OnPopupMenu, this);
|
Bind(wxEVT_MENU, &CWatchView::OnPopupMenu, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWatchView::Update()
|
void CWatchView::Repopulate()
|
||||||
{
|
{
|
||||||
if (Core::IsRunning())
|
if (Core::IsRunning())
|
||||||
{
|
{
|
||||||
|
@ -269,11 +270,12 @@ void CWatchView::OnMouseDownR(wxGridEvent& event)
|
||||||
|
|
||||||
void CWatchView::OnPopupMenu(wxCommandEvent& event)
|
void CWatchView::OnPopupMenu(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
CFrame* main_frame = static_cast<CFrame*>(GetGrandParent()->GetParent());
|
// FIXME: This is terrible. Generate events instead.
|
||||||
CCodeWindow* code_window = main_frame->g_pCodeWindow;
|
CFrame* cframe = wxGetApp().GetCFrame();
|
||||||
CWatchWindow* watch_window = code_window->m_WatchWindow;
|
CCodeWindow* code_window = cframe->g_pCodeWindow;
|
||||||
CMemoryWindow* memory_window = code_window->m_MemoryWindow;
|
CWatchWindow* watch_window = code_window->GetPanel<CWatchWindow>();
|
||||||
CBreakPointWindow* breakpoint_window = code_window->m_BreakpointWindow;
|
CMemoryWindow* memory_window = code_window->GetPanel<CMemoryWindow>();
|
||||||
|
CBreakPointWindow* breakpoint_window = code_window->GetPanel<CBreakPointWindow>();
|
||||||
|
|
||||||
wxString strNewVal;
|
wxString strNewVal;
|
||||||
TMemCheck MemCheck;
|
TMemCheck MemCheck;
|
||||||
|
|
|
@ -37,7 +37,7 @@ class CWatchView : public wxGrid
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CWatchView(wxWindow* parent, wxWindowID id = wxID_ANY);
|
CWatchView(wxWindow* parent, wxWindowID id = wxID_ANY);
|
||||||
void Update() override;
|
void Repopulate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void OnMouseDownR(wxGridEvent& event);
|
void OnMouseDownR(wxGridEvent& event);
|
||||||
|
|
|
@ -25,9 +25,12 @@ public:
|
||||||
: DolphinAuiToolBar(parent, id, wxDefaultPosition, wxDefaultSize,
|
: DolphinAuiToolBar(parent, id, wxDefaultPosition, wxDefaultSize,
|
||||||
wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_TEXT)
|
wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_TEXT)
|
||||||
{
|
{
|
||||||
SetToolBitmapSize(wxSize(16, 16));
|
wxSize bitmap_size = FromDIP(wxSize(16, 16));
|
||||||
|
SetToolBitmapSize(bitmap_size);
|
||||||
|
|
||||||
m_Bitmaps[Toolbar_File] = WxUtils::LoadResourceBitmap("toolbar_debugger_delete");
|
m_Bitmaps[Toolbar_File] = WxUtils::LoadScaledResourceBitmap(
|
||||||
|
"toolbar_debugger_delete", this, bitmap_size, wxDefaultSize,
|
||||||
|
WxUtils::LSI_SCALE_DOWN | WxUtils::LSI_ALIGN_CENTER);
|
||||||
|
|
||||||
AddTool(ID_LOAD, _("Load"), m_Bitmaps[Toolbar_File]);
|
AddTool(ID_LOAD, _("Load"), m_Bitmaps[Toolbar_File]);
|
||||||
Bind(wxEVT_TOOL, &CWatchWindow::Event_LoadAll, parent, ID_LOAD);
|
Bind(wxEVT_TOOL, &CWatchWindow::Event_LoadAll, parent, ID_LOAD);
|
||||||
|
@ -80,7 +83,7 @@ CWatchWindow::~CWatchWindow()
|
||||||
void CWatchWindow::NotifyUpdate()
|
void CWatchWindow::NotifyUpdate()
|
||||||
{
|
{
|
||||||
if (m_GPRGridView != nullptr)
|
if (m_GPRGridView != nullptr)
|
||||||
m_GPRGridView->Update();
|
m_GPRGridView->Repopulate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWatchWindow::Event_SaveAll(wxCommandEvent& WXUNUSED(event))
|
void CWatchWindow::Event_SaveAll(wxCommandEvent& WXUNUSED(event))
|
||||||
|
|
|
@ -323,14 +323,9 @@ EVT_MOVE(CFrame::OnMove)
|
||||||
EVT_HOST_COMMAND(wxID_ANY, CFrame::OnHostMessage)
|
EVT_HOST_COMMAND(wxID_ANY, CFrame::OnHostMessage)
|
||||||
|
|
||||||
EVT_AUI_PANE_CLOSE(CFrame::OnPaneClose)
|
EVT_AUI_PANE_CLOSE(CFrame::OnPaneClose)
|
||||||
EVT_AUINOTEBOOK_PAGE_CLOSE(wxID_ANY, CFrame::OnNotebookPageClose)
|
|
||||||
EVT_AUINOTEBOOK_ALLOW_DND(wxID_ANY, CFrame::OnAllowNotebookDnD)
|
|
||||||
EVT_AUINOTEBOOK_PAGE_CHANGED(wxID_ANY, CFrame::OnNotebookPageChanged)
|
|
||||||
EVT_AUINOTEBOOK_TAB_RIGHT_UP(wxID_ANY, CFrame::OnTab)
|
|
||||||
|
|
||||||
// Post events to child panels
|
// Post events to child panels
|
||||||
EVT_MENU_RANGE(IDM_INTERPRETER, IDM_ADDRBOX, CFrame::PostEvent)
|
EVT_MENU_RANGE(IDM_INTERPRETER, IDM_ADDRBOX, CFrame::PostEvent)
|
||||||
EVT_TEXT(IDM_ADDRBOX, CFrame::PostEvent)
|
|
||||||
|
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
@ -643,11 +638,10 @@ void CFrame::OnClose(wxCloseEvent& event)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Close the log window now so that its settings are saved
|
m_LogWindow->SaveSettings();
|
||||||
if (m_LogWindow)
|
|
||||||
m_LogWindow->Close();
|
|
||||||
m_LogWindow = nullptr;
|
|
||||||
}
|
}
|
||||||
|
if (m_LogWindow)
|
||||||
|
m_LogWindow->RemoveAllListeners();
|
||||||
|
|
||||||
// Uninit
|
// Uninit
|
||||||
m_Mgr->UnInit();
|
m_Mgr->UnInit();
|
||||||
|
@ -745,6 +739,11 @@ void CFrame::OnHostMessage(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
switch (event.GetId())
|
switch (event.GetId())
|
||||||
{
|
{
|
||||||
|
case IDM_UPDATE_DISASM_DIALOG: // For breakpoints causing pausing
|
||||||
|
if (!g_pCodeWindow || Core::GetState() != Core::CORE_PAUSE)
|
||||||
|
return;
|
||||||
|
// fallthrough
|
||||||
|
|
||||||
case IDM_UPDATE_GUI:
|
case IDM_UPDATE_GUI:
|
||||||
UpdateGUI();
|
UpdateGUI();
|
||||||
break;
|
break;
|
||||||
|
@ -826,33 +825,29 @@ void CFrame::OnHostMessage(wxCommandEvent& event)
|
||||||
|
|
||||||
void CFrame::OnRenderWindowSizeRequest(int width, int height)
|
void CFrame::OnRenderWindowSizeRequest(int width, int height)
|
||||||
{
|
{
|
||||||
if (!Core::IsRunning() || !SConfig::GetInstance().bRenderWindowAutoSize ||
|
if (!SConfig::GetInstance().bRenderWindowAutoSize || !Core::IsRunning() ||
|
||||||
RendererIsFullscreen() || m_RenderFrame->IsMaximized())
|
RendererIsFullscreen() || m_RenderFrame->IsMaximized())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int old_width, old_height, log_width = 0, log_height = 0;
|
wxSize requested_size(width, height);
|
||||||
m_RenderFrame->GetClientSize(&old_width, &old_height);
|
// Convert to window pixels, since the size is from the backend it will be in framebuffer px.
|
||||||
|
requested_size *= 1.0 / m_RenderFrame->GetContentScaleFactor();
|
||||||
|
wxSize old_size;
|
||||||
|
|
||||||
// Add space for the log/console/debugger window
|
if (!SConfig::GetInstance().bRenderToMain)
|
||||||
if (SConfig::GetInstance().bRenderToMain && (SConfig::GetInstance().m_InterfaceLogWindow ||
|
|
||||||
SConfig::GetInstance().m_InterfaceLogConfigWindow) &&
|
|
||||||
!m_Mgr->GetPane("Pane 1").IsFloating())
|
|
||||||
{
|
{
|
||||||
switch (m_Mgr->GetPane("Pane 1").dock_direction)
|
old_size = m_RenderFrame->GetClientSize();
|
||||||
{
|
}
|
||||||
case wxAUI_DOCK_LEFT:
|
else
|
||||||
case wxAUI_DOCK_RIGHT:
|
{
|
||||||
log_width = m_Mgr->GetPane("Pane 1").rect.GetWidth();
|
// Resize for the render panel only, this implicitly retains space for everything else
|
||||||
break;
|
// (i.e. log panel, toolbar, statusbar, etc) without needing to compute for them.
|
||||||
case wxAUI_DOCK_TOP:
|
old_size = m_RenderParent->GetSize();
|
||||||
case wxAUI_DOCK_BOTTOM:
|
|
||||||
log_height = m_Mgr->GetPane("Pane 1").rect.GetHeight();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_width != width + log_width || old_height != height + log_height)
|
wxSize diff = requested_size - old_size;
|
||||||
m_RenderFrame->SetClientSize(width + log_width, height + log_height);
|
if (diff != wxSize())
|
||||||
|
m_RenderFrame->SetSize(m_RenderFrame->GetSize() + diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFrame::RendererHasFocus()
|
bool CFrame::RendererHasFocus()
|
||||||
|
|
|
@ -46,7 +46,7 @@ class CRenderFrame : public wxFrame
|
||||||
public:
|
public:
|
||||||
CRenderFrame(wxFrame* parent, wxWindowID id = wxID_ANY, const wxString& title = "Dolphin",
|
CRenderFrame(wxFrame* parent, wxWindowID id = wxID_ANY, const wxString& title = "Dolphin",
|
||||||
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
|
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
|
||||||
long style = wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE);
|
long style = wxDEFAULT_FRAME_STYLE);
|
||||||
|
|
||||||
bool ShowFullScreen(bool show, long style = wxFULLSCREEN_ALL) override;
|
bool ShowFullScreen(bool show, long style = wxFULLSCREEN_ALL) override;
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ public:
|
||||||
wxToolBar* m_ToolBar = nullptr;
|
wxToolBar* m_ToolBar = nullptr;
|
||||||
// AUI
|
// AUI
|
||||||
wxAuiManager* m_Mgr = nullptr;
|
wxAuiManager* m_Mgr = nullptr;
|
||||||
bool bFloatWindow[IDM_CODE_WINDOW - IDM_LOG_WINDOW + 1];
|
bool bFloatWindow[IDM_DEBUG_WINDOW_LIST_END - IDM_DEBUG_WINDOW_LIST_START] = {};
|
||||||
|
|
||||||
// Perspectives (Should find a way to make all of this private)
|
// Perspectives (Should find a way to make all of this private)
|
||||||
void DoAddPage(wxWindow* Win, int i, bool Float);
|
void DoAddPage(wxWindow* Win, int i, bool Float);
|
||||||
|
@ -211,12 +211,12 @@ private:
|
||||||
|
|
||||||
// Perspectives
|
// Perspectives
|
||||||
void AddRemoveBlankPage();
|
void AddRemoveBlankPage();
|
||||||
void OnNotebookPageClose(wxAuiNotebookEvent& event);
|
void OnNotebookAllowDnD(wxAuiNotebookEvent& event);
|
||||||
void OnAllowNotebookDnD(wxAuiNotebookEvent& event);
|
|
||||||
void OnNotebookPageChanged(wxAuiNotebookEvent& event);
|
void OnNotebookPageChanged(wxAuiNotebookEvent& event);
|
||||||
|
void OnNotebookPageClose(wxAuiNotebookEvent& event);
|
||||||
|
void OnNotebookTabRightUp(wxAuiNotebookEvent& event);
|
||||||
void OnFloatWindow(wxCommandEvent& event);
|
void OnFloatWindow(wxCommandEvent& event);
|
||||||
void ToggleFloatWindow(int Id);
|
void ToggleFloatWindow(int Id);
|
||||||
void OnTab(wxAuiNotebookEvent& event);
|
|
||||||
int GetNotebookAffiliation(wxWindowID Id);
|
int GetNotebookAffiliation(wxWindowID Id);
|
||||||
void ClosePages();
|
void ClosePages();
|
||||||
void CloseAllNotebooks();
|
void CloseAllNotebooks();
|
||||||
|
@ -228,7 +228,6 @@ private:
|
||||||
// Float window
|
// Float window
|
||||||
void DoUnfloatPage(int Id);
|
void DoUnfloatPage(int Id);
|
||||||
void OnFloatingPageClosed(wxCloseEvent& event);
|
void OnFloatingPageClosed(wxCloseEvent& event);
|
||||||
void OnFloatingPageSize(wxSizeEvent& event);
|
|
||||||
void DoFloatNotebookPage(wxWindowID Id);
|
void DoFloatNotebookPage(wxWindowID Id);
|
||||||
wxFrame* CreateParentFrame(wxWindowID Id = wxID_ANY, const wxString& title = "",
|
wxFrame* CreateParentFrame(wxWindowID Id = wxID_ANY, const wxString& title = "",
|
||||||
wxWindow* = nullptr);
|
wxWindow* = nullptr);
|
||||||
|
|
|
@ -152,41 +152,22 @@ void CFrame::ToggleLogConfigWindow(bool bShow)
|
||||||
|
|
||||||
void CFrame::OnToggleWindow(wxCommandEvent& event)
|
void CFrame::OnToggleWindow(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
bool bShow = GetMenuBar()->IsChecked(event.GetId());
|
bool show = GetMenuBar()->IsChecked(event.GetId());
|
||||||
|
|
||||||
switch (event.GetId())
|
switch (event.GetId())
|
||||||
{
|
{
|
||||||
case IDM_LOG_WINDOW:
|
case IDM_LOG_WINDOW:
|
||||||
if (!g_pCodeWindow)
|
if (!g_pCodeWindow)
|
||||||
SConfig::GetInstance().m_InterfaceLogWindow = bShow;
|
SConfig::GetInstance().m_InterfaceLogWindow = show;
|
||||||
ToggleLogWindow(bShow);
|
ToggleLogWindow(show);
|
||||||
break;
|
break;
|
||||||
case IDM_LOG_CONFIG_WINDOW:
|
case IDM_LOG_CONFIG_WINDOW:
|
||||||
if (!g_pCodeWindow)
|
if (!g_pCodeWindow)
|
||||||
SConfig::GetInstance().m_InterfaceLogConfigWindow = bShow;
|
SConfig::GetInstance().m_InterfaceLogConfigWindow = show;
|
||||||
ToggleLogConfigWindow(bShow);
|
ToggleLogConfigWindow(show);
|
||||||
break;
|
|
||||||
case IDM_REGISTER_WINDOW:
|
|
||||||
g_pCodeWindow->ToggleRegisterWindow(bShow);
|
|
||||||
break;
|
|
||||||
case IDM_WATCH_WINDOW:
|
|
||||||
g_pCodeWindow->ToggleWatchWindow(bShow);
|
|
||||||
break;
|
|
||||||
case IDM_BREAKPOINT_WINDOW:
|
|
||||||
g_pCodeWindow->ToggleBreakPointWindow(bShow);
|
|
||||||
break;
|
|
||||||
case IDM_MEMORY_WINDOW:
|
|
||||||
g_pCodeWindow->ToggleMemoryWindow(bShow);
|
|
||||||
break;
|
|
||||||
case IDM_JIT_WINDOW:
|
|
||||||
g_pCodeWindow->ToggleJitWindow(bShow);
|
|
||||||
break;
|
|
||||||
case IDM_SOUND_WINDOW:
|
|
||||||
g_pCodeWindow->ToggleSoundWindow(bShow);
|
|
||||||
break;
|
|
||||||
case IDM_VIDEO_WINDOW:
|
|
||||||
g_pCodeWindow->ToggleVideoWindow(bShow);
|
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
g_pCodeWindow->TogglePanel(event.GetId(), show);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,20 +180,21 @@ void CFrame::ClosePages()
|
||||||
|
|
||||||
if (g_pCodeWindow)
|
if (g_pCodeWindow)
|
||||||
{
|
{
|
||||||
g_pCodeWindow->ToggleCodeWindow(false);
|
for (int i = IDM_REGISTER_WINDOW; i < IDM_DEBUG_WINDOW_LIST_END; ++i)
|
||||||
g_pCodeWindow->ToggleRegisterWindow(false);
|
{
|
||||||
g_pCodeWindow->ToggleWatchWindow(false);
|
g_pCodeWindow->TogglePanel(i, false);
|
||||||
g_pCodeWindow->ToggleBreakPointWindow(false);
|
}
|
||||||
g_pCodeWindow->ToggleMemoryWindow(false);
|
|
||||||
g_pCodeWindow->ToggleJitWindow(false);
|
|
||||||
g_pCodeWindow->ToggleSoundWindow(false);
|
|
||||||
g_pCodeWindow->ToggleVideoWindow(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrame::OnNotebookPageChanged(wxAuiNotebookEvent& event)
|
void CFrame::OnNotebookPageChanged(wxAuiNotebookEvent& event)
|
||||||
{
|
{
|
||||||
event.Skip();
|
// Event is intended for someone else
|
||||||
|
if (event.GetPropagatedFrom() != nullptr)
|
||||||
|
{
|
||||||
|
event.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!g_pCodeWindow)
|
if (!g_pCodeWindow)
|
||||||
return;
|
return;
|
||||||
|
@ -230,39 +212,45 @@ void CFrame::OnNotebookPageChanged(wxAuiNotebookEvent& event)
|
||||||
|
|
||||||
void CFrame::OnNotebookPageClose(wxAuiNotebookEvent& event)
|
void CFrame::OnNotebookPageClose(wxAuiNotebookEvent& event)
|
||||||
{
|
{
|
||||||
|
// Event is intended for someone else
|
||||||
|
if (event.GetPropagatedFrom() != nullptr)
|
||||||
|
{
|
||||||
|
event.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Override event
|
// Override event
|
||||||
event.Veto();
|
event.Veto();
|
||||||
|
|
||||||
wxAuiNotebook* Ctrl = (wxAuiNotebook*)event.GetEventObject();
|
wxAuiNotebook* nb = static_cast<wxAuiNotebook*>(event.GetEventObject());
|
||||||
|
int page_id = nb->GetPage(event.GetSelection())->GetId();
|
||||||
|
|
||||||
if (Ctrl->GetPage(event.GetSelection())->GetId() == IDM_LOG_WINDOW)
|
switch (page_id)
|
||||||
ToggleLogWindow(false);
|
{
|
||||||
if (Ctrl->GetPage(event.GetSelection())->GetId() == IDM_LOG_CONFIG_WINDOW)
|
case IDM_LOG_WINDOW:
|
||||||
ToggleLogConfigWindow(false);
|
case IDM_LOG_CONFIG_WINDOW:
|
||||||
if (Ctrl->GetPage(event.GetSelection())->GetId() == IDM_REGISTER_WINDOW)
|
{
|
||||||
g_pCodeWindow->ToggleRegisterWindow(false);
|
GetMenuBar()->Check(page_id, !GetMenuBar()->IsChecked(page_id));
|
||||||
if (Ctrl->GetPage(event.GetSelection())->GetId() == IDM_WATCH_WINDOW)
|
wxCommandEvent ev(wxEVT_MENU, page_id);
|
||||||
g_pCodeWindow->ToggleWatchWindow(false);
|
OnToggleWindow(ev);
|
||||||
if (Ctrl->GetPage(event.GetSelection())->GetId() == IDM_BREAKPOINT_WINDOW)
|
break;
|
||||||
g_pCodeWindow->ToggleBreakPointWindow(false);
|
}
|
||||||
if (Ctrl->GetPage(event.GetSelection())->GetId() == IDM_JIT_WINDOW)
|
case IDM_CODE_WINDOW:
|
||||||
g_pCodeWindow->ToggleJitWindow(false);
|
break; // Code Window is not allowed to be closed
|
||||||
if (Ctrl->GetPage(event.GetSelection())->GetId() == IDM_MEMORY_WINDOW)
|
default:
|
||||||
g_pCodeWindow->ToggleMemoryWindow(false);
|
// Check for the magic empty panel.
|
||||||
if (Ctrl->GetPage(event.GetSelection())->GetId() == IDM_SOUND_WINDOW)
|
if (nb->GetPageText(event.GetSelection()).IsSameAs("<>"))
|
||||||
g_pCodeWindow->ToggleSoundWindow(false);
|
break;
|
||||||
if (Ctrl->GetPage(event.GetSelection())->GetId() == IDM_VIDEO_WINDOW)
|
|
||||||
g_pCodeWindow->ToggleVideoWindow(false);
|
g_pCodeWindow->TogglePanel(page_id, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrame::OnFloatingPageClosed(wxCloseEvent& event)
|
void CFrame::OnFloatingPageClosed(wxCloseEvent& event)
|
||||||
{
|
{
|
||||||
ToggleFloatWindow(event.GetId() - IDM_LOG_WINDOW_PARENT + IDM_FLOAT_LOG_WINDOW);
|
// TODO: This is a good place to save the window size and position to an INI
|
||||||
}
|
|
||||||
|
|
||||||
void CFrame::OnFloatingPageSize(wxSizeEvent& event)
|
ToggleFloatWindow(event.GetId() - IDM_LOG_WINDOW_PARENT + IDM_FLOAT_LOG_WINDOW);
|
||||||
{
|
|
||||||
event.Skip();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrame::OnFloatWindow(wxCommandEvent& event)
|
void CFrame::OnFloatWindow(wxCommandEvent& event)
|
||||||
|
@ -320,9 +308,15 @@ void CFrame::DoUnfloatPage(int Id)
|
||||||
Win->Destroy();
|
Win->Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrame::OnTab(wxAuiNotebookEvent& event)
|
void CFrame::OnNotebookTabRightUp(wxAuiNotebookEvent& event)
|
||||||
{
|
{
|
||||||
event.Skip();
|
// Event is intended for someone else
|
||||||
|
if (event.GetPropagatedFrom() != nullptr)
|
||||||
|
{
|
||||||
|
event.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!g_pCodeWindow)
|
if (!g_pCodeWindow)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -354,10 +348,21 @@ void CFrame::OnTab(wxAuiNotebookEvent& event)
|
||||||
PopupMenu(&MenuPopup, Pt);
|
PopupMenu(&MenuPopup, Pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrame::OnAllowNotebookDnD(wxAuiNotebookEvent& event)
|
void CFrame::OnNotebookAllowDnD(wxAuiNotebookEvent& event)
|
||||||
{
|
{
|
||||||
event.Skip();
|
// NOTE: This event was sent FROM the source notebook TO the destination notebook so
|
||||||
event.Allow();
|
// all the member variables are related to the source, we can't get the drop target.
|
||||||
|
// NOTE: This function is "part of the internal interface" but there's no clean alternative.
|
||||||
|
if (event.GetPropagatedFrom() != nullptr)
|
||||||
|
{
|
||||||
|
// Drop target was one of the notebook's children, we don't care about this event.
|
||||||
|
event.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Since the destination is one of our own notebooks, make sure the source is as well.
|
||||||
|
// If the source is some other panel, leave the event in the default reject state.
|
||||||
|
if (m_Mgr->GetPane(event.GetDragSource()).window)
|
||||||
|
event.Allow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrame::ShowResizePane()
|
void CFrame::ShowResizePane()
|
||||||
|
@ -391,12 +396,7 @@ void CFrame::ShowResizePane()
|
||||||
void CFrame::TogglePane()
|
void CFrame::TogglePane()
|
||||||
{
|
{
|
||||||
// Get the first notebook
|
// Get the first notebook
|
||||||
wxAuiNotebook* NB = nullptr;
|
wxAuiNotebook* NB = GetNotebookFromId(0);
|
||||||
for (u32 i = 0; i < m_Mgr->GetAllPanes().GetCount(); i++)
|
|
||||||
{
|
|
||||||
if (m_Mgr->GetAllPanes()[i].window->IsKindOf(CLASSINFO(wxAuiNotebook)))
|
|
||||||
NB = (wxAuiNotebook*)m_Mgr->GetAllPanes()[i].window;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NB)
|
if (NB)
|
||||||
{
|
{
|
||||||
|
@ -450,6 +450,7 @@ void CFrame::DoRemovePage(wxWindow* Win, bool bHide)
|
||||||
{
|
{
|
||||||
Win->Destroy();
|
Win->Destroy();
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -468,13 +469,17 @@ void CFrame::DoAddPage(wxWindow* Win, int i, bool Float)
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
// The page was already previously added, no need to add it again.
|
// The page was already previously added, no need to add it again.
|
||||||
if (Win && GetNotebookFromId(i)->GetPageIndex(Win) != wxNOT_FOUND)
|
if (GetNotebookFromId(i)->GetPageIndex(Win) != wxNOT_FOUND)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!Float)
|
if (!Float)
|
||||||
|
{
|
||||||
GetNotebookFromId(i)->AddPage(Win, Win->GetName(), true);
|
GetNotebookFromId(i)->AddPage(Win, Win->GetName(), true);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
CreateParentFrame(Win->GetId() + IDM_LOG_WINDOW_PARENT - IDM_LOG_WINDOW, Win->GetName(), Win);
|
CreateParentFrame(Win->GetId() + IDM_LOG_WINDOW_PARENT - IDM_LOG_WINDOW, Win->GetName(), Win);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrame::PopulateSavedPerspectives()
|
void CFrame::PopulateSavedPerspectives()
|
||||||
|
@ -664,8 +669,7 @@ void CFrame::SetPaneSize()
|
||||||
if (Perspectives.size() <= ActivePerspective)
|
if (Perspectives.size() <= ActivePerspective)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int iClientX = GetSize().GetX();
|
wxSize client_size = GetClientSize();
|
||||||
int iClientY = GetSize().GetY();
|
|
||||||
|
|
||||||
for (u32 i = 0, j = 0; i < m_Mgr->GetAllPanes().GetCount(); i++)
|
for (u32 i = 0, j = 0; i < m_Mgr->GetAllPanes().GetCount(); i++)
|
||||||
{
|
{
|
||||||
|
@ -687,8 +691,8 @@ void CFrame::SetPaneSize()
|
||||||
H = MathUtil::Clamp<u32>(H, 5, 95);
|
H = MathUtil::Clamp<u32>(H, 5, 95);
|
||||||
|
|
||||||
// Convert percentages to pixel lengths
|
// Convert percentages to pixel lengths
|
||||||
W = (W * iClientX) / 100;
|
W = (W * client_size.GetWidth()) / 100;
|
||||||
H = (H * iClientY) / 100;
|
H = (H * client_size.GetHeight()) / 100;
|
||||||
m_Mgr->GetAllPanes()[i].BestSize(W, H).MinSize(W, H);
|
m_Mgr->GetAllPanes()[i].BestSize(W, H).MinSize(W, H);
|
||||||
|
|
||||||
j++;
|
j++;
|
||||||
|
@ -815,7 +819,7 @@ void CFrame::UpdateCurrentPerspective()
|
||||||
current->Perspective = m_Mgr->SavePerspective();
|
current->Perspective = m_Mgr->SavePerspective();
|
||||||
|
|
||||||
// Get client size
|
// Get client size
|
||||||
int iClientX = GetSize().GetX(), iClientY = GetSize().GetY();
|
wxSize client_size = GetClientSize();
|
||||||
current->Width.clear();
|
current->Width.clear();
|
||||||
current->Height.clear();
|
current->Height.clear();
|
||||||
for (u32 i = 0; i < m_Mgr->GetAllPanes().GetCount(); i++)
|
for (u32 i = 0; i < m_Mgr->GetAllPanes().GetCount(); i++)
|
||||||
|
@ -823,10 +827,10 @@ void CFrame::UpdateCurrentPerspective()
|
||||||
if (!m_Mgr->GetAllPanes()[i].window->IsKindOf(CLASSINFO(wxAuiToolBar)))
|
if (!m_Mgr->GetAllPanes()[i].window->IsKindOf(CLASSINFO(wxAuiToolBar)))
|
||||||
{
|
{
|
||||||
// Save width and height as a percentage of the client width and height
|
// Save width and height as a percentage of the client width and height
|
||||||
current->Width.push_back((m_Mgr->GetAllPanes()[i].window->GetClientSize().GetX() * 100) /
|
current->Width.push_back((m_Mgr->GetAllPanes()[i].window->GetSize().GetX() * 100) /
|
||||||
iClientX);
|
client_size.GetWidth());
|
||||||
current->Height.push_back((m_Mgr->GetAllPanes()[i].window->GetClientSize().GetY() * 100) /
|
current->Height.push_back((m_Mgr->GetAllPanes()[i].window->GetSize().GetY() * 100) /
|
||||||
iClientY);
|
client_size.GetHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -952,23 +956,40 @@ wxFrame* CFrame::CreateParentFrame(wxWindowID Id, const wxString& Title, wxWindo
|
||||||
|
|
||||||
m_MainSizer->Add(Child, 1, wxEXPAND);
|
m_MainSizer->Add(Child, 1, wxEXPAND);
|
||||||
|
|
||||||
|
// If the tab is not the one currently being shown to the user then it will
|
||||||
|
// be hidden. Make sure it is being shown.
|
||||||
|
Child->Show();
|
||||||
|
|
||||||
Frame->Bind(wxEVT_CLOSE_WINDOW, &CFrame::OnFloatingPageClosed, this);
|
Frame->Bind(wxEVT_CLOSE_WINDOW, &CFrame::OnFloatingPageClosed, this);
|
||||||
|
|
||||||
|
// TODO: This is a good place to load window position and size settings from an INI
|
||||||
|
|
||||||
// Main sizer
|
// Main sizer
|
||||||
Frame->SetSizer(m_MainSizer);
|
Frame->SetSizerAndFit(m_MainSizer);
|
||||||
// Minimum frame size
|
|
||||||
Frame->SetMinSize(wxSize(200, 200));
|
|
||||||
Frame->Show();
|
Frame->Show();
|
||||||
return Frame;
|
return Frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxAuiNotebook* CFrame::CreateEmptyNotebook()
|
wxAuiNotebook* CFrame::CreateEmptyNotebook()
|
||||||
{
|
{
|
||||||
const long NOTEBOOK_STYLE = wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE |
|
static constexpr long NOTEBOOK_STYLE = wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE |
|
||||||
wxAUI_NB_TAB_EXTERNAL_MOVE | wxAUI_NB_SCROLL_BUTTONS |
|
wxAUI_NB_CLOSE_BUTTON | wxAUI_NB_TAB_EXTERNAL_MOVE |
|
||||||
wxAUI_NB_WINDOWLIST_BUTTON | wxNO_BORDER;
|
wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_WINDOWLIST_BUTTON |
|
||||||
|
wxNO_BORDER;
|
||||||
|
|
||||||
return new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, NOTEBOOK_STYLE);
|
auto* nb = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, NOTEBOOK_STYLE);
|
||||||
|
|
||||||
|
// wxAuiNotebookEvent is derived from wxCommandEvent so they bubble up from child panels.
|
||||||
|
// This is a problem if the panels contain their own AUI Notebooks like DSPDebuggerLLE
|
||||||
|
// since we receive its events as though they came from our own children which we do
|
||||||
|
// not want to deal with. Binding directly to our notebooks and ignoring any event that
|
||||||
|
// has been propagated from somewhere else resolves it.
|
||||||
|
nb->Bind(wxEVT_AUINOTEBOOK_ALLOW_DND, &CFrame::OnNotebookAllowDnD, this);
|
||||||
|
nb->Bind(wxEVT_AUINOTEBOOK_PAGE_CHANGED, &CFrame::OnNotebookPageChanged, this);
|
||||||
|
nb->Bind(wxEVT_AUINOTEBOOK_PAGE_CLOSE, &CFrame::OnNotebookPageClose, this);
|
||||||
|
nb->Bind(wxEVT_AUINOTEBOOK_TAB_RIGHT_UP, &CFrame::OnNotebookTabRightUp, this);
|
||||||
|
|
||||||
|
return nb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrame::AddRemoveBlankPage()
|
void CFrame::AddRemoveBlankPage()
|
||||||
|
|
|
@ -642,10 +642,10 @@ void CFrame::BootGame(const std::string& filename)
|
||||||
StartGame(bootfile);
|
StartGame(bootfile);
|
||||||
if (UseDebugger && g_pCodeWindow)
|
if (UseDebugger && g_pCodeWindow)
|
||||||
{
|
{
|
||||||
if (g_pCodeWindow->m_WatchWindow)
|
if (g_pCodeWindow->HasPanel<CWatchWindow>())
|
||||||
g_pCodeWindow->m_WatchWindow->LoadAll();
|
g_pCodeWindow->GetPanel<CWatchWindow>()->LoadAll();
|
||||||
if (g_pCodeWindow->m_BreakpointWindow)
|
if (g_pCodeWindow->HasPanel<CBreakPointWindow>())
|
||||||
g_pCodeWindow->m_BreakpointWindow->LoadAll();
|
g_pCodeWindow->GetPanel<CBreakPointWindow>()->LoadAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -842,7 +842,7 @@ void CFrame::OnPlay(wxCommandEvent& WXUNUSED(event))
|
||||||
|
|
||||||
wxThread::Sleep(20);
|
wxThread::Sleep(20);
|
||||||
g_pCodeWindow->JumpToAddress(PC);
|
g_pCodeWindow->JumpToAddress(PC);
|
||||||
g_pCodeWindow->Update();
|
g_pCodeWindow->Repopulate();
|
||||||
// Update toolbar with Play/Pause status
|
// Update toolbar with Play/Pause status
|
||||||
UpdateGUI();
|
UpdateGUI();
|
||||||
}
|
}
|
||||||
|
@ -1165,18 +1165,15 @@ void CFrame::DoStop()
|
||||||
|
|
||||||
if (UseDebugger && g_pCodeWindow)
|
if (UseDebugger && g_pCodeWindow)
|
||||||
{
|
{
|
||||||
if (g_pCodeWindow->m_WatchWindow)
|
if (g_pCodeWindow->HasPanel<CWatchWindow>())
|
||||||
{
|
g_pCodeWindow->GetPanel<CWatchWindow>()->SaveAll();
|
||||||
g_pCodeWindow->m_WatchWindow->SaveAll();
|
PowerPC::watches.Clear();
|
||||||
PowerPC::watches.Clear();
|
if (g_pCodeWindow->HasPanel<CBreakPointWindow>())
|
||||||
}
|
g_pCodeWindow->GetPanel<CBreakPointWindow>()->SaveAll();
|
||||||
if (g_pCodeWindow->m_BreakpointWindow)
|
PowerPC::breakpoints.Clear();
|
||||||
{
|
PowerPC::memchecks.Clear();
|
||||||
g_pCodeWindow->m_BreakpointWindow->SaveAll();
|
if (g_pCodeWindow->HasPanel<CBreakPointWindow>())
|
||||||
PowerPC::breakpoints.Clear();
|
g_pCodeWindow->GetPanel<CBreakPointWindow>()->NotifyUpdate();
|
||||||
PowerPC::memchecks.Clear();
|
|
||||||
g_pCodeWindow->m_BreakpointWindow->NotifyUpdate();
|
|
||||||
}
|
|
||||||
g_symbolDB.Clear();
|
g_symbolDB.Clear();
|
||||||
Host_NotifyMapLoaded();
|
Host_NotifyMapLoaded();
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,9 @@ enum
|
||||||
IDM_CONFIG_LOGGER,
|
IDM_CONFIG_LOGGER,
|
||||||
|
|
||||||
// Views
|
// Views
|
||||||
IDM_LOG_WINDOW,
|
// IMPORTANT: Make sure IDM_FLOAT_xxx and IDM_xxx_PARENT are kept in sync!
|
||||||
|
IDM_DEBUG_WINDOW_LIST_START, // Bookend for doing array lookups
|
||||||
|
IDM_LOG_WINDOW = IDM_DEBUG_WINDOW_LIST_START,
|
||||||
IDM_LOG_CONFIG_WINDOW,
|
IDM_LOG_CONFIG_WINDOW,
|
||||||
IDM_REGISTER_WINDOW,
|
IDM_REGISTER_WINDOW,
|
||||||
IDM_WATCH_WINDOW,
|
IDM_WATCH_WINDOW,
|
||||||
|
@ -173,9 +175,10 @@ enum
|
||||||
IDM_SOUND_WINDOW,
|
IDM_SOUND_WINDOW,
|
||||||
IDM_VIDEO_WINDOW,
|
IDM_VIDEO_WINDOW,
|
||||||
IDM_CODE_WINDOW,
|
IDM_CODE_WINDOW,
|
||||||
|
IDM_DEBUG_WINDOW_LIST_END, // Bookend for doing array lookups
|
||||||
|
|
||||||
// List Column Title Toggles
|
// List Column Title Toggles
|
||||||
IDM_SHOW_SYSTEM,
|
IDM_SHOW_SYSTEM = IDM_DEBUG_WINDOW_LIST_END,
|
||||||
IDM_SHOW_BANNER,
|
IDM_SHOW_BANNER,
|
||||||
IDM_SHOW_MAKER,
|
IDM_SHOW_MAKER,
|
||||||
IDM_SHOW_FILENAME,
|
IDM_SHOW_FILENAME,
|
||||||
|
@ -345,6 +348,7 @@ enum
|
||||||
// custom message macro
|
// custom message macro
|
||||||
#define EVT_HOST_COMMAND(id, fn) EVT_COMMAND(id, wxEVT_HOST_COMMAND, fn)
|
#define EVT_HOST_COMMAND(id, fn) EVT_COMMAND(id, wxEVT_HOST_COMMAND, fn)
|
||||||
|
|
||||||
|
// FIXME: This should be changed to wxThreadEvent
|
||||||
wxDECLARE_EVENT(wxEVT_HOST_COMMAND, wxCommandEvent);
|
wxDECLARE_EVENT(wxEVT_HOST_COMMAND, wxCommandEvent);
|
||||||
|
|
||||||
// Sent to wxTheApp
|
// Sent to wxTheApp
|
||||||
|
|
|
@ -25,18 +25,11 @@ LogConfigWindow::LogConfigWindow(wxWindow* parent, wxWindowID id)
|
||||||
_("Log Configuration")),
|
_("Log Configuration")),
|
||||||
enableAll(true)
|
enableAll(true)
|
||||||
{
|
{
|
||||||
Bind(wxEVT_CLOSE_WINDOW, &LogConfigWindow::OnClose, this);
|
|
||||||
SetMinSize(wxSize(100, 100));
|
|
||||||
m_LogManager = LogManager::GetInstance();
|
m_LogManager = LogManager::GetInstance();
|
||||||
CreateGUIControls();
|
CreateGUIControls();
|
||||||
LoadSettings();
|
LoadSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogConfigWindow::OnClose(wxCloseEvent& event)
|
|
||||||
{
|
|
||||||
SaveSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogConfigWindow::CreateGUIControls()
|
void LogConfigWindow::CreateGUIControls()
|
||||||
{
|
{
|
||||||
// Verbosity
|
// Verbosity
|
||||||
|
@ -68,23 +61,26 @@ void LogConfigWindow::CreateGUIControls()
|
||||||
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
|
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
|
||||||
m_checks->Append(StrToWxStr(m_LogManager->GetFullName((LogTypes::LOG_TYPE)i)));
|
m_checks->Append(StrToWxStr(m_LogManager->GetFullName((LogTypes::LOG_TYPE)i)));
|
||||||
|
|
||||||
|
const int space1 = FromDIP(1);
|
||||||
|
const int space5 = FromDIP(5);
|
||||||
|
|
||||||
// Sizers
|
// Sizers
|
||||||
wxStaticBoxSizer* sbOutputs = new wxStaticBoxSizer(wxVERTICAL, this, _("Logger Outputs"));
|
wxStaticBoxSizer* sbOutputs = new wxStaticBoxSizer(wxVERTICAL, this, _("Logger Outputs"));
|
||||||
sbOutputs->Add(m_writeFileCB, 0, wxDOWN, 1);
|
sbOutputs->Add(m_writeFileCB, 0);
|
||||||
sbOutputs->Add(m_writeConsoleCB, 0, wxDOWN, 1);
|
sbOutputs->Add(m_writeConsoleCB, 0, wxTOP, space1);
|
||||||
sbOutputs->Add(m_writeWindowCB, 0);
|
sbOutputs->Add(m_writeWindowCB, 0, wxTOP, space1);
|
||||||
|
|
||||||
wxStaticBoxSizer* sbLogTypes = new wxStaticBoxSizer(wxVERTICAL, this, _("Log Types"));
|
wxStaticBoxSizer* sbLogTypes = new wxStaticBoxSizer(wxVERTICAL, this, _("Log Types"));
|
||||||
sbLogTypes->Add(m_checks, 1, wxEXPAND);
|
sbLogTypes->Add(m_checks, 1, wxEXPAND);
|
||||||
|
|
||||||
wxBoxSizer* sMain = new wxBoxSizer(wxVERTICAL);
|
wxBoxSizer* sMain = new wxBoxSizer(wxVERTICAL);
|
||||||
sMain->Add(m_verbosity, 0, wxEXPAND | wxLEFT | wxRIGHT, 5);
|
sMain->Add(m_verbosity, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
|
||||||
sMain->Add(sbOutputs, 0, wxEXPAND | wxLEFT | wxRIGHT, 5);
|
sMain->Add(sbOutputs, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
|
||||||
sMain->Add(btn_toggle_all, 0, wxEXPAND | wxLEFT | wxRIGHT, 5);
|
sMain->Add(btn_toggle_all, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
|
||||||
sMain->Add(sbLogTypes, 1, wxEXPAND | wxLEFT | wxRIGHT, 5);
|
sMain->Add(sbLogTypes, 1, wxEXPAND | wxLEFT | wxRIGHT, space5);
|
||||||
|
|
||||||
SetSizer(sMain);
|
sMain->SetMinSize(FromDIP(wxSize(100, 100)));
|
||||||
Layout();
|
SetSizerAndFit(sMain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogConfigWindow::LoadSettings()
|
void LogConfigWindow::LoadSettings()
|
||||||
|
|
|
@ -31,7 +31,6 @@ private:
|
||||||
|
|
||||||
void CreateGUIControls();
|
void CreateGUIControls();
|
||||||
void OnVerbosityChange(wxCommandEvent& event);
|
void OnVerbosityChange(wxCommandEvent& event);
|
||||||
void OnClose(wxCloseEvent& event);
|
|
||||||
void OnWriteFileChecked(wxCommandEvent& event);
|
void OnWriteFileChecked(wxCommandEvent& event);
|
||||||
void OnWriteConsoleChecked(wxCommandEvent& event);
|
void OnWriteConsoleChecked(wxCommandEvent& event);
|
||||||
void OnWriteWindowChecked(wxCommandEvent& event);
|
void OnWriteWindowChecked(wxCommandEvent& event);
|
||||||
|
|
|
@ -39,7 +39,6 @@ CLogWindow::CLogWindow(CFrame* parent, wxWindowID id, const wxPoint& pos, const
|
||||||
: wxPanel(parent, id, pos, size, style, name), x(0), y(0), winpos(0), Parent(parent),
|
: wxPanel(parent, id, pos, size, style, name), x(0), y(0), winpos(0), Parent(parent),
|
||||||
m_LogAccess(true), m_Log(nullptr), m_cmdline(nullptr), m_FontChoice(nullptr)
|
m_LogAccess(true), m_Log(nullptr), m_cmdline(nullptr), m_FontChoice(nullptr)
|
||||||
{
|
{
|
||||||
Bind(wxEVT_CLOSE_WINDOW, &CLogWindow::OnClose, this);
|
|
||||||
Bind(wxEVT_TIMER, &CLogWindow::OnLogTimer, this);
|
Bind(wxEVT_TIMER, &CLogWindow::OnLogTimer, this);
|
||||||
|
|
||||||
m_LogManager = LogManager::GetInstance();
|
m_LogManager = LogManager::GetInstance();
|
||||||
|
@ -94,6 +93,7 @@ void CLogWindow::CreateGUIControls()
|
||||||
|
|
||||||
m_LogManager->SetLogLevel((LogTypes::LOG_TYPE)i, (LogTypes::LOG_LEVELS)(verbosity));
|
m_LogManager->SetLogLevel((LogTypes::LOG_TYPE)i, (LogTypes::LOG_LEVELS)(verbosity));
|
||||||
}
|
}
|
||||||
|
m_has_listeners = true;
|
||||||
|
|
||||||
// Font
|
// Font
|
||||||
m_FontChoice = new wxChoice(this, wxID_ANY);
|
m_FontChoice = new wxChoice(this, wxID_ANY);
|
||||||
|
@ -132,11 +132,13 @@ void CLogWindow::CreateGUIControls()
|
||||||
new wxButton(this, wxID_ANY, _("Clear"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
|
new wxButton(this, wxID_ANY, _("Clear"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
|
||||||
m_clear_log_btn->Bind(wxEVT_BUTTON, &CLogWindow::OnClear, this);
|
m_clear_log_btn->Bind(wxEVT_BUTTON, &CLogWindow::OnClear, this);
|
||||||
|
|
||||||
|
const int space3 = FromDIP(3);
|
||||||
|
|
||||||
// Sizers
|
// Sizers
|
||||||
wxBoxSizer* sTop = new wxBoxSizer(wxHORIZONTAL);
|
wxBoxSizer* sTop = new wxBoxSizer(wxHORIZONTAL);
|
||||||
sTop->Add(m_clear_log_btn);
|
sTop->Add(m_clear_log_btn, 0, wxALIGN_CENTER_VERTICAL);
|
||||||
sTop->Add(m_FontChoice, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 3);
|
sTop->Add(m_FontChoice, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, space3);
|
||||||
sTop->Add(m_WrapLine, 0, wxALIGN_CENTER_VERTICAL);
|
sTop->Add(m_WrapLine, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, space3);
|
||||||
|
|
||||||
sBottom = new wxBoxSizer(wxVERTICAL);
|
sBottom = new wxBoxSizer(wxVERTICAL);
|
||||||
PopulateBottom();
|
PopulateBottom();
|
||||||
|
@ -149,15 +151,17 @@ void CLogWindow::CreateGUIControls()
|
||||||
m_cmdline->SetFocus();
|
m_cmdline->SetFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLogWindow::OnClose(wxCloseEvent& event)
|
CLogWindow::~CLogWindow()
|
||||||
{
|
{
|
||||||
SaveSettings();
|
|
||||||
event.Skip();
|
|
||||||
RemoveAllListeners();
|
RemoveAllListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLogWindow::RemoveAllListeners()
|
void CLogWindow::RemoveAllListeners()
|
||||||
{
|
{
|
||||||
|
if (!m_has_listeners)
|
||||||
|
return;
|
||||||
|
m_has_listeners = false;
|
||||||
|
|
||||||
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i)
|
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i)
|
||||||
{
|
{
|
||||||
m_LogManager->RemoveListener(static_cast<LogTypes::LOG_TYPE>(i),
|
m_LogManager->RemoveListener(static_cast<LogTypes::LOG_TYPE>(i),
|
||||||
|
|
|
@ -28,7 +28,11 @@ public:
|
||||||
CLogWindow(CFrame* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
|
CLogWindow(CFrame* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
|
||||||
const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL,
|
const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL,
|
||||||
const wxString& name = _("Log"));
|
const wxString& name = _("Log"));
|
||||||
|
~CLogWindow() override;
|
||||||
|
|
||||||
|
// Listeners must be removed explicitly before the window is closed to prevent crashes on OS X
|
||||||
|
// when closing via the Dock. (The Core is probably being shutdown before the window)
|
||||||
|
void RemoveAllListeners();
|
||||||
void SaveSettings();
|
void SaveSettings();
|
||||||
void Log(LogTypes::LOG_LEVELS, const char* text) override;
|
void Log(LogTypes::LOG_LEVELS, const char* text) override;
|
||||||
|
|
||||||
|
@ -42,6 +46,7 @@ private:
|
||||||
LogManager* m_LogManager;
|
LogManager* m_LogManager;
|
||||||
std::queue<std::pair<u8, wxString>> msgQueue;
|
std::queue<std::pair<u8, wxString>> msgQueue;
|
||||||
bool m_writeFile, m_writeWindow, m_LogAccess;
|
bool m_writeFile, m_writeWindow, m_LogAccess;
|
||||||
|
bool m_has_listeners = false;
|
||||||
|
|
||||||
// Controls
|
// Controls
|
||||||
wxBoxSizer* sBottom;
|
wxBoxSizer* sBottom;
|
||||||
|
@ -57,11 +62,9 @@ private:
|
||||||
void CreateGUIControls();
|
void CreateGUIControls();
|
||||||
void PopulateBottom();
|
void PopulateBottom();
|
||||||
void UnPopulateBottom();
|
void UnPopulateBottom();
|
||||||
void OnClose(wxCloseEvent& event);
|
|
||||||
void OnFontChange(wxCommandEvent& event);
|
void OnFontChange(wxCommandEvent& event);
|
||||||
void OnWrapLineCheck(wxCommandEvent& event);
|
void OnWrapLineCheck(wxCommandEvent& event);
|
||||||
void OnClear(wxCommandEvent& event);
|
void OnClear(wxCommandEvent& event);
|
||||||
void OnLogTimer(wxTimerEvent& WXUNUSED(event));
|
void OnLogTimer(wxTimerEvent& WXUNUSED(event));
|
||||||
void RemoveAllListeners();
|
|
||||||
void UpdateLog();
|
void UpdateLog();
|
||||||
};
|
};
|
||||||
|
|
|
@ -66,13 +66,6 @@ void ShowErrorDialog(const wxString& error_msg)
|
||||||
wxMessageBox(error_msg, _("Error"), wxOK | wxICON_ERROR);
|
wxMessageBox(error_msg, _("Error"), wxOK | wxICON_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxBitmap LoadResourceBitmap(const std::string& name, const wxSize& padded_size)
|
|
||||||
{
|
|
||||||
wxWindow* context = wxTheApp->GetTopWindow();
|
|
||||||
return LoadScaledResourceBitmap(name, context, padded_size, wxDefaultSize,
|
|
||||||
LSI_SCALE_DOWN | LSI_ALIGN_VCENTER, *wxWHITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxBitmap CreateDisabledButtonBitmap(const wxBitmap& original)
|
wxBitmap CreateDisabledButtonBitmap(const wxBitmap& original)
|
||||||
{
|
{
|
||||||
wxImage image = original.ConvertToImage();
|
wxImage image = original.ConvertToImage();
|
||||||
|
|
|
@ -29,9 +29,6 @@ void Explore(const std::string& path);
|
||||||
// Displays a wxMessageBox geared for errors
|
// Displays a wxMessageBox geared for errors
|
||||||
void ShowErrorDialog(const wxString& error_msg);
|
void ShowErrorDialog(const wxString& error_msg);
|
||||||
|
|
||||||
// Reads a PNG from the Resources folder
|
|
||||||
wxBitmap LoadResourceBitmap(const std::string& name, const wxSize& padded_size = wxDefaultSize);
|
|
||||||
|
|
||||||
// From a wxBitmap, creates the corresponding disabled version for toolbar buttons
|
// From a wxBitmap, creates the corresponding disabled version for toolbar buttons
|
||||||
wxBitmap CreateDisabledButtonBitmap(const wxBitmap& original);
|
wxBitmap CreateDisabledButtonBitmap(const wxBitmap& original);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue