From ce28d5725b079ee76d8a9af5c8a22eaa9fbbe78a Mon Sep 17 00:00:00 2001 From: Raphaël Zumer Date: Fri, 31 Jul 2020 20:20:47 +0000 Subject: Update dependencies in the readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1a01bc3..ce4f32a 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ As for the rest, the interface should be pretty straightforward. If you have a q * Install dependencies: ```sh -sudo apt-get install libgtk-3-dev libcurl4-gnutls-dev libpcap0.8-dev libsdl2-dev +sudo apt-get install libgtk-3-dev libcurl4-gnutls-dev libpcap0.8-dev libsdl2-dev qtbase5-dev qtdeclarative5-dev libslirp-dev ``` * Compile: @@ -55,7 +55,7 @@ make -j$(nproc --all) 1. Install [MSYS2](https://www.msys2.org/) 2. Open the **MSYS2 MinGW 64-bit** terminal 3. Update the packages using `pacman -Syu` and reopen the terminal if it asks you to -4. Install dependencies: `pacman -S git make mingw-w64-x86_64-{cmake,mesa,SDL2,toolchain}` +4. Install dependencies: `pacman -S git make mingw-w64-x86_64-{cmake,mesa,SDL2,toolchain,qt5,libslirp}` 5. Run the following commands ```bash git clone https://github.com/Arisotura/melonDS.git -- cgit v1.2.3 From 68e310e4ef971b42bb1ab4effd5c49ce1dd58c33 Mon Sep 17 00:00:00 2001 From: Raphaël Zumer Date: Fri, 31 Jul 2020 16:34:28 -0400 Subject: Deploy Qt libraries with dynamic Windows builds Also stop using msys-dist.sh with the static CI build. --- .github/workflows/build-windows.yml | 5 ++--- msys-dist.sh | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index bbf68af..569cebc 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -36,9 +36,8 @@ jobs: - name: Make run: | C:\tools\msys64\usr\bin\bash.exe -lc "export PATH=`"/mingw64/bin:`$PATH`" \ - && cd melonDS/build && make -j$(nproc --all) \ - && ../msys-dist.sh" + && cd melonDS/build && make -j$(nproc --all)" - uses: actions/upload-artifact@v1 with: name: melonDS - path: C:\tools\msys64\home\runneradmin\melonDS\build\dist + path: C:\tools\msys64\home\runneradmin\melonDS\build\melonDS.exe diff --git a/msys-dist.sh b/msys-dist.sh index 87c9d7e..d95a6d3 100755 --- a/msys-dist.sh +++ b/msys-dist.sh @@ -11,4 +11,5 @@ for lib in $(ldd melonDS.exe | grep mingw | sed "s/.*=> //" | sed "s/(.*)//"); d cp "${lib}" dist done -cp melonDS.exe dist \ No newline at end of file +cp melonDS.exe dist +windeployqt dist -- cgit v1.2.3 From 36bdb591be2f49f9a1b4965ceb516ab960fbadba Mon Sep 17 00:00:00 2001 From: RSDuck Date: Sun, 9 Aug 2020 13:29:04 +0200 Subject: fix JIT for code in VRAM apparantely Pokemon B/W needs this fixes #708 --- src/ARMJIT_Memory.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ARMJIT_Memory.cpp b/src/ARMJIT_Memory.cpp index 35cfdf0..f2367f6 100644 --- a/src/ARMJIT_Memory.cpp +++ b/src/ARMJIT_Memory.cpp @@ -773,6 +773,7 @@ bool GetMirrorLocation(int region, u32 num, u32 addr, u32& memoryOffset, u32& mi { mirrorStart = addr & ~0xFFFFF; mirrorSize = 0x100000; + return true; } return false; case memregion_VWRAM: -- cgit v1.2.3 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 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 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(-) 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 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 4299ef5f067c0f7aac338fbdd5e36726f8c8af64 Mon Sep 17 00:00:00 2001 From: RSDuck Date: Fri, 14 Aug 2020 23:38:47 +0200 Subject: use unordered map for JIT RestoreCandidates also fix WifiRead32? --- src/ARMJIT.cpp | 153 +++++++++++--------------------------------------- src/ARMJIT_Memory.cpp | 2 +- 2 files changed, 33 insertions(+), 122 deletions(-) diff --git a/src/ARMJIT.cpp b/src/ARMJIT.cpp index 0eb792c..59f7f54 100644 --- a/src/ARMJIT.cpp +++ b/src/ARMJIT.cpp @@ -38,6 +38,14 @@ namespace ARMJIT Compiler* JITCompiler; + +std::unordered_map JitBlocks9; +std::unordered_map JitBlocks7; + +std::unordered_map RestoreCandidates; + +TinyVector InvalidLiterals; + AddressRange CodeIndexITCM[ITCMPhysicalSize / 512]; AddressRange CodeIndexMainRAM[NDS::MainRAMMaxSize / 512]; AddressRange CodeIndexSWRAM[NDS::SharedWRAMSize / 512]; @@ -52,9 +60,6 @@ AddressRange CodeIndexNWRAM_A[DSi::NWRAMSize / 512]; AddressRange CodeIndexNWRAM_B[DSi::NWRAMSize / 512]; AddressRange CodeIndexNWRAM_C[DSi::NWRAMSize / 512]; -std::unordered_map JitBlocks9; -std::unordered_map JitBlocks7; - u64 FastBlockLookupITCM[ITCMPhysicalSize / 2]; u64 FastBlockLookupMainRAM[NDS::MainRAMMaxSize / 2]; u64 FastBlockLookupSWRAM[NDS::SharedWRAMSize / 2]; @@ -146,8 +151,6 @@ u32 LocaliseCodeAddress(u32 num, u32 addr) return 0; } -TinyVector InvalidLiterals; - template T SlowRead9(u32 addr, ARMv5* cpu) { @@ -286,97 +289,6 @@ void SlowBlockTransfer7(u32 addr, u64* data, u32 num) INSTANTIATE_SLOWMEM(0) INSTANTIATE_SLOWMEM(1) -template -struct UnreliableHashTable -{ - struct Bucket - { - K KeyA, KeyB; - V ValA, ValB; - }; - - Bucket Table[Size]; - - void Reset() - { - for (int i = 0; i < Size; i++) - { - Table[i].ValA = Table[i].ValB = InvalidValue; - } - } - - UnreliableHashTable() - { - Reset(); - } - - V Insert(K key, V value) - { - u32 slot = XXH3_64bits(&key, sizeof(K)) & (Size - 1); - Bucket* bucket = &Table[slot]; - - if (bucket->ValA == value || bucket->ValB == value) - { - return InvalidValue; - } - else if (bucket->ValA == InvalidValue) - { - bucket->KeyA = key; - bucket->ValA = value; - } - else if (bucket->ValB == InvalidValue) - { - bucket->KeyB = key; - bucket->ValB = value; - } - else - { - V prevVal = bucket->ValB; - bucket->KeyB = bucket->KeyA; - bucket->ValB = bucket->ValA; - bucket->KeyA = key; - bucket->ValA = value; - return prevVal; - } - - return InvalidValue; - } - - void Remove(K key) - { - u32 slot = XXH3_64bits(&key, sizeof(K)) & (Size - 1); - Bucket* bucket = &Table[slot]; - - if (bucket->KeyA == key && bucket->ValA != InvalidValue) - { - bucket->ValA = InvalidValue; - if (bucket->ValB != InvalidValue) - { - bucket->KeyA = bucket->KeyB; - bucket->ValA = bucket->ValB; - bucket->ValB = InvalidValue; - } - } - if (bucket->KeyB == key && bucket->ValB != InvalidValue) - bucket->ValB = InvalidValue; - } - - V LookUp(K addr) - { - u32 slot = XXH3_64bits(&addr, 4) & (Size - 1); - Bucket* bucket = &Table[slot]; - - if (bucket->ValA != InvalidValue && bucket->KeyA == addr) - return bucket->ValA; - if (bucket->ValB != InvalidValue && bucket->KeyB == addr) - return bucket->ValB; - - return InvalidValue; - } -}; - -UnreliableHashTable RestoreCandidates; - void Init() { JITCompiler = new Compiler(); @@ -622,6 +534,20 @@ InterpreterFunc InterpretTHUMB[ARMInstrInfo::tk_Count] = }; #undef F +void RetireJitBlock(JitBlock* block) +{ + auto it = RestoreCandidates.find(block->InstrHash); + if (it != RestoreCandidates.end()) + { + delete it->second; + it->second = block; + } + else + { + RestoreCandidates[block->InstrHash] = block; + } +} + void CompileBlock(ARM* cpu) { bool thumb = cpu->CPSR & 0x20; @@ -659,10 +585,7 @@ void CompileBlock(ARM* cpu) } // some memory has been remapped - JitBlock* prevBlock = RestoreCandidates.Insert(existingBlockIt->second->InstrHash, existingBlockIt->second); - if (prevBlock) - delete prevBlock; - + RetireJitBlock(existingBlockIt->second); map.erase(existingBlockIt); } @@ -906,11 +829,13 @@ void CompileBlock(ARM* cpu) u32 literalHash = (u32)XXH3_64bits(literalValues, numLiterals * 4); u32 instrHash = (u32)XXH3_64bits(instrValues, i * 4); - JitBlock* prevBlock = RestoreCandidates.LookUp(instrHash); + auto prevBlockIt = RestoreCandidates.find(instrHash); + JitBlock* prevBlock = NULL; bool mayRestore = true; - if (prevBlock) + if (prevBlockIt != RestoreCandidates.end()) { - RestoreCandidates.Remove(instrHash); + prevBlock = prevBlockIt->second; + RestoreCandidates.erase(prevBlockIt); mayRestore = prevBlock->StartAddr == blockAddr && prevBlock->LiteralHash == literalHash; @@ -932,7 +857,6 @@ void CompileBlock(ARM* cpu) else { mayRestore = false; - prevBlock = NULL; } JitBlock* block; @@ -1078,9 +1002,7 @@ void InvalidateByAddr(u32 localAddr) if (!literalInvalidation) { - JitBlock* prevBlock = RestoreCandidates.Insert(block->InstrHash, block); - if (prevBlock) - delete prevBlock; + RetireJitBlock(block); } else { @@ -1166,20 +1088,9 @@ void ResetBlockCache() InvalidLiterals.Clear(); for (int i = 0; i < ARMJIT_Memory::memregions_Count; i++) memset(FastBlockLookupRegions[i], 0xFF, CodeRegionSizes[i] * sizeof(u64) / 2); - RestoreCandidates.Reset(); - for (int i = 0; i < sizeof(RestoreCandidates.Table)/sizeof(RestoreCandidates.Table[0]); i++) - { - if (RestoreCandidates.Table[i].ValA) - { - delete RestoreCandidates.Table[i].ValA; - RestoreCandidates.Table[i].ValA = NULL; - } - if (RestoreCandidates.Table[i].ValA) - { - delete RestoreCandidates.Table[i].ValB; - RestoreCandidates.Table[i].ValB = NULL; - } - } + for (auto it = RestoreCandidates.begin(); it != RestoreCandidates.end(); it++) + delete it->second; + RestoreCandidates.clear(); for (auto it : JitBlocks9) { JitBlock* block = it.second; diff --git a/src/ARMJIT_Memory.cpp b/src/ARMJIT_Memory.cpp index f2367f6..7885fb7 100644 --- a/src/ARMJIT_Memory.cpp +++ b/src/ARMJIT_Memory.cpp @@ -1008,7 +1008,7 @@ void WifiWrite32(u32 addr, u32 val) u32 WifiRead32(u32 addr) { - return Wifi::Read(addr) | (Wifi::Read(addr + 2) << 16); + return (u32)Wifi::Read(addr) | ((u32)Wifi::Read(addr + 2) << 16); } template -- 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(-) 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(-) 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 ba373ca72a4ae3442725820d4556fc2a56676dd9 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 17 Aug 2020 19:15:45 +0200 Subject: DSi: make ARM9-clock-selector actually work --- src/CP15.cpp | 6 ++--- src/DSi.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++------------------ src/NDS.cpp | 5 +++-- src/NDS.h | 2 ++ 4 files changed, 58 insertions(+), 26 deletions(-) diff --git a/src/CP15.cpp b/src/CP15.cpp index f6476ab..3f9e79d 100644 --- a/src/CP15.cpp +++ b/src/CP15.cpp @@ -616,11 +616,11 @@ void ARMv5::CP15Write(u32 id, u32 val) case 0xF00: //printf("cache debug index register %08X\n", val); return; - + case 0xF10: //printf("cache debug instruction tag %08X\n", val); return; - + case 0xF20: //printf("cache debug data tag %08X\n", val); return; @@ -632,7 +632,7 @@ void ARMv5::CP15Write(u32 id, u32 val) case 0xF40: //printf("cache debug data cache %08X\n", val); return; - + } if ((id & 0xF00) == 0xF00) // test/debug shit? diff --git a/src/DSi.cpp b/src/DSi.cpp index 42541fe..66b8ed0 100644 --- a/src/DSi.cpp +++ b/src/DSi.cpp @@ -699,20 +699,37 @@ void MapNWRAMRange(u32 cpu, u32 num, u32 val) } } +void ApplyNewRAMSize(u32 size) +{ + switch (size) + { + case 0: + case 1: + NDS::MainRAMMask = 0x3FFFFF; + printf("RAM: 4MB\n"); + break; + case 2: + case 3: // TODO: debug console w/ 32MB? + NDS::MainRAMMask = 0xFFFFFF; + printf("RAM: 16MB\n"); + break; + } +} + void Set_SCFG_Clock9(u16 val) { - SCFG_Clock9 = val & 0x0187; - return; - NDS::ARM9Timestamp >>= NDS::ARM9ClockShift; + NDS::ARM9Target >>= NDS::ARM9ClockShift; printf("CLOCK9=%04X\n", val); SCFG_Clock9 = val & 0x0187; if (SCFG_Clock9 & (1<<0)) NDS::ARM9ClockShift = 2; else NDS::ARM9ClockShift = 1; + NDS::ARM9Timestamp <<= NDS::ARM9ClockShift; + NDS::ARM9Target <<= NDS::ARM9ClockShift; NDS::ARM9->UpdateRegionTimings(0x00000000, 0xFFFFFFFF); } @@ -1549,25 +1566,37 @@ void ARM9IOWrite32(u32 addr, u32 val) switch (addr) { case 0x04004008: - SCFG_EXT[0] &= ~0x8007F19F; - SCFG_EXT[0] |= (val & 0x8007F19F); - SCFG_EXT[1] &= ~0x0000F080; - SCFG_EXT[1] |= (val & 0x0000F080); - printf("SCFG_EXT = %08X / %08X (val9 %08X)\n", SCFG_EXT[0], SCFG_EXT[1], val); - /*switch ((SCFG_EXT[0] >> 14) & 0x3) { - case 0: - case 1: - NDS::MainRAMMask = 0x3FFFFF; - printf("RAM: 4MB\n"); - break; - case 2: - case 3: // TODO: debug console w/ 32MB? - NDS::MainRAMMask = 0xFFFFFF; - printf("RAM: 16MB\n"); - break; - }*/ - printf("from %08X, ARM7 %08X, %08X\n", NDS::GetPC(0), NDS::GetPC(1), NDS::ARM7->R[1]); + u32 oldram = (SCFG_EXT[0] >> 14) & 0x3; + u32 newram = (val >> 14) & 0x3; + + SCFG_EXT[0] &= ~0x8007F19F; + SCFG_EXT[0] |= (val & 0x8007F19F); + SCFG_EXT[1] &= ~0x0000F080; + SCFG_EXT[1] |= (val & 0x0000F080); + printf("SCFG_EXT = %08X / %08X (val9 %08X)\n", SCFG_EXT[0], SCFG_EXT[1], val); + /*switch ((SCFG_EXT[0] >> 14) & 0x3) + { + case 0: + case 1: + NDS::MainRAMMask = 0x3FFFFF; + printf("RAM: 4MB\n"); + //baziderp=true; + break; + case 2: + case 3: // TODO: debug console w/ 32MB? + NDS::MainRAMMask = 0xFFFFFF; + printf("RAM: 16MB\n"); + break; + }*/ + // HAX!! + // a change to the RAM size setting is supposed to apply immediately (it does so on hardware) + // however, doing so will cause DS-mode app startup to break, because the change happens while the ARM7 + // is still busy clearing/relocating shit + //if (newram != oldram) + // NDS::ScheduleEvent(NDS::Event_DSi_RAMSizeChange, false, 512*512*512, ApplyNewRAMSize, newram); + printf("from %08X, ARM7 %08X, %08X\n", NDS::GetPC(0), NDS::GetPC(1), NDS::ARM7->R[1]); + } return; case 0x04004040: diff --git a/src/NDS.cpp b/src/NDS.cpp index 823d39a..bb579f6 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -1817,15 +1817,16 @@ void debug(u32 param) fwrite(&val, 4, 1, shit); } fclose(shit);*/ + FILE* - shit = fopen("debug/dump9.bin", "wb"); + shit = fopen("debug/picto9.bin", "wb"); for (u32 i = 0x02000000; i < 0x04000000; i+=4) { u32 val = DSi::ARM9Read32(i); fwrite(&val, 4, 1, shit); } fclose(shit); - shit = fopen("debug/dump7.bin", "wb"); + shit = fopen("debug/picto7.bin", "wb"); for (u32 i = 0x02000000; i < 0x04000000; i+=4) { u32 val = DSi::ARM7Read32(i); diff --git a/src/NDS.h b/src/NDS.h index e0a5045..91bfd1c 100644 --- a/src/NDS.h +++ b/src/NDS.h @@ -47,6 +47,8 @@ enum Event_DSi_SDIOTransfer, Event_DSi_NWifi, + Event_DSi_RAMSizeChange, + Event_MAX }; -- cgit v1.2.3 From 6f4e7c60b29242a692f2595cd319d285792a3c3d Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 19 Aug 2020 00:46:16 +0200 Subject: GPU2D: allow writes to DISPCNT, master brightness, capture, dispFIFO regardless of POWCNT. fixes #665 --- src/GPU2D.cpp | 77 +++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 604a4ee..2c3086c 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -35,9 +35,6 @@ // * [Gericom] bit15 is used as bottom green bit for palettes. TODO: check where this applies. // tested on the normal BG palette and applies there // -// oh also, changing DISPCNT bit16-17 midframe doesn't work (ignored? applied for next frame?) -// TODO, eventually: check whether other DISPCNT bits can be changed midframe -// // for VRAM display mode, VRAM must be mapped to LCDC // // FIFO display mode: @@ -78,7 +75,10 @@ // * for rotscaled sprites: coordinates that are inside the sprite are clamped to the sprite region // after being transformed for mosaic -// TODO: find which parts of DISPCNT are latched. for example, not possible to change video mode midframe. +// TODO: master brightness, display capture and mainmem FIFO are separate circuitry, distinct from +// the tile renderers. +// for example these aren't affected by POWCNT GPU-disable bits. +// to model the hardware more accurately, the relevant logic should be moved to GPU.cpp. GPU2D::GPU2D(u32 num) @@ -309,8 +309,6 @@ u32 GPU2D::Read32(u32 addr) void GPU2D::Write8(u32 addr, u8 val) { - if (!Enabled) return; - switch (addr & 0x00000FFF) { case 0x000: @@ -329,7 +327,12 @@ void GPU2D::Write8(u32 addr, u8 val) DispCnt = (DispCnt & 0x00FFFFFF) | (val << 24); if (Num) DispCnt &= 0xC0B1FFF7; return; + } + if (!Enabled) return; + + switch (addr & 0x00000FFF) + { case 0x008: BGCnt[0] = (BGCnt[0] & 0xFF00) | val; return; case 0x009: BGCnt[0] = (BGCnt[0] & 0x00FF) | (val << 8); return; case 0x00A: BGCnt[1] = (BGCnt[1] & 0xFF00) | val; return; @@ -405,8 +408,6 @@ void GPU2D::Write8(u32 addr, u8 val) void GPU2D::Write16(u32 addr, u16 val) { - if (!Enabled) return; - switch (addr & 0x00000FFF) { case 0x000: @@ -418,6 +419,22 @@ void GPU2D::Write16(u32 addr, u16 val) if (Num) DispCnt &= 0xC0B1FFF7; return; + case 0x068: + DispFIFO[DispFIFOWritePtr] = val; + return; + case 0x06A: + DispFIFO[DispFIFOWritePtr+1] = val; + DispFIFOWritePtr += 2; + DispFIFOWritePtr &= 0xF; + return; + + case 0x06C: MasterBrightness = val; return; + } + + if (!Enabled) return; + + switch (addr & 0x00000FFF) + { case 0x008: BGCnt[0] = val; return; case 0x00A: BGCnt[1] = val; return; case 0x00C: BGCnt[2] = val; return; @@ -526,17 +543,6 @@ void GPU2D::Write16(u32 addr, u16 val) EVY = val & 0x1F; if (EVY > 16) EVY = 16; return; - - case 0x068: - DispFIFO[DispFIFOWritePtr] = val; - return; - case 0x06A: - DispFIFO[DispFIFOWritePtr+1] = val; - DispFIFOWritePtr += 2; - DispFIFOWritePtr &= 0xF; - return; - - case 0x06C: MasterBrightness = val; return; } //printf("unknown GPU write16 %08X %04X\n", addr, val); @@ -544,8 +550,6 @@ void GPU2D::Write16(u32 addr, u16 val) void GPU2D::Write32(u32 addr, u32 val) { - if (!Enabled) return; - switch (addr & 0x00000FFF) { case 0x000: @@ -553,6 +557,24 @@ void GPU2D::Write32(u32 addr, u32 val) if (Num) DispCnt &= 0xC0B1FFF7; return; + case 0x064: + // TODO: check what happens when writing to it during display + // esp. if a capture is happening + CaptureCnt = val & 0xEF3F1F1F; + return; + + case 0x068: + DispFIFO[DispFIFOWritePtr] = val & 0xFFFF; + DispFIFO[DispFIFOWritePtr+1] = val >> 16; + DispFIFOWritePtr += 2; + DispFIFOWritePtr &= 0xF; + return; + } + + if (!Enabled) return; + + switch (addr & 0x00000FFF) + { case 0x028: if (val & 0x08000000) val |= 0xF0000000; BGXRef[0] = val; @@ -574,19 +596,6 @@ void GPU2D::Write32(u32 addr, u32 val) BGYRef[1] = val; if (GPU::VCount < 192) BGYRefInternal[1] = BGYRef[1]; return; - - case 0x064: - // TODO: check what happens when writing to it during display - // esp. if a capture is happening - CaptureCnt = val & 0xEF3F1F1F; - return; - - case 0x068: - DispFIFO[DispFIFOWritePtr] = val & 0xFFFF; - DispFIFO[DispFIFOWritePtr+1] = val >> 16; - DispFIFOWritePtr += 2; - DispFIFOWritePtr &= 0xF; - return; } Write16(addr, val&0xFFFF); -- cgit v1.2.3 From a32d997e1c341085da4ccfe5ae4c812f64681f10 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 19 Aug 2020 04:18:17 +0200 Subject: SPU: don't process channels with len<4 --- src/SPU.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SPU.cpp b/src/SPU.cpp index cd5c5b8..5b74bda 100644 --- a/src/SPU.cpp +++ b/src/SPU.cpp @@ -420,6 +420,8 @@ void Channel::Run(s32* buf, u32 samples) { if (!(Cnt & (1<<31))) return; + if ((type < 3) && ((Length+LoopPos) < 16)) return; + if (KeyOn) { Start(); -- cgit v1.2.3 From de19ce6250dcdcaae8a5a67d2e88694b771eafad Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 19 Aug 2020 13:02:54 +0200 Subject: 3D/GL: make polygon generation code cleaner, add quicker codepath for triangles (also laying ground for some evil experiment) also fix stupid bug with line polygons --- src/GPU3D_OpenGL.cpp | 126 +++++++++++++++++++++++++-------------------------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 8a06874..b47f0b5 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -527,6 +527,46 @@ void SetupPolygon(RendererPolygon* rp, Polygon* polygon) } } +u32* SetupVertex(Polygon* poly, int vid, Vertex* vtx, u32 vtxattr, u32* vptr) +{ + u32 z = poly->FinalZ[vid]; + u32 w = poly->FinalW[vid]; + + u32 alpha = (poly->Attr >> 16) & 0x1F; + + // Z should always fit within 16 bits, so it's okay to do this + u32 zshift = 0; + while (z > 0xFFFF) { z >>= 1; zshift++; } + + u32 x, y; + if (ScaleFactor > 1) + { + x = (vtx->HiresPosition[0] * ScaleFactor) >> 4; + y = (vtx->HiresPosition[1] * ScaleFactor) >> 4; + } + else + { + x = vtx->FinalPosition[0]; + y = vtx->FinalPosition[1]; + } + + *vptr++ = x | (y << 16); + *vptr++ = z | (w << 16); + + *vptr++ = (vtx->FinalColor[0] >> 1) | + ((vtx->FinalColor[1] >> 1) << 8) | + ((vtx->FinalColor[2] >> 1) << 16) | + (alpha << 24); + + *vptr++ = (u16)vtx->TexCoords[0] | ((u16)vtx->TexCoords[1] << 16); + + *vptr++ = vtxattr | (zshift << 16); + *vptr++ = poly->TexParam; + *vptr++ = poly->TexPalette; + + return vptr; +} + void BuildPolygons(RendererPolygon* polygons, int npolys) { u32* vptr = &VertexBuffer[0]; @@ -564,43 +604,16 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) { Vertex* vtx = poly->Vertices[j]; - u32 z = poly->FinalZ[j]; - u32 w = poly->FinalW[j]; - - // Z should always fit within 16 bits, so it's okay to do this - u32 zshift = 0; - while (z > 0xFFFF) { z >>= 1; zshift++; } - - u32 x, y; - if (ScaleFactor > 1) - { - x = (vtx->HiresPosition[0] * ScaleFactor) >> 4; - y = (vtx->HiresPosition[1] * ScaleFactor) >> 4; - } - else - { - x = vtx->FinalPosition[0]; - y = vtx->FinalPosition[1]; - } - if (j > 0) { - if (lastx == x && lasty == y) continue; + if (lastx == vtx->FinalPosition[0] && + lasty == vtx->FinalPosition[1]) continue; } - *vptr++ = x | (y << 16); - *vptr++ = z | (w << 16); - - *vptr++ = (vtx->FinalColor[0] >> 1) | - ((vtx->FinalColor[1] >> 1) << 8) | - ((vtx->FinalColor[2] >> 1) << 16) | - (alpha << 24); - - *vptr++ = (u16)vtx->TexCoords[0] | ((u16)vtx->TexCoords[1] << 16); + lastx = vtx->FinalPosition[0]; + lasty = vtx->FinalPosition[1]; - *vptr++ = vtxattr | (zshift << 16); - *vptr++ = poly->TexParam; - *vptr++ = poly->TexPalette; + vptr = SetupVertex(poly, j, vtx, vtxattr, vptr); *iptr++ = vidx; rp->NumIndices++; @@ -610,46 +623,33 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) if (nout >= 2) break; } } - else + else if (poly->NumVertices == 3) // regular triangle { rp->PrimType = GL_TRIANGLES; - for (int j = 0; j < poly->NumVertices; j++) + for (int j = 0; j < 3; j++) { Vertex* vtx = poly->Vertices[j]; - u32 z = poly->FinalZ[j]; - u32 w = poly->FinalW[j]; - - // Z should always fit within 16 bits, so it's okay to do this - u32 zshift = 0; - while (z > 0xFFFF) { z >>= 1; zshift++; } - - u32 x, y; - if (ScaleFactor > 1) - { - x = (vtx->HiresPosition[0] * ScaleFactor) >> 4; - y = (vtx->HiresPosition[1] * ScaleFactor) >> 4; - } - else - { - x = vtx->FinalPosition[0]; - y = vtx->FinalPosition[1]; - } - - *vptr++ = x | (y << 16); - *vptr++ = z | (w << 16); + vptr = SetupVertex(poly, j, vtx, vtxattr, vptr); + vidx++; + } - *vptr++ = (vtx->FinalColor[0] >> 1) | - ((vtx->FinalColor[1] >> 1) << 8) | - ((vtx->FinalColor[2] >> 1) << 16) | - (alpha << 24); + // build a triangle + *iptr++ = vidx_first; + *iptr++ = vidx - 2; + *iptr++ = vidx - 1; + rp->NumIndices += 3; + } + else + { + rp->PrimType = GL_TRIANGLES; - *vptr++ = (u16)vtx->TexCoords[0] | ((u16)vtx->TexCoords[1] << 16); + for (int j = 0; j < poly->NumVertices; j++) + { + Vertex* vtx = poly->Vertices[j]; - *vptr++ = vtxattr | (zshift << 16); - *vptr++ = poly->TexParam; - *vptr++ = poly->TexPalette; + vptr = SetupVertex(poly, j, vtx, vtxattr, vptr); if (j >= 2) { -- cgit v1.2.3 From 00f33343e4b2b58eacba46238928fc7c870063ad Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 19 Aug 2020 14:53:42 +0200 Subject: 3D/GL: experimental attempt at reducing warping on quads, pentagons, etc... --- src/GPU3D_OpenGL.cpp | 124 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 114 insertions(+), 10 deletions(-) diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index b47f0b5..1abc1de 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -641,26 +641,130 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) *iptr++ = vidx - 1; rp->NumIndices += 3; } - else + else // quad, pentagon, etc { rp->PrimType = GL_TRIANGLES; - for (int j = 0; j < poly->NumVertices; j++) + if (false) { - Vertex* vtx = poly->Vertices[j]; + // regular triangle-splitting - vptr = SetupVertex(poly, j, vtx, vtxattr, vptr); + for (int j = 0; j < poly->NumVertices; j++) + { + Vertex* vtx = poly->Vertices[j]; + + vptr = SetupVertex(poly, j, vtx, vtxattr, vptr); - if (j >= 2) + if (j >= 2) + { + // build a triangle + *iptr++ = vidx_first; + *iptr++ = vidx - 1; + *iptr++ = vidx; + rp->NumIndices += 3; + } + + vidx++; + } + } + else + { + // attempt at 'better' splitting + // this doesn't get rid of the error while splitting a bigger polygon into triangles + // but we can attempt to reduce it + + u32 cX = 0, cY = 0; + float cZ = 0; + float cW = 0; + + float cR = 0, cG = 0, cB = 0; + float cS = 0, cT = 0; + + for (int j = 0; j < poly->NumVertices; j++) { - // build a triangle - *iptr++ = vidx_first; - *iptr++ = vidx - 1; - *iptr++ = vidx; - rp->NumIndices += 3; + Vertex* vtx = poly->Vertices[j]; + + cX += vtx->HiresPosition[0]; + cY += vtx->HiresPosition[1]; + + float fw = (float)poly->FinalW[j] * poly->NumVertices; + cW += 1.0f / fw; + + if (poly->WBuffer) cZ += poly->FinalZ[j] / fw; + else cZ += poly->FinalZ[j]; + + cR += (vtx->FinalColor[0] >> 1) / fw; + cG += (vtx->FinalColor[1] >> 1) / fw; + cB += (vtx->FinalColor[2] >> 1) / fw; + + cS += vtx->TexCoords[0] / fw; + cT += vtx->TexCoords[1] / fw; } + cX /= poly->NumVertices; + cY /= poly->NumVertices; + + cW = 1.0f / cW; + + if (poly->WBuffer) cZ *= cW; + else cZ /= poly->NumVertices; + + cR *= cW; + cG *= cW; + cB *= cW; + + cS *= cW; + cT *= cW; + + cX = (cX * ScaleFactor) >> 4; + cY = (cY * ScaleFactor) >> 4; + + u32 w = (u32)cW; + + u32 z = (u32)cZ; + u32 zshift = 0; + while (z > 0xFFFF) { z >>= 1; zshift++; } + + // build center vertex + *vptr++ = cX | (cY << 16); + *vptr++ = z | (w << 16); + + *vptr++ = (u32)cR | + ((u32)cG << 8) | + ((u32)cB << 16) | + (alpha << 24); + + *vptr++ = (u16)cS | ((u16)cT << 16); + + *vptr++ = vtxattr | (zshift << 16); + *vptr++ = poly->TexParam; + *vptr++ = poly->TexPalette; + vidx++; + + // build the final polygon + for (int j = 0; j < poly->NumVertices; j++) + { + Vertex* vtx = poly->Vertices[j]; + + vptr = SetupVertex(poly, j, vtx, vtxattr, vptr); + + if (j >= 1) + { + // build a triangle + *iptr++ = vidx_first; + *iptr++ = vidx - 1; + *iptr++ = vidx; + rp->NumIndices += 3; + } + + vidx++; + } + + *iptr++ = vidx_first; + *iptr++ = vidx - 1; + *iptr++ = vidx_first + 1; + rp->NumIndices += 3; } } -- cgit v1.2.3 From e1add6f3d7dc5131f67708ebb2050a09581d9142 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 19 Aug 2020 16:25:40 +0200 Subject: 3D: add a bunch of missing variables to savestates. oops. fixes #716 --- src/GPU3D.cpp | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index bd27783..d9d6ba8 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -401,8 +401,33 @@ void DoSavestate(Savestate* file) file->Var32(&NumTestCommands); file->Var32(&DispCnt); + file->Var8(&AlphaRefVal); file->Var8(&AlphaRef); + file->VarArray(ToonTable, 32*2); + file->VarArray(EdgeTable, 8*2); + + file->Var32(&FogColor); + file->Var32(&FogOffset); + file->VarArray(FogDensityTable, 32); + + file->Var32(&ClearAttr1); + file->Var32(&ClearAttr2); + + file->Var32(&RenderDispCnt); + file->Var8(&RenderAlphaRef); + + file->VarArray(RenderToonTable, 32*2); + file->VarArray(RenderEdgeTable, 8*2); + + file->Var32(&RenderFogColor); + file->Var32(&RenderFogOffset); + file->Var32(&RenderFogShift); + file->VarArray(RenderFogDensityTable, 34); + + file->Var32(&RenderClearAttr1); + file->Var32(&RenderClearAttr2); + file->Var32(&ZeroDotWLimit); file->Var32(&GXStat); @@ -471,9 +496,6 @@ void DoSavestate(Savestate* file) file->Var32(&NumPolygons); file->Var32(&NumOpaquePolygons); - file->Var32(&ClearAttr1); - file->Var32(&ClearAttr2); - file->Var32(&FlushRequest); file->Var32(&FlushAttributes); -- cgit v1.2.3 From c9447935ffccce531d556cc0a572b020e07ba987 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 19 Aug 2020 17:53:31 +0200 Subject: NWifi: correctly determine ROM/chip/etc IDs based on hardware version (as specified in firmware). fixes #700 --- src/DSi_NWifi.cpp | 39 +++++++++++++++++++++++++++++++++------ src/DSi_NWifi.h | 4 ++++ src/SPI.cpp | 1 + src/SPI.h | 1 + 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/DSi_NWifi.cpp b/src/DSi_NWifi.cpp index 73cf4b4..54719cf 100644 --- a/src/DSi_NWifi.cpp +++ b/src/DSi_NWifi.cpp @@ -165,6 +165,36 @@ void DSi_NWifi::Reset() printf("NWifi MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + u8 type = SPI_Firmware::GetNWifiVersion(); + switch (type) + { + case 1: // AR6002 + ROMID = 0x20000188; + ChipID = 0x02000001; + HostIntAddr = 0x00500400; + break; + + case 2: // AR6013 + ROMID = 0x23000024; + ChipID = 0x0D000000; + HostIntAddr = 0x00520000; + break; + + case 3: // AR6014 (3DS) + ROMID = 0x2300006F; + ChipID = 0x0D000001; + HostIntAddr = 0x00520000; + printf("NWifi: hardware is 3DS type, unchecked\n"); + break; + + default: + printf("NWifi: unknown hardware type %02X, assuming AR6002\n"); + ROMID = 0x20000188; + ChipID = 0x02000001; + HostIntAddr = 0x00500400; + break; + } + memset(EEPROM, 0, 0x400); *(u32*)&EEPROM[0x000] = 0x300; @@ -755,8 +785,7 @@ void DSi_NWifi::BMI_Command() case 0x08: // BMI_GET_TARGET_ID MB_Write32(4, 0xFFFFFFFF); MB_Write32(4, 0x0000000C); - //MB_Write32(4, 0x20000118); - MB_Write32(4, 0x23000024); // ROM version (TODO: how to determine correct one?) + MB_Write32(4, ROMID); MB_Write32(4, 0x00000002); return; @@ -1436,7 +1465,7 @@ u32 DSi_NWifi::WindowRead(u32 addr) { printf("NWifi: window read %08X\n", addr); - if ((addr & 0xFFFF00) == 0x520000) + if ((addr & 0xFFFF00) == HostIntAddr) { // RAM host interest area // TODO: different base based on hardware version @@ -1462,9 +1491,7 @@ u32 DSi_NWifi::WindowRead(u32 addr) switch (addr) { case 0x40EC: // chip ID - // 0D000000 / 0D000001 == AR6013 - // TODO: check firmware.bin to determine the correct value - return 0x0D000001; + return ChipID; // SOC_RESET_CAUSE case 0x40C0: return 2; diff --git a/src/DSi_NWifi.h b/src/DSi_NWifi.h index a72d54d..7efd40c 100644 --- a/src/DSi_NWifi.h +++ b/src/DSi_NWifi.h @@ -127,6 +127,10 @@ private: u32 WindowData, WindowReadAddr, WindowWriteAddr; + u32 ROMID; + u32 ChipID; + u32 HostIntAddr; + u8 EEPROM[0x400]; u32 EEPROMReady; diff --git a/src/SPI.cpp b/src/SPI.cpp index eff0a05..1c88b58 100644 --- a/src/SPI.cpp +++ b/src/SPI.cpp @@ -241,6 +241,7 @@ void SetupDirectBoot() u8 GetConsoleType() { return Firmware[0x1D]; } u8 GetWifiVersion() { return Firmware[0x2F]; } +u8 GetNWifiVersion() { return Firmware[0x1FD]; } // for DSi; will return 0xFF on a DS u8 GetRFVersion() { return Firmware[0x40]; } u8* GetWifiMAC() { return &Firmware[0x36]; } diff --git a/src/SPI.h b/src/SPI.h index 21734c4..0e0eb5a 100644 --- a/src/SPI.h +++ b/src/SPI.h @@ -28,6 +28,7 @@ void SetupDirectBoot(); u8 GetConsoleType(); u8 GetWifiVersion(); +u8 GetNWifiVersion(); u8 GetRFVersion(); u8* GetWifiMAC(); -- cgit v1.2.3 From 660792d64ba2a1bab5187270a892d05ba1133dce Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 19 Aug 2020 19:16:09 +0200 Subject: wifi: * don't receive packets if the RX buffer is zero-sized * avoid potential out-of-bound writes --- src/Wifi.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Wifi.cpp b/src/Wifi.cpp index 8188151..8a06041 100644 --- a/src/Wifi.cpp +++ b/src/Wifi.cpp @@ -816,6 +816,9 @@ bool CheckRX(bool block) if (!(IOPORT(W_RXCnt) & 0x8000)) return false; + if (IOPORT(W_RXBufBegin) == IOPORT(W_RXBufEnd)) + return false; + u16 framelen; u16 framectl; u8 txrate; @@ -1049,7 +1052,7 @@ void USTimer(u32 param) if (!(RXTime & RXHalfwordTimeMask)) { u16 addr = IOPORT(W_RXTXAddr) << 1; - *(u16*)&RAM[addr] = *(u16*)&RXBuffer[RXBufferPtr]; + if (addr < 0x1FFF) *(u16*)&RAM[addr] = *(u16*)&RXBuffer[RXBufferPtr]; IncrementRXAddr(addr); RXBufferPtr += 2; @@ -1146,7 +1149,7 @@ void RFTransfer_Type3() // TODO: wifi waitstates u16 Read(u32 addr) -{ +{//printf("WIFI READ %08X\n", addr); if (addr >= 0x04810000) return 0; @@ -1236,7 +1239,7 @@ u16 Read(u32 addr) } void Write(u32 addr, u16 val) -{ +{//printf("WIFI WRITE %08X %04X\n", addr, val); if (addr >= 0x04810000) return; -- cgit v1.2.3 From 959e7f568da28872058c7e266db6aca1cc3f464c Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 20 Aug 2020 01:19:09 +0200 Subject: GL: be more careful with framebuffer mappings. might fix issues. --- src/GPU3D_OpenGL.cpp | 5 +++-- src/GPU_OpenGL.cpp | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 1abc1de..f7b9b42 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -1159,8 +1159,9 @@ void RenderFrame() { CurShaderID = -1; - if (Antialias) glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[2]); - else glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[FrontBuffer]); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + if (Antialias) glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FramebufferID[2]); + else glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FramebufferID[FrontBuffer]); ShaderConfig.uScreenSize[0] = ScreenW; ShaderConfig.uScreenSize[1] = ScreenH; diff --git a/src/GPU_OpenGL.cpp b/src/GPU_OpenGL.cpp index 1cb6864..b460e07 100644 --- a/src/GPU_OpenGL.cpp +++ b/src/GPU_OpenGL.cpp @@ -162,7 +162,8 @@ void SetRenderSettings(RenderSettings& settings) void RenderFrame() { - glBindFramebuffer(GL_FRAMEBUFFER, CompScreenOutputFB); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, CompScreenOutputFB); glDisable(GL_DEPTH_TEST); glDisable(GL_STENCIL_TEST); -- cgit v1.2.3 From 0688a15e47eeb8a2761e0d318b8686a9728ce227 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 20 Aug 2020 01:37:33 +0200 Subject: blarg --- src/GPU3D_OpenGL.cpp | 4 ++++ src/GPU_OpenGL.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index f7b9b42..debb5fa 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -372,6 +372,8 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 1024, 48, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + return true; } @@ -479,6 +481,8 @@ void SetRenderSettings(GPU::RenderSettings& settings) glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); glBufferData(GL_PIXEL_PACK_BUFFER, 256*192*4, NULL, GL_DYNAMIC_READ); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + //glLineWidth(scale); //glLineWidth(1.5); } diff --git a/src/GPU_OpenGL.cpp b/src/GPU_OpenGL.cpp index b460e07..359e9cd 100644 --- a/src/GPU_OpenGL.cpp +++ b/src/GPU_OpenGL.cpp @@ -121,6 +121,8 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + return true; } @@ -157,6 +159,8 @@ void SetRenderSettings(RenderSettings& settings) glBindFramebuffer(GL_FRAMEBUFFER, CompScreenOutputFB); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, CompScreenOutputTex, 0); glDrawBuffers(1, fbassign); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); } -- cgit v1.2.3 From b5f9278b3a12dbeca2a3b33e8c6331dd9995d5e0 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 20 Aug 2020 03:01:05 +0200 Subject: GL: hopefully finally fix the checkerboard issue --- src/GPU3D_OpenGL.cpp | 74 +++++++++++----------------------------------------- 1 file changed, 15 insertions(+), 59 deletions(-) diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index debb5fa..72b3fc6 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -342,9 +342,6 @@ bool Init() SetupDefaultTexParams(FramebufferTex[5]); SetupDefaultTexParams(FramebufferTex[7]); - // downscale framebuffer for antialiased mode - SetupDefaultTexParams(FramebufferTex[2]); - // downscale framebuffer for display capture (always 256x192) SetupDefaultTexParams(FramebufferTex[3]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 192, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); @@ -406,52 +403,26 @@ void Reset() void SetRenderSettings(GPU::RenderSettings& settings) { int scale = settings.GL_ScaleFactor; - bool antialias = false; // REMOVE ME! - - if (antialias) scale *= 2; ScaleFactor = scale; - Antialias = antialias; ScreenW = 256 * scale; ScreenH = 192 * scale; - if (!antialias) - { - glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[4]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); - //glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH32F_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); - //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ScreenW, ScreenH, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[6]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 1, 1, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[7]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); - } - else - { - glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[4]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW/2, ScreenH/2, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW/2, ScreenH/2, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[6]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[7]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); - } + glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + glBindTexture(GL_TEXTURE_2D, FramebufferTex[4]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ScreenW, ScreenH, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + + glBindTexture(GL_TEXTURE_2D, FramebufferTex[6]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[7]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ScreenW, ScreenH, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[3]); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[3], 0); @@ -466,12 +437,6 @@ void SetRenderSettings(GPU::RenderSettings& settings) glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[1], 0); - glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[4], 0); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[5], 0); - glDrawBuffers(2, fbassign); - - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[2]); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[2], 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[6], 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[7], 0); glDrawBuffers(2, fbassign); @@ -1164,8 +1129,7 @@ void RenderFrame() CurShaderID = -1; glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - if (Antialias) glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FramebufferID[2]); - else glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FramebufferID[FrontBuffer]); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FramebufferID[FrontBuffer]); ShaderConfig.uScreenSize[0] = ScreenW; ShaderConfig.uScreenSize[1] = ScreenH; @@ -1327,14 +1291,6 @@ void RenderFrame() RenderSceneChunk(0, 192); } - if (Antialias) - { - glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferID[2]); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FramebufferID[FrontBuffer]); - glBlitFramebuffer(0, 0, ScreenW, ScreenH, 0, 0, ScreenW/2, ScreenH/2, GL_COLOR_BUFFER_BIT, GL_LINEAR); - } - - //glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[FrontBuffer]); FrontBuffer = FrontBuffer ? 0 : 1; } -- cgit v1.2.3 From 0151a666ef841277a2638f58b117a92b19fee350 Mon Sep 17 00:00:00 2001 From: Raphaël Zumer Date: Sat, 22 Aug 2020 08:47:23 -0400 Subject: Document CMake build dependency on Linux --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ce4f32a..e0b89c1 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ As for the rest, the interface should be pretty straightforward. If you have a q * Install dependencies: ```sh -sudo apt-get install libgtk-3-dev libcurl4-gnutls-dev libpcap0.8-dev libsdl2-dev qtbase5-dev qtdeclarative5-dev libslirp-dev +sudo apt-get install cmake libgtk-3-dev libcurl4-gnutls-dev libpcap0.8-dev libsdl2-dev qtbase5-dev qtdeclarative5-dev libslirp-dev ``` * Compile: -- cgit v1.2.3 From 7464e42ccd68e3fb6455cc60f708a25f00ce6a53 Mon Sep 17 00:00:00 2001 From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com> Date: Sun, 16 Aug 2020 15:11:28 +0100 Subject: Add instructions for static builds Add instructions for static builds fix --- README.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ce4f32a..cc53fa8 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,8 @@ make -j$(nproc --all) 1. Install [MSYS2](https://www.msys2.org/) 2. Open the **MSYS2 MinGW 64-bit** terminal 3. Update the packages using `pacman -Syu` and reopen the terminal if it asks you to + +#### Dynamic builds (with DLLs) 4. Install dependencies: `pacman -S git make mingw-w64-x86_64-{cmake,mesa,SDL2,toolchain,qt5,libslirp}` 5. Run the following commands ```bash @@ -66,9 +68,22 @@ make -j$(nproc --all) make -j$(nproc --all) ../msys-dist.sh ``` - If everything went well, melonDS and the libraries it needs should now be in the `dist` folder. +#### Static builds (without DLLs, standalone executable) +4. Install dependencies: `pacman -S git make mingw-w64-x86_64-{cmake,mesa,SDL2,toolchain,qt5-static,libslirp}` +5. Run the following commands + ```bash + git clone https://github.com/Arisotura/melonDS.git + cd melonDS + mkdir build + cd build + cmake .. -G 'MSYS Makefiles' -DBUILD_STATIC=ON -DQT5_STATIC_DIR=/mingw64/qt5-static + make -j$(nproc --all) + mkdir dist && cp melonDS.exe dist + ``` +If everything went well, melonDS should now be in the `dist` folder. + ## TODO LIST * DSi emulation -- cgit v1.2.3 From c29e6303140af7aa7744d4bc4650399e286a3ac1 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 24 Aug 2020 12:00:13 +0200 Subject: oops. fixes #725 --- src/GPU3D_OpenGL.cpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 72b3fc6..ba77a0c 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -519,6 +519,27 @@ u32* SetupVertex(Polygon* poly, int vid, Vertex* vtx, u32 vtxattr, u32* vptr) y = vtx->FinalPosition[1]; } + // correct nearly-vertical edges that would look vertical on the DS + /*{ + int vtopid = vid - 1; + if (vtopid < 0) vtopid = poly->NumVertices-1; + Vertex* vtop = poly->Vertices[vtopid]; + if (vtop->FinalPosition[1] >= vtx->FinalPosition[1]) + { + vtopid = vid + 1; + if (vtopid >= poly->NumVertices) vtopid = 0; + vtop = poly->Vertices[vtopid]; + } + if ((vtop->FinalPosition[1] < vtx->FinalPosition[1]) && + (vtx->FinalPosition[0] == vtop->FinalPosition[0]-1)) + { + if (ScaleFactor > 1) + x = (vtop->HiresPosition[0] * ScaleFactor) >> 4; + else + x = vtop->FinalPosition[0]; + } + }*/ + *vptr++ = x | (y << 16); *vptr++ = z | (w << 16); @@ -1076,9 +1097,9 @@ void RenderSceneChunk(int y, int h) glStencilMask(0); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[4]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[FrontBuffer ? 6 : 4]); glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[FrontBuffer ? 7 : 5]); glBindBuffer(GL_ARRAY_BUFFER, ClearVertexBufferID); glBindVertexArray(ClearVertexArrayID); -- 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(-) 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(-) 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(-) 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 39af95e8696d640802fe5fb7312e01de42097d43 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 24 Aug 2020 19:55:20 +0200 Subject: make the AR engine use the correct bus funcs based on DS/DSi mode --- src/AREngine.cpp | 77 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 25 deletions(-) diff --git a/src/AREngine.cpp b/src/AREngine.cpp index 8ebf46c..b47bcd4 100644 --- a/src/AREngine.cpp +++ b/src/AREngine.cpp @@ -19,6 +19,7 @@ #include #include #include "NDS.h" +#include "DSi.h" #include "AREngine.h" @@ -28,6 +29,13 @@ namespace AREngine // AR code file - frontend is responsible for managing this ARCodeFile* CodeFile; +u8 (*BusRead8)(u32 addr); +u16 (*BusRead16)(u32 addr); +u32 (*BusRead32)(u32 addr); +void (*BusWrite8)(u32 addr, u8 val); +void (*BusWrite16)(u32 addr, u16 val); +void (*BusWrite32)(u32 addr, u32 val); + bool Init() { @@ -43,6 +51,25 @@ void DeInit() void Reset() { CodeFile = nullptr; + + if (NDS::ConsoleType == 1) + { + BusRead8 = DSi::ARM7Read8; + BusRead16 = DSi::ARM7Read16; + BusRead32 = DSi::ARM7Read32; + BusWrite8 = DSi::ARM7Write8; + BusWrite16 = DSi::ARM7Write16; + BusWrite32 = DSi::ARM7Write32; + } + else + { + BusRead8 = NDS::ARM7Read8; + BusRead16 = NDS::ARM7Read16; + BusRead32 = NDS::ARM7Read32; + BusWrite8 = NDS::ARM7Write8; + BusWrite16 = NDS::ARM7Write16; + BusWrite32 = NDS::ARM7Write32; + } } @@ -102,15 +129,15 @@ void RunCheat(ARCode& arcode) switch (op) { case16(0x00): // 32-bit write - NDS::ARM7Write32((a & 0x0FFFFFFF) + offset, b); + BusWrite32((a & 0x0FFFFFFF) + offset, b); break; case16(0x10): // 16-bit write - NDS::ARM7Write16((a & 0x0FFFFFFF) + offset, b & 0xFFFF); + BusWrite16((a & 0x0FFFFFFF) + offset, b & 0xFFFF); break; case16(0x20): // 8-bit write - NDS::ARM7Write8((a & 0x0FFFFFFF) + offset, b & 0xFF); + BusWrite8((a & 0x0FFFFFFF) + offset, b & 0xFF); break; case16(0x30): // IF b > u32[a] @@ -118,7 +145,7 @@ void RunCheat(ARCode& arcode) condstack <<= 1; condstack |= cond; - u32 chk = NDS::ARM7Read32(a & 0x0FFFFFFF); + u32 chk = BusRead32(a & 0x0FFFFFFF); cond = (b > chk) ? 1:0; } @@ -129,7 +156,7 @@ void RunCheat(ARCode& arcode) condstack <<= 1; condstack |= cond; - u32 chk = NDS::ARM7Read32(a & 0x0FFFFFFF); + u32 chk = BusRead32(a & 0x0FFFFFFF); cond = (b < chk) ? 1:0; } @@ -140,7 +167,7 @@ void RunCheat(ARCode& arcode) condstack <<= 1; condstack |= cond; - u32 chk = NDS::ARM7Read32(a & 0x0FFFFFFF); + u32 chk = BusRead32(a & 0x0FFFFFFF); cond = (b == chk) ? 1:0; } @@ -151,7 +178,7 @@ void RunCheat(ARCode& arcode) condstack <<= 1; condstack |= cond; - u32 chk = NDS::ARM7Read32(a & 0x0FFFFFFF); + u32 chk = BusRead32(a & 0x0FFFFFFF); cond = (b != chk) ? 1:0; } @@ -162,7 +189,7 @@ void RunCheat(ARCode& arcode) condstack <<= 1; condstack |= cond; - u16 val = NDS::ARM7Read16(a & 0x0FFFFFFF); + u16 val = BusRead16(a & 0x0FFFFFFF); u16 chk = ~(b >> 16); chk &= val; @@ -175,7 +202,7 @@ void RunCheat(ARCode& arcode) condstack <<= 1; condstack |= cond; - u16 val = NDS::ARM7Read16(a & 0x0FFFFFFF); + u16 val = BusRead16(a & 0x0FFFFFFF); u16 chk = ~(b >> 16); chk &= val; @@ -188,7 +215,7 @@ void RunCheat(ARCode& arcode) condstack <<= 1; condstack |= cond; - u16 val = NDS::ARM7Read16(a & 0x0FFFFFFF); + u16 val = BusRead16(a & 0x0FFFFFFF); u16 chk = ~(b >> 16); chk &= val; @@ -201,7 +228,7 @@ void RunCheat(ARCode& arcode) condstack <<= 1; condstack |= cond; - u16 val = NDS::ARM7Read16(a & 0x0FFFFFFF); + u16 val = BusRead16(a & 0x0FFFFFFF); u16 chk = ~(b >> 16); chk &= val; @@ -210,7 +237,7 @@ void RunCheat(ARCode& arcode) break; case16(0xB0): // offset = u32[a + offset] - offset = NDS::ARM7Read32((a & 0x0FFFFFFF) + offset); + offset = BusRead32((a & 0x0FFFFFFF) + offset); break; case 0xC0: // FOR 0..b @@ -247,7 +274,7 @@ void RunCheat(ARCode& arcode) break; case 0xC6: // u32[b] = offset - NDS::ARM7Write32(b, offset); + BusWrite32(b, offset); break; case 0xD0: // ENDIF @@ -296,30 +323,30 @@ void RunCheat(ARCode& arcode) break; case 0xD6: // u32[b+offset] = datareg / offset += 4 - NDS::ARM7Write32(b + offset, datareg); + BusWrite32(b + offset, datareg); offset += 4; break; case 0xD7: // u16[b+offset] = datareg / offset += 2 - NDS::ARM7Write16(b + offset, datareg & 0xFFFF); + BusWrite16(b + offset, datareg & 0xFFFF); offset += 2; break; case 0xD8: // u8[b+offset] = datareg / offset += 1 - NDS::ARM7Write8(b + offset, datareg & 0xFF); + BusWrite8(b + offset, datareg & 0xFF); offset += 1; break; case 0xD9: // datareg = u32[b+offset] - datareg = NDS::ARM7Read32(b + offset); + datareg = BusRead32(b + offset); break; case 0xDA: // datareg = u16[b+offset] - datareg = NDS::ARM7Read16(b + offset); + datareg = BusRead16(b + offset); break; case 0xDB: // datareg = u8[b+offset] - datareg = NDS::ARM7Read8(b + offset); + datareg = BusRead8(b + offset); break; case 0xDC: // offset += b @@ -334,8 +361,8 @@ void RunCheat(ARCode& arcode) u32 bytesleft = b; while (bytesleft >= 8) { - NDS::ARM7Write32(dstaddr, *code++); dstaddr += 4; - NDS::ARM7Write32(dstaddr, *code++); dstaddr += 4; + BusWrite32(dstaddr, *code++); dstaddr += 4; + BusWrite32(dstaddr, *code++); dstaddr += 4; bytesleft -= 8; } if (bytesleft > 0) @@ -344,13 +371,13 @@ void RunCheat(ARCode& arcode) code += 2; if (bytesleft >= 4) { - NDS::ARM7Write32(dstaddr, *(u32*)leftover); dstaddr += 4; + BusWrite32(dstaddr, *(u32*)leftover); dstaddr += 4; leftover += 4; bytesleft -= 4; } while (bytesleft > 0) { - NDS::ARM7Write8(dstaddr, *leftover++); dstaddr++; + BusWrite8(dstaddr, *leftover++); dstaddr++; bytesleft--; } } @@ -366,14 +393,14 @@ void RunCheat(ARCode& arcode) u32 bytesleft = b; while (bytesleft >= 4) { - NDS::ARM7Write32(dstaddr, NDS::ARM7Read32(srcaddr)); + BusWrite32(dstaddr, BusRead32(srcaddr)); srcaddr += 4; dstaddr += 4; bytesleft -= 4; } while (bytesleft > 0) { - NDS::ARM7Write8(dstaddr, NDS::ARM7Read8(srcaddr)); + BusWrite8(dstaddr, BusRead8(srcaddr)); srcaddr++; dstaddr++; bytesleft--; -- 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(-) 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(-) 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 30fc6bbc09bfc1e57044b766813e57733777948a Mon Sep 17 00:00:00 2001 From: RSDuck Date: Sun, 23 Aug 2020 00:52:15 +0200 Subject: JIT: fix QDSUB/QSUB for interpreter run --- src/ARMJIT.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ARMJIT.cpp b/src/ARMJIT.cpp index 59f7f54..31983f6 100644 --- a/src/ARMJIT.cpp +++ b/src/ARMJIT.cpp @@ -480,7 +480,7 @@ InterpreterFunc InterpretARM[ARMInstrInfo::ak_Count] = F_ALU(CMN,), F(MUL), F(MLA), F(UMULL), F(UMLAL), F(SMULL), F(SMLAL), F(SMLAxy), F(SMLAWy), F(SMULWy), F(SMLALxy), F(SMULxy), - F(CLZ), F(QADD), F(QDADD), F(QSUB), F(QDSUB), + F(CLZ), F(QADD), F(QSUB), F(QDADD), F(QDSUB), F_MEM_WB(STR), F_MEM_WB(STRB), -- 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(-) 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(-) 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 e5dd692d3279a1bc79ef6b0923c2210f98ec5ed1 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 25 Aug 2020 00:17:22 +0200 Subject: AES: fix bug where CCM-encrypt MAC could be obliterated, by attempting to write it while the output FIFO was full --- src/DSi_AES.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/DSi_AES.cpp b/src/DSi_AES.cpp index dfa67bd..8f5c3f3 100644 --- a/src/DSi_AES.cpp +++ b/src/DSi_AES.cpp @@ -52,6 +52,10 @@ u8 KeyY[4][16]; u8 CurKey[16]; u8 CurMAC[16]; +// output MAC for CCM encrypt +u8 OutputMAC[16]; +bool OutputMACDue; + AES_ctx Ctx; @@ -129,6 +133,9 @@ void Reset() memset(CurKey, 0, sizeof(CurKey)); memset(CurMAC, 0, sizeof(CurMAC)); + memset(OutputMAC, 0, sizeof(OutputMAC)); + OutputMACDue = false; + // initialize keys // slot 0: modcrypt @@ -272,6 +279,8 @@ void WriteCnt(u32 val) // transfer start (checkme) RemBlocks = BlkCnt >> 16; + OutputMACDue = false; + if (AESMode == 0 && (!(val & (1<<20)))) printf("AES: CCM-DECRYPT MAC FROM WRFIFO, TODO\n"); if (RemBlocks > 0) @@ -347,6 +356,15 @@ u32 ReadOutputFIFO() DSi::CheckNDMAs(1, 0x2B); else DSi::StopNDMAs(1, 0x2B); + + if (OutputMACDue && OutputFIFO->Level() <= 12) + { + OutputFIFO->Write(*(u32*)&OutputMAC[0]); + OutputFIFO->Write(*(u32*)&OutputMAC[4]); + OutputFIFO->Write(*(u32*)&OutputMAC[8]); + OutputFIFO->Write(*(u32*)&OutputMAC[12]); + OutputMACDue = false; + } } return ret; @@ -429,13 +447,8 @@ void Update() Ctx.Iv[15] = 0x00; AES_CTR_xcrypt_buffer(&Ctx, CurMAC, 16); - u8 finalmac[16]; - Swap16(finalmac, CurMAC); - - OutputFIFO->Write(*(u32*)&finalmac[0]); - OutputFIFO->Write(*(u32*)&finalmac[4]); - OutputFIFO->Write(*(u32*)&finalmac[8]); - OutputFIFO->Write(*(u32*)&finalmac[12]); + Swap16(OutputMAC, CurMAC); + OutputMACDue = true; // CHECKME Cnt &= ~(1<<21); -- 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(-) 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 b12e1a1b6e2c983f522ef1369a6bfb8167b1bf4c Mon Sep 17 00:00:00 2001 From: RSDuck Date: Tue, 25 Aug 2020 18:13:17 +0200 Subject: JIT fastmem: fix out of bounds read seems to fix #727 --- src/ARMJIT_Memory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ARMJIT_Memory.cpp b/src/ARMJIT_Memory.cpp index 7885fb7..c5c8f04 100644 --- a/src/ARMJIT_Memory.cpp +++ b/src/ARMJIT_Memory.cpp @@ -524,8 +524,8 @@ bool MapAtAddress(u32 addr) { u32 sectionOffset = offset; bool hasCode = isExecutable && ARMJIT::PageContainsCode(&range[offset / 512]); - while ((!isExecutable || ARMJIT::PageContainsCode(&range[offset / 512]) == hasCode) - && offset < mirrorSize + while (offset < mirrorSize + && (!isExecutable || ARMJIT::PageContainsCode(&range[offset / 512]) == hasCode) && (!skipDTCM || mirrorStart + offset != NDS::ARM9->DTCMBase)) { assert(states[(mirrorStart + offset) >> 12] == memstate_Unmapped); -- cgit v1.2.3 From ba0cbc53ca6e80282d63f6fcee2fb28d2ff7975e Mon Sep 17 00:00:00 2001 From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com> Date: Wed, 26 Aug 2020 14:21:34 +0100 Subject: Update build-ubuntu.yml --- .github/workflows/build-ubuntu.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-ubuntu.yml b/.github/workflows/build-ubuntu.yml index 5974c69..d275f1f 100644 --- a/.github/workflows/build-ubuntu.yml +++ b/.github/workflows/build-ubuntu.yml @@ -24,8 +24,8 @@ jobs: working-directory: ${{runner.workspace}} run: | # Fetch a new version of CMake, because the default is too old. sudo rm -f /etc/apt/sources.list.d/dotnetdev.list /etc/apt/sources.list.d/microsoft-prod.list \ - && sudo apt-get update \ - && sudo apt-get install cmake libcurl4-gnutls-dev libpcap0.8-dev libsdl2-dev qt5-default libslirp-dev + && sudo apt update \ + && sudo apt install cmake libcurl4-gnutls-dev libpcap0.8-dev libsdl2-dev qt5-default libslirp0=4.1.0-2ubuntu2.1 libslirp-dev --allow-downgrades - name: Create build environment run: mkdir ${{runner.workspace}}/build - name: Configure -- 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(+) 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 9bfaf8682db10d5e1fe82ee4cefa3e7f0d9fbb1b Mon Sep 17 00:00:00 2001 From: qeeg Date: Mon, 31 Aug 2020 16:37:42 -0500 Subject: Fix a typo --- src/NDS.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NDS.cpp b/src/NDS.cpp index bb579f6..a23772c 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -3745,7 +3745,7 @@ void ARM7IOWrite8(u32 addr, u8 val) return; case 0x04000301: - val & 0xC0; + val &= 0xC0; if (val == 0x40) printf("!! GBA MODE NOT SUPPORTED\n"); else if (val == 0x80) ARM7->Halt(1); else if (val == 0xC0) EnterSleepMode(); -- cgit v1.2.3 From aa94cbaeb0cca8c3f05639fd93a979b38757f899 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 3 Sep 2020 11:51:50 +0200 Subject: DSi: add support for 8-bit VRAM writes when enabled in SCFG_EXT. fixes #733 --- src/DSi.cpp | 14 ++++++++++++++ src/DSi_Camera.cpp | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/DSi.cpp b/src/DSi.cpp index 66b8ed0..a96322b 100644 --- a/src/DSi.cpp +++ b/src/DSi.cpp @@ -912,6 +912,20 @@ void ARM9Write8(u32 addr, u8 val) case 0x04000000: ARM9IOWrite8(addr, val); return; + + case 0x06000000: + if (!(SCFG_EXT[0] & (1<<13))) return; +#ifdef JIT_ENABLED + ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_VRAM>(addr); +#endif + switch (addr & 0x00E00000) + { + case 0x00000000: GPU::WriteVRAM_ABG(addr, val); return; + case 0x00200000: GPU::WriteVRAM_BBG(addr, val); return; + case 0x00400000: GPU::WriteVRAM_AOBJ(addr, val); return; + case 0x00600000: GPU::WriteVRAM_BOBJ(addr, val); return; + default: GPU::WriteVRAM_LCDC(addr, val); return; + } } return NDS::ARM9Write8(addr, val); diff --git a/src/DSi_Camera.cpp b/src/DSi_Camera.cpp index cc44052..56cba1c 100644 --- a/src/DSi_Camera.cpp +++ b/src/DSi_Camera.cpp @@ -140,7 +140,7 @@ u16 DSi_Camera::ReadReg(u16 addr) case 0x301A: return ((~StandbyCnt) & 0x4000) >> 12; } - printf("DSi_Camera%d: unknown read %04X\n", Num, addr); + //printf("DSi_Camera%d: unknown read %04X\n", Num, addr); return 0; } @@ -162,5 +162,5 @@ void DSi_Camera::WriteReg(u16 addr, u16 val) return; } - printf("DSi_Camera%d: unknown write %04X %04X\n", Num, addr, val); + //printf("DSi_Camera%d: unknown write %04X %04X\n", Num, addr, val); } -- cgit v1.2.3 From 81eda0f19c7e05a496eef22384773205a1efa7c9 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 3 Sep 2020 19:05:13 +0200 Subject: bahahahhh --- src/melonDLDI.h | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/melonDLDI.h diff --git a/src/melonDLDI.h b/src/melonDLDI.h new file mode 100644 index 0000000..466afc0 --- /dev/null +++ b/src/melonDLDI.h @@ -0,0 +1,54 @@ +/* + 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 MELONDLDI_H +#define MELONDLDI_H + +const u8 melonDLDI[] = +{ + 0xED, 0xA5, 0x8D, 0xBF, 0x20, 0x43, 0x68, 0x69, 0x73, 0x68, 0x6D, 0x00, 0x01, 0x01, 0x00, 0x00, + 0x6D, 0x65, 0x6C, 0x6F, 0x6E, 0x44, 0x53, 0x20, 0x44, 0x4C, 0x44, 0x49, 0x20, 0x64, 0x72, 0x69, + 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xBF, 0xC0, 0x01, 0x80, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4D, 0x45, 0x4C, 0x4E, 0x23, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0xBF, 0x88, 0x00, 0x80, 0xBF, + 0x30, 0x01, 0x80, 0xBF, 0x70, 0x01, 0x80, 0xBF, 0xB0, 0x01, 0x80, 0xBF, 0xB8, 0x01, 0x80, 0xBF, + 0x01, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1, 0x01, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1, + 0x01, 0xC3, 0xA0, 0xE3, 0x1A, 0xCE, 0x8C, 0xE2, 0x02, 0x39, 0xA0, 0xE3, 0xB0, 0x30, 0xCC, 0xE1, + 0x08, 0x00, 0xCC, 0xE5, 0x0C, 0x10, 0xCC, 0xE5, 0x21, 0x14, 0xA0, 0xE1, 0x0B, 0x10, 0xCC, 0xE5, + 0x21, 0x14, 0xA0, 0xE1, 0x0A, 0x10, 0xCC, 0xE5, 0x21, 0x14, 0xA0, 0xE1, 0x09, 0x10, 0xCC, 0xE5, + 0x21, 0x14, 0xA0, 0xE1, 0x0D, 0x10, 0xCC, 0xE5, 0xBE, 0x10, 0xCC, 0xE1, 0x03, 0x31, 0xA0, 0xE3, + 0x00, 0x00, 0x52, 0xE3, 0x01, 0x34, 0x83, 0x13, 0x01, 0x35, 0x83, 0xE3, 0x04, 0x30, 0x8C, 0xE5, + 0x41, 0x36, 0xA0, 0xE3, 0x01, 0x00, 0x10, 0xE3, 0x07, 0x00, 0x00, 0x1A, 0x04, 0x00, 0x9C, 0xE5, + 0x02, 0x05, 0x10, 0xE3, 0x10, 0x10, 0x93, 0x15, 0x00, 0x00, 0x52, 0x13, 0x04, 0x10, 0x82, 0x14, + 0x02, 0x01, 0x10, 0xE3, 0xF8, 0xFF, 0xFF, 0x1A, 0x1E, 0xFF, 0x2F, 0xE1, 0x00, 0x10, 0xA0, 0xE3, + 0x04, 0x00, 0x9C, 0xE5, 0x02, 0x05, 0x10, 0xE3, 0x00, 0x00, 0x52, 0x13, 0x04, 0x10, 0x92, 0x14, + 0x10, 0x10, 0x83, 0x15, 0x02, 0x01, 0x10, 0xE3, 0xF8, 0xFF, 0xFF, 0x1A, 0x1E, 0xFF, 0x2F, 0xE1, + 0x03, 0x00, 0x12, 0xE3, 0x00, 0x00, 0xA0, 0x13, 0x1E, 0xFF, 0x2F, 0x11, 0x78, 0x40, 0x2D, 0xE9, + 0x00, 0x40, 0xA0, 0xE1, 0x01, 0x50, 0xA0, 0xE1, 0x00, 0x60, 0xA0, 0xE3, 0xC0, 0x00, 0xA0, 0xE3, + 0x06, 0x10, 0x84, 0xE0, 0xCD, 0xFF, 0xFF, 0xEB, 0x01, 0x60, 0x86, 0xE2, 0x05, 0x00, 0x56, 0xE1, + 0xF9, 0xFF, 0xFF, 0x3A, 0x78, 0x40, 0xBD, 0xE8, 0x01, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1, + 0x03, 0x00, 0x12, 0xE3, 0x00, 0x00, 0xA0, 0x13, 0x1E, 0xFF, 0x2F, 0x11, 0x78, 0x40, 0x2D, 0xE9, + 0x00, 0x40, 0xA0, 0xE1, 0x01, 0x50, 0xA0, 0xE1, 0x00, 0x60, 0xA0, 0xE3, 0xC1, 0x00, 0xA0, 0xE3, + 0x06, 0x10, 0x84, 0xE0, 0xBD, 0xFF, 0xFF, 0xEB, 0x01, 0x60, 0x86, 0xE2, 0x05, 0x00, 0x56, 0xE1, + 0xF9, 0xFF, 0xFF, 0x3A, 0x78, 0x40, 0xBD, 0xE8, 0x01, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1, + 0x01, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1, 0x01, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1, +}; + +#endif // MELONDLDI_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(-) 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 3739e4dd670145aa7c555c9dd372efc32a93a676 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 4 Sep 2020 10:36:50 +0200 Subject: muhhahahahahh --- melon.rc | 8 ++++---- src/version.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/melon.rc b/melon.rc index c6ee672..dae2772 100644 --- a/melon.rc +++ b/melon.rc @@ -6,8 +6,8 @@ //include version information in .exe, modify these values to match your needs 1 VERSIONINFO -FILEVERSION 0,8,3,0 -PRODUCTVERSION 0,8,3,0 +FILEVERSION 0,9,0,0 +PRODUCTVERSION 0,9,0,0 FILETYPE VFT_APP { BLOCK "StringFileInfo" @@ -15,14 +15,14 @@ FILETYPE VFT_APP BLOCK "040904E4" { VALUE "CompanyName", "Melon Factory of Kuribo64" - VALUE "FileVersion", "0.8.3" + VALUE "FileVersion", "0.9" VALUE "FileDescription", "DS emulator, sorta. also 1st quality melon." VALUE "InternalName", "SDnolem" VALUE "LegalCopyright", "2016-2020 Arisotura & co." VALUE "LegalTrademarks", "" VALUE "OriginalFilename", "zafkflzdasd.exe" VALUE "ProductName", "melonDS" - VALUE "ProductVersion", "0.8.3" + VALUE "ProductVersion", "0.9" } } BLOCK "VarFileInfo" diff --git a/src/version.h b/src/version.h index 9084606..f0498d7 100644 --- a/src/version.h +++ b/src/version.h @@ -19,7 +19,7 @@ #ifndef VERSION_H #define VERSION_H -#define MELONDS_VERSION "0.8.3-JIT" +#define MELONDS_VERSION "0.9" #define MELONDS_URL "http://melonds.kuribo64.net/" -- 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(-) 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 9772201345ab47cc820fd6c08247c133605f8b84 Mon Sep 17 00:00:00 2001 From: RSDuck Date: Fri, 4 Sep 2020 20:37:14 +0200 Subject: remove some UB - savestates used to read a four bytes from a single byte value - a few unassigned variables - some other things - also make the ROR macro an inline function --- src/ARM.h | 5 ++++- src/ARMJIT.cpp | 5 ++++- src/ARMJIT_A64/ARMJIT_ALU.cpp | 6 +++--- src/ARMJIT_A64/ARMJIT_Compiler.cpp | 2 +- src/ARMJIT_A64/ARMJIT_LoadStore.cpp | 6 +++--- src/ARMJIT_x64/ARMJIT_ALU.cpp | 6 +++--- src/ARMJIT_x64/ARMJIT_Compiler.cpp | 2 +- src/ARMJIT_x64/ARMJIT_LoadStore.cpp | 8 ++++---- src/DMA.cpp | 6 ++++-- src/GPU2D.cpp | 1 + src/GPU3D.cpp | 14 +++++++------- src/NDS.cpp | 2 +- src/Savestate.cpp | 18 +++++++++++++++++- src/Savestate.h | 2 ++ src/Wifi.cpp | 2 +- src/dolphin/Arm64Emitter.cpp | 2 +- src/dolphin/Arm64Emitter.h | 2 +- src/dolphin/x64Emitter.cpp | 2 +- src/dolphin/x64Emitter.h | 2 +- 19 files changed, 60 insertions(+), 33 deletions(-) diff --git a/src/ARM.h b/src/ARM.h index deacbee..52c971a 100644 --- a/src/ARM.h +++ b/src/ARM.h @@ -24,7 +24,10 @@ #include "types.h" #include "NDS.h" -#define ROR(x, n) (((x) >> (n)) | ((x) << (32-(n)))) +inline u32 ROR(u32 x, u32 n) +{ + return (x >> (n&0x1F)) | (x << ((32-n)&0x1F)); +} enum { diff --git a/src/ARMJIT.cpp b/src/ARMJIT.cpp index 31983f6..c9d2b62 100644 --- a/src/ARMJIT.cpp +++ b/src/ARMJIT.cpp @@ -1087,7 +1087,10 @@ void ResetBlockCache() InvalidLiterals.Clear(); for (int i = 0; i < ARMJIT_Memory::memregions_Count; i++) - memset(FastBlockLookupRegions[i], 0xFF, CodeRegionSizes[i] * sizeof(u64) / 2); + { + if (FastBlockLookupRegions[i]) + memset(FastBlockLookupRegions[i], 0xFF, CodeRegionSizes[i] * sizeof(u64) / 2); + } for (auto it = RestoreCandidates.begin(); it != RestoreCandidates.end(); it++) delete it->second; RestoreCandidates.clear(); diff --git a/src/ARMJIT_A64/ARMJIT_ALU.cpp b/src/ARMJIT_A64/ARMJIT_ALU.cpp index 26a89cb..52a2258 100644 --- a/src/ARMJIT_A64/ARMJIT_ALU.cpp +++ b/src/ARMJIT_A64/ARMJIT_ALU.cpp @@ -436,7 +436,7 @@ void Compiler::A_Comp_GetOp2(bool S, Op2& op2) Comp_AddCycles_C(); u32 shift = (CurInstr.Instr >> 7) & 0x1E; - u32 imm = ROR(CurInstr.Instr & 0xFF, shift); + u32 imm = ::ROR(CurInstr.Instr & 0xFF, shift); if (S && shift && (CurInstr.SetFlags & 0x2)) { @@ -447,7 +447,7 @@ void Compiler::A_Comp_GetOp2(bool S, Op2& op2) ANDI2R(RCPSR, RCPSR, ~(1 << 29)); } - op2 = Op2(ROR(CurInstr.Instr & 0xFF, (CurInstr.Instr >> 7) & 0x1E)); + op2 = Op2(imm); } else { @@ -523,7 +523,7 @@ void Compiler::A_Comp_ALUMovOp() case ST_LSL: LSL(rd, op2.Reg.Rm, op2.Reg.ShiftAmount); break; case ST_LSR: LSR(rd, op2.Reg.Rm, op2.Reg.ShiftAmount); break; case ST_ASR: ASR(rd, op2.Reg.Rm, op2.Reg.ShiftAmount); break; - case ST_ROR: ROR_(rd, op2.Reg.Rm, op2.Reg.ShiftAmount); break; + case ST_ROR: ROR(rd, op2.Reg.Rm, op2.Reg.ShiftAmount); break; } } else diff --git a/src/ARMJIT_A64/ARMJIT_Compiler.cpp b/src/ARMJIT_A64/ARMJIT_Compiler.cpp index b046123..80c7f04 100644 --- a/src/ARMJIT_A64/ARMJIT_Compiler.cpp +++ b/src/ARMJIT_A64/ARMJIT_Compiler.cpp @@ -76,7 +76,7 @@ void Compiler::A_Comp_MSR() if (CurInstr.Instr & (1 << 25)) { val = W0; - MOVI2R(val, ROR((CurInstr.Instr & 0xFF), ((CurInstr.Instr >> 7) & 0x1E))); + MOVI2R(val, ::ROR((CurInstr.Instr & 0xFF), ((CurInstr.Instr >> 7) & 0x1E))); } else { diff --git a/src/ARMJIT_A64/ARMJIT_LoadStore.cpp b/src/ARMJIT_A64/ARMJIT_LoadStore.cpp index 6140ffc..14aa847 100644 --- a/src/ARMJIT_A64/ARMJIT_LoadStore.cpp +++ b/src/ARMJIT_A64/ARMJIT_LoadStore.cpp @@ -65,7 +65,7 @@ bool Compiler::Comp_MemLoadLiteral(int size, bool signExtend, int rd, u32 addr) if (size == 32) { CurCPU->DataRead32(addr & ~0x3, &val); - val = ROR(val, (addr & 0x3) << 3); + val = ::ROR(val, (addr & 0x3) << 3); } else if (size == 16) { @@ -151,7 +151,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, Op2 offset, int size, int flags) { if (offset.Reg.ShiftType == ST_ROR) { - ROR_(W0, offset.Reg.Rm, offset.Reg.ShiftAmount); + ROR(W0, offset.Reg.Rm, offset.Reg.ShiftAmount); offset = Op2(W0); } @@ -220,7 +220,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, Op2 offset, int size, int flags) if (size == 32) { if (staticAddress & 0x3) - ROR_(rdMapped, W0, (staticAddress & 0x3) << 3); + ROR(rdMapped, W0, (staticAddress & 0x3) << 3); else MOV(rdMapped, W0); } diff --git a/src/ARMJIT_x64/ARMJIT_ALU.cpp b/src/ARMJIT_x64/ARMJIT_ALU.cpp index 57a38c4..24d22ed 100644 --- a/src/ARMJIT_x64/ARMJIT_ALU.cpp +++ b/src/ARMJIT_x64/ARMJIT_ALU.cpp @@ -110,7 +110,7 @@ OpArg Compiler::A_Comp_GetALUOp2(bool S, bool& carryUsed) Comp_AddCycles_C(); u32 shift = (CurInstr.Instr >> 7) & 0x1E; - u32 imm = ROR(CurInstr.Instr & 0xFF, shift); + u32 imm = ::ROR(CurInstr.Instr & 0xFF, shift); carryUsed = false; if (S && shift) @@ -493,7 +493,7 @@ OpArg Compiler::Comp_RegShiftReg(int op, Gen::OpArg rs, Gen::OpArg rm, bool S, b { if (S) BT(32, R(RSCRATCH), Imm8(31)); - ROR_(32, R(RSCRATCH), R(ECX)); + ROR(32, R(RSCRATCH), R(ECX)); if (S) SETcc(CC_C, R(RSCRATCH2)); } @@ -555,7 +555,7 @@ OpArg Compiler::Comp_RegShiftImm(int op, int amount, OpArg rm, bool S, bool& car case 3: // ROR MOV(32, R(RSCRATCH), rm); if (amount > 0) - ROR_(32, R(RSCRATCH), Imm8(amount)); + ROR(32, R(RSCRATCH), Imm8(amount)); else { BT(32, R(RCPSR), Imm8(29)); diff --git a/src/ARMJIT_x64/ARMJIT_Compiler.cpp b/src/ARMJIT_x64/ARMJIT_Compiler.cpp index 1fdbaf8..c6419c9 100644 --- a/src/ARMJIT_x64/ARMJIT_Compiler.cpp +++ b/src/ARMJIT_x64/ARMJIT_Compiler.cpp @@ -106,7 +106,7 @@ void Compiler::A_Comp_MSR() Comp_AddCycles_C(); OpArg val = CurInstr.Instr & (1 << 25) - ? Imm32(ROR((CurInstr.Instr & 0xFF), ((CurInstr.Instr >> 7) & 0x1E))) + ? Imm32(::ROR((CurInstr.Instr & 0xFF), ((CurInstr.Instr >> 7) & 0x1E))) : MapReg(CurInstr.A_Reg(0)); u32 mask = 0; diff --git a/src/ARMJIT_x64/ARMJIT_LoadStore.cpp b/src/ARMJIT_x64/ARMJIT_LoadStore.cpp index 57d98cc..1be6608 100644 --- a/src/ARMJIT_x64/ARMJIT_LoadStore.cpp +++ b/src/ARMJIT_x64/ARMJIT_LoadStore.cpp @@ -73,7 +73,7 @@ bool Compiler::Comp_MemLoadLiteral(int size, bool signExtend, int rd, u32 addr) if (size == 32) { CurCPU->DataRead32(addr & ~0x3, &val); - val = ROR(val, (addr & 0x3) << 3); + val = ::ROR(val, (addr & 0x3) << 3); } else if (size == 16) { @@ -225,13 +225,13 @@ void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flag if (addrIsStatic) { if (staticAddress & 0x3) - ROR_(32, rdMapped, Imm8((staticAddress & 0x3) * 8)); + ROR(32, rdMapped, Imm8((staticAddress & 0x3) * 8)); } else { AND(32, R(RSCRATCH3), Imm8(0x3)); SHL(32, R(RSCRATCH3), Imm8(3)); - ROR_(32, rdMapped, R(RSCRATCH3)); + ROR(32, rdMapped, R(RSCRATCH3)); } } } @@ -270,7 +270,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flag { MOV(32, rdMapped, R(RSCRATCH)); if (staticAddress & 0x3) - ROR_(32, rdMapped, Imm8((staticAddress & 0x3) * 8)); + ROR(32, rdMapped, Imm8((staticAddress & 0x3) * 8)); } else { diff --git a/src/DMA.cpp b/src/DMA.cpp index cd2df45..18b8a2f 100644 --- a/src/DMA.cpp +++ b/src/DMA.cpp @@ -73,6 +73,8 @@ void DMA::Reset() SrcAddrInc = 0; DstAddrInc = 0; + Stall = false; + Running = false; InProgress = false; @@ -111,8 +113,8 @@ void DMA::DoSavestate(Savestate* file) file->Var32(&DstAddrInc); file->Var32(&Running); - file->Var32((u32*)&InProgress); - file->Var32((u32*)&IsGXFIFODMA); + file->Bool32(&InProgress); + file->Bool32(&IsGXFIFODMA); } void DMA::WriteCnt(u32 val) diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 2c3086c..07790b7 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -102,6 +102,7 @@ GPU2D::~GPU2D() void GPU2D::Reset() { + Enabled = false; DispCnt = 0; memset(BGCnt, 0, 4*2); memset(BGXPos, 0, 4*2); diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index d9d6ba8..5ccacf4 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -470,7 +470,7 @@ void DoSavestate(Savestate* file) file->VarArray(vtx->Color, sizeof(s32)*3); file->VarArray(vtx->TexCoords, sizeof(s16)*2); - file->Var32((u32*)&vtx->Clipped); + file->Bool32(&vtx->Clipped); file->VarArray(vtx->FinalPosition, sizeof(s32)*2); file->VarArray(vtx->FinalColor, sizeof(s32)*3); @@ -507,7 +507,7 @@ void DoSavestate(Savestate* file) file->VarArray(vtx->Color, sizeof(s32)*3); file->VarArray(vtx->TexCoords, sizeof(s16)*2); - file->Var32((u32*)&vtx->Clipped); + file->Bool32(&vtx->Clipped); file->VarArray(vtx->FinalPosition, sizeof(s32)*2); file->VarArray(vtx->FinalColor, sizeof(s32)*3); @@ -545,17 +545,17 @@ void DoSavestate(Savestate* file) file->VarArray(poly->FinalZ, sizeof(s32)*10); file->VarArray(poly->FinalW, sizeof(s32)*10); - file->Var32((u32*)&poly->WBuffer); + file->Bool32(&poly->WBuffer); file->Var32(&poly->Attr); file->Var32(&poly->TexParam); file->Var32(&poly->TexPalette); - file->Var32((u32*)&poly->FacingView); - file->Var32((u32*)&poly->Translucent); + file->Bool32(&poly->FacingView); + file->Bool32(&poly->Translucent); - file->Var32((u32*)&poly->IsShadowMask); - file->Var32((u32*)&poly->IsShadow); + file->Bool32(&poly->IsShadowMask); + file->Bool32(&poly->IsShadow); if (file->IsAtleastVersion(4, 1)) file->Var32((u32*)&poly->Type); diff --git a/src/NDS.cpp b/src/NDS.cpp index f926399..20f149a 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -775,7 +775,7 @@ bool DoSavestate(Savestate* file) file->Var8(&WRAMCnt); - file->Var32((u32*)&RunningGame); + file->Bool32(&RunningGame); if (!file->Saving) { diff --git a/src/Savestate.cpp b/src/Savestate.cpp index 0337ff2..ba8ffd9 100644 --- a/src/Savestate.cpp +++ b/src/Savestate.cpp @@ -261,6 +261,22 @@ void Savestate::Var64(u64* var) } } +void Savestate::Bool32(bool* var) +{ + // for compability + if (Saving) + { + u32 val = *var; + Var32(&val); + } + else + { + u32 val; + Var32(&val); + *var = val != 0; + } +} + void Savestate::VarArray(void* data, u32 len) { if (Error) return; @@ -273,4 +289,4 @@ void Savestate::VarArray(void* data, u32 len) { fread(data, len, 1, file); } -} +} \ No newline at end of file diff --git a/src/Savestate.h b/src/Savestate.h index a5447b3..c3c2e1d 100644 --- a/src/Savestate.h +++ b/src/Savestate.h @@ -46,6 +46,8 @@ public: void Var32(u32* var); void Var64(u64* var); + void Bool32(bool* var); + void VarArray(void* data, u32 len); bool IsAtleastVersion(u32 major, u32 minor) diff --git a/src/Wifi.cpp b/src/Wifi.cpp index 8a06041..2957007 100644 --- a/src/Wifi.cpp +++ b/src/Wifi.cpp @@ -237,7 +237,7 @@ void DoSavestate(Savestate* file) file->Var64(&USCounter); file->Var64(&USCompare); - file->Var32((u32*)&BlockBeaconIRQ14); + file->Bool32(&BlockBeaconIRQ14); file->Var32(&ComStatus); file->Var32(&TXCurSlot); diff --git a/src/dolphin/Arm64Emitter.cpp b/src/dolphin/Arm64Emitter.cpp index 97c93ba..289b20c 100644 --- a/src/dolphin/Arm64Emitter.cpp +++ b/src/dolphin/Arm64Emitter.cpp @@ -1631,7 +1631,7 @@ void ARM64XEmitter::ASR(ARM64Reg Rd, ARM64Reg Rm, int shift) int bits = Is64Bit(Rd) ? 64 : 32; SBFM(Rd, Rm, shift, bits - 1); } -void ARM64XEmitter::ROR_(ARM64Reg Rd, ARM64Reg Rm, int shift) +void ARM64XEmitter::ROR(ARM64Reg Rd, ARM64Reg Rm, int shift) { EXTR(Rd, Rm, Rm, shift); } diff --git a/src/dolphin/Arm64Emitter.h b/src/dolphin/Arm64Emitter.h index 4c49502..3da3912 100644 --- a/src/dolphin/Arm64Emitter.h +++ b/src/dolphin/Arm64Emitter.h @@ -727,7 +727,7 @@ public: void LSR(ARM64Reg Rd, ARM64Reg Rm, int shift); void LSL(ARM64Reg Rd, ARM64Reg Rm, int shift); void ASR(ARM64Reg Rd, ARM64Reg Rm, int shift); - void ROR_(ARM64Reg Rd, ARM64Reg Rm, int shift); + void ROR(ARM64Reg Rd, ARM64Reg Rm, int shift); // Logical (immediate) void AND(ARM64Reg Rd, ARM64Reg Rn, u32 immr, u32 imms, bool invert = false); diff --git a/src/dolphin/x64Emitter.cpp b/src/dolphin/x64Emitter.cpp index 343f314..fd90ba7 100644 --- a/src/dolphin/x64Emitter.cpp +++ b/src/dolphin/x64Emitter.cpp @@ -1214,7 +1214,7 @@ void XEmitter::ROL(int bits, const OpArg& dest, const OpArg& shift) { WriteShift(bits, dest, shift, 0); } -void XEmitter::ROR_(int bits, const OpArg& dest, const OpArg& shift) +void XEmitter::ROR(int bits, const OpArg& dest, const OpArg& shift) { WriteShift(bits, dest, shift, 1); } diff --git a/src/dolphin/x64Emitter.h b/src/dolphin/x64Emitter.h index 869acb6..8799600 100644 --- a/src/dolphin/x64Emitter.h +++ b/src/dolphin/x64Emitter.h @@ -489,7 +489,7 @@ public: // Shift void ROL(int bits, const OpArg& dest, const OpArg& shift); - void ROR_(int bits, const OpArg& dest, const OpArg& shift); + void ROR(int bits, const OpArg& dest, const OpArg& shift); void RCL(int bits, const OpArg& dest, const OpArg& shift); void RCR(int bits, const OpArg& dest, const OpArg& shift); void SHL(int bits, const OpArg& dest, const OpArg& shift); -- 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(-) 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 00e2ec3faf43b1fa6ad3def0e97828083244a47a Mon Sep 17 00:00:00 2001 From: PoroCYon <3253268+PoroCYon@users.noreply.github.com> Date: Mon, 7 Sep 2020 02:09:03 +0000 Subject: fix 8-bit ConsoleID address decoding typo (#749) --- src/DSi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DSi.cpp b/src/DSi.cpp index a96322b..e8b1231 100644 --- a/src/DSi.cpp +++ b/src/DSi.cpp @@ -1703,7 +1703,7 @@ u8 ARM7IORead8(u32 addr) case 0x04004501: return DSi_I2C::Cnt; case 0x04004D00: if (SCFG_BIOS & (1<<10)) return 0; return ConsoleID & 0xFF; - case 0x04004fD01: if (SCFG_BIOS & (1<<10)) return 0; return (ConsoleID >> 8) & 0xFF; + case 0x04004D01: if (SCFG_BIOS & (1<<10)) return 0; return (ConsoleID >> 8) & 0xFF; case 0x04004D02: if (SCFG_BIOS & (1<<10)) return 0; return (ConsoleID >> 16) & 0xFF; case 0x04004D03: if (SCFG_BIOS & (1<<10)) return 0; return (ConsoleID >> 24) & 0xFF; case 0x04004D04: if (SCFG_BIOS & (1<<10)) return 0; return (ConsoleID >> 32) & 0xFF; -- 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(+) 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 edf4c66724b7371c3cafde68ea457b5aac372cb6 Mon Sep 17 00:00:00 2001 From: RSDuck Date: Fri, 11 Sep 2020 19:29:06 +0200 Subject: fix build on Switch --- src/ARMJIT_Memory.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ARMJIT_Memory.cpp b/src/ARMJIT_Memory.cpp index c5c8f04..d321d2f 100644 --- a/src/ARMJIT_Memory.cpp +++ b/src/ARMJIT_Memory.cpp @@ -279,6 +279,7 @@ bool UnmapFromRange(u32 addr, u32 num, u32 offset, u32 size) #endif } +#ifndef __SWITCH__ void SetCodeProtectionRange(u32 addr, u32 size, u32 num, int protection) { u8* dst = (u8*)(num == 0 ? FastMem9Start : FastMem7Start) + addr; @@ -303,6 +304,7 @@ void SetCodeProtectionRange(u32 addr, u32 size, u32 num, int protection) mprotect(dst, size, posixProt); #endif } +#endif struct Mapping { -- cgit v1.2.3 From a88df197089842f008bdeb1d79dc3b1a16c28da9 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 18 Sep 2020 00:29:08 +0200 Subject: avoid out-of-bounds read in GPU2D. fixes #763 --- src/GPU2D.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 07790b7..7964aa4 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -815,7 +815,6 @@ void GPU2D::DrawScanline(u32 line) int i = 0; for (; i < (stride & ~1); i+=2) *(u64*)&dst[i] = *(u64*)&BGOBJLine[i]; - if (stride & 1) dst[i] = BGOBJLine[i]; } break; -- cgit v1.2.3 From 2850dfed1596f486dbd0a5036631ae3d5bb80b06 Mon Sep 17 00:00:00 2001 From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com> Date: Sat, 19 Sep 2020 17:10:03 +0100 Subject: Fix Ubuntu AArch64 CI (#764) --- .github/workflows/build-ubuntu-aarch64.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build-ubuntu-aarch64.yml b/.github/workflows/build-ubuntu-aarch64.yml index 8ece6f2..3d1f309 100644 --- a/.github/workflows/build-ubuntu-aarch64.yml +++ b/.github/workflows/build-ubuntu-aarch64.yml @@ -22,7 +22,6 @@ jobs: working-directory: ${{runner.workspace}} run: | sudo apt update - sudo apt full-upgrade - name: Install dependencies shell: bash working-directory: ${{runner.workspace}} -- cgit v1.2.3 From 4b705556bcd3eabaff608ab06b24765472745c21 Mon Sep 17 00:00:00 2001 From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com> Date: Thu, 24 Sep 2020 18:17:39 +0100 Subject: Fix Ubuntu AArch64 CI - again (#767) * Fix Ubuntu AArch64 CI - again * Update build-ubuntu-aarch64.yml * Update build-ubuntu-aarch64.yml * Update build-ubuntu-aarch64.yml * Update build-ubuntu-aarch64.yml * Update build-ubuntu-aarch64.yml --- .github/workflows/build-ubuntu-aarch64.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-ubuntu-aarch64.yml b/.github/workflows/build-ubuntu-aarch64.yml index 3d1f309..6fd59b2 100644 --- a/.github/workflows/build-ubuntu-aarch64.yml +++ b/.github/workflows/build-ubuntu-aarch64.yml @@ -20,8 +20,11 @@ jobs: - name: Upgrade system shell: bash working-directory: ${{runner.workspace}} - run: | + run: | #Fix grub installation error - https://github.com/actions/virtual-environments/issues/1605 sudo apt update + sudo apt-get install grub-efi + sudo update-grub + sudo apt full-upgrade - name: Install dependencies shell: bash working-directory: ${{runner.workspace}} @@ -31,7 +34,8 @@ jobs: sudo rm /etc/apt/sources.list sudo mv /etc/apt/sources.list{.new,} sudo apt update - sudo apt install {gcc-10,g++-10,pkg-config}-aarch64-linux-gnu libsdl2-dev:arm64 qtbase5-dev:arm64 libslirp-dev:arm64 + sudo apt install aptitude + sudo aptitude install -y {gcc-10,g++-10,pkg-config}-aarch64-linux-gnu libsdl2-dev:arm64 qtbase5-dev:arm64 libslirp-dev:arm64 - name: Create build environment run: mkdir ${{runner.workspace}}/build - name: Configure -- 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(-) 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 9d5791f8e51be38821ea64053f06c54e2b36b8b8 Mon Sep 17 00:00:00 2001 From: RSDuck Date: Thu, 1 Oct 2020 13:32:06 +0200 Subject: use fixed sized integers from stdint.h --- src/types.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/types.h b/src/types.h index 234d4c0..c10b70d 100644 --- a/src/types.h +++ b/src/types.h @@ -19,13 +19,15 @@ #ifndef TYPES_H #define TYPES_H -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -typedef unsigned long long int u64; -typedef signed char s8; -typedef signed short s16; -typedef signed int s32; -typedef signed long long int s64; +#include + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; #endif // TYPES_H -- 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(-) 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 ef4215e172d2a83f39cb90a804e3f20d290ad52d Mon Sep 17 00:00:00 2001 From: RSDuck Date: Tue, 6 Oct 2020 00:48:35 +0200 Subject: flush to file after importing SRAM --- src/NDSCart.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index 5710213..077bf48 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -1037,6 +1037,13 @@ void RelocateSave(const char* path, bool write) int ImportSRAM(const u8* data, u32 length) { memcpy(NDSCart_SRAM::SRAM, data, std::min(length, NDSCart_SRAM::SRAMLength)); + FILE* f = Platform::OpenFile(NDSCart_SRAM::SRAMPath, "wb"); + if (f) + { + fwrite(NDSCart_SRAM::SRAM, NDSCart_SRAM::SRAMLength, 1, f); + fclose(f); + } + return length - NDSCart_SRAM::SRAMLength; } -- 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(-) 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(-) 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 From 65be1840f02a7499fa08178abcefddfefec6d9b0 Mon Sep 17 00:00:00 2001 From: RSDuck Date: Thu, 15 Oct 2020 05:59:22 +0200 Subject: change JIT branch optimisations default to 1 branch linking is dead --- src/Config.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Config.cpp b/src/Config.cpp index 8bda9ae..341b14c 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -46,7 +46,7 @@ int RandomizeMAC; #ifdef JIT_ENABLED int JIT_Enable = false; int JIT_MaxBlockSize = 32; -int JIT_BranchOptimisations = 2; +int JIT_BranchOptimisations = true; int JIT_LiteralOptimisations = true; int JIT_FastMemory = true; #endif @@ -71,7 +71,7 @@ ConfigEntry ConfigFile[] = #ifdef JIT_ENABLED {"JIT_Enable", 0, &JIT_Enable, 0, NULL, 0}, {"JIT_MaxBlockSize", 0, &JIT_MaxBlockSize, 32, NULL, 0}, - {"JIT_BranchOptimisations", 0, &JIT_BranchOptimisations, 2, NULL, 0}, + {"JIT_BranchOptimisations", 0, &JIT_BranchOptimisations, 1, NULL, 0}, {"JIT_LiteralOptimisations", 0, &JIT_LiteralOptimisations, 1, NULL, 0}, {"JIT_FastMemory", 0, &JIT_FastMemory, 1, NULL, 0}, #endif -- cgit v1.2.3