diff --git a/stella/src/build/makefile b/stella/src/build/makefile index bdbaa837d..b6e078228 100644 --- a/stella/src/build/makefile +++ b/stella/src/build/makefile @@ -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) diff --git a/stella/src/emucore/Console.cxx b/stella/src/emucore/Console.cxx index 5a0d90dea..9624086bb 100644 --- a/stella/src/emucore/Console.cxx +++ b/stella/src/emucore/Console.cxx @@ -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 @@ -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 { diff --git a/stella/src/emucore/Console.hxx b/stella/src/emucore/Console.hxx index c248abac7..ff1e0109e 100644 --- a/stella/src/emucore/Console.hxx +++ b/stella/src/emucore/Console.hxx @@ -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; diff --git a/stella/src/emucore/EventHandler.cxx b/stella/src/emucore/EventHandler.cxx index ae7388d60..e7dcd5fe1 100644 --- a/stella/src/emucore/EventHandler.cxx +++ b/stella/src/emucore/EventHandler.cxx @@ -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 @@ -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); diff --git a/stella/src/emucore/Settings.cxx b/stella/src/emucore/Settings.cxx index b1b387a29..b3e582ca4 100644 --- a/stella/src/emucore/Settings.cxx +++ b/stella/src/emucore/Settings.cxx @@ -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 +#include + #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&) { diff --git a/stella/src/emucore/Settings.hxx b/stella/src/emucore/Settings.hxx index d6fe76f85..dfb8f30fe 100644 --- a/stella/src/emucore/Settings.hxx +++ b/stella/src/emucore/Settings.hxx @@ -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 diff --git a/stella/src/ui/common/SettingsUNIX.cxx b/stella/src/ui/common/SettingsUNIX.cxx index 0f151480b..23bda1a44 100644 --- a/stella/src/ui/common/SettingsUNIX.cxx +++ b/stella/src/ui/common/SettingsUNIX.cxx @@ -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 +#include #include +#include +#include +#include + +#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 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 The directory to save snapshot files to\n" << " -ssname 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; +} diff --git a/stella/src/ui/common/SettingsUNIX.hxx b/stella/src/ui/common/SettingsUNIX.hxx index b1c9c862d..11c55ce64 100644 --- a/stella/src/ui/common/SettingsUNIX.hxx +++ b/stella/src/ui/common/SettingsUNIX.hxx @@ -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 diff --git a/stella/src/ui/sdl/mainSDL.cxx b/stella/src/ui/sdl/mainSDL.cxx index b519e60ab..9bc85ec03 100644 --- a/stella/src/ui/sdl/mainSDL.cxx +++ b/stella/src/ui/sdl/mainSDL.cxx @@ -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 @@ -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()); diff --git a/stella/src/ui/x11/mainX11.cxx b/stella/src/ui/x11/mainX11.cxx index 8c312b82b..473d6fe36 100644 --- a/stella/src/ui/x11/mainX11.cxx +++ b/stella/src/ui/x11/mainX11.cxx @@ -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 @@ -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());