- merged the main.cpp code into sdl.cpp and a new config.cpp
- config.cpp contains the configuration and args parsing
This commit is contained in:
parent
c39de3f8a8
commit
3ee6888bbd
|
@ -1,6 +1,6 @@
|
||||||
my_list = Split("""
|
my_list = Split("""
|
||||||
input.cpp
|
input.cpp
|
||||||
main.cpp
|
config.cpp
|
||||||
sdl.cpp
|
sdl.cpp
|
||||||
sdl-joystick.cpp
|
sdl-joystick.cpp
|
||||||
sdl-sound.cpp
|
sdl-sound.cpp
|
||||||
|
|
|
@ -0,0 +1,366 @@
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "throttle.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "../common/cheat.h"
|
||||||
|
|
||||||
|
#include "input.h"
|
||||||
|
#include "dface.h"
|
||||||
|
|
||||||
|
#include "sdl.h"
|
||||||
|
#include "sdl-video.h"
|
||||||
|
#include "unix-netplay.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int frameskip;
|
||||||
|
char *cpalette;
|
||||||
|
char *soundrecfn;
|
||||||
|
int ntsccol, ntschue, ntsctint;
|
||||||
|
char *DrBaseDirectory;
|
||||||
|
|
||||||
|
DSETTINGS Settings;
|
||||||
|
CFGSTRUCT DriverConfig[]={
|
||||||
|
#ifdef OPENGL
|
||||||
|
AC(_stretchx),
|
||||||
|
AC(_stretchy),
|
||||||
|
AC(_opengl),
|
||||||
|
AC(_openglip),
|
||||||
|
#endif
|
||||||
|
AC(Settings.special),
|
||||||
|
AC(Settings.specialfs),
|
||||||
|
AC(_doublebuf),
|
||||||
|
AC(_xscale),
|
||||||
|
AC(_yscale),
|
||||||
|
AC(_xscalefs),
|
||||||
|
AC(_yscalefs),
|
||||||
|
AC(_bpp),
|
||||||
|
AC(_efx),
|
||||||
|
AC(_efxfs),
|
||||||
|
AC(_fullscreen),
|
||||||
|
AC(_xres),
|
||||||
|
AC(_yres),
|
||||||
|
ACS(netplaynick),
|
||||||
|
AC(netlocalplayers),
|
||||||
|
AC(tport),
|
||||||
|
ACS(netpassword),
|
||||||
|
ACS(netgamekey),
|
||||||
|
ENDCFGSTRUCT
|
||||||
|
};
|
||||||
|
|
||||||
|
//-fshack x Set the environment variable SDL_VIDEODRIVER to \"x\" when
|
||||||
|
// entering full screen mode and x is not \"0\".
|
||||||
|
|
||||||
|
char *DriverUsage=
|
||||||
|
"-xres x Set horizontal resolution to x for full screen mode.\n\
|
||||||
|
-yres x Set vertical resolution to x for full screen mode.\n\
|
||||||
|
-xscale(fs) x Multiply width by x(Real numbers >0 with OpenGL, otherwise integers >0).\n\
|
||||||
|
-yscale(fs) x Multiply height by x(Real numbers >0 with OpenGL, otherwise integers >0).\n\
|
||||||
|
-bpp(fs) x Bits per pixel for SDL surface(and video mode in fs). 8, 16, 32.\n\
|
||||||
|
-opengl x Enable OpenGL support if x is 1.\n\
|
||||||
|
-openglip x Enable OpenGL linear interpolation if x is 1.\n\
|
||||||
|
-doublebuf x \n\
|
||||||
|
-special(fs) x Specify special scaling filter.\n\
|
||||||
|
-stretch(x/y) x Stretch to fill surface on x or y axis(fullscreen, only with OpenGL).\n\
|
||||||
|
-efx(fs) x Enable special effects. Logically OR the following together:\n\
|
||||||
|
1 = scanlines(for yscale>=2).\n\
|
||||||
|
2 = TV blur(for bpp of 16 or 32).\n\
|
||||||
|
-fs x Select full screen mode if x is non zero.\n\
|
||||||
|
-connect s Connect to server 's' for TCP/IP network play.\n\
|
||||||
|
-netnick s Set the nickname to use in network play.\n\
|
||||||
|
-netgamekey s Use key 's' to create a unique session for the game loaded.\n\
|
||||||
|
-netpassword s Password to use for connecting to the server.\n\
|
||||||
|
-netlocalplayers x Set the number of local players.\n\
|
||||||
|
-netport x Use TCP/IP port x for network play.";
|
||||||
|
|
||||||
|
ARGPSTRUCT DriverArgs[]={
|
||||||
|
#ifdef OPENGL
|
||||||
|
{"-opengl",0,&_opengl,0},
|
||||||
|
{"-openglip",0,&_openglip,0},
|
||||||
|
{"-stretchx",0,&_stretchx,0},
|
||||||
|
{"-stretchy",0,&_stretchy,0},
|
||||||
|
#endif
|
||||||
|
{"-special",0,&Settings.special,0},
|
||||||
|
{"-specialfs",0,&Settings.specialfs,0},
|
||||||
|
{"-doublebuf",0,&_doublebuf,0},
|
||||||
|
{"-bpp",0,&_bpp,0},
|
||||||
|
{"-xscale",0,&_xscale,2},
|
||||||
|
{"-yscale",0,&_yscale,2},
|
||||||
|
{"-efx",0,&_efx,0},
|
||||||
|
{"-xscalefs",0,&_xscalefs,2},
|
||||||
|
{"-yscalefs",0,&_yscalefs,2},
|
||||||
|
{"-efxfs",0,&_efxfs,0},
|
||||||
|
{"-xres",0,&_xres,0},
|
||||||
|
{"-yres",0,&_yres,0},
|
||||||
|
{"-fs",0,&_fullscreen,0},
|
||||||
|
//{"-fshack",0,&_fshack,0x4001},
|
||||||
|
{"-connect",0,&netplayhost,0x4001},
|
||||||
|
{"-netport",0,&tport,0},
|
||||||
|
{"-netlocalplayers",0,&netlocalplayers,0},
|
||||||
|
{"-netnick",0,&netplaynick,0x4001},
|
||||||
|
{"-netpassword",0,&netpassword,0x4001},
|
||||||
|
{0,0,0,0}
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "usage.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
SetDefaults(void)
|
||||||
|
{
|
||||||
|
Settings.special=Settings.specialfs=0;
|
||||||
|
_bpp=8;
|
||||||
|
_xres=640;
|
||||||
|
_yres=480;
|
||||||
|
_fullscreen=0;
|
||||||
|
_xscale=2.50;
|
||||||
|
_yscale=2;
|
||||||
|
_xscalefs=_yscalefs=2;
|
||||||
|
_efx=_efxfs=0;
|
||||||
|
//_fshack=_fshacksave=0;
|
||||||
|
#ifdef OPENGL
|
||||||
|
_opengl=1;
|
||||||
|
_stretchx=1;
|
||||||
|
_stretchy=0;
|
||||||
|
_openglip=1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unimplemented.
|
||||||
|
*/
|
||||||
|
void DoDriverArgs(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles arguments passed to FCEU. Hopefully obsolete with new
|
||||||
|
* configuration system.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
DoArgs(int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
static ARGPSTRUCT FCEUArgs[]={
|
||||||
|
{"-soundbufsize",0,&soundbufsize,0},
|
||||||
|
{"-soundrate",0,&soundrate,0},
|
||||||
|
{"-soundq",0,&soundq,0},
|
||||||
|
#ifdef FRAMESKIP
|
||||||
|
{"-frameskip",0,&frameskip,0},
|
||||||
|
#endif
|
||||||
|
{"-sound",0,&_sound,0},
|
||||||
|
{"-soundvol",0,&soundvol,0},
|
||||||
|
{"-cpalette",0,&cpalette,0x4001},
|
||||||
|
{"-soundrecord",0,&soundrecfn,0x4001},
|
||||||
|
|
||||||
|
{"-ntsccol",0,&ntsccol,0},
|
||||||
|
{"-pal",0,&eoptions,0x8000|EO_PAL},
|
||||||
|
|
||||||
|
{"-lowpass",0,&eoptions,0x8000|EO_LOWPASS},
|
||||||
|
{"-gg",0,&eoptions,0x8000|EO_GAMEGENIE},
|
||||||
|
{"-no8lim",0,&eoptions,0x8001},
|
||||||
|
{"-snapname",0,&eoptions,0x8000|EO_SNAPNAME},
|
||||||
|
{"-nofs",0,&eoptions,0x8000|EO_NOFOURSCORE},
|
||||||
|
{"-clipsides",0,&eoptions,0x8000|EO_CLIPSIDES},
|
||||||
|
{"-nothrottle",0,&eoptions,0x8000|EO_NOTHROTTLE},
|
||||||
|
{"-slstart",0,&srendlinev[0],0},{"-slend",0,&erendlinev[0],0},
|
||||||
|
{"-slstartp",0,&srendlinev[1],0},{"-slendp",0,&erendlinev[1],0},
|
||||||
|
{0,(int *)InputArgs,0,0},
|
||||||
|
{0,(int *)DriverArgs,0,0},
|
||||||
|
{0,0,0,0}
|
||||||
|
};
|
||||||
|
|
||||||
|
ParseArguments(argc, argv, FCEUArgs);
|
||||||
|
if(cpalette) {
|
||||||
|
if(cpalette[0] == '0') {
|
||||||
|
if(cpalette[1] == 0) {
|
||||||
|
free(cpalette);
|
||||||
|
cpalette=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FCEUI_SetVidSystem((eoptions&EO_PAL)?1:0);
|
||||||
|
FCEUI_SetGameGenie((eoptions&EO_GAMEGENIE)?1:0);
|
||||||
|
FCEUI_SetLowPass((eoptions&EO_LOWPASS)?1:0);
|
||||||
|
|
||||||
|
FCEUI_DisableSpriteLimitation(eoptions&1);
|
||||||
|
FCEUI_SetSnapName(eoptions&EO_SNAPNAME);
|
||||||
|
|
||||||
|
for(x = 0; x < 2; x++) {
|
||||||
|
if(srendlinev[x]<0 || srendlinev[x]>239) srendlinev[x]=0;
|
||||||
|
if(erendlinev[x]<srendlinev[x] || erendlinev[x]>239) erendlinev[x]=239;
|
||||||
|
}
|
||||||
|
|
||||||
|
FCEUI_SetRenderedLines(srendlinev[0],erendlinev[0],srendlinev[1],erendlinev[1]);
|
||||||
|
DoDriverArgs();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a custom pallete from a file and load it into the core.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
LoadCPalette()
|
||||||
|
{
|
||||||
|
uint8 tmpp[192];
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
if(!(fp = FCEUD_UTF8fopen(cpalette, "rb"))) {
|
||||||
|
printf(" Error loading custom palette from file: %s\n", cpalette);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fread(tmpp, 1, 192, fp);
|
||||||
|
FCEUI_SetPaletteArray(tmpp);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static CFGSTRUCT fceuconfig[]= {
|
||||||
|
AC(soundrate),
|
||||||
|
AC(soundq),
|
||||||
|
AC(_sound),
|
||||||
|
AC(soundvol),
|
||||||
|
AC(soundbufsize),
|
||||||
|
ACS(cpalette),
|
||||||
|
AC(ntsctint),
|
||||||
|
AC(ntschue),
|
||||||
|
AC(ntsccol),
|
||||||
|
AC(eoptions),
|
||||||
|
ACA(srendlinev),
|
||||||
|
ACA(erendlinev),
|
||||||
|
ADDCFGSTRUCT(InputConfig),
|
||||||
|
ADDCFGSTRUCT(DriverConfig),
|
||||||
|
ENDCFGSTRUCT
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for SaveFCEUConfig() that sets the path. Hopefully
|
||||||
|
* obsolete with new configuration system.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
SaveConfig()
|
||||||
|
{
|
||||||
|
char tdir[2048];
|
||||||
|
sprintf(tdir,"%s"PSS"fceu98.cfg", DrBaseDirectory);
|
||||||
|
FCEUI_GetNTSCTH(&ntsctint, &ntschue);
|
||||||
|
SaveFCEUConfig(tdir, fceuconfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for LoadFCEUConfig() that sets the path. Hopefully
|
||||||
|
* obsolete with the new configuration system.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
LoadConfig()
|
||||||
|
{
|
||||||
|
char tdir[2048];
|
||||||
|
sprintf(tdir,"%s"PSS"fceu98.cfg",DrBaseDirectory);
|
||||||
|
|
||||||
|
/* Get default settings for if no config file exists. */
|
||||||
|
FCEUI_GetNTSCTH(&ntsctint, &ntschue);
|
||||||
|
LoadFCEUConfig(tdir,fceuconfig);
|
||||||
|
InputUserActiveFix();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the subdirectories used for saving snapshots, movies, game
|
||||||
|
* saves, etc. Hopefully obsolete with new configuration system.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
CreateDirs(void)
|
||||||
|
{
|
||||||
|
char *subs[7]={"fcs","fcm","snaps","gameinfo","sav","cheats","movie"};
|
||||||
|
char tdir[2048];
|
||||||
|
int x;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
mkdir((char *)DrBaseDirectory);
|
||||||
|
for(x = 0; x < 6; x++) {
|
||||||
|
sprintf(tdir,"%s"PSS"%s",DrBaseDirectory,subs[x]);
|
||||||
|
mkdir(tdir);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
mkdir((char *)DrBaseDirectory,S_IRWXU);
|
||||||
|
for(x = 0; x < 6; x++) {
|
||||||
|
sprintf(tdir,"%s"PSS"%s",DrBaseDirectory,subs[x]);
|
||||||
|
mkdir(tdir,S_IRWXU);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to locate FCEU's application directory. This will
|
||||||
|
* hopefully become obsolete once the new configuration system is in
|
||||||
|
* place.
|
||||||
|
*/
|
||||||
|
static uint8 *
|
||||||
|
GetBaseDirectory()
|
||||||
|
{
|
||||||
|
uint8 *ol;
|
||||||
|
uint8 *ret;
|
||||||
|
|
||||||
|
ol=(uint8 *)getenv("HOME");
|
||||||
|
|
||||||
|
if(ol) {
|
||||||
|
ret=(uint8 *)malloc(strlen((char *)ol)+1+strlen("./fceultra"));
|
||||||
|
strcpy((char *)ret,(char *)ol);
|
||||||
|
strcat((char *)ret,"/.fceultra");
|
||||||
|
} else {
|
||||||
|
#ifdef WIN32
|
||||||
|
char *sa;
|
||||||
|
|
||||||
|
ret=(uint8*)malloc(MAX_PATH+1);
|
||||||
|
GetModuleFileName(NULL,(char*)ret,MAX_PATH+1);
|
||||||
|
|
||||||
|
sa=strrchr((char*)ret,'\\');
|
||||||
|
if(sa)
|
||||||
|
*sa = 0;
|
||||||
|
#else
|
||||||
|
ret=(uint8 *)malloc(sizeof(uint8));
|
||||||
|
ret[0]=0;
|
||||||
|
#endif
|
||||||
|
printf("%s\n",ret);
|
||||||
|
}
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
InitConfig(int argc,
|
||||||
|
char **argv)
|
||||||
|
{
|
||||||
|
DrBaseDirectory = (char *)GetBaseDirectory();
|
||||||
|
FCEUI_SetBaseDirectory(DrBaseDirectory);
|
||||||
|
|
||||||
|
CreateDirs();
|
||||||
|
|
||||||
|
if(argc<=1) {
|
||||||
|
ShowUsage(argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
LoadConfig();
|
||||||
|
DoArgs(argc - 2, &argv[1]);
|
||||||
|
|
||||||
|
FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue);
|
||||||
|
if(cpalette) {
|
||||||
|
LoadCPalette();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
extern int frameskip;
|
||||||
|
extern char *cpalette;
|
||||||
|
extern char *soundrecfn;
|
||||||
|
extern int ntsccol, ntschue, ntsctint;
|
||||||
|
extern char *DrBaseDirectory;
|
||||||
|
|
||||||
|
int InitConfig(int, char **);
|
||||||
|
void SaveConfig(void);
|
||||||
|
void SetDefaults(void);
|
|
@ -10,7 +10,6 @@ extern ARGPSTRUCT DriverArgs[];
|
||||||
extern char *DriverUsage;
|
extern char *DriverUsage;
|
||||||
|
|
||||||
void DoDriverArgs(void);
|
void DoDriverArgs(void);
|
||||||
uint8 *GetBaseDirectory(void);
|
|
||||||
|
|
||||||
int InitSound(FCEUGI *gi);
|
int InitSound(FCEUGI *gi);
|
||||||
void WriteSound(int32 *Buffer, int Count);
|
void WriteSound(int32 *Buffer, int Count);
|
||||||
|
|
|
@ -1,604 +0,0 @@
|
||||||
/* FCE Ultra - NES/Famicom Emulator
|
|
||||||
*
|
|
||||||
* Copyright notice for this file:
|
|
||||||
* Copyright (C) 2002 Xodnizel
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
/// \file
|
|
||||||
/// \brief A set of functions for dealing with the main execution loop. Much of this code will likely be dispersed to sdl.cpp and other files since we no longer support non-SDL and non-Windows builds.
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <strings.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
#include "throttle.h"
|
|
||||||
|
|
||||||
#include "../common/cheat.h"
|
|
||||||
|
|
||||||
#include "input.h"
|
|
||||||
#include "dface.h"
|
|
||||||
|
|
||||||
extern int32 fps_scale;
|
|
||||||
|
|
||||||
int CloseGame(void);
|
|
||||||
|
|
||||||
static char *soundrecfn=0; /* File name of sound recording. */
|
|
||||||
|
|
||||||
static int ntsccol=0,ntschue=0,ntsctint=0;
|
|
||||||
int soundvol=100;
|
|
||||||
long soundq=0;
|
|
||||||
int _sound=1;
|
|
||||||
long soundrate=48000;
|
|
||||||
#ifdef WIN32
|
|
||||||
long soundbufsize=52;
|
|
||||||
#else
|
|
||||||
long soundbufsize=24;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef FRAMESKIP
|
|
||||||
static int frameskip=0;
|
|
||||||
#endif
|
|
||||||
static int inited=0;
|
|
||||||
static int isloaded=0; // Is game loaded?
|
|
||||||
|
|
||||||
int srendlinev[2]={8,0};
|
|
||||||
int erendlinev[2]={231,239};
|
|
||||||
|
|
||||||
|
|
||||||
static uint8 *DrBaseDirectory;
|
|
||||||
|
|
||||||
int eoptions=0;
|
|
||||||
|
|
||||||
static void DriverKill(void);
|
|
||||||
static int DriverInitialize(FCEUGI *gi);
|
|
||||||
int gametype = 0;
|
|
||||||
|
|
||||||
FCEUGI *CurGame=NULL;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for ParseGIInput().
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
ParseGI(FCEUGI *gi)
|
|
||||||
{
|
|
||||||
ParseGIInput(gi);
|
|
||||||
gametype = gi->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints an error string to STDOUT.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
FCEUD_PrintError(char *s)
|
|
||||||
{
|
|
||||||
puts(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints the given string to STDOUT.
|
|
||||||
*/
|
|
||||||
void FCEUD_Message(char *s)
|
|
||||||
{
|
|
||||||
fputs(s, stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *cpalette=0;
|
|
||||||
/**
|
|
||||||
* Read a custom pallete from a file and load it into the core.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
LoadCPalette()
|
|
||||||
{
|
|
||||||
uint8 tmpp[192];
|
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
if(!(fp = FCEUD_UTF8fopen(cpalette, "rb"))) {
|
|
||||||
printf(" Error loading custom palette from file: %s\n", cpalette);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fread(tmpp, 1, 192, fp);
|
|
||||||
FCEUI_SetPaletteArray(tmpp);
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static CFGSTRUCT fceuconfig[]={
|
|
||||||
AC(soundrate),
|
|
||||||
AC(soundq),
|
|
||||||
AC(_sound),
|
|
||||||
AC(soundvol),
|
|
||||||
AC(soundbufsize),
|
|
||||||
ACS(cpalette),
|
|
||||||
AC(ntsctint),
|
|
||||||
AC(ntschue),
|
|
||||||
AC(ntsccol),
|
|
||||||
AC(eoptions),
|
|
||||||
ACA(srendlinev),
|
|
||||||
ACA(erendlinev),
|
|
||||||
ADDCFGSTRUCT(InputConfig),
|
|
||||||
ADDCFGSTRUCT(DriverConfig),
|
|
||||||
ENDCFGSTRUCT
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for SaveFCEUConfig() that sets the path. Hopefully
|
|
||||||
* obsolete with new configuration system.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
SaveConfig()
|
|
||||||
{
|
|
||||||
char tdir[2048];
|
|
||||||
sprintf(tdir,"%s"PSS"fceu98.cfg", DrBaseDirectory);
|
|
||||||
FCEUI_GetNTSCTH(&ntsctint, &ntschue);
|
|
||||||
SaveFCEUConfig(tdir, fceuconfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for LoadFCEUConfig() that sets the path. Hopefully
|
|
||||||
* obsolete with the new configuration system.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
LoadConfig()
|
|
||||||
{
|
|
||||||
char tdir[2048];
|
|
||||||
sprintf(tdir,"%s"PSS"fceu98.cfg",DrBaseDirectory);
|
|
||||||
|
|
||||||
/* Get default settings for if no config file exists. */
|
|
||||||
FCEUI_GetNTSCTH(&ntsctint, &ntschue);
|
|
||||||
LoadFCEUConfig(tdir,fceuconfig);
|
|
||||||
InputUserActiveFix();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the subdirectories used for saving snapshots, movies, game
|
|
||||||
* saves, etc. Hopefully obsolete with new configuration system.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
CreateDirs(void)
|
|
||||||
{
|
|
||||||
char *subs[7]={"fcs","fcm","snaps","gameinfo","sav","cheats","movie"};
|
|
||||||
char tdir[2048];
|
|
||||||
int x;
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
mkdir((char *)DrBaseDirectory);
|
|
||||||
for(x = 0; x < 6; x++) {
|
|
||||||
sprintf(tdir,"%s"PSS"%s",DrBaseDirectory,subs[x]);
|
|
||||||
mkdir(tdir);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
mkdir((char *)DrBaseDirectory,S_IRWXU);
|
|
||||||
for(x = 0; x < 6; x++) {
|
|
||||||
sprintf(tdir,"%s"PSS"%s",DrBaseDirectory,subs[x]);
|
|
||||||
mkdir(tdir,S_IRWXU);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef WIN32
|
|
||||||
/**
|
|
||||||
* Capture and handle signals sent to FCEU.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
SetSignals(void (*t)(int))
|
|
||||||
{
|
|
||||||
// XXX soules - why do we capture these? Seems unnecessary.
|
|
||||||
int sigs[11]={SIGINT,SIGTERM,SIGHUP,SIGPIPE,SIGSEGV,SIGFPE,SIGKILL,SIGALRM,SIGABRT,SIGUSR1,SIGUSR2};
|
|
||||||
int x;
|
|
||||||
for(x = 0; x < 11; x++) {
|
|
||||||
signal(sigs[x], t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
CloseStuff(int signum)
|
|
||||||
{
|
|
||||||
// XXX soules - again, not clear why this is necessary
|
|
||||||
DriverKill();
|
|
||||||
printf("\nSignal %d has been caught and dealt with...\n",signum);
|
|
||||||
switch(signum) {
|
|
||||||
case SIGINT:printf("How DARE you interrupt me!\n");break;
|
|
||||||
case SIGTERM:printf("MUST TERMINATE ALL HUMANS\n");break;
|
|
||||||
case SIGHUP:printf("Reach out and hang-up on someone.\n");break;
|
|
||||||
case SIGPIPE:printf("The pipe has broken! Better watch out for floods...\n");break;
|
|
||||||
case SIGSEGV:printf("Iyeeeeeeeee!!! A segmentation fault has occurred. Have a fluffy day.\n");break;
|
|
||||||
/* So much SIGBUS evil. */
|
|
||||||
#ifdef SIGBUS
|
|
||||||
#if(SIGBUS!=SIGSEGV)
|
|
||||||
case SIGBUS:printf("I told you to be nice to the driver.\n");break;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
case SIGFPE:printf("Those darn floating points. Ne'er know when they'll bite!\n");break;
|
|
||||||
case SIGALRM:printf("Don't throw your clock at the meowing cats!\n");break;
|
|
||||||
case SIGABRT:printf("Abort, Retry, Ignore, Fail?\n");break;
|
|
||||||
case SIGUSR1:
|
|
||||||
case SIGUSR2:printf("Killing your processes is not nice.\n");break;
|
|
||||||
}
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles arguments passed to FCEU. Hopefully obsolete with new
|
|
||||||
* configuration system.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
DoArgs(int argc,
|
|
||||||
char *argv[])
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
|
|
||||||
static ARGPSTRUCT FCEUArgs[]={
|
|
||||||
{"-soundbufsize",0,&soundbufsize,0},
|
|
||||||
{"-soundrate",0,&soundrate,0},
|
|
||||||
{"-soundq",0,&soundq,0},
|
|
||||||
#ifdef FRAMESKIP
|
|
||||||
{"-frameskip",0,&frameskip,0},
|
|
||||||
#endif
|
|
||||||
{"-sound",0,&_sound,0},
|
|
||||||
{"-soundvol",0,&soundvol,0},
|
|
||||||
{"-cpalette",0,&cpalette,0x4001},
|
|
||||||
{"-soundrecord",0,&soundrecfn,0x4001},
|
|
||||||
|
|
||||||
{"-ntsccol",0,&ntsccol,0},
|
|
||||||
{"-pal",0,&eoptions,0x8000|EO_PAL},
|
|
||||||
|
|
||||||
{"-lowpass",0,&eoptions,0x8000|EO_LOWPASS},
|
|
||||||
{"-gg",0,&eoptions,0x8000|EO_GAMEGENIE},
|
|
||||||
{"-no8lim",0,&eoptions,0x8001},
|
|
||||||
{"-snapname",0,&eoptions,0x8000|EO_SNAPNAME},
|
|
||||||
{"-nofs",0,&eoptions,0x8000|EO_NOFOURSCORE},
|
|
||||||
{"-clipsides",0,&eoptions,0x8000|EO_CLIPSIDES},
|
|
||||||
{"-nothrottle",0,&eoptions,0x8000|EO_NOTHROTTLE},
|
|
||||||
{"-slstart",0,&srendlinev[0],0},{"-slend",0,&erendlinev[0],0},
|
|
||||||
{"-slstartp",0,&srendlinev[1],0},{"-slendp",0,&erendlinev[1],0},
|
|
||||||
{0,(int *)InputArgs,0,0},
|
|
||||||
{0,(int *)DriverArgs,0,0},
|
|
||||||
{0,0,0,0}
|
|
||||||
};
|
|
||||||
|
|
||||||
ParseArguments(argc, argv, FCEUArgs);
|
|
||||||
if(cpalette) {
|
|
||||||
if(cpalette[0] == '0') {
|
|
||||||
if(cpalette[1] == 0) {
|
|
||||||
free(cpalette);
|
|
||||||
cpalette=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FCEUI_SetVidSystem((eoptions&EO_PAL)?1:0);
|
|
||||||
FCEUI_SetGameGenie((eoptions&EO_GAMEGENIE)?1:0);
|
|
||||||
FCEUI_SetLowPass((eoptions&EO_LOWPASS)?1:0);
|
|
||||||
|
|
||||||
FCEUI_DisableSpriteLimitation(eoptions&1);
|
|
||||||
FCEUI_SetSnapName(eoptions&EO_SNAPNAME);
|
|
||||||
|
|
||||||
for(x = 0; x < 2; x++) {
|
|
||||||
if(srendlinev[x]<0 || srendlinev[x]>239) srendlinev[x]=0;
|
|
||||||
if(erendlinev[x]<srendlinev[x] || erendlinev[x]>239) erendlinev[x]=239;
|
|
||||||
}
|
|
||||||
|
|
||||||
FCEUI_SetRenderedLines(srendlinev[0],erendlinev[0],srendlinev[1],erendlinev[1]);
|
|
||||||
DoDriverArgs();
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "usage.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a game, given a full path/filename. The driver code must be
|
|
||||||
* initialized after the game is loaded, because the emulator code
|
|
||||||
* provides data necessary for the driver code(number of scanlines to
|
|
||||||
* render, what virtual input devices to use, etc.).
|
|
||||||
*/
|
|
||||||
int LoadGame(const char *path)
|
|
||||||
{
|
|
||||||
FCEUGI *tmp;
|
|
||||||
|
|
||||||
CloseGame();
|
|
||||||
if(!(tmp = FCEUI_LoadGame(path, 1))) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
CurGame=tmp;
|
|
||||||
ParseGI(tmp);
|
|
||||||
RefreshThrottleFPS();
|
|
||||||
|
|
||||||
if(!DriverInitialize(tmp)) {
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
if(soundrecfn) {
|
|
||||||
if(!FCEUI_BeginWaveRecord(soundrecfn)) {
|
|
||||||
free(soundrecfn);
|
|
||||||
soundrecfn=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
isloaded=1;
|
|
||||||
|
|
||||||
FCEUD_NetworkConnect();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Closes a game. Frees memory, and deinitializes the drivers.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
CloseGame()
|
|
||||||
{
|
|
||||||
if(!isloaded) {
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
FCEUI_CloseGame();
|
|
||||||
DriverKill();
|
|
||||||
isloaded=0;
|
|
||||||
CurGame=0;
|
|
||||||
|
|
||||||
if(soundrecfn) {
|
|
||||||
FCEUI_EndWaveRecord();
|
|
||||||
}
|
|
||||||
|
|
||||||
InputUserActiveFix();
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count);
|
|
||||||
|
|
||||||
void DoFun(void)
|
|
||||||
{
|
|
||||||
uint8 *gfx;
|
|
||||||
int32 *sound;
|
|
||||||
int32 ssize;
|
|
||||||
static int fskipc=0;
|
|
||||||
static int opause=0;
|
|
||||||
|
|
||||||
#ifdef FRAMESKIP
|
|
||||||
fskipc=(fskipc+1)%(frameskip+1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(NoWaiting) {
|
|
||||||
gfx = 0;
|
|
||||||
}
|
|
||||||
FCEUI_Emulate(&gfx, &sound, &ssize, fskipc);
|
|
||||||
FCEUD_Update(gfx, sound, ssize);
|
|
||||||
|
|
||||||
if(opause!=FCEUI_EmulationPaused()) {
|
|
||||||
opause=FCEUI_EmulationPaused();
|
|
||||||
SilenceSound(opause);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Common Layer Interface main() loop. This should get merged into
|
|
||||||
* the SDL main() loop since we're only supporting SDL now.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
CLImain(int argc,
|
|
||||||
char *argv[])
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if(!(ret=FCEUI_Initialize())) {
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
DrBaseDirectory=GetBaseDirectory();
|
|
||||||
FCEUI_SetBaseDirectory((char *)DrBaseDirectory);
|
|
||||||
|
|
||||||
CreateDirs();
|
|
||||||
|
|
||||||
if(argc<=1) {
|
|
||||||
ShowUsage(argv[0]);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadConfig();
|
|
||||||
DoArgs(argc-2,&argv[1]);
|
|
||||||
FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue);
|
|
||||||
if(cpalette) {
|
|
||||||
LoadCPalette();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* All the config files and arguments are parsed now. */
|
|
||||||
if(!LoadGame(argv[argc-1])) {
|
|
||||||
DriverKill();
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
while(CurGame) {
|
|
||||||
DoFun();
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseGame();
|
|
||||||
|
|
||||||
SaveConfig();
|
|
||||||
|
|
||||||
FCEUI_Kill();
|
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize all of the subsystem drivers: video, audio, joystick,
|
|
||||||
* keyboard, mouse.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
DriverInitialize(FCEUGI *gi)
|
|
||||||
{
|
|
||||||
#ifndef WIN32
|
|
||||||
SetSignals(CloseStuff);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Initialize video before all else, due to some wacko dependencies
|
|
||||||
in the SexyAL code(DirectSound) that need to be fixed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if(InitVideo(gi) < 0) return 0;
|
|
||||||
inited|=4;
|
|
||||||
|
|
||||||
if(InitSound(gi))
|
|
||||||
inited|=1;
|
|
||||||
|
|
||||||
if(InitJoysticks())
|
|
||||||
inited|=2;
|
|
||||||
|
|
||||||
if(!InitKeyboard()) return 0;
|
|
||||||
inited|=8;
|
|
||||||
|
|
||||||
InitOtherInput();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shut down all of the subsystem drivers: video, audio, joystick,
|
|
||||||
* keyboard.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
DriverKill()
|
|
||||||
{
|
|
||||||
SaveConfig();
|
|
||||||
|
|
||||||
#ifndef WIN32
|
|
||||||
SetSignals(SIG_IGN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(inited&2)
|
|
||||||
KillJoysticks();
|
|
||||||
if(inited&8)
|
|
||||||
KillKeyboard();
|
|
||||||
if(inited&4)
|
|
||||||
KillVideo();
|
|
||||||
if(inited&1)
|
|
||||||
KillSound();
|
|
||||||
if(inited&16)
|
|
||||||
KillMouse();
|
|
||||||
inited=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the video, audio, and input subsystems with the provided
|
|
||||||
* video (XBuf) and audio (Buffer) information.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
FCEUD_Update(uint8 *XBuf,
|
|
||||||
int32 *Buffer,
|
|
||||||
int Count)
|
|
||||||
{
|
|
||||||
extern int FCEUDnetplay;
|
|
||||||
|
|
||||||
int ocount = Count;
|
|
||||||
// apply frame scaling to Count
|
|
||||||
Count = (Count<<8)/fps_scale;
|
|
||||||
if(Count) {
|
|
||||||
int32 can=GetWriteSound();
|
|
||||||
static int uflow=0;
|
|
||||||
int32 tmpcan;
|
|
||||||
|
|
||||||
// don't underflow when scaling fps
|
|
||||||
if(can >= GetMaxSound() && fps_scale<=256) uflow=1; /* Go into massive underflow mode. */
|
|
||||||
|
|
||||||
if(can > Count) can=Count;
|
|
||||||
else uflow=0;
|
|
||||||
|
|
||||||
WriteSound(Buffer,can);
|
|
||||||
|
|
||||||
//if(uflow) puts("Underflow");
|
|
||||||
tmpcan = GetWriteSound();
|
|
||||||
// don't underflow when scaling fps
|
|
||||||
if(fps_scale>256 || ((tmpcan < Count*0.90) && !uflow)) {
|
|
||||||
if(XBuf && (inited&4) && !(NoWaiting & 2))
|
|
||||||
BlitScreen(XBuf);
|
|
||||||
Buffer+=can;
|
|
||||||
Count-=can;
|
|
||||||
if(Count) {
|
|
||||||
if(NoWaiting) {
|
|
||||||
can=GetWriteSound();
|
|
||||||
if(Count>can) Count=can;
|
|
||||||
WriteSound(Buffer,Count);
|
|
||||||
} else {
|
|
||||||
while(Count>0) {
|
|
||||||
WriteSound(Buffer,(Count<ocount) ? Count : ocount);
|
|
||||||
Count -= ocount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} //else puts("Skipped");
|
|
||||||
else if(!NoWaiting && FCEUDnetplay && (uflow || tmpcan >= (Count * 1.8))) {
|
|
||||||
if(Count > tmpcan) Count=tmpcan;
|
|
||||||
while(tmpcan > 0) {
|
|
||||||
// printf("Overwrite: %d\n", (Count <= tmpcan)?Count : tmpcan);
|
|
||||||
WriteSound(Buffer, (Count <= tmpcan)?Count : tmpcan);
|
|
||||||
tmpcan -= Count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if(!NoWaiting && (!(eoptions&EO_NOTHROTTLE) || FCEUI_EmulationPaused()))
|
|
||||||
SpeedThrottle();
|
|
||||||
if(XBuf && (inited&4)) {
|
|
||||||
BlitScreen(XBuf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FCEUD_UpdateInput();
|
|
||||||
//if(!Count && !NoWaiting && !(eoptions&EO_NOTHROTTLE))
|
|
||||||
// SpeedThrottle();
|
|
||||||
//if(XBuf && (inited&4))
|
|
||||||
//{
|
|
||||||
// BlitScreen(XBuf);
|
|
||||||
//}
|
|
||||||
//if(Count)
|
|
||||||
// WriteSound(Buffer,Count,NoWaiting);
|
|
||||||
//FCEUD_UpdateInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Maybe ifndef WXWINDOWS would be better? ^_^ */
|
|
||||||
/**
|
|
||||||
* Opens a file to be read a byte at a time.
|
|
||||||
*/
|
|
||||||
FILE *FCEUD_UTF8fopen(const char *fn, const char *mode)
|
|
||||||
{
|
|
||||||
return(fopen(fn,mode));
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *s_linuxCompilerString = "g++ " __VERSION__;
|
|
||||||
/**
|
|
||||||
* Returns the compiler string.
|
|
||||||
*/
|
|
||||||
char *FCEUD_GetCompilerString() {
|
|
||||||
return (char *)s_linuxCompilerString;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unimplemented.
|
|
||||||
*/
|
|
||||||
void FCEUD_DebugBreakpoint() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unimplemented.
|
|
||||||
*/
|
|
||||||
void FCEUD_TraceInstruction() {
|
|
||||||
return;
|
|
||||||
}
|
|
|
@ -1,6 +1,23 @@
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "throttle.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "../common/cheat.h"
|
||||||
|
|
||||||
|
#include "input.h"
|
||||||
|
#include "dface.h"
|
||||||
|
|
||||||
#include "sdl.h"
|
#include "sdl.h"
|
||||||
#include "sdl-video.h"
|
#include "sdl-video.h"
|
||||||
|
@ -10,116 +27,6 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DSETTINGS Settings;
|
|
||||||
CFGSTRUCT DriverConfig[]={
|
|
||||||
#ifdef OPENGL
|
|
||||||
AC(_stretchx),
|
|
||||||
AC(_stretchy),
|
|
||||||
AC(_opengl),
|
|
||||||
AC(_openglip),
|
|
||||||
#endif
|
|
||||||
AC(Settings.special),
|
|
||||||
AC(Settings.specialfs),
|
|
||||||
AC(_doublebuf),
|
|
||||||
AC(_xscale),
|
|
||||||
AC(_yscale),
|
|
||||||
AC(_xscalefs),
|
|
||||||
AC(_yscalefs),
|
|
||||||
AC(_bpp),
|
|
||||||
AC(_efx),
|
|
||||||
AC(_efxfs),
|
|
||||||
AC(_fullscreen),
|
|
||||||
AC(_xres),
|
|
||||||
AC(_yres),
|
|
||||||
ACS(netplaynick),
|
|
||||||
AC(netlocalplayers),
|
|
||||||
AC(tport),
|
|
||||||
ACS(netpassword),
|
|
||||||
ACS(netgamekey),
|
|
||||||
ENDCFGSTRUCT
|
|
||||||
};
|
|
||||||
|
|
||||||
//-fshack x Set the environment variable SDL_VIDEODRIVER to \"x\" when
|
|
||||||
// entering full screen mode and x is not \"0\".
|
|
||||||
|
|
||||||
char *DriverUsage=
|
|
||||||
"-xres x Set horizontal resolution to x for full screen mode.\n\
|
|
||||||
-yres x Set vertical resolution to x for full screen mode.\n\
|
|
||||||
-xscale(fs) x Multiply width by x(Real numbers >0 with OpenGL, otherwise integers >0).\n\
|
|
||||||
-yscale(fs) x Multiply height by x(Real numbers >0 with OpenGL, otherwise integers >0).\n\
|
|
||||||
-bpp(fs) x Bits per pixel for SDL surface(and video mode in fs). 8, 16, 32.\n\
|
|
||||||
-opengl x Enable OpenGL support if x is 1.\n\
|
|
||||||
-openglip x Enable OpenGL linear interpolation if x is 1.\n\
|
|
||||||
-doublebuf x \n\
|
|
||||||
-special(fs) x Specify special scaling filter.\n\
|
|
||||||
-stretch(x/y) x Stretch to fill surface on x or y axis(fullscreen, only with OpenGL).\n\
|
|
||||||
-efx(fs) x Enable special effects. Logically OR the following together:\n\
|
|
||||||
1 = scanlines(for yscale>=2).\n\
|
|
||||||
2 = TV blur(for bpp of 16 or 32).\n\
|
|
||||||
-fs x Select full screen mode if x is non zero.\n\
|
|
||||||
-connect s Connect to server 's' for TCP/IP network play.\n\
|
|
||||||
-netnick s Set the nickname to use in network play.\n\
|
|
||||||
-netgamekey s Use key 's' to create a unique session for the game loaded.\n\
|
|
||||||
-netpassword s Password to use for connecting to the server.\n\
|
|
||||||
-netlocalplayers x Set the number of local players.\n\
|
|
||||||
-netport x Use TCP/IP port x for network play.";
|
|
||||||
|
|
||||||
ARGPSTRUCT DriverArgs[]={
|
|
||||||
#ifdef OPENGL
|
|
||||||
{"-opengl",0,&_opengl,0},
|
|
||||||
{"-openglip",0,&_openglip,0},
|
|
||||||
{"-stretchx",0,&_stretchx,0},
|
|
||||||
{"-stretchy",0,&_stretchy,0},
|
|
||||||
#endif
|
|
||||||
{"-special",0,&Settings.special,0},
|
|
||||||
{"-specialfs",0,&Settings.specialfs,0},
|
|
||||||
{"-doublebuf",0,&_doublebuf,0},
|
|
||||||
{"-bpp",0,&_bpp,0},
|
|
||||||
{"-xscale",0,&_xscale,2},
|
|
||||||
{"-yscale",0,&_yscale,2},
|
|
||||||
{"-efx",0,&_efx,0},
|
|
||||||
{"-xscalefs",0,&_xscalefs,2},
|
|
||||||
{"-yscalefs",0,&_yscalefs,2},
|
|
||||||
{"-efxfs",0,&_efxfs,0},
|
|
||||||
{"-xres",0,&_xres,0},
|
|
||||||
{"-yres",0,&_yres,0},
|
|
||||||
{"-fs",0,&_fullscreen,0},
|
|
||||||
//{"-fshack",0,&_fshack,0x4001},
|
|
||||||
{"-connect",0,&netplayhost,0x4001},
|
|
||||||
{"-netport",0,&tport,0},
|
|
||||||
{"-netlocalplayers",0,&netlocalplayers,0},
|
|
||||||
{"-netnick",0,&netplaynick,0x4001},
|
|
||||||
{"-netpassword",0,&netpassword,0x4001},
|
|
||||||
{0,0,0,0}
|
|
||||||
};
|
|
||||||
|
|
||||||
static void SetDefaults(void)
|
|
||||||
{
|
|
||||||
Settings.special=Settings.specialfs=0;
|
|
||||||
_bpp=8;
|
|
||||||
_xres=640;
|
|
||||||
_yres=480;
|
|
||||||
_fullscreen=0;
|
|
||||||
_xscale=2.50;
|
|
||||||
_yscale=2;
|
|
||||||
_xscalefs=_yscalefs=2;
|
|
||||||
_efx=_efxfs=0;
|
|
||||||
//_fshack=_fshacksave=0;
|
|
||||||
#ifdef OPENGL
|
|
||||||
_opengl=1;
|
|
||||||
_stretchx=1;
|
|
||||||
_stretchy=0;
|
|
||||||
_openglip=1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unimplemented.
|
|
||||||
*/
|
|
||||||
void DoDriverArgs(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unimplemented. Returns 0.
|
* Unimplemented. Returns 0.
|
||||||
|
@ -230,47 +137,363 @@ GetKeyboard()
|
||||||
return ((char *)KeyState);
|
return ((char *)KeyState);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempts to locate FCEU's application directory. This will
|
|
||||||
* hopefully become obsolete once the new configuration system is in
|
|
||||||
* place.
|
|
||||||
*/
|
|
||||||
uint8 *
|
|
||||||
GetBaseDirectory()
|
|
||||||
{
|
|
||||||
uint8 *ol;
|
|
||||||
uint8 *ret;
|
|
||||||
|
|
||||||
ol=(uint8 *)getenv("HOME");
|
|
||||||
|
|
||||||
if(ol) {
|
|
||||||
ret=(uint8 *)malloc(strlen((char *)ol)+1+strlen("./fceultra"));
|
|
||||||
strcpy((char *)ret,(char *)ol);
|
|
||||||
strcat((char *)ret,"/.fceultra");
|
|
||||||
} else {
|
|
||||||
#ifdef WIN32
|
|
||||||
char *sa;
|
|
||||||
|
|
||||||
ret=(uint8*)malloc(MAX_PATH+1);
|
|
||||||
GetModuleFileName(NULL,(char*)ret,MAX_PATH+1);
|
|
||||||
|
|
||||||
sa=strrchr((char*)ret,'\\');
|
|
||||||
if(sa)
|
|
||||||
*sa = 0;
|
|
||||||
#else
|
|
||||||
ret=(uint8 *)malloc(sizeof(uint8));
|
|
||||||
ret[0]=0;
|
|
||||||
#endif
|
|
||||||
printf("%s\n",ret);
|
|
||||||
}
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef OPENGL
|
#ifdef OPENGL
|
||||||
int sdlhaveogl;
|
int sdlhaveogl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
extern int32 fps_scale;
|
||||||
|
|
||||||
|
int CloseGame(void);
|
||||||
|
|
||||||
|
int soundvol=100;
|
||||||
|
long soundq=0;
|
||||||
|
int _sound=1;
|
||||||
|
long soundrate=48000;
|
||||||
|
#ifdef WIN32
|
||||||
|
long soundbufsize=52;
|
||||||
|
#else
|
||||||
|
long soundbufsize=24;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int inited=0;
|
||||||
|
static int isloaded=0; // Is game loaded?
|
||||||
|
|
||||||
|
int srendlinev[2]={8,0};
|
||||||
|
int erendlinev[2]={231,239};
|
||||||
|
|
||||||
|
|
||||||
|
int eoptions=0;
|
||||||
|
|
||||||
|
static void DriverKill(void);
|
||||||
|
static int DriverInitialize(FCEUGI *gi);
|
||||||
|
int gametype = 0;
|
||||||
|
|
||||||
|
FCEUGI *CurGame=NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for ParseGIInput().
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ParseGI(FCEUGI *gi)
|
||||||
|
{
|
||||||
|
ParseGIInput(gi);
|
||||||
|
gametype = gi->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints an error string to STDOUT.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
FCEUD_PrintError(char *s)
|
||||||
|
{
|
||||||
|
puts(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the given string to STDOUT.
|
||||||
|
*/
|
||||||
|
void FCEUD_Message(char *s)
|
||||||
|
{
|
||||||
|
fputs(s, stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
/**
|
||||||
|
* Capture and handle signals sent to FCEU.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
SetSignals(void (*t)(int))
|
||||||
|
{
|
||||||
|
// XXX soules - why do we capture these? Seems unnecessary.
|
||||||
|
int sigs[11]={SIGINT,SIGTERM,SIGHUP,SIGPIPE,SIGSEGV,SIGFPE,SIGKILL,SIGALRM,SIGABRT,SIGUSR1,SIGUSR2};
|
||||||
|
int x;
|
||||||
|
for(x = 0; x < 11; x++) {
|
||||||
|
signal(sigs[x], t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
CloseStuff(int signum)
|
||||||
|
{
|
||||||
|
// XXX soules - again, not clear why this is necessary
|
||||||
|
DriverKill();
|
||||||
|
printf("\nSignal %d has been caught and dealt with...\n",signum);
|
||||||
|
switch(signum) {
|
||||||
|
case SIGINT:printf("How DARE you interrupt me!\n");break;
|
||||||
|
case SIGTERM:printf("MUST TERMINATE ALL HUMANS\n");break;
|
||||||
|
case SIGHUP:printf("Reach out and hang-up on someone.\n");break;
|
||||||
|
case SIGPIPE:printf("The pipe has broken! Better watch out for floods...\n");break;
|
||||||
|
case SIGSEGV:printf("Iyeeeeeeeee!!! A segmentation fault has occurred. Have a fluffy day.\n");break;
|
||||||
|
/* So much SIGBUS evil. */
|
||||||
|
#ifdef SIGBUS
|
||||||
|
#if(SIGBUS!=SIGSEGV)
|
||||||
|
case SIGBUS:printf("I told you to be nice to the driver.\n");break;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
case SIGFPE:printf("Those darn floating points. Ne'er know when they'll bite!\n");break;
|
||||||
|
case SIGALRM:printf("Don't throw your clock at the meowing cats!\n");break;
|
||||||
|
case SIGABRT:printf("Abort, Retry, Ignore, Fail?\n");break;
|
||||||
|
case SIGUSR1:
|
||||||
|
case SIGUSR2:printf("Killing your processes is not nice.\n");break;
|
||||||
|
}
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "usage.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a game, given a full path/filename. The driver code must be
|
||||||
|
* initialized after the game is loaded, because the emulator code
|
||||||
|
* provides data necessary for the driver code(number of scanlines to
|
||||||
|
* render, what virtual input devices to use, etc.).
|
||||||
|
*/
|
||||||
|
int LoadGame(const char *path)
|
||||||
|
{
|
||||||
|
FCEUGI *tmp;
|
||||||
|
|
||||||
|
CloseGame();
|
||||||
|
if(!(tmp = FCEUI_LoadGame(path, 1))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
CurGame=tmp;
|
||||||
|
ParseGI(tmp);
|
||||||
|
RefreshThrottleFPS();
|
||||||
|
|
||||||
|
if(!DriverInitialize(tmp)) {
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
if(soundrecfn) {
|
||||||
|
if(!FCEUI_BeginWaveRecord(soundrecfn)) {
|
||||||
|
free(soundrecfn);
|
||||||
|
soundrecfn=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isloaded=1;
|
||||||
|
|
||||||
|
FCEUD_NetworkConnect();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes a game. Frees memory, and deinitializes the drivers.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
CloseGame()
|
||||||
|
{
|
||||||
|
if(!isloaded) {
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
FCEUI_CloseGame();
|
||||||
|
DriverKill();
|
||||||
|
isloaded=0;
|
||||||
|
CurGame=0;
|
||||||
|
|
||||||
|
if(soundrecfn) {
|
||||||
|
FCEUI_EndWaveRecord();
|
||||||
|
}
|
||||||
|
|
||||||
|
InputUserActiveFix();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count);
|
||||||
|
|
||||||
|
void DoFun(void)
|
||||||
|
{
|
||||||
|
uint8 *gfx;
|
||||||
|
int32 *sound;
|
||||||
|
int32 ssize;
|
||||||
|
static int fskipc=0;
|
||||||
|
static int opause=0;
|
||||||
|
|
||||||
|
#ifdef FRAMESKIP
|
||||||
|
fskipc=(fskipc+1)%(frameskip+1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(NoWaiting) {
|
||||||
|
gfx = 0;
|
||||||
|
}
|
||||||
|
FCEUI_Emulate(&gfx, &sound, &ssize, fskipc);
|
||||||
|
FCEUD_Update(gfx, sound, ssize);
|
||||||
|
|
||||||
|
if(opause!=FCEUI_EmulationPaused()) {
|
||||||
|
opause=FCEUI_EmulationPaused();
|
||||||
|
SilenceSound(opause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize all of the subsystem drivers: video, audio, joystick,
|
||||||
|
* keyboard, mouse.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
DriverInitialize(FCEUGI *gi)
|
||||||
|
{
|
||||||
|
#ifndef WIN32
|
||||||
|
SetSignals(CloseStuff);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Initialize video before all else, due to some wacko dependencies
|
||||||
|
in the SexyAL code(DirectSound) that need to be fixed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(InitVideo(gi) < 0) return 0;
|
||||||
|
inited|=4;
|
||||||
|
|
||||||
|
if(InitSound(gi))
|
||||||
|
inited|=1;
|
||||||
|
|
||||||
|
if(InitJoysticks())
|
||||||
|
inited|=2;
|
||||||
|
|
||||||
|
if(!InitKeyboard()) return 0;
|
||||||
|
inited|=8;
|
||||||
|
|
||||||
|
InitOtherInput();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shut down all of the subsystem drivers: video, audio, joystick,
|
||||||
|
* keyboard.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
DriverKill()
|
||||||
|
{
|
||||||
|
SaveConfig();
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
SetSignals(SIG_IGN);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(inited&2)
|
||||||
|
KillJoysticks();
|
||||||
|
if(inited&8)
|
||||||
|
KillKeyboard();
|
||||||
|
if(inited&4)
|
||||||
|
KillVideo();
|
||||||
|
if(inited&1)
|
||||||
|
KillSound();
|
||||||
|
if(inited&16)
|
||||||
|
KillMouse();
|
||||||
|
inited=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the video, audio, and input subsystems with the provided
|
||||||
|
* video (XBuf) and audio (Buffer) information.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
FCEUD_Update(uint8 *XBuf,
|
||||||
|
int32 *Buffer,
|
||||||
|
int Count)
|
||||||
|
{
|
||||||
|
extern int FCEUDnetplay;
|
||||||
|
|
||||||
|
int ocount = Count;
|
||||||
|
// apply frame scaling to Count
|
||||||
|
Count = (Count<<8)/fps_scale;
|
||||||
|
if(Count) {
|
||||||
|
int32 can=GetWriteSound();
|
||||||
|
static int uflow=0;
|
||||||
|
int32 tmpcan;
|
||||||
|
|
||||||
|
// don't underflow when scaling fps
|
||||||
|
if(can >= GetMaxSound() && fps_scale<=256) uflow=1; /* Go into massive underflow mode. */
|
||||||
|
|
||||||
|
if(can > Count) can=Count;
|
||||||
|
else uflow=0;
|
||||||
|
|
||||||
|
WriteSound(Buffer,can);
|
||||||
|
|
||||||
|
//if(uflow) puts("Underflow");
|
||||||
|
tmpcan = GetWriteSound();
|
||||||
|
// don't underflow when scaling fps
|
||||||
|
if(fps_scale>256 || ((tmpcan < Count*0.90) && !uflow)) {
|
||||||
|
if(XBuf && (inited&4) && !(NoWaiting & 2))
|
||||||
|
BlitScreen(XBuf);
|
||||||
|
Buffer+=can;
|
||||||
|
Count-=can;
|
||||||
|
if(Count) {
|
||||||
|
if(NoWaiting) {
|
||||||
|
can=GetWriteSound();
|
||||||
|
if(Count>can) Count=can;
|
||||||
|
WriteSound(Buffer,Count);
|
||||||
|
} else {
|
||||||
|
while(Count>0) {
|
||||||
|
WriteSound(Buffer,(Count<ocount) ? Count : ocount);
|
||||||
|
Count -= ocount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} //else puts("Skipped");
|
||||||
|
else if(!NoWaiting && FCEUDnetplay && (uflow || tmpcan >= (Count * 1.8))) {
|
||||||
|
if(Count > tmpcan) Count=tmpcan;
|
||||||
|
while(tmpcan > 0) {
|
||||||
|
// printf("Overwrite: %d\n", (Count <= tmpcan)?Count : tmpcan);
|
||||||
|
WriteSound(Buffer, (Count <= tmpcan)?Count : tmpcan);
|
||||||
|
tmpcan -= Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if(!NoWaiting && (!(eoptions&EO_NOTHROTTLE) || FCEUI_EmulationPaused()))
|
||||||
|
SpeedThrottle();
|
||||||
|
if(XBuf && (inited&4)) {
|
||||||
|
BlitScreen(XBuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FCEUD_UpdateInput();
|
||||||
|
//if(!Count && !NoWaiting && !(eoptions&EO_NOTHROTTLE))
|
||||||
|
// SpeedThrottle();
|
||||||
|
//if(XBuf && (inited&4))
|
||||||
|
//{
|
||||||
|
// BlitScreen(XBuf);
|
||||||
|
//}
|
||||||
|
//if(Count)
|
||||||
|
// WriteSound(Buffer,Count,NoWaiting);
|
||||||
|
//FCEUD_UpdateInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Maybe ifndef WXWINDOWS would be better? ^_^ */
|
||||||
|
/**
|
||||||
|
* Opens a file to be read a byte at a time.
|
||||||
|
*/
|
||||||
|
FILE *FCEUD_UTF8fopen(const char *fn, const char *mode)
|
||||||
|
{
|
||||||
|
return(fopen(fn,mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *s_linuxCompilerString = "g++ " __VERSION__;
|
||||||
|
/**
|
||||||
|
* Returns the compiler string.
|
||||||
|
*/
|
||||||
|
char *FCEUD_GetCompilerString() {
|
||||||
|
return (char *)s_linuxCompilerString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unimplemented.
|
||||||
|
*/
|
||||||
|
void FCEUD_DebugBreakpoint() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unimplemented.
|
||||||
|
*/
|
||||||
|
void FCEUD_TraceInstruction() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Involved with updating the button configuration, but not entirely
|
* Involved with updating the button configuration, but not entirely
|
||||||
* sure how yet - soules.
|
* sure how yet - soules.
|
||||||
|
@ -449,11 +672,44 @@ main(int argc,
|
||||||
|
|
||||||
SetDefaults();
|
SetDefaults();
|
||||||
|
|
||||||
{
|
int error;
|
||||||
int ret = CLImain(argc, argv);
|
|
||||||
|
// initialize the infrastructure
|
||||||
|
error = FCEUI_Initialize();
|
||||||
|
if(error != 1) {
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
return (ret) ? 0 : -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX configuration initialization
|
||||||
|
error = InitConfig(argc, argv);
|
||||||
|
if(error) {
|
||||||
|
SDL_Quit();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// load the specified game
|
||||||
|
error = LoadGame(argv[argc - 1]);
|
||||||
|
if(error != 1) {
|
||||||
|
DriverKill();
|
||||||
|
SDL_Quit();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop playing the game
|
||||||
|
while(CurGame) {
|
||||||
|
DoFun();
|
||||||
|
}
|
||||||
|
CloseGame();
|
||||||
|
|
||||||
|
// save the configuration information
|
||||||
|
SaveConfig();
|
||||||
|
|
||||||
|
// exit the infrastructure
|
||||||
|
FCEUI_Kill();
|
||||||
|
|
||||||
|
SDL_Quit();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -476,6 +732,7 @@ FCEUD_GetTimeFreq(void)
|
||||||
return 1000;
|
return 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// dummy functions
|
// dummy functions
|
||||||
|
|
||||||
#define DUMMY(f) void f(void) {FCEU_DispMessage("Not implemented.");}
|
#define DUMMY(f) void f(void) {FCEU_DispMessage("Not implemented.");}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void ShowUsage(char *prog)
|
static void ShowUsage(char *prog)
|
||||||
{
|
{
|
||||||
printf("\nUsage is as follows:\n%s <options> filename\n\n",prog);
|
printf("\nUsage is as follows:\n%s <options> filename\n\n",prog);
|
||||||
puts("Options:");
|
puts("Options:");
|
||||||
|
|
Loading…
Reference in New Issue