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>
This commit is contained in:
parent
38c8b886ea
commit
c66df57256
|
@ -16,6 +16,7 @@ SET(SOURCES_QT_SDL
|
|||
WifiSettingsDialog.cpp
|
||||
InterfaceSettingsDialog.cpp
|
||||
ROMInfoDialog.cpp
|
||||
RAMInfoDialog.cpp
|
||||
TitleManagerDialog.cpp
|
||||
Input.cpp
|
||||
LAN_PCap.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;
|
||||
}
|
|
@ -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
|
|
@ -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>
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue