From 1da9b3806c67282f7fc2c48b5b0b4614e553c34d Mon Sep 17 00:00:00 2001 From: Raphaël Zumer Date: Sun, 8 Dec 2019 15:31:18 -0500 Subject: Hook up the GBA slot to the UI A GBA cartridge may be loaded in the same way as a DS cartridge. If the extension of the selected file is "gba", it will be treated as a GBA file. The system boot logic is still centered around the DS cartridge, so loading a GBA file will not start or reset it. --- src/libui_sdl/main.cpp | 145 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 96 insertions(+), 49 deletions(-) (limited to 'src/libui_sdl') diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index d6aa460..68bc6b8 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -105,9 +105,9 @@ int EmuRunning; volatile int EmuStatus; bool RunningSomething; -char ROMPath[1024]; -char SRAMPath[1024]; -char PrevSRAMPath[1024]; // for savestate 'undo load' +char ROMPath[2][1024]; +char SRAMPath[2][1024]; +char PrevSRAMPath[2][1024]; // for savestate 'undo load' bool SavestateLoaded; @@ -184,7 +184,7 @@ void SetupScreenRects(int width, int height); void TogglePause(void* blarg); void Reset(void* blarg); -void SetupSRAMPath(); +void SetupSRAMPath(int slot); void SaveState(int slot); void LoadState(int slot); @@ -1648,12 +1648,18 @@ void Reset(void* blarg) SavestateLoaded = false; uiMenuItemDisable(MenuItem_UndoStateLoad); - if (ROMPath[0] == '\0') + if (ROMPath[0][0] == '\0') NDS::LoadBIOS(); else { - SetupSRAMPath(); - NDS::LoadROM(ROMPath, SRAMPath, Config::DirectBoot); + SetupSRAMPath(0); + NDS::LoadROM(ROMPath[0], SRAMPath[0], Config::DirectBoot); + } + + if (ROMPath[1][0] != '\0') + { + SetupSRAMPath(1); + NDS::LoadGBAROM(ROMPath[1], SRAMPath[1]); } Run(); @@ -1688,41 +1694,53 @@ void Stop(bool internal) OSD::AddMessage(0xFFC040, "Shutdown"); } -void SetupSRAMPath() +void SetupSRAMPath(int slot) { - strncpy(SRAMPath, ROMPath, 1023); - SRAMPath[1023] = '\0'; - strncpy(SRAMPath + strlen(ROMPath) - 3, "sav", 3); + strncpy(SRAMPath[slot], ROMPath[slot], 1023); + SRAMPath[slot][1023] = '\0'; + strncpy(SRAMPath[slot] + strlen(ROMPath[slot]) - 3, "sav", 3); } -void TryLoadROM(char* file, int prevstatus) +void TryLoadROM(char* file, int slot, int prevstatus) { char oldpath[1024]; char oldsram[1024]; - strncpy(oldpath, ROMPath, 1024); - strncpy(oldsram, SRAMPath, 1024); + strncpy(oldpath, ROMPath[slot], 1024); + strncpy(oldsram, SRAMPath[slot], 1024); - strncpy(ROMPath, file, 1023); - ROMPath[1023] = '\0'; + strncpy(ROMPath[slot], file, 1023); + ROMPath[slot][1023] = '\0'; - SetupSRAMPath(); + SetupSRAMPath(0); + SetupSRAMPath(1); - if (NDS::LoadROM(ROMPath, SRAMPath, Config::DirectBoot)) + if (slot == 0 && NDS::LoadROM(ROMPath[slot], SRAMPath[slot], Config::DirectBoot)) { SavestateLoaded = false; uiMenuItemDisable(MenuItem_UndoStateLoad); - strncpy(PrevSRAMPath, SRAMPath, 1024); // safety + // Reload the inserted GBA cartridge (if any) + if (ROMPath[1][0] != '\0') NDS::LoadGBAROM(ROMPath[1], SRAMPath[1]); + + strncpy(PrevSRAMPath[slot], SRAMPath[slot], 1024); // safety Run(); } + else if (slot == 1 && NDS::LoadGBAROM(ROMPath[slot], SRAMPath[slot])) + { + SavestateLoaded = false; + uiMenuItemDisable(MenuItem_UndoStateLoad); + + strncpy(PrevSRAMPath[slot], SRAMPath[slot], 1024); // safety + if (RunningSomething) Run(); // do not start just from a GBA cart + } else { uiMsgBoxError(MainWindow, "Failed to load the ROM", "Make sure the file can be accessed and isn't opened in another application."); - strncpy(ROMPath, oldpath, 1024); - strncpy(SRAMPath, oldsram, 1024); + strncpy(ROMPath[slot], oldpath, 1024); + strncpy(SRAMPath[slot], oldsram, 1024); EmuRunning = prevstatus; } } @@ -1735,22 +1753,22 @@ void GetSavestateName(int slot, char* filename, int len) { int pos; - if (ROMPath[0] == '\0') // running firmware, no ROM + if (ROMPath[0][0] == '\0') // running firmware, no ROM { strcpy(filename, "firmware"); pos = 8; } else { - int l = strlen(ROMPath); + int l = strlen(ROMPath[0]); pos = l; - while (ROMPath[pos] != '.' && pos > 0) pos--; + while (ROMPath[0][pos] != '.' && pos > 0) pos--; if (pos == 0) pos = l; // avoid buffer overflow. shoddy if (pos > len-5) pos = len-5; - strncpy(&filename[0], ROMPath, pos); + strncpy(&filename[0], ROMPath[0], pos); } strcpy(&filename[pos], ".ml"); filename[pos+3] = '0'+slot; @@ -1818,16 +1836,16 @@ void LoadState(int slot) if (!failed) { - if (Config::SavestateRelocSRAM && ROMPath[0]!='\0') + if (Config::SavestateRelocSRAM && ROMPath[0][0]!='\0') { - strncpy(PrevSRAMPath, SRAMPath, 1024); + strncpy(PrevSRAMPath[0], SRAMPath[0], 1024); - strncpy(SRAMPath, filename, 1019); - int len = strlen(SRAMPath); - strcpy(&SRAMPath[len], ".sav"); - SRAMPath[len+4] = '\0'; + strncpy(SRAMPath[0], filename, 1019); + int len = strlen(SRAMPath[0]); + strcpy(&SRAMPath[0][len], ".sav"); + SRAMPath[0][len+4] = '\0'; - NDS::RelocateSave(SRAMPath, false); + NDS::RelocateSave(SRAMPath[0], false); } char msg[64]; @@ -1883,14 +1901,14 @@ void SaveState(int slot) if (slot > 0) uiMenuItemEnable(MenuItem_LoadStateSlot[slot-1]); - if (Config::SavestateRelocSRAM && ROMPath[0]!='\0') + if (Config::SavestateRelocSRAM && ROMPath[0][0]!='\0') { - strncpy(SRAMPath, filename, 1019); - int len = strlen(SRAMPath); - strcpy(&SRAMPath[len], ".sav"); - SRAMPath[len+4] = '\0'; + strncpy(SRAMPath[0], filename, 1019); + int len = strlen(SRAMPath[0]); + strcpy(&SRAMPath[0][len], ".sav"); + SRAMPath[0][len+4] = '\0'; - NDS::RelocateSave(SRAMPath, true); + NDS::RelocateSave(SRAMPath[0], true); } } @@ -1917,10 +1935,10 @@ void UndoStateLoad() NDS::DoSavestate(backup); delete backup; - if (ROMPath[0]!='\0') + if (ROMPath[0][0]!='\0') { - strncpy(SRAMPath, PrevSRAMPath, 1024); - NDS::RelocateSave(SRAMPath, false); + strncpy(SRAMPath[0], PrevSRAMPath[0], 1024); + NDS::RelocateSave(SRAMPath[0], false); } OSD::AddMessage(0, "State load undone"); @@ -1964,7 +1982,11 @@ void OnDropFile(uiWindow* window, char* file, void* blarg) while (EmuStatus != 2); } - TryLoadROM(file, prevstatus); + TryLoadROM(file, 0, prevstatus); + } + else if (!strcasecmp(ext, "gba")) + { + TryLoadROM(file, 1, prevstatus); } } @@ -1995,7 +2017,7 @@ void OnOpenFile(uiMenuItem* item, uiWindow* window, void* blarg) EmuRunning = 2; while (EmuStatus != 2); - char* file = uiOpenFile(window, "DS ROM (*.nds)|*.nds;*.srl|Any file|*.*", Config::LastROMFolder); + char* file = uiOpenFile(window, "DS ROM (*.nds)|*.nds;*.srl|GBA ROM (*.gba)|*.gba|Any file|*.*", Config::LastROMFolder); if (!file) { EmuRunning = prevstatus; @@ -2006,8 +2028,17 @@ void OnOpenFile(uiMenuItem* item, uiWindow* window, void* blarg) while (file[pos] != '/' && file[pos] != '\\' && pos > 0) pos--; strncpy(Config::LastROMFolder, file, pos); Config::LastROMFolder[pos] = '\0'; + char* ext = &file[strlen(file)-3]; + + if (!strcasecmp(ext, "gba")) + { + TryLoadROM(file, 1, prevstatus); + } + else + { + TryLoadROM(file, 0, prevstatus); + } - TryLoadROM(file, prevstatus); uiFreeText(file); } @@ -2032,7 +2063,7 @@ void OnRun(uiMenuItem* item, uiWindow* window, void* blarg) { if (!RunningSomething) { - ROMPath[0] = '\0'; + ROMPath[0][0] = '\0'; NDS::LoadBIOS(); } @@ -2852,14 +2883,30 @@ int main(int argc, char** argv) if (!strcasecmp(ext, "nds") || !strcasecmp(ext, "srl")) { - strncpy(ROMPath, file, 1023); - ROMPath[1023] = '\0'; + strncpy(ROMPath[0], file, 1023); + ROMPath[0][1023] = '\0'; - SetupSRAMPath(); + SetupSRAMPath(0); - if (NDS::LoadROM(ROMPath, SRAMPath, Config::DirectBoot)) + if (NDS::LoadROM(ROMPath[0], SRAMPath[0], Config::DirectBoot)) Run(); } + + if (argc > 2) + { + file = argv[2]; + ext = &file[strlen(file)-3]; + + if (!strcasecmp(ext, "gba")) + { + strncpy(ROMPath[1], file, 1023); + ROMPath[1][1023] = '\0'; + + SetupSRAMPath(1); + + NDS::LoadGBAROM(ROMPath[1], SRAMPath[1]); + } + } } uiMain(); -- cgit v1.2.3 From 91bf62a1d45fd8e81c6c77cb7072898f184c3a1c Mon Sep 17 00:00:00 2001 From: Raphaël Zumer Date: Sun, 8 Dec 2019 15:55:06 -0500 Subject: Keep GBA carts loaded when booting to firmware --- src/libui_sdl/main.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/libui_sdl') diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 68bc6b8..1e6069e 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -2065,6 +2065,12 @@ void OnRun(uiMenuItem* item, uiWindow* window, void* blarg) { ROMPath[0][0] = '\0'; NDS::LoadBIOS(); + + if (ROMPath[1][0] != '\0') + { + SetupSRAMPath(1); + NDS::LoadGBAROM(ROMPath[1], SRAMPath[1]); + } } Run(); -- cgit v1.2.3 From 4e8b0c8ce451bc11de8b11b4da14a24242c8c34e Mon Sep 17 00:00:00 2001 From: Raphaël Zumer Date: Mon, 9 Dec 2019 06:09:30 -0500 Subject: Eject GBA cartridges on stop from the UI --- src/GBACart.cpp | 31 +++++++++++++++++++++++++++---- src/libui_sdl/main.cpp | 3 +++ 2 files changed, 30 insertions(+), 4 deletions(-) (limited to 'src/libui_sdl') diff --git a/src/GBACart.cpp b/src/GBACart.cpp index 937958c..a0483b1 100644 --- a/src/GBACart.cpp +++ b/src/GBACart.cpp @@ -145,9 +145,9 @@ void LoadSave(const char* path) } else if (SRAMType == S_FLASH1M) { - // Macronix 128K chip - SRAMFlash.device = 0x09; - SRAMFlash.manufacturer = 0xC2; + // Sanyo 128K chip + SRAMFlash.device = 0x13; + SRAMFlash.manufacturer = 0x62; } } @@ -175,7 +175,30 @@ void RelocateSave(const char* path, bool write) u8 Read_Flash(u32 addr) { - // TODO: pokemen + if (SRAMFlash.cmd == 0) // no cmd + { + return *(u8*)&SRAM[addr + 0x10000 * SRAMFlash.bank]; + } + + // TODO properly keep track of command sequences, + // and deny unauthorized writes + switch (SRAMFlash.cmd) + { + case 0x90: // chip ID + if (addr == 0x0A000000) return SRAMFlash.manufacturer; + if (addr == 0x0A000001) return SRAMFlash.device; + break; + case 0xF0: // terminate command (TODO: break if non-Macronix chip and not at the end of an ID call?) + SRAMFlash.state = 0; + SRAMFlash.cmd = 0; + break; + case 0xB0: // bank switching (128K only) + break; // we don't track the request for now + default: + printf("GBACart_SRAM::Read_Flash: unknown command 0x%02X @ 0x%08X\n", SRAMFlash.cmd, addr); + break; + } + return 0xFF; } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 1e6069e..31b0488 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -1674,6 +1674,9 @@ void Stop(bool internal) while (EmuStatus != 2); RunningSomething = false; + // eject any inserted GBA cartridge + ROMPath[1][0] = '\0'; + uiWindowSetTitle(MainWindow, "melonDS " MELONDS_VERSION); for (int i = 0; i < 9; i++) uiMenuItemDisable(MenuItem_SaveStateSlot[i]); -- cgit v1.2.3 From ca9f183d24c028cbbbecbe07aefb37bdcd04a581 Mon Sep 17 00:00:00 2001 From: Raphaël Zumer Date: Tue, 10 Dec 2019 17:54:34 -0500 Subject: Hook up solar sensor control to the UI It uses hardcoded keypad left and right arrows. --- src/GBACart.cpp | 8 +++++--- src/GBACart.h | 2 +- src/libui_sdl/main.cpp | 15 +++++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) (limited to 'src/libui_sdl') diff --git a/src/GBACart.cpp b/src/GBACart.cpp index 5b81900..a7ddf9b 100644 --- a/src/GBACart.cpp +++ b/src/GBACart.cpp @@ -462,6 +462,7 @@ const char SOLAR_SENSOR_GAMECODES[10][5] = bool CartInserted; +bool HasSolarSensor; u8* CartROM; u32 CartROMSize; u32 CartCRC; @@ -488,6 +489,7 @@ void DeInit() void Reset() { CartInserted = false; + HasSolarSensor = false; if (CartROM) delete[] CartROM; CartROM = NULL; CartROMSize = 0; @@ -529,10 +531,10 @@ bool LoadROM(const char* path, const char* sram) for (int i = 0; i < sizeof(SOLAR_SENSOR_GAMECODES)/sizeof(SOLAR_SENSOR_GAMECODES[0]); i++) { - if (strcmp(gamecode, SOLAR_SENSOR_GAMECODES[i]) == 0) CartGPIO.has_solar_sensor = true; + if (strcmp(gamecode, SOLAR_SENSOR_GAMECODES[i]) == 0) HasSolarSensor = true; } - if (CartGPIO.has_solar_sensor) + if (HasSolarSensor) { printf("GBA solar sensor support detected!\n"); } @@ -570,7 +572,7 @@ void WriteGPIO(u32 addr, u16 val) case 0xC4: CartGPIO.data &= ~CartGPIO.direction; CartGPIO.data |= val & CartGPIO.direction; - if (CartGPIO.has_solar_sensor) GBACart_SolarSensor::Process(&CartGPIO); + if (HasSolarSensor) GBACart_SolarSensor::Process(&CartGPIO); break; case 0xC6: CartGPIO.direction = val; diff --git a/src/GBACart.h b/src/GBACart.h index 32a2171..032c4fc 100644 --- a/src/GBACart.h +++ b/src/GBACart.h @@ -45,13 +45,13 @@ namespace GBACart struct GPIO { - bool has_solar_sensor; u16 data; u16 direction; u16 control; }; extern bool CartInserted; +extern bool HasSolarSensor; extern u8* CartROM; extern u32 CartROMSize; diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 31b0488..1b7cfe6 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -38,6 +38,7 @@ #include "DlgWifiSettings.h" #include "../NDS.h" +#include "../GBACart.h" #include "../GPU.h" #include "../SPU.h" #include "../Wifi.h" @@ -1291,6 +1292,20 @@ int OnAreaKeyEvent(uiAreaHandler* handler, uiArea* area, uiAreaKeyEvent* evt) { if (evt->Modifiers == 0x0) UndoStateLoad(); } + else if (evt->Scancode == 0x4B) // Keypad left + { + if (GBACart::CartInserted && GBACart::HasSolarSensor) + { + if (GBACart_SolarSensor::LightLevel > 0) GBACart_SolarSensor::LightLevel--; + } + } + else if (evt->Scancode == 0x4D) // Keypad right + { + if (GBACart::CartInserted && GBACart::HasSolarSensor) + { + if (GBACart_SolarSensor::LightLevel < 10) GBACart_SolarSensor::LightLevel++; + } + } for (int i = 0; i < 12; i++) if (EventMatchesKey(evt, Config::KeyMapping[i], false)) -- cgit v1.2.3 From f257b007a250e33ecc7a86c7447ccf049964dd8d Mon Sep 17 00:00:00 2001 From: Raphaël Zumer Date: Tue, 10 Dec 2019 18:44:53 -0500 Subject: Properly pass through GBA GPIO writes --- src/GBACart.cpp | 2 ++ src/NDS.cpp | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/libui_sdl/main.cpp | 2 ++ 3 files changed, 92 insertions(+) (limited to 'src/libui_sdl') diff --git a/src/GBACart.cpp b/src/GBACart.cpp index a7ddf9b..7e5e3b5 100644 --- a/src/GBACart.cpp +++ b/src/GBACart.cpp @@ -630,8 +630,10 @@ void Process(GBACart::GPIO* gpio) if (gpio->data & 4) return; // Boktai chip select if (gpio->data & 2) // Reset { + u8 prev = LightSample; LightCounter = 0; LightSample = LIGHT_VALUE; + printf("Solar sensor reset (sample: 0x%02X -> 0x%02X)\n", prev, LightSample); } if (gpio->data & 1 && LightEdge) LightCounter++; diff --git a/src/NDS.cpp b/src/NDS.cpp index a906fbb..47f96c9 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -1803,6 +1803,19 @@ void ARM9Write8(u32 addr, u8 val) // checkme return; + case 0x08000000: + case 0x09000000: + if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write + if (GBACart::CartInserted) + { + if ((addr & 0x00FFFFFF) >= 0xC4 && (addr & 0x00FFFFFF) <= 0xC9) + { + GBACart::WriteGPIO(addr & (GBACart::CartROMSize-1), val); + return; + } + } + break; + case 0x0A000000: if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write if (GBACart::CartInserted) @@ -1854,6 +1867,21 @@ void ARM9Write16(u32 addr, u16 val) *(u16*)&GPU::OAM[addr & 0x7FF] = val; return; + case 0x08000000: + case 0x09000000: + if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write + if (GBACart::CartInserted) + { + // Note: the lower bound is adjusted such that a write starting + // there will hit the first byte of the GPIO region. + if ((addr & 0x00FFFFFF) >= 0xC3 && (addr & 0x00FFFFFF) <= 0xC9) + { + GBACart::WriteGPIO(addr & (GBACart::CartROMSize-1), val); + return; + } + } + break; + case 0x0A000000: if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write if (GBACart::CartInserted) @@ -1905,6 +1933,22 @@ void ARM9Write32(u32 addr, u32 val) *(u32*)&GPU::OAM[addr & 0x7FF] = val; return; + case 0x08000000: + case 0x09000000: + if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write + if (GBACart::CartInserted) + { + // Note: the lower bound is adjusted such that a write starting + // there will hit the first byte of the GPIO region. + if ((addr & 0x00FFFFFF) >= 0xC1 && (addr & 0x00FFFFFF) <= 0xC9) + { + GBACart::WriteGPIO(addr & (GBACart::CartROMSize-1), val & 0xFF); + GBACart::WriteGPIO((addr + 2) & (GBACart::CartROMSize-1), (val >> 16) & 0xFF); + return; + } + } + break; + case 0x0A000000: if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write if (GBACart::CartInserted) @@ -2177,6 +2221,19 @@ void ARM7Write8(u32 addr, u8 val) GPU::WriteVRAM_ARM7(addr, val); return; + case 0x08000000: + case 0x09000000: + if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write + if (GBACart::CartInserted) + { + if ((addr & 0x00FFFFFF) >= 0xC4 && (addr & 0x00FFFFFF) <= 0xC9) + { + GBACart::WriteGPIO(addr & (GBACart::CartROMSize-1), val); + return; + } + } + break; + case 0x0A000000: if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write if (GBACart::CartInserted) @@ -2231,6 +2288,21 @@ void ARM7Write16(u32 addr, u16 val) GPU::WriteVRAM_ARM7(addr, val); return; + case 0x08000000: + case 0x09000000: + if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write + if (GBACart::CartInserted) + { + // Note: the lower bound is adjusted such that a write starting + // there will hit the first byte of the GPIO region. + if ((addr & 0x00FFFFFF) >= 0xC3 && (addr & 0x00FFFFFF) <= 0xC9) + { + GBACart::WriteGPIO(addr & (GBACart::CartROMSize-1), val); + return; + } + } + break; + case 0x0A000000: if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write if (GBACart::CartInserted) @@ -2286,6 +2358,22 @@ void ARM7Write32(u32 addr, u32 val) GPU::WriteVRAM_ARM7(addr, val); return; + case 0x08000000: + case 0x09000000: + if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write + if (GBACart::CartInserted) + { + // Note: the lower bound is adjusted such that a write starting + // there will hit the first byte of the GPIO region. + if ((addr & 0x00FFFFFF) >= 0xC1 && (addr & 0x00FFFFFF) <= 0xC9) + { + GBACart::WriteGPIO(addr & (GBACart::CartROMSize-1), val & 0xFF); + GBACart::WriteGPIO((addr + 2) & (GBACart::CartROMSize-1), (val >> 16) & 0xFF); + return; + } + } + break; + case 0x0A000000: if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write if (GBACart::CartInserted) diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 1b7cfe6..d2a38f2 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -1297,6 +1297,7 @@ int OnAreaKeyEvent(uiAreaHandler* handler, uiArea* area, uiAreaKeyEvent* evt) if (GBACart::CartInserted && GBACart::HasSolarSensor) { if (GBACart_SolarSensor::LightLevel > 0) GBACart_SolarSensor::LightLevel--; + printf("Solar sensor level set to %d\n", GBACart_SolarSensor::LightLevel); } } else if (evt->Scancode == 0x4D) // Keypad right @@ -1304,6 +1305,7 @@ int OnAreaKeyEvent(uiAreaHandler* handler, uiArea* area, uiAreaKeyEvent* evt) if (GBACart::CartInserted && GBACart::HasSolarSensor) { if (GBACart_SolarSensor::LightLevel < 10) GBACart_SolarSensor::LightLevel++; + printf("Solar sensor level set to %d\n", GBACart_SolarSensor::LightLevel); } } -- cgit v1.2.3 From f8e43ac486aa7bbc9ebfdbd23b959f0fa163c51d Mon Sep 17 00:00:00 2001 From: Raphaël Zumer Date: Tue, 10 Dec 2019 19:24:28 -0500 Subject: Display solar sensor level changes on OSD --- src/libui_sdl/main.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/libui_sdl') diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index d2a38f2..a96b77a 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -1297,7 +1297,9 @@ int OnAreaKeyEvent(uiAreaHandler* handler, uiArea* area, uiAreaKeyEvent* evt) if (GBACart::CartInserted && GBACart::HasSolarSensor) { if (GBACart_SolarSensor::LightLevel > 0) GBACart_SolarSensor::LightLevel--; - printf("Solar sensor level set to %d\n", GBACart_SolarSensor::LightLevel); + char msg[64]; + sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); + OSD::AddMessage(0, msg); } } else if (evt->Scancode == 0x4D) // Keypad right @@ -1305,7 +1307,9 @@ int OnAreaKeyEvent(uiAreaHandler* handler, uiArea* area, uiAreaKeyEvent* evt) if (GBACart::CartInserted && GBACart::HasSolarSensor) { if (GBACart_SolarSensor::LightLevel < 10) GBACart_SolarSensor::LightLevel++; - printf("Solar sensor level set to %d\n", GBACart_SolarSensor::LightLevel); + char msg[64]; + sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); + OSD::AddMessage(0, msg); } } -- cgit v1.2.3 From be19e0e8d49485d91c4106bad79daa766f7cb131 Mon Sep 17 00:00:00 2001 From: Raphaël Zumer Date: Wed, 11 Dec 2019 19:21:59 -0500 Subject: Make solar sensor hotkeys configurable --- src/libui_sdl/DlgInputConfig.cpp | 6 ++++-- src/libui_sdl/PlatformConfig.cpp | 32 ++++++++++++++++++-------------- src/libui_sdl/PlatformConfig.h | 2 ++ src/libui_sdl/main.cpp | 38 ++++++++++++++++++-------------------- 4 files changed, 42 insertions(+), 36 deletions(-) (limited to 'src/libui_sdl') diff --git a/src/libui_sdl/DlgInputConfig.cpp b/src/libui_sdl/DlgInputConfig.cpp index a80e2ec..21394b1 100644 --- a/src/libui_sdl/DlgInputConfig.cpp +++ b/src/libui_sdl/DlgInputConfig.cpp @@ -71,7 +71,9 @@ char hotkeylabels[HK_MAX][32] = "Pause/resume:", "Reset:", "Fast forward:", - "Fast forward (toggle):" + "Fast forward (toggle):", + "Decrease sunlight (Boktai):", + "Increase sunlight (Boktai):" }; int openedmask; @@ -514,7 +516,7 @@ void Open(int type) memcpy(dlg->keymap, Config::HKKeyMapping, sizeof(int)*HK_MAX); memcpy(dlg->joymap, Config::HKJoyMapping, sizeof(int)*HK_MAX); - dlg->win = uiNewWindow("Hotkey config - melonDS", 600, 100, 0, 0, 0); + dlg->win = uiNewWindow("Hotkey config - melonDS", 700, 100, 0, 0, 0); } uiControl(dlg->win)->UserData = dlg; diff --git a/src/libui_sdl/PlatformConfig.cpp b/src/libui_sdl/PlatformConfig.cpp index c8ec19f..a2eaab9 100644 --- a/src/libui_sdl/PlatformConfig.cpp +++ b/src/libui_sdl/PlatformConfig.cpp @@ -93,25 +93,29 @@ ConfigEntry PlatformConfigFile[] = {"Joy_X", 0, &JoyMapping[10], -1, NULL, 0}, {"Joy_Y", 0, &JoyMapping[11], -1, NULL, 0}, - {"HKKey_Lid", 0, &HKKeyMapping[HK_Lid], 0x0D, NULL, 0}, - {"HKKey_Mic", 0, &HKKeyMapping[HK_Mic], 0x35, NULL, 0}, - {"HKKey_Pause", 0, &HKKeyMapping[HK_Pause], -1, NULL, 0}, - {"HKKey_Reset", 0, &HKKeyMapping[HK_Reset], -1, NULL, 0}, - {"HKKey_FastForward", 0, &HKKeyMapping[HK_FastForward], 0x0F, NULL, 0}, - {"HKKey_FastForwardToggle", 0, &HKKeyMapping[HK_FastForwardToggle], -1, NULL, 0}, - - {"HKJoy_Lid", 0, &HKJoyMapping[HK_Lid], -1, NULL, 0}, - {"HKJoy_Mic", 0, &HKJoyMapping[HK_Mic], -1, NULL, 0}, - {"HKJoy_Pause", 0, &HKJoyMapping[HK_Pause], -1, NULL, 0}, - {"HKJoy_Reset", 0, &HKJoyMapping[HK_Reset], -1, NULL, 0}, - {"HKJoy_FastForward", 0, &HKJoyMapping[HK_FastForward], -1, NULL, 0}, - {"HKJoy_FastForwardToggle", 0, &HKJoyMapping[HK_FastForwardToggle], -1, NULL, 0}, + {"HKKey_Lid", 0, &HKKeyMapping[HK_Lid], 0x0D, NULL, 0}, + {"HKKey_Mic", 0, &HKKeyMapping[HK_Mic], 0x35, NULL, 0}, + {"HKKey_Pause", 0, &HKKeyMapping[HK_Pause], -1, NULL, 0}, + {"HKKey_Reset", 0, &HKKeyMapping[HK_Reset], -1, NULL, 0}, + {"HKKey_FastForward", 0, &HKKeyMapping[HK_FastForward], 0x0F, NULL, 0}, + {"HKKey_FastForwardToggle", 0, &HKKeyMapping[HK_FastForwardToggle], -1, NULL, 0}, + {"HKKey_SolarSensorDecrease", 0, &HKKeyMapping[HK_SolarSensorDecrease], 0x4B, NULL, 0}, + {"HKKey_SolarSensorIncrease", 0, &HKKeyMapping[HK_SolarSensorIncrease], 0x4D, NULL, 0}, + + {"HKJoy_Lid", 0, &HKJoyMapping[HK_Lid], -1, NULL, 0}, + {"HKJoy_Mic", 0, &HKJoyMapping[HK_Mic], -1, NULL, 0}, + {"HKJoy_Pause", 0, &HKJoyMapping[HK_Pause], -1, NULL, 0}, + {"HKJoy_Reset", 0, &HKJoyMapping[HK_Reset], -1, NULL, 0}, + {"HKJoy_FastForward", 0, &HKJoyMapping[HK_FastForward], -1, NULL, 0}, + {"HKJoy_FastForwardToggle", 0, &HKJoyMapping[HK_FastForwardToggle], -1, NULL, 0}, + {"HKJoy_SolarSensorDecrease", 0, &HKJoyMapping[HK_SolarSensorDecrease], -1, NULL, 0}, + {"HKJoy_SolarSensorIncrease", 0, &HKJoyMapping[HK_SolarSensorIncrease], -1, NULL, 0}, {"JoystickID", 0, &JoystickID, 0, NULL, 0}, {"WindowWidth", 0, &WindowWidth, 256, NULL, 0}, {"WindowHeight", 0, &WindowHeight, 384, NULL, 0}, - {"WindowMax", 0, &WindowMaximized, 0, NULL, 0}, + {"WindowMax", 0, &WindowMaximized, 0, NULL, 0}, {"ScreenRotation", 0, &ScreenRotation, 0, NULL, 0}, {"ScreenGap", 0, &ScreenGap, 0, NULL, 0}, diff --git a/src/libui_sdl/PlatformConfig.h b/src/libui_sdl/PlatformConfig.h index 842e72a..682b9bc 100644 --- a/src/libui_sdl/PlatformConfig.h +++ b/src/libui_sdl/PlatformConfig.h @@ -29,6 +29,8 @@ enum HK_Reset, HK_FastForward, HK_FastForwardToggle, + HK_SolarSensorDecrease, + HK_SolarSensorIncrease, HK_MAX }; diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index a96b77a..38804f6 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -949,6 +949,24 @@ int EmuThreadFunc(void* burp) if (HotkeyPressed(HK_Pause)) uiQueueMain(TogglePause, NULL); if (HotkeyPressed(HK_Reset)) uiQueueMain(Reset, NULL); + if (GBACart::CartInserted && GBACart::HasSolarSensor) + { + if (HotkeyPressed(HK_SolarSensorDecrease)) + { + if (GBACart_SolarSensor::LightLevel > 0) GBACart_SolarSensor::LightLevel--; + char msg[64]; + sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); + OSD::AddMessage(0, msg); + } + if (HotkeyPressed(HK_SolarSensorIncrease)) + { + if (GBACart_SolarSensor::LightLevel < 10) GBACart_SolarSensor::LightLevel++; + char msg[64]; + sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); + OSD::AddMessage(0, msg); + } + } + if (EmuRunning == 1) { EmuStatus = 1; @@ -1292,26 +1310,6 @@ int OnAreaKeyEvent(uiAreaHandler* handler, uiArea* area, uiAreaKeyEvent* evt) { if (evt->Modifiers == 0x0) UndoStateLoad(); } - else if (evt->Scancode == 0x4B) // Keypad left - { - if (GBACart::CartInserted && GBACart::HasSolarSensor) - { - if (GBACart_SolarSensor::LightLevel > 0) GBACart_SolarSensor::LightLevel--; - char msg[64]; - sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); - OSD::AddMessage(0, msg); - } - } - else if (evt->Scancode == 0x4D) // Keypad right - { - if (GBACart::CartInserted && GBACart::HasSolarSensor) - { - if (GBACart_SolarSensor::LightLevel < 10) GBACart_SolarSensor::LightLevel++; - char msg[64]; - sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); - OSD::AddMessage(0, msg); - } - } for (int i = 0; i < 12; i++) if (EventMatchesKey(evt, Config::KeyMapping[i], false)) -- cgit v1.2.3 From 22d11209b0466e3c852da543ddfc512b66735bc2 Mon Sep 17 00:00:00 2001 From: Raphaël Zumer Date: Sun, 22 Dec 2019 15:49:23 -0500 Subject: Split GBA Reset and Eject logic into two sets This allows solving some crashes and provides more flexibility in how GBA cartridges change state between soft and hard resets. Since save states including GBA data do not carry over the original save file path, and the GBA cartridge is being reset along with the other parts of the system, this is needed to avoid losing the GBA state on reset following a state load, while preserving the behavior where cartridges are ejected when calling Stop(). --- src/GBACart.cpp | 35 ++++++++++++++++++++++++++++++----- src/GBACart.h | 2 ++ src/libui_sdl/main.cpp | 22 ++++++++++++++++++++-- 3 files changed, 52 insertions(+), 7 deletions(-) (limited to 'src/libui_sdl') diff --git a/src/GBACart.cpp b/src/GBACart.cpp index 7753482..4d44d3a 100644 --- a/src/GBACart.cpp +++ b/src/GBACart.cpp @@ -76,10 +76,14 @@ void DeInit() } void Reset() +{ + // do nothing, we don't want to clear GBA SRAM on reset +} + +void Eject() { if (SRAMFile) fclose(SRAMFile); if (SRAM) delete[] SRAM; - SRAM = NULL; SRAMFile = NULL; SRAMLength = 0; @@ -524,15 +528,30 @@ void DeInit() void Reset() { + // Do not reset cartridge ROM. + // Prefer keeping the inserted cartridge on reset. + // This allows resetting a DS game without losing GBA state, + // and resetting to firmware without the slot being emptied. + // The Stop function will clear the cartridge state via Eject(). + + GBACart_SRAM::Reset(); + GBACart_SolarSensor::Reset(); +} + +void Eject() +{ + if (CartROM) delete[] CartROM; + CartInserted = false; HasSolarSensor = false; - if (CartROM) delete[] CartROM; CartROM = NULL; CartROMSize = 0; + CartCRC = NULL; + CartID = NULL; CartGPIO = {}; - GBACart_SRAM::Reset(); - GBACart_SolarSensor::Reset(); + GBACart_SRAM::Eject(); + Reset(); } void DoSavestate(Savestate* file) @@ -545,10 +564,16 @@ void DoSavestate(Savestate* file) // since unlike with DS, it's not loaded in advance file->Var32(&CartROMSize); - if (!CartROMSize) return; // no GBA cartridge state? nothing to do here. + if (!CartROMSize) // no GBA cartridge state? nothing to do here + { + // do eject the cartridge if something is inserted + Eject(); + return; + } u32 oldCRC = CartCRC; file->Var32(&CartCRC); + if (CartCRC != oldCRC) { // delete and reallocate ROM so that it is zero-padded to its full length diff --git a/src/GBACart.h b/src/GBACart.h index fd26326..96a05b8 100644 --- a/src/GBACart.h +++ b/src/GBACart.h @@ -57,10 +57,12 @@ extern bool CartInserted; extern bool HasSolarSensor; extern u8* CartROM; extern u32 CartROMSize; +extern u32 CartCRC; bool Init(); void DeInit(); void Reset(); +void Eject(); void DoSavestate(Savestate* file); bool LoadROM(const char* path, const char* sram); diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 38804f6..af69f8e 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -1694,6 +1694,7 @@ void Stop(bool internal) RunningSomething = false; // eject any inserted GBA cartridge + GBACart::Eject(); ROMPath[1][0] = '\0'; uiWindowSetTitle(MainWindow, "melonDS " MELONDS_VERSION); @@ -1834,6 +1835,8 @@ void LoadState(int slot) return; } + u32 oldGBACartCRC = GBACart::CartCRC; + // backup Savestate* backup = new Savestate("timewarp.mln", true); NDS::DoSavestate(backup); @@ -1870,9 +1873,24 @@ void LoadState(int slot) NDS::RelocateSave(SRAMPath[0], false); } + bool loadedPartialGBAROM = false; + + // in case we have a GBA cart inserted, and the GBA ROM changes + // due to having loaded a save state, we do not want to reload + // the previous cartridge on reset, or commit writes to any + // loaded save file. therefore, their paths are "nulled". + if (GBACart::CartInserted && GBACart::CartCRC != oldGBACartCRC) + { + ROMPath[1][0] = '\0'; + SRAMPath[1][0] = '\0'; + loadedPartialGBAROM = true; + } + char msg[64]; - if (slot > 0) sprintf(msg, "State loaded from slot %d", slot); - else sprintf(msg, "State loaded from file"); + if (slot > 0) sprintf(msg, "State loaded from slot %d%s", + slot, loadedPartialGBAROM ? " (GBA ROM header only)" : ""); + else sprintf(msg, "State loaded from file%s", + loadedPartialGBAROM ? " (GBA ROM header only)" : ""); OSD::AddMessage(0, msg); SavestateLoaded = true; -- cgit v1.2.3