- SDL now uses the new configuration system
This commit is contained in:
parent
24288cd015
commit
091d0b225d
|
@ -10,10 +10,7 @@ Doxygen integration - DONE
|
|||
* website integration
|
||||
|
||||
Linux build - soules
|
||||
* go through #def variables and figure out which we need and which we don't
|
||||
- check OpenGL code
|
||||
* lots of testing and code clean-up
|
||||
* figure out why its running 640x480 instead of 512x448
|
||||
* clean-up of input device code
|
||||
|
||||
Windows build - zeromus
|
||||
* verify rerecording
|
||||
|
|
|
@ -52,7 +52,7 @@ void FCEUI_NetplayText(uint8 *text);
|
|||
*/
|
||||
void FCEUD_NetworkClose(void);
|
||||
|
||||
int FCEUI_BeginWaveRecord(char *fn);
|
||||
int FCEUI_BeginWaveRecord(const char *fn);
|
||||
int FCEUI_EndWaveRecord(void);
|
||||
|
||||
void FCEUI_ResetNES(void);
|
||||
|
@ -146,7 +146,7 @@ void FCEUI_SetRenderedLines(int ntscf, int ntscl, int palf, int pall);
|
|||
|
||||
/* Sets the base directory(save states, snapshots, etc. are saved in directories
|
||||
below this directory. */
|
||||
void FCEUI_SetBaseDirectory(char *dir);
|
||||
void FCEUI_SetBaseDirectory(const char *dir);
|
||||
|
||||
/* Tells FCE Ultra to copy the palette data pointed to by pal and use it.
|
||||
Data pointed to by pal needs to be 64*3 bytes in length.
|
||||
|
|
|
@ -17,7 +17,8 @@ Config::_addOption(char shortArg,
|
|||
int type)
|
||||
{
|
||||
// make sure we have a valid type
|
||||
if(type != INTEGER && type != STRING) {
|
||||
if(type != INTEGER && type != STRING &&
|
||||
type != DOUBLE && type != FUNCTION) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -25,17 +26,21 @@ Config::_addOption(char shortArg,
|
|||
if(_shortArgMap.find(shortArg) != _shortArgMap.end() ||
|
||||
_longArgMap.find(longArg) != _longArgMap.end() ||
|
||||
(type == INTEGER && _intOptMap.find(name) != _intOptMap.end()) ||
|
||||
(type == STRING && _strOptMap.find(name) != _strOptMap.end())) {
|
||||
(type == STRING && _strOptMap.find(name) != _strOptMap.end()) ||
|
||||
(type == DOUBLE && _dblOptMap.find(name) != _dblOptMap.end())) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// add the option
|
||||
switch(type) {
|
||||
case(STRING):
|
||||
_strOptMap[name] = "";
|
||||
break;
|
||||
case(INTEGER):
|
||||
_intOptMap[name] = 0;
|
||||
break;
|
||||
case(STRING):
|
||||
_strOptMap[name] = "";
|
||||
case(DOUBLE):
|
||||
_dblOptMap[name] = 0.0;
|
||||
break;
|
||||
case(FUNCTION):
|
||||
_fnOptMap[name] = NULL;
|
||||
|
@ -49,6 +54,44 @@ Config::_addOption(char shortArg,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Config::_addOption(const std::string &longArg,
|
||||
const std::string &name,
|
||||
int type)
|
||||
{
|
||||
// make sure we have a valid type
|
||||
if(type != STRING && type != INTEGER && type != DOUBLE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check if the option already exists
|
||||
if(_longArgMap.find(longArg) != _longArgMap.end() ||
|
||||
(type == STRING && _strOptMap.find(name) != _strOptMap.end()) ||
|
||||
(type == INTEGER && _intOptMap.find(name) != _intOptMap.end()) ||
|
||||
(type == DOUBLE && _dblOptMap.find(name) != _dblOptMap.end())) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// add the option
|
||||
switch(type) {
|
||||
case(STRING):
|
||||
_strOptMap[name] = "";
|
||||
break;
|
||||
case(INTEGER):
|
||||
_intOptMap[name] = 0;
|
||||
break;
|
||||
case(DOUBLE):
|
||||
_dblOptMap[name] = 0.0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_longArgMap[longArg] = name;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a given option and sets its default value. The option is
|
||||
* specified as a short command line (-f), long command line (--foo),
|
||||
|
@ -78,6 +121,36 @@ Config::addOption(char shortArg,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a given option and sets its default value. The option is
|
||||
* specified as a short command line (-f), long command line (--foo),
|
||||
* option name (Foo), its type (integer or string), and its default
|
||||
* value.
|
||||
*/
|
||||
int
|
||||
Config::addOption(char shortArg,
|
||||
const std::string &longArg,
|
||||
const std::string &name,
|
||||
double defaultValue)
|
||||
{
|
||||
int error;
|
||||
|
||||
// add the option to the config system
|
||||
error = _addOption(shortArg, longArg, name, DOUBLE);
|
||||
if(error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
// set the option to the default value
|
||||
error = setOption(name, defaultValue);
|
||||
if(error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a given option and sets its default value. The option is
|
||||
* specified as a short command line (-f), long command line (--foo),
|
||||
|
@ -111,7 +184,7 @@ int
|
|||
Config::addOption(char shortArg,
|
||||
const std::string &longArg,
|
||||
const std::string &name,
|
||||
void (*defaultFn)(void))
|
||||
void (*defaultFn)(const std::string &))
|
||||
{
|
||||
int error;
|
||||
|
||||
|
@ -130,6 +203,72 @@ Config::addOption(char shortArg,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Config::addOption(const std::string &longArg,
|
||||
const std::string &name,
|
||||
const std::string &defaultValue)
|
||||
{
|
||||
int error;
|
||||
|
||||
// add the option to the config system
|
||||
error = _addOption(longArg, name, STRING);
|
||||
if(error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
// set the option to the default value
|
||||
error = setOption(name, defaultValue);
|
||||
if(error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Config::addOption(const std::string &longArg,
|
||||
const std::string &name,
|
||||
int defaultValue)
|
||||
{
|
||||
int error;
|
||||
|
||||
// add the option to the config system
|
||||
error = _addOption(longArg, name, INTEGER);
|
||||
if(error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
// set the option to the default value
|
||||
error = setOption(name, defaultValue);
|
||||
if(error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Config::addOption(const std::string &longArg,
|
||||
const std::string &name,
|
||||
double defaultValue)
|
||||
{
|
||||
int error;
|
||||
|
||||
// add the option to the config system
|
||||
error = _addOption(longArg, name, DOUBLE);
|
||||
if(error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
// set the option to the default value
|
||||
error = setOption(name, defaultValue);
|
||||
if(error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Config::addOption(const std::string &name,
|
||||
const std::string &defaultValue)
|
||||
|
@ -156,6 +295,19 @@ Config::addOption(const std::string &name,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Config::addOption(const std::string &name,
|
||||
double defaultValue)
|
||||
{
|
||||
if(_dblOptMap.find(name) != _dblOptMap.end()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// add the option
|
||||
_dblOptMap[name] = defaultValue;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified option to the given integer value.
|
||||
*/
|
||||
|
@ -176,6 +328,26 @@ Config::setOption(const std::string &name,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified option to the given integer value.
|
||||
*/
|
||||
int
|
||||
Config::setOption(const std::string &name,
|
||||
double value)
|
||||
{
|
||||
std::map<std::string, double>::iterator opt_i;
|
||||
|
||||
// confirm that the option exists
|
||||
opt_i = _dblOptMap.find(name);
|
||||
if(opt_i == _dblOptMap.end()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// set the option
|
||||
opt_i->second = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified option to the given string value.
|
||||
*/
|
||||
|
@ -201,9 +373,9 @@ Config::setOption(const std::string &name,
|
|||
*/
|
||||
int
|
||||
Config::setOption(const std::string &name,
|
||||
void (*value)(void))
|
||||
void (*value)(const std::string &))
|
||||
{
|
||||
std::map<std::string, void (*)(void)>::iterator opt_i;
|
||||
std::map<std::string, void (*)(const std::string &)>::iterator opt_i;
|
||||
|
||||
// confirm that the option exists
|
||||
opt_i = _fnOptMap.find(name);
|
||||
|
@ -268,6 +440,23 @@ Config::getOption(const std::string &name,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Config::getOption(const std::string &name,
|
||||
double *value)
|
||||
{
|
||||
std::map<std::string, double>::iterator opt_i;
|
||||
|
||||
// confirm that the option exists
|
||||
opt_i = _dblOptMap.find(name);
|
||||
if(opt_i == _dblOptMap.end()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// get the option
|
||||
(*value) = opt_i->second;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the command line arguments. Short args are of the form -f
|
||||
* <opt>, long args are of the form --foo <opt>. Returns < 0 on error,
|
||||
|
@ -281,7 +470,8 @@ Config::_parseArgs(int argc,
|
|||
std::map<std::string, std::string>::iterator long_i, str_i;
|
||||
std::map<char, std::string>::iterator short_i;
|
||||
std::map<std::string, int>::iterator int_i;
|
||||
std::map<std::string, void (*)(void)>::iterator fn_i;
|
||||
std::map<std::string, double>::iterator dbl_i;
|
||||
std::map<std::string, void (*)(const std::string &)>::iterator fn_i;
|
||||
std::string arg, opt, value;
|
||||
|
||||
for(int i = 1; i < argc; i++) {
|
||||
|
@ -318,13 +508,6 @@ Config::_parseArgs(int argc,
|
|||
opt = short_i->second;
|
||||
}
|
||||
|
||||
// check if its a function, and if so, call the function
|
||||
fn_i = _fnOptMap.find(opt);
|
||||
if(fn_i != _fnOptMap.end()) {
|
||||
(*(fn_i->second))();
|
||||
continue;
|
||||
}
|
||||
|
||||
// make sure we've got a value
|
||||
if(i + 1 >= argc) {
|
||||
// XXX missing value
|
||||
|
@ -335,10 +518,16 @@ Config::_parseArgs(int argc,
|
|||
// now, find the appropriate option entry, and update it
|
||||
str_i = _strOptMap.find(opt);
|
||||
int_i = _intOptMap.find(opt);
|
||||
dbl_i = _dblOptMap.find(opt);
|
||||
fn_i = _fnOptMap.find(opt);
|
||||
if(str_i != _strOptMap.end()) {
|
||||
str_i->second = argv[i];
|
||||
} else if(int_i != _intOptMap.end()) {
|
||||
int_i->second = atol(argv[i]);
|
||||
} else if(dbl_i != _dblOptMap.end()) {
|
||||
dbl_i->second = atof(argv[i]);
|
||||
} else if(fn_i != _fnOptMap.end()) {
|
||||
(*(fn_i->second))(argv[i]);
|
||||
} else {
|
||||
// XXX invalid option? shouldn't happen
|
||||
return -1;
|
||||
|
@ -386,6 +575,7 @@ Config::_load()
|
|||
unsigned int pos, eqPos;
|
||||
std::fstream config;
|
||||
std::map<std::string, int>::iterator int_i;
|
||||
std::map<std::string, double>::iterator dbl_i;
|
||||
std::map<std::string, std::string>::iterator str_i;
|
||||
std::string configFile = _dir + "/fceu.cfg";
|
||||
std::string line, name, value;
|
||||
|
@ -399,7 +589,7 @@ Config::_load()
|
|||
config.open(configFile.c_str(), std::ios::in | std::ios::out);
|
||||
if(!config.is_open()) {
|
||||
// XXX file couldn't be opened?
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(!config.eof()) {
|
||||
|
@ -422,11 +612,14 @@ Config::_load()
|
|||
|
||||
// check if the option exists, and if so, set it appropriately
|
||||
str_i = _strOptMap.find(name);
|
||||
dbl_i = _dblOptMap.find(name);
|
||||
int_i = _intOptMap.find(name);
|
||||
if(str_i != _strOptMap.end()) {
|
||||
str_i->second = value;
|
||||
} else if(int_i != _intOptMap.end()) {
|
||||
int_i->second = atol(value.c_str());
|
||||
} else if(dbl_i != _dblOptMap.end()) {
|
||||
dbl_i->second = atof(value.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -449,6 +642,7 @@ Config::save()
|
|||
int error;
|
||||
std::fstream config;
|
||||
std::map<std::string, int>::iterator int_i;
|
||||
std::map<std::string, double>::iterator dbl_i;
|
||||
std::map<std::string, std::string>::iterator str_i;
|
||||
std::string configFile = _dir + "/fceu.cfg";
|
||||
char buf[1024];
|
||||
|
@ -470,6 +664,11 @@ Config::save()
|
|||
int_i->first.c_str(), int_i->second);
|
||||
config.write(buf, strlen(buf));
|
||||
}
|
||||
for(dbl_i = _dblOptMap.begin(); dbl_i != _dblOptMap.end(); int_i++) {
|
||||
snprintf(buf, 1024, "%s = %f\n",
|
||||
dbl_i->first.c_str(), dbl_i->second);
|
||||
config.write(buf, strlen(buf));
|
||||
}
|
||||
for(str_i = _strOptMap.begin(); str_i != _strOptMap.end(); str_i++) {
|
||||
snprintf(buf, 1024, "%s = %s\n",
|
||||
str_i->first.c_str(), str_i->second.c_str());
|
||||
|
|
|
@ -10,20 +10,23 @@ private:
|
|||
|
||||
std::map<std::string, std::string> _strOptMap;
|
||||
std::map<std::string, int> _intOptMap;
|
||||
std::map<std::string, void (*)(void)> _fnOptMap;
|
||||
std::map<std::string, double> _dblOptMap;
|
||||
std::map<std::string, void (*)(const std::string &)> _fnOptMap;
|
||||
|
||||
std::map<char, std::string> _shortArgMap;
|
||||
std::map<std::string, std::string> _longArgMap;
|
||||
|
||||
private:
|
||||
int _addOption(char, const std::string &, const std::string &, int);
|
||||
int _addOption(const std::string &, const std::string &, int);
|
||||
int _load(void);
|
||||
int _parseArgs(int, char **);
|
||||
|
||||
public:
|
||||
const static int STRING = 1;
|
||||
const static int INTEGER = 2;
|
||||
const static int FUNCTION = 3;
|
||||
const static int DOUBLE = 3;
|
||||
const static int FUNCTION = 4;
|
||||
|
||||
public:
|
||||
Config(std::string d) : _dir(d) { }
|
||||
|
@ -33,25 +36,39 @@ public:
|
|||
* Adds a configuration option. All options must be added before
|
||||
* parse().
|
||||
*/
|
||||
int addOption(char, const std::string &,
|
||||
const std::string &, int);
|
||||
int addOption(char, const std::string &,
|
||||
const std::string &, const std::string &);
|
||||
int addOption(char, const std::string &,
|
||||
const std::string &, void (*)(void));
|
||||
const std::string &, int);
|
||||
int addOption(char, const std::string &,
|
||||
const std::string &, double);
|
||||
int addOption(char, const std::string &,
|
||||
const std::string &, void (*)(const std::string &));
|
||||
|
||||
int addOption(const std::string &,
|
||||
const std::string &, const std::string &);
|
||||
int addOption(const std::string &, const std::string &, int);
|
||||
int addOption(const std::string &, const std::string &, double);
|
||||
//int addOption(const std::string &,
|
||||
// const std::string &, void (*)(const std::string &));
|
||||
|
||||
int addOption(const std::string &, const std::string &);
|
||||
int addOption(const std::string &, int);
|
||||
int addOption(const std::string &, double);
|
||||
//int addOption(const std::string &, void (*)(const std::string &));
|
||||
|
||||
/**
|
||||
* Sets a configuration option. Can be called at any time.
|
||||
*/
|
||||
int setOption(const std::string &, int);
|
||||
int setOption(const std::string &, const std::string &);
|
||||
int setOption(const std::string &, void (*)(void));
|
||||
int setOption(const std::string &, int);
|
||||
int setOption(const std::string &, double);
|
||||
int setOption(const std::string &, void (*)(const std::string &));
|
||||
|
||||
int getOption(const std::string &, std::string *);
|
||||
int getOption(const std::string &, const char **);
|
||||
int getOption(const std::string &, int *);
|
||||
int getOption(const std::string &, double *);
|
||||
|
||||
/**
|
||||
* Parse the arguments. Also read in the configuration file and
|
||||
|
|
|
@ -26,218 +26,19 @@
|
|||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
int frameskip;
|
||||
char *cpalette;
|
||||
char *soundrecfn;
|
||||
int ntsccol, ntschue, ntsctint;
|
||||
char *DrBaseDirectory;
|
||||
|
||||
static int srendlinev[2]={8,0};
|
||||
static int erendlinev[2]={231,239};
|
||||
|
||||
static int soundvol=100;
|
||||
static long soundq=0;
|
||||
|
||||
int _sound=1;
|
||||
long soundrate=48000;
|
||||
#ifdef WIN32
|
||||
long soundbufsize=52;
|
||||
#else
|
||||
long soundbufsize=24;
|
||||
#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}
|
||||
};
|
||||
|
||||
#include "usage.h"
|
||||
|
||||
void
|
||||
SetDefaults(void)
|
||||
{
|
||||
Settings.special=Settings.specialfs=0;
|
||||
_bpp=8;
|
||||
_xres=640;
|
||||
_yres=480;
|
||||
_fullscreen=0;
|
||||
_xscale=2;
|
||||
_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();
|
||||
}
|
||||
//#include "usage.h"
|
||||
|
||||
/**
|
||||
* Read a custom pallete from a file and load it into the core.
|
||||
*/
|
||||
static void
|
||||
LoadCPalette()
|
||||
LoadCPalette(const std::string &file)
|
||||
{
|
||||
uint8 tmpp[192];
|
||||
FILE *fp;
|
||||
|
||||
if(!(fp = FCEUD_UTF8fopen(cpalette, "rb"))) {
|
||||
printf(" Error loading custom palette from file: %s\n", cpalette);
|
||||
if(!(fp = FCEUD_UTF8fopen(file.c_str(), "rb"))) {
|
||||
printf(" Error loading custom palette from file: %s\n", file.c_str());
|
||||
return;
|
||||
}
|
||||
fread(tmpp, 1, 192, fp);
|
||||
|
@ -245,76 +46,28 @@ LoadCPalette()
|
|||
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)
|
||||
CreateDirs(const std::string &dir)
|
||||
{
|
||||
char *subs[7]={"fcs","fcm","snaps","gameinfo","sav","cheats","movie"};
|
||||
char tdir[2048];
|
||||
std::string subdir;
|
||||
int x;
|
||||
|
||||
#ifdef WIN32
|
||||
mkdir((char *)DrBaseDirectory);
|
||||
mkdir(dir.c_str());
|
||||
for(x = 0; x < 6; x++) {
|
||||
sprintf(tdir,"%s"PSS"%s",DrBaseDirectory,subs[x]);
|
||||
mkdir(tdir);
|
||||
subdir = dir + PSS + subs[x];
|
||||
mkdir(subdir.c_str());
|
||||
}
|
||||
#else
|
||||
mkdir((char *)DrBaseDirectory,S_IRWXU);
|
||||
mkdir(dir.c_str(), S_IRWXU);
|
||||
for(x = 0; x < 6; x++) {
|
||||
sprintf(tdir,"%s"PSS"%s",DrBaseDirectory,subs[x]);
|
||||
mkdir(tdir,S_IRWXU);
|
||||
subdir = dir + PSS + subs[x];
|
||||
mkdir(subdir.c_str(), S_IRWXU);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -324,58 +77,242 @@ CreateDirs(void)
|
|||
* hopefully become obsolete once the new configuration system is in
|
||||
* place.
|
||||
*/
|
||||
static uint8 *
|
||||
GetBaseDirectory()
|
||||
static void
|
||||
GetBaseDirectory(std::string &dir)
|
||||
{
|
||||
uint8 *ol;
|
||||
uint8 *ret;
|
||||
char *home, *lastBS;
|
||||
|
||||
ol=(uint8 *)getenv("HOME");
|
||||
|
||||
if(ol) {
|
||||
ret=(uint8 *)malloc(strlen((char *)ol)+1+strlen("./fceultra"));
|
||||
strcpy((char *)ret,(char *)ol);
|
||||
strcat((char *)ret,"/.fceultra");
|
||||
home = getenv("HOME");
|
||||
if(home) {
|
||||
dir = std::string(home) + "/.fceultra";
|
||||
} else {
|
||||
#ifdef WIN32
|
||||
char *sa;
|
||||
home = new char[MAX_PATH + 1];
|
||||
GetModuleFileName(NULL, home, MAX_PATH + 1);
|
||||
|
||||
ret=(uint8*)malloc(MAX_PATH+1);
|
||||
GetModuleFileName(NULL,(char*)ret,MAX_PATH+1);
|
||||
lastBS = strrchr(home,'\\');
|
||||
if(lastBS) {
|
||||
*lastBS = 0;
|
||||
}
|
||||
|
||||
sa=strrchr((char*)ret,'\\');
|
||||
if(sa)
|
||||
*sa = 0;
|
||||
dir = std::string(home);
|
||||
delete[] home;
|
||||
#else
|
||||
ret=(uint8 *)malloc(sizeof(uint8));
|
||||
ret[0]=0;
|
||||
dir = "";
|
||||
#endif
|
||||
printf("%s\n",ret);
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
InitConfig(int argc,
|
||||
char **argv)
|
||||
Config *
|
||||
InitConfig()
|
||||
{
|
||||
DrBaseDirectory = (char *)GetBaseDirectory();
|
||||
FCEUI_SetBaseDirectory(DrBaseDirectory);
|
||||
std::string dir, prefix;
|
||||
Config *config;
|
||||
|
||||
CreateDirs();
|
||||
GetBaseDirectory(dir);
|
||||
|
||||
if(argc<=1) {
|
||||
ShowUsage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
LoadConfig();
|
||||
DoArgs(argc - 2, &argv[1]);
|
||||
FCEUI_SetBaseDirectory(dir.c_str());
|
||||
CreateDirs(dir);
|
||||
|
||||
FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue);
|
||||
if(cpalette) {
|
||||
LoadCPalette();
|
||||
config = new Config(dir);
|
||||
|
||||
// sound options
|
||||
config->addOption('s', "sound", "SDL.Sound", 1);
|
||||
config->addOption("volume", "SDL.SoundVolume", 100);
|
||||
config->addOption("SDL.SoundRate", 48000);
|
||||
config->addOption("SDL.SoundQuality", 0);
|
||||
config->addOption("soundrecord", "SDL.SoundRecordFile", "");
|
||||
#ifdef WIN32
|
||||
config->addOption("SDL.SoundBufSize", 52);
|
||||
#else
|
||||
config->addOption("SDL.SoundBufSize", 24);
|
||||
#endif
|
||||
|
||||
// old EOptions
|
||||
config->addOption('g', "gamegenie", "SDL.GameGenie", 0);
|
||||
config->addOption("lowpass", "SDL.LowPass", 0);
|
||||
config->addOption("pal", "SDL.PAL", 0);
|
||||
config->addOption("frameskip", "SDL.Frameskip", 0);
|
||||
config->addOption("SDL.SnapName", 0);
|
||||
config->addOption("SDL.ClipSides", 0);
|
||||
config->addOption("SDL.NoThrottle", 0);
|
||||
config->addOption("SDL.DisableSpriteLimit", 0);
|
||||
|
||||
// color control
|
||||
config->addOption('p', "palette", "SDL.Palette", "");
|
||||
config->addOption("tint", "SDL.Tint", 56);
|
||||
config->addOption("hue", "SDL.Hue", 72);
|
||||
config->addOption("color", "SDL.Color", 0);
|
||||
|
||||
// scanline settings
|
||||
config->addOption("SDL.ScanLineStart", 0);
|
||||
config->addOption("SDL.ScanLineEnd", 239);
|
||||
|
||||
// video controls
|
||||
config->addOption('x', "xres", "SDL.XResolution", 512);
|
||||
config->addOption('y', "yres", "SDL.YResolution", 448);
|
||||
config->addOption('f', "fullscreen", "SDL.Fullscreen", 0);
|
||||
config->addOption('b', "bpp", "SDL.BitsPerPixel", 32);
|
||||
config->addOption("doublebuf", "SDL.DoubleBuffering", 0);
|
||||
config->addOption("xscale", "SDL.XScale", 1.0);
|
||||
config->addOption("yscale", "SDL.YScale", 1.0);
|
||||
config->addOption("xstretch", "SDL.XStretch", 0);
|
||||
config->addOption("ystretch", "SDL.YStretch", 0);
|
||||
|
||||
// OpenGL options
|
||||
config->addOption("opengl", "SDL.OpenGL", 0);
|
||||
config->addOption("SDL.OpenGLip", 0);
|
||||
config->addOption("SDL.SpecialFilter", 0);
|
||||
config->addOption("SDL.SpecialFX", 0);
|
||||
|
||||
// network play options
|
||||
config->addOption('n', "net", "SDL.NetworkServer", "");
|
||||
config->addOption('u', "user", "SDL.NetworkUsername", "");
|
||||
config->addOption('w', "pass", "SDL.NetworkPassword", "");
|
||||
config->addOption('k', "netkey", "SDL.NetworkGameKey", "");
|
||||
config->addOption('p', "port", "SDL.NetworkPort", 0xFCE);
|
||||
config->addOption('l', "players", "SDL.NetworkNumPlayers", 1);
|
||||
|
||||
// input configuration options
|
||||
config->addOption("SDL.Input.0", "GamePad.0");
|
||||
config->addOption("SDL.Input.1", "GamePad.1");
|
||||
config->addOption("SDL.Input.2", "None");
|
||||
|
||||
// Allow for input configuration
|
||||
config->addOption('i', "inputcfg", "SDL.InputCfg", InputCfg);
|
||||
|
||||
// GamePad 0 - 3
|
||||
for(unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++) {
|
||||
char buf[64];
|
||||
snprintf(buf, 20, "SDL.Input.GamePad.%d.", i);
|
||||
prefix = buf;
|
||||
|
||||
config->addOption(prefix + "DeviceType", DefaultGamePadDevice[i]);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < GAMEPAD_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + GamePadNames[j], DefaultGamePad[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
// PowerPad 0 - 1
|
||||
for(unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++) {
|
||||
char buf[64];
|
||||
snprintf(buf, 20, "SDL.Input.PowerPad.%d.", i);
|
||||
prefix = buf;
|
||||
|
||||
config->addOption(prefix + "DeviceType", DefaultPowerPadDevice[i]);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < POWERPAD_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix +PowerPadNames[j], DefaultPowerPad[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
// QuizKing
|
||||
prefix = "SDL.Input.QuizKing.";
|
||||
config->addOption(prefix + "DeviceType", DefaultQuizKingDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < QUIZKING_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + QuizKingNames[j], DefaultQuizKing[j]);
|
||||
}
|
||||
|
||||
// HyperShot
|
||||
prefix = "SDL.Input.HyperShot.";
|
||||
config->addOption(prefix + "DeviceType", DefaultHyperShotDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < HYPERSHOT_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + HyperShotNames[j], DefaultHyperShot[j]);
|
||||
}
|
||||
|
||||
// Mahjong
|
||||
prefix = "SDL.Input.Mahjong.";
|
||||
config->addOption(prefix + "DeviceType", DefaultMahjongDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < MAHJONG_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + MahjongNames[j], DefaultMahjong[j]);
|
||||
}
|
||||
|
||||
// TopRider
|
||||
prefix = "SDL.Input.TopRider.";
|
||||
config->addOption(prefix + "DeviceType", DefaultTopRiderDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < TOPRIDER_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + TopRiderNames[j], DefaultTopRider[j]);
|
||||
}
|
||||
|
||||
// FTrainer
|
||||
prefix = "SDL.Input.FTrainer.";
|
||||
config->addOption(prefix + "DeviceType", DefaultFTrainerDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < FTRAINER_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + FTrainerNames[j], DefaultFTrainer[j]);
|
||||
}
|
||||
|
||||
// FamilyKeyBoard
|
||||
prefix = "SDL.Input.FamilyKeyBoard.";
|
||||
config->addOption(prefix + "DeviceType", DefaultFamilyKeyBoardDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < FAMILYKEYBOARD_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + FamilyKeyBoardNames[j],
|
||||
DefaultFamilyKeyBoard[j]);
|
||||
}
|
||||
|
||||
// All mouse devices
|
||||
config->addOption("SDL.OekaKids.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.OekaKids.0.DeviceNum", 0);
|
||||
|
||||
config->addOption("SDL.Arkanoid.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.Arkanoid.0.DeviceNum", 0);
|
||||
|
||||
config->addOption("SDL.Shadow.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.Shadow.0.DeviceNum", 0);
|
||||
|
||||
config->addOption("SDL.Zapper.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.Zapper.0.DeviceNum", 0);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
void
|
||||
UpdateEMUCore(Config *config)
|
||||
{
|
||||
int ntsccol, ntsctint, ntschue, flag, start, end;
|
||||
std::string cpalette;
|
||||
|
||||
config->getOption("SDL.Color", &ntsccol);
|
||||
config->getOption("SDL.Tint", &ntsctint);
|
||||
config->getOption("SDL.Hue", &ntschue);
|
||||
FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue);
|
||||
|
||||
config->getOption("SDL.Palette", &cpalette);
|
||||
if(cpalette.size()) {
|
||||
LoadCPalette(cpalette);
|
||||
}
|
||||
|
||||
config->getOption("SDL.PAL", &flag);
|
||||
FCEUI_SetVidSystem(flag ? 1 : 0);
|
||||
|
||||
config->getOption("SDL.GameGenie", &flag);
|
||||
FCEUI_SetGameGenie(flag ? 1 : 0);
|
||||
|
||||
config->getOption("SDL.LowPass", &flag);
|
||||
FCEUI_SetLowPass(flag ? 1 : 0);
|
||||
|
||||
config->getOption("SDL.DisableSpriteLimit", &flag);
|
||||
FCEUI_DisableSpriteLimitation(flag ? 1 : 0);
|
||||
|
||||
config->getOption("SDL.DisableSpriteLimit", &flag);
|
||||
FCEUI_SetSnapName(flag ? 1 : 0);
|
||||
|
||||
config->getOption("SDL.ScanLineStart", &start);
|
||||
config->getOption("SDL.ScanLineEnd", &end);
|
||||
|
||||
#if DOING_SCANLINE_CHECKS
|
||||
for(int i = 0; i < 2; x++) {
|
||||
if(srendlinev[x]<0 || srendlinev[x]>239) srendlinev[x]=0;
|
||||
if(erendlinev[x]<srendlinev[x] || erendlinev[x]>239) erendlinev[x]=239;
|
||||
}
|
||||
#endif
|
||||
|
||||
FCEUI_SetRenderedLines(start + 8, end - 8, start, end);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
extern int frameskip;
|
||||
extern char *cpalette;
|
||||
extern char *soundrecfn;
|
||||
extern int ntsccol, ntschue, ntsctint;
|
||||
extern char *DrBaseDirectory;
|
||||
#include "../common/configSys.h"
|
||||
|
||||
int InitConfig(int, char **);
|
||||
void SaveConfig(void);
|
||||
void SetDefaults(void);
|
||||
Config *InitConfig(void);
|
||||
void UpdateEMUCore(Config *);
|
||||
|
|
|
@ -29,15 +29,15 @@
|
|||
#include "../common/cheat.h"
|
||||
#include "../../fceu.h"
|
||||
|
||||
|
||||
/** GLOBALS **/
|
||||
int NoWaiting=1;
|
||||
|
||||
|
||||
/* UsrInputType[] is user-specified. InputType[] is current
|
||||
(game loading can override user settings)
|
||||
*/
|
||||
static int UsrInputType[3] = {SI_GAMEPAD, SI_GAMEPAD, SIFC_NONE};
|
||||
static int InputType[3] = {0, 0, 0};
|
||||
static int UsrInputType[NUM_INPUT_DEVICES];
|
||||
static int InputType[NUM_INPUT_DEVICES];
|
||||
static int cspec = 0;
|
||||
|
||||
extern int gametype;
|
||||
|
@ -990,41 +990,106 @@ ConfigButton(char *text,
|
|||
/**
|
||||
* Update the button configuration for a specified device.
|
||||
*/
|
||||
extern Config *g_config;
|
||||
|
||||
void
|
||||
ConfigDevice(int which,
|
||||
int arg)
|
||||
{
|
||||
uint8 buf[256];
|
||||
char buf[256];
|
||||
int x;
|
||||
std::string prefix;
|
||||
char *str[10]={"A","B","SELECT","START","UP","DOWN","LEFT","RIGHT","Rapid A","Rapid B"};
|
||||
|
||||
// XXX soules - set the configuration options so that later calls
|
||||
// don't override these. This is a temp hack until I
|
||||
// can clean up this file.
|
||||
|
||||
ButtonConfigBegin();
|
||||
switch(which) {
|
||||
case FCFGD_QUIZKING:
|
||||
prefix = "SDL.Input.QuizKing.";
|
||||
for(x = 0; x < 6; x++) {
|
||||
sprintf((char *)buf, "Quiz King Buzzer #%d", x+1);
|
||||
ConfigButton((char *)buf, &QuizKingButtons[x]);
|
||||
sprintf(buf, "Quiz King Buzzer #%d", x+1);
|
||||
ConfigButton(buf, &QuizKingButtons[x]);
|
||||
|
||||
g_config->setOption(prefix + QuizKingNames[x],
|
||||
QuizKingButtons[x].ButtonNum[0]);
|
||||
}
|
||||
|
||||
if(QuizKingButtons[0].ButtType[0] == BUTTC_KEYBOARD) {
|
||||
g_config->setOption(prefix + "DeviceType", "Keyboard");
|
||||
} else if(QuizKingButtons[0].ButtType[0] == BUTTC_JOYSTICK) {
|
||||
g_config->setOption(prefix + "DeviceType", "Joystick");
|
||||
} else {
|
||||
g_config->setOption(prefix + "DeviceType", "Unknown");
|
||||
}
|
||||
g_config->setOption(prefix + "DeviceNum",
|
||||
QuizKingButtons[0].DeviceNum[0]);
|
||||
break;
|
||||
case FCFGD_HYPERSHOT:
|
||||
prefix = "SDL.Input.HyperShot.";
|
||||
for(x = 0; x < 4; x++) {
|
||||
sprintf((char *)buf, "Hyper Shot %d: %s",
|
||||
sprintf(buf, "Hyper Shot %d: %s",
|
||||
((x & 2) >> 1) + 1, (x & 1) ? "JUMP" : "RUN");
|
||||
ConfigButton((char *)buf, &HyperShotButtons[x]);
|
||||
ConfigButton(buf, &HyperShotButtons[x]);
|
||||
|
||||
g_config->setOption(prefix + HyperShotNames[x],
|
||||
HyperShotButtons[x].ButtonNum[0]);
|
||||
}
|
||||
|
||||
if(HyperShotButtons[0].ButtType[0] == BUTTC_KEYBOARD) {
|
||||
g_config->setOption(prefix + "DeviceType", "Keyboard");
|
||||
} else if(HyperShotButtons[0].ButtType[0] == BUTTC_JOYSTICK) {
|
||||
g_config->setOption(prefix + "DeviceType", "Joystick");
|
||||
} else {
|
||||
g_config->setOption(prefix + "DeviceType", "Unknown");
|
||||
}
|
||||
g_config->setOption(prefix + "DeviceNum",
|
||||
HyperShotButtons[0].DeviceNum[0]);
|
||||
break;
|
||||
case FCFGD_POWERPAD:
|
||||
snprintf(buf, 256, "SDL.Input.PowerPad.%d", (arg & 1));
|
||||
prefix = buf;
|
||||
for(x = 0; x < 12; x++) {
|
||||
sprintf((char *)buf, "PowerPad %d: %d", (arg & 1) + 1, x + 11);
|
||||
ConfigButton((char *)buf, &powerpadsc[arg&1][x]);
|
||||
sprintf(buf, "PowerPad %d: %d", (arg & 1) + 1, x + 11);
|
||||
ConfigButton(buf, &powerpadsc[arg&1][x]);
|
||||
|
||||
g_config->setOption(prefix + PowerPadNames[x],
|
||||
powerpadsc[arg & 1][x].ButtonNum[0]);
|
||||
}
|
||||
|
||||
if(powerpadsc[arg & 1][0].ButtType[0] == BUTTC_KEYBOARD) {
|
||||
g_config->setOption(prefix + "DeviceType", "Keyboard");
|
||||
} else if(powerpadsc[arg & 1][0].ButtType[0] == BUTTC_JOYSTICK) {
|
||||
g_config->setOption(prefix + "DeviceType", "Joystick");
|
||||
} else {
|
||||
g_config->setOption(prefix + "DeviceType", "Unknown");
|
||||
}
|
||||
g_config->setOption(prefix + "DeviceNum",
|
||||
powerpadsc[arg & 1][0].DeviceNum[0]);
|
||||
break;
|
||||
|
||||
case FCFGD_GAMEPAD:
|
||||
snprintf(buf, 256, "SDL.Input.GamePad.%d", arg);
|
||||
prefix = buf;
|
||||
for(x = 0; x < 10; x++) {
|
||||
sprintf((char *)buf, "GamePad #%d: %s", arg + 1, str[x]);
|
||||
ConfigButton((char *)buf, &GamePadConfig[arg][x]);
|
||||
sprintf(buf, "GamePad #%d: %s", arg + 1, str[x]);
|
||||
ConfigButton(buf, &GamePadConfig[arg][x]);
|
||||
|
||||
g_config->setOption(prefix + GamePadNames[x],
|
||||
GamePadConfig[arg][x].ButtonNum[0]);
|
||||
}
|
||||
|
||||
if(GamePadConfig[arg][0].ButtType[0] == BUTTC_KEYBOARD) {
|
||||
g_config->setOption(prefix + "DeviceType", "Keyboard");
|
||||
} else if(GamePadConfig[arg][0].ButtType[0] == BUTTC_JOYSTICK) {
|
||||
g_config->setOption(prefix + "DeviceType", "Joystick");
|
||||
} else {
|
||||
g_config->setOption(prefix + "DeviceType", "Unknown");
|
||||
}
|
||||
g_config->setOption(prefix + "DeviceNum",
|
||||
GamePadConfig[arg][0].DeviceNum[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1035,16 +1100,16 @@ ConfigDevice(int which,
|
|||
/**
|
||||
* Update the button configuration for a device, specified by a text string.
|
||||
*/
|
||||
static void
|
||||
InputCfg(char *text)
|
||||
void
|
||||
InputCfg(const std::string &text)
|
||||
{
|
||||
if(!strncasecmp(text, "gamepad", strlen("gamepad"))) {
|
||||
if(text.find("gamepad") != std::string::npos) {
|
||||
ConfigDevice(FCFGD_GAMEPAD, (text[strlen("gamepad")] - '1') & 3);
|
||||
} else if(!strncasecmp(text, "powerpad", strlen("powerpad"))) {
|
||||
} else if(text.find("powerpad") != std::string::npos) {
|
||||
ConfigDevice(FCFGD_POWERPAD, (text[strlen("powerpad")] - '1') & 1);
|
||||
} else if(!strcasecmp(text,"hypershot")) {
|
||||
} else if(text.find("hypershot") != std::string::npos) {
|
||||
ConfigDevice(FCFGD_HYPERSHOT, 0);
|
||||
} else if(!strcasecmp(text,"quizking")) {
|
||||
} else if(text.find("quizking") != std::string::npos) {
|
||||
ConfigDevice(FCFGD_QUIZKING, 0);
|
||||
}
|
||||
}
|
||||
|
@ -1108,7 +1173,7 @@ Input2(char *text)
|
|||
}
|
||||
|
||||
/** GLOBALS **/
|
||||
|
||||
#if 0
|
||||
CFGSTRUCT InputConfig[]={
|
||||
ACA(UsrInputType),
|
||||
AC(powerpadsc),
|
||||
|
@ -1128,4 +1193,238 @@ ARGPSTRUCT InputArgs[]={
|
|||
{"-input2",0,(void *)Input2,0x2000},
|
||||
{0,0,0,0}
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Hack to map the new configuration onto the existing button
|
||||
* configuration management. Will probably want to change this in the
|
||||
* future - soules.
|
||||
*/
|
||||
void
|
||||
UpdateInput(Config *config)
|
||||
{
|
||||
char buf[64];
|
||||
std::string device, prefix;
|
||||
|
||||
for(unsigned int i = 0; i < 3; i++) {
|
||||
snprintf(buf, 64, "SDL.Input.%d", i);
|
||||
config->getOption(buf, &device);
|
||||
|
||||
if(device == "None") {
|
||||
UsrInputType[i] = SI_NONE;
|
||||
} else if(device.find("GamePad") != std::string::npos) {
|
||||
UsrInputType[i] = (i < 2) ? SI_GAMEPAD : SI_NONE;
|
||||
} else if(device.find("PowerPad.0") != std::string::npos) {
|
||||
UsrInputType[i] = (i < 2) ? SI_POWERPADA : SI_NONE;
|
||||
} else if(device.find("PowerPad.1") != std::string::npos) {
|
||||
UsrInputType[i] = (i < 2) ? SI_POWERPADB : SI_NONE;
|
||||
} else if(device.find("QuizKing") != std::string::npos) {
|
||||
UsrInputType[i] = (i < 2) ? SI_NONE : SIFC_QUIZKING;
|
||||
} else if(device.find("HyperShot") != std::string::npos) {
|
||||
UsrInputType[i] = (i < 2) ? SI_NONE : SIFC_HYPERSHOT;
|
||||
} else if(device.find("Mahjong") != std::string::npos) {
|
||||
UsrInputType[i] = (i < 2) ? SI_NONE : SIFC_MAHJONG;
|
||||
} else if(device.find("TopRider") != std::string::npos) {
|
||||
UsrInputType[i] = (i < 2) ? SI_NONE : SIFC_TOPRIDER;
|
||||
} else if(device.find("FTrainer") != std::string::npos) {
|
||||
UsrInputType[i] = (i < 2) ? SI_NONE : SIFC_FTRAINERA;
|
||||
} else if(device.find("FamilyKeyBoard") != std::string::npos) {
|
||||
UsrInputType[i] = (i < 2) ? SI_NONE : SIFC_FKB;
|
||||
} else if(device.find("OekaKids") != std::string::npos) {
|
||||
UsrInputType[i] = (i < 2) ? SI_NONE : SIFC_OEKAKIDS;
|
||||
} else if(device.find("Arkanoid") != std::string::npos) {
|
||||
UsrInputType[i] = (i < 2) ? SI_ARKANOID : SIFC_ARKANOID;
|
||||
} else if(device.find("Shadow") != std::string::npos) {
|
||||
UsrInputType[i] = (i < 2) ? SI_NONE : SIFC_SHADOW;
|
||||
} else if(device.find("Zapper") != std::string::npos) {
|
||||
UsrInputType[i] = (i < 2) ? SI_ZAPPER : SIFC_NONE;
|
||||
} else if(device.find("BWorld") != std::string::npos) {
|
||||
UsrInputType[i] = (i < 2) ? SI_NONE : SIFC_BWORLD;
|
||||
} else if(device.find("4Player") != std::string::npos) {
|
||||
UsrInputType[i] = (i < 2) ? SI_NONE : SIFC_4PLAYER;
|
||||
} else {
|
||||
// Unknown device
|
||||
UsrInputType[i] = SI_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
// update each of the devices' configuration structure
|
||||
// XXX soules - this is temporary until this file is cleaned up to
|
||||
// simplify the interface between configuration and
|
||||
// structure data. This will likely include the
|
||||
// removal of multiple input buttons for a single
|
||||
// input device key.
|
||||
int type, devnum, button;
|
||||
|
||||
// gamepad 0 - 3
|
||||
for(unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++) {
|
||||
char buf[64];
|
||||
snprintf(buf, 20, "SDL.Input.GamePad.%d.", i);
|
||||
prefix = buf;
|
||||
|
||||
config->getOption(prefix + "DeviceType", &device);
|
||||
if(device.find("Keyboard") != std::string::npos) {
|
||||
type = BUTTC_KEYBOARD;
|
||||
} else if(device.find("Joystick") != std::string::npos) {
|
||||
type = BUTTC_JOYSTICK;
|
||||
} else {
|
||||
type = 0;
|
||||
}
|
||||
|
||||
config->getOption(prefix + "DeviceNum", &devnum);
|
||||
for(unsigned int j = 0; j < GAMEPAD_NUM_BUTTONS; j++) {
|
||||
config->getOption(prefix + GamePadNames[j], &button);
|
||||
|
||||
GamePadConfig[i][j].ButtType[0] = type;
|
||||
GamePadConfig[i][j].DeviceNum[0] = devnum;
|
||||
GamePadConfig[i][j].ButtonNum[0] = button;
|
||||
GamePadConfig[i][j].NumC = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// PowerPad 0 - 1
|
||||
for(unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++) {
|
||||
char buf[64];
|
||||
snprintf(buf, 20, "SDL.Input.PowerPad.%d.", i);
|
||||
prefix = buf;
|
||||
|
||||
config->getOption(prefix + "DeviceType", &device);
|
||||
if(device.find("Keyboard") != std::string::npos) {
|
||||
type = BUTTC_KEYBOARD;
|
||||
} else if(device.find("Joystick") != std::string::npos) {
|
||||
type = BUTTC_JOYSTICK;
|
||||
} else {
|
||||
type = 0;
|
||||
}
|
||||
|
||||
config->getOption(prefix + "DeviceNum", &devnum);
|
||||
for(unsigned int j = 0; j < POWERPAD_NUM_BUTTONS; j++) {
|
||||
config->getOption(prefix + PowerPadNames[j], &button);
|
||||
|
||||
powerpadsc[i][j].ButtType[0] = type;
|
||||
powerpadsc[i][j].DeviceNum[0] = devnum;
|
||||
powerpadsc[i][j].ButtonNum[0] = button;
|
||||
powerpadsc[i][j].NumC = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// QuizKing
|
||||
prefix = "SDL.Input.QuizKing.";
|
||||
config->getOption(prefix + "DeviceType", &device);
|
||||
if(device.find("Keyboard") != std::string::npos) {
|
||||
type = BUTTC_KEYBOARD;
|
||||
} else if(device.find("Joystick") != std::string::npos) {
|
||||
type = BUTTC_JOYSTICK;
|
||||
} else {
|
||||
type = 0;
|
||||
}
|
||||
config->getOption(prefix + "DeviceNum", &devnum);
|
||||
for(unsigned int j = 0; j < QUIZKING_NUM_BUTTONS; j++) {
|
||||
config->getOption(prefix + QuizKingNames[j], &button);
|
||||
|
||||
QuizKingButtons[j].ButtType[0] = type;
|
||||
QuizKingButtons[j].DeviceNum[0] = devnum;
|
||||
QuizKingButtons[j].ButtonNum[0] = button;
|
||||
QuizKingButtons[j].NumC = 1;
|
||||
}
|
||||
|
||||
// HyperShot
|
||||
prefix = "SDL.Input.HyperShot.";
|
||||
config->getOption(prefix + "DeviceType", &device);
|
||||
if(device.find("Keyboard") != std::string::npos) {
|
||||
type = BUTTC_KEYBOARD;
|
||||
} else if(device.find("Joystick") != std::string::npos) {
|
||||
type = BUTTC_JOYSTICK;
|
||||
} else {
|
||||
type = 0;
|
||||
}
|
||||
config->getOption(prefix + "DeviceNum", &devnum);
|
||||
for(unsigned int j = 0; j < HYPERSHOT_NUM_BUTTONS; j++) {
|
||||
config->getOption(prefix + HyperShotNames[j], &button);
|
||||
|
||||
HyperShotButtons[j].ButtType[0] = type;
|
||||
HyperShotButtons[j].DeviceNum[0] = devnum;
|
||||
HyperShotButtons[j].ButtonNum[0] = button;
|
||||
HyperShotButtons[j].NumC = 1;
|
||||
}
|
||||
|
||||
// Mahjong
|
||||
prefix = "SDL.Input.Mahjong.";
|
||||
config->getOption(prefix + "DeviceType", &device);
|
||||
if(device.find("Keyboard") != std::string::npos) {
|
||||
type = BUTTC_KEYBOARD;
|
||||
} else if(device.find("Joystick") != std::string::npos) {
|
||||
type = BUTTC_JOYSTICK;
|
||||
} else {
|
||||
type = 0;
|
||||
}
|
||||
config->getOption(prefix + "DeviceNum", &devnum);
|
||||
for(unsigned int j = 0; j < MAHJONG_NUM_BUTTONS; j++) {
|
||||
config->getOption(prefix + MahjongNames[j], &button);
|
||||
|
||||
MahjongButtons[j].ButtType[0] = type;
|
||||
MahjongButtons[j].DeviceNum[0] = devnum;
|
||||
MahjongButtons[j].ButtonNum[0] = button;
|
||||
MahjongButtons[j].NumC = 1;
|
||||
}
|
||||
|
||||
// TopRider
|
||||
prefix = "SDL.Input.TopRider.";
|
||||
config->getOption(prefix + "DeviceType", &device);
|
||||
if(device.find("Keyboard") != std::string::npos) {
|
||||
type = BUTTC_KEYBOARD;
|
||||
} else if(device.find("Joystick") != std::string::npos) {
|
||||
type = BUTTC_JOYSTICK;
|
||||
} else {
|
||||
type = 0;
|
||||
}
|
||||
config->getOption(prefix + "DeviceNum", &devnum);
|
||||
for(unsigned int j = 0; j < TOPRIDER_NUM_BUTTONS; j++) {
|
||||
config->getOption(prefix + TopRiderNames[j], &button);
|
||||
|
||||
TopRiderButtons[j].ButtType[0] = type;
|
||||
TopRiderButtons[j].DeviceNum[0] = devnum;
|
||||
TopRiderButtons[j].ButtonNum[0] = button;
|
||||
TopRiderButtons[j].NumC = 1;
|
||||
}
|
||||
|
||||
// FTrainer
|
||||
prefix = "SDL.Input.FTrainer.";
|
||||
config->getOption(prefix + "DeviceType", &device);
|
||||
if(device.find("Keyboard") != std::string::npos) {
|
||||
type = BUTTC_KEYBOARD;
|
||||
} else if(device.find("Joystick") != std::string::npos) {
|
||||
type = BUTTC_JOYSTICK;
|
||||
} else {
|
||||
type = 0;
|
||||
}
|
||||
config->getOption(prefix + "DeviceNum", &devnum);
|
||||
for(unsigned int j = 0; j < FTRAINER_NUM_BUTTONS; j++) {
|
||||
config->getOption(prefix + FTrainerNames[j], &button);
|
||||
|
||||
FTrainerButtons[j].ButtType[0] = type;
|
||||
FTrainerButtons[j].DeviceNum[0] = devnum;
|
||||
FTrainerButtons[j].ButtonNum[0] = button;
|
||||
FTrainerButtons[j].NumC = 1;
|
||||
}
|
||||
|
||||
// FamilyKeyBoard
|
||||
prefix = "SDL.Input.FamilyKeyBoard.";
|
||||
config->getOption(prefix + "DeviceType", &device);
|
||||
if(device.find("Keyboard") != std::string::npos) {
|
||||
type = BUTTC_KEYBOARD;
|
||||
} else if(device.find("Joystick") != std::string::npos) {
|
||||
type = BUTTC_JOYSTICK;
|
||||
} else {
|
||||
type = 0;
|
||||
}
|
||||
config->getOption(prefix + "DeviceNum", &devnum);
|
||||
for(unsigned int j = 0; j < FAMILYKEYBOARD_NUM_BUTTONS; j++) {
|
||||
config->getOption(prefix + FamilyKeyBoardNames[j], &button);
|
||||
|
||||
fkbmap[j].ButtType[0] = type;
|
||||
fkbmap[j].DeviceNum[0] = devnum;
|
||||
fkbmap[j].ButtonNum[0] = button;
|
||||
fkbmap[j].NumC = 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#ifndef _aosdfjk02fmasf
|
||||
#define _aosdfjk02fmasf
|
||||
|
||||
#include "../common/configSys.h"
|
||||
|
||||
#define MAXBUTTCONFIG 4
|
||||
typedef struct {
|
||||
uint8 ButtType[MAXBUTTCONFIG];
|
||||
|
@ -37,4 +40,8 @@ void DecreaseEmulationSpeed(void);
|
|||
int DTestButtonJoy(ButtConfig *bc);
|
||||
|
||||
void FCEUD_UpdateInput(void);
|
||||
|
||||
void UpdateInput(Config *config);
|
||||
void InputCfg(const std::string &);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __FCEU_SDL_MAIN_H
|
||||
#define __FCEU_SDL_MAIN_H
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "../../driver.h"
|
||||
#include "../common/config.h"
|
||||
|
@ -42,3 +46,110 @@ extern long soundbufsize;
|
|||
|
||||
int CLImain(int argc, char *argv[]);
|
||||
|
||||
// Device management defaults
|
||||
#define NUM_INPUT_DEVICES 3
|
||||
|
||||
// GamePad defaults
|
||||
#define GAMEPAD_NUM_DEVICES 4
|
||||
#define GAMEPAD_NUM_BUTTONS 10
|
||||
static char *GamePadNames[GAMEPAD_NUM_BUTTONS] =
|
||||
{"A", "B", "Select", "Start",
|
||||
"Up", "Down", "Left", "Right", "TurboA", "TurboB"};
|
||||
static char *DefaultGamePadDevice[GAMEPAD_NUM_DEVICES] =
|
||||
{"Keyboard", "None", "None", "None"};
|
||||
static int DefaultGamePad[GAMEPAD_NUM_DEVICES][GAMEPAD_NUM_BUTTONS] =
|
||||
{ { SDLK_KP2, SDLK_KP3, SDLK_TAB, SDLK_RETURN,
|
||||
SDLK_w, SDLK_s, SDLK_a, SDLK_d, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
|
||||
|
||||
// PowerPad defaults
|
||||
#define POWERPAD_NUM_DEVICES 2
|
||||
#define POWERPAD_NUM_BUTTONS 12
|
||||
static char *PowerPadNames[POWERPAD_NUM_BUTTONS] =
|
||||
{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B"};
|
||||
static char *DefaultPowerPadDevice[POWERPAD_NUM_DEVICES] =
|
||||
{"Keyboard", "None"};
|
||||
static int DefaultPowerPad[POWERPAD_NUM_DEVICES][POWERPAD_NUM_BUTTONS] =
|
||||
{ { SDLK_o, SDLK_p, SDLK_LEFTBRACKET, SDLK_RIGHTBRACKET,
|
||||
SDLK_k, SDLK_l, SDLK_SEMICOLON, SDLK_QUOTE,
|
||||
SDLK_m, SDLK_COMMA, SDLK_PERIOD, SDLK_SLASH },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
|
||||
|
||||
// QuizKing defaults
|
||||
#define QUIZKING_NUM_BUTTONS 6
|
||||
static char *QuizKingNames[QUIZKING_NUM_BUTTONS] =
|
||||
{ "0", "1", "2", "3", "4", "5" };
|
||||
static char *DefaultQuizKingDevice = "Keyboard";
|
||||
static int DefaultQuizKing[QUIZKING_NUM_BUTTONS] =
|
||||
{ SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_y };
|
||||
|
||||
// HyperShot defaults
|
||||
#define HYPERSHOT_NUM_BUTTONS 4
|
||||
static char *HyperShotNames[HYPERSHOT_NUM_BUTTONS] =
|
||||
{ "0", "1", "2", "3" };
|
||||
static char *DefaultHyperShotDevice = "Keyboard";
|
||||
static int DefaultHyperShot[HYPERSHOT_NUM_BUTTONS] =
|
||||
{ SDLK_q, SDLK_w, SDLK_e, SDLK_r };
|
||||
|
||||
// Mahjong defaults
|
||||
#define MAHJONG_NUM_BUTTONS 21
|
||||
static char *MahjongNames[MAHJONG_NUM_BUTTONS] =
|
||||
{ "00", "01", "02", "03", "04", "05", "06", "07",
|
||||
"08", "09", "10", "11", "12", "13", "14", "15",
|
||||
"16", "17", "18", "19", "20" };
|
||||
static char *DefaultMahjongDevice = "Keyboard";
|
||||
static int DefaultMahjong[MAHJONG_NUM_BUTTONS] =
|
||||
{ SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_a, SDLK_s, SDLK_d,
|
||||
SDLK_f, SDLK_g, SDLK_h, SDLK_j, SDLK_k, SDLK_l, SDLK_z, SDLK_x,
|
||||
SDLK_c, SDLK_v, SDLK_b, SDLK_n, SDLK_m };
|
||||
|
||||
// TopRider defaults
|
||||
#define TOPRIDER_NUM_BUTTONS 8
|
||||
static char *TopRiderNames[TOPRIDER_NUM_BUTTONS] =
|
||||
{ "0", "1", "2", "3", "4", "5", "6", "7" };
|
||||
static char *DefaultTopRiderDevice = "Keyboard";
|
||||
static int DefaultTopRider[TOPRIDER_NUM_BUTTONS] =
|
||||
{ SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_y, SDLK_u, SDLK_i };
|
||||
|
||||
// FTrainer defaults
|
||||
#define FTRAINER_NUM_BUTTONS 12
|
||||
static char *FTrainerNames[FTRAINER_NUM_BUTTONS] =
|
||||
{ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B" };
|
||||
static char *DefaultFTrainerDevice = "Keyboard";
|
||||
static int DefaultFTrainer[FTRAINER_NUM_BUTTONS] =
|
||||
{ SDLK_o, SDLK_p, SDLK_LEFTBRACKET, SDLK_RIGHTBRACKET,
|
||||
SDLK_k, SDLK_l, SDLK_SEMICOLON, SDLK_QUOTE,
|
||||
SDLK_m, SDLK_COMMA, SDLK_PERIOD, SDLK_SLASH };
|
||||
|
||||
// FamilyKeyBoard defaults
|
||||
#define FAMILYKEYBOARD_NUM_BUTTONS 0x48
|
||||
static char *FamilyKeyBoardNames[FAMILYKEYBOARD_NUM_BUTTONS] =
|
||||
{ "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8",
|
||||
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
|
||||
"MINUS", "EQUAL", "BACKSLASH", "BACKSPACE",
|
||||
"ESCAPE", "Q", "W", "E", "R", "T", "Y", "U", "I", "O",
|
||||
"P", "GRAVE", "BRACKET_LEFT", "ENTER",
|
||||
"LEFTCONTROL", "A", "S", "D", "F", "G", "H", "J", "K",
|
||||
"L", "SEMICOLON", "APOSTROPHE", "BRACKET_RIGHT", "INSERT",
|
||||
"LEFTSHIFT", "Z", "X", "C", "V", "B", "N", "M", "COMMA",
|
||||
"PERIOD", "SLASH", "RIGHTALT", "RIGHTSHIFT", "LEFTALT", "SPACE",
|
||||
"DELETE", "END", "PAGEDOWN",
|
||||
"CURSORUP", "CURSORLEFT", "CURSORRIGHT", "CURSORDOWN" };
|
||||
static char *DefaultFamilyKeyBoardDevice = "Keyboard";
|
||||
static int DefaultFamilyKeyBoard[FAMILYKEYBOARD_NUM_BUTTONS] =
|
||||
{ SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5, SDLK_F6, SDLK_F7, SDLK_F8,
|
||||
SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5,
|
||||
SDLK_6, SDLK_7, SDLK_8, SDLK_9, SDLK_0,
|
||||
SDLK_MINUS, SDLK_EQUALS, SDLK_BACKSLASH, SDLK_BACKSPACE,
|
||||
SDLK_ESCAPE, SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_y, SDLK_u,
|
||||
SDLK_i, SDLK_o, SDLK_p, SDLK_BACKQUOTE, SDLK_LEFTBRACKET, SDLK_RETURN,
|
||||
SDLK_LCTRL, SDLK_a, SDLK_s, SDLK_d, SDLK_f, SDLK_g, SDLK_h, SDLK_j,
|
||||
SDLK_k, SDLK_l, SDLK_SEMICOLON, SDLK_QUOTE, SDLK_RIGHTBRACKET,
|
||||
SDLK_INSERT, SDLK_LSHIFT, SDLK_z, SDLK_x, SDLK_c, SDLK_v, SDLK_b,
|
||||
SDLK_n, SDLK_m, SDLK_COMMA, SDLK_PERIOD, SDLK_SLASH, SDLK_RALT,
|
||||
SDLK_RSHIFT, SDLK_LALT, SDLK_SPACE, SDLK_DELETE, SDLK_END, SDLK_PAGEDOWN,
|
||||
SDLK_UP, SDLK_LEFT, SDLK_RIGHT, SDLK_DOWN };
|
||||
|
||||
#endif
|
||||
|
|
|
@ -30,7 +30,10 @@
|
|||
#include "sdl.h"
|
||||
|
||||
#define MAX_JOYSTICKS 32
|
||||
static SDL_Joystick *Joysticks[MAX_JOYSTICKS] = {NULL};
|
||||
static SDL_Joystick *s_Joysticks[MAX_JOYSTICKS] = {NULL};
|
||||
|
||||
static int s_jinited = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Tests if the given button is active on the joystick.
|
||||
|
@ -44,7 +47,7 @@ DTestButtonJoy(ButtConfig *bc)
|
|||
if(bc->ButtonNum[x] & 0x8000) {
|
||||
/* Axis "button" */
|
||||
int pos;
|
||||
pos = SDL_JoystickGetAxis(Joysticks[bc->DeviceNum[x]],
|
||||
pos = SDL_JoystickGetAxis(s_Joysticks[bc->DeviceNum[x]],
|
||||
bc->ButtonNum[x] & 16383);
|
||||
if ((bc->ButtonNum[x] & 0x4000) && pos <= -16383) {
|
||||
return(1);
|
||||
|
@ -53,11 +56,11 @@ DTestButtonJoy(ButtConfig *bc)
|
|||
}
|
||||
} else if(bc->ButtonNum[x] & 0x2000) {
|
||||
/* Hat "button" */
|
||||
if(SDL_JoystickGetHat(Joysticks[bc->DeviceNum[x]],
|
||||
if(SDL_JoystickGetHat(s_Joysticks[bc->DeviceNum[x]],
|
||||
(((bc->ButtonNum[x] >> 8) & 0x1F) &
|
||||
(bc->ButtonNum[x]&0xFF)))) {
|
||||
return(1);
|
||||
} else if(SDL_JoystickGetButton(Joysticks[bc->DeviceNum[x]],
|
||||
} else if(SDL_JoystickGetButton(s_Joysticks[bc->DeviceNum[x]],
|
||||
bc->ButtonNum[x])) {
|
||||
return(1);
|
||||
}
|
||||
|
@ -66,8 +69,6 @@ DTestButtonJoy(ButtConfig *bc)
|
|||
return(0);
|
||||
}
|
||||
|
||||
static int jinited = 0;
|
||||
|
||||
/**
|
||||
* Shutdown the SDL joystick subsystem.
|
||||
*/
|
||||
|
@ -76,15 +77,15 @@ KillJoysticks()
|
|||
{
|
||||
int n; /* joystick index */
|
||||
|
||||
if(!jinited) {
|
||||
if(!s_jinited) {
|
||||
return(-1);
|
||||
}
|
||||
|
||||
for(n = 0; n < MAX_JOYSTICKS; n++) {
|
||||
if (Joysticks[n] != 0) {
|
||||
SDL_JoystickClose(Joysticks[n]);
|
||||
if (s_Joysticks[n] != 0) {
|
||||
SDL_JoystickClose(s_Joysticks[n]);
|
||||
}
|
||||
Joysticks[n]=0;
|
||||
s_Joysticks[n]=0;
|
||||
}
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
return(0);
|
||||
|
@ -108,12 +109,12 @@ InitJoysticks()
|
|||
|
||||
for(n = 0; n < total; n++) {
|
||||
/* Open the joystick under SDL. */
|
||||
Joysticks[n] = SDL_JoystickOpen(n);
|
||||
s_Joysticks[n] = SDL_JoystickOpen(n);
|
||||
//printf("Could not open joystick %d: %s.\n",
|
||||
//joy[n] - 1, SDL_GetError());
|
||||
continue;
|
||||
}
|
||||
|
||||
jinited = 1;
|
||||
s_jinited = 1;
|
||||
return(1);
|
||||
}
|
||||
|
|
|
@ -74,93 +74,107 @@ glClear_Func p_glClear;
|
|||
glMatrixMode_Func p_glMatrixMode;
|
||||
glDisable_Func p_glDisable;
|
||||
|
||||
void SetOpenGLPalette(uint8 *data)
|
||||
void
|
||||
SetOpenGLPalette(uint8 *data)
|
||||
{
|
||||
if(!HiBuffer)
|
||||
{
|
||||
p_glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||
p_glColorTableEXT(GL_TEXTURE_2D,GL_RGB,256,GL_RGBA,GL_UNSIGNED_BYTE,data);
|
||||
}
|
||||
else
|
||||
SetPaletteBlitToHigh((uint8*)data);
|
||||
if(!HiBuffer) {
|
||||
p_glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||
p_glColorTableEXT(GL_TEXTURE_2D, GL_RGB, 256,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
} else {
|
||||
SetPaletteBlitToHigh((uint8*)data);
|
||||
}
|
||||
}
|
||||
|
||||
void BlitOpenGL(uint8 *buf)
|
||||
void
|
||||
BlitOpenGL(uint8 *buf)
|
||||
{
|
||||
p_glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||
if(HiBuffer)
|
||||
{
|
||||
static int xo=0;
|
||||
xo=(xo+1)&3;
|
||||
Blit8ToHigh(buf,(uint8*)HiBuffer,256,240,256*4,1,1);
|
||||
if(!xo)
|
||||
p_glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,256,256, 0, GL_RGBA,GL_UNSIGNED_BYTE,
|
||||
HiBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
//glPixelStorei(GL_UNPACK_ROW_LENGTH, 256);
|
||||
p_glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, 256, 256, 0,
|
||||
GL_COLOR_INDEX,GL_UNSIGNED_BYTE,buf);
|
||||
}
|
||||
p_glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||
if(HiBuffer) {
|
||||
static int xo = 0;
|
||||
xo = (xo + 1) & 3;
|
||||
Blit8ToHigh(buf, (uint8*)HiBuffer, 256, 240, 256*4, 1, 1);
|
||||
if(!xo) {
|
||||
p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, HiBuffer);
|
||||
}
|
||||
} else {
|
||||
//glPixelStorei(GL_UNPACK_ROW_LENGTH, 256);
|
||||
p_glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, 256, 256, 0,
|
||||
GL_COLOR_INDEX,GL_UNSIGNED_BYTE,buf);
|
||||
}
|
||||
|
||||
p_glBegin(GL_QUADS);
|
||||
p_glTexCoord2f(1.0f*left/256, 1.0f*bottom/256); // Bottom left of our picture.
|
||||
p_glVertex2f(-1.0f, -1.0f); // Bottom left of target.
|
||||
p_glBegin(GL_QUADS);
|
||||
p_glTexCoord2f(1.0f*left/256, 1.0f*bottom/256); // Bottom left of picture.
|
||||
p_glVertex2f(-1.0f, -1.0f); // Bottom left of target.
|
||||
|
||||
p_glTexCoord2f(1.0f*right/256, 1.0f*bottom/256); // Bottom right of our picture.
|
||||
p_glVertex2f( 1.0f, -1.0f); // Bottom right of target.
|
||||
p_glTexCoord2f(1.0f*right/256, 1.0f*bottom/256);// Bottom right of picture.
|
||||
p_glVertex2f( 1.0f, -1.0f); // Bottom right of target.
|
||||
|
||||
p_glTexCoord2f(1.0f*right/256, 1.0f*top/256); // Top right of our picture.
|
||||
p_glVertex2f( 1.0f, 1.0f); // Top right of target.
|
||||
p_glTexCoord2f(1.0f*right/256, 1.0f*top/256); // Top right of our picture.
|
||||
p_glVertex2f( 1.0f, 1.0f); // Top right of target.
|
||||
|
||||
p_glTexCoord2f(1.0f*left/256, 1.0f*top/256); // Top left of our picture.
|
||||
p_glVertex2f(-1.0f, 1.0f); // Top left of target.
|
||||
p_glEnd();
|
||||
p_glTexCoord2f(1.0f*left/256, 1.0f*top/256); // Top left of our picture.
|
||||
p_glVertex2f(-1.0f, 1.0f); // Top left of target.
|
||||
p_glEnd();
|
||||
|
||||
//glDisable(GL_BLEND);
|
||||
if(scanlines)
|
||||
{
|
||||
p_glEnable(GL_BLEND);
|
||||
//glDisable(GL_BLEND);
|
||||
if(scanlines) {
|
||||
p_glEnable(GL_BLEND);
|
||||
|
||||
p_glBindTexture(GL_TEXTURE_2D, textures[1]);
|
||||
p_glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA);
|
||||
p_glBindTexture(GL_TEXTURE_2D, textures[1]);
|
||||
p_glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA);
|
||||
|
||||
p_glBegin(GL_QUADS);
|
||||
p_glBegin(GL_QUADS);
|
||||
|
||||
p_glTexCoord2f(1.0f*left/256, 1.0f*bottom/256); // Bottom left of our picture.
|
||||
p_glVertex2f(-1.0f, -1.0f); // Bottom left of target.
|
||||
p_glTexCoord2f(1.0f*left/256,
|
||||
1.0f*bottom/256); // Bottom left of our picture.
|
||||
p_glVertex2f(-1.0f, -1.0f); // Bottom left of target.
|
||||
|
||||
p_glTexCoord2f(1.0f*right/256, 1.0f*bottom/256); // Bottom right of our picture.
|
||||
p_glVertex2f( 1.0f, -1.0f); // Bottom right of target.
|
||||
p_glTexCoord2f(1.0f*right/256,
|
||||
1.0f*bottom/256); // Bottom right of our picture.
|
||||
p_glVertex2f( 1.0f, -1.0f); // Bottom right of target.
|
||||
|
||||
p_glTexCoord2f(1.0f*right/256, 1.0f*top/256); // Top right of our picture.
|
||||
p_glVertex2f( 1.0f, 1.0f); // Top right of target.
|
||||
p_glTexCoord2f(1.0f*right/256,
|
||||
1.0f*top/256); // Top right of our picture.
|
||||
p_glVertex2f( 1.0f, 1.0f); // Top right of target.
|
||||
|
||||
p_glTexCoord2f(1.0f*left/256, 1.0f*top/256); // Top left of our picture.
|
||||
p_glVertex2f(-1.0f, 1.0f); // Top left of target.
|
||||
p_glTexCoord2f(1.0f*left/256,
|
||||
1.0f*top/256); // Top left of our picture.
|
||||
p_glVertex2f(-1.0f, 1.0f); // Top left of target.
|
||||
|
||||
p_glEnd();
|
||||
p_glDisable(GL_BLEND);
|
||||
}
|
||||
SDL_GL_SwapBuffers();
|
||||
p_glEnd();
|
||||
p_glDisable(GL_BLEND);
|
||||
}
|
||||
SDL_GL_SwapBuffers();
|
||||
}
|
||||
|
||||
void KillOpenGL(void)
|
||||
void
|
||||
KillOpenGL(void)
|
||||
{
|
||||
if(textures[0])
|
||||
p_glDeleteTextures(2, &textures[0]);
|
||||
textures[0]=0;
|
||||
if(HiBuffer)
|
||||
{
|
||||
free(HiBuffer);
|
||||
HiBuffer=0;
|
||||
}
|
||||
if(textures[0]) {
|
||||
p_glDeleteTextures(2, &textures[0]);
|
||||
}
|
||||
textures[0]=0;
|
||||
if(HiBuffer) {
|
||||
free(HiBuffer);
|
||||
HiBuffer=0;
|
||||
}
|
||||
}
|
||||
/* Rectangle, left, right(not inclusive), top, bottom(not inclusive). */
|
||||
|
||||
int InitOpenGL(int l, int r, int t, int b, double xscale,double yscale, int efx, int ipolate,
|
||||
int stretchx, int stretchy, SDL_Surface *screen)
|
||||
int
|
||||
InitOpenGL(int l,
|
||||
int r,
|
||||
int t,
|
||||
int b,
|
||||
double xscale,
|
||||
double yscale,
|
||||
int efx,
|
||||
int ipolate,
|
||||
int stretchx,
|
||||
int stretchy,
|
||||
SDL_Surface *screen)
|
||||
{
|
||||
const char *extensions;
|
||||
|
||||
|
@ -211,8 +225,8 @@ int InitOpenGL(int l, int r, int t, int b, double xscale,double yscale, int efx,
|
|||
}
|
||||
|
||||
{
|
||||
int rw=(r-l)*xscale;
|
||||
int rh=(b-t)*yscale;
|
||||
int rw=(int)((r-l)*xscale);
|
||||
int rh=(int)((b-t)*yscale);
|
||||
int sx=(screen->w-rw)/2; // Start x
|
||||
int sy=(screen->h-rh)/2; // Start y
|
||||
|
||||
|
|
|
@ -27,11 +27,17 @@
|
|||
|
||||
#include "sdl.h"
|
||||
|
||||
static volatile int *Buffer = 0;
|
||||
static unsigned int BufferSize;
|
||||
static unsigned int BufferRead;
|
||||
static unsigned int BufferWrite;
|
||||
static volatile unsigned int BufferIn;
|
||||
#include "../common/configSys.h"
|
||||
extern Config *g_config;
|
||||
|
||||
static volatile int *s_Buffer = 0;
|
||||
static unsigned int s_BufferSize;
|
||||
static unsigned int s_BufferRead;
|
||||
static unsigned int s_BufferWrite;
|
||||
static volatile unsigned int s_BufferIn;
|
||||
|
||||
static int s_mute = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Callback from the SDL to get and play audio data.
|
||||
|
@ -46,10 +52,10 @@ fillaudio(void *udata,
|
|||
|
||||
while(len) {
|
||||
int16 sample = 0;
|
||||
if(BufferIn) {
|
||||
sample = Buffer[BufferRead];
|
||||
BufferRead = (BufferRead + 1) % BufferSize;
|
||||
BufferIn--;
|
||||
if(s_BufferIn) {
|
||||
sample = s_Buffer[s_BufferRead];
|
||||
s_BufferRead = (s_BufferRead + 1) % s_BufferSize;
|
||||
s_BufferIn--;
|
||||
} else {
|
||||
sample = 0;
|
||||
}
|
||||
|
@ -66,8 +72,13 @@ fillaudio(void *udata,
|
|||
int
|
||||
InitSound(FCEUGI *gi)
|
||||
{
|
||||
int sound, soundrate, soundbufsize, soundvolume, soundq;
|
||||
SDL_AudioSpec spec;
|
||||
if(!_sound) return(0);
|
||||
|
||||
g_config->getOption("SDL.Sound", &sound);
|
||||
if(!sound) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&spec, 0, sizeof(spec));
|
||||
if(SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
|
||||
|
@ -76,6 +87,12 @@ InitSound(FCEUGI *gi)
|
|||
return(0);
|
||||
}
|
||||
|
||||
// load configuration variables
|
||||
g_config->getOption("SDL.SoundRate", &soundrate);
|
||||
g_config->getOption("SDL.SoundBufSize", &soundbufsize);
|
||||
g_config->getOption("SDL.SoundVolume", &soundvolume);
|
||||
g_config->getOption("SDL.SoundQuality", &soundq);
|
||||
|
||||
spec.freq = soundrate;
|
||||
spec.format = AUDIO_S16SYS;
|
||||
spec.channels = 1;
|
||||
|
@ -83,18 +100,18 @@ InitSound(FCEUGI *gi)
|
|||
spec.callback = fillaudio;
|
||||
spec.userdata = 0;
|
||||
|
||||
BufferSize = soundbufsize * soundrate / 1000;
|
||||
s_BufferSize = soundbufsize * soundrate / 1000;
|
||||
|
||||
// XXX soules - what is this??
|
||||
/* SDL uses at least double-buffering, so multiply by 2. */
|
||||
BufferSize -= spec.samples * 2;
|
||||
s_BufferSize -= spec.samples * 2;
|
||||
|
||||
if(BufferSize < spec.samples) BufferSize = spec.samples;
|
||||
if(s_BufferSize < spec.samples) s_BufferSize = spec.samples;
|
||||
|
||||
Buffer = (int *)malloc(sizeof(int) * BufferSize);
|
||||
BufferRead = BufferWrite = BufferIn = 0;
|
||||
s_Buffer = (int *)malloc(sizeof(int) * s_BufferSize);
|
||||
s_BufferRead = s_BufferWrite = s_BufferIn = 0;
|
||||
|
||||
//printf("SDL Size: %d, Internal size: %d\n",spec.samples,BufferSize);
|
||||
//printf("SDL Size: %d, Internal size: %d\n",spec.samples,s_BufferSize);
|
||||
|
||||
if(SDL_OpenAudio(&spec, 0) < 0) {
|
||||
puts(SDL_GetError());
|
||||
|
@ -102,6 +119,9 @@ InitSound(FCEUGI *gi)
|
|||
return(0);
|
||||
}
|
||||
SDL_PauseAudio(0);
|
||||
|
||||
FCEUI_SetSoundVolume(soundvolume);
|
||||
FCEUI_SetSoundQuality(soundq);
|
||||
FCEUI_Sound(soundrate);
|
||||
return(1);
|
||||
}
|
||||
|
@ -113,7 +133,7 @@ InitSound(FCEUGI *gi)
|
|||
uint32
|
||||
GetMaxSound(void)
|
||||
{
|
||||
return(BufferSize);
|
||||
return(s_BufferSize);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,7 +142,7 @@ GetMaxSound(void)
|
|||
uint32
|
||||
GetWriteSound(void)
|
||||
{
|
||||
return(BufferSize - BufferIn);
|
||||
return(s_BufferSize - s_BufferIn);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -133,14 +153,14 @@ WriteSound(int32 *buf,
|
|||
int Count)
|
||||
{
|
||||
while(Count) {
|
||||
while(BufferIn == BufferSize) {
|
||||
while(s_BufferIn == s_BufferSize) {
|
||||
SDL_Delay(1);
|
||||
}
|
||||
|
||||
Buffer[BufferWrite] = *buf;
|
||||
s_Buffer[s_BufferWrite] = *buf;
|
||||
Count--;
|
||||
BufferWrite = (BufferWrite + 1) % BufferSize;
|
||||
BufferIn++;
|
||||
s_BufferWrite = (s_BufferWrite + 1) % s_BufferSize;
|
||||
s_BufferIn++;
|
||||
buf++;
|
||||
}
|
||||
}
|
||||
|
@ -163,17 +183,14 @@ KillSound(void)
|
|||
FCEUI_Sound(0);
|
||||
SDL_CloseAudio();
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
if(Buffer) {
|
||||
free((void *)Buffer);
|
||||
Buffer = 0;
|
||||
if(s_Buffer) {
|
||||
free((void *)s_Buffer);
|
||||
s_Buffer = 0;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
static int mute=0;
|
||||
static int soundvolume=100;
|
||||
|
||||
/**
|
||||
* Adjust the volume either down (-1), up (1), or to the default (0).
|
||||
* Unmutes if mute was active before.
|
||||
|
@ -181,6 +198,9 @@ static int soundvolume=100;
|
|||
void
|
||||
FCEUD_SoundVolumeAdjust(int n)
|
||||
{
|
||||
int soundvolume;
|
||||
g_config->getOption("SDL.SoundVolume", &soundvolume);
|
||||
|
||||
switch(n) {
|
||||
case -1:
|
||||
soundvolume -= 10;
|
||||
|
@ -199,8 +219,10 @@ FCEUD_SoundVolumeAdjust(int n)
|
|||
break;
|
||||
}
|
||||
|
||||
mute = 0;
|
||||
s_mute = 0;
|
||||
FCEUI_SetSoundVolume(soundvolume);
|
||||
g_config->setOption("SDL.SoundVolume", soundvolume);
|
||||
|
||||
FCEU_DispMessage("Sound volume %d.", soundvolume);
|
||||
}
|
||||
|
||||
|
@ -210,12 +232,15 @@ FCEUD_SoundVolumeAdjust(int n)
|
|||
void
|
||||
FCEUD_SoundToggle(void)
|
||||
{
|
||||
if(mute) {
|
||||
mute = 0;
|
||||
if(s_mute) {
|
||||
int soundvolume;
|
||||
g_config->getOption("SDL.SoundVolume", &soundvolume);
|
||||
|
||||
s_mute = 0;
|
||||
FCEUI_SetSoundVolume(soundvolume);
|
||||
FCEU_DispMessage("Sound mute off.");
|
||||
} else {
|
||||
mute = 1;
|
||||
s_mute = 1;
|
||||
FCEUI_SetSoundVolume(0);
|
||||
FCEU_DispMessage("Sound mute on.");
|
||||
}
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
#include "sdl.h"
|
||||
#include "throttle.h"
|
||||
|
||||
static uint64 tfreq;
|
||||
static uint64 desiredfps;
|
||||
static uint64 s_tfreq;
|
||||
static uint64 s_desiredfps;
|
||||
|
||||
static int32 fps_scale_table[]=
|
||||
static int32 s_fpsScaleTable[]=
|
||||
{ 3, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048 };
|
||||
int32 fps_scale = 256;
|
||||
int32 g_fpsScale = 256;
|
||||
|
||||
#define fps_table_size (sizeof(fps_scale_table) / sizeof(fps_scale_table[0]))
|
||||
#define FPS_TABLE_SIZE (sizeof(s_fpsScaleTable) / sizeof(s_fpsScaleTable[0]))
|
||||
|
||||
/**
|
||||
* Refreshes the FPS throttling variables.
|
||||
|
@ -19,10 +19,10 @@ int32 fps_scale = 256;
|
|||
void
|
||||
RefreshThrottleFPS()
|
||||
{
|
||||
desiredfps = FCEUI_GetDesiredFPS() >> 8;
|
||||
desiredfps = (desiredfps * fps_scale) >> 8;
|
||||
tfreq = 10000000;
|
||||
tfreq <<= 16; /* Adjustment for fps returned from FCEUI_GetDesiredFPS(). */
|
||||
s_desiredfps = FCEUI_GetDesiredFPS() >> 8;
|
||||
s_desiredfps = (s_desiredfps * g_fpsScale) >> 8;
|
||||
s_tfreq = 10000000;
|
||||
s_tfreq <<= 16; /* Adjust for fps returned from FCEUI_GetDesiredFPS(). */
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -44,8 +44,8 @@ SpeedThrottle()
|
|||
ttime = SDL_GetTicks();
|
||||
ttime *= 10000;
|
||||
|
||||
if((ttime - ltime) < (tfreq / desiredfps)) {
|
||||
int64 delay = (tfreq / desiredfps) - (ttime - ltime);
|
||||
if((ttime - ltime) < (s_tfreq / s_desiredfps)) {
|
||||
int64 delay = (s_tfreq / s_desiredfps) - (ttime - ltime);
|
||||
if(delay > 0) {
|
||||
SDL_Delay(delay / 10000);
|
||||
}
|
||||
|
@ -55,10 +55,10 @@ SpeedThrottle()
|
|||
} while(doDelay);
|
||||
|
||||
// update the "last time" to match when we want the next tick
|
||||
if((ttime - ltime) >= ((tfreq * 4) / desiredfps)) {
|
||||
if((ttime - ltime) >= ((s_tfreq * 4) / s_desiredfps)) {
|
||||
ltime = ttime;
|
||||
} else {
|
||||
ltime += tfreq / desiredfps;
|
||||
ltime += s_tfreq / s_desiredfps;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,15 +71,15 @@ IncreaseEmulationSpeed()
|
|||
int i = 0;
|
||||
|
||||
// find the next entry in the FPS rate table
|
||||
while(i < (fps_table_size - 1) && fps_scale_table[i] < fps_scale) {
|
||||
while(i < (FPS_TABLE_SIZE - 1) && s_fpsScaleTable[i] < g_fpsScale) {
|
||||
i++;
|
||||
}
|
||||
fps_scale = fps_scale_table[i+1];
|
||||
g_fpsScale = s_fpsScaleTable[i+1];
|
||||
|
||||
// refresh the FPS throttling variables
|
||||
RefreshThrottleFPS();
|
||||
|
||||
FCEU_DispMessage("emulation speed %d%%",(fps_scale*100)>>8);
|
||||
FCEU_DispMessage("emulation speed %d%%",(g_fpsScale*100)>>8);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -91,15 +91,15 @@ DecreaseEmulationSpeed()
|
|||
int i = 1;
|
||||
|
||||
// find the previous entry in the FPS rate table
|
||||
while(i < fps_table_size && fps_scale_table[i] < fps_scale) {
|
||||
while(i < FPS_TABLE_SIZE && s_fpsScaleTable[i] < g_fpsScale) {
|
||||
i++;
|
||||
}
|
||||
fps_scale = fps_scale_table[i - 1];
|
||||
g_fpsScale = s_fpsScaleTable[i - 1];
|
||||
|
||||
// refresh the FPS throttling variables
|
||||
RefreshThrottleFPS();
|
||||
|
||||
FCEU_DispMessage("emulation speed %d%%",(fps_scale*100)>>8);
|
||||
FCEU_DispMessage("emulation speed %d%%",(g_fpsScale*100)>>8);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -110,19 +110,19 @@ FCEUD_SetEmulationSpeed(int cmd)
|
|||
{
|
||||
switch(cmd) {
|
||||
case EMUSPEED_SLOWEST:
|
||||
fps_scale = fps_scale_table[0];
|
||||
g_fpsScale = s_fpsScaleTable[0];
|
||||
break;
|
||||
case EMUSPEED_SLOWER:
|
||||
DecreaseEmulationSpeed();
|
||||
break;
|
||||
case EMUSPEED_NORMAL:
|
||||
fps_scale = 256;
|
||||
g_fpsScale = 256;
|
||||
break;
|
||||
case EMUSPEED_FASTER:
|
||||
IncreaseEmulationSpeed();
|
||||
break;
|
||||
case EMUSPEED_FASTEST:
|
||||
fps_scale = fps_scale_table[fps_table_size - 1];
|
||||
g_fpsScale = s_fpsScaleTable[FPS_TABLE_SIZE - 1];
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
|
@ -130,5 +130,5 @@ FCEUD_SetEmulationSpeed(int cmd)
|
|||
|
||||
RefreshThrottleFPS();
|
||||
|
||||
FCEU_DispMessage("emulation speed %d%%",(fps_scale*100)>>8);
|
||||
FCEU_DispMessage("emulation speed %d%%",(g_fpsScale*100)>>8);
|
||||
}
|
||||
|
|
|
@ -33,28 +33,34 @@
|
|||
#include "sdl-icon.h"
|
||||
#include "dface.h"
|
||||
|
||||
SDL_Surface *screen;
|
||||
#include "../common/configSys.h"
|
||||
|
||||
static SDL_Surface *BlitBuf; // Buffer when using hardware-accelerated blits.
|
||||
static SDL_Surface *IconSurface=NULL;
|
||||
// GLOBALS
|
||||
extern Config *g_config;
|
||||
|
||||
static int curbpp;
|
||||
static int srendline,erendline;
|
||||
static int tlines;
|
||||
static int inited;
|
||||
// STATIC GLOBALS
|
||||
static SDL_Surface *s_screen;
|
||||
|
||||
static SDL_Surface *s_BlitBuf; // Buffer when using hardware-accelerated blits.
|
||||
static SDL_Surface *s_IconSurface = NULL;
|
||||
|
||||
static int s_curbpp;
|
||||
static int s_srendline, s_erendline;
|
||||
static int s_tlines;
|
||||
static int s_inited;
|
||||
|
||||
#ifdef OPENGL
|
||||
extern int sdlhaveogl;
|
||||
static int usingogl;
|
||||
static int s_useOpenGL;
|
||||
#endif
|
||||
static double exs,eys;
|
||||
static int eefx;
|
||||
static double s_exs, s_eys;
|
||||
static int s_eefx;
|
||||
static int s_clipSides;
|
||||
static int s_fullscreen;
|
||||
|
||||
#define NWIDTH (256 - ((eoptions & EO_CLIPSIDES) ? 16 : 0))
|
||||
#define NOFFSET (eoptions & EO_CLIPSIDES ? 8 : 0)
|
||||
#define NWIDTH (256 - (s_clipSides ? 16 : 0))
|
||||
#define NOFFSET (s_clipSides ? 8 : 0)
|
||||
|
||||
|
||||
static int paletterefresh;
|
||||
static int s_paletterefresh;
|
||||
|
||||
/**
|
||||
* Attempts to destroy the graphical video display. Returns 0 on
|
||||
|
@ -64,27 +70,27 @@ int
|
|||
KillVideo()
|
||||
{
|
||||
// if the IconSurface has been initialized, destroy it
|
||||
if(IconSurface) {
|
||||
SDL_FreeSurface(IconSurface);
|
||||
IconSurface=0;
|
||||
if(s_IconSurface) {
|
||||
SDL_FreeSurface(s_IconSurface);
|
||||
s_IconSurface=0;
|
||||
}
|
||||
|
||||
// if the rest of the system has been initialized, shut it down
|
||||
if(inited) {
|
||||
if(s_inited) {
|
||||
#ifdef OPENGL
|
||||
// check for OpenGL and shut it down
|
||||
if(usingogl)
|
||||
if(s_useOpenGL)
|
||||
KillOpenGL();
|
||||
else
|
||||
#endif
|
||||
// shut down the system that converts from 8 to 16/32 bpp
|
||||
if(curbpp > 8)
|
||||
if(s_curbpp > 8)
|
||||
KillBlitToHigh();
|
||||
|
||||
// shut down the SDL video sub-system
|
||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||
|
||||
inited = 0;
|
||||
s_inited = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -93,7 +99,7 @@ KillVideo()
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int sponge;
|
||||
static int s_sponge;
|
||||
|
||||
/**
|
||||
* Attempts to initialize the graphical video display. Returns 0 on
|
||||
|
@ -105,26 +111,33 @@ InitVideo(FCEUGI *gi)
|
|||
// XXX soules - const? is this necessary?
|
||||
const SDL_VideoInfo *vinf;
|
||||
int error, flags = 0;
|
||||
int doublebuf, xstretch, ystretch, xres, yres;
|
||||
|
||||
FCEUI_printf("Initializing video...");
|
||||
|
||||
// check the starting, ending, and total scan lines
|
||||
FCEUI_GetCurrentVidSystem(&srendline, &erendline);
|
||||
tlines = erendline - srendline + 1;
|
||||
|
||||
// load the relevant configuration variables
|
||||
g_config->getOption("SDL.Fullscreen", &s_fullscreen);
|
||||
g_config->getOption("SDL.DoubleBuffering", &doublebuf);
|
||||
#ifdef OPENGL
|
||||
g_config->getOption("SDL.OpenGL", &s_useOpenGL);
|
||||
#endif
|
||||
// XXX soules - what is the sponge variable?
|
||||
if(_fullscreen) {
|
||||
sponge = Settings.specialfs;
|
||||
} else {
|
||||
sponge = Settings.special;
|
||||
}
|
||||
g_config->getOption("SDL.SpecialFilter", &s_sponge);
|
||||
g_config->getOption("SDL.XStretch", &xstretch);
|
||||
g_config->getOption("SDL.YStretch", &ystretch);
|
||||
g_config->getOption("SDL.XResolution", &xres);
|
||||
g_config->getOption("SDL.YResolution", &yres);
|
||||
g_config->getOption("SDL.ClipSides", &s_clipSides);
|
||||
|
||||
// check the starting, ending, and total scan lines
|
||||
FCEUI_GetCurrentVidSystem(&s_srendline, &s_erendline);
|
||||
s_tlines = s_erendline - s_srendline + 1;
|
||||
|
||||
|
||||
// check for OpenGL and set the global flags
|
||||
#ifdef OPENGL
|
||||
usingogl = 0;
|
||||
if(_opengl && sdlhaveogl && !sponge) {
|
||||
if(s_useOpenGL && !s_sponge) {
|
||||
flags = SDL_OPENGL;
|
||||
usingogl = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -136,19 +149,19 @@ InitVideo(FCEUGI *gi)
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
inited = 1;
|
||||
s_inited = 1;
|
||||
|
||||
// shows the cursor within the display window
|
||||
SDL_ShowCursor(0);
|
||||
|
||||
// determine if we can allocate the display on the video card
|
||||
vinf=SDL_GetVideoInfo();
|
||||
vinf = SDL_GetVideoInfo();
|
||||
if(vinf->hw_available) {
|
||||
flags |= SDL_HWSURFACE;
|
||||
}
|
||||
|
||||
// check if we are rendering fullscreen
|
||||
if(_fullscreen) {
|
||||
if(s_fullscreen) {
|
||||
flags |= SDL_FULLSCREEN;
|
||||
}
|
||||
|
||||
|
@ -158,122 +171,139 @@ InitVideo(FCEUGI *gi)
|
|||
|
||||
// enable double buffering if requested and we have hardware support
|
||||
#ifdef OPENGL
|
||||
if(usingogl) {
|
||||
if(s_useOpenGL) {
|
||||
FCEU_printf("Initializing with OpenGL (Disable with '-opengl 0').\n");
|
||||
if(_doublebuf) {
|
||||
if(doublebuf) {
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if(_doublebuf && (flags & SDL_HWSURFACE)) {
|
||||
if(doublebuf && (flags & SDL_HWSURFACE)) {
|
||||
flags |= SDL_DOUBLEBUF;
|
||||
}
|
||||
|
||||
if(_fullscreen) {
|
||||
int desbpp = _bpp;
|
||||
if(s_fullscreen) {
|
||||
int desbpp;
|
||||
g_config->getOption("SDL.BitsPerPixel", &desbpp);
|
||||
|
||||
exs = _xscalefs;
|
||||
eys = _yscalefs;
|
||||
eefx = _efxfs;
|
||||
g_config->getOption("SDL.XScale", &s_exs);
|
||||
g_config->getOption("SDL.YScale", &s_eys);
|
||||
g_config->getOption("SDL.SpecialFX", &s_eefx);
|
||||
|
||||
#ifdef OPENGL
|
||||
if(!usingogl) {exs=(int)exs;eys=(int)eys;}
|
||||
else desbpp=0;
|
||||
if(!s_useOpenGL) {
|
||||
s_exs = (int)s_exs;
|
||||
s_eys = (int)s_eys;
|
||||
} else {
|
||||
desbpp = 0;
|
||||
}
|
||||
|
||||
if(sponge) {
|
||||
exs = eys = 2;
|
||||
if(sponge == 3 || sponge == 4) {
|
||||
exs = eys = 3;
|
||||
if(s_sponge) {
|
||||
if(s_sponge == 3 || s_sponge == 4) {
|
||||
s_exs = s_eys = 3;
|
||||
} else {
|
||||
s_exs = s_eys = 2;
|
||||
}
|
||||
eefx=0;
|
||||
if(sponge == 1 || sponge == 3) {
|
||||
s_eefx = 0;
|
||||
if(s_sponge == 1 || s_sponge == 3) {
|
||||
desbpp = 32;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( (usingogl && !_stretchx) || !usingogl)
|
||||
if((s_useOpenGL && !xstretch) || !s_useOpenGL)
|
||||
#endif
|
||||
if(_xres < (NWIDTH * exs) || exs <= 0.01) {
|
||||
if(xres < (NWIDTH * s_exs) || s_exs <= 0.01) {
|
||||
FCEUD_PrintError("xscale out of bounds.");
|
||||
KillVideo();
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef OPENGL
|
||||
if( (usingogl && !_stretchy) || !usingogl)
|
||||
if((s_useOpenGL && !ystretch) || !s_useOpenGL)
|
||||
#endif
|
||||
if(_yres<tlines*eys || eys <= 0.01) {
|
||||
if(yres < s_tlines * s_eys || s_eys <= 0.01) {
|
||||
FCEUD_PrintError("yscale out of bounds.");
|
||||
KillVideo();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
screen = SDL_SetVideoMode(_xres, _yres, desbpp, flags);
|
||||
if(!screen) {
|
||||
s_screen = SDL_SetVideoMode(xres, yres, desbpp, flags);
|
||||
if(!s_screen) {
|
||||
FCEUD_PrintError(SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
int desbpp=0;
|
||||
// not fullscreen
|
||||
int desbpp = 0;
|
||||
|
||||
exs=_xscale;
|
||||
eys=_yscale;
|
||||
eefx=_efx;
|
||||
g_config->getOption("SDL.XScale", &s_exs);
|
||||
g_config->getOption("SDL.YScale", &s_eys);
|
||||
g_config->getOption("SDL.SpecialFX", &s_eefx);
|
||||
|
||||
if(sponge) {
|
||||
exs = eys = 2;
|
||||
if(sponge >= 3) {
|
||||
exs = eys = 3;
|
||||
if(s_sponge) {
|
||||
if(s_sponge >= 3) {
|
||||
s_exs = s_eys = 3;
|
||||
} else {
|
||||
s_exs = s_eys = 2;
|
||||
}
|
||||
eefx = 0;
|
||||
s_eefx = 0;
|
||||
|
||||
// XXX soules - no clue what below comment is from
|
||||
// SDL's 32bpp->16bpp code is slighty faster than mine, at least :/
|
||||
if(sponge == 1 || sponge == 3) {
|
||||
desbpp=32;
|
||||
if(s_sponge == 1 || s_sponge == 3) {
|
||||
desbpp = 32;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef OPENGL
|
||||
if(!usingogl) {exs=(int)exs;eys=(int)eys;}
|
||||
if(exs <= 0.01)
|
||||
{
|
||||
FCEUD_PrintError("xscale out of bounds.");
|
||||
KillVideo();
|
||||
return -1;
|
||||
}
|
||||
if(eys <= 0.01)
|
||||
{
|
||||
FCEUD_PrintError("yscale out of bounds.");
|
||||
KillVideo();
|
||||
return -1;
|
||||
}
|
||||
if(!s_useOpenGL) {
|
||||
s_exs = (int)s_exs;
|
||||
s_eys = (int)s_eys;
|
||||
}
|
||||
if(s_exs <= 0.01) {
|
||||
FCEUD_PrintError("xscale out of bounds.");
|
||||
KillVideo();
|
||||
return -1;
|
||||
}
|
||||
if(s_eys <= 0.01) {
|
||||
FCEUD_PrintError("yscale out of bounds.");
|
||||
KillVideo();
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
screen = SDL_SetVideoMode((int)(NWIDTH*exs), (int)(tlines*eys),
|
||||
s_screen = SDL_SetVideoMode((int)(NWIDTH * s_exs),
|
||||
(int)(s_tlines * s_eys),
|
||||
desbpp, flags);
|
||||
if(!screen) {
|
||||
if(!s_screen) {
|
||||
FCEUD_PrintError(SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
curbpp=screen->format->BitsPerPixel;
|
||||
if(!screen) {
|
||||
s_curbpp = s_screen->format->BitsPerPixel;
|
||||
if(!s_screen) {
|
||||
FCEUD_PrintError(SDL_GetError());
|
||||
KillVideo();
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// XXX soules - this would be creating a surface on the video
|
||||
// card, but was commented out for some reason...
|
||||
//BlitBuf=SDL_CreateRGBSurface(SDL_HWSURFACE,256,240,screen->format->BitsPerPixel,screen->format->Rmask,screen->format->Gmask,screen->format->Bmask,0);
|
||||
s_BlitBuf = SDL_CreateRGBSurface(SDL_HWSURFACE, 256, 240,
|
||||
s_screen->format->BitsPerPixel,
|
||||
s_screen->format->Rmask,
|
||||
s_screen->format->Gmask,
|
||||
s_screen->format->Bmask, 0);
|
||||
#endif
|
||||
|
||||
FCEU_printf(" Video Mode: %d x %d x %d bpp %s\n",
|
||||
screen->w, screen->h, screen->format->BitsPerPixel,
|
||||
_fullscreen ? "full screen" : "");
|
||||
s_screen->w, s_screen->h, s_screen->format->BitsPerPixel,
|
||||
s_fullscreen ? "full screen" : "");
|
||||
|
||||
if(curbpp != 8 && curbpp != 16 && curbpp != 24 && curbpp != 32) {
|
||||
FCEU_printf(" Sorry, %dbpp modes are not supported by FCE Ultra. Supported bit depths are 8bpp, 16bpp, and 32bpp.\n", curbpp);
|
||||
if(s_curbpp != 8 && s_curbpp != 16 && s_curbpp != 24 && s_curbpp != 32) {
|
||||
FCEU_printf(" Sorry, %dbpp modes are not supported by FCE Ultra. Supported bit depths are 8bpp, 16bpp, and 32bpp.\n", s_curbpp);
|
||||
KillVideo();
|
||||
return -1;
|
||||
}
|
||||
|
@ -287,31 +317,42 @@ InitVideo(FCEUGI *gi)
|
|||
|
||||
// create the surface for displaying graphical messages
|
||||
#ifdef LSB_FIRST
|
||||
IconSurface = SDL_CreateRGBSurfaceFrom((void *)fceu_playicon.pixel_data,
|
||||
32, 32, 24, 32*3,
|
||||
0xFF, 0xFF00, 0xFF0000, 0x00);
|
||||
s_IconSurface = SDL_CreateRGBSurfaceFrom((void *)fceu_playicon.pixel_data,
|
||||
32, 32, 24, 32 * 3,
|
||||
0xFF, 0xFF00, 0xFF0000, 0x00);
|
||||
#else
|
||||
IconSurface = SDL_CreateRGBSurfaceFrom((void *)fceu_playicon.pixel_data,
|
||||
32, 32, 24, 32*3,
|
||||
0xFF0000, 0xFF00, 0xFF, 0x00);
|
||||
s_IconSurface = SDL_CreateRGBSurfaceFrom((void *)fceu_playicon.pixel_data,
|
||||
32, 32, 24, 32 * 3,
|
||||
0xFF0000, 0xFF00, 0xFF, 0x00);
|
||||
#endif
|
||||
SDL_WM_SetIcon(IconSurface,0);
|
||||
paletterefresh = 1;
|
||||
SDL_WM_SetIcon(s_IconSurface,0);
|
||||
s_paletterefresh = 1;
|
||||
|
||||
// XXX soules - can't SDL do this for us?
|
||||
// if using more than 8bpp, initialize the conversion routines
|
||||
if(curbpp > 8)
|
||||
if(s_curbpp > 8)
|
||||
#ifdef OPENGL
|
||||
if(!usingogl)
|
||||
if(!s_useOpenGL)
|
||||
#endif
|
||||
InitBlitToHigh(curbpp>>3,screen->format->Rmask,screen->format->Gmask,screen->format->Bmask,eefx,sponge);
|
||||
InitBlitToHigh(s_curbpp >> 3,
|
||||
s_screen->format->Rmask,
|
||||
s_screen->format->Gmask,
|
||||
s_screen->format->Bmask,
|
||||
s_eefx, s_sponge);
|
||||
#ifdef OPENGL
|
||||
if(usingogl)
|
||||
if(!InitOpenGL((eoptions&EO_CLIPSIDES)?8:0,256-((eoptions&EO_CLIPSIDES)?8:0),srendline,erendline+1,exs,eys,eefx,_openglip,_stretchx,_stretchy,screen)) {
|
||||
if(s_useOpenGL) {
|
||||
int openGLip;
|
||||
g_config->getOption("SDL.OpenGLip", &openGLip);
|
||||
|
||||
if(!InitOpenGL(NOFFSET, 256 - (s_clipSides ? 8 : 0),
|
||||
s_srendline, s_erendline + 1,
|
||||
s_exs, s_eys, s_eefx,
|
||||
openGLip, xstretch, ystretch, s_screen)) {
|
||||
FCEUD_PrintError("Error initializing OpenGL.");
|
||||
KillVideo();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -322,24 +363,24 @@ InitVideo(FCEUGI *gi)
|
|||
void
|
||||
ToggleFS()
|
||||
{
|
||||
int error;
|
||||
int error, fullscreen = s_fullscreen;
|
||||
|
||||
// shut down the current video system
|
||||
KillVideo();
|
||||
|
||||
// flip the fullscreen flag
|
||||
_fullscreen = !_fullscreen;
|
||||
g_config->setOption("SDL.Fullscreen", !fullscreen);
|
||||
|
||||
// try to initialize the video
|
||||
error = InitVideo(GameInfo);
|
||||
if(error) {
|
||||
// if we fail, just continue with what worked before
|
||||
_fullscreen = !_fullscreen;
|
||||
g_config->setOption("SDL.Fullscreen", fullscreen);
|
||||
InitVideo(GameInfo);
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_Color psdl[256];
|
||||
static SDL_Color s_psdl[256];
|
||||
|
||||
/**
|
||||
* Sets the color for a particular index in the palette.
|
||||
|
@ -350,11 +391,11 @@ FCEUD_SetPalette(uint8 index,
|
|||
uint8 g,
|
||||
uint8 b)
|
||||
{
|
||||
psdl[index].r = r;
|
||||
psdl[index].g = g;
|
||||
psdl[index].b = b;
|
||||
s_psdl[index].r = r;
|
||||
s_psdl[index].g = g;
|
||||
s_psdl[index].b = b;
|
||||
|
||||
paletterefresh = 1;
|
||||
s_paletterefresh = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -366,9 +407,9 @@ FCEUD_GetPalette(uint8 index,
|
|||
uint8 *g,
|
||||
uint8 *b)
|
||||
{
|
||||
*r = psdl[index].r;
|
||||
*g = psdl[index].g;
|
||||
*b = psdl[index].b;
|
||||
*r = s_psdl[index].r;
|
||||
*g = s_psdl[index].g;
|
||||
*b = s_psdl[index].b;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -378,15 +419,15 @@ static void
|
|||
RedoPalette()
|
||||
{
|
||||
#ifdef OPENGL
|
||||
if(usingogl)
|
||||
SetOpenGLPalette((uint8*)psdl);
|
||||
if(s_useOpenGL)
|
||||
SetOpenGLPalette((uint8*)s_psdl);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if(curbpp > 8) {
|
||||
SetPaletteBlitToHigh((uint8*)psdl);
|
||||
if(s_curbpp > 8) {
|
||||
SetPaletteBlitToHigh((uint8*)s_psdl);
|
||||
} else {
|
||||
SDL_SetPalette(screen, SDL_PHYSPAL, psdl, 0, 256);
|
||||
SDL_SetPalette(s_screen, SDL_PHYSPAL, s_psdl, 0, 256);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -409,31 +450,31 @@ BlitScreen(uint8 *XBuf)
|
|||
uint8 *dest;
|
||||
int xo = 0, yo = 0;
|
||||
|
||||
if(!screen) {
|
||||
if(!s_screen) {
|
||||
return;
|
||||
}
|
||||
|
||||
// refresh the palette if required
|
||||
if(paletterefresh) {
|
||||
if(s_paletterefresh) {
|
||||
RedoPalette();
|
||||
paletterefresh=0;
|
||||
s_paletterefresh = 0;
|
||||
}
|
||||
|
||||
#ifdef OPENGL
|
||||
// OpenGL is handled separately
|
||||
if(usingogl) {
|
||||
if(s_useOpenGL) {
|
||||
BlitOpenGL(XBuf);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// XXX soules - not entirely sure why this is being done yet
|
||||
XBuf += srendline * 256;
|
||||
XBuf += s_srendline * 256;
|
||||
|
||||
if(BlitBuf) {
|
||||
TmpScreen = BlitBuf;
|
||||
if(s_BlitBuf) {
|
||||
TmpScreen = s_BlitBuf;
|
||||
} else {
|
||||
TmpScreen = screen;
|
||||
TmpScreen = s_screen;
|
||||
}
|
||||
|
||||
// lock the display, if necessary
|
||||
|
@ -445,32 +486,33 @@ BlitScreen(uint8 *XBuf)
|
|||
|
||||
dest = (uint8*)TmpScreen->pixels;
|
||||
|
||||
if(_fullscreen) {
|
||||
xo = (int)(((TmpScreen->w - NWIDTH * exs)) / 2);
|
||||
dest += xo * (curbpp >> 3);
|
||||
if(TmpScreen->h > (tlines * eys)) {
|
||||
yo = (int)((TmpScreen->h - tlines * eys) / 2);
|
||||
if(s_fullscreen) {
|
||||
xo = (int)(((TmpScreen->w - NWIDTH * s_exs)) / 2);
|
||||
dest += xo * (s_curbpp >> 3);
|
||||
if(TmpScreen->h > (s_tlines * s_eys)) {
|
||||
yo = (int)((TmpScreen->h - s_tlines * s_eys) / 2);
|
||||
dest += yo * TmpScreen->pitch;
|
||||
}
|
||||
}
|
||||
|
||||
// XXX soules - again, I'm surprised SDL can't handle this
|
||||
// perform the blit, converting bpp if necessary
|
||||
if(curbpp > 8) {
|
||||
if(BlitBuf) {
|
||||
Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, tlines,
|
||||
if(s_curbpp > 8) {
|
||||
if(s_BlitBuf) {
|
||||
Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines,
|
||||
TmpScreen->pitch, 1, 1);
|
||||
} else {
|
||||
Blit8ToHigh(XBuf + NOFFSET,dest, NWIDTH, tlines,
|
||||
TmpScreen->pitch, (int)exs, (int)eys);
|
||||
Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines,
|
||||
TmpScreen->pitch, (int)s_exs, (int)s_eys);
|
||||
}
|
||||
} else {
|
||||
if(BlitBuf) {
|
||||
Blit8To8(XBuf + NOFFSET, dest, NWIDTH, tlines,
|
||||
TmpScreen->pitch, 1, 1, 0, sponge);
|
||||
if(s_BlitBuf) {
|
||||
Blit8To8(XBuf + NOFFSET, dest, NWIDTH, s_tlines,
|
||||
TmpScreen->pitch, 1, 1, 0, s_sponge);
|
||||
} else {
|
||||
Blit8To8(XBuf + NOFFSET, dest, NWIDTH, tlines,
|
||||
TmpScreen->pitch, (int)exs, (int)eys, eefx, sponge);
|
||||
Blit8To8(XBuf + NOFFSET, dest, NWIDTH, s_tlines,
|
||||
TmpScreen->pitch, (int)s_exs, (int)s_eys,
|
||||
s_eefx, s_sponge);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -480,29 +522,30 @@ BlitScreen(uint8 *XBuf)
|
|||
}
|
||||
|
||||
// if we have a hardware video buffer, do a fast video->video copy
|
||||
if(BlitBuf) {
|
||||
if(s_BlitBuf) {
|
||||
SDL_Rect srect;
|
||||
SDL_Rect drect;
|
||||
|
||||
srect.x = 0;
|
||||
srect.y = 0;
|
||||
srect.w = NWIDTH;
|
||||
srect.h = tlines;
|
||||
srect.h = s_tlines;
|
||||
|
||||
drect.x = 0;
|
||||
drect.y = 0;
|
||||
drect.w = (Uint16)(exs * NWIDTH);
|
||||
drect.h = (Uint16)(eys * tlines);
|
||||
drect.w = (Uint16)(s_exs * NWIDTH);
|
||||
drect.h = (Uint16)(s_eys * s_tlines);
|
||||
|
||||
SDL_BlitSurface(BlitBuf, &srect, screen, &drect);
|
||||
SDL_BlitSurface(s_BlitBuf, &srect, s_screen, &drect);
|
||||
}
|
||||
|
||||
// ensure that the display is updated
|
||||
SDL_UpdateRect(screen, xo, yo, (Uint32)(NWIDTH*exs), (Uint32)(tlines*eys));
|
||||
SDL_UpdateRect(s_screen, xo, yo,
|
||||
(Uint32)(NWIDTH * s_exs), (Uint32)(s_tlines * s_eys));
|
||||
|
||||
// have to flip the displayed buffer in the case of double buffering
|
||||
if(screen->flags & SDL_DOUBLEBUF) {
|
||||
SDL_Flip(screen);
|
||||
if(s_screen->flags & SDL_DOUBLEBUF) {
|
||||
SDL_Flip(s_screen);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -514,11 +557,11 @@ uint32
|
|||
PtoV(uint16 x,
|
||||
uint16 y)
|
||||
{
|
||||
y = (uint16)((double)y / eys);
|
||||
x = (uint16)((double)x / exs);
|
||||
if(eoptions & EO_CLIPSIDES) {
|
||||
y = (uint16)((double)y / s_eys);
|
||||
x = (uint16)((double)x / s_exs);
|
||||
if(s_clipSides) {
|
||||
x += 8;
|
||||
}
|
||||
y += srendline;
|
||||
y += s_srendline;
|
||||
return (x | (y << 16));
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include "sdl-video.h"
|
||||
#include "unix-netplay.h"
|
||||
|
||||
#include "../common/configSys.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
@ -34,7 +36,7 @@ int sdlhaveogl;
|
|||
#endif
|
||||
|
||||
|
||||
extern int32 fps_scale;
|
||||
extern int32 g_fpsScale;
|
||||
|
||||
int CloseGame(void);
|
||||
|
||||
|
@ -47,6 +49,10 @@ static void DriverKill(void);
|
|||
static int DriverInitialize(FCEUGI *gi);
|
||||
int gametype = 0;
|
||||
|
||||
|
||||
// global configuration object
|
||||
Config *g_config;
|
||||
|
||||
/**
|
||||
* Prints an error string to STDOUT.
|
||||
*/
|
||||
|
@ -119,6 +125,8 @@ CloseStuff(int signum)
|
|||
*/
|
||||
int LoadGame(const char *path)
|
||||
{
|
||||
std::string filename;
|
||||
|
||||
CloseGame();
|
||||
if(!FCEUI_LoadGame(path, 1)) {
|
||||
return 0;
|
||||
|
@ -129,10 +137,11 @@ int LoadGame(const char *path)
|
|||
if(!DriverInitialize(GameInfo)) {
|
||||
return(0);
|
||||
}
|
||||
if(soundrecfn) {
|
||||
if(!FCEUI_BeginWaveRecord(soundrecfn)) {
|
||||
free(soundrecfn);
|
||||
soundrecfn=0;
|
||||
|
||||
g_config->getOption("SDL.SoundRecordFile", &filename);
|
||||
if(filename.size()) {
|
||||
if(!FCEUI_BeginWaveRecord(filename.c_str())) {
|
||||
g_config->setOption("SDL.SoundRecordFile", "");
|
||||
}
|
||||
}
|
||||
isloaded = 1;
|
||||
|
@ -147,6 +156,8 @@ int LoadGame(const char *path)
|
|||
int
|
||||
CloseGame()
|
||||
{
|
||||
std::string filename;
|
||||
|
||||
if(!isloaded) {
|
||||
return(0);
|
||||
}
|
||||
|
@ -155,7 +166,8 @@ CloseGame()
|
|||
isloaded = 0;
|
||||
GameInfo = 0;
|
||||
|
||||
if(soundrecfn) {
|
||||
g_config->getOption("SDL.SoundRecordFile", &filename);
|
||||
if(filename.size()) {
|
||||
FCEUI_EndWaveRecord();
|
||||
}
|
||||
|
||||
|
@ -165,7 +177,7 @@ CloseGame()
|
|||
|
||||
void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count);
|
||||
|
||||
void DoFun(void)
|
||||
static void DoFun(int frameskip)
|
||||
{
|
||||
uint8 *gfx;
|
||||
int32 *sound;
|
||||
|
@ -224,7 +236,7 @@ DriverInitialize(FCEUGI *gi)
|
|||
static void
|
||||
DriverKill()
|
||||
{
|
||||
SaveConfig();
|
||||
//SaveConfig();
|
||||
|
||||
#ifndef WIN32
|
||||
// XXX soules - capturing all these signals seems pointless
|
||||
|
@ -253,14 +265,14 @@ FCEUD_Update(uint8 *XBuf,
|
|||
|
||||
int ocount = Count;
|
||||
// apply frame scaling to Count
|
||||
Count = (Count<<8)/fps_scale;
|
||||
Count = (Count<<8) / g_fpsScale;
|
||||
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 >= GetMaxSound() && g_fpsScale<=256) uflow=1; /* Go into massive underflow mode. */
|
||||
|
||||
if(can > Count) can=Count;
|
||||
else uflow=0;
|
||||
|
@ -270,7 +282,7 @@ FCEUD_Update(uint8 *XBuf,
|
|||
//if(uflow) puts("Underflow");
|
||||
tmpcan = GetWriteSound();
|
||||
// don't underflow when scaling fps
|
||||
if(fps_scale>256 || ((tmpcan < Count*0.90) && !uflow)) {
|
||||
if(g_fpsScale>256 || ((tmpcan < Count*0.90) && !uflow)) {
|
||||
if(XBuf && (inited&4) && !(NoWaiting & 2))
|
||||
BlitScreen(XBuf);
|
||||
Buffer+=can;
|
||||
|
@ -356,6 +368,8 @@ int
|
|||
main(int argc,
|
||||
char *argv[])
|
||||
{
|
||||
int error, frameskip;
|
||||
|
||||
FCEUD_Message("\nStarting "FCEU_NAME_AND_VERSION"...\n");
|
||||
|
||||
#ifdef WIN32
|
||||
|
@ -378,9 +392,12 @@ main(int argc,
|
|||
#endif
|
||||
#endif
|
||||
|
||||
SetDefaults();
|
||||
|
||||
int error;
|
||||
// Initialize the configuration system
|
||||
g_config = InitConfig();
|
||||
if(!g_config) {
|
||||
SDL_Quit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// initialize the infrastructure
|
||||
error = FCEUI_Initialize();
|
||||
|
@ -389,15 +406,22 @@ main(int argc,
|
|||
return -1;
|
||||
}
|
||||
|
||||
// XXX configuration initialization
|
||||
error = InitConfig(argc, argv);
|
||||
if(error) {
|
||||
int romIndex = g_config->parse(argc, argv);
|
||||
if(romIndex <= 0) {
|
||||
FCEUD_Message("\nError parsing command line arguments\n");
|
||||
SDL_Quit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// update the input devices
|
||||
UpdateInput(g_config);
|
||||
|
||||
// update the emu core
|
||||
UpdateEMUCore(g_config);
|
||||
g_config->getOption("SDL.Frameskip", &frameskip);
|
||||
|
||||
// load the specified game
|
||||
error = LoadGame(argv[argc - 1]);
|
||||
error = LoadGame(argv[romIndex]);
|
||||
if(error != 1) {
|
||||
DriverKill();
|
||||
SDL_Quit();
|
||||
|
@ -406,12 +430,12 @@ main(int argc,
|
|||
|
||||
// loop playing the game
|
||||
while(GameInfo) {
|
||||
DoFun();
|
||||
DoFun(frameskip);
|
||||
}
|
||||
CloseGame();
|
||||
|
||||
// save the configuration information
|
||||
SaveConfig();
|
||||
// save the configuration information?
|
||||
//SaveConfig();
|
||||
|
||||
// exit the infrastructure
|
||||
FCEUI_Kill();
|
||||
|
|
|
@ -2,47 +2,3 @@
|
|||
#include "main.h"
|
||||
#include "dface.h"
|
||||
#include "input.h"
|
||||
|
||||
typedef struct {
|
||||
int xres;
|
||||
int yres;
|
||||
double xscale,yscale;
|
||||
double xscalefs,yscalefs;
|
||||
int efx,efxfs;
|
||||
int bpp;
|
||||
int fullscreen;
|
||||
int doublebuf;
|
||||
char *fshack;
|
||||
char *fshacksave;
|
||||
#ifdef OPENGL
|
||||
int opengl;
|
||||
int openglip;
|
||||
int stretchx,stretchy;
|
||||
#endif
|
||||
int special,specialfs;
|
||||
} DSETTINGS;
|
||||
|
||||
extern DSETTINGS Settings;
|
||||
|
||||
#define _doublebuf Settings.doublebuf
|
||||
#define _bpp Settings.bpp
|
||||
#define _xres Settings.xres
|
||||
#define _yres Settings.yres
|
||||
#define _fullscreen Settings.fullscreen
|
||||
#define _xscale Settings.xscale
|
||||
#define _yscale Settings.yscale
|
||||
#define _xscalefs Settings.xscalefs
|
||||
#define _yscalefs Settings.yscalefs
|
||||
#define _efx Settings.efx
|
||||
#define _efxfs Settings.efxfs
|
||||
#define _ebufsize Settings.ebufsize
|
||||
#define _fshack Settings.fshack
|
||||
#define _fshacksave Settings.fshacksave
|
||||
|
||||
#ifdef OPENGL
|
||||
#define _opengl Settings.opengl
|
||||
#define _openglip Settings.openglip
|
||||
#define _stretchx Settings.stretchx
|
||||
#define _stretchy Settings.stretchy
|
||||
#endif
|
||||
|
||||
|
|
|
@ -48,6 +48,11 @@
|
|||
#include "../../fceu.h"
|
||||
#include "../../utils/md5.h"
|
||||
|
||||
#include <string>
|
||||
#include "../common/configSys.h"
|
||||
|
||||
extern Config *g_config;
|
||||
|
||||
#ifndef socklen_t
|
||||
#define socklen_t int
|
||||
#endif
|
||||
|
@ -56,264 +61,283 @@
|
|||
#define SOL_TCP IPPROTO_TCP
|
||||
#endif
|
||||
|
||||
|
||||
char *netplayhost=0;
|
||||
char *netplaynick=0;
|
||||
char *netgamekey = 0;
|
||||
char *netpassword = 0;
|
||||
int netlocalplayers = 1;
|
||||
|
||||
int Port=0xFCE;
|
||||
int FCEUDnetplay=0;
|
||||
|
||||
int tport=0xFCE;
|
||||
|
||||
static int Socket=-1;
|
||||
static int s_Socket = -1;
|
||||
|
||||
static void en32(uint8 *buf, uint32 morp)
|
||||
static void
|
||||
en32(uint8 *buf,
|
||||
uint32 morp)
|
||||
{
|
||||
buf[0]=morp;
|
||||
buf[1]=morp>>8;
|
||||
buf[2]=morp>>16;
|
||||
buf[3]=morp>>24;
|
||||
buf[0] = morp;
|
||||
buf[1] = morp >> 8;
|
||||
buf[2] = morp >> 16;
|
||||
buf[3] = morp >> 24;
|
||||
}
|
||||
|
||||
/*
|
||||
static uint32 de32(uint8 *morp)
|
||||
{
|
||||
return(morp[0]|(morp[1]<<8)|(morp[2]<<16)|(morp[3]<<24));
|
||||
}
|
||||
*/
|
||||
int FCEUD_NetworkConnect(void)
|
||||
|
||||
int
|
||||
FCEUD_NetworkConnect(void)
|
||||
{
|
||||
struct sockaddr_in sockin; /* I want to play with fighting robots. */
|
||||
struct hostent *phostentb;
|
||||
unsigned long hadr;
|
||||
int TSocket;
|
||||
int netdivisor;
|
||||
struct sockaddr_in sockin;
|
||||
struct hostent *phostentb;
|
||||
unsigned long hadr;
|
||||
int TSocket, tcpopt, error;
|
||||
int netdivisor;
|
||||
|
||||
if(!netplayhost) return(0);
|
||||
|
||||
if( (TSocket=socket(AF_INET,SOCK_STREAM,0))==-1)
|
||||
{
|
||||
puts("Error creating stream socket.");
|
||||
FCEUD_NetworkClose();
|
||||
return(0);
|
||||
}
|
||||
|
||||
{
|
||||
int tcpopt = 1;
|
||||
#ifdef BEOS
|
||||
if(setsockopt(TSocket, SOL_SOCKET, TCP_NODELAY, &tcpopt, sizeof(int)))
|
||||
#elif WIN32
|
||||
if(setsockopt(TSocket, SOL_TCP, TCP_NODELAY, (char*)&tcpopt, sizeof(int)))
|
||||
#else
|
||||
if(setsockopt(TSocket, SOL_TCP, TCP_NODELAY, &tcpopt, sizeof(int)))
|
||||
#endif
|
||||
puts("Nodelay fail");
|
||||
}
|
||||
|
||||
memset(&sockin,0,sizeof(sockin));
|
||||
sockin.sin_family=AF_INET;
|
||||
|
||||
hadr=inet_addr(netplayhost);
|
||||
|
||||
if(hadr!=INADDR_NONE)
|
||||
sockin.sin_addr.s_addr=hadr;
|
||||
else
|
||||
{
|
||||
puts("*** Looking up host name...");
|
||||
if(!(phostentb=gethostbyname((const char *)netplayhost)))
|
||||
{
|
||||
puts("Error getting host network information.");
|
||||
close(TSocket);
|
||||
FCEUD_NetworkClose();
|
||||
return(0);
|
||||
}
|
||||
memcpy(&sockin.sin_addr,phostentb->h_addr,phostentb->h_length);
|
||||
}
|
||||
|
||||
sockin.sin_port=htons(tport);
|
||||
puts("*** Connecting to remote host...");
|
||||
if(connect(TSocket,(struct sockaddr *)&sockin,sizeof(sockin))==-1)
|
||||
{
|
||||
puts("Error connecting to remote host.");
|
||||
close(TSocket);
|
||||
FCEUD_NetworkClose();
|
||||
return(0);
|
||||
}
|
||||
Socket=TSocket;
|
||||
puts("*** Sending initialization data to server...");
|
||||
{
|
||||
uint8 *sendbuf;
|
||||
uint8 buf[5];
|
||||
uint32 sblen;
|
||||
|
||||
sblen = 4 + 16 + 16 + 64 + 1 + (netplaynick?strlen(netplaynick):0);
|
||||
sendbuf = (uint8 *)malloc(sblen);
|
||||
memset(sendbuf, 0, sblen);
|
||||
|
||||
en32(sendbuf, sblen - 4);
|
||||
|
||||
if(netgamekey)
|
||||
{
|
||||
struct md5_context md5;
|
||||
uint8 md5out[16];
|
||||
|
||||
md5_starts(&md5);
|
||||
md5_update(&md5, GameInfo->MD5, 16);
|
||||
md5_update(&md5, (uint8 *)netgamekey, strlen(netgamekey));
|
||||
md5_finish(&md5, md5out);
|
||||
memcpy(sendbuf + 4, md5out, 16);
|
||||
}
|
||||
else
|
||||
memcpy(sendbuf + 4, GameInfo->MD5, 16);
|
||||
|
||||
if(netpassword)
|
||||
{
|
||||
struct md5_context md5;
|
||||
uint8 md5out[16];
|
||||
|
||||
md5_starts(&md5);
|
||||
md5_update(&md5, (uint8 *)netpassword, strlen(netpassword));
|
||||
md5_finish(&md5, md5out);
|
||||
memcpy(sendbuf + 4 + 16, md5out, 16);
|
||||
}
|
||||
|
||||
memset(sendbuf + 4 + 16 + 16, 0, 64);
|
||||
|
||||
sendbuf[4 + 16 + 16 + 64] = netlocalplayers;
|
||||
|
||||
if(netplaynick)
|
||||
memcpy(sendbuf + 4 + 16 + 16 + 64 + 1,netplaynick,strlen(netplaynick));
|
||||
|
||||
#ifdef WIN32
|
||||
send(Socket, (char*)sendbuf, sblen, 0);
|
||||
#else
|
||||
send(Socket, sendbuf, sblen, 0);
|
||||
#endif
|
||||
free(sendbuf);
|
||||
|
||||
#ifdef WIN32
|
||||
recv(Socket, (char*)buf, 1, 0);
|
||||
#else
|
||||
recv(Socket, buf, 1, MSG_WAITALL);
|
||||
#endif
|
||||
netdivisor = buf[0];
|
||||
}
|
||||
|
||||
puts("*** Connection established.");
|
||||
|
||||
FCEUDnetplay = 1;
|
||||
FCEUI_NetplayStart(netlocalplayers, netdivisor);
|
||||
return(1);
|
||||
}
|
||||
// get any required configuration variables
|
||||
int port, localPlayers;
|
||||
std::string server, username, password, key;
|
||||
g_config->getOption("SDL.NetworkServer", &server);
|
||||
g_config->getOption("SDL.NetworkUsername", &username);
|
||||
g_config->getOption("SDL.NetworkPassword", &password);
|
||||
g_config->getOption("SDL.NetworkGameKey", &key);
|
||||
g_config->getOption("SDL.NetworkPort", &port);
|
||||
g_config->getOption("SDL.NetworkPlayers", &localPlayers);
|
||||
|
||||
|
||||
int FCEUD_SendData(void *data, uint32 len)
|
||||
{
|
||||
int check;
|
||||
#ifndef WIN32
|
||||
if(!ioctl(fileno(stdin),FIONREAD,&check))
|
||||
#endif
|
||||
if(check)
|
||||
{
|
||||
char buf[1024];
|
||||
char *f;
|
||||
fgets(buf,1024,stdin);
|
||||
if((f=strrchr(buf,'\n')))
|
||||
*f=0;
|
||||
FCEUI_NetplayText((uint8 *)buf);
|
||||
}
|
||||
#ifdef WIN32
|
||||
send(Socket, (char*)data, len ,0);
|
||||
#else
|
||||
send(Socket, data, len ,0);
|
||||
#endif
|
||||
return(1);
|
||||
}
|
||||
|
||||
int FCEUD_RecvData(void *data, uint32 len)
|
||||
{
|
||||
NoWaiting&=~2;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
fd_set funfun;
|
||||
struct timeval popeye;
|
||||
|
||||
popeye.tv_sec=0;
|
||||
popeye.tv_usec=100000;
|
||||
|
||||
FD_ZERO(&funfun);
|
||||
FD_SET(Socket,&funfun);
|
||||
|
||||
switch(select(Socket + 1,&funfun,0,0,&popeye))
|
||||
{
|
||||
case 0: continue;
|
||||
case -1:return(0);
|
||||
}
|
||||
|
||||
if(FD_ISSET(Socket,&funfun))
|
||||
{
|
||||
#ifdef WIN32
|
||||
if(recv(Socket,(char*)data,len,0) == len)
|
||||
#else
|
||||
if(recv(Socket,data,len,MSG_WAITALL) == len)
|
||||
#endif
|
||||
{
|
||||
//unsigned long beefie;
|
||||
|
||||
FD_ZERO(&funfun);
|
||||
FD_SET(Socket, &funfun);
|
||||
|
||||
popeye.tv_sec = popeye.tv_usec = 0;
|
||||
if(select(Socket + 1, &funfun, 0, 0, &popeye) == 1)
|
||||
//if(!ioctl(Socket,FIONREAD,&beefie))
|
||||
// if(beefie)
|
||||
{
|
||||
NoWaiting|=2;
|
||||
//puts("Yaya");
|
||||
// only initialize if remote server is specified
|
||||
if(!server.size()) {
|
||||
return 0;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
TSocket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(TSocket < 0) {
|
||||
puts("Error creating stream socket.");
|
||||
FCEUD_NetworkClose();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// try to setup TCP_NODELAY to avoid network jitters
|
||||
tcpopt = 1;
|
||||
#ifdef BEOS
|
||||
error = setsockopt(TSocket, SOL_SOCKET, TCP_NODELAY, &tcpopt, sizeof(int));
|
||||
#elif WIN32
|
||||
error = setsockopt(TSocket, SOL_TCP, TCP_NODELAY,
|
||||
(char*)&tcpopt, sizeof(int));
|
||||
#else
|
||||
error = setsockopt(TSocket, SOL_TCP, TCP_NODELAY, &tcpopt, sizeof(int));
|
||||
#endif
|
||||
if(error) {
|
||||
puts("Nodelay fail");
|
||||
}
|
||||
|
||||
memset(&sockin, 0, sizeof(sockin));
|
||||
sockin.sin_family = AF_INET;
|
||||
hadr = inet_addr(server.c_str());
|
||||
if(hadr != INADDR_NONE) {
|
||||
sockin.sin_addr.s_addr = hadr;
|
||||
} else {
|
||||
puts("*** Looking up host name...");
|
||||
phostentb = gethostbyname(server.c_str());
|
||||
if(!phostentb) {
|
||||
puts("Error getting host network information.");
|
||||
close(TSocket);
|
||||
FCEUD_NetworkClose();
|
||||
return(0);
|
||||
}
|
||||
memcpy(&sockin.sin_addr, phostentb->h_addr, phostentb->h_length);
|
||||
}
|
||||
|
||||
sockin.sin_port = htons(port);
|
||||
puts("*** Connecting to remote host...");
|
||||
error = connect(TSocket, (struct sockaddr *)&sockin, sizeof(sockin));
|
||||
if(error < 0) {
|
||||
puts("Error connecting to remote host.");
|
||||
close(TSocket);
|
||||
FCEUD_NetworkClose();
|
||||
return 0;
|
||||
}
|
||||
|
||||
s_Socket = TSocket;
|
||||
|
||||
puts("*** Sending initialization data to server...");
|
||||
uint8 *sendbuf;
|
||||
uint8 buf[5];
|
||||
uint32 sblen, data;
|
||||
|
||||
sblen = 4 + 16 + 16 + 64 + 1 + username.size();
|
||||
sendbuf = (uint8 *)malloc(sblen);
|
||||
memset(sendbuf, 0, sblen);
|
||||
|
||||
// XXX soules - should use htons instead of en32() from above!
|
||||
//data = htons(sblen - 4);
|
||||
//memcpy(sendbuf, &data, sizeof(data));
|
||||
en32(sendbuf, sblen - 4);
|
||||
|
||||
if(key.size()) {
|
||||
struct md5_context md5;
|
||||
uint8 md5out[16];
|
||||
|
||||
md5_starts(&md5);
|
||||
md5_update(&md5, GameInfo->MD5, 16);
|
||||
md5_update(&md5, (uint8 *)key.c_str(), key.size());
|
||||
md5_finish(&md5, md5out);
|
||||
memcpy(sendbuf + 4, md5out, 16);
|
||||
} else {
|
||||
memcpy(sendbuf + 4, GameInfo->MD5, 16);
|
||||
}
|
||||
|
||||
if(password.size()) {
|
||||
struct md5_context md5;
|
||||
uint8 md5out[16];
|
||||
|
||||
md5_starts(&md5);
|
||||
md5_update(&md5, (uint8 *)password.c_str(), password.size());
|
||||
md5_finish(&md5, md5out);
|
||||
memcpy(sendbuf + 4 + 16, md5out, 16);
|
||||
}
|
||||
|
||||
memset(sendbuf + 4 + 16 + 16, 0, 64);
|
||||
|
||||
sendbuf[4 + 16 + 16 + 64] = (uint8)localPlayers;
|
||||
|
||||
if(username.size()) {
|
||||
memcpy(sendbuf + 4 + 16 + 16 + 64 + 1,
|
||||
username.c_str(), username.size());
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
send(s_Socket, (char*)sendbuf, sblen, 0);
|
||||
#else
|
||||
send(s_Socket, sendbuf, sblen, 0);
|
||||
#endif
|
||||
free(sendbuf);
|
||||
|
||||
#ifdef WIN32
|
||||
recv(s_Socket, (char*)buf, 1, 0);
|
||||
#else
|
||||
recv(s_Socket, buf, 1, MSG_WAITALL);
|
||||
#endif
|
||||
netdivisor = buf[0];
|
||||
|
||||
puts("*** Connection established.");
|
||||
|
||||
FCEUDnetplay = 1;
|
||||
FCEUI_NetplayStart(localPlayers, netdivisor);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void FCEUD_NetworkClose(void)
|
||||
|
||||
int
|
||||
FCEUD_SendData(void *data,
|
||||
uint32 len)
|
||||
{
|
||||
if(Socket>0)
|
||||
{
|
||||
#ifdef BEOS
|
||||
closesocket(Socket);
|
||||
#else
|
||||
close(Socket);
|
||||
#endif
|
||||
}
|
||||
Socket=-1;
|
||||
int check = 0, error = 0;
|
||||
#ifndef WIN32
|
||||
error = ioctl(fileno(stdin), FIONREAD, &check);
|
||||
#endif
|
||||
if(!error && check) {
|
||||
char buf[1024];
|
||||
char *f;
|
||||
fgets(buf, 1024, stdin);
|
||||
if((f=strrchr(buf,'\n'))) {
|
||||
*f = 0;
|
||||
}
|
||||
FCEUI_NetplayText((uint8 *)buf);
|
||||
}
|
||||
|
||||
if(FCEUDnetplay)
|
||||
FCEUI_NetplayStop();
|
||||
FCEUDnetplay = 0;
|
||||
#ifdef WIN32
|
||||
send(s_Socket, (char*)data, len ,0);
|
||||
#else
|
||||
send(s_Socket, data, len ,0);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void FCEUD_NetplayText(uint8 *text)
|
||||
int
|
||||
FCEUD_RecvData(void *data,
|
||||
uint32 len)
|
||||
{
|
||||
char *tot = (char *)malloc(strlen((const char *)text) + 1);
|
||||
char *tmp;
|
||||
strcpy(tot, (const char *)text);
|
||||
tmp = tot;
|
||||
int size;
|
||||
NoWaiting &= ~2;
|
||||
|
||||
for(;;) {
|
||||
fd_set funfun;
|
||||
struct timeval popeye;
|
||||
|
||||
popeye.tv_sec=0;
|
||||
popeye.tv_usec=100000;
|
||||
|
||||
FD_ZERO(&funfun);
|
||||
FD_SET(s_Socket, &funfun);
|
||||
|
||||
while(*tmp)
|
||||
{
|
||||
if(*tmp < 0x20) *tmp = ' ';
|
||||
tmp++;
|
||||
}
|
||||
puts(tot);
|
||||
free(tot);
|
||||
switch(select(s_Socket + 1,&funfun,0,0,&popeye)) {
|
||||
case 0: continue;
|
||||
case -1:return(0);
|
||||
}
|
||||
|
||||
if(FD_ISSET(s_Socket,&funfun)) {
|
||||
#ifdef WIN32
|
||||
size = recv(s_Socket, (char*)data, len, 0);
|
||||
#else
|
||||
size = recv(s_Socket, data, len, MSG_WAITALL);
|
||||
#endif
|
||||
|
||||
if(size == len) {
|
||||
//unsigned long beefie;
|
||||
|
||||
FD_ZERO(&funfun);
|
||||
FD_SET(s_Socket, &funfun);
|
||||
|
||||
popeye.tv_sec = popeye.tv_usec = 0;
|
||||
if(select(s_Socket + 1, &funfun, 0, 0, &popeye) == 1)
|
||||
//if(!ioctl(s_Socket,FIONREAD,&beefie))
|
||||
// if(beefie)
|
||||
{
|
||||
NoWaiting|=2;
|
||||
//puts("Yaya");
|
||||
}
|
||||
return(1);
|
||||
} else {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
FCEUD_NetworkClose(void)
|
||||
{
|
||||
if(s_Socket > 0) {
|
||||
#ifdef BEOS
|
||||
closesocket(s_Socket);
|
||||
#else
|
||||
close(s_Socket);
|
||||
#endif
|
||||
}
|
||||
s_Socket = -1;
|
||||
|
||||
if(FCEUDnetplay) {
|
||||
FCEUI_NetplayStop();
|
||||
}
|
||||
FCEUDnetplay = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FCEUD_NetplayText(uint8 *text)
|
||||
{
|
||||
char *tot = (char *)malloc(strlen((const char *)text) + 1);
|
||||
char *tmp;
|
||||
strcpy(tot, (const char *)text);
|
||||
tmp = tot;
|
||||
|
||||
while(*tmp) {
|
||||
if(*tmp < 0x20) {
|
||||
*tmp = ' ';
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
puts(tot);
|
||||
free(tot);
|
||||
}
|
||||
|
|
|
@ -588,7 +588,7 @@ static char FileExt[2048]; /* Includes the . character, as in ".nes" */
|
|||
|
||||
static char FileBaseDirectory[2048];
|
||||
|
||||
void FCEUI_SetBaseDirectory(char *dir)
|
||||
void FCEUI_SetBaseDirectory(const char *dir)
|
||||
{
|
||||
strncpy(BaseDirectory,dir,2047);
|
||||
BaseDirectory[2047]=0;
|
||||
|
|
|
@ -78,7 +78,7 @@ int FCEUI_EndWaveRecord(void)
|
|||
}
|
||||
|
||||
|
||||
int FCEUI_BeginWaveRecord(char *fn)
|
||||
int FCEUI_BeginWaveRecord(const char *fn)
|
||||
{
|
||||
int r;
|
||||
|
||||
|
|
Loading…
Reference in New Issue