diff --git a/pcsx2/gui/Debugger/CtrlRegisterList.cpp b/pcsx2/gui/Debugger/CtrlRegisterList.cpp
index a99f504933..f4f2537116 100644
--- a/pcsx2/gui/Debugger/CtrlRegisterList.cpp
+++ b/pcsx2/gui/Debugger/CtrlRegisterList.cpp
@@ -1,17 +1,17 @@
/* PCSX2 - PS2 Emulator for PCs
- * Copyright (C) 2002-2014 PCSX2 Dev Team
- *
- * PCSX2 is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Lesser General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with PCSX2.
- * If not, see .
- */
+* Copyright (C) 2002-2014 PCSX2 Dev Team
+*
+* PCSX2 is free software: you can redistribute it and/or modify it under the terms
+* of the GNU Lesser General Public License as published by the Free Software Found-
+* ation, either version 3 of the License, or (at your option) any later version.
+*
+* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+* PURPOSE. See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with PCSX2.
+* If not, see .
+*/
#include "PrecompiledHeader.h"
#include "CtrlRegisterList.h"
@@ -20,505 +20,436 @@
#include "DebugEvents.h"
#include "AppConfig.h"
-BEGIN_EVENT_TABLE(CtrlRegisterList, wxWindow)
- EVT_PAINT(CtrlRegisterList::paintEvent)
- 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)
+CtrlRegisterList::CtrlRegisterList(wxWindow* parent, DebugInterface* _cpu) :
+ wxWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS | wxBORDER_NONE),
+ cpu(_cpu),
+ lastPc(0),
+ maxBits(128),
+ lastCycles(0),
+ needsValueUpdating(true),
+ needsSizeUpdating(true)
{
- rowHeight = g_Conf->EmuOptions.Debugger.FontHeight+2;
- charWidth = g_Conf->EmuOptions.Debugger.FontWidth;
- category = 0;
- maxBits = 128;
- lastPc = 0xFFFFFFFF;
+ int rowHeight = g_Conf->EmuOptions.Debugger.FontHeight + 2;
+ int charWidth = g_Conf->EmuOptions.Debugger.FontWidth;
- for (int i = 0; i < cpu->getRegisterCategoryCount(); i++)
- {
- int count = cpu->getRegisterCount(i);
- ChangedReg* regs = new ChangedReg[count];
- memset(regs,0,sizeof(ChangedReg)*count);
- changedCategories.push_back(regs);
+#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
+ registerCategories = new wxNotebook(this, -1);
+ registerCategories->Bind(wxEVT_BOOKCTRL_PAGE_CHANGED, &CtrlRegisterList::categoryChangedEvent, this);
+ for (int cat = 0; cat < cpu->getRegisterCategoryCount(); cat++)
+ {
+ int numRegs = cpu->getRegisterCount(cat);
- int maxLen = 0;
- for (int k = 0; k < cpu->getRegisterCount(i); k++)
- {
- maxLen = std::max(maxLen,strlen(cpu->getRegisterName(i,k)));
- }
+ changedCategories.push_back(std::vector(numRegs));
- int x = 17+(maxLen+3)*charWidth;
- startPositions.push_back(x);
- currentRows.push_back(0);
- }
+ wxGrid* regGrid = new wxGrid(registerCategories, -1);
- SetDoubleBuffered(true);
- SetInitialSize(ClientToWindowSize(GetMinClientSize()));
+ registerGrids.push_back(regGrid);
+ registerCategories->AddPage(regGrid, cpu->getRegisterCategoryName(cat));
+
+ 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, cpu->getRegisterName(cat, row));
+ for (int col = 0; col < numCols; col++)
+ regGrid->SetColLabelValue(col, std::to_string(32 * (numCols - col) - 1) + std::string("-") +
+ std::to_string(32 * (numCols - col - 1)));
+ break;
+ case DebugInterface::SPECIAL:
+ regGrid->CreateGrid(numRegs, 1);
+ for (int row = 0; row < numRegs; row++)
+ regGrid->SetRowLabelValue(row, cpu->getRegisterName(cat, row));
+ break;
+ }
+
+ regGrid->EnableEditing(false);
+ regGrid->SetDefaultCellFont(font);
+ regGrid->DisableDragGridSize();
+ regGrid->DisableDragRowSize();
+ regGrid->DisableDragColSize();
+ regGrid->Bind(wxEVT_PAINT, &CtrlRegisterList::paintEvent, this);
+ regGrid->Bind(wxEVT_GRID_LABEL_LEFT_CLICK, &CtrlRegisterList::gridEvent, this);
+ regGrid->Bind(wxEVT_GRID_LABEL_RIGHT_CLICK, &CtrlRegisterList::gridEvent, this);
+ regGrid->Bind(wxEVT_GRID_CELL_RIGHT_CLICK, &CtrlRegisterList::gridEvent, this);
+ regGrid->Bind(wxEVT_GRID_CELL_LEFT_CLICK, &CtrlRegisterList::gridEvent, this);
+ regGrid->Bind(wxEVT_KEY_DOWN, &CtrlRegisterList::keydownEvent, 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.
+// 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 numRows = regGrid->GetNumberRows();
+ int numCols = regGrid->GetNumberCols();
+
+ std::vector& 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 col = 0; col < numCols; col++)
+ {
+ const wxColor colorChanged = wxColor(0xFF0000FF);
+ const wxColor colorUnchanged = wxColor(0xFF004000);
+ wxColor textColor;
+ wxString cellValue;
+
+ switch (type)
+ {
+ case DebugInterface::NORMAL:
+ cellValue = wxString::Format("%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)
+{
+ wxGrid* regGrid = registerGrids[cat];
+
+ // Make sure that the number of shown cols is correct.
+ {
+ int regBits = cpu->getRegisterSize(cat);
+ int numCols = regGrid->GetNumberCols();
+
+ 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
+ }
+
+ regGrid->AutoSize();
+ wxSize pageSize = regGrid->GetSize();
+
+ // Hacks below
+ {
+ // 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 to 1/2 screen size.
+ // 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(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)
{
- 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)
- return;
+ if (cpu->getPC() == lastPc && cpu->getCycles() == lastCycles)
+ return;
- for (size_t cat = 0; cat < changedCategories.size(); cat++)
- {
- ChangedReg* regs = changedCategories[cat];
- int size = cpu->getRegisterSize(category);
+ for (int cat = 0; cat < cpu->getRegisterCategoryCount(); cat++)
+ {
+ std::vector& regs = changedCategories[cat];
+ int size = cpu->getRegisterSize(cat);
- 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;
- }
+ if (reg.oldValue._u32[0] != newValue._u32[0] || changed)
+ {
+ reg.changed[0] = true;
+ }
+ reg.oldValue = newValue;
+ }
+ }
+ }
- reg.oldValue = newValue;
- }
- }
- }
-
- lastPc = cpu->getPC();
+ lastPc = cpu->getPC();
+ lastCycles = cpu->getCycles();
}
void CtrlRegisterList::paintEvent(wxPaintEvent & evt)
{
- wxPaintDC dc(this);
- render(dc);
+ updateHandler();
+ evt.Skip();
}
-void CtrlRegisterList::redraw()
+void CtrlRegisterList::updateHandler()
{
- wxClientDC dc(this);
- render(dc);
+ if (cpu->isCpuPaused() || needsValueUpdating)
+ {
+ refreshChangedRegs();
+ updateValues(getCurrentCategory());
+ needsValueUpdating = false;
+ }
+
+ if (needsSizeUpdating)
+ {
+ updateSize(getCurrentCategory());
+ needsSizeUpdating = false;
+ }
+
+ wxGrid* regGrid = registerGrids[getCurrentCategory()];
+ regGrid->ClearSelection();
}
-void drawU32Text(wxDC& dc, u32 value, int x, int y)
+
+void CtrlRegisterList::changeValue(RegisterChangeMode mode, int cat, int reg)
{
- char str[32];
- sprintf(str,"%08X",value);
- dc.DrawText(wxString(str,wxConvUTF8),x,y);
+ wchar_t str[64];
+
+ u128 oldValue = cpu->getRegister(cat, reg);
+
+ 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(cat, reg, oldValue);
+ oldValue = cpu->getRegister(cat, reg);
+ }
+ needsValueUpdating = true;
+ needsSizeUpdating = true;
}
-void CtrlRegisterList::render(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);
-
- dc.SetBrush(wxBrush(white));
- dc.SetPen(wxPen(white));
-
- wxSize size = GetSize();
- 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(0xFFFFEFE8)));
- dc.SetPen(wxPen(wxColor(0xFFFFEFE8)));
- 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(3,maxBits/32-1);
- int actualX = size.x-4-(startIndex+1)*(8*charWidth+2);
- x = std::max(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)
{
- 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 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;
}
-void CtrlRegisterList::setCurrentRow(int row)
+int CtrlRegisterList::getCurrentCategory() const
{
- 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();
+ return registerCategories->GetSelection();
}
-void CtrlRegisterList::mouseEvent(wxMouseEvent& evt)
+
+void CtrlRegisterList::gridEvent(wxGridEvent& evt)
{
- if (evt.GetEventType() == wxEVT_RIGHT_UP)
- {
- int y = evt.GetPosition().y;
+ // Mouse events
+ if (evt.GetEventType() == wxEVT_GRID_CELL_RIGHT_CLICK ||
+ evt.GetEventType() == wxEVT_GRID_LABEL_RIGHT_CLICK)
+ {
+ wxMenu menu;
+ int bits = cpu->getRegisterSize(getCurrentCategory());
- if (y >= rowHeight)
- {
- int row = (y-rowHeight)/rowHeight;
- if (row != currentRows[category] && row < cpu->getRegisterCount(category))
- setCurrentRow(row);
- }
+ 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();
- wxMenu menu;
- int bits = cpu->getRegisterSize(category);
+ 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");
+ }
- 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();
+ 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;
+ }
- 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))
- {
- int x = evt.GetPosition().x;
- int y = evt.GetPosition().y;
-
- if (y < rowHeight)
- {
- int piece = GetSize().x/cpu->getRegisterCategoryCount();
- int cat = std::min(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();
- }
+ menu.Bind(wxEVT_COMMAND_MENU_SELECTED, &CtrlRegisterList::onPopupClick, this);
+ PopupMenu(&menu, evt.GetPosition());
+ }
+ needsValueUpdating = true;
+ evt.Skip();
}
-void CtrlRegisterList::keydownEvent(wxKeyEvent& evt)
+void CtrlRegisterList::categoryChangedEvent(wxBookCtrlEvent& evt)
{
- switch (evt.GetKeyCode())
- {
- case WXK_UP:
- setCurrentRow(std::max(currentRows[category]-1,0));
- break;
- case WXK_DOWN:
- setCurrentRow(std::min(currentRows[category]+1,cpu->getRegisterCount(category)));
- break;
- case WXK_TAB:
- category = (category+1) % cpu->getRegisterCategoryCount();
- Refresh();
- break;
- }
+ needsSizeUpdating = true;
+ needsValueUpdating = true;
+ evt.Skip();
}
+
+void CtrlRegisterList::keydownEvent(wxEvent& evt)
+{
+ needsValueUpdating = true;
+ evt.Skip();
+}
\ No newline at end of file
diff --git a/pcsx2/gui/Debugger/CtrlRegisterList.h b/pcsx2/gui/Debugger/CtrlRegisterList.h
index ada912281d..1fe68746a3 100644
--- a/pcsx2/gui/Debugger/CtrlRegisterList.h
+++ b/pcsx2/gui/Debugger/CtrlRegisterList.h
@@ -1,89 +1,63 @@
/* PCSX2 - PS2 Emulator for PCs
- * Copyright (C) 2002-2014 PCSX2 Dev Team
- *
- * PCSX2 is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Lesser General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with PCSX2.
- * If not, see .
- */
-
+* Copyright (C) 2002-2014 PCSX2 Dev Team
+*
+* PCSX2 is free software: you can redistribute it and/or modify it under the terms
+* of the GNU Lesser General Public License as published by the Free Software Found-
+* ation, either version 3 of the License, or (at your option) any later version.
+*
+* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+* PURPOSE. See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with PCSX2.
+* If not, see .
+*/
#pragma once
#include
+#include
+#include
#include "DebugTools/DebugInterface.h"
#include "DebugTools/DisassemblyManager.h"
-class CtrlRegisterList: public wxWindow
+class CtrlRegisterList : public wxWindow
{
public:
- CtrlRegisterList(wxWindow* parent, DebugInterface* _cpu);
-
- void paintEvent(wxPaintEvent & evt);
- void mouseEvent(wxMouseEvent& evt);
- void keydownEvent(wxKeyEvent& evt);
- void onPopupClick(wxCommandEvent& evt);
- void redraw();
- DECLARE_EVENT_TABLE()
+ CtrlRegisterList(wxWindow* parent, DebugInterface* _cpu);
- virtual wxSize GetMinClientSize() const
- {
- int columnChars = 0;
- int maxWidth = 0;
- int maxRows = 0;
-
- for (int i = 0; i < cpu->getRegisterCategoryCount(); i++)
- {
- int bits = std::min(maxBits,cpu->getRegisterSize(i));
- int start = startPositions[i];
-
- int w = start+(bits/4) * charWidth;
- if (bits > 32)
- w += (bits/32)*2-2;
-
- maxWidth = std::max(maxWidth,w);
- columnChars += strlen(cpu->getRegisterCategoryName(i))+1;
- maxRows = std::max(maxRows,cpu->getRegisterCount(i));
- }
-
- maxWidth = std::max(columnChars*charWidth,maxWidth+4);
-
- return wxSize(maxWidth,(maxRows+1)*rowHeight);
- }
-
- virtual wxSize DoGetBestClientSize() const
- {
- return GetMinClientSize();
- }
+ // Event handlers
+ void paintEvent(wxPaintEvent & evt);
+ void onPopupClick(wxCommandEvent& evt);
+ void gridEvent(wxGridEvent& evt);
+ void categoryChangedEvent(wxBookCtrlEvent& evt);
+ void keydownEvent(wxEvent& evt);
private:
- enum RegisterChangeMode { LOWER64, UPPER64, CHANGE32 };
+ enum RegisterChangeMode { LOWER64, UPPER64, CHANGE32 };
- void render(wxDC& dc);
- void refreshChangedRegs();
- void setCurrentRow(int row);
- void changeValue(RegisterChangeMode mode);
+ void refreshChangedRegs();
- void postEvent(wxEventType type, wxString text);
- void postEvent(wxEventType type, int value);
+ 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);
- struct ChangedReg
- {
- u128 oldValue;
- bool changed[4];
- };
+ struct ChangedReg
+ {
+ u128 oldValue;
+ bool changed[4];
+ ChangedReg() { memset(this, 0, sizeof(*this)); }
+ };
- std::vector changedCategories;
- std::vector startPositions;
- std::vector currentRows;
- DebugInterface* cpu;
- int rowHeight,charWidth;
- u32 lastPc;
- int category;
- int maxBits;
+ std::vector> 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 registerGrids; // Grids displaying register values for each of the tabs.
};
\ No newline at end of file