Merge pull request #13712 from SuperSamus/cheat-search-improvements

CheatSearchWidget: New feature, writing a value to all selected addresses
This commit is contained in:
JMC47
2025-10-09 13:58:00 -04:00
committed by GitHub
35 changed files with 552 additions and 782 deletions
+42 -7
View File
@@ -14,6 +14,7 @@
#include <QComboBox>
#include <QCursor>
#include <QHBoxLayout>
#include <QInputDialog>
#include <QLabel>
#include <QLineEdit>
#include <QMenu>
@@ -491,18 +492,24 @@ void CheatSearchWidget::OnAddressTableContextMenu()
if (m_address_table->selectedItems().isEmpty())
return;
auto* item = m_address_table->selectedItems()[0];
const u32 address = item->data(ADDRESS_TABLE_ADDRESS_ROLE).toUInt();
QMenu* menu = new QMenu(this);
menu->setAttribute(Qt::WA_DeleteOnClose, true);
menu->addAction(tr("Show in memory"), [this, address] { emit ShowMemory(address); });
menu->addAction(tr("Add to watch"), this, [this, address] {
const QString name = QStringLiteral("mem_%1").arg(address, 8, 16, QLatin1Char('0'));
emit RequestWatch(name, address);
menu->addAction(tr("Show in memory"), this, [this] {
auto* item = m_address_table->selectedItems()[0];
const u32 address = item->data(ADDRESS_TABLE_ADDRESS_ROLE).toUInt();
emit ShowMemory(address);
});
menu->addAction(tr("Add to watch"), this, [this] {
for (auto* const item : m_address_table->selectedItems())
{
const u32 address = item->data(ADDRESS_TABLE_ADDRESS_ROLE).toUInt();
const QString name = QStringLiteral("mem_%1").arg(address, 8, 16, QLatin1Char('0'));
emit RequestWatch(name, address);
}
});
menu->addAction(tr("Generate Action Replay Code(s)"), this, &CheatSearchWidget::GenerateARCodes);
menu->addAction(tr("Write value"), this, &CheatSearchWidget::WriteValue);
menu->exec(QCursor::pos());
}
@@ -586,6 +593,34 @@ void CheatSearchWidget::GenerateARCodes()
}
}
void CheatSearchWidget::WriteValue()
{
if (m_address_table->selectedItems().isEmpty())
return;
bool ok{};
QString text = QInputDialog::getText(this, tr("Write value"), tr("Value:"), QLineEdit::Normal,
QString{}, &ok);
if (!ok || !m_last_value_session->SetValueFromString(text.toStdString(),
m_parse_values_as_hex_checkbox->isChecked()))
{
m_info_label_1->setText(tr("Invalid value."));
return;
}
auto items = m_address_table->selectedItems();
std::vector<u32> addresses(items.size());
std::transform(items.begin(), items.end(), addresses.begin(), [](QTableWidgetItem* item) {
return item->data(ADDRESS_TABLE_ADDRESS_ROLE).toUInt();
});
Core::CPUThreadGuard guard{m_system};
if (!m_last_value_session->WriteValue(guard, std::span<u32>(addresses)))
{
m_info_label_1->setText(tr("There was an error writing (some) values."));
}
}
size_t CheatSearchWidget::GetTableRowCount() const
{
return std::min(TABLE_MAX_ROWS, m_last_value_session->GetResultCount());
@@ -71,6 +71,7 @@ private:
UpdateSource source);
void RecreateGUITable();
void GenerateARCodes();
void WriteValue();
int GetVisibleRowsBeginIndex() const;
int GetVisibleRowsEndIndex() const;
size_t GetTableRowCount() const;
@@ -277,7 +277,7 @@ void ThreadWidget::Update()
};
const auto format_hex_from = [&format_hex](const Core::CPUThreadGuard& guard, u32 addr) {
addr =
PowerPC::MMU::HostIsRAMAddress(guard, addr) ? PowerPC::MMU::HostRead_U32(guard, addr) : 0;
PowerPC::MMU::HostIsRAMAddress(guard, addr) ? PowerPC::MMU::HostRead<u32>(guard, addr) : 0;
return format_hex(addr);
};
const auto get_state = [](u16 thread_state) {
@@ -463,7 +463,7 @@ void ThreadWidget::UpdateThreadCallstack(const Core::CPUThreadGuard& guard,
m_callstack_table->setItem(i, 0, new QTableWidgetItem(format_hex(sp)));
if (PowerPC::MMU::HostIsRAMAddress(guard, sp + 4))
{
const u32 lr_save = PowerPC::MMU::HostRead_U32(guard, sp + 4);
const u32 lr_save = PowerPC::MMU::HostRead<u32>(guard, sp + 4);
m_callstack_table->setItem(i, 2, new QTableWidgetItem(format_hex(lr_save)));
m_callstack_table->setItem(
i, 3,
@@ -474,7 +474,7 @@ void ThreadWidget::UpdateThreadCallstack(const Core::CPUThreadGuard& guard,
{
m_callstack_table->setItem(i, 2, new QTableWidgetItem(QStringLiteral("--------")));
}
sp = PowerPC::MMU::HostRead_U32(guard, sp);
sp = PowerPC::MMU::HostRead<u32>(guard, sp);
m_callstack_table->setItem(i, 1, new QTableWidgetItem(format_hex(sp)));
}
}
@@ -203,12 +203,12 @@ void WatchWidget::Update()
{
if (PowerPC::MMU::HostIsRAMAddress(guard, entry.address))
{
hex->setText(QStringLiteral("%1").arg(PowerPC::MMU::HostRead_U32(guard, entry.address), 8,
hex->setText(QStringLiteral("%1").arg(PowerPC::MMU::HostRead<u32>(guard, entry.address), 8,
16, QLatin1Char('0')));
decimal->setText(QString::number(PowerPC::MMU::HostRead_U32(guard, entry.address)));
decimal->setText(QString::number(PowerPC::MMU::HostRead<u32>(guard, entry.address)));
string->setText(
QString::fromStdString(PowerPC::MMU::HostGetString(guard, entry.address, 32)));
floatValue->setText(QString::number(PowerPC::MMU::HostRead_F32(guard, entry.address)));
floatValue->setText(QString::number(PowerPC::MMU::HostRead<float>(guard, entry.address)));
lockValue->setCheckState(entry.locked ? Qt::Checked : Qt::Unchecked);
}
}
@@ -425,7 +425,7 @@ void WatchWidget::OnItemChanged(QTableWidgetItem* item)
}
else
{
PowerPC::MMU::HostWrite_U32(guard, value, debug_interface.GetWatch(row).address);
PowerPC::MMU::HostWrite<u32>(guard, value, debug_interface.GetWatch(row).address);
}
}
else
+2 -2
View File
@@ -1644,7 +1644,7 @@ RSOVector MenuBar::DetectRSOModules(ParallelProgressDialog& progress)
for (; len < MODULE_NAME_MAX_LENGTH; ++len)
{
const auto res = PowerPC::MMU::HostRead_U8(guard, *found_addr - (len + 1));
const auto res = PowerPC::MMU::HostRead<u8>(guard, *found_addr - (len + 1));
if (!std::isprint(res))
{
break;
@@ -1988,7 +1988,7 @@ void MenuBar::SearchInstruction()
for (u32 addr = Memory::MEM1_BASE_ADDR; addr < Memory::MEM1_BASE_ADDR + memory.GetRamSizeReal();
addr += 4)
{
if (op_std == PPCTables::GetInstructionName(PowerPC::MMU::HostRead_U32(guard, addr), addr))
if (op_std == PPCTables::GetInstructionName(PowerPC::MMU::HostRead<u32>(guard, addr), addr))
{
NOTICE_LOG_FMT(POWERPC, "Found {} at {:08x}", op_std, addr);
found = true;