Add list to show, edit and delete breakpoints

This commit is contained in:
Kingcom 2014-02-27 13:22:19 +01:00
parent aad9ea0e05
commit 4e2e178417
15 changed files with 440 additions and 10 deletions

View File

@ -11,6 +11,7 @@ disassembly view:
page up move visible area up one page
page down move visible area down one page
f10 step over
f11 step into
tab toggle display symbols
left click select line/toggle breakpoint if line is already highlighted
right click open context menu
@ -29,3 +30,11 @@ memory view:
any overwrite ansi byte
left click select byte/nibble
right click open context menu
breakpoint list:
up select previous item
down select next item
delete remove selected breakpoint
return edit selected breakpoint
space toggle enable state of selected breakpoint

View File

@ -326,6 +326,7 @@ set(pcsx2GuiSources
gui/Debugger/CtrlDisassemblyView.cpp
gui/Debugger/CtrlRegisterList.cpp
gui/Debugger/CtrlMemView.cpp
gui/Debugger/DebuggerLists.cpp
gui/Debugger/DisassemblyDialog.cpp
gui/Debugger/DebugEvents.cpp
gui/ExecutorThread.cpp
@ -381,6 +382,7 @@ set(pcsx2GuiHeaders
gui/Debugger/CtrlDisassemblyView.h
gui/Debugger/CtrlRegisterList.h
gui/Debugger/CtrlMemView.h
gui/Debugger/DebuggerLists.h
gui/Debugger/DisassemblyDialog.h
gui/Debugger/DebugEvents.h
gui/i18n.h

View File

@ -385,6 +385,10 @@ const std::vector<BreakPoint> CBreakPoints::GetBreakpoints()
return breakPoints_;
}
// including them earlier causes some ambiguities
#include "App.h"
#include "Debugger/DisassemblyDialog.h"
void CBreakPoints::Update(u32 addr)
{
bool resume = false;
@ -402,6 +406,5 @@ void CBreakPoints::Update(u32 addr)
if (resume)
r5900Debug.resumeCpu();
// Redraw in order to show the breakpoint.
// host->UpdateDisassembly();
wxGetApp().GetDisassemblyPtr()->update();
}

View File

@ -1059,3 +1059,11 @@ void CtrlDisassemblyView::editBreakpoint()
postEvent(debEVT_UPDATE,0);
}
}
void CtrlDisassemblyView::getOpcodeText(u32 address, char* dest)
{
DisassemblyLineInfo line;
address = manager.getStartAddress(address);
manager.getLine(address,displaySymbols,line);
sprintf(dest,"%s %s",line.name.c_str(),line.params.c_str());
}

View File

