Reworked properties file handling. The 'stella.pro' file is now assumed

to be a master file and is read-only.  When the user merges the
properties for a given ROM, they are now stored in 'user.pro'.  The
advantage of doing it this way is that users can get updated properties
from stella.pro with each release of Stella, and at the same time keep
any customized properties in their own user.pro file.  Merging is still
activated with 'Alt s' key combo, while saving the current properties
to a separate game-specific properties file is activated with 'Ctrl s'.

Fixed UNIX and Win32 ports for the above; the OSX and PSP ports need
to be fixed by the respective maintainers (a one-liner fix).

Fixed bug where changing audio settings from AudioDialog didn't
actually close/open the sound subsystem (and hence changes weren't
taking effect).


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@775 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2005-09-11 22:55:51 +00:00
parent 32f00975ad
commit 09a8f8f10d
13 changed files with 166 additions and 237 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: mainSDL.cxx,v 1.49 2005-08-25 15:19:17 stephena Exp $
// $Id: mainSDL.cxx,v 1.50 2005-09-11 22:55:51 stephena Exp $
//============================================================================
#include <fstream>
@ -72,23 +72,29 @@ OSystem* theOSystem = (OSystem*) NULL;
*/
void SetupProperties(PropertiesSet& set)
{
bool useMemList = true; // It seems we always need the list in memory
string theAltPropertiesFile = theOSystem->settings().getString("pro");
string thePropertiesFile = theOSystem->propertiesInputFilename();
// Several properties files can exist, so we attempt to load from
// all of them. If the user has specified a properties file, use
// that one. Otherwise, load both the system and user properties
// files, and have the user file override all entries from the
// system file.
stringstream buf;
if(theAltPropertiesFile != "")
ostringstream buf;
string altpro = theOSystem->settings().getString("pro");
if(altpro != "")
{
buf << "Game properties: \'" << theAltPropertiesFile << "\'\n";
set.load(theAltPropertiesFile, useMemList);
}
else if(thePropertiesFile != "")
{
buf << "Game properties: \'" << thePropertiesFile << "\'\n";
set.load(thePropertiesFile, useMemList);
buf << "Game properties: \'" << altpro << "\'\n";
set.load(altpro);
}
else
set.load("", false);
{
const string& sysPro = theOSystem->systemProperties();
const string& userPro = theOSystem->userProperties();
buf << "Game properties: \'" << sysPro << "\', \'" << userPro << "\'\n";
set.load(sysPro);
set.load(userPro);
}
if(theOSystem->settings().getBool("showinfo"))
cout << buf.str() << endl;

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.69 2005-09-06 19:42:35 stephena Exp $
// $Id: Console.cxx,v 1.70 2005-09-11 22:55:51 stephena Exp $
//============================================================================
#include <assert.h>
@ -333,7 +333,7 @@ void Console::saveProperties(string filename, bool merge)
if(myOSystem->propSet().merge(myProperties, filename))
myOSystem->frameBuffer().showMessage("Properties merged");
else
myOSystem->frameBuffer().showMessage("Properties not merged");
myOSystem->frameBuffer().showMessage("Error merging properties");
}
else // Save to the specified file directly
{
@ -347,7 +347,7 @@ void Console::saveProperties(string filename, bool merge)
}
else
{
myOSystem->frameBuffer().showMessage("Properties not saved");
myOSystem->frameBuffer().showMessage("Error saving properties");
}
}
}

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.94 2005-09-04 13:26:44 optixx Exp $
// $Id: EventHandler.cxx,v 1.95 2005-09-11 22:55:51 stephena Exp $
//============================================================================
#include <algorithm>
@ -385,8 +385,8 @@ void EventHandler::poll(uInt32 time)
myOSystem->console().enableBits(true);
break;
case SDLK_s: // Alt-s merges properties into stella.pro
myOSystem->console().saveProperties(myOSystem->propertiesOutputFilename(), true);
case SDLK_s: // Alt-s merges properties into user properties (user.pro)
myOSystem->console().saveProperties(myOSystem->userProperties(), true);
break;
}
}

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: OSystem.cxx,v 1.38 2005-09-11 15:44:51 stephena Exp $
// $Id: OSystem.cxx,v 1.39 2005-09-11 22:55:51 stephena Exp $
//============================================================================
#include <cassert>
@ -139,18 +139,12 @@ void OSystem::setStateDir(const string& statedir)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystem::setPropertiesFiles(const string& userprops,
const string& systemprops)
void OSystem::setPropertiesDir(const string& userpath,
const string& systempath)
{
// Set up the input and output properties files
myPropertiesOutputFile = userprops;
if(FilesystemNode::fileExists(userprops))
myPropertiesInputFile = userprops;
else if(FilesystemNode::fileExists(systemprops))
myPropertiesInputFile = systemprops;
else
myPropertiesInputFile = "";
myUserPropertiesFile = userpath + BSPF_PATH_SEPARATOR + "user.pro";
mySystemPropertiesFile = systempath + BSPF_PATH_SEPARATOR + "stella.pro";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

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: OSystem.hxx,v 1.28 2005-08-29 18:36:41 stephena Exp $
// $Id: OSystem.hxx,v 1.29 2005-09-11 22:55:51 stephena Exp $
//============================================================================
#ifndef OSYSTEM_HXX
@ -43,7 +43,7 @@ class Debugger;
other objects belong.
@author Stephen Anthony
@version $Id: OSystem.hxx,v 1.28 2005-08-29 18:36:41 stephena Exp $
@version $Id: OSystem.hxx,v 1.29 2005-09-11 22:55:51 stephena Exp $
*/
class OSystem
{
@ -195,19 +195,19 @@ class OSystem
/**
This method should be called to get the filename of the
properties (stella.pro) file for the purpose of loading.
system-wide properties file (stella.pro).
@return String representing the full path of the properties filename.
*/
const string& propertiesInputFilename() { return myPropertiesInputFile; }
const string& systemProperties() { return mySystemPropertiesFile; }
/**
This method should be called to get the filename of the
properties (stella.pro) file for the purpose of saving.
user-specific properties file (user.pro).
@return String representing the full path of the properties filename.
*/
const string& propertiesOutputFilename() { return myPropertiesOutputFile; }
const string& userProperties() { return myUserPropertiesFile; }
/**
This method should be called to get the filename of the config file
@ -325,7 +325,7 @@ class OSystem
/**
Set the locations of game properties files
*/
void setPropertiesFiles(const string& userprops, const string& systemprops);
void setPropertiesDir(const string& userpath, const string& systempath);
/**
Set the locations of config files
@ -381,8 +381,8 @@ class OSystem
string myBaseDir;
string myStateDir;
string myPropertiesInputFile;
string myPropertiesOutputFile;
string mySystemPropertiesFile;
string myUserPropertiesFile;
string myConfigInputFile;
string myConfigOutputFile;

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: PropsSet.cxx,v 1.11 2005-09-06 19:42:35 stephena Exp $
// $Id: PropsSet.cxx,v 1.12 2005-09-11 22:55:51 stephena Exp $
//============================================================================
#include <assert.h>
@ -23,11 +23,8 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertiesSet::PropertiesSet()
: myRoot(0),
mySize(0),
myUseMemList(true),
myPropertiesFilename(""),
mySaveOnExit(false)
: myRoot(NULL),
mySize(0)
{
myDefaultProperties = &defaultProperties();
}
@ -35,29 +32,14 @@ PropertiesSet::PropertiesSet()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertiesSet::~PropertiesSet()
{
if(myPropertiesStream.is_open())
myPropertiesStream.close();
if(myUseMemList && mySaveOnExit && (myPropertiesFilename != ""))
{
ofstream out(myPropertiesFilename.c_str());
if(out.is_open())
{
save(out);
out.close();
}
}
deleteNode(myRoot);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PropertiesSet::getMD5(string md5, Properties &properties)
void PropertiesSet::getMD5(const string& md5, Properties &properties)
{
bool found = false;
if(myUseMemList)
{
// Make sure tree isn't empty
if(myRoot == 0)
{
@ -90,37 +72,6 @@ void PropertiesSet::getMD5(string md5, Properties &properties)
properties = *(current->props);
else
properties = myDefaultProperties;
}
else
{
// Loop reading properties until required properties found
for(;;)
{
// Make sure the stream is still good or we're done
if(!myPropertiesStream)
{
break;
}
// Get the property list associated with this profile
Properties currentProperties(myDefaultProperties);
currentProperties.load(myPropertiesStream);
// If the stream is still good then insert the properties
if(myPropertiesStream)
{
string currentMd5 = currentProperties.get("Cartridge.MD5");
if(currentMd5 == md5)
{
properties = currentProperties;
return;
}
}
}
properties = myDefaultProperties;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -145,6 +96,7 @@ void PropertiesSet::insertNode(TreeNode* &t, const Properties& properties)
{
delete t->props;
t->props = new Properties(properties);
t->count++;
}
}
else
@ -153,6 +105,7 @@ void PropertiesSet::insertNode(TreeNode* &t, const Properties& properties)
t->props = new Properties(properties);
t->left = 0;
t->right = 0;
t->count = 1;
++mySize;
}
@ -171,37 +124,27 @@ void PropertiesSet::deleteNode(TreeNode *node)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PropertiesSet::load(string filename, bool useList)
void PropertiesSet::load(const string& filename)
{
myUseMemList = useList;
ifstream in(filename.c_str(), ios::in);
if(filename == "")
return;
myPropertiesStream.open(filename.c_str(), ios::in);
if(myUseMemList)
{
// Loop reading properties
for(;;)
{
// Make sure the stream is still good or we're done
if(!myPropertiesStream)
{
if(!in)
break;
}
// Get the property list associated with this profile
Properties properties(myDefaultProperties);
properties.load(myPropertiesStream);
properties.load(in);
// If the stream is still good then insert the properties
if(myPropertiesStream)
{
if(in)
insert(properties);
}
}
}
if(in)
in.close();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -222,6 +165,7 @@ void PropertiesSet::saveNode(ostream& out, TreeNode *node)
{
if(node)
{
if(node->count > 1)
node->props->save(out);
saveNode(out, node->left);
saveNode(out, node->right);
@ -246,18 +190,18 @@ uInt32 PropertiesSet::size() const
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool PropertiesSet::merge(Properties& properties, string& filename, bool saveOnExit)
bool PropertiesSet::merge(const Properties& properties, const string& filename)
{
myPropertiesFilename = filename;
mySaveOnExit = saveOnExit;
// Can't merge the properties if the PropertiesSet isn't in memory
if(!myUseMemList)
return false;
ofstream out(filename.c_str());
if(out.is_open())
{
insert(properties);
save(out);
out.close();
return true;
}
else
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -13,17 +13,15 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: PropsSet.hxx,v 1.7 2005-06-16 01:11:28 stephena Exp $
// $Id: PropsSet.hxx,v 1.8 2005-09-11 22:55:51 stephena Exp $
//============================================================================
#ifndef PROPERTIESSET_HXX
#define PROPERTIESSET_HXX
#ifndef PROPERTIES_SET_HXX
#define PROPERTIES_SET_HXX
#include <fstream>
#include <string>
#include "bspf.hxx"
#include "Props.hxx"
class Properties;
@ -51,23 +49,23 @@ class PropertiesSet
*/
virtual ~PropertiesSet();
public:
/**
Get the property from the set with the given MD5.
@param md5 The md5 of the property to get
@param properties The property with the given MD5, or
the default property if not found
@param properties The property with the given MD5, or the default
properties if not found
*/
void getMD5(string md5, Properties& properties);
void getMD5(const string& md5, Properties& properties);
/**
Load properties from the specified file. Use the given
defaults properties as the defaults for any properties loaded.
@param string The input file to use
@param useList Flag to indicate storing properties in memory (default true)
@param filename Full pathname of input file to use
*/
void load(string filename, bool useList = true);
void load(const string& filename);
/**
Save properties to the specified output stream
@ -92,21 +90,19 @@ class PropertiesSet
Merge the given properties into the collection.
@param properties The properties to merge
@param saveOnExit Whether to sync the PropertiesSet to disk on exit
@param filename Where the PropertiesSet should be saved
@param filename Full pathname of properties file to save
@return True on success, false on failure
Failure will occur if the PropertiesSet isn't currently in memory
Failure occurs if file couldn't be opened for writing
*/
bool merge(Properties& properties, string& filename, bool saveOnExit = true);
bool merge(const Properties& properties, const string& filename);
private:
struct TreeNode
{
Properties *props;
TreeNode *left;
TreeNode *right;
struct TreeNode {
Properties* props;
TreeNode* left;
TreeNode* right;
int count;
};
/**
@ -154,31 +150,18 @@ class PropertiesSet
*/
static const Properties& defaultProperties();
private:
// The root of the BST
TreeNode* myRoot;
// Default properties to use for properties objects
static Properties ourDefaultProperties;
// The default properties set
const Properties* myDefaultProperties;
// Property to use as the key
string myKey;
// The size of the properties bst (i.e. the number of properties in it)
uInt32 mySize;
// Whether to construct an in-memory list or rescan the file each time
bool myUseMemList;
// The default properties set
const Properties* myDefaultProperties;
// The file stream for the stella.pro file
ifstream myPropertiesStream;
// The filename where this PropertiesSet should be saved
string myPropertiesFilename;
// Whether or not to actually save the PropertiesSet on exit
bool mySaveOnExit;
// Default properties to use for properties objects
static Properties ourDefaultProperties;
};
#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: AudioDialog.cxx,v 1.15 2005-09-10 16:19:20 bwmott Exp $
// $Id: AudioDialog.cxx,v 1.16 2005-09-11 22:55:51 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -167,6 +167,7 @@ void AudioDialog::saveConfig()
// be a time-consuming operation
if(restart)
{
instance()->sound().close();
instance()->sound().initialize();
instance()->sound().mute(true);
}

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: PopUpWidget.cxx,v 1.16 2005-08-30 17:51:26 stephena Exp $
// $Id: PopUpWidget.cxx,v 1.17 2005-09-11 22:55:51 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -204,7 +204,9 @@ void PopUpDialog::setSelection(int item)
void PopUpDialog::sendSelection()
{
if(_popUpBoss->_cmd)
_popUpBoss->sendCommand(_popUpBoss->_cmd, _selection, _popUpBoss->_id);
_popUpBoss->sendCommand(_popUpBoss->_cmd,
_popUpBoss->_entries[_selection].tag,
_popUpBoss->_id);
// We remove the dialog when the user has selected an item
parent()->removeDialog();

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: PopUpWidget.hxx,v 1.7 2005-06-16 00:56:00 stephena Exp $
// $Id: PopUpWidget.hxx,v 1.8 2005-09-11 22:55:51 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project

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: OSystemMACOSX.cxx,v 1.4 2005-06-16 01:11:29 stephena Exp $
// $Id: OSystemMACOSX.cxx,v 1.5 2005-09-11 22:55:51 stephena Exp $
//============================================================================
#include <cstdlib>
@ -73,10 +73,12 @@ OSystemMACOSX::OSystemMACOSX()
string statedir = basedir + "/state";
setStateDir(statedir);
// FIXME - use setPropertiesDir() method
string userPropertiesFile = basedir + "/stella.pro";
strcat(parentdir,"/../../../stella.pro");
string systemPropertiesFile = parentdir;
setPropertiesFiles(userPropertiesFile, systemPropertiesFile);
////
string userConfigFile = basedir + "/stellarc";
string systemConfigFile = "/etc/stellarc";

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: OSystemUNIX.cxx,v 1.12 2005-06-16 01:11:29 stephena Exp $
// $Id: OSystemUNIX.cxx,v 1.13 2005-09-11 22:55:51 stephena Exp $
//============================================================================
#include <cstdlib>
@ -39,7 +39,7 @@
setBaseDir()
setStateDir()
setPropertiesFiles()
setPropertiesDir()
setConfigFiles()
setCacheFile()
@ -60,9 +60,7 @@ OSystemUNIX::OSystemUNIX()
string statedir = basedir + "/state";
setStateDir(statedir);
string userPropertiesFile = basedir + "/stella.pro";
string systemPropertiesFile = "/etc/stella.pro";
setPropertiesFiles(userPropertiesFile, systemPropertiesFile);
setPropertiesDir(basedir, "/etc");
string userConfigFile = basedir + "/stellarc";
string systemConfigFile = "/etc/stellarc";

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: OSystemWin32.cxx,v 1.6 2005-09-11 15:44:51 stephena Exp $
// $Id: OSystemWin32.cxx,v 1.7 2005-09-11 22:55:51 stephena Exp $
//============================================================================
#include <sstream>
@ -29,7 +29,7 @@
setBaseDir()
setStateDir()
setPropertiesFiles()
setPropertiesDir()
setConfigFiles()
setCacheFile()
@ -55,8 +55,7 @@ OSystemWin32::OSystemWin32()
string stateDir = basedir + "state\\";
setStateDir(stateDir);
string propsFile = basedir + "stella.pro";
setPropertiesFiles(propsFile, propsFile); // Input and output are the same
setPropertiesDir(basedir, basedir);
string configFile = basedir + "stella.ini";
setConfigFiles(configFile, configFile); // Input and output are the same