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 FontWidth;
|
||||||
u8 FontHeight;
|
u8 FontHeight;
|
||||||
|
u32 WindowWidth;
|
||||||
|
u32 WindowHeight;
|
||||||
|
|
||||||
DebugOptions();
|
DebugOptions();
|
||||||
void LoadSave( IniInterface& conf );
|
void LoadSave( IniInterface& conf );
|
||||||
|
|
||||||
bool operator ==( const DebugOptions& right ) const
|
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
|
bool operator !=( const DebugOptions& right ) const
|
||||||
|
|
|
@ -379,6 +379,8 @@ Pcsx2Config::DebugOptions::DebugOptions()
|
||||||
ShowDebuggerOnStart = false;
|
ShowDebuggerOnStart = false;
|
||||||
FontWidth = 8;
|
FontWidth = 8;
|
||||||
FontHeight = 12;
|
FontHeight = 12;
|
||||||
|
WindowWidth = 0;
|
||||||
|
WindowHeight = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pcsx2Config::DebugOptions::LoadSave( IniInterface& ini )
|
void Pcsx2Config::DebugOptions::LoadSave( IniInterface& ini )
|
||||||
|
@ -388,6 +390,8 @@ void Pcsx2Config::DebugOptions::LoadSave( IniInterface& ini )
|
||||||
IniBitBool( ShowDebuggerOnStart );
|
IniBitBool( ShowDebuggerOnStart );
|
||||||
IniBitfield(FontWidth);
|
IniBitfield(FontWidth);
|
||||||
IniBitfield(FontHeight);
|
IniBitfield(FontHeight);
|
||||||
|
IniBitfield(WindowWidth);
|
||||||
|
IniBitfield(WindowHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,7 @@ void SysCoreThread::Reset()
|
||||||
GetVmMemory().DecommitAll();
|
GetVmMemory().DecommitAll();
|
||||||
SysClearExecutionCache();
|
SysClearExecutionCache();
|
||||||
sApp.PostAppMethod( &Pcsx2App::leaveDebugMode );
|
sApp.PostAppMethod( &Pcsx2App::leaveDebugMode );
|
||||||
|
g_FrameCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "BreakpointWindow.h"
|
#include "BreakpointWindow.h"
|
||||||
#include "AppConfig.h"
|
#include "AppConfig.h"
|
||||||
#include "System.h"
|
#include "System.h"
|
||||||
|
#include "DisassemblyDialog.h"
|
||||||
|
|
||||||
#include <wx/mstream.h>
|
#include <wx/mstream.h>
|
||||||
#include <wx/clipbrd.h>
|
#include <wx/clipbrd.h>
|
||||||
|
@ -147,8 +148,8 @@ CtrlDisassemblyView::CtrlDisassemblyView(wxWindow* parent, DebugInterface* _cpu)
|
||||||
{
|
{
|
||||||
manager.setCpu(cpu);
|
manager.setCpu(cpu);
|
||||||
windowStart = 0x100000;
|
windowStart = 0x100000;
|
||||||
rowHeight = g_Conf->EmuOptions.Debugger.FontHeight+2;
|
rowHeight = getDebugFontHeight()+2;
|
||||||
charWidth = g_Conf->EmuOptions.Debugger.FontWidth;
|
charWidth = getDebugFontWidth();
|
||||||
displaySymbols = true;
|
displaySymbols = true;
|
||||||
visibleRows = 1;
|
visibleRows = 1;
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "BreakpointWindow.h"
|
#include "BreakpointWindow.h"
|
||||||
#include "DebugEvents.h"
|
#include "DebugEvents.h"
|
||||||
|
#include "DisassemblyDialog.h"
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <wx/clipbrd.h>
|
#include <wx/clipbrd.h>
|
||||||
|
|
||||||
|
@ -55,8 +56,8 @@ enum MemoryViewMenuIdentifiers
|
||||||
CtrlMemView::CtrlMemView(wxWindow* parent, DebugInterface* _cpu)
|
CtrlMemView::CtrlMemView(wxWindow* parent, DebugInterface* _cpu)
|
||||||
: wxWindow(parent,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxWANTS_CHARS|wxVSCROLL), cpu(_cpu)
|
: wxWindow(parent,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxWANTS_CHARS|wxVSCROLL), cpu(_cpu)
|
||||||
{
|
{
|
||||||
rowHeight = g_Conf->EmuOptions.Debugger.FontHeight;
|
rowHeight = getDebugFontHeight();
|
||||||
charWidth = g_Conf->EmuOptions.Debugger.FontWidth;
|
charWidth = getDebugFontWidth();
|
||||||
windowStart = 0x480000;
|
windowStart = 0x480000;
|
||||||
curAddress = windowStart;
|
curAddress = windowStart;
|
||||||
rowSize = 16;
|
rowSize = 16;
|
||||||
|
|
|
@ -16,456 +16,547 @@
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
#include "CtrlRegisterList.h"
|
#include "CtrlRegisterList.h"
|
||||||
#include "DebugTools/Debug.h"
|
#include "DebugTools/Debug.h"
|
||||||
|
|
||||||
#include "DebugEvents.h"
|
#include "DebugEvents.h"
|
||||||
#include "AppConfig.h"
|
#include "AppConfig.h"
|
||||||
|
#include "DisassemblyDialog.h"
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(CtrlRegisterList, wxWindow)
|
BEGIN_EVENT_TABLE(CtrlRegisterList, wxWindow)
|
||||||
EVT_PAINT(CtrlRegisterList::paintEvent)
|
EVT_SIZE(CtrlRegisterList::sizeEvent)
|
||||||
EVT_GRID_LABEL_LEFT_CLICK(CtrlRegisterList::gridEvent)
|
EVT_LEFT_DOWN(CtrlRegisterList::mouseEvent)
|
||||||
EVT_GRID_LABEL_RIGHT_CLICK(CtrlRegisterList::gridEvent)
|
EVT_RIGHT_DOWN(CtrlRegisterList::mouseEvent)
|
||||||
EVT_GRID_CELL_LEFT_CLICK(CtrlRegisterList::gridEvent)
|
EVT_RIGHT_UP(CtrlRegisterList::mouseEvent)
|
||||||
EVT_GRID_CELL_RIGHT_CLICK(CtrlRegisterList::gridEvent)
|
EVT_MOTION(CtrlRegisterList::mouseEvent)
|
||||||
EVT_KEY_DOWN(CtrlRegisterList::keydownEvent)
|
EVT_KEY_DOWN(CtrlRegisterList::keydownEvent)
|
||||||
EVT_BOOKCTRL_PAGE_CHANGED(-1, CtrlRegisterList::categoryChangedEvent)
|
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
enum DisassemblyMenuIdentifiers
|
enum DisassemblyMenuIdentifiers
|
||||||
{
|
{
|
||||||
ID_REGISTERLIST_DISPLAY32 = 1,
|
ID_REGISTERLIST_DISPLAY32 = 1,
|
||||||
ID_REGISTERLIST_DISPLAY64,
|
ID_REGISTERLIST_DISPLAY64,
|
||||||
ID_REGISTERLIST_DISPLAY128,
|
ID_REGISTERLIST_DISPLAY128,
|
||||||
ID_REGISTERLIST_CHANGELOWER,
|
ID_REGISTERLIST_CHANGELOWER,
|
||||||
ID_REGISTERLIST_CHANGEUPPER,
|
ID_REGISTERLIST_CHANGEUPPER,
|
||||||
ID_REGISTERLIST_CHANGEVALUE
|
ID_REGISTERLIST_CHANGEVALUE
|
||||||
};
|
};
|
||||||
|
|
||||||
CtrlRegisterList::CtrlRegisterList(wxWindow* parent, DebugInterface* _cpu) :
|
|
||||||
wxWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS | wxBORDER_NONE),
|
CtrlRegisterList::CtrlRegisterList(wxWindow* parent, DebugInterface* _cpu)
|
||||||
cpu(_cpu),
|
: wxScrolledWindow(parent,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxWANTS_CHARS|wxBORDER_NONE|wxVSCROLL), cpu(_cpu)
|
||||||
lastPc(0),
|
|
||||||
lastCycles(0),
|
|
||||||
maxBits(128),
|
|
||||||
needsSizeUpdating(true),
|
|
||||||
needsValueUpdating(true)
|
|
||||||
{
|
{
|
||||||
int rowHeight = g_Conf->EmuOptions.Debugger.FontHeight;
|
rowHeight = getDebugFontHeight()+2;
|
||||||
int charWidth = g_Conf->EmuOptions.Debugger.FontWidth;
|
charWidth = getDebugFontWidth();
|
||||||
|
category = 0;
|
||||||
|
maxBits = 128;
|
||||||
|
lastPc = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
for (int i = 0; i < cpu->getRegisterCategoryCount(); i++)
|
||||||
|
{
|
||||||
|
int count = cpu->getRegisterCount(i);
|
||||||
|
|
||||||
#ifdef _WIN32
|
ChangedReg* regs = new ChangedReg[count];
|
||||||
wxFont font = wxFont(wxSize(charWidth, rowHeight), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL,
|
memset(regs,0,sizeof(ChangedReg)*count);
|
||||||
false, L"Lucida Console");
|
changedCategories.push_back(regs);
|
||||||
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);
|
|
||||||
|
|
||||||
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);
|
SetDoubleBuffered(true);
|
||||||
registerCategories->AddPage(regGrid, wxString(cpu->getRegisterCategoryName(cat), wxConvUTF8));
|
SetInitialSize(ClientToWindowSize(GetMinClientSize()));
|
||||||
|
|
||||||
DebugInterface::RegisterType type = cpu->getRegisterType(cat);
|
wxSize actualSize = getOptimalSize();
|
||||||
int registerBits = cpu->getRegisterSize(cat);
|
SetVirtualSize(actualSize);
|
||||||
|
SetScrollbars(1, rowHeight, actualSize.x, actualSize.y / rowHeight, 0, 0);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when this window needs to update the strings in the cells.
|
wxSize CtrlRegisterList::getOptimalSize() const
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
wxGrid* regGrid = registerGrids[cat];
|
int columnChars = 0;
|
||||||
int numRows = regGrid->GetNumberRows();
|
int maxWidth = 0;
|
||||||
int numCols = regGrid->GetNumberCols();
|
int maxRows = 0;
|
||||||
|
|
||||||
std::vector<ChangedReg>& changedRegs = changedCategories[cat];
|
for (int i = 0; i < cpu->getRegisterCategoryCount(); i++)
|
||||||
DebugInterface::RegisterType type = cpu->getRegisterType(cat);
|
{
|
||||||
for (int row = 0; row < numRows; row++)
|
int bits = std::min<u32>(maxBits, cpu->getRegisterSize(i));
|
||||||
{
|
int start = startPositions[i];
|
||||||
wxColor bgColor = regGrid->GetGridCursorRow() == row ? wxColor(0xFFFFDFE0) :
|
|
||||||
wxColor(0xFFFFEFFF);
|
|
||||||
u128 value = cpu->getRegister(cat, row);
|
|
||||||
ChangedReg& changed = changedRegs[row];
|
|
||||||
|
|
||||||
for (int col = 0; col < numCols; col++)
|
int w = start + (bits / 4) * charWidth;
|
||||||
{
|
if (bits > 32)
|
||||||
const wxColor colorChanged = wxColor(0xFF0000FF);
|
w += (bits / 32) * 2 - 2;
|
||||||
const wxColor colorUnchanged = wxColor(0xFF004000);
|
|
||||||
wxColor textColor;
|
|
||||||
wxString cellValue;
|
|
||||||
|
|
||||||
switch (type)
|
maxWidth = std::max<int>(maxWidth, w);
|
||||||
{
|
columnChars += strlen(cpu->getRegisterCategoryName(i)) + 1;
|
||||||
case DebugInterface::NORMAL:
|
maxRows = std::max<int>(maxRows, cpu->getRegisterCount(i));
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CtrlRegisterList::updateSize(int cat)
|
maxWidth = std::max<int>(columnChars*charWidth, maxWidth + 4);
|
||||||
{
|
|
||||||
wxGrid* regGrid = registerGrids[cat];
|
|
||||||
|
|
||||||
int regBits = cpu->getRegisterSize(cat);
|
return wxSize(maxWidth, (maxRows + 1)*rowHeight);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CtrlRegisterList::postEvent(wxEventType type, wxString text)
|
void CtrlRegisterList::postEvent(wxEventType type, wxString text)
|
||||||
{
|
{
|
||||||
wxCommandEvent event(type, GetId());
|
wxCommandEvent event( type, GetId() );
|
||||||
event.SetEventObject(this);
|
event.SetEventObject(this);
|
||||||
event.SetString(text);
|
event.SetString(text);
|
||||||
wxPostEvent(this, event);
|
wxPostEvent(this,event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CtrlRegisterList::postEvent(wxEventType type, int value)
|
void CtrlRegisterList::postEvent(wxEventType type, int value)
|
||||||
{
|
{
|
||||||
wxCommandEvent event(type, GetId());
|
wxCommandEvent event( type, GetId() );
|
||||||
event.SetEventObject(this);
|
event.SetEventObject(this);
|
||||||
event.SetInt(value);
|
event.SetInt(value);
|
||||||
wxPostEvent(this, event);
|
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()
|
void CtrlRegisterList::refreshChangedRegs()
|
||||||
{
|
{
|
||||||
if (cpu->getPC() == lastPc && cpu->getCycles() == lastCycles)
|
if (cpu->getPC() == lastPc)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int cat = 0; cat < cpu->getRegisterCategoryCount(); cat++)
|
for (size_t cat = 0; cat < changedCategories.size(); cat++)
|
||||||
{
|
{
|
||||||
std::vector<ChangedReg>& regs = changedCategories[cat];
|
ChangedReg* regs = changedCategories[cat];
|
||||||
int size = cpu->getRegisterSize(cat);
|
int size = cpu->getRegisterSize(category);
|
||||||
|
|
||||||
for (int i = 0; i < cpu->getRegisterCount(cat); i++)
|
for (int i = 0; i < cpu->getRegisterCount(cat); i++)
|
||||||
{
|
{
|
||||||
ChangedReg& reg = regs[i];
|
ChangedReg& reg = regs[i];
|
||||||
memset(®.changed, 0, sizeof(reg.changed));
|
memset(®.changed,0,sizeof(reg.changed));
|
||||||
|
|
||||||
u128 newValue = cpu->getRegister(cat, i);
|
u128 newValue = cpu->getRegister(cat,i);
|
||||||
|
|
||||||
if (reg.oldValue != newValue)
|
if (reg.oldValue != newValue)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
if (size >= 128 && (reg.oldValue._u32[3] != newValue._u32[3] || reg.oldValue._u32[2] != newValue._u32[2]))
|
if (size >= 128 && (reg.oldValue._u32[3] != newValue._u32[3] || reg.oldValue._u32[2] != newValue._u32[2]))
|
||||||
{
|
{
|
||||||
changed = true;
|
changed = true;
|
||||||
reg.changed[3] = true;
|
reg.changed[3] = true;
|
||||||
reg.changed[2] = true;
|
reg.changed[2] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size >= 64 && (reg.oldValue._u32[1] != newValue._u32[1] || changed))
|
if (size >= 64 && (reg.oldValue._u32[1] != newValue._u32[1] || changed))
|
||||||
{
|
{
|
||||||
changed = true;
|
changed = true;
|
||||||
reg.changed[1] = true;
|
reg.changed[1] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reg.oldValue._u32[0] != newValue._u32[0] || changed)
|
if (reg.oldValue._u32[0] != newValue._u32[0] || changed)
|
||||||
{
|
{
|
||||||
reg.changed[0] = true;
|
reg.changed[0] = true;
|
||||||
}
|
}
|
||||||
reg.oldValue = newValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lastPc = cpu->getPC();
|
reg.oldValue = newValue;
|
||||||
lastCycles = cpu->getCycles();
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastPc = cpu->getPC();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CtrlRegisterList::paintEvent(wxPaintEvent & evt)
|
void CtrlRegisterList::redraw()
|
||||||
{
|
{
|
||||||
updateHandler();
|
Update();
|
||||||
evt.Skip();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CtrlRegisterList::updateHandler()
|
void CtrlRegisterList::sizeEvent(wxSizeEvent& evt)
|
||||||
{
|
{
|
||||||
if (cpu->isCpuPaused() || needsValueUpdating)
|
Refresh();
|
||||||
{
|
evt.Skip();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CtrlRegisterList::changeValue(RegisterChangeMode mode, int cat, int reg)
|
void drawU32Text(wxDC& dc, u32 value, int x, int y)
|
||||||
{
|
{
|
||||||
wxString oldStr;
|
char str[32];
|
||||||
u128 oldValue = cpu->getRegister(cat, reg);
|
sprintf(str,"%08X",value);
|
||||||
|
dc.DrawText(wxString(str,wxConvUTF8),x,y);
|
||||||
|
}
|
||||||
|
|
||||||
switch (mode)
|
void CtrlRegisterList::OnDraw(wxDC& dc)
|
||||||
{
|
{
|
||||||
case LOWER64:
|
#ifdef WIN32
|
||||||
oldStr = wxsFormat(L"0x%016llX", oldValue._u64[0]);
|
wxFont font = wxFont(wxSize(charWidth,rowHeight-2),wxFONTFAMILY_DEFAULT,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_NORMAL,false,L"Lucida Console");
|
||||||
break;
|
#else
|
||||||
case UPPER64:
|
wxFont font = wxFont(8,wxFONTFAMILY_DEFAULT,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_NORMAL,false,L"Lucida Console");
|
||||||
oldStr = wxsFormat(L"0x%016llX", oldValue._u64[1]);
|
font.SetPixelSize(wxSize(charWidth,rowHeight-2));
|
||||||
break;
|
#endif
|
||||||
case CHANGE32:
|
dc.SetFont(font);
|
||||||
oldStr = wxsFormat(L"0x%08X", oldValue._u64[0]);
|
|
||||||
break;
|
// clear background
|
||||||
}
|
wxColor white = wxColor(0xFFFFFFFF);
|
||||||
|
|
||||||
u64 newValue;
|
dc.SetBrush(wxBrush(white));
|
||||||
if (executeExpressionWindow(this, cpu, newValue, oldStr))
|
dc.SetPen(wxPen(white));
|
||||||
{
|
|
||||||
switch (mode)
|
wxSize size = GetClientSize();
|
||||||
{
|
dc.DrawRectangle(0,0,size.x,size.y);
|
||||||
case LOWER64:
|
|
||||||
oldValue._u64[0] = newValue;
|
refreshChangedRegs();
|
||||||
break;
|
|
||||||
case UPPER64:
|
wxColor colorChanged = wxColor(0xFF0000FF);
|
||||||
oldValue._u64[1] = newValue;
|
wxColor colorUnchanged = wxColor(0xFF004000);
|
||||||
break;
|
wxColor colorNormal = wxColor(0xFF600000);
|
||||||
case CHANGE32:
|
|
||||||
oldValue._u32[0] = newValue;
|
// draw categories
|
||||||
break;
|
int piece = size.x/cpu->getRegisterCategoryCount();
|
||||||
}
|
for (int i = 0; i < cpu->getRegisterCategoryCount(); i++)
|
||||||
cpu->setRegister(cat, reg, oldValue);
|
{
|
||||||
oldValue = cpu->getRegister(cat, reg);
|
const char* name = cpu->getRegisterCategoryName(i);
|
||||||
}
|
|
||||||
needsValueUpdating = true;
|
int x = i*piece;
|
||||||
needsSizeUpdating = true;
|
|
||||||
|
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)
|
void CtrlRegisterList::onPopupClick(wxCommandEvent& evt)
|
||||||
{
|
{
|
||||||
int cat = getCurrentCategory();
|
switch (evt.GetId())
|
||||||
wxGrid* regGrid = registerGrids[cat];
|
{
|
||||||
int reg = regGrid->GetGridCursorRow();
|
case ID_REGISTERLIST_DISPLAY32:
|
||||||
switch (evt.GetId())
|
maxBits = 32;
|
||||||
{
|
SetInitialSize(ClientToWindowSize(GetMinClientSize()));
|
||||||
case ID_REGISTERLIST_DISPLAY32:
|
postEvent(debEVT_UPDATELAYOUT,0);
|
||||||
maxBits = 32;
|
Refresh();
|
||||||
postEvent(debEVT_UPDATELAYOUT, 0);
|
break;
|
||||||
Refresh();
|
case ID_REGISTERLIST_DISPLAY64:
|
||||||
break;
|
maxBits = 64;
|
||||||
case ID_REGISTERLIST_DISPLAY64:
|
SetInitialSize(ClientToWindowSize(GetMinClientSize()));
|
||||||
maxBits = 64;
|
postEvent(debEVT_UPDATELAYOUT,0);
|
||||||
postEvent(debEVT_UPDATELAYOUT, 0);
|
Refresh();
|
||||||
Refresh();
|
break;
|
||||||
break;
|
case ID_REGISTERLIST_DISPLAY128:
|
||||||
case ID_REGISTERLIST_DISPLAY128:
|
maxBits = 128;
|
||||||
maxBits = 128;
|
SetInitialSize(ClientToWindowSize(GetMinClientSize()));
|
||||||
postEvent(debEVT_UPDATELAYOUT, 0);
|
postEvent(debEVT_UPDATELAYOUT,0);
|
||||||
Refresh();
|
Refresh();
|
||||||
break;
|
break;
|
||||||
case ID_REGISTERLIST_CHANGELOWER:
|
case ID_REGISTERLIST_CHANGELOWER:
|
||||||
changeValue(LOWER64, cat, reg);
|
changeValue(LOWER64);
|
||||||
Refresh();
|
Refresh();
|
||||||
break;
|
break;
|
||||||
case ID_REGISTERLIST_CHANGEUPPER:
|
case ID_REGISTERLIST_CHANGEUPPER:
|
||||||
changeValue(UPPER64, cat, reg);
|
changeValue(UPPER64);
|
||||||
Refresh();
|
Refresh();
|
||||||
break;
|
break;
|
||||||
case ID_REGISTERLIST_CHANGEVALUE:
|
case ID_REGISTERLIST_CHANGEVALUE:
|
||||||
if (cpu->getRegisterSize(cat) == 32)
|
if (cpu->getRegisterSize(category) == 32)
|
||||||
changeValue(CHANGE32, cat, reg);
|
changeValue(CHANGE32);
|
||||||
else
|
else
|
||||||
changeValue(LOWER64, cat, reg);
|
changeValue(LOWER64);
|
||||||
Refresh();
|
Refresh();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
wxMessageBox(L"Unimplemented.", L"Unimplemented.", wxICON_INFORMATION);
|
wxMessageBox( L"Unimplemented.", L"Unimplemented.", wxICON_INFORMATION);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
needsValueUpdating = true;
|
|
||||||
needsSizeUpdating = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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::mouseEvent(wxMouseEvent& evt)
|
||||||
void CtrlRegisterList::gridEvent(wxGridEvent& evt)
|
|
||||||
{
|
{
|
||||||
// Mouse events
|
int xOffset, yOffset;
|
||||||
if (evt.GetEventType() == wxEVT_GRID_CELL_RIGHT_CLICK ||
|
((wxScrolledWindow*) this)->GetViewStart(&xOffset, &yOffset);
|
||||||
evt.GetEventType() == wxEVT_GRID_LABEL_RIGHT_CLICK)
|
|
||||||
{
|
|
||||||
wxMenu menu;
|
|
||||||
int bits = cpu->getRegisterSize(getCurrentCategory());
|
|
||||||
|
|
||||||
menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY32, L"Display 32 bit");
|
wxClientDC dc(this);
|
||||||
menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY64, L"Display 64 bit");
|
wxPoint pos = evt.GetPosition();
|
||||||
menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY128, L"Display 128 bit");
|
int x = dc.DeviceToLogicalX(pos.x) + xOffset;
|
||||||
menu.AppendSeparator();
|
int y = dc.DeviceToLogicalY(pos.y) + yOffset;
|
||||||
|
|
||||||
if (bits >= 64)
|
if (evt.GetEventType() == wxEVT_RIGHT_UP)
|
||||||
{
|
{
|
||||||
menu.Append(ID_REGISTERLIST_CHANGELOWER, L"Change lower 64 bit");
|
if (y >= rowHeight)
|
||||||
menu.Append(ID_REGISTERLIST_CHANGEUPPER, L"Change upper 64 bit");
|
{
|
||||||
}
|
int row = (y-rowHeight)/rowHeight;
|
||||||
else {
|
if (row != currentRows[category] && row < cpu->getRegisterCount(category))
|
||||||
menu.Append(ID_REGISTERLIST_CHANGEVALUE, L"Change value");
|
setCurrentRow(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (maxBits)
|
wxMenu menu;
|
||||||
{
|
int bits = cpu->getRegisterSize(category);
|
||||||
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, wxCommandEventHandler(CtrlRegisterList::onPopupClick), nullptr, this);
|
menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY32, L"Display 32 bit");
|
||||||
PopupMenu(&menu, evt.GetPosition());
|
menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY64, L"Display 64 bit");
|
||||||
needsValueUpdating = true;
|
menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY128, L"Display 128 bit");
|
||||||
}
|
menu.AppendSeparator();
|
||||||
else
|
|
||||||
{
|
|
||||||
evt.Skip();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CtrlRegisterList::categoryChangedEvent(wxBookCtrlEvent& evt)
|
if (bits >= 64)
|
||||||
{
|
{
|
||||||
needsSizeUpdating = true;
|
menu.Append(ID_REGISTERLIST_CHANGELOWER, L"Change lower 64 bit");
|
||||||
needsValueUpdating = true;
|
menu.Append(ID_REGISTERLIST_CHANGEUPPER, L"Change upper 64 bit");
|
||||||
evt.Skip();
|
} 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)
|
void CtrlRegisterList::keydownEvent(wxKeyEvent& evt)
|
||||||
{
|
{
|
||||||
needsValueUpdating = true;
|
switch (evt.GetKeyCode())
|
||||||
evt.Skip();
|
{
|
||||||
|
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
|
#pragma once
|
||||||
#include <wx/wx.h>
|
#include <wx/wx.h>
|
||||||
#include <wx/notebook.h>
|
|
||||||
#include <wx/grid.h>
|
|
||||||
#include "DebugTools/DebugInterface.h"
|
#include "DebugTools/DebugInterface.h"
|
||||||
#include "DebugTools/DisassemblyManager.h"
|
#include "DebugTools/DisassemblyManager.h"
|
||||||
|
|
||||||
class CtrlRegisterList : public wxWindow
|
class CtrlRegisterList: public wxScrolledWindow
|
||||||
{
|
{
|
||||||
public:
|
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
|
return wxSize(optimalSize.x,0);
|
||||||
void paintEvent(wxPaintEvent & evt);
|
}
|
||||||
void onPopupClick(wxCommandEvent& evt);
|
|
||||||
void gridEvent(wxGridEvent& evt);
|
virtual wxSize DoGetBestClientSize() const
|
||||||
void categoryChangedEvent(wxBookCtrlEvent& evt);
|
{
|
||||||
void keydownEvent(wxKeyEvent& evt);
|
return GetMinClientSize();
|
||||||
DECLARE_EVENT_TABLE()
|
}
|
||||||
private:
|
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 postEvent(wxEventType type, wxString text);
|
||||||
void updateHandler();
|
void postEvent(wxEventType type, int value);
|
||||||
void updateValues(int cat);
|
|
||||||
void updateSize(int cat);
|
|
||||||
int getCurrentCategory() const;
|
|
||||||
void postEvent(wxEventType type, wxString text);
|
|
||||||
void postEvent(wxEventType type, int value);
|
|
||||||
|
|
||||||
struct ChangedReg
|
struct ChangedReg
|
||||||
{
|
{
|
||||||
u128 oldValue;
|
u128 oldValue;
|
||||||
bool changed[4];
|
bool changed[4];
|
||||||
ChangedReg() { memset(this, 0, sizeof(*this)); }
|
};
|
||||||
};
|
|
||||||
|
|
||||||
|
std::vector<ChangedReg*> changedCategories;
|
||||||
|
std::vector<int> startPositions;
|
||||||
|
std::vector<int> currentRows;
|
||||||
|
|
||||||
std::vector<std::vector<ChangedReg>> changedCategories;
|
DebugInterface* cpu;
|
||||||
|
int rowHeight,charWidth;
|
||||||
DebugInterface* cpu; // Used to get register values and other info from the emu
|
u32 lastPc;
|
||||||
u32 lastPc, lastCycles;
|
int category;
|
||||||
int maxBits; // maximum number of bits beings displayed
|
int maxBits;
|
||||||
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.
|
|
||||||
};
|
|
|
@ -39,6 +39,7 @@ BEGIN_EVENT_TABLE(DisassemblyDialog, wxFrame)
|
||||||
EVT_COMMAND( wxID_ANY, debEVT_UPDATE, DisassemblyDialog::onDebuggerEvent )
|
EVT_COMMAND( wxID_ANY, debEVT_UPDATE, DisassemblyDialog::onDebuggerEvent )
|
||||||
EVT_COMMAND( wxID_ANY, debEVT_BREAKPOINTWINDOW, DisassemblyDialog::onDebuggerEvent )
|
EVT_COMMAND( wxID_ANY, debEVT_BREAKPOINTWINDOW, DisassemblyDialog::onDebuggerEvent )
|
||||||
EVT_COMMAND( wxID_ANY, debEVT_MAPLOADED, DisassemblyDialog::onDebuggerEvent )
|
EVT_COMMAND( wxID_ANY, debEVT_MAPLOADED, DisassemblyDialog::onDebuggerEvent )
|
||||||
|
EVT_SIZE(DisassemblyDialog::onSizeEvent)
|
||||||
EVT_CLOSE( DisassemblyDialog::onClose )
|
EVT_CLOSE( DisassemblyDialog::onClose )
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
@ -176,7 +177,7 @@ void CpuTabPage::update()
|
||||||
{
|
{
|
||||||
breakpointList->reloadBreakpoints();
|
breakpointList->reloadBreakpoints();
|
||||||
|
|
||||||
if (threadList != NULL)
|
if (threadList != NULL && cpu->isAlive())
|
||||||
{
|
{
|
||||||
threadList->reloadThreads();
|
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 ),
|
wxFrame( parent, wxID_ANY, L"Debugger", wxDefaultPosition,wxDefaultSize,wxRESIZE_BORDER|wxCLOSE_BOX|wxCAPTION|wxSYSTEM_MENU ),
|
||||||
currentCpu(NULL)
|
currentCpu(NULL)
|
||||||
{
|
{
|
||||||
|
int width = g_Conf->EmuOptions.Debugger.WindowWidth;
|
||||||
|
int height = g_Conf->EmuOptions.Debugger.WindowHeight;
|
||||||
|
|
||||||
topSizer = new wxBoxSizer( wxVERTICAL );
|
topSizer = new wxBoxSizer( wxVERTICAL );
|
||||||
wxPanel *panel = new wxPanel(this, wxID_ANY,
|
wxPanel *panel = new wxPanel(this, wxID_ANY,
|
||||||
|
@ -252,7 +255,7 @@ DisassemblyDialog::DisassemblyDialog(wxWindow* parent):
|
||||||
topSizer->Add(topRowSizer,0,wxLEFT|wxRIGHT|wxTOP,3);
|
topSizer->Add(topRowSizer,0,wxLEFT|wxRIGHT|wxTOP,3);
|
||||||
|
|
||||||
// create middle part of the window
|
// create middle part of the window
|
||||||
wxNotebook* middleBook = new wxNotebook(panel,wxID_ANY);
|
middleBook = new wxNotebook(panel,wxID_ANY);
|
||||||
middleBook->SetBackgroundColour(wxColour(0xFFF0F0F0));
|
middleBook->SetBackgroundColour(wxColour(0xFFF0F0F0));
|
||||||
eeTab = new CpuTabPage(middleBook,&r5900Debug);
|
eeTab = new CpuTabPage(middleBook,&r5900Debug);
|
||||||
iopTab = new CpuTabPage(middleBook,&r3000Debug);
|
iopTab = new CpuTabPage(middleBook,&r3000Debug);
|
||||||
|
@ -267,9 +270,23 @@ DisassemblyDialog::DisassemblyDialog(wxWindow* parent):
|
||||||
SetMinSize(wxSize(1000,600));
|
SetMinSize(wxSize(1000,600));
|
||||||
panel->GetSizer()->Fit(this);
|
panel->GetSizer()->Fit(this);
|
||||||
|
|
||||||
|
if (width != 0 && height != 0)
|
||||||
|
SetSize(width,height);
|
||||||
|
|
||||||
setDebugMode(true,true);
|
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
|
#ifdef WIN32
|
||||||
WXLRESULT DisassemblyDialog::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
|
WXLRESULT DisassemblyDialog::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
|
||||||
{
|
{
|
||||||
|
@ -469,7 +486,7 @@ void DisassemblyDialog::onDebuggerEvent(wxCommandEvent& evt)
|
||||||
if (type == debEVT_SETSTATUSBARTEXT)
|
if (type == debEVT_SETSTATUSBARTEXT)
|
||||||
{
|
{
|
||||||
DebugInterface* cpu = reinterpret_cast<DebugInterface*>(evt.GetClientData());
|
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());
|
GetStatusBar()->SetLabel(evt.GetString());
|
||||||
} else if (type == debEVT_UPDATELAYOUT)
|
} else if (type == debEVT_UPDATELAYOUT)
|
||||||
{
|
{
|
||||||
|
@ -568,6 +585,19 @@ void DisassemblyDialog::setDebugMode(bool debugMode, bool switchPC)
|
||||||
|
|
||||||
if (running)
|
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)
|
if (debugMode)
|
||||||
{
|
{
|
||||||
CBreakPoints::ClearTemporaryBreakPoints();
|
CBreakPoints::ClearTemporaryBreakPoints();
|
||||||
|
@ -596,6 +626,12 @@ void DisassemblyDialog::setDebugMode(bool debugMode, bool switchPC)
|
||||||
stepOverButton->Enable(false);
|
stepOverButton->Enable(false);
|
||||||
stepOutButton->Enable(false);
|
stepOutButton->Enable(false);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
breakRunButton->SetLabel(L"Run");
|
||||||
|
stepIntoButton->Enable(false);
|
||||||
|
stepOverButton->Enable(false);
|
||||||
|
stepOutButton->Enable(false);
|
||||||
|
currentCpu = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
update();
|
update();
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "CtrlMemView.h"
|
#include "CtrlMemView.h"
|
||||||
#include "DebugEvents.h"
|
#include "DebugEvents.h"
|
||||||
#include "DebuggerLists.h"
|
#include "DebuggerLists.h"
|
||||||
|
#include "../MSWstuff.h"
|
||||||
|
|
||||||
class DebuggerHelpDialog: public wxDialog
|
class DebuggerHelpDialog: public wxDialog
|
||||||
{
|
{
|
||||||
|
@ -30,6 +31,16 @@ public:
|
||||||
DebuggerHelpDialog(wxWindow* parent);
|
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
|
class CpuTabPage: public wxPanel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -91,6 +102,7 @@ protected:
|
||||||
void onDebuggerEvent(wxCommandEvent& evt);
|
void onDebuggerEvent(wxCommandEvent& evt);
|
||||||
void onPageChanging(wxCommandEvent& evt);
|
void onPageChanging(wxCommandEvent& evt);
|
||||||
void onBreakpointClick(wxCommandEvent& evt);
|
void onBreakpointClick(wxCommandEvent& evt);
|
||||||
|
void onSizeEvent(wxSizeEvent& event);
|
||||||
void onClose(wxCloseEvent& evt);
|
void onClose(wxCloseEvent& evt);
|
||||||
void stepOver();
|
void stepOver();
|
||||||
void stepInto();
|
void stepInto();
|
||||||
|
@ -100,6 +112,7 @@ private:
|
||||||
CpuTabPage* eeTab;
|
CpuTabPage* eeTab;
|
||||||
CpuTabPage* iopTab;
|
CpuTabPage* iopTab;
|
||||||
CpuTabPage* currentCpu;
|
CpuTabPage* currentCpu;
|
||||||
|
wxNotebook* middleBook;
|
||||||
|
|
||||||
wxBoxSizer* topSizer;
|
wxBoxSizer* topSizer;
|
||||||
wxButton* breakRunButton;
|
wxButton* breakRunButton;
|
||||||
|
|
Loading…
Reference in New Issue