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");
|
||||
|
||||
wxBoxSizer* sMainSizer = new wxBoxSizer(wxVERTICAL);
|
||||
sMainSizer->Add(m_pEditAddress, 0, wxEXPAND | wxALL, 5);
|
||||
sMainSizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxALL, 5);
|
||||
const int space5 = FromDIP(5);
|
||||
wxBoxSizer* main_szr = new wxBoxSizer(wxVERTICAL);
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ CBreakPointView::CBreakPointView(wxWindow* parent, const wxWindowID id)
|
|||
Refresh();
|
||||
}
|
||||
|
||||
void CBreakPointView::Update()
|
||||
void CBreakPointView::Repopulate()
|
||||
{
|
||||
ClearAll();
|
||||
|
||||
|
@ -98,6 +98,6 @@ void CBreakPointView::DeleteCurrentSelection()
|
|||
u32 Address = (u32)GetItemData(item);
|
||||
PowerPC::breakpoints.Remove(Address);
|
||||
PowerPC::memchecks.Remove(Address);
|
||||
Update();
|
||||
Repopulate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@ class CBreakPointView : public wxListCtrl
|
|||
public:
|
||||
CBreakPointView(wxWindow* parent, const wxWindowID id);
|
||||
|
||||
void Update() override;
|
||||
void Repopulate();
|
||||
void DeleteCurrentSelection();
|
||||
};
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <array>
|
||||
|
||||
// clang-format off
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/aui/framemanager.h>
|
||||
|
@ -32,11 +34,15 @@ public:
|
|||
: DolphinAuiToolBar(parent, id, wxDefaultPosition, wxDefaultSize,
|
||||
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");
|
||||
m_Bitmaps[Toolbar_Add_BP] = WxUtils::LoadResourceBitmap("toolbar_add_breakpoint");
|
||||
m_Bitmaps[Toolbar_Add_MC] = WxUtils::LoadResourceBitmap("toolbar_add_memorycheck");
|
||||
static const std::array<const char* const, Num_Bitmaps> image_names{
|
||||
{"toolbar_debugger_delete", "toolbar_add_breakpoint", "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]);
|
||||
Bind(wxEVT_TOOL, &CBreakPointWindow::OnDelete, parent, ID_DELETE);
|
||||
|
@ -84,8 +90,6 @@ CBreakPointWindow::CBreakPointWindow(CCodeWindow* _pCodeWindow, wxWindow* parent
|
|||
const wxSize& size, long style)
|
||||
: wxPanel(parent, id, position, size, style, title), m_pCodeWindow(_pCodeWindow)
|
||||
{
|
||||
Bind(wxEVT_CLOSE_WINDOW, &CBreakPointWindow::OnClose, this);
|
||||
|
||||
m_mgr.SetManagedWindow(this);
|
||||
m_mgr.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_LIVE_RESIZE);
|
||||
|
||||
|
@ -108,15 +112,9 @@ CBreakPointWindow::~CBreakPointWindow()
|
|||
m_mgr.UnInit();
|
||||
}
|
||||
|
||||
void CBreakPointWindow::OnClose(wxCloseEvent& event)
|
||||
{
|
||||
SaveAll();
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void CBreakPointWindow::NotifyUpdate()
|
||||
{
|
||||
m_BreakPointListView->Update();
|
||||
m_BreakPointListView->Repopulate();
|
||||
}
|
||||
|
||||
void CBreakPointWindow::OnDelete(wxCommandEvent& WXUNUSED(event))
|
||||
|
|
|
@ -21,21 +21,21 @@ public:
|
|||
~CBreakPointWindow();
|
||||
|
||||
void NotifyUpdate();
|
||||
void SaveAll();
|
||||
void LoadAll();
|
||||
|
||||
private:
|
||||
friend class CBreakPointBar;
|
||||
|
||||
void OnDelete(wxCommandEvent& WXUNUSED(event));
|
||||
void OnClear(wxCommandEvent& WXUNUSED(event));
|
||||
void OnAddBreakPoint(wxCommandEvent& WXUNUSED(event));
|
||||
void OnAddMemoryCheck(wxCommandEvent& WXUNUSED(event));
|
||||
void Event_SaveAll(wxCommandEvent& WXUNUSED(event));
|
||||
void SaveAll();
|
||||
void Event_LoadAll(wxCommandEvent& WXUNUSED(event));
|
||||
void LoadAll();
|
||||
void OnSelectBP(wxListEvent& event);
|
||||
|
||||
private:
|
||||
wxAuiManager m_mgr;
|
||||
CBreakPointView* m_BreakPointListView;
|
||||
CCodeWindow* m_pCodeWindow;
|
||||
|
||||
void OnClose(wxCloseEvent& event);
|
||||
void OnSelectBP(wxListEvent& event);
|
||||
};
|
||||
|
|
|
@ -53,9 +53,9 @@ CCodeView::CCodeView(DebugInterface* debuginterface, SymbolDB* symboldb, wxWindo
|
|||
wxWindowID Id)
|
||||
: wxControl(parent, Id), m_debugger(debuginterface), m_symbol_db(symboldb), m_plain(false),
|
||||
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_MOUSEWHEEL, &CCodeView::OnScrollWheel, 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_MENU, &CCodeView::OnPopupMenu, 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)
|
||||
|
@ -80,7 +87,7 @@ void CCodeView::OnMouseDown(wxMouseEvent& event)
|
|||
int x = event.m_x;
|
||||
int y = event.m_y;
|
||||
|
||||
if (x > 16)
|
||||
if (x > m_left_col_width)
|
||||
{
|
||||
m_oldSelection = m_selection;
|
||||
m_selection = YToAddress(y);
|
||||
|
@ -131,7 +138,7 @@ void CCodeView::OnMouseMove(wxMouseEvent& event)
|
|||
{
|
||||
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)
|
||||
{
|
||||
|
@ -162,7 +169,7 @@ void CCodeView::RaiseEvent()
|
|||
|
||||
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_selecting = false;
|
||||
|
@ -222,10 +229,6 @@ void CCodeView::InsertBlrNop(int Blr)
|
|||
|
||||
void CCodeView::OnPopupMenu(wxCommandEvent& event)
|
||||
{
|
||||
#if wxUSE_CLIPBOARD
|
||||
wxTheClipboard->Open();
|
||||
#endif
|
||||
|
||||
switch (event.GetId())
|
||||
{
|
||||
case IDM_GOTOINMEMVIEW:
|
||||
|
@ -234,11 +237,15 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event)
|
|||
|
||||
#if wxUSE_CLIPBOARD
|
||||
case IDM_COPYADDRESS:
|
||||
{
|
||||
wxClipboardLocker locker;
|
||||
wxTheClipboard->SetData(new wxTextDataObject(wxString::Format("%08x", m_selection)));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case IDM_COPYCODE:
|
||||
{
|
||||
wxClipboardLocker locker;
|
||||
std::string disasm = m_debugger->Disassemble(m_selection);
|
||||
wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(disasm)));
|
||||
}
|
||||
|
@ -246,8 +253,9 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event)
|
|||
|
||||
case IDM_COPYHEX:
|
||||
{
|
||||
std::string temp = StringFromFormat("%08x", m_debugger->ReadInstruction(m_selection));
|
||||
wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(temp)));
|
||||
wxClipboardLocker locker;
|
||||
wxTheClipboard->SetData(
|
||||
new wxTextDataObject(wxString::Format("%08x", m_debugger->ReadInstruction(m_selection))));
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -266,6 +274,7 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event)
|
|||
std::string disasm = m_debugger->Disassemble(addr);
|
||||
text += StringFromFormat("%08x: ", addr) + disasm + "\r\n";
|
||||
}
|
||||
wxClipboardLocker locker;
|
||||
wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(text)));
|
||||
}
|
||||
}
|
||||
|
@ -283,6 +292,7 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event)
|
|||
InsertBlrNop(0);
|
||||
Refresh();
|
||||
break;
|
||||
|
||||
case IDM_INSERTNOP:
|
||||
InsertBlrNop(1);
|
||||
Refresh();
|
||||
|
@ -332,12 +342,11 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event)
|
|||
|
||||
case IDM_PATCHALERT:
|
||||
break;
|
||||
}
|
||||
|
||||
#if wxUSE_CLIPBOARD
|
||||
wxTheClipboard->Close();
|
||||
#endif
|
||||
event.Skip();
|
||||
default:
|
||||
event.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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_INSERTBLR, _("Insert &blr"))->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);
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void CCodeView::OnErase(wxEraseEvent& event)
|
||||
{
|
||||
}
|
||||
|
||||
void CCodeView::OnPaint(wxPaintEvent& event)
|
||||
{
|
||||
// -------------------------
|
||||
// General settings
|
||||
// -------------------------
|
||||
std::unique_ptr<wxGraphicsContext> ctx(wxGraphicsContext::Create(wxPaintDC(this)));
|
||||
wxPaintDC paint_dc(this);
|
||||
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);
|
||||
|
||||
wxDouble w, h;
|
||||
ctx->GetTextExtent("0WJyq", &w, &h);
|
||||
|
||||
if (h > m_rowHeight)
|
||||
m_rowHeight = h;
|
||||
|
||||
ctx->GetTextExtent("W", &w, &h);
|
||||
int charWidth = w;
|
||||
|
||||
struct branch
|
||||
struct Branch
|
||||
{
|
||||
int src, dst, srcAddr;
|
||||
};
|
||||
|
||||
branch branches[256];
|
||||
int numBranches = 0;
|
||||
// TODO: Add any drawing code here...
|
||||
int width = rc.width;
|
||||
int numRows = ((rc.height / m_rowHeight) / 2) + 2;
|
||||
Branch branches[256];
|
||||
int num_branches = 0;
|
||||
const int num_rows = ((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
|
||||
// -------------------------
|
||||
|
||||
const wxColour bgColor = *wxWHITE;
|
||||
wxPen nullPen(bgColor);
|
||||
wxPen currentPen(*wxBLACK_PEN);
|
||||
wxPen selPen(*wxGREY_PEN);
|
||||
nullPen.SetStyle(wxPENSTYLE_TRANSPARENT);
|
||||
currentPen.SetStyle(wxPENSTYLE_SOLID);
|
||||
wxBrush currentBrush(*wxLIGHT_GREY_BRUSH);
|
||||
wxBrush pcBrush(*wxGREEN_BRUSH);
|
||||
wxBrush bpBrush(*wxRED_BRUSH);
|
||||
wxColour branch_color = wxTheColourDatabase->Find("PURPLE");
|
||||
wxColour blr_color = wxTheColourDatabase->Find("DARK GREEN");
|
||||
wxColour instr_color = wxTheColourDatabase->Find("VIOLET");
|
||||
wxGraphicsPen null_pen = ctx->CreatePen(*wxTRANSPARENT_PEN);
|
||||
wxGraphicsPen focus_pen = ctx->CreatePen(wxPen(*wxBLACK, pen_width));
|
||||
wxGraphicsPen selection_pen = ctx->CreatePen(wxPen("GREY", pen_width));
|
||||
wxGraphicsBrush pc_brush = ctx->CreateBrush(*wxGREEN_BRUSH);
|
||||
wxGraphicsBrush bp_brush = ctx->CreateBrush(*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
|
||||
// -----------------------------
|
||||
for (int i = -numRows; i <= numRows; i++)
|
||||
for (int i = -num_rows; i <= num_rows; i++)
|
||||
{
|
||||
unsigned int address = m_curAddress + (i * m_align);
|
||||
|
||||
int rowY1 = (rc.height / 2) + (m_rowHeight * i) - (m_rowHeight / 2);
|
||||
int rowY2 = (rc.height / 2) + (m_rowHeight * i) + (m_rowHeight / 2);
|
||||
int row_y = (rc.height / 2) + (m_rowHeight * i) - (m_rowHeight / 2);
|
||||
|
||||
wxString temp = wxString::Format("%08x", address);
|
||||
u32 color = m_debugger->GetColor(address);
|
||||
wxBrush rowBrush(wxColour(color >> 16, color >> 8, color));
|
||||
ctx->SetBrush(nullBrush);
|
||||
ctx->SetPen(nullPen);
|
||||
ctx->DrawRectangle(0, rowY1, 16, rowY2 - rowY1 + 2);
|
||||
|
||||
if (m_selecting && (address == m_selection))
|
||||
ctx->SetPen(selPen);
|
||||
else
|
||||
ctx->SetPen(i == 0 ? currentPen : nullPen);
|
||||
wxBrush row_brush(wxColour(color >> 16, color >> 8, color));
|
||||
ctx->SetBrush(back_brush);
|
||||
ctx->SetPen(null_pen);
|
||||
ctx->DrawRectangle(0, row_y, m_left_col_width, m_rowHeight);
|
||||
|
||||
if (address == m_debugger->GetPC())
|
||||
ctx->SetBrush(pcBrush);
|
||||
ctx->SetBrush(pc_brush);
|
||||
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)
|
||||
{
|
||||
// the address text is dark red
|
||||
ctx->SetFont(DebuggerFont, wxColour("#600000"));
|
||||
ctx->DrawText(temp, 17, rowY1);
|
||||
ctx->SetFont(DebuggerFont, wxColour(0x60, 0x00, 0x00));
|
||||
ctx->DrawText(temp, text_col, row_y);
|
||||
ctx->SetFont(DebuggerFont, *wxBLACK);
|
||||
}
|
||||
|
||||
|
@ -488,31 +505,32 @@ void CCodeView::OnPaint(wxPaintEvent& event)
|
|||
{
|
||||
u32 offs = std::stoul(hex_str, nullptr, 16);
|
||||
|
||||
branches[numBranches].src = rowY1 + (m_rowHeight / 2);
|
||||
branches[numBranches].srcAddr = (address / m_align);
|
||||
branches[numBranches++].dst =
|
||||
(int)(rowY1 + ((s64)(u32)offs - (s64)(u32)address) * m_rowHeight / m_align +
|
||||
branches[num_branches].src = row_y + (m_rowHeight / 2);
|
||||
branches[num_branches].srcAddr = (address / m_align);
|
||||
branches[num_branches++].dst =
|
||||
(int)(row_y + ((s64)(u32)offs - (s64)(u32)address) * m_rowHeight / m_align +
|
||||
m_rowHeight / 2);
|
||||
desc = StringFromFormat("-->%s", m_debugger->GetDescription(offs).c_str());
|
||||
|
||||
// the -> arrow illustrations are purple
|
||||
ctx->SetFont(DebuggerFont, wxTheColourDatabase->Find("PURPLE"));
|
||||
ctx->SetFont(DebuggerFont, branch_color);
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
if (opcode == "blr")
|
||||
ctx->SetFont(DebuggerFont, wxTheColourDatabase->Find("DARK GREEN"));
|
||||
ctx->SetFont(DebuggerFont, blr_color);
|
||||
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())
|
||||
{
|
||||
|
@ -527,15 +545,16 @@ void CCodeView::OnPaint(wxPaintEvent& event)
|
|||
// UnDecorateSymbolName(desc,temp,255,UNDNAME_COMPLETE);
|
||||
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
|
||||
if (m_debugger->IsBreakpoint(address))
|
||||
{
|
||||
ctx->SetBrush(bpBrush);
|
||||
ctx->DrawRectangle(2, rowY1 + 1, 11, 11);
|
||||
ctx->SetPen(null_pen);
|
||||
ctx->SetBrush(bp_brush);
|
||||
ctx->DrawEllipse(bp_offset_x, row_y + bp_offset_y, bp_size.GetWidth(), bp_size.GetHeight());
|
||||
}
|
||||
}
|
||||
} // end of for
|
||||
|
@ -544,22 +563,24 @@ void CCodeView::OnPaint(wxPaintEvent& event)
|
|||
// -------------------------
|
||||
// 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;
|
||||
MoveTo(x - 2, branches[i].src);
|
||||
int x = text_col + 52 * char_width + (branches[i].srcAddr % 9) * 8;
|
||||
branch_path.MoveToPoint(x - 2 * scale, branches[i].src);
|
||||
|
||||
if (branches[i].dst < rc.height + 400 && branches[i].dst > -400)
|
||||
{
|
||||
LineTo(ctx, x + 2, branches[i].src);
|
||||
LineTo(ctx, x + 2, branches[i].dst);
|
||||
LineTo(ctx, x - 4, branches[i].dst);
|
||||
branch_path.AddLineToPoint(x + 2 * scale, branches[i].src);
|
||||
branch_path.AddLineToPoint(x + 2 * scale, branches[i].dst);
|
||||
branch_path.AddLineToPoint(x - 4 * scale, branches[i].dst);
|
||||
|
||||
MoveTo(x, branches[i].dst - 4);
|
||||
LineTo(ctx, x - 4, branches[i].dst);
|
||||
LineTo(ctx, x + 1, branches[i].dst + 5);
|
||||
branch_path.MoveToPoint(x, branches[i].dst - 4 * scale);
|
||||
branch_path.AddLineToPoint(x - 4 * scale, branches[i].dst);
|
||||
branch_path.AddLineToPoint(x + 1 * scale, branches[i].dst + 5 * scale);
|
||||
}
|
||||
// else
|
||||
//{
|
||||
|
@ -575,18 +596,19 @@ void CCodeView::OnPaint(wxPaintEvent& event)
|
|||
// LineTo(ctx, x, branches[i].dst+4);
|
||||
// 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)
|
||||
{
|
||||
Refresh();
|
||||
|
|
|
@ -40,7 +40,6 @@ public:
|
|||
void SetPlain() { m_plain = true; }
|
||||
private:
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
void OnErase(wxEraseEvent& event);
|
||||
void OnScrollWheel(wxMouseEvent& event);
|
||||
void OnMouseDown(wxMouseEvent& event);
|
||||
void OnMouseMove(wxMouseEvent& event);
|
||||
|
@ -55,14 +54,6 @@ private:
|
|||
u32 AddrToBranch(u32 addr);
|
||||
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
|
||||
{
|
||||
u32 address;
|
||||
|
@ -70,6 +61,8 @@ private:
|
|||
};
|
||||
std::vector<BlrStruct> m_blrList;
|
||||
|
||||
static constexpr int LEFT_COL_WIDTH = 16;
|
||||
|
||||
DebugInterface* m_debugger;
|
||||
SymbolDB* m_symbol_db;
|
||||
|
||||
|
@ -78,10 +71,9 @@ private:
|
|||
int m_curAddress;
|
||||
int m_align;
|
||||
int m_rowHeight;
|
||||
int m_left_col_width;
|
||||
|
||||
u32 m_selection;
|
||||
u32 m_oldSelection;
|
||||
bool m_selecting;
|
||||
|
||||
int m_lx, m_ly;
|
||||
};
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "DolphinWX/Debugger/CodeWindow.h"
|
||||
#include "DolphinWX/Debugger/DebuggerUIUtil.h"
|
||||
#include "DolphinWX/Debugger/JitWindow.h"
|
||||
#include "DolphinWX/Debugger/MemoryWindow.h"
|
||||
#include "DolphinWX/Debugger/RegisterWindow.h"
|
||||
#include "DolphinWX/Debugger/WatchWindow.h"
|
||||
#include "DolphinWX/AuiToolBar.h"
|
||||
|
@ -54,9 +55,8 @@
|
|||
CCodeWindow::CCodeWindow(const SConfig& _LocalCoreStartupParameter, CFrame* parent, wxWindowID id,
|
||||
const wxPoint& position, const wxSize& size, long style,
|
||||
const wxString& name)
|
||||
: wxPanel(parent, id, position, size, style, name), Parent(parent), m_RegisterWindow(nullptr),
|
||||
m_WatchWindow(nullptr), m_BreakpointWindow(nullptr), m_MemoryWindow(nullptr),
|
||||
m_JitWindow(nullptr), m_SoundWindow(nullptr), m_VideoWindow(nullptr), codeview(nullptr)
|
||||
: wxPanel(parent, id, position, size, style, name), m_sibling_panels(), Parent(parent),
|
||||
codeview(nullptr)
|
||||
{
|
||||
InitBitmaps();
|
||||
|
||||
|
@ -88,21 +88,31 @@ CCodeWindow::CCodeWindow(const SConfig& _LocalCoreStartupParameter, CFrame* pare
|
|||
|
||||
m_aui_manager.SetManagedWindow(this);
|
||||
m_aui_manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_LIVE_RESIZE);
|
||||
m_aui_manager.AddPane(m_aui_toolbar,
|
||||
wxAuiPaneInfo().MinSize(150, -1).ToolbarPane().Top().Floatable(false));
|
||||
m_aui_manager.AddPane(
|
||||
callstack,
|
||||
wxAuiPaneInfo().MinSize(150, 100).Left().CloseButton(false).Floatable(false).Caption(
|
||||
_("Callstack")));
|
||||
m_aui_manager.AddPane(
|
||||
symbols, wxAuiPaneInfo().MinSize(150, 100).Left().CloseButton(false).Floatable(false).Caption(
|
||||
_("Symbols")));
|
||||
m_aui_manager.AddPane(
|
||||
calls, wxAuiPaneInfo().MinSize(150, 100).Left().CloseButton(false).Floatable(false).Caption(
|
||||
_("Function calls")));
|
||||
m_aui_manager.AddPane(
|
||||
callers, wxAuiPaneInfo().MinSize(150, 100).Left().CloseButton(false).Floatable(false).Caption(
|
||||
_("Function callers")));
|
||||
m_aui_manager.AddPane(m_aui_toolbar, wxAuiPaneInfo().ToolbarPane().Top().Floatable(false));
|
||||
m_aui_manager.AddPane(callstack, wxAuiPaneInfo()
|
||||
.MinSize(FromDIP(wxSize(150, 100)))
|
||||
.Left()
|
||||
.CloseButton(false)
|
||||
.Floatable(false)
|
||||
.Caption(_("Callstack")));
|
||||
m_aui_manager.AddPane(symbols, wxAuiPaneInfo()
|
||||
.MinSize(FromDIP(wxSize(150, 100)))
|
||||
.Left()
|
||||
.CloseButton(false)
|
||||
.Floatable(false)
|
||||
.Caption(_("Symbols")));
|
||||
m_aui_manager.AddPane(calls, wxAuiPaneInfo()
|
||||
.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.Update();
|
||||
|
||||
|
@ -144,30 +154,30 @@ void CCodeWindow::OnHostMessage(wxCommandEvent& event)
|
|||
{
|
||||
case IDM_NOTIFY_MAP_LOADED:
|
||||
NotifyMapLoaded();
|
||||
if (m_BreakpointWindow)
|
||||
m_BreakpointWindow->NotifyUpdate();
|
||||
if (HasPanel<CBreakPointWindow>())
|
||||
GetPanel<CBreakPointWindow>()->NotifyUpdate();
|
||||
break;
|
||||
|
||||
case IDM_UPDATE_DISASM_DIALOG:
|
||||
Update();
|
||||
if (CPU::IsStepping())
|
||||
Parent->UpdateGUI();
|
||||
if (m_RegisterWindow)
|
||||
m_RegisterWindow->NotifyUpdate();
|
||||
if (m_WatchWindow)
|
||||
m_WatchWindow->NotifyUpdate();
|
||||
Repopulate();
|
||||
if (HasPanel<CRegisterWindow>())
|
||||
GetPanel<CRegisterWindow>()->NotifyUpdate();
|
||||
if (HasPanel<CWatchWindow>())
|
||||
GetPanel<CWatchWindow>()->NotifyUpdate();
|
||||
if (HasPanel<CMemoryWindow>())
|
||||
GetPanel<CMemoryWindow>()->Refresh();
|
||||
break;
|
||||
|
||||
case IDM_UPDATE_BREAKPOINTS:
|
||||
if (m_BreakpointWindow)
|
||||
m_BreakpointWindow->NotifyUpdate();
|
||||
Repopulate();
|
||||
if (HasPanel<CBreakPointWindow>())
|
||||
GetPanel<CBreakPointWindow>()->NotifyUpdate();
|
||||
if (HasPanel<CMemoryWindow>())
|
||||
GetPanel<CMemoryWindow>()->Refresh();
|
||||
break;
|
||||
|
||||
case IDM_UPDATE_JIT_PANE:
|
||||
// Check if the JIT pane is in the AUI notebook. If not, add it and switch to it.
|
||||
if (!m_JitWindow)
|
||||
ToggleJitWindow(true);
|
||||
m_JitWindow->ViewAddr(codeview->GetSelection());
|
||||
RequirePanel<CJitWindow>()->ViewAddr(codeview->GetSelection());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -195,12 +205,12 @@ void CCodeWindow::OnCodeStep(wxCommandEvent& event)
|
|||
|
||||
case IDM_SKIP:
|
||||
PC += 4;
|
||||
Update();
|
||||
Repopulate();
|
||||
break;
|
||||
|
||||
case IDM_SETPC:
|
||||
PC = codeview->GetSelection();
|
||||
Update();
|
||||
Repopulate();
|
||||
break;
|
||||
|
||||
case IDM_GOTOPC:
|
||||
|
@ -373,8 +383,12 @@ void CCodeWindow::StepOut()
|
|||
PowerPC::SetMode(old_mode);
|
||||
CPU::PauseAndLock(false, false);
|
||||
|
||||
Host_UpdateDisasmDialog();
|
||||
UpdateButtonStates();
|
||||
JumpToAddress(PC);
|
||||
{
|
||||
wxCommandEvent ev(wxEVT_HOST_COMMAND, IDM_UPDATE_DISASM_DIALOG);
|
||||
GetEventHandler()->ProcessEvent(ev);
|
||||
}
|
||||
|
||||
// Update all toolbars in the aui manager
|
||||
Parent->UpdateGUI();
|
||||
}
|
||||
|
@ -386,7 +400,7 @@ void CCodeWindow::ToggleBreakpoint()
|
|||
{
|
||||
if (codeview)
|
||||
codeview->ToggleBreakpoint(codeview->GetSelection());
|
||||
Update();
|
||||
Repopulate();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -695,7 +709,7 @@ void CCodeWindow::PopulateToolbar(wxToolBar* toolBar)
|
|||
}
|
||||
|
||||
// Update GUI
|
||||
void CCodeWindow::Update()
|
||||
void CCodeWindow::Repopulate()
|
||||
{
|
||||
if (!codeview)
|
||||
return;
|
||||
|
@ -714,41 +728,28 @@ void CCodeWindow::UpdateButtonStates()
|
|||
bool Initialized = (Core::GetState() != Core::CORE_UNINITIALIZED);
|
||||
bool Pause = (Core::GetState() == Core::CORE_PAUSE);
|
||||
bool Stepping = CPU::IsStepping();
|
||||
bool can_step = Initialized && Stepping;
|
||||
wxToolBar* ToolBar = GetToolBar();
|
||||
|
||||
// Toolbar
|
||||
if (!ToolBar)
|
||||
return;
|
||||
|
||||
if (!Initialized)
|
||||
{
|
||||
ToolBar->EnableTool(IDM_STEPOVER, false);
|
||||
ToolBar->EnableTool(IDM_STEPOUT, false);
|
||||
ToolBar->EnableTool(IDM_SKIP, false);
|
||||
}
|
||||
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->EnableTool(IDM_STEP, can_step);
|
||||
ToolBar->EnableTool(IDM_STEPOVER, can_step);
|
||||
ToolBar->EnableTool(IDM_STEPOUT, can_step);
|
||||
ToolBar->EnableTool(IDM_SKIP, can_step);
|
||||
ToolBar->EnableTool(IDM_SETPC, Pause);
|
||||
ToolBar->Realize();
|
||||
|
||||
// Menu bar
|
||||
// ------------------
|
||||
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_OFF, Pause);
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
#include <wx/aui/framemanager.h>
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/panel.h>
|
||||
|
@ -12,16 +14,16 @@
|
|||
#include "Common/Event.h"
|
||||
#include "DolphinWX/Globals.h"
|
||||
|
||||
class CCodeView;
|
||||
class CFrame;
|
||||
struct SConfig;
|
||||
class CBreakPointWindow;
|
||||
class CRegisterWindow;
|
||||
class CWatchWindow;
|
||||
class CBreakPointWindow;
|
||||
class CMemoryWindow;
|
||||
class CJitWindow;
|
||||
class CCodeView;
|
||||
class DSPDebuggerLLE;
|
||||
class GFXDebuggerPanel;
|
||||
struct SConfig;
|
||||
|
||||
class DolphinAuiToolBar;
|
||||
class wxListBox;
|
||||
|
@ -29,6 +31,48 @@ class wxMenu;
|
|||
class wxMenuBar;
|
||||
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
|
||||
{
|
||||
public:
|
||||
|
@ -41,10 +85,8 @@ public:
|
|||
void Save();
|
||||
|
||||
// Parent interaction
|
||||
CFrame* Parent;
|
||||
wxMenuBar* GetMenuBar();
|
||||
wxToolBar* GetToolBar();
|
||||
wxBitmap m_Bitmaps[Toolbar_Debug_Bitmap_Max];
|
||||
|
||||
bool UseInterpreter();
|
||||
bool BootToPause();
|
||||
|
@ -53,7 +95,7 @@ public:
|
|||
bool JITNoBlockLinking();
|
||||
bool JumpToAddress(u32 address);
|
||||
|
||||
void Update() override;
|
||||
void Repopulate();
|
||||
void NotifyMapLoaded();
|
||||
void CreateMenu(const SConfig& _LocalCoreStartupParameter, wxMenuBar* pMenuBar);
|
||||
void CreateMenuOptions(wxMenu* pMenu);
|
||||
|
@ -63,29 +105,35 @@ public:
|
|||
void OpenPages();
|
||||
|
||||
// Menu bar
|
||||
void ToggleCodeWindow(bool bShow);
|
||||
void ToggleRegisterWindow(bool bShow);
|
||||
void ToggleWatchWindow(bool bShow);
|
||||
void ToggleBreakPointWindow(bool bShow);
|
||||
void ToggleMemoryWindow(bool bShow);
|
||||
void ToggleJitWindow(bool bShow);
|
||||
void ToggleSoundWindow(bool bShow);
|
||||
void ToggleVideoWindow(bool bShow);
|
||||
// FIXME: This belongs in a separate class.
|
||||
void TogglePanel(int id, bool show);
|
||||
wxPanel* GetUntypedPanel(int id) const;
|
||||
bool HasUntypedPanel(int id) const { return GetUntypedPanel(id) != nullptr; }
|
||||
template <class T>
|
||||
T* GetPanel() const
|
||||
{
|
||||
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
|
||||
CRegisterWindow* m_RegisterWindow;
|
||||
CWatchWindow* m_WatchWindow;
|
||||
CBreakPointWindow* m_BreakpointWindow;
|
||||
CMemoryWindow* m_MemoryWindow;
|
||||
CJitWindow* m_JitWindow;
|
||||
DSPDebuggerLLE* m_SoundWindow;
|
||||
GFXDebuggerPanel* m_VideoWindow;
|
||||
TogglePanel(Details::DebugPanelToID<T>::ID, true);
|
||||
return GetPanel<T>();
|
||||
}
|
||||
|
||||
// Settings
|
||||
bool bAutomaticStart;
|
||||
bool bBootToPause;
|
||||
bool bShowOnStart[IDM_VIDEO_WINDOW - IDM_LOG_WINDOW + 1];
|
||||
int iNbAffiliation[IDM_CODE_WINDOW - IDM_LOG_WINDOW + 1];
|
||||
bool bShowOnStart[IDM_DEBUG_WINDOW_LIST_END - IDM_DEBUG_WINDOW_LIST_START];
|
||||
int iNbAffiliation[IDM_DEBUG_WINDOW_LIST_END - IDM_DEBUG_WINDOW_LIST_START];
|
||||
|
||||
private:
|
||||
void OnCPUMode(wxCommandEvent& event);
|
||||
|
@ -99,7 +147,6 @@ private:
|
|||
void OnProfilerMenu(wxCommandEvent& event);
|
||||
|
||||
void OnSymbolListChange(wxCommandEvent& event);
|
||||
void OnSymbolListContextMenu(wxContextMenuEvent& event);
|
||||
void OnCallstackListChange(wxCommandEvent& event);
|
||||
void OnCallersListChange(wxCommandEvent& event);
|
||||
void OnCallsListChange(wxCommandEvent& event);
|
||||
|
@ -116,7 +163,15 @@ private:
|
|||
void UpdateCallstack();
|
||||
|
||||
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;
|
||||
wxListBox* callstack;
|
||||
wxListBox* symbols;
|
||||
|
|
|
@ -453,7 +453,7 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
|
|||
break;
|
||||
case IDM_PATCH_HLE_FUNCTIONS:
|
||||
HLE::PatchFunctions();
|
||||
Update();
|
||||
Repopulate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -464,7 +464,6 @@ void CCodeWindow::NotifyMapLoaded()
|
|||
return;
|
||||
|
||||
g_symbolDB.FillInCallers();
|
||||
// symbols->Show(false); // hide it for faster filling
|
||||
symbols->Freeze(); // HyperIris: wx style fast filling
|
||||
symbols->Clear();
|
||||
for (const auto& symbol : g_symbolDB.Symbols())
|
||||
|
@ -473,8 +472,7 @@ void CCodeWindow::NotifyMapLoaded()
|
|||
symbols->SetClientData(idx, (void*)&symbol.second);
|
||||
}
|
||||
symbols->Thaw();
|
||||
// symbols->Show(true);
|
||||
Update();
|
||||
Repopulate();
|
||||
}
|
||||
|
||||
void CCodeWindow::OnSymbolListChange(wxCommandEvent& event)
|
||||
|
@ -487,8 +485,9 @@ void CCodeWindow::OnSymbolListChange(wxCommandEvent& event)
|
|||
{
|
||||
if (pSymbol->type == Symbol::Type::Data)
|
||||
{
|
||||
if (m_MemoryWindow) // && m_MemoryWindow->IsVisible())
|
||||
m_MemoryWindow->JumpToAddress(pSymbol->address);
|
||||
CMemoryWindow* memory = GetPanel<CMemoryWindow>();
|
||||
if (memory)
|
||||
memory->JumpToAddress(pSymbol->address);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -498,10 +497,6 @@ void CCodeWindow::OnSymbolListChange(wxCommandEvent& event)
|
|||
}
|
||||
}
|
||||
|
||||
void CCodeWindow::OnSymbolListContextMenu(wxContextMenuEvent& event)
|
||||
{
|
||||
}
|
||||
|
||||
// Change the global DebuggerFont
|
||||
void CCodeWindow::OnChangeFont(wxCommandEvent& event)
|
||||
{
|
||||
|
@ -511,157 +506,104 @@ void CCodeWindow::OnChangeFont(wxCommandEvent& event)
|
|||
wxFontDialog dialog(this, data);
|
||||
if (dialog.ShowModal() == wxID_OK)
|
||||
DebuggerFont = dialog.GetFontData().GetChosenFont();
|
||||
|
||||
// TODO: Send event to all panels that tells them to reload the font when it changes.
|
||||
}
|
||||
|
||||
// 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()
|
||||
{
|
||||
ToggleCodeWindow(true);
|
||||
if (bShowOnStart[0])
|
||||
// This is forced, and should always be placed as the first tab in the notebook.
|
||||
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);
|
||||
if (bShowOnStart[IDM_LOG_CONFIG_WINDOW - IDM_LOG_WINDOW])
|
||||
if (bShowOnStart[IDM_LOG_CONFIG_WINDOW - IDM_DEBUG_WINDOW_LIST_START])
|
||||
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)
|
||||
{
|
||||
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)
|
||||
// Iterate normal panels that don't have weird rules.
|
||||
for (int i = IDM_REGISTER_WINDOW; i < IDM_CODE_WINDOW; ++i)
|
||||
{
|
||||
if (!m_RegisterWindow)
|
||||
m_RegisterWindow = new CRegisterWindow(Parent, IDM_REGISTER_WINDOW);
|
||||
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;
|
||||
if (bShowOnStart[i - IDM_DEBUG_WINDOW_LIST_START])
|
||||
TogglePanel(i, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,9 +32,8 @@ static DSPDebuggerLLE* m_DebuggerFrame = nullptr;
|
|||
|
||||
DSPDebuggerLLE::DSPDebuggerLLE(wxWindow* parent, wxWindowID id)
|
||||
: 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);
|
||||
|
||||
m_DebuggerFrame = this;
|
||||
|
@ -46,11 +45,12 @@ DSPDebuggerLLE::DSPDebuggerLLE(wxWindow* parent, wxWindowID id)
|
|||
m_Toolbar =
|
||||
new DolphinAuiToolBar(this, ID_TOOLBAR, wxDefaultPosition, wxDefaultSize, wxAUI_TB_HORZ_TEXT);
|
||||
m_Toolbar->AddTool(ID_RUNTOOL, _("Pause"),
|
||||
wxArtProvider::GetBitmap(wxART_TICK_MARK, wxART_OTHER, wxSize(10, 10)));
|
||||
wxArtProvider::GetBitmap(wxART_TICK_MARK, wxART_OTHER, m_toolbar_item_size));
|
||||
m_Toolbar->AddTool(ID_STEPTOOL, _("Step"),
|
||||
wxArtProvider::GetBitmap(wxART_GO_DOWN, wxART_OTHER, wxSize(10, 10)));
|
||||
m_Toolbar->AddTool(ID_SHOWPCTOOL, _("Show PC"),
|
||||
wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_OTHER, wxSize(10, 10)));
|
||||
wxArtProvider::GetBitmap(wxART_GO_DOWN, wxART_OTHER, m_toolbar_item_size));
|
||||
m_Toolbar->AddTool(
|
||||
ID_SHOWPCTOOL, _("Show PC"),
|
||||
wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_OTHER, m_toolbar_item_size));
|
||||
m_Toolbar->AddSeparator();
|
||||
|
||||
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->Realize();
|
||||
|
||||
m_SymbolList =
|
||||
new wxListBox(this, wxID_ANY, wxDefaultPosition, wxSize(140, 100), 0, nullptr, wxLB_SORT);
|
||||
m_SymbolList = new wxListBox(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(100, 80)),
|
||||
0, nullptr, wxLB_SORT);
|
||||
m_SymbolList->Bind(wxEVT_LISTBOX, &DSPDebuggerLLE::OnSymbolListChange, this);
|
||||
|
||||
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);
|
||||
m_CodeView = new CCodeView(&debug_interface, &DSPSymbols::g_dsp_symbol_db, code_panel);
|
||||
m_CodeView->SetPlain();
|
||||
code_sizer->Add(m_CodeView, 1, wxALL | wxEXPAND);
|
||||
code_sizer->Add(m_CodeView, 1, wxEXPAND);
|
||||
code_panel->SetSizer(code_sizer);
|
||||
m_MainNotebook->AddPage(code_panel, _("Disassembly"), true);
|
||||
|
||||
wxPanel* mem_panel = new wxPanel(m_MainNotebook, wxID_ANY);
|
||||
wxBoxSizer* mem_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
// TODO insert memViewer class
|
||||
m_MemView = new CMemoryView(&debug_interface, mem_panel);
|
||||
mem_sizer->Add(m_MemView, 1, wxALL | wxEXPAND);
|
||||
mem_sizer->Add(m_MemView, 1, wxEXPAND);
|
||||
mem_panel->SetSizer(mem_sizer);
|
||||
m_MainNotebook->AddPage(mem_panel, _("Memory"));
|
||||
|
||||
|
@ -111,11 +110,6 @@ DSPDebuggerLLE::~DSPDebuggerLLE()
|
|||
m_DebuggerFrame = nullptr;
|
||||
}
|
||||
|
||||
void DSPDebuggerLLE::OnClose(wxCloseEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void DSPDebuggerLLE::OnChangeState(wxCommandEvent& event)
|
||||
{
|
||||
if (DSPCore_GetState() == DSPCORE_STOP)
|
||||
|
@ -134,7 +128,7 @@ void DSPDebuggerLLE::OnChangeState(wxCommandEvent& event)
|
|||
if (DSPCore_GetState() == DSPCORE_STEPPING)
|
||||
{
|
||||
DSPCore_Step();
|
||||
Update();
|
||||
Repopulate();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -149,24 +143,24 @@ void DSPDebuggerLLE::OnChangeState(wxCommandEvent& event)
|
|||
|
||||
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)
|
||||
m_DebuggerFrame->Update();
|
||||
m_DebuggerFrame->Repopulate();
|
||||
}
|
||||
|
||||
void DSPDebuggerLLE::Update()
|
||||
void DSPDebuggerLLE::Repopulate()
|
||||
{
|
||||
#if defined __WXGTK__
|
||||
if (!wxIsMainThread())
|
||||
wxMutexGuiEnter();
|
||||
#endif
|
||||
UpdateSymbolMap();
|
||||
UpdateDisAsmListView();
|
||||
UpdateRegisterFlags();
|
||||
UpdateState();
|
||||
#if defined __WXGTK__
|
||||
if (!wxIsMainThread())
|
||||
wxMutexGuiLeave();
|
||||
#endif
|
||||
}
|
||||
|
||||
void DSPDebuggerLLE::FocusOnPC()
|
||||
|
@ -180,14 +174,14 @@ void DSPDebuggerLLE::UpdateState()
|
|||
{
|
||||
m_Toolbar->SetToolLabel(ID_RUNTOOL, _("Pause"));
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Toolbar->SetToolLabel(ID_RUNTOOL, _("Run"));
|
||||
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->Realize();
|
||||
|
@ -201,7 +195,7 @@ void DSPDebuggerLLE::UpdateDisAsmListView()
|
|||
// show PC
|
||||
FocusOnPC();
|
||||
m_CachedStepCounter = g_dsp.step_counter;
|
||||
m_Regs->Update();
|
||||
m_Regs->Repopulate();
|
||||
}
|
||||
|
||||
void DSPDebuggerLLE::UpdateSymbolMap()
|
||||
|
|
|
@ -23,7 +23,7 @@ public:
|
|||
DSPDebuggerLLE(wxWindow* parent, wxWindowID id = wxID_ANY);
|
||||
virtual ~DSPDebuggerLLE();
|
||||
|
||||
void Update() override;
|
||||
void Repopulate();
|
||||
|
||||
private:
|
||||
enum
|
||||
|
@ -52,8 +52,8 @@ private:
|
|||
wxListBox* m_SymbolList;
|
||||
wxTextCtrl* m_addr_txtctrl;
|
||||
wxAuiNotebook* m_MainNotebook;
|
||||
wxSize m_toolbar_item_size;
|
||||
|
||||
void OnClose(wxCloseEvent& event);
|
||||
void OnChangeState(wxCommandEvent& event);
|
||||
// void OnRightClick(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)
|
||||
: wxGrid(parent, id, wxDefaultPosition, wxSize(130, 120))
|
||||
: wxGrid(parent, id, wxDefaultPosition, wxDLG_UNIT(parent, wxSize(100, 80)))
|
||||
{
|
||||
m_register_table = new CDSPRegTable();
|
||||
|
||||
|
@ -83,7 +83,7 @@ DSPRegisterView::DSPRegisterView(wxWindow* parent, wxWindowID id)
|
|||
AutoSizeColumns();
|
||||
}
|
||||
|
||||
void DSPRegisterView::Update()
|
||||
void DSPRegisterView::Repopulate()
|
||||
{
|
||||
m_register_table->UpdateCachedRegs();
|
||||
ForceRefresh();
|
||||
|
|
|
@ -38,7 +38,7 @@ class DSPRegisterView : public wxGrid
|
|||
{
|
||||
public:
|
||||
DSPRegisterView(wxWindow* parent, wxWindowID id = wxID_ANY);
|
||||
void Update() override;
|
||||
void Repopulate();
|
||||
|
||||
private:
|
||||
// Owned by wx. Deleted implicitly upon destruction.
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <wx/sizer.h>
|
||||
#include <wx/textctrl.h>
|
||||
|
||||
#include "Common/CommonFuncs.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/IniFile.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
|
@ -26,10 +27,6 @@ GFXDebuggerPanel::GFXDebuggerPanel(wxWindow* parent, wxWindowID id, const wxPoin
|
|||
g_pdebugger = this;
|
||||
|
||||
CreateGUIControls();
|
||||
|
||||
Bind(wxEVT_CLOSE_WINDOW, &GFXDebuggerPanel::OnClose, this);
|
||||
|
||||
LoadSettings();
|
||||
}
|
||||
|
||||
GFXDebuggerPanel::~GFXDebuggerPanel()
|
||||
|
@ -38,55 +35,6 @@ GFXDebuggerPanel::~GFXDebuggerPanel()
|
|||
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
|
||||
{
|
||||
PauseEvent event;
|
||||
|
@ -118,10 +66,9 @@ void GFXDebuggerPanel::CreateGUIControls()
|
|||
|
||||
{NEXT_ERROR, _("Error")}};
|
||||
pauseEventMap = map;
|
||||
const int numPauseEventMap = sizeof(map) / sizeof(PauseEventMap);
|
||||
static constexpr int numPauseEventMap = ArraySize(map);
|
||||
|
||||
// Basic settings
|
||||
CenterOnParent();
|
||||
const int space3 = FromDIP(3);
|
||||
|
||||
m_pButtonPause = new wxButton(this, wxID_ANY, _("Pause"), wxDefaultPosition, wxDefaultSize, 0,
|
||||
wxDefaultValidator, _("Pause"));
|
||||
|
@ -139,10 +86,11 @@ void GFXDebuggerPanel::CreateGUIControls()
|
|||
wxDefaultValidator, _("Continue"));
|
||||
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"));
|
||||
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"));
|
||||
for (int i = 0; i < numPauseEventMap; i++)
|
||||
{
|
||||
|
@ -180,7 +128,7 @@ void GFXDebuggerPanel::CreateGUIControls()
|
|||
m_pButtonClearPixelShaderCache->Bind(wxEVT_BUTTON,
|
||||
&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"));
|
||||
m_pDumpList->Insert(_("Pixel Shader"), 0);
|
||||
m_pDumpList->Append(_("Vertex Shader"));
|
||||
|
@ -196,31 +144,40 @@ void GFXDebuggerPanel::CreateGUIControls()
|
|||
|
||||
wxBoxSizer* sMain = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxStaticBoxSizer* const pFlowCtrlBox = new wxStaticBoxSizer(wxVERTICAL, this, _("Flow Control"));
|
||||
wxBoxSizer* const pPauseAtNextSzr = new wxBoxSizer(wxHORIZONTAL);
|
||||
pFlowCtrlBox->Add(m_pButtonPause);
|
||||
pPauseAtNextSzr->Add(m_pButtonPauseAtNext);
|
||||
pPauseAtNextSzr->Add(m_pCount);
|
||||
pPauseAtNextSzr->Add(m_pPauseAtList);
|
||||
pFlowCtrlBox->Add(pPauseAtNextSzr);
|
||||
pFlowCtrlBox->Add(m_pButtonPauseAtNextFrame);
|
||||
pFlowCtrlBox->Add(m_pButtonCont);
|
||||
pPauseAtNextSzr->Add(m_pCount, 0, wxALIGN_CENTER_VERTICAL);
|
||||
pPauseAtNextSzr->Add(m_pPauseAtList, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, space3);
|
||||
|
||||
wxFlexGridSizer* const flow_szr = new wxFlexGridSizer(2, space3, space3);
|
||||
flow_szr->Add(m_pButtonPause, 0, wxEXPAND);
|
||||
flow_szr->AddSpacer(1);
|
||||
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"));
|
||||
wxBoxSizer* const pDumpSzr = new wxBoxSizer(wxHORIZONTAL);
|
||||
pDumpSzr->Add(m_pButtonDump);
|
||||
pDumpSzr->Add(m_pDumpList);
|
||||
pDebugBox->Add(pDumpSzr);
|
||||
wxGridSizer* const pDbgGrid = new wxGridSizer(2, 5, 5);
|
||||
pDbgGrid->Add(m_pButtonUpdateScreen);
|
||||
pDbgGrid->Add(m_pButtonClearScreen);
|
||||
pDbgGrid->Add(m_pButtonClearTextureCache);
|
||||
pDbgGrid->Add(m_pButtonClearVertexShaderCache);
|
||||
pDbgGrid->Add(m_pButtonClearPixelShaderCache);
|
||||
pDebugBox->Add(pDbgGrid);
|
||||
pDebugBox->Add(pDumpSzr, 0, wxEXPAND);
|
||||
pDebugBox->Add(pDbgGrid, 1, wxTOP, space3);
|
||||
|
||||
sMain->Add(pFlowCtrlBox, 0, 0, 5);
|
||||
sMain->Add(pDebugBox, 0, 0, 5);
|
||||
sMain->Add(pFlowCtrlBox);
|
||||
sMain->Add(pDebugBox);
|
||||
SetSizerAndFit(sMain);
|
||||
|
||||
OnContinue();
|
||||
|
@ -248,12 +205,6 @@ void GFXDebuggerPanel::OnContinue()
|
|||
m_pButtonClearPixelShaderCache->Disable();
|
||||
}
|
||||
|
||||
// General settings
|
||||
void GFXDebuggerPanel::GeneralSettings(wxCommandEvent& event)
|
||||
{
|
||||
SaveSettings();
|
||||
}
|
||||
|
||||
void GFXDebuggerPanel::OnPauseButton(wxCommandEvent& event)
|
||||
{
|
||||
GFXDebuggerPauseFlag = true;
|
||||
|
|
|
@ -20,9 +20,6 @@ public:
|
|||
|
||||
virtual ~GFXDebuggerPanel();
|
||||
|
||||
void SaveSettings() const;
|
||||
void LoadSettings();
|
||||
|
||||
bool bInfoLog;
|
||||
bool bPrimLog;
|
||||
bool bSaveTextures;
|
||||
|
@ -49,11 +46,8 @@ private:
|
|||
wxButton* m_pButtonClearPixelShaderCache;
|
||||
wxTextCtrl* m_pCount;
|
||||
|
||||
void OnClose(wxCloseEvent& event);
|
||||
void CreateGUIControls();
|
||||
|
||||
void GeneralSettings(wxCommandEvent& event);
|
||||
|
||||
// These set GFXDebuggerPauseFlag to true (either immediately or once the specified event has
|
||||
// occurred)
|
||||
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,
|
||||
wxDefaultSize, wxTE_MULTILINE),
|
||||
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_SINGLE_SEL | wxLC_SORT_ASCENDING),
|
||||
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")));
|
||||
button_refresh->Bind(wxEVT_BUTTON, &CJitWindow::OnRefresh, this);
|
||||
|
||||
SetSizer(sizerBig);
|
||||
|
||||
sizerSplit->Fit(this);
|
||||
sizerBig->Fit(this);
|
||||
SetSizerAndFit(sizerBig);
|
||||
|
||||
#if defined(_M_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*/)
|
||||
{
|
||||
block_list->Update();
|
||||
block_list->Repopulate();
|
||||
}
|
||||
|
||||
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"));
|
||||
}
|
||||
|
||||
void JitBlockList::Update()
|
||||
void JitBlockList::Repopulate()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
JitBlockList(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size,
|
||||
long style);
|
||||
void Init();
|
||||
void Update() override;
|
||||
void Repopulate();
|
||||
};
|
||||
|
||||
class CJitWindow : public wxPanel
|
||||
|
@ -33,7 +33,7 @@ public:
|
|||
const wxString& name = _("JIT Block Viewer"));
|
||||
|
||||
void ViewAddr(u32 em_address);
|
||||
void Update() override;
|
||||
void Repopulate();
|
||||
|
||||
private:
|
||||
void OnRefresh(wxCommandEvent& /*event*/);
|
||||
|
|
|
@ -22,6 +22,8 @@ MemoryCheckDlg::MemoryCheckDlg(CBreakPointWindow* parent)
|
|||
Bind(wxEVT_BUTTON, &MemoryCheckDlg::OnOK, this, wxID_OK);
|
||||
Bind(wxEVT_RADIOBUTTON, &MemoryCheckDlg::OnRadioButtonClick, this);
|
||||
|
||||
const int space5 = FromDIP(5);
|
||||
|
||||
m_textAddress = new wxStaticText(this, wxID_ANY, _("Address"));
|
||||
m_textStartAddress = new wxStaticText(this, wxID_ANY, _("Start"));
|
||||
m_textStartAddress->Disable();
|
||||
|
@ -46,14 +48,22 @@ MemoryCheckDlg::MemoryCheckDlg(CBreakPointWindow* parent)
|
|||
m_radioBreakLog->SetValue(true);
|
||||
|
||||
auto* sAddressBox = new wxBoxSizer(wxHORIZONTAL);
|
||||
sAddressBox->Add(m_textAddress, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
|
||||
sAddressBox->Add(m_pEditAddress, 1, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM, 10);
|
||||
sAddressBox->AddSpacer(space5);
|
||||
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);
|
||||
sAddressRangeBox->Add(m_textStartAddress, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
|
||||
sAddressRangeBox->Add(m_pEditStartAddress, 1, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM, 10);
|
||||
sAddressRangeBox->Add(m_textEndAddress, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
|
||||
sAddressRangeBox->Add(m_pEditEndAddress, 1, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM, 5);
|
||||
sAddressRangeBox->AddSpacer(space5);
|
||||
sAddressRangeBox->Add(m_textStartAddress, 0, wxALIGN_CENTER_VERTICAL);
|
||||
sAddressRangeBox->AddSpacer(space5);
|
||||
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"));
|
||||
sActions->Add(m_radioRead, 0, wxEXPAND);
|
||||
|
@ -67,19 +77,26 @@ MemoryCheckDlg::MemoryCheckDlg(CBreakPointWindow* parent)
|
|||
sFlags->Add(m_radioBreakLog);
|
||||
|
||||
auto* sOptionsBox = new wxBoxSizer(wxHORIZONTAL);
|
||||
sOptionsBox->Add(sActions, 1, wxEXPAND | wxRIGHT | wxTOP | wxBOTTOM, 5);
|
||||
sOptionsBox->Add(sFlags, 1, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 5);
|
||||
sOptionsBox->Add(sActions, 1, wxEXPAND, space5);
|
||||
sOptionsBox->Add(sFlags, 1, wxEXPAND | wxLEFT, space5);
|
||||
|
||||
auto* sControls = new wxBoxSizer(wxVERTICAL);
|
||||
sControls->Add(m_radioAddress, 0, wxEXPAND);
|
||||
sControls->AddSpacer(5);
|
||||
sControls->Add(sAddressBox, 0, wxEXPAND);
|
||||
sControls->AddSpacer(5);
|
||||
sControls->Add(m_radioRange, 0, wxEXPAND);
|
||||
sControls->AddSpacer(5);
|
||||
sControls->Add(sAddressRangeBox, 0, wxEXPAND);
|
||||
sControls->AddSpacer(5);
|
||||
sControls->Add(sOptionsBox, 0, wxEXPAND);
|
||||
|
||||
auto* sMainSizer = new wxBoxSizer(wxVERTICAL);
|
||||
sMainSizer->Add(sControls, 0, wxEXPAND | wxTOP | wxRIGHT | wxLEFT, 5);
|
||||
sMainSizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||
sMainSizer->AddSpacer(space5);
|
||||
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);
|
||||
SetFocus();
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <wx/brush.h>
|
||||
|
@ -17,6 +19,7 @@
|
|||
#include "Common/CommonTypes.h"
|
||||
#include "Common/DebugInterface.h"
|
||||
#include "Common/StringUtil.h"
|
||||
#include "Core/HW/Memmap.h"
|
||||
#include "Core/PowerPC/PPCSymbolDB.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
#include "DolphinWX/Debugger/CodeWindow.h"
|
||||
|
@ -25,6 +28,7 @@
|
|||
#include "DolphinWX/Debugger/WatchWindow.h"
|
||||
#include "DolphinWX/Frame.h"
|
||||
#include "DolphinWX/Globals.h"
|
||||
#include "DolphinWX/Main.h"
|
||||
#include "DolphinWX/WxUtils.h"
|
||||
|
||||
enum
|
||||
|
@ -42,11 +46,12 @@ enum
|
|||
IDM_VIEWASHEX,
|
||||
};
|
||||
|
||||
wxDEFINE_EVENT(DOLPHIN_EVT_MEMORY_VIEW_DATA_TYPE_CHANGED, wxCommandEvent);
|
||||
|
||||
CMemoryView::CMemoryView(DebugInterface* debuginterface, wxWindow* parent)
|
||||
: wxControl(parent, wxID_ANY), debugger(debuginterface),
|
||||
align(debuginterface->GetInstructionSize(0)), rowHeight(13), selection(0), oldSelection(0),
|
||||
selecting(false), memory(0), curAddress(debuginterface->GetPC()),
|
||||
dataType(MemoryDataType::U8), viewAsType(VIEWAS_FP)
|
||||
: wxControl(parent, wxID_ANY), debugger(debuginterface), align(0), rowHeight(FromDIP(13)),
|
||||
m_left_col_width(FromDIP(LEFT_COL_WIDTH)), selection(0), oldSelection(0), selecting(false),
|
||||
memory(0), curAddress(debuginterface->GetPC()), m_data_type(MemoryDataType::U8)
|
||||
{
|
||||
Bind(wxEVT_PAINT, &CMemoryView::OnPaint, 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_MENU, &CMemoryView::OnPopupMenu, 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)
|
||||
|
@ -68,10 +105,10 @@ int CMemoryView::YToAddress(int y)
|
|||
|
||||
void CMemoryView::OnMouseDownL(wxMouseEvent& event)
|
||||
{
|
||||
int x = event.m_x;
|
||||
int y = event.m_y;
|
||||
int x = event.GetX();
|
||||
int y = event.GetY();
|
||||
|
||||
if (x > 16)
|
||||
if (x > m_left_col_width)
|
||||
{
|
||||
oldSelection = selection;
|
||||
selection = YToAddress(y);
|
||||
|
@ -99,7 +136,7 @@ void CMemoryView::OnMouseMove(wxMouseEvent& event)
|
|||
{
|
||||
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)
|
||||
{
|
||||
|
@ -120,7 +157,7 @@ void CMemoryView::OnMouseMove(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);
|
||||
selecting = false;
|
||||
|
@ -137,11 +174,11 @@ void CMemoryView::OnScrollWheel(wxMouseEvent& event)
|
|||
|
||||
if (scroll_down)
|
||||
{
|
||||
curAddress += num_lines * 4;
|
||||
curAddress += num_lines * align;
|
||||
}
|
||||
else
|
||||
{
|
||||
curAddress -= num_lines * 4;
|
||||
curAddress -= num_lines * align;
|
||||
}
|
||||
|
||||
Refresh();
|
||||
|
@ -150,25 +187,26 @@ void CMemoryView::OnScrollWheel(wxMouseEvent& event)
|
|||
|
||||
void CMemoryView::OnPopupMenu(wxCommandEvent& event)
|
||||
{
|
||||
CFrame* main_frame = static_cast<CFrame*>(GetGrandParent()->GetParent());
|
||||
CCodeWindow* code_window = main_frame->g_pCodeWindow;
|
||||
CWatchWindow* watch_window = code_window->m_WatchWindow;
|
||||
|
||||
#if wxUSE_CLIPBOARD
|
||||
wxTheClipboard->Open();
|
||||
#endif
|
||||
// FIXME: This is terrible. Generate events instead.
|
||||
CFrame* cframe = wxGetApp().GetCFrame();
|
||||
CCodeWindow* code_window = cframe->g_pCodeWindow;
|
||||
CWatchWindow* watch_window = code_window->GetPanel<CWatchWindow>();
|
||||
|
||||
switch (event.GetId())
|
||||
{
|
||||
#if wxUSE_CLIPBOARD
|
||||
case IDM_COPYADDRESS:
|
||||
{
|
||||
wxClipboardLocker clipboard_lock;
|
||||
wxTheClipboard->SetData(new wxTextDataObject(wxString::Format("%08x", selection)));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case IDM_COPYHEX:
|
||||
{
|
||||
std::string temp = StringFromFormat("%08x", debugger->ReadExtraMemory(memory, selection));
|
||||
wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(temp)));
|
||||
wxClipboardLocker clipboard_lock;
|
||||
wxTheClipboard->SetData(new wxTextDataObject(
|
||||
wxString::Format("%08x", debugger->ReadExtraMemory(memory, selection))));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
@ -186,24 +224,21 @@ void CMemoryView::OnPopupMenu(wxCommandEvent& event)
|
|||
break;
|
||||
|
||||
case IDM_VIEWASFP:
|
||||
viewAsType = VIEWAS_FP;
|
||||
Refresh();
|
||||
SetDataType(MemoryDataType::FloatingPoint);
|
||||
break;
|
||||
|
||||
case IDM_VIEWASASCII:
|
||||
viewAsType = VIEWAS_ASCII;
|
||||
Refresh();
|
||||
SetDataType(MemoryDataType::ASCII);
|
||||
break;
|
||||
|
||||
case IDM_VIEWASHEX:
|
||||
viewAsType = VIEWAS_HEX;
|
||||
Refresh();
|
||||
SetDataType(m_last_hex_type);
|
||||
break;
|
||||
|
||||
default:
|
||||
event.Skip();
|
||||
break;
|
||||
}
|
||||
|
||||
#if wxUSE_CLIPBOARD
|
||||
wxTheClipboard->Close();
|
||||
#endif
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void CMemoryView::OnMouseDownR(wxMouseEvent& event)
|
||||
|
@ -216,12 +251,14 @@ void CMemoryView::OnMouseDownR(wxMouseEvent& event)
|
|||
menu.Append(IDM_COPYHEX, _("Copy &hex"));
|
||||
#endif
|
||||
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;
|
||||
viewAsSubMenu->Append(IDM_VIEWASFP, _("FP value"));
|
||||
viewAsSubMenu->Append(IDM_VIEWASASCII, "ASCII");
|
||||
viewAsSubMenu->Append(IDM_VIEWASHEX, _("Hex"));
|
||||
viewAsSubMenu->AppendRadioItem(IDM_VIEWASFP, _("FP value"))
|
||||
->Check(m_data_type == MemoryDataType::FloatingPoint);
|
||||
viewAsSubMenu->AppendRadioItem(IDM_VIEWASASCII, "ASCII")
|
||||
->Check(m_data_type == MemoryDataType::ASCII);
|
||||
viewAsSubMenu->AppendRadioItem(IDM_VIEWASHEX, _("Hex"))->Check(IsHexMode());
|
||||
menu.AppendSubMenu(viewAsSubMenu, _("View As:"));
|
||||
|
||||
PopupMenu(&menu);
|
||||
|
@ -231,176 +268,160 @@ void CMemoryView::OnPaint(wxPaintEvent& event)
|
|||
{
|
||||
wxPaintDC dc(this);
|
||||
wxRect rc = GetClientRect();
|
||||
wxFont hFont("Courier");
|
||||
hFont.SetFamily(wxFONTFAMILY_TELETYPE);
|
||||
|
||||
wxCoord w, h;
|
||||
dc.GetTextExtent("0WJyq", &w, &h, nullptr, nullptr, &hFont);
|
||||
if (h > rowHeight)
|
||||
rowHeight = h;
|
||||
dc.GetTextExtent("0WJyq", &w, &h, nullptr, nullptr, &DebuggerFont);
|
||||
if (h > rowHeight)
|
||||
rowHeight = h;
|
||||
|
||||
if (viewAsType == VIEWAS_HEX)
|
||||
dc.SetFont(hFont);
|
||||
else
|
||||
if (DebuggerFont.IsFixedWidth())
|
||||
{
|
||||
dc.SetFont(DebuggerFont);
|
||||
}
|
||||
else
|
||||
{
|
||||
dc.SetFont(wxFont(DebuggerFont.GetPointSize(), wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL,
|
||||
wxFONTWEIGHT_NORMAL, false, "Courier"));
|
||||
}
|
||||
|
||||
dc.GetTextExtent("W", &w, &h);
|
||||
int fontSize = w;
|
||||
int textPlacement = 17 + 9 * fontSize;
|
||||
int font_width;
|
||||
{
|
||||
wxFontMetrics metrics = dc.GetFontMetrics();
|
||||
font_width = metrics.averageWidth;
|
||||
if (metrics.height > rowHeight)
|
||||
rowHeight = metrics.height;
|
||||
}
|
||||
|
||||
// TODO: Add any drawing code here...
|
||||
int width = rc.width;
|
||||
int numRows = (rc.height / rowHeight) / 2 + 2;
|
||||
dc.SetBackgroundMode(wxPENSTYLE_TRANSPARENT);
|
||||
const wxColour bgColor = *wxWHITE;
|
||||
wxPen nullPen(bgColor);
|
||||
wxPen currentPen(*wxBLACK_PEN);
|
||||
wxPen selPen(*wxGREY_PEN);
|
||||
nullPen.SetStyle(wxPENSTYLE_TRANSPARENT);
|
||||
const int row_start_x = m_left_col_width + 1;
|
||||
const int mchk_x = FromDIP(LEFT_COL_WIDTH / 8);
|
||||
const wxSize mchk_size = FromDIP(wxSize(LEFT_COL_WIDTH * 3 / 4, LEFT_COL_WIDTH * 3 / 4));
|
||||
const int mchk_offset_y = (rowHeight - mchk_size.GetHeight()) / 2;
|
||||
|
||||
wxBrush currentBrush(*wxLIGHT_GREY_BRUSH);
|
||||
wxBrush pcBrush(*wxGREEN_BRUSH);
|
||||
wxBrush mcBrush(*wxBLUE_BRUSH);
|
||||
wxBrush bgBrush(bgColor);
|
||||
wxBrush nullBrush(bgColor);
|
||||
nullBrush.SetStyle(wxBRUSHSTYLE_TRANSPARENT);
|
||||
int col_width = rc.width - m_left_col_width;
|
||||
int num_rows = (rc.height / rowHeight) / 2 + 2;
|
||||
const wxColour navy_color = wxTheColourDatabase->Find("NAVY");
|
||||
|
||||
dc.SetPen(nullPen);
|
||||
dc.SetBrush(bgBrush);
|
||||
dc.DrawRectangle(0, 0, 16, rc.height);
|
||||
dc.DrawRectangle(0, 0, rc.width, 5 + 8);
|
||||
const int pen_width = FromDIP(1);
|
||||
wxPen focus_pen(*wxBLACK, pen_width);
|
||||
wxPen selection_pen(*wxLIGHT_GREY, pen_width);
|
||||
wxBrush pc_brush(*wxGREEN_BRUSH);
|
||||
wxBrush mc_brush(*wxBLUE_BRUSH);
|
||||
wxBrush bg_brush(*wxWHITE_BRUSH);
|
||||
|
||||
// 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 rowY2 = rc.height / 2 + rowHeight * row + rowHeight / 2;
|
||||
int row_y = 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);
|
||||
u32 col = debugger->GetColor(address);
|
||||
wxBrush rowBrush(wxColour(col >> 16, col >> 8, col));
|
||||
dc.SetBrush(nullBrush);
|
||||
dc.SetPen(nullPen);
|
||||
dc.DrawRectangle(0, rowY1, 16, rowY2);
|
||||
dc.SetBrush(bg_brush);
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
dc.DrawRectangle(0, row_y, m_left_col_width, rowHeight);
|
||||
|
||||
if (selecting && (address == selection))
|
||||
dc.SetPen(selPen);
|
||||
dc.SetPen(selection_pen);
|
||||
else
|
||||
dc.SetPen(row == 0 ? currentPen : nullPen);
|
||||
dc.SetPen(row == 0 ? focus_pen : *wxTRANSPARENT_PEN);
|
||||
|
||||
if (address == debugger->GetPC())
|
||||
dc.SetBrush(pcBrush);
|
||||
dc.SetBrush(pc_brush);
|
||||
else
|
||||
dc.SetBrush(rowBrush);
|
||||
|
||||
dc.DrawRectangle(16, rowY1, width, rowY2 - 1);
|
||||
dc.SetBrush(currentBrush);
|
||||
dc.SetTextForeground("#600000"); // Dark red
|
||||
dc.DrawText(temp, 17, rowY1);
|
||||
dc.DrawRectangle(m_left_col_width, row_y, col_width, rowHeight);
|
||||
dc.SetTextForeground(wxColour(0x60, 0x00, 0x00)); // Dark red
|
||||
draw_text(temp);
|
||||
|
||||
if (viewAsType != VIEWAS_HEX)
|
||||
if (!IsHexMode())
|
||||
{
|
||||
char mem[256];
|
||||
debugger->GetRawMemoryString(memory, address, mem, 256);
|
||||
dc.SetTextForeground(wxTheColourDatabase->Find("NAVY"));
|
||||
dc.DrawText(StrToWxStr(mem), 17 + fontSize * (8), rowY1);
|
||||
dc.SetTextForeground(*wxBLACK);
|
||||
dc.SetTextForeground(navy_color);
|
||||
draw_text(StrToWxStr(mem), 2);
|
||||
}
|
||||
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))
|
||||
continue;
|
||||
|
||||
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(*wxTRANSPARENT_PEN);
|
||||
dc.SetBrush(mc_brush);
|
||||
dc.DrawEllipse(mchk_x, row_y + mchk_offset_y, mchk_size.GetWidth(), mchk_size.GetHeight());
|
||||
}
|
||||
}
|
||||
|
||||
dc.SetPen(currentPen);
|
||||
}
|
||||
|
||||
void CMemoryView::OnResize(wxSizeEvent& event)
|
||||
|
|
|
@ -13,9 +13,13 @@ enum class MemoryDataType
|
|||
{
|
||||
U8,
|
||||
U16,
|
||||
U32
|
||||
U32,
|
||||
ASCII,
|
||||
FloatingPoint
|
||||
};
|
||||
|
||||
wxDECLARE_EVENT(DOLPHIN_EVT_MEMORY_VIEW_DATA_TYPE_CHANGED, wxCommandEvent);
|
||||
|
||||
class CMemoryView : public wxControl
|
||||
{
|
||||
public:
|
||||
|
@ -29,12 +33,8 @@ public:
|
|||
Refresh();
|
||||
}
|
||||
|
||||
void SetDataType(MemoryDataType data_type)
|
||||
{
|
||||
dataType = data_type;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void SetDataType(MemoryDataType data_type);
|
||||
MemoryDataType GetDataType() const { return m_data_type; }
|
||||
void SetMemCheckOptions(bool read, bool write, bool log)
|
||||
{
|
||||
memCheckRead = read;
|
||||
|
@ -43,6 +43,12 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
int YToAddress(int y);
|
||||
bool IsHexMode() const
|
||||
{
|
||||
return m_data_type != MemoryDataType::ASCII && m_data_type != MemoryDataType::FloatingPoint;
|
||||
}
|
||||
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
void OnMouseDownL(wxMouseEvent& event);
|
||||
void OnMouseMove(wxMouseEvent& event);
|
||||
|
@ -50,14 +56,15 @@ private:
|
|||
void OnMouseDownR(wxMouseEvent& event);
|
||||
void OnScrollWheel(wxMouseEvent& event);
|
||||
void OnPopupMenu(wxCommandEvent& event);
|
||||
|
||||
int YToAddress(int y);
|
||||
void OnResize(wxSizeEvent& event);
|
||||
|
||||
static constexpr int LEFT_COL_WIDTH = 16;
|
||||
|
||||
DebugInterface* debugger;
|
||||
|
||||
int align;
|
||||
unsigned int align;
|
||||
int rowHeight;
|
||||
int m_left_col_width;
|
||||
|
||||
u32 selection;
|
||||
u32 oldSelection;
|
||||
|
@ -65,18 +72,11 @@ private:
|
|||
|
||||
int memory;
|
||||
int curAddress;
|
||||
MemoryDataType dataType;
|
||||
|
||||
bool memCheckRead;
|
||||
bool memCheckWrite;
|
||||
bool memCheckLog;
|
||||
|
||||
enum EViewAsType
|
||||
{
|
||||
VIEWAS_ASCII = 0,
|
||||
VIEWAS_FP,
|
||||
VIEWAS_HEX,
|
||||
};
|
||||
|
||||
EViewAsType viewAsType;
|
||||
MemoryDataType m_data_type;
|
||||
MemoryDataType m_last_hex_type = MemoryDataType::U8;
|
||||
};
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <wx/button.h>
|
||||
|
@ -12,10 +13,13 @@
|
|||
#include <wx/listbox.h>
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/radiobox.h>
|
||||
#include <wx/radiobut.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/srchctrl.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/utils.h>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/FileUtil.h"
|
||||
|
@ -43,9 +47,7 @@ enum
|
|||
IDM_DUMP_MEM2,
|
||||
IDM_DUMP_FAKEVMEM,
|
||||
IDM_VALBOX,
|
||||
IDM_U8,
|
||||
IDM_U16,
|
||||
IDM_U32,
|
||||
IDM_DATA_TYPE_RBOX,
|
||||
IDM_SEARCH,
|
||||
IDM_ASCII,
|
||||
IDM_HEX,
|
||||
|
@ -53,30 +55,24 @@ enum
|
|||
};
|
||||
|
||||
BEGIN_EVENT_TABLE(CMemoryWindow, wxPanel)
|
||||
EVT_LISTBOX(IDM_SYMBOLLIST, CMemoryWindow::OnSymbolListChange)
|
||||
EVT_HOST_COMMAND(wxID_ANY, CMemoryWindow::OnHostMessage)
|
||||
EVT_BUTTON(IDM_SETVALBUTTON, CMemoryWindow::SetMemoryValue)
|
||||
EVT_BUTTON(IDM_DUMP_MEMORY, CMemoryWindow::OnDumpMemory)
|
||||
EVT_BUTTON(IDM_DUMP_MEM2, CMemoryWindow::OnDumpMem2)
|
||||
EVT_BUTTON(IDM_DUMP_FAKEVMEM, CMemoryWindow::OnDumpFakeVMEM)
|
||||
EVT_CHECKBOX(IDM_U8, CMemoryWindow::U8)
|
||||
EVT_CHECKBOX(IDM_U16, CMemoryWindow::U16)
|
||||
EVT_CHECKBOX(IDM_U32, CMemoryWindow::U32)
|
||||
EVT_BUTTON(IDM_SEARCH, CMemoryWindow::onSearch)
|
||||
EVT_CHECKBOX(IDM_ASCII, CMemoryWindow::onAscii)
|
||||
EVT_CHECKBOX(IDM_HEX, CMemoryWindow::onHex)
|
||||
EVT_RADIOBUTTON(IDM_MEMCHECK_OPTIONS_CHANGE, CMemoryWindow::onMemCheckOptionChange)
|
||||
EVT_CHECKBOX(IDM_MEMCHECK_OPTIONS_CHANGE, CMemoryWindow::onMemCheckOptionChange)
|
||||
EVT_RADIOBOX(IDM_DATA_TYPE_RBOX, CMemoryWindow::OnDataTypeChanged)
|
||||
EVT_BUTTON(IDM_SEARCH, CMemoryWindow::OnSearch)
|
||||
EVT_RADIOBUTTON(IDM_MEMCHECK_OPTIONS_CHANGE, CMemoryWindow::OnMemCheckOptionChange)
|
||||
EVT_CHECKBOX(IDM_MEMCHECK_OPTIONS_CHANGE, CMemoryWindow::OnMemCheckOptionChange)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
CMemoryWindow::CMemoryWindow(CCodeWindow* code_window, wxWindow* parent, wxWindowID id,
|
||||
const wxPoint& pos, const wxSize& size, long style,
|
||||
const wxString& name)
|
||||
: wxPanel(parent, id, pos, size, style, name), m_code_window(code_window)
|
||||
CMemoryWindow::CMemoryWindow(wxWindow* parent, wxWindowID id, const wxPoint& pos,
|
||||
const wxSize& size, long style, const wxString& name)
|
||||
: wxPanel(parent, id, pos, size, style, name)
|
||||
{
|
||||
DebugInterface* di = &PowerPC::debug_interface;
|
||||
|
||||
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->Bind(wxEVT_TEXT, &CMemoryWindow::OnAddrBoxChange, this);
|
||||
|
@ -85,13 +81,17 @@ CMemoryWindow::CMemoryWindow(CCodeWindow* code_window, wxWindow* parent, wxWindo
|
|||
valbox =
|
||||
new wxTextCtrl(this, IDM_VALBOX, "", wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
|
||||
valbox->Bind(wxEVT_TEXT_ENTER, &CMemoryWindow::SetMemoryValueFromValBox, this);
|
||||
valbox->Bind(wxEVT_TEXT, &CMemoryWindow::OnValueChanged, this);
|
||||
|
||||
wxGridSizer* const search_sizer = new wxGridSizer(1);
|
||||
search_sizer->Add(addrbox);
|
||||
const int space3 = FromDIP(3);
|
||||
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(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_MEM2, _("Dump EXRAM")), 0, wxEXPAND);
|
||||
if (!SConfig::GetInstance().bMMU)
|
||||
|
@ -99,73 +99,57 @@ CMemoryWindow::CMemoryWindow(CCodeWindow* code_window, wxWindow* parent, wxWindo
|
|||
|
||||
wxStaticBoxSizer* const sizerSearchType = new wxStaticBoxSizer(wxVERTICAL, this, _("Search"));
|
||||
sizerSearchType->Add(btnSearch = new wxButton(this, IDM_SEARCH, _("Search")));
|
||||
sizerSearchType->Add(chkAscii = new wxCheckBox(this, IDM_ASCII, "Ascii "));
|
||||
sizerSearchType->Add(chkHex = new wxCheckBox(this, IDM_HEX, _("Hex")));
|
||||
sizerSearchType->Add(m_rb_ascii = new wxRadioButton(this, IDM_ASCII, "Ascii", wxDefaultPosition,
|
||||
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"));
|
||||
sizerDataTypes->SetMinSize(74, 40);
|
||||
sizerDataTypes->Add(chk8 = new wxCheckBox(this, IDM_U8, "U8"));
|
||||
sizerDataTypes->Add(chk16 = new wxCheckBox(this, IDM_U16, "U16"));
|
||||
sizerDataTypes->Add(chk32 = new wxCheckBox(this, IDM_U32, "U32"));
|
||||
wxArrayString data_type_options;
|
||||
data_type_options.Add("U8");
|
||||
data_type_options.Add("U16");
|
||||
data_type_options.Add("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");
|
||||
sizerMemCheckOptions->Add(rdbReadWrite = new wxRadioButton(this, IDM_MEMCHECK_OPTIONS_CHANGE,
|
||||
"Read and Write", wxDefaultPosition,
|
||||
wxDefaultSize, wxRB_GROUP));
|
||||
sizerMemCheckOptions->Add(rdbRead =
|
||||
new wxRadioButton(this, IDM_MEMCHECK_OPTIONS_CHANGE, "Read only"));
|
||||
sizerMemCheckOptions->Add(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(rdbReadWrite = new wxRadioButton(this, IDM_MEMCHECK_OPTIONS_CHANGE,
|
||||
"Read and Write", wxDefaultPosition,
|
||||
wxDefaultSize, wxRB_GROUP));
|
||||
memcheck_options_sizer->Add(
|
||||
rdbRead = new wxRadioButton(this, IDM_MEMCHECK_OPTIONS_CHANGE, "Read only"));
|
||||
memcheck_options_sizer->Add(
|
||||
rdbWrite = new wxRadioButton(this, IDM_MEMCHECK_OPTIONS_CHANGE, "Write only"));
|
||||
memcheck_options_sizer->Add(chkLog = new wxCheckBox(this, IDM_MEMCHECK_OPTIONS_CHANGE, "Log"));
|
||||
|
||||
wxBoxSizer* const sizerRight = new wxBoxSizer(wxVERTICAL);
|
||||
sizerRight->Add(search_sizer);
|
||||
sizerRight->AddSpacer(5);
|
||||
sizerRight->Add(dump_sizer);
|
||||
sizerRight->Add(sizerSearchType);
|
||||
sizerRight->Add(sizerDataTypes);
|
||||
sizerRight->Add(sizerMemCheckOptions);
|
||||
sizerRight->AddSpacer(space5);
|
||||
sizerRight->Add(dump_sizer, 0, wxEXPAND);
|
||||
sizerRight->Add(sizerSearchType, 0, wxEXPAND);
|
||||
sizerRight->Add(m_rbox_data_type, 0, wxEXPAND);
|
||||
sizerRight->Add(memcheck_options_sizer, 0, wxEXPAND);
|
||||
|
||||
wxBoxSizer* const sizerBig = new wxBoxSizer(wxHORIZONTAL);
|
||||
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);
|
||||
chkHex->SetValue(1); // Set defaults
|
||||
chk8->SetValue(1);
|
||||
chkLog->SetValue(1);
|
||||
m_rb_hex->SetValue(true); // Set defaults
|
||||
chkLog->SetValue(true);
|
||||
m_rbox_data_type->SetSelection(static_cast<int>(memview->GetDataType()));
|
||||
|
||||
sizerRight->Fit(this);
|
||||
sizerBig->Fit(this);
|
||||
}
|
||||
|
||||
void CMemoryWindow::Save(IniFile& ini) const
|
||||
{
|
||||
// Prevent these bad values that can happen after a crash or hanging
|
||||
if (GetPosition().x != -32000 && GetPosition().y != -32000)
|
||||
{
|
||||
IniFile::Section* mem_window = ini.GetOrCreateSection("MemoryWindow");
|
||||
mem_window->Set("x", GetPosition().x);
|
||||
mem_window->Set("y", GetPosition().y);
|
||||
mem_window->Set("w", GetSize().GetWidth());
|
||||
mem_window->Set("h", GetSize().GetHeight());
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
memview->Center(_Address);
|
||||
|
@ -219,55 +203,14 @@ void CMemoryWindow::OnAddrBoxChange(wxCommandEvent& event)
|
|||
event.Skip();
|
||||
}
|
||||
|
||||
void CMemoryWindow::Update()
|
||||
void CMemoryWindow::Repopulate()
|
||||
{
|
||||
memview->Refresh();
|
||||
memview->Center(PC);
|
||||
}
|
||||
|
||||
void CMemoryWindow::NotifyMapLoaded()
|
||||
void CMemoryWindow::OnValueChanged(wxCommandEvent&)
|
||||
{
|
||||
symbols->Show(false); // hide it for faster filling
|
||||
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;
|
||||
}
|
||||
m_continue_search = false;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void CMemoryWindow::U8(wxCommandEvent& event)
|
||||
void CMemoryWindow::OnDataTypeChanged(wxCommandEvent& ev)
|
||||
{
|
||||
chk16->SetValue(0);
|
||||
chk32->SetValue(0);
|
||||
memview->SetDataType(MemoryDataType::U8);
|
||||
static constexpr std::array<MemoryDataType, 5> map{{MemoryDataType::U8, MemoryDataType::U16,
|
||||
MemoryDataType::U32, MemoryDataType::ASCII,
|
||||
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);
|
||||
chk32->SetValue(0);
|
||||
memview->SetDataType(MemoryDataType::U16);
|
||||
}
|
||||
|
||||
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;
|
||||
wxBusyCursor hourglass_cursor;
|
||||
u8* ram_ptr = nullptr;
|
||||
u32 ram_size = 0;
|
||||
// NOTE: We're assuming the base address is zero.
|
||||
switch (memview->GetMemoryType())
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
if (Memory::m_pRAM)
|
||||
{
|
||||
TheRAM = Memory::m_pRAM;
|
||||
szRAM = Memory::REALRAM_SIZE;
|
||||
ram_ptr = Memory::m_pRAM;
|
||||
ram_size = Memory::REALRAM_SIZE;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
|
@ -344,131 +288,115 @@ void CMemoryWindow::onSearch(wxCommandEvent& event)
|
|||
u8* aram = DSP::GetARAMPtr();
|
||||
if (aram)
|
||||
{
|
||||
TheRAM = aram;
|
||||
szRAM = DSP::ARAM_SIZE;
|
||||
ram_ptr = aram;
|
||||
ram_size = DSP::ARAM_SIZE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Now we have memory to look in
|
||||
// Are we looking for ASCII string, or hex?
|
||||
// memview->cu
|
||||
wxString rawData = valbox->GetValue();
|
||||
std::vector<u8> Dest; // May need a better name
|
||||
u32 size = 0;
|
||||
int pad = rawData.size() % 2; // If it's uneven
|
||||
unsigned int i = 0;
|
||||
long count = 0;
|
||||
char copy[3] = {0};
|
||||
long newsize = 0;
|
||||
unsigned char* tmp2 = nullptr;
|
||||
char* tmpstr = nullptr;
|
||||
|
||||
if (chkHex->GetValue())
|
||||
if (!ram_ptr)
|
||||
{
|
||||
// We are looking for hex
|
||||
// If it's uneven
|
||||
size = (rawData.size() / 2) + pad;
|
||||
Dest.resize(size + 32);
|
||||
newsize = rawData.size();
|
||||
m_search_result_msg->SetLabel(_("Memory Not Ready"));
|
||||
return;
|
||||
}
|
||||
|
||||
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];
|
||||
memset(tmpstr, 0, newsize + 2);
|
||||
tmpstr[0] = '0';
|
||||
unsigned long byte = 0;
|
||||
conversion_buffer[0] = search_val[i];
|
||||
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
|
||||
{
|
||||
// Looking for an ascii string
|
||||
size = rawData.size();
|
||||
Dest.resize(size + 1);
|
||||
tmpstr = new char[size + 1];
|
||||
|
||||
tmp2 = &Dest.front();
|
||||
sprintf(tmpstr, "%s", WxStrToStr(rawData).c_str());
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
tmp2[i] = tmpstr[i];
|
||||
|
||||
delete[] tmpstr;
|
||||
const auto& bytes = search_val.ToUTF8();
|
||||
search_bytes.assign(bytes.data(), bytes.data() + bytes.length());
|
||||
}
|
||||
search_val.Clear();
|
||||
|
||||
if (size)
|
||||
// For completeness
|
||||
if (search_bytes.size() > ram_size)
|
||||
{
|
||||
unsigned char* pnt = &Dest.front();
|
||||
unsigned int k = 0;
|
||||
// grab
|
||||
wxString txt = addrbox->GetValue();
|
||||
u32 addr = 0;
|
||||
if (txt.size())
|
||||
m_search_result_msg->SetLabel(_("Value Too Large"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (search_bytes.empty())
|
||||
{
|
||||
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);
|
||||
}
|
||||
i = addr + 4;
|
||||
for (; i < szRAM; ++i)
|
||||
{
|
||||
for (k = 0; k < size; ++k)
|
||||
unsigned long addr_ul = 0;
|
||||
if (addr_val.ToULong(&addr_ul, 16))
|
||||
{
|
||||
if (i + k > szRAM)
|
||||
break;
|
||||
if (k > size)
|
||||
break;
|
||||
if (pnt[k] != TheRAM[i + k])
|
||||
{
|
||||
k = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (k == size)
|
||||
{
|
||||
// Match was found
|
||||
wxMessageBox(_("A match was found. Placing viewer at the offset."));
|
||||
addrbox->SetValue(wxString::Format("%08x", i));
|
||||
// memview->curAddress = i;
|
||||
// memview->Refresh();
|
||||
OnAddrBoxChange(event);
|
||||
return;
|
||||
addr = static_cast<u32>(addr_ul);
|
||||
// Don't find the result we're already looking at
|
||||
if (m_continue_search && addr == m_last_search_address)
|
||||
addr += 1;
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
chkHex->SetValue(0);
|
||||
}
|
||||
|
||||
void CMemoryWindow::onHex(wxCommandEvent& event)
|
||||
{
|
||||
chkAscii->SetValue(0);
|
||||
}
|
||||
|
||||
void CMemoryWindow::onMemCheckOptionChange(wxCommandEvent& event)
|
||||
void CMemoryWindow::OnMemCheckOptionChange(wxCommandEvent& event)
|
||||
{
|
||||
if (rdbReadWrite->GetValue())
|
||||
memview->SetMemCheckOptions(true, true, chkLog->GetValue());
|
||||
|
|
|
@ -12,51 +12,46 @@ class CCodeWindow;
|
|||
class IniFile;
|
||||
class wxButton;
|
||||
class wxCheckBox;
|
||||
class wxRadioBox;
|
||||
class wxRadioButton;
|
||||
class wxListBox;
|
||||
class wxSearchCtrl;
|
||||
class wxStaticText;
|
||||
class wxTextCtrl;
|
||||
class wxRadioButton;
|
||||
|
||||
class CMemoryWindow : public wxPanel
|
||||
{
|
||||
public:
|
||||
CMemoryWindow(CCodeWindow* code_window, wxWindow* parent, wxWindowID id = wxID_ANY,
|
||||
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
|
||||
long style = wxTAB_TRAVERSAL | wxBORDER_NONE, const wxString& name = _("Memory"));
|
||||
CMemoryWindow(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL | wxBORDER_NONE,
|
||||
const wxString& name = _("Memory"));
|
||||
|
||||
void Save(IniFile& _IniFile) const;
|
||||
void Load(IniFile& _IniFile);
|
||||
|
||||
void Update() override;
|
||||
void NotifyMapLoaded();
|
||||
void Repopulate();
|
||||
|
||||
void JumpToAddress(u32 _Address);
|
||||
|
||||
private:
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
||||
void U8(wxCommandEvent& event);
|
||||
void U16(wxCommandEvent& event);
|
||||
void U32(wxCommandEvent& event);
|
||||
void onSearch(wxCommandEvent& event);
|
||||
void onAscii(wxCommandEvent& event);
|
||||
void onHex(wxCommandEvent& event);
|
||||
void OnSymbolListChange(wxCommandEvent& event);
|
||||
void OnDataTypeChanged(wxCommandEvent& event);
|
||||
void OnSearch(wxCommandEvent& event);
|
||||
void OnAddrBoxChange(wxCommandEvent& event);
|
||||
void OnHostMessage(wxCommandEvent& event);
|
||||
void OnValueChanged(wxCommandEvent&);
|
||||
void SetMemoryValueFromValBox(wxCommandEvent& event);
|
||||
void SetMemoryValue(wxCommandEvent& event);
|
||||
void OnDumpMemory(wxCommandEvent& event);
|
||||
void OnDumpMem2(wxCommandEvent& event);
|
||||
void OnDumpFakeVMEM(wxCommandEvent& event);
|
||||
void onMemCheckOptionChange(wxCommandEvent& event);
|
||||
void OnMemCheckOptionChange(wxCommandEvent& event);
|
||||
|
||||
wxCheckBox* chk8;
|
||||
wxCheckBox* chk16;
|
||||
wxCheckBox* chk32;
|
||||
wxButton* btnSearch;
|
||||
wxCheckBox* chkAscii;
|
||||
wxCheckBox* chkHex;
|
||||
wxRadioButton* m_rb_ascii;
|
||||
wxRadioButton* m_rb_hex;
|
||||
|
||||
wxRadioBox* m_rbox_data_type;
|
||||
wxStaticText* m_search_result_msg;
|
||||
|
||||
wxCheckBox* chkLog;
|
||||
wxRadioButton* rdbRead;
|
||||
wxRadioButton* rdbWrite;
|
||||
|
@ -65,8 +60,10 @@ private:
|
|||
CCodeWindow* m_code_window;
|
||||
|
||||
CMemoryView* memview;
|
||||
wxListBox* symbols;
|
||||
|
||||
wxSearchCtrl* addrbox;
|
||||
wxTextCtrl* valbox;
|
||||
|
||||
u32 m_last_search_address = 0;
|
||||
bool m_continue_search = false;
|
||||
};
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "DolphinWX/Debugger/WatchWindow.h"
|
||||
#include "DolphinWX/Frame.h"
|
||||
#include "DolphinWX/Globals.h"
|
||||
#include "DolphinWX/Main.h"
|
||||
#include "DolphinWX/WxUtils.h"
|
||||
|
||||
// F-zero 80005e60 wtf??
|
||||
|
@ -466,7 +467,7 @@ CRegisterView::CRegisterView(wxWindow* parent, wxWindowID id) : wxGrid(parent, i
|
|||
AutoSizeColumns();
|
||||
}
|
||||
|
||||
void CRegisterView::Update()
|
||||
void CRegisterView::Repopulate()
|
||||
{
|
||||
m_register_table->UpdateCachedRegs();
|
||||
ForceRefresh();
|
||||
|
@ -507,10 +508,11 @@ void CRegisterView::OnMouseDownR(wxGridEvent& event)
|
|||
|
||||
void CRegisterView::OnPopupMenu(wxCommandEvent& event)
|
||||
{
|
||||
CFrame* main_frame = static_cast<CFrame*>(GetGrandParent()->GetParent());
|
||||
CCodeWindow* code_window = main_frame->g_pCodeWindow;
|
||||
CWatchWindow* watch_window = code_window->m_WatchWindow;
|
||||
CMemoryWindow* memory_window = code_window->m_MemoryWindow;
|
||||
// FIXME: This is terrible. Generate events instead.
|
||||
CFrame* cframe = wxGetApp().GetCFrame();
|
||||
CCodeWindow* code_window = cframe->g_pCodeWindow;
|
||||
CWatchWindow* watch_window = code_window->GetPanel<CWatchWindow>();
|
||||
CMemoryWindow* memory_window = code_window->GetPanel<CMemoryWindow>();
|
||||
|
||||
switch (event.GetId())
|
||||
{
|
||||
|
|
|
@ -51,7 +51,7 @@ public:
|
|||
void UpdateCachedRegs();
|
||||
|
||||
private:
|
||||
static constexpr size_t NUM_SPECIALS = 14;
|
||||
static constexpr int NUM_SPECIALS = 14;
|
||||
|
||||
std::array<u32, 32> m_CachedRegs{};
|
||||
std::array<u32, NUM_SPECIALS> m_CachedSpecialRegs{};
|
||||
|
@ -72,7 +72,7 @@ class CRegisterView : public wxGrid
|
|||
{
|
||||
public:
|
||||
CRegisterView(wxWindow* parent, wxWindowID id = wxID_ANY);
|
||||
void Update() override;
|
||||
void Repopulate();
|
||||
|
||||
private:
|
||||
void OnMouseDownR(wxGridEvent& event);
|
||||
|
|
|
@ -21,7 +21,7 @@ void CRegisterWindow::CreateGUIControls()
|
|||
{
|
||||
wxBoxSizer* sGrid = new wxBoxSizer(wxVERTICAL);
|
||||
m_GPRGridView = new CRegisterView(this);
|
||||
sGrid->Add(m_GPRGridView, 1, wxGROW);
|
||||
sGrid->Add(m_GPRGridView, 1, wxEXPAND);
|
||||
SetSizer(sGrid);
|
||||
|
||||
NotifyUpdate();
|
||||
|
@ -30,5 +30,5 @@ void CRegisterWindow::CreateGUIControls()
|
|||
void CRegisterWindow::NotifyUpdate()
|
||||
{
|
||||
if (m_GPRGridView != nullptr)
|
||||
m_GPRGridView->Update();
|
||||
m_GPRGridView->Repopulate();
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "DolphinWX/Debugger/WatchView.h"
|
||||
#include "DolphinWX/Debugger/WatchWindow.h"
|
||||
#include "DolphinWX/Frame.h"
|
||||
#include "DolphinWX/Main.h"
|
||||
#include "DolphinWX/WxUtils.h"
|
||||
|
||||
enum
|
||||
|
@ -232,7 +233,7 @@ CWatchView::CWatchView(wxWindow* parent, wxWindowID id) : wxGrid(parent, id)
|
|||
Bind(wxEVT_MENU, &CWatchView::OnPopupMenu, this);
|
||||
}
|
||||
|
||||
void CWatchView::Update()
|
||||
void CWatchView::Repopulate()
|
||||
{
|
||||
if (Core::IsRunning())
|
||||
{
|
||||
|
@ -269,11 +270,12 @@ void CWatchView::OnMouseDownR(wxGridEvent& event)
|
|||
|
||||
void CWatchView::OnPopupMenu(wxCommandEvent& event)
|
||||
{
|
||||
CFrame* main_frame = static_cast<CFrame*>(GetGrandParent()->GetParent());
|
||||
CCodeWindow* code_window = main_frame->g_pCodeWindow;
|
||||
CWatchWindow* watch_window = code_window->m_WatchWindow;
|
||||
CMemoryWindow* memory_window = code_window->m_MemoryWindow;
|
||||
CBreakPointWindow* breakpoint_window = code_window->m_BreakpointWindow;
|
||||
// FIXME: This is terrible. Generate events instead.
|
||||
CFrame* cframe = wxGetApp().GetCFrame();
|
||||
CCodeWindow* code_window = cframe->g_pCodeWindow;
|
||||
CWatchWindow* watch_window = code_window->GetPanel<CWatchWindow>();
|
||||
CMemoryWindow* memory_window = code_window->GetPanel<CMemoryWindow>();
|
||||
CBreakPointWindow* breakpoint_window = code_window->GetPanel<CBreakPointWindow>();
|
||||
|
||||
wxString strNewVal;
|
||||
TMemCheck MemCheck;
|
||||
|
|
|
@ -37,7 +37,7 @@ class CWatchView : public wxGrid
|
|||
{
|
||||
public:
|
||||
CWatchView(wxWindow* parent, wxWindowID id = wxID_ANY);
|
||||
void Update() override;
|
||||
void Repopulate();
|
||||
|
||||
private:
|
||||
void OnMouseDownR(wxGridEvent& event);
|
||||
|
|
|
@ -25,9 +25,12 @@ public:
|
|||
: DolphinAuiToolBar(parent, id, wxDefaultPosition, wxDefaultSize,
|
||||
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]);
|
||||
Bind(wxEVT_TOOL, &CWatchWindow::Event_LoadAll, parent, ID_LOAD);
|
||||
|
@ -80,7 +83,7 @@ CWatchWindow::~CWatchWindow()
|
|||
void CWatchWindow::NotifyUpdate()
|
||||
{
|
||||
if (m_GPRGridView != nullptr)
|
||||
m_GPRGridView->Update();
|
||||
m_GPRGridView->Repopulate();
|
||||
}
|
||||
|
||||
void CWatchWindow::Event_SaveAll(wxCommandEvent& WXUNUSED(event))
|
||||
|
|
|
@ -323,14 +323,9 @@ EVT_MOVE(CFrame::OnMove)
|
|||
EVT_HOST_COMMAND(wxID_ANY, CFrame::OnHostMessage)
|
||||
|
||||
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
|
||||
EVT_MENU_RANGE(IDM_INTERPRETER, IDM_ADDRBOX, CFrame::PostEvent)
|
||||
EVT_TEXT(IDM_ADDRBOX, CFrame::PostEvent)
|
||||
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
@ -643,11 +638,10 @@ void CFrame::OnClose(wxCloseEvent& event)
|
|||
}
|
||||
else
|
||||
{
|
||||
// Close the log window now so that its settings are saved
|
||||
if (m_LogWindow)
|
||||
m_LogWindow->Close();
|
||||
m_LogWindow = nullptr;
|
||||
m_LogWindow->SaveSettings();
|
||||
}
|
||||
if (m_LogWindow)
|
||||
m_LogWindow->RemoveAllListeners();
|
||||
|
||||
// Uninit
|
||||
m_Mgr->UnInit();
|
||||
|
@ -745,6 +739,11 @@ void CFrame::OnHostMessage(wxCommandEvent& event)
|
|||
{
|
||||
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:
|
||||
UpdateGUI();
|
||||
break;
|
||||
|
@ -826,33 +825,29 @@ void CFrame::OnHostMessage(wxCommandEvent& event)
|
|||
|
||||
void CFrame::OnRenderWindowSizeRequest(int width, int height)
|
||||
{
|
||||
if (!Core::IsRunning() || !SConfig::GetInstance().bRenderWindowAutoSize ||
|
||||
if (!SConfig::GetInstance().bRenderWindowAutoSize || !Core::IsRunning() ||
|
||||
RendererIsFullscreen() || m_RenderFrame->IsMaximized())
|
||||
return;
|
||||
|
||||
int old_width, old_height, log_width = 0, log_height = 0;
|
||||
m_RenderFrame->GetClientSize(&old_width, &old_height);
|
||||
wxSize requested_size(width, 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 && (SConfig::GetInstance().m_InterfaceLogWindow ||
|
||||
SConfig::GetInstance().m_InterfaceLogConfigWindow) &&
|
||||
!m_Mgr->GetPane("Pane 1").IsFloating())
|
||||
if (!SConfig::GetInstance().bRenderToMain)
|
||||
{
|
||||
switch (m_Mgr->GetPane("Pane 1").dock_direction)
|
||||
{
|
||||
case wxAUI_DOCK_LEFT:
|
||||
case wxAUI_DOCK_RIGHT:
|
||||
log_width = m_Mgr->GetPane("Pane 1").rect.GetWidth();
|
||||
break;
|
||||
case wxAUI_DOCK_TOP:
|
||||
case wxAUI_DOCK_BOTTOM:
|
||||
log_height = m_Mgr->GetPane("Pane 1").rect.GetHeight();
|
||||
break;
|
||||
}
|
||||
old_size = m_RenderFrame->GetClientSize();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Resize for the render panel only, this implicitly retains space for everything else
|
||||
// (i.e. log panel, toolbar, statusbar, etc) without needing to compute for them.
|
||||
old_size = m_RenderParent->GetSize();
|
||||
}
|
||||
|
||||
if (old_width != width + log_width || old_height != height + log_height)
|
||||
m_RenderFrame->SetClientSize(width + log_width, height + log_height);
|
||||
wxSize diff = requested_size - old_size;
|
||||
if (diff != wxSize())
|
||||
m_RenderFrame->SetSize(m_RenderFrame->GetSize() + diff);
|
||||
}
|
||||
|
||||
bool CFrame::RendererHasFocus()
|
||||
|
|
|
@ -46,7 +46,7 @@ class CRenderFrame : public wxFrame
|
|||
public:
|
||||
CRenderFrame(wxFrame* parent, wxWindowID id = wxID_ANY, const wxString& title = "Dolphin",
|
||||
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;
|
||||
|
||||
|
@ -130,7 +130,7 @@ public:
|
|||
wxToolBar* m_ToolBar = nullptr;
|
||||
// AUI
|
||||
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)
|
||||
void DoAddPage(wxWindow* Win, int i, bool Float);
|
||||
|
@ -211,12 +211,12 @@ private:
|
|||
|
||||
// Perspectives
|
||||
void AddRemoveBlankPage();
|
||||
void OnNotebookPageClose(wxAuiNotebookEvent& event);
|
||||
void OnAllowNotebookDnD(wxAuiNotebookEvent& event);
|
||||
void OnNotebookAllowDnD(wxAuiNotebookEvent& event);
|
||||
void OnNotebookPageChanged(wxAuiNotebookEvent& event);
|
||||
void OnNotebookPageClose(wxAuiNotebookEvent& event);
|
||||
void OnNotebookTabRightUp(wxAuiNotebookEvent& event);
|
||||
void OnFloatWindow(wxCommandEvent& event);
|
||||
void ToggleFloatWindow(int Id);
|
||||
void OnTab(wxAuiNotebookEvent& event);
|
||||
int GetNotebookAffiliation(wxWindowID Id);
|
||||
void ClosePages();
|
||||
void CloseAllNotebooks();
|
||||
|
@ -228,7 +228,6 @@ private:
|
|||
// Float window
|
||||
void DoUnfloatPage(int Id);
|
||||
void OnFloatingPageClosed(wxCloseEvent& event);
|
||||
void OnFloatingPageSize(wxSizeEvent& event);
|
||||
void DoFloatNotebookPage(wxWindowID Id);
|
||||
wxFrame* CreateParentFrame(wxWindowID Id = wxID_ANY, const wxString& title = "",
|
||||
wxWindow* = nullptr);
|
||||
|
|
|
@ -152,41 +152,22 @@ void CFrame::ToggleLogConfigWindow(bool bShow)
|
|||
|
||||
void CFrame::OnToggleWindow(wxCommandEvent& event)
|
||||
{
|
||||
bool bShow = GetMenuBar()->IsChecked(event.GetId());
|
||||
bool show = GetMenuBar()->IsChecked(event.GetId());
|
||||
|
||||
switch (event.GetId())
|
||||
{
|
||||
case IDM_LOG_WINDOW:
|
||||
if (!g_pCodeWindow)
|
||||
SConfig::GetInstance().m_InterfaceLogWindow = bShow;
|
||||
ToggleLogWindow(bShow);
|
||||
SConfig::GetInstance().m_InterfaceLogWindow = show;
|
||||
ToggleLogWindow(show);
|
||||
break;
|
||||
case IDM_LOG_CONFIG_WINDOW:
|
||||
if (!g_pCodeWindow)
|
||||
SConfig::GetInstance().m_InterfaceLogConfigWindow = bShow;
|
||||
ToggleLogConfigWindow(bShow);
|
||||
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);
|
||||
SConfig::GetInstance().m_InterfaceLogConfigWindow = show;
|
||||
ToggleLogConfigWindow(show);
|
||||
break;
|
||||
default:
|
||||
g_pCodeWindow->TogglePanel(event.GetId(), show);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,20 +180,21 @@ void CFrame::ClosePages()
|
|||
|
||||
if (g_pCodeWindow)
|
||||
{
|
||||
g_pCodeWindow->ToggleCodeWindow(false);
|
||||
g_pCodeWindow->ToggleRegisterWindow(false);
|
||||
g_pCodeWindow->ToggleWatchWindow(false);
|
||||
g_pCodeWindow->ToggleBreakPointWindow(false);
|
||||
g_pCodeWindow->ToggleMemoryWindow(false);
|
||||
g_pCodeWindow->ToggleJitWindow(false);
|
||||
g_pCodeWindow->ToggleSoundWindow(false);
|
||||
g_pCodeWindow->ToggleVideoWindow(false);
|
||||
for (int i = IDM_REGISTER_WINDOW; i < IDM_DEBUG_WINDOW_LIST_END; ++i)
|
||||
{
|
||||
g_pCodeWindow->TogglePanel(i, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CFrame::OnNotebookPageChanged(wxAuiNotebookEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
// Event is intended for someone else
|
||||
if (event.GetPropagatedFrom() != nullptr)
|
||||
{
|
||||
event.Skip();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_pCodeWindow)
|
||||
return;
|
||||
|
@ -230,39 +212,45 @@ void CFrame::OnNotebookPageChanged(wxAuiNotebookEvent& event)
|
|||
|
||||
void CFrame::OnNotebookPageClose(wxAuiNotebookEvent& event)
|
||||
{
|
||||
// Event is intended for someone else
|
||||
if (event.GetPropagatedFrom() != nullptr)
|
||||
{
|
||||
event.Skip();
|
||||
return;
|
||||
}
|
||||
|
||||
// Override event
|
||||
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)
|
||||
ToggleLogWindow(false);
|
||||
if (Ctrl->GetPage(event.GetSelection())->GetId() == IDM_LOG_CONFIG_WINDOW)
|
||||
ToggleLogConfigWindow(false);
|
||||
if (Ctrl->GetPage(event.GetSelection())->GetId() == IDM_REGISTER_WINDOW)
|
||||
g_pCodeWindow->ToggleRegisterWindow(false);
|
||||
if (Ctrl->GetPage(event.GetSelection())->GetId() == IDM_WATCH_WINDOW)
|
||||
g_pCodeWindow->ToggleWatchWindow(false);
|
||||
if (Ctrl->GetPage(event.GetSelection())->GetId() == IDM_BREAKPOINT_WINDOW)
|
||||
g_pCodeWindow->ToggleBreakPointWindow(false);
|
||||
if (Ctrl->GetPage(event.GetSelection())->GetId() == IDM_JIT_WINDOW)
|
||||
g_pCodeWindow->ToggleJitWindow(false);
|
||||
if (Ctrl->GetPage(event.GetSelection())->GetId() == IDM_MEMORY_WINDOW)
|
||||
g_pCodeWindow->ToggleMemoryWindow(false);
|
||||
if (Ctrl->GetPage(event.GetSelection())->GetId() == IDM_SOUND_WINDOW)
|
||||
g_pCodeWindow->ToggleSoundWindow(false);
|
||||
if (Ctrl->GetPage(event.GetSelection())->GetId() == IDM_VIDEO_WINDOW)
|
||||
g_pCodeWindow->ToggleVideoWindow(false);
|
||||
switch (page_id)
|
||||
{
|
||||
case IDM_LOG_WINDOW:
|
||||
case IDM_LOG_CONFIG_WINDOW:
|
||||
{
|
||||
GetMenuBar()->Check(page_id, !GetMenuBar()->IsChecked(page_id));
|
||||
wxCommandEvent ev(wxEVT_MENU, page_id);
|
||||
OnToggleWindow(ev);
|
||||
break;
|
||||
}
|
||||
case IDM_CODE_WINDOW:
|
||||
break; // Code Window is not allowed to be closed
|
||||
default:
|
||||
// Check for the magic empty panel.
|
||||
if (nb->GetPageText(event.GetSelection()).IsSameAs("<>"))
|
||||
break;
|
||||
|
||||
g_pCodeWindow->TogglePanel(page_id, false);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
event.Skip();
|
||||
ToggleFloatWindow(event.GetId() - IDM_LOG_WINDOW_PARENT + IDM_FLOAT_LOG_WINDOW);
|
||||
}
|
||||
|
||||
void CFrame::OnFloatWindow(wxCommandEvent& event)
|
||||
|
@ -320,9 +308,15 @@ void CFrame::DoUnfloatPage(int Id)
|
|||
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)
|
||||
return;
|
||||
|
||||
|
@ -354,10 +348,21 @@ void CFrame::OnTab(wxAuiNotebookEvent& event)
|
|||
PopupMenu(&MenuPopup, Pt);
|
||||
}
|
||||
|
||||
void CFrame::OnAllowNotebookDnD(wxAuiNotebookEvent& event)
|
||||
void CFrame::OnNotebookAllowDnD(wxAuiNotebookEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
event.Allow();
|
||||
// NOTE: This event was sent FROM the source notebook TO the destination notebook so
|
||||
// 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()
|
||||
|
@ -391,12 +396,7 @@ void CFrame::ShowResizePane()
|
|||
void CFrame::TogglePane()
|
||||
{
|
||||
// Get the first notebook
|
||||
wxAuiNotebook* NB = nullptr;
|
||||
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;
|
||||
}
|
||||
wxAuiNotebook* NB = GetNotebookFromId(0);
|
||||
|
||||
if (NB)
|
||||
{
|
||||
|
@ -450,6 +450,7 @@ void CFrame::DoRemovePage(wxWindow* Win, bool bHide)
|
|||
{
|
||||
Win->Destroy();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -468,13 +469,17 @@ void CFrame::DoAddPage(wxWindow* Win, int i, bool Float)
|
|||
i = 0;
|
||||
|
||||
// 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;
|
||||
|
||||
if (!Float)
|
||||
{
|
||||
GetNotebookFromId(i)->AddPage(Win, Win->GetName(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
CreateParentFrame(Win->GetId() + IDM_LOG_WINDOW_PARENT - IDM_LOG_WINDOW, Win->GetName(), Win);
|
||||
}
|
||||
}
|
||||
|
||||
void CFrame::PopulateSavedPerspectives()
|
||||
|
@ -664,8 +669,7 @@ void CFrame::SetPaneSize()
|
|||
if (Perspectives.size() <= ActivePerspective)
|
||||
return;
|
||||
|
||||
int iClientX = GetSize().GetX();
|
||||
int iClientY = GetSize().GetY();
|
||||
wxSize client_size = GetClientSize();
|
||||
|
||||
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);
|
||||
|
||||
// Convert percentages to pixel lengths
|
||||
W = (W * iClientX) / 100;
|
||||
H = (H * iClientY) / 100;
|
||||
W = (W * client_size.GetWidth()) / 100;
|
||||
H = (H * client_size.GetHeight()) / 100;
|
||||
m_Mgr->GetAllPanes()[i].BestSize(W, H).MinSize(W, H);
|
||||
|
||||
j++;
|
||||
|
@ -815,7 +819,7 @@ void CFrame::UpdateCurrentPerspective()
|
|||
current->Perspective = m_Mgr->SavePerspective();
|
||||
|
||||
// Get client size
|
||||
int iClientX = GetSize().GetX(), iClientY = GetSize().GetY();
|
||||
wxSize client_size = GetClientSize();
|
||||
current->Width.clear();
|
||||
current->Height.clear();
|
||||
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)))
|
||||
{
|
||||
// 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) /
|
||||
iClientX);
|
||||
current->Height.push_back((m_Mgr->GetAllPanes()[i].window->GetClientSize().GetY() * 100) /
|
||||
iClientY);
|
||||
current->Width.push_back((m_Mgr->GetAllPanes()[i].window->GetSize().GetX() * 100) /
|
||||
client_size.GetWidth());
|
||||
current->Height.push_back((m_Mgr->GetAllPanes()[i].window->GetSize().GetY() * 100) /
|
||||
client_size.GetHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -952,23 +956,40 @@ wxFrame* CFrame::CreateParentFrame(wxWindowID Id, const wxString& Title, wxWindo
|
|||
|
||||
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);
|
||||
|
||||
// TODO: This is a good place to load window position and size settings from an INI
|
||||
|
||||
// Main sizer
|
||||
Frame->SetSizer(m_MainSizer);
|
||||
// Minimum frame size
|
||||
Frame->SetMinSize(wxSize(200, 200));
|
||||
Frame->SetSizerAndFit(m_MainSizer);
|
||||
Frame->Show();
|
||||
return Frame;
|
||||
}
|
||||
|
||||
wxAuiNotebook* CFrame::CreateEmptyNotebook()
|
||||
{
|
||||
const 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_WINDOWLIST_BUTTON | wxNO_BORDER;
|
||||
static constexpr long NOTEBOOK_STYLE = wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE |
|
||||
wxAUI_NB_CLOSE_BUTTON | wxAUI_NB_TAB_EXTERNAL_MOVE |
|
||||
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()
|
||||
|
|
|
@ -642,10 +642,10 @@ void CFrame::BootGame(const std::string& filename)
|
|||
StartGame(bootfile);
|
||||
if (UseDebugger && g_pCodeWindow)
|
||||
{
|
||||
if (g_pCodeWindow->m_WatchWindow)
|
||||
g_pCodeWindow->m_WatchWindow->LoadAll();
|
||||
if (g_pCodeWindow->m_BreakpointWindow)
|
||||
g_pCodeWindow->m_BreakpointWindow->LoadAll();
|
||||
if (g_pCodeWindow->HasPanel<CWatchWindow>())
|
||||
g_pCodeWindow->GetPanel<CWatchWindow>()->LoadAll();
|
||||
if (g_pCodeWindow->HasPanel<CBreakPointWindow>())
|
||||
g_pCodeWindow->GetPanel<CBreakPointWindow>()->LoadAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -842,7 +842,7 @@ void CFrame::OnPlay(wxCommandEvent& WXUNUSED(event))
|
|||
|
||||
wxThread::Sleep(20);
|
||||
g_pCodeWindow->JumpToAddress(PC);
|
||||
g_pCodeWindow->Update();
|
||||
g_pCodeWindow->Repopulate();
|
||||
// Update toolbar with Play/Pause status
|
||||
UpdateGUI();
|
||||
}
|
||||
|
@ -1165,18 +1165,15 @@ void CFrame::DoStop()
|
|||
|
||||
if (UseDebugger && g_pCodeWindow)
|
||||
{
|
||||
if (g_pCodeWindow->m_WatchWindow)
|
||||
{
|
||||
g_pCodeWindow->m_WatchWindow->SaveAll();
|
||||
PowerPC::watches.Clear();
|
||||
}
|
||||
if (g_pCodeWindow->m_BreakpointWindow)
|
||||
{
|
||||
g_pCodeWindow->m_BreakpointWindow->SaveAll();
|
||||
PowerPC::breakpoints.Clear();
|
||||
PowerPC::memchecks.Clear();
|
||||
g_pCodeWindow->m_BreakpointWindow->NotifyUpdate();
|
||||
}
|
||||
if (g_pCodeWindow->HasPanel<CWatchWindow>())
|
||||
g_pCodeWindow->GetPanel<CWatchWindow>()->SaveAll();
|
||||
PowerPC::watches.Clear();
|
||||
if (g_pCodeWindow->HasPanel<CBreakPointWindow>())
|
||||
g_pCodeWindow->GetPanel<CBreakPointWindow>()->SaveAll();
|
||||
PowerPC::breakpoints.Clear();
|
||||
PowerPC::memchecks.Clear();
|
||||
if (g_pCodeWindow->HasPanel<CBreakPointWindow>())
|
||||
g_pCodeWindow->GetPanel<CBreakPointWindow>()->NotifyUpdate();
|
||||
g_symbolDB.Clear();
|
||||
Host_NotifyMapLoaded();
|
||||
}
|
||||
|
|
|
@ -163,7 +163,9 @@ enum
|
|||
IDM_CONFIG_LOGGER,
|
||||
|
||||
// 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_REGISTER_WINDOW,
|
||||
IDM_WATCH_WINDOW,
|
||||
|
@ -173,9 +175,10 @@ enum
|
|||
IDM_SOUND_WINDOW,
|
||||
IDM_VIDEO_WINDOW,
|
||||
IDM_CODE_WINDOW,
|
||||
IDM_DEBUG_WINDOW_LIST_END, // Bookend for doing array lookups
|
||||
|
||||
// List Column Title Toggles
|
||||
IDM_SHOW_SYSTEM,
|
||||
IDM_SHOW_SYSTEM = IDM_DEBUG_WINDOW_LIST_END,
|
||||
IDM_SHOW_BANNER,
|
||||
IDM_SHOW_MAKER,
|
||||
IDM_SHOW_FILENAME,
|
||||
|
@ -345,6 +348,7 @@ enum
|
|||
// custom message macro
|
||||
#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);
|
||||
|
||||
// Sent to wxTheApp
|
||||
|
|
|
@ -25,18 +25,11 @@ LogConfigWindow::LogConfigWindow(wxWindow* parent, wxWindowID id)
|
|||
_("Log Configuration")),
|
||||
enableAll(true)
|
||||
{
|
||||
Bind(wxEVT_CLOSE_WINDOW, &LogConfigWindow::OnClose, this);
|
||||
SetMinSize(wxSize(100, 100));
|
||||
m_LogManager = LogManager::GetInstance();
|
||||
CreateGUIControls();
|
||||
LoadSettings();
|
||||
}
|
||||
|
||||
void LogConfigWindow::OnClose(wxCloseEvent& event)
|
||||
{
|
||||
SaveSettings();
|
||||
}
|
||||
|
||||
void LogConfigWindow::CreateGUIControls()
|
||||
{
|
||||
// Verbosity
|
||||
|
@ -68,23 +61,26 @@ void LogConfigWindow::CreateGUIControls()
|
|||
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
|
||||
m_checks->Append(StrToWxStr(m_LogManager->GetFullName((LogTypes::LOG_TYPE)i)));
|
||||
|
||||
const int space1 = FromDIP(1);
|
||||
const int space5 = FromDIP(5);
|
||||
|
||||
// Sizers
|
||||
wxStaticBoxSizer* sbOutputs = new wxStaticBoxSizer(wxVERTICAL, this, _("Logger Outputs"));
|
||||
sbOutputs->Add(m_writeFileCB, 0, wxDOWN, 1);
|
||||
sbOutputs->Add(m_writeConsoleCB, 0, wxDOWN, 1);
|
||||
sbOutputs->Add(m_writeWindowCB, 0);
|
||||
sbOutputs->Add(m_writeFileCB, 0);
|
||||
sbOutputs->Add(m_writeConsoleCB, 0, wxTOP, space1);
|
||||
sbOutputs->Add(m_writeWindowCB, 0, wxTOP, space1);
|
||||
|
||||
wxStaticBoxSizer* sbLogTypes = new wxStaticBoxSizer(wxVERTICAL, this, _("Log Types"));
|
||||
sbLogTypes->Add(m_checks, 1, wxEXPAND);
|
||||
|
||||
wxBoxSizer* sMain = new wxBoxSizer(wxVERTICAL);
|
||||
sMain->Add(m_verbosity, 0, wxEXPAND | wxLEFT | wxRIGHT, 5);
|
||||
sMain->Add(sbOutputs, 0, wxEXPAND | wxLEFT | wxRIGHT, 5);
|
||||
sMain->Add(btn_toggle_all, 0, wxEXPAND | wxLEFT | wxRIGHT, 5);
|
||||
sMain->Add(sbLogTypes, 1, wxEXPAND | wxLEFT | wxRIGHT, 5);
|
||||
sMain->Add(m_verbosity, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
|
||||
sMain->Add(sbOutputs, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
|
||||
sMain->Add(btn_toggle_all, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
|
||||
sMain->Add(sbLogTypes, 1, wxEXPAND | wxLEFT | wxRIGHT, space5);
|
||||
|
||||
SetSizer(sMain);
|
||||
Layout();
|
||||
sMain->SetMinSize(FromDIP(wxSize(100, 100)));
|
||||
SetSizerAndFit(sMain);
|
||||
}
|
||||
|
||||
void LogConfigWindow::LoadSettings()
|
||||
|
|
|
@ -31,7 +31,6 @@ private:
|
|||
|
||||
void CreateGUIControls();
|
||||
void OnVerbosityChange(wxCommandEvent& event);
|
||||
void OnClose(wxCloseEvent& event);
|
||||
void OnWriteFileChecked(wxCommandEvent& event);
|
||||
void OnWriteConsoleChecked(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),
|
||||
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);
|
||||
|
||||
m_LogManager = LogManager::GetInstance();
|
||||
|
@ -94,6 +93,7 @@ void CLogWindow::CreateGUIControls()
|
|||
|
||||
m_LogManager->SetLogLevel((LogTypes::LOG_TYPE)i, (LogTypes::LOG_LEVELS)(verbosity));
|
||||
}
|
||||
m_has_listeners = true;
|
||||
|
||||
// Font
|
||||
m_FontChoice = new wxChoice(this, wxID_ANY);
|
||||
|
@ -132,11 +132,13 @@ void CLogWindow::CreateGUIControls()
|
|||
new wxButton(this, wxID_ANY, _("Clear"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
|
||||
m_clear_log_btn->Bind(wxEVT_BUTTON, &CLogWindow::OnClear, this);
|
||||
|
||||
const int space3 = FromDIP(3);
|
||||
|
||||
// Sizers
|
||||
wxBoxSizer* sTop = new wxBoxSizer(wxHORIZONTAL);
|
||||
sTop->Add(m_clear_log_btn);
|
||||
sTop->Add(m_FontChoice, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 3);
|
||||
sTop->Add(m_WrapLine, 0, wxALIGN_CENTER_VERTICAL);
|
||||
sTop->Add(m_clear_log_btn, 0, wxALIGN_CENTER_VERTICAL);
|
||||
sTop->Add(m_FontChoice, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, space3);
|
||||
sTop->Add(m_WrapLine, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, space3);
|
||||
|
||||
sBottom = new wxBoxSizer(wxVERTICAL);
|
||||
PopulateBottom();
|
||||
|
@ -149,15 +151,17 @@ void CLogWindow::CreateGUIControls()
|
|||
m_cmdline->SetFocus();
|
||||
}
|
||||
|
||||
void CLogWindow::OnClose(wxCloseEvent& event)
|
||||
CLogWindow::~CLogWindow()
|
||||
{
|
||||
SaveSettings();
|
||||
event.Skip();
|
||||
RemoveAllListeners();
|
||||
}
|
||||
|
||||
void CLogWindow::RemoveAllListeners()
|
||||
{
|
||||
if (!m_has_listeners)
|
||||
return;
|
||||
m_has_listeners = false;
|
||||
|
||||
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++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,
|
||||
const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL,
|
||||
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 Log(LogTypes::LOG_LEVELS, const char* text) override;
|
||||
|
||||
|
@ -42,6 +46,7 @@ private:
|
|||
LogManager* m_LogManager;
|
||||
std::queue<std::pair<u8, wxString>> msgQueue;
|
||||
bool m_writeFile, m_writeWindow, m_LogAccess;
|
||||
bool m_has_listeners = false;
|
||||
|
||||
// Controls
|
||||
wxBoxSizer* sBottom;
|
||||
|
@ -57,11 +62,9 @@ private:
|
|||
void CreateGUIControls();
|
||||
void PopulateBottom();
|
||||
void UnPopulateBottom();
|
||||
void OnClose(wxCloseEvent& event);
|
||||
void OnFontChange(wxCommandEvent& event);
|
||||
void OnWrapLineCheck(wxCommandEvent& event);
|
||||
void OnClear(wxCommandEvent& event);
|
||||
void OnLogTimer(wxTimerEvent& WXUNUSED(event));
|
||||
void RemoveAllListeners();
|
||||
void UpdateLog();
|
||||
};
|
||||
|
|
|
@ -66,13 +66,6 @@ void ShowErrorDialog(const wxString& error_msg)
|
|||
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)
|
||||
{
|
||||
wxImage image = original.ConvertToImage();
|
||||
|
|
|
@ -29,9 +29,6 @@ void Explore(const std::string& path);
|
|||
// Displays a wxMessageBox geared for errors
|
||||
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
|
||||
wxBitmap CreateDisabledButtonBitmap(const wxBitmap& original);
|
||||
|
||||
|
|
Loading…
Reference in New Issue