2018-02-16 06:53:52 -07:00
|
|
|
// Copyright 2018 Dolphin Emulator Project
|
2021-07-04 19:22:19 -06:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2018-02-16 06:53:52 -07:00
|
|
|
|
2018-07-06 16:40:15 -06:00
|
|
|
#include "DolphinQt/Config/NewPatchDialog.h"
|
2018-02-16 06:53:52 -07:00
|
|
|
|
Patches for Resident Evil 2/3 audio issues
These games are erroneously zeroing buffers before they can be fully copied to ARAM by DMA. The responsible memset() calls are followed by a call to DVDRead() which issues dcbi instructions that effectively cancel the memset() on real hardware. Because Dolphin lacks dcache emulation, the effects of the memset() calls are observed, which causes missing audio.
In a comment on the original bug, phire noted that the issue can be corrected by simply nop'ing out the offending memset() calls. Because the games dynamically load different .rel executables based on the character and/or language, the addresses of these calls can vary.
To deal generally with the problem of code being dynamically loaded to fixed, known addresses, the patch engine is extended to support conditional patches which require a match against a known value. This sort of thing is already achievable with Action Replay/Gecko codes, but their use depends on enabling cheats globally in Dolphin, which is not a prerequisite shared by patches.
Patches are included for every region, character, and language combination. They are enabled by default.
The end result is an approximation of the games' behavior on real hardware without the associated complexity of proper dcache emulation.
https://bugs.dolphin-emu.org/issues/9840
2020-12-29 15:24:46 -07:00
|
|
|
#include <QCheckBox>
|
2018-02-16 06:53:52 -07:00
|
|
|
#include <QDialogButtonBox>
|
|
|
|
#include <QGridLayout>
|
|
|
|
#include <QGroupBox>
|
|
|
|
#include <QLabel>
|
|
|
|
#include <QLineEdit>
|
|
|
|
#include <QPushButton>
|
|
|
|
#include <QRadioButton>
|
|
|
|
#include <QScrollArea>
|
|
|
|
#include <QVBoxLayout>
|
|
|
|
|
2018-05-13 13:34:38 -06:00
|
|
|
#include "Core/PatchEngine.h"
|
2019-03-04 12:49:00 -07:00
|
|
|
#include "DolphinQt/QtUtils/ModalMessageBox.h"
|
2018-05-13 13:34:38 -06:00
|
|
|
|
2020-12-29 15:28:27 -07:00
|
|
|
struct NewPatchEntry
|
|
|
|
{
|
|
|
|
NewPatchEntry() = default;
|
|
|
|
|
|
|
|
// These entries share the lifetime of their associated text widgets, and because they are
|
|
|
|
// captured by pointer by various edit handlers, they should not copied or moved.
|
|
|
|
NewPatchEntry(const NewPatchEntry&) = delete;
|
|
|
|
NewPatchEntry& operator=(const NewPatchEntry&) = delete;
|
|
|
|
NewPatchEntry(NewPatchEntry&&) = delete;
|
|
|
|
NewPatchEntry& operator=(NewPatchEntry&&) = delete;
|
|
|
|
|
|
|
|
QLineEdit* address = nullptr;
|
|
|
|
QLineEdit* value = nullptr;
|
|
|
|
QLineEdit* comparand = nullptr;
|
|
|
|
PatchEngine::PatchEntry entry;
|
|
|
|
};
|
|
|
|
|
2018-05-06 10:02:39 -06:00
|
|
|
NewPatchDialog::NewPatchDialog(QWidget* parent, PatchEngine::Patch& patch)
|
|
|
|
: QDialog(parent), m_patch(patch)
|
2018-02-16 06:53:52 -07:00
|
|
|
{
|
|
|
|
setWindowTitle(tr("Patch Editor"));
|
2018-05-04 18:29:16 -06:00
|
|
|
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
|
|
|
|
2018-02-16 06:53:52 -07:00
|
|
|
CreateWidgets();
|
|
|
|
ConnectWidgets();
|
|
|
|
|
|
|
|
for (size_t i = 0; i < m_patch.entries.size(); i++)
|
|
|
|
{
|
2019-04-23 10:46:38 -06:00
|
|
|
m_entry_layout->addWidget(CreateEntry(m_patch.entries[i]));
|
2018-02-16 06:53:52 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (m_patch.entries.empty())
|
|
|
|
{
|
|
|
|
AddEntry();
|
2020-12-10 04:58:27 -07:00
|
|
|
m_patch.enabled = true;
|
2018-02-16 06:53:52 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-29 15:28:27 -07:00
|
|
|
NewPatchDialog::~NewPatchDialog() = default;
|
|
|
|
|
2018-02-16 06:53:52 -07:00
|
|
|
void NewPatchDialog::CreateWidgets()
|
|
|
|
{
|
|
|
|
m_name_edit = new QLineEdit;
|
|
|
|
m_name_edit->setPlaceholderText(tr("Patch name"));
|
|
|
|
m_name_edit->setText(QString::fromStdString(m_patch.name));
|
|
|
|
|
|
|
|
m_entry_widget = new QWidget;
|
|
|
|
m_entry_layout = new QVBoxLayout;
|
|
|
|
|
|
|
|
auto* scroll_area = new QScrollArea;
|
|
|
|
m_entry_widget->setLayout(m_entry_layout);
|
|
|
|
scroll_area->setWidget(m_entry_widget);
|
|
|
|
scroll_area->setWidgetResizable(true);
|
|
|
|
|
|
|
|
m_add_button = new QPushButton(tr("Add"));
|
|
|
|
|
|
|
|
m_button_box = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel);
|
|
|
|
|
|
|
|
auto* layout = new QGridLayout;
|
|
|
|
|
|
|
|
layout->addWidget(m_name_edit, 0, 0);
|
|
|
|
layout->addWidget(scroll_area, 1, 0);
|
|
|
|
layout->addWidget(m_add_button, 2, 0);
|
|
|
|
layout->addWidget(m_button_box, 3, 0);
|
|
|
|
|
|
|
|
setLayout(layout);
|
|
|
|
}
|
|
|
|
|
|
|
|
void NewPatchDialog::ConnectWidgets()
|
|
|
|
{
|
2019-07-30 07:35:46 -06:00
|
|
|
connect(m_name_edit, qOverload<const QString&>(&QLineEdit::textEdited),
|
2018-02-16 06:53:52 -07:00
|
|
|
[this](const QString& name) { m_patch.name = name.toStdString(); });
|
|
|
|
|
2019-07-23 16:18:58 -06:00
|
|
|
connect(m_add_button, &QPushButton::clicked, this, &NewPatchDialog::AddEntry);
|
2018-02-16 06:53:52 -07:00
|
|
|
|
|
|
|
connect(m_button_box, &QDialogButtonBox::accepted, this, &NewPatchDialog::accept);
|
|
|
|
connect(m_button_box, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
|
|
|
}
|
|
|
|
|
|
|
|
void NewPatchDialog::AddEntry()
|
|
|
|
{
|
2020-12-29 15:28:27 -07:00
|
|
|
m_entry_layout->addWidget(CreateEntry({}));
|
2018-02-16 06:53:52 -07:00
|
|
|
}
|
|
|
|
|
Patches for Resident Evil 2/3 audio issues
These games are erroneously zeroing buffers before they can be fully copied to ARAM by DMA. The responsible memset() calls are followed by a call to DVDRead() which issues dcbi instructions that effectively cancel the memset() on real hardware. Because Dolphin lacks dcache emulation, the effects of the memset() calls are observed, which causes missing audio.
In a comment on the original bug, phire noted that the issue can be corrected by simply nop'ing out the offending memset() calls. Because the games dynamically load different .rel executables based on the character and/or language, the addresses of these calls can vary.
To deal generally with the problem of code being dynamically loaded to fixed, known addresses, the patch engine is extended to support conditional patches which require a match against a known value. This sort of thing is already achievable with Action Replay/Gecko codes, but their use depends on enabling cheats globally in Dolphin, which is not a prerequisite shared by patches.
Patches are included for every region, character, and language combination. They are enabled by default.
The end result is an approximation of the games' behavior on real hardware without the associated complexity of proper dcache emulation.
https://bugs.dolphin-emu.org/issues/9840
2020-12-29 15:24:46 -07:00
|
|
|
static u32 OnTextEdited(QLineEdit* edit, const QString& text)
|
|
|
|
{
|
|
|
|
bool okay = false;
|
|
|
|
u32 value = text.toUInt(&okay, 16);
|
|
|
|
|
|
|
|
QFont font;
|
|
|
|
QPalette palette;
|
|
|
|
|
|
|
|
font.setBold(!okay);
|
|
|
|
|
|
|
|
if (!okay)
|
|
|
|
palette.setColor(QPalette::Text, Qt::red);
|
|
|
|
|
|
|
|
edit->setFont(font);
|
|
|
|
edit->setPalette(palette);
|
|
|
|
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2020-12-29 15:28:27 -07:00
|
|
|
QGroupBox* NewPatchDialog::CreateEntry(const PatchEngine::PatchEntry& entry)
|
2018-02-16 06:53:52 -07:00
|
|
|
{
|
|
|
|
QGroupBox* box = new QGroupBox();
|
|
|
|
|
|
|
|
auto* type = new QGroupBox(tr("Type"));
|
|
|
|
auto* type_layout = new QHBoxLayout;
|
|
|
|
auto* remove = new QPushButton(tr("Remove"));
|
|
|
|
|
2018-03-04 11:08:57 -07:00
|
|
|
auto* byte = new QRadioButton(tr("8-bit"));
|
|
|
|
auto* word = new QRadioButton(tr("16-bit"));
|
|
|
|
auto* dword = new QRadioButton(tr("32-bit"));
|
2018-02-16 06:53:52 -07:00
|
|
|
|
|
|
|
type_layout->addWidget(byte);
|
|
|
|
type_layout->addWidget(word);
|
|
|
|
type_layout->addWidget(dword);
|
|
|
|
type->setLayout(type_layout);
|
|
|
|
|
Patches for Resident Evil 2/3 audio issues
These games are erroneously zeroing buffers before they can be fully copied to ARAM by DMA. The responsible memset() calls are followed by a call to DVDRead() which issues dcbi instructions that effectively cancel the memset() on real hardware. Because Dolphin lacks dcache emulation, the effects of the memset() calls are observed, which causes missing audio.
In a comment on the original bug, phire noted that the issue can be corrected by simply nop'ing out the offending memset() calls. Because the games dynamically load different .rel executables based on the character and/or language, the addresses of these calls can vary.
To deal generally with the problem of code being dynamically loaded to fixed, known addresses, the patch engine is extended to support conditional patches which require a match against a known value. This sort of thing is already achievable with Action Replay/Gecko codes, but their use depends on enabling cheats globally in Dolphin, which is not a prerequisite shared by patches.
Patches are included for every region, character, and language combination. They are enabled by default.
The end result is an approximation of the games' behavior on real hardware without the associated complexity of proper dcache emulation.
https://bugs.dolphin-emu.org/issues/9840
2020-12-29 15:24:46 -07:00
|
|
|
auto* address = new QLineEdit;
|
2018-02-16 06:53:52 -07:00
|
|
|
auto* value = new QLineEdit;
|
Patches for Resident Evil 2/3 audio issues
These games are erroneously zeroing buffers before they can be fully copied to ARAM by DMA. The responsible memset() calls are followed by a call to DVDRead() which issues dcbi instructions that effectively cancel the memset() on real hardware. Because Dolphin lacks dcache emulation, the effects of the memset() calls are observed, which causes missing audio.
In a comment on the original bug, phire noted that the issue can be corrected by simply nop'ing out the offending memset() calls. Because the games dynamically load different .rel executables based on the character and/or language, the addresses of these calls can vary.
To deal generally with the problem of code being dynamically loaded to fixed, known addresses, the patch engine is extended to support conditional patches which require a match against a known value. This sort of thing is already achievable with Action Replay/Gecko codes, but their use depends on enabling cheats globally in Dolphin, which is not a prerequisite shared by patches.
Patches are included for every region, character, and language combination. They are enabled by default.
The end result is an approximation of the games' behavior on real hardware without the associated complexity of proper dcache emulation.
https://bugs.dolphin-emu.org/issues/9840
2020-12-29 15:24:46 -07:00
|
|
|
auto* comparand = new QLineEdit;
|
2018-02-16 06:53:52 -07:00
|
|
|
|
2020-12-29 15:28:27 -07:00
|
|
|
auto* new_entry = m_entries.emplace_back(std::make_unique<NewPatchEntry>()).get();
|
|
|
|
new_entry->address = address;
|
|
|
|
new_entry->value = value;
|
|
|
|
new_entry->comparand = comparand;
|
|
|
|
new_entry->entry = entry;
|
Patches for Resident Evil 2/3 audio issues
These games are erroneously zeroing buffers before they can be fully copied to ARAM by DMA. The responsible memset() calls are followed by a call to DVDRead() which issues dcbi instructions that effectively cancel the memset() on real hardware. Because Dolphin lacks dcache emulation, the effects of the memset() calls are observed, which causes missing audio.
In a comment on the original bug, phire noted that the issue can be corrected by simply nop'ing out the offending memset() calls. Because the games dynamically load different .rel executables based on the character and/or language, the addresses of these calls can vary.
To deal generally with the problem of code being dynamically loaded to fixed, known addresses, the patch engine is extended to support conditional patches which require a match against a known value. This sort of thing is already achievable with Action Replay/Gecko codes, but their use depends on enabling cheats globally in Dolphin, which is not a prerequisite shared by patches.
Patches are included for every region, character, and language combination. They are enabled by default.
The end result is an approximation of the games' behavior on real hardware without the associated complexity of proper dcache emulation.
https://bugs.dolphin-emu.org/issues/9840
2020-12-29 15:24:46 -07:00
|
|
|
|
|
|
|
auto* conditional = new QCheckBox(tr("Conditional"));
|
|
|
|
auto* comparand_label = new QLabel(tr("Comparand:"));
|
2018-02-16 06:53:52 -07:00
|
|
|
|
|
|
|
auto* layout = new QGridLayout;
|
|
|
|
layout->addWidget(type, 0, 0, 1, -1);
|
Patches for Resident Evil 2/3 audio issues
These games are erroneously zeroing buffers before they can be fully copied to ARAM by DMA. The responsible memset() calls are followed by a call to DVDRead() which issues dcbi instructions that effectively cancel the memset() on real hardware. Because Dolphin lacks dcache emulation, the effects of the memset() calls are observed, which causes missing audio.
In a comment on the original bug, phire noted that the issue can be corrected by simply nop'ing out the offending memset() calls. Because the games dynamically load different .rel executables based on the character and/or language, the addresses of these calls can vary.
To deal generally with the problem of code being dynamically loaded to fixed, known addresses, the patch engine is extended to support conditional patches which require a match against a known value. This sort of thing is already achievable with Action Replay/Gecko codes, but their use depends on enabling cheats globally in Dolphin, which is not a prerequisite shared by patches.
Patches are included for every region, character, and language combination. They are enabled by default.
The end result is an approximation of the games' behavior on real hardware without the associated complexity of proper dcache emulation.
https://bugs.dolphin-emu.org/issues/9840
2020-12-29 15:24:46 -07:00
|
|
|
layout->addWidget(new QLabel(tr("Address:")), 1, 0);
|
|
|
|
layout->addWidget(address, 1, 1);
|
2018-02-16 06:53:52 -07:00
|
|
|
layout->addWidget(new QLabel(tr("Value:")), 2, 0);
|
|
|
|
layout->addWidget(value, 2, 1);
|
Patches for Resident Evil 2/3 audio issues
These games are erroneously zeroing buffers before they can be fully copied to ARAM by DMA. The responsible memset() calls are followed by a call to DVDRead() which issues dcbi instructions that effectively cancel the memset() on real hardware. Because Dolphin lacks dcache emulation, the effects of the memset() calls are observed, which causes missing audio.
In a comment on the original bug, phire noted that the issue can be corrected by simply nop'ing out the offending memset() calls. Because the games dynamically load different .rel executables based on the character and/or language, the addresses of these calls can vary.
To deal generally with the problem of code being dynamically loaded to fixed, known addresses, the patch engine is extended to support conditional patches which require a match against a known value. This sort of thing is already achievable with Action Replay/Gecko codes, but their use depends on enabling cheats globally in Dolphin, which is not a prerequisite shared by patches.
Patches are included for every region, character, and language combination. They are enabled by default.
The end result is an approximation of the games' behavior on real hardware without the associated complexity of proper dcache emulation.
https://bugs.dolphin-emu.org/issues/9840
2020-12-29 15:24:46 -07:00
|
|
|
layout->addWidget(conditional, 3, 0, 1, -1);
|
|
|
|
layout->addWidget(comparand_label, 4, 0);
|
|
|
|
layout->addWidget(comparand, 4, 1);
|
|
|
|
layout->addWidget(remove, 5, 0, 1, -1);
|
2018-02-16 06:53:52 -07:00
|
|
|
box->setLayout(layout);
|
|
|
|
|
Patches for Resident Evil 2/3 audio issues
These games are erroneously zeroing buffers before they can be fully copied to ARAM by DMA. The responsible memset() calls are followed by a call to DVDRead() which issues dcbi instructions that effectively cancel the memset() on real hardware. Because Dolphin lacks dcache emulation, the effects of the memset() calls are observed, which causes missing audio.
In a comment on the original bug, phire noted that the issue can be corrected by simply nop'ing out the offending memset() calls. Because the games dynamically load different .rel executables based on the character and/or language, the addresses of these calls can vary.
To deal generally with the problem of code being dynamically loaded to fixed, known addresses, the patch engine is extended to support conditional patches which require a match against a known value. This sort of thing is already achievable with Action Replay/Gecko codes, but their use depends on enabling cheats globally in Dolphin, which is not a prerequisite shared by patches.
Patches are included for every region, character, and language combination. They are enabled by default.
The end result is an approximation of the games' behavior on real hardware without the associated complexity of proper dcache emulation.
https://bugs.dolphin-emu.org/issues/9840
2020-12-29 15:24:46 -07:00
|
|
|
connect(address, qOverload<const QString&>(&QLineEdit::textEdited),
|
2020-12-29 15:28:27 -07:00
|
|
|
[new_entry](const QString& text) {
|
|
|
|
new_entry->entry.address = OnTextEdited(new_entry->address, text);
|
|
|
|
});
|
2018-02-16 06:53:52 -07:00
|
|
|
|
2019-07-30 07:35:46 -06:00
|
|
|
connect(value, qOverload<const QString&>(&QLineEdit::textEdited),
|
2020-12-29 15:28:27 -07:00
|
|
|
[new_entry](const QString& text) {
|
|
|
|
new_entry->entry.value = OnTextEdited(new_entry->value, text);
|
|
|
|
});
|
2018-02-16 06:53:52 -07:00
|
|
|
|
Patches for Resident Evil 2/3 audio issues
These games are erroneously zeroing buffers before they can be fully copied to ARAM by DMA. The responsible memset() calls are followed by a call to DVDRead() which issues dcbi instructions that effectively cancel the memset() on real hardware. Because Dolphin lacks dcache emulation, the effects of the memset() calls are observed, which causes missing audio.
In a comment on the original bug, phire noted that the issue can be corrected by simply nop'ing out the offending memset() calls. Because the games dynamically load different .rel executables based on the character and/or language, the addresses of these calls can vary.
To deal generally with the problem of code being dynamically loaded to fixed, known addresses, the patch engine is extended to support conditional patches which require a match against a known value. This sort of thing is already achievable with Action Replay/Gecko codes, but their use depends on enabling cheats globally in Dolphin, which is not a prerequisite shared by patches.
Patches are included for every region, character, and language combination. They are enabled by default.
The end result is an approximation of the games' behavior on real hardware without the associated complexity of proper dcache emulation.
https://bugs.dolphin-emu.org/issues/9840
2020-12-29 15:24:46 -07:00
|
|
|
connect(comparand, qOverload<const QString&>(&QLineEdit::textEdited),
|
2020-12-29 15:28:27 -07:00
|
|
|
[new_entry](const QString& text) {
|
|
|
|
new_entry->entry.comparand = OnTextEdited(new_entry->comparand, text);
|
2018-02-16 06:53:52 -07:00
|
|
|
});
|
|
|
|
|
2020-12-29 15:28:27 -07:00
|
|
|
connect(remove, &QPushButton::clicked, [this, box, new_entry] {
|
|
|
|
if (m_entries.size() > 1)
|
2018-02-16 06:53:52 -07:00
|
|
|
{
|
2019-04-23 10:46:38 -06:00
|
|
|
box->setVisible(false);
|
2018-02-16 06:53:52 -07:00
|
|
|
m_entry_layout->removeWidget(box);
|
2019-04-23 10:46:38 -06:00
|
|
|
box->deleteLater();
|
2020-12-11 14:10:36 -07:00
|
|
|
|
2020-12-29 15:28:27 -07:00
|
|
|
m_entries.erase(std::find_if(m_entries.begin(), m_entries.end(),
|
|
|
|
[new_entry](const auto& e) { return e.get() == new_entry; }));
|
2018-02-16 06:53:52 -07:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-12-29 15:28:27 -07:00
|
|
|
connect(byte, &QRadioButton::toggled, [new_entry](bool checked) {
|
2018-02-16 06:53:52 -07:00
|
|
|
if (checked)
|
2020-12-29 15:28:27 -07:00
|
|
|
new_entry->entry.type = PatchEngine::PatchType::Patch8Bit;
|
2018-02-16 06:53:52 -07:00
|
|
|
});
|
|
|
|
|
2020-12-29 15:28:27 -07:00
|
|
|
connect(word, &QRadioButton::toggled, [new_entry](bool checked) {
|
2018-02-16 06:53:52 -07:00
|
|
|
if (checked)
|
2020-12-29 15:28:27 -07:00
|
|
|
new_entry->entry.type = PatchEngine::PatchType::Patch16Bit;
|
2018-02-16 06:53:52 -07:00
|
|
|
});
|
|
|
|
|
2020-12-29 15:28:27 -07:00
|
|
|
connect(dword, &QRadioButton::toggled, [new_entry](bool checked) {
|
2018-02-16 06:53:52 -07:00
|
|
|
if (checked)
|
2020-12-29 15:28:27 -07:00
|
|
|
new_entry->entry.type = PatchEngine::PatchType::Patch32Bit;
|
2018-02-16 06:53:52 -07:00
|
|
|
});
|
|
|
|
|
2019-04-23 10:46:38 -06:00
|
|
|
byte->setChecked(entry.type == PatchEngine::PatchType::Patch8Bit);
|
|
|
|
word->setChecked(entry.type == PatchEngine::PatchType::Patch16Bit);
|
|
|
|
dword->setChecked(entry.type == PatchEngine::PatchType::Patch32Bit);
|
2018-02-16 06:53:52 -07:00
|
|
|
|
2020-12-29 15:28:27 -07:00
|
|
|
connect(conditional, &QCheckBox::toggled, [new_entry, comparand_label, comparand](bool checked) {
|
|
|
|
new_entry->entry.conditional = checked;
|
Patches for Resident Evil 2/3 audio issues
These games are erroneously zeroing buffers before they can be fully copied to ARAM by DMA. The responsible memset() calls are followed by a call to DVDRead() which issues dcbi instructions that effectively cancel the memset() on real hardware. Because Dolphin lacks dcache emulation, the effects of the memset() calls are observed, which causes missing audio.
In a comment on the original bug, phire noted that the issue can be corrected by simply nop'ing out the offending memset() calls. Because the games dynamically load different .rel executables based on the character and/or language, the addresses of these calls can vary.
To deal generally with the problem of code being dynamically loaded to fixed, known addresses, the patch engine is extended to support conditional patches which require a match against a known value. This sort of thing is already achievable with Action Replay/Gecko codes, but their use depends on enabling cheats globally in Dolphin, which is not a prerequisite shared by patches.
Patches are included for every region, character, and language combination. They are enabled by default.
The end result is an approximation of the games' behavior on real hardware without the associated complexity of proper dcache emulation.
https://bugs.dolphin-emu.org/issues/9840
2020-12-29 15:24:46 -07:00
|
|
|
comparand_label->setVisible(checked);
|
|
|
|
comparand->setVisible(checked);
|
|
|
|
});
|
|
|
|
|
|
|
|
conditional->setChecked(entry.conditional);
|
|
|
|
comparand_label->setVisible(entry.conditional);
|
|
|
|
comparand->setVisible(entry.conditional);
|
|
|
|
|
|
|
|
address->setText(QStringLiteral("%1").arg(entry.address, 8, 16, QLatin1Char('0')));
|
2019-04-23 10:46:38 -06:00
|
|
|
value->setText(QStringLiteral("%1").arg(entry.value, 8, 16, QLatin1Char('0')));
|
Patches for Resident Evil 2/3 audio issues
These games are erroneously zeroing buffers before they can be fully copied to ARAM by DMA. The responsible memset() calls are followed by a call to DVDRead() which issues dcbi instructions that effectively cancel the memset() on real hardware. Because Dolphin lacks dcache emulation, the effects of the memset() calls are observed, which causes missing audio.
In a comment on the original bug, phire noted that the issue can be corrected by simply nop'ing out the offending memset() calls. Because the games dynamically load different .rel executables based on the character and/or language, the addresses of these calls can vary.
To deal generally with the problem of code being dynamically loaded to fixed, known addresses, the patch engine is extended to support conditional patches which require a match against a known value. This sort of thing is already achievable with Action Replay/Gecko codes, but their use depends on enabling cheats globally in Dolphin, which is not a prerequisite shared by patches.
Patches are included for every region, character, and language combination. They are enabled by default.
The end result is an approximation of the games' behavior on real hardware without the associated complexity of proper dcache emulation.
https://bugs.dolphin-emu.org/issues/9840
2020-12-29 15:24:46 -07:00
|
|
|
comparand->setText(QStringLiteral("%1").arg(entry.comparand, 8, 16, QLatin1Char('0')));
|
2018-02-16 06:53:52 -07:00
|
|
|
|
|
|
|
return box;
|
|
|
|
}
|
|
|
|
|
|
|
|
void NewPatchDialog::accept()
|
|
|
|
{
|
|
|
|
if (m_name_edit->text().isEmpty())
|
|
|
|
{
|
2019-03-04 12:49:00 -07:00
|
|
|
ModalMessageBox::critical(this, tr("Error"), tr("You have to enter a name."));
|
2018-02-16 06:53:52 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool valid = true;
|
|
|
|
|
2020-12-29 15:28:27 -07:00
|
|
|
for (const auto& entry : m_entries)
|
2018-02-16 06:53:52 -07:00
|
|
|
{
|
2020-12-29 15:28:27 -07:00
|
|
|
entry->address->text().toUInt(&valid, 16);
|
|
|
|
if (!valid)
|
|
|
|
break;
|
|
|
|
|
|
|
|
entry->value->text().toUInt(&valid, 16);
|
2018-02-16 06:53:52 -07:00
|
|
|
if (!valid)
|
|
|
|
break;
|
2020-12-29 15:28:27 -07:00
|
|
|
|
|
|
|
if (entry->entry.conditional)
|
|
|
|
{
|
|
|
|
entry->comparand->text().toUInt(&valid, 16);
|
|
|
|
if (!valid)
|
|
|
|
break;
|
|
|
|
}
|
2018-02-16 06:53:52 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!valid)
|
|
|
|
{
|
2019-03-04 12:49:00 -07:00
|
|
|
ModalMessageBox::critical(
|
2018-02-16 06:53:52 -07:00
|
|
|
this, tr("Error"),
|
|
|
|
tr("Some values you provided are invalid.\nPlease check the highlighted values."));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-12-29 15:28:27 -07:00
|
|
|
m_patch.entries.clear();
|
|
|
|
|
|
|
|
for (const auto& entry : m_entries)
|
|
|
|
{
|
|
|
|
m_patch.entries.emplace_back(entry->entry);
|
|
|
|
}
|
|
|
|
|
2018-02-16 06:53:52 -07:00
|
|
|
QDialog::accept();
|
|
|
|
}
|