diff options
-rw-r--r-- | melonDS.cbp | 1 | ||||
-rw-r--r-- | src/NDS.cpp | 10 | ||||
-rw-r--r-- | src/NDS.h | 2 | ||||
-rw-r--r-- | src/NDSCart.cpp | 23 | ||||
-rw-r--r-- | src/libui_sdl/main.cpp | 40 | ||||
-rw-r--r-- | src/melon_fopen.h | 52 |
6 files changed, 99 insertions, 29 deletions
diff --git a/melonDS.cbp b/melonDS.cbp index d0485d6..7e83b98 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -229,6 +229,7 @@ <Unit filename="src/libui_sdl/libui/windows/winpublic.cpp" /> <Unit filename="src/libui_sdl/libui/windows/winutil.cpp" /> <Unit filename="src/libui_sdl/main.cpp" /> + <Unit filename="src/melon_fopen.h" /> <Unit filename="src/types.h" /> <Unit filename="src/version.h" /> <Unit filename="xp.manifest" /> diff --git a/src/NDS.cpp b/src/NDS.cpp index d25c1ff..d4f6594 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -352,14 +352,18 @@ void Stop() SPU::Stop(); } -void LoadROM(const char* path, bool direct) +bool LoadROM(const char* path, bool direct) { - Reset(); - if (NDSCart::LoadROM(path, direct)) + { Running = true; + return true; + } else + { printf("Failed to load ROM %s\n", path); + return false; + } } void LoadBIOS() @@ -106,7 +106,7 @@ void DeInit(); void Reset(); void Stop(); -void LoadROM(const char* path, bool direct); +bool LoadROM(const char* path, bool direct); void LoadBIOS(); void SetupDirectBoot(); diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index 216b3fb..03f536a 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -22,6 +22,8 @@ #include "NDSCart.h" #include "ARM.h" +#include "melon_fopen.h" + namespace NDSCart_SRAM { @@ -92,7 +94,7 @@ void LoadSave(char* path) strncpy(SRAMPath, path, 255); SRAMPath[255] = '\0'; - FILE* f = fopen(path, "rb"); + FILE* f = melon_fopen(path, "rb"); if (f) { fseek(f, 0, SEEK_END); @@ -624,7 +626,7 @@ void Write(u8 val, u32 hold) if (islast && (CurCmd == 0x02 || CurCmd == 0x0A) && (SRAMLength > 0)) { - FILE* f = fopen(SRAMPath, "wb"); + FILE* f = melon_fopen(SRAMPath, "wb"); if (f) { fwrite(SRAM, SRAMLength, 1, f); @@ -817,15 +819,14 @@ bool LoadROM(const char* path, bool direct) // TODO: streaming mode? for really big ROMs or systems with limited RAM // for now we're lazy - if (CartROM) delete[] CartROM; - - FILE* f = fopen(path, "rb"); + FILE* f = melon_fopen(path, "rb"); if (!f) { - printf("Failed to open ROM file %s\n", path); return false; } + NDS::Reset(); + fseek(f, 0, SEEK_END); u32 len = (u32)ftell(f); @@ -845,6 +846,11 @@ bool LoadROM(const char* path, bool direct) fclose(f); //CartROM = f; + // generate a ROM ID + // note: most games don't check the actual value + // it just has to stay the same throughout gameplay + CartID = 0x00001FC2; + if (direct) { NDS::SetupDirectBoot(); @@ -853,11 +859,6 @@ bool LoadROM(const char* path, bool direct) CartInserted = true; - // generate a ROM ID - // note: most games don't check the actual value - // it just has to stay the same throughout gameplay - CartID = 0x00001FC2; - u32 arm9base = *(u32*)&CartROM[0x20]; if (arm9base < 0x8000) { diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 7c6508c..6797139 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -400,6 +400,27 @@ void Stop(bool internal) uiAreaQueueRedrawAll(MainDrawArea); } +void TryLoadROM(char* file, int prevstatus) +{ + char oldpath[1024]; + strncpy(oldpath, ROMPath, 1024); + + strncpy(ROMPath, file, 1023); + ROMPath[1023] = '\0'; + + if (NDS::LoadROM(ROMPath, Config::DirectBoot)) + Run(); + 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); + EmuRunning = prevstatus; + } +} + int OnCloseWindow(uiWindow* window, void* blarg) { @@ -410,6 +431,7 @@ int OnCloseWindow(uiWindow* window, void* blarg) void OnDropFile(uiWindow* window, char* file, void* blarg) { char* ext = &file[strlen(file)-3]; + int prevstatus = EmuRunning; if (!strcasecmp(ext, "nds") || !strcasecmp(ext, "srl")) { @@ -419,11 +441,7 @@ void OnDropFile(uiWindow* window, char* file, void* blarg) while (EmuStatus != 2); } - strncpy(ROMPath, file, 1023); - ROMPath[1023] = '\0'; - - NDS::LoadROM(ROMPath, Config::DirectBoot); - Run(); + TryLoadROM(file, prevstatus); } } @@ -456,14 +474,8 @@ void OnOpenFile(uiMenuItem* item, uiWindow* window, void* blarg) return; } - strncpy(ROMPath, file, 1023); - ROMPath[1023] = '\0'; + TryLoadROM(file, prevstatus); uiFreeText(file); - // TODO: change libui to store strings in stack-allocated buffers? - // so we don't have to free it after use - - NDS::LoadROM(ROMPath, Config::DirectBoot); - Run(); } void OnRun(uiMenuItem* item, uiWindow* window, void* blarg) @@ -689,8 +701,8 @@ int main(int argc, char** argv) strncpy(ROMPath, file, 1023); ROMPath[1023] = '\0'; - NDS::LoadROM(ROMPath, Config::DirectBoot); - Run(); + if (NDS::LoadROM(ROMPath, Config::DirectBoot)) + Run(); } } diff --git a/src/melon_fopen.h b/src/melon_fopen.h new file mode 100644 index 0000000..603e15f --- /dev/null +++ b/src/melon_fopen.h @@ -0,0 +1,52 @@ +/* + Copyright 2016-2017 StapleButter + + 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 MELON_FOPEN_H +#define MELON_FOPEN_H + +#ifdef __WIN32__ + +#include <windows.h> + +static FILE* melon_fopen(const char* path, const char* mode) +{ + int len = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); + if (len < 1) return NULL; + WCHAR* fatass = new WCHAR[len]; + int res = MultiByteToWideChar(CP_UTF8, 0, path, -1, fatass, len); + if (res != len) return NULL; // checkme? + + // this will be more than enough + WCHAR fatmode[4]; + fatmode[0] = mode[0]; + fatmode[1] = mode[1]; + fatmode[2] = mode[2]; + fatmode[3] = 0; + + FILE* ret = _wfopen(fatass, fatmode); + delete[] fatass; + return ret; +} + +#else + +#define melon_fopen fopen + +#endif + +#endif // MELON_FOPEN_H |