Eliminated requirement for two platform specific files wrt porting.

They both referred to each other, so it made more sense to only have
one file.

Porters will now only need to define their own SettingsXXX, derived from
Settings.hxx, for platform specific stuff.

Updated the X11 and SDL ports wrt to the previously mentioned stuff.
The next task will be to update the DOS port, which should be
incredibly easy (assuming I can get a stable DOS dev environment) ...


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@183 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2003-09-19 15:45:01 +00:00
parent 14de7f7e62
commit 63ea3d3e93
10 changed files with 530 additions and 354 deletions

View File

@ -13,7 +13,7 @@
## See the file "license" for information on usage and redistribution of
## this file, and for a DISCLAIMER OF ALL WARRANTIES.
##
## $Id: makefile,v 1.38 2003-09-12 18:08:52 stephena Exp $
## $Id: makefile,v 1.39 2003-09-19 15:45:01 stephena Exp $
##============================================================================
##============================================================================
@ -199,7 +199,7 @@ unix-x:
LDFLAGS+="$(CFLAGS.X11)" \
LDLIBS="-lX11 -lXext" \
LDLIBS+="$(LIBS.X11)" \
OBJS="mainX11.o FrontendUNIX.o SettingsUNIX.o"
OBJS="mainX11.o SettingsUNIX.o"
OBJS+="$(OBJS.X11)"
linux-x:
@ -212,7 +212,7 @@ linux-x:
LDFLAGS+="$(CFLAGS.X11)" \
LDLIBS="-lX11 -lXext" \
LDLIBS+="$(LIBS.X11)" \
OBJS="mainX11.o FrontendUNIX.o SettingsUNIX.o" \
OBJS="mainX11.o SettingsUNIX.o" \
OBJS+="$(OBJS.X11)"
linux-sdl:
@ -225,7 +225,7 @@ linux-sdl:
LDFLAGS+="$(CFLAGS.SDL)" \
LDLIBS="-lX11 -lXext" \
LDLIBS+="$(LIBS.SDL)" \
OBJS="mainSDL.o RectList.o FrontendUNIX.o SettingsUNIX.o" \
OBJS="mainSDL.o RectList.o SettingsUNIX.o" \
OBJS+="$(OBJS.SDL)"
bsdi-x:
@ -265,7 +265,7 @@ CORE_OBJS = Booster.o Cart.o Cart2K.o Cart3F.o Cart4K.o CartAR.o CartDPC.o \
CartMB.o Console.o Control.o Driving.o \
Event.o Joystick.o Keyboard.o M6532.o MD5.o MediaSrc.o Paddles.o \
Props.o PropsSet.o Random.o Sound.o Switches.o Settings.o TIA.o \
Serializer.o Deserializer.o TIASound.o EventHandler.o Frontend.o \
Serializer.o Deserializer.o TIASound.o EventHandler.o \
$(M6502_OBJS)
stella.exe: $(CORE_OBJS) $(OBJS)

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Console.cxx,v 1.14 2003-09-12 18:08:53 stephena Exp $
// $Id: Console.cxx,v 1.15 2003-09-19 15:45:01 stephena Exp $
//============================================================================
#include <assert.h>
@ -28,7 +28,6 @@
#include "Driving.hxx"
#include "Event.hxx"
#include "EventHandler.hxx"
#include "Frontend.hxx"
#include "Joystick.hxx"
#include "Keyboard.hxx"
#include "M6502Low.hxx"
@ -50,11 +49,9 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Console::Console(const uInt8* image, uInt32 size, const char* filename,
Settings& rcsettings, PropertiesSet& propertiesSet, Frontend& frontend,
uInt32 sampleRate)
Settings& rcsettings, PropertiesSet& propertiesSet, uInt32 sampleRate)
: mySettings(rcsettings),
myPropSet(propertiesSet),
myFrontend(frontend)
myPropSet(propertiesSet)
{
myControllers[0] = 0;
myControllers[1] = 0;
@ -66,9 +63,6 @@ Console::Console(const uInt8* image, uInt32 size, const char* filename,
// Inform the settings object about the console
mySettings.setConsole(this);
// Inform the frontend object about the console
myFrontend.setConsole(this);
// Create an event handler which will collect and dispatch events
myEventHandler = new EventHandler(this);
myEvent = myEventHandler->event();
@ -179,8 +173,7 @@ Console::Console(const uInt8* image, uInt32 size, const char* filename,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Console::Console(const Console& console)
: mySettings(console.mySettings),
myPropSet(console.myPropSet),
myFrontend(console.myFrontend)
myPropSet(console.myPropSet)
{
// TODO: Write this method
assert(false);
@ -196,12 +189,6 @@ Console::~Console()
delete myEventHandler;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Frontend& Console::frontend() const
{
return myFrontend;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const Properties& Console::properties() const
{

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Console.hxx,v 1.10 2003-09-12 18:08:53 stephena Exp $
// $Id: Console.hxx,v 1.11 2003-09-19 15:45:01 stephena Exp $
//============================================================================
#ifndef CONSOLE_HXX
@ -23,7 +23,6 @@ class Console;
class Controller;
class Event;
class EventHandler;
class Frontend;
class MediaSource;
class PropertiesSet;
class Settings;
@ -41,7 +40,7 @@ class System;
This class represents the entire game console.
@author Bradford W. Mott
@version $Id: Console.hxx,v 1.10 2003-09-12 18:08:53 stephena Exp $
@version $Id: Console.hxx,v 1.11 2003-09-19 15:45:01 stephena Exp $
*/
class Console
{
@ -58,7 +57,7 @@ class Console
@param sampleRate The rate to create audio samples at
*/
Console(const uInt8* image, uInt32 size, const char* filename,
Settings& rcsettings, PropertiesSet& propertiesSet, Frontend& frontend,
Settings& rcsettings, PropertiesSet& propertiesSet,
uInt32 sampleRate);
/**
@ -94,13 +93,6 @@ class Console
return *myMediaSource;
}
/**
Get the frontend used by the console
@return The frontend used by the console
*/
Frontend& frontend() const;
/**
Get the properties being used by the game
@ -252,9 +244,6 @@ class Console
// Reference to the PropertiesSet object
PropertiesSet& myPropSet;
// Reference to the Frontend object
Frontend& myFrontend;
// Pointer to the EventHandler object
EventHandler* myEventHandler;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: EventHandler.cxx,v 1.6 2003-09-12 18:08:53 stephena Exp $
// $Id: EventHandler.cxx,v 1.7 2003-09-19 15:45:01 stephena Exp $
//============================================================================
#include <algorithm>
@ -22,7 +22,6 @@
#include "Console.hxx"
#include "Event.hxx"
#include "EventHandler.hxx"
#include "Frontend.hxx"
#include "MediaSrc.hxx"
#include "Settings.hxx"
#include "StellaEvent.hxx"
@ -114,13 +113,13 @@ void EventHandler::sendKeyEvent(StellaEvent::KeyCode key, Int32 state)
}
else if(event == Event::Pause)
{
myConsole->frontend().setPauseEvent();
myConsole->settings().setPauseEvent();
return;
}
else if(event == Event::Quit)
{
myConsole->settings().save();
myConsole->frontend().setQuitEvent();
myConsole->settings().saveConfig();
myConsole->settings().setQuitEvent();
return;
}
@ -168,13 +167,13 @@ void EventHandler::sendJoyEvent(StellaEvent::JoyStick stick,
}
else if(event == Event::Pause)
{
myConsole->frontend().setPauseEvent();
myConsole->settings().setPauseEvent();
return;
}
else if(event == Event::Quit)
{
myConsole->settings().save();
myConsole->frontend().setQuitEvent();
myConsole->settings().saveConfig();
myConsole->settings().setQuitEvent();
return;
}
@ -193,13 +192,13 @@ void EventHandler::sendEvent(Event::Type event, Int32 state)
// the emulation core
if(event == Event::Pause && state == 1)
{
myConsole->frontend().setPauseEvent();
myConsole->settings().setPauseEvent();
return;
}
else if(event == Event::Quit && state == 1)
{
myConsole->settings().save();
myConsole->frontend().setQuitEvent();
myConsole->settings().saveConfig();
myConsole->settings().setQuitEvent();
return;
}
@ -392,7 +391,7 @@ void EventHandler::saveState()
// Do a state save using the System
string md5 = myConsole->properties().get("Cartridge.MD5");
string filename = myConsole->frontend().stateFilename(md5, myCurrentState);
string filename = myConsole->settings().stateFilename(myCurrentState);
int result = myConsole->system().saveState(filename, md5);
// Print appropriate message
@ -430,7 +429,7 @@ void EventHandler::loadState()
// Do a state save using the System
string md5 = myConsole->properties().get("Cartridge.MD5");
string filename = myConsole->frontend().stateFilename(md5, myCurrentState);
string filename = myConsole->settings().stateFilename(myCurrentState);
int result = myConsole->system().loadState(filename, md5);
if(result == 1)
@ -451,7 +450,7 @@ void EventHandler::takeSnapshot()
string message, filename;
// Now save the snapshot file
filename = myConsole->frontend().snapshotFilename();
filename = myConsole->settings().snapshotFilename();
myConsole->snapshot().savePNG(filename, myConsole->mediaSource(),
myConsole->settings().theZoomLevel);

View File

@ -13,26 +13,48 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Settings.cxx,v 1.4 2003-09-12 18:08:53 stephena Exp $
// $Id: Settings.cxx,v 1.5 2003-09-19 15:45:01 stephena Exp $
//============================================================================
#include <sstream>
#include <fstream>
#include "bspf.hxx"
#include "Console.hxx"
#include "EventHandler.hxx"
#include "Settings.hxx"
#ifdef DEVELOPER_SUPPORT
#include "Props.hxx"
#endif
class Console;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Settings::Settings()
: myPauseIndicator(false),
myQuitIndicator(false),
myConsole(0)
{
theDesiredFrameRate = 60;
theKeymapList = "";
theJoymapList = "";
theZoomLevel = 1;
#ifdef SNAPSHOT_SUPPORT
theSnapshotDir = "";
theSnapshotName = "romname";
theMultipleSnapshotFlag = true;
theZoomLevel = 1;
}
#endif
#ifdef DEVELOPER_SUPPORT
userDefinedProperties.set("Display.Format", "-1");
userDefinedProperties.set("Display.XStart", "-1");
userDefinedProperties.set("Display.Width", "-1");
userDefinedProperties.set("Display.YStart", "-1");
userDefinedProperties.set("Display.Height", "-1");
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Settings::Settings(const string& infile, const string& outfile)
{
theMergePropertiesFlag = false;
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -40,6 +62,168 @@ Settings::~Settings()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Settings::loadConfig()
{
string line, key, value;
uInt32 equalPos;
ifstream in(mySettingsInputFilename.c_str());
if(!in || !in.is_open())
{
cout << "Error: Couldn't load settings file\n";
return;
}
while(getline(in, line))
{
// Strip all whitespace and tabs from the line
uInt32 garbage;
while((garbage = line.find(" ")) != string::npos)
line.erase(garbage, 1);
while((garbage = line.find("\t")) != string::npos)
line.erase(garbage, 1);
// Ignore commented and empty lines
if((line.length() == 0) || (line[0] == ';'))
continue;
// Search for the equal sign and discard the line if its not found
if((equalPos = line.find("=")) == string::npos)
continue;
key = line.substr(0, equalPos);
value = line.substr(equalPos + 1, line.length() - key.length() - 1);
// Check for absent key or value
if((key.length() == 0) || (value.length() == 0))
continue;
set(key, value);
}
in.close();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Settings::loadCommandLine(Int32 argc, char** argv)
{
// Make sure we have the correct number of command line arguments
if(argc == 1)
return false;
for(Int32 i = 1; i < (argc - 1); ++i)
{
// strip off the '-' character
string key = argv[i];
key = key.substr(1, key.length());
string value = argv[++i];
set(key, value);
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Settings::saveConfig()
{
if(!myConsole)
return;
ofstream out(mySettingsOutputFilename.c_str());
if(!out || !out.is_open())
{
cout << "Error: Couldn't save settings file\n";
return;
}
out << "fps = " << theDesiredFrameRate << endl
<< "zoom = " << theZoomLevel << endl
<< "keymap = " << myConsole->eventHandler().getKeymap() << endl
<< "joymap = " << myConsole->eventHandler().getJoymap() << endl
#ifdef SNAPSHOT_SUPPORT
<< "ssdir = " << theSnapshotDir << endl
<< "ssname = " << theSnapshotName << endl
<< "sssingle = " << theMultipleSnapshotFlag << endl
#endif
#ifdef DEVELOPER_SUPPORT
<< "Dmerge = " << theMergePropertiesFlag << endl
#endif
<< getArguments() << endl;
out.close();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Settings::set(string& key, string& value)
{
// Now set up the options by key
if(key == "fps")
{
// They're setting the desired frame rate
uInt32 rate = atoi(value.c_str());
if(rate < 1)
cout << "Invalid rate " << rate << endl;
else
theDesiredFrameRate = rate;
}
else if(key == "zoom")
{
// They're setting the initial window size
uInt32 zoom = atoi(value.c_str());
if(zoom < 1)
cout << "Invalid zoom value " << zoom << endl;
else
theZoomLevel = zoom;
}
else if(key == "keymap")
{
theKeymapList = value;
}
else if(key == "joymap")
{
theJoymapList = value;
}
#ifdef SNAPSHOT_SUPPORT
else if(key == "ssdir")
{
theSnapshotDir = value;
}
else if(key == "ssname")
{
if((value != "md5sum") && (value != "romname"))
cout << "Invalid snapshot name " << value << endl;
else
theSnapshotName = value;
}
else if(key == "sssingle")
{
uInt32 option = atoi(value.c_str());
if(option == 1)
theMultipleSnapshotFlag = false;
else if(option == 0)
theMultipleSnapshotFlag = true;
}
#endif
#ifdef DEVELOPER_SUPPORT
else if(key == "Dmerge")
{
uInt32 option = atoi(value.c_str());
if(option == 1)
theMergePropertiesFlag = true;
else if(option == 0)
theMergePropertiesFlag = false;
}
#endif
else
{
// Pass the key to the derived class to see if it knows
// what to do with it
setArgument(key, value);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Settings::Settings(const Settings&)
{

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Settings.hxx,v 1.4 2003-09-12 18:08:53 stephena Exp $
// $Id: Settings.hxx,v 1.5 2003-09-19 15:45:01 stephena Exp $
//============================================================================
#ifndef SETTINGS_HXX
@ -32,7 +32,7 @@ class Console;
This class provides an interface for accessing frontend specific settings.
@author Stephen Anthony
@version $Id: Settings.hxx,v 1.4 2003-09-12 18:08:53 stephena Exp $
@version $Id: Settings.hxx,v 1.5 2003-09-19 15:45:01 stephena Exp $
*/
class Settings
{
@ -41,7 +41,6 @@ class Settings
Create a new settings abstract class
*/
Settings();
Settings(const string& infile, const string& outfile);
/**
Destructor
@ -50,33 +49,138 @@ class Settings
public:
/**
This method should be called to display the supported settings.
@param message A short message about this version of Stella
This method should be called to load the current settings from an rc file.
*/
virtual void usage(string& message) = 0;
void loadConfig();
/**
This method should be called to save the current settings to an rc file.
*/
virtual void save() = 0;
void saveConfig();
/**
This method should be called to load the arguments from the commandline.
*/
bool loadCommandLine(Int32 argc, char** argv);
public:
//////////////////////////////////////////////////////////////////////
// The following methods are system-specific and must be implemented
// in derived classes.
//////////////////////////////////////////////////////////////////////
/**
This method should be called to set arguments.
@param key The variable to be set
@param value The value for the variable to hold
*/
virtual void setArgument(string& key, string& value) = 0;
/**
This method should be called to get system-specific settings.
@return A string representing all the key/value pairs.
*/
virtual string getArguments() = 0;
/**
This method should be called to get the filename of a state file
given the state number.
@return String representing the full path of the state filename.
*/
virtual string stateFilename(uInt32 state) = 0;
/**
This method should be called to get the filename of a snapshot.
@return String representing the full path of the snapshot filename.
*/
virtual string snapshotFilename() = 0;
//////////////////////////////////////////////////////////////////////
public:
/**
This method should be called when the emulation core sets
the console object.
*/
virtual void setConsole(Console* console) = 0;
void setConsole(Console* console) { myConsole = console; }
/**
This method should be called when the emulation core receives
a QUIT event.
*/
void setQuitEvent() { myQuitIndicator = true; }
/**
This method determines whether the QUIT event has been received.
@return Boolean representing whether a QUIT event has been received
*/
bool quit() { return myQuitIndicator; }
/**
This method should be called at when the emulation core receives
a PAUSE event.
*/
void setPauseEvent() { myPauseIndicator = !myPauseIndicator; }
/**
This method determines whether the PAUSE event has been received.
@return Boolean representing whether a PAUSE event has been received
*/
bool pause() { return myPauseIndicator; }
/**
This method should be called to get the filename of the users'
properties (stella.pro) file.
@return String representing the full path of the user properties filename.
*/
string userPropertiesFilename() { return myUserPropertiesFile; }
/**
This method should be called to get the filename of the system
properties (stella.pro) file.
@return String representing the full path of the system properties filename.
*/
string systemPropertiesFilename() { return mySystemPropertiesFile; }
/**
This method should be called to get the filename of the users'
config (stellarc) file.
@return String representing the full path of the user config filename.
*/
string userConfigFilename() { return myUserConfigFile; }
/**
This method should be called to get the filename of the system
config (stellarc) file.
@return String representing the full path of the system config filename.
*/
string systemConfigFilename() { return mySystemConfigFile; }
public:
// The following settings are needed by the emulation core and are
// common among all settings objects
// Indicates what the desired frame rate is
uInt32 theDesiredFrameRate;
// The keymap to use
string theKeymapList;
// The joymap to use
string theJoymapList;
// The scale factor for the window/screen
uInt32 theZoomLevel;
// The path to save snapshot files
string theSnapshotDir;
@ -87,9 +191,6 @@ class Settings
// overwriting the same file.
bool theMultipleSnapshotFlag;
// The amount the of zoom for the window/screen
uInt32 theZoomLevel;
#ifdef DEVELOPER_SUPPORT
// User-modified properties
Properties userDefinedProperties;
@ -99,12 +200,35 @@ class Settings
bool theMergePropertiesFlag;
#endif
protected:
bool myPauseIndicator;
bool myQuitIndicator;
string myStateDir;
string myStateFile;
string mySnapshotFile;
string myUserPropertiesFile;
string mySystemPropertiesFile;
string myUserConfigFile;
string mySystemConfigFile;
// The global Console object
Console* myConsole;
// The full pathname of the settings file for input
string mySettingsInputFilename;
// The full pathname of the settings file for output
string mySettingsOutputFilename;
private:
// Copy constructor isn't supported by this class so make it private
Settings(const Settings&);
// Assignment operator isn't supported by this class so make it private
Settings& operator = (const Settings&);
void set(string& key, string& value);
};
#endif

View File

@ -13,27 +13,29 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: SettingsUNIX.cxx,v 1.2 2003-09-12 18:08:53 stephena Exp $
// $Id: SettingsUNIX.cxx,v 1.3 2003-09-19 15:45:01 stephena Exp $
//============================================================================
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "bspf.hxx"
#include "Console.hxx"
#include "EventHandler.hxx"
#include "StellaEvent.hxx"
#ifdef DEVELOPER_SUPPORT
#include "Props.hxx"
#endif
#include "Settings.hxx"
#include "SettingsUNIX.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SettingsUNIX::SettingsUNIX(const string& infile, const string& outfile)
: mySettingsInputFilename(infile),
mySettingsOutputFilename(outfile)
SettingsUNIX::SettingsUNIX()
{
// Initialize UNIX specific settings
theUseFullScreenFlag = false;
theGrabMouseFlag = false;
theCenterWindowFlag = false;
@ -42,110 +44,49 @@ SettingsUNIX::SettingsUNIX(const string& infile, const string& outfile)
theUsePrivateColormapFlag = false;
theAccurateTimingFlag = true;
theDesiredVolume = -1;
theDesiredFrameRate = 60;
thePaddleMode = 0;
theAlternateProFile = "";
theSoundDriver = "oss";
theLeftJoystickNumber = 0;
theRightJoystickNumber = 1;
#ifdef DEVELOPER_SUPPORT
userDefinedProperties.set("Display.Format", "-1");
userDefinedProperties.set("Display.XStart", "-1");
userDefinedProperties.set("Display.Width", "-1");
userDefinedProperties.set("Display.YStart", "-1");
userDefinedProperties.set("Display.Height", "-1");
// Set up user specific filenames
myHomeDir = getenv("HOME");
string basepath = myHomeDir + "/.stella";
theMergePropertiesFlag = false;
#endif
if(access(basepath.c_str(), R_OK|W_OK|X_OK) != 0 )
mkdir(basepath.c_str(), 0777);
handleRCFile();
myStateDir = basepath + "/state/";
if(access(myStateDir.c_str(), R_OK|W_OK|X_OK) != 0 )
mkdir(myStateDir.c_str(), 0777);
myUserPropertiesFile = basepath + "/stella.pro";
mySystemPropertiesFile = "/etc/stella.pro";
myUserConfigFile = basepath + "/stellarc";
mySystemConfigFile = "/etc/stellarc";
// Set up the names of the input and output config files
mySettingsOutputFilename = myUserConfigFile;
if(access(myUserConfigFile.c_str(), R_OK) == 0)
mySettingsInputFilename = myUserConfigFile;
else
mySettingsInputFilename = mySystemConfigFile;
mySnapshotFile = "";
myStateFile = "";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SettingsUNIX::~SettingsUNIX()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SettingsUNIX::setConsole(Console* console)
{
myConsole = console;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool SettingsUNIX::handleCommandLineArgs(int argc, char* argv[])
{
// Make sure we have the correct number of command line arguments
if(argc == 1)
return false;
for(Int32 i = 1; i < (argc - 1); ++i)
{
// strip off the '-' character
string key = argv[i];
key = key.substr(1, key.length());
string value = argv[++i];
parseArg(key, value);
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SettingsUNIX::handleRCFile()
{
string line, key, value;
uInt32 equalPos;
ifstream in(mySettingsInputFilename.c_str());
if(!in || !in.is_open())
return;
while(getline(in, line))
{
// Strip all whitespace and tabs from the line
uInt32 garbage;
while((garbage = line.find(" ")) != string::npos)
line.erase(garbage, 1);
while((garbage = line.find("\t")) != string::npos)
line.erase(garbage, 1);
// Ignore commented and empty lines
if((line.length() == 0) || (line[0] == ';'))
continue;
// Search for the equal sign and discard the line if its not found
if((equalPos = line.find("=")) == string::npos)
continue;
key = line.substr(0, equalPos);
value = line.substr(equalPos + 1, line.length() - key.length() - 1);
// Check for absent key or value
if((key.length() == 0) || (value.length() == 0))
continue;
parseArg(key, value);
}
in.close();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SettingsUNIX::parseArg(string& key, string& value)
void SettingsUNIX::setArgument(string& key, string& value)
{
// Now set up the options by key
if(key == "fps")
{
// They're setting the desired frame rate
uInt32 rate = atoi(value.c_str());
if(rate < 1)
cout << "Invalid rate " << rate << endl;
else
theDesiredFrameRate = rate;
}
else if(key == "paddle")
if(key == "paddle")
{
// They're trying to set the paddle emulation mode
uInt32 pMode;
@ -216,15 +157,6 @@ void SettingsUNIX::parseArg(string& key, string& value)
else if(option == 0)
theAccurateTimingFlag = false;
}
else if(key == "zoom")
{
// They're setting the initial window size
uInt32 zoom = atoi(value.c_str());
if(zoom < 1)
cout << "Invalid zoom value " << zoom << endl;
else
theZoomLevel = zoom;
}
else if(key == "volume")
{
// They're setting the desired volume
@ -236,25 +168,6 @@ void SettingsUNIX::parseArg(string& key, string& value)
theDesiredVolume = volume;
}
else if(key == "ssdir")
{
theSnapshotDir = value;
}
else if(key == "ssname")
{
if((value != "md5sum") && (value != "romname"))
cout << "Invalid snapshot name " << value << endl;
else
theSnapshotName = value;
}
else if(key == "sssingle")
{
uInt32 option = atoi(value.c_str());
if(option == 1)
theMultipleSnapshotFlag = false;
else if(option == 0)
theMultipleSnapshotFlag = true;
}
else if(key == "sound")
{
if((value != "oss") && (value != "sdl") && (value != "alsa"))
@ -262,14 +175,6 @@ void SettingsUNIX::parseArg(string& key, string& value)
theSoundDriver = value;
}
else if(key == "keymap")
{
theKeymapList = value;
}
else if(key == "joymap")
{
theJoymapList = value;
}
else if(key == "joyleft")
{
Int32 joynum = atoi(value.c_str());
@ -286,16 +191,6 @@ void SettingsUNIX::parseArg(string& key, string& value)
else
theRightJoystickNumber = joynum;
}
#ifdef DEVELOPER_SUPPORT
else if(key == "Dmerge")
{
uInt32 option = atoi(value.c_str());
if(option == 1)
theMergePropertiesFlag = true;
else if(option == 0)
theMergePropertiesFlag = false;
}
#endif
else
{
cout << "Undefined option " << key << endl;
@ -303,17 +198,11 @@ void SettingsUNIX::parseArg(string& key, string& value)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SettingsUNIX::save()
string SettingsUNIX::getArguments()
{
if(!myConsole)
return;
ostringstream buf;
ofstream out(mySettingsOutputFilename.c_str());
if(!out || !out.is_open())
return;
out << "fps = " << theDesiredFrameRate << endl
<< "paddle = " << thePaddleMode << endl
buf << "paddle = " << thePaddleMode << endl
<< "owncmap = " << theUsePrivateColormapFlag << endl
<< "fullscreen = " << theUseFullScreenFlag << endl
<< "grabmouse = " << theGrabMouseFlag << endl
@ -323,20 +212,11 @@ void SettingsUNIX::save()
<< "accurate = " << theAccurateTimingFlag << endl
<< "zoom = " << theZoomLevel << endl
<< "volume = " << theDesiredVolume << endl
<< "ssdir = " << theSnapshotDir << endl
<< "ssname = " << theSnapshotName << endl
<< "sssingle = " << theMultipleSnapshotFlag << endl
<< "sound = " << theSoundDriver << endl
#ifdef DEVELOPER_SUPPORT
<< "Dmerge = " << theMergePropertiesFlag << endl
#endif
<< "keymap = " << myConsole->eventHandler().getKeymap() << endl
<< "joymap = " << myConsole->eventHandler().getJoymap() << endl
<< "joyleft = " << theLeftJoystickNumber << endl
<< "joyright = " << theRightJoystickNumber << endl
<< endl;
<< "joyright = " << theRightJoystickNumber << endl;
out.close();
return buf.str();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -366,7 +246,7 @@ void SettingsUNIX::usage(string& message)
<< " -pro <props file> Use the given properties file instead of stella.pro\n"
<< " -showinfo <0|1> Shows some game info\n"
<< " -accurate <0|1> Accurate game timing (uses more CPU)\n"
#ifdef HAVE_PNG
#ifdef SNAPSHOT_SUPPORT
<< " -ssdir <path> The directory to save snapshot files to\n"
<< " -ssname <name> How to name the snapshot (romname or md5sum)\n"
<< " -sssingle <0|1> Generate single snapshot instead of many\n"
@ -393,3 +273,66 @@ void SettingsUNIX::usage(string& message)
#endif
<< endl;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string SettingsUNIX::stateFilename(uInt32 state)
{
if(!myConsole)
return "";
ostringstream buf;
buf << myStateDir << myConsole->properties().get("Cartridge.MD5")
<< ".st" << state;
myStateFile = buf.str();
return myStateFile;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string SettingsUNIX::snapshotFilename()
{
if(!myConsole)
return "";
string filename;
string path = theSnapshotDir;
if(theSnapshotName == "romname")
path = path + "/" + myConsole->properties().get("Cartridge.Name");
else if(theSnapshotName == "md5sum")
path = path + "/" + myConsole->properties().get("Cartridge.MD5");
// Replace all spaces in name with underscores
replace(path.begin(), path.end(), ' ', '_');
// Check whether we want multiple snapshots created
if(theMultipleSnapshotFlag)
{
// Determine if the file already exists, checking each successive filename
// until one doesn't exist
filename = path + ".png";
if(access(filename.c_str(), F_OK) == 0 )
{
ostringstream buf;
for(uInt32 i = 1; ;++i)
{
buf.str("");
buf << path << "_" << i << ".png";
if(access(buf.str().c_str(), F_OK) == -1 )
break;
}
filename = buf.str();
}
}
else
filename = path + ".png";
mySnapshotFile = filename;
return mySnapshotFile;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string SettingsUNIX::userHomeDir()
{
return myHomeDir;
}

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: SettingsUNIX.hxx,v 1.2 2003-09-12 18:08:54 stephena Exp $
// $Id: SettingsUNIX.hxx,v 1.3 2003-09-19 15:45:01 stephena Exp $
//============================================================================
#ifndef SETTINGS_UNIX_HXX
@ -28,7 +28,7 @@ class Console;
This class defines UNIX-like OS's (Linux) system specific settings.
@author Stephen Anthony
@version $Id: SettingsUNIX.hxx,v 1.2 2003-09-12 18:08:54 stephena Exp $
@version $Id: SettingsUNIX.hxx,v 1.3 2003-09-19 15:45:01 stephena Exp $
*/
class SettingsUNIX : public Settings
{
@ -36,36 +36,58 @@ class SettingsUNIX : public Settings
/**
Create a new UNIX settings object
*/
SettingsUNIX(const string& infile, const string& outfile);
SettingsUNIX();
/**
Destructor
*/
virtual ~SettingsUNIX();
public:
/**
This method should be called to set arguments.
@param key The variable to be set
@param value The value for the variable to hold
*/
virtual void setArgument(string& key, string& value);
/**
This method should be called to get system-specific settings.
@return A string representing all the key/value pairs.
*/
virtual string getArguments();
/**
This method should be called to get the filename of a state file
given the state number.
@return String representing the full path of the state filename.
*/
virtual string stateFilename(uInt32 state);
/**
This method should be called to get the filename of a snapshot.
@return String representing the full path of the snapshot filename.
*/
virtual string snapshotFilename();
public:
/**
Display the commandline settings for this UNIX version of Stella.
@param message A short message about this version of Stella
*/
virtual void usage(string& message);
void usage(string& message);
/**
Save the current settings to an rc file.
*/
virtual void save();
Return the users UNIX home directory
/**
Let the frontend know about the console object.
@param message A short message about this version of Stella
*/
virtual void setConsole(Console* console);
public:
/**
Handle UNIX commandline arguments
*/
bool handleCommandLineArgs(Int32 ac, char** av);
string userHomeDir();
public:
// Indicates whether to use fullscreen
@ -93,9 +115,6 @@ class SettingsUNIX : public Settings
// Indicates what the desired volume is
Int32 theDesiredVolume;
// Indicates what the desired frame rate is
uInt32 theDesiredFrameRate;
// Indicate which paddle mode we're using:
// 0 - Mouse emulates paddle 0
// 1 - Mouse emulates paddle 1
@ -117,17 +136,8 @@ class SettingsUNIX : public Settings
Int32 theRightJoystickNumber;
private:
void handleRCFile();
void parseArg(string& key, string& value);
// The full pathname of the settings file for input
string mySettingsInputFilename;
// The full pathname of the settings file for output
string mySettingsOutputFilename;
// The global Console object
Console* myConsole;
// The UNIX home directory
string myHomeDir;
};
#endif

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: mainSDL.cxx,v 1.50 2003-09-12 18:08:54 stephena Exp $
// $Id: mainSDL.cxx,v 1.51 2003-09-19 15:45:01 stephena Exp $
//============================================================================
#include <fstream>
@ -35,7 +35,6 @@
#include "Event.hxx"
#include "StellaEvent.hxx"
#include "EventHandler.hxx"
#include "Frontend.hxx"
#include "MediaSrc.hxx"
#include "PropsSet.hxx"
#include "Sound.hxx"
@ -55,7 +54,6 @@
#endif
#ifdef UNIX
#include "FrontendUNIX.hxx"
#include "SettingsUNIX.hxx"
#endif
@ -100,13 +98,8 @@ static uInt32 theWidth, theHeight, theMaxWindowSize, theWindowSize;
static void cleanup();
static bool setupJoystick();
static void handleEvents();
static void takeSnapshot();
static uInt32 getTicks();
static bool setupProperties(PropertiesSet& set);
static void handleRCFile();
static void usage();
#ifdef HAVE_JOYSTICK
static SDL_Joystick* theLeftJoystick = (SDL_Joystick*) NULL;
@ -123,9 +116,6 @@ static Console* theConsole = (Console*) NULL;
// Pointer to the sound object or the null pointer
static Sound* theSound = (Sound*) NULL;
// Pointer to the frontend object or the null pointer
static Frontend* theFrontend = (Frontend*) NULL;
// Pointer to the settings object or the null pointer
#ifdef UNIX
static SettingsUNIX* theSettings = (SettingsUNIX*) NULL;
@ -492,7 +482,7 @@ void setupPalette()
// Make the palette be 75% as bright if pause is selected
float shade = 1.0;
if(theFrontend->pause())
if(theSettings->pause())
shade = 0.75;
const uInt32* gamePalette = theConsole->mediaSource().palette();
@ -930,11 +920,11 @@ void handleEvents()
{
if(theSettings->theMergePropertiesFlag) // Attempt to merge with propertiesSet
{
theConsole->saveProperties(theConsole->frontend().userPropertiesFilename(), true);
theConsole->saveProperties(theSettings->userPropertiesFilename(), true);
}
else // Save to file in home directory
{
string newPropertiesFile = theConsole->frontend().userHomeDir() + "/" + \
string newPropertiesFile = theSettings->userHomeDir() + "/" + \
theConsole->properties().get("Cartridge.Name") + ".pro";
replace(newPropertiesFile.begin(), newPropertiesFile.end(), ' ', '_');
theConsole->saveProperties(newPropertiesFile);
@ -1026,7 +1016,7 @@ void handleEvents()
{
if((event.active.state & SDL_APPACTIVE) && (event.active.gain == 0))
{
if(!theFrontend->pause())
if(!theSettings->pause())
{
theConsole->eventHandler().sendEvent(Event::Pause, 1);
}
@ -1152,15 +1142,15 @@ bool setupProperties(PropertiesSet& set)
return true;
}
if(theFrontend->userPropertiesFilename() != "")
if(theSettings->userPropertiesFilename() != "")
{
set.load(theFrontend->userPropertiesFilename(),
set.load(theSettings->userPropertiesFilename(),
&Console::defaultProperties(), useMemList);
return true;
}
else if(theFrontend->systemPropertiesFilename() != "")
else if(theSettings->systemPropertiesFilename() != "")
{
set.load(theFrontend->systemPropertiesFilename(),
set.load(theSettings->systemPropertiesFilename(),
&Console::defaultProperties(), useMemList);
return true;
}
@ -1180,9 +1170,6 @@ void cleanup()
if(theSettings)
delete theSettings;
if(theFrontend)
delete theFrontend;
if(theConsole)
delete theConsole;
@ -1209,36 +1196,18 @@ void cleanup()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int main(int argc, char* argv[])
{
// First set up the frontend to communicate with the emulation core
#ifdef UNIX
theFrontend = new FrontendUNIX();
#endif
if(!theFrontend)
{
cerr << "ERROR: Couldn't set up the frontend.\n";
cleanup();
return 0;
}
// Create some settings for the emulator
string infile = "";
string outfile = theFrontend->userConfigFilename();
if(theFrontend->userConfigFilename() != "")
infile = theFrontend->userConfigFilename();
else if(theFrontend->systemConfigFilename() != "")
infile = theFrontend->systemConfigFilename();
#ifdef UNIX
theSettings = new SettingsUNIX(infile, outfile);
theSettings = new SettingsUNIX();
#endif
if(!theSettings)
{
cleanup();
return 0;
}
theSettings->loadConfig();
// Take care of commandline arguments
if(!theSettings->handleCommandLineArgs(argc, argv))
if(!theSettings->loadCommandLine(argc, argv))
{
string message = "Stella for SDL version 1.4\n\nUsage: stella.sdl [option ...] file";
theSettings->usage(message);
@ -1318,7 +1287,7 @@ int main(int argc, char* argv[])
// Create the 2600 game console
theConsole = new Console(image, size, filename, *theSettings, propertiesSet,
*theFrontend, theSound->getSampleRate());
theSound->getSampleRate());
// Free the image since we don't need it any longer
delete[] image;
@ -1354,7 +1323,7 @@ int main(int argc, char* argv[])
for(;;)
{
// Exit if the user wants to quit
if(theFrontend->quit())
if(theSettings->quit())
{
break;
}
@ -1362,7 +1331,7 @@ int main(int argc, char* argv[])
// Call handleEvents here to see if user pressed pause
startTime = getTicks();
handleEvents();
if(theFrontend->pause())
if(theSettings->pause())
{
updateDisplay(theConsole->mediaSource());
SDL_Delay(10);
@ -1400,14 +1369,14 @@ int main(int argc, char* argv[])
for(;;)
{
// Exit if the user wants to quit
if(theFrontend->quit())
if(theSettings->quit())
{
break;
}
startTime = getTicks();
handleEvents();
if(!theFrontend->pause())
if(!theSettings->pause())
{
theConsole->mediaSource().update();
theSound->updateSound(theConsole->mediaSource());

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: mainX11.cxx,v 1.41 2003-09-12 18:08:54 stephena Exp $
// $Id: mainX11.cxx,v 1.42 2003-09-19 15:45:01 stephena Exp $
//============================================================================
#include <fstream>
@ -39,7 +39,6 @@
#include "Event.hxx"
#include "StellaEvent.hxx"
#include "EventHandler.hxx"
#include "Frontend.hxx"
#include "MediaSrc.hxx"
#include "PropsSet.hxx"
#include "Sound.hxx"
@ -61,7 +60,6 @@
#endif
#ifdef UNIX
#include "FrontendUNIX.hxx"
#include "SettingsUNIX.hxx"
#endif
@ -97,11 +95,8 @@ static uInt32 theWidth, theHeight, theMaxWindowSize, theWindowSize;
static void cleanup();
static bool setupJoystick();
static void handleEvents();
static uInt32 getTicks();
static bool setupProperties(PropertiesSet& set);
static void handleRCFile();
static void usage();
#ifdef HAVE_JOYSTICK
// File descriptors for the joystick devices
@ -118,9 +113,6 @@ static Console* theConsole = (Console*) NULL;
// Pointer to the sound object or the null pointer
static Sound* theSound = (Sound*) NULL;
// Pointer to the frontend object or the null pointer
static Frontend* theFrontend = (Frontend*) NULL;
// Pointer to the settings object or the null pointer
#ifdef UNIX
static SettingsUNIX* theSettings = (SettingsUNIX*) NULL;
@ -452,7 +444,7 @@ void setupPalette()
// Make the palette be 75% as bright if pause is selected
float shade = 1.0;
if(theFrontend->pause())
if(theSettings->pause())
shade = 0.75;
// Allocate colors in the default colormap
@ -731,11 +723,11 @@ void handleEvents()
{
if(theSettings->theMergePropertiesFlag) // Attempt to merge with propertiesSet
{
theConsole->saveProperties(theConsole->frontend().userPropertiesFilename(), true);
theConsole->saveProperties(theSettings->userPropertiesFilename(), true);
}
else // Save to file in home directory
{
string newPropertiesFile = theConsole->frontend().userHomeDir() + "/" + \
string newPropertiesFile = theSettings->userHomeDir() + "/" + \
theConsole->properties().get("Cartridge.Name") + ".pro";
replace(newPropertiesFile.begin(), newPropertiesFile.end(), ' ', '_');
theConsole->saveProperties(newPropertiesFile);
@ -798,7 +790,7 @@ void handleEvents()
}
else if(event.type == UnmapNotify)
{
if(!theFrontend->pause())
if(!theSettings->pause())
{
theConsole->eventHandler().sendEvent(Event::Pause, 1);
}
@ -1125,15 +1117,15 @@ bool setupProperties(PropertiesSet& set)
return true;
}
if(theFrontend->userPropertiesFilename() != "")
if(theSettings->userPropertiesFilename() != "")
{
set.load(theFrontend->userPropertiesFilename(),
set.load(theSettings->userPropertiesFilename(),
&Console::defaultProperties(), useMemList);
return true;
}
else if(theFrontend->systemPropertiesFilename() != "")
else if(theSettings->systemPropertiesFilename() != "")
{
set.load(theFrontend->systemPropertiesFilename(),
set.load(theSettings->systemPropertiesFilename(),
&Console::defaultProperties(), useMemList);
return true;
}
@ -1153,9 +1145,6 @@ void cleanup()
if(theSettings)
delete theSettings;
if(theFrontend)
delete theFrontend;
if(theConsole)
delete theConsole;
@ -1189,36 +1178,18 @@ void cleanup()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int main(int argc, char* argv[])
{
// First set up the frontend to communicate with the emulation core
#ifdef UNIX
theFrontend = new FrontendUNIX();
#endif
if(!theFrontend)
{
cerr << "ERROR: Couldn't set up the frontend.\n";
cleanup();
return 0;
}
// Create some settings for the emulator
string infile = "";
string outfile = theFrontend->userConfigFilename();
if(theFrontend->userConfigFilename() != "")
infile = theFrontend->userConfigFilename();
else if(theFrontend->systemConfigFilename() != "")
infile = theFrontend->systemConfigFilename();
#ifdef UNIX
theSettings = new SettingsUNIX(infile, outfile);
theSettings = new SettingsUNIX();
#endif
if(!theSettings)
{
cleanup();
return 0;
}
theSettings->loadConfig();
// Take care of commandline arguments
if(!theSettings->handleCommandLineArgs(argc, argv))
if(!theSettings->loadCommandLine(argc, argv))
{
string message = "Stella for X11 version 1.4\n\nUsage: stella.x11 [option ...] file";
theSettings->usage(message);
@ -1290,7 +1261,7 @@ int main(int argc, char* argv[])
// Create the 2600 game console
theConsole = new Console(image, size, filename, *theSettings, propertiesSet,
*theFrontend, theSound->getSampleRate());
theSound->getSampleRate());
// Free the image since we don't need it any longer
delete[] image;
@ -1327,7 +1298,7 @@ int main(int argc, char* argv[])
for(;;)
{
// Exit if the user wants to quit
if(theFrontend->quit())
if(theSettings->quit())
{
break;
}
@ -1335,7 +1306,7 @@ int main(int argc, char* argv[])
// Call handleEvents here to see if user pressed pause
startTime = getTicks();
handleEvents();
if(theFrontend->pause())
if(theSettings->pause())
{
updateDisplay(theConsole->mediaSource());
usleep(10000);
@ -1374,14 +1345,14 @@ int main(int argc, char* argv[])
for(;;)
{
// Exit if the user wants to quit
if(theFrontend->quit())
if(theSettings->quit())
{
break;
}
startTime = getTicks();
handleEvents();
if(!theFrontend->pause())
if(!theSettings->pause())
{
theConsole->mediaSource().update();
theSound->updateSound(theConsole->mediaSource());