aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build-ubuntu.yml4
-rw-r--r--README.md19
-rw-r--r--melon.rc8
-rw-r--r--src/AREngine.cpp77
-rw-r--r--src/ARM.h5
-rw-r--r--src/ARMJIT.cpp7
-rw-r--r--src/ARMJIT_A64/ARMJIT_ALU.cpp6
-rw-r--r--src/ARMJIT_A64/ARMJIT_Compiler.cpp2
-rw-r--r--src/ARMJIT_A64/ARMJIT_LoadStore.cpp6
-rw-r--r--src/ARMJIT_Memory.cpp4
-rw-r--r--src/ARMJIT_x64/ARMJIT_ALU.cpp6
-rw-r--r--src/ARMJIT_x64/ARMJIT_Compiler.cpp2
-rw-r--r--src/ARMJIT_x64/ARMJIT_LoadStore.cpp8
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/Config.cpp12
-rw-r--r--src/Config.h6
-rw-r--r--src/DMA.cpp6
-rw-r--r--src/DSi.cpp14
-rw-r--r--src/DSi_AES.cpp27
-rw-r--r--src/DSi_Camera.cpp4
-rw-r--r--src/DSi_SD.cpp22
-rw-r--r--src/GPU.h1
-rw-r--r--src/GPU2D.cpp1
-rw-r--r--src/GPU3D.cpp14
-rw-r--r--src/GPU3D_OpenGL.cpp52
-rw-r--r--src/NDS.cpp11
-rw-r--r--src/NDSCart.cpp281
-rw-r--r--src/NDSCart.h1
-rw-r--r--src/SPI.cpp25
-rw-r--r--src/Savestate.cpp18
-rw-r--r--src/Savestate.h2
-rw-r--r--src/Wifi.cpp2
-rw-r--r--src/dolphin/Arm64Emitter.cpp2
-rw-r--r--src/dolphin/Arm64Emitter.h2
-rw-r--r--src/dolphin/x64Emitter.cpp2
-rw-r--r--src/dolphin/x64Emitter.h2
-rw-r--r--src/frontend/qt_sdl/EmuSettingsDialog.cpp42
-rw-r--r--src/frontend/qt_sdl/EmuSettingsDialog.h2
-rw-r--r--src/frontend/qt_sdl/EmuSettingsDialog.ui491
-rw-r--r--src/frontend/qt_sdl/Platform.cpp19
-rw-r--r--src/frontend/qt_sdl/PlatformConfig.cpp8
-rw-r--r--src/frontend/qt_sdl/PlatformConfig.h2
-rw-r--r--src/frontend/qt_sdl/VideoSettingsDialog.cpp15
-rw-r--r--src/frontend/qt_sdl/VideoSettingsDialog.h2
-rw-r--r--src/frontend/qt_sdl/VideoSettingsDialog.ui12
-rw-r--r--src/frontend/qt_sdl/WifiSettingsDialog.cpp59
-rw-r--r--src/frontend/qt_sdl/WifiSettingsDialog.h7
-rw-r--r--src/frontend/qt_sdl/WifiSettingsDialog.ui12
-rw-r--r--src/frontend/qt_sdl/main.cpp39
-rw-r--r--src/melonDLDI.h54
-rw-r--r--src/version.h2
51 files changed, 972 insertions, 456 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
diff --git a/README.md b/README.md
index e0b89c1..b7ab97a 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
<h2 align="center"><b>melonDS</b></h2>
<p align="center">
<a href="http://melonds.kuribo64.net/" alt="melonDS website"><img src="https://img.shields.io/badge/website-melonds.kuribo64.net-%2331352e.svg"></a>
-<a href="http://melonds.kuribo64.net/downloads.php" alt="Release: 0.8.3"><img src="https://img.shields.io/badge/release-0.8.3-%235c913b.svg"></a>
+<a href="http://melonds.kuribo64.net/downloads.php" alt="Release: 0.9"><img src="https://img.shields.io/badge/release-0.9-%235c913b.svg"></a>
<a href="https://www.gnu.org/licenses/gpl-3.0" alt="License: GPLv3"><img src="https://img.shields.io/badge/License-GPL%20v3-%23ff554d.svg"></a>
<a href="https://kiwiirc.com/client/irc.badnik.net/?nick=IRC-Source_?#melonds" alt="IRC channel: #melonds"><img src="https://img.shields.io/badge/IRC%20chat-%23melonds-%23dd2e44.svg"></a>
</p>
@@ -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
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/AREngine.cpp b/src/AREngine.cpp
index 8ebf46c..b47bcd4 100644
--- a/src/AREngine.cpp
+++ b/src/AREngine.cpp
@@ -19,6 +19,7 @@
#include <stdio.h>
#include <string.h>
#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--;
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 59f7f54..c9d2b62 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),
@@ -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_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);
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/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 d198093..2c5fd2c 100644
--- a/src/Config.cpp
+++ b/src/Config.cpp
@@ -31,11 +31,17 @@ 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];
char DSiFirmwarePath[1024];
char DSiNANDPath[1024];
+int DSiSDEnable;
+char DSiSDPath[1024];
+
+int RandomizeMAC;
#ifdef JIT_ENABLED
int JIT_Enable = false;
@@ -50,11 +56,17 @@ 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},
{"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},
#ifdef JIT_ENABLED
{"JIT_Enable", 0, &JIT_Enable, 0, NULL, 0},
diff --git a/src/Config.h b/src/Config.h
index 5916b4a..9fd7488 100644
--- a/src/Config.h
+++ b/src/Config.h
@@ -45,11 +45,17 @@ 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];
extern char DSiFirmwarePath[1024];
extern char DSiNANDPath[1024];
+extern int DSiSDEnable;
+extern char DSiSDPath[1024];
+
+extern int RandomizeMAC;
#ifdef JIT_ENABLED
extern int JIT_Enable;
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/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<u8>(addr, val); return;
+ case 0x00200000: GPU::WriteVRAM_BBG<u8>(addr, val); return;
+ case 0x00400000: GPU::WriteVRAM_AOBJ<u8>(addr, val); return;
+ case 0x00600000: GPU::WriteVRAM_BOBJ<u8>(addr, val); return;
+ default: GPU::WriteVRAM_LCDC<u8>(addr, val); return;
+ }
}
return NDS::ARM9Write8(addr, val);
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);
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);
}
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/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/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/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp
index 72b3fc6..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;
@@ -519,6 +520,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);
@@ -614,7 +636,7 @@ void BuildPolygons(RendererPolygon* polygons, int npolys)
{
rp->PrimType = GL_TRIANGLES;
- if (false)
+ if (!BetterPolygons)
{
// regular triangle-splitting
@@ -814,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);
@@ -832,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;
@@ -918,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;
@@ -1009,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)
{
@@ -1076,9 +1108,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);
diff --git a/src/NDS.cpp b/src/NDS.cpp
index bb579f6..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)
{
@@ -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)
@@ -3745,7 +3750,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();
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/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/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);
diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.cpp b/src/frontend/qt_sdl/EmuSettingsDialog.cpp
index dc7eaf5..79ce5ed 100644
--- a/src/frontend/qt_sdl/EmuSettingsDialog.cpp
+++ b/src/frontend/qt_sdl/EmuSettingsDialog.cpp
@@ -44,11 +44,15 @@ EmuSettingsDialog::EmuSettingsDialog(QWidget* parent) : QDialog(parent), ui(new
ui->txtBIOS9Path->setText(Config::BIOS9Path);
ui->txtBIOS7Path->setText(Config::BIOS7Path);
ui->txtFirmwarePath->setText(Config::FirmwarePath);
+ ui->cbDLDIEnable->setChecked(Config::DLDIEnable != 0);
+ ui->txtDLDISDPath->setText(Config::DLDISDPath);
ui->txtDSiBIOS9Path->setText(Config::DSiBIOS9Path);
ui->txtDSiBIOS7Path->setText(Config::DSiBIOS7Path);
ui->txtDSiFirmwarePath->setText(Config::DSiFirmwarePath);
ui->txtDSiNANDPath->setText(Config::DSiNANDPath);
+ ui->cbDSiSDEnable->setChecked(Config::DSiSDEnable != 0);
+ ui->txtDSiSDPath->setText(Config::DSiSDPath);
ui->cbxConsoleType->addItem("DS");
ui->cbxConsoleType->addItem("DSi (experimental)");
@@ -141,10 +145,14 @@ void EmuSettingsDialog::done(int r)
std::string bios9Path = ui->txtBIOS9Path->text().toStdString();
std::string bios7Path = ui->txtBIOS7Path->text().toStdString();
std::string firmwarePath = ui->txtFirmwarePath->text().toStdString();
+ int dldiEnable = ui->cbDLDIEnable->isChecked() ? 1:0;
+ std::string dldiSDPath = ui->txtDLDISDPath->text().toStdString();
std::string dsiBios9Path = ui->txtDSiBIOS9Path->text().toStdString();
std::string dsiBios7Path = ui->txtDSiBIOS7Path->text().toStdString();
std::string dsiFirmwarePath = ui->txtDSiFirmwarePath->text().toStdString();
std::string dsiNANDPath = ui->txtDSiNANDPath->text().toStdString();
+ int dsiSDEnable = ui->cbDSiSDEnable->isChecked() ? 1:0;
+ std::string dsiSDPath = ui->txtDSiSDPath->text().toStdString();
if (consoleType != Config::ConsoleType
|| directBoot != Config::DirectBoot
@@ -158,10 +166,14 @@ void EmuSettingsDialog::done(int r)
|| strcmp(Config::BIOS9Path, bios9Path.c_str()) != 0
|| strcmp(Config::BIOS7Path, bios7Path.c_str()) != 0
|| strcmp(Config::FirmwarePath, firmwarePath.c_str()) != 0
+ || dldiEnable != Config::DLDIEnable
+ || strcmp(Config::DLDISDPath, dldiSDPath.c_str()) != 0
|| strcmp(Config::DSiBIOS9Path, dsiBios9Path.c_str()) != 0
|| strcmp(Config::DSiBIOS7Path, dsiBios7Path.c_str()) != 0
|| strcmp(Config::DSiFirmwarePath, dsiFirmwarePath.c_str()) != 0
- || strcmp(Config::DSiNANDPath, dsiNANDPath.c_str()) != 0)
+ || strcmp(Config::DSiNANDPath, dsiNANDPath.c_str()) != 0
+ || dsiSDEnable != Config::DSiSDEnable
+ || strcmp(Config::DSiSDPath, dsiSDPath.c_str()) != 0)
{
if (RunningSomething
&& QMessageBox::warning(this, "Reset necessary to apply changes",
@@ -172,11 +184,15 @@ void EmuSettingsDialog::done(int r)
strncpy(Config::BIOS9Path, bios9Path.c_str(), 1023); Config::BIOS9Path[1023] = '\0';
strncpy(Config::BIOS7Path, bios7Path.c_str(), 1023); Config::BIOS7Path[1023] = '\0';
strncpy(Config::FirmwarePath, firmwarePath.c_str(), 1023); Config::FirmwarePath[1023] = '\0';
+ Config::DLDIEnable = dldiEnable;
+ strncpy(Config::DLDISDPath, dldiSDPath.c_str(), 1023); Config::DLDISDPath[1023] = '\0';
strncpy(Config::DSiBIOS9Path, dsiBios9Path.c_str(), 1023); Config::DSiBIOS9Path[1023] = '\0';
strncpy(Config::DSiBIOS7Path, dsiBios7Path.c_str(), 1023); Config::DSiBIOS7Path[1023] = '\0';
strncpy(Config::DSiFirmwarePath, dsiFirmwarePath.c_str(), 1023); Config::DSiFirmwarePath[1023] = '\0';
strncpy(Config::DSiNANDPath, dsiNANDPath.c_str(), 1023); Config::DSiNANDPath[1023] = '\0';
+ Config::DSiSDEnable = dsiSDEnable;
+ strncpy(Config::DSiSDPath, dsiSDPath.c_str(), 1023); Config::DSiSDPath[1023] = '\0';
#ifdef JIT_ENABLED
Config::JIT_Enable = jitEnable;
@@ -260,6 +276,18 @@ void EmuSettingsDialog::on_btnDSiBIOS7Browse_clicked()
ui->txtDSiBIOS7Path->setText(file);
}
+void EmuSettingsDialog::on_btnDLDISDBrowse_clicked()
+{
+ QString file = QFileDialog::getOpenFileName(this,
+ "Select DLDI SD image...",
+ EmuDirectory,
+ "Image files (*.bin *.rom *.img);;Any file (*.*)");
+
+ if (file.isEmpty()) return;
+
+ ui->txtDLDISDPath->setText(file);
+}
+
void EmuSettingsDialog::on_btnDSiFirmwareBrowse_clicked()
{
QString file = QFileDialog::getOpenFileName(this,
@@ -284,6 +312,18 @@ void EmuSettingsDialog::on_btnDSiNANDBrowse_clicked()
ui->txtDSiNANDPath->setText(file);
}
+void EmuSettingsDialog::on_btnDSiSDBrowse_clicked()
+{
+ QString file = QFileDialog::getOpenFileName(this,
+ "Select DSi SD image...",
+ EmuDirectory,
+ "Image files (*.bin *.rom *.img);;Any file (*.*)");
+
+ if (file.isEmpty()) return;
+
+ ui->txtDSiSDPath->setText(file);
+}
+
void EmuSettingsDialog::on_chkEnableJIT_toggled()
{
bool disabled = !ui->chkEnableJIT->isChecked();
diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.h b/src/frontend/qt_sdl/EmuSettingsDialog.h
index 1a16ebc..158793c 100644
--- a/src/frontend/qt_sdl/EmuSettingsDialog.h
+++ b/src/frontend/qt_sdl/EmuSettingsDialog.h
@@ -58,11 +58,13 @@ private slots:
void on_btnBIOS9Browse_clicked();
void on_btnBIOS7Browse_clicked();
void on_btnFirmwareBrowse_clicked();
+ void on_btnDLDISDBrowse_clicked();
void on_btnDSiBIOS9Browse_clicked();
void on_btnDSiBIOS7Browse_clicked();
void on_btnDSiFirmwareBrowse_clicked();
void on_btnDSiNANDBrowse_clicked();
+ void on_btnDSiSDBrowse_clicked();
void on_chkEnableJIT_toggled();
diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.ui b/src/frontend/qt_sdl/EmuSettingsDialog.ui
index 11d48cc..ac5506f 100644
--- a/src/frontend/qt_sdl/EmuSettingsDialog.ui
+++ b/src/frontend/qt_sdl/EmuSettingsDialog.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>514</width>
- <height>359</height>
+ <width>575</width>
+ <height>254</height>
</rect>
</property>
<property name="sizePolicy">
@@ -86,209 +86,242 @@
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
- <string>BIOS Files</string>
+ <string>DS-mode</string>
</attribute>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QGroupBox" name="groupBox">
- <property name="title">
- <string>DS mode</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="2" column="0">
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>DS firmware:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLineEdit" name="txtFirmwarePath">
- <property name="whatsThis">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DS-mode firmware&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Possible firmwares:&lt;/p&gt;&lt;p&gt;* 128 KB: DS-mode firmware from a DSi or 3DS. Not bootable.&lt;/p&gt;&lt;p&gt;* 256 KB: regular DS firmware.&lt;/p&gt;&lt;p&gt;* 512 KB: iQue DS firmware.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLineEdit" name="txtBIOS7Path">
- <property name="whatsThis">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DS-mode ARM7 BIOS&lt;/p&gt;&lt;p&gt;Size should be 16 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QPushButton" name="btnBIOS9Browse">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Browse...</string>
- </property>
- <property name="autoDefault">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QPushButton" name="btnFirmwareBrowse">
- <property name="text">
- <string>Browse...</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>DS ARM7 BIOS:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>DS ARM9 BIOS:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QPushButton" name="btnBIOS7Browse">
- <property name="text">
- <string>Browse...</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="txtBIOS9Path">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>290</width>
- <height>0</height>
- </size>
- </property>
- <property name="statusTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DS-mode ARM9 BIOS&lt;/p&gt;&lt;p&gt;Size should be 4 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_3">
- <property name="title">
- <string>DSi mode</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="0" column="2">
- <widget class="QPushButton" name="btnDSiBIOS9Browse">
- <property name="text">
- <string>Browse...</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>DSi ARM9 BIOS:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QPushButton" name="btnDSiFirmwareBrowse">
- <property name="text">
- <string>Browse...</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLineEdit" name="txtDSiBIOS7Path">
- <property name="whatsThis">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DSi-mode ARM7 BIOS&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Size should be 64 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLineEdit" name="txtDSiFirmwarePath">
- <property name="whatsThis">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DSi-mode firmware (used for DS-mode backwards compatibility)&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Size should be 128 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_6">
- <property name="text">
- <string>DSi ARM7 BIOS:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_7">
- <property name="text">
- <string>DSi firmware:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QPushButton" name="btnDSiBIOS7Browse">
- <property name="text">
- <string>Browse...</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="txtDSiBIOS9Path">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="whatsThis">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DSi-mode ARM9 BIOS&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Size should be 64 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_8">
- <property name="text">
- <string>DSi NAND:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QLineEdit" name="txtDSiNANDPath">
- <property name="whatsThis">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DSi NAND dump&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Should have 'nocash footer' at the end&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- <item row="3" column="2">
- <widget class="QPushButton" name="btnDSiNANDBrowse">
- <property name="text">
- <string>Browse...</string>
- </property>
- </widget>
- </item>
- </layout>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="txtBIOS7Path">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DS-mode ARM7 BIOS&lt;/p&gt;&lt;p&gt;Size should be 16 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="txtFirmwarePath">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DS-mode firmware&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Possible firmwares:&lt;/p&gt;&lt;p&gt;* 128 KB: DS-mode firmware from a DSi or 3DS. Not bootable.&lt;/p&gt;&lt;p&gt;* 256 KB: regular DS firmware.&lt;/p&gt;&lt;p&gt;* 512 KB: iQue DS firmware.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>DS firmware:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>DS ARM7 BIOS:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="btnBIOS7Browse">
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QPushButton" name="btnFirmwareBrowse">
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QPushButton" name="btnBIOS9Browse">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>DS ARM9 BIOS:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="txtBIOS9Path">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>290</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="statusTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DS-mode ARM9 BIOS&lt;/p&gt;&lt;p&gt;Size should be 4 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <spacer name="verticalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_4">
+ <attribute name="title">
+ <string>DSi-mode</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="txtDSiBIOS7Path">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DSi-mode ARM7 BIOS&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Size should be 64 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="2">
+ <widget class="QPushButton" name="btnDSiSDBrowse">
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_8">
+ <property name="text">
+ <string>DSi NAND:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <widget class="QPushButton" name="btnDSiNANDBrowse">
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>DSi ARM7 BIOS:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QPushButton" name="btnDSiFirmwareBrowse">
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="txtDSiNANDPath">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DSi NAND dump&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Should have 'nocash footer' at the end&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QPushButton" name="btnDSiBIOS9Browse">
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_10">
+ <property name="text">
+ <string>DSi SD card:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="txtDSiBIOS9Path">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DSi-mode ARM9 BIOS&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Size should be 64 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>DSi firmware:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>DSi ARM9 BIOS:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="txtDSiFirmwarePath">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DSi-mode firmware (used for DS-mode backwards compatibility)&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Size should be 128 KB&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QLineEdit" name="txtDSiSDPath">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;SD image file for emulating the DSi's SD card&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="3">
+ <widget class="QCheckBox" name="cbDSiSDEnable">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Simulate a SD card being inserted in the DSi's SD slot. Requires a SD card image.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>Enable DSi SD card</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="btnDSiBIOS7Browse">
+ <property name="text">
+ <string>Browse...</string>
+ </property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
- <string>CPU Emulation</string>
+ <string>CPU emulation</string>
</attribute>
<layout class="QFormLayout" name="formLayout_5">
<item row="0" column="0">
@@ -354,6 +387,53 @@
</item>
</layout>
</widget>
+ <widget class="QWidget" name="tab_5">
+ <attribute name="title">
+ <string>DLDI</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="0" column="0" colspan="3">
+ <widget class="QCheckBox" name="cbDLDIEnable">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enable the built-in DLDI driver, to let homebrew access files from a given SD image.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>Enable DLDI (for homebrew)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="btnDLDISDBrowse">
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="txtDLDISDPath"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_11">
+ <property name="text">
+ <string>DLDI SD card:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
<item>
@@ -369,23 +449,8 @@
</layout>
</widget>
<tabstops>
- <tabstop>tabWidget</tabstop>
<tabstop>cbxConsoleType</tabstop>
<tabstop>chkDirectBoot</tabstop>
- <tabstop>txtBIOS9Path</tabstop>
- <tabstop>txtBIOS7Path</tabstop>
- <tabstop>txtFirmwarePath</tabstop>
- <tabstop>txtDSiBIOS9Path</tabstop>
- <tabstop>txtDSiBIOS7Path</tabstop>
- <tabstop>txtDSiFirmwarePath</tabstop>
- <tabstop>txtDSiNANDPath</tabstop>
- <tabstop>btnBIOS9Browse</tabstop>
- <tabstop>btnBIOS7Browse</tabstop>
- <tabstop>btnFirmwareBrowse</tabstop>
- <tabstop>btnDSiBIOS9Browse</tabstop>
- <tabstop>btnDSiBIOS7Browse</tabstop>
- <tabstop>btnDSiFirmwareBrowse</tabstop>
- <tabstop>btnDSiNANDBrowse</tabstop>
<tabstop>chkEnableJIT</tabstop>
<tabstop>spnJITMaximumBlockSize</tabstop>
</tabstops>
diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp
index 05a0c2d..a716feb 100644
--- a/src/frontend/qt_sdl/Platform.cpp
+++ b/src/frontend/qt_sdl/Platform.cpp
@@ -77,7 +77,7 @@ u8 PacketBuffer[2048];
void Init(int argc, char** argv)
{
-#if defined(__WIN32__) || defined(UNIX_PORTABLE)
+#if defined(__WIN32__) || defined(PORTABLE)
if (argc > 0 && strlen(argv[0]) > 0)
{
int len = strlen(argv[0]);
@@ -137,13 +137,20 @@ FILE* OpenFile(const char* path, const char* mode, bool mustexist)
}
QIODevice::OpenMode qmode;
- if (strlen(mode) > 1 && mode[0] == 'r' && mode[1] == '+') {
+ if (strlen(mode) > 1 && mode[0] == 'r' && mode[1] == '+')
+ {
qmode = QIODevice::OpenModeFlag::ReadWrite;
- } else if (strlen(mode) > 1 && mode[0] == 'w' && mode[1] == '+') {
+ }
+ else if (strlen(mode) > 1 && mode[0] == 'w' && mode[1] == '+')
+ {
qmode = QIODevice::OpenModeFlag::Truncate | QIODevice::OpenModeFlag::ReadWrite;
- } else if (mode[0] == 'w') {
+ }
+ else if (mode[0] == 'w')
+ {
qmode = QIODevice::OpenModeFlag::Truncate | QIODevice::OpenModeFlag::WriteOnly;
- } else {
+ }
+ else
+ {
qmode = QIODevice::OpenModeFlag::ReadOnly;
}
@@ -167,7 +174,7 @@ FILE* OpenLocalFile(const char* path, const char* mode)
else
{
#ifdef PORTABLE
- fullpath = path;
+ fullpath = QString(EmuDirectory) + QDir::separator() + path;
#else
// Check user configuration directory
QDir config(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation));
diff --git a/src/frontend/qt_sdl/PlatformConfig.cpp b/src/frontend/qt_sdl/PlatformConfig.cpp
index 76c5f4b..4468d0e 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;
@@ -135,15 +135,15 @@ ConfigEntry PlatformConfigFile[] =
{"IntegerScaling", 0, &IntegerScaling, 0, NULL, 0},
{"ScreenFilter", 0, &ScreenFilter, 1, NULL, 0},
- {"ScreenUseGL", 0, &ScreenUseGL, 1, NULL, 0},
+ {"ScreenUseGL", 0, &ScreenUseGL, 0, NULL, 0},
{"ScreenVSync", 0, &ScreenVSync, 0, NULL, 0},
{"ScreenVSyncInterval", 0, &ScreenVSyncInterval, 1, NULL, 0},
- {"3DRenderer", 0, &_3DRenderer, 1, NULL, 0},
+ {"3DRenderer", 0, &_3DRenderer, 0, NULL, 0},
{"Threaded3D", 0, &Threaded3D, 1, NULL, 0},
{"GL_ScaleFactor", 0, &GL_ScaleFactor, 1, NULL, 0},
- {"GL_Antialias", 0, &GL_Antialias, 0, NULL, 0},
+ {"GL_BetterPolygons", 0, &GL_BetterPolygons, 0, NULL, 0},
{"LimitFPS", 0, &LimitFPS, 0, NULL, 0},
{"AudioSync", 0, &AudioSync, 1, NULL, 0},
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..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);
@@ -167,3 +175,10 @@ void VideoSettingsDialog::on_cbxGLResolution_currentIndexChanged(int idx)
emit updateVideoSettings(false);
}
+
+void VideoSettingsDialog::on_cbBetterPolygons_stateChanged(int state)
+{
+ Config::GL_BetterPolygons = (state != 0);
+
+ emit updateVideoSettings(false);
+}
diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.h b/src/frontend/qt_sdl/VideoSettingsDialog.h
index 2311d4d..2645eef 100644
--- a/src/frontend/qt_sdl/VideoSettingsDialog.h
+++ b/src/frontend/qt_sdl/VideoSettingsDialog.h
@@ -64,6 +64,7 @@ private slots:
void on_sbVSyncInterval_valueChanged(int val);
void on_cbxGLResolution_currentIndexChanged(int idx);
+ void on_cbBetterPolygons_stateChanged(int state);
void on_cbSoftwareThreaded_stateChanged(int state);
@@ -78,6 +79,7 @@ private:
int oldVSyncInterval;
int oldSoftThreaded;
int oldGLScale;
+ int oldGLBetterPolygons;
};
#endif // VIDEOSETTINGSDIALOG_H
diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.ui b/src/frontend/qt_sdl/VideoSettingsDialog.ui
index 6cdd5d8..6985304 100644
--- a/src/frontend/qt_sdl/VideoSettingsDialog.ui
+++ b/src/frontend/qt_sdl/VideoSettingsDialog.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>482</width>
- <height>237</height>
+ <height>244</height>
</rect>
</property>
<property name="sizePolicy">
@@ -43,6 +43,16 @@
</property>
</widget>
</item>
+ <item row="2" column="0">
+ <widget class="QCheckBox" name="cbBetterPolygons">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enabling this may help reduce distortion on quads and more complex polygons, but may also reduce performance.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>Improved polygon splitting</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/src/frontend/qt_sdl/WifiSettingsDialog.cpp b/src/frontend/qt_sdl/WifiSettingsDialog.cpp
index 457a78d..67297ad 100644
--- a/src/frontend/qt_sdl/WifiSettingsDialog.cpp
+++ b/src/frontend/qt_sdl/WifiSettingsDialog.cpp
@@ -17,7 +17,7 @@
*/
#include <stdio.h>
-#include <QFileDialog>
+#include <QMessageBox>
#include "types.h"
#include "Platform.h"
@@ -41,6 +41,10 @@
WifiSettingsDialog* WifiSettingsDialog::currentDlg = nullptr;
+bool WifiSettingsDialog::needsReset = false;
+
+extern bool RunningSomething;
+
WifiSettingsDialog::WifiSettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::WifiSettingsDialog)
{
@@ -53,6 +57,7 @@ WifiSettingsDialog::WifiSettingsDialog(QWidget* parent) : QDialog(parent), ui(ne
ui->cbDirectMode->setText("Direct mode (requires " PCAP_NAME " and ethernet connection)");
ui->cbBindAnyAddr->setChecked(Config::SocketBindAnyAddr != 0);
+ ui->cbRandomizeMAC->setChecked(Config::RandomizeMAC != 0);
int sel = 0;
for (int i = 0; i < LAN_PCap::NumAdapters; i++)
@@ -77,33 +82,49 @@ WifiSettingsDialog::~WifiSettingsDialog()
delete ui;
}
-void WifiSettingsDialog::on_WifiSettingsDialog_accepted()
+void WifiSettingsDialog::done(int r)
{
- Config::SocketBindAnyAddr = ui->cbBindAnyAddr->isChecked() ? 1:0;
- Config::DirectLAN = ui->cbDirectMode->isChecked() ? 1:0;
+ needsReset = false;
- int sel = ui->cbxDirectAdapter->currentIndex();
- if (sel < 0 || sel >= LAN_PCap::NumAdapters) sel = 0;
- if (LAN_PCap::NumAdapters < 1)
- {
- Config::LANDevice[0] = '\0';
- }
- else
+ if (r == QDialog::Accepted)
{
- strncpy(Config::LANDevice, LAN_PCap::Adapters[sel].DeviceName, 127);
- Config::LANDevice[127] = '\0';
+ int randommac = ui->cbRandomizeMAC->isChecked() ? 1:0;
+
+ if (randommac != Config::RandomizeMAC)
+ {
+ if (RunningSomething
+ && QMessageBox::warning(this, "Reset necessary to apply changes",
+ "The emulation will be reset for the changes to take place.",
+ QMessageBox::Ok, QMessageBox::Cancel) != QMessageBox::Ok)
+ return;
+ }
+
+ Config::SocketBindAnyAddr = ui->cbBindAnyAddr->isChecked() ? 1:0;
+ Config::RandomizeMAC = randommac;
+ Config::DirectLAN = ui->cbDirectMode->isChecked() ? 1:0;
+
+ int sel = ui->cbxDirectAdapter->currentIndex();
+ if (sel < 0 || sel >= LAN_PCap::NumAdapters) sel = 0;
+ if (LAN_PCap::NumAdapters < 1)
+ {
+ Config::LANDevice[0] = '\0';
+ }
+ else
+ {
+ strncpy(Config::LANDevice, LAN_PCap::Adapters[sel].DeviceName, 127);
+ Config::LANDevice[127] = '\0';
+ }
+
+ Config::Save();
+
+ needsReset = true;
}
- Config::Save();
+ QDialog::done(r);
closeDlg();
}
-void WifiSettingsDialog::on_WifiSettingsDialog_rejected()
-{
- closeDlg();
-}
-
void WifiSettingsDialog::on_cbDirectMode_stateChanged(int state)
{
updateAdapterControls();
diff --git a/src/frontend/qt_sdl/WifiSettingsDialog.h b/src/frontend/qt_sdl/WifiSettingsDialog.h
index f8aad1b..6c1f863 100644
--- a/src/frontend/qt_sdl/WifiSettingsDialog.h
+++ b/src/frontend/qt_sdl/WifiSettingsDialog.h
@@ -42,7 +42,7 @@ public:
}
currentDlg = new WifiSettingsDialog(parent);
- currentDlg->show();
+ currentDlg->open();
return currentDlg;
}
static void closeDlg()
@@ -50,9 +50,10 @@ public:
currentDlg = nullptr;
}
+ static bool needsReset;
+
private slots:
- void on_WifiSettingsDialog_accepted();
- void on_WifiSettingsDialog_rejected();
+ void done(int r);
void on_cbDirectMode_stateChanged(int state);
void on_cbxDirectAdapter_currentIndexChanged(int sel);
diff --git a/src/frontend/qt_sdl/WifiSettingsDialog.ui b/src/frontend/qt_sdl/WifiSettingsDialog.ui
index bfee1fd..6668d88 100644
--- a/src/frontend/qt_sdl/WifiSettingsDialog.ui
+++ b/src/frontend/qt_sdl/WifiSettingsDialog.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>479</width>
- <height>217</height>
+ <height>240</height>
</rect>
</property>
<property name="sizePolicy">
@@ -39,6 +39,16 @@
</property>
</widget>
</item>
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="cbRandomizeMAC">
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Randomizes the console's MAC address upon reset. Required for local multiplayer if each melonDS instance uses the same firmware file.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>Randomize MAC address</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp
index f91f879..f8cdd24 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);
}
@@ -1333,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();
}
@@ -1747,14 +1750,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 +1767,9 @@ void MainWindow::onWifiSettingsFinished(int res)
Platform::LAN_DeInit();
Platform::LAN_Init();
+ if (WifiSettingsDialog::needsReset)
+ onReset();
+
emuThread->emuUnpause();
}
@@ -1874,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);
@@ -2066,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);
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
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/"