diff --git a/pcsx2-qt/Debugger/Breakpoints/BreakpointDialog.cpp b/pcsx2-qt/Debugger/Breakpoints/BreakpointDialog.cpp
index 5cee329a2d..194197e00e 100644
--- a/pcsx2-qt/Debugger/Breakpoints/BreakpointDialog.cpp
+++ b/pcsx2-qt/Debugger/Breakpoints/BreakpointDialog.cpp
@@ -42,6 +42,7 @@ BreakpointDialog::BreakpointDialog(QWidget* parent, DebugInterface* cpu, Breakpo
m_ui.rdoExecute->setChecked(true);
m_ui.chkEnable->setChecked(bp->enabled);
m_ui.txtAddress->setText(QtUtils::FilledQStringFromValue(bp->addr, 16));
+ m_ui.txtDescription->setText(QString::fromStdString(bp->description));
if (bp->hasCond)
m_ui.txtCondition->setText(QString::fromStdString(bp->cond.expressionString));
@@ -53,6 +54,8 @@ BreakpointDialog::BreakpointDialog(QWidget* parent, DebugInterface* cpu, Breakpo
m_ui.txtAddress->setText(QtUtils::FilledQStringFromValue(mc->start, 16));
m_ui.txtSize->setText(QtUtils::FilledQStringFromValue(mc->end - mc->start, 16));
+ m_ui.txtDescription->setText(QString::fromStdString(mc->description));
+
m_ui.chkRead->setChecked(mc->memCond & MEMCHECK_READ);
m_ui.chkWrite->setChecked(mc->memCond & MEMCHECK_WRITE);
m_ui.chkChange->setChecked(mc->memCond & MEMCHECK_WRITE_ONCHANGE);
@@ -102,6 +105,7 @@ void BreakpointDialog::accept()
}
bp->addr = address;
+ bp->description = m_ui.txtDescription->text().toStdString();
bp->enabled = m_ui.chkEnable->isChecked();
@@ -138,6 +142,7 @@ void BreakpointDialog::accept()
mc->start = startAddress;
mc->end = startAddress + size;
+ mc->description = m_ui.txtDescription->text().toStdString();
if (!m_ui.txtCondition->text().isEmpty())
{
diff --git a/pcsx2-qt/Debugger/Breakpoints/BreakpointDialog.ui b/pcsx2-qt/Debugger/Breakpoints/BreakpointDialog.ui
index a15212baf0..ec751dd211 100644
--- a/pcsx2-qt/Debugger/Breakpoints/BreakpointDialog.ui
+++ b/pcsx2-qt/Debugger/Breakpoints/BreakpointDialog.ui
@@ -10,7 +10,7 @@
0
0
375
- 250
+ 300
@@ -22,19 +22,19 @@
375
- 250
+ 300
375
- 250
+ 300
375
- 250
+ 300
@@ -44,7 +44,7 @@
20
- 210
+ 260
341
32
@@ -102,14 +102,17 @@
110
10
- 251
- 41
+ 250
+ 79
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
-
@@ -139,6 +142,29 @@
+ -
+
+
+ Description
+
+
+
+ -
+
+
+
+ 0
+ 19
+
+
+
+
+ 16777215
+ 19
+
+
+
+
@@ -148,7 +174,7 @@
110
- 50
+ 100
251
91
@@ -224,13 +250,13 @@
110
- 140
+ 190
251
61
-
+
-
diff --git a/pcsx2-qt/Debugger/Breakpoints/BreakpointModel.cpp b/pcsx2-qt/Debugger/Breakpoints/BreakpointModel.cpp
index 7f8deb09cf..80ac55d7b4 100644
--- a/pcsx2-qt/Debugger/Breakpoints/BreakpointModel.cpp
+++ b/pcsx2-qt/Debugger/Breakpoints/BreakpointModel.cpp
@@ -72,11 +72,13 @@ QVariant BreakpointModel::data(const QModelIndex& index, int role) const
switch (index.column())
{
case BreakpointColumns::ENABLED:
- return "";
+ return (bp->enabled) ? tr("Enabled") : tr("Disabled");
case BreakpointColumns::TYPE:
return tr("Execute");
case BreakpointColumns::OFFSET:
return QtUtils::FilledQStringFromValue(bp->addr, 16);
+ case BreakpointColumns::DESCRIPTION:
+ return QString::fromStdString(bp->description);
case BreakpointColumns::SIZE_LABEL:
return QString::fromStdString(m_cpu.GetSymbolGuardian().FunctionStartingAtAddress(bp->addr).name);
case BreakpointColumns::OPCODE:
@@ -105,6 +107,8 @@ QVariant BreakpointModel::data(const QModelIndex& index, int role) const
}
case BreakpointColumns::OFFSET:
return QtUtils::FilledQStringFromValue(mc->start, 16);
+ case BreakpointColumns::DESCRIPTION:
+ return QString::fromStdString(mc->description);
case BreakpointColumns::SIZE_LABEL:
return QString::number(mc->end - mc->start, 16);
case BreakpointColumns::OPCODE:
@@ -116,6 +120,29 @@ QVariant BreakpointModel::data(const QModelIndex& index, int role) const
}
}
}
+ else if (role == Qt::EditRole)
+ {
+ if (const auto* bp = std::get_if(&bp_mc))
+ {
+ switch (index.column())
+ {
+ case BreakpointColumns::CONDITION:
+ return bp->hasCond ? QString::fromStdString(bp->cond.expressionString) : "";
+ case BreakpointColumns::DESCRIPTION:
+ return QString::fromStdString(bp->description);
+ }
+ }
+ else if (const auto* mc = std::get_if(&bp_mc))
+ {
+ switch (index.column())
+ {
+ case BreakpointColumns::CONDITION:
+ return mc->hasCond ? QString::fromStdString(mc->cond.expressionString) : "";
+ case BreakpointColumns::DESCRIPTION:
+ return QString::fromStdString(mc->description);
+ }
+ }
+ }
else if (role == BreakpointModel::DataRole)
{
if (const auto* bp = std::get_if(&bp_mc))
@@ -128,6 +155,8 @@ QVariant BreakpointModel::data(const QModelIndex& index, int role) const
return MEMCHECK_INVALID;
case BreakpointColumns::OFFSET:
return bp->addr;
+ case BreakpointColumns::DESCRIPTION:
+ return QString::fromStdString(bp->description);
case BreakpointColumns::SIZE_LABEL:
return QString::fromStdString(m_cpu.GetSymbolGuardian().FunctionStartingAtAddress(bp->addr).name);
case BreakpointColumns::OPCODE:
@@ -149,6 +178,8 @@ QVariant BreakpointModel::data(const QModelIndex& index, int role) const
return mc->memCond;
case BreakpointColumns::OFFSET:
return mc->start;
+ case BreakpointColumns::DESCRIPTION:
+ return QString::fromStdString(mc->description);
case BreakpointColumns::SIZE_LABEL:
return mc->end - mc->start;
case BreakpointColumns::OPCODE:
@@ -172,6 +203,8 @@ QVariant BreakpointModel::data(const QModelIndex& index, int role) const
return MEMCHECK_INVALID;
case BreakpointColumns::OFFSET:
return QtUtils::FilledQStringFromValue(bp->addr, 16);
+ case BreakpointColumns::DESCRIPTION:
+ return QString::fromStdString(bp->description);
case BreakpointColumns::SIZE_LABEL:
return QString::fromStdString(m_cpu.GetSymbolGuardian().FunctionStartingAtAddress(bp->addr).name);
case BreakpointColumns::OPCODE:
@@ -191,6 +224,8 @@ QVariant BreakpointModel::data(const QModelIndex& index, int role) const
return mc->memCond;
case BreakpointColumns::OFFSET:
return QtUtils::FilledQStringFromValue(mc->start, 16);
+ case BreakpointColumns::DESCRIPTION:
+ return QString::fromStdString(mc->description);
case BreakpointColumns::SIZE_LABEL:
return mc->end - mc->start;
case BreakpointColumns::OPCODE:
@@ -233,6 +268,8 @@ QVariant BreakpointModel::headerData(int section, Qt::Orientation orientation, i
case BreakpointColumns::OFFSET:
//: Warning: limited space available. Abbreviate if needed.
return tr("OFFSET");
+ case BreakpointColumns::DESCRIPTION:
+ return "DESCRIPTION";
case BreakpointColumns::SIZE_LABEL:
//: Warning: limited space available. Abbreviate if needed.
return tr("SIZE / LABEL");
@@ -260,6 +297,8 @@ QVariant BreakpointModel::headerData(int section, Qt::Orientation orientation, i
return "TYPE";
case BreakpointColumns::OFFSET:
return "OFFSET";
+ case BreakpointColumns::DESCRIPTION:
+ return "DESCRIPTION";
case BreakpointColumns::SIZE_LABEL:
return "SIZE / LABEL";
case BreakpointColumns::OPCODE:
@@ -282,6 +321,7 @@ Qt::ItemFlags BreakpointModel::flags(const QModelIndex& index) const
switch (index.column())
{
case BreakpointColumns::CONDITION:
+ case BreakpointColumns::DESCRIPTION:
return Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable | Qt::ItemFlag::ItemIsEditable;
case BreakpointColumns::TYPE:
case BreakpointColumns::OPCODE:
@@ -395,6 +435,27 @@ bool BreakpointModel::setData(const QModelIndex& index, const QVariant& value, i
emit dataChanged(index, index);
return true;
}
+ else if (role == Qt::EditRole && index.column() == BreakpointColumns::DESCRIPTION)
+ {
+ // Update BreakPoint description
+ if (auto* bp = std::get_if(&bp_mc))
+ {
+ const QString descValue = value.toString();
+ Host::RunOnCPUThread([cpu = m_cpu.getCpuType(), bp, descValue] {
+ CBreakPoints::ChangeBreakPointDescription(cpu, bp->addr, descValue.toStdString());
+ });
+ }
+ // Update MemCheck description
+ else if (auto* mc = std::get_if(&bp_mc))
+ {
+ const QString descValue = value.toString();
+ Host::RunOnCPUThread([cpu = m_cpu.getCpuType(), mc, descValue] {
+ CBreakPoints::ChangeMemCheckDescription(cpu, mc->start, mc->end, descValue.toStdString());
+ });
+ }
+ emit dataChanged(index, index);
+ return true;
+ }
return false;
}
@@ -451,7 +512,7 @@ bool BreakpointModel::insertBreakpointRows(int row, int count, std::vector(result);
+ // Description
+ if (!fields[BreakpointColumns::DESCRIPTION].isEmpty())
+ {
+ mc.description = fields[BreakpointColumns::DESCRIPTION].toStdString();
+ }
+
insertBreakpointRows(0, 1, {mc});
}
}
diff --git a/pcsx2-qt/Debugger/Breakpoints/BreakpointModel.h b/pcsx2-qt/Debugger/Breakpoints/BreakpointModel.h
index fd603bb858..161625eb6e 100644
--- a/pcsx2-qt/Debugger/Breakpoints/BreakpointModel.h
+++ b/pcsx2-qt/Debugger/Breakpoints/BreakpointModel.h
@@ -21,6 +21,7 @@ public:
ENABLED = 0,
TYPE,
OFFSET,
+ DESCRIPTION,
SIZE_LABEL,
OPCODE,
CONDITION,
@@ -38,6 +39,7 @@ public:
QHeaderView::ResizeMode::ResizeToContents,
QHeaderView::ResizeMode::ResizeToContents,
QHeaderView::ResizeMode::ResizeToContents,
+ QHeaderView::ResizeMode::ResizeToContents,
QHeaderView::ResizeMode::Stretch,
QHeaderView::ResizeMode::Stretch,
QHeaderView::ResizeMode::ResizeToContents,
diff --git a/pcsx2-qt/Debugger/Breakpoints/BreakpointView.cpp b/pcsx2-qt/Debugger/Breakpoints/BreakpointView.cpp
index 603f399d27..64eec9f8b5 100644
--- a/pcsx2-qt/Debugger/Breakpoints/BreakpointView.cpp
+++ b/pcsx2-qt/Debugger/Breakpoints/BreakpointView.cpp
@@ -21,11 +21,7 @@ BreakpointView::BreakpointView(const DebuggerViewParameters& parameters)
connect(m_ui.breakpointList, &QTableView::doubleClicked, this, &BreakpointView::onDoubleClicked);
m_ui.breakpointList->setModel(m_model);
- for (std::size_t i = 0; auto mode : BreakpointModel::HeaderResizeModes)
- {
- m_ui.breakpointList->horizontalHeader()->setSectionResizeMode(i, mode);
- i++;
- }
+ this->resizeColumns();
}
void BreakpointView::onDoubleClicked(const QModelIndex& index)
@@ -124,6 +120,7 @@ void BreakpointView::contextDelete()
void BreakpointView::contextNew()
{
BreakpointDialog* bpDialog = new BreakpointDialog(this, &cpu(), *m_model);
+ connect(bpDialog, &QDialog::accepted, this, &BreakpointView::resizeColumns);
bpDialog->setAttribute(Qt::WA_DeleteOnClose);
bpDialog->show();
}
@@ -140,6 +137,7 @@ void BreakpointView::contextEdit()
auto bpObject = m_model->at(selectedRow);
BreakpointDialog* bpDialog = new BreakpointDialog(this, &cpu(), *m_model, bpObject, selectedRow);
+ connect(bpDialog, &QDialog::accepted, this, &BreakpointView::resizeColumns);
bpDialog->setAttribute(Qt::WA_DeleteOnClose);
bpDialog->show();
}
@@ -172,3 +170,12 @@ void BreakpointView::saveBreakpointsToDebuggerSettings()
{
DebuggerSettingsManager::saveGameSettings(m_model);
}
+
+void BreakpointView::resizeColumns()
+{
+ for (std::size_t i = 0; auto mode : BreakpointModel::HeaderResizeModes)
+ {
+ m_ui.breakpointList->horizontalHeader()->setSectionResizeMode(i, mode);
+ i++;
+ }
+}
diff --git a/pcsx2-qt/Debugger/Breakpoints/BreakpointView.h b/pcsx2-qt/Debugger/Breakpoints/BreakpointView.h
index 333fd36315..52dd529f50 100644
--- a/pcsx2-qt/Debugger/Breakpoints/BreakpointView.h
+++ b/pcsx2-qt/Debugger/Breakpoints/BreakpointView.h
@@ -32,6 +32,8 @@ public:
void contextEdit();
void contextPasteCSV();
+ void resizeColumns();
+
void saveBreakpointsToDebuggerSettings();
private:
diff --git a/pcsx2-qt/Debugger/DebuggerSettingsManager.cpp b/pcsx2-qt/Debugger/DebuggerSettingsManager.cpp
index 81a23c8858..d83a73adca 100644
--- a/pcsx2-qt/Debugger/DebuggerSettingsManager.cpp
+++ b/pcsx2-qt/Debugger/DebuggerSettingsManager.cpp
@@ -12,7 +12,7 @@
#include "VMManager.h"
std::mutex DebuggerSettingsManager::writeLock;
-const QString DebuggerSettingsManager::settingsFileVersion = "0.00";
+const QString DebuggerSettingsManager::settingsFileVersion = "0.01";
QJsonObject DebuggerSettingsManager::loadGameSettingsJSON()
{
@@ -62,6 +62,17 @@ void DebuggerSettingsManager::loadGameSettings(BreakpointModel* bpModel)
return;
}
+ // Breakpoint descriptions were added at debugger settings file version 0.01. If loading
+ // saved breakpoints from a previous version (only 0.00 existed prior), the breakpoints will be
+ // missing a description. This code will add in an empty description so that the previous
+ // version, 0.00, is compatible with 0.01.
+ bool isMissingDescription = false;
+ const QJsonValue savedVersionValue = loadGameSettingsJSON().value("Version");
+ if (!savedVersionValue.isUndefined())
+ {
+ isMissingDescription = savedVersionValue.toString().toStdString() == "0.00";
+ }
+
const QJsonArray breakpointsArray = breakpointsValue.toArray();
for (u32 row = 0; row < breakpointsArray.size(); row++)
{
@@ -71,7 +82,13 @@ void DebuggerSettingsManager::loadGameSettings(BreakpointModel* bpModel)
Console.WriteLn("Debugger Settings Manager: Failed to load invalid Breakpoint object.");
continue;
}
- const QJsonObject rowObject = rowValue.toObject();
+ QJsonObject rowObject = rowValue.toObject();
+
+ // Add empty description for saved breakpoints from debugger settings versions prior to 0.01
+ if (isMissingDescription)
+ {
+ rowObject.insert(QString("DESCRIPTION"), QJsonValue(""));
+ }
QStringList fields;
u32 col = 0;
diff --git a/pcsx2/DebugTools/Breakpoints.cpp b/pcsx2/DebugTools/Breakpoints.cpp
index 8bc670e294..db1bbd3845 100644
--- a/pcsx2/DebugTools/Breakpoints.cpp
+++ b/pcsx2/DebugTools/Breakpoints.cpp
@@ -285,6 +285,16 @@ BreakPointCond* CBreakPoints::GetBreakPointCondition(BreakPointCpu cpu, u32 addr
return NULL;
}
+void CBreakPoints::ChangeBreakPointDescription(BreakPointCpu cpu, u32 addr, const std::string& description)
+{
+ const size_t bp = FindBreakpoint(cpu, addr, true, false);
+ if (bp != INVALID_BREAKPOINT)
+ {
+ breakPoints_[bp].description = description;
+ Update();
+ }
+}
+
void CBreakPoints::AddMemCheck(BreakPointCpu cpu, u32 start, u32 end, MemCheckCondition cond, MemCheckResult result)
{
// This will ruin any pending memchecks.
@@ -356,6 +366,16 @@ void CBreakPoints::ChangeMemCheckAddCond(BreakPointCpu cpu, u32 start, u32 end,
}
}
+void CBreakPoints::ChangeMemCheckDescription(BreakPointCpu cpu, u32 start, u32 end, const std::string& description)
+{
+ const size_t mc = FindMemCheck(cpu, start, end);
+ if (mc != INVALID_MEMCHECK)
+ {
+ memChecks_[mc].description = description;
+ Update(cpu);
+ }
+}
+
void CBreakPoints::ClearAllMemChecks()
{
// This will ruin any pending memchecks.
diff --git a/pcsx2/DebugTools/Breakpoints.h b/pcsx2/DebugTools/Breakpoints.h
index fd100b4cc7..61c532adb8 100644
--- a/pcsx2/DebugTools/Breakpoints.h
+++ b/pcsx2/DebugTools/Breakpoints.h
@@ -37,6 +37,8 @@ struct BreakPoint
BreakPointCond cond;
BreakPointCpu cpu;
+ std::string description;
+
bool operator==(const BreakPoint& other) const
{
return addr == other.addr;
@@ -78,6 +80,8 @@ struct MemCheck
MemCheckResult result;
BreakPointCpu cpu;
+ std::string description;
+
u32 numHits;
u32 lastPC;
@@ -119,12 +123,14 @@ public:
static void ChangeBreakPointAddCond(BreakPointCpu cpu, u32 addr, const BreakPointCond& cond);
static void ChangeBreakPointRemoveCond(BreakPointCpu cpu, u32 addr);
static BreakPointCond* GetBreakPointCondition(BreakPointCpu cpu, u32 addr);
+ static void ChangeBreakPointDescription(BreakPointCpu cpu, u32 addr, const std::string& description);
static void AddMemCheck(BreakPointCpu cpu, u32 start, u32 end, MemCheckCondition cond, MemCheckResult result);
static void RemoveMemCheck(BreakPointCpu cpu, u32 start, u32 end);
static void ChangeMemCheck(BreakPointCpu cpu, u32 start, u32 end, MemCheckCondition cond, MemCheckResult result);
static void ChangeMemCheckRemoveCond(BreakPointCpu cpu, u32 start, u32 end);
static void ChangeMemCheckAddCond(BreakPointCpu cpu, u32 start, u32 end, const BreakPointCond& cond);
+ static void ChangeMemCheckDescription(BreakPointCpu cpu, u32 start, u32 end, const std::string& description);
static void ClearAllMemChecks();
static void SetSkipFirst(BreakPointCpu cpu, u32 pc);