- 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:
gimmedonutnow 2006-08-03 05:35:21 +00:00
parent c39de3f8a8
commit 3ee6888bbd
7 changed files with 783 additions and 756 deletions

View File

@ -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

366
src/drivers/sdl/config.cpp Normal file
View File

@ -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;
}

9
src/drivers/sdl/config.h Normal file
View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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.");}

View File

@ -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:");