From f23e782966d108d27403af17d8f0074a01154c29 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 11 Aug 2020 15:58:41 +0200 Subject: hey look. Arisotura the lazy derp finally made a dialog. --- src/frontend/qt_sdl/CheatsDialog.ui | 108 ++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 src/frontend/qt_sdl/CheatsDialog.ui (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/CheatsDialog.ui b/src/frontend/qt_sdl/CheatsDialog.ui new file mode 100644 index 0000000..12e28e2 --- /dev/null +++ b/src/frontend/qt_sdl/CheatsDialog.ui @@ -0,0 +1,108 @@ + + + CheatsDialog + + + + 0 + 0 + 609 + 417 + + + + AR cheat code editor - melonDS + + + + + + QLayout::SetDefaultConstraint + + + + + New category + + + + + + + New AR code + + + + + + + Delete code + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + + + + + 2 + 0 + + + + + 200 + 0 + + + + + + + + + 3 + 0 + + + + + 200 + 0 + + + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + -- cgit v1.2.3 From 0bd53a34ef975b12563ccfa6247def84789d098b Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 11 Aug 2020 17:38:29 +0200 Subject: lay base for the actual dialog also make EmuSettingsDialog properly modal --- src/frontend/qt_sdl/CMakeLists.txt | 1 + src/frontend/qt_sdl/CheatsDialog.cpp | 61 +++++++++++++++++++++++++++++++ src/frontend/qt_sdl/CheatsDialog.h | 65 +++++++++++++++++++++++++++++++++ src/frontend/qt_sdl/EmuSettingsDialog.h | 2 +- src/frontend/qt_sdl/main.cpp | 27 ++++++++++++++ src/frontend/qt_sdl/main.h | 5 +++ 6 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 src/frontend/qt_sdl/CheatsDialog.cpp create mode 100644 src/frontend/qt_sdl/CheatsDialog.h (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index 05c42d1..9a0a025 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..2654e75 --- /dev/null +++ b/src/frontend/qt_sdl/CheatsDialog.cpp @@ -0,0 +1,61 @@ +/* + 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 +#include + +#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; + + +CheatsDialog::CheatsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::CheatsDialog) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + + // setup UI here +} + +CheatsDialog::~CheatsDialog() +{ + delete ui; +} + +void CheatsDialog::on_CheatsDialog_accepted() +{ + // save shit here + + closeDlg(); +} + +void CheatsDialog::on_CheatsDialog_rejected() +{ + // don't save shit here + + closeDlg(); +} diff --git a/src/frontend/qt_sdl/CheatsDialog.h b/src/frontend/qt_sdl/CheatsDialog.h new file mode 100644 index 0000000..99582c8 --- /dev/null +++ b/src/frontend/qt_sdl/CheatsDialog.h @@ -0,0 +1,65 @@ +/* + 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 + +namespace Ui { class CheatsDialog; } +class CheatsDialog; + +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(); + + // + +private: + Ui::CheatsDialog* ui; + + // +}; + +#endif // CHEATSDIALOG_H diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.h b/src/frontend/qt_sdl/EmuSettingsDialog.h index c24a147..1a16ebc 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() diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index e7f35c2..903e654 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -34,6 +34,7 @@ #include "main.h" #include "Input.h" +#include "CheatsDialog.h" #include "EmuSettingsDialog.h" #include "InputConfigDialog.h" #include "VideoSettingsDialog.h" @@ -1062,6 +1063,14 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) actStop = menu->addAction("Stop"); connect(actStop, &QAction::triggered, this, &MainWindow::onStop); + + menu->addSeparator(); + + actEnableCheats = menu->addAction("Enable cheats"); + 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"); @@ -1651,6 +1660,24 @@ void MainWindow::onStop() NDS::Stop(); } +void MainWindow::onEnableCheats(bool checked) +{ + // +} + +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() { diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 7f33973..cad30d6 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -198,6 +198,9 @@ private slots: void onPause(bool checked); void onReset(); void onStop(); + void onEnableCheats(bool checked); + void onSetupCheats(); + void onCheatsDialogFinished(int res); void onOpenEmuSettings(); void onEmuSettingsDialogFinished(int res); @@ -245,6 +248,8 @@ public: QAction* actPause; QAction* actReset; QAction* actStop; + QAction* actEnableCheats; + QAction* actSetupCheats; QAction* actEmuSettings; QAction* actInputConfig; -- cgit v1.2.3 From 28b8f614ee778b67d9b8f573ee34435739742020 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 11 Aug 2020 18:03:44 +0200 Subject: heh --- src/frontend/qt_sdl/CheatsDialog.ui | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/CheatsDialog.ui b/src/frontend/qt_sdl/CheatsDialog.ui index 12e28e2..3191ef2 100644 --- a/src/frontend/qt_sdl/CheatsDialog.ui +++ b/src/frontend/qt_sdl/CheatsDialog.ui @@ -104,5 +104,38 @@ - + + + buttonBox + accepted() + CheatsDialog + accept() + + + 304 + 396 + + + 304 + 208 + + + + + buttonBox + rejected() + CheatsDialog + reject() + + + 304 + 396 + + + 304 + 208 + + + + -- cgit v1.2.3 From 4cefff25282fa041dca4b66342ca169b50621959 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 13 Aug 2020 00:20:34 +0200 Subject: add AR code file parser and shit --- src/ARCodeFile.cpp | 176 ++++++++++++++++++++++++++++++++++++ src/ARCodeFile.h | 63 +++++++++++++ src/ARCodeList.cpp | 38 -------- src/ARCodeList.h | 33 ------- src/AREngine.cpp | 139 ++++++---------------------- src/AREngine.h | 4 + src/CMakeLists.txt | 2 +- src/frontend/qt_sdl/CheatsDialog.ui | 3 + 8 files changed, 276 insertions(+), 182 deletions(-) create mode 100644 src/ARCodeFile.cpp create mode 100644 src/ARCodeFile.h delete mode 100644 src/ARCodeList.cpp delete mode 100644 src/ARCodeList.h (limited to 'src/frontend') diff --git a/src/ARCodeFile.cpp b/src/ARCodeFile.cpp new file mode 100644 index 0000000..d2f47ff --- /dev/null +++ b/src/ARCodeFile.cpp @@ -0,0 +1,176 @@ +/* + 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 +#include +#include "ARCodeFile.h" +#include "Platform.h" + + +// TODO: import codes from other sources (usrcheat.dat, ...) +// TODO: more user-friendly error reporting + + +ARCodeFile::ARCodeFile(const char* filename) +{ + memset(Filename, 0, sizeof(Filename)); + strncpy(Filename, filename, 1023); + + Error = false; + + Categories.clear(); + + FILE* f = Platform::OpenFile(Filename, "r"); + if (!f) return; + + bool isincat = false; + ARCodeCat curcat; + + bool isincode = false; + ARCode curcode; + + char linebuf[1024]; + while (!feof(f)) + { + fgets(linebuf, 1024, f); + linebuf[1023] = '\0'; + + char* start = linebuf; + while (start[0]==' ' || start[0]=='\t') + start++; + + if (start[0]=='#' || start[0]=='\r' || start[0]=='\n' || start[0]=='\0') + continue; + + if (!strncasecmp(start, "CAT", 3)) + { + char catname[128]; + int ret = sscanf(start, "CAT %127[^\n]", catname); + catname[127] = '\0'; + + if (ret < 1) + { + printf("AR: malformed CAT line: %s\n", start); + fclose(f); + Error = true; + return; + } + + if (isincode) curcat.Codes.push_back(curcode); + isincode = false; + + if (isincat) Categories.push_back(curcat); + isincat = true; + + memcpy(curcat.Name, catname, 128); + curcat.Codes.clear(); + } + else if (!strncasecmp(start, "CODE", 4)) + { + int enable; + char codename[128]; + int ret = sscanf(start, "CODE %d %127[^\n]", &enable, codename); + codename[127] = '\0'; + + if (ret < 2) + { + printf("AR: malformed CODE line: %s\n", start); + fclose(f); + Error = true; + return; + } + + if (!isincat) + { + printf("AR: encountered CODE line with no category started\n"); + fclose(f); + Error = true; + return; + } + + if (isincode) curcat.Codes.push_back(curcode); + isincode = true; + + memcpy(curcode.Name, codename, 128); + curcode.Enabled = enable!=0; + curcode.CodeLen = 0; + } + else + { + u32 c0, c1; + int ret = sscanf(start, "%08X %08X", &c0, &c1); + + if (ret < 2) + { + printf("AR: malformed data line: %s\n", start); + fclose(f); + Error = true; + return; + } + + if (!isincode) + { + printf("AR: encountered data line with no code started\n"); + fclose(f); + Error = true; + return; + } + + if (curcode.CodeLen >= 2*64) + { + printf("AR: code too long!\n"); + fclose(f); + Error = true; + return; + } + + u32 idx = curcode.CodeLen; + curcode.Code[idx+0] = c0; + curcode.Code[idx+1] = c1; + curcode.CodeLen += 2; + } + } + + if (isincode) curcat.Codes.push_back(curcode); + if (isincat) Categories.push_back(curcat); + + fclose(f); + + printf("PARSED OUTPUT\n"); + for (ARCodeCatList::iterator it = Categories.begin(); it != Categories.end(); it++) + { + ARCodeCat& cat = *it; + printf("CAT %s\n", cat.Name); + + for (ARCodeList::iterator jt = cat.Codes.begin(); jt != cat.Codes.end(); jt++) + { + ARCode& code = *jt; + printf("CODE %d %s\n", code.Enabled, code.Name); + + for (u32 i = 0; i < code.CodeLen; i+=2) + { + printf("%08X %08X\n", code.Code[i], code.Code[i+1]); + } + } + } +} + +ARCodeFile::~ARCodeFile() +{ + // +} diff --git a/src/ARCodeFile.h b/src/ARCodeFile.h new file mode 100644 index 0000000..548bfeb --- /dev/null +++ b/src/ARCodeFile.h @@ -0,0 +1,63 @@ +/* + 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 ARCODEFILE_H +#define ARCODEFILE_H + +#include + +#include "types.h" + +typedef struct +{ + char Name[128]; + bool Enabled; + u32 CodeLen; + u32 Code[2*64]; + +} ARCode; + +typedef std::vector ARCodeList; + +typedef struct +{ + char Name[128]; + ARCodeList Codes; + +} ARCodeCat; + +typedef std::vector ARCodeCatList; + + +class ARCodeFile +{ +public: + ARCodeFile(const char* filename); + ~ARCodeFile(); + + bool Error; + + bool Save(); + + ARCodeCatList Categories; + +private: + char Filename[1024]; +}; + +#endif // ARCODEFILE_H diff --git a/src/ARCodeList.cpp b/src/ARCodeList.cpp deleted file mode 100644 index 380481f..0000000 --- a/src/ARCodeList.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - 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 -#include "ARCodeList.h" - -/* - Action Replay code list format - - header: - 00 - magic MLAR - 04 - version major - 06 - version minor - 08 - length - 0C - number of codes - - code header: - 00 - magic MLCD - 04 - name length - 08 - code length - 0C - enable flag - 10 - code data (UTF8 name then actual code) -*/ diff --git a/src/ARCodeList.h b/src/ARCodeList.h deleted file mode 100644 index b46510c..0000000 --- a/src/ARCodeList.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - 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 ARCODELIST_H -#define ARCODELIST_H - -#include "types.h" - -#define ARCL_MAJOR 1 -#define ARCL_MINOR 1 - -class ARCodeList -{ -public: - // -}; - -#endif // ARCODELIST_H diff --git a/src/AREngine.cpp b/src/AREngine.cpp index 2b6df65..8ebf46c 100644 --- a/src/AREngine.cpp +++ b/src/AREngine.cpp @@ -25,119 +25,30 @@ namespace AREngine { -typedef struct -{ - u32 Code[2 * 64]; // TODO: more sensible size for this? allocate on demand? - bool Enabled; - -} CheatEntry; - -// TODO: more sensible size for this? allocate on demand? -CheatEntry CheatCodes[64]; -u32 NumCheatCodes; - - -void ParseTextCode(char* text, int tlen, u32* code, int clen) // or whatever this should be named? -{ - u32 cur_word = 0; - u32 ndigits = 0; - u32 nin = 0; - u32 nout = 0; - - char c; - while ((c = *text++) != '\0') - { - u32 val; - if (c >= '0' && c <= '9') - val = c - '0'; - else if (c >= 'a' && c <= 'f') - val = c - 'a' + 0xA; - else if (c >= 'A' && c <= 'F') - val = c - 'A' + 0xA; - else - continue; - - cur_word <<= 4; - cur_word |= val; - - ndigits++; - if (ndigits >= 8) - { - if (nout >= clen) - { - printf("AR: code too long!\n"); - return; - } - - *code++ = cur_word; - nout++; - - ndigits = 0; - cur_word = 0; - } - - nin++; - if (nin >= tlen) break; - } - - if (nout & 1) - { - printf("AR: code was missing one word\n"); - if (nout >= clen) - { - printf("AR: code too long!\n"); - return; - } - *code++ = 0; - } -} +// AR code file - frontend is responsible for managing this +ARCodeFile* CodeFile; bool Init() { + CodeFile = nullptr; + return true; } void DeInit() { - // } void Reset() { - memset(CheatCodes, 0, sizeof(CheatCodes)); - NumCheatCodes = 0; - - // TODO: acquire codes from a sensible source! - CheatEntry* entry = &CheatCodes[0]; - u32* ptr = &entry->Code[0]; - - /*char* test = R"(9209D09A 00000000 -6209B468 00000000 -B209B468 00000000 -10000672 000003FF -D2000000 00000000 -9209D09A 00000000 -94000130 FCBF0000 -6209B468 00000000 -B209B468 00000000 -200006B3 00000001 -200006B4 00000001 -D2000000 00000000 -9209D09A 00000000 -94000130 FC7F0000 -6209B468 00000000 -B209B468 00000000 -10000672 00000000 -D2000000 00000000)"; - ParseTextCode(test, entry->Code, 2*64); - printf("PARSED CODE:\n"); - for (int i = 0; i < 2*64; i+=2) - { - printf("%08X %08X\n", entry->Code[i], entry->Code[i+1]); - } - entry->Enabled = true; - NumCheatCodes++;*/ + CodeFile = nullptr; +} + + +void SetCodeFile(ARCodeFile* file) +{ + CodeFile = file; } @@ -147,9 +58,9 @@ D2000000 00000000)"; case ((x)+0x08): case ((x)+0x09): case ((x)+0x0A): case ((x)+0x0B): \ case ((x)+0x0C): case ((x)+0x0D): case ((x)+0x0E): case ((x)+0x0F) -void RunCheat(CheatEntry* entry) +void RunCheat(ARCode& arcode) { - u32* code = &entry->Code[0]; + u32* code = &arcode.Code[0]; u32 offset = 0; u32 datareg = 0; @@ -166,9 +77,11 @@ void RunCheat(CheatEntry* entry) for (;;) { + if (code >= &arcode.Code[arcode.CodeLen]) + break; + u32 a = *code++; u32 b = *code++; - if ((a|b) == 0) break; u8 op = a >> 24; @@ -179,7 +92,7 @@ void RunCheat(CheatEntry* entry) if ((op & 0xF0) == 0xE0) { for (u32 i = 0; i < b; i += 8) - *code += 2; + code += 2; } continue; @@ -428,7 +341,7 @@ void RunCheat(CheatEntry* entry) if (bytesleft > 0) { u8* leftover = (u8*)code; - *code += 2; + code += 2; if (bytesleft >= 4) { NDS::ARM7Write32(dstaddr, *(u32*)leftover); dstaddr += 4; @@ -477,13 +390,19 @@ void RunCheat(CheatEntry* entry) void RunCheats() { - // TODO: make it disableable in general + if (!CodeFile) return; - for (u32 i = 0; i < NumCheatCodes; i++) + for (ARCodeCatList::iterator i = CodeFile->Categories.begin(); i != CodeFile->Categories.end(); i++) { - CheatEntry* entry = &CheatCodes[i]; - if (entry->Enabled) - RunCheat(entry); + ARCodeCat& cat = *i; + + for (ARCodeList::iterator j = cat.Codes.begin(); j != cat.Codes.end(); j++) + { + ARCode& code = *j; + + if (code.Enabled) + RunCheat(code); + } } } diff --git a/src/AREngine.h b/src/AREngine.h index a78405f..3b1c5fa 100644 --- a/src/AREngine.h +++ b/src/AREngine.h @@ -19,6 +19,8 @@ #ifndef ARENGINE_H #define ARENGINE_H +#include "ARCodeFile.h" + namespace AREngine { @@ -26,6 +28,8 @@ bool Init(); void DeInit(); void Reset(); +void SetCodeFile(ARCodeFile* file); + void RunCheats(); } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dd81f52..24a7ecf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,7 +3,7 @@ project(core) set (CMAKE_CXX_STANDARD 14) add_library(core STATIC - ARCodeList.cpp + ARCodeFile.cpp AREngine.cpp ARM.cpp ARM_InstrTable.h diff --git a/src/frontend/qt_sdl/CheatsDialog.ui b/src/frontend/qt_sdl/CheatsDialog.ui index 3191ef2..493111d 100644 --- a/src/frontend/qt_sdl/CheatsDialog.ui +++ b/src/frontend/qt_sdl/CheatsDialog.ui @@ -74,6 +74,9 @@ 0 + + true + -- cgit v1.2.3 From f8d1d08e9c13d39ccb6d0c50ae74e7bbe9ed52c8 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 15 Aug 2020 00:14:05 +0200 Subject: (finally) build the goddamn cheat interface --- src/ARCodeFile.cpp | 61 +++--- src/ARCodeFile.h | 7 +- src/Config.cpp | 2 +- src/frontend/FrontendUtil.h | 6 + src/frontend/Util_ROM.cpp | 49 +++++ src/frontend/qt_sdl/CheatsDialog.cpp | 357 ++++++++++++++++++++++++++++++++- src/frontend/qt_sdl/CheatsDialog.h | 33 ++- src/frontend/qt_sdl/CheatsDialog.ui | 4 +- src/frontend/qt_sdl/PlatformConfig.cpp | 4 + src/frontend/qt_sdl/PlatformConfig.h | 2 + src/frontend/qt_sdl/main.cpp | 16 +- 11 files changed, 506 insertions(+), 35 deletions(-) (limited to 'src/frontend') diff --git a/src/ARCodeFile.cpp b/src/ARCodeFile.cpp index d2f47ff..57c710d 100644 --- a/src/ARCodeFile.cpp +++ b/src/ARCodeFile.cpp @@ -35,8 +35,21 @@ ARCodeFile::ARCodeFile(const char* filename) Categories.clear(); + if (!Load()) + Error = true; +} + +ARCodeFile::~ARCodeFile() +{ + Categories.clear(); +} + +bool ARCodeFile::Load() +{ FILE* f = Platform::OpenFile(Filename, "r"); - if (!f) return; + if (!f) return true; + + Categories.clear(); bool isincat = false; ARCodeCat curcat; @@ -60,15 +73,14 @@ ARCodeFile::ARCodeFile(const char* filename) if (!strncasecmp(start, "CAT", 3)) { char catname[128]; - int ret = sscanf(start, "CAT %127[^\n]", catname); + int ret = sscanf(start, "CAT %127[^\r\n]", catname); catname[127] = '\0'; if (ret < 1) { printf("AR: malformed CAT line: %s\n", start); fclose(f); - Error = true; - return; + return false; } if (isincode) curcat.Codes.push_back(curcode); @@ -84,23 +96,21 @@ ARCodeFile::ARCodeFile(const char* filename) { int enable; char codename[128]; - int ret = sscanf(start, "CODE %d %127[^\n]", &enable, codename); + int ret = sscanf(start, "CODE %d %127[^\r\n]", &enable, codename); codename[127] = '\0'; if (ret < 2) { printf("AR: malformed CODE line: %s\n", start); fclose(f); - Error = true; - return; + return false; } if (!isincat) { printf("AR: encountered CODE line with no category started\n"); fclose(f); - Error = true; - return; + return false; } if (isincode) curcat.Codes.push_back(curcode); @@ -119,24 +129,21 @@ ARCodeFile::ARCodeFile(const char* filename) { printf("AR: malformed data line: %s\n", start); fclose(f); - Error = true; - return; + return false; } if (!isincode) { printf("AR: encountered data line with no code started\n"); fclose(f); - Error = true; - return; + return false; } if (curcode.CodeLen >= 2*64) { printf("AR: code too long!\n"); fclose(f); - Error = true; - return; + return false; } u32 idx = curcode.CodeLen; @@ -150,27 +157,35 @@ ARCodeFile::ARCodeFile(const char* filename) if (isincat) Categories.push_back(curcat); fclose(f); + return true; +} + +bool ARCodeFile::Save() +{ + FILE* f = Platform::OpenFile(Filename, "w"); + if (!f) return false; - printf("PARSED OUTPUT\n"); for (ARCodeCatList::iterator it = Categories.begin(); it != Categories.end(); it++) { ARCodeCat& cat = *it; - printf("CAT %s\n", cat.Name); + + if (it != Categories.begin()) fprintf(f, "\n"); + fprintf(f, "CAT %s\n\n", cat.Name); for (ARCodeList::iterator jt = cat.Codes.begin(); jt != cat.Codes.end(); jt++) { ARCode& code = *jt; - printf("CODE %d %s\n", code.Enabled, code.Name); + fprintf(f, "CODE %d %s\n", code.Enabled, code.Name); for (u32 i = 0; i < code.CodeLen; i+=2) { - printf("%08X %08X\n", code.Code[i], code.Code[i+1]); + fprintf(f, "%08X %08X\n", code.Code[i], code.Code[i+1]); } + + fprintf(f, "\n"); } } -} -ARCodeFile::~ARCodeFile() -{ - // + fclose(f); + return true; } diff --git a/src/ARCodeFile.h b/src/ARCodeFile.h index 548bfeb..374c56e 100644 --- a/src/ARCodeFile.h +++ b/src/ARCodeFile.h @@ -19,7 +19,7 @@ #ifndef ARCODEFILE_H #define ARCODEFILE_H -#include +#include #include "types.h" @@ -32,7 +32,7 @@ typedef struct } ARCode; -typedef std::vector ARCodeList; +typedef std::list ARCodeList; typedef struct { @@ -41,7 +41,7 @@ typedef struct } ARCodeCat; -typedef std::vector ARCodeCatList; +typedef std::list ARCodeCatList; class ARCodeFile @@ -52,6 +52,7 @@ public: bool Error; + bool Load(); bool Save(); ARCodeCatList Categories; diff --git a/src/Config.cpp b/src/Config.cpp index de1c70d..d198093 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -104,7 +104,7 @@ void Load() while (!feof(f)) { fgets(linebuf, 1024, f); - int ret = sscanf(linebuf, "%31[A-Za-z_0-9]=%[^\t\n]", entryname, entryval); + int ret = sscanf(linebuf, "%31[A-Za-z_0-9]=%[^\t\r\n]", entryname, entryval); entryname[31] = '\0'; if (ret < 2) continue; diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index 099583f..d30c4e1 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,9 @@ bool SaveState(const char* filename); // undo the latest savestate load void UndoStateLoad(); +// 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..421a6e6 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,25 @@ int VerifyDSiNAND() return Load_OK; } +void LoadCheats() +{ + if (CheatFile) + { + delete CheatFile; + CheatFile = nullptr; + } + + char filename[1024]; + strncpy(filename, ROMPath[ROMSlot_NDS], 1023); + filename[1023] = '\0'; + strncpy(filename + strlen(ROMPath[ROMSlot_NDS]) - 3, "mch", 3); + + // TODO: check for error (malformed cheat file, ...) + CheatFile = new ARCodeFile(filename); + + AREngine::SetCodeFile(CheatsOn ? CheatFile : nullptr); +} + int LoadBIOS() { int res; @@ -235,6 +271,8 @@ int LoadBIOS() SavestateLoaded = false; + LoadCheats(); + return Load_OK; } @@ -295,6 +333,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 +427,8 @@ int Reset() return Load_ROMLoadError; } + LoadCheats(); + return Load_OK; } @@ -539,4 +581,11 @@ void UndoStateLoad() } } +void EnableCheats(bool enable) +{ + CheatsOn = enable; + if (CheatFile) + AREngine::SetCodeFile(CheatsOn ? CheatFile : nullptr); +} + } diff --git a/src/frontend/qt_sdl/CheatsDialog.cpp b/src/frontend/qt_sdl/CheatsDialog.cpp index 2654e75..05fedc5 100644 --- a/src/frontend/qt_sdl/CheatsDialog.cpp +++ b/src/frontend/qt_sdl/CheatsDialog.cpp @@ -18,6 +18,7 @@ #include #include +#include #include "types.h" #include "Platform.h" @@ -32,30 +33,380 @@ 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); - // setup UI here + 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() { - // save shit here + codeFile->Save(); closeDlg(); } void CheatsDialog::on_CheatsDialog_rejected() { - // don't save shit here + 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()) + { + parentitem = item; + } + else if (data.canConvert()) + { + parentitem = item->parent(); + } + else + { + printf("what?? :(\n"); + return; + } + + ARCodeCatList::iterator it_cat = parentitem->data().value(); + 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 it_cat = data.value(); + + (*it_cat).Codes.clear(); + codeFile->Categories.erase(it_cat); + + model->invisibleRootItem()->removeRow(item->row()); + } + else if (data.canConvert()) + { + ARCodeList::iterator it_code = data.value(); + ARCodeCatList::iterator it_cat = item->parent()->data().value(); + + (*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()) + { + ui->btnDeleteCode->setEnabled(true); + ui->txtCode->setEnabled(false); + ui->txtCode->setPlaceholderText(""); + ui->txtCode->clear(); + } + else if (data.canConvert()) + { + ARCode& code = *(data.value()); + + 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()) + { + ARCodeCat& cat = *(data.value()); + + 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()) + { + ARCode& code = *(data.value()); + + 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()) + 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()); + 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 index 99582c8..20f2c65 100644 --- a/src/frontend/qt_sdl/CheatsDialog.h +++ b/src/frontend/qt_sdl/CheatsDialog.h @@ -20,10 +20,31 @@ #define CHEATSDIALOG_H #include +#include +#include +#include +#include + +#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 @@ -54,12 +75,20 @@ 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 index 493111d..d0bc586 100644 --- a/src/frontend/qt_sdl/CheatsDialog.ui +++ b/src/frontend/qt_sdl/CheatsDialog.ui @@ -11,7 +11,7 @@ - AR cheat code editor - melonDS + Cheat code editor - melonDS @@ -36,7 +36,7 @@ - Delete code + Delete diff --git a/src/frontend/qt_sdl/PlatformConfig.cpp b/src/frontend/qt_sdl/PlatformConfig.cpp index bfb3f97..76c5f4b 100644 --- a/src/frontend/qt_sdl/PlatformConfig.cpp +++ b/src/frontend/qt_sdl/PlatformConfig.cpp @@ -72,6 +72,8 @@ char MicWavPath[1024]; char LastROMFolder[1024]; +int EnableCheats; + bool EnableJIT; ConfigEntry PlatformConfigFile[] = @@ -162,6 +164,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..bc9bba4 100644 --- a/src/frontend/qt_sdl/PlatformConfig.h +++ b/src/frontend/qt_sdl/PlatformConfig.h @@ -85,6 +85,8 @@ extern char MicWavPath[1024]; extern char LastROMFolder[1024]; +extern int EnableCheats; + } #endif // PLATFORMCONFIG_H diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 903e654..f91f879 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -1067,6 +1067,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) menu->addSeparator(); actEnableCheats = menu->addAction("Enable cheats"); + actEnableCheats->setCheckable(true); connect(actEnableCheats, &QAction::triggered, this, &MainWindow::onEnableCheats); actSetupCheats = menu->addAction("Setup cheat codes"); @@ -1218,6 +1219,10 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) actReset->setEnabled(false); actStop->setEnabled(false); + actSetupCheats->setEnabled(false); + + + actEnableCheats->setChecked(Config::EnableCheats != 0); actSavestateSRAMReloc->setChecked(Config::SavestateRelocSRAM != 0); @@ -1662,7 +1667,8 @@ void MainWindow::onStop() void MainWindow::onEnableCheats(bool checked) { - // + Config::EnableCheats = checked?1:0; + Frontend::EnableCheats(Config::EnableCheats != 0); } void MainWindow::onSetupCheats() @@ -1881,6 +1887,8 @@ void MainWindow::onEmuStart() actPause->setChecked(false); actReset->setEnabled(true); actStop->setEnabled(true); + + actSetupCheats->setEnabled(true); } void MainWindow::onEmuStop() @@ -1897,6 +1905,8 @@ void MainWindow::onEmuStop() actPause->setEnabled(false); actReset->setEnabled(false); actStop->setEnabled(false); + + actSetupCheats->setEnabled(false); } void MainWindow::onUpdateVideoSettings(bool glchange) @@ -2028,6 +2038,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) @@ -2084,6 +2096,8 @@ int main(int argc, char** argv) Input::CloseJoystick(); + Frontend::DeInit_ROM(); + if (audioDevice) SDL_CloseAudioDevice(audioDevice); if (micDevice) SDL_CloseAudioDevice(micDevice); -- cgit v1.2.3 From e27d55505f7cc7b1d351647777f0af45055050bc Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 15 Aug 2020 01:11:18 +0200 Subject: blarg --- src/frontend/Util_ROM.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/frontend') diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index 421a6e6..716ed04 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -224,9 +224,16 @@ void LoadCheats() } char filename[1024]; - strncpy(filename, ROMPath[ROMSlot_NDS], 1023); - filename[1023] = '\0'; - strncpy(filename + strlen(ROMPath[ROMSlot_NDS]) - 3, "mch", 3); + 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); -- cgit v1.2.3 From abccc44eecb943720993c5d3e89234f435770aee Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 24 Aug 2020 19:19:41 +0200 Subject: make MAC randomization optional --- src/Config.cpp | 2 + src/Config.h | 2 + src/SPI.cpp | 25 +++++++------ src/frontend/qt_sdl/WifiSettingsDialog.cpp | 59 ++++++++++++++++++++---------- src/frontend/qt_sdl/WifiSettingsDialog.h | 7 ++-- src/frontend/qt_sdl/WifiSettingsDialog.ui | 12 +++++- src/frontend/qt_sdl/main.cpp | 7 +++- 7 files changed, 77 insertions(+), 37 deletions(-) (limited to 'src/frontend') diff --git a/src/Config.cpp b/src/Config.cpp index d198093..2a98935 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -56,6 +56,8 @@ ConfigEntry ConfigFile[] = {"DSiFirmwarePath", 1, DSiFirmwarePath, 0, "", 1023}, {"DSiNANDPath", 1, DSiNANDPath, 0, "", 1023}, + {"RandomizeMAC", 0, &RandomizeMAC, 0, NULL, 0}, + #ifdef JIT_ENABLED {"JIT_Enable", 0, &JIT_Enable, 0, NULL, 0}, {"JIT_MaxBlockSize", 0, &JIT_MaxBlockSize, 32, NULL, 0}, diff --git a/src/Config.h b/src/Config.h index 5916b4a..a0f09dc 100644 --- a/src/Config.h +++ b/src/Config.h @@ -51,6 +51,8 @@ extern char DSiBIOS7Path[1024]; extern char DSiFirmwarePath[1024]; extern char DSiNANDPath[1024]; +extern int RandomizeMAC; + #ifdef JIT_ENABLED extern int JIT_Enable; extern int JIT_MaxBlockSize; diff --git a/src/SPI.cpp b/src/SPI.cpp index 1c88b58..2ba5e66 100644 --- a/src/SPI.cpp +++ b/src/SPI.cpp @@ -179,24 +179,25 @@ void Reset() //Firmware[userdata+0x64] &= 0xBF; *(u16*)&Firmware[userdata+0x72] = CRC16(&Firmware[userdata], 0x70, 0xFFFF); + + if (Config::RandomizeMAC) + { + // replace MAC address with random address + Firmware[0x36] = 0x00; + Firmware[0x37] = 0x09; + Firmware[0x38] = 0xBF; + Firmware[0x39] = rand()&0xFF; + Firmware[0x3A] = rand()&0xFF; + Firmware[0x3B] = rand()&0xFF; + + *(u16*)&Firmware[0x2A] = CRC16(&Firmware[0x2C], *(u16*)&Firmware[0x2C], 0x0000); + } } -#if 0 - // replace MAC address with random address - // TODO: make optional? - Firmware[0x36] = 0x00; - Firmware[0x37] = 0x09; - Firmware[0x38] = 0xBF; - Firmware[0x39] = rand()&0xFF; - Firmware[0x3A] = rand()&0xFF; - Firmware[0x3B] = rand()&0xFF; -#endif printf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", Firmware[0x36], Firmware[0x37], Firmware[0x38], Firmware[0x39], Firmware[0x3A], Firmware[0x3B]); - //*(u16*)&Firmware[0x2A] = CRC16(&Firmware[0x2C], *(u16*)&Firmware[0x2C], 0x0000); - // verify shit printf("FW: WIFI CRC16 = %s\n", VerifyCRC16(0x0000, 0x2C, *(u16*)&Firmware[0x2C], 0x2A)?"GOOD":"BAD"); printf("FW: AP1 CRC16 = %s\n", VerifyCRC16(0x0000, 0x7FA00&FirmwareMask, 0xFE, 0x7FAFE&FirmwareMask)?"GOOD":"BAD"); 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 -#include +#include #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 @@ 0 0 479 - 217 + 240 @@ -39,6 +39,16 @@ + + + + <html><head/><body><p>Randomizes the console's MAC address upon reset. Required for local multiplayer if each melonDS instance uses the same firmware file.</p></body></html> + + + Randomize MAC address + + + diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index f91f879..0228399 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -1747,14 +1747,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(); @@ -1764,6 +1764,9 @@ void MainWindow::onWifiSettingsFinished(int res) Platform::LAN_DeInit(); Platform::LAN_Init(); + if (WifiSettingsDialog::needsReset) + onReset(); + emuThread->emuUnpause(); } -- cgit v1.2.3 From e7025abcdc81f558706204375b753aad77490147 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 24 Aug 2020 19:32:07 +0200 Subject: * fix build error * make betterer polygon splitting an option * add GL_LEQUAL depth test for 'equal' mode, might help --- src/Config.cpp | 2 ++ src/GPU.h | 1 + src/GPU3D_OpenGL.cpp | 27 +++++++++++++++++++-------- src/frontend/qt_sdl/PlatformConfig.cpp | 4 ++-- src/frontend/qt_sdl/PlatformConfig.h | 2 +- src/frontend/qt_sdl/VideoSettingsDialog.cpp | 7 +++++++ src/frontend/qt_sdl/VideoSettingsDialog.h | 1 + src/frontend/qt_sdl/VideoSettingsDialog.ui | 12 +++++++++++- src/frontend/qt_sdl/main.cpp | 3 +++ 9 files changed, 47 insertions(+), 12 deletions(-) (limited to 'src/frontend') diff --git a/src/Config.cpp b/src/Config.cpp index 2a98935..949c1bf 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -37,6 +37,8 @@ char DSiBIOS7Path[1024]; char DSiFirmwarePath[1024]; char DSiNANDPath[1024]; +int RandomizeMAC; + #ifdef JIT_ENABLED int JIT_Enable = false; int JIT_MaxBlockSize = 32; diff --git a/src/GPU.h b/src/GPU.h index 039e065..c7d25ec 100644 --- a/src/GPU.h +++ b/src/GPU.h @@ -79,6 +79,7 @@ typedef struct bool Soft_Threaded; int GL_ScaleFactor; + bool GL_BetterPolygons; } RenderSettings; diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index ba77a0c..658b261 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -113,7 +113,7 @@ GLuint TexMemID; GLuint TexPalMemID; int ScaleFactor; -bool Antialias; +bool BetterPolygons; int ScreenW, ScreenH; GLuint FramebufferTex[8]; @@ -405,6 +405,7 @@ void SetRenderSettings(GPU::RenderSettings& settings) int scale = settings.GL_ScaleFactor; ScaleFactor = scale; + BetterPolygons = settings.GL_BetterPolygons; ScreenW = 256 * scale; ScreenH = 192 * scale; @@ -635,7 +636,7 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) { rp->PrimType = GL_TRIANGLES; - if (false) + if (!BetterPolygons) { // regular triangle-splitting @@ -835,6 +836,10 @@ void RenderSceneChunk(int y, int h) GLboolean fogenable = (RenderDispCnt & (1<<7)) ? GL_TRUE : GL_FALSE; + // TODO: proper 'equal' depth test! + // (has margin of +-0x200 in Z-buffer mode, +-0xFF in W-buffer mode) + // for now we're using GL_LEQUAL to make it work to some extent + // pass 1: opaque pixels UseRenderShader(flags); @@ -853,8 +858,10 @@ void RenderSceneChunk(int y, int h) if (rp->PolyData->IsShadowMask) { i++; continue; } - // zorp - glDepthFunc(GL_LESS); + if (rp->PolyData->Attr & (1<<14)) + glDepthFunc(GL_LEQUAL); + else + glDepthFunc(GL_LESS); u32 polyattr = rp->PolyData->Attr; u32 polyid = (polyattr >> 24) & 0x3F; @@ -939,8 +946,10 @@ void RenderSceneChunk(int y, int h) { UseRenderShader(flags | RenderFlag_Trans); - // zorp - glDepthFunc(GL_LESS); + if (rp->PolyData->Attr & (1<<14)) + glDepthFunc(GL_LEQUAL); + else + glDepthFunc(GL_LESS); u32 polyattr = rp->PolyData->Attr; u32 polyid = (polyattr >> 24) & 0x3F; @@ -1030,8 +1039,10 @@ void RenderSceneChunk(int y, int h) if (!(polyattr & (1<<15))) transfog = fogenable; else transfog = GL_FALSE; - // zorp - glDepthFunc(GL_LESS); + if (rp->PolyData->Attr & (1<<14)) + glDepthFunc(GL_LEQUAL); + else + glDepthFunc(GL_LESS); if (rp->PolyData->IsShadow) { diff --git a/src/frontend/qt_sdl/PlatformConfig.cpp b/src/frontend/qt_sdl/PlatformConfig.cpp index 76c5f4b..0628eaa 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; @@ -143,7 +143,7 @@ ConfigEntry PlatformConfigFile[] = {"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}, diff --git a/src/frontend/qt_sdl/PlatformConfig.h b/src/frontend/qt_sdl/PlatformConfig.h index bc9bba4..9deee7f 100644 --- a/src/frontend/qt_sdl/PlatformConfig.h +++ b/src/frontend/qt_sdl/PlatformConfig.h @@ -64,7 +64,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; diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.cpp b/src/frontend/qt_sdl/VideoSettingsDialog.cpp index ba433c3..ac1ed7a 100644 --- a/src/frontend/qt_sdl/VideoSettingsDialog.cpp +++ b/src/frontend/qt_sdl/VideoSettingsDialog.cpp @@ -167,3 +167,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..f18793c 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); 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 @@ 0 0 482 - 237 + 244 @@ -43,6 +43,16 @@ + + + + <html><head/><body><p>Enabling this may help reduce distortion on quads and more complex polygons, but may also reduce performance.</p></body></html> + + + Improved polygon splitting + + + diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 0228399..1e7e4a6 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -405,8 +405,11 @@ void EmuThread::run() 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); } -- cgit v1.2.3 From 13521211d2222304706490a36d635e319293214b Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 24 Aug 2020 19:32:44 +0200 Subject: make software renderer the default --- src/frontend/qt_sdl/PlatformConfig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/PlatformConfig.cpp b/src/frontend/qt_sdl/PlatformConfig.cpp index 0628eaa..990bf09 100644 --- a/src/frontend/qt_sdl/PlatformConfig.cpp +++ b/src/frontend/qt_sdl/PlatformConfig.cpp @@ -139,7 +139,7 @@ ConfigEntry PlatformConfigFile[] = {"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}, -- cgit v1.2.3 From 3685edeef2c3e73a8ebdd4ac0c473a8c570e563b Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 24 Aug 2020 20:03:24 +0200 Subject: make GL display also not default --- src/frontend/qt_sdl/PlatformConfig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/PlatformConfig.cpp b/src/frontend/qt_sdl/PlatformConfig.cpp index 990bf09..4468d0e 100644 --- a/src/frontend/qt_sdl/PlatformConfig.cpp +++ b/src/frontend/qt_sdl/PlatformConfig.cpp @@ -135,7 +135,7 @@ 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}, -- cgit v1.2.3 From f4427a89d031350d1f9d7257a080fe42019bf43d Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 24 Aug 2020 20:13:58 +0200 Subject: disable savestate menu items in DSi mode --- src/frontend/qt_sdl/main.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 1e7e4a6..c00a8ab 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -1880,14 +1880,27 @@ void MainWindow::onTitleUpdate(QString title) 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); -- cgit v1.2.3 From 31e83b2bf3cdc0a1562d6345a060680af49b79d6 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 24 Aug 2020 21:14:46 +0200 Subject: fix config file lookup. fixes #717 --- src/frontend/qt_sdl/Platform.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index 05a0c2d..b9d3235 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]); @@ -167,7 +167,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)); -- cgit v1.2.3 From b36b3feb7f4bc4434fd06c0f7179b8efaa936f58 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 24 Aug 2020 21:25:10 +0200 Subject: support .dsi extension for dragdrop/cmdline launching --- src/frontend/qt_sdl/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index c00a8ab..f8cdd24 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -1336,7 +1336,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(); } @@ -2085,7 +2085,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); -- cgit v1.2.3 From 4be68aafe081ffbd254c2e14b85ed0cb9faa6e6c Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 25 Aug 2020 00:34:57 +0200 Subject: make SD support actually be a thing --- src/Config.cpp | 4 ++ src/Config.h | 2 + src/DSi_SD.cpp | 22 ++++--- src/frontend/qt_sdl/EmuSettingsDialog.cpp | 22 ++++++- src/frontend/qt_sdl/EmuSettingsDialog.h | 1 + src/frontend/qt_sdl/EmuSettingsDialog.ui | 101 +++++++++++++++++++----------- 6 files changed, 108 insertions(+), 44 deletions(-) (limited to 'src/frontend') diff --git a/src/Config.cpp b/src/Config.cpp index 949c1bf..ea8dec7 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -36,6 +36,8 @@ char DSiBIOS9Path[1024]; char DSiBIOS7Path[1024]; char DSiFirmwarePath[1024]; char DSiNANDPath[1024]; +int DSiSDEnable; +char DSiSDPath[1024]; int RandomizeMAC; @@ -57,6 +59,8 @@ ConfigEntry ConfigFile[] = {"DSiBIOS7Path", 1, DSiBIOS7Path, 0, "", 1023}, {"DSiFirmwarePath", 1, DSiFirmwarePath, 0, "", 1023}, {"DSiNANDPath", 1, DSiNANDPath, 0, "", 1023}, + {"DSiSDEnable", 0, &DSiSDEnable, 0, NULL, 0}, + {"DSiSDPath", 1, DSiSDPath, 0, "", 1023}, {"RandomizeMAC", 0, &RandomizeMAC, 0, NULL, 0}, diff --git a/src/Config.h b/src/Config.h index a0f09dc..23db647 100644 --- a/src/Config.h +++ b/src/Config.h @@ -50,6 +50,8 @@ extern char DSiBIOS9Path[1024]; extern char DSiBIOS7Path[1024]; extern char DSiFirmwarePath[1024]; extern char DSiNANDPath[1024]; +extern int DSiSDEnable; +extern char DSiSDPath[1024]; extern int RandomizeMAC; diff --git a/src/DSi_SD.cpp b/src/DSi_SD.cpp index def7a33..45a597b 100644 --- a/src/DSi_SD.cpp +++ b/src/DSi_SD.cpp @@ -117,13 +117,19 @@ void DSi_SDHost::Reset() if (Num == 0) { - // TODO: eventually pull from host filesystem - /*DSi_MMCStorage* sd = new DSi_MMCStorage(this, false, "sd.bin"); - u8 sd_cid[16] = {0xBD, 0x12, 0x34, 0x56, 0x78, 0x03, 0x4D, 0x30, 0x30, 0x46, 0x50, 0x41, 0x00, 0x00, 0x15, 0x00}; - sd->SetCID(sd_cid);*/ - DSi_MMCStorage* sd = NULL; + DSi_MMCStorage* sd; + DSi_MMCStorage* mmc; - DSi_MMCStorage* mmc = new DSi_MMCStorage(this, true, Config::DSiNANDPath); + if (Config::DSiSDEnable) + { + sd = new DSi_MMCStorage(this, false, Config::DSiSDPath); + u8 sd_cid[16] = {0xBD, 0x12, 0x34, 0x56, 0x78, 0x03, 0x4D, 0x30, 0x30, 0x46, 0x50, 0x41, 0x00, 0x00, 0x15, 0x00}; + sd->SetCID(sd_cid); + } + else + sd = nullptr; + + mmc = new DSi_MMCStorage(this, true, Config::DSiNANDPath); mmc->SetCID(DSi::eMMC_CID); Ports[0] = sd; @@ -429,14 +435,14 @@ u16 DSi_SDHost::Read(u32 addr) if (!Num) { if (Ports[0]) // basic check of whether the SD card is inserted - ret |= 0x0030; + ret |= 0x00B0; else ret |= 0x0008; } else { // SDIO wifi is always inserted, I guess - ret |= 0x0030; + ret |= 0x00B0; } return ret; } diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.cpp b/src/frontend/qt_sdl/EmuSettingsDialog.cpp index dc7eaf5..483ce34 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.cpp +++ b/src/frontend/qt_sdl/EmuSettingsDialog.cpp @@ -49,6 +49,8 @@ EmuSettingsDialog::EmuSettingsDialog(QWidget* parent) : QDialog(parent), ui(new 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)"); @@ -145,6 +147,8 @@ void EmuSettingsDialog::done(int r) 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 @@ -161,7 +165,9 @@ void EmuSettingsDialog::done(int r) || 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", @@ -177,6 +183,8 @@ void EmuSettingsDialog::done(int r) 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; @@ -284,6 +292,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 1a16ebc..5814141 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.h +++ b/src/frontend/qt_sdl/EmuSettingsDialog.h @@ -63,6 +63,7 @@ private slots: 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..5b1bed5 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.ui +++ b/src/frontend/qt_sdl/EmuSettingsDialog.ui @@ -7,7 +7,7 @@ 0 0 514 - 359 + 407 @@ -191,13 +191,47 @@ DSi mode - - + + + + DSi NAND: + + + + + + + + 0 + 0 + + + + <html><head/><body><p>DSi-mode ARM9 BIOS</p><p><br/></p><p>Size should be 64 KB</p></body></html> + + + + + Browse... + + + + <html><head/><body><p>DSi-mode firmware (used for DS-mode backwards compatibility)</p><p><br/></p><p>Size should be 128 KB</p></body></html> + + + + + + + <html><head/><body><p>DSi-mode ARM7 BIOS</p><p><br/></p><p>Size should be 64 KB</p></body></html> + + + @@ -205,24 +239,24 @@ - - + + Browse... - - + + - <html><head/><body><p>DSi-mode ARM7 BIOS</p><p><br/></p><p>Size should be 64 KB</p></body></html> + <html><head/><body><p>DSi NAND dump</p><p><br/></p><p>Should have 'nocash footer' at the end</p></body></html> - - - - <html><head/><body><p>DSi-mode firmware (used for DS-mode backwards compatibility)</p><p><br/></p><p>Size should be 128 KB</p></body></html> + + + + DSi SD card: @@ -233,49 +267,46 @@ - - + + - DSi firmware: + Browse... - - + + Browse... - - - - - 0 - 0 - - - - <html><head/><body><p>DSi-mode ARM9 BIOS</p><p><br/></p><p>Size should be 64 KB</p></body></html> + + + + DSi firmware: - - + + + + <html><head/><body><p>Simulate a SD card being inserted in the DSi's SD slot. Requires a SD card image.</p></body></html> + - DSi NAND: + Enable DSi SD card - - + + - <html><head/><body><p>DSi NAND dump</p><p><br/></p><p>Should have 'nocash footer' at the end</p></body></html> + <html><head/><body><p>SD image file for emulating the DSi's SD card</p></body></html> - - + + Browse... -- cgit v1.2.3 From aed7a3224338e6b097aee324a4222e94f35277e8 Mon Sep 17 00:00:00 2001 From: v1993 Date: Mon, 31 Aug 2020 18:56:20 +0300 Subject: Fix "Improved polygon splitting" option in GUI --- src/frontend/qt_sdl/VideoSettingsDialog.cpp | 8 ++++++++ src/frontend/qt_sdl/VideoSettingsDialog.h | 1 + 2 files changed, 9 insertions(+) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.cpp b/src/frontend/qt_sdl/VideoSettingsDialog.cpp index ac1ed7a..971fee7 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); @@ -60,6 +61,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 +71,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 +104,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 +123,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); diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.h b/src/frontend/qt_sdl/VideoSettingsDialog.h index f18793c..2645eef 100644 --- a/src/frontend/qt_sdl/VideoSettingsDialog.h +++ b/src/frontend/qt_sdl/VideoSettingsDialog.h @@ -79,6 +79,7 @@ private: int oldVSyncInterval; int oldSoftThreaded; int oldGLScale; + int oldGLBetterPolygons; }; #endif // VIDEOSETTINGSDIALOG_H -- cgit v1.2.3 From 5431c469c3b3444d4ae0dc7677bb3a0588c5f88f Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 3 Sep 2020 20:28:07 +0200 Subject: actually add DLDI. bahahahhh --- src/CMakeLists.txt | 1 + src/Config.cpp | 4 + src/Config.h | 2 + src/NDS.cpp | 7 +- src/NDSCart.cpp | 281 +++++++++++----- src/NDSCart.h | 1 + src/frontend/qt_sdl/EmuSettingsDialog.cpp | 20 ++ src/frontend/qt_sdl/EmuSettingsDialog.h | 1 + src/frontend/qt_sdl/EmuSettingsDialog.ui | 522 ++++++++++++++++-------------- 9 files changed, 508 insertions(+), 331 deletions(-) (limited to 'src/frontend') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 24a7ecf..8839fc2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -33,6 +33,7 @@ add_library(core STATIC GPU3D_OpenGL.cpp GPU3D_OpenGL_shaders.h GPU3D_Soft.cpp + melonDLDI.h NDS.cpp NDSCart.cpp OpenGLSupport.cpp diff --git a/src/Config.cpp b/src/Config.cpp index ea8dec7..2c5fd2c 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -31,6 +31,8 @@ const char* kConfigFile = "melonDS.ini"; char BIOS9Path[1024]; char BIOS7Path[1024]; char FirmwarePath[1024]; +int DLDIEnable; +char DLDISDPath[1024]; char DSiBIOS9Path[1024]; char DSiBIOS7Path[1024]; @@ -54,6 +56,8 @@ ConfigEntry ConfigFile[] = {"BIOS9Path", 1, BIOS9Path, 0, "", 1023}, {"BIOS7Path", 1, BIOS7Path, 0, "", 1023}, {"FirmwarePath", 1, FirmwarePath, 0, "", 1023}, + {"DLDIEnable", 0, &DLDIEnable, 0, NULL, 0}, + {"DLDISDPath", 1, DLDISDPath, 0, "", 1023}, {"DSiBIOS9Path", 1, DSiBIOS9Path, 0, "", 1023}, {"DSiBIOS7Path", 1, DSiBIOS7Path, 0, "", 1023}, diff --git a/src/Config.h b/src/Config.h index 23db647..9fd7488 100644 --- a/src/Config.h +++ b/src/Config.h @@ -45,6 +45,8 @@ void Save(); extern char BIOS9Path[1024]; extern char BIOS7Path[1024]; extern char FirmwarePath[1024]; +extern int DLDIEnable; +extern char DLDISDPath[1024]; extern char DSiBIOS9Path[1024]; extern char DSiBIOS7Path[1024]; diff --git a/src/NDS.cpp b/src/NDS.cpp index a23772c..f926399 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -2537,7 +2537,8 @@ void ARM7Write8(u32 addr, u8 val) return; } - printf("unknown arm7 write8 %08X %02X @ %08X\n", addr, val, ARM7->R[15]); + if (ARM7->R[15] > 0x00002F30) // ARM7 BIOS bug + printf("unknown arm7 write8 %08X %02X @ %08X\n", addr, val, ARM7->R[15]); } void ARM7Write16(u32 addr, u16 val) @@ -3455,6 +3456,10 @@ void ARM9IOWrite32(u32 addr, u32 val) PowerControl9 = val & 0x820F; GPU::SetPowerCnt(PowerControl9); return; + + case 0x04100010: + NDSCart::WriteROMData(val); + return; } if (addr >= 0x04000000 && addr < 0x04000060) diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index a5e0f41..6abfc7c 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -25,7 +25,9 @@ #include "CRC32.h" #include "DSi_AES.h" #include "Platform.h" +#include "Config.h" #include "ROMList.h" +#include "melonDLDI.h" namespace NDSCart_SRAM @@ -464,11 +466,13 @@ u16 SPICnt; u32 ROMCnt; u8 ROMCommand[8]; -u32 ROMDataOut; +u32 ROMData; -u8 DataOut[0x4000]; -u32 DataOutPos; -u32 DataOutLen; +u8 TransferData[0x4000]; +u32 TransferPos; +u32 TransferLen; +u32 TransferDir; +u8 TransferCmd[8]; bool CartInserted; u8* CartROM; @@ -478,6 +482,8 @@ u32 CartID; bool CartIsHomebrew; bool CartIsDSi; +FILE* CartSD; + u32 CmdEncMode; u32 DataEncMode; @@ -489,6 +495,7 @@ u64 Key2_Y; void ROMCommand_Retail(u8* cmd); void ROMCommand_RetailNAND(u8* cmd); +void ROMCommand_Homebrew(u8* cmd); void (*ROMCommandHandler)(u8* cmd); @@ -615,6 +622,8 @@ bool Init() CartROM = NULL; + CartSD = NULL; + return true; } @@ -622,6 +631,8 @@ void DeInit() { if (CartROM) delete[] CartROM; + if (CartSD) fclose(CartSD); + NDSCart_SRAM::DeInit(); } @@ -635,6 +646,9 @@ void Reset() CartIsHomebrew = false; CartIsDSi = false; + if (CartSD) fclose(CartSD); + CartSD = NULL; + ROMCommandHandler = NULL; NDSCart_SRAM::Reset(); @@ -650,11 +664,13 @@ void DoSavestate(Savestate* file) file->Var32(&ROMCnt); file->VarArray(ROMCommand, 8); - file->Var32(&ROMDataOut); + file->Var32(&ROMData); - file->VarArray(DataOut, 0x4000); - file->Var32(&DataOutPos); - file->Var32(&DataOutLen); + file->VarArray(TransferData, 0x4000); + file->Var32(&TransferPos); + file->Var32(&TransferLen); + file->Var32(&TransferDir); + file->VarArray(TransferCmd, 8); // cart inserted/len/ROM/etc should be already populated // savestate should be loaded after the right game is loaded @@ -670,10 +686,8 @@ void DoSavestate(Savestate* file) } -void ApplyDLDIPatch() +void ApplyDLDIPatch(const u8* patch, u32 len) { - // TODO: embed patches? let the user choose? default to some builtin driver? - u32 offset = *(u32*)&CartROM[0x20]; u32 size = *(u32*)&CartROM[0x2C]; @@ -696,23 +710,7 @@ void ApplyDLDIPatch() return; } - printf("DLDI shit found at %08X (%08X)\n", dldioffset, offset+dldioffset); - - FILE* f = fopen("dldi.bin", "rb"); - if (!f) - { - printf("no DLDI patch available. oh well\n"); - return; - } - - u32 dldisize; - fseek(f, 0, SEEK_END); - dldisize = ftell(f); - fseek(f, 0, SEEK_SET); - - u8* patch = new u8[dldisize]; - fread(patch, dldisize, 1, f); - fclose(f); + printf("DLDI structure found at %08X (%08X)\n", dldioffset, offset+dldioffset); if (*(u32*)&patch[0] != 0xBF8DA5ED || *(u32*)&patch[4] != 0x69684320 || @@ -743,7 +741,7 @@ void ApplyDLDIPatch() u32 patchsize = 1 << patch[0x0D]; u32 patchend = patchbase + patchsize; - memcpy(&binary[dldioffset], patch, dldisize); + memcpy(&binary[dldioffset], patch, len); *(u32*)&binary[dldioffset+0x40] += delta; *(u32*)&binary[dldioffset+0x44] += delta; @@ -807,7 +805,6 @@ void ApplyDLDIPatch() memset(&binary[dldioffset+fixstart], 0, fixend-fixstart); } - delete[] patch; printf("applied DLDI patch\n"); } @@ -987,11 +984,13 @@ bool LoadROM(const char* path, const char* sram, bool direct) Key1_Encrypt((u32*)&CartROM[arm9base]); } } - else - { - CartIsHomebrew = true; - //ApplyDLDIPatch(); - } + } + + if ((arm9base < 0x4000) || (gamecode == 0x23232323)) + { + CartIsHomebrew = true; + if (Config::DLDIEnable) + ApplyDLDIPatch(melonDLDI, sizeof(melonDLDI)); } if (direct) @@ -1005,7 +1004,9 @@ bool LoadROM(const char* path, const char* sram, bool direct) CartInserted = true; // TODO: support more fancy cart types (homebrew?, flashcarts, etc) - if (CartID & 0x08000000) + if (CartIsHomebrew) + ROMCommandHandler = ROMCommand_Homebrew; + else if (CartID & 0x08000000) ROMCommandHandler = ROMCommand_RetailNAND; else ROMCommandHandler = ROMCommand_Retail; @@ -1017,6 +1018,13 @@ bool LoadROM(const char* path, const char* sram, bool direct) printf("Save file: %s\n", sram); NDSCart_SRAM::LoadSave(sram, romparams.SaveMemType); + if (CartIsHomebrew && Config::DLDIEnable) + { + CartSD = Platform::OpenLocalFile(Config::DLDISDPath, "r+b"); + } + else + CartSD = NULL; + return true; } @@ -1034,14 +1042,17 @@ void ResetCart() ROMCnt = 0; memset(ROMCommand, 0, 8); - ROMDataOut = 0; + ROMData = 0; Key2_X = 0; Key2_Y = 0; - memset(DataOut, 0, 0x4000); - DataOutPos = 0; - DataOutLen = 0; + memset(TransferData, 0, 0x4000); + TransferPos = 0; + TransferLen = 0; + TransferDir = 0; + memset(TransferCmd, 0, 8); + TransferCmd[0] = 0xFF; CmdEncMode = 0; DataEncMode = 0; @@ -1055,7 +1066,7 @@ void ReadROM(u32 addr, u32 len, u32 offset) if ((addr+len) > CartROMSize) len = CartROMSize - addr; - memcpy(DataOut+offset, CartROM+addr, len); + memcpy(TransferData+offset, CartROM+addr, len); } void ReadROM_B7(u32 addr, u32 len, u32 offset) @@ -1069,7 +1080,7 @@ void ReadROM_B7(u32 addr, u32 len, u32 offset) addr = 0x8000 + (addr & 0x1FF); } - memcpy(DataOut+offset, CartROM+addr, len); + memcpy(TransferData+offset, CartROM+addr, len); } @@ -1079,16 +1090,41 @@ void ROMEndTransfer(u32 param) if (SPICnt & (1<<14)) NDS::SetIRQ((NDS::ExMemCnt[0]>>11)&0x1, NDS::IRQ_CartSendDone); + + if (TransferDir == 1) + { + // finish a write + + u8* cmd = TransferCmd; + switch (cmd[0]) + { + case 0xC1: + { + u32 sector = (cmd[1]<<24) | (cmd[2]<<16) | (cmd[3]<<8) | cmd[4]; + u64 addr = sector * 0x200ULL; + + if (CartSD) + { + fseek(CartSD, addr, SEEK_SET); + fwrite(TransferData, TransferLen, 1, CartSD); + } + } + break; + } + } } void ROMPrepareData(u32 param) { - if (DataOutPos >= DataOutLen) - ROMDataOut = 0; - else - ROMDataOut = *(u32*)&DataOut[DataOutPos]; + if (TransferDir == 0) + { + if (TransferPos >= TransferLen) + ROMData = 0; + else + ROMData = *(u32*)&TransferData[TransferPos]; - DataOutPos += 4; + TransferPos += 4; + } ROMCnt |= (1<<23); @@ -1106,16 +1142,16 @@ void ROMCommand_Retail(u8* cmd) case 0xB7: { u32 addr = (cmd[1]<<24) | (cmd[2]<<16) | (cmd[3]<<8) | cmd[4]; - memset(DataOut, 0, DataOutLen); + memset(TransferData, 0, TransferLen); - if (((addr + DataOutLen - 1) >> 12) != (addr >> 12)) + if (((addr + TransferLen - 1) >> 12) != (addr >> 12)) { u32 len1 = 0x1000 - (addr & 0xFFF); ReadROM_B7(addr, len1, 0); - ReadROM_B7(addr+len1, DataOutLen-len1, len1); + ReadROM_B7(addr+len1, TransferLen-len1, len1); } else - ReadROM_B7(addr, DataOutLen, 0); + ReadROM_B7(addr, TransferLen, 0); } break; @@ -1136,8 +1172,8 @@ void ROMCommand_RetailNAND(u8* cmd) // Jam with the Band stores words 6-9 of this at 0x02131BB0 // it doesn't seem to use those anywhere later - for (u32 pos = 0; pos < DataOutLen; pos += 4) - *(u32*)&DataOut[pos] = 0; + for (u32 pos = 0; pos < TransferLen; pos += 4) + *(u32*)&TransferData[pos] = 0; } break; @@ -1150,16 +1186,16 @@ void ROMCommand_RetailNAND(u8* cmd) case 0xB7: { u32 addr = (cmd[1]<<24) | (cmd[2]<<16) | (cmd[3]<<8) | cmd[4]; - memset(DataOut, 0, DataOutLen); + memset(TransferData, 0, TransferLen); - if (((addr + DataOutLen - 1) >> 12) != (addr >> 12)) + if (((addr + TransferLen - 1) >> 12) != (addr >> 12)) { u32 len1 = 0x1000 - (addr & 0xFFF); ReadROM_B7(addr, len1, 0); - ReadROM_B7(addr+len1, DataOutLen-len1, len1); + ReadROM_B7(addr+len1, TransferLen-len1, len1); } else - ReadROM_B7(addr, DataOutLen, 0); + ReadROM_B7(addr, TransferLen, 0); } break; @@ -1169,13 +1205,59 @@ void ROMCommand_RetailNAND(u8* cmd) // * bit7: busy? error? // * bit5: accessing savemem - for (u32 pos = 0; pos < DataOutLen; pos += 4) - *(u32*)&DataOut[pos] = NDSCart_SRAM::StatusReg * 0x01010101; + for (u32 pos = 0; pos < TransferLen; pos += 4) + *(u32*)&TransferData[pos] = NDSCart_SRAM::StatusReg * 0x01010101; + } + break; + + default: + printf("unknown NAND command %02X %04Xn", cmd[0], TransferLen); + break; + } +} + +void ROMCommand_Homebrew(u8* cmd) +{ + switch (cmd[0]) + { + case 0xB7: + { + u32 addr = (cmd[1]<<24) | (cmd[2]<<16) | (cmd[3]<<8) | cmd[4]; + memset(TransferData, 0, TransferLen); + + if (((addr + TransferLen - 1) >> 12) != (addr >> 12)) + { + u32 len1 = 0x1000 - (addr & 0xFFF); + ReadROM_B7(addr, len1, 0); + ReadROM_B7(addr+len1, TransferLen-len1, len1); + } + else + ReadROM_B7(addr, TransferLen, 0); + } + break; + + case 0xC0: // SD read + { + u32 sector = (cmd[1]<<24) | (cmd[2]<<16) | (cmd[3]<<8) | cmd[4]; + u64 addr = sector * 0x200ULL; + + if (CartSD) + { + fseek(CartSD, addr, SEEK_SET); + fread(TransferData, TransferLen, 1, CartSD); + } + } + break; + + case 0xC1: // SD write + { + TransferDir = 1; + memcpy(TransferCmd, cmd, 8); } break; default: - printf("unknown NAND command %02X %04Xn", cmd[0], DataOutLen); + printf("unknown homebrew cart command %02X\n", cmd[0]); break; } } @@ -1215,8 +1297,8 @@ void WriteROMCnt(u32 val) else if (datasize > 0) datasize = 0x100 << datasize; - DataOutPos = 0; - DataOutLen = datasize; + TransferPos = 0; + TransferLen = datasize; // handle KEY1 encryption as needed. // KEY2 encryption is implemented in hardware and doesn't need to be handled. @@ -1242,28 +1324,32 @@ void WriteROMCnt(u32 val) cmd[4], cmd[5], cmd[6], cmd[7], datasize);*/ + // default is read + // commands that do writes will change this + TransferDir = 0; + switch (cmd[0]) { case 0x9F: - memset(DataOut, 0xFF, DataOutLen); + memset(TransferData, 0xFF, TransferLen); break; case 0x00: - memset(DataOut, 0, DataOutLen); - if (DataOutLen > 0x1000) + memset(TransferData, 0, TransferLen); + if (TransferLen > 0x1000) { ReadROM(0, 0x1000, 0); - for (u32 pos = 0x1000; pos < DataOutLen; pos += 0x1000) - memcpy(DataOut+pos, DataOut, 0x1000); + for (u32 pos = 0x1000; pos < TransferLen; pos += 0x1000) + memcpy(TransferData+pos, TransferData, 0x1000); } else - ReadROM(0, DataOutLen, 0); + ReadROM(0, TransferLen, 0); break; case 0x90: case 0xB8: - for (u32 pos = 0; pos < DataOutLen; pos += 4) - *(u32*)&DataOut[pos] = CartID; + for (u32 pos = 0; pos < TransferLen; pos += 4) + *(u32*)&TransferData[pos] = CartID; break; case 0x3C: @@ -1292,8 +1378,8 @@ void WriteROMCnt(u32 val) break; case 0x10: - for (u32 pos = 0; pos < DataOutLen; pos += 4) - *(u32*)&DataOut[pos] = CartID; + for (u32 pos = 0; pos < TransferLen; pos += 4) + *(u32*)&TransferData[pos] = CartID; break; case 0x20: @@ -1343,29 +1429,52 @@ void WriteROMCnt(u32 val) NDS::ScheduleEvent(NDS::Event_ROMTransfer, false, xfercycle*(cmddelay+4), ROMPrepareData, 0); } +void AdvanceROMTransfer() +{ + ROMCnt &= ~(1<<23); + + if (TransferPos < TransferLen) + { + u32 xfercycle = (ROMCnt & (1<<27)) ? 8 : 5; + u32 delay = 4; + if (!(ROMCnt & (1<<30))) + { + if (!(TransferPos & 0x1FF)) + delay += ((ROMCnt >> 16) & 0x3F); + } + + NDS::ScheduleEvent(NDS::Event_ROMTransfer, false, xfercycle*delay, ROMPrepareData, 0); + } + else + ROMEndTransfer(0); +} + u32 ReadROMData() { if (ROMCnt & (1<<23)) { - ROMCnt &= ~(1<<23); + AdvanceROMTransfer(); + } + + return ROMData; +} - if (DataOutPos < DataOutLen) +void WriteROMData(u32 val) +{ + ROMData = val; + + if (ROMCnt & (1<<23)) + { + if (TransferDir == 1) { - u32 xfercycle = (ROMCnt & (1<<27)) ? 8 : 5; - u32 delay = 4; - if (!(ROMCnt & (1<<30))) - { - if (!(DataOutPos & 0x1FF)) - delay += ((ROMCnt >> 16) & 0x3F); - } + if (TransferPos < TransferLen) + *(u32*)&TransferData[TransferPos] = ROMData; - NDS::ScheduleEvent(NDS::Event_ROMTransfer, false, xfercycle*delay, ROMPrepareData, 0); + TransferPos += 4; } - else - ROMEndTransfer(0); - } - return ROMDataOut; + AdvanceROMTransfer(); + } } diff --git a/src/NDSCart.h b/src/NDSCart.h index adc821f..a759c15 100644 --- a/src/NDSCart.h +++ b/src/NDSCart.h @@ -52,6 +52,7 @@ void ResetCart(); void WriteROMCnt(u32 val); u32 ReadROMData(); +void WriteROMData(u32 val); void WriteSPICnt(u16 val); u8 ReadSPIData(); diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.cpp b/src/frontend/qt_sdl/EmuSettingsDialog.cpp index 483ce34..79ce5ed 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.cpp +++ b/src/frontend/qt_sdl/EmuSettingsDialog.cpp @@ -44,6 +44,8 @@ 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); @@ -143,6 +145,8 @@ 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(); @@ -162,6 +166,8 @@ 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 @@ -178,6 +184,8 @@ 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'; @@ -268,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, diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.h b/src/frontend/qt_sdl/EmuSettingsDialog.h index 5814141..158793c 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.h +++ b/src/frontend/qt_sdl/EmuSettingsDialog.h @@ -58,6 +58,7 @@ 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(); diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.ui b/src/frontend/qt_sdl/EmuSettingsDialog.ui index 5b1bed5..ac5506f 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.ui +++ b/src/frontend/qt_sdl/EmuSettingsDialog.ui @@ -6,8 +6,8 @@ 0 0 - 514 - 407 + 575 + 254 @@ -86,240 +86,242 @@ - BIOS Files + DS-mode - - - - - DS mode - - - - - - DS firmware: - - - - - - - <html><head/><body><p>DS-mode firmware</p><p><br/></p><p>Possible firmwares:</p><p>* 128 KB: DS-mode firmware from a DSi or 3DS. Not bootable.</p><p>* 256 KB: regular DS firmware.</p><p>* 512 KB: iQue DS firmware.</p></body></html> - - - - - - - <html><head/><body><p>DS-mode ARM7 BIOS</p><p>Size should be 16 KB</p></body></html> - - - - - - - - 0 - 0 - - - - Browse... - - - true - - - - - - - Browse... - - - - - - - DS ARM7 BIOS: - - - - - - - DS ARM9 BIOS: - - - - - - - Browse... - - - - - - - - 0 - 0 - - - - - 290 - 0 - - - - - - - <html><head/><body><p>DS-mode ARM9 BIOS</p><p>Size should be 4 KB</p></body></html> - - - - - - - - - - DSi mode - - - - - - DSi NAND: - - - - - - - - 0 - 0 - - - - <html><head/><body><p>DSi-mode ARM9 BIOS</p><p><br/></p><p>Size should be 64 KB</p></body></html> - - - - - - - Browse... - - - - - - - <html><head/><body><p>DSi-mode firmware (used for DS-mode backwards compatibility)</p><p><br/></p><p>Size should be 128 KB</p></body></html> - - - - - - - <html><head/><body><p>DSi-mode ARM7 BIOS</p><p><br/></p><p>Size should be 64 KB</p></body></html> - - - - - - - DSi ARM9 BIOS: - - - - - - - Browse... - - - - - - - <html><head/><body><p>DSi NAND dump</p><p><br/></p><p>Should have 'nocash footer' at the end</p></body></html> - - - - - - - DSi SD card: - - - - - - - DSi ARM7 BIOS: - - - - - - - Browse... - - - - - - - Browse... - - - - - - - DSi firmware: - - - - - - - <html><head/><body><p>Simulate a SD card being inserted in the DSi's SD slot. Requires a SD card image.</p></body></html> - - - Enable DSi SD card - - - - - - - <html><head/><body><p>SD image file for emulating the DSi's SD card</p></body></html> - - - - - - - Browse... - - - - + + + + + <html><head/><body><p>DS-mode ARM7 BIOS</p><p>Size should be 16 KB</p></body></html> + + + + + + + <html><head/><body><p>DS-mode firmware</p><p><br/></p><p>Possible firmwares:</p><p>* 128 KB: DS-mode firmware from a DSi or 3DS. Not bootable.</p><p>* 256 KB: regular DS firmware.</p><p>* 512 KB: iQue DS firmware.</p></body></html> + + + + + + + DS firmware: + + + + + + + DS ARM7 BIOS: + + + + + + + Browse... + + + + + + + Browse... + + + + + + + + 0 + 0 + + + + Browse... + + + true + + + + + + + DS ARM9 BIOS: + + + + + + + + 0 + 0 + + + + + 290 + 0 + + + + + + + <html><head/><body><p>DS-mode ARM9 BIOS</p><p>Size should be 4 KB</p></body></html> + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + DSi-mode + + + + + + <html><head/><body><p>DSi-mode ARM7 BIOS</p><p><br/></p><p>Size should be 64 KB</p></body></html> + + + + + + + Browse... + + + + + + + DSi NAND: + + + + + + + Browse... + + + + + + + DSi ARM7 BIOS: + + + + + + + Browse... + + + + + + + <html><head/><body><p>DSi NAND dump</p><p><br/></p><p>Should have 'nocash footer' at the end</p></body></html> + + + + + + + Browse... + + + + + + + DSi SD card: + + + + + + + + 0 + 0 + + + + <html><head/><body><p>DSi-mode ARM9 BIOS</p><p><br/></p><p>Size should be 64 KB</p></body></html> + + + + + + + DSi firmware: + + + + + + + DSi ARM9 BIOS: + + + + + + + <html><head/><body><p>DSi-mode firmware (used for DS-mode backwards compatibility)</p><p><br/></p><p>Size should be 128 KB</p></body></html> + + + + + + + <html><head/><body><p>SD image file for emulating the DSi's SD card</p></body></html> + + + + + + + <html><head/><body><p>Simulate a SD card being inserted in the DSi's SD slot. Requires a SD card image.</p></body></html> + + + Enable DSi SD card + + + + + + + Browse... + - CPU Emulation + CPU emulation @@ -385,6 +387,53 @@ + + + DLDI + + + + + + <html><head/><body><p>Enable the built-in DLDI driver, to let homebrew access files from a given SD image.</p></body></html> + + + Enable DLDI (for homebrew) + + + + + + + Browse... + + + + + + + + + + DLDI SD card: + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + @@ -400,23 +449,8 @@ - tabWidget cbxConsoleType chkDirectBoot - txtBIOS9Path - txtBIOS7Path - txtFirmwarePath - txtDSiBIOS9Path - txtDSiBIOS7Path - txtDSiFirmwarePath - txtDSiNANDPath - btnBIOS9Browse - btnBIOS7Browse - btnFirmwareBrowse - btnDSiBIOS9Browse - btnDSiBIOS7Browse - btnDSiFirmwareBrowse - btnDSiNANDBrowse chkEnableJIT spnJITMaximumBlockSize -- cgit v1.2.3 From 94d12c68b3cc8240d52c4123cf804641fa66b40a Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 4 Sep 2020 13:41:51 +0200 Subject: heh --- README.md | 2 +- src/frontend/qt_sdl/Platform.cpp | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'src/frontend') diff --git a/README.md b/README.md index cc53fa8..61532a9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

melonDS

- +

diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index b9d3235..a716feb 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -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; } -- cgit v1.2.3 From ea640398f9d2a28a8807e618ab79c5b6a7960d00 Mon Sep 17 00:00:00 2001 From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com> Date: Sun, 6 Sep 2020 21:59:35 +0100 Subject: Add support for fullscreen hotkey (#748) --- src/frontend/qt_sdl/InputConfigDialog.cpp | 6 ++++-- src/frontend/qt_sdl/InputConfigDialog.h | 2 +- src/frontend/qt_sdl/PlatformConfig.cpp | 2 ++ src/frontend/qt_sdl/PlatformConfig.h | 1 + src/frontend/qt_sdl/main.cpp | 17 +++++++++++++++++ src/frontend/qt_sdl/main.h | 4 ++++ 6 files changed, 29 insertions(+), 3 deletions(-) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/InputConfigDialog.cpp b/src/frontend/qt_sdl/InputConfigDialog.cpp index 81baa65..2292441 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) 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/PlatformConfig.cpp b/src/frontend/qt_sdl/PlatformConfig.cpp index 4468d0e..c2d40c4 100644 --- a/src/frontend/qt_sdl/PlatformConfig.cpp +++ b/src/frontend/qt_sdl/PlatformConfig.cpp @@ -110,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}, @@ -119,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}, diff --git a/src/frontend/qt_sdl/PlatformConfig.h b/src/frontend/qt_sdl/PlatformConfig.h index 9deee7f..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 diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index f8cdd24..9d2a2ca 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -266,6 +266,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(); } @@ -364,6 +365,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) { @@ -1878,6 +1881,20 @@ 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() { // TODO: make savestates work in DSi mode!! diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index cad30d6..6ae5122 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; @@ -229,6 +231,8 @@ private slots: void onEmuStop(); void onUpdateVideoSettings(bool glchange); + + void onFullscreenToggled(); private: void createScreenPanel(); -- cgit v1.2.3 From f2fa52f26ceb1f385d58e57ab26ca7d5349978d2 Mon Sep 17 00:00:00 2001 From: RSDuck Date: Fri, 11 Sep 2020 03:08:06 +0200 Subject: add functionality to import savefiles --- src/NDS.cpp | 5 +++++ src/NDS.h | 2 ++ src/NDSCart.cpp | 6 ++++++ src/NDSCart.h | 2 ++ src/frontend/FrontendUtil.h | 3 +++ src/frontend/Util_ROM.cpp | 15 +++++++++++++++ src/frontend/qt_sdl/main.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ src/frontend/qt_sdl/main.h | 2 ++ 8 files changed, 76 insertions(+) (limited to 'src/frontend') diff --git a/src/NDS.cpp b/src/NDS.cpp index 20f149a..90149ad 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -1124,6 +1124,11 @@ void MicInputFrame(s16* data, int samples) return SPI_TSC::MicInputFrame(data, samples); } +int ImportSRAM(u8* data, u32 length) +{ + return NDSCart::ImportSRAM(data, length); +} + void Halt() { diff --git a/src/NDS.h b/src/NDS.h index 91bfd1c..046d84b 100644 --- a/src/NDS.h +++ b/src/NDS.h @@ -211,6 +211,8 @@ void SetLidClosed(bool closed); void MicInputFrame(s16* data, int samples); +int ImportSRAM(u8* data, u32 length); + void ScheduleEvent(u32 id, bool periodic, s32 delay, void (*func)(u32), u32 param); void CancelEvent(u32 id); diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index 6abfc7c..5710213 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -1034,6 +1034,12 @@ void RelocateSave(const char* path, bool write) NDSCart_SRAM::RelocateSave(path, write); } +int ImportSRAM(const u8* data, u32 length) +{ + memcpy(NDSCart_SRAM::SRAM, data, std::min(length, NDSCart_SRAM::SRAMLength)); + return length - NDSCart_SRAM::SRAMLength; +} + void ResetCart() { // CHECKME: what if there is a transfer in progress? diff --git a/src/NDSCart.h b/src/NDSCart.h index a759c15..9fe916d 100644 --- a/src/NDSCart.h +++ b/src/NDSCart.h @@ -48,6 +48,8 @@ void DecryptSecureArea(u8* out); bool LoadROM(const char* path, const char* sram, bool direct); void RelocateSave(const char* path, bool write); +int ImportSRAM(const u8* data, u32 length); + void ResetCart(); void WriteROMCnt(u32 val); diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index d30c4e1..caac9f0 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -100,6 +100,9 @@ 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); diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index 716ed04..f61c3e3 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -588,6 +588,21 @@ 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; diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 9d2a2ca..1900998 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -1052,6 +1052,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"); @@ -1220,6 +1223,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) actLoadState[i]->setEnabled(false); } actUndoStateLoad->setEnabled(false); + actImportSavefile->setEnabled(false); actPause->setEnabled(false); actReset->setEnabled(false); @@ -1618,6 +1622,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(); @@ -1923,6 +1962,7 @@ void MainWindow::onEmuStart() actPause->setChecked(false); actReset->setEnabled(true); actStop->setEnabled(true); + actImportSavefile->setEnabled(true); actSetupCheats->setEnabled(true); } @@ -1937,6 +1977,7 @@ void MainWindow::onEmuStop() actLoadState[i]->setEnabled(false); } actUndoStateLoad->setEnabled(false); + actImportSavefile->setEnabled(false); actPause->setEnabled(false); actReset->setEnabled(false); diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 6ae5122..978df9e 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -195,6 +195,7 @@ private slots: void onSaveState(); void onLoadState(); void onUndoStateLoad(); + void onImportSavefile(); void onQuit(); void onPause(bool checked); @@ -247,6 +248,7 @@ public: QAction* actSaveState[9]; QAction* actLoadState[9]; QAction* actUndoStateLoad; + QAction* actImportSavefile; QAction* actQuit; QAction* actPause; -- cgit v1.2.3 From 697730240394cd9fedcf7924f29ffa625fc784fd Mon Sep 17 00:00:00 2001 From: RSDuck Date: Wed, 30 Sep 2020 23:58:42 +0200 Subject: make OpenGL renderer a build option mostly meant for the Switch port --- CMakeLists.txt | 6 ++++++ src/CMakeLists.txt | 31 ++++++++++++++++++++--------- src/GPU.cpp | 13 ++++++++++-- src/GPU.h | 2 ++ src/GPU2D.cpp | 2 ++ src/GPU3D.cpp | 6 ++++++ src/GPU3D.h | 2 ++ src/frontend/qt_sdl/VideoSettingsDialog.cpp | 4 ++++ src/frontend/qt_sdl/main.cpp | 12 +++++++++++ 9 files changed, 67 insertions(+), 11 deletions(-) (limited to 'src/frontend') diff --git a/CMakeLists.txt b/CMakeLists.txt index 6729e73..8b8d699 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,12 @@ else() option(ENABLE_LTO "Enable link-time optimization" OFF) endif() +option(ENABLE_OGLRENDERER "Enable OpenGL renderer" ON) + +if (ENABLE_OGLRENDERER) + add_definitions(-DOGLRENDERER_ENABLED) +endif() + if (CMAKE_BUILD_TYPE STREQUAL Debug) add_compile_options(-Og) endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8839fc2..d6c3897 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,17 +26,12 @@ add_library(core STATIC FIFO.h GBACart.cpp GPU.cpp - GPU_OpenGL.cpp - GPU_OpenGL_shaders.h GPU2D.cpp GPU3D.cpp - GPU3D_OpenGL.cpp - GPU3D_OpenGL_shaders.h GPU3D_Soft.cpp melonDLDI.h NDS.cpp NDSCart.cpp - OpenGLSupport.cpp Platform.h ROMList.h RTC.cpp @@ -52,6 +47,16 @@ add_library(core STATIC xxhash/xxhash.c ) +if (ENABLE_OGLRENDERER) + target_sources(core PRIVATE + GPU_OpenGL.cpp + GPU_OpenGL_shaders.h + GPU3D_OpenGL.cpp + GPU3D_OpenGL_shaders.h + OpenGLSupport.cpp + ) +endif() + if (ENABLE_JIT) enable_language(ASM) @@ -95,8 +100,16 @@ if (ENABLE_JIT) endif() endif() -if (WIN32) - target_link_libraries(core ole32 comctl32 ws2_32 opengl32) +if (ENABLE_OGLRENDERER) + if (WIN32) + target_link_libraries(core ole32 comctl32 ws2_32 opengl32) + else() + target_link_libraries(core GL EGL) + endif() else() - target_link_libraries(core GL EGL) -endif() + if (WIN32) + target_link_libraries(core ole32 comctl32 ws2_32) + else() + target_link_libraries(core) + endif() +endif() \ No newline at end of file diff --git a/src/GPU.cpp b/src/GPU.cpp index 29867db..7989750 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -280,6 +280,7 @@ void AssignFramebuffers() void InitRenderer(int renderer) { +#ifdef OGLRENDERER_ENABLED if (renderer == 1) { if (!GLCompositor::Init()) @@ -292,8 +293,8 @@ void InitRenderer(int renderer) renderer = 0; } } - - if (renderer == 0) + else +#endif { GPU3D::SoftRenderer::Init(); } @@ -308,11 +309,13 @@ void DeInitRenderer() { GPU3D::SoftRenderer::DeInit(); } +#ifdef OGLRENDERER_ENABLED else { GPU3D::GLRenderer::DeInit(); GLCompositor::DeInit(); } +#endif } void ResetRenderer() @@ -321,11 +324,13 @@ void ResetRenderer() { GPU3D::SoftRenderer::Reset(); } +#ifdef OGLRENDERER_ENABLED else { GLCompositor::Reset(); GPU3D::GLRenderer::Reset(); } +#endif } void SetRenderSettings(int renderer, RenderSettings& settings) @@ -364,11 +369,13 @@ void SetRenderSettings(int renderer, RenderSettings& settings) { GPU3D::SoftRenderer::SetRenderSettings(settings); } +#ifdef OGLRENDERER_ENABLED else { GLCompositor::SetRenderSettings(settings); GPU3D::GLRenderer::SetRenderSettings(settings); } +#endif } @@ -1055,7 +1062,9 @@ void StartScanline(u32 line) GPU2D_B->VBlank(); GPU3D::VBlank(); +#ifdef OGLRENDERER_ENABLED if (Accelerated) GLCompositor::RenderFrame(); +#endif } else if (VCount == 144) { diff --git a/src/GPU.h b/src/GPU.h index c7d25ec..1564ef7 100644 --- a/src/GPU.h +++ b/src/GPU.h @@ -437,6 +437,7 @@ void SetDispStat(u32 cpu, u16 val); void SetVCount(u16 val); +#ifdef OGLRENDERER_ENABLED namespace GLCompositor { @@ -450,6 +451,7 @@ void RenderFrame(); void BindOutputTexture(); } +#endif } diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 7964aa4..7774c65 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -949,6 +949,7 @@ void GPU2D::VBlankEnd() //OBJMosaicY = 0; //OBJMosaicYCount = 0; +#ifdef OGLRENDERER_ENABLED if (Accelerated) { if ((Num == 0) && (CaptureCnt & (1<<31)) && (((CaptureCnt >> 29) & 0x3) != 1)) @@ -956,6 +957,7 @@ void GPU2D::VBlankEnd() GPU3D::GLRenderer::PrepareCaptureFrame(); } } +#endif } diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 5ccacf4..74debfe 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -2528,13 +2528,19 @@ void VBlank() void VCount215() { if (GPU::Renderer == 0) SoftRenderer::RenderFrame(); +#ifdef OGLRENDERER_ENABLED else GLRenderer::RenderFrame(); +#endif } u32* GetLine(int line) { if (GPU::Renderer == 0) return SoftRenderer::GetLine(line); +#ifdef OGLRENDERER_ENABLED else return GLRenderer::GetLine(line); +#else + return NULL; +#endif } diff --git a/src/GPU3D.h b/src/GPU3D.h index 71f069d..c69adde 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -139,6 +139,7 @@ u32* GetLine(int line); } +#ifdef OGLRENDERER_ENABLED namespace GLRenderer { @@ -154,6 +155,7 @@ u32* GetLine(int line); void SetupAccelFrame(); } +#endif } diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.cpp b/src/frontend/qt_sdl/VideoSettingsDialog.cpp index 971fee7..1397ccd 100644 --- a/src/frontend/qt_sdl/VideoSettingsDialog.cpp +++ b/src/frontend/qt_sdl/VideoSettingsDialog.cpp @@ -50,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); diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 1900998..e0c12e3 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -49,7 +49,9 @@ #include "NDS.h" #include "GBACart.h" +#ifdef OGLRENDERER_ENABLED #include "OpenGLSupport.h" +#endif #include "GPU.h" #include "SPU.h" #include "Wifi.h" @@ -336,13 +338,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); @@ -396,13 +402,17 @@ 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; @@ -923,12 +933,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); -- cgit v1.2.3 From 0d845c9e69e19046f351ce396da8eec150243387 Mon Sep 17 00:00:00 2001 From: Valeri Date: Thu, 1 Oct 2020 14:44:09 +0300 Subject: Random minor fixes (#757) * Fix incorrect/questionable assert() usage Originally reported by https://lgtm.com/projects/g/Arisotura/melonDS/?mode=tree&ruleFocus=2159000700, but also includes a bunch of other fixes. * Fix some `printf` warnings Rule https://lgtm.com/projects/g/Arisotura/melonDS/?mode=tree&ruleFocus=2160310550 * Remove useless check It is never passed thanks to `if (num_in < 1) {...; return}` before Rule https://lgtm.com/projects/g/Arisotura/melonDS/?mode=tree&ruleFocus=2154840804 * Add missing header guard, rename other to avoid conflicts Rule https://lgtm.com/projects/g/Arisotura/melonDS/?mode=tree&ruleFocus=2163210746 * Make DSi_SDDevice destructor virtual Rule https://lgtm.com/projects/g/Arisotura/melonDS/?mode=tree&ruleFocus=2158670642 * Use thread-safe localtime_r, assign `time` result directly Rule https://lgtm.com/projects/g/Arisotura/melonDS/?mode=tree&ruleFocus=2154840805 * Fix MinGW build It needs _POSIX_THREAD_SAFE_FUNCTIONS to export `localtime_r` --- src/ARMJIT_A64/ARMJIT_Compiler.h | 6 ++--- src/ARMJIT_A64/ARMJIT_LoadStore.cpp | 4 +-- src/ARMJIT_Compiler.h | 7 +++++- src/ARMJIT_RegisterCache.h | 3 ++- src/ARMJIT_x64/ARMJIT_ALU.cpp | 7 +++--- src/ARMJIT_x64/ARMJIT_Compiler.h | 6 ++--- src/ARMJIT_x64/ARMJIT_LoadStore.cpp | 4 +-- src/Config.cpp | 2 +- src/DSi_SD.h | 2 +- src/RTC.cpp | 41 ++++++++++++++++--------------- src/frontend/qt_sdl/InputConfigDialog.cpp | 2 +- src/frontend/qt_sdl/main.cpp | 1 - 12 files changed, 46 insertions(+), 39 deletions(-) (limited to 'src/frontend') diff --git a/src/ARMJIT_A64/ARMJIT_Compiler.h b/src/ARMJIT_A64/ARMJIT_Compiler.h index 0e7d54c..af7497a 100644 --- a/src/ARMJIT_A64/ARMJIT_Compiler.h +++ b/src/ARMJIT_A64/ARMJIT_Compiler.h @@ -1,5 +1,5 @@ -#ifndef ARMJIT_COMPILER_H -#define ARMJIT_COMPILER_H +#ifndef ARMJIT_A64_COMPILER_H +#define ARMJIT_A64_COMPILER_H #include "../ARM.h" #include "../ARMJIT.h" @@ -266,4 +266,4 @@ public: } -#endif \ No newline at end of file +#endif diff --git a/src/ARMJIT_A64/ARMJIT_LoadStore.cpp b/src/ARMJIT_A64/ARMJIT_LoadStore.cpp index 14aa847..86e257a 100644 --- a/src/ARMJIT_A64/ARMJIT_LoadStore.cpp +++ b/src/ARMJIT_A64/ARMJIT_LoadStore.cpp @@ -42,7 +42,7 @@ s64 Compiler::RewriteMemAccess(u64 pc) return patch.PatchOffset; } printf("this is a JIT bug! %08x\n", __builtin_bswap32(*(u32*)pc)); - assert(false); + abort(); } bool Compiler::Comp_MemLoadLiteral(int size, bool signExtend, int rd, u32 addr) @@ -807,4 +807,4 @@ void Compiler::T_Comp_LDMIA_STMIA() } } -} \ No newline at end of file +} diff --git a/src/ARMJIT_Compiler.h b/src/ARMJIT_Compiler.h index 513c103..25a0210 100644 --- a/src/ARMJIT_Compiler.h +++ b/src/ARMJIT_Compiler.h @@ -1,3 +1,6 @@ +#ifndef ARMJIT_COMPILER_H +#define ARMJIT_COMPILER_H + #if defined(__x86_64__) #include "ARMJIT_x64/ARMJIT_Compiler.h" #elif defined(__aarch64__) @@ -9,4 +12,6 @@ namespace ARMJIT { extern Compiler* JITCompiler; -} \ No newline at end of file +} + +#endif diff --git a/src/ARMJIT_RegisterCache.h b/src/ARMJIT_RegisterCache.h index feb2d35..b11255e 100644 --- a/src/ARMJIT_RegisterCache.h +++ b/src/ARMJIT_RegisterCache.h @@ -61,7 +61,8 @@ public: } } - assert("Welp!"); + printf("this is a JIT bug! LoadRegister failed\n"); + abort(); } void PutLiteral(int reg, u32 val) diff --git a/src/ARMJIT_x64/ARMJIT_ALU.cpp b/src/ARMJIT_x64/ARMJIT_ALU.cpp index 24d22ed..511b3b1 100644 --- a/src/ARMJIT_x64/ARMJIT_ALU.cpp +++ b/src/ARMJIT_x64/ARMJIT_ALU.cpp @@ -209,7 +209,8 @@ void Compiler::A_Comp_Arith() Comp_ArithTriOp(&Compiler::AND, rd, rn, op2, carryUsed, sFlag|opSymmetric|opInvertOp2); break; default: - assert("unimplemented"); + printf("this is a JIT bug! %04x\n", op); + abort(); } if (CurInstr.A_Reg(12) == 15) @@ -566,7 +567,7 @@ OpArg Compiler::Comp_RegShiftImm(int op, int amount, OpArg rm, bool S, bool& car return R(RSCRATCH); } - assert(false); + abort(); } void Compiler::T_Comp_ShiftImm() @@ -779,4 +780,4 @@ void Compiler::T_Comp_RelAddr() MOV(32, rd, Imm32((R15 & ~2) + offset)); } -} \ No newline at end of file +} diff --git a/src/ARMJIT_x64/ARMJIT_Compiler.h b/src/ARMJIT_x64/ARMJIT_Compiler.h index 9a64d09..3e900c3 100644 --- a/src/ARMJIT_x64/ARMJIT_Compiler.h +++ b/src/ARMJIT_x64/ARMJIT_Compiler.h @@ -1,5 +1,5 @@ -#ifndef ARMJIT_COMPILER_H -#define ARMJIT_COMPILER_H +#ifndef ARMJIT_X64_COMPILER_H +#define ARMJIT_X64_COMPILER_H #include "../dolphin/x64Emitter.h" @@ -252,4 +252,4 @@ public: } -#endif \ No newline at end of file +#endif diff --git a/src/ARMJIT_x64/ARMJIT_LoadStore.cpp b/src/ARMJIT_x64/ARMJIT_LoadStore.cpp index 1be6608..8b4e8fe 100644 --- a/src/ARMJIT_x64/ARMJIT_LoadStore.cpp +++ b/src/ARMJIT_x64/ARMJIT_LoadStore.cpp @@ -39,7 +39,7 @@ s32 Compiler::RewriteMemAccess(u64 pc) return patch.Offset; } - printf("this is a JIT bug %x\n", pc); + printf("this is a JIT bug %llx\n", pc); abort(); } @@ -819,4 +819,4 @@ void Compiler::T_Comp_LDMIA_STMIA() ADD(32, rb, Imm8(offset)); } -} \ No newline at end of file +} diff --git a/src/Config.cpp b/src/Config.cpp index 2c5fd2c..8bda9ae 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -169,7 +169,7 @@ void Save() if (entry->Type == 0) fprintf(f, "%s=%d\n", entry->Name, *(int*)entry->Value); else - fprintf(f, "%s=%s\n", entry->Name, entry->Value); + fprintf(f, "%s=%s\n", entry->Name, (char*)entry->Value); entry++; } diff --git a/src/DSi_SD.h b/src/DSi_SD.h index 30da6c7..43f5a98 100644 --- a/src/DSi_SD.h +++ b/src/DSi_SD.h @@ -103,7 +103,7 @@ class DSi_SDDevice { public: DSi_SDDevice(DSi_SDHost* host) { Host = host; IRQ = false; } - ~DSi_SDDevice() {} + virtual ~DSi_SDDevice() {} virtual void Reset() = 0; diff --git a/src/RTC.cpp b/src/RTC.cpp index ba51dff..aff3dd3 100644 --- a/src/RTC.cpp +++ b/src/RTC.cpp @@ -16,6 +16,9 @@ with melonDS. If not, see http://www.gnu.org/licenses/. */ +// Required by MinGW to enable localtime_r in time.h +#define _POSIX_THREAD_SAFE_FUNCTIONS + #include #include #include @@ -125,31 +128,29 @@ void ByteIn(u8 val) case 0x20: { - time_t timestamp; - struct tm* timedata; - time(×tamp); - timedata = localtime(×tamp); - - Output[0] = BCD(timedata->tm_year - 100); - Output[1] = BCD(timedata->tm_mon + 1); - Output[2] = BCD(timedata->tm_mday); - Output[3] = BCD(timedata->tm_wday); - Output[4] = BCD(timedata->tm_hour); - Output[5] = BCD(timedata->tm_min); - Output[6] = BCD(timedata->tm_sec); + time_t timestamp = time(NULL); + struct tm timedata; + localtime_r(×tamp, &timedata); + + Output[0] = BCD(timedata.tm_year - 100); + Output[1] = BCD(timedata.tm_mon + 1); + Output[2] = BCD(timedata.tm_mday); + Output[3] = BCD(timedata.tm_wday); + Output[4] = BCD(timedata.tm_hour); + Output[5] = BCD(timedata.tm_min); + Output[6] = BCD(timedata.tm_sec); } break; case 0x60: { - time_t timestamp; - struct tm* timedata; - time(×tamp); - timedata = localtime(×tamp); - - Output[0] = BCD(timedata->tm_hour); - Output[1] = BCD(timedata->tm_min); - Output[2] = BCD(timedata->tm_sec); + time_t timestamp = time(NULL); + struct tm timedata; + localtime_r(×tamp, &timedata); + + Output[0] = BCD(timedata.tm_hour); + Output[1] = BCD(timedata.tm_min); + Output[2] = BCD(timedata.tm_sec); } break; diff --git a/src/frontend/qt_sdl/InputConfigDialog.cpp b/src/frontend/qt_sdl/InputConfigDialog.cpp index 2292441..522b16c 100644 --- a/src/frontend/qt_sdl/InputConfigDialog.cpp +++ b/src/frontend/qt_sdl/InputConfigDialog.cpp @@ -228,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/main.cpp b/src/frontend/qt_sdl/main.cpp index e0c12e3..3a735fb 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -115,7 +115,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]; -- cgit v1.2.3 From f8c4bf6db140f590f2cf781e9da67ed208bd47f5 Mon Sep 17 00:00:00 2001 From: kyandora <71771686+kyandora@users.noreply.github.com> Date: Wed, 7 Oct 2020 01:33:11 +0200 Subject: save microphone hotkeys (#781) --- src/frontend/qt_sdl/InputConfigDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/InputConfigDialog.cpp b/src/frontend/qt_sdl/InputConfigDialog.cpp index 522b16c..9f08731 100644 --- a/src/frontend/qt_sdl/InputConfigDialog.cpp +++ b/src/frontend/qt_sdl/InputConfigDialog.cpp @@ -179,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]; -- cgit v1.2.3 From dc46da0e24666c67c1780b24e58151d31d8ba34c Mon Sep 17 00:00:00 2001 From: Madhav Kanbur Date: Tue, 13 Oct 2020 11:02:58 +0530 Subject: Input : Treat numpad keys as keypresses Typically, modifiers are masked out of keypresses to distinguish between hotkeys and keypresses. This patch prevents the numpad modifier from getting masked out in KeyPress() and KeyRelease(). Signed-off-by: Madhav Kanbur --- src/frontend/qt_sdl/Input.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/frontend') 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]) -- cgit v1.2.3