aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
author2jun0 <soo28819@naver.com>2022-03-07 06:33:11 +0900
committerGitHub <noreply@github.com>2022-03-06 22:33:11 +0100
commitc66df57256b0eecc09a49a960457d32a10b7cb00 (patch)
tree2135a01d6536eefaeda2fbf58ee41d68481b07bc /src
parent38c8b886ea2feefac1a707df52c122b01dca2dd8 (diff)
Implement MainRAM management dialog😁 (#1248)
* Implement MainRAM management dialog * Modify RAMInfoDialog - use emuThread to avoid a race condition. - replace RAMUpdateThread to QTimer Co-Authored-By: RSDuck <RSDuck@users.noreply.github.com> * Update src/frontend/qt_sdl/RAMInfoDialog.cpp small typo Co-authored-by: Rayyan Ansari <68647953+RayyanAnsari@users.noreply.github.com> * Update src/frontend/qt_sdl/RAMInfoDialog.h small typo Co-authored-by: Rayyan Ansari <68647953+RayyanAnsari@users.noreply.github.com> * typo errors in RAMInfoDialog Rrevious->Previous * add new line to the end of the file Co-authored-by: Rayyan Ansari <rayyan@ansari.sh> * enable raminfo when cart is inserted * Modify that only the 'value' item can be edited in RAMinfoDialog * fix: function name incorrect error * fix: function name incorrect error2 * fix: wrong way to get ram value Co-authored-by: RSDuck <RSDuck@users.noreply.github.com> Co-authored-by: Rayyan Ansari <68647953+RayyanAnsari@users.noreply.github.com> Co-authored-by: Rayyan Ansari <rayyan@ansari.sh>
Diffstat (limited to 'src')
-rw-r--r--src/frontend/qt_sdl/CMakeLists.txt1
-rw-r--r--src/frontend/qt_sdl/RAMInfoDialog.cpp302
-rw-r--r--src/frontend/qt_sdl/RAMInfoDialog.h161
-rw-r--r--src/frontend/qt_sdl/RAMInfoDialog.ui237
-rw-r--r--src/frontend/qt_sdl/main.cpp11
-rw-r--r--src/frontend/qt_sdl/main.h2
6 files changed, 714 insertions, 0 deletions
diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt
index 4b5cb12..8b29bae 100644
--- a/src/frontend/qt_sdl/CMakeLists.txt
+++ b/src/frontend/qt_sdl/CMakeLists.txt
@@ -16,6 +16,7 @@ SET(SOURCES_QT_SDL
WifiSettingsDialog.cpp
InterfaceSettingsDialog.cpp
ROMInfoDialog.cpp
+ RAMInfoDialog.cpp
TitleManagerDialog.cpp
Input.cpp
LAN_PCap.cpp
diff --git a/src/frontend/qt_sdl/RAMInfoDialog.cpp b/src/frontend/qt_sdl/RAMInfoDialog.cpp
new file mode 100644
index 0000000..b13ff02
--- /dev/null
+++ b/src/frontend/qt_sdl/RAMInfoDialog.cpp
@@ -0,0 +1,302 @@
+/*
+ Copyright 2016-2021 Arisotura
+
+ This file is part of melonDS.
+
+ melonDS is free software: you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation, either version 3 of the License, or (at your option)
+ any later version.
+
+ melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with melonDS. If not, see http://www.gnu.org/licenses/.
+*/
+
+#include "RAMInfoDialog.h"
+#include "ui_RAMInfoDialog.h"
+
+#include "main.h"
+
+extern EmuThread* emuThread;
+
+s32 GetMainRAMValue(const u32& addr, const ramInfo_ByteType& byteType)
+{
+ switch (byteType)
+ {
+ case ramInfo_OneByte:
+ return *(s8*)(NDS::MainRAM + (addr&NDS::MainRAMMask));
+ case ramInfo_TwoBytes:
+ return *(s16*)(NDS::MainRAM + (addr&NDS::MainRAMMask));
+ case ramInfo_FourBytes:
+ return *(s32*)(NDS::MainRAM + (addr&NDS::MainRAMMask));
+ default:
+ return 0;
+ }
+}
+
+RAMInfoDialog* RAMInfoDialog::currentDlg = nullptr;
+
+RAMInfoDialog::RAMInfoDialog(QWidget* parent) : QDialog(parent), ui(new Ui::RAMInfoDialog)
+{
+ ui->setupUi(this);
+ setAttribute(Qt::WA_DeleteOnClose);
+
+ qRegisterMetaType<QVector<int>>("QVector<int>");
+ qRegisterMetaType<u32>("u32");
+ qRegisterMetaType<s32>("s32");
+ qRegisterMetaType<s16>("s16");
+ qRegisterMetaType<s8>("s8");
+
+ SearchThread = new RAMSearchThread(this);
+ connect(SearchThread, &RAMSearchThread::SetProgressbarValue, this, &RAMInfoDialog::SetProgressbarValue);
+ connect(SearchThread, &RAMSearchThread::finished, this, &RAMInfoDialog::OnSearchFinished);
+ // First search (Show everything in main ram)
+ SearchThread->Start(ramInfoSTh_SearchAll);
+
+ TableUpdater = new QTimer(this);
+ TableUpdater->setInterval(100);
+ connect(TableUpdater, &QTimer::timeout, this, &RAMInfoDialog::ShowRowsInTable);
+ TableUpdater->start();
+}
+
+RAMInfoDialog::~RAMInfoDialog()
+{
+ delete SearchThread;
+ if (TableUpdater->isActive())
+ TableUpdater->stop();
+ delete TableUpdater;
+ delete ui;
+}
+
+void RAMInfoDialog::OnSearchFinished()
+{
+ SearchThread->wait();
+ ui->btnSearch->setEnabled(true);
+ ui->ramTable->clearContents();
+ ui->ramTable->setRowCount(SearchThread->GetResults()->size());
+ ui->ramTable->verticalScrollBar()->setSliderPosition(0);
+ ui->txtFound->setText(QString("Found: %1").arg(SearchThread->GetResults()->size()));
+}
+
+void RAMInfoDialog::ShowRowsInTable()
+{
+ const u32& scrollValue = ui->ramTable->verticalScrollBar()->sliderPosition();
+ std::vector<ramInfo_RowData>* RowDataVector = SearchThread->GetResults();
+
+ for (u32 row = scrollValue; row < std::min<u32>(scrollValue+25, RowDataVector->size()); row++)
+ {
+ ramInfo_RowData& rowData = RowDataVector->at(row);
+ rowData.Update(SearchThread->GetSearchByteType());
+
+ if (ui->ramTable->item(row, ramInfo_Address) == nullptr)
+ {
+ // A new row
+ QTableWidgetItem* addressItem = new QTableWidgetItem(QString("%1").arg(rowData.Address, 8, 16));
+ QTableWidgetItem* valueItem = new QTableWidgetItem(QString("%1").arg(rowData.Value));
+ QTableWidgetItem* previousItem = new QTableWidgetItem(QString("%1").arg(rowData.Previous));
+
+ addressItem->setFlags(addressItem->flags() & ~Qt::ItemIsEditable);
+ valueItem->setFlags(valueItem->flags() | Qt::ItemIsEditable);
+ previousItem->setFlags(previousItem->flags() & ~Qt::ItemIsEditable);
+
+ ui->ramTable->setItem(row, ramInfo_Address, addressItem);
+ ui->ramTable->setItem(row, ramInfo_Value, valueItem);
+ ui->ramTable->setItem(row, ramInfo_Previous, previousItem);
+ }
+ else
+ {
+ // A row that exists
+ ui->ramTable->item(row, ramInfo_Address)->setText(QString("%1").arg(rowData.Address, 8, 16));
+ ui->ramTable->item(row, ramInfo_Value)->setText(QString("%1").arg(rowData.Value));
+ ui->ramTable->item(row, ramInfo_Previous)->setText(QString("%1").arg(rowData.Previous));
+ if (rowData.Value != rowData.Previous)
+ ui->ramTable->item(row, ramInfo_Previous)->setForeground(Qt::red);
+ }
+ }
+}
+
+void RAMInfoDialog::ClearTableContents()
+{
+ ui->ramTable->clearContents();
+ ui->ramTable->setRowCount(0);
+}
+
+void RAMInfoDialog::SetProgressbarValue(const u32& value)
+{
+ ui->progressBar->setValue(value);
+}
+
+void RAMInfoDialog::done(int r)
+{
+ QDialog::done(r);
+ closeDlg();
+}
+
+void RAMInfoDialog::on_btnSearch_clicked()
+{
+ ui->btnSearch->setEnabled(false);
+ ui->radiobtn1byte->setEnabled(false);
+ ui->radiobtn2bytes->setEnabled(false);
+ ui->radiobtn4bytes->setEnabled(false);
+
+ if (ui->txtSearch->text().isEmpty())
+ SearchThread->Start(ramInfoSTh_SearchAll);
+ else
+ SearchThread->Start(ui->txtSearch->text().toInt());
+
+ if (!TableUpdater->isActive())
+ TableUpdater->start();
+}
+
+void RAMInfoDialog::on_btnClear_clicked()
+{
+ SearchThread->Stop();
+ TableUpdater->stop();
+
+ ui->radiobtn1byte->setEnabled(true);
+ ui->radiobtn2bytes->setEnabled(true);
+ ui->radiobtn4bytes->setEnabled(true);
+
+ OnSearchFinished();
+}
+
+void RAMInfoDialog::on_radiobtn1byte_clicked()
+{
+ SearchThread->SetSearchByteType(ramInfo_OneByte);
+}
+
+void RAMInfoDialog::on_radiobtn2bytes_clicked()
+{
+ SearchThread->SetSearchByteType(ramInfo_TwoBytes);
+}
+
+void RAMInfoDialog::on_radiobtn4bytes_clicked()
+{
+ SearchThread->SetSearchByteType(ramInfo_FourBytes);
+}
+
+void RAMInfoDialog::on_ramTable_itemChanged(QTableWidgetItem *item)
+{
+ ramInfo_RowData& rowData = SearchThread->GetResults()->at(item->row());
+ s32 itemValue = item->text().toInt();
+
+ if (rowData.Value != itemValue)
+ rowData.SetValue(itemValue);
+}
+
+/**
+ * RAMSearchThread
+ */
+
+RAMSearchThread::RAMSearchThread(RAMInfoDialog* dialog) : Dialog(dialog)
+{
+ RowDataVector = new std::vector<ramInfo_RowData>();
+}
+
+RAMSearchThread::~RAMSearchThread()
+{
+ Stop();
+ if (RowDataVector)
+ {
+ delete RowDataVector;
+ RowDataVector = nullptr;
+ }
+}
+
+void RAMSearchThread::Start(const s32& searchValue, const ramInfoSTh_SearchMode& searchMode)
+{
+ SearchValue = searchValue;
+ SearchMode = searchMode;
+ start();
+}
+
+void RAMSearchThread::Start(const ramInfoSTh_SearchMode& searchMode)
+{
+ SearchMode = searchMode;
+ start();
+}
+
+void RAMSearchThread::Stop()
+{
+ SearchRunning = false;
+ RowDataVector->clear();
+ quit();
+ wait();
+}
+
+void RAMSearchThread::run()
+{
+ SearchRunning = true;
+ u32 progress = 0;
+
+ // Pause game running
+ emuThread->emuPause();
+
+ // For following search modes below, RowDataVector must be filled.
+ if (SearchMode == ramInfoSTh_SearchAll || RowDataVector->size() == 0)
+ {
+ // First search mode
+ for (u32 addr = 0x02000000; SearchRunning && addr < 0x02000000+NDS::MainRAMMaxSize; addr += SearchByteType)
+ {
+ const s32& value = GetMainRAMValue(addr, SearchByteType);
+
+ RowDataVector->push_back({ addr, value, value });
+
+ // A solution to prevent to call too many slot.
+ u32 newProgress = (int)((addr-0x02000000) / (NDS::MainRAMMaxSize-1.0f) * 100);
+ if (progress < newProgress)
+ {
+ progress = newProgress;
+ emit SetProgressbarValue(progress);
+ }
+ }
+ }
+
+ if (SearchMode == ramInfoSTh_Default)
+ {
+ // Next search mode
+ std::vector<ramInfo_RowData>* newRowDataVector = new std::vector<ramInfo_RowData>();
+ for (u32 row = 0; SearchRunning && row < RowDataVector->size(); row++)
+ {
+ const u32& addr = RowDataVector->at(row).Address;
+ const s32& value = GetMainRAMValue(addr, SearchByteType);
+
+ if (SearchValue == value)
+ newRowDataVector->push_back({ addr, value, value });
+
+ // A solution to prevent to call too many slot.
+ u32 newProgress = (int)(row / (RowDataVector->size()-1.0f) * 100);
+ if (progress < newProgress)
+ {
+ progress = newProgress;
+ emit SetProgressbarValue(progress);
+ }
+ }
+ delete RowDataVector;
+ RowDataVector = newRowDataVector;
+ }
+
+ // Unpause game running
+ emuThread->emuUnpause();
+
+ SearchRunning = false;
+}
+
+void RAMSearchThread::SetSearchByteType(const ramInfo_ByteType& bytetype)
+{
+ SearchByteType = bytetype;
+}
+
+ramInfo_ByteType RAMSearchThread::GetSearchByteType() const
+{
+ return SearchByteType;
+}
+
+std::vector<ramInfo_RowData>* RAMSearchThread::GetResults()
+{
+ return RowDataVector;
+}
diff --git a/src/frontend/qt_sdl/RAMInfoDialog.h b/src/frontend/qt_sdl/RAMInfoDialog.h
new file mode 100644
index 0000000..f44ae93
--- /dev/null
+++ b/src/frontend/qt_sdl/RAMInfoDialog.h
@@ -0,0 +1,161 @@
+/*
+ Copyright 2016-2021 Arisotura
+
+ This file is part of melonDS.
+
+ melonDS is free software: you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation, either version 3 of the License, or (at your option)
+ any later version.
+
+ melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with melonDS. If not, see http://www.gnu.org/licenses/.
+*/
+
+#ifndef RAMINFODIALOG_H
+#define RAMINFODIALOG_H
+
+#include <QDialog>
+#include <QTableWidget>
+#include <QScrollBar>
+#include <QThread>
+#include <QTimer>
+
+#include "types.h"
+#include "NDS.h"
+
+namespace Ui { class RAMInfoDialog; }
+class RAMInfoDialog;
+class RAMSearchThread;
+class RAMUpdateThread;
+
+enum ramInfo_ByteType
+{
+ ramInfo_OneByte = 1,
+ ramInfo_TwoBytes = 2,
+ ramInfo_FourBytes = 4
+};
+
+enum ramInfoSTh_SearchMode
+{
+ ramInfoSTh_Default,
+ ramInfoSTh_SearchAll
+};
+
+enum
+{
+ ramInfo_Address,
+ ramInfo_Value,
+ ramInfo_Previous
+};
+
+s32 GetMainRAMValue(const u32& addr, const ramInfo_ByteType& byteType);
+
+struct ramInfo_RowData
+{
+ u32 Address;
+ s32 Value;
+ s32 Previous;
+
+ void Update(const ramInfo_ByteType& byteType)
+ {
+ Value = GetMainRAMValue(Address, byteType);
+ }
+
+ void SetValue(const s32& value)
+ {
+ NDS::MainRAM[Address&NDS::MainRAMMask] = (u32)value;
+ Value = value;
+ }
+};
+
+class RAMInfoDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit RAMInfoDialog(QWidget* parent);
+ ~RAMInfoDialog();
+
+ static RAMInfoDialog* currentDlg;
+ static RAMInfoDialog* openDlg(QWidget* parent)
+ {
+ if (currentDlg)
+ {
+ currentDlg->activateWindow();
+ return currentDlg;
+ }
+
+ currentDlg = new RAMInfoDialog(parent);
+ currentDlg->show();
+ return currentDlg;
+ }
+ static void closeDlg()
+ {
+ currentDlg = nullptr;
+ }
+
+ s32 SearchValue = 0;
+
+ void ClearTableContents();
+
+private slots:
+ void done(int r);
+
+ void on_btnSearch_clicked();
+ void on_btnClear_clicked();
+ void on_radiobtn1byte_clicked();
+ void on_radiobtn2bytes_clicked();
+ void on_radiobtn4bytes_clicked();
+ void on_ramTable_itemChanged(QTableWidgetItem *item);
+
+ void OnSearchFinished();
+ void ShowRowsInTable();
+ void SetProgressbarValue(const u32& value);
+
+private:
+ Ui::RAMInfoDialog* ui;
+
+ RAMSearchThread* SearchThread;
+ QTimer* TableUpdater;
+};
+
+class RAMSearchThread : public QThread
+{
+ Q_OBJECT
+
+public:
+ explicit RAMSearchThread(RAMInfoDialog* dialog);
+ ~RAMSearchThread() override;
+
+ void Start(const s32& searchValue, const ramInfoSTh_SearchMode& searchMode = ramInfoSTh_Default);
+ void Start(const ramInfoSTh_SearchMode& searchMode);
+
+ void SetSearchByteType(const ramInfo_ByteType& bytetype);
+ ramInfo_ByteType GetSearchByteType() const;
+ std::vector<ramInfo_RowData>* GetResults();
+
+ void Stop();
+
+private:
+ void run();
+
+ RAMInfoDialog* Dialog;
+ bool SearchRunning = false;
+
+ ramInfoSTh_SearchMode SearchMode;
+ s32 SearchValue;
+ ramInfo_ByteType SearchByteType = ramInfo_OneByte;
+ std::vector<ramInfo_RowData>* RowDataVector = nullptr;
+
+ void ClearTableContents();
+
+signals:
+ void SetProgressbarValue(const u32& value);
+};
+
+#endif // RAMINFODIALOG_H
diff --git a/src/frontend/qt_sdl/RAMInfoDialog.ui b/src/frontend/qt_sdl/RAMInfoDialog.ui
new file mode 100644
index 0000000..46beaa5
--- /dev/null
+++ b/src/frontend/qt_sdl/RAMInfoDialog.ui
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>RAMInfoDialog</class>
+ <widget class="QDialog" name="RAMInfoDialog">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>550</width>
+ <height>411</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>550</width>
+ <height>411</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>550</width>
+ <height>411</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>RAM info - melonDS</string>
+ </property>
+ <property name="modal">
+ <bool>false</bool>
+ </property>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="geometry">
+ <rect>
+ <x>340</x>
+ <y>10</y>
+ <width>201</width>
+ <height>111</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Search</string>
+ </property>
+ <widget class="QPushButton" name="btnSearch">
+ <property name="geometry">
+ <rect>
+ <x>130</x>
+ <y>20</y>
+ <width>61</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Search</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" name="txtSearch">
+ <property name="geometry">
+ <rect>
+ <x>50</x>
+ <y>20</y>
+ <width>71</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="maxLength">
+ <number>5</number>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="btnClear">
+ <property name="geometry">
+ <rect>
+ <x>120</x>
+ <y>80</y>
+ <width>71</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Clear</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="labelValue">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>20</y>
+ <width>41</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Value:</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="radiobtn1byte">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>50</y>
+ <width>90</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>1byte</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="radiobtn2bytes">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>70</y>
+ <width>90</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>2bytes</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="radiobtn4bytes">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>90</y>
+ <width>90</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>4bytes</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QProgressBar" name="progressBar">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>380</y>
+ <width>321</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="textVisible">
+ <bool>true</bool>
+ </property>
+ <property name="format">
+ <string>%p%</string>
+ </property>
+ </widget>
+ <widget class="QTableWidget" name="ramTable">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>321</width>
+ <height>341</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>321</width>
+ <height>341</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>321</width>
+ <height>341</height>
+ </size>
+ </property>
+ <property name="editTriggers">
+ <set>QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked</set>
+ </property>
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="verticalHeaderMinimumSectionSize">
+ <number>16</number>
+ </attribute>
+ <attribute name="verticalHeaderDefaultSectionSize">
+ <number>16</number>
+ </attribute>
+ <column>
+ <property name="text">
+ <string>Address</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Value</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Previous</string>
+ </property>
+ </column>
+ </widget>
+ <widget class="QLabel" name="txtFound">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>101</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Found:</string>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp
index 535bfee..7454ffc 100644
--- a/src/frontend/qt_sdl/main.cpp
+++ b/src/frontend/qt_sdl/main.cpp
@@ -60,6 +60,7 @@
#include "WifiSettingsDialog.h"
#include "InterfaceSettingsDialog.h"
#include "ROMInfoDialog.h"
+#include "RAMInfoDialog.h"
#include "TitleManagerDialog.h"
#include "types.h"
@@ -1440,6 +1441,9 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
actROMInfo = menu->addAction("ROM info");
connect(actROMInfo, &QAction::triggered, this, &MainWindow::onROMInfo);
+ actRAMInfo = menu->addAction("RAM info");
+ connect(actRAMInfo, &QAction::triggered, this, &MainWindow::onRAMInfo);
+
actTitleManager = menu->addAction("Manage DSi titles");
connect(actTitleManager, &QAction::triggered, this, &MainWindow::onOpenTitleManager);
}
@@ -1671,6 +1675,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
actEnableCheats->setChecked(Config::EnableCheats);
actROMInfo->setEnabled(false);
+ actRAMInfo->setEnabled(false);
actSavestateSRAMReloc->setChecked(Config::SavestateRelocSRAM);
@@ -2082,6 +2087,7 @@ void MainWindow::updateCartInserted(bool gba)
actImportSavefile->setEnabled(inserted);
actSetupCheats->setEnabled(inserted);
actROMInfo->setEnabled(inserted);
+ actRAMInfo->setEnabled(inserted);
}
}
@@ -2557,6 +2563,11 @@ void MainWindow::onROMInfo()
ROMInfoDialog* dlg = ROMInfoDialog::openDlg(this);
}
+void MainWindow::onRAMInfo()
+{
+ RAMInfoDialog* dlg = RAMInfoDialog::openDlg(this);
+}
+
void MainWindow::onOpenTitleManager()
{
TitleManagerDialog* dlg = TitleManagerDialog::openDlg(this);
diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h
index d4e40d7..6929d69 100644
--- a/src/frontend/qt_sdl/main.h
+++ b/src/frontend/qt_sdl/main.h
@@ -252,6 +252,7 @@ private slots:
void onSetupCheats();
void onCheatsDialogFinished(int res);
void onROMInfo();
+ void onRAMInfo();
void onOpenTitleManager();
void onOpenEmuSettings();
@@ -341,6 +342,7 @@ public:
QAction* actEnableCheats;
QAction* actSetupCheats;
QAction* actROMInfo;
+ QAction* actRAMInfo;
QAction* actTitleManager;
QAction* actEmuSettings;