mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-07 22:55:40 +12:00
Add cheat picker window
This commit is contained in:
parent
ca1c42c280
commit
63f54478f0
5 changed files with 358 additions and 6 deletions
|
@ -14,7 +14,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
set(CMAKE_BUILD_TYPE Release)
|
set(CMAKE_BUILD_TYPE RelWithDebInfo)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
project(Alber)
|
project(Alber)
|
||||||
|
@ -197,10 +197,10 @@ set(RENDERER_SW_SOURCE_FILES src/core/renderer_sw/renderer_sw.cpp)
|
||||||
if(NOT ANDROID)
|
if(NOT ANDROID)
|
||||||
if(ENABLE_QT_GUI)
|
if(ENABLE_QT_GUI)
|
||||||
set(FRONTEND_SOURCE_FILES src/panda_qt/main.cpp src/panda_qt/screen.cpp src/panda_qt/main_window.cpp src/panda_qt/about_window.cpp
|
set(FRONTEND_SOURCE_FILES src/panda_qt/main.cpp src/panda_qt/screen.cpp src/panda_qt/main_window.cpp src/panda_qt/about_window.cpp
|
||||||
src/panda_qt/config_window.cpp src/panda_qt/zep.cpp src/panda_qt/text_editor.cpp
|
src/panda_qt/config_window.cpp src/panda_qt/zep.cpp src/panda_qt/text_editor.cpp src/panda_qt/cheats_window.cpp
|
||||||
)
|
)
|
||||||
set(FRONTEND_HEADER_FILES include/panda_qt/screen.hpp include/panda_qt/main_window.hpp include/panda_qt/about_window.hpp
|
set(FRONTEND_HEADER_FILES include/panda_qt/screen.hpp include/panda_qt/main_window.hpp include/panda_qt/about_window.hpp
|
||||||
include/panda_qt/config_window.hpp include/panda_qt/text_editor.hpp
|
include/panda_qt/config_window.hpp include/panda_qt/text_editor.hpp include/panda_qt/cheats_window.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
source_group("Source Files\\Qt" FILES ${FRONTEND_SOURCE_FILES})
|
source_group("Source Files\\Qt" FILES ${FRONTEND_SOURCE_FILES})
|
||||||
|
|
26
include/panda_qt/cheats_window.hpp
Normal file
26
include/panda_qt/cheats_window.hpp
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <memory>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QWidget>
|
||||||
|
#include "emulator.hpp"
|
||||||
|
|
||||||
|
class QListWidget;
|
||||||
|
|
||||||
|
class CheatsWindow final : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
CheatsWindow(Emulator* emu, const std::filesystem::path& path, QWidget* parent = nullptr);
|
||||||
|
~CheatsWindow() = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void addEntry();
|
||||||
|
void removeClicked();
|
||||||
|
|
||||||
|
QListWidget* cheatList;
|
||||||
|
std::filesystem::path cheatPath;
|
||||||
|
Emulator* emu;
|
||||||
|
};
|
|
@ -12,6 +12,7 @@
|
||||||
#include "emulator.hpp"
|
#include "emulator.hpp"
|
||||||
#include "panda_qt/about_window.hpp"
|
#include "panda_qt/about_window.hpp"
|
||||||
#include "panda_qt/config_window.hpp"
|
#include "panda_qt/config_window.hpp"
|
||||||
|
#include "panda_qt/cheats_window.hpp"
|
||||||
#include "panda_qt/screen.hpp"
|
#include "panda_qt/screen.hpp"
|
||||||
#include "panda_qt/text_editor.hpp"
|
#include "panda_qt/text_editor.hpp"
|
||||||
#include "services/hid.hpp"
|
#include "services/hid.hpp"
|
||||||
|
@ -54,15 +55,19 @@ class MainWindow : public QMainWindow {
|
||||||
ScreenWidget screen;
|
ScreenWidget screen;
|
||||||
AboutWindow* aboutWindow;
|
AboutWindow* aboutWindow;
|
||||||
ConfigWindow* configWindow;
|
ConfigWindow* configWindow;
|
||||||
|
CheatsWindow* cheatsEditor;
|
||||||
TextEditorWindow* luaEditor;
|
TextEditorWindow* luaEditor;
|
||||||
QMenuBar* menuBar = nullptr;
|
QMenuBar* menuBar = nullptr;
|
||||||
|
|
||||||
|
QAction* cheatsEditorAction = nullptr;
|
||||||
|
|
||||||
void swapEmuBuffer();
|
void swapEmuBuffer();
|
||||||
void emuThreadMainLoop();
|
void emuThreadMainLoop();
|
||||||
void selectLuaFile();
|
void selectLuaFile();
|
||||||
void selectROM();
|
void selectROM();
|
||||||
void dumpRomFS();
|
void dumpRomFS();
|
||||||
void openLuaEditor();
|
void openLuaEditor();
|
||||||
|
void openCheatsEditor();
|
||||||
void showAboutMenu();
|
void showAboutMenu();
|
||||||
void sendMessage(const EmulatorMessage& message);
|
void sendMessage(const EmulatorMessage& message);
|
||||||
void dispatchMessage(const EmulatorMessage& message);
|
void dispatchMessage(const EmulatorMessage& message);
|
||||||
|
|
313
src/panda_qt/cheats_window.cpp
Normal file
313
src/panda_qt/cheats_window.cpp
Normal file
|
@ -0,0 +1,313 @@
|
||||||
|
#include "panda_qt/cheats_window.hpp"
|
||||||
|
#include <qlistwidget.h>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QTextEdit>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include "cheats.hpp"
|
||||||
|
#include "emulator.hpp"
|
||||||
|
|
||||||
|
using CheatHandle = u32;
|
||||||
|
|
||||||
|
CheatHandle BAD_CHEAT = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
struct CheatMetadata
|
||||||
|
{
|
||||||
|
CheatHandle handle = BAD_CHEAT;
|
||||||
|
std::string name = "New cheat";
|
||||||
|
std::string code;
|
||||||
|
bool enabled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
u32 addCheat(Emulator* emu, u8* data, size_t size)
|
||||||
|
{
|
||||||
|
if ((size % 8) != 0) {
|
||||||
|
return BAD_CHEAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cheats::Cheat cheat;
|
||||||
|
cheat.enabled = true;
|
||||||
|
cheat.type = Cheats::CheatType::ActionReplay;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < size; i += 8) {
|
||||||
|
auto read32 = [](const u8* ptr) { return (u32(ptr[3]) << 24) | (u32(ptr[2]) << 16) | (u32(ptr[1]) << 8) | u32(ptr[0]); };
|
||||||
|
|
||||||
|
// Data is passed to us in big endian so we bswap
|
||||||
|
u32 firstWord = Common::swap32(read32(data + i));
|
||||||
|
u32 secondWord = Common::swap32(read32(data + i + 4));
|
||||||
|
cheat.instructions.insert(cheat.instructions.end(), {firstWord, secondWord});
|
||||||
|
}
|
||||||
|
|
||||||
|
return emu->getCheats().addCheat(cheat);
|
||||||
|
}
|
||||||
|
|
||||||
|
class CheatEntryWidget : public QWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CheatEntryWidget(Emulator* emu, CheatMetadata metadata, QListWidget* parent);
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
name->setText(metadata.name.c_str());
|
||||||
|
enabled->setChecked(metadata.enabled);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Remove()
|
||||||
|
{
|
||||||
|
emu->getCheats().removeCheat(metadata.handle);
|
||||||
|
cheatList->takeItem(cheatList->row(listItem));
|
||||||
|
deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
const CheatMetadata& GetMetadata()
|
||||||
|
{
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetMetadata(const CheatMetadata& metadata)
|
||||||
|
{
|
||||||
|
this->metadata = metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void checkboxChanged(int state);
|
||||||
|
void editClicked();
|
||||||
|
|
||||||
|
Emulator* emu;
|
||||||
|
CheatMetadata metadata;
|
||||||
|
u32 handle;
|
||||||
|
QLabel* name;
|
||||||
|
QCheckBox* enabled;
|
||||||
|
QListWidget* cheatList;
|
||||||
|
QListWidgetItem* listItem;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CheatEditDialog : public QDialog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CheatEditDialog(Emulator* emu, CheatEntryWidget& cheatEntry);
|
||||||
|
|
||||||
|
void accepted();
|
||||||
|
void rejected();
|
||||||
|
private:
|
||||||
|
Emulator* emu;
|
||||||
|
CheatEntryWidget& cheatEntry;
|
||||||
|
QTextEdit* codeEdit;
|
||||||
|
QLineEdit* nameEdit;
|
||||||
|
};
|
||||||
|
|
||||||
|
CheatEntryWidget::CheatEntryWidget(Emulator* emu, CheatMetadata metadata, QListWidget* parent)
|
||||||
|
: QWidget(), emu(emu), metadata(metadata), cheatList(parent)
|
||||||
|
{
|
||||||
|
QHBoxLayout* layout = new QHBoxLayout;
|
||||||
|
|
||||||
|
enabled = new QCheckBox;
|
||||||
|
enabled->setChecked(metadata.enabled);
|
||||||
|
|
||||||
|
name = new QLabel(metadata.name.c_str());
|
||||||
|
QPushButton* buttonEdit = new QPushButton(tr("Edit"));
|
||||||
|
|
||||||
|
connect(enabled, &QCheckBox::stateChanged, this, &CheatEntryWidget::checkboxChanged);
|
||||||
|
connect(buttonEdit, &QPushButton::clicked, this, &CheatEntryWidget::editClicked);
|
||||||
|
|
||||||
|
layout->addWidget(enabled);
|
||||||
|
layout->addWidget(name);
|
||||||
|
layout->addWidget(buttonEdit);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
listItem = new QListWidgetItem;
|
||||||
|
listItem->setSizeHint(sizeHint());
|
||||||
|
parent->addItem(listItem);
|
||||||
|
parent->setItemWidget(listItem, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheatEntryWidget::checkboxChanged(int state)
|
||||||
|
{
|
||||||
|
bool enabled = state == Qt::Checked;
|
||||||
|
if (metadata.handle == BAD_CHEAT)
|
||||||
|
{
|
||||||
|
printf("Cheat handle is bad, this shouldn't happen\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabled)
|
||||||
|
{
|
||||||
|
emu->getCheats().enableCheat(metadata.handle);
|
||||||
|
metadata.enabled = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
emu->getCheats().disableCheat(metadata.handle);
|
||||||
|
metadata.enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheatEntryWidget::editClicked()
|
||||||
|
{
|
||||||
|
CheatEditDialog* dialog = new CheatEditDialog(emu, *this);
|
||||||
|
dialog->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
CheatEditDialog::CheatEditDialog(Emulator* emu, CheatEntryWidget& cheatEntry) : QDialog(), emu(emu), cheatEntry(cheatEntry)
|
||||||
|
{
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
setModal(true);
|
||||||
|
|
||||||
|
QVBoxLayout* layout = new QVBoxLayout;
|
||||||
|
const CheatMetadata& metadata = cheatEntry.GetMetadata();
|
||||||
|
codeEdit = new QTextEdit;
|
||||||
|
nameEdit = new QLineEdit;
|
||||||
|
nameEdit->setText(metadata.name.c_str());
|
||||||
|
nameEdit->setPlaceholderText(tr("Cheat name"));
|
||||||
|
layout->addWidget(nameEdit);
|
||||||
|
|
||||||
|
QFont font;
|
||||||
|
font.setFamily("Courier");
|
||||||
|
font.setFixedPitch(true);
|
||||||
|
font.setPointSize(10);
|
||||||
|
codeEdit->setFont(font);
|
||||||
|
|
||||||
|
if (metadata.code.size() != 0)
|
||||||
|
{
|
||||||
|
// Nicely format it like so:
|
||||||
|
// 01234567 89ABCDEF
|
||||||
|
// 01234567 89ABCDEF
|
||||||
|
std::string formattedCode;
|
||||||
|
for (size_t i = 0; i < metadata.code.size(); i += 2)
|
||||||
|
{
|
||||||
|
if (i != 0) {
|
||||||
|
if (i % 8 == 0 && i % 16 != 0)
|
||||||
|
{
|
||||||
|
formattedCode += " ";
|
||||||
|
}
|
||||||
|
else if (i % 16 == 0)
|
||||||
|
{
|
||||||
|
formattedCode += "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
formattedCode += metadata.code[i];
|
||||||
|
formattedCode += metadata.code[i + 1];
|
||||||
|
}
|
||||||
|
codeEdit->setText(formattedCode.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
layout->addWidget(codeEdit);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
auto buttons = QDialogButtonBox::Ok | QDialogButtonBox::Cancel;
|
||||||
|
QDialogButtonBox* button_box = new QDialogButtonBox(buttons);
|
||||||
|
layout->addWidget(button_box);
|
||||||
|
|
||||||
|
connect(button_box, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||||
|
connect(button_box, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||||
|
connect(this, &QDialog::rejected, this, &CheatEditDialog::rejected);
|
||||||
|
connect(this, &QDialog::accepted, this, &CheatEditDialog::accepted);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheatEditDialog::accepted()
|
||||||
|
{
|
||||||
|
QString code = codeEdit->toPlainText();
|
||||||
|
code.replace(QRegularExpression("[^0-9a-fA-F]"), "");
|
||||||
|
|
||||||
|
CheatMetadata metadata = cheatEntry.GetMetadata();
|
||||||
|
bool isEditing = metadata.handle != BAD_CHEAT;
|
||||||
|
metadata.name = nameEdit->text().toStdString();
|
||||||
|
metadata.code = code.toStdString();
|
||||||
|
|
||||||
|
std::vector<uint8_t> bytes;
|
||||||
|
for (size_t i = 0; i < metadata.code.size(); i += 2)
|
||||||
|
{
|
||||||
|
std::string hex = metadata.code.substr(i, 2);
|
||||||
|
bytes.push_back((uint8_t)std::stoul(hex, nullptr, 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEditing)
|
||||||
|
{
|
||||||
|
emu->getCheats().removeCheat(metadata.handle);
|
||||||
|
u32 handle = addCheat(emu, bytes.data(), bytes.size());
|
||||||
|
metadata.handle = handle;
|
||||||
|
cheatEntry.SetMetadata(metadata);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (metadata.name.empty())
|
||||||
|
{
|
||||||
|
metadata.name = tr("Cheat code").toStdString();
|
||||||
|
}
|
||||||
|
u32 handle = addCheat(emu, bytes.data(), bytes.size());
|
||||||
|
metadata.handle = handle;
|
||||||
|
cheatEntry.SetMetadata(metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
cheatEntry.Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheatEditDialog::rejected()
|
||||||
|
{
|
||||||
|
bool isEditing = cheatEntry.GetMetadata().handle != BAD_CHEAT;
|
||||||
|
|
||||||
|
if (!isEditing)
|
||||||
|
{
|
||||||
|
// Was adding a cheat but pressed cancel
|
||||||
|
cheatEntry.Remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CheatsWindow::CheatsWindow(Emulator* emu, const std::filesystem::path& cheatPath, QWidget* parent)
|
||||||
|
: QWidget(parent, Qt::Window), emu(emu), cheatPath(cheatPath)
|
||||||
|
{
|
||||||
|
QVBoxLayout* layout = new QVBoxLayout;
|
||||||
|
layout->setContentsMargins(6, 6, 6, 6);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
cheatList = new QListWidget;
|
||||||
|
layout->addWidget(cheatList);
|
||||||
|
|
||||||
|
QWidget* buttonBox = new QWidget;
|
||||||
|
QHBoxLayout* buttonLayout = new QHBoxLayout;
|
||||||
|
|
||||||
|
QPushButton* buttonAdd = new QPushButton(tr("Add"));
|
||||||
|
QPushButton* buttonRemove = new QPushButton(tr("Remove"));
|
||||||
|
|
||||||
|
connect(buttonAdd, &QPushButton::clicked, this, &CheatsWindow::addEntry);
|
||||||
|
connect(buttonRemove, &QPushButton::clicked, this, &CheatsWindow::removeClicked);
|
||||||
|
|
||||||
|
buttonLayout->addWidget(buttonAdd);
|
||||||
|
buttonLayout->addWidget(buttonRemove);
|
||||||
|
buttonBox->setLayout(buttonLayout);
|
||||||
|
|
||||||
|
layout->addWidget(buttonBox);
|
||||||
|
|
||||||
|
// TODO: load cheats from saved cheats per game
|
||||||
|
// for (const CheatMetadata& metadata : getSavedCheats())
|
||||||
|
// {
|
||||||
|
// new CheatEntryWidget(emu, metadata, cheatList);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheatsWindow::addEntry()
|
||||||
|
{
|
||||||
|
// CheatEntryWidget is added to the list when it's created
|
||||||
|
CheatEntryWidget* entry = new CheatEntryWidget(emu, {BAD_CHEAT, "New cheat", "", true}, cheatList);
|
||||||
|
CheatEditDialog* dialog = new CheatEditDialog(emu, *entry);
|
||||||
|
dialog->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheatsWindow::removeClicked()
|
||||||
|
{
|
||||||
|
QListWidgetItem* item = cheatList->currentItem();
|
||||||
|
if (item == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CheatEntryWidget* entry = static_cast<CheatEntryWidget*>(cheatList->itemWidget(item));
|
||||||
|
entry->Remove();
|
||||||
|
}
|
|
@ -48,20 +48,24 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent)
|
||||||
|
|
||||||
auto dumpRomFSAction = toolsMenu->addAction(tr("Dump RomFS"));
|
auto dumpRomFSAction = toolsMenu->addAction(tr("Dump RomFS"));
|
||||||
auto luaEditorAction = toolsMenu->addAction(tr("Open Lua Editor"));
|
auto luaEditorAction = toolsMenu->addAction(tr("Open Lua Editor"));
|
||||||
|
cheatsEditorAction = toolsMenu->addAction(tr("Open Cheats Editor"));
|
||||||
|
cheatsEditorAction->setEnabled(false);
|
||||||
connect(dumpRomFSAction, &QAction::triggered, this, &MainWindow::dumpRomFS);
|
connect(dumpRomFSAction, &QAction::triggered, this, &MainWindow::dumpRomFS);
|
||||||
connect(luaEditorAction, &QAction::triggered, this, &MainWindow::openLuaEditor);
|
connect(luaEditorAction, &QAction::triggered, this, &MainWindow::openLuaEditor);
|
||||||
|
connect(cheatsEditorAction, &QAction::triggered, this, &MainWindow::openCheatsEditor);
|
||||||
|
|
||||||
auto aboutAction = aboutMenu->addAction(tr("About Panda3DS"));
|
auto aboutAction = aboutMenu->addAction(tr("About Panda3DS"));
|
||||||
connect(aboutAction, &QAction::triggered, this, &MainWindow::showAboutMenu);
|
connect(aboutAction, &QAction::triggered, this, &MainWindow::showAboutMenu);
|
||||||
|
|
||||||
|
emu = new Emulator();
|
||||||
|
emu->setOutputSize(screen.surfaceWidth, screen.surfaceHeight);
|
||||||
|
|
||||||
// Set up misc objects
|
// Set up misc objects
|
||||||
aboutWindow = new AboutWindow(nullptr);
|
aboutWindow = new AboutWindow(nullptr);
|
||||||
configWindow = new ConfigWindow(this);
|
configWindow = new ConfigWindow(this);
|
||||||
|
cheatsEditor = new CheatsWindow(emu, {});
|
||||||
luaEditor = new TextEditorWindow(this, "script.lua", "");
|
luaEditor = new TextEditorWindow(this, "script.lua", "");
|
||||||
|
|
||||||
emu = new Emulator();
|
|
||||||
emu->setOutputSize(screen.surfaceWidth, screen.surfaceHeight);
|
|
||||||
|
|
||||||
auto args = QCoreApplication::arguments();
|
auto args = QCoreApplication::arguments();
|
||||||
if (args.size() > 1) {
|
if (args.size() > 1) {
|
||||||
auto romPath = std::filesystem::current_path() / args.at(1).toStdU16String();
|
auto romPath = std::filesystem::current_path() / args.at(1).toStdU16String();
|
||||||
|
@ -184,6 +188,7 @@ MainWindow::~MainWindow() {
|
||||||
delete menuBar;
|
delete menuBar;
|
||||||
delete aboutWindow;
|
delete aboutWindow;
|
||||||
delete configWindow;
|
delete configWindow;
|
||||||
|
delete cheatsEditor;
|
||||||
delete luaEditor;
|
delete luaEditor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,10 +239,13 @@ void MainWindow::showAboutMenu() {
|
||||||
|
|
||||||
void MainWindow::openLuaEditor() { luaEditor->show(); }
|
void MainWindow::openLuaEditor() { luaEditor->show(); }
|
||||||
|
|
||||||
|
void MainWindow::openCheatsEditor() { cheatsEditor->show(); }
|
||||||
|
|
||||||
void MainWindow::dispatchMessage(const EmulatorMessage& message) {
|
void MainWindow::dispatchMessage(const EmulatorMessage& message) {
|
||||||
switch (message.type) {
|
switch (message.type) {
|
||||||
case MessageType::LoadROM:
|
case MessageType::LoadROM:
|
||||||
emu->loadROM(*message.path.p);
|
emu->loadROM(*message.path.p);
|
||||||
|
cheatsEditorAction->setEnabled(true);
|
||||||
// Clean up the allocated path
|
// Clean up the allocated path
|
||||||
delete message.path.p;
|
delete message.path.p;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Reference in a new issue