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..4860f4d9f6 100644
--- a/pcsx2-qt/Debugger/Breakpoints/BreakpointModel.cpp
+++ b/pcsx2-qt/Debugger/Breakpoints/BreakpointModel.cpp
@@ -77,6 +77,8 @@ QVariant BreakpointModel::data(const QModelIndex& index, int role) const
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:
@@ -393,6 +433,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;
}
@@ -548,6 +609,12 @@ void BreakpointModel::loadBreakpointFromFieldList(QStringList fields)
return;
}
+ // Description
+ if (!fields[BreakpointColumns::DESCRIPTION].isEmpty())
+ {
+ bp.description = fields[BreakpointColumns::DESCRIPTION].toStdString();
+ }
+
insertBreakpointRows(0, 1, {bp});
}
else
@@ -608,6 +675,12 @@ void BreakpointModel::loadBreakpointFromFieldList(QStringList fields)
}
mc.result = static_cast(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..ffded4e579 100644
--- a/pcsx2-qt/Debugger/Breakpoints/BreakpointView.cpp
+++ b/pcsx2-qt/Debugger/Breakpoints/BreakpointView.cpp
@@ -21,6 +21,11 @@ BreakpointView::BreakpointView(const DebuggerViewParameters& parameters)
connect(m_ui.breakpointList, &QTableView::doubleClicked, this, &BreakpointView::onDoubleClicked);
m_ui.breakpointList->setModel(m_model);
+ this->resizeColumns();
+}
+
+void BreakpointView::resizeColumns()
+{
for (std::size_t i = 0; auto mode : BreakpointModel::HeaderResizeModes)
{
m_ui.breakpointList->horizontalHeader()->setSectionResizeMode(i, mode);
@@ -124,6 +129,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 +146,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();
}
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..bec1acf0ee 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()
{
@@ -61,6 +61,18 @@ void DebuggerSettingsManager::loadGameSettings(BreakpointModel* bpModel)
Console.WriteLnFmt("Debugger Settings Manager: Failed to read Breakpoints array from settings file: '{}'", path);
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.
+ const QJsonValue savedVersionValue = loadGameSettingsJSON().value("Version");
+ const QString savedVersion = savedVersionValue.toString();
+ bool isMissingDescription = false;
+ if (!savedVersionValue.isUndefined())
+ {
+ isMissingDescription = savedVersion.toStdString() == "0.00";
+ }
const QJsonArray breakpointsArray = breakpointsValue.toArray();
for (u32 row = 0; row < breakpointsArray.size(); row++)
@@ -71,7 +83,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..da87b27d84 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, 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, 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..3d63f39fcc 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, 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, std::string description);
static void ClearAllMemChecks();
static void SetSkipFirst(BreakPointCpu cpu, u32 pc);