diff --git a/apu/apu.cpp b/apu/apu.cpp index 86af9c65..9702f58d 100644 --- a/apu/apu.cpp +++ b/apu/apu.cpp @@ -249,7 +249,7 @@ void S9xDumpSPCSnapshot(void) static void SPCSnapshotCallback(void) { - S9xSPCDump(S9xGetFilenameInc((".spc"), SPC_DIR)); + S9xSPCDump(S9xGetFilenameInc((".spc"), SPC_DIR).c_str()); printf("Dumped key-on triggered spc snapshot.\n"); } diff --git a/bsx.cpp b/bsx.cpp index 2881dbed..12cbc3c7 100644 --- a/bsx.cpp +++ b/bsx.cpp @@ -738,13 +738,11 @@ void S9xBSXSetStream1 (uint8 count) if (BSX.sat_stream1.is_open()) BSX.sat_stream1.close(); //If Stream already opened for one file: Close it. - char path[PATH_MAX + 1], name[PATH_MAX + 1]; + std::string path = S9xGetDirectory(SAT_DIR) + SLASH_STR; - strcpy(path, S9xGetDirectory(SAT_DIR)); - strcat(path, SLASH_STR); - - snprintf(name, PATH_MAX + 1, "BSX%04X-%d.bin", (BSX.PPU[0x2188 - BSXPPUBASE] | (BSX.PPU[0x2189 - BSXPPUBASE] * 256)), count); //BSXHHHH-DDD.bin - strcat(path, name); + char name[PATH_MAX]; + snprintf(name, PATH_MAX, "BSX%04X-%d.bin", (BSX.PPU[0x2188 - BSXPPUBASE] | (BSX.PPU[0x2189 - BSXPPUBASE] * 256)), count); //BSXHHHH-DDD.bin + path += name; BSX.sat_stream1.clear(); BSX.sat_stream1.open(path, std::ios::in | std::ios::binary); @@ -770,13 +768,12 @@ void S9xBSXSetStream2 (uint8 count) if (BSX.sat_stream2.is_open()) BSX.sat_stream2.close(); //If Stream already opened for one file: Close it. - char path[PATH_MAX + 1], name[PATH_MAX + 1]; - strcpy(path, S9xGetDirectory(SAT_DIR)); - strcat(path, SLASH_STR); + std::string path = S9xGetDirectory(SAT_DIR) + SLASH_STR; - snprintf(name, PATH_MAX + 1, "BSX%04X-%d.bin", (BSX.PPU[0x218E - BSXPPUBASE] | (BSX.PPU[0x218F - BSXPPUBASE] * 256)), count); //BSXHHHH-DDD.bin - strcat(path, name); + char name[PATH_MAX]; + snprintf(name, PATH_MAX, "BSX%04X-%d.bin", (BSX.PPU[0x218E - BSXPPUBASE] | (BSX.PPU[0x218F - BSXPPUBASE] * 256)), count); //BSXHHHH-DDD.bin + path += name; BSX.sat_stream2.clear(); BSX.sat_stream2.open(path, std::ios::in | std::ios::binary); @@ -1207,20 +1204,15 @@ uint8 * S9xGetBasePointerBSX (uint32 address) static bool8 BSX_LoadBIOS (void) { FILE *fp; - char path[PATH_MAX + 1], name[PATH_MAX + 1]; bool8 r = FALSE; - strcpy(path, S9xGetDirectory(BIOS_DIR)); - strcat(path, SLASH_STR); - strcpy(name, path); - strcat(name, "BS-X.bin"); + std::string name = S9xGetDirectory(BIOS_DIR) + SLASH_STR + "BS-X.bin"; - fp = fopen(name, "rb"); + fp = fopen(name.c_str(), "rb"); if (!fp) { - strcpy(name, path); - strcat(name, "BS-X.bios"); - fp = fopen(name, "rb"); + name = S9xGetDirectory(BIOS_DIR) + SLASH_STR + "BS-X.bios"; + fp = fopen(name.c_str(), "rb"); } if (fp) @@ -1255,7 +1247,7 @@ void S9xInitBSX (void) { Settings.BS = FALSE; - if (is_BSX_BIOS(Memory.ROM,Memory.CalculatedSize)) + if (is_BSX_BIOS(Memory.ROM,Memory.CalculatedSize)) { // BS-X itself diff --git a/compat.cpp b/compat.cpp deleted file mode 100644 index e03d3d83..00000000 --- a/compat.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include "port.h" - -void _splitpath(const char *path, char *drive, char *dir, char *fname, char *ext) -{ - char *slash = strrchr((char *)path, SLASH_CHAR); - char *dot = strrchr((char *)path, '.'); - - *drive = '\0'; - - if (dot && slash && dot < slash) - { - dot = 0; - } - - if (!slash) - { - *dir = '\0'; - strcpy(fname, path); - - if (dot) - { - fname[dot - path] = '\0'; - strcpy(ext, dot + 1); - } - else - { - *ext = '\0'; - } - } - else - { - strcpy(dir, path); - dir[slash - path] = '\0'; - strcpy(fname, slash + 1); - - if (dot) - { - fname[(dot - slash) - 1] = '\0'; - strcpy(ext, dot + 1); - } - else - { - *ext = '\0'; - } - } -} - -void _makepath(char *path, const char *drive, const char *dir, const char *fname, const char *ext) -{ - if (dir && *dir) - { - strcpy(path, dir); - strcat(path, "/"); - } - else - *path = '\0'; - - strcat(path, fname); - - if (ext && *ext) - { - if (*ext != '.') - strcat(path, "."); - strcat(path, ext); - } -} diff --git a/controls.cpp b/controls.cpp index 85dd4cc6..878c809f 100644 --- a/controls.cpp +++ b/controls.cpp @@ -2259,11 +2259,11 @@ void S9xApplyCommand (s9xcommand_t cmd, int16 data1, int16 data2) case LoadOopsFile: { - const char *filename = S9xGetFilename("oops", SNAPSHOT_DIR); + std::string filename = S9xGetFilename("oops", SNAPSHOT_DIR); - if (S9xUnfreezeGame(filename)) + if (S9xUnfreezeGame(filename.c_str())) { - snprintf(buf, 256, "%.240s.oops loaded", S9xBasename(Memory.ROMFilename)); + snprintf(buf, 256, "%.240s.oops loaded", S9xBasename(Memory.ROMFilename).c_str()); S9xSetInfoString(buf); } else @@ -2292,15 +2292,15 @@ void S9xApplyCommand (s9xcommand_t cmd, int16 data1, int16 data2) case QuickLoad009: case QuickLoad010: { - char filename[PATH_MAX + 1]; - char drive[_MAX_DRIVE + 1], dir[_MAX_DIR + 1], def[_MAX_FNAME + 1], ext[_MAX_EXT + 1]; + std::string ext = std::to_string(i - QuickLoad000); + while (ext.length() < 3) + ext = '0' + ext; - _splitpath(Memory.ROMFilename, drive, dir, def, ext); - snprintf(filename, PATH_MAX + 1, "%.2s%.512s%.512s.%03d", S9xGetDirectory(SNAPSHOT_DIR), SLASH_STR, def, i - QuickLoad000); + auto filename = S9xGetFilename(ext, SNAPSHOT_DIR); - if (S9xUnfreezeGame(filename)) + if (S9xUnfreezeGame(filename.c_str())) { - snprintf(buf, 256, "%.240s.%03d loaded", def, i - QuickLoad000); + snprintf(buf, 256, "Quick save-state %s loaded", ext.c_str()); S9xSetInfoString(buf); } else @@ -2321,16 +2321,16 @@ void S9xApplyCommand (s9xcommand_t cmd, int16 data1, int16 data2) case QuickSave009: case QuickSave010: { - char filename[PATH_MAX + 1]; - char drive[_MAX_DRIVE + 1], dir[_MAX_DIR + 1], def[_MAX_FNAME + 1], ext[_MAX_EXT + 1]; + std::string ext = std::to_string(i - QuickLoad000); + while (ext.length() < 3) + ext = '0' + ext; - _splitpath(Memory.ROMFilename, drive, dir, def, ext); - snprintf(filename, PATH_MAX + 1, "%.2s%.512s%.512s.%03d", S9xGetDirectory(SNAPSHOT_DIR), SLASH_STR, def, i - QuickSave000); + auto filename = S9xGetFilename(ext, SNAPSHOT_DIR); - snprintf(buf, 256, "%.240s.%03d saved", def, i - QuickSave000); + snprintf(buf, 256, "Quick save-state %s saved", ext.c_str()); S9xSetInfoString(buf); - S9xFreezeGame(filename); + S9xFreezeGame(filename.c_str()); break; } diff --git a/display.h b/display.h index a2f12670..3a47f04f 100644 --- a/display.h +++ b/display.h @@ -44,10 +44,10 @@ void S9xToggleSoundChannel (int); bool8 S9xOpenSnapshotFile (const char *, bool8, STREAM *); void S9xCloseSnapshotFile (STREAM); const char * S9xStringInput (const char *); -const char * S9xGetDirectory (enum s9x_getdirtype); -const char * S9xGetFilename (const char *, enum s9x_getdirtype); -const char * S9xGetFilenameInc (const char *, enum s9x_getdirtype); -const char * S9xBasename (const char *); +std::string S9xGetDirectory (enum s9x_getdirtype); +std::string S9xGetFilename (std::string, enum s9x_getdirtype); +std::string S9xGetFilenameInc (std::string, enum s9x_getdirtype); +std::string S9xBasename (std::string); // Routines the port has to implement if it uses command-line diff --git a/fscompat.cpp b/fscompat.cpp new file mode 100644 index 00000000..fc6175dc --- /dev/null +++ b/fscompat.cpp @@ -0,0 +1,191 @@ +#include +#include "port.h" +#include +#include + +using std::string; + +bool SplitPath::ext_is(const string &other) +{ + if (strcasecmp(ext.c_str(), other.c_str()) == 0) + return true; + if (other[0] != '.' && (strcasecmp(other.c_str(), &(ext.c_str()[1])) == 0)) + return true; + return false; +} + +std::string makepath(const SplitPath &path) +{ + return makepath(path.drive, path.dir, path.stem, path.ext); +} + +#if __cplusplus >= 201703L +#include +namespace fs = std::filesystem; + +SplitPath splitpath(string str) +{ + SplitPath output{}; + fs::path path(str); + + if (path.has_root_name()) + output.drive = path.root_name(); + + if (path.has_filename()) + { + output.stem = path.stem(); + output.ext = path.extension(); + path.remove_filename(); + } + + if (!path.empty()) + output.dir = path; + + return output; +} + +string makepath(const string &drive, const string &dir, const string &stem, const string &ext) +{ + fs::path path(drive); + path = path / dir / stem; + path.replace_extension(ext); + return path.string(); +} + +#else +constexpr auto npos = std::string::npos; + +SplitPath splitpath(string path) +{ + SplitPath output{}; + +#ifdef _WIN32 + if (path.length() > 2 && path[1] == ':') + { + output.drive = path.substr(0, 2); + path = path.substr(2); + } +#endif + auto slash = path.rfind(SLASH_CHAR); + auto dot = path.rfind('.'); + + if (dot != npos && slash != npos && dot < slash) + { + dot = npos; + } + else if (dot != npos) + { + output.ext = path.substr(dot); + } + + if (slash != npos) + { + output.dir = path.substr(0, slash + 1); + output.stem = path.substr(slash + 1, dot - slash - 1); + } + else + { + output.stem = path.substr(0, dot); + } + + return output; +} + +string makepath(string drive, string dir, string stem, string ext) +{ + string output; + + if (!drive.empty()) + { + output += drive + ":"; + if (!dir.empty() && dir[0] != SLASH_CHAR) + output += SLASH_CHAR; + } + + if (!dir.empty()) + { + output += dir; + if (output[output.length() - 1] != SLASH_CHAR) + output += SLASH_CHAR; + } + + if (!stem.empty()) + { + output += stem; + } + + if (!ext.empty()) + { + if (ext[0] != '.') + output += '.'; + output += ext; + } + + return output; +} + +void _splitpath(const char *path, char *drive, char *dir, char *fname, char *ext) +{ + char *slash = strrchr((char *)path, SLASH_CHAR); + char *dot = strrchr((char *)path, '.'); + + *drive = '\0'; + + if (dot && slash && dot < slash) + { + dot = 0; + } + + if (!slash) + { + *dir = '\0'; + strcpy(fname, path); + + if (dot) + { + fname[dot - path] = '\0'; + strcpy(ext, dot + 1); + } + else + { + *ext = '\0'; + } + } + else + { + strcpy(dir, path); + dir[slash - path] = '\0'; + strcpy(fname, slash + 1); + + if (dot) + { + fname[(dot - slash) - 1] = '\0'; + strcpy(ext, dot + 1); + } + else + { + *ext = '\0'; + } + } +} + +void _makepath(char *path, const char *drive, const char *dir, const char *fname, const char *ext) +{ + if (dir && *dir) + { + strcpy(path, dir); + strcat(path, "/"); + } + else + *path = '\0'; + + strcat(path, fname); + + if (ext && *ext) + { + if (*ext != '.') + strcat(path, "."); + strcat(path, ext); + } +} +#endif \ No newline at end of file diff --git a/gfx.cpp b/gfx.cpp index 37e56c70..1e26db44 100644 --- a/gfx.cpp +++ b/gfx.cpp @@ -195,7 +195,7 @@ void S9xStartScreenRefresh (void) } if (GFX.InfoStringTimeout > 0 && --GFX.InfoStringTimeout == 0) - GFX.InfoString = NULL; + GFX.InfoString.clear(); IPPU.TotalEmulatedFrames++; } @@ -1739,12 +1739,9 @@ void S9xReRefresh (void) void S9xSetInfoString (const char *string) { - static std::string info_string; - if (Settings.InitialInfoStringTimeout > 0) { - info_string = string; - GFX.InfoString = info_string.c_str(); + GFX.InfoString = string; GFX.InfoStringTimeout = Settings.InitialInfoStringTimeout; S9xReRefresh(); } @@ -2042,8 +2039,8 @@ void S9xDisplayMessages (uint16 *screen, int ppl, int width, int height, int sca if (Settings.DisplayMovieFrame && S9xMovieActive()) S9xDisplayString(GFX.FrameDisplayString, 1, 1, false); - if (GFX.InfoString && *GFX.InfoString) - S9xDisplayString(GFX.InfoString, 5, 1, true); + if (!GFX.InfoString.empty()) + S9xDisplayString(GFX.InfoString.c_str(), 5, 1, true); } static uint16 get_crosshair_color (uint8 color) diff --git a/gfx.h b/gfx.h index ad232692..a1f4e1a2 100644 --- a/gfx.h +++ b/gfx.h @@ -66,7 +66,7 @@ struct SGFX void (*DrawMode7BG2Math) (uint32, uint32, int); void (*DrawMode7BG2Nomath) (uint32, uint32, int); - const char *InfoString; + std::string InfoString; uint32 InfoStringTimeout; char FrameDisplayString[256]; diff --git a/gtk/CMakeLists.txt b/gtk/CMakeLists.txt index 87e470d2..6d1bcf18 100644 --- a/gtk/CMakeLists.txt +++ b/gtk/CMakeLists.txt @@ -25,6 +25,7 @@ string(APPEND LOCALEDIR ${CMAKE_INSTALL_PREFIX} "/" ${CMAKE_INSTALL_DATAROOTDIR} add_compile_definitions(HAVE_LIBPNG ZLIB SNES9X_GTK NETPLAY_SUPPORT + JMA_SUPPORT UNZIP_SUPPORT HAVE_MKSTEMP HAVE_STRINGS_H @@ -270,7 +271,7 @@ list(APPEND SOURCES ../netplay.cpp ../server.cpp ../loadzip.cpp - ../compat.cpp + ../fscompat.cpp src/gtk_netplay_dialog.cpp src/gtk_netplay_dialog.h src/gtk_netplay.cpp @@ -295,6 +296,7 @@ set(LIBJMA_SOURCES add_library(jma ${LIBJMA_SOURCES}) target_include_directories(jma PRIVATE ${INCLUDES}) target_compile_options(jma PUBLIC ${ARGS}) +list(APPEND LIBS jma) add_executable(sourcify src/sourcify.c) diff --git a/gtk/meson.build b/gtk/meson.build index a5a4bace..1a811b23 100644 --- a/gtk/meson.build +++ b/gtk/meson.build @@ -328,7 +328,7 @@ srcs += [ '../netplay.cpp', '../server.cpp', '../loadzip.cpp', - '../compat.cpp', + '../fscompat.cpp', 'src/gtk_netplay_dialog.cpp', 'src/gtk_netplay_dialog.h', 'src/gtk_netplay.cpp', diff --git a/gtk/src/gtk_file.cpp b/gtk/src/gtk_file.cpp index e5ff062a..94c8a17d 100644 --- a/gtk/src/gtk_file.cpp +++ b/gtk/src/gtk_file.cpp @@ -19,12 +19,7 @@ namespace fs = std::filesystem; using namespace std::literals; -// TODO: -// Snes9x core requires persistent memory for const char * returns, but won't -// manage them. This is used to hold the data. Functions here are Non-reentrant. -static std::string filename_common; - -const char *S9xGetFilenameInc(const char *e, enum s9x_getdirtype dirtype) +std::string S9xGetFilenameInc(std::string e, enum s9x_getdirtype dirtype) { fs::path rom_filename(Memory.ROMFilename); @@ -33,13 +28,15 @@ const char *S9xGetFilenameInc(const char *e, enum s9x_getdirtype dirtype) fs::path new_filename; + if (e[0] != '.') + e = "." + e; int i = 0; do { std::string new_extension = std::to_string(i); while (new_extension.length() < 3) new_extension = "0"s + new_extension; - new_extension += "."s + e; + new_extension += e; new_filename = filename_base; new_filename.replace_extension(new_extension); @@ -47,11 +44,10 @@ const char *S9xGetFilenameInc(const char *e, enum s9x_getdirtype dirtype) i++; } while (fs::exists(new_filename)); - filename_common = new_filename; - return filename_common.c_str(); + return new_filename; } -const char *S9xGetDirectory(enum s9x_getdirtype dirtype) +std::string S9xGetDirectory(enum s9x_getdirtype dirtype) { std::string dirname; @@ -102,7 +98,7 @@ const char *S9xGetDirectory(enum s9x_getdirtype dirtype) } /* Anything else, use ROM filename path */ - if (dirname == "" && gui_config && !gui_config->rom_loaded) + if (dirname == "" && gui_config && gui_config->rom_loaded) { fs::path path(Memory.ROMFilename); @@ -114,33 +110,25 @@ const char *S9xGetDirectory(enum s9x_getdirtype dirtype) dirname = path; } - filename_common = dirname; - return filename_common.c_str(); + return dirname; } -const char *S9xGetFilename(const char *ex, enum s9x_getdirtype dirtype) +std::string S9xGetFilename(std::string ex, enum s9x_getdirtype dirtype) { fs::path path(S9xGetDirectory(dirtype)); path /= fs::path(Memory.ROMFilename).filename(); path.replace_extension(ex); - filename_common = path.string(); - return filename_common.c_str(); + return path.string(); } -const char *S9xBasename(const char *f) +std::string S9xBasename(std::string filename) { - const char *p; - - if ((p = strrchr(f, '/')) != NULL || (p = strrchr(f, '\\')) != NULL) - return (p + 1); - - return f; + return fs::path(filename).filename().string(); } -const char *S9xBasenameNoExt(const char *f) +std::string S9xBasenameNoExt(std::string f) { - filename_common = fs::path(f).stem(); - return filename_common.c_str(); + return fs::path(f).stem(); } bool8 S9xOpenSnapshotFile(const char *filename, bool8 read_only, STREAM *file) @@ -176,35 +164,35 @@ void S9xCloseSnapshotFile(STREAM file) void S9xAutoSaveSRAM() { - Memory.SaveSRAM(S9xGetFilename(".srm", SRAM_DIR)); - S9xSaveCheatFile(S9xGetFilename(".cht", CHEAT_DIR)); + Memory.SaveSRAM(S9xGetFilename(".srm", SRAM_DIR).c_str()); + S9xSaveCheatFile(S9xGetFilename(".cht", CHEAT_DIR).c_str()); } -void S9xLoadState(const char *filename) +void S9xLoadState(std::string filename) { - S9xFreezeGame(S9xGetFilename(".undo", SNAPSHOT_DIR)); + S9xFreezeGame(S9xGetFilename(".undo", SNAPSHOT_DIR).c_str()); - if (S9xUnfreezeGame(filename)) + if (S9xUnfreezeGame(filename.c_str())) { auto info_string = filename + " loaded"s; S9xSetInfoString(info_string.c_str()); } else { - fprintf(stderr, "Failed to load state file: %s\n", filename); + fprintf(stderr, "Failed to load state file: %s\n", filename.c_str()); } } -void S9xSaveState(const char *filename) +void S9xSaveState(std::string filename) { - if (S9xFreezeGame(filename)) + if (S9xFreezeGame(filename.c_str())) { auto info_string = filename + " saved"s; S9xSetInfoString(info_string.c_str()); } else { - fprintf(stderr, "Couldn't save state file: %s\n", filename); + fprintf(stderr, "Couldn't save state file: %s\n", filename.c_str()); } } @@ -226,7 +214,6 @@ void S9xQuickSaveSlot(int slot) return; auto filename = save_slot_path(slot); - if (S9xFreezeGame(filename.c_str())) { auto info_string = filename.filename().string() + " saved"; @@ -242,7 +229,7 @@ void S9xQuickLoadSlot(int slot) auto filename = save_slot_path(slot); if (fs::exists(filename)) - S9xFreezeGame(S9xGetFilename(".undo", SNAPSHOT_DIR)); + S9xFreezeGame(S9xGetFilename(".undo", SNAPSHOT_DIR).c_str()); if (S9xUnfreezeGame(filename.c_str())) { diff --git a/gtk/src/gtk_file.h b/gtk/src/gtk_file.h index 4ee91408..323329c2 100644 --- a/gtk/src/gtk_file.h +++ b/gtk/src/gtk_file.h @@ -6,11 +6,12 @@ #ifndef __GTK_FILE_H #define __GTK_FILE_H +#include -const char *S9xBasenameNoExt(const char *); +std::string S9xBasenameNoExt(std::string); -void S9xLoadState(const char *filename); -void S9xSaveState(const char *filename); +void S9xLoadState(std::string); +void S9xSaveState(std::string); void S9xQuickSaveSlot(int slot); void S9xQuickLoadSlot(int slot); diff --git a/gtk/src/gtk_s9x.cpp b/gtk/src/gtk_s9x.cpp index 847f0a4c..18cb5d78 100644 --- a/gtk/src/gtk_s9x.cpp +++ b/gtk/src/gtk_s9x.cpp @@ -177,7 +177,7 @@ int S9xOpenROM(const char *rom_filename) if (loaded) { - Memory.LoadSRAM(S9xGetFilename(".srm", SRAM_DIR)); + Memory.LoadSRAM(S9xGetFilename(".srm", SRAM_DIR).c_str()); } else { diff --git a/gtk/src/gtk_s9xwindow.cpp b/gtk/src/gtk_s9xwindow.cpp index 0b475f74..15c8d88d 100644 --- a/gtk/src/gtk_s9xwindow.cpp +++ b/gtk/src/gtk_s9xwindow.cpp @@ -203,7 +203,7 @@ void Snes9xWindow::connect_signals() }); get_object("load_state_undo")->signal_activate().connect([&] { - S9xUnfreezeGame(S9xGetFilename(".undo", SNAPSHOT_DIR)); + S9xUnfreezeGame(S9xGetFilename(".undo", SNAPSHOT_DIR).c_str()); }); get_object("save_spc_item")->signal_activate().connect([&] { @@ -650,7 +650,7 @@ std::string Snes9xWindow::open_movie_dialog(bool readonly) if (!readonly) { - const char *default_name = S9xGetFilename(".smv", s9x_getdirtype::ROM_DIR); + auto default_name = S9xGetFilename(".smv", s9x_getdirtype::ROM_DIR); dialog.set_current_name(default_name); } @@ -774,7 +774,7 @@ void Snes9xWindow::load_state_dialog() dialog.hide(); if (result == Gtk::RESPONSE_ACCEPT) { - S9xLoadState(dialog.get_filename().c_str()); + S9xLoadState(dialog.get_filename()); } unpause_from_focus_change(); @@ -836,7 +836,7 @@ void Snes9xWindow::save_state_dialog() dialog.hide(); if (result == GTK_RESPONSE_ACCEPT) - S9xSaveState(dialog.get_filename().c_str()); + S9xSaveState(dialog.get_filename()); unpause_from_focus_change(); } diff --git a/memmap.cpp b/memmap.cpp index 655ebc4f..da0eb090 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -1251,27 +1251,15 @@ uint32 CMemory::FileLoader (uint8 *buffer, const char *filename, uint32 maxsize) // ** Memory.ROMFilename uint32 totalSize = 0; - char fname[PATH_MAX + 1]; - char drive[_MAX_DRIVE + 1], dir[_MAX_DIR + 1], name[_MAX_FNAME + 1], exts[_MAX_EXT + 1]; - char *ext; - -#if defined(__WIN32__) || defined(__MACOSX__) - ext = &exts[1]; -#else - ext = &exts[0]; -#endif - memset(NSRTHeader, 0, sizeof(NSRTHeader)); HeaderCount = 0; - _splitpath(filename, drive, dir, name, exts); - _makepath(fname, drive, dir, name, exts); + auto path = splitpath(filename); int nFormat = FILE_DEFAULT; - if (strcasecmp(ext, "zip") == 0 || strcasecmp(ext, "msu1") == 0) + if (path.ext_is(".zip") || path.ext_is(".msu1")) nFormat = FILE_ZIP; - else - if (strcasecmp(ext, "jma") == 0) + else if (path.ext_is(".jma")) nFormat = FILE_JMA; switch (nFormat) @@ -1279,13 +1267,13 @@ uint32 CMemory::FileLoader (uint8 *buffer, const char *filename, uint32 maxsize) case FILE_ZIP: { #ifdef UNZIP_SUPPORT - if (!LoadZip(fname, &totalSize, buffer)) + if (!LoadZip(filename, &totalSize, buffer)) { S9xMessage(S9X_ERROR, S9X_ROM_INFO, "Invalid Zip archive."); return (0); } - strcpy(ROMFilename, fname); + strcpy(ROMFilename, filename); #else S9xMessage(S9X_ERROR, S9X_ROM_INFO, "This binary was not created with Zip support."); return (0); @@ -1296,7 +1284,7 @@ uint32 CMemory::FileLoader (uint8 *buffer, const char *filename, uint32 maxsize) case FILE_JMA: { #ifdef JMA_SUPPORT - size_t size = load_jma_file(fname, buffer); + size_t size = load_jma_file(filename, buffer); if (!size) { S9xMessage(S9X_ERROR, S9X_ROM_INFO, "Invalid JMA archive."); @@ -1305,7 +1293,7 @@ uint32 CMemory::FileLoader (uint8 *buffer, const char *filename, uint32 maxsize) totalSize = HeaderRemove(size, buffer); - strcpy(ROMFilename, fname); + strcpy(ROMFilename, filename); #else S9xMessage(S9X_ERROR, S9X_ROM_INFO, "This binary was not created with JMA support."); return (0); @@ -1316,58 +1304,26 @@ uint32 CMemory::FileLoader (uint8 *buffer, const char *filename, uint32 maxsize) case FILE_DEFAULT: default: { - STREAM fp = OPEN_STREAM(fname, "rb"); + STREAM fp = OPEN_STREAM(filename, "rb"); if (!fp) return (0); - strcpy(ROMFilename, fname); + strcpy(ROMFilename, filename); - int len = 0; uint32 size = 0; - bool8 more = FALSE; - uint8 *ptr = buffer; - do - { - size = READ_STREAM(ptr, maxsize + 0x200 - (ptr - buffer), fp); - CLOSE_STREAM(fp); + size = READ_STREAM(buffer, maxsize + 0x200, fp); + CLOSE_STREAM(fp); - size = HeaderRemove(size, ptr); - totalSize += size; - ptr += size; - - // check for multi file roms - if (ptr - buffer < maxsize + 0x200 && - (isdigit(ext[0]) && ext[1] == 0 && ext[0] < '9')) - { - more = TRUE; - ext[0]++; - _makepath(fname, drive, dir, name, exts); - } - else - if (ptr - buffer < maxsize + 0x200 && - (((len = strlen(name)) == 7 || len == 8) && - strncasecmp(name, "sf", 2) == 0 && - isdigit(name[2]) && isdigit(name[3]) && isdigit(name[4]) && isdigit(name[5]) && - isalpha(name[len - 1]))) - { - more = TRUE; - name[len - 1]++; - _makepath(fname, drive, dir, name, exts); - } - else - more = FALSE; - - } while (more && (fp = OPEN_STREAM(fname, "rb")) != NULL); + totalSize = HeaderRemove(size, buffer); break; } } - if (HeaderCount == 0) + if (HeaderCount == 0) S9xMessage(S9X_INFO, S9X_HEADERS_INFO, "No ROM file header found."); - else - if (HeaderCount == 1) + else if (HeaderCount == 1) S9xMessage(S9X_INFO, S9X_HEADERS_INFO, "Found ROM file header (and ignored it)."); else S9xMessage(S9X_INFO, S9X_HEADERS_INFO, "Found multiple ROM file headers (and ignored them)."); @@ -1571,16 +1527,14 @@ bool8 CMemory::LoadROMInt (int32 ROMfillSize) LoROM = FALSE; HiROM = TRUE; } - else - if (Settings.ForceInterleaveGD24 && CalculatedSize == 0x300000) + else if (Settings.ForceInterleaveGD24 && CalculatedSize == 0x300000) { bool8 t = LoROM; LoROM = HiROM; HiROM = t; S9xDeinterleaveGD24(CalculatedSize, ROM); } - else - if (Settings.ForceInterleaved2) + else if (Settings.ForceInterleaved2) S9xDeinterleaveType2(CalculatedSize, ROM); else { @@ -1633,7 +1587,7 @@ bool8 CMemory::LoadROMInt (int32 ROMfillSize) S9xReset(); S9xDeleteCheats(); - S9xLoadCheatFile(S9xGetFilename(".cht", CHEAT_DIR)); + S9xLoadCheatFile(S9xGetFilename(".cht", CHEAT_DIR).c_str()); return (TRUE); } @@ -1716,7 +1670,7 @@ bool8 CMemory::LoadMultiCartInt () if (Multi.cartSizeA) { - if (is_SufamiTurbo_Cart(ROM + Multi.cartOffsetA, Multi.cartSizeA)) + if (is_SufamiTurbo_Cart(ROM + Multi.cartOffsetA, Multi.cartSizeA)) Multi.cartType = 4; else if (is_BSCartSA1_BIOS(ROM + Multi.cartOffsetA, Multi.cartSizeA)) @@ -1744,13 +1698,9 @@ bool8 CMemory::LoadMultiCartInt () FILE *fp; size_t size; - char path[PATH_MAX + 1]; + std::string path = S9xGetDirectory(BIOS_DIR) + SLASH_STR + "STBIOS.bin"; - strcpy(path, S9xGetDirectory(BIOS_DIR)); - strcat(path, SLASH_STR); - strcat(path, "STBIOS.bin"); - - fp = fopen(path, "rb"); + fp = fopen(path.c_str(), "rb"); if (fp) { size = fread((void *) ROM, 1, 0x40000, fp); @@ -1761,7 +1711,7 @@ bool8 CMemory::LoadMultiCartInt () else return (FALSE); - strcpy(ROMFilename, path); + strcpy(ROMFilename, path.c_str()); } switch (Multi.cartType) @@ -1785,10 +1735,9 @@ bool8 CMemory::LoadMultiCartInt () return (FALSE); } - if (Multi.cartSizeA) + if (Multi.cartSizeA) strcpy(ROMFilename, Multi.fileNameA); - else - if (Multi.cartSizeB) + else if (Multi.cartSizeB) strcpy(ROMFilename, Multi.fileNameB); memset(&SNESGameFixes, 0, sizeof(SNESGameFixes)); @@ -1799,7 +1748,7 @@ bool8 CMemory::LoadMultiCartInt () S9xReset(); S9xDeleteCheats(); - S9xLoadCheatFile(S9xGetFilename(".cht", CHEAT_DIR)); + S9xLoadCheatFile(S9xGetFilename(".cht", CHEAT_DIR).c_str()); return (TRUE); } @@ -1889,7 +1838,7 @@ bool8 CMemory::LoadSRTC (void) { FILE *fp; - fp = fopen(S9xGetFilename(".rtc", SRAM_DIR), "rb"); + fp = fopen(S9xGetFilename(".rtc", SRAM_DIR).c_str(), "rb"); if (!fp) return (FALSE); @@ -1904,7 +1853,7 @@ bool8 CMemory::SaveSRTC (void) { FILE *fp; - fp = fopen(S9xGetFilename(".rtc", SRAM_DIR), "wb"); + fp = fopen(S9xGetFilename(".rtc", SRAM_DIR).c_str(), "wb"); if (!fp) return (FALSE); @@ -1945,7 +1894,7 @@ bool8 CMemory::LoadSRAM (const char *filename) size = (1 << (Multi.sramSizeB + 3)) * 128; - file = fopen(S9xGetFilename(".srm", SRAM_DIR), "rb"); + file = fopen(S9xGetFilename(".srm", SRAM_DIR).c_str(), "rb"); if (file) { len = fread((char *) Multi.sramB, 1, 0x10000, file); @@ -1978,18 +1927,13 @@ bool8 CMemory::LoadSRAM (const char *filename) return (TRUE); } - else - if (Settings.BS && !Settings.BSXItself) + else if (Settings.BS && !Settings.BSXItself) { // The BS game's SRAM was not found // Try to read BS-X.srm instead - char path[PATH_MAX + 1]; + std::string path = S9xGetDirectory(SRAM_DIR) + SLASH_STR + "BS-X.srm"; - strcpy(path, S9xGetDirectory(SRAM_DIR)); - strcat(path, SLASH_STR); - strcat(path, "BS-X.srm"); - - file = fopen(path, "rb"); + file = fopen(path.c_str(), "rb"); if (file) { len = fread((char *) SRAM, 1, size, file); @@ -2033,7 +1977,7 @@ bool8 CMemory::SaveSRAM (const char *filename) strcpy(temp, ROMFilename); strcpy(ROMFilename, Multi.fileNameB); - strcpy(name, S9xGetFilename(".srm", SRAM_DIR)); + strcpy(name, S9xGetFilename(".srm", SRAM_DIR).c_str()); size = (1 << (Multi.sramSizeB + 3)) * 128; @@ -2280,13 +2224,11 @@ void CMemory::InitROM (void) else Settings.DSP = 1; // DSP1 } - else - if (ROMType == 0x05) + else if (ROMType == 0x05) { if (ROMSpeed == 0x20) Settings.DSP = 2; // DSP2 - else - if (ROMSpeed == 0x30 && RomHeader[0x2a] == 0xb2) + else if (ROMSpeed == 0x30 && RomHeader[0x2a] == 0xb2) Settings.DSP = 3; // DSP3 else Settings.DSP = 1; // DSP1 @@ -2300,8 +2242,7 @@ void CMemory::InitROM (void) DSP0.boundary = 0x7000; DSP0.maptype = M_DSP1_HIROM; } - else - if (CalculatedSize > 0x100000) + else if (CalculatedSize > 0x100000) { DSP0.boundary = 0x4000; DSP0.maptype = M_DSP1_LOROM_L; @@ -2440,65 +2381,53 @@ void CMemory::InitROM (void) CalculatedChecksum = 0; if (HiROM) - { + { if (Settings.BS) /* Do nothing */; - else - if (Settings.SPC7110) + else if (Settings.SPC7110) Map_SPC7110HiROMMap(); - else - if (ExtendedFormat != NOPE) + else if (ExtendedFormat != NOPE) Map_ExtendedHiROMMap(); - else - if (Multi.cartType == 3) + else if (Multi.cartType == 3) Map_BSCartHiROMMap(); else Map_HiROMMap(); - } - else - { + } + else + { if (Settings.BS) /* Do nothing */; - else - if (Settings.SETA && Settings.SETA != ST_018) + else if (Settings.SETA && Settings.SETA != ST_018) Map_SetaDSPLoROMMap(); - else - if (Settings.SuperFX) + else if (Settings.SuperFX) Map_SuperFXLoROMMap(); - else - if (Settings.SA1) + else if (Settings.SA1) { if (Multi.cartType == 5) Map_BSSA1LoROMMap(); else Map_SA1LoROMMap(); } - else - if (Settings.SDD1) + else if (Settings.SDD1) Map_SDD1LoROMMap(); - else - if (ExtendedFormat != NOPE) + else if (ExtendedFormat != NOPE) Map_JumboLoROMMap(); else if (strncmp(ROMName, "WANDERERS FROM YS", 17) == 0) Map_NoMAD1LoROMMap(); - else - if (Multi.cartType == 3) + else if (Multi.cartType == 3) if (strncmp(ROMName, "SOUND NOVEL-TCOOL", 17) == 0 || strncmp(ROMName, "DERBY STALLION 96", 17) == 0) Map_BSCartLoROMMap(1); else Map_BSCartLoROMMap(0); - else - if (strncmp(ROMName, "SOUND NOVEL-TCOOL", 17) == 0 || + else if (strncmp(ROMName, "SOUND NOVEL-TCOOL", 17) == 0 || strncmp(ROMName, "DERBY STALLION 96", 17) == 0) Map_ROM24MBSLoROMMap(); - else - if (strncmp(ROMName, "THOROUGHBRED BREEDER3", 21) == 0 || + else if (strncmp(ROMName, "THOROUGHBRED BREEDER3", 21) == 0 || strncmp(ROMName, "RPG-TCOOL 2", 11) == 0) Map_SRAM512KLoROMMap(); - else - if (strncmp(ROMName, "ADD-ON BASE CASSETE", 19) == 0) + else if (strncmp(ROMName, "ADD-ON BASE CASSETE", 19) == 0) { if (Multi.cartType == 4) { @@ -2548,11 +2477,9 @@ void CMemory::InitROM (void) // NTSC/PAL if (Settings.ForceNTSC) Settings.PAL = FALSE; - else - if (Settings.ForcePAL) + else if (Settings.ForcePAL) Settings.PAL = TRUE; - else - if (!Settings.BS && (((ROMRegion >= 2) && (ROMRegion <= 12)) || ROMRegion == 18)) // 18 is used by "Tintin in Tibet (Europe) (En,Es,Sv)" + else if (!Settings.BS && (((ROMRegion >= 2) && (ROMRegion <= 12)) || ROMRegion == 18)) // 18 is used by "Tintin in Tibet (Europe) (En,Es,Sv)" Settings.PAL = TRUE; else Settings.PAL = FALSE; @@ -3394,8 +3321,7 @@ void CMemory::Checksum_Calculate (void) if (Settings.BS && !Settings.BSXItself) sum = checksum_calc_sum(ROM, CalculatedSize) - checksum_calc_sum(ROM + (HiROM ? 0xffb0 : 0x7fb0), 48); - else - if (Settings.SPC7110) + else if (Settings.SPC7110) { sum = checksum_calc_sum(ROM, CalculatedSize); if (CalculatedSize == 0x300000) @@ -3440,8 +3366,7 @@ const char * CMemory::Size (void) if (Multi.cartType == 4) strcpy(str, "N/A"); - else - if (ROMSize < 7 || ROMSize - 7 > 23) + else if (ROMSize < 7 || ROMSize - 7 > 23) strcpy(str, "Corrupt"); else sprintf(str, "%dMbits", 1 << (ROMSize - 7)); @@ -3470,41 +3395,29 @@ const char * CMemory::KartContents (void) if (Settings.BS) strcpy(chip, "+BS"); - else - if (Settings.SuperFX) + else if (Settings.SuperFX) strcpy(chip, "+Super FX"); - else - if (Settings.SDD1) + else if (Settings.SDD1) strcpy(chip, "+S-DD1"); - else - if (Settings.OBC1) + else if (Settings.OBC1) strcpy(chip, "+OBC1"); - else - if (Settings.SA1) + else if (Settings.SA1) strcpy(chip, "+SA-1"); - else - if (Settings.SPC7110RTC) + else if (Settings.SPC7110RTC) strcpy(chip, "+SPC7110+RTC"); - else - if (Settings.SPC7110) + else if (Settings.SPC7110) strcpy(chip, "+SPC7110"); - else - if (Settings.SRTC) + else if (Settings.SRTC) strcpy(chip, "+S-RTC"); - else - if (Settings.C4) + else if (Settings.C4) strcpy(chip, "+C4"); - else - if (Settings.SETA == ST_010) + else if (Settings.SETA == ST_010) strcpy(chip, "+ST-010"); - else - if (Settings.SETA == ST_011) + else if (Settings.SETA == ST_011) strcpy(chip, "+ST-011"); - else - if (Settings.SETA == ST_018) + else if (Settings.SETA == ST_018) strcpy(chip, "+ST-018"); - else - if (Settings.DSP) + else if (Settings.DSP) sprintf(chip, "+DSP-%d", Settings.DSP); else strcpy(chip, ""); @@ -4036,30 +3949,16 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r long offset = header ? 512 : 0; int ret; bool flag; - char dir[_MAX_DIR + 1], drive[_MAX_DRIVE + 1], name[_MAX_FNAME + 1], ext[_MAX_EXT + 1], ips[_MAX_EXT + 3], fname[PATH_MAX + 1]; - const char *n; + char ips[8]; - _splitpath(rom_filename, drive, dir, name, ext); + std::string patch_path = S9xGetDirectory(PATCH_DIR) + SLASH_STR; - // BPS - _makepath(fname, drive, dir, name, "bps"); - - if ((patch_file = OPEN_FSTREAM(fname, "rb")) != NULL) - { - printf("Using BPS patch %s", fname); - - Stream *s = new fStream(patch_file); - ret = ReadBPSPatch(s, 0, rom_size); - s->closeStream(); - - if (ret) - { - printf("!\n"); - return; - } - else - printf(" failed!\n"); - } + int rom_filename_length = strlen(rom_filename); + const char *ext = NULL; + if (rom_filename_length < 4) + return; + if (rom_filename[rom_filename_length - 4] == '.') + ext = &rom_filename[rom_filename_length - 3]; #ifdef UNZIP_SUPPORT if (!strcasecmp(ext, "zip") || !strcasecmp(ext, ".zip")) @@ -4082,57 +3981,8 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r printf(" failed!\n"); } assert(unzClose(file) == UNZ_OK); - } - } -#endif - n = S9xGetFilename(".bps", PATCH_DIR); - - if ((patch_file = OPEN_FSTREAM(n, "rb")) != NULL) - { - printf("Using BPS patch %s", n); - - Stream *s = new fStream(patch_file); - ret = ReadBPSPatch(s, 0, rom_size); - s->closeStream(); - - if (ret) - { - printf("!\n"); - return; - } - else - printf(" failed!\n"); - } - - // UPS - - _makepath(fname, drive, dir, name, "ups"); - - if ((patch_file = OPEN_FSTREAM(fname, "rb")) != NULL) - { - printf("Using UPS patch %s", fname); - - Stream *s = new fStream(patch_file); - ret = ReadUPSPatch(s, 0, rom_size); - s->closeStream(); - - if (ret) - { - printf("!\n"); - return; - } - else - printf(" failed!\n"); - } - -#ifdef UNZIP_SUPPORT - if (!strcasecmp(ext, "zip") || !strcasecmp(ext, ".zip")) - { - unzFile file = unzOpen(rom_filename); - if (file) - { - int port = unzFindExtension(file, "ups"); + port = unzFindExtension(file, "ups"); if (port == UNZ_OK) { printf(" in %s", rom_filename); @@ -4147,164 +3997,8 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r printf(" failed!\n"); } assert(unzClose(file) == UNZ_OK); - } - } -#endif - n = S9xGetFilename(".ups", PATCH_DIR); - - if ((patch_file = OPEN_FSTREAM(n, "rb")) != NULL) - { - printf("Using UPS patch %s", n); - - Stream *s = new fStream(patch_file); - ret = ReadUPSPatch(s, 0, rom_size); - s->closeStream(); - - if (ret) - { - printf("!\n"); - return; - } - else - printf(" failed!\n"); - } - - // IPS - - _makepath(fname, drive, dir, name, "ips"); - - if ((patch_file = OPEN_FSTREAM(fname, "rb")) != NULL) - { - printf("Using IPS patch %s", fname); - - Stream *s = new fStream(patch_file); - ret = ReadIPSPatch(s, offset, rom_size); - s->closeStream(); - - if (ret) - { - printf("!\n"); - return; - } - else - printf(" failed!\n"); - } - - if (_MAX_EXT > 6) - { - i = 0; - flag = false; - - do - { - snprintf(ips, 8, "%03d.ips", i); - _makepath(fname, drive, dir, name, ips); - - if (!(patch_file = OPEN_FSTREAM(fname, "rb"))) - break; - - printf("Using IPS patch %s", fname); - - Stream *s = new fStream(patch_file); - ret = ReadIPSPatch(s, offset, rom_size); - s->closeStream(); - - if (ret) - { - printf("!\n"); - flag = true; - } - else - { - printf(" failed!\n"); - break; - } - } while (++i < 1000); - - if (flag) - return; - } - - if (_MAX_EXT > 3) - { - i = 0; - flag = false; - - do - { - snprintf(ips, _MAX_EXT + 2, "ips%d", i); - if (strlen(ips) > _MAX_EXT) - break; - _makepath(fname, drive, dir, name, ips); - - if (!(patch_file = OPEN_FSTREAM(fname, "rb"))) - break; - - printf("Using IPS patch %s", fname); - - Stream *s = new fStream(patch_file); - ret = ReadIPSPatch(s, offset, rom_size); - s->closeStream(); - - if (ret) - { - printf("!\n"); - flag = true; - } - else - { - printf(" failed!\n"); - break; - } - } while (++i != 0); - - if (flag) - return; - } - - if (_MAX_EXT > 2) - { - i = 0; - flag = false; - - do - { - snprintf(ips, 4, "ip%d", i); - _makepath(fname, drive, dir, name, ips); - - if (!(patch_file = OPEN_FSTREAM(fname, "rb"))) - break; - - printf("Using IPS patch %s", fname); - - Stream *s = new fStream(patch_file); - ret = ReadIPSPatch(s, offset, rom_size); - s->closeStream(); - - if (ret) - { - printf("!\n"); - flag = true; - } - else - { - printf(" failed!\n"); - break; - } - } while (++i < 10); - - if (flag) - return; - } - -#ifdef UNZIP_SUPPORT - if (!strcasecmp(ext, "zip") || !strcasecmp(ext, ".zip")) - { - unzFile file = unzOpen(rom_filename); - if (file) - { - int port = unzFindExtension(file, "ips"); + port = unzFindExtension(file, "ips"); while (port == UNZ_OK) { printf(" in %s", rom_filename); @@ -4363,7 +4057,7 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r do { - snprintf(ips, _MAX_EXT + 2, "ips%d", i); + snprintf(ips, 8, "ips%d", i); if (strlen(ips) > _MAX_EXT) break; @@ -4389,7 +4083,7 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r if (unzFindExtension(file, ips, false, false) == UNZ_OK) printf("WARNING: Ignoring extra .%s files!\n", ips); - } while (++i != 0); + } while (++i < 1000); } if (!flag) @@ -4431,13 +4125,71 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r return; } } + + // Mercurial Magic (MSU-1 distribution pack) + if (strcasecmp(ext, "msu1") && strcasecmp(ext, ".msu1")) // ROM was *NOT* loaded from a .msu1 pack + { + Stream *s = S9xMSU1OpenFile("patch.bps", TRUE); + if (s) + { + printf("Using BPS patch from msu1"); + ret = ReadBPSPatch(s, offset, rom_size); + s->closeStream(); + + if (ret) + printf("!\n"); + else + printf(" failed!\n"); + } + } #endif - n = S9xGetFilename(".ips", PATCH_DIR); + // BPS + std::string filename = patch_path + S9xGetFilename(".bps", PATCH_DIR); - if ((patch_file = OPEN_FSTREAM(n, "rb")) != NULL) + if ((patch_file = OPEN_FSTREAM(filename.c_str(), "rb")) != NULL) { - printf("Using IPS patch %s", n); + printf("Using BPS patch %s", filename.c_str()); + + Stream *s = new fStream(patch_file); + ret = ReadBPSPatch(s, 0, rom_size); + s->closeStream(); + + if (ret) + { + printf("!\n"); + return; + } + else + printf(" failed!\n"); + } + + // UPS + filename = patch_path + S9xGetFilename(".ups", PATCH_DIR); + + if ((patch_file = OPEN_FSTREAM(filename.c_str(), "rb")) != NULL) + { + printf("Using UPS patch %s", filename.c_str());; + + Stream *s = new fStream(patch_file); + ret = ReadUPSPatch(s, 0, rom_size); + s->closeStream(); + + if (ret) + { + printf("!\n"); + return; + } + else + printf(" failed!\n"); + } + + // IPS + filename = patch_path + S9xGetFilename(".ips", PATCH_DIR); + + if ((patch_file = OPEN_FSTREAM(filename.c_str(), "rb")) != NULL) + { + printf("Using IPS patch %s", filename.c_str()); Stream *s = new fStream(patch_file); ret = ReadIPSPatch(s, offset, rom_size); @@ -4452,129 +4204,95 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r printf(" failed!\n"); } - if (_MAX_EXT > 6) + i = 0; + flag = false; + + do { - i = 0; - flag = false; + snprintf(ips, 8, "%03d.ips", i); + filename = patch_path + S9xGetFilename(ips, PATCH_DIR); - do + if (!(patch_file = OPEN_FSTREAM(filename.c_str(), "rb"))) + break; + + printf("Using IPS patch %s", filename.c_str()); + + Stream *s = new fStream(patch_file); + ret = ReadIPSPatch(s, offset, rom_size); + s->closeStream(); + + if (ret) { - snprintf(ips, 9, ".%03d.ips", i); - n = S9xGetFilename(ips, PATCH_DIR); - - if (!(patch_file = OPEN_FSTREAM(n, "rb"))) - break; - - printf("Using IPS patch %s", n); - - Stream *s = new fStream(patch_file); - ret = ReadIPSPatch(s, offset, rom_size); - s->closeStream(); - - if (ret) - { - printf("!\n"); - flag = true; - } - else - { - printf(" failed!\n"); - break; - } - } while (++i < 1000); - - if (flag) - return; - } - - if (_MAX_EXT > 3) - { - i = 0; - flag = false; - - do - { - snprintf(ips, _MAX_EXT + 3, ".ips%d", i); - if (strlen(ips) > _MAX_EXT + 1) - break; - n = S9xGetFilename(ips, PATCH_DIR); - - if (!(patch_file = OPEN_FSTREAM(n, "rb"))) - break; - - printf("Using IPS patch %s", n); - - Stream *s = new fStream(patch_file); - ret = ReadIPSPatch(s, offset, rom_size); - s->closeStream(); - - if (ret) - { - printf("!\n"); - flag = true; - } - else - { - printf(" failed!\n"); - break; - } - } while (++i != 0); - - if (flag) - return; - } - - if (_MAX_EXT > 2) - { - i = 0; - flag = false; - - do - { - snprintf(ips, 5, ".ip%d", i); - n = S9xGetFilename(ips, PATCH_DIR); - - if (!(patch_file = OPEN_FSTREAM(n, "rb"))) - break; - - printf("Using IPS patch %s", n); - - Stream *s = new fStream(patch_file); - ret = ReadIPSPatch(s, offset, rom_size); - s->closeStream(); - - if (ret) - { - printf("!\n"); - flag = true; - } - else - { - printf(" failed!\n"); - break; - } - } while (++i < 10); - - if (flag) - return; - } - -#ifdef UNZIP_SUPPORT - // Mercurial Magic (MSU-1 distribution pack) - if (strcasecmp(ext, "msu1") && strcasecmp(ext, ".msu1")) // ROM was *NOT* loaded from a .msu1 pack - { - Stream *s = S9xMSU1OpenFile("patch.bps", TRUE); - if (s) - { - printf("Using BPS patch %s.msu1", name); - ret = ReadBPSPatch(s, offset, rom_size); - s->closeStream(); - - if (ret) - printf("!\n"); - else - printf(" failed!\n"); + printf("!\n"); + flag = true; } - } -#endif -} + else + { + printf(" failed!\n"); + break; + } + + } while (i < 1000); + + if (flag) + return; + + i = 0; + flag = false; + do + { + snprintf(ips, 8, "ips%d", i); + filename = patch_path + S9xGetFilename(ips, PATCH_DIR); + + if (!(patch_file = OPEN_FSTREAM(filename.c_str(), "rb"))) + break; + + printf("Using IPS patch %s", filename.c_str()); + + Stream *s = new fStream(patch_file); + ret = ReadIPSPatch(s, offset, rom_size); + s->closeStream(); + + if (ret) + { + printf("!\n"); + flag = true; + } + else + { + printf(" failed!\n"); + break; + } + } while (++i < 1000); + + if (flag) + return; + + i = 0; + flag = false; + do + { + snprintf(ips, 4, "ip%d", i); + filename = patch_path + S9xGetFilename(ips, PATCH_DIR); + + if (!(patch_file = OPEN_FSTREAM(filename.c_str(), "rb"))) + break; + + printf("Using IPS patch %s", filename.c_str());; + + Stream *s = new fStream(patch_file); + ret = ReadIPSPatch(s, offset, rom_size); + s->closeStream(); + + if (ret) + { + printf("!\n"); + flag = true; + } + else + { + printf(" failed!\n"); + break; + } + } while (++i < 10); +} \ No newline at end of file diff --git a/msu1.cpp b/msu1.cpp index 71cb0878..649385ec 100644 --- a/msu1.cpp +++ b/msu1.cpp @@ -57,27 +57,27 @@ static int unzFindExtension(unzFile &file, const char *ext, bool restart = TRUE, STREAM S9xMSU1OpenFile(const char *msu_ext, bool skip_unpacked) { - const char *filename = S9xGetFilename(msu_ext, ROMFILENAME_DIR); + auto filename = S9xGetFilename(msu_ext, ROMFILENAME_DIR); STREAM file = 0; if (!skip_unpacked) { - file = OPEN_STREAM(filename, "rb"); + file = OPEN_STREAM(filename.c_str(), "rb"); if (file) - printf("Using msu file %s.\n", filename); + printf("Using msu file %s.\n", filename.c_str()); } #ifdef UNZIP_SUPPORT // look for msu1 pack file in the rom or patch dir if msu data file not found in rom dir if (!file) { - const char *zip_filename = S9xGetFilename(".msu1", ROMFILENAME_DIR); - unzFile unzFile = unzOpen(zip_filename); + auto zip_filename = S9xGetFilename(".msu1", ROMFILENAME_DIR); + unzFile unzFile = unzOpen(zip_filename.c_str()); if (!unzFile) { zip_filename = S9xGetFilename(".msu1", PATCH_DIR); - unzFile = unzOpen(zip_filename); + unzFile = unzOpen(zip_filename.c_str()); } if (unzFile) @@ -85,7 +85,7 @@ STREAM S9xMSU1OpenFile(const char *msu_ext, bool skip_unpacked) int port = unzFindExtension(unzFile, msu_ext, true, true, true); if (port == UNZ_OK) { - printf(" in %s.\n", zip_filename); + printf(" in %s.\n", zip_filename.c_str()); file = new unzStream(unzFile); } else @@ -207,15 +207,14 @@ bool S9xMSU1ROMExists(void) return true; } #ifdef UNZIP_SUPPORT - char drive[_MAX_DRIVE + 1], dir[_MAX_DIR + 1], def[_MAX_FNAME + 1], ext[_MAX_EXT + 1]; - _splitpath(Memory.ROMFilename, drive, dir, def, ext); - if (!strcasecmp(ext, ".msu1")) + + if (splitpath(Memory.ROMFilename).ext_is(".msu1")) return true; - unzFile unzFile = unzOpen(S9xGetFilename(".msu1", ROMFILENAME_DIR)); + unzFile unzFile = unzOpen(S9xGetFilename(".msu1", ROMFILENAME_DIR).c_str()); if(!unzFile) - unzFile = unzOpen(S9xGetFilename(".msu1", PATCH_DIR)); + unzFile = unzOpen(S9xGetFilename(".msu1", PATCH_DIR).c_str()); if (unzFile) { diff --git a/port.h b/port.h index bf674ad7..e56a04fa 100644 --- a/port.h +++ b/port.h @@ -114,24 +114,9 @@ typedef size_t pint; #define START_EXTERN_C extern "C" { #define END_EXTERN_C } -#ifndef __WIN32__ -#ifndef PATH_MAX -#define PATH_MAX 1024 -#endif -#define _MAX_DRIVE 1 -#define _MAX_DIR PATH_MAX -#define _MAX_FNAME PATH_MAX -#define _MAX_EXT PATH_MAX -#define _MAX_PATH PATH_MAX -#else -#ifndef PATH_MAX -#define PATH_MAX _MAX_PATH -#endif -#endif +#include "fscompat.h" #ifndef __WIN32__ -void _splitpath (const char *, char *, char *, char *, char *); -void _makepath (char *, const char *, const char *, const char *, const char *); #define S9xDisplayString DisplayStringFromBottom #else // __WIN32__ #define snprintf _snprintf diff --git a/screenshot.cpp b/screenshot.cpp index 90df1006..1572edf5 100644 --- a/screenshot.cpp +++ b/screenshot.cpp @@ -23,11 +23,10 @@ bool8 S9xDoScreenshot (int width, int height) png_infop info_ptr; png_color_8 sig_bit; int imgwidth, imgheight; - const char *fname; - fname = S9xGetFilenameInc(".png", SCREENSHOT_DIR); + std::string fname = S9xGetFilenameInc(".png", SCREENSHOT_DIR); - fp = fopen(fname, "wb"); + fp = fopen(fname.c_str(), "wb"); if (!fp) { S9xMessage(S9X_ERROR, 0, "Failed to take screenshot."); @@ -38,7 +37,7 @@ bool8 S9xDoScreenshot (int width, int height) if (!png_ptr) { fclose(fp); - remove(fname); + remove(fname.c_str()); S9xMessage(S9X_ERROR, 0, "Failed to take screenshot."); return (FALSE); } @@ -48,7 +47,7 @@ bool8 S9xDoScreenshot (int width, int height) { png_destroy_write_struct(&png_ptr, (png_infopp) NULL); fclose(fp); - remove(fname); + remove(fname.c_str()); S9xMessage(S9X_ERROR, 0, "Failed to take screenshot."); return (FALSE); } @@ -57,7 +56,7 @@ bool8 S9xDoScreenshot (int width, int height) { png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); - remove(fname); + remove(fname.c_str()); S9xMessage(S9X_ERROR, 0, "Failed to take screenshot."); return (FALSE); } @@ -70,8 +69,7 @@ bool8 S9xDoScreenshot (int width, int height) if (width > SNES_WIDTH && height <= SNES_HEIGHT_EXTENDED) imgheight = height << 1; } - else - if (Settings.StretchScreenshots == 2) + else if (Settings.StretchScreenshots == 2) { if (width <= SNES_WIDTH) imgwidth = width << 1; @@ -130,11 +128,10 @@ bool8 S9xDoScreenshot (int width, int height) fclose(fp); - fprintf(stderr, "%s saved.\n", fname); + fprintf(stderr, "%s saved.\n", fname.c_str()); - const char *base = S9xBasename(fname); - sprintf(String, "Saved screenshot %s", base); - S9xMessage(S9X_INFO, 0, String); + std::string base = "Saved screenshot " + S9xBasename(fname); + S9xMessage(S9X_INFO, 0, base.c_str()); return (TRUE); #else diff --git a/snapshot.cpp b/snapshot.cpp index 75540d4d..14b02aa6 100644 --- a/snapshot.cpp +++ b/snapshot.cpp @@ -1009,9 +1009,9 @@ void S9xResetSaveTimer (bool8 dontsave) if (!Settings.DontSaveOopsSnapshot && !dontsave && t != -1 && time(NULL) - t > 300) { - const char *filename = S9xGetFilename("oops", SNAPSHOT_DIR); + auto filename = S9xGetFilename("oops", SNAPSHOT_DIR); S9xMessage(S9X_INFO, S9X_FREEZE_FILE_INFO, SAVE_INFO_OOPS); - S9xFreezeGame(filename); + S9xFreezeGame(filename.c_str()); } t = time(NULL); @@ -1043,11 +1043,11 @@ bool8 S9xFreezeGame (const char *filename) S9xResetSaveTimer(TRUE); - const char *base = S9xBasename(filename); + auto base = S9xBasename(filename); if (S9xMovieActive()) - sprintf(String, MOVIE_INFO_SNAPSHOT " %s", base); + sprintf(String, MOVIE_INFO_SNAPSHOT " %s", base.c_str()); else - sprintf(String, SAVE_INFO_SNAPSHOT " %s", base); + sprintf(String, SAVE_INFO_SNAPSHOT " %s", base.c_str()); S9xMessage(S9X_INFO, S9X_FREEZE_FILE_INFO, String); @@ -1100,12 +1100,10 @@ void S9xMessageFromResult(int result, const char* base) bool8 S9xUnfreezeGame (const char *filename) { STREAM stream = NULL; - char drive[_MAX_DRIVE + 1], dir[_MAX_DIR + 1], def[_MAX_FNAME + 1], ext[_MAX_EXT + 1]; - const char *base = S9xBasename(filename); - - _splitpath(filename, drive, dir, def, ext); - S9xResetSaveTimer(!strcmp(ext, "oops") || !strcmp(ext, "oop") || !strcmp(ext, ".oops") || !strcmp(ext, ".oop")); + auto base = S9xBasename(filename); + auto path = splitpath(filename); + S9xResetSaveTimer(path.ext_is(".oops") || path.ext_is(".oop")); if (S9xOpenSnapshotFile(filename, TRUE, &stream)) { @@ -1116,26 +1114,26 @@ bool8 S9xUnfreezeGame (const char *filename) if (result != SUCCESS) { - S9xMessageFromResult(result, base); + S9xMessageFromResult(result, base.c_str()); return (FALSE); } if (S9xMovieActive()) { if (S9xMovieReadOnly()) - sprintf(String, MOVIE_INFO_REWIND " %s", base); + sprintf(String, MOVIE_INFO_REWIND " %s", base.c_str()); else - sprintf(String, MOVIE_INFO_RERECORD " %s", base); + sprintf(String, MOVIE_INFO_RERECORD " %s", base.c_str()); } else - sprintf(String, SAVE_INFO_LOAD " %s", base); + sprintf(String, SAVE_INFO_LOAD " %s", base.c_str()); S9xMessage(S9X_INFO, S9X_FREEZE_FILE_INFO, String); return (TRUE); } - sprintf(String, SAVE_ERR_SAVE_NOT_FOUND, base); + sprintf(String, SAVE_ERR_SAVE_NOT_FOUND, base.c_str()); S9xMessage(S9X_INFO, S9X_FREEZE_FILE_INFO, String); return (FALSE); @@ -1145,7 +1143,7 @@ bool8 S9xUnfreezeScreenshot(const char *filename, uint16 **image_buffer, int &wi { STREAM stream = NULL; - const char *base = S9xBasename(filename); + auto base = S9xBasename(filename); if(S9xOpenSnapshotFile(filename, TRUE, &stream)) { @@ -1156,14 +1154,14 @@ bool8 S9xUnfreezeScreenshot(const char *filename, uint16 **image_buffer, int &wi if(result != SUCCESS) { - S9xMessageFromResult(result, base); + S9xMessageFromResult(result, base.c_str()); return (FALSE); } return (TRUE); } - sprintf(String, SAVE_ERR_SAVE_NOT_FOUND, base); + sprintf(String, SAVE_ERR_SAVE_NOT_FOUND, base.c_str()); S9xMessage(S9X_INFO, S9X_FREEZE_FILE_INFO, String); return (FALSE); diff --git a/snes9x.cpp b/snes9x.cpp index 4a1ae67c..e2886405 100644 --- a/snes9x.cpp +++ b/snes9x.cpp @@ -39,26 +39,19 @@ static bool parse_controller_spec (int port, const char *arg) { if (!strcasecmp(arg, "none")) S9xSetController(port, CTL_NONE, 0, 0, 0, 0); - else - if (!strncasecmp(arg, "pad", 3) && arg[3] >= '1' && arg[3] <= '8' && arg[4] == '\0') + else if (!strncasecmp(arg, "pad", 3) && arg[3] >= '1' && arg[3] <= '8' && arg[4] == '\0') S9xSetController(port, CTL_JOYPAD, arg[3] - '1', 0, 0, 0); - else - if (!strncasecmp(arg, "mouse", 5) && arg[5] >= '1' && arg[5] <= '2' && arg[6] == '\0') + else if (!strncasecmp(arg, "mouse", 5) && arg[5] >= '1' && arg[5] <= '2' && arg[6] == '\0') S9xSetController(port, CTL_MOUSE, arg[5] - '1', 0, 0, 0); - else - if (!strcasecmp(arg, "superscope")) + else if (!strcasecmp(arg, "superscope")) S9xSetController(port, CTL_SUPERSCOPE, 0, 0, 0, 0); - else - if (!strcasecmp(arg, "justifier")) + else if (!strcasecmp(arg, "justifier")) S9xSetController(port, CTL_JUSTIFIER, 0, 0, 0, 0); - else - if (!strcasecmp(arg, "two-justifiers")) + else if (!strcasecmp(arg, "two-justifiers")) S9xSetController(port, CTL_JUSTIFIER, 1, 0, 0, 0); - else - if (!strcasecmp(arg, "macsrifle")) + else if (!strcasecmp(arg, "macsrifle")) S9xSetController(port, CTL_MACSRIFLE, 0, 0, 0, 0); - else - if (!strncasecmp(arg, "mp5:", 4) && ((arg[4] >= '1' && arg[4] <= '8') || arg[4] == 'n') && + else if (!strncasecmp(arg, "mp5:", 4) && ((arg[4] >= '1' && arg[4] <= '8') || arg[4] == 'n') && ((arg[5] >= '1' && arg[5] <= '8') || arg[5] == 'n') && ((arg[6] >= '1' && arg[6] <= '8') || arg[6] == 'n') && ((arg[7] >= '1' && arg[7] <= '8') || arg[7] == 'n') && arg[8] == '\0')