@ -22,6 +22,7 @@ public:
void scanFunctions();
void clearFunctions() { manager.clear(); };
void redraw();
void getOpcodeText(u32 address, char* dest);
u32 getInstructionSizeAt(u32 address)
{

View File

@ -0,0 +1,334 @@
#include "PrecompiledHeader.h"
#include "DebuggerLists.h"
#include "BreakpointWindow.h"
#include "DebugEvents.h"
void insertListViewColumns(wxListCtrl* list, GenericListViewColumn* columns, int count)
{
int totalWidth = list->GetSize().x;
for (int i = 0; i < count; i++)
{
wxListItem column;
column.SetText(columns[i].name);
column.SetWidth(totalWidth * columns[i].size);
list->InsertColumn(i,column);
}
}
void resizeListViewColumns(wxListCtrl* list, GenericListViewColumn* columns, int count, int totalWidth)
{
for (int i = 0; i < count; i++)
{
list->SetColumnWidth(i,totalWidth*columns[i].size);
}
}
//
// BreakpointList
//
BEGIN_EVENT_TABLE(BreakpointList, wxWindow)
EVT_SIZE(BreakpointList::sizeEvent)
EVT_KEY_DOWN(BreakpointList::keydownEvent)
END_EVENT_TABLE()
enum { BPL_TYPE, BPL_OFFSET, BPL_SIZELABEL, BPL_OPCODE, BPL_CONDITION, BPL_HITS, BPL_ENABLED, BPL_COLUMNCOUNT };
GenericListViewColumn breakpointColumns[BPL_COLUMNCOUNT] = {
{ L"Type", 0.12f },
{ L"Offset", 0.12f },
{ L"Size/Label", 0.18f },
{ L"Opcode", 0.28f },
{ L"Condition", 0.17f },
{ L"Hits", 0.05f },
{ L"Enabled", 0.08f }
};
BreakpointList::BreakpointList(wxWindow* parent, DebugInterface* _cpu, CtrlDisassemblyView* _disassembly)
: wxListView(parent,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxLC_VIRTUAL|wxLC_REPORT|wxLC_SINGLE_SEL), cpu(_cpu), disasm(_disassembly)
{
insertListViewColumns(this,breakpointColumns,BPL_COLUMNCOUNT);
}
void BreakpointList::sizeEvent(wxSizeEvent& evt)
{
resizeListViewColumns(this,breakpointColumns,BPL_COLUMNCOUNT,evt.GetSize().x);
}
void BreakpointList::update()
{
int newRows = getTotalBreakpointCount();
SetItemCount(newRows);
Refresh();
}
int BreakpointList::getTotalBreakpointCount()
{
int count = (int)CBreakPoints::GetMemChecks().size();
for (size_t i = 0; i < CBreakPoints::GetBreakpoints().size(); i++)
{
if (!displayedBreakPoints_[i].temporary) count++;
}
return count;
}
wxString BreakpointList::OnGetItemText(long item, long col) const
{
wchar_t dest[256];
bool isMemory;
int index = getBreakpointIndex(item,isMemory);
if (index == -1) return L"Invalid";
switch (col)
{
case BPL_TYPE:
{
if (isMemory) {
switch ((int)displayedMemChecks_[index].cond) {
case MEMCHECK_READ:
wcscpy(dest,L"Read");
break;
case MEMCHECK_WRITE:
wcscpy(dest,L"Write");
break;
case MEMCHECK_READWRITE:
wcscpy(dest,L"Read/Write");
break;
case MEMCHECK_WRITE | MEMCHECK_WRITE_ONCHANGE:
wcscpy(dest,L"Write Change");
break;
case MEMCHECK_READWRITE | MEMCHECK_WRITE_ONCHANGE:
wcscpy(dest,L"Read/Write Change");
break;
}
} else {
wcscpy(dest,L"Execute");
}
}
break;
case BPL_OFFSET:
{
if (isMemory) {
swprintf(dest,256,L"0x%08X",displayedMemChecks_[index].start);
} else {
swprintf(dest,256,L"0x%08X",displayedBreakPoints_[index].addr);
}
}
break;
case BPL_SIZELABEL:
{
if (isMemory) {
auto mc = displayedMemChecks_[index];
if (mc.end == 0)
swprintf(dest,256,L"0x%08X",1);
else
swprintf(dest,256,L"0x%08X",mc.end-mc.start);
} else {
const std::string sym = symbolMap.GetLabelString(displayedBreakPoints_[index].addr);
if (!sym.empty())
{
swprintf(dest,256,L"%S",sym.c_str());
} else {
wcscpy(dest,L"-");
}
}
}
break;
case BPL_OPCODE:
{
if (isMemory) {
wcscpy(dest,L"-");
} else {
char temp[256];
disasm->getOpcodeText(displayedBreakPoints_[index].addr, temp);
swprintf(dest,256,L"%S",temp);
}
}
break;
case BPL_CONDITION:
{
if (isMemory || displayedBreakPoints_[index].hasCond == false) {
wcscpy(dest,L"-");
} else {
swprintf(dest,256,L"%S",displayedBreakPoints_[index].cond.expressionString);
}
}
break;
case BPL_HITS:
{
if (isMemory) {
swprintf(dest,256,L"%d",displayedMemChecks_[index].numHits);
} else {
swprintf(dest,256,L"-");
}
}
break;
case BPL_ENABLED:
{
if (isMemory) {
swprintf(dest,256,L"%S",displayedMemChecks_[index].cond & MEMCHECK_BREAK ? "true" : "false");
} else {
swprintf(dest,256,L"%S",displayedBreakPoints_[index].enabled ? "true" : "false");
}
}
break;
default:
return L"Invalid";
}
return dest;
}
void BreakpointList::keydownEvent(wxKeyEvent& evt)
{
int sel = GetFirstSelected();
switch (evt.GetKeyCode())
{
case WXK_DELETE:
if (sel+1 == GetItemCount())
Select(sel-1);
removeBreakpoint(sel);
break;
case WXK_UP:
if (sel > 0)
Select(sel-1);
break;
case WXK_DOWN:
if (sel+1 < GetItemCount())
Select(sel+1);
break;
case WXK_RETURN:
editBreakpoint(sel);
break;
case WXK_SPACE:
toggleEnabled(sel);
break;
}
}
int BreakpointList::getBreakpointIndex(int itemIndex, bool& isMemory) const
{
// memory breakpoints first
if (itemIndex < (int)displayedMemChecks_.size())
{
isMemory = true;
return itemIndex;
}
itemIndex -= (int)displayedMemChecks_.size();
size_t i = 0;
while (i < displayedBreakPoints_.size())
{
if (displayedBreakPoints_[i].temporary)
{
i++;
continue;
}
// the index is 0 when there are no more breakpoints to skip
if (itemIndex == 0)
{
isMemory = false;
return (int)i;
}
i++;
itemIndex--;
}
return -1;
}
void BreakpointList::reloadBreakpoints()
{
// Update the items we're displaying from the debugger.
displayedBreakPoints_ = CBreakPoints::GetBreakpoints();
displayedMemChecks_= CBreakPoints::GetMemChecks();
update();
}
void BreakpointList::editBreakpoint(int itemIndex)
{
bool isMemory;
int index = getBreakpointIndex(itemIndex, isMemory);
if (index == -1) return;
BreakpointWindow win(this,cpu);
if (isMemory)
{
auto mem = displayedMemChecks_[index];
win.loadFromMemcheck(mem);
if (win.ShowModal() == wxID_OK)
{
CBreakPoints::RemoveMemCheck(mem.start,mem.end);
win.addBreakpoint();
}
} else {
auto bp = displayedBreakPoints_[index];
win.loadFromBreakpoint(bp);
if (win.ShowModal() == wxID_OK)
{
CBreakPoints::RemoveBreakPoint(bp.addr);
win.addBreakpoint();
}
}
}
void BreakpointList::toggleEnabled(int itemIndex)
{
bool isMemory;
int index = getBreakpointIndex(itemIndex, isMemory);
if (index == -1) return;
if (isMemory) {
MemCheck mcPrev = displayedMemChecks_[index];
CBreakPoints::ChangeMemCheck(mcPrev.start, mcPrev.end, mcPrev.cond, MemCheckResult(mcPrev.result ^ MEMCHECK_BREAK));
} else {
BreakPoint bpPrev = displayedBreakPoints_[index];
CBreakPoints::ChangeBreakPoint(bpPrev.addr, !bpPrev.enabled);
}
}
void BreakpointList::gotoBreakpointAddress(int itemIndex)
{
bool isMemory;
int index = getBreakpointIndex(itemIndex,isMemory);
if (index == -1) return;
if (isMemory)
{
u32 address = displayedMemChecks_[index].start;
postEvent(debEVT_GOTOINMEMORYVIEW,address);
} else {
u32 address = displayedBreakPoints_[index].addr;
postEvent(debEVT_GOTOINDISASM,address);
}
}
void BreakpointList::removeBreakpoint(int itemIndex)
{
bool isMemory;
int index = getBreakpointIndex(itemIndex,isMemory);
if (index == -1) return;
if (isMemory)
{
auto mc = displayedMemChecks_[index];
CBreakPoints::RemoveMemCheck(mc.start, mc.end);
} else {
u32 address = displayedBreakPoints_[index].addr;
CBreakPoints::RemoveBreakPoint(address);
}
}
void BreakpointList::postEvent(wxEventType type, int value)
{
wxCommandEvent event( type, GetId() );
event.SetEventObject(this);
event.SetInt(value);
wxPostEvent(this,event);
}

View File

@ -0,0 +1,39 @@
#pragma once
#include <wx/listctrl.h>
#include "DebugTools/DebugInterface.h"
#include "DebugTools/Breakpoints.h"
#include "CtrlDisassemblyView.h"
struct GenericListViewColumn
{
wchar_t *name;
float size;
int flags;
};
class BreakpointList: public wxListView
{
public:
BreakpointList(wxWindow* parent, DebugInterface* _cpu, CtrlDisassemblyView* _disassembly);
void reloadBreakpoints();
void update();
DECLARE_EVENT_TABLE()
protected:
wxString OnGetItemText(long item, long col) const;
void sizeEvent(wxSizeEvent& evt);
void keydownEvent(wxKeyEvent& evt);
private:
int getBreakpointIndex(int itemIndex, bool& isMemory) const;
int getTotalBreakpointCount();
void editBreakpoint(int itemIndex);
void toggleEnabled(int itemIndex);
void gotoBreakpointAddress(int itemIndex);
void removeBreakpoint(int itemIndex);
void postEvent(wxEventType type, int value);
std::vector<BreakPoint> displayedBreakPoints_;
std::vector<MemCheck> displayedMemChecks_;
DebugInterface* cpu;
CtrlDisassemblyView* disasm;
};

View File

@ -74,11 +74,22 @@ CpuTabPage::CpuTabPage(wxWindow* parent, DebugInterface* _cpu)
// create bottom section
bottomTabs->AddPage(memory,L"Memory");
breakpointList = new BreakpointList(bottomTabs,cpu,disassembly);
bottomTabs->AddPage(breakpointList,L"Breakpoints");
mainSizer->Add(bottomTabs,1,wxEXPAND);
mainSizer->Layout();
}
void CpuTabPage::update()
{
breakpointList->reloadBreakpoints();
Refresh();
}
DisassemblyDialog::DisassemblyDialog(wxWindow* parent):
wxFrame( parent, wxID_ANY, L"Debugger", wxDefaultPosition,wxDefaultSize,wxRESIZE_BORDER|wxCLOSE_BOX|wxCAPTION|wxSYSTEM_MENU ),
currentCpu(NULL)
@ -203,7 +214,7 @@ void DisassemblyDialog::onPageChanging(wxCommandEvent& evt)
if (currentCpu != NULL)
{
currentCpu->getDisassembly()->SetFocus();
currentCpu->Refresh();
currentCpu->update();
}
}
@ -365,7 +376,7 @@ void DisassemblyDialog::update()
{
stepOverButton->Enable(true);
breakpointButton->Enable(true);
currentCpu->Refresh();
currentCpu->update();
} else {
stepOverButton->Enable(false);
breakpointButton->Enable(false);

View File

@ -7,6 +7,7 @@
#include "CtrlRegisterList.h"
#include "CtrlMemView.h"
#include "DebugEvents.h"
#include "DebuggerLists.h"
class DebuggerHelpDialog: public wxDialog
{
@ -23,12 +24,14 @@ public:
CtrlRegisterList* getRegisterList() { return registerList; };
CtrlMemView* getMemoryView() { return memory; };
wxNotebook* getBottomTabs() { return bottomTabs; };
void update();
private:
DebugInterface* cpu;
CtrlDisassemblyView* disassembly;
CtrlRegisterList* registerList;
CtrlMemView* memory;
wxNotebook* bottomTabs;
BreakpointList* breakpointList;
};
class DisassemblyDialog : public wxFrame

View File

@ -178,6 +178,8 @@
<Outputs Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">%(RootDir)%(Directory)\%(Filename).h</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RootDir)%(Directory)\%(Filename).h</Outputs>
</CustomBuild>
<None Include="..\..\gui\Debugger\DebuggerLists.cpp" />
<None Include="..\..\gui\Debugger\DebuggerLists.h" />
<None Include="..\..\Utilities\folderdesc.txt" />
<None Include="..\..\Docs\License.txt" />
<None Include="..\..\x86\aVUzerorec.S" />

View File

@ -207,6 +207,12 @@
<None Include="..\..\gui\Dialogs\BaseConfigurationDialog.inl">
<Filter>AppHost\Dialogs</Filter>
</None>
<None Include="..\..\gui\Debugger\DebuggerLists.cpp">
<Filter>AppHost\Debugger</Filter>
</None>
<None Include="..\..\gui\Debugger\DebuggerLists.h">
<Filter>AppHost\Debugger</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\Patch.cpp">

View File

@ -424,6 +424,7 @@
<ClCompile Include="..\..\gui\Debugger\CtrlMemView.cpp" />
<ClCompile Include="..\..\gui\Debugger\CtrlRegisterList.cpp" />
<ClCompile Include="..\..\gui\Debugger\DebugEvents.cpp" />
<ClCompile Include="..\..\gui\Debugger\DebuggerLists.cpp" />
<ClCompile Include="..\..\gui\Debugger\DisassemblyDialog.cpp" />
<ClCompile Include="..\..\gui\Dialogs\GameDatabaseDialog.cpp" />
<ClCompile Include="..\..\gui\Dialogs\McdConfigDialog.cpp" />
@ -708,6 +709,7 @@
<ClInclude Include="..\..\gui\Debugger\CtrlMemView.h" />
<ClInclude Include="..\..\gui\Debugger\CtrlRegisterList.h" />
<ClInclude Include="..\..\gui\Debugger\DebugEvents.h" />
<ClInclude Include="..\..\gui\Debugger\DebuggerLists.h" />
<ClInclude Include="..\..\gui\Debugger\DisassemblyDialog.h" />
<ClInclude Include="..\..\gui\Panels\MemoryCardPanels.h" />
<ClInclude Include="..\..\IPU\IPUdma.h" />

View File

@ -844,13 +844,15 @@
<ClCompile Include="..\..\DebugTools\SymbolMap.cpp">
<Filter>System\Ps2\Debug</Filter>
</ClCompile>
<ClCompile Include="..\..\gui\Debugger\DebuggerLists.cpp">
<Filter>AppHost\Debugger</Filter>
</ClCompile>
<ClCompile Include="..\..\sif2.cpp">
<Filter>System\Ps2\EmotionEngine\DMAC\Sif</Filter>
</ClCompile>
<ClCompile Include="..\..\Gte.cpp">
<Filter>System\Ps2\Iop\PS1 Components</Filter>
</ClCompile>
</ItemGroup>
</ClCompile> </ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\Patch.h">
<Filter>Misc</Filter>
@ -1255,10 +1257,12 @@
<ClInclude Include="..\..\DebugTools\SymbolMap.h">
<Filter>System\Ps2\Debug</Filter>
</ClInclude>
<ClInclude Include="..\..\gui\Debugger\DebuggerLists.h">
<Filter>AppHost\Debugger</Filter>
</ClInclude>
<ClInclude Include="..\..\Gte.h">
<Filter>System\Ps2\Iop\PS1 Components</Filter>
</ClInclude>
</ItemGroup>
</ClInclude> </ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\..\3rdparty\wxWidgets\include\wx\msw\wx.rc">
<Filter>AppHost\Resources</Filter>

View File

@ -424,6 +424,7 @@
<ClCompile Include="..\..\gui\Debugger\CtrlMemView.cpp" />
<ClCompile Include="..\..\gui\Debugger\CtrlRegisterList.cpp" />
<ClCompile Include="..\..\gui\Debugger\DebugEvents.cpp" />
<ClCompile Include="..\..\gui\Debugger\DebuggerLists.cpp" />
<ClCompile Include="..\..\gui\Debugger\DisassemblyDialog.cpp" />
<ClCompile Include="..\..\gui\Dialogs\GameDatabaseDialog.cpp" />
<ClCompile Include="..\..\gui\Dialogs\McdConfigDialog.cpp" />
@ -708,6 +709,7 @@
<ClInclude Include="..\..\gui\Debugger\CtrlMemView.h" />
<ClInclude Include="..\..\gui\Debugger\CtrlRegisterList.h" />
<ClInclude Include="..\..\gui\Debugger\DebugEvents.h" />
<ClInclude Include="..\..\gui\Debugger\DebuggerLists.h" />
<ClInclude Include="..\..\gui\Debugger\DisassemblyDialog.h" />
<ClInclude Include="..\..\gui\Panels\MemoryCardPanels.h" />
<ClInclude Include="..\..\IPU\IPUdma.h" />

View File

@ -850,7 +850,9 @@
<ClCompile Include="..\..\Gte.cpp">
<Filter>System\Ps2\Iop\PS1 Components</Filter>
</ClCompile>
</ItemGroup>
<ClCompile Include="..\..\gui\Debugger\DebuggerLists.cpp">
<Filter>AppHost\Debugger</Filter>
</ClCompile> </ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\Patch.h">
<Filter>Misc</Filter>
@ -1258,7 +1260,9 @@
<ClInclude Include="..\..\Gte.h">
<Filter>System\Ps2\Iop\PS1 Components</Filter>
</ClInclude>
</ItemGroup>
<ClInclude Include="..\..\gui\Debugger\DebuggerLists.h">
<Filter>AppHost\Debugger</Filter>
</ClInclude> </ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\..\3rdparty\wxWidgets\include\wx\msw\wx.rc">
<Filter>AppHost\Resources</Filter>