mirror of
https://github.com/dborth/snes9xgx.git
synced 2024-11-24 19:46:58 +01:00
1265 lines
47 KiB
C++
1265 lines
47 KiB
C++
/**********************************************************************************
|
|
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
|
|
|
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
|
Jerremy Koot (jkoot@snes9x.com)
|
|
|
|
(c) Copyright 2002 - 2004 Matthew Kendora
|
|
|
|
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
|
|
|
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
|
|
|
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
|
|
|
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
|
Kris Bleakley (codeviolation@hotmail.com)
|
|
|
|
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
|
|
Nach (n-a-c-h@users.sourceforge.net),
|
|
zones (kasumitokoduck@yahoo.com)
|
|
|
|
(c) Copyright 2006 - 2007 nitsuja
|
|
|
|
|
|
BS-X C emulator code
|
|
(c) Copyright 2005 - 2006 Dreamer Nom,
|
|
zones
|
|
|
|
C4 x86 assembler and some C emulation code
|
|
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
|
Nach,
|
|
zsKnight (zsknight@zsnes.com)
|
|
|
|
C4 C++ code
|
|
(c) Copyright 2003 - 2006 Brad Jorsch,
|
|
Nach
|
|
|
|
DSP-1 emulator code
|
|
(c) Copyright 1998 - 2006 _Demo_,
|
|
Andreas Naive (andreasnaive@gmail.com)
|
|
Gary Henderson,
|
|
Ivar (ivar@snes9x.com),
|
|
John Weidman,
|
|
Kris Bleakley,
|
|
Matthew Kendora,
|
|
Nach,
|
|
neviksti (neviksti@hotmail.com)
|
|
|
|
DSP-2 emulator code
|
|
(c) Copyright 2003 John Weidman,
|
|
Kris Bleakley,
|
|
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
|
Matthew Kendora,
|
|
neviksti
|
|
|
|
|
|
DSP-3 emulator code
|
|
(c) Copyright 2003 - 2006 John Weidman,
|
|
Kris Bleakley,
|
|
Lancer,
|
|
z80 gaiden
|
|
|
|
DSP-4 emulator code
|
|
(c) Copyright 2004 - 2006 Dreamer Nom,
|
|
John Weidman,
|
|
Kris Bleakley,
|
|
Nach,
|
|
z80 gaiden
|
|
|
|
OBC1 emulator code
|
|
(c) Copyright 2001 - 2004 zsKnight,
|
|
pagefault (pagefault@zsnes.com),
|
|
Kris Bleakley,
|
|
Ported from x86 assembler to C by sanmaiwashi
|
|
|
|
SPC7110 and RTC C++ emulator code
|
|
(c) Copyright 2002 Matthew Kendora with research by
|
|
zsKnight,
|
|
John Weidman,
|
|
Dark Force
|
|
|
|
S-DD1 C emulator code
|
|
(c) Copyright 2003 Brad Jorsch with research by
|
|
Andreas Naive,
|
|
John Weidman
|
|
|
|
S-RTC C emulator code
|
|
(c) Copyright 2001-2006 byuu,
|
|
John Weidman
|
|
|
|
ST010 C++ emulator code
|
|
(c) Copyright 2003 Feather,
|
|
John Weidman,
|
|
Kris Bleakley,
|
|
Matthew Kendora
|
|
|
|
Super FX x86 assembler emulator code
|
|
(c) Copyright 1998 - 2003 _Demo_,
|
|
pagefault,
|
|
zsKnight,
|
|
|
|
Super FX C emulator code
|
|
(c) Copyright 1997 - 1999 Ivar,
|
|
Gary Henderson,
|
|
John Weidman
|
|
|
|
Sound DSP emulator code is derived from SNEeSe and OpenSPC:
|
|
(c) Copyright 1998 - 2003 Brad Martin
|
|
(c) Copyright 1998 - 2006 Charles Bilyue'
|
|
|
|
SH assembler code partly based on x86 assembler code
|
|
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
|
|
|
2xSaI filter
|
|
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
|
|
|
HQ2x, HQ3x, HQ4x filters
|
|
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
|
|
|
Win32 GUI code
|
|
(c) Copyright 2003 - 2006 blip,
|
|
funkyass,
|
|
Matthew Kendora,
|
|
Nach,
|
|
nitsuja
|
|
|
|
Mac OS GUI code
|
|
(c) Copyright 1998 - 2001 John Stiles
|
|
(c) Copyright 2001 - 2007 zones
|
|
|
|
|
|
Specific ports contains the works of other authors. See headers in
|
|
individual files.
|
|
|
|
|
|
Snes9x homepage: http://www.snes9x.com
|
|
|
|
Permission to use, copy, modify and/or distribute Snes9x in both binary
|
|
and source form, for non-commercial purposes, is hereby granted without
|
|
fee, providing that this license information and copyright notice appear
|
|
with all copies and any derived work.
|
|
|
|
This software is provided 'as-is', without any express or implied
|
|
warranty. In no event shall the authors be held liable for any damages
|
|
arising from the use of this software or it's derivatives.
|
|
|
|
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
|
seek permission of the copyright holders first. Commercial use includes,
|
|
but is not limited to, charging money for Snes9x or software derived from
|
|
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
|
using Snes9x as a promotion for your commercial product.
|
|
|
|
The copyright holders request that bug fixes and improvements to the code
|
|
should be forwarded to them so everyone can benefit from the modifications
|
|
in future versions.
|
|
|
|
Super NES and Super Nintendo Entertainment System are trademarks of
|
|
Nintendo Co., Limited and its subsidiary companies.
|
|
**********************************************************************************/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <ctype.h>
|
|
#ifdef HAVE_STRINGS_H
|
|
#include <strings.h>
|
|
#endif
|
|
|
|
#include "snes9x.h"
|
|
#include "memmap.h"
|
|
#include "display.h"
|
|
|
|
#ifndef NGC
|
|
#include "cheats.h"
|
|
#endif
|
|
|
|
#include "controls.h"
|
|
|
|
#ifndef NGC
|
|
#include "netplay.h"
|
|
#include "logger.h"
|
|
#endif
|
|
#include "gfx.h"
|
|
|
|
#ifdef DEBUGGER
|
|
extern FILE *trace;
|
|
#endif
|
|
|
|
static char *rom_filename=NULL;
|
|
|
|
void S9xUsage ()
|
|
{
|
|
S9xMessage (S9X_INFO, S9X_USAGE, "snes9x: S9xUsage: snes9x <options> <rom image filename>\n");
|
|
S9xMessage (S9X_INFO, S9X_USAGE, "Where <options> can be:");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "");
|
|
|
|
/* SOUND OPTIONS */
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-sound or -so Enable digital sound output");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-nosound or -ns Disable digital sound output");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-soundskip or -sk <0-3> Sound CPU skip-waiting method");
|
|
#ifdef SHOW_OBSOLETE_OPTIONS
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-ratio or -ra <num> Ratio of 65c816 to SPC700 instructions (ignored)");
|
|
#endif
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-soundquality, -sq, or -r <num> Set sound playback quality");
|
|
#ifndef __MSDOS__
|
|
S9xMessage (S9X_INFO, S9X_USAGE, "\
|
|
0 - off, 1 - 8192, 2 - 11025, 3 - 16000,\n\
|
|
4 - 22050, 5 - 32000 (default), 6 - 44100,\n\
|
|
7 - 48000");
|
|
#else
|
|
S9xMessage (S9X_INFO, S9X_USAGE, "\
|
|
0 - off, 1 - 8192, 2 - 11025, 3 - 16500,\n\
|
|
4 - 22050 (default), 5 - 29300, 6 - 36600,\n\
|
|
7 - 44000");
|
|
#endif
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-altsampledecode or -alt Use alternate sample decoder");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-stereo or -st Enable stereo sound output (implies -sound)");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-mono Enable monaural sound output (implies -sound)");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-soundsync or -sy Enable sound sync to CPU at startup");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-soundsync2 or -sy2 Alternate method to sync sound");
|
|
#ifdef USE_THREADS
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-threadsound or -ts Use a separate thread to output sound");
|
|
#endif
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-nois Turn off interpolated sound");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-echo or -e Enable DSP echo effects at startup");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-noecho or -ne Disable DSP echo effects at startup");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-envx or -ex Enable volume envelope height reading");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-nosamplecaching, -nsc, or -nc Disable sample caching");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-nomastervolume or -nmv Disable master volume setting");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-fix 'Fix' sound frequencies");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "");
|
|
|
|
/* FEATURE OPTIONS */
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-conf <filename> 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, "-hdma or -ha Enable HDMA emulation at startup");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-nohdma or -nh Disable HDMA emulation at startup");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-transparency or -tr Enable transparency effects");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-notransparency or -nt Disable transparency effects at start");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-windows Enable graphic window effects");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-nowindows or -nw Disable graphic window effects");
|
|
#ifdef SHOW_OBSOLETE_OPTIONS
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-layering or -L Enable BG Layering Hack at startup (ignored)");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-nolayering or -nl Disable BG Layering Hack at startup (ignored)");
|
|
#endif
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-im7 Enable Mode 7 interpolation effects");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-displayframerate or -dfr Display the frame rate counter");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-aidoshm <shmid> Run in AIDO mode, with specified SHM ID");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "");
|
|
|
|
/* DISPLAY OPTIONS */
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-hires or -hi Enable support for hi-res and interlace modes");
|
|
#ifdef SHOW_OBSOLETE_OPTIONS
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-16 or -sixteen Enable 16-bit rendering");
|
|
#endif
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-frameskip or -f <num> Screen update frame skip rate");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-frametime or -ft <float> Milliseconds per frame for frameskip auto-adjust");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "");
|
|
|
|
/* ROM OPTIONS */
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-hirom, -hr, or -fh Force Hi-ROM memory map");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-lorom, -lr, or -fl Force Lo-ROM memory map");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-bs Use BS Satellite System ROM mapping");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-bsxbootup Boot up BS games from BS-X");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-nointerleave or -ni ROM image is not in interleaved format");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-interleaved or -i ROM image is in interleaved format");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-interleaved2 or -i2 ROM image is in interleaved 2 format");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-interleavedgd24 or -gd24 ROM image is in interleaved gd24 format");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-header, -he, or -hd Force the detection of a ROM image header");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-noheader or -nhd Force the detection of no ROM image header");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-ntsc or -n Force NTSC timing (60 frames/sec)");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-pal or -p Force PAL timing (50 frames/sec)");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-superfx or -sfx Force detection of the SuperFX chip");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-nosuperfx or -nosfx Force detection of no SuperFX chip");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-dsp1 Force detection of the DSP-1 chip");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-nodsp1 Force detection of no DSP-1 chip");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "");
|
|
|
|
/* Multi ROMs OPTIONS */
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-multi Enable multi cartridge system");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-carta <filename> ROM in slot A. Use with -multi");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-cartb <filename> ROM in slot B. Use with -multi");
|
|
|
|
/* OPTIONS FOR DEBUGGING USE */
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-hdmahacks or -h <1-199> Changes HDMA transfer timing");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-speedhacks or -sh Enable speed hacks");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-nospeedhacks or -nsh Disable speed hacks");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-invalidvramaccess Allow invalid VRAM access");
|
|
#ifdef DEBUGGER
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-debug or -d Set the Debugger flag at startup");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-trace or -t Begin CPU instruction tracing at startup");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-noirq Disable processor IRQ (for debugging)");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "--selftest Run self tests and exit");
|
|
#ifdef DEBUG_MAXCOUNT
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-maxcount <N> Only run through N cycles of the main loop");
|
|
#endif
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "");
|
|
#endif
|
|
|
|
/* PATCH/CHEAT OPTIONS */
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-nopatch Do not apply any available IPS patches");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-cheat Apply saved cheats");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-nocheat Do not apply saved cheats");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-gamegenie or -gg <code> Supply a Game Genie code");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-actionreplay or -ar <code> Supply a Pro-Action Reply code");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-goldfinger or -gf <code> Supply a Gold Finger code");
|
|
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, "-port# <control> 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, " one-justifier ditto");
|
|
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, "");
|
|
|
|
#ifdef NETPLAY_SUPPORT
|
|
/* NETPLAY OPTIONS */
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-net Enable netplay");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-port or -po <num> Use port <num> for netplay");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-server or -srv <string> Use the specified server for netplay");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "");
|
|
#endif
|
|
|
|
#ifdef STORM
|
|
/* "STORM" OPTIONS */
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-nosecondjoy Set secondjoy=0");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-showfps Set dofps=1");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-hicolor Set hicolor=1");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-minimal Turn off "Keyboard with exception of ESC"");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-ahiunit <num> Set AHI Unit to <num>");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "");
|
|
#endif
|
|
S9xMessage(S9X_INFO, S9X_USAGE, " DeHackEd's commands:");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-dumpstreams Save audio/video data to disk");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-mute Don't output audio to sound card, use with above.");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-upanddown Override protection from pressing");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, " left+right or up+down together");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-autodemo Start emulator playing a movie");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-maxframes <num> Stop emulator after playing specified");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, " number of frames. Requires -dumpstreams");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "-oldturbo Turbo button renders all frames, but slower");
|
|
S9xMessage(S9X_INFO, S9X_USAGE, "");
|
|
#ifndef NGC
|
|
S9xExtraUsage();
|
|
#endif
|
|
|
|
S9xMessage (S9X_INFO, S9X_USAGE, "\
|
|
\nROM image needs to be in Super MagiCom (*.smc), Super FamiCom (*.sfc),\n\
|
|
*.fig, or split (*.1, *.2, or sf32527a, sf32527b, etc) format and can be\n\
|
|
compressed with zip, gzip, JMA, or compress.\n");
|
|
|
|
exit (1);
|
|
}
|
|
|
|
#ifdef STORM
|
|
extern int dofps;
|
|
extern int hicolor;
|
|
extern int secondjoy;
|
|
extern int minimal;
|
|
int prelude=0;
|
|
extern int unit;
|
|
#endif
|
|
|
|
#ifndef NGC
|
|
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") ||
|
|
!strcasecmp(arg, "one-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(!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;
|
|
}
|
|
|
|
#endif
|
|
|
|
char *S9xParseArgs (char **argv, int argc)
|
|
{
|
|
|
|
#ifndef NGC
|
|
// Nintendo Gamecube has NO COMMAND LINE ARGUMENTS -;) ***/
|
|
for (int i = 1; i < argc; i++)
|
|
{
|
|
if (*argv[i] == '-')
|
|
{
|
|
if (strcasecmp (argv [i], "--selftest") == 0)
|
|
{
|
|
// FIXME: Probable missuse of S9X_USAGE
|
|
// FIXME: Actual tests. But at least this checks for coredumps.
|
|
S9xMessage (S9X_INFO, S9X_USAGE, "Running selftest ...");
|
|
S9xMessage (S9X_INFO, S9X_USAGE, "snes9x started:\t[OK]");
|
|
S9xMessage (S9X_INFO, S9X_USAGE, "All tests ok.");
|
|
exit(0);
|
|
}
|
|
if (strcasecmp (argv [i], "-so") == 0 ||
|
|
strcasecmp (argv [i], "-sound") == 0)
|
|
{
|
|
Settings.NextAPUEnabled = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-ns") == 0 ||
|
|
strcasecmp (argv [i], "-nosound") == 0)
|
|
{
|
|
Settings.NextAPUEnabled = FALSE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-soundskip") == 0 ||
|
|
strcasecmp (argv [i], "-sk") == 0)
|
|
{
|
|
if (i + 1 < argc)
|
|
Settings.SoundSkipMethod = atoi (argv [++i]);
|
|
else
|
|
S9xUsage ();
|
|
}
|
|
else if (strcasecmp (argv [i], "-ra") == 0 ||
|
|
strcasecmp (argv [i], "-ratio") == 0)
|
|
{
|
|
if ((i + 1) < argc)
|
|
{
|
|
}
|
|
else
|
|
S9xUsage ();
|
|
}
|
|
else if (strcasecmp (argv [i], "-h") == 0 ||
|
|
strcasecmp (argv [i], "-hdmahacks") == 0)
|
|
{
|
|
if (i + 1 < argc)
|
|
{
|
|
int p = atoi (argv [++i]);
|
|
if (p > 0 && p < 200)
|
|
Settings.HDMATimingHack = p;
|
|
}
|
|
else
|
|
S9xUsage ();
|
|
}
|
|
else if (strcasecmp (argv [i], "-nh") == 0 ||
|
|
strcasecmp (argv [i], "-nohdma") == 0)
|
|
{
|
|
Settings.DisableHDMA = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-ha") == 0 ||
|
|
strcasecmp (argv [i], "-hdma") == 0)
|
|
{
|
|
Settings.DisableHDMA = FALSE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-nsh") == 0 ||
|
|
strcasecmp (argv [i], "-nospeedhacks") == 0)
|
|
{
|
|
Settings.ShutdownMaster = FALSE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-sh") == 0 ||
|
|
strcasecmp (argv [i], "-speedhacks") == 0)
|
|
{
|
|
Settings.ShutdownMaster = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-invalidvramaccess") == 0)
|
|
{
|
|
Settings.BlockInvalidVRAMAccess = FALSE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-p") == 0 ||
|
|
strcasecmp (argv [i], "-pal") == 0)
|
|
{
|
|
Settings.ForcePAL = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-n") == 0 ||
|
|
strcasecmp (argv [i], "-ntsc") == 0)
|
|
{
|
|
Settings.ForceNTSC = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-f") == 0 ||
|
|
strcasecmp (argv [i], "-frameskip") == 0)
|
|
{
|
|
if (i + 1 < argc)
|
|
Settings.SkipFrames = atoi (argv [++i]) + 1;
|
|
else
|
|
S9xUsage ();
|
|
}
|
|
else if (strcasecmp (argv [i], "-fh") == 0 ||
|
|
strcasecmp (argv [i], "-hr") == 0 ||
|
|
strcasecmp (argv [i], "-hirom") == 0)
|
|
Settings.ForceHiROM = TRUE;
|
|
else if (strcasecmp (argv [i], "-fl") == 0 ||
|
|
strcasecmp (argv [i], "-lr") == 0 ||
|
|
strcasecmp (argv [i], "-lorom") == 0)
|
|
Settings.ForceLoROM = TRUE;
|
|
else if (strcasecmp (argv [i], "-hd") == 0 ||
|
|
strcasecmp (argv [i], "-header") == 0 ||
|
|
strcasecmp (argv [i], "-he") == 0)
|
|
{
|
|
Settings.ForceHeader = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-nhd") == 0 ||
|
|
strcasecmp (argv [i], "-noheader") == 0)
|
|
{
|
|
Settings.ForceNoHeader = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-bs") == 0)
|
|
{
|
|
Settings.BS = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-bsxbootup") == 0)
|
|
{
|
|
Settings.BSXBootup = TRUE;
|
|
}
|
|
#ifdef DEBUGGER
|
|
else if (strcasecmp (argv [i], "-d") == 0 ||
|
|
strcasecmp (argv [i], "-debug") == 0)
|
|
{
|
|
CPU.Flags |= DEBUG_MODE_FLAG;
|
|
}
|
|
else if (strcasecmp (argv [i], "-t") == 0 ||
|
|
strcasecmp (argv [i], "-trace") == 0)
|
|
{
|
|
if(!trace) trace = fopen ("trace.log", "wb");
|
|
CPU.Flags |= TRACE_FLAG;
|
|
}
|
|
#endif
|
|
else if (strcasecmp (argv [i], "-L") == 0 ||
|
|
strcasecmp (argv [i], "-layering") == 0)
|
|
Settings.BGLayering = TRUE;
|
|
else if (strcasecmp (argv [i], "-nl") == 0 ||
|
|
strcasecmp (argv [i], "-nolayering") == 0)
|
|
Settings.BGLayering = FALSE;
|
|
else if (strcasecmp (argv [i], "-tr") == 0 ||
|
|
strcasecmp (argv [i], "-transparency") == 0)
|
|
{
|
|
Settings.ForceTransparency = TRUE;
|
|
Settings.ForceNoTransparency = FALSE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-nt") == 0 ||
|
|
strcasecmp (argv [i], "-notransparency") == 0)
|
|
{
|
|
Settings.ForceNoTransparency = TRUE;
|
|
Settings.ForceTransparency = FALSE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-hi") == 0 ||
|
|
strcasecmp (argv [i], "-hires") == 0)
|
|
{
|
|
Settings.SupportHiRes = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-16") == 0 ||
|
|
strcasecmp (argv [i], "-sixteen") == 0)
|
|
{
|
|
}
|
|
else if (strcasecmp (argv [i], "-displayframerate") == 0 ||
|
|
strcasecmp (argv [i], "-dfr") == 0)
|
|
{
|
|
Settings.DisplayFrameRate = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-nomessagesinimage") == 0)
|
|
Settings.AutoDisplayMessages = FALSE;
|
|
else if (strcasecmp (argv [i], "-i") == 0 ||
|
|
strcasecmp (argv [i], "-interleaved") == 0)
|
|
Settings.ForceInterleaved = TRUE;
|
|
else if (strcasecmp (argv [i], "-i2") == 0 ||
|
|
strcasecmp (argv [i], "-interleaved2") == 0)
|
|
Settings.ForceInterleaved2=TRUE;
|
|
else if (strcasecmp (argv [i], "-gd24") == 0 ||
|
|
strcasecmp (argv [i], "-interleavedgd24") == 0)
|
|
Settings.ForceInterleaveGD24 = TRUE;
|
|
else if (strcasecmp (argv [i], "-ni") == 0 ||
|
|
strcasecmp (argv [i], "-nointerleave") == 0)
|
|
Settings.ForceNotInterleaved = TRUE;
|
|
else if (strcasecmp (argv [i], "-noirq") == 0)
|
|
Settings.DisableIRQ = TRUE;
|
|
else if (strcasecmp (argv [i], "-nw") == 0 ||
|
|
strcasecmp (argv [i], "-nowindows") == 0)
|
|
{
|
|
Settings.DisableGraphicWindows = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-nopatch") == 0)
|
|
{
|
|
Settings.NoPatch=TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-nocheat") == 0)
|
|
{
|
|
Settings.ApplyCheats=FALSE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-cheat") == 0)
|
|
{
|
|
Settings.ApplyCheats=TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-windows") == 0)
|
|
{
|
|
Settings.DisableGraphicWindows = FALSE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-aidoshm") == 0)
|
|
{
|
|
if (i + 1 < argc)
|
|
{
|
|
Settings.AIDOShmId = atoi (argv [++i]);
|
|
fprintf(stderr, "Snes9X running in AIDO mode. shmid: %d\n",
|
|
Settings.AIDOShmId);
|
|
} else
|
|
S9xUsage ();
|
|
}
|
|
#ifdef DEBUG_MAXCOUNT
|
|
else if (strcasecmp (argv [i], "-maxcount") == 0)
|
|
{
|
|
if (i + 1 < argc)
|
|
{
|
|
Settings.MaxCount = atol (argv [++i]);
|
|
fprintf(stderr, "Running for a maximum of %d loops.\n",
|
|
Settings.MaxCount);
|
|
} else
|
|
S9xUsage ();
|
|
}
|
|
#endif
|
|
else if (strcasecmp (argv [i], "-im7") == 0)
|
|
{
|
|
Settings.Mode7Interpolate = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-gg") == 0 ||
|
|
strcasecmp (argv [i], "-gamegenie") == 0)
|
|
{
|
|
if (i + 1 < argc)
|
|
{
|
|
uint32 address;
|
|
uint8 byte;
|
|
const char *error;
|
|
if ((error = S9xGameGenieToRaw (argv [++i], address, byte)) == NULL)
|
|
S9xAddCheat (TRUE, FALSE, address, byte);
|
|
else
|
|
S9xMessage (S9X_ERROR, S9X_GAME_GENIE_CODE_ERROR,
|
|
error);
|
|
}
|
|
else
|
|
S9xUsage ();
|
|
}
|
|
else if (strcasecmp (argv [i], "-ar") == 0 ||
|
|
strcasecmp (argv [i], "-actionreplay") == 0)
|
|
{
|
|
if (i + 1 < argc)
|
|
{
|
|
uint32 address;
|
|
uint8 byte;
|
|
const char *error;
|
|
if ((error = S9xProActionReplayToRaw (argv [++i], address, byte)) == NULL)
|
|
S9xAddCheat (TRUE, FALSE, address, byte);
|
|
else
|
|
S9xMessage (S9X_ERROR, S9X_ACTION_REPLY_CODE_ERROR,
|
|
error);
|
|
}
|
|
else
|
|
S9xUsage ();
|
|
}
|
|
else if (strcasecmp (argv [i], "-gf") == 0 ||
|
|
strcasecmp (argv [i], "-goldfinger") == 0)
|
|
{
|
|
if (i + 1 < argc)
|
|
{
|
|
uint32 address;
|
|
uint8 bytes [3];
|
|
bool8 sram;
|
|
uint8 num_bytes;
|
|
const char *error;
|
|
if ((error = S9xGoldFingerToRaw (argv [++i], address, sram,
|
|
num_bytes, bytes)) == NULL)
|
|
{
|
|
for (int c = 0; c < num_bytes; c++)
|
|
S9xAddCheat (TRUE, FALSE, address + c, bytes [c]);
|
|
}
|
|
else
|
|
S9xMessage (S9X_ERROR, S9X_GOLD_FINGER_CODE_ERROR,
|
|
error);
|
|
}
|
|
else
|
|
S9xUsage ();
|
|
}
|
|
else if (strcasecmp (argv[i], "-ft") == 0 ||
|
|
strcasecmp (argv [i], "-frametime") == 0)
|
|
{
|
|
if (i + 1 < argc)
|
|
{
|
|
double ft;
|
|
if (sscanf (argv [++i], "%lf", &ft) == 1)
|
|
{
|
|
Settings.FrameTimePAL = (int32) ft;
|
|
Settings.FrameTimeNTSC = (int32) ft;
|
|
}
|
|
}
|
|
else
|
|
S9xUsage ();
|
|
}
|
|
else if (strcasecmp (argv [i], "-e") == 0 ||
|
|
strcasecmp (argv [i], "-echo") == 0)
|
|
Settings.DisableSoundEcho = FALSE;
|
|
else if (strcasecmp (argv [i], "-ne") == 0 ||
|
|
strcasecmp (argv [i], "-noecho") == 0)
|
|
Settings.DisableSoundEcho = TRUE;
|
|
else if (strcasecmp (argv [i], "-r") == 0 ||
|
|
strcasecmp (argv [i], "-soundquality") == 0 ||
|
|
strcasecmp (argv [i], "-sq") == 0)
|
|
{
|
|
if (i + 1 < argc)
|
|
Settings.SoundPlaybackRate = atoi (argv [++i]) & 7;
|
|
else
|
|
S9xUsage ();
|
|
}
|
|
else if (strcasecmp (argv [i], "-stereo") == 0 ||
|
|
strcasecmp (argv [i], "-st") == 0)
|
|
{
|
|
Settings.Stereo = TRUE;
|
|
Settings.APUEnabled = TRUE;
|
|
Settings.NextAPUEnabled = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-mono") == 0)
|
|
{
|
|
Settings.Stereo = FALSE;
|
|
Settings.NextAPUEnabled = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-envx") == 0 ||
|
|
strcasecmp (argv [i], "-ex") == 0)
|
|
{
|
|
Settings.SoundEnvelopeHeightReading = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-nosamplecaching") == 0 ||
|
|
strcasecmp (argv [i], "-nsc") == 0 ||
|
|
strcasecmp (argv [i], "-nc") == 0)
|
|
{
|
|
Settings.DisableSampleCaching = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-nomastervolume") == 0 ||
|
|
strcasecmp (argv [i], "-nmv") == 0)
|
|
{
|
|
Settings.DisableMasterVolume = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-soundsync") == 0 ||
|
|
strcasecmp (argv [i], "-sy") == 0)
|
|
{
|
|
Settings.SoundSync = TRUE;
|
|
Settings.SoundEnvelopeHeightReading = TRUE;
|
|
Settings.InterpolatedSound = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-soundsync2") == 0 ||
|
|
strcasecmp (argv [i], "-sy2") == 0)
|
|
{
|
|
Settings.SoundSync = 2;
|
|
Settings.SoundEnvelopeHeightReading = TRUE;
|
|
Settings.InterpolatedSound = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-nois") == 0)
|
|
{
|
|
Settings.InterpolatedSound = FALSE;
|
|
}
|
|
#ifdef USE_THREADS
|
|
else if (strcasecmp (argv [i], "-threadsound") == 0 ||
|
|
strcasecmp (argv [i], "-ts") == 0)
|
|
{
|
|
Settings.ThreadSound = TRUE;
|
|
}
|
|
#endif
|
|
else if (strcasecmp (argv [i], "-alt") == 0 ||
|
|
strcasecmp (argv [i], "-altsampledecode") == 0)
|
|
{
|
|
Settings.AltSampleDecode = 1;
|
|
}
|
|
else if (strcasecmp (argv [i], "-fix") == 0)
|
|
{
|
|
Settings.FixFrequency = 1;
|
|
}
|
|
else if (strcasecmp (argv [i], "-nosuperfx") == 0 ||
|
|
strcasecmp (argv [i], "-nosfx") == 0)
|
|
Settings.ForceNoSuperFX = TRUE;
|
|
else if (strcasecmp (argv [i], "-superfx") == 0 ||
|
|
strcasecmp (argv [i], "-sfx") == 0)
|
|
Settings.ForceSuperFX = TRUE;
|
|
else if (strcasecmp (argv [i], "-dsp1") == 0)
|
|
Settings.ForceDSP1 = TRUE;
|
|
else if (strcasecmp (argv [i], "-nodsp1") == 0)
|
|
Settings.ForceNoDSP1 = TRUE;
|
|
else if (strcasecmp (argv [i], "-nomp5") == 0)
|
|
Settings.MultiPlayer5Master = FALSE;
|
|
else if (strcasecmp (argv [i], "-nomouse") == 0)
|
|
Settings.MouseMaster = FALSE;
|
|
else if (strcasecmp (argv [i], "-nosuperscope") == 0)
|
|
Settings.SuperScopeMaster = FALSE;
|
|
else if (strcasecmp (argv [i], "-nojustifier") == 0)
|
|
Settings.JustifierMaster = FALSE;
|
|
else if (strcasecmp (argv[i], "-port1") == 0 ||
|
|
strcasecmp (argv[i], "-port2") == 0)
|
|
{
|
|
if (i + 1 < argc)
|
|
{
|
|
i++;
|
|
if(!parse_controller_spec(argv[i-1][5]-'1', argv[i]))
|
|
S9xUsage ();
|
|
}
|
|
else
|
|
S9xUsage ();
|
|
}
|
|
#ifdef NETPLAY_SUPPORT
|
|
else if (strcasecmp (argv [i], "-port") == 0 ||
|
|
strcasecmp (argv [i], "-po") == 0)
|
|
{
|
|
if (i + 1 < argc)
|
|
{
|
|
Settings.NetPlay = TRUE;
|
|
Settings.Port = -atoi (argv [++i]);
|
|
}
|
|
else
|
|
S9xUsage ();
|
|
}
|
|
else if (strcasecmp (argv [i], "-server") == 0 ||
|
|
strcasecmp (argv [i], "-srv") == 0)
|
|
{
|
|
if (i + 1 < argc)
|
|
{
|
|
Settings.NetPlay = TRUE;
|
|
strncpy (Settings.ServerName, argv [++i], 127);
|
|
Settings.ServerName [127] = 0;
|
|
}
|
|
else
|
|
S9xUsage ();
|
|
}
|
|
else if (strcasecmp (argv [i], "-net") == 0)
|
|
{
|
|
Settings.NetPlay = TRUE;
|
|
}
|
|
#endif
|
|
#ifdef STORM
|
|
else if (strcasecmp(argv[i],"-nosecondjoy")==0){secondjoy=0;}
|
|
else if (strcasecmp(argv[i],"-showfps")==0){dofps=1;}
|
|
else if (strcasecmp(argv[i],"-hicolor")==0){hicolor=1;}
|
|
else if (strcasecmp(argv[i],"-minimal")==0){minimal=1;printf("Keyboard with exception of ESC switched off!\n");}
|
|
else if (strcasecmp(argv[i],"-ahiunit")==0)
|
|
{
|
|
if (i+1<argc)
|
|
{
|
|
fprintf(stderr,"AHI Unit set to: Unit %i\n",atoi(argv[++i]));
|
|
unit=atoi(argv[++i]);
|
|
}
|
|
}
|
|
#endif
|
|
else if (strcasecmp (argv[i], "-dumpstreams") == 0)
|
|
dumpstreams = 1;
|
|
else if (strcasecmp (argv[i], "-maxframes") == 0)
|
|
maxframes = atoi(argv[++i]);
|
|
else if (strcasecmp (argv[i], "-mute") == 0)
|
|
Settings.Mute = 1;
|
|
else if (strcasecmp (argv[i], "-upanddown") == 0)
|
|
Settings.UpAndDown = 1;
|
|
else if (strcasecmp (argv[i], "-oldturbo") == 0)
|
|
Settings.OldTurbo = 1;
|
|
else if (strcasecmp(argv[i], "-autodemo") == 0) {
|
|
i++;
|
|
if (!argv[i])
|
|
abort();
|
|
strcpy(autodemo, argv[i]);
|
|
}
|
|
else if (strcasecmp(argv[i], "-keypress") == 0) // videologger output of controller 1
|
|
Settings.DisplayPressedKeys = 1;
|
|
else if (strcasecmp(argv[i], "-keypress2") == 0) // S9xDisplayMessages output of all controllers and peripherals
|
|
Settings.DisplayPressedKeys = 2;
|
|
else if (strcasecmp (argv [i], "-conf") == 0)
|
|
{
|
|
if (++i>=argc) S9xUsage();
|
|
// Else do nothing, S9xLoadConfigFiles() handled it
|
|
}
|
|
else if (strcasecmp (argv [i], "-nostdconf") == 0)
|
|
{
|
|
// Do nothing, S9xLoadConfigFiles() handled it
|
|
}
|
|
else if (strcasecmp (argv [i], "-version") == 0)
|
|
{
|
|
printf("Snes9X " VERSION "\n");
|
|
exit(0);
|
|
}
|
|
else if (strcasecmp (argv [i], "-help") == 0)
|
|
{
|
|
S9xUsage();
|
|
}
|
|
else if (strcasecmp (argv [i], "-multi") == 0)
|
|
{
|
|
Settings.Multi = TRUE;
|
|
}
|
|
else if (strcasecmp (argv [i], "-carta") == 0)
|
|
{
|
|
if (i + 1 < argc)
|
|
{
|
|
strncpy (Settings.CartAName, argv [++i], _MAX_PATH);
|
|
}
|
|
}
|
|
else if (strcasecmp (argv [i], "-cartb") == 0)
|
|
{
|
|
if (i + 1 < argc)
|
|
{
|
|
strncpy (Settings.CartBName, argv [++i], _MAX_PATH);
|
|
}
|
|
}
|
|
|
|
else
|
|
S9xParseArg (argv, i, argc);
|
|
}
|
|
else
|
|
rom_filename = argv [i];
|
|
}
|
|
|
|
S9xVerifyControllers();
|
|
|
|
#endif
|
|
|
|
return (rom_filename);
|
|
}
|
|
|
|
#ifndef NGC
|
|
void S9xParseCheatsFile (const char *rom_filename)
|
|
{
|
|
FILE *f;
|
|
char dir [_MAX_DIR];
|
|
char drive [_MAX_DRIVE];
|
|
char name [_MAX_FNAME];
|
|
char ext [_MAX_EXT];
|
|
char fname [_MAX_PATH];
|
|
char buf [80];
|
|
uint32 address;
|
|
uint8 byte;
|
|
uint8 bytes [3];
|
|
bool8 sram;
|
|
uint8 num_bytes;
|
|
const char *error;
|
|
char *p;
|
|
|
|
_splitpath (rom_filename, drive, dir, name, ext);
|
|
_makepath (fname, drive, dir, name, "pat");
|
|
|
|
if ((f = fopen(fname, "r")) != NULL)
|
|
{
|
|
while(fgets(buf, 80, f) != NULL)
|
|
{
|
|
if ((p = strrchr (buf, '\n')) != NULL)
|
|
*p = '\0';
|
|
if (((error = S9xGameGenieToRaw (buf, address, byte)) == NULL) ||
|
|
((error = S9xProActionReplayToRaw (buf, address, byte)) == NULL))
|
|
{
|
|
S9xAddCheat (TRUE, FALSE, address, byte);
|
|
}
|
|
else
|
|
if ((error = S9xGoldFingerToRaw (buf, address, sram,
|
|
num_bytes, bytes)) == NULL)
|
|
{
|
|
for (int c = 0; c < num_bytes; c++)
|
|
S9xAddCheat (TRUE, FALSE, address + c, bytes [c]);
|
|
}
|
|
else
|
|
S9xMessage (S9X_ERROR, S9X_GAME_GENIE_CODE_ERROR, error);
|
|
}
|
|
fclose(f);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifndef NGC
|
|
#include "conffile.h"
|
|
#include "crosshairs.h"
|
|
|
|
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(const char *fname, ConfigFile &conf){
|
|
STREAM fp;
|
|
if((fp=OPEN_STREAM(fname, "r"))!=NULL){
|
|
fprintf(stdout, "Reading config file %s\n", fname);
|
|
conf.LoadFile(new fReader(fp));
|
|
CLOSE_STREAM(fp);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void S9xLoadConfigFiles(char **argv, int argc){
|
|
int i;
|
|
bool skip=false;
|
|
|
|
for(i=0; i<argc; i++){
|
|
if(!strcasecmp(argv[i], "-nostdconf")){
|
|
skip=true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static ConfigFile conf; // static because some of its functions return pointers that would otherwise become invalid after this function
|
|
conf.Clear();
|
|
|
|
if(!skip){
|
|
#ifdef SYS_CONFIG_FILE
|
|
try_load(SYS_CONFIG_FILE, conf);
|
|
S9xParsePortConfig(conf, 0);
|
|
#endif
|
|
|
|
std::string fname;
|
|
fname=S9xGetDirectory(DEFAULT_DIR);
|
|
fname+=SLASH_STR "snes9x.conf";
|
|
if(!try_load(fname.c_str(), conf)){
|
|
fname=S9xGetDirectory(DEFAULT_DIR);
|
|
fname+=SLASH_STR "snes9x.cfg";
|
|
try_load(fname.c_str(), conf);
|
|
}
|
|
|
|
fname=S9xGetDirectory(ROM_DIR);
|
|
fname+=SLASH_STR "snes9x.conf";
|
|
if(!try_load(fname.c_str(), conf)){
|
|
fname=S9xGetDirectory(ROM_DIR);
|
|
fname+=SLASH_STR "snes9x.cfg";
|
|
try_load(fname.c_str(), conf);
|
|
}
|
|
} else {
|
|
fprintf(stderr, "Skipping standard config files\n");
|
|
}
|
|
|
|
for(i=0; i<argc-1; i++){
|
|
if(!strcasecmp(argv[i], "-conf")) try_load(argv[++i], conf);
|
|
}
|
|
|
|
/* Parse config file here */
|
|
Settings.NextAPUEnabled=conf.GetBool("Sound::APUEnabled", Settings.APUEnabled);
|
|
Settings.SoundSkipMethod=conf.GetInt("Sound::SoundSkip", 0);
|
|
i=conf.GetInt("CPU::HDMATimingHack", 100);
|
|
if(i>0 && i<200) Settings.HDMATimingHack = i;
|
|
Settings.DisableHDMA=conf.GetBool("Settings::DisableHDMA", false);
|
|
Settings.ShutdownMaster=conf.GetBool("Settings::SpeedHacks", false);
|
|
Settings.BlockInvalidVRAMAccess=conf.GetBool("Settings::BlockInvalidVRAMAccess", true);
|
|
Settings.ForcePAL=conf.GetBool("ROM::PAL", false);
|
|
Settings.ForceNTSC=conf.GetBool("ROM::NTSC", false);
|
|
if(!strcasecmp(conf.GetString("Settings::FrameSkip", "Auto"),"Auto")){
|
|
Settings.SkipFrames=AUTO_FRAMERATE;
|
|
} else {
|
|
Settings.SkipFrames=conf.GetUInt("Settings::FrameSkip", 0)+1;
|
|
}
|
|
Settings.TurboSkipFrames=conf.GetUInt("Settings::TurboFrameSkip", 15);
|
|
Settings.TurboMode=conf.GetBool("Settings::TurboMode",false);
|
|
Settings.StretchScreenshots=conf.GetInt("Settings::StretchScreenshots",1);
|
|
Settings.InitialInfoStringTimeout=conf.GetInt("Settings::MessageDisplayTime",120);
|
|
Settings.AutoSaveDelay=conf.GetUInt("Settings::AutoSaveDelay", 30);
|
|
Settings.ForceHiROM=conf.GetBool("ROM::HiROM", false);
|
|
Settings.ForceLoROM=conf.GetBool("ROM::LoROM", false);
|
|
if(conf.Exists("ROM::Header")){
|
|
Settings.ForceHeader=conf.GetBool("ROM::Header");
|
|
Settings.ForceNoHeader=!Settings.ForceHeader;
|
|
}
|
|
Settings.BS=conf.GetBool("ROM::BS", false);
|
|
#ifdef DEBUGGER
|
|
if(conf.GetBool("DEBUG::Debugger", false)) CPU.Flags |= DEBUG_MODE_FLAG;
|
|
if(conf.GetBool("DEBUG::Trace", false)){
|
|
if(!trace) trace = fopen ("trace.log", "wb");
|
|
CPU.Flags |= TRACE_FLAG;
|
|
}
|
|
#endif
|
|
Settings.BGLayering=conf.GetBool("Settings::BGLayeringHack", false);
|
|
if(conf.Exists("Display::Transparency")){
|
|
Settings.ForceTransparency=conf.GetBool("Display::Transparency", true);
|
|
Settings.ForceNoTransparency=!Settings.ForceTransparency;
|
|
}
|
|
Settings.SupportHiRes=conf.GetBool("Display::HiRes", true);
|
|
Settings.DisplayFrameRate=conf.GetBool("Display::FrameRate", false);
|
|
if(conf.Exists("Display::DisplayInput"))
|
|
Settings.DisplayPressedKeys=conf.GetBool("Display::DisplayInput", false)?1:0;
|
|
// GFX.FrameDisplay=conf.GetBool("Display::DisplayFrameCount", false);
|
|
GFX.FrameDisplay=TRUE;
|
|
Settings.AutoDisplayMessages=conf.GetBool("Display::MessagesInImage", true);
|
|
if(conf.Exists("ROM::Interleaved")){
|
|
Settings.ForceInterleaved=conf.GetBool("ROM::Interleaved", false);
|
|
Settings.ForceNotInterleaved=!Settings.ForceInterleaved;
|
|
}
|
|
Settings.ForceInterleaved2=conf.GetBool("ROM::Interleaved2", false);
|
|
Settings.ForceInterleaveGD24=conf.GetBool("ROM::InterleaveGD24", false);
|
|
Settings.DisableIRQ=conf.GetBool("CPU::DisableIRQ", false);
|
|
Settings.DisableGraphicWindows=!conf.GetBool("Display::GraphicWindows", true);
|
|
Settings.NoPatch=!conf.GetBool("ROM::Patch", true);
|
|
Settings.ApplyCheats=conf.GetBool("ROM::Cheat", true);
|
|
#ifdef DEBUG_MAXCOUNT
|
|
if(conf.Exists("DEBUG::MaxCount")){
|
|
Settings.MaxCount = conf.GetUInt("DEBUG::MaxCount", 1);
|
|
fprintf(stderr, "Running for a maximum of %d loops.\n", Settings.MaxCount);
|
|
}
|
|
#endif
|
|
Settings.Mode7Interpolate=conf.GetBool("Display::Mode7Interpolate", false);
|
|
Settings.FrameTimePAL=conf.GetUInt("Settings::PALFrameTime", 20000);
|
|
Settings.FrameTimeNTSC=conf.GetUInt("Settings::NTSCFrameTime", 16667);
|
|
if(conf.Exists("Settings::FrameTime")){
|
|
double ft;
|
|
if (sscanf(conf.GetString("Settings::FrameTime"), "%lf", &ft) == 1)
|
|
{
|
|
Settings.FrameTimePAL = (int32) ft;
|
|
Settings.FrameTimeNTSC = (int32) ft;
|
|
}
|
|
}
|
|
Settings.FrameTime = Settings.FrameTimeNTSC;
|
|
Settings.DisableSoundEcho=!conf.GetBool("Sound::Echo", true);
|
|
Settings.SoundPlaybackRate=conf.GetUInt("Sound::Rate", Settings.SoundPlaybackRate) & 7;
|
|
Settings.SoundBufferSize=conf.GetUInt("Sound::BufferSize", Settings.SoundBufferSize);
|
|
if(conf.Exists("Sound::Stereo")){
|
|
Settings.Stereo = conf.GetBool("Sound::Stereo");
|
|
Settings.APUEnabled = TRUE;
|
|
Settings.NextAPUEnabled = TRUE;
|
|
}
|
|
if(conf.Exists("Sound::Mono")){
|
|
Settings.Stereo = !conf.GetBool("Sound::Mono");
|
|
Settings.NextAPUEnabled = TRUE;
|
|
}
|
|
Settings.SoundEnvelopeHeightReading=conf.GetBool("Sound::EnvelopeHeightReading");
|
|
Settings.DisableSampleCaching=!conf.GetBool("Sound::SampleCaching");
|
|
Settings.DisableMasterVolume=!conf.GetBool("Sound::MasterVolume");
|
|
Settings.InterpolatedSound=conf.GetBool("Sound::Interpolate", true);
|
|
if(conf.Exists("Sound::Sync")){
|
|
Settings.SoundSync=conf.GetInt("Sound::Sync", 1);
|
|
if(Settings.SoundSync>2) Settings.SoundSync=1;
|
|
Settings.SoundEnvelopeHeightReading = TRUE;
|
|
Settings.InterpolatedSound = TRUE;
|
|
}
|
|
#ifdef USE_THREADS
|
|
Settings.ThreadSound=conf.GetBool("Sound::ThreadSound", false);
|
|
#endif
|
|
if(conf.Exists("Sound::AltDecode")){
|
|
Settings.AltSampleDecode=conf.GetInt("Sound::AltDecode", 1);
|
|
}
|
|
if(conf.Exists("Sound::FixFrequency")){
|
|
Settings.FixFrequency=conf.GetInt("Sound::FixFrequency", 1);
|
|
}
|
|
if(conf.Exists("ROM::SuperFX")){
|
|
Settings.ForceSuperFX=conf.GetBool("ROM::SuperFX");
|
|
Settings.ForceNoSuperFX=!Settings.ForceSuperFX;
|
|
}
|
|
if(conf.Exists("ROM::DSP1")){
|
|
Settings.ForceDSP1=conf.GetBool("ROM::DSP1");
|
|
Settings.ForceNoDSP1=!Settings.ForceDSP1;
|
|
}
|
|
Settings.MultiPlayer5Master=conf.GetBool("Controls::MP5Master", true);
|
|
Settings.MouseMaster=conf.GetBool("Controls::MouseMaster", true);
|
|
Settings.SuperScopeMaster=conf.GetBool("Controls::SuperscopeMaster", true);
|
|
Settings.JustifierMaster=conf.GetBool("Controls::JustifierMaster", true);
|
|
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"));
|
|
}
|
|
#ifdef NETPLAY_SUPPORT
|
|
Settings.Port = NP_DEFAULT_PORT;
|
|
if(conf.Exists("Netplay::Port")){
|
|
Settings.NetPlay = TRUE;
|
|
Settings.Port = -(int)conf.GetUInt("Netplay::Port");
|
|
}
|
|
Settings.ServerName[0]='\0';
|
|
if(conf.Exists("Netplay::Server")){
|
|
Settings.NetPlay = TRUE;
|
|
conf.GetString("Netplay::Server", Settings.ServerName, 128);
|
|
}
|
|
Settings.NetPlay=conf.GetBool("Netplay::Enable");
|
|
#endif
|
|
#ifdef STORM
|
|
secondjoy=conf.GetBool("STORM::EnableSecondJoy",true)?1:0;
|
|
dofps=conf.GetBool("STORM::ShowFPS",false)?1:0;
|
|
hicolor=conf.GetBool("STORM::HiColor",false)?1:0;
|
|
if((minimal=conf.GetBool("STORM::Minimal")?1:0)){
|
|
printf("Keyboard with exception of ESC switched off!\n");
|
|
}
|
|
if(conf.Exists("STORM::AHIunit")){
|
|
unit=conf.GetInt("STORM::AHIunit",0);
|
|
fprintf(stderr,"AHI Unit set to: Unit %i\n",unit);
|
|
}
|
|
#endif
|
|
Settings.JoystickEnabled=conf.GetBool("Controls::Joystick", Settings.JoystickEnabled);
|
|
Settings.UpAndDown=conf.GetBool("Controls::AllowLeftRight", false);
|
|
Settings.SnapshotScreenshots=conf.GetBool("Settings::SnapshotScreenshots", true);
|
|
Settings.MovieTruncate=conf.GetBool("Settings::MovieTruncateAtEnd", false);
|
|
Settings.MovieNotifyIgnored=conf.GetBool("Settings::MovieNotifyIgnored", false);
|
|
Settings.DisplayWatchedAddresses=conf.GetBool("Settings::DisplayWatchedAddresses", false);
|
|
Settings.WrongMovieStateProtection=conf.GetBool("Settings::WrongMovieStateProtection", true);
|
|
rom_filename=conf.GetStringDup("ROM::Filename", NULL);
|
|
|
|
S9xParsePortConfig(conf, 1);
|
|
S9xVerifyControllers();
|
|
}
|
|
|
|
#endif /*** Nintendo Gamecube Exclusion ***/
|