diff --git a/Assets/dll/melonDS.wbx.gz b/Assets/dll/melonDS.wbx.gz index 68ad90b9b6..2b1e15bdd6 100644 Binary files a/Assets/dll/melonDS.wbx.gz and b/Assets/dll/melonDS.wbx.gz differ diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/LibMelonDS.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/LibMelonDS.cs index 73afe2e5aa..e4116f54cd 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/LibMelonDS.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/LibMelonDS.cs @@ -29,6 +29,17 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS POWER = 0x8000, } + [StructLayout(LayoutKind.Sequential)] + public new class FrameInfo : LibWaterboxCore.FrameInfo + { + public long Time; + public Buttons Keys; + public byte TouchX; + public byte TouchY; + public byte MicVolume; + public byte GBALightSensor; + } + [Flags] public enum LoadFlags : uint { @@ -41,14 +52,14 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS } [StructLayout(LayoutKind.Sequential)] - public new class FrameInfo : LibWaterboxCore.FrameInfo + public class LoadData { - public long Time; - public Buttons Keys; - public byte TouchX; - public byte TouchY; - public byte MicVolume; - public byte GBALightSensor; + public IntPtr DsRomData; + public int DsRomLength; + public IntPtr GbaRomData; + public int GbaRomLength; + public IntPtr GbaRamData; + public int GbaRamLength; } [StructLayout(LayoutKind.Sequential)] @@ -65,7 +76,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS } [BizImport(CC)] - public abstract bool Init(LoadFlags flags, FirmwareSettings fwSettings); + public abstract bool Init(LoadFlags flags, LoadData loadData, FirmwareSettings fwSettings); [BizImport(CC)] public abstract void PutSaveRam(byte[] data, uint len); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.cs index 762849231c..8e788b09cc 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.cs @@ -47,7 +47,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS Filename = "melonDS.wbx", SbrkHeapSizeKB = 2 * 1024, SealedHeapSizeKB = 4, - InvisibleHeapSizeKB = 4, + InvisibleHeapSizeKB = 4 * 1024, PlainHeapSizeKB = 4, MmapHeapSizeKB = 1024 * 1024, SkipCoreConsistencyCheck = CoreComm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxCoreConsistencyCheck), @@ -93,15 +93,12 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS var message = _syncSettings.FirmwareMessage.Length != 0 ? Encoding.UTF8.GetBytes(_syncSettings.FirmwareMessage) : new byte[1] { 0 }; fwSettings.FirmwareMessageLength = message.Length; - _exe.AddReadonlyFile(roms[0], "game.rom"); - if (gbacartpresent) + var loadData = new LibMelonDS.LoadData { - _exe.AddReadonlyFile(roms[1], "gba.rom"); - if (gbasrampresent) - { - _exe.AddReadonlyFile(roms[2], "gba.ram"); - } - } + DsRomLength = roms[0].Length, + GbaRomLength = gbacartpresent ? roms[1].Length : 0, + GbaRamLength = gbasrampresent ? roms[2].Length : 0, + }; if (_syncSettings.UseRealBIOS) { _exe.AddReadonlyFile(bios7, "bios7.rom"); @@ -121,31 +118,30 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS unsafe { - fixed (byte* namePtr = &name[0], messagePtr = &message[0]) + fixed (byte* + dsRomPtr = roms[0], + gbaRomPtr = gbacartpresent ? roms[1] : null, + gbaRamPtr = gbasrampresent ? roms[2] : null, + namePtr = &name[0], + messagePtr = &message[0]) { + loadData.DsRomData = (IntPtr)dsRomPtr; + loadData.GbaRomData = (IntPtr)gbaRomPtr; + loadData.GbaRamData = (IntPtr)gbaRamPtr; fwSettings.FirmwareUsername = (IntPtr)namePtr; fwSettings.FirmwareMessage = (IntPtr)messagePtr; - if (!_core.Init(flags, fwSettings)) + if (!_core.Init(flags, loadData, fwSettings)) { throw new InvalidOperationException("Init returned false!"); } } } - _exe.RemoveReadonlyFile("game.rom"); - if (gbacartpresent) - { - _exe.RemoveReadonlyFile("gba.rom"); - if (gbasrampresent) - { - _exe.RemoveReadonlyFile("gba.ram"); - } - } - if (_syncSettings.UseRealBIOS) + /*if (_syncSettings.UseRealBIOS) { _exe.RemoveReadonlyFile("bios7.rom"); _exe.RemoveReadonlyFile("bios9.rom"); - } + }*/ if (fw != null) { _exe.RemoveReadonlyFile("firmware.bin"); diff --git a/waterbox/melon/BizConfig.cpp b/waterbox/melon/BizConfig.cpp new file mode 100644 index 0000000000..16bdfa4efe --- /dev/null +++ b/waterbox/melon/BizConfig.cpp @@ -0,0 +1,58 @@ +#include +#include +#include +#include "BizConfig.h" + +namespace Config +{ + +#ifdef JIT_ENABLED +bool JIT_Enable = false; +int JIT_MaxBlockSize = 32; +bool JIT_BranchOptimisations = true; +bool JIT_LiteralOptimisations = true; +bool JIT_FastMemory = true; +#endif + +bool ExternalBIOSEnable; + +std::string BIOS9Path = "bios9.rom"; +std::string BIOS7Path = "bios7.rom"; +std::string FirmwarePath = "firmware.bin"; + +std::string DSiBIOS9Path = "bios9i.rom"; +std::string DSiBIOS7Path = "bios7i.rom"; +std::string DSiFirmwarePath = "firmwarei.bin"; +std::string DSiNANDPath = "nand.bin"; + +bool DLDIEnable = false; +std::string DLDISDPath = ""; +int DLDISize = 0; +bool DLDIReadOnly = true; +bool DLDIFolderSync = false; +std::string DLDIFolderPath = ""; + +bool DSiSDEnable = false; +std::string DSiSDPath = ""; +int DSiSDSize = 0; +bool DSiSDReadOnly = true; +bool DSiSDFolderSync = false; +std::string DSiSDFolderPath = ""; + +bool FirmwareOverrideSettings; +std::string FirmwareUsername; +int FirmwareLanguage; +int FirmwareBirthdayMonth; +int FirmwareBirthdayDay; +int FirmwareFavouriteColour; +std::string FirmwareMessage; +std::string FirmwareMAC; +bool RandomizeMAC; + +int AudioBitrate; + +bool FixedBootTime = true; +bool UseRealTime = false; +int TimeAtBoot = 0; + +} diff --git a/waterbox/melon/BizConfig.h b/waterbox/melon/BizConfig.h new file mode 100644 index 0000000000..0454833ee4 --- /dev/null +++ b/waterbox/melon/BizConfig.h @@ -0,0 +1,60 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#include + +namespace Config +{ + +#ifdef JIT_ENABLED +extern bool JIT_Enable; +extern int JIT_MaxBlockSize; +extern bool JIT_BranchOptimisations; +extern bool JIT_LiteralOptimisations; +extern bool JIT_FastMemory; +#endif + +extern bool ExternalBIOSEnable; + +extern std::string BIOS9Path; +extern std::string BIOS7Path; +extern std::string FirmwarePath; + +extern std::string DSiBIOS9Path; +extern std::string DSiBIOS7Path; +extern std::string DSiFirmwarePath; +extern std::string DSiNANDPath; + +extern bool DLDIEnable; +extern std::string DLDISDPath; +extern int DLDISize; +extern bool DLDIReadOnly; +extern bool DLDIFolderSync; +extern std::string DLDIFolderPath; + +extern bool DSiSDEnable; +extern std::string DSiSDPath; +extern int DSiSDSize; +extern bool DSiSDReadOnly; +extern bool DSiSDFolderSync; +extern std::string DSiSDFolderPath; + +extern bool FirmwareOverrideSettings; +extern std::string FirmwareUsername; +extern int FirmwareLanguage; +extern int FirmwareBirthdayMonth; +extern int FirmwareBirthdayDay; +extern int FirmwareFavouriteColour; +extern std::string FirmwareMessage; +extern std::string FirmwareMAC; +extern bool RandomizeMAC; + +extern int AudioBitrate; + +extern bool FixedBootTime; +extern bool UseRealTime; +extern int TimeAtBoot; + +} + +#endif diff --git a/waterbox/melon/BizInterface.cpp b/waterbox/melon/BizInterface.cpp index 7d59949b87..cf0cb143de 100644 --- a/waterbox/melon/BizInterface.cpp +++ b/waterbox/melon/BizInterface.cpp @@ -4,10 +4,9 @@ #include "RTC.h" #include "ARM.h" #include "NDSCart.h" -#include "NDSCart_SRAMManager.h" #include "GBACart.h" #include "Platform.h" -#include "Config.h" +#include "BizConfig.h" #include "types.h" #include "frontend/mic_blow.h" @@ -39,9 +38,16 @@ typedef enum FIRMWARE_OVERRIDE = 0x10, } LoadFlags; -static const char* bios9_path = "bios9.rom"; -static const char* bios7_path = "bios7.rom"; -static const char* firmware_path = "firmware.bin"; +typedef struct +{ + u8* DsRomData; + u32 DsRomLen; + u8* GbaRomData; + u32 GbaRomLen; + u8* GbaRamData; + u32 GbaRamLen; +} LoadData; + static const char* rom_path = "game.rom"; static const char* sram_path = "save.ram"; static const char* gba_rom_path = "gba.rom"; @@ -60,72 +66,73 @@ typedef struct s32 FirmwareMessageLength; } FirmwareSettings; -EXPORT bool Init(LoadFlags flags, FirmwareSettings* fwSettings) +EXPORT bool Init(LoadFlags flags, LoadData* loadData, FirmwareSettings* fwSettings) { Config::ExternalBIOSEnable = !!(flags & USE_REAL_BIOS); - - strncpy(Config::BIOS9Path, Config::ExternalBIOSEnable ? bios9_path : no_path, 1023); - Config::BIOS9Path[1023] = '\0'; - strncpy(Config::BIOS7Path, Config::ExternalBIOSEnable ? bios7_path : no_path, 1023); - Config::BIOS7Path[1023] = '\0'; - strncpy(Config::FirmwarePath, firmware_path, 1023); - Config::FirmwarePath[1023] = '\0'; + Config::AudioBitrate = !!(flags & ACCURATE_AUDIO_BITRATE) ? 1 : 2; + Config::FirmwareOverrideSettings = !!(flags & FIRMWARE_OVERRIDE); + biz_skip_fw = !!(flags & SKIP_FIRMWARE); NDS::SetConsoleType(0); // time calls are deterministic under wbx, so this will force the mac address to a constant value instead of relying on whatever is in the firmware // fixme: might want to allow the user to specify mac address? srand(time(NULL)); Config::RandomizeMAC = true; - Config::AudioBitrate = !!(flags & ACCURATE_AUDIO_BITRATE) ? 1 : 2; - Config::FixedBootTime = true; - Config::UseRealTime = false; - Config::TimeAtBoot = 0; biz_time = 0; RTC::RtcCallback = BizRtcCallback; - Config::FirmwareOverrideSettings = !!(flags & FIRMWARE_OVERRIDE); if (Config::FirmwareOverrideSettings) { - memcpy(Config::FirmwareUsername, fwSettings->FirmwareUsername, fwSettings->FirmwareUsernameLength); - Config::FirmwareUsername[fwSettings->FirmwareUsernameLength] = 0; + std::string fwUsername(fwSettings->FirmwareUsername, fwSettings->FirmwareUsernameLength); + fwUsername += '\0'; + Config::FirmwareUsername = fwUsername; Config::FirmwareLanguage = fwSettings->FirmwareLanguage; Config::FirmwareBirthdayMonth = fwSettings->FirmwareBirthdayMonth; Config::FirmwareBirthdayDay = fwSettings->FirmwareBirthdayDay; Config::FirmwareFavouriteColour = fwSettings->FirmwareFavouriteColour; - memcpy(Config::FirmwareMessage, fwSettings->FirmwareMessage, fwSettings->FirmwareMessageLength); - Config::FirmwareMessage[fwSettings->FirmwareMessageLength] = 0; + std::string fwMessage(fwSettings->FirmwareMessage, fwSettings->FirmwareMessageLength); + fwMessage += '\0'; + Config::FirmwareMessage = fwMessage; } if (!NDS::Init()) return false; GPU::InitRenderer(false); GPU::SetRenderSettings(false, biz_render_settings); - biz_skip_fw = !!(flags & SKIP_FIRMWARE); - if (!NDS::LoadROM(rom_path, no_path, biz_skip_fw)) return false; - if (flags & GBA_CART_PRESENT) { if (!NDS::LoadGBAROM(gba_rom_path, gba_sram_path)) return false; } + if (!NDS::LoadCart(loadData->DsRomData, loadData->DsRomLen, nullptr, 0)) return false; + if (flags & GBA_CART_PRESENT) + { + if (!NDS::LoadGBACart(loadData->GbaRomData, loadData->GbaRomLen, loadData->GbaRamData, loadData->GbaRamLen)) + return false; + } + NDS::LoadBIOS(); + if (biz_skip_fw) NDS::SetupDirectBoot(""); + NDS::Start(); Config::FirmwareOverrideSettings = false; return true; } +namespace NDSCart { extern CartCommon* Cart; } +extern bool NdsSaveRamIsDirty; + EXPORT void PutSaveRam(u8* data, u32 len) { - if (NDSCart_SRAMManager::SecondaryBufferLength > 0) - NDSCart_SRAMManager::UpdateBuffer(data, len); + NDS::LoadSave(data, len); + NdsSaveRamIsDirty = false; } EXPORT void GetSaveRam(u8* data) { - if (NDSCart_SRAMManager::SecondaryBufferLength > 0) - NDSCart_SRAMManager::FlushSecondaryBuffer(data, NDSCart_SRAMManager::SecondaryBufferLength); + if (NDSCart::Cart) NDSCart::Cart->GetSaveData(data); } EXPORT s32 GetSaveRamLength() { - return NDSCart_SRAMManager::SecondaryBufferLength; + return NDSCart::Cart ? NDSCart::Cart->GetSaveLen() : 0; } EXPORT bool SaveRamIsDirty() { - return NDSCart_SRAMManager::NeedsFlush(); + return NdsSaveRamIsDirty; } /* excerpted from gbatek @@ -292,8 +299,8 @@ EXPORT void FrameAdvance(MyFrameInfo* f) { if (f->Keys & 0x8000) { - NDS::LoadBIOS(false); - if (biz_skip_fw) NDS::SetupDirectBoot(); + NDS::LoadBIOS(); + if (biz_skip_fw) NDS::SetupDirectBoot(""); } NDS::SetKeyMask(~f->Keys & 0xFFF); diff --git a/waterbox/melon/BizPlatform.cpp b/waterbox/melon/BizPlatform.cpp index 72e6701a3d..7969b995a1 100644 --- a/waterbox/melon/BizPlatform.cpp +++ b/waterbox/melon/BizPlatform.cpp @@ -5,6 +5,9 @@ #include #include #include "Platform.h" +#include "BizConfig.h" + +bool NdsSaveRamIsDirty = false; namespace Platform { @@ -25,20 +28,44 @@ int GetConfigInt(ConfigEntry entry) { const int imgsizes[] = {0, 256, 512, 1024, 2048, 4096}; - /*switch (entry) + switch (entry) { +#ifdef JIT_ENABLED + case JIT_MaxBlockSize: return Config::JIT_MaxBlockSize; +#endif + case DLDI_ImageSize: return imgsizes[Config::DLDISize]; case DSiSD_ImageSize: return imgsizes[Config::DSiSDSize]; - }*/ + + case Firm_Language: return Config::FirmwareLanguage; + case Firm_BirthdayMonth: return Config::FirmwareBirthdayMonth; + case Firm_BirthdayDay: return Config::FirmwareBirthdayDay; + case Firm_Color: return Config::FirmwareFavouriteColour; + + case AudioBitrate: return Config::AudioBitrate; + + case TimeAtBoot: return Config::TimeAtBoot; + + default: break; + } return 0; } bool GetConfigBool(ConfigEntry entry) { - /*switch (entry) + switch (entry) { +#ifdef JIT_ENABLED + case JIT_Enable: return Config::JIT_Enable != 0; + case JIT_LiteralOptimizations: return Config::JIT_LiteralOptimisations != 0; + case JIT_BranchOptimizations: return Config::JIT_BranchOptimisations != 0; + case JIT_FastMemory: return Config::JIT_FastMemory != 0; +#endif + + case ExternalBIOSEnable: return Config::ExternalBIOSEnable != 0; + case DLDI_Enable: return Config::DLDIEnable != 0; case DLDI_ReadOnly: return Config::DLDIReadOnly != 0; case DLDI_FolderSync: return Config::DLDIFolderSync != 0; @@ -46,33 +73,94 @@ bool GetConfigBool(ConfigEntry entry) case DSiSD_Enable: return Config::DSiSDEnable != 0; case DSiSD_ReadOnly: return Config::DSiSDReadOnly != 0; case DSiSD_FolderSync: return Config::DSiSDFolderSync != 0; - }*/ + + case Firm_RandomizeMAC: return Config::RandomizeMAC != 0; + case Firm_OverrideSettings: return Config::FirmwareOverrideSettings != 0; + + case UseRealTime: return Config::UseRealTime != 0; + case FixedBootTime: return Config::FixedBootTime != 0; + + default: break; + } return false; } std::string GetConfigString(ConfigEntry entry) { - /*switch (entry) + switch (entry) { + case BIOS9Path: return Config::BIOS9Path; + case BIOS7Path: return Config::BIOS7Path; + case FirmwarePath: return Config::FirmwarePath; + + case DSi_BIOS9Path: return Config::DSiBIOS9Path; + case DSi_BIOS7Path: return Config::DSiBIOS7Path; + case DSi_FirmwarePath: return Config::DSiFirmwarePath; + case DSi_NANDPath: return Config::DSiNANDPath; + case DLDI_ImagePath: return Config::DLDISDPath; case DLDI_FolderPath: return Config::DLDIFolderPath; case DSiSD_ImagePath: return Config::DSiSDPath; case DSiSD_FolderPath: return Config::DSiSDFolderPath; - }*/ + + case Firm_Username: return Config::FirmwareUsername; + case Firm_Message: return Config::FirmwareMessage; + + default: break; + } return ""; } -FILE* OpenFile(const char* path, const char* mode, bool mustexist) +bool GetConfigArray(ConfigEntry entry, void* data) { - return fopen(path, mode); + switch (entry) + { + case Firm_MAC: + { + std::string& mac_in = Config::FirmwareMAC; + u8* mac_out = (u8*)data; + + int o = 0; + u8 tmp = 0; + for (int i = 0; i < 18; i++) + { + char c = mac_in[i]; + if (c == '\0') break; + + int n; + if (c >= '0' && c <= '9') n = c - '0'; + else if (c >= 'a' && c <= 'f') n = c - 'a' + 10; + else if (c >= 'A' && c <= 'F') n = c - 'A' + 10; + else continue; + + if (!(o & 1)) + tmp = n; + else + mac_out[o >> 1] = n | (tmp << 4); + + o++; + if (o >= 12) return true; + } + } + return false; + default: break; + } + + return false; } -FILE* OpenLocalFile(const char* path, const char* mode) + +FILE* OpenFile(std::string path, std::string mode, bool mustexist) { - return fopen(path, mode); + return fopen(path.c_str(), mode.c_str()); +} + +FILE* OpenLocalFile(std::string path, std::string mode) +{ + return fopen(path.c_str(), mode.c_str()); } Thread* Thread_Create(std::function func) @@ -145,6 +233,17 @@ bool Mutex_TryLock(Mutex* mutex) return ((std::mutex*) mutex)->try_lock(); } + +void WriteNDSSave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen) +{ + bool NdsSaveRamIsDirty = true; +} + +void WriteGBASave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen) +{ +} + + bool MP_Init() { return false; diff --git a/waterbox/melon/Makefile b/waterbox/melon/Makefile index 694c22a5be..41e367d26e 100644 --- a/waterbox/melon/Makefile +++ b/waterbox/melon/Makefile @@ -1,10 +1,11 @@ +CCFLAGS := -Wno-discarded-qualifiers + CXXFLAGS := -DMELONDS_VERSION="" \ -I./melonDS/src -I./melonDS/src/teakra/include \ -Wall -Wextra -Werror=int-to-pointer-cast \ - -Wcast-qual -Wfatal-errors -Wno-missing-braces \ - -Wno-unused-parameter -Wno-parentheses -Wno-sign-compare \ - -Wno-unused-variable -Wno-unused-function \ - -pedantic -std=c++17 + -Wfatal-errors -Wno-unused-parameter -Wno-unused-variable \ + -Wno-unused-but-set-variable -Wno-sign-compare \ + -fno-strict-aliasing -std=c++17 TARGET = melonDS.wbx @@ -73,6 +74,7 @@ SRCS = \ $(addprefix melonDS/src/teakra/src/,$(TEAKRA_SRCS)) \ $(addprefix melonDS/src/fatfs/,$(FATFS_SRCS)) \ $(addprefix melonDS/src/,$(MISC_SRCS)) \ + BizConfig.cpp \ BizInterface.cpp \ BizPlatform.cpp diff --git a/waterbox/melon/melonDS b/waterbox/melon/melonDS index 608b7d2f36..e59387b3fc 160000 --- a/waterbox/melon/melonDS +++ b/waterbox/melon/melonDS @@ -1 +1 @@ -Subproject commit 608b7d2f36c986cfb5a31e9ebf016968015d592f +Subproject commit e59387b3fcc8dde8e8df1e1a1c1251c53720c2bc