Changed the Settings class to act like Props class. Now it contains

properties of the <key, value> type.

This is a much cleaner approach, and it eliminates the problems of
object slicing experienced before (passing SettingsUNIX through a
Settings pointer, and then needing the stuff specific to SettingsUNIX,
requiring a cast).


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@186 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2003-09-23 00:58:31 +00:00
parent dd6d7f7981
commit 4651f21bcd
6 changed files with 268 additions and 443 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: EventHandler.cxx,v 1.8 2003-09-21 14:33:33 stephena Exp $
// $Id: EventHandler.cxx,v 1.9 2003-09-23 00:58:31 stephena Exp $
//============================================================================
#include <algorithm>
@ -212,7 +212,7 @@ void EventHandler::setKeymap()
{
// Since istringstream swallows whitespace, we have to make the
// delimiters be spaces
string list = myConsole->settings().theKeymapList;
string list = myConsole->settings().getString("keymap");
replace(list.begin(), list.end(), ':', ' ');
if(isValidList(list, StellaEvent::LastKCODE))
@ -236,7 +236,7 @@ void EventHandler::setJoymap()
{
// Since istringstream swallows whitespace, we have to make the
// delimiters be spaces
string list = myConsole->settings().theJoymapList;
string list = myConsole->settings().getString("joymap");
replace(list.begin(), list.end(), ':', ' ');
if(isValidList(list, StellaEvent::LastJSTICK*StellaEvent::LastJCODE))
@ -452,7 +452,7 @@ void EventHandler::takeSnapshot()
// Now save the snapshot file
filename = myConsole->settings().snapshotFilename();
myConsole->snapshot().savePNG(filename, myConsole->mediaSource(),
myConsole->settings().theZoomLevel);
myConsole->settings().getInt("zoom"));
message = "Snapshot saved";
myConsole->mediaSource().showMessage(message, 120);

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.cxx,v 1.6 2003-09-21 14:33:33 stephena Exp $
// $Id: Settings.cxx,v 1.7 2003-09-23 00:58:31 stephena Exp $
//============================================================================
#include <assert.h>
@ -29,7 +29,6 @@
#include "Props.hxx"
#endif
class Console;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Settings::Settings()
@ -37,15 +36,24 @@ Settings::Settings()
myQuitIndicator(false),
myConsole(0)
{
theDesiredFrameRate = 60;
theKeymapList = "";
theJoymapList = "";
theZoomLevel = 1;
// First create the settings array
myCapacity = 30;
mySettings = new Setting[myCapacity];
mySize = 0;
// Now fill it with options that are common to all versions of Stella
set("framerate", "60");
set("keymap", "");
set("joymap", "");
set("zoom", "1");
set("showinfo", "false");
set("mergeprops", "false");
set("paddle", "0");
#ifdef SNAPSHOT_SUPPORT
theSnapshotDir = "";
theSnapshotName = "romname";
theMultipleSnapshotFlag = true;
set("ssdir", "");
set("ssname", "");
set("sssingle", "false");
#endif
#ifdef DEVELOPER_SUPPORT
userDefinedProperties.set("Display.Format", "-1");
@ -53,14 +61,14 @@ Settings::Settings()
userDefinedProperties.set("Display.Width", "-1");
userDefinedProperties.set("Display.YStart", "-1");
userDefinedProperties.set("Display.Height", "-1");
theMergePropertiesFlag = false;
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Settings::~Settings()
{
// Free the settings array
delete[] mySettings;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -151,92 +159,101 @@ void Settings::saveConfig()
<< "; without the '-' character." << endl
<< ";" << endl
<< "; Values are the same as those allowed on the commandline." << endl
<< "; Boolean values are specified as 1 (for true) and 0 (for false)" << endl
<< ";" << endl
<< "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;
<< "; Boolean values are specified as 1 (or true) and 0 (or false)" << endl
<< ";" << endl;
// Write out each of the key and value pairs
for(uInt32 i = 0; i < mySize; ++i)
out << mySettings[i].key << " = " << mySettings[i].value << endl;
out.close();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Settings::set(string& key, string& value)
void Settings::set(const string& key, const string& value)
{
// Now set up the options by key
if(key == "fps")
// See if the setting already exists
for(uInt32 i = 0; i < mySize; ++i)
{
// They're setting the desired frame rate
uInt32 rate = atoi(value.c_str());
if(rate < 1)
cout << "Invalid rate " << rate << endl;
else
theDesiredFrameRate = rate;
if(key == mySettings[i].key)
{
mySettings[i].value = value;
return;
}
}
else if(key == "zoom")
// See if the array needs to be resized
if(mySize == myCapacity)
{
// 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;
// Yes, so we'll make the array twice as large
Setting* newSettings = new Setting[myCapacity * 2];
for(uInt32 i = 0; i < mySize; ++i)
{
newSettings[i] = mySettings[i];
}
delete[] mySettings;
mySettings = newSettings;
myCapacity *= 2;
}
else if(key == "keymap")
// Add new property to the array
mySettings[mySize].key = key;
mySettings[mySize].value = value;
++mySize;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Int32 Settings::getInt(const string& key) const
{
// Try to find the named setting and answer its value
for(uInt32 i = 0; i < mySize; ++i)
{
theKeymapList = value;
if(key == mySettings[i].key)
{
return atoi(mySettings[i].value.c_str());
}
}
else if(key == "joymap")
return -1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Settings::getBool(const string& key) const
{
// Try to find the named setting and answer its value
for(uInt32 i = 0; i < mySize; ++i)
{
theJoymapList = value;
if(key == mySettings[i].key)
{
if(mySettings[i].value == "1" || mySettings[i].value == "true")
return true;
else if(mySettings[i].value == "0" || mySettings[i].value == "false")
return false;
else
return false;
}
}
#ifdef SNAPSHOT_SUPPORT
else if(key == "ssdir")
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string Settings::getString(const string& key) const
{
// Try to find the named setting and answer its value
for(uInt32 i = 0; i < mySize; ++i)
{
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);
if(key == mySettings[i].key)
{
return mySettings[i].value;
}
}
return "";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

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.5 2003-09-19 15:45:01 stephena Exp $
// $Id: Settings.hxx,v 1.6 2003-09-23 00:58:31 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.5 2003-09-19 15:45:01 stephena Exp $
@version $Id: Settings.hxx,v 1.6 2003-09-23 00:58:31 stephena Exp $
*/
class Settings
{
@ -63,27 +63,47 @@ class Settings
*/
bool loadCommandLine(Int32 argc, char** argv);
/**
Get the value assigned to the specified key. If the key does
not exist then -1 is returned.
@param key The key of the setting to lookup
@return The integer value of the setting
*/
Int32 getInt(const string& key) const;
/**
Get the value assigned to the specified key. If the key does
not exist then false is returned.
@param key The key of the setting to lookup
@return The boolean value of the setting
*/
bool getBool(const string& key) const;
/**
Get the value assigned to the specified key. If the key does
not exist then the empty string is returned.
@param key The key of the setting to lookup
@return The string value of the setting
*/
string getString(const string& key) const;
/**
Set the value associated with key to the given value.
@param key The key of the setting
@param value The value to assign to the setting
*/
void set(const string& key, const string& value);
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.
@ -99,7 +119,13 @@ class Settings
*/
virtual string snapshotFilename() = 0;
//////////////////////////////////////////////////////////////////////
/**
This method should be called to display usage information.
@param message A short message about this version of Stella
*/
virtual void usage(string& message) = 0;
public:
/**
This method should be called when the emulation core sets
@ -165,45 +191,22 @@ class Settings
*/
string systemConfigFilename() { return mySystemConfigFile; }
/**
Return the default directory for storing data.
*/
string baseDir() { return myBaseDir; }
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;
// What the snapshot should be called (romname or md5sum)
string theSnapshotName;
// Indicates whether to generate multiple snapshots or keep
// overwriting the same file.
bool theMultipleSnapshotFlag;
#ifdef DEVELOPER_SUPPORT
// User-modified properties
Properties userDefinedProperties;
// Whether to save user-defined properties to a file or
// merge into the propertiesset file for future use
bool theMergePropertiesFlag;
#endif
protected:
bool myPauseIndicator;
bool myQuitIndicator;
string myBaseDir;
string myStateDir;
string myStateFile;
string mySnapshotFile;
@ -228,7 +231,21 @@ class Settings
// Assignment operator isn't supported by this class so make it private
Settings& operator = (const Settings&);
void set(string& key, string& value);
// Structure used for storing properties
struct Setting
{
string key;
string value;
};
// Pointer to a dynamically allocated array of settings
Setting* mySettings;
// Current capacity of the settings array
unsigned int myCapacity;
// Size of the settings array (i.e. the number of <key,value> pairs)
unsigned int mySize;
};
#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: SettingsUNIX.cxx,v 1.3 2003-09-19 15:45:01 stephena Exp $
// $Id: SettingsUNIX.cxx,v 1.4 2003-09-23 00:58:31 stephena Exp $
//============================================================================
#include <cstdlib>
@ -35,35 +35,20 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SettingsUNIX::SettingsUNIX()
{
// Initialize UNIX specific settings
theUseFullScreenFlag = false;
theGrabMouseFlag = false;
theCenterWindowFlag = false;
theShowInfoFlag = false;
theHideCursorFlag = false;
theUsePrivateColormapFlag = false;
theAccurateTimingFlag = true;
theDesiredVolume = -1;
thePaddleMode = 0;
theAlternateProFile = "";
theSoundDriver = "oss";
theLeftJoystickNumber = 0;
theRightJoystickNumber = 1;
// First set variables that the parent class needs
myBaseDir = getenv("HOME");
string stelladir = myBaseDir + "/.stella";
// Set up user specific filenames
myHomeDir = getenv("HOME");
string basepath = myHomeDir + "/.stella";
if(access(stelladir.c_str(), R_OK|W_OK|X_OK) != 0 )
mkdir(stelladir.c_str(), 0777);
if(access(basepath.c_str(), R_OK|W_OK|X_OK) != 0 )
mkdir(basepath.c_str(), 0777);
myStateDir = basepath + "/state/";
myStateDir = stelladir + "/state/";
if(access(myStateDir.c_str(), R_OK|W_OK|X_OK) != 0 )
mkdir(myStateDir.c_str(), 0777);
myUserPropertiesFile = basepath + "/stella.pro";
myUserPropertiesFile = stelladir + "/stella.pro";
mySystemPropertiesFile = "/etc/stella.pro";
myUserConfigFile = basepath + "/stellarc";
myUserConfigFile = stelladir + "/stellarc";
mySystemConfigFile = "/etc/stellarc";
// Set up the names of the input and output config files
@ -75,6 +60,18 @@ SettingsUNIX::SettingsUNIX()
mySnapshotFile = "";
myStateFile = "";
// Now create UNIX specific settings
set("fullscreen", "false");
set("grabmouse", "false");
set("center", "false");
set("hidecursor", "false");
set("owncmap", "false");
set("accurate", "true");
set("volume", "-1");
set("sound", "oss");
set("joyleft", "0");
set("joyright", "1");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -82,143 +79,6 @@ SettingsUNIX::~SettingsUNIX()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SettingsUNIX::setArgument(string& key, string& value)
{
// Now set up the options by key
if(key == "paddle")
{
// They're trying to set the paddle emulation mode
uInt32 pMode;
if(value == "real")
{
thePaddleMode = 4;
}
else
{
pMode = atoi(value.c_str());
if((pMode > 0) && (pMode < 4))
thePaddleMode = pMode;
}
}
else if(key == "owncmap")
{
uInt32 option = atoi(value.c_str());
if(option == 1)
theUsePrivateColormapFlag = true;
else if(option == 0)
theUsePrivateColormapFlag = false;
}
else if(key == "fullscreen")
{
uInt32 option = atoi(value.c_str());
if(option == 1)
theUseFullScreenFlag = true;
else if(option == 0)
theUseFullScreenFlag = false;
}
else if(key == "grabmouse")
{
uInt32 option = atoi(value.c_str());
if(option == 1)
theGrabMouseFlag = true;
else if(option == 0)
theGrabMouseFlag = false;
}
else if(key == "hidecursor")
{
uInt32 option = atoi(value.c_str());
if(option == 1)
theHideCursorFlag = true;
else if(option == 0)
theHideCursorFlag = false;
}
else if(key == "center")
{
uInt32 option = atoi(value.c_str());
if(option == 1)
theCenterWindowFlag = true;
else if(option == 0)
theCenterWindowFlag = false;
}
else if(key == "showinfo")
{
uInt32 option = atoi(value.c_str());
if(option == 1)
theShowInfoFlag = true;
else if(option == 0)
theShowInfoFlag = false;
}
else if(key == "accurate")
{
uInt32 option = atoi(value.c_str());
if(option == 1)
theAccurateTimingFlag = true;
else if(option == 0)
theAccurateTimingFlag = false;
}
else if(key == "volume")
{
// They're setting the desired volume
Int32 volume = atoi(value.c_str());
if(volume < -1)
volume = -1;
else if(volume > 100)
volume = 100;
theDesiredVolume = volume;
}
else if(key == "sound")
{
if((value != "oss") && (value != "sdl") && (value != "alsa"))
value = "0";
theSoundDriver = value;
}
else if(key == "joyleft")
{
Int32 joynum = atoi(value.c_str());
if((joynum < 0) || (joynum >= StellaEvent::LastJSTICK))
cout << "Invalid left joystick.\n";
else
theLeftJoystickNumber = joynum;
}
else if(key == "joyright")
{
Int32 joynum = atoi(value.c_str());
if((joynum < 0) || (joynum >= StellaEvent::LastJSTICK))
cout << "Invalid right joystick.\n";
else
theRightJoystickNumber = joynum;
}
else
{
cout << "Undefined option " << key << endl;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string SettingsUNIX::getArguments()
{
ostringstream buf;
buf << "paddle = " << thePaddleMode << endl
<< "owncmap = " << theUsePrivateColormapFlag << endl
<< "fullscreen = " << theUseFullScreenFlag << endl
<< "grabmouse = " << theGrabMouseFlag << endl
<< "hidecursor = " << theHideCursorFlag << endl
<< "center = " << theCenterWindowFlag << endl
<< "showinfo = " << theShowInfoFlag << endl
<< "accurate = " << theAccurateTimingFlag << endl
<< "zoom = " << theZoomLevel << endl
<< "volume = " << theDesiredVolume << endl
<< "sound = " << theSoundDriver << endl
<< "joyleft = " << theLeftJoystickNumber << endl
<< "joyright = " << theRightJoystickNumber << endl;
return buf.str();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SettingsUNIX::usage(string& message)
{
@ -227,7 +87,7 @@ void SettingsUNIX::usage(string& message)
<< endl
<< "Valid options are:" << endl
<< endl
<< " -fps <number> Display the given number of frames per second\n"
<< " -framerate <number> Display the given number of frames per second\n"
<< " -zoom <size> Makes window be 'size' times normal\n"
<< " -owncmap <0|1> Install a private colormap\n"
<< " -fullscreen <0|1> Play the game in fullscreen mode\n"
@ -243,7 +103,7 @@ void SettingsUNIX::usage(string& message)
#else
<< " -paddle <0|1|2|3> Indicates which paddle the mouse should emulate\n"
#endif
<< " -pro <props file> Use the given properties file instead of stella.pro\n"
<< " -altpro <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 SNAPSHOT_SUPPORT
@ -268,7 +128,7 @@ void SettingsUNIX::usage(string& message)
<< " -Dwidth Sets \"Display.Width\"\n"
<< " -Dystart Sets \"Display.YStart\"\n"
<< " -Dheight Sets \"Display.Height\"\n"
<< " -Dmerge <0|1> Merge changed properties into properties file,\n"
<< " -mergeprops <0|1> Merge changed properties into properties file,\n"
<< " or save into a separate file\n"
#endif
<< endl;
@ -295,7 +155,8 @@ string SettingsUNIX::snapshotFilename()
return "";
string filename;
string path = theSnapshotDir;
string path = getString("ssdir");
string theSnapshotName = getString("ssname");
if(theSnapshotName == "romname")
path = path + "/" + myConsole->properties().get("Cartridge.Name");
@ -306,7 +167,7 @@ string SettingsUNIX::snapshotFilename()
replace(path.begin(), path.end(), ' ', '_');
// Check whether we want multiple snapshots created
if(theMultipleSnapshotFlag)
if(!getBool("sssingle"))
{
// Determine if the file already exists, checking each successive filename
// until one doesn't exist
@ -330,9 +191,3 @@ string SettingsUNIX::snapshotFilename()
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.3 2003-09-19 15:45:01 stephena Exp $
// $Id: SettingsUNIX.hxx,v 1.4 2003-09-23 00:58:31 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.3 2003-09-19 15:45:01 stephena Exp $
@version $Id: SettingsUNIX.hxx,v 1.4 2003-09-23 00:58:31 stephena Exp $
*/
class SettingsUNIX : public Settings
{
@ -44,21 +44,6 @@ class SettingsUNIX : public Settings
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.
@ -74,70 +59,12 @@ class SettingsUNIX : public Settings
*/
virtual string snapshotFilename();
public:
/**
Display the commandline settings for this UNIX version of Stella.
@param message A short message about this version of Stella
*/
void usage(string& message);
/**
Return the users UNIX home directory
@param message A short message about this version of Stella
*/
string userHomeDir();
public:
// Indicates whether to use fullscreen
bool theUseFullScreenFlag;
// Indicates whether mouse can leave the game window
bool theGrabMouseFlag;
// Indicates whether to center the game window
bool theCenterWindowFlag;
// Indicates whether to show some game info on program exit
bool theShowInfoFlag;
// Indicates whether to show cursor in the game window
bool theHideCursorFlag;
// Indicates whether to allocate colors from a private color map
bool theUsePrivateColormapFlag;
// Indicates whether to use more/less accurate emulation,
// resulting in more/less CPU usage.
bool theAccurateTimingFlag;
// Indicates what the desired volume is
Int32 theDesiredVolume;
// Indicate which paddle mode we're using:
// 0 - Mouse emulates paddle 0
// 1 - Mouse emulates paddle 1
// 2 - Mouse emulates paddle 2
// 3 - Mouse emulates paddle 3
// 4 - Use real Atari 2600 paddles
uInt32 thePaddleMode;
// An alternate properties file to use
string theAlternateProFile;
// Indicates which sound driver to use at run-time
string theSoundDriver;
// The left joystick number (0 .. StellaEvent::LastJSTICK)
Int32 theLeftJoystickNumber;
// The right joystick number (0 .. StellaEvent::LastJSTICK)
Int32 theRightJoystickNumber;
private:
// The UNIX home directory
string myHomeDir;
virtual void usage(string& message);
};
#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.51 2003-09-19 15:45:01 stephena Exp $
// $Id: mainSDL.cxx,v 1.52 2003-09-23 00:58:31 stephena Exp $
//============================================================================
#include <fstream>
@ -117,9 +117,7 @@ static Console* theConsole = (Console*) NULL;
static Sound* theSound = (Sound*) NULL;
// Pointer to the settings object or the null pointer
#ifdef UNIX
static SettingsUNIX* theSettings = (SettingsUNIX*) NULL;
#endif
static Settings* theSettings = (Settings*) NULL;
// Indicates if the mouse should be grabbed
static bool theGrabMouseIndicator = false;
@ -136,6 +134,12 @@ static bool isFullscreen = false;
// Indicates whether the window is currently centered
static bool isCentered = false;
// Indicates the current paddle mode
static Int32 thePaddleMode;
// Indicates whether to show information during program execution
static bool theShowInfoFlag;
struct Switches
{
SDLKey scanCode;
@ -290,8 +294,8 @@ bool setupDisplay()
x11Available = true;
sdlflags = SDL_SWSURFACE;
sdlflags |= theSettings->theUseFullScreenFlag ? SDL_FULLSCREEN : 0;
sdlflags |= theSettings->theUsePrivateColormapFlag ? SDL_HWPALETTE : 0;
sdlflags |= theConsole->settings().getBool("fullscreen") ? SDL_FULLSCREEN : 0;
sdlflags |= theConsole->settings().getBool("owncmap") ? SDL_HWPALETTE : 0;
// Get the desired width and height of the display
theWidth = theConsole->mediaSource().width();
@ -303,10 +307,10 @@ bool setupDisplay()
theMaxWindowSize = maxWindowSizeForScreen();
// Check to see if window size will fit in the screen
if(theSettings->theZoomLevel > theMaxWindowSize)
if((uInt32)theConsole->settings().getInt("zoom") > theMaxWindowSize)
theWindowSize = theMaxWindowSize;
else
theWindowSize = theSettings->theZoomLevel;
theWindowSize = theConsole->settings().getInt("zoom");
// Set up the rectangle list to be used in updateDisplay
rectList = new RectList();
@ -327,9 +331,9 @@ bool setupDisplay()
setupPalette();
// Make sure that theUseFullScreenFlag sets up fullscreen mode correctly
theGrabMouseIndicator = theSettings->theGrabMouseFlag;
theHideCursorIndicator = theSettings->theHideCursorFlag;
if(theSettings->theUseFullScreenFlag)
theGrabMouseIndicator = theConsole->settings().getBool("grabmouse");
theHideCursorIndicator = theConsole->settings().getBool("hidecursor");
if(theConsole->settings().getBool("fullscreen"))
{
grabMouse(true);
showCursor(false);
@ -345,7 +349,8 @@ bool setupDisplay()
}
// Center the window if centering is selected and not fullscreen
if(theSettings->theCenterWindowFlag && !theSettings->theUseFullScreenFlag)
if(theConsole->settings().getBool("center") &&
!theConsole->settings().getBool("fullscreen"))
centerWindow();
return true;
@ -362,35 +367,37 @@ bool setupJoystick()
// Initialize the joystick subsystem
if((SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) || (SDL_NumJoysticks() <= 0))
{
if(theSettings->theShowInfoFlag)
if(theShowInfoFlag)
cout << "No joysticks present, use the keyboard.\n";
theLeftJoystick = theRightJoystick = 0;
return true;
}
if((theLeftJoystick = SDL_JoystickOpen(theSettings->theLeftJoystickNumber)) != NULL)
theLeftJoystickNumber = (uInt32) theConsole->settings().getInt("joyleft");
if((theLeftJoystick = SDL_JoystickOpen(theLeftJoystickNumber)) != NULL)
{
if(theSettings->theShowInfoFlag)
if(theShowInfoFlag)
cout << "Left joystick is a "
<< SDL_JoystickName(theSettings->theLeftJoystickNumber)
<< SDL_JoystickName(theLeftJoystickNumber)
<< " with " << SDL_JoystickNumButtons(theLeftJoystick) << " buttons.\n";
}
else
{
if(theSettings->theShowInfoFlag)
if(theShowInfoFlag)
cout << "Left joystick not present, use keyboard instead.\n";
}
if((theRightJoystick = SDL_JoystickOpen(theSettings->theRightJoystickNumber)) != NULL)
theRightJoystickNumber = theConsole->settings().getInt("joyright");
if((theRightJoystick = SDL_JoystickOpen(theRightJoystickNumber)) != NULL)
{
if(theSettings->theShowInfoFlag)
if(theShowInfoFlag)
cout << "Right joystick is a "
<< SDL_JoystickName(theSettings->theRightJoystickNumber)
<< SDL_JoystickName(theRightJoystickNumber)
<< " with " << SDL_JoystickNumButtons(theRightJoystick) << " buttons.\n";
}
else
{
if(theSettings->theShowInfoFlag)
if(theShowInfoFlag)
cout << "Right joystick not present, use keyboard instead.\n";
}
#endif
@ -559,7 +566,7 @@ void resizeWindow(int mode)
// A resize may mean that the window is no longer centered
isCentered = false;
if(theSettings->theCenterWindowFlag)
if(theConsole->settings().getBool("center"))
centerWindow();
}
@ -603,9 +610,6 @@ void centerWindow()
*/
void toggleFullscreen()
{
int width = theWidth * theWindowSize * 2;
int height = theHeight * theWindowSize;
isFullscreen = !isFullscreen;
if(isFullscreen)
sdlflags |= SDL_FULLSCREEN;
@ -625,7 +629,7 @@ void toggleFullscreen()
grabMouse(theGrabMouseIndicator);
showCursor(!theHideCursorIndicator);
if(theSettings->theCenterWindowFlag)
if(theConsole->settings().getBool("center"))
centerWindow();
}
}
@ -823,7 +827,6 @@ void updateDisplay(MediaSource& mediaSource)
void handleEvents()
{
SDL_Event event;
Uint8 button;
Uint8 type;
SDLKey key;
SDLMod mod;
@ -918,13 +921,13 @@ void handleEvents()
}
else if((mod & KMOD_ALT) && key == SDLK_s) // Alt-s saves properties to a file
{
if(theSettings->theMergePropertiesFlag) // Attempt to merge with propertiesSet
if(theConsole->settings().getBool("mergeprops")) // Attempt to merge with propertiesSet
{
theConsole->saveProperties(theSettings->userPropertiesFilename(), true);
}
else // Save to file in home directory
{
string newPropertiesFile = theSettings->userHomeDir() + "/" + \
string newPropertiesFile = theConsole->settings().baseDir() + "/" + \
theConsole->properties().get("Cartridge.Name") + ".pro";
replace(newPropertiesFile.begin(), newPropertiesFile.end(), ' ', '_');
theConsole->saveProperties(newPropertiesFile);
@ -980,13 +983,13 @@ void handleEvents()
resistance = (Int32)((fudgeFactor * x) / width);
// Now, set the event of the correct paddle to the calculated resistance
if(theSettings->thePaddleMode == 0)
if(thePaddleMode == 0)
type = Event::PaddleZeroResistance;
else if(theSettings->thePaddleMode == 1)
else if(thePaddleMode == 1)
type = Event::PaddleOneResistance;
else if(theSettings->thePaddleMode == 2)
else if(thePaddleMode == 2)
type = Event::PaddleTwoResistance;
else if(theSettings->thePaddleMode == 3)
else if(thePaddleMode == 3)
type = Event::PaddleThreeResistance;
theConsole->eventHandler().sendEvent(type, resistance);
@ -1001,13 +1004,13 @@ void handleEvents()
else
value = 0;
if(theSettings->thePaddleMode == 0)
if(thePaddleMode == 0)
type = Event::PaddleZeroFire;
else if(theSettings->thePaddleMode == 1)
else if(thePaddleMode == 1)
type = Event::PaddleOneFire;
else if(theSettings->thePaddleMode == 2)
else if(thePaddleMode == 2)
type = Event::PaddleTwoFire;
else if(theSettings->thePaddleMode == 3)
else if(thePaddleMode == 3)
type = Event::PaddleThreeFire;
theConsole->eventHandler().sendEvent(type, value);
@ -1127,31 +1130,33 @@ uInt32 maxWindowSizeForScreen()
bool setupProperties(PropertiesSet& set)
{
bool useMemList = false;
string theAlternateProFile = theSettings->getString("altpro");
string theUserProFile = theSettings->userPropertiesFilename();
string theSystemProFile = theSettings->systemPropertiesFilename();
#ifdef DEVELOPER_SUPPORT
// If the user wishes to merge any property modifications to the
// PropertiesSet file, then the PropertiesSet file MUST be loaded
// into memory.
useMemList = theSettings->theMergePropertiesFlag;
useMemList = theSettings->getBool("mergeprops");
#endif
// Check to see if the user has specified an alternate .pro file.
if(theSettings->theAlternateProFile != "")
if(theAlternateProFile != "")
{
set.load(theSettings->theAlternateProFile, &Console::defaultProperties(), useMemList);
set.load(theAlternateProFile, &Console::defaultProperties(), useMemList);
return true;
}
if(theSettings->userPropertiesFilename() != "")
if(theUserProFile != "")
{
set.load(theSettings->userPropertiesFilename(),
&Console::defaultProperties(), useMemList);
set.load(theUserProFile, &Console::defaultProperties(), useMemList);
return true;
}
else if(theSettings->systemPropertiesFilename() != "")
else if(theSystemProFile != "")
{
set.load(theSettings->systemPropertiesFilename(),
&Console::defaultProperties(), useMemList);
set.load(theSystemProFile, &Console::defaultProperties(), useMemList);
return true;
}
else
@ -1215,6 +1220,10 @@ int main(int argc, char* argv[])
return 0;
}
// Cache some settings so they don't have to be repeatedly searched for
thePaddleMode = theSettings->getInt("paddle");
theShowInfoFlag = theSettings->getBool("showinfo");
// Get a pointer to the file which contains the cartridge ROM
const char* file = argv[argc - 1];
@ -1242,45 +1251,45 @@ int main(int argc, char* argv[])
}
// Create a sound object for playing audio
if(theSettings->theSoundDriver == "0")
string driver = theSettings->getString("sound");
if(driver == "0")
{
// even if sound has been disabled, we still need a sound object
theSound = new Sound();
if(theSettings->theShowInfoFlag)
if(theShowInfoFlag)
cout << "Sound disabled.\n";
}
#ifdef SOUND_ALSA
else if(theSettings->theSoundDriver == "alsa")
else if(driver == "alsa")
{
theSound = new SoundALSA();
if(theSettings->theShowInfoFlag)
if(theShowInfoFlag)
cout << "Using ALSA for sound.\n";
}
#endif
#ifdef SOUND_OSS
else if(theSettings->theSoundDriver == "oss")
else if(driver == "oss")
{
theSound = new SoundOSS();
if(theSettings->theShowInfoFlag)
if(theShowInfoFlag)
cout << "Using OSS for sound.\n";
}
#endif
#ifdef SOUND_SDL
else if(theSettings->theSoundDriver == "sdl")
else if(driver == "sdl")
{
theSound = new SoundSDL();
if(theSettings->theShowInfoFlag)
if(theShowInfoFlag)
cout << "Using SDL for sound.\n";
}
#endif
else // a driver that doesn't exist was requested, so disable sound
{
cerr << "ERROR: Sound support for "
<< theSettings->theSoundDriver << " not available.\n";
cerr << "ERROR: Sound support for " << driver << " not available.\n";
theSound = new Sound();
}
theSound->setSoundVolume(theSettings->theDesiredVolume);
theSound->setSoundVolume(theSettings->getInt("volume"));
// Get just the filename of the file containing the ROM image
const char* filename = (!strrchr(file, '/')) ? file : strrchr(file, '/') + 1;
@ -1310,11 +1319,11 @@ int main(int argc, char* argv[])
// and are needed to calculate the overall frames per second.
uInt32 frameTime = 0, numberOfFrames = 0;
if(theSettings->theAccurateTimingFlag) // normal, CPU-intensive timing
if(theSettings->getBool("accurate")) // normal, CPU-intensive timing
{
// Set up accurate timing stuff
uInt32 startTime, delta;
uInt32 timePerFrame = (uInt32)(1000000.0 / (double)theSettings->theDesiredFrameRate);
uInt32 timePerFrame = (uInt32)(1000000.0 / (double)theSettings->getInt("framerate"));
// Set the base for the timers
frameTime = 0;
@ -1359,7 +1368,7 @@ int main(int argc, char* argv[])
{
// Set up less accurate timing stuff
uInt32 startTime, virtualTime, currentTime;
uInt32 timePerFrame = (uInt32)(1000000.0 / (double)theSettings->theDesiredFrameRate);
uInt32 timePerFrame = (uInt32)(1000000.0 / (double)theSettings->getInt("framerate"));
// Set the base for the timers
virtualTime = getTicks();
@ -1396,7 +1405,7 @@ int main(int argc, char* argv[])
}
}
if(theSettings->theShowInfoFlag)
if(theShowInfoFlag)
{
double executionTime = (double) frameTime / 1000000.0;
double framesPerSecond = (double) numberOfFrames / executionTime;