/*****************************************************************************\ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. This file is licensed under the Snes9x License. For further information, consult the LICENSE file in the root directory. \*****************************************************************************/ #include #include #ifdef HAVE_STRINGS_H #include #endif #include "snes9x.h" #include "memmap.h" #include "controls.h" #include "crosshairs.h" #include "cheats.h" #include "display.h" #include "conffile.h" #ifdef NETPLAY_SUPPORT #include "netplay.h" #endif #ifdef DEBUGGER #include "debug.h" extern FILE *trace; #endif #define S9X_CONF_FILE_NAME "snes9x.conf" static char *rom_filename = NULL; static bool parse_controller_spec (int, const char *); static void parse_crosshair_spec (enum crosscontrols, const char *); static bool try_load_config_file (const char *, ConfigFile &); 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') 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') S9xSetController(port, CTL_MOUSE, arg[5] - '1', 0, 0, 0); else if (!strcasecmp(arg, "superscope")) S9xSetController(port, CTL_SUPERSCOPE, 0, 0, 0, 0); else if (!strcasecmp(arg, "justifier")) S9xSetController(port, CTL_JUSTIFIER, 0, 0, 0, 0); else if (!strcasecmp(arg, "two-justifiers")) S9xSetController(port, CTL_JUSTIFIER, 1, 0, 0, 0); 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') && ((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') S9xSetController(port, CTL_MP5, (arg[4] == 'n') ? -1 : arg[4] - '1', (arg[5] == 'n') ? -1 : arg[5] - '1', (arg[6] == 'n') ? -1 : arg[6] - '1', (arg[7] == 'n') ? -1 : arg[7] - '1'); else return (false); return (true); } static void parse_crosshair_spec (enum crosscontrols ctl, const char *spec) { int idx = -1, i; const char *fg = NULL, *bg = NULL, *s = spec; if (s[0] == '"') { s++; for (i = 0; s[i] != '\0'; i++) if (s[i] == '"' && s[i - 1] != '\\') break; idx = 31 - ctl; std::string fname(s, i); if (!S9xLoadCrosshairFile(idx, fname.c_str())) return; s += i + 1; } else { if (isdigit(*s)) { idx = *s - '0'; s++; } if (isdigit(*s)) { idx = idx * 10 + *s - '0'; s++; } if (idx > 31) { fprintf(stderr, "Invalid crosshair spec '%s'.\n", spec); return; } } while (*s != '\0' && isspace(*s)) s++; if (*s != '\0') { fg = s; while (isalnum(*s)) s++; if (*s != '/' || !isalnum(s[1])) { fprintf(stderr, "Invalid crosshair spec '%s.'\n", spec); return; } bg = ++s; while (isalnum(*s)) s++; if (*s != '\0') { fprintf(stderr, "Invalid crosshair spec '%s'.\n", spec); return; } } S9xSetControllerCrosshair(ctl, idx, fg, bg); } static bool try_load_config_file (const char *fname, ConfigFile &conf) { FSTREAM fp; fp = OPEN_FSTREAM(fname, "r"); if (fp) { fprintf(stdout, "Reading config file %s.\n", fname); fStream fS(fp); conf.LoadFile(&fS); CLOSE_FSTREAM(fp); return (true); } return (false); } void S9xLoadConfigFiles (char **argv, int argc) { static ConfigFile conf; // static because some of its functions return pointers conf.Clear(); bool skip = false; for (int i = 0; i < argc; i++) { if (!strcasecmp(argv[i], "-nostdconf")) { skip = true; break; } } if (!skip) { std::string fname; fname = S9xGetDirectory(DEFAULT_DIR); fname += SLASH_STR S9X_CONF_FILE_NAME; try_load_config_file(fname.c_str(), conf); } else fprintf(stderr, "Skipping standard config files.\n"); for (int i = 0; i < argc - 1; i++) if (!strcasecmp(argv[i], "-conf")) try_load_config_file(argv[++i], conf); // Parse config file here // ROM Settings.ForceInterleaved2 = conf.GetBool("ROM::Interleaved2", false); Settings.ForceInterleaveGD24 = conf.GetBool("ROM::InterleaveGD24", false); Settings.ApplyCheats = conf.GetBool("ROM::Cheat", false); Cheat.enabled = false; Settings.NoPatch = !conf.GetBool("ROM::Patch", true); Settings.IgnorePatchChecksum = conf.GetBool("ROM::IgnorePatchChecksum", false); Settings.ForceLoROM = conf.GetBool("ROM::LoROM", false); Settings.ForceHiROM = conf.GetBool("ROM::HiROM", false); if (Settings.ForceLoROM) Settings.ForceHiROM = false; Settings.ForcePAL = conf.GetBool("ROM::PAL", false); Settings.ForceNTSC = conf.GetBool("ROM::NTSC", false); if (Settings.ForcePAL) Settings.ForceNTSC = false; if (conf.Exists("ROM::Header")) { Settings.ForceHeader = conf.GetBool("ROM::Header", false); Settings.ForceNoHeader = !Settings.ForceHeader; } if (conf.Exists("ROM::Interleaved")) { Settings.ForceInterleaved = conf.GetBool("ROM::Interleaved", false); Settings.ForceNotInterleaved = !Settings.ForceInterleaved; } rom_filename = conf.GetStringDup("ROM::Filename", NULL); Settings.InitialSnapshotFilename[0] = '\0'; // Sound Settings.SoundSync = conf.GetBool("Sound::Sync", false); Settings.SixteenBitSound = conf.GetBool("Sound::16BitSound", true); Settings.Stereo = conf.GetBool("Sound::Stereo", true); Settings.ReverseStereo = conf.GetBool("Sound::ReverseStereo", false); Settings.SoundPlaybackRate = conf.GetUInt("Sound::Rate", 48000); Settings.SoundInputRate = conf.GetUInt("Sound::InputRate", 31950); Settings.Mute = conf.GetBool("Sound::Mute", false); Settings.DynamicRateControl = conf.GetBool("Sound::DynamicRateControl", false); Settings.DynamicRateLimit = conf.GetInt ("Sound::DynamicRateLimit", 5); Settings.InterpolationMethod = conf.GetInt ("Sound::InterpolationMethod", 2); // Display Settings.SupportHiRes = conf.GetBool("Display::HiRes", false); Settings.Transparency = conf.GetBool("Display::Transparency", true); Settings.DisableGraphicWindows = !conf.GetBool("Display::GraphicWindows", true); Settings.DisplayTime = conf.GetBool("Display::DisplayTime", false); Settings.DisplayFrameRate = conf.GetBool("Display::DisplayFrameRate", true); Settings.DisplayWatchedAddresses = conf.GetBool("Display::DisplayWatchedAddresses", false); Settings.DisplayPressedKeys = conf.GetBool("Display::DisplayInput", false); Settings.DisplayMovieFrame = conf.GetBool("Display::DisplayFrameCount", false); Settings.AutoDisplayMessages = conf.GetBool("Display::MessagesInImage", true); Settings.InitialInfoStringTimeout = conf.GetInt ("Display::MessageDisplayTime", 120); Settings.BilinearFilter = conf.GetBool("Display::BilinearFilter", false); // Settings Settings.BSXBootup = conf.GetBool("Settings::BSXBootup", false); Settings.TurboMode = conf.GetBool("Settings::TurboMode", false); Settings.TurboSkipFrames = conf.GetUInt("Settings::TurboFrameSkip", 15); Settings.MovieTruncate = conf.GetBool("Settings::MovieTruncateAtEnd", false); Settings.MovieNotifyIgnored = conf.GetBool("Settings::MovieNotifyIgnored", false); Settings.WrongMovieStateProtection = conf.GetBool("Settings::WrongMovieStateProtection", true); Settings.StretchScreenshots = conf.GetInt ("Settings::StretchScreenshots", 1); Settings.SnapshotScreenshots = conf.GetBool("Settings::SnapshotScreenshots", true); Settings.DontSaveOopsSnapshot = conf.GetBool("Settings::DontSaveOopsSnapshot", false); Settings.AutoSaveDelay = conf.GetUInt("Settings::AutoSaveDelay", 0); if (conf.Exists("Settings::FrameTime")) Settings.FrameTimePAL = Settings.FrameTimeNTSC = conf.GetUInt("Settings::FrameTime", 16667); if (!strcasecmp(conf.GetString("Settings::FrameSkip", "Auto"), "Auto")) Settings.SkipFrames = AUTO_FRAMERATE; else Settings.SkipFrames = conf.GetUInt("Settings::FrameSkip", 0) + 1; // Controls Settings.MouseMaster = conf.GetBool("Controls::MouseMaster", true); Settings.SuperScopeMaster = conf.GetBool("Controls::SuperscopeMaster", true); Settings.JustifierMaster = conf.GetBool("Controls::JustifierMaster", true); Settings.MacsRifleMaster = conf.GetBool("Controls::MacsRifleMaster", true); Settings.MultiPlayer5Master = conf.GetBool("Controls::MP5Master", true); Settings.UpAndDown = conf.GetBool("Controls::AllowLeftRight", false); if (conf.Exists("Controls::Port1")) parse_controller_spec(0, conf.GetString("Controls::Port1")); if (conf.Exists("Controls::Port2")) parse_controller_spec(1, conf.GetString("Controls::Port2")); if (conf.Exists("Controls::Mouse1Crosshair")) parse_crosshair_spec(X_MOUSE1, conf.GetString("Controls::Mouse1Crosshair")); if (conf.Exists("Controls::Mouse2Crosshair")) parse_crosshair_spec(X_MOUSE2, conf.GetString("Controls::Mouse2Crosshair")); if (conf.Exists("Controls::SuperscopeCrosshair")) parse_crosshair_spec(X_SUPERSCOPE, conf.GetString("Controls::SuperscopeCrosshair")); if (conf.Exists("Controls::Justifier1Crosshair")) parse_crosshair_spec(X_JUSTIFIER1, conf.GetString("Controls::Justifier1Crosshair")); if (conf.Exists("Controls::Justifier2Crosshair")) parse_crosshair_spec(X_JUSTIFIER2, conf.GetString("Controls::Justifier2Crosshair")); if (conf.Exists("Controls::MacsRifleCrosshair")) parse_crosshair_spec(X_MACSRIFLE, conf.GetString("Controls::MacsRifleCrosshair")); // Hack Settings.SuperFXClockMultiplier = conf.GetUInt("Hack::SuperFXClockMultiplier", 100); Settings.OverclockMode = conf.GetUInt("Hack::OverclockMode", 0); Settings.SeparateEchoBuffer = conf.GetBool("Hack::SeparateEchoBuffer", false); Settings.DisableGameSpecificHacks = !conf.GetBool("Hack::EnableGameSpecificHacks", true); Settings.BlockInvalidVRAMAccessMaster = !conf.GetBool("Hack::AllowInvalidVRAMAccess", false); Settings.HDMATimingHack = conf.GetInt ("Hack::HDMATiming", 100); Settings.MaxSpriteTilesPerLine = conf.GetInt ("Hack::MaxSpriteTilesPerLine", 34); // Netplay #ifdef NETPLAY_SUPPORT Settings.NetPlay = conf.GetBool("Netplay::Enable"); Settings.Port = NP_DEFAULT_PORT; if (conf.Exists("Netplay::Port")) Settings.Port = -(int) conf.GetUInt("Netplay::Port"); Settings.ServerName[0] = '\0'; if (conf.Exists("Netplay::Server")) conf.GetString("Netplay::Server", Settings.ServerName, 128); #endif // Debug #ifdef DEBUGGER if (conf.GetBool("DEBUG::Debugger", false)) CPU.Flags |= DEBUG_MODE_FLAG; if (conf.GetBool("DEBUG::Trace", false)) { ENSURE_TRACE_OPEN(trace,"trace.log","wb") CPU.Flags |= TRACE_FLAG; } Settings.TraceSMP = FALSE; #endif S9xParsePortConfig(conf, 1); S9xVerifyControllers(); } void S9xUsage (void) { /* 12345678901234567890123456789012345678901234567890123456789012345678901234567890 */ S9xMessage(S9X_INFO, S9X_USAGE, ""); S9xMessage(S9X_INFO, S9X_USAGE, "Snes9x " VERSION); S9xMessage(S9X_INFO, S9X_USAGE, ""); S9xMessage(S9X_INFO, S9X_USAGE, "usage: snes9x [options] "); S9xMessage(S9X_INFO, S9X_USAGE, ""); // SOUND OPTIONS S9xMessage(S9X_INFO, S9X_USAGE, "-soundsync Synchronize sound as far as possible"); S9xMessage(S9X_INFO, S9X_USAGE, "-playbackrate Set sound playback rate"); S9xMessage(S9X_INFO, S9X_USAGE, "-inputrate Set sound input rate"); S9xMessage(S9X_INFO, S9X_USAGE, "-reversestereo Reverse stereo sound output"); S9xMessage(S9X_INFO, S9X_USAGE, "-nostereo Disable stereo sound output"); S9xMessage(S9X_INFO, S9X_USAGE, "-eightbit Use 8bit sound instead of 16bit"); S9xMessage(S9X_INFO, S9X_USAGE, "-mute Mute sound"); S9xMessage(S9X_INFO, S9X_USAGE, ""); // DISPLAY OPTIONS S9xMessage(S9X_INFO, S9X_USAGE, "-displaytime Display the time"); S9xMessage(S9X_INFO, S9X_USAGE, "-displayframerate Display the frame rate counter"); S9xMessage(S9X_INFO, S9X_USAGE, "-displaykeypress Display input of all controllers and peripherals"); S9xMessage(S9X_INFO, S9X_USAGE, "-nohires (Not recommended) Disable support for hi-res and"); S9xMessage(S9X_INFO, S9X_USAGE, " interlace modes"); S9xMessage(S9X_INFO, S9X_USAGE, "-notransparency (Not recommended) Disable transparency effects"); S9xMessage(S9X_INFO, S9X_USAGE, "-nowindows (Not recommended) Disable graphic window effects"); S9xMessage(S9X_INFO, S9X_USAGE, ""); // CONTROLLER OPTIONS S9xMessage(S9X_INFO, S9X_USAGE, "-nomp5 Disable emulation of the Multiplayer 5 adapter"); S9xMessage(S9X_INFO, S9X_USAGE, "-nomouse Disable emulation of the SNES mouse"); S9xMessage(S9X_INFO, S9X_USAGE, "-nosuperscope Disable emulation of the Superscope"); S9xMessage(S9X_INFO, S9X_USAGE, "-nojustifier Disable emulation of the Konami Justifier"); S9xMessage(S9X_INFO, S9X_USAGE, "-nomacsrifle Disable emulation of the M.A.C.S. Rifle"); S9xMessage(S9X_INFO, S9X_USAGE, "-port# Specify which controller to emulate in port 1/2"); S9xMessage(S9X_INFO, S9X_USAGE, " Controllers: none No controller"); S9xMessage(S9X_INFO, S9X_USAGE, " pad# Joypad number 1-8"); S9xMessage(S9X_INFO, S9X_USAGE, " mouse# Mouse number 1-2"); S9xMessage(S9X_INFO, S9X_USAGE, " superscope Superscope (not useful with -port1)"); S9xMessage(S9X_INFO, S9X_USAGE, " justifier Blue Justifier (not useful with -port1)"); S9xMessage(S9X_INFO, S9X_USAGE, " two-justifiers Blue & Pink Justifiers"); S9xMessage(S9X_INFO, S9X_USAGE, " mp5:#### MP5 with the 4 named pads (1-8 or n)"); S9xMessage(S9X_INFO, S9X_USAGE, " macsrifle M.A.C.S. Rifle"); S9xMessage(S9X_INFO, S9X_USAGE, ""); // ROM OPTIONS S9xMessage(S9X_INFO, S9X_USAGE, "-hirom Force Hi-ROM memory map"); S9xMessage(S9X_INFO, S9X_USAGE, "-lorom Force Lo-ROM memory map"); S9xMessage(S9X_INFO, S9X_USAGE, "-ntsc Force NTSC timing (60 frames/sec)"); S9xMessage(S9X_INFO, S9X_USAGE, "-pal Force PAL timing (50 frames/sec)"); S9xMessage(S9X_INFO, S9X_USAGE, "-nointerleave Assume the ROM image is not in interleaved"); S9xMessage(S9X_INFO, S9X_USAGE, " format"); S9xMessage(S9X_INFO, S9X_USAGE, "-interleaved Assume the ROM image is in interleaved format"); S9xMessage(S9X_INFO, S9X_USAGE, "-interleaved2 Assume the ROM image is in interleaved 2 format"); S9xMessage(S9X_INFO, S9X_USAGE, "-interleavedgd24 Assume the ROM image is in interleaved gd24"); S9xMessage(S9X_INFO, S9X_USAGE, " format"); S9xMessage(S9X_INFO, S9X_USAGE, "-noheader Assume the ROM image doesn't have a header of a"); S9xMessage(S9X_INFO, S9X_USAGE, " copier"); S9xMessage(S9X_INFO, S9X_USAGE, "-header Assume the ROM image has a header of a copier"); S9xMessage(S9X_INFO, S9X_USAGE, "-bsxbootup Boot up BS games from BS-X"); S9xMessage(S9X_INFO, S9X_USAGE, ""); // PATCH/CHEAT OPTIONS S9xMessage(S9X_INFO, S9X_USAGE, "-nopatch Do not apply any available IPS/UPS patches"); S9xMessage(S9X_INFO, S9X_USAGE, "-cheat Apply saved cheats"); S9xMessage(S9X_INFO, S9X_USAGE, "-cheatcode Supply a cheat code in Game Genie,"); S9xMessage(S9X_INFO, S9X_USAGE, " Pro-Action Replay, or Raw format (address=byte)"); S9xMessage(S9X_INFO, S9X_USAGE, ""); #ifdef NETPLAY_SUPPORT // NETPLAY OPTIONS S9xMessage(S9X_INFO, S9X_USAGE, "-net Enable netplay"); S9xMessage(S9X_INFO, S9X_USAGE, "-port Use port for netplay (use with -net)"); S9xMessage(S9X_INFO, S9X_USAGE, "-server Use the specified server for netplay"); S9xMessage(S9X_INFO, S9X_USAGE, " (use with -net)"); S9xMessage(S9X_INFO, S9X_USAGE, ""); #endif // HACKING OR DEBUGGING OPTIONS #ifdef DEBUGGER S9xMessage(S9X_INFO, S9X_USAGE, "-debug Set the Debugger flag"); S9xMessage(S9X_INFO, S9X_USAGE, "-trace Begin CPU instruction tracing"); #endif S9xMessage(S9X_INFO, S9X_USAGE, "-hdmatiming <1-199> (Not recommended) Changes HDMA transfer timings"); S9xMessage(S9X_INFO, S9X_USAGE, " event comes"); S9xMessage(S9X_INFO, S9X_USAGE, "-invalidvramaccess (Not recommended) Allow invalid VRAM access"); S9xMessage(S9X_INFO, S9X_USAGE, ""); // OTHER OPTIONS S9xMessage(S9X_INFO, S9X_USAGE, "-frameskip Screen update frame skip rate"); S9xMessage(S9X_INFO, S9X_USAGE, "-frametime Milliseconds per frame for frameskip auto-adjust"); S9xMessage(S9X_INFO, S9X_USAGE, "-upanddown Override protection from pressing left+right or"); S9xMessage(S9X_INFO, S9X_USAGE, " up+down together"); S9xMessage(S9X_INFO, S9X_USAGE, "-conf Use specified conf file (after standard files)"); S9xMessage(S9X_INFO, S9X_USAGE, "-nostdconf Do not load the standard config files"); S9xMessage(S9X_INFO, S9X_USAGE, ""); S9xMessage(S9X_INFO, S9X_USAGE, ""); S9xMessage(S9X_INFO, S9X_USAGE, "ROM image can be compressed with zip, gzip, JMA, or compress."); exit(1); } void S9xParseArgsForCheats (char **argv, int argc) { for (int i = 1; i < argc; i++) { if (!strcasecmp(argv[i], "-gamegenie") || !strcasecmp(argv[i], "-actionreplay") || !strcasecmp(argv[i], "-cheatcode")) { if (i + 1 < argc) { if (S9xAddCheatGroup ("Unknown", argv[++i]) < 0) { S9xMessage(S9X_ERROR, S9X_GAME_GENIE_CODE_ERROR, "Code format invalid"); } else { S9xEnableCheatGroup (Cheat.g.size() - 1); } } else S9xUsage(); } } } char * S9xParseArgs (char **argv, int argc) { for (int i = 1; i < argc; i++) { if (*argv[i] == '-') { if (!strcasecmp(argv[i], "-help")) S9xUsage(); else // SOUND OPTIONS if (!strcasecmp(argv[i], "-soundsync")) Settings.SoundSync = TRUE; else if (!strcasecmp(argv[i], "-dynamicratecontrol")) { Settings.DynamicRateControl = TRUE; Settings.DynamicRateLimit = 5; } else if (!strcasecmp(argv[i], "-playbackrate")) { if (i + 1 < argc) { Settings.SoundPlaybackRate = atoi(argv[++i]); if (Settings.SoundPlaybackRate < 8192) Settings.SoundPlaybackRate = 8192; } else S9xUsage(); } else if (!strcasecmp(argv[i], "-inputrate")) { if (i + 1 < argc) { Settings.SoundInputRate = atoi(argv[++i]); if (Settings.SoundInputRate < 31700) Settings.SoundInputRate = 31700; if (Settings.SoundInputRate > 32300) Settings.SoundInputRate = 32300; } else S9xUsage(); } else if (!strcasecmp(argv[i], "-reversestereo")) Settings.ReverseStereo = TRUE; else if (!strcasecmp(argv[i], "-nostereo")) Settings.Stereo = FALSE; else if (!strcasecmp(argv[i], "-eightbit")) Settings.SixteenBitSound = FALSE; else if (!strcasecmp(argv[i], "-mute")) Settings.Mute = TRUE; else // DISPLAY OPTIONS if (!strcasecmp(argv[i], "-displaytime")) Settings.DisplayTime = TRUE; else if (!strcasecmp(argv[i], "-displayframerate")) Settings.DisplayFrameRate = TRUE; else if (!strcasecmp(argv[i], "-displaykeypress")) Settings.DisplayPressedKeys = TRUE; else if (!strcasecmp(argv[i], "-nohires")) Settings.SupportHiRes = FALSE; else if (!strcasecmp(argv[i], "-notransparency")) Settings.Transparency = FALSE; else if (!strcasecmp(argv[i], "-nowindows")) Settings.DisableGraphicWindows = TRUE; else // CONTROLLER OPTIONS if (!strcasecmp(argv[i], "-nomp5")) Settings.MultiPlayer5Master = FALSE; else if (!strcasecmp(argv[i], "-nomouse")) Settings.MouseMaster = FALSE; else if (!strcasecmp(argv[i], "-nosuperscope")) Settings.SuperScopeMaster = FALSE; else if (!strcasecmp(argv[i], "-nojustifier")) Settings.JustifierMaster = FALSE; else if (!strcasecmp(argv[i], "-nomacsrifle")) Settings.MacsRifleMaster = FALSE; else if (!strcasecmp(argv[i], "-port1") || !strcasecmp(argv[i], "-port2")) { if (i + 1 < argc) { i++; if (!parse_controller_spec(argv[i - 1][5] - '1', argv[i])) S9xUsage(); } else S9xUsage(); } else // ROM OPTIONS if (!strcasecmp(argv[i], "-hirom")) Settings.ForceHiROM = TRUE; else if (!strcasecmp(argv[i], "-lorom")) Settings.ForceLoROM = TRUE; else if (!strcasecmp(argv[i], "-ntsc")) Settings.ForceNTSC = TRUE; else if (!strcasecmp(argv[i], "-pal")) Settings.ForcePAL = TRUE; else if (!strcasecmp(argv[i], "-nointerleave")) Settings.ForceNotInterleaved = TRUE; else if (!strcasecmp(argv[i], "-interleaved")) Settings.ForceInterleaved = TRUE; else if (!strcasecmp(argv[i], "-interleaved2")) Settings.ForceInterleaved2 = TRUE; else if (!strcasecmp(argv[i], "-interleavedgd24")) Settings.ForceInterleaveGD24 = TRUE; else if (!strcasecmp(argv[i], "-noheader")) Settings.ForceNoHeader = TRUE; else if (!strcasecmp(argv[i], "-header")) Settings.ForceHeader = TRUE; else if (!strcasecmp(argv[i], "-bsxbootup")) Settings.BSXBootup = TRUE; else if (!strcasecmp(argv[i], "-snapshot")) { if (i + 1 < argc) { strncpy(Settings.InitialSnapshotFilename, argv[++i], PATH_MAX); Settings.InitialSnapshotFilename[PATH_MAX] = 0; } else S9xUsage(); } else // PATCH/CHEAT OPTIONS if (!strcasecmp(argv[i], "-nopatch")) Settings.NoPatch = TRUE; else if (!strcasecmp(argv[i], "-cheat")) Settings.ApplyCheats = TRUE; else if (!strcasecmp(argv[i], "-gamegenie") || !strcasecmp(argv[i], "-actionreplay") || !strcasecmp(argv[i], "-cheatcode")) { if (i + 1 < argc) { if (S9xAddCheatGroup ("Unknown", argv[++i]) < 0) { S9xMessage(S9X_ERROR, S9X_GAME_GENIE_CODE_ERROR, "Code format invalid"); } else { S9xEnableCheatGroup (Cheat.g.size() - 1); } } else S9xUsage(); } else // NETPLAY OPTIONS #ifdef NETPLAY_SUPPORT if (!strcasecmp(argv[i], "-net")) Settings.NetPlay = TRUE; else if (!strcasecmp(argv[i], "-port")) { if (i + 1 < argc) Settings.Port = -atoi(argv[++i]); else S9xUsage(); } else if (!strcasecmp(argv[i], "-server")) { if (i + 1 < argc) { strncpy(Settings.ServerName, argv[++i], 127); Settings.ServerName[127] = 0; } else S9xUsage(); } else #endif // HACKING OR DEBUGGING OPTIONS #ifdef DEBUGGER if (!strcasecmp(argv[i], "-debug")) CPU.Flags |= DEBUG_MODE_FLAG; else if (!strcasecmp(argv[i], "-trace")) { ENSURE_TRACE_OPEN(trace,"trace.log","wb") CPU.Flags |= TRACE_FLAG; } else #endif if (!strcasecmp(argv[i], "-hdmatiming")) { if (i + 1 < argc) { int p = atoi(argv[++i]); if (p > 0 && p < 200) Settings.HDMATimingHack = p; } else S9xUsage(); } else if (!strcasecmp(argv[i], "-invalidvramaccess")) Settings.BlockInvalidVRAMAccessMaster = FALSE; else // OTHER OPTIONS if (!strcasecmp(argv[i], "-frameskip")) { if (i + 1 < argc) Settings.SkipFrames = atoi(argv[++i]) + 1; else S9xUsage(); } else if (!strcasecmp(argv[i], "-frametime")) { if (i + 1 < argc) Settings.FrameTimePAL = Settings.FrameTimeNTSC = atoi(argv[++i]); else S9xUsage(); } else if (!strcasecmp(argv[i], "-upanddown")) Settings.UpAndDown = TRUE; else if (!strcasecmp(argv[i], "-conf")) { if (++i >= argc) S9xUsage(); // Else do nothing, S9xLoadConfigFiles() handled it. } else if (!strcasecmp(argv[i], "-nostdconf")) { // Do nothing, S9xLoadConfigFiles() handled it. } } else rom_filename = argv[i]; } S9xVerifyControllers(); return (rom_filename); }