mirror of https://github.com/PCSX2/pcsx2.git
Merge pull request #1070 from Kingcom/registerlist
Revert to old register list, make it scrollable
This commit is contained in:
commit
6e34f183ea
|
@ -414,13 +414,16 @@ struct Pcsx2Config
|
|||
|
||||
u8 FontWidth;
|
||||
u8 FontHeight;
|
||||
u32 WindowWidth;
|
||||
u32 WindowHeight;
|
||||
|
||||
DebugOptions();
|
||||
void LoadSave( IniInterface& conf );
|
||||
|
||||
bool operator ==( const DebugOptions& right ) const
|
||||
{
|
||||
return OpEqu( bitset ) && OpEqu( FontWidth ) && OpEqu( FontHeight );
|
||||
return OpEqu( bitset ) && OpEqu( FontWidth ) && OpEqu( FontHeight )
|
||||
&& OpEqu( WindowWidth ) && OpEqu( WindowHeight );
|
||||
}
|
||||
|
||||
bool operator !=( const DebugOptions& right ) const
|
||||
|
|
|
@ -379,6 +379,8 @@ Pcsx2Config::DebugOptions::DebugOptions()
|
|||
ShowDebuggerOnStart = false;
|
||||
FontWidth = 8;
|
||||
FontHeight = 12;
|
||||
WindowWidth = 0;
|
||||
WindowHeight = 0;
|
||||
}
|
||||
|
||||
void Pcsx2Config::DebugOptions::LoadSave( IniInterface& ini )
|
||||
|
@ -388,6 +390,8 @@ void Pcsx2Config::DebugOptions::LoadSave( IniInterface& ini )
|
|||
IniBitBool( ShowDebuggerOnStart );
|
||||
IniBitfield(FontWidth);
|
||||
IniBitfield(FontHeight);
|
||||
IniBitfield(WindowWidth);
|
||||
IniBitfield(WindowHeight);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -134,6 +134,7 @@ void SysCoreThread::Reset()
|
|||
GetVmMemory().DecommitAll();
|
||||
SysClearExecutionCache();
|
||||
sApp.PostAppMethod( &Pcsx2App::leaveDebugMode );
|
||||
g_FrameCount = 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "BreakpointWindow.h"
|
||||
#include "AppConfig.h"
|
||||
#include "System.h"
|
||||
#include "DisassemblyDialog.h"
|
||||
|
||||
#include <wx/mstream.h>
|
||||
#include <wx/clipbrd.h>
|
||||
|
@ -147,8 +148,8 @@ CtrlDisassemblyView::CtrlDisassemblyView(wxWindow* parent, DebugInterface* _cpu)
|
|||
{
|
||||
manager.setCpu(cpu);
|
||||
windowStart = 0x100000;
|
||||
rowHeight = g_Conf->EmuOptions.Debugger.FontHeight+2;
|
||||
charWidth = g_Conf->EmuOptions.Debugger.FontWidth;
|
||||
rowHeight = getDebugFontHeight()+2;
|
||||
charWidth = getDebugFontWidth();
|
||||
displaySymbols = true;
|
||||
visibleRows = 1;
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "BreakpointWindow.h"
|
||||
#include "DebugEvents.h"
|
||||
#include "DisassemblyDialog.h"
|
||||
#include <wchar.h>
|
||||
#include <wx/clipbrd.h>
|
||||
|
||||
|
@ -55,8 +56,8 @@ enum MemoryViewMenuIdentifiers
|
|||
CtrlMemView::CtrlMemView(wxWindow* parent, DebugInterface* _cpu)
|
||||
: wxWindow(parent,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxWANTS_CHARS|wxVSCROLL), cpu(_cpu)
|
||||
{
|
||||
rowHeight = g_Conf->EmuOptions.Debugger.FontHeight;
|
||||
charWidth = g_Conf->EmuOptions.Debugger.FontWidth;
|
||||
rowHeight = getDebugFontHeight();
|
||||
charWidth = getDebugFontWidth();
|
||||
windowStart = 0x480000;
|
||||
curAddress = windowStart;
|
||||
rowSize = 16;
|
||||
|
|
|
@ -16,456 +16,547 @@
|
|||
#include "PrecompiledHeader.h"
|
||||
#include "CtrlRegisterList.h"
|
||||
#include "DebugTools/Debug.h"
|
||||
|
||||
#include "DebugEvents.h"
|
||||
#include "AppConfig.h"
|
||||
#include "DisassemblyDialog.h"
|
||||
|
||||
BEGIN_EVENT_TABLE(CtrlRegisterList, wxWindow)
|
||||
EVT_PAINT(CtrlRegisterList::paintEvent)
|
||||
EVT_GRID_LABEL_LEFT_CLICK(CtrlRegisterList::gridEvent)
|
||||
EVT_GRID_LABEL_RIGHT_CLICK(CtrlRegisterList::gridEvent)
|
||||
EVT_GRID_CELL_LEFT_CLICK(CtrlRegisterList::gridEvent)
|
||||
EVT_GRID_CELL_RIGHT_CLICK(CtrlRegisterList::gridEvent)
|
||||
EVT_KEY_DOWN(CtrlRegisterList::keydownEvent)
|
||||
EVT_BOOKCTRL_PAGE_CHANGED(-1, CtrlRegisterList::categoryChangedEvent)
|
||||
EVT_SIZE(CtrlRegisterList::sizeEvent)
|
||||
EVT_LEFT_DOWN(CtrlRegisterList::mouseEvent)
|
||||
EVT_RIGHT_DOWN(CtrlRegisterList::mouseEvent)
|
||||
EVT_RIGHT_UP(CtrlRegisterList::mouseEvent)
|
||||
EVT_MOTION(CtrlRegisterList::mouseEvent)
|
||||
EVT_KEY_DOWN(CtrlRegisterList::keydownEvent)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
enum DisassemblyMenuIdentifiers
|
||||
{
|
||||
ID_REGISTERLIST_DISPLAY32 = 1,
|
||||
ID_REGISTERLIST_DISPLAY64,
|
||||
ID_REGISTERLIST_DISPLAY128,
|
||||
ID_REGISTERLIST_CHANGELOWER,
|
||||
ID_REGISTERLIST_CHANGEUPPER,
|
||||
ID_REGISTERLIST_CHANGEVALUE
|
||||
ID_REGISTERLIST_DISPLAY32 = 1,
|
||||
ID_REGISTERLIST_DISPLAY64,
|
||||
ID_REGISTERLIST_DISPLAY128,
|
||||
ID_REGISTERLIST_CHANGELOWER,
|
||||
ID_REGISTERLIST_CHANGEUPPER,
|
||||
ID_REGISTERLIST_CHANGEVALUE
|
||||
};
|
||||
|
||||
CtrlRegisterList::CtrlRegisterList(wxWindow* parent, DebugInterface* _cpu) :
|
||||
wxWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS | wxBORDER_NONE),
|
||||
cpu(_cpu),
|
||||
lastPc(0),
|
||||
lastCycles(0),
|
||||
maxBits(128),
|
||||
needsSizeUpdating(true),
|
||||
needsValueUpdating(true)
|
||||
|
||||
CtrlRegisterList::CtrlRegisterList(wxWindow* parent, DebugInterface* _cpu)
|
||||
: wxScrolledWindow(parent,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxWANTS_CHARS|wxBORDER_NONE|wxVSCROLL), cpu(_cpu)
|
||||
{
|
||||
int rowHeight = g_Conf->EmuOptions.Debugger.FontHeight;
|
||||
int charWidth = g_Conf->EmuOptions.Debugger.FontWidth;
|
||||
rowHeight = getDebugFontHeight()+2;
|
||||
charWidth = getDebugFontWidth();
|
||||
category = 0;
|
||||
maxBits = 128;
|
||||
lastPc = 0xFFFFFFFF;
|
||||
|
||||
for (int i = 0; i < cpu->getRegisterCategoryCount(); i++)
|
||||
{
|
||||
int count = cpu->getRegisterCount(i);
|
||||
|
||||
#ifdef _WIN32
|
||||
wxFont font = wxFont(wxSize(charWidth, rowHeight), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL,
|
||||
false, L"Lucida Console");
|
||||
wxFont labelFont = font.Bold();
|
||||
#else
|
||||
wxFont font = wxFont(8, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, L"Lucida Console");
|
||||
font.SetPixelSize(wxSize(charWidth, rowHeight));
|
||||
wxFont labelFont = font;
|
||||
labelFont.SetWeight(wxFONTWEIGHT_BOLD);
|
||||
#endif
|
||||
registerCategories = new wxNotebook(this, wxID_ANY);
|
||||
// 'c' and 'C', much time wasted.
|
||||
#if wxMAJOR_VERSION >= 3
|
||||
registerCategories->Connect(wxEVT_BOOKCTRL_PAGE_CHANGED, wxBookCtrlEventHandler(CtrlRegisterList::categoryChangedEvent), nullptr, this);
|
||||
#else
|
||||
registerCategories->Connect(wxEVT_COMMAND_BOOKCTRL_PAGE_CHANGED, wxBookctrlEventHandler(CtrlRegisterList::categoryChangedEvent), nullptr, this);
|
||||
#endif
|
||||
for (int cat = 0; cat < cpu->getRegisterCategoryCount(); cat++)
|
||||
{
|
||||
int numRegs = cpu->getRegisterCount(cat);
|
||||
ChangedReg* regs = new ChangedReg[count];
|
||||
memset(regs,0,sizeof(ChangedReg)*count);
|
||||
changedCategories.push_back(regs);
|
||||
|
||||
changedCategories.push_back(std::vector<ChangedReg>(numRegs));
|
||||
int maxLen = 0;
|
||||
for (int k = 0; k < cpu->getRegisterCount(i); k++)
|
||||
{
|
||||
maxLen = std::max<int>(maxLen,strlen(cpu->getRegisterName(i,k)));
|
||||
}
|
||||
|
||||
wxGrid* regGrid = new wxGrid(registerCategories, -1);
|
||||
int x = 17+(maxLen+3)*charWidth;
|
||||
startPositions.push_back(x);
|
||||
currentRows.push_back(0);
|
||||
}
|
||||
|
||||
registerGrids.push_back(regGrid);
|
||||
registerCategories->AddPage(regGrid, wxString(cpu->getRegisterCategoryName(cat), wxConvUTF8));
|
||||
SetDoubleBuffered(true);
|
||||
SetInitialSize(ClientToWindowSize(GetMinClientSize()));
|
||||
|
||||
DebugInterface::RegisterType type = cpu->getRegisterType(cat);
|
||||
int registerBits = cpu->getRegisterSize(cat);
|
||||
|
||||
int numCols;
|
||||
switch (type)
|
||||
{
|
||||
case DebugInterface::NORMAL: // display them in 32 bit parts
|
||||
numCols = registerBits / 32;
|
||||
regGrid->CreateGrid(numRegs, numCols);
|
||||
for (int row = 0; row < numRegs; row++)
|
||||
regGrid->SetRowLabelValue(row, wxString(cpu->getRegisterName(cat, row), wxConvUTF8));
|
||||
for (int col = 0; col < numCols; col++)
|
||||
regGrid->SetColLabelValue(col, wxsFormat(L"%d-%d", 32 * (numCols - col) - 1, 32 * (numCols - col - 1)));
|
||||
break;
|
||||
case DebugInterface::SPECIAL:
|
||||
regGrid->CreateGrid(numRegs, 1);
|
||||
for (int row = 0; row < numRegs; row++)
|
||||
regGrid->SetRowLabelValue(row, wxString(cpu->getRegisterName(cat, row), wxConvUTF8));
|
||||
break;
|
||||
}
|
||||
|
||||
regGrid->EnableEditing(false);
|
||||
regGrid->SetDefaultCellFont(font);
|
||||
regGrid->SetLabelFont(labelFont);
|
||||
regGrid->DisableDragGridSize();
|
||||
regGrid->DisableDragRowSize();
|
||||
regGrid->DisableDragColSize();
|
||||
regGrid->Connect(wxEVT_PAINT, wxPaintEventHandler(CtrlRegisterList::paintEvent), nullptr, this);
|
||||
regGrid->Connect(wxEVT_GRID_LABEL_LEFT_CLICK, wxGridEventHandler(CtrlRegisterList::gridEvent), nullptr, this);
|
||||
regGrid->Connect(wxEVT_GRID_LABEL_RIGHT_CLICK, wxGridEventHandler(CtrlRegisterList::gridEvent), nullptr, this);
|
||||
regGrid->Connect(wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler(CtrlRegisterList::gridEvent), nullptr, this);
|
||||
regGrid->Connect(wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler(CtrlRegisterList::gridEvent), nullptr, this);
|
||||
regGrid->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CtrlRegisterList::keydownEvent), nullptr, this);
|
||||
}
|
||||
|
||||
for (int cat = 0; cat < cpu->getRegisterCategoryCount(); cat++)
|
||||
updateValues(cat);
|
||||
|
||||
updateSize(getCurrentCategory()); // getCurrentCategory() = 0
|
||||
|
||||
SetDoubleBuffered(true);
|
||||
wxSize actualSize = getOptimalSize();
|
||||
SetVirtualSize(actualSize);
|
||||
SetScrollbars(1, rowHeight, actualSize.x, actualSize.y / rowHeight, 0, 0);
|
||||
}
|
||||
|
||||
// Called when this window needs to update the strings in the cells.
|
||||
// This has to be called every repaint of the window since the registers
|
||||
// can change unpredictably and there seems to be currently is no mechanism
|
||||
// for the rest of pcsx2 alerting the debugger when values change.
|
||||
void CtrlRegisterList::updateValues(int cat)
|
||||
wxSize CtrlRegisterList::getOptimalSize() const
|
||||
{
|
||||
wxGrid* regGrid = registerGrids[cat];
|
||||
int numRows = regGrid->GetNumberRows();
|
||||
int numCols = regGrid->GetNumberCols();
|
||||
int columnChars = 0;
|
||||
int maxWidth = 0;
|
||||
int maxRows = 0;
|
||||
|
||||
std::vector<ChangedReg>& changedRegs = changedCategories[cat];
|
||||
DebugInterface::RegisterType type = cpu->getRegisterType(cat);
|
||||
for (int row = 0; row < numRows; row++)
|
||||
{
|
||||
wxColor bgColor = regGrid->GetGridCursorRow() == row ? wxColor(0xFFFFDFE0) :
|
||||
wxColor(0xFFFFEFFF);
|
||||
u128 value = cpu->getRegister(cat, row);
|
||||
ChangedReg& changed = changedRegs[row];
|
||||
for (int i = 0; i < cpu->getRegisterCategoryCount(); i++)
|
||||
{
|
||||
int bits = std::min<u32>(maxBits, cpu->getRegisterSize(i));
|
||||
int start = startPositions[i];
|
||||
|
||||
for (int col = 0; col < numCols; col++)
|
||||
{
|
||||
const wxColor colorChanged = wxColor(0xFF0000FF);
|
||||
const wxColor colorUnchanged = wxColor(0xFF004000);
|
||||
wxColor textColor;
|
||||
wxString cellValue;
|
||||
int w = start + (bits / 4) * charWidth;
|
||||
if (bits > 32)
|
||||
w += (bits / 32) * 2 - 2;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DebugInterface::NORMAL:
|
||||
cellValue = wxsFormat(L"%08X", value._u32[numCols - col - 1]);
|
||||
textColor = changed.changed[numCols - col - 1] ? colorChanged : colorUnchanged;
|
||||
break;
|
||||
case DebugInterface::SPECIAL:
|
||||
cellValue = cpu->getRegisterString(cat, row);
|
||||
textColor = (changed.changed[0] || changed.changed[1] || changed.changed[2] || changed.changed[3]) ?
|
||||
colorChanged : colorUnchanged;
|
||||
break;
|
||||
default: pxAssert(0 && "Unreachable switch case");
|
||||
}
|
||||
if (regGrid->GetCellTextColour(row, col) != textColor)
|
||||
regGrid->SetCellTextColour(row, col, textColor);
|
||||
if (regGrid->GetCellValue(row, col) != cellValue)
|
||||
regGrid->SetCellValue(row, col, cellValue);
|
||||
if (regGrid->GetCellBackgroundColour(row, col) != bgColor)
|
||||
regGrid->SetCellBackgroundColour(row, col, bgColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
maxWidth = std::max<int>(maxWidth, w);
|
||||
columnChars += strlen(cpu->getRegisterCategoryName(i)) + 1;
|
||||
maxRows = std::max<int>(maxRows, cpu->getRegisterCount(i));
|
||||
}
|
||||
|
||||
void CtrlRegisterList::updateSize(int cat)
|
||||
{
|
||||
wxGrid* regGrid = registerGrids[cat];
|
||||
maxWidth = std::max<int>(columnChars*charWidth, maxWidth + 4);
|
||||
|
||||
int regBits = cpu->getRegisterSize(cat);
|
||||
int numCols = regGrid->GetNumberCols();
|
||||
|
||||
#if wxMAJOR_VERSION >= 3
|
||||
int shownCols = 0;
|
||||
while (shownCols < numCols && regGrid->IsColShown(shownCols)) shownCols++;
|
||||
if (shownCols > maxBits / 32)
|
||||
shownCols = (maxBits / 32);
|
||||
else if (shownCols < regBits / 32)
|
||||
shownCols = std::min(maxBits / 32, regBits / 32);
|
||||
|
||||
for (int col = 0; col < numCols; col++)
|
||||
if (col < shownCols)
|
||||
regGrid->ShowCol(numCols - col - 1); // Big-endian representation so flip order
|
||||
else
|
||||
regGrid->HideCol(numCols - col - 1); // Big-endian representation so flip order
|
||||
#endif
|
||||
|
||||
regGrid->AutoSize();
|
||||
wxSize pageSize = regGrid->GetSize();
|
||||
|
||||
// Hack: Sometimes the vertical scroll bar covers some of the text so add some room
|
||||
pageSize.x += 20;
|
||||
|
||||
// Hack: AFAIK wxNotebook does not provide a way to get the necessary size
|
||||
// for the tabs so we use a rough approximation and hope that the tabs
|
||||
// will have enough room to all be shown. 50 pixels per tab should hopefully work.
|
||||
int minX = registerCategories->GetPageCount() * 50;
|
||||
pageSize.x = std::max(pageSize.x, minX);
|
||||
|
||||
// Hack: Sometimes showing all the rows on the screen take up too much
|
||||
// vertical room and squeezes other components (breakpoint window, etc.)
|
||||
// into nothing so we limit the vertical size with this heuristic.
|
||||
// If necessary, this will automatically create a vertical scroll bar so
|
||||
// all rows can be accessed.
|
||||
int screenSize = wxSystemSettings::GetMetric(wxSYS_SCREEN_Y);
|
||||
pageSize.y = std::min(std::max(screenSize - 400, screenSize / 2), pageSize.y);
|
||||
|
||||
regGrid->SetSize(pageSize);
|
||||
|
||||
wxSize size = registerCategories->CalcSizeFromPage(pageSize);
|
||||
if (registerCategories->GetSize() != size)
|
||||
registerCategories->SetSize(size);
|
||||
SetMinSize(size); // registerCategories is the whole window so same min-size
|
||||
|
||||
// Need to update the whole debugger window since other components
|
||||
// may be resized due to this component being resized
|
||||
postEvent(debEVT_UPDATELAYOUT, 0);
|
||||
return wxSize(maxWidth, (maxRows + 1)*rowHeight);
|
||||
}
|
||||
|
||||
void CtrlRegisterList::postEvent(wxEventType type, wxString text)
|
||||
{
|
||||
wxCommandEvent event(type, GetId());
|
||||
event.SetEventObject(this);
|
||||
event.SetString(text);
|
||||
wxPostEvent(this, event);
|
||||
wxCommandEvent event( type, GetId() );
|
||||
event.SetEventObject(this);
|
||||
event.SetString(text);
|
||||
wxPostEvent(this,event);
|
||||
}
|
||||
|
||||
void CtrlRegisterList::postEvent(wxEventType type, int value)
|
||||
{
|
||||
wxCommandEvent event(type, GetId());
|
||||
event.SetEventObject(this);
|
||||
event.SetInt(value);
|
||||
wxPostEvent(this, event);
|
||||
wxCommandEvent event( type, GetId() );
|
||||
event.SetEventObject(this);
|
||||
event.SetInt(value);
|
||||
wxPostEvent(this,event);
|
||||
}
|
||||
|
||||
|
||||
// Sets the "changed" flag for values that have changed from the last cycle.
|
||||
// These values are colored differently when they are displayed.
|
||||
void CtrlRegisterList::refreshChangedRegs()
|
||||
{
|
||||
if (cpu->getPC() == lastPc && cpu->getCycles() == lastCycles)
|
||||
return;
|
||||
if (cpu->getPC() == lastPc)
|
||||
return;
|
||||
|
||||
for (int cat = 0; cat < cpu->getRegisterCategoryCount(); cat++)
|
||||
{
|
||||
std::vector<ChangedReg>& regs = changedCategories[cat];
|
||||
int size = cpu->getRegisterSize(cat);
|
||||
for (size_t cat = 0; cat < changedCategories.size(); cat++)
|
||||
{
|
||||
ChangedReg* regs = changedCategories[cat];
|
||||
int size = cpu->getRegisterSize(category);
|
||||
|
||||
for (int i = 0; i < cpu->getRegisterCount(cat); i++)
|
||||
{
|
||||
ChangedReg& reg = regs[i];
|
||||
memset(®.changed, 0, sizeof(reg.changed));
|
||||
for (int i = 0; i < cpu->getRegisterCount(cat); i++)
|
||||
{
|
||||
ChangedReg& reg = regs[i];
|
||||
memset(®.changed,0,sizeof(reg.changed));
|
||||
|
||||
u128 newValue = cpu->getRegister(cat, i);
|
||||
u128 newValue = cpu->getRegister(cat,i);
|
||||
|
||||
if (reg.oldValue != newValue)
|
||||
{
|
||||
bool changed = false;
|
||||
if (reg.oldValue != newValue)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
if (size >= 128 && (reg.oldValue._u32[3] != newValue._u32[3] || reg.oldValue._u32[2] != newValue._u32[2]))
|
||||
{
|
||||
changed = true;
|
||||
reg.changed[3] = true;
|
||||
reg.changed[2] = true;
|
||||
}
|
||||
if (size >= 128 && (reg.oldValue._u32[3] != newValue._u32[3] || reg.oldValue._u32[2] != newValue._u32[2]))
|
||||
{
|
||||
changed = true;
|
||||
reg.changed[3] = true;
|
||||
reg.changed[2] = true;
|
||||
}
|
||||
|
||||
if (size >= 64 && (reg.oldValue._u32[1] != newValue._u32[1] || changed))
|
||||
{
|
||||
changed = true;
|
||||
reg.changed[1] = true;
|
||||
}
|
||||
if (size >= 64 && (reg.oldValue._u32[1] != newValue._u32[1] || changed))
|
||||
{
|
||||
changed = true;
|
||||
reg.changed[1] = true;
|
||||
}
|
||||
|
||||
if (reg.oldValue._u32[0] != newValue._u32[0] || changed)
|
||||
{
|
||||
reg.changed[0] = true;
|
||||
}
|
||||
reg.oldValue = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (reg.oldValue._u32[0] != newValue._u32[0] || changed)
|
||||
{
|
||||
reg.changed[0] = true;
|
||||
}
|
||||
|
||||
lastPc = cpu->getPC();
|
||||
lastCycles = cpu->getCycles();
|
||||
reg.oldValue = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lastPc = cpu->getPC();
|
||||
}
|
||||
|
||||
void CtrlRegisterList::paintEvent(wxPaintEvent & evt)
|
||||
void CtrlRegisterList::redraw()
|
||||
{
|
||||
updateHandler();
|
||||
evt.Skip();
|
||||
Update();
|
||||
}
|
||||
|
||||
void CtrlRegisterList::updateHandler()
|
||||
void CtrlRegisterList::sizeEvent(wxSizeEvent& evt)
|
||||
{
|
||||
if (cpu->isCpuPaused() || needsValueUpdating)
|
||||
{
|
||||
refreshChangedRegs();
|
||||
updateValues(getCurrentCategory());
|
||||
needsValueUpdating = false;
|
||||
}
|
||||
|
||||
if (needsSizeUpdating)
|
||||
{
|
||||
updateSize(getCurrentCategory());
|
||||
needsSizeUpdating = false;
|
||||
}
|
||||
|
||||
// The wxGrid allows selecting boxes with a bold outline
|
||||
// but we don't want this, and there is no setting to turn off this feature
|
||||
wxGrid* regGrid = registerGrids[getCurrentCategory()];
|
||||
regGrid->ClearSelection();
|
||||
Refresh();
|
||||
evt.Skip();
|
||||
}
|
||||
|
||||
void CtrlRegisterList::changeValue(RegisterChangeMode mode, int cat, int reg)
|
||||
void drawU32Text(wxDC& dc, u32 value, int x, int y)
|
||||
{
|
||||
wxString oldStr;
|
||||
u128 oldValue = cpu->getRegister(cat, reg);
|
||||
char str[32];
|
||||
sprintf(str,"%08X",value);
|
||||
dc.DrawText(wxString(str,wxConvUTF8),x,y);
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case LOWER64:
|
||||
oldStr = wxsFormat(L"0x%016llX", oldValue._u64[0]);
|
||||
break;
|
||||
case UPPER64:
|
||||
oldStr = wxsFormat(L"0x%016llX", oldValue._u64[1]);
|
||||
break;
|
||||
case CHANGE32:
|
||||
oldStr = wxsFormat(L"0x%08X", oldValue._u64[0]);
|
||||
break;
|
||||
}
|
||||
void CtrlRegisterList::OnDraw(wxDC& dc)
|
||||
{
|
||||
#ifdef WIN32
|
||||
wxFont font = wxFont(wxSize(charWidth,rowHeight-2),wxFONTFAMILY_DEFAULT,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_NORMAL,false,L"Lucida Console");
|
||||
#else
|
||||
wxFont font = wxFont(8,wxFONTFAMILY_DEFAULT,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_NORMAL,false,L"Lucida Console");
|
||||
font.SetPixelSize(wxSize(charWidth,rowHeight-2));
|
||||
#endif
|
||||
dc.SetFont(font);
|
||||
|
||||
// clear background
|
||||
wxColor white = wxColor(0xFFFFFFFF);
|
||||
|
||||
u64 newValue;
|
||||
if (executeExpressionWindow(this, cpu, newValue, oldStr))
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case LOWER64:
|
||||
oldValue._u64[0] = newValue;
|
||||
break;
|
||||
case UPPER64:
|
||||
oldValue._u64[1] = newValue;
|
||||
break;
|
||||
case CHANGE32:
|
||||
oldValue._u32[0] = newValue;
|
||||
break;
|
||||
}
|
||||
cpu->setRegister(cat, reg, oldValue);
|
||||
oldValue = cpu->getRegister(cat, reg);
|
||||
}
|
||||
needsValueUpdating = true;
|
||||
needsSizeUpdating = true;
|
||||
dc.SetBrush(wxBrush(white));
|
||||
dc.SetPen(wxPen(white));
|
||||
|
||||
wxSize size = GetClientSize();
|
||||
dc.DrawRectangle(0,0,size.x,size.y);
|
||||
|
||||
refreshChangedRegs();
|
||||
|
||||
wxColor colorChanged = wxColor(0xFF0000FF);
|
||||
wxColor colorUnchanged = wxColor(0xFF004000);
|
||||
wxColor colorNormal = wxColor(0xFF600000);
|
||||
|
||||
// draw categories
|
||||
int piece = size.x/cpu->getRegisterCategoryCount();
|
||||
for (int i = 0; i < cpu->getRegisterCategoryCount(); i++)
|
||||
{
|
||||
const char* name = cpu->getRegisterCategoryName(i);
|
||||
|
||||
int x = i*piece;
|
||||
|
||||
if (i == category)
|
||||
{
|
||||
dc.SetBrush(wxBrush(wxColor(0xFF70FF70)));
|
||||
dc.SetPen(wxPen(wxColor(0xFF000000)));
|
||||
} else {
|
||||
dc.SetBrush(wxBrush(wxColor(0xFFFFEFE8)));
|
||||
dc.SetPen(wxPen(wxColor(0xFF000000)));
|
||||
}
|
||||
|
||||
if (i == cpu->getRegisterCategoryCount()-1)
|
||||
piece += size.x-piece*cpu->getRegisterCategoryCount()-1;
|
||||
|
||||
dc.DrawRectangle(x,0,piece+1,rowHeight);
|
||||
|
||||
// center text
|
||||
x += (piece-strlen(name)*charWidth)/2;
|
||||
dc.DrawText(wxString(name,wxConvUTF8),x,2);
|
||||
}
|
||||
|
||||
int nameStart = 17;
|
||||
int valueStart = startPositions[category];
|
||||
|
||||
ChangedReg* changedRegs = changedCategories[category];
|
||||
int registerBits = cpu->getRegisterSize(category);
|
||||
DebugInterface::RegisterType type = cpu->getRegisterType(category);
|
||||
|
||||
for (int i = 0; i < cpu->getRegisterCount(category); i++)
|
||||
{
|
||||
int x = valueStart;
|
||||
int y = rowHeight*(i+1);
|
||||
|
||||
if (currentRows[category] == i)
|
||||
{
|
||||
dc.SetBrush(wxBrush(wxColor(0xFFFFCFC8)));
|
||||
dc.SetPen(wxPen(wxColor(0xFFFFEFE8)));
|
||||
dc.DrawRectangle(0,y,size.x,rowHeight);
|
||||
} else if (i % 2)
|
||||
{
|
||||
wxColor color = wxColor(237,242,255,255);
|
||||
dc.SetBrush(wxBrush(color));
|
||||
dc.SetPen(wxPen(color));
|
||||
dc.DrawRectangle(0, y, size.x, rowHeight);
|
||||
}
|
||||
|
||||
const char* name = cpu->getRegisterName(category,i);
|
||||
dc.SetTextForeground(colorNormal);
|
||||
dc.DrawText(wxString(name,wxConvUTF8),nameStart,y+2);
|
||||
|
||||
u128 value = cpu->getRegister(category,i);
|
||||
ChangedReg& changed = changedRegs[i];
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DebugInterface::NORMAL: // display them in 32 bit parts
|
||||
switch (registerBits)
|
||||
{
|
||||
case 128:
|
||||
{
|
||||
int startIndex = std::min<int>(3,maxBits/32-1);
|
||||
int actualX = size.x-4-(startIndex+1)*(8*charWidth+2);
|
||||
x = std::max<int>(actualX,x);
|
||||
|
||||
if (startIndex != 3)
|
||||
{
|
||||
bool c = false;
|
||||
for (int i = 3; i > startIndex; i--)
|
||||
c = c || changed.changed[i];
|
||||
|
||||
if (c)
|
||||
{
|
||||
dc.SetTextForeground(colorChanged);
|
||||
dc.DrawText(L"+",x-charWidth,y+2);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = startIndex; i >= 0; i--)
|
||||
{
|
||||
if (changed.changed[i])
|
||||
dc.SetTextForeground(colorChanged);
|
||||
else
|
||||
dc.SetTextForeground(colorUnchanged);
|
||||
|
||||
drawU32Text(dc,value._u32[i],x,y+2);
|
||||
x += charWidth*8+2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 64:
|
||||
{
|
||||
if (maxBits < 64 && changed.changed[1])
|
||||
{
|
||||
dc.SetTextForeground(colorChanged);
|
||||
dc.DrawText(L"+",x-charWidth,y+2);
|
||||
}
|
||||
|
||||
for (int i = 1; i >= 0; i--)
|
||||
{
|
||||
if (changed.changed[i])
|
||||
dc.SetTextForeground(colorChanged);
|
||||
else
|
||||
dc.SetTextForeground(colorUnchanged);
|
||||
|
||||
drawU32Text(dc,value._u32[i],x,y+2);
|
||||
x += charWidth*8+2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 32:
|
||||
{
|
||||
if (changed.changed[0])
|
||||
dc.SetTextForeground(colorChanged);
|
||||
else
|
||||
dc.SetTextForeground(colorUnchanged);
|
||||
|
||||
drawU32Text(dc,value._u32[0],x,y+2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DebugInterface::SPECIAL: // let debug interface format them and just display them
|
||||
{
|
||||
if (changed.changed[0] || changed.changed[1] || changed.changed[2] || changed.changed[3])
|
||||
dc.SetTextForeground(colorChanged);
|
||||
else
|
||||
dc.SetTextForeground(colorUnchanged);
|
||||
|
||||
dc.DrawText(cpu->getRegisterString(category,i),x,y+2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CtrlRegisterList::changeValue(RegisterChangeMode mode)
|
||||
{
|
||||
wchar_t str[64];
|
||||
|
||||
u128 oldValue = cpu->getRegister(category,currentRows[category]);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case LOWER64:
|
||||
swprintf(str,64,L"0x%016llX",oldValue._u64[0]);
|
||||
break;
|
||||
case UPPER64:
|
||||
swprintf(str,64,L"0x%016llX",oldValue._u64[1]);
|
||||
break;
|
||||
case CHANGE32:
|
||||
swprintf(str,64,L"0x%08X",oldValue._u32[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
u64 newValue;
|
||||
if (executeExpressionWindow(this,cpu,newValue,str))
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case LOWER64:
|
||||
oldValue._u64[0] = newValue;
|
||||
break;
|
||||
case UPPER64:
|
||||
oldValue._u64[1] = newValue;
|
||||
break;
|
||||
case CHANGE32:
|
||||
oldValue._u32[0] = newValue;
|
||||
break;
|
||||
}
|
||||
|
||||
cpu->setRegister(category,currentRows[category],oldValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CtrlRegisterList::onPopupClick(wxCommandEvent& evt)
|
||||
{
|
||||
int cat = getCurrentCategory();
|
||||
wxGrid* regGrid = registerGrids[cat];
|
||||
int reg = regGrid->GetGridCursorRow();
|
||||
switch (evt.GetId())
|
||||
{
|
||||
case ID_REGISTERLIST_DISPLAY32:
|
||||
maxBits = 32;
|
||||
postEvent(debEVT_UPDATELAYOUT, 0);
|
||||
Refresh();
|
||||
break;
|
||||
case ID_REGISTERLIST_DISPLAY64:
|
||||
maxBits = 64;
|
||||
postEvent(debEVT_UPDATELAYOUT, 0);
|
||||
Refresh();
|
||||
break;
|
||||
case ID_REGISTERLIST_DISPLAY128:
|
||||
maxBits = 128;
|
||||
postEvent(debEVT_UPDATELAYOUT, 0);
|
||||
Refresh();
|
||||
break;
|
||||
case ID_REGISTERLIST_CHANGELOWER:
|
||||
changeValue(LOWER64, cat, reg);
|
||||
Refresh();
|
||||
break;
|
||||
case ID_REGISTERLIST_CHANGEUPPER:
|
||||
changeValue(UPPER64, cat, reg);
|
||||
Refresh();
|
||||
break;
|
||||
case ID_REGISTERLIST_CHANGEVALUE:
|
||||
if (cpu->getRegisterSize(cat) == 32)
|
||||
changeValue(CHANGE32, cat, reg);
|
||||
else
|
||||
changeValue(LOWER64, cat, reg);
|
||||
Refresh();
|
||||
break;
|
||||
default:
|
||||
wxMessageBox(L"Unimplemented.", L"Unimplemented.", wxICON_INFORMATION);
|
||||
break;
|
||||
}
|
||||
needsValueUpdating = true;
|
||||
needsSizeUpdating = true;
|
||||
switch (evt.GetId())
|
||||
{
|
||||
case ID_REGISTERLIST_DISPLAY32:
|
||||
maxBits = 32;
|
||||
SetInitialSize(ClientToWindowSize(GetMinClientSize()));
|
||||
postEvent(debEVT_UPDATELAYOUT,0);
|
||||
Refresh();
|
||||
break;
|
||||
case ID_REGISTERLIST_DISPLAY64:
|
||||
maxBits = 64;
|
||||
SetInitialSize(ClientToWindowSize(GetMinClientSize()));
|
||||
postEvent(debEVT_UPDATELAYOUT,0);
|
||||
Refresh();
|
||||
break;
|
||||
case ID_REGISTERLIST_DISPLAY128:
|
||||
maxBits = 128;
|
||||
SetInitialSize(ClientToWindowSize(GetMinClientSize()));
|
||||
postEvent(debEVT_UPDATELAYOUT,0);
|
||||
Refresh();
|
||||
break;
|
||||
case ID_REGISTERLIST_CHANGELOWER:
|
||||
changeValue(LOWER64);
|
||||
Refresh();
|
||||
break;
|
||||
case ID_REGISTERLIST_CHANGEUPPER:
|
||||
changeValue(UPPER64);
|
||||
Refresh();
|
||||
break;
|
||||
case ID_REGISTERLIST_CHANGEVALUE:
|
||||
if (cpu->getRegisterSize(category) == 32)
|
||||
changeValue(CHANGE32);
|
||||
else
|
||||
changeValue(LOWER64);
|
||||
Refresh();
|
||||
break;
|
||||
default:
|
||||
wxMessageBox( L"Unimplemented.", L"Unimplemented.", wxICON_INFORMATION);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int CtrlRegisterList::getCurrentCategory() const
|
||||
void CtrlRegisterList::setCurrentRow(int row)
|
||||
{
|
||||
return registerCategories->GetSelection();
|
||||
char str[256];
|
||||
u128 value ;
|
||||
wxString text;
|
||||
|
||||
const char* name = cpu->getRegisterName(category,row);
|
||||
|
||||
switch (cpu->getRegisterType(category))
|
||||
{
|
||||
case DebugInterface::NORMAL:
|
||||
value = cpu->getRegister(category,row);
|
||||
switch (cpu->getRegisterSize(category))
|
||||
{
|
||||
case 128:
|
||||
sprintf(str,"%s = 0x%08X%08X%08X%08X",name,value._u32[3],value._u32[2],value._u32[1],value._u32[0]);
|
||||
break;
|
||||
case 64:
|
||||
sprintf(str,"%s = 0x%08X%08X",name,value._u32[1],value._u32[0]);
|
||||
break;
|
||||
case 32:
|
||||
sprintf(str,"%s = 0x%08X",name,value._u32[0]);
|
||||
break;
|
||||
}
|
||||
text = wxString(str,wxConvUTF8);
|
||||
break;
|
||||
case DebugInterface::SPECIAL:
|
||||
text = wxString(name,wxConvUTF8) + L" = " + cpu->getRegisterString(category,row);
|
||||
break;
|
||||
}
|
||||
|
||||
currentRows[category] = row;
|
||||
postEvent(debEVT_SETSTATUSBARTEXT,text);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
void CtrlRegisterList::gridEvent(wxGridEvent& evt)
|
||||
void CtrlRegisterList::mouseEvent(wxMouseEvent& evt)
|
||||
{
|
||||
// Mouse events
|
||||
if (evt.GetEventType() == wxEVT_GRID_CELL_RIGHT_CLICK ||
|
||||
evt.GetEventType() == wxEVT_GRID_LABEL_RIGHT_CLICK)
|
||||
{
|
||||
wxMenu menu;
|
||||
int bits = cpu->getRegisterSize(getCurrentCategory());
|
||||
int xOffset, yOffset;
|
||||
((wxScrolledWindow*) this)->GetViewStart(&xOffset, &yOffset);
|
||||
|
||||
menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY32, L"Display 32 bit");
|
||||
menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY64, L"Display 64 bit");
|
||||
menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY128, L"Display 128 bit");
|
||||
menu.AppendSeparator();
|
||||
wxClientDC dc(this);
|
||||
wxPoint pos = evt.GetPosition();
|
||||
int x = dc.DeviceToLogicalX(pos.x) + xOffset;
|
||||
int y = dc.DeviceToLogicalY(pos.y) + yOffset;
|
||||
|
||||
if (bits >= 64)
|
||||
{
|
||||
menu.Append(ID_REGISTERLIST_CHANGELOWER, L"Change lower 64 bit");
|
||||
menu.Append(ID_REGISTERLIST_CHANGEUPPER, L"Change upper 64 bit");
|
||||
}
|
||||
else {
|
||||
menu.Append(ID_REGISTERLIST_CHANGEVALUE, L"Change value");
|
||||
}
|
||||
if (evt.GetEventType() == wxEVT_RIGHT_UP)
|
||||
{
|
||||
if (y >= rowHeight)
|
||||
{
|
||||
int row = (y-rowHeight)/rowHeight;
|
||||
if (row != currentRows[category] && row < cpu->getRegisterCount(category))
|
||||
setCurrentRow(row);
|
||||
}
|
||||
|
||||
switch (maxBits)
|
||||
{
|
||||
case 128:
|
||||
menu.Check(ID_REGISTERLIST_DISPLAY128, true);
|
||||
break;
|
||||
case 64:
|
||||
menu.Check(ID_REGISTERLIST_DISPLAY64, true);
|
||||
break;
|
||||
case 32:
|
||||
menu.Check(ID_REGISTERLIST_DISPLAY32, true);
|
||||
break;
|
||||
}
|
||||
wxMenu menu;
|
||||
int bits = cpu->getRegisterSize(category);
|
||||
|
||||
menu.Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(CtrlRegisterList::onPopupClick), nullptr, this);
|
||||
PopupMenu(&menu, evt.GetPosition());
|
||||
needsValueUpdating = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
evt.Skip();
|
||||
}
|
||||
}
|
||||
menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY32, L"Display 32 bit");
|
||||
menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY64, L"Display 64 bit");
|
||||
menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY128, L"Display 128 bit");
|
||||
menu.AppendSeparator();
|
||||
|
||||
void CtrlRegisterList::categoryChangedEvent(wxBookCtrlEvent& evt)
|
||||
{
|
||||
needsSizeUpdating = true;
|
||||
needsValueUpdating = true;
|
||||
evt.Skip();
|
||||
if (bits >= 64)
|
||||
{
|
||||
menu.Append(ID_REGISTERLIST_CHANGELOWER, L"Change lower 64 bit");
|
||||
menu.Append(ID_REGISTERLIST_CHANGEUPPER, L"Change upper 64 bit");
|
||||
} else {
|
||||
menu.Append(ID_REGISTERLIST_CHANGEVALUE, L"Change value");
|
||||
}
|
||||
|
||||
switch (maxBits)
|
||||
{
|
||||
case 128:
|
||||
menu.Check(ID_REGISTERLIST_DISPLAY128,true);
|
||||
break;
|
||||
case 64:
|
||||
menu.Check(ID_REGISTERLIST_DISPLAY64,true);
|
||||
break;
|
||||
case 32:
|
||||
menu.Check(ID_REGISTERLIST_DISPLAY32,true);
|
||||
break;
|
||||
}
|
||||
|
||||
menu.Connect(wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)&CtrlRegisterList::onPopupClick, NULL, this);
|
||||
PopupMenu(&menu,evt.GetPosition());
|
||||
return;
|
||||
}
|
||||
|
||||
if (evt.ButtonIsDown(wxMOUSE_BTN_LEFT) || evt.ButtonIsDown(wxMOUSE_BTN_RIGHT))
|
||||
{
|
||||
if (y < rowHeight)
|
||||
{
|
||||
int piece = GetSize().x/cpu->getRegisterCategoryCount();
|
||||
int cat = std::min<int>(x/piece,cpu->getRegisterCategoryCount()-1);
|
||||
|
||||
if (cat != category)
|
||||
{
|
||||
category = cat;
|
||||
Refresh();
|
||||
}
|
||||
} else {
|
||||
int row = (y-rowHeight)/rowHeight;
|
||||
if (row != currentRows[category] && row < cpu->getRegisterCount(category))
|
||||
setCurrentRow(row);
|
||||
}
|
||||
|
||||
SetFocus();
|
||||
SetFocusFromKbd();
|
||||
}
|
||||
}
|
||||
|
||||
void CtrlRegisterList::keydownEvent(wxKeyEvent& evt)
|
||||
{
|
||||
needsValueUpdating = true;
|
||||
evt.Skip();
|
||||
switch (evt.GetKeyCode())
|
||||
{
|
||||
case WXK_UP:
|
||||
setCurrentRow(std::max<int>(currentRows[category]-1,0));
|
||||
break;
|
||||
case WXK_DOWN:
|
||||
setCurrentRow(std::min<int>(currentRows[category]+1,cpu->getRegisterCount(category)-1));
|
||||
break;
|
||||
case WXK_TAB:
|
||||
category = (category+1) % cpu->getRegisterCategoryCount();
|
||||
Refresh();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,50 +15,60 @@
|
|||
|
||||
#pragma once
|
||||
#include <wx/wx.h>
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/grid.h>
|
||||
|
||||
#include "DebugTools/DebugInterface.h"
|
||||
#include "DebugTools/DisassemblyManager.h"
|
||||
|
||||
class CtrlRegisterList : public wxWindow
|
||||
class CtrlRegisterList: public wxScrolledWindow
|
||||
{
|
||||
public:
|
||||
CtrlRegisterList(wxWindow* parent, DebugInterface* _cpu);
|
||||
CtrlRegisterList(wxWindow* parent, DebugInterface* _cpu);
|
||||
|
||||
void mouseEvent(wxMouseEvent& evt);
|
||||
void keydownEvent(wxKeyEvent& evt);
|
||||
void onPopupClick(wxCommandEvent& evt);
|
||||
void sizeEvent(wxSizeEvent& evt);
|
||||
void redraw();
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
||||
virtual wxSize GetMinClientSize() const
|
||||
{
|
||||
wxSize optimalSize = getOptimalSize();
|
||||
if (GetWindowStyle() & wxVSCROLL)
|
||||
optimalSize.x += wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
|
||||
|
||||
// Event handlers
|
||||
void paintEvent(wxPaintEvent & evt);
|
||||
void onPopupClick(wxCommandEvent& evt);
|
||||
void gridEvent(wxGridEvent& evt);
|
||||
void categoryChangedEvent(wxBookCtrlEvent& evt);
|
||||
void keydownEvent(wxKeyEvent& evt);
|
||||
DECLARE_EVENT_TABLE()
|
||||
return wxSize(optimalSize.x,0);
|
||||
}
|
||||
|
||||
virtual wxSize DoGetBestClientSize() const
|
||||
{
|
||||
return GetMinClientSize();
|
||||
}
|
||||
private:
|
||||
enum RegisterChangeMode { LOWER64, UPPER64, CHANGE32 };
|
||||
enum RegisterChangeMode { LOWER64, UPPER64, CHANGE32 };
|
||||
|
||||
void refreshChangedRegs();
|
||||
void OnDraw(wxDC& dc);
|
||||
void refreshChangedRegs();
|
||||
void setCurrentRow(int row);
|
||||
void changeValue(RegisterChangeMode mode);
|
||||
wxSize getOptimalSize() const;
|
||||
|
||||
void changeValue(RegisterChangeMode mode, int cat, int reg);
|
||||
void updateHandler();
|
||||
void updateValues(int cat);
|
||||
void updateSize(int cat);
|
||||
int getCurrentCategory() const;
|
||||
void postEvent(wxEventType type, wxString text);
|
||||
void postEvent(wxEventType type, int value);
|
||||
void postEvent(wxEventType type, wxString text);
|
||||
void postEvent(wxEventType type, int value);
|
||||
|
||||
struct ChangedReg
|
||||
{
|
||||
u128 oldValue;
|
||||
bool changed[4];
|
||||
ChangedReg() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
struct ChangedReg
|
||||
{
|
||||
u128 oldValue;
|
||||
bool changed[4];
|
||||
};
|
||||
|
||||
std::vector<ChangedReg*> changedCategories;
|
||||
std::vector<int> startPositions;
|
||||
std::vector<int> currentRows;
|
||||
|
||||
std::vector<std::vector<ChangedReg>> changedCategories;
|
||||
|
||||
DebugInterface* cpu; // Used to get register values and other info from the emu
|
||||
u32 lastPc, lastCycles;
|
||||
int maxBits; // maximum number of bits beings displayed
|
||||
bool needsSizeUpdating, needsValueUpdating; // flags set in events to signal that values/sizes should be updated on the next display
|
||||
wxNotebook* registerCategories; // Occupies this entire window. Is the tabbed window for selecting register categories.
|
||||
std::vector<wxGrid*> registerGrids; // Grids displaying register values for each of the tabs.
|
||||
};
|
||||
DebugInterface* cpu;
|
||||
int rowHeight,charWidth;
|
||||
u32 lastPc;
|
||||
int category;
|
||||
int maxBits;
|
||||
};
|
|
@ -39,6 +39,7 @@ BEGIN_EVENT_TABLE(DisassemblyDialog, wxFrame)
|
|||
EVT_COMMAND( wxID_ANY, debEVT_UPDATE, DisassemblyDialog::onDebuggerEvent )
|
||||
EVT_COMMAND( wxID_ANY, debEVT_BREAKPOINTWINDOW, DisassemblyDialog::onDebuggerEvent )
|
||||
EVT_COMMAND( wxID_ANY, debEVT_MAPLOADED, DisassemblyDialog::onDebuggerEvent )
|
||||
EVT_SIZE(DisassemblyDialog::onSizeEvent)
|
||||
EVT_CLOSE( DisassemblyDialog::onClose )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
@ -176,7 +177,7 @@ void CpuTabPage::update()
|
|||
{
|
||||
breakpointList->reloadBreakpoints();
|
||||
|
||||
if (threadList != NULL)
|
||||
if (threadList != NULL && cpu->isAlive())
|
||||
{
|
||||
threadList->reloadThreads();
|
||||
|
||||
|
@ -217,6 +218,8 @@ DisassemblyDialog::DisassemblyDialog(wxWindow* parent):
|
|||
wxFrame( parent, wxID_ANY, L"Debugger", wxDefaultPosition,wxDefaultSize,wxRESIZE_BORDER|wxCLOSE_BOX|wxCAPTION|wxSYSTEM_MENU ),
|
||||
currentCpu(NULL)
|
||||
{
|
||||
int width = g_Conf->EmuOptions.Debugger.WindowWidth;
|
||||
int height = g_Conf->EmuOptions.Debugger.WindowHeight;
|
||||
|
||||
topSizer = new wxBoxSizer( wxVERTICAL );
|
||||
wxPanel *panel = new wxPanel(this, wxID_ANY,
|
||||
|
@ -252,7 +255,7 @@ DisassemblyDialog::DisassemblyDialog(wxWindow* parent):
|
|||
topSizer->Add(topRowSizer,0,wxLEFT|wxRIGHT|wxTOP,3);
|
||||
|
||||
// create middle part of the window
|
||||
wxNotebook* middleBook = new wxNotebook(panel,wxID_ANY);
|
||||
middleBook = new wxNotebook(panel,wxID_ANY);
|
||||
middleBook->SetBackgroundColour(wxColour(0xFFF0F0F0));
|
||||
eeTab = new CpuTabPage(middleBook,&r5900Debug);
|
||||
iopTab = new CpuTabPage(middleBook,&r3000Debug);
|
||||
|
@ -267,9 +270,23 @@ DisassemblyDialog::DisassemblyDialog(wxWindow* parent):
|
|||
SetMinSize(wxSize(1000,600));
|
||||
panel->GetSizer()->Fit(this);
|
||||
|
||||
if (width != 0 && height != 0)
|
||||
SetSize(width,height);
|
||||
|
||||
setDebugMode(true,true);
|
||||
}
|
||||
|
||||
void DisassemblyDialog::onSizeEvent(wxSizeEvent& event)
|
||||
{
|
||||
if (event.GetEventType() == wxEVT_SIZE)
|
||||
{
|
||||
g_Conf->EmuOptions.Debugger.WindowWidth = event.GetSize().x;
|
||||
g_Conf->EmuOptions.Debugger.WindowHeight = event.GetSize().y;
|
||||
}
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
WXLRESULT DisassemblyDialog::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
|
||||
{
|
||||
|
@ -469,7 +486,7 @@ void DisassemblyDialog::onDebuggerEvent(wxCommandEvent& evt)
|
|||
if (type == debEVT_SETSTATUSBARTEXT)
|
||||
{
|
||||
DebugInterface* cpu = reinterpret_cast<DebugInterface*>(evt.GetClientData());
|
||||
if (cpu != NULL && cpu == currentCpu->getCpu())
|
||||
if (cpu != NULL && currentCpu != NULL && cpu == currentCpu->getCpu())
|
||||
GetStatusBar()->SetLabel(evt.GetString());
|
||||
} else if (type == debEVT_UPDATELAYOUT)
|
||||
{
|
||||
|
@ -568,6 +585,19 @@ void DisassemblyDialog::setDebugMode(bool debugMode, bool switchPC)
|
|||
|
||||
if (running)
|
||||
{
|
||||
if (currentCpu == NULL)
|
||||
{
|
||||
wxWindow* currentPage = middleBook->GetCurrentPage();
|
||||
|
||||
if (currentPage == eeTab)
|
||||
currentCpu = eeTab;
|
||||
else if (currentPage == iopTab)
|
||||
currentCpu = iopTab;
|
||||
|
||||
if (currentCpu != NULL)
|
||||
currentCpu->update();
|
||||
}
|
||||
|
||||
if (debugMode)
|
||||
{
|
||||
CBreakPoints::ClearTemporaryBreakPoints();
|
||||
|
@ -596,6 +626,12 @@ void DisassemblyDialog::setDebugMode(bool debugMode, bool switchPC)
|
|||
stepOverButton->Enable(false);
|
||||
stepOutButton->Enable(false);
|
||||
}
|
||||
} else {
|
||||
breakRunButton->SetLabel(L"Run");
|
||||
stepIntoButton->Enable(false);
|
||||
stepOverButton->Enable(false);
|
||||
stepOutButton->Enable(false);
|
||||
currentCpu = NULL;
|
||||
}
|
||||
|
||||
update();
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "CtrlMemView.h"
|
||||
#include "DebugEvents.h"
|
||||
#include "DebuggerLists.h"
|
||||
#include "../MSWstuff.h"
|
||||
|
||||
class DebuggerHelpDialog: public wxDialog
|
||||
{
|
||||
|
@ -30,6 +31,16 @@ public:
|
|||
DebuggerHelpDialog(wxWindow* parent);
|
||||
};
|
||||
|
||||
inline int getDebugFontWidth()
|
||||
{
|
||||
return (int) ceil(g_Conf->EmuOptions.Debugger.FontWidth*MSW_GetDPIScale());
|
||||
}
|
||||
|
||||
inline int getDebugFontHeight()
|
||||
{
|
||||
return (int)ceil(g_Conf->EmuOptions.Debugger.FontHeight*MSW_GetDPIScale());
|
||||
}
|
||||
|
||||
class CpuTabPage: public wxPanel
|
||||
{
|
||||
public:
|
||||
|
@ -91,6 +102,7 @@ protected:
|
|||
void onDebuggerEvent(wxCommandEvent& evt);
|
||||
void onPageChanging(wxCommandEvent& evt);
|
||||
void onBreakpointClick(wxCommandEvent& evt);
|
||||
void onSizeEvent(wxSizeEvent& event);
|
||||
void onClose(wxCloseEvent& evt);
|
||||
void stepOver();
|
||||
void stepInto();
|
||||
|
@ -100,6 +112,7 @@ private:
|
|||
CpuTabPage* eeTab;
|
||||
CpuTabPage* iopTab;
|
||||
CpuTabPage* currentCpu;
|
||||
wxNotebook* middleBook;
|
||||
|
||||
wxBoxSizer* topSizer;
|
||||
wxButton* breakRunButton;
|
||||
|
|
Loading…
Reference in New Issue