aboutsummaryrefslogtreecommitdiff
path: root/src/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend')
-rw-r--r--src/frontend/FrontendUtil.h9
-rw-r--r--src/frontend/Util_ROM.cpp71
-rw-r--r--src/frontend/qt_sdl/CMakeLists.txt1
-rw-r--r--src/frontend/qt_sdl/CheatsDialog.cpp412
-rw-r--r--src/frontend/qt_sdl/CheatsDialog.h94
-rw-r--r--src/frontend/qt_sdl/CheatsDialog.ui144
-rw-r--r--src/frontend/qt_sdl/EmuSettingsDialog.cpp42
-rw-r--r--src/frontend/qt_sdl/EmuSettingsDialog.h4
-rw-r--r--src/frontend/qt_sdl/EmuSettingsDialog.ui491
-rw-r--r--src/frontend/qt_sdl/Input.cpp8
-rw-r--r--src/frontend/qt_sdl/InputConfigDialog.cpp10
-rw-r--r--src/frontend/qt_sdl/InputConfigDialog.h2
-rw-r--r--src/frontend/qt_sdl/Platform.cpp19
-rw-r--r--src/frontend/qt_sdl/PlatformConfig.cpp14
-rw-r--r--src/frontend/qt_sdl/PlatformConfig.h5
-rw-r--r--src/frontend/qt_sdl/VideoSettingsDialog.cpp19
-rw-r--r--src/frontend/qt_sdl/VideoSettingsDialog.h2
-rw-r--r--src/frontend/qt_sdl/VideoSettingsDialog.ui12
-rw-r--r--src/frontend/qt_sdl/WifiSettingsDialog.cpp59
-rw-r--r--src/frontend/qt_sdl/WifiSettingsDialog.h7
-rw-r--r--src/frontend/qt_sdl/WifiSettingsDialog.ui12
-rw-r--r--src/frontend/qt_sdl/main.cpp151
-rw-r--r--src/frontend/qt_sdl/main.h11
23 files changed, 1331 insertions, 268 deletions
diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h
index 099583f..caac9f0 100644
--- a/src/frontend/FrontendUtil.h
+++ b/src/frontend/FrontendUtil.h
@@ -67,6 +67,9 @@ extern bool SavestateLoaded;
// initialize the ROM handling utility
void Init_ROM();
+// deinitialize the ROM handling utility
+void DeInit_ROM();
+
// load the BIOS/firmware and boot from it
int LoadBIOS();
@@ -97,6 +100,12 @@ bool SaveState(const char* filename);
// undo the latest savestate load
void UndoStateLoad();
+// imports savedata from an external file. Returns the difference between the filesize and the SRAM size
+int ImportSRAM(const char* filename);
+
+// enable or disable cheats
+void EnableCheats(bool enable);
+
// setup the display layout based on the provided display size and parameters
// * screenWidth/screenHeight: size of the host display
diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp
index 8116a93..f61c3e3 100644
--- a/src/frontend/Util_ROM.cpp
+++ b/src/frontend/Util_ROM.cpp
@@ -27,6 +27,8 @@
#include "NDS.h"
#include "GBACart.h"
+#include "AREngine.h"
+
namespace Frontend
{
@@ -37,6 +39,9 @@ char PrevSRAMPath[ROMSlot_MAX][1024]; // for savestate 'undo load'
bool SavestateLoaded;
+ARCodeFile* CheatFile;
+bool CheatsOn;
+
void Init_ROM()
{
@@ -48,6 +53,18 @@ void Init_ROM()
memset(SRAMPath[ROMSlot_GBA], 0, 1024);
memset(PrevSRAMPath[ROMSlot_NDS], 0, 1024);
memset(PrevSRAMPath[ROMSlot_GBA], 0, 1024);
+
+ CheatFile = nullptr;
+ CheatsOn = false;
+}
+
+void DeInit_ROM()
+{
+ if (CheatFile)
+ {
+ delete CheatFile;
+ CheatFile = nullptr;
+ }
}
// TODO: currently, when failing to load a ROM for whatever reason, we attempt
@@ -198,6 +215,32 @@ int VerifyDSiNAND()
return Load_OK;
}
+void LoadCheats()
+{
+ if (CheatFile)
+ {
+ delete CheatFile;
+ CheatFile = nullptr;
+ }
+
+ char filename[1024];
+ if (ROMPath[ROMSlot_NDS][0] != '\0')
+ {
+ strncpy(filename, ROMPath[ROMSlot_NDS], 1023);
+ filename[1023] = '\0';
+ strncpy(filename + strlen(ROMPath[ROMSlot_NDS]) - 3, "mch", 3);
+ }
+ else
+ {
+ strncpy(filename, "firmware.mch", 1023);
+ }
+
+ // TODO: check for error (malformed cheat file, ...)
+ CheatFile = new ARCodeFile(filename);
+
+ AREngine::SetCodeFile(CheatsOn ? CheatFile : nullptr);
+}
+
int LoadBIOS()
{
int res;
@@ -235,6 +278,8 @@ int LoadBIOS()
SavestateLoaded = false;
+ LoadCheats();
+
return Load_OK;
}
@@ -295,6 +340,8 @@ int LoadROM(const char* file, int slot)
{
SavestateLoaded = false;
+ LoadCheats();
+
// Reload the inserted GBA cartridge (if any)
// TODO: report failure there??
if (ROMPath[ROMSlot_GBA][0] != '\0') NDS::LoadGBAROM(ROMPath[ROMSlot_GBA], SRAMPath[ROMSlot_GBA]);
@@ -387,6 +434,8 @@ int Reset()
return Load_ROMLoadError;
}
+ LoadCheats();
+
return Load_OK;
}
@@ -539,4 +588,26 @@ void UndoStateLoad()
}
}
+int ImportSRAM(const char* filename)
+{
+ FILE* file = fopen(filename, "rb");
+ fseek(file, 0, SEEK_END);
+ u32 size = ftell(file);
+ u8* importData = new u8[size];
+ rewind(file);
+ fread(importData, size, 1, file);
+ fclose(file);
+
+ int diff = NDS::ImportSRAM(importData, size);
+ delete[] importData;
+ return diff;
+}
+
+void EnableCheats(bool enable)
+{
+ CheatsOn = enable;
+ if (CheatFile)
+ AREngine::SetCodeFile(CheatsOn ? CheatFile : nullptr);
+}
+
}
diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt
index 55b8125..f12a9ed 100644
--- a/src/frontend/qt_sdl/CMakeLists.txt
+++ b/src/frontend/qt_sdl/CMakeLists.txt
@@ -3,6 +3,7 @@ project(qt_sdl)
SET(SOURCES_QT_SDL
main.cpp
main_shaders.h
+ CheatsDialog.cpp
EmuSettingsDialog.cpp
InputConfigDialog.cpp
VideoSettingsDialog.cpp
diff --git a/src/frontend/qt_sdl/CheatsDialog.cpp b/src/frontend/qt_sdl/CheatsDialog.cpp
new file mode 100644
index 0000000..05fedc5
--- /dev/null
+++ b/src/frontend/qt_sdl/CheatsDialog.cpp
@@ -0,0 +1,412 @@
+/*
+ Copyright 2016-2020 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 <stdio.h>
+#include <QFileDialog>
+#include <QMessageBox>
+
+#include "types.h"
+#include "Platform.h"
+#include "Config.h"
+#include "PlatformConfig.h"
+
+#include "CheatsDialog.h"
+#include "ui_CheatsDialog.h"
+
+
+CheatsDialog* CheatsDialog::currentDlg = nullptr;
+
+extern char* EmuDirectory;
+
+namespace Frontend { extern ARCodeFile* CheatFile; }
+
+
+CheatsDialog::CheatsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::CheatsDialog)
+{
+ ui->setupUi(this);
+ setAttribute(Qt::WA_DeleteOnClose);
+
+ codeFile = Frontend::CheatFile;
+
+ QStandardItemModel* model = new QStandardItemModel();
+ ui->tvCodeList->setModel(model);
+ connect(model, &QStandardItemModel::itemChanged, this, &CheatsDialog::onCheatEntryModified);
+ connect(ui->tvCodeList->selectionModel(), &QItemSelectionModel::selectionChanged, this, &CheatsDialog::onCheatSelectionChanged);
+
+ {
+ QStandardItem* root = model->invisibleRootItem();
+
+ for (ARCodeCatList::iterator i = codeFile->Categories.begin(); i != codeFile->Categories.end(); i++)
+ {
+ ARCodeCat& cat = *i;
+
+ QStandardItem* catitem = new QStandardItem(cat.Name);
+ catitem->setEditable(true);
+ catitem->setData(QVariant::fromValue(i));
+ root->appendRow(catitem);
+
+ for (ARCodeList::iterator j = cat.Codes.begin(); j != cat.Codes.end(); j++)
+ {
+ ARCode& code = *j;
+
+ QStandardItem* codeitem = new QStandardItem(code.Name);
+ codeitem->setEditable(true);
+ codeitem->setCheckable(true);
+ codeitem->setCheckState(code.Enabled ? Qt::Checked : Qt::Unchecked);
+ codeitem->setData(QVariant::fromValue(j));
+ catitem->appendRow(codeitem);
+ }
+ }
+ }
+
+ ui->txtCode->setPlaceholderText("");
+ codeChecker = new ARCodeChecker(ui->txtCode->document());
+
+ ui->btnNewARCode->setEnabled(false);
+ ui->btnDeleteCode->setEnabled(false);
+ ui->txtCode->setEnabled(false);
+}
+
+CheatsDialog::~CheatsDialog()
+{
+ QAbstractItemModel* model = ui->tvCodeList->model();
+ ui->tvCodeList->setModel(nullptr);
+ delete model;
+
+ delete codeChecker;
+
+ delete ui;
+}
+
+void CheatsDialog::on_CheatsDialog_accepted()
+{
+ codeFile->Save();
+
+ closeDlg();
+}
+
+void CheatsDialog::on_CheatsDialog_rejected()
+{
+ codeFile->Load();
+
+ closeDlg();
+}
+
+void CheatsDialog::on_btnNewCat_clicked()
+{
+ QStandardItem* root = ((QStandardItemModel*)ui->tvCodeList->model())->invisibleRootItem();
+
+ ARCodeCat cat;
+ cat.Codes.clear();
+ memset(cat.Name, 0, 128);
+ strncpy(cat.Name, "(new category)", 127);
+
+ codeFile->Categories.push_back(cat);
+ ARCodeCatList::iterator id = codeFile->Categories.end(); id--;
+
+ QStandardItem* catitem = new QStandardItem(cat.Name);
+ catitem->setEditable(true);
+ catitem->setData(QVariant::fromValue(id));
+ root->appendRow(catitem);
+
+ ui->tvCodeList->selectionModel()->select(catitem->index(), QItemSelectionModel::ClearAndSelect);
+ ui->tvCodeList->edit(catitem->index());
+}
+
+void CheatsDialog::on_btnNewARCode_clicked()
+{
+ QModelIndexList indices = ui->tvCodeList->selectionModel()->selectedIndexes();
+ if (indices.isEmpty())
+ {
+ // ????
+ return;
+ }
+
+ QStandardItemModel* model = (QStandardItemModel*)ui->tvCodeList->model();
+ QStandardItem* item = model->itemFromIndex(indices.first());
+ QStandardItem* parentitem;
+
+ QVariant data = item->data();
+ if (data.canConvert<ARCodeCatList::iterator>())
+ {
+ parentitem = item;
+ }
+ else if (data.canConvert<ARCodeList::iterator>())
+ {
+ parentitem = item->parent();
+ }
+ else
+ {
+ printf("what?? :(\n");
+ return;
+ }
+
+ ARCodeCatList::iterator it_cat = parentitem->data().value<ARCodeCatList::iterator>();
+ ARCodeCat& cat = *it_cat;
+
+ ARCode code;
+ memset(code.Name, 0, 128);
+ strncpy(code.Name, "(new AR code)", 127);
+ code.Enabled = true;
+ code.CodeLen = 0;
+ memset(code.Code, 0, sizeof(code.Code));
+
+ cat.Codes.push_back(code);
+ ARCodeList::iterator id = cat.Codes.end(); id--;
+
+ QStandardItem* codeitem = new QStandardItem(code.Name);
+ codeitem->setEditable(true);
+ codeitem->setCheckable(true);
+ codeitem->setCheckState(code.Enabled ? Qt::Checked : Qt::Unchecked);
+ codeitem->setData(QVariant::fromValue(id));
+ parentitem->appendRow(codeitem);
+
+ ui->tvCodeList->selectionModel()->select(codeitem->index(), QItemSelectionModel::ClearAndSelect);
+ ui->tvCodeList->edit(codeitem->index());
+}
+
+void CheatsDialog::on_btnDeleteCode_clicked()
+{
+ QModelIndexList indices = ui->tvCodeList->selectionModel()->selectedIndexes();
+ if (indices.isEmpty())
+ {
+ // ????
+ return;
+ }
+
+ QMessageBox::StandardButton res = QMessageBox::question(this,
+ "Confirm deletion",
+ "Really delete the selected item?",
+ QMessageBox::Yes|QMessageBox::No,
+ QMessageBox::No);
+ if (res != QMessageBox::Yes) return;
+
+ QStandardItemModel* model = (QStandardItemModel*)ui->tvCodeList->model();
+ QStandardItem* item = model->itemFromIndex(indices.first());
+
+ QVariant data = item->data();
+ if (data.canConvert<ARCodeCatList::iterator>())
+ {
+ ARCodeCatList::iterator it_cat = data.value<ARCodeCatList::iterator>();
+
+ (*it_cat).Codes.clear();
+ codeFile->Categories.erase(it_cat);
+
+ model->invisibleRootItem()->removeRow(item->row());
+ }
+ else if (data.canConvert<ARCodeList::iterator>())
+ {
+ ARCodeList::iterator it_code = data.value<ARCodeList::iterator>();
+ ARCodeCatList::iterator it_cat = item->parent()->data().value<ARCodeCatList::iterator>();
+
+ (*it_cat).Codes.erase(it_code);
+
+ item->parent()->removeRow(item->row());
+ }
+}
+
+void CheatsDialog::onCheatSelectionChanged(const QItemSelection& sel, const QItemSelection& desel)
+{
+ QModelIndexList indices = sel.indexes();
+ if (indices.isEmpty())
+ {
+ ui->btnNewARCode->setEnabled(false);
+ ui->btnDeleteCode->setEnabled(false);
+ ui->txtCode->setEnabled(false);
+ ui->txtCode->setPlaceholderText("");
+ ui->txtCode->clear();
+ }
+ else
+ {
+ QStandardItem* item = ((QStandardItemModel*)ui->tvCodeList->model())->itemFromIndex(indices.first());
+
+ QVariant data = item->data();
+ if (data.canConvert<ARCodeCatList::iterator>())
+ {
+ ui->btnDeleteCode->setEnabled(true);
+ ui->txtCode->setEnabled(false);
+ ui->txtCode->setPlaceholderText("");
+ ui->txtCode->clear();
+ }
+ else if (data.canConvert<ARCodeList::iterator>())
+ {
+ ARCode& code = *(data.value<ARCodeList::iterator>());
+
+ ui->btnDeleteCode->setEnabled(true);
+ ui->txtCode->setEnabled(true);
+ ui->txtCode->setPlaceholderText("(enter AR code here)");
+
+ QString codestr = "";
+ for (u32 i = 0; i < code.CodeLen; i += 2)
+ {
+ u32 c0 = code.Code[i+0];
+ u32 c1 = code.Code[i+1];
+ //codestr += QString("%1 %2\n").arg(c0, 8, 16, '0').arg(c1, 8, 16, '0').toUpper();
+ codestr += QString::asprintf("%08X %08X\n", c0, c1);
+ }
+ ui->txtCode->setPlainText(codestr);
+ }
+
+ ui->btnNewARCode->setEnabled(true);
+ }
+}
+
+void CheatsDialog::onCheatEntryModified(QStandardItem* item)
+{
+ QVariant data = item->data();
+ if (data.canConvert<ARCodeCatList::iterator>())
+ {
+ ARCodeCat& cat = *(data.value<ARCodeCatList::iterator>());
+
+ if (item->text().isEmpty())
+ {
+ QString oldname = QString(cat.Name);
+ item->setText(oldname.isEmpty() ? "(blank category name??)" : oldname);
+ }
+ else
+ {
+ strncpy(cat.Name, item->text().toStdString().c_str(), 127);
+ cat.Name[127] = '\0';
+ }
+ }
+ else if (data.canConvert<ARCodeList::iterator>())
+ {
+ ARCode& code = *(data.value<ARCodeList::iterator>());
+
+ if (item->text().isEmpty())
+ {
+ QString oldname = QString(code.Name);
+ item->setText(oldname.isEmpty() ? "(blank code name??)" : oldname);
+ }
+ else
+ {
+ strncpy(code.Name, item->text().toStdString().c_str(), 127);
+ code.Name[127] = '\0';
+ }
+
+ code.Enabled = (item->checkState() == Qt::Checked);
+ }
+}
+
+void CheatsDialog::on_txtCode_textChanged()
+{
+ QModelIndexList indices = ui->tvCodeList->selectionModel()->selectedIndexes();
+ if (indices.isEmpty())
+ return;
+
+ QStandardItem* item = ((QStandardItemModel*)ui->tvCodeList->model())->itemFromIndex(indices.first());
+ QVariant data = item->data();
+ if (!data.canConvert<ARCodeList::iterator>())
+ return;
+
+ bool error = false;
+ u32 codeout[2*64];
+ u32 codelen = 0;
+
+ QString text = ui->txtCode->document()->toPlainText();
+ QStringList lines = text.split('\n', QString::SkipEmptyParts);
+ for (QStringList::iterator it = lines.begin(); it != lines.end(); it++)
+ {
+ QString line = *it;
+ line = line.trimmed();
+ if (line.isEmpty()) continue;
+
+ if (line.length() > 17)
+ {
+ error = true;
+ break;
+ }
+
+ QStringList numbers = line.split(' ');
+ if (numbers.length() != 2)
+ {
+ error = true;
+ break;
+ }
+
+ QStringList::iterator jt = numbers.begin();
+ QString s0 = *jt++;
+ QString s1 = *jt++;
+
+ bool c0good, c1good;
+ u32 c0, c1;
+
+ c0 = s0.toUInt(&c0good, 16);
+ c1 = s1.toUInt(&c1good, 16);
+
+ if (!c0good || !c1good)
+ {
+ error = true;
+ break;
+ }
+
+ if (codelen >= 2*64)
+ {
+ error = true;
+ break;
+ }
+
+ codeout[codelen++] = c0;
+ codeout[codelen++] = c1;
+ }
+
+ ui->btnNewCat->setEnabled(!error);
+ ui->btnNewARCode->setEnabled(!error);
+ ui->btnDeleteCode->setEnabled(!error);
+ ui->tvCodeList->setEnabled(!error);
+ ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!error);
+
+ if (error) return;
+
+ ARCode& code = *(data.value<ARCodeList::iterator>());
+ memcpy(code.Code, codeout, codelen*sizeof(u32));
+ code.CodeLen = codelen;
+}
+
+void ARCodeChecker::highlightBlock(const QString& text)
+{
+ QTextCharFormat errformat; errformat.setForeground(Qt::red);
+
+ {
+ QRegularExpression expr("^\\s*[0-9A-Fa-f]{1,8} [0-9A-Fa-f]{1,8}\\s*$");
+ QRegularExpressionMatchIterator it = expr.globalMatch(text);
+ if (!it.hasNext())
+ {
+ setFormat(0, text.length(), errformat);
+ }
+ }
+
+ /*{
+ QRegularExpression expr("[^0-9A-Fa-f\\s]+");
+ QRegularExpressionMatchIterator it = expr.globalMatch(text);
+ while (it.hasNext())
+ {
+ QRegularExpressionMatch match = it.next();
+ setFormat(match.capturedStart(), match.capturedLength(), errformat);
+ }
+ }
+ {
+ QRegularExpression expr("[0-9A-Fa-f]{9,}");
+ QRegularExpressionMatchIterator it = expr.globalMatch(text);
+ while (it.hasNext())
+ {
+ QRegularExpressionMatch match = it.next();
+ setFormat(match.capturedStart(), match.capturedLength(), errformat);
+ }
+ }*/
+}
diff --git a/src/frontend/qt_sdl/CheatsDialog.h b/src/frontend/qt_sdl/CheatsDialog.h
new file mode 100644
index 0000000..20f2c65
--- /dev/null
+++ b/src/frontend/qt_sdl/CheatsDialog.h
@@ -0,0 +1,94 @@
+/*
+ Copyright 2016-2020 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 CHEATSDIALOG_H
+#define CHEATSDIALOG_H
+
+#include <QDialog>
+#include <QAbstractItemModel>
+#include <QStandardItemModel>
+#include <QItemSelection>
+#include <QSyntaxHighlighter>
+
+#include "ARCodeFile.h"
+
+Q_DECLARE_METATYPE(ARCodeList::iterator)
+Q_DECLARE_METATYPE(ARCodeCatList::iterator)
+
+namespace Ui { class CheatsDialog; }
+class CheatsDialog;
+
+class ARCodeChecker : public QSyntaxHighlighter
+{
+ Q_OBJECT
+
+public:
+ ARCodeChecker(QTextDocument* parent) : QSyntaxHighlighter(parent) {}
+ ~ARCodeChecker() {}
+
+protected:
+ void highlightBlock(const QString& text) override;
+};
+
+class CheatsDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit CheatsDialog(QWidget* parent);
+ ~CheatsDialog();
+
+ static CheatsDialog* currentDlg;
+ static CheatsDialog* openDlg(QWidget* parent)
+ {
+ if (currentDlg)
+ {
+ currentDlg->activateWindow();
+ return currentDlg;
+ }
+
+ currentDlg = new CheatsDialog(parent);
+ currentDlg->open();
+ return currentDlg;
+ }
+ static void closeDlg()
+ {
+ currentDlg = nullptr;
+ }
+
+private slots:
+ void on_CheatsDialog_accepted();
+ void on_CheatsDialog_rejected();
+
+ void on_btnNewCat_clicked();
+ void on_btnNewARCode_clicked();
+ void on_btnDeleteCode_clicked();
+
+ void onCheatSelectionChanged(const QItemSelection& sel, const QItemSelection& desel);
+ void onCheatEntryModified(QStandardItem* item);
+
+ void on_txtCode_textChanged();
+
+private:
+ Ui::CheatsDialog* ui;
+
+ ARCodeFile* codeFile;
+ ARCodeChecker* codeChecker;
+};
+
+#endif // CHEATSDIALOG_H
diff --git a/src/frontend/qt_sdl/CheatsDialog.ui b/src/frontend/qt_sdl/CheatsDialog.ui
new file mode 100644
index 0000000..d0bc586
--- /dev/null
+++ b/src/frontend/qt_sdl/CheatsDialog.ui
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CheatsDialog</class>
+ <widget class="QDialog" name="CheatsDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>609</width>
+ <height>417</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Cheat code editor - melonDS</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btnNewCat">
+ <property name="text">
+ <string>New category</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnNewARCode">
+ <property name="text">
+ <string>New AR code</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnDeleteCode">
+ <property name="text">
+ <string>Delete</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QTreeView" name="tvCodeList">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>2</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>200</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="headerHidden">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="txtCode">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>3</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>200</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>CheatsDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>304</x>
+ <y>396</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>304</x>
+ <y>208</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>CheatsDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>304</x>
+ <y>396</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>304</x>
+ <y>208</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.cpp b/src/frontend/qt_sdl/EmuSettingsDialog.cpp
index dc7eaf5..79ce5ed 100644
--- a/src/frontend/qt_sdl/EmuSettingsDialog.cpp
+++ b/src/frontend/qt_sdl/EmuSettingsDialog.cpp
@@ -44,11 +44,15 @@ EmuSettingsDialog::EmuSettingsDialog(QWidget* parent) : QDialog(parent), ui(new
ui->txtBIOS9Path->setText(Config::BIOS9Path);
ui->txtBIOS7Path->setText(Config::BIOS7Path);
ui->txtFirmwarePath->setText(Config::FirmwarePath);
+ ui->cbDLDIEnable->setChecked(Config::DLDIEnable != 0);
+ ui->txtDLDISDPath->setText(Config::DLDISDPath);
ui->txtDSiBIOS9Path->setText(Config::DSiBIOS9Path);
ui->txtDSiBIOS7Path->setText(Config::DSiBIOS7Path);
ui->txtDSiFirmwarePath->setText(Config::DSiFirmwarePath);
ui->txtDSiNANDPath->setText(Config::DSiNANDPath);
+ ui->cbDSiSDEnable->setChecked(Config::DSiSDEnable != 0);
+ ui->txtDSiSDPath->setText(Config::DSiSDPath);
ui->cbxConsoleType->addItem("DS");
ui->cbxConsoleType->addItem("DSi (experimental)");
@@ -141,10 +145,14 @@ void EmuSettingsDialog::done(int r)
std::string bios9Path = ui->txtBIOS9Path->text().toStdString();
std::string bios7Path = ui->txtBIOS7Path->text().toStdString();
std::string firmwarePath = ui->txtFirmwarePath->text().toStdString();
+ int dldiEnable = ui->cbDLDIEnable->isChecked() ? 1:0;
+ std::string dldiSDPath = ui->txtDLDISDPath->text().toStdString();
std::string dsiBios9Path = ui->txtDSiBIOS9Path->text().toStdString();
std::string dsiBios7Path = ui->txtDSiBIOS7Path->text().toStdString();
std::string dsiFirmwarePath = ui->txtDSiFirmwarePath->text().toStdString();
std::string dsiNANDPath = ui->txtDSiNANDPath->text().toStdString();
+ int dsiSDEnable = ui->cbDSiSDEnable->isChecked() ? 1:0;
+ std::string dsiSDPath = ui->txtDSiSDPath->text().toStdString();
if (consoleType != Config::ConsoleType
|| directBoot != Config::DirectBoot
@@ -158,10 +166,14 @@ void EmuSettingsDialog::done(int r)
|| strcmp(Config::BIOS9Path, bios9Path.c_str()) != 0
|| strcmp(Config::BIOS7Path, bios7Path.c_str()) != 0
|| strcmp(Config::FirmwarePath, firmwarePath.c_str()) != 0
+ || dldiEnable != Config::DLDIEnable
+ || strcmp(Config::DLDISDPath, dldiSDPath.c_str()) != 0
|| strcmp(Config::DSiBIOS9Path, dsiBios9Path.c_str()) != 0
|| strcmp(Config::DSiBIOS7Path, dsiBios7Path.c_str()) != 0
|| strcmp(Config::DSiFirmwarePath, dsiFirmwarePath.c_str()) != 0
- || strcmp(Config::DSiNANDPath, dsiNANDPath.c_str()) != 0)
+ || strcmp(Config::DSiNANDPath, dsiNANDPath.c_str()) != 0
+ || dsiSDEnable != Config::DSiSDEnable
+ || strcmp(Config::DSiSDPath, dsiSDPath.c_str()) != 0)
{
if (RunningSomething
&& QMessageBox::warning(this, "Reset necessary to apply changes",
@@ -172,11 +184,15 @@ void EmuSettingsDialog::done(int r)
strncpy(Config::BIOS9Path, bios9Path.c_str(), 1023); Config::BIOS9Path[1023] = '\0';
strncpy(Config::BIOS7Path, bios7Path.c_str(), 1023); Config::BIOS7Path[1023] = '\0';
strncpy(Config::FirmwarePath, firmwarePath.c_str(), 1023); Config::FirmwarePath[1023] = '\0';
+ Config::DLDIEnable = dldiEnable;
+ strncpy(Config::DLDISDPath, dldiSDPath.c_str(), 1023); Config::DLDISDPath[1023] = '\0';
strncpy(Config::DSiBIOS9Path, dsiBios9Path.c_str(), 1023); Config::DSiBIOS9Path[1023] = '\0';
strncpy(Config::DSiBIOS7Path, dsiBios7Path.c_str(), 1023); Config::DSiBIOS7Path[1023] = '\0';
strncpy(Config::DSiFirmwarePath, dsiFirmwarePath.c_str(), 1023); Config::DSiFirmwarePath[1023] = '\0';
strncpy(Config::DSiNANDPath, dsiNANDPath.c_str(), 1023); Config::DSiNANDPath[1023] = '\0';
+ Config::DSiSDEnable = dsiSDEnable;
+ strncpy(Config::DSiSDPath, dsiSDPath.c_str(), 1023); Config::DSiSDPath[1023] = '\0';
#ifdef JIT_ENABLED
Config::JIT_Enable = jitEnable;
@@ -260,6 +276,18 @@ void EmuSettingsDialog::on_btnDSiBIOS7Browse_clicked()
ui->txtDSiBIOS7Path->setText(file);
}
+void EmuSettingsDialog::on_btnDLDISDBrowse_clicked()
+{
+ QString file = QFileDialog::getOpenFileName(this,
+ "Select DLDI SD image...",
+ EmuDirectory,
+ "Image files (*.bin *.rom *.img);;Any file (*.*)");
+
+ if (file.isEmpty()) return;
+
+ ui->txtDLDISDPath->setText(file);
+}
+
void EmuSettingsDialog::on_btnDSiFirmwareBrowse_clicked()
{
QString file = QFileDialog::getOpenFileName(this,
@@ -284,6 +312,18 @@ void EmuSettingsDialog::on_btnDSiNANDBrowse_clicked()
ui->txtDSiNANDPath->setText(file);
}
+void EmuSettingsDialog::on_btnDSiSDBrowse_clicked()
+{
+ QString file = QFileDialog::getOpenFileName(this,
+ "Select DSi SD image...",
+ EmuDirectory,
+ "Image files (*.bin *.rom *.img);;Any file (*.*)");
+
+ if (file.isEmpty()) return;
+
+ ui->txtDSiSDPath->setText(file);
+}
+
void EmuSettingsDialog::on_chkEnableJIT_toggled()
{
bool disabled = !ui->chkEnableJIT->isChecked();
diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.h b/src/frontend/qt_sdl/EmuSettingsDialog.h
index c24a147..158793c 100644
--- a/src/frontend/qt_sdl/EmuSettingsDialog.h
+++ b/src/frontend/qt_sdl/EmuSettingsDialog.h
@@ -42,7 +42,7 @@ public:
}
currentDlg = new EmuSettingsDialog(parent);
- currentDlg->show();
+ currentDlg->open();
return currentDlg;
}
static void closeDlg()
@@ -58,11 +58,13 @@ private slots:
void on_btnBIOS9Browse_clicked();
void on_btnBIOS7Browse_clicked();
void on_btnFirmwareBrowse_clicked();
+ void on_btnDLDISDBrowse_clicked();
void on_btnDSiBIOS9Browse_clicked();
void on_btnDSiBIOS7Browse_clicked();
void on_btnDSiFirmwareBrowse_clicked();
void on_btnDSiNANDBrowse_clicked();
+ void on_btnDSiSDBrowse_clicked();
void on_chkEnableJIT_toggled();
diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.ui b/src/frontend/qt_sdl/EmuSettingsDialog.ui
index 11d48cc..ac5506f 100644
--- a/src/frontend/qt_sdl/EmuSettingsDialog.ui
+++ b/src/frontend/qt_sdl/EmuSettingsDialog.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>514</width>
- <height>359</height>
+ <width>575</width>
+ <height>254</height>
</rect>
</property>
<property name="sizePolicy">
@@ -86,209 +86,242 @@
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
- <string>BIOS Files</string>
+ <string>DS-mode</string>
</attribute>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QGroupBox" name="groupBox">
- <property name="title">
- <string>DS mode</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="2" column="0">
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>DS firmware:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLineEdit" name="txtFirmwarePath">
- <property name="whatsThis">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DS-mode firmware&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Possible firmwares:&lt;/p&gt;&lt;p&gt;* 128 KB: DS-mode firmware from a DSi or 3DS. Not bootable.&lt;/p&gt;&lt;p&gt;* 256 KB: regular DS firmware.&lt;/p&gt;&lt;p&gt;* 512 KB: iQue DS firmware.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLineEdit" name="txtBIOS7Path">
- <property name="whatsThis">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DS-mode ARM7 BIOS&lt;/p&gt;&lt;p&gt;Size should be 16 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QPushButton" name="btnBIOS9Browse">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Browse...</string>
- </property>
- <property name="autoDefault">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QPushButton" name="btnFirmwareBrowse">
- <property name="text">
- <string>Browse...</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>DS ARM7 BIOS:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>DS ARM9 BIOS:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QPushButton" name="btnBIOS7Browse">
- <property name="text">
- <string>Browse...</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="txtBIOS9Path">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>290</width>
- <height>0</height>
- </size>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DS-mode ARM9 BIOS&lt;/p&gt;&lt;p&gt;Size should be 4 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_3">
- <property name="title">
- <string>DSi mode</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="0" column="2">
- <widget class="QPushButton" name="btnDSiBIOS9Browse">
- <property name="text">
- <string>Browse...</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>DSi ARM9 BIOS:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QPushButton" name="btnDSiFirmwareBrowse">
- <property name="text">
- <string>Browse...</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLineEdit" name="txtDSiBIOS7Path">
- <property name="whatsThis">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DSi-mode ARM7 BIOS&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Size should be 64 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLineEdit" name="txtDSiFirmwarePath">
- <property name="whatsThis">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DSi-mode firmware (used for DS-mode backwards compatibility)&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Size should be 128 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_6">
- <property name="text">
- <string>DSi ARM7 BIOS:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_7">
- <property name="text">
- <string>DSi firmware:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QPushButton" name="btnDSiBIOS7Browse">
- <property name="text">
- <string>Browse...</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="txtDSiBIOS9Path">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="whatsThis">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DSi-mode ARM9 BIOS&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Size should be 64 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_8">
- <property name="text">
- <string>DSi NAND:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QLineEdit" name="txtDSiNANDPath">
- <property name="whatsThis">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DSi NAND dump&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Should have 'nocash footer' at the end&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- <item row="3" column="2">
- <widget class="QPushButton" name="btnDSiNANDBrowse">
- <property name="text">
- <string>Browse...</string>
- </property>
- </widget>
- </item>
- </layout>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="txtBIOS7Path">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DS-mode ARM7 BIOS&lt;/p&gt;&lt;p&gt;Size should be 16 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="txtFirmwarePath">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DS-mode firmware&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Possible firmwares:&lt;/p&gt;&lt;p&gt;* 128 KB: DS-mode firmware from a DSi or 3DS. Not bootable.&lt;/p&gt;&lt;p&gt;* 256 KB: regular DS firmware.&lt;/p&gt;&lt;p&gt;* 512 KB: iQue DS firmware.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>DS firmware:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>DS ARM7 BIOS:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="btnBIOS7Browse">
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QPushButton" name="btnFirmwareBrowse">
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QPushButton" name="btnBIOS9Browse">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>DS ARM9 BIOS:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="txtBIOS9Path">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>290</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="statusTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DS-mode ARM9 BIOS&lt;/p&gt;&lt;p&gt;Size should be 4 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <spacer name="verticalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_4">
+ <attribute name="title">
+ <string>DSi-mode</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="txtDSiBIOS7Path">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DSi-mode ARM7 BIOS&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Size should be 64 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="2">
+ <widget class="QPushButton" name="btnDSiSDBrowse">
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_8">
+ <property name="text">
+ <string>DSi NAND:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <widget class="QPushButton" name="btnDSiNANDBrowse">
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>DSi ARM7 BIOS:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QPushButton" name="btnDSiFirmwareBrowse">
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="txtDSiNANDPath">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DSi NAND dump&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Should have 'nocash footer' at the end&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QPushButton" name="btnDSiBIOS9Browse">
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_10">
+ <property name="text">
+ <string>DSi SD card:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="txtDSiBIOS9Path">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DSi-mode ARM9 BIOS&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Size should be 64 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>DSi firmware:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>DSi ARM9 BIOS:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="txtDSiFirmwarePath">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DSi-mode firmware (used for DS-mode backwards compatibility)&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Size should be 128 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QLineEdit" name="txtDSiSDPath">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;SD image file for emulating the DSi's SD card&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="3">
+ <widget class="QCheckBox" name="cbDSiSDEnable">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Simulate a SD card being inserted in the DSi's SD slot. Requires a SD card image.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>Enable DSi SD card</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="btnDSiBIOS7Browse">
+ <property name="text">
+ <string>Browse...</string>
+ </property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
- <string>CPU Emulation</string>
+ <string>CPU emulation</string>
</attribute>
<layout class="QFormLayout" name="formLayout_5">
<item row="0" column="0">
@@ -354,6 +387,53 @@
</item>
</layout>
</widget>
+ <widget class="QWidget" name="tab_5">
+ <attribute name="title">
+ <string>DLDI</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="0" column="0" colspan="3">
+ <widget class="QCheckBox" name="cbDLDIEnable">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enable the built-in DLDI driver, to let homebrew access files from a given SD image.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>Enable DLDI (for homebrew)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="btnDLDISDBrowse">
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="txtDLDISDPath"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_11">
+ <property name="text">
+ <string>DLDI SD card:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
<item>
@@ -369,23 +449,8 @@
</layout>
</widget>
<tabstops>
- <tabstop>tabWidget</tabstop>
<tabstop>cbxConsoleType</tabstop>
<tabstop>chkDirectBoot</tabstop>
- <tabstop>txtBIOS9Path</tabstop>
- <tabstop>txtBIOS7Path</tabstop>
- <tabstop>txtFirmwarePath</tabstop>
- <tabstop>txtDSiBIOS9Path</tabstop>
- <tabstop>txtDSiBIOS7Path</tabstop>
- <tabstop>txtDSiFirmwarePath</tabstop>
- <tabstop>txtDSiNANDPath</tabstop>
- <tabstop>btnBIOS9Browse</tabstop>
- <tabstop>btnBIOS7Browse</tabstop>
- <tabstop>btnFirmwareBrowse</tabstop>
- <tabstop>btnDSiBIOS9Browse</tabstop>
- <tabstop>btnDSiBIOS7Browse</tabstop>
- <tabstop>btnDSiFirmwareBrowse</tabstop>
- <tabstop>btnDSiNANDBrowse</tabstop>
<tabstop>chkEnableJIT</tabstop>
<tabstop>spnJITMaximumBlockSize</tabstop>
</tabstops>
diff --git a/src/frontend/qt_sdl/Input.cpp b/src/frontend/qt_sdl/Input.cpp
index 84d20ad..11b64cc 100644
--- a/src/frontend/qt_sdl/Input.cpp
+++ b/src/frontend/qt_sdl/Input.cpp
@@ -98,7 +98,9 @@ int GetEventKeyVal(QKeyEvent* event)
void KeyPress(QKeyEvent* event)
{
int keyHK = GetEventKeyVal(event);
- int keyKP = keyHK & ~event->modifiers();
+ int keyKP = keyHK;
+ if (event->modifiers() != Qt::KeypadModifier)
+ keyKP &= ~event->modifiers();
for (int i = 0; i < 12; i++)
if (keyKP == Config::KeyMapping[i])
@@ -112,7 +114,9 @@ void KeyPress(QKeyEvent* event)
void KeyRelease(QKeyEvent* event)
{
int keyHK = GetEventKeyVal(event);
- int keyKP = keyHK & ~event->modifiers();
+ int keyKP = keyHK;
+ if (event->modifiers() != Qt::KeypadModifier)
+ keyKP &= ~event->modifiers();
for (int i = 0; i < 12; i++)
if (keyKP == Config::KeyMapping[i])
diff --git a/src/frontend/qt_sdl/InputConfigDialog.cpp b/src/frontend/qt_sdl/InputConfigDialog.cpp
index 81baa65..9f08731 100644
--- a/src/frontend/qt_sdl/InputConfigDialog.cpp
+++ b/src/frontend/qt_sdl/InputConfigDialog.cpp
@@ -54,6 +54,7 @@ const int hk_general[] =
HK_Reset,
HK_FastForward,
HK_FastForwardToggle,
+ HK_FullscreenToggle,
HK_Lid,
HK_Mic,
};
@@ -64,6 +65,7 @@ const char* hk_general_labels[] =
"Reset",
"Fast forward",
"Toggle FPS limit",
+ "Toggle Fullscreen",
"Close/open lid",
"Microphone",
};
@@ -86,7 +88,7 @@ InputConfigDialog::InputConfigDialog(QWidget* parent) : QDialog(parent), ui(new
addonsJoyMap[i] = Config::HKJoyMapping[hk_addons[i]];
}
- for (int i = 0; i < 6; i++)
+ for (int i = 0; i < 7; i++)
{
hkGeneralKeyMap[i] = Config::HKKeyMapping[hk_general[i]];
hkGeneralJoyMap[i] = Config::HKJoyMapping[hk_general[i]];
@@ -94,7 +96,7 @@ InputConfigDialog::InputConfigDialog(QWidget* parent) : QDialog(parent), ui(new
populatePage(ui->tabInput, 12, dskeylabels, keypadKeyMap, keypadJoyMap);
populatePage(ui->tabAddons, 2, hk_addons_labels, addonsKeyMap, addonsJoyMap);
- populatePage(ui->tabHotkeysGeneral, 6, hk_general_labels, hkGeneralKeyMap, hkGeneralJoyMap);
+ populatePage(ui->tabHotkeysGeneral, 7, hk_general_labels, hkGeneralKeyMap, hkGeneralJoyMap);
int njoy = SDL_NumJoysticks();
if (njoy > 0)
@@ -177,7 +179,7 @@ void InputConfigDialog::on_InputConfigDialog_accepted()
Config::HKJoyMapping[hk_addons[i]] = addonsJoyMap[i];
}
- for (int i = 0; i < 6; i++)
+ for (int i = 0; i < 7; i++)
{
Config::HKKeyMapping[hk_general[i]] = hkGeneralKeyMap[i];
Config::HKJoyMapping[hk_general[i]] = hkGeneralJoyMap[i];
@@ -226,7 +228,7 @@ void KeyMapButton::keyPressEvent(QKeyEvent* event)
{
if (!isChecked()) return QPushButton::keyPressEvent(event);
- printf("KEY PRESSED = %08X %08X | %08X %08X %08X\n", event->key(), event->modifiers(), event->nativeVirtualKey(), event->nativeModifiers(), event->nativeScanCode());
+ printf("KEY PRESSED = %08X %08X | %08X %08X %08X\n", event->key(), (int)event->modifiers(), event->nativeVirtualKey(), event->nativeModifiers(), event->nativeScanCode());
int key = event->key();
int mod = event->modifiers();
diff --git a/src/frontend/qt_sdl/InputConfigDialog.h b/src/frontend/qt_sdl/InputConfigDialog.h
index de57414..95e0532 100644
--- a/src/frontend/qt_sdl/InputConfigDialog.h
+++ b/src/frontend/qt_sdl/InputConfigDialog.h
@@ -64,7 +64,7 @@ private:
int keypadKeyMap[12], keypadJoyMap[12];
int addonsKeyMap[2], addonsJoyMap[2];
- int hkGeneralKeyMap[6], hkGeneralJoyMap[6];
+ int hkGeneralKeyMap[7], hkGeneralJoyMap[7];
};
diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp
index 05a0c2d..a716feb 100644
--- a/src/frontend/qt_sdl/Platform.cpp
+++ b/src/frontend/qt_sdl/Platform.cpp
@@ -77,7 +77,7 @@ u8 PacketBuffer[2048];
void Init(int argc, char** argv)
{
-#if defined(__WIN32__) || defined(UNIX_PORTABLE)
+#if defined(__WIN32__) || defined(PORTABLE)
if (argc > 0 && strlen(argv[0]) > 0)
{
int len = strlen(argv[0]);
@@ -137,13 +137,20 @@ FILE* OpenFile(const char* path, const char* mode, bool mustexist)
}
QIODevice::OpenMode qmode;
- if (strlen(mode) > 1 && mode[0] == 'r' && mode[1] == '+') {
+ if (strlen(mode) > 1 && mode[0] == 'r' && mode[1] == '+')
+ {
qmode = QIODevice::OpenModeFlag::ReadWrite;
- } else if (strlen(mode) > 1 && mode[0] == 'w' && mode[1] == '+') {
+ }
+ else if (strlen(mode) > 1 && mode[0] == 'w' && mode[1] == '+')
+ {
qmode = QIODevice::OpenModeFlag::Truncate | QIODevice::OpenModeFlag::ReadWrite;
- } else if (mode[0] == 'w') {
+ }
+ else if (mode[0] == 'w')
+ {
qmode = QIODevice::OpenModeFlag::Truncate | QIODevice::OpenModeFlag::WriteOnly;
- } else {
+ }
+ else
+ {
qmode = QIODevice::OpenModeFlag::ReadOnly;
}
@@ -167,7 +174,7 @@ FILE* OpenLocalFile(const char* path, const char* mode)
else
{
#ifdef PORTABLE
- fullpath = path;
+ fullpath = QString(EmuDirectory) + QDir::separator() + path;
#else
// Check user configuration directory
QDir config(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation));
diff --git a/src/frontend/qt_sdl/PlatformConfig.cpp b/src/frontend/qt_sdl/PlatformConfig.cpp
index bfb3f97..c2d40c4 100644
--- a/src/frontend/qt_sdl/PlatformConfig.cpp
+++ b/src/frontend/qt_sdl/PlatformConfig.cpp
@@ -51,7 +51,7 @@ int _3DRenderer;
int Threaded3D;
int GL_ScaleFactor;
-int GL_Antialias;
+int GL_BetterPolygons;
int LimitFPS;
int AudioSync;
@@ -72,6 +72,8 @@ char MicWavPath[1024];
char LastROMFolder[1024];
+int EnableCheats;
+
bool EnableJIT;
ConfigEntry PlatformConfigFile[] =
@@ -108,6 +110,7 @@ ConfigEntry PlatformConfigFile[] =
{"HKKey_Reset", 0, &HKKeyMapping[HK_Reset], -1, NULL, 0},
{"HKKey_FastForward", 0, &HKKeyMapping[HK_FastForward], -1, NULL, 0},
{"HKKey_FastForwardToggle", 0, &HKKeyMapping[HK_FastForwardToggle], -1, NULL, 0},
+ {"HKKey_FullscreenToggle", 0, &HKKeyMapping[HK_FullscreenToggle], -1, NULL, 0},
{"HKKey_SolarSensorDecrease", 0, &HKKeyMapping[HK_SolarSensorDecrease], -1, NULL, 0},
{"HKKey_SolarSensorIncrease", 0, &HKKeyMapping[HK_SolarSensorIncrease], -1, NULL, 0},
@@ -117,6 +120,7 @@ ConfigEntry PlatformConfigFile[] =
{"HKJoy_Reset", 0, &HKJoyMapping[HK_Reset], -1, NULL, 0},
{"HKJoy_FastForward", 0, &HKJoyMapping[HK_FastForward], -1, NULL, 0},
{"HKJoy_FastForwardToggle", 0, &HKJoyMapping[HK_FastForwardToggle], -1, NULL, 0},
+ {"HKJoy_FastForwardToggle", 0, &HKJoyMapping[HK_FullscreenToggle], -1, NULL, 0},
{"HKJoy_SolarSensorDecrease", 0, &HKJoyMapping[HK_SolarSensorDecrease], -1, NULL, 0},
{"HKJoy_SolarSensorIncrease", 0, &HKJoyMapping[HK_SolarSensorIncrease], -1, NULL, 0},
@@ -133,15 +137,15 @@ ConfigEntry PlatformConfigFile[] =
{"IntegerScaling", 0, &IntegerScaling, 0, NULL, 0},
{"ScreenFilter", 0, &ScreenFilter, 1, NULL, 0},
- {"ScreenUseGL", 0, &ScreenUseGL, 1, NULL, 0},
+ {"ScreenUseGL", 0, &ScreenUseGL, 0, NULL, 0},
{"ScreenVSync", 0, &ScreenVSync, 0, NULL, 0},
{"ScreenVSyncInterval", 0, &ScreenVSyncInterval, 1, NULL, 0},
- {"3DRenderer", 0, &_3DRenderer, 1, NULL, 0},
+ {"3DRenderer", 0, &_3DRenderer, 0, NULL, 0},
{"Threaded3D", 0, &Threaded3D, 1, NULL, 0},
{"GL_ScaleFactor", 0, &GL_ScaleFactor, 1, NULL, 0},
- {"GL_Antialias", 0, &GL_Antialias, 0, NULL, 0},
+ {"GL_BetterPolygons", 0, &GL_BetterPolygons, 0, NULL, 0},
{"LimitFPS", 0, &LimitFPS, 0, NULL, 0},
{"AudioSync", 0, &AudioSync, 1, NULL, 0},
@@ -162,6 +166,8 @@ ConfigEntry PlatformConfigFile[] =
{"LastROMFolder", 1, LastROMFolder, 0, "", 1023},
+ {"EnableCheats", 0, &EnableCheats, 0, NULL, 0},
+
{"", -1, NULL, 0, NULL, 0}
};
diff --git a/src/frontend/qt_sdl/PlatformConfig.h b/src/frontend/qt_sdl/PlatformConfig.h
index 791bb07..ca03d80 100644
--- a/src/frontend/qt_sdl/PlatformConfig.h
+++ b/src/frontend/qt_sdl/PlatformConfig.h
@@ -29,6 +29,7 @@ enum
HK_Reset,
HK_FastForward,
HK_FastForwardToggle,
+ HK_FullscreenToggle,
HK_SolarSensorDecrease,
HK_SolarSensorIncrease,
HK_MAX
@@ -64,7 +65,7 @@ extern int _3DRenderer;
extern int Threaded3D;
extern int GL_ScaleFactor;
-extern int GL_Antialias;
+extern int GL_BetterPolygons;
extern int LimitFPS;
extern int AudioSync;
@@ -85,6 +86,8 @@ extern char MicWavPath[1024];
extern char LastROMFolder[1024];
+extern int EnableCheats;
+
}
#endif // PLATFORMCONFIG_H
diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.cpp b/src/frontend/qt_sdl/VideoSettingsDialog.cpp
index ba433c3..1397ccd 100644
--- a/src/frontend/qt_sdl/VideoSettingsDialog.cpp
+++ b/src/frontend/qt_sdl/VideoSettingsDialog.cpp
@@ -42,6 +42,7 @@ VideoSettingsDialog::VideoSettingsDialog(QWidget* parent) : QDialog(parent), ui(
oldVSyncInterval = Config::ScreenVSyncInterval;
oldSoftThreaded = Config::Threaded3D;
oldGLScale = Config::GL_ScaleFactor;
+ oldGLBetterPolygons = Config::GL_BetterPolygons;
grp3DRenderer = new QButtonGroup(this);
grp3DRenderer->addButton(ui->rb3DSoftware, 0);
@@ -49,6 +50,10 @@ VideoSettingsDialog::VideoSettingsDialog(QWidget* parent) : QDialog(parent), ui(
connect(grp3DRenderer, SIGNAL(buttonClicked(int)), this, SLOT(onChange3DRenderer(int)));
grp3DRenderer->button(Config::_3DRenderer)->setChecked(true);
+#ifndef OGLRENDERER_ENABLED
+ ui->rb3DOpenGL->setEnabled(false);
+#endif
+
ui->cbGLDisplay->setChecked(Config::ScreenUseGL != 0);
ui->cbVSync->setChecked(Config::ScreenVSync != 0);
@@ -60,6 +65,8 @@ VideoSettingsDialog::VideoSettingsDialog(QWidget* parent) : QDialog(parent), ui(
ui->cbxGLResolution->addItem(QString("%1x native (%2x%3)").arg(i).arg(256*i).arg(192*i));
ui->cbxGLResolution->setCurrentIndex(Config::GL_ScaleFactor-1);
+ ui->cbBetterPolygons->setChecked(Config::GL_BetterPolygons != 0);
+
if (!Config::ScreenVSync)
ui->sbVSyncInterval->setEnabled(false);
@@ -68,12 +75,14 @@ VideoSettingsDialog::VideoSettingsDialog(QWidget* parent) : QDialog(parent), ui(
ui->cbGLDisplay->setEnabled(true);
ui->cbSoftwareThreaded->setEnabled(true);
ui->cbxGLResolution->setEnabled(false);
+ ui->cbBetterPolygons->setEnabled(false);
}
else
{
ui->cbGLDisplay->setEnabled(false);
ui->cbSoftwareThreaded->setEnabled(false);
ui->cbxGLResolution->setEnabled(true);
+ ui->cbBetterPolygons->setEnabled(true);
}
}
@@ -99,6 +108,7 @@ void VideoSettingsDialog::on_VideoSettingsDialog_rejected()
Config::ScreenVSyncInterval = oldVSyncInterval;
Config::Threaded3D = oldSoftThreaded;
Config::GL_ScaleFactor = oldGLScale;
+ Config::GL_BetterPolygons = oldGLBetterPolygons;
bool new_gl = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0);
emit updateVideoSettings(old_gl != new_gl);
@@ -117,12 +127,14 @@ void VideoSettingsDialog::onChange3DRenderer(int renderer)
ui->cbGLDisplay->setEnabled(true);
ui->cbSoftwareThreaded->setEnabled(true);
ui->cbxGLResolution->setEnabled(false);
+ ui->cbBetterPolygons->setEnabled(false);
}
else
{
ui->cbGLDisplay->setEnabled(false);
ui->cbSoftwareThreaded->setEnabled(false);
ui->cbxGLResolution->setEnabled(true);
+ ui->cbBetterPolygons->setEnabled(true);
}
bool new_gl = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0);
@@ -167,3 +179,10 @@ void VideoSettingsDialog::on_cbxGLResolution_currentIndexChanged(int idx)
emit updateVideoSettings(false);
}
+
+void VideoSettingsDialog::on_cbBetterPolygons_stateChanged(int state)
+{
+ Config::GL_BetterPolygons = (state != 0);
+
+ emit updateVideoSettings(false);
+}
diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.h b/src/frontend/qt_sdl/VideoSettingsDialog.h
index 2311d4d..2645eef 100644
--- a/src/frontend/qt_sdl/VideoSettingsDialog.h
+++ b/src/frontend/qt_sdl/VideoSettingsDialog.h
@@ -64,6 +64,7 @@ private slots:
void on_sbVSyncInterval_valueChanged(int val);
void on_cbxGLResolution_currentIndexChanged(int idx);
+ void on_cbBetterPolygons_stateChanged(int state);
void on_cbSoftwareThreaded_stateChanged(int state);
@@ -78,6 +79,7 @@ private:
int oldVSyncInterval;
int oldSoftThreaded;
int oldGLScale;
+ int oldGLBetterPolygons;
};
#endif // VIDEOSETTINGSDIALOG_H
diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.ui b/src/frontend/qt_sdl/VideoSettingsDialog.ui
index 6cdd5d8..6985304 100644
--- a/src/frontend/qt_sdl/VideoSettingsDialog.ui
+++ b/src/frontend/qt_sdl/VideoSettingsDialog.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>482</width>
- <height>237</height>
+ <height>244</height>
</rect>
</property>
<property name="sizePolicy">
@@ -43,6 +43,16 @@
</property>
</widget>
</item>
+ <item row="2" column="0">
+ <widget class="QCheckBox" name="cbBetterPolygons">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enabling this may help reduce distortion on quads and more complex polygons, but may also reduce performance.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>Improved polygon splitting</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/src/frontend/qt_sdl/WifiSettingsDialog.cpp b/src/frontend/qt_sdl/WifiSettingsDialog.cpp
index 457a78d..67297ad 100644
--- a/src/frontend/qt_sdl/WifiSettingsDialog.cpp
+++ b/src/frontend/qt_sdl/WifiSettingsDialog.cpp
@@ -17,7 +17,7 @@
*/
#include <stdio.h>
-#include <QFileDialog>
+#include <QMessageBox>
#include "types.h"
#include "Platform.h"
@@ -41,6 +41,10 @@
WifiSettingsDialog* WifiSettingsDialog::currentDlg = nullptr;
+bool WifiSettingsDialog::needsReset = false;
+
+extern bool RunningSomething;
+
WifiSettingsDialog::WifiSettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::WifiSettingsDialog)
{
@@ -53,6 +57,7 @@ WifiSettingsDialog::WifiSettingsDialog(QWidget* parent) : QDialog(parent), ui(ne
ui->cbDirectMode->setText("Direct mode (requires " PCAP_NAME " and ethernet connection)");
ui->cbBindAnyAddr->setChecked(Config::SocketBindAnyAddr != 0);
+ ui->cbRandomizeMAC->setChecked(Config::RandomizeMAC != 0);
int sel = 0;
for (int i = 0; i < LAN_PCap::NumAdapters; i++)
@@ -77,33 +82,49 @@ WifiSettingsDialog::~WifiSettingsDialog()
delete ui;
}
-void WifiSettingsDialog::on_WifiSettingsDialog_accepted()
+void WifiSettingsDialog::done(int r)
{
- Config::SocketBindAnyAddr = ui->cbBindAnyAddr->isChecked() ? 1:0;
- Config::DirectLAN = ui->cbDirectMode->isChecked() ? 1:0;
+ needsReset = false;
- int sel = ui->cbxDirectAdapter->currentIndex();
- if (sel < 0 || sel >= LAN_PCap::NumAdapters) sel = 0;
- if (LAN_PCap::NumAdapters < 1)
- {
- Config::LANDevice[0] = '\0';
- }
- else
+ if (r == QDialog::Accepted)
{
- strncpy(Config::LANDevice, LAN_PCap::Adapters[sel].DeviceName, 127);
- Config::LANDevice[127] = '\0';
+ int randommac = ui->cbRandomizeMAC->isChecked() ? 1:0;
+
+ if (randommac != Config::RandomizeMAC)
+ {
+ if (RunningSomething
+ && QMessageBox::warning(this, "Reset necessary to apply changes",
+ "The emulation will be reset for the changes to take place.",
+ QMessageBox::Ok, QMessageBox::Cancel) != QMessageBox::Ok)
+ return;
+ }
+
+ Config::SocketBindAnyAddr = ui->cbBindAnyAddr->isChecked() ? 1:0;
+ Config::RandomizeMAC = randommac;
+ Config::DirectLAN = ui->cbDirectMode->isChecked() ? 1:0;
+
+ int sel = ui->cbxDirectAdapter->currentIndex();
+ if (sel < 0 || sel >= LAN_PCap::NumAdapters) sel = 0;
+ if (LAN_PCap::NumAdapters < 1)
+ {
+ Config::LANDevice[0] = '\0';
+ }
+ else
+ {
+ strncpy(Config::LANDevice, LAN_PCap::Adapters[sel].DeviceName, 127);
+ Config::LANDevice[127] = '\0';
+ }
+
+ Config::Save();
+
+ needsReset = true;
}
- Config::Save();
+ QDialog::done(r);
closeDlg();
}
-void WifiSettingsDialog::on_WifiSettingsDialog_rejected()
-{
- closeDlg();
-}
-
void WifiSettingsDialog::on_cbDirectMode_stateChanged(int state)
{
updateAdapterControls();
diff --git a/src/frontend/qt_sdl/WifiSettingsDialog.h b/src/frontend/qt_sdl/WifiSettingsDialog.h
index f8aad1b..6c1f863 100644
--- a/src/frontend/qt_sdl/WifiSettingsDialog.h
+++ b/src/frontend/qt_sdl/WifiSettingsDialog.h
@@ -42,7 +42,7 @@ public:
}
currentDlg = new WifiSettingsDialog(parent);
- currentDlg->show();
+ currentDlg->open();
return currentDlg;
}
static void closeDlg()
@@ -50,9 +50,10 @@ public:
currentDlg = nullptr;
}
+ static bool needsReset;
+
private slots:
- void on_WifiSettingsDialog_accepted();
- void on_WifiSettingsDialog_rejected();
+ void done(int r);
void on_cbDirectMode_stateChanged(int state);
void on_cbxDirectAdapter_currentIndexChanged(int sel);
diff --git a/src/frontend/qt_sdl/WifiSettingsDialog.ui b/src/frontend/qt_sdl/WifiSettingsDialog.ui
index bfee1fd..6668d88 100644
--- a/src/frontend/qt_sdl/WifiSettingsDialog.ui
+++ b/src/frontend/qt_sdl/WifiSettingsDialog.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>479</width>
- <height>217</height>
+ <height>240</height>
</rect>
</property>
<property name="sizePolicy">
@@ -39,6 +39,16 @@
</property>
</widget>
</item>
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="cbRandomizeMAC">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Randomizes the console's MAC address upon reset. Required for local multiplayer if each melonDS instance uses the same firmware file.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>Randomize MAC address</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp
index 722ebd5..6c49803 100644
--- a/src/frontend/qt_sdl/main.cpp
+++ b/src/frontend/qt_sdl/main.cpp
@@ -41,6 +41,7 @@
#include "main.h"
#include "Input.h"
+#include "CheatsDialog.h"
#include "EmuSettingsDialog.h"
#include "InputConfigDialog.h"
#include "VideoSettingsDialog.h"
@@ -55,7 +56,9 @@
#include "NDS.h"
#include "GBACart.h"
+#ifdef OGLRENDERER_ENABLED
#include "OpenGLSupport.h"
+#endif
#include "GPU.h"
#include "SPU.h"
#include "Wifi.h"
@@ -120,7 +123,6 @@ void audioCallback(void* data, Uint8* stream, int len)
if (num_in < len_in-margin)
{
int last = num_in-1;
- if (last < 0) last = 0;
for (int i = num_in; i < len_in-margin; i++)
((u32*)buf_in)[i] = ((u32*)buf_in)[last];
@@ -273,6 +275,7 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent)
connect(this, SIGNAL(windowEmuPause()), mainWindow->actPause, SLOT(trigger()));
connect(this, SIGNAL(windowEmuReset()), mainWindow->actReset, SLOT(trigger()));
connect(this, SIGNAL(screenLayoutChange()), mainWindow->panel, SLOT(onScreenLayoutChanged()));
+ connect(this, SIGNAL(windowFullscreenToggle()), mainWindow, SLOT(onFullscreenToggled()));
if (mainWindow->hasOGL) initOpenGL();
}
@@ -342,13 +345,17 @@ void EmuThread::run()
videoSettings.Soft_Threaded = Config::Threaded3D != 0;
videoSettings.GL_ScaleFactor = Config::GL_ScaleFactor;
+#ifdef OGLRENDERER_ENABLED
if (hasOGL)
{
oglContext->makeCurrent(oglSurface);
videoRenderer = OpenGL::Init() ? Config::_3DRenderer : 0;
}
else
+#endif
+ {
videoRenderer = 0;
+ }
GPU::InitRenderer(videoRenderer);
GPU::SetRenderSettings(videoRenderer, videoSettings);
@@ -371,6 +378,8 @@ void EmuThread::run()
if (Input::HotkeyPressed(HK_Pause)) emit windowEmuPause();
if (Input::HotkeyPressed(HK_Reset)) emit windowEmuReset();
+
+ if (Input::HotkeyPressed(HK_FullscreenToggle)) emit windowFullscreenToggle();
if (GBACart::CartInserted && GBACart::HasSolarSensor)
{
@@ -400,20 +409,27 @@ void EmuThread::run()
if (hasOGL != mainWindow->hasOGL)
{
hasOGL = mainWindow->hasOGL;
+#ifdef OGLRENDERER_ENABLED
if (hasOGL)
{
oglContext->makeCurrent(oglSurface);
videoRenderer = OpenGL::Init() ? Config::_3DRenderer : 0;
}
else
+#endif
+ {
videoRenderer = 0;
+ }
}
else
videoRenderer = hasOGL ? Config::_3DRenderer : 0;
videoSettingsDirty = false;
+
videoSettings.Soft_Threaded = Config::Threaded3D != 0;
videoSettings.GL_ScaleFactor = Config::GL_ScaleFactor;
+ videoSettings.GL_BetterPolygons = Config::GL_BetterPolygons;
+
GPU::SetRenderSettings(videoRenderer, videoSettings);
}
@@ -924,12 +940,14 @@ void ScreenPanelGL::paintGL()
int frontbuf = GPU::FrontBuffer;
glActiveTexture(GL_TEXTURE0);
+#ifdef OGLRENDERER_ENABLED
if (GPU::Renderer != 0)
{
// hardware-accelerated render
GPU::GLCompositor::BindOutputTexture();
}
else
+#endif
{
// regular render
glBindTexture(GL_TEXTURE_2D, screenTexture);
@@ -1053,6 +1071,9 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
actUndoStateLoad->setShortcut(QKeySequence(Qt::Key_F12));
connect(actUndoStateLoad, &QAction::triggered, this, &MainWindow::onUndoStateLoad);
+ actImportSavefile = menu->addAction("Import savefile");
+ connect(actImportSavefile, &QAction::triggered, this, &MainWindow::onImportSavefile);
+
menu->addSeparator();
actQuit = menu->addAction("Quit");
@@ -1070,6 +1091,15 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
actStop = menu->addAction("Stop");
connect(actStop, &QAction::triggered, this, &MainWindow::onStop);
+
+ menu->addSeparator();
+
+ actEnableCheats = menu->addAction("Enable cheats");
+ actEnableCheats->setCheckable(true);
+ connect(actEnableCheats, &QAction::triggered, this, &MainWindow::onEnableCheats);
+
+ actSetupCheats = menu->addAction("Setup cheat codes");
+ connect(actSetupCheats, &QAction::triggered, this, &MainWindow::onSetupCheats);
}
{
QMenu* menu = menubar->addMenu("Config");
@@ -1212,11 +1242,16 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
actLoadState[i]->setEnabled(false);
}
actUndoStateLoad->setEnabled(false);
+ actImportSavefile->setEnabled(false);
actPause->setEnabled(false);
actReset->setEnabled(false);
actStop->setEnabled(false);
+ actSetupCheats->setEnabled(false);
+
+
+ actEnableCheats->setChecked(Config::EnableCheats != 0);
actSavestateSRAMReloc->setChecked(Config::SavestateRelocSRAM != 0);
@@ -1327,7 +1362,7 @@ void MainWindow::dragEnterEvent(QDragEnterEvent* event)
QString filename = urls.at(0).toLocalFile();
QString ext = filename.right(3);
- if (ext == "nds" || ext == "srl" || (ext == "gba" && RunningSomething))
+ if (ext == "nds" || ext == "srl" || ext == "dsi" || (ext == "gba" && RunningSomething))
event->acceptProposedAction();
}
@@ -1651,6 +1686,41 @@ void MainWindow::onUndoStateLoad()
OSD::AddMessage(0, "State load undone");
}
+void MainWindow::onImportSavefile()
+{
+ if (!RunningSomething) return;
+
+ emuThread->emuPause();
+ QString path = QFileDialog::getOpenFileName(this,
+ "Select savefile",
+ Config::LastROMFolder,
+ "Savefiles (*.sav *.bin *.dsv);;Any file (*.*)");
+
+ if (!path.isEmpty())
+ {
+ if (QMessageBox::warning(this,
+ "Emulation will be reset and data overwritten",
+ "The emulation will be reset and the current savefile overwritten.",
+ QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok)
+ {
+ int res = Frontend::Reset();
+ if (res != Frontend::Load_OK)
+ {
+ QMessageBox::critical(this, "melonDS", "Reset failed\n" + loadErrorStr(res));
+ }
+ else
+ {
+ int diff = Frontend::ImportSRAM(path.toStdString().c_str());
+ if (diff > 0)
+ OSD::AddMessage(0, "Trimmed savefile");
+ else if (diff < 0)
+ OSD::AddMessage(0, "Savefile shorter than SRAM");
+ }
+ }
+ }
+ emuThread->emuUnpause();
+}
+
void MainWindow::onQuit()
{
QApplication::quit();
@@ -1704,6 +1774,25 @@ void MainWindow::onStop()
NDS::Stop();
}
+void MainWindow::onEnableCheats(bool checked)
+{
+ Config::EnableCheats = checked?1:0;
+ Frontend::EnableCheats(Config::EnableCheats != 0);
+}
+
+void MainWindow::onSetupCheats()
+{
+ emuThread->emuPause();
+
+ CheatsDialog* dlg = CheatsDialog::openDlg(this);
+ connect(dlg, &CheatsDialog::finished, this, &MainWindow::onCheatsDialogFinished);
+}
+
+void MainWindow::onCheatsDialogFinished(int res)
+{
+ emuThread->emuUnpause();
+}
+
void MainWindow::onOpenEmuSettings()
{
@@ -1767,14 +1856,14 @@ void MainWindow::onAudioSettingsFinished(int res)
void MainWindow::onOpenWifiSettings()
{
+ emuThread->emuPause();
+
WifiSettingsDialog* dlg = WifiSettingsDialog::openDlg(this);
connect(dlg, &WifiSettingsDialog::finished, this, &MainWindow::onWifiSettingsFinished);
}
void MainWindow::onWifiSettingsFinished(int res)
{
- emuThread->emuPause();
-
if (Wifi::MPInited)
{
Platform::MP_DeInit();
@@ -1784,6 +1873,9 @@ void MainWindow::onWifiSettingsFinished(int res)
Platform::LAN_DeInit();
Platform::LAN_Init();
+ if (WifiSettingsDialog::needsReset)
+ onReset();
+
emuThread->emuUnpause();
}
@@ -1892,21 +1984,51 @@ void MainWindow::onTitleUpdate(QString title)
setWindowTitle(title);
}
+void MainWindow::onFullscreenToggled()
+{
+ if (!mainWindow->isFullScreen())
+ {
+ mainWindow->showFullScreen();
+ mainWindow->menuBar()->hide();
+ }
+ else
+ {
+ mainWindow->showNormal();
+ mainWindow->menuBar()->show();
+ }
+}
+
void MainWindow::onEmuStart()
{
- for (int i = 1; i < 9; i++)
+ // TODO: make savestates work in DSi mode!!
+ if (Config::ConsoleType == 1)
{
- actSaveState[i]->setEnabled(true);
- actLoadState[i]->setEnabled(Frontend::SavestateExists(i));
+ for (int i = 0; i < 9; i++)
+ {
+ actSaveState[i]->setEnabled(false);
+ actLoadState[i]->setEnabled(false);
+ }
+ actUndoStateLoad->setEnabled(false);
+ }
+ else
+ {
+ for (int i = 1; i < 9; i++)
+ {
+ actSaveState[i]->setEnabled(true);
+ actLoadState[i]->setEnabled(Frontend::SavestateExists(i));
+ }
+ actSaveState[0]->setEnabled(true);
+ actLoadState[0]->setEnabled(true);
+ actUndoStateLoad->setEnabled(false);
}
- actSaveState[0]->setEnabled(true);
- actLoadState[0]->setEnabled(true);
- actUndoStateLoad->setEnabled(false);
actPause->setEnabled(true);
actPause->setChecked(false);
actReset->setEnabled(true);
actStop->setEnabled(true);
+ actImportSavefile->setEnabled(true);
+
+ actSetupCheats->setEnabled(true);
}
void MainWindow::onEmuStop()
@@ -1919,10 +2041,13 @@ void MainWindow::onEmuStop()
actLoadState[i]->setEnabled(false);
}
actUndoStateLoad->setEnabled(false);
+ actImportSavefile->setEnabled(false);
actPause->setEnabled(false);
actReset->setEnabled(false);
actStop->setEnabled(false);
+
+ actSetupCheats->setEnabled(false);
}
void MainWindow::onUpdateVideoSettings(bool glchange)
@@ -2054,6 +2179,8 @@ int main(int argc, char** argv)
micWavBuffer = nullptr;
Frontend::Init_ROM();
+ Frontend::EnableCheats(Config::EnableCheats != 0);
+
Frontend::Init_Audio(audioFreq);
if (Config::MicInputType == 1)
@@ -2080,7 +2207,7 @@ int main(int argc, char** argv)
char* file = argv[1];
char* ext = &file[strlen(file)-3];
- if (!strcasecmp(ext, "nds") || !strcasecmp(ext, "srl"))
+ if (!strcasecmp(ext, "nds") || !strcasecmp(ext, "srl") || !strcasecmp(ext, "dsi"))
{
int res = Frontend::LoadROM(file, Frontend::ROMSlot_NDS);
@@ -2110,6 +2237,8 @@ int main(int argc, char** argv)
Input::CloseJoystick();
+ Frontend::DeInit_ROM();
+
if (audioDevice) SDL_CloseAudioDevice(audioDevice);
if (micDevice) SDL_CloseAudioDevice(micDevice);
diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h
index 7f33973..978df9e 100644
--- a/src/frontend/qt_sdl/main.h
+++ b/src/frontend/qt_sdl/main.h
@@ -69,6 +69,8 @@ signals:
void windowLimitFPSChange();
void screenLayoutChange();
+
+ void windowFullscreenToggle();
private:
volatile int EmuStatus;
@@ -193,11 +195,15 @@ private slots:
void onSaveState();
void onLoadState();
void onUndoStateLoad();
+ void onImportSavefile();
void onQuit();
void onPause(bool checked);
void onReset();
void onStop();
+ void onEnableCheats(bool checked);
+ void onSetupCheats();
+ void onCheatsDialogFinished(int res);
void onOpenEmuSettings();
void onEmuSettingsDialogFinished(int res);
@@ -226,6 +232,8 @@ private slots:
void onEmuStop();
void onUpdateVideoSettings(bool glchange);
+
+ void onFullscreenToggled();
private:
void createScreenPanel();
@@ -240,11 +248,14 @@ public:
QAction* actSaveState[9];
QAction* actLoadState[9];
QAction* actUndoStateLoad;
+ QAction* actImportSavefile;
QAction* actQuit;
QAction* actPause;
QAction* actReset;
QAction* actStop;
+ QAction* actEnableCheats;
+ QAction* actSetupCheats;
QAction* actEmuSettings;
QAction* actInputConfig;