Reworked properties handling, resulting in less memory usage and greatly

improved speed.  The main stella.pro properties have been integrated
directly into Stella, so a properties file needn't be distributed with
the application any more.  Support still exists for a system-wide
stella.pro and a per-user user.pro; however, Stella will work fine without
them.

Greatly reduced memory usage in properties storage by moving to an
enum-based key system (so string descriptors for keys are no longer
being stored).  Eliminated parsing and construction of the internal
properties set by pre-parsing the data with a perl script (included
in the new 'src/tools' directory).  This pre-parser constructs
a balanced binary search AVL tree in array format, so in the worst
case, the BST only has to look through 12 entries.

Fixed some string constructor issues, hopefully fixing compile problems
with the WinCE port.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1016 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2006-03-05 01:18:42 +00:00
parent e6b236ef2e
commit a48670693a
24 changed files with 5230 additions and 624 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: TiaOutputWidget.cxx,v 1.9 2006-02-22 17:38:04 stephena Exp $
// $Id: TiaOutputWidget.cxx,v 1.10 2006-03-05 01:18:41 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -101,7 +101,7 @@ void TiaOutputWidget::handleMouseDown(int x, int y, int button, int clickCount)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
{
int ystart = atoi(instance()->console().properties().get("Display.YStart").c_str());
int ystart = atoi(instance()->console().properties().get(Display_YStart).c_str());
switch(cmd)
{

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: Cart.cxx,v 1.18 2005-12-23 20:48:50 stephena Exp $
// $Id: Cart.cxx,v 1.19 2006-03-05 01:18:41 stephena Exp $
//============================================================================
#include <assert.h>
@ -50,7 +50,7 @@ Cartridge* Cartridge::create(const uInt8* image, uInt32 size,
Cartridge* cartridge = 0;
// Get the type of the cartridge we're creating
string type = properties.get("Cartridge.Type", true);
string type = properties.get(Cartridge_Type);
// See if we should try to auto-detect the cartridge type
if(type == "AUTO-DETECT")
@ -117,120 +117,70 @@ Cartridge::~Cartridge()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string Cartridge::autodetectType(const uInt8* image, uInt32 size)
{
// The following is a simple table mapping games to type's using MD5 values
struct MD5ToType
{
const char* md5;
const char* type;
};
static MD5ToType table[] = {
{"5336f86f6b982cc925532f2e80aa1e17", "E0"}, // Death Star
{"b311ab95e85bc0162308390728a7361d", "E0"}, // Gyruss
{"c29f8db680990cb45ef7fef6ab57a2c2", "E0"}, // Super Cobra
{"085322bae40d904f53bdcc56df0593fc", "E0"}, // Tutankamn
{"c7f13ef38f61ee2367ada94fdcc6d206", "E0"}, // Popeye
{"6339d28c9a7f92054e70029eb0375837", "E0"}, // Star Wars, Arcade
{"27c6a2ca16ad7d814626ceea62fa8fb4", "E0"}, // Frogger II
{"3347a6dd59049b15a38394aa2dafa585", "E0"}, // Montezuma's Revenge
{"6dda84fb8e442ecf34241ac0d1d91d69", "F6SC"}, // Dig Dug
{"57fa2d09c9e361de7bd2aa3a9575a760", "F8SC"}, // Stargate
{"3a771876e4b61d42e3a3892ad885d889", "F8SC"}, // Defender ][
{"efefc02bbc5258815457f7a5b8d8750a", "FASC"}, // Tunnel runner
{"7e51a58de2c0db7d33715f518893b0db", "FASC"}, // Mountain King
{"9947f1ebabb56fd075a96c6d37351efa", "FASC"}, // Omega Race
{"0443cfa9872cdb49069186413275fa21", "E7"}, // Burger Timer
{"76f53abbbf39a0063f24036d6ee0968a", "E7"}, // Bump-N-Jump
{"3b76242691730b2dd22ec0ceab351bc6", "E7"}, // He-Man
{"ac7c2260378975614192ca2bc3d20e0b", "FE"}, // Decathlon
{"4f618c2429138e0280969193ed6c107e", "FE"}, // Robot Tank
{"6d842c96d5a01967be9680080dd5be54", "DPC"}, // Pitfall II
{"d3bb42228a6cd452c111c1932503cc03", "UA"}, // Funky Fish
{"8bbfd951c89cc09c148bfabdefa08bec", "UA"}, // Pleiades
{(char*)0, (char*)0}
};
// Get the MD5 message-digest for the ROM image
string md5 = MD5(image, size);
// Take a closer look at the ROM image and try to figure out its type
// Guess type based on size
const char* type = 0;
// First we'll see if it's type is listed in the table above
for(MD5ToType* entry = table; (entry->md5 != 0); ++entry)
if((size % 8448) == 0)
{
if(entry->md5 == md5)
{
type = entry->type;
break;
}
type = "AR";
}
// If we didn't find the type in the table then guess it based on size
if(type == 0)
else if((size == 2048) || (memcmp(image, image + 2048, 2048) == 0))
{
if((size % 8448) == 0)
{
type = "AR";
}
else if((size == 2048) || (memcmp(image, image + 2048, 2048) == 0))
{
type = "2K";
}
else if((size == 4096) || (memcmp(image, image + 4096, 4096) == 0))
{
type = "4K";
}
else if((size == 8192) || (memcmp(image, image + 8192, 8192) == 0))
{
type = isProbably3F(image, size) ? "3F" : "F8";
}
else if((size == 10495) || (size == 10240))
{
type = "DPC";
}
else if(size == 12288)
{
type = "FASC";
}
else if(size == 32768)
{
// Assume this is a 32K super-cart then check to see if it is
type = "F4SC";
type = "2K";
}
else if((size == 4096) || (memcmp(image, image + 4096, 4096) == 0))
{
type = "4K";
}
else if((size == 8192) || (memcmp(image, image + 8192, 8192) == 0))
{
type = isProbably3F(image, size) ? "3F" : "F8";
}
else if((size == 10495) || (size == 10240))
{
type = "DPC";
}
else if(size == 12288)
{
type = "FASC";
}
else if(size == 32768)
{
// Assume this is a 32K super-cart then check to see if it is
type = "F4SC";
uInt8 first = image[0];
for(uInt32 i = 0; i < 256; ++i)
uInt8 first = image[0];
for(uInt32 i = 0; i < 256; ++i)
{
if(image[i] != first)
{
if(image[i] != first)
{
// It's not a super cart (probably)
type = isProbably3F(image, size) ? "3F" : "F4";
break;
}
// It's not a super cart (probably)
type = isProbably3F(image, size) ? "3F" : "F4";
break;
}
}
else if(size == 65536)
{
type = isProbably3F(image, size) ? "3F" : "MB";
}
else if(size == 131072)
{
type = isProbably3F(image, size) ? "3F" : "MC";
}
else
{
// Assume this is a 16K super-cart then check to see if it is
type = "F6SC";
}
else if(size == 65536)
{
type = isProbably3F(image, size) ? "3F" : "MB";
}
else if(size == 131072)
{
type = isProbably3F(image, size) ? "3F" : "MC";
}
else
{
// Assume this is a 16K super-cart then check to see if it is
type = "F6SC";
uInt8 first = image[0];
for(uInt32 i = 0; i < 256; ++i)
uInt8 first = image[0];
for(uInt32 i = 0; i < 256; ++i)
{
if(image[i] != first)
{
if(image[i] != first)
{
// It's not a super cart (probably)
type = isProbably3F(image, size) ? "3F" : "F6";
break;
}
// It's not a super cart (probably)
type = isProbably3F(image, size) ? "3F" : "F6";
break;
}
}
}
@ -289,31 +239,37 @@ Cartridge& Cartridge::operator = (const Cartridge&)
// doesn't support bankswitching at all.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge::bank(uInt16 b) {
void Cartridge::bank(uInt16 b)
{
// do nothing.
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Cartridge::bank() {
int Cartridge::bank()
{
return 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Cartridge::bankCount() {
int Cartridge::bankCount()
{
return 1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Cartridge::patch(uInt16 address, uInt8 value) {
bool Cartridge::patch(uInt16 address, uInt8 value)
{
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Cartridge::save(ofstream& out) {
bool Cartridge::save(ofstream& out)
{
int size = -1;
uInt8* image = getImage(size);
if(image == 0 || size <= 0) {
if(image == 0 || size <= 0)
{
cerr << "save not supported" << endl;
return false;
}
@ -325,8 +281,8 @@ bool Cartridge::save(ofstream& out) {
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8* Cartridge::getImage(int& size) {
uInt8* Cartridge::getImage(int& size)
{
size = 0;
return 0;
}

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.83 2006-02-05 02:49:47 stephena Exp $
// $Id: Console.cxx,v 1.84 2006-03-05 01:18:41 stephena Exp $
//============================================================================
#include <assert.h>
@ -83,19 +83,19 @@ Console::Console(const uInt8* image, uInt32 size, const string& md5,
setDeveloperProperties();
// Make sure height is set properly for PAL ROM
if(myProperties.get("Display.Format", true) == "PAL")
if(myProperties.get("Display.Height") == "210")
myProperties.set("Display.Height", "250");
if(myProperties.get(Display_Format) == "PAL")
if(myProperties.get(Display_Height) == "210")
myProperties.set(Display_Height, "250");
// Setup the controllers based on properties
string left = myProperties.get("Controller.Left", true);
string right = myProperties.get("Controller.Right", true);
string left = myProperties.get(Controller_Left);
string right = myProperties.get(Controller_Right);
// Swap the ports if necessary
// Note that this doesn't swap the actual controllers,
// just the ports that they're attached to
Controller::Jack leftjack, rightjack;
if(myProperties.get("Console.SwapPorts", true) == "NO")
if(myProperties.get(Console_SwapPorts) == "NO")
{
leftjack = Controller::Left;
rightjack = Controller::Right;
@ -192,7 +192,7 @@ Console::Console(const uInt8* image, uInt32 size, const string& md5,
uInt32 framerate = myOSystem->settings().getInt("framerate");
if(framerate == 0)
{
string s = myProperties.get("Display.Format", true);
const string& s = myProperties.get(Display_Format);
if(s == "NTSC")
framerate = 60;
else if(s == "PAL")
@ -210,7 +210,7 @@ Console::Console(const uInt8* image, uInt32 size, const string& md5,
// The # of channels can be overridden in the AudioDialog box or on
// the commandline, but it can't be saved.
uInt32 channels;
string s = myProperties.get("Cartridge.Sound", true);
const string& s = myProperties.get(Cartridge_Sound);
if(s == "STEREO")
channels = 2;
else if(s == "MONO")
@ -252,7 +252,7 @@ Console::Console(const Console& console)
Console::~Console()
{
#ifdef CHEATCODE_SUPPORT
myOSystem->cheat().saveCheats(myProperties.get("Cartridge.MD5"));
myOSystem->cheat().saveCheats(myProperties.get(Cartridge_MD5));
#endif
delete mySystem;
@ -279,19 +279,19 @@ Console& Console::operator = (const Console&)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::toggleFormat()
{
string format = myProperties.get("Display.Format", true);
const string& format = myProperties.get(Display_Format);
uInt32 framerate = 60;
if(format == "NTSC")
{
myProperties.set("Display.Format", "PAL");
myProperties.set(Display_Format, "PAL");
mySystem->reset();
myOSystem->frameBuffer().showMessage("PAL Mode");
framerate = 50;
}
else if(format == "PAL")
{
myProperties.set("Display.Format", "NTSC");
myProperties.set(Display_Format, "NTSC");
mySystem->reset();
myOSystem->frameBuffer().showMessage("NTSC Mode");
framerate = 60;
@ -354,17 +354,17 @@ void Console::togglePalette(const string& palette)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::togglePhosphor()
{
string phosphor = myProperties.get("Display.Phosphor", true);
const string& phosphor = myProperties.get(Display_Phosphor);
bool enable;
if(phosphor == "YES")
{
myProperties.set("Display.Phosphor", "No");
myProperties.set(Display_Phosphor, "No");
enable = false;
myOSystem->frameBuffer().showMessage("Phosphor effect disabled");
}
else
{
myProperties.set("Display.Phosphor", "Yes");
myProperties.set(Display_Phosphor, "Yes");
enable = true;
myOSystem->frameBuffer().showMessage("Phosphor effect enabled");
}
@ -405,11 +405,11 @@ void Console::saveProperties(string filename, bool merge)
void Console::initializeVideo()
{
string title = string("Stella ") + STELLA_VERSION +
": \"" + myProperties.get("Cartridge.Name") + "\"";
": \"" + myProperties.get(Cartridge_Name) + "\"";
myOSystem->frameBuffer().initialize(title,
myMediaSource->width() << 1,
myMediaSource->height());
bool enable = myProperties.get("Display.Phosphor", true) == "YES";
bool enable = myProperties.get(Display_Phosphor) == "YES";
myOSystem->frameBuffer().enablePhosphor(enable);
setPalette();
}
@ -433,7 +433,7 @@ void Console::setChannels(int channels)
// Save to properties
string sound = channels == 2 ? "Stereo" : "Mono";
myProperties.set("Cartridge.Sound", sound);
myProperties.set(Cartridge_Sound, sound);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -465,8 +465,8 @@ void Console::fry()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::changeXStart(const uInt32 direction)
{
Int32 xstart = atoi(myProperties.get("Display.XStart").c_str());
uInt32 width = atoi(myProperties.get("Display.Width").c_str());
Int32 xstart = atoi(myProperties.get(Display_XStart).c_str());
uInt32 width = atoi(myProperties.get(Display_Width).c_str());
ostringstream strval;
string message;
@ -495,7 +495,7 @@ void Console::changeXStart(const uInt32 direction)
}
strval << xstart;
myProperties.set("Display.XStart", strval.str());
myProperties.set(Display_XStart, strval.str());
mySystem->reset();
initializeVideo();
@ -507,7 +507,7 @@ void Console::changeXStart(const uInt32 direction)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::changeYStart(const uInt32 direction)
{
Int32 ystart = atoi(myProperties.get("Display.YStart").c_str());
Int32 ystart = atoi(myProperties.get(Display_YStart).c_str());
ostringstream strval;
string message;
@ -531,7 +531,7 @@ void Console::changeYStart(const uInt32 direction)
}
strval << ystart;
myProperties.set("Display.YStart", strval.str());
myProperties.set(Display_YStart, strval.str());
mySystem->reset();
initializeVideo();
@ -543,8 +543,8 @@ void Console::changeYStart(const uInt32 direction)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::changeWidth(const uInt32 direction)
{
uInt32 xstart = atoi(myProperties.get("Display.XStart").c_str());
Int32 width = atoi(myProperties.get("Display.Width").c_str());
uInt32 xstart = atoi(myProperties.get(Display_XStart).c_str());
Int32 width = atoi(myProperties.get(Display_Width).c_str());
ostringstream strval;
string message;
@ -573,7 +573,7 @@ void Console::changeWidth(const uInt32 direction)
}
strval << width;
myProperties.set("Display.Width", strval.str());
myProperties.set(Display_Width, strval.str());
mySystem->reset();
initializeVideo();
@ -585,7 +585,7 @@ void Console::changeWidth(const uInt32 direction)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::changeHeight(const uInt32 direction)
{
Int32 height = atoi(myProperties.get("Display.Height").c_str());
Int32 height = atoi(myProperties.get(Display_Height).c_str());
ostringstream strval;
string message;
@ -609,7 +609,7 @@ void Console::changeHeight(const uInt32 direction)
}
strval << height;
myProperties.set("Display.Height", strval.str());
myProperties.set(Display_Height, strval.str());
mySystem->reset();
initializeVideo();
@ -642,64 +642,64 @@ void Console::setDeveloperProperties()
s = settings.getString("type");
if(s != "")
myProperties.set("Cartridge.Type", s);
myProperties.set(Cartridge_Type, s);
s = settings.getString("ld");
if(s != "")
myProperties.set("Console.LeftDifficulty", s);
myProperties.set(Console_LeftDifficulty, s);
s = settings.getString("rd");
if(s != "")
myProperties.set("Console.RightDifficulty", s);
myProperties.set(Console_RightDifficulty, s);
s = settings.getString("tv");
if(s != "")
myProperties.set("Console.TelevisionType", s);
myProperties.set(Console_TelevisionType, s);
s = settings.getString("sp");
if(s != "")
myProperties.set("Console.SwapPorts", s);
myProperties.set(Console_SwapPorts, s);
s = settings.getString("lc");
if(s != "")
myProperties.set("Controller.Left", s);
myProperties.set(Controller_Left, s);
s = settings.getString("rc");
if(s != "")
myProperties.set("Controller.Right", s);
myProperties.set(Controller_Right, s);
s = settings.getString("bc");
if(s != "")
{
myProperties.set("Controller.Left", s);
myProperties.set("Controller.Right", s);
myProperties.set(Controller_Left, s);
myProperties.set(Controller_Right, s);
}
s = settings.getString("format");
if(s != "")
myProperties.set("Display.Format", s);
myProperties.set(Display_Format, s);
s = settings.getString("xstart");
if(s != "")
myProperties.set("Display.XStart", s);
myProperties.set(Display_XStart, s);
s = settings.getString("ystart");
if(s != "")
myProperties.set("Display.YStart", s);
myProperties.set(Display_YStart, s);
s = settings.getString("width");
if(s != "")
myProperties.set("Display.Width", s);
myProperties.set(Display_Width, s);
s = settings.getString("height");
if(s != "")
myProperties.set("Display.Height", s);
myProperties.set(Display_Height, s);
s = settings.getString("pp");
if(s != "")
myProperties.set("Display.Phosphor", s);
myProperties.set(Display_Phosphor, s);
s = settings.getString("hmove");
if(s != "")
myProperties.set("Emulation.HmoveBlanks", s);
myProperties.set(Emulation_HmoveBlanks, s);
}

File diff suppressed because it is too large Load Diff

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.151 2006-03-02 13:10:53 stephena Exp $
// $Id: EventHandler.cxx,v 1.152 2006-03-05 01:18:42 stephena Exp $
//============================================================================
#include <sstream>
@ -403,7 +403,7 @@ void EventHandler::poll(uInt32 time)
break;
case SDLK_RIGHTBRACKET:
myOSystem->sound().adjustVolume(1);
myOSystem->sound().adjustVolume(+1);
break;
case SDLK_END: // Alt-End increases XStart
@ -584,7 +584,7 @@ void EventHandler::poll(uInt32 time)
case SDLK_s: // Ctrl-s saves properties to a file
string newPropertiesFile = myOSystem->baseDir() + BSPF_PATH_SEPARATOR +
myOSystem->console().properties().get("Cartridge.Name") + ".pro";
myOSystem->console().properties().get(Cartridge_Name) + ".pro";
myOSystem->console().saveProperties(newPropertiesFile);
break;
}
@ -1272,7 +1272,9 @@ void EventHandler::setActionMappings()
for(i = 0; i < kActionListSize; ++i)
{
Event::Type event = ourActionList[i].event;
ourActionList[i].key = "None";
if(ourActionList[i].key)
free(ourActionList[i].key);
ourActionList[i].key = strdup("None");
string key = "";
for(j = 0; j < SDLK_LAST; ++j) // key mapping
{
@ -1374,7 +1376,11 @@ void EventHandler::setActionMappings()
key = prepend + ", " + key;
if(key != "")
ourActionList[i].key = key;
{
if(ourActionList[i].key)
free(ourActionList[i].key);
ourActionList[i].key = strdup(key.c_str());
}
}
}
@ -1833,7 +1839,7 @@ inline bool EventHandler::eventIsAnalog(Event::Type event)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::saveState()
{
string md5 = myOSystem->console().properties().get("Cartridge.MD5");
string md5 = myOSystem->console().properties().get(Cartridge_MD5);
ostringstream buf;
buf << myOSystem->stateDir() << BSPF_PATH_SEPARATOR << md5 << ".st" << myLSState;
@ -1878,7 +1884,7 @@ void EventHandler::changeState()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::loadState()
{
string md5 = myOSystem->console().properties().get("Cartridge.MD5");
string md5 = myOSystem->console().properties().get(Cartridge_MD5);
ostringstream buf;
buf << myOSystem->stateDir() << BSPF_PATH_SEPARATOR << md5 << ".st" << myLSState;
@ -1928,9 +1934,9 @@ void EventHandler::takeSnapshot()
sspath += BSPF_PATH_SEPARATOR;
if(ssname == "romname")
sspath += myOSystem->console().properties().get("Cartridge.Name");
sspath += myOSystem->console().properties().get(Cartridge_Name);
else if(ssname == "md5sum")
sspath += myOSystem->console().properties().get("Cartridge.MD5");
sspath += myOSystem->console().properties().get(Cartridge_MD5);
// Check whether we want multiple snapshots created
if(!myOSystem->settings().getBool("sssingle"))
@ -2354,106 +2360,101 @@ void EventHandler::setSDLMappings()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// FIXME - this must be handled better in the future ///
#ifndef _WIN32_WCE
ActionList EventHandler::ourActionList[kActionListSize] = {
{ Event::ConsoleSelect, "Select", "" },
{ Event::ConsoleReset, "Reset", "" },
{ Event::ConsoleColor, "Color TV", "" },
{ Event::ConsoleBlackWhite, "Black & White TV", "" },
{ Event::ConsoleLeftDifficultyA, "P1 Difficulty A", "" },
{ Event::ConsoleLeftDifficultyB, "P1 Difficulty B", "" },
{ Event::ConsoleRightDifficultyA, "P2 Difficulty A", "" },
{ Event::ConsoleRightDifficultyB, "P2 Difficulty B", "" },
{ Event::SaveState, "Save State", "" },
{ Event::ChangeState, "Change State", "" },
{ Event::LoadState, "Load State", "" },
{ Event::TakeSnapshot, "Snapshot", "" },
{ Event::Pause, "Pause", "" },
{ Event::Fry, "Fry cartridge", "" },
{ Event::VolumeDecrease, "Decrease volume", "" },
{ Event::VolumeIncrease, "Increase volume", "" },
{ Event::MenuMode, "Toggle options menu mode", "" },
{ Event::CmdMenuMode, "Toggle command menu mode", "" },
{ Event::DebuggerMode, "Toggle debugger mode", "" },
{ Event::LauncherMode, "Enter ROM launcher", "" },
{ Event::Quit, "Quit", "" },
{ Event::ConsoleSelect, "Select", 0 },
{ Event::ConsoleReset, "Reset", 0 },
{ Event::ConsoleColor, "Color TV", 0 },
{ Event::ConsoleBlackWhite, "Black & White TV", 0 },
{ Event::ConsoleLeftDifficultyA, "P1 Difficulty A", 0 },
{ Event::ConsoleLeftDifficultyB, "P1 Difficulty B", 0 },
{ Event::ConsoleRightDifficultyA, "P2 Difficulty A", 0 },
{ Event::ConsoleRightDifficultyB, "P2 Difficulty B", 0 },
{ Event::SaveState, "Save State", 0 },
{ Event::ChangeState, "Change State", 0 },
{ Event::LoadState, "Load State", 0 },
{ Event::TakeSnapshot, "Snapshot", 0 },
{ Event::Pause, "Pause", 0 },
{ Event::Fry, "Fry cartridge", 0 },
{ Event::VolumeDecrease, "Decrease volume", 0 },
{ Event::VolumeIncrease, "Increase volume", 0 },
{ Event::MenuMode, "Toggle options menu mode", 0 },
{ Event::CmdMenuMode, "Toggle command menu mode", 0 },
{ Event::DebuggerMode, "Toggle debugger mode", 0 },
{ Event::LauncherMode, "Enter ROM launcher", 0 },
{ Event::Quit, "Quit", 0 },
{ Event::JoystickZeroUp, "P1 Joystick Up", "" },
{ Event::JoystickZeroDown, "P1 Joystick Down", "" },
{ Event::JoystickZeroLeft, "P1 Joystick Left", "" },
{ Event::JoystickZeroRight, "P1 Joystick Right", "" },
{ Event::JoystickZeroFire, "P1 Joystick Fire", "" },
{ Event::JoystickZeroUp, "P1 Joystick Up", 0 },
{ Event::JoystickZeroDown, "P1 Joystick Down", 0 },
{ Event::JoystickZeroLeft, "P1 Joystick Left", 0 },
{ Event::JoystickZeroRight, "P1 Joystick Right", 0 },
{ Event::JoystickZeroFire, "P1 Joystick Fire", 0 },
{ Event::JoystickOneUp, "P2 Joystick Up", "" },
{ Event::JoystickOneDown, "P2 Joystick Down", "" },
{ Event::JoystickOneLeft, "P2 Joystick Left", "" },
{ Event::JoystickOneRight, "P2 Joystick Right", "" },
{ Event::JoystickOneFire, "P2 Joystick Fire", "" },
{ Event::JoystickOneUp, "P2 Joystick Up", 0 },
{ Event::JoystickOneDown, "P2 Joystick Down", 0 },
{ Event::JoystickOneLeft, "P2 Joystick Left", 0 },
{ Event::JoystickOneRight, "P2 Joystick Right", 0 },
{ Event::JoystickOneFire, "P2 Joystick Fire", 0 },
{ Event::PaddleZeroAnalog, "Paddle 1 Analog", "" },
{ Event::PaddleZeroDecrease, "Paddle 1 Decrease", "" },
{ Event::PaddleZeroIncrease, "Paddle 1 Increase", "" },
{ Event::PaddleZeroFire, "Paddle 1 Fire", "" },
{ Event::PaddleZeroAnalog, "Paddle 1 Analog", 0 },
{ Event::PaddleZeroDecrease, "Paddle 1 Decrease", 0 },
{ Event::PaddleZeroIncrease, "Paddle 1 Increase", 0 },
{ Event::PaddleZeroFire, "Paddle 1 Fire", 0 },
{ Event::PaddleOneAnalog, "Paddle 2 Analog", "" },
{ Event::PaddleOneDecrease, "Paddle 2 Decrease", "" },
{ Event::PaddleOneIncrease, "Paddle 2 Increase", "" },
{ Event::PaddleOneFire, "Paddle 2 Fire", "" },
{ Event::PaddleOneAnalog, "Paddle 2 Analog", 0 },
{ Event::PaddleOneDecrease, "Paddle 2 Decrease", 0 },
{ Event::PaddleOneIncrease, "Paddle 2 Increase", 0 },
{ Event::PaddleOneFire, "Paddle 2 Fire", 0 },
{ Event::PaddleTwoAnalog, "Paddle 3 Analog", "" },
{ Event::PaddleTwoDecrease, "Paddle 3 Decrease", "" },
{ Event::PaddleTwoIncrease, "Paddle 3 Increase", "" },
{ Event::PaddleTwoFire, "Paddle 3 Fire", "" },
{ Event::PaddleTwoAnalog, "Paddle 3 Analog", 0 },
{ Event::PaddleTwoDecrease, "Paddle 3 Decrease", 0 },
{ Event::PaddleTwoIncrease, "Paddle 3 Increase", 0 },
{ Event::PaddleTwoFire, "Paddle 3 Fire", 0 },
{ Event::PaddleThreeAnalog, "Paddle 4 Analog", "" },
{ Event::PaddleThreeDecrease, "Paddle 4 Decrease", "" },
{ Event::PaddleThreeIncrease, "Paddle 4 Increase", "" },
{ Event::PaddleThreeFire, "Paddle 4 Fire", "" },
{ Event::PaddleThreeAnalog, "Paddle 4 Analog", 0 },
{ Event::PaddleThreeDecrease, "Paddle 4 Decrease", 0 },
{ Event::PaddleThreeIncrease, "Paddle 4 Increase", 0 },
{ Event::PaddleThreeFire, "Paddle 4 Fire", 0 },
{ Event::BoosterGripZeroTrigger, "P1 Booster-Grip Trigger", "" },
{ Event::BoosterGripZeroBooster, "P1 Booster-Grip Booster", "" },
{ Event::BoosterGripZeroTrigger, "P1 Booster-Grip Trigger", 0 },
{ Event::BoosterGripZeroBooster, "P1 Booster-Grip Booster", 0 },
{ Event::BoosterGripOneTrigger, "P2 Booster-Grip Trigger", "" },
{ Event::BoosterGripOneBooster, "P2 Booster-Grip Booster", "" },
{ Event::BoosterGripOneTrigger, "P2 Booster-Grip Trigger", 0 },
{ Event::BoosterGripOneBooster, "P2 Booster-Grip Booster", 0 },
{ Event::DrivingZeroCounterClockwise, "P1 Driving Controller Left", "" },
{ Event::DrivingZeroClockwise, "P1 Driving Controller Right", "" },
{ Event::DrivingZeroFire, "P1 Driving Controller Fire", "" },
{ Event::DrivingZeroCounterClockwise, "P1 Driving Controller Left", 0 },
{ Event::DrivingZeroClockwise, "P1 Driving Controller Right", 0 },
{ Event::DrivingZeroFire, "P1 Driving Controller Fire", 0 },
{ Event::DrivingOneCounterClockwise, "P2 Driving Controller Left", "" },
{ Event::DrivingOneClockwise, "P2 Driving Controller Right", "" },
{ Event::DrivingOneFire, "P2 Driving Controller Fire", "" },
{ Event::DrivingOneCounterClockwise, "P2 Driving Controller Left", 0 },
{ Event::DrivingOneClockwise, "P2 Driving Controller Right", 0 },
{ Event::DrivingOneFire, "P2 Driving Controller Fire", 0 },
{ Event::KeyboardZero1, "P1 Keyboard 1", "" },
{ Event::KeyboardZero2, "P1 Keyboard 2", "" },
{ Event::KeyboardZero3, "P1 Keyboard 3", "" },
{ Event::KeyboardZero4, "P1 Keyboard 4", "" },
{ Event::KeyboardZero5, "P1 Keyboard 5", "" },
{ Event::KeyboardZero6, "P1 Keyboard 6", "" },
{ Event::KeyboardZero7, "P1 Keyboard 7", "" },
{ Event::KeyboardZero8, "P1 Keyboard 8", "" },
{ Event::KeyboardZero9, "P1 Keyboard 9", "" },
{ Event::KeyboardZeroStar, "P1 Keyboard *", "" },
{ Event::KeyboardZero0, "P1 Keyboard 0", "" },
{ Event::KeyboardZeroPound, "P1 Keyboard #", "" },
{ Event::KeyboardZero1, "P1 Keyboard 1", 0 },
{ Event::KeyboardZero2, "P1 Keyboard 2", 0 },
{ Event::KeyboardZero3, "P1 Keyboard 3", 0 },
{ Event::KeyboardZero4, "P1 Keyboard 4", 0 },
{ Event::KeyboardZero5, "P1 Keyboard 5", 0 },
{ Event::KeyboardZero6, "P1 Keyboard 6", 0 },
{ Event::KeyboardZero7, "P1 Keyboard 7", 0 },
{ Event::KeyboardZero8, "P1 Keyboard 8", 0 },
{ Event::KeyboardZero9, "P1 Keyboard 9", 0 },
{ Event::KeyboardZeroStar, "P1 Keyboard *", 0 },
{ Event::KeyboardZero0, "P1 Keyboard 0", 0 },
{ Event::KeyboardZeroPound, "P1 Keyboard #", 0 },
{ Event::KeyboardOne1, "P2 Keyboard 1", "" },
{ Event::KeyboardOne2, "P2 Keyboard 2", "" },
{ Event::KeyboardOne3, "P2 Keyboard 3", "" },
{ Event::KeyboardOne4, "P2 Keyboard 4", "" },
{ Event::KeyboardOne5, "P2 Keyboard 5", "" },
{ Event::KeyboardOne6, "P2 Keyboard 6", "" },
{ Event::KeyboardOne7, "P2 Keyboard 7", "" },
{ Event::KeyboardOne8, "P2 Keyboard 8", "" },
{ Event::KeyboardOne9, "P2 Keyboard 9", "" },
{ Event::KeyboardOneStar, "P2 Keyboard *", "" },
{ Event::KeyboardOne0, "P2 Keyboard 0", "" },
{ Event::KeyboardOnePound, "P2 Keyboard #", "" }
{ Event::KeyboardOne1, "P2 Keyboard 1", 0 },
{ Event::KeyboardOne2, "P2 Keyboard 2", 0 },
{ Event::KeyboardOne3, "P2 Keyboard 3", 0 },
{ Event::KeyboardOne4, "P2 Keyboard 4", 0 },
{ Event::KeyboardOne5, "P2 Keyboard 5", 0 },
{ Event::KeyboardOne6, "P2 Keyboard 6", 0 },
{ Event::KeyboardOne7, "P2 Keyboard 7", 0 },
{ Event::KeyboardOne8, "P2 Keyboard 8", 0 },
{ Event::KeyboardOne9, "P2 Keyboard 9", 0 },
{ Event::KeyboardOneStar, "P2 Keyboard *", 0 },
{ Event::KeyboardOne0, "P2 Keyboard 0", 0 },
{ Event::KeyboardOnePound, "P2 Keyboard #", 0 }
};
#else
ActionList EventHandler::ourActionList[kActionListSize];
#endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const Event::Type EventHandler::Paddle_Resistance[4] = {

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.hxx,v 1.79 2006-03-02 13:10:53 stephena Exp $
// $Id: EventHandler.hxx,v 1.80 2006-03-05 01:18:42 stephena Exp $
//============================================================================
#ifndef EVENTHANDLER_HXX
@ -56,8 +56,8 @@ enum MouseButton {
// Structure used for action menu items
struct ActionList {
Event::Type event;
string action;
string key;
const char* action;
char* key;
};
enum {
@ -107,7 +107,7 @@ struct JoyMouse {
mapping can take place.
@author Stephen Anthony
@version $Id: EventHandler.hxx,v 1.79 2006-03-02 13:10:53 stephena Exp $
@version $Id: EventHandler.hxx,v 1.80 2006-03-05 01:18:42 stephena Exp $
*/
class EventHandler
{

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: EventStreamer.cxx,v 1.5 2006-01-08 02:28:03 stephena Exp $
// $Id: EventStreamer.cxx,v 1.6 2006-03-05 01:18:42 stephena Exp $
//============================================================================
#include "bspf.hxx"
@ -62,7 +62,7 @@ bool EventStreamer::startRecording()
return false;
// And save the current state to it
string md5 = myOSystem->console().properties().get("Cartridge.MD5");
string md5 = myOSystem->console().properties().get(Cartridge_MD5);
if(!myOSystem->console().system().saveState(md5, myStreamWriter))
return false;
myEventHistory.clear();
@ -111,7 +111,7 @@ cerr << "EventStreamer::loadRecording()\n";
return false;
// Load ROM state
string md5 = myOSystem->console().properties().get("Cartridge.MD5");
string md5 = myOSystem->console().properties().get(Cartridge_MD5);
if(!myOSystem->console().system().loadState(md5, myStreamReader))
return false;

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: FrameBuffer.cxx,v 1.77 2006-01-20 13:45:45 stephena Exp $
// $Id: FrameBuffer.cxx,v 1.78 2006-03-05 01:18:42 stephena Exp $
//============================================================================
#include <sstream>
@ -132,7 +132,7 @@ void FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height,
#ifdef DEVELOPER_SUPPORT
if(&myOSystem->console())
{
enablePhosphor(myOSystem->console().properties().get("Display.Phosphor", true) == "YES");
enablePhosphor(myOSystem->console().properties().get(Display_Phosphor) == "YES");
setPalette(myOSystem->console().mediaSource().palette());
}
#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: OSystem.cxx,v 1.62 2006-03-02 13:10:53 stephena Exp $
// $Id: OSystem.cxx,v 1.63 2006-03-05 01:18:42 stephena Exp $
//============================================================================
#include <cassert>
@ -442,7 +442,7 @@ bool OSystem::openROM(const string& rom, string& md5, uInt8** image, int* size)
Properties props;
myPropSet->getMD5(md5, props);
string name = props.get("Cartridge.Name");
string name = props.get(Cartridge_Name);
if(name == "Untitled")
{
// Get the filename from the rom pathname
@ -450,8 +450,8 @@ bool OSystem::openROM(const string& rom, string& md5, uInt8** image, int* size)
if(pos+1 != string::npos)
{
name = rom.substr(pos+1);
props.set("Cartridge.MD5", md5);
props.set("Cartridge.Name", name);
props.set(Cartridge_MD5, md5);
props.set(Cartridge_Name, name);
myPropSet->insert(props);
}
}

View File

@ -13,21 +13,19 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Props.cxx,v 1.11 2005-09-22 22:10:57 stephena Exp $
// $Id: Props.cxx,v 1.12 2006-03-05 01:18:42 stephena Exp $
//============================================================================
#include <cctype>
#include <algorithm>
#include "GuiUtils.hxx"
#include "Props.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Properties::Properties(const Properties* defaults)
Properties::Properties()
{
myDefaults = defaults;
myCapacity = 16;
myProperties = new Property[myCapacity];
mySize = 0;
setDefaults();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -39,85 +37,53 @@ Properties::Properties(const Properties& properties)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Properties::~Properties()
{
// Free the properties array
delete[] myProperties;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string Properties::get(const string& key, bool useUppercase) const
const string& Properties::get(PropertyType key) const
{
string s;
// Try to find the named property and answer its value
for(uInt32 i = 0; i < mySize; ++i)
{
if(key == myProperties[i].key)
{
s = myProperties[i].value;
if(useUppercase)
transform(s.begin(), s.end(), s.begin(), (int(*)(int)) toupper);
return s;
}
}
// Oops, property wasn't found so ask defaults if we have one
if(myDefaults != 0)
{
// Ask the default properties object to find the key
s = myDefaults->get(key);
if(useUppercase)
transform(s.begin(), s.end(), s.begin(), (int(*)(int)) toupper);
return s;
}
if(key >= 0 && key < LastPropType)
return myProperties[key];
else
{
// No default properties object so just return the empty string
return "";
}
return EmptyString;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Properties::set(const string& key, const string& value)
void Properties::set(PropertyType key, const string& value)
{
// See if the property already exists
for(uInt32 i = 0; i < mySize; ++i)
if(key >= 0 && key < LastPropType)
{
if(key == myProperties[i].key)
myProperties[key] = value;
switch(key)
{
myProperties[i].value = value;
return;
case Cartridge_Sound:
case Cartridge_Type:
case Console_LeftDifficulty:
case Console_RightDifficulty:
case Console_TelevisionType:
case Console_SwapPorts:
case Controller_Left:
case Controller_Right:
case Display_Format:
case Display_Phosphor:
case Emulation_HmoveBlanks:
{
transform(myProperties[key].begin(), myProperties[key].end(),
myProperties[key].begin(), (int(*)(int)) toupper);
break;
}
default:
break;
}
}
// See if the array needs to be resized
if(mySize == myCapacity)
{
// Yes, so we'll make the array twice as large
Property* newProperties = new Property[myCapacity * 2];
for(uInt32 i = 0; i < mySize; ++i)
{
newProperties[i] = myProperties[i];
}
delete[] myProperties;
myProperties = newProperties;
myCapacity *= 2;
}
// Add new property to the array
myProperties[mySize].key = key;
myProperties[mySize].value = value;
++mySize;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Properties::load(istream& in)
{
// Empty my property array
mySize = 0;
setDefaults();
string line, key, value;
string::size_type one, two, three, four, garbage;
@ -152,7 +118,8 @@ void Properties::load(istream& in)
value = line.substr(three + 1, four - three - 1);
// Set the property
set(key, value);
PropertyType type = getPropertyType(key);
set(type, value);
}
}
@ -160,14 +127,14 @@ void Properties::load(istream& in)
void Properties::save(ostream& out)
{
// Write out each of the key and value pairs
for(uInt32 i = 0; i < mySize; ++i)
for(int i = 0; i < LastPropType; ++i)
{
// Try to save some space by only saving the items that differ from default
if(myProperties[i].value != myDefaults->get(myProperties[i].key))
if(myProperties[i] != ourDefaultProperties[i])
{
writeQuotedString(out, myProperties[i].key);
writeQuotedString(out, ourPropertyNames[i]);
out.put(' ');
writeQuotedString(out, myProperties[i].value);
writeQuotedString(out, myProperties[i]);
out.put('\n');
}
}
@ -249,9 +216,6 @@ Properties& Properties::operator = (const Properties& properties)
// Do the assignment only if this isn't a self assignment
if(this != &properties)
{
// Free the properties array
delete[] myProperties;
// Now, make myself a copy of the given object
copy(properties);
}
@ -262,28 +226,86 @@ Properties& Properties::operator = (const Properties& properties)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Properties::copy(const Properties& properties)
{
// Remember the defaults to use
myDefaults = properties.myDefaults;
// Create an array of the same size as properties
myCapacity = properties.myCapacity;
myProperties = new Property[myCapacity];
// Now, copy each property from properties
mySize = properties.mySize;
for(uInt32 i = 0; i < mySize; ++i)
{
for(int i = 0; i < LastPropType; ++i)
myProperties[i] = properties.myProperties[i];
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Properties::print()
{
cout << get("Cartridge.MD5") << "|"
<< get("Cartridge.Name") << "|"
<< get("Cartridge.Rarity") << "|"
<< get("Cartridge.Manufacturer") << "|"
<< get("Cartridge.Note")
cout << get(Cartridge_MD5) << "|"
<< get(Cartridge_Name) << "|"
<< get(Cartridge_Rarity) << "|"
<< get(Cartridge_Manufacturer) << "|"
<< get(Cartridge_Note)
<< endl;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Properties::setDefaults()
{
for(int i = 0; i < LastPropType; ++i)
myProperties[i] = ourDefaultProperties[i];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyType Properties::getPropertyType(const string& name)
{
for(int i = 0; i < LastPropType; ++i)
if(ourPropertyNames[i] == name)
return (PropertyType)i;
// Otherwise, indicate that the item wasn't found
return LastPropType;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const char* Properties::ourDefaultProperties[LastPropType] = {
"", // Cartridge.MD5
"", // Cartridge.Manufacturer
"", // Cartridge.ModelNo
"Untitled", // Cartridge.Name
"", // Cartridge.Note
"", // Cartridge.Rarity
"MONO", // Cartridge.Sound
"AUTO-DETECT", // Cartridge.Type
"B", // Console.LeftDifficulty
"B", // Console.RightDifficulty
"COLOR", // Console.TelevisionType
"NO", // Console.SwapPorts
"JOYSTICK", // Controller.Left
"JOYSTICK", // Controller.Right
"NTSC", // Display.Format
"0", // Display.XStart
"160", // Display.Width
"34", // Display.YStart
"210", // Display.Height
"NO", // Display.Phosphor
"YES" // Emulation.HmoveBlanks
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const char* Properties::ourPropertyNames[LastPropType] = {
"Cartridge.MD5",
"Cartridge.Manufacturer",
"Cartridge.ModelNo",
"Cartridge.Name",
"Cartridge.Note",
"Cartridge.Rarity",
"Cartridge.Sound",
"Cartridge.Type",
"Console.LeftDifficulty",
"Console.RightDifficulty",
"Console.TelevisionType",
"Console.SwapPorts",
"Controller.Left",
"Controller.Right",
"Display.Format",
"Display.XStart",
"Display.Width",
"Display.YStart",
"Display.Height",
"Display.Phosphor",
"Emulation.HmoveBlanks"
};

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: Props.hxx,v 1.6 2005-09-22 22:10:57 stephena Exp $
// $Id: Props.hxx,v 1.7 2006-03-05 01:18:42 stephena Exp $
//============================================================================
#ifndef PROPERTIES_HXX
@ -21,6 +21,31 @@
#include "bspf.hxx"
enum PropertyType {
Cartridge_MD5,
Cartridge_Manufacturer,
Cartridge_ModelNo,
Cartridge_Name,
Cartridge_Note,
Cartridge_Rarity,
Cartridge_Sound,
Cartridge_Type,
Console_LeftDifficulty,
Console_RightDifficulty,
Console_TelevisionType,
Console_SwapPorts,
Controller_Left,
Controller_Right,
Display_Format,
Display_XStart,
Display_Width,
Display_YStart,
Display_Height,
Display_Phosphor,
Emulation_HmoveBlanks,
LastPropType
};
/**
This class represents objects which maintain a collection of
properties. A property is a key and its corresponding value.
@ -30,7 +55,7 @@
if the property key is not found in the original property list.
@author Bradford W. Mott
@version $Id: Props.hxx,v 1.6 2005-09-22 22:10:57 stephena Exp $
@version $Id: Props.hxx,v 1.7 2006-03-05 01:18:42 stephena Exp $
*/
class Properties
{
@ -38,10 +63,8 @@ class Properties
/**
Creates an empty properties object with the specified defaults. The
new properties object does not claim ownership of the defaults.
@param defaults The defaults
*/
Properties(const Properties* defaults = 0);
Properties();
/**
Creates a properties list by copying another one
@ -60,22 +83,19 @@ class Properties
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 property to lookup
@param useUppercase Convert the property to uppercase
@return The value of the property
@param key The key of the property to lookup
@return The value of the property
*/
string get(const string& key, bool useUppercase = false) const;
const string& get(PropertyType key) const;
/**
Set the value associated with key to the given value.
@param key The key of the property to set
@param value The value to assign to the property
@param key The key of the property to set
@param value The value to assign to the property
*/
void set(const string& key, const string& value);
void set(PropertyType key, const string& value);
public:
/**
Load properties from the specified input stream
@ -95,24 +115,10 @@ class Properties
*/
void print();
public:
/**
Read the next quoted string from the specified input stream
and returns it.
@param in The input stream to use
@return The string inside the quotes
*/
static string readQuotedString(istream& in);
/**
Write the specified string to the given output stream as a
quoted string.
@param out The output stream to use
@param s The string to output
*/
static void writeQuotedString(ostream& out, const string& s);
Resets all properties to their defaults
*/
void setDefaults();
public:
/**
@ -133,24 +139,40 @@ class Properties
*/
void copy(const Properties& properties);
/**
Read the next quoted string from the specified input stream
and returns it.
@param in The input stream to use
@return The string inside the quotes
*/
static string readQuotedString(istream& in);
/**
Write the specified string to the given output stream as a
quoted string.
@param out The output stream to use
@param s The string to output
*/
static void writeQuotedString(ostream& out, const string& s);
/**
Get the property type associated with the named property
@param name The PropertyType key associated with the given string
*/
static PropertyType getPropertyType(const string& name);
private:
// Structure used for storing properties
struct Property
{
string key;
string value;
};
// The array of properties
string myProperties[LastPropType];
// Pointer to properties object to use for defaults or the null pointer
const Properties* myDefaults;
// List of default properties to use when none have been provided
static const char* ourDefaultProperties[LastPropType];
// Pointer to a dynamically allocated array of properties
Property* myProperties;
// Current capacity of the properties array
unsigned int myCapacity;
// Size of the properties array (i.e. the number of <key,value> pairs)
unsigned int mySize;
// The text strings associated with each property type
static const char* ourPropertyNames[LastPropType];
};
#endif

View File

@ -13,11 +13,13 @@
// 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.19 2006-03-03 19:58:35 stephena Exp $
// $Id: PropsSet.cxx,v 1.20 2006-03-05 01:18:42 stephena Exp $
//============================================================================
#include <assert.h>
#include "GuiUtils.hxx"
#include "DefProps.hxx"
#include "Props.hxx"
#include "PropsSet.hxx"
@ -26,8 +28,6 @@ PropertiesSet::PropertiesSet()
: myRoot(NULL),
mySize(0)
{
myDefaultProperties = &defaultProperties();
loadInternalDefaults();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -39,40 +39,59 @@ PropertiesSet::~PropertiesSet()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PropertiesSet::getMD5(const string& md5, Properties &properties)
{
properties.setDefaults();
bool found = false;
// Make sure tree isn't empty
if(myRoot == 0)
// First check our dynamic BST for the object
if(myRoot != 0)
{
properties = myDefaultProperties;
return;
bool found = false;
TreeNode* current = myRoot;
while(current)
{
string currentMd5 = current->props->get(Cartridge_MD5);
if(currentMd5 == md5)
{
found = true;
break;
}
else
{
if(md5 < currentMd5)
current = current->left;
else
current = current->right;
}
}
if(found)
properties = *(current->props);
}
// Else, do a BST search for the node with the given md5
TreeNode* current = myRoot;
while(current)
// Otherwise, search the internal BST array
if(!found)
{
string currentMd5 = current->props->get("Cartridge.MD5");
int i = 0;
while(i < ARRAYSIZE(DefProps))
{
int cmp = strncmp(md5.c_str(), DefProps[i][Cartridge_MD5], 32);
if(cmp == 0)
{
for(int p = 0; p < LastPropType; ++p)
if(DefProps[i][p] != "")
properties.set((PropertyType)p, DefProps[i][p]);
if(currentMd5 == md5)
{
found = true;
break;
}
else
{
if(md5 < currentMd5)
current = current->left;
else
current = current->right;
}
found = true;
break;
}
else if(cmp < 0)
i = 2*i + 1; // left child
else
i = 2*i + 2; // right child
}
}
if(found)
properties = *(current->props);
else
properties = myDefaultProperties;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -87,8 +106,8 @@ void PropertiesSet::insertNode(TreeNode* &t, const Properties& properties,
{
if(t)
{
string md5 = properties.get("Cartridge.MD5");
string currentMd5 = t->props->get("Cartridge.MD5");
string md5 = properties.get(Cartridge_MD5);
string currentMd5 = t->props->get(Cartridge_MD5);
if(md5 < currentMd5)
insertNode(t->left, properties, save);
@ -138,12 +157,12 @@ void PropertiesSet::load(const string& filename, bool save)
break;
// Get the property list associated with this profile
Properties properties(myDefaultProperties);
properties.load(in);
Properties prop;
prop.load(in);
// If the stream is still good then insert the properties
if(in)
insert(properties, save);
insert(prop, save);
}
if(in)
in.close();
@ -205,46 +224,3 @@ bool PropertiesSet::merge(const Properties& properties, const string& filename)
else
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PropertiesSet::loadInternalDefaults()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const Properties& PropertiesSet::defaultProperties()
{
// Make sure the <key,value> pairs are in the default properties object
ourDefaultProperties.set("Cartridge.Cheats", "");
ourDefaultProperties.set("Cartridge.Filename", "");
ourDefaultProperties.set("Cartridge.MD5", "");
ourDefaultProperties.set("Cartridge.Manufacturer", "");
ourDefaultProperties.set("Cartridge.ModelNo", "");
ourDefaultProperties.set("Cartridge.Name", "Untitled");
ourDefaultProperties.set("Cartridge.Note", "");
ourDefaultProperties.set("Cartridge.Rarity", "");
ourDefaultProperties.set("Cartridge.Sound", "Mono");
ourDefaultProperties.set("Cartridge.Type", "AUTO-DETECT");
ourDefaultProperties.set("Console.LeftDifficulty", "B");
ourDefaultProperties.set("Console.RightDifficulty", "B");
ourDefaultProperties.set("Console.TelevisionType", "Color");
ourDefaultProperties.set("Console.SwapPorts", "No");
ourDefaultProperties.set("Controller.Left", "Joystick");
ourDefaultProperties.set("Controller.Right", "Joystick");
ourDefaultProperties.set("Display.Format", "NTSC");
ourDefaultProperties.set("Display.XStart", "0");
ourDefaultProperties.set("Display.Width", "160");
ourDefaultProperties.set("Display.YStart", "34");
ourDefaultProperties.set("Display.Height", "210");
ourDefaultProperties.set("Display.Phosphor", "No");
ourDefaultProperties.set("Emulation.HmoveBlanks", "Yes");
return ourDefaultProperties;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Properties PropertiesSet::ourDefaultProperties;

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.hxx,v 1.11 2006-03-03 19:58:35 stephena Exp $
// $Id: PropsSet.hxx,v 1.12 2006-03-05 01:18:42 stephena Exp $
//============================================================================
#ifndef PROPERTIES_SET_HXX
@ -25,32 +25,6 @@
class Properties;
enum PropertyType {
Cartridge_Cheats,
Cartridge_Filename,
Cartridge_MD5,
Cartridge_Manufacturer,
Cartridge_ModelNo,
Cartridge_Name,
Cartridge_Note,
Cartridge_Rarity,
Cartridge_Sound,
Cartridge_Type,
Console_LeftDifficulty,
Console_RightDifficulty,
Console_TelevisionType,
Console_SwapPorts,
Controller_Left,
Controller_Right,
Display_Format,
Display_XStart,
Display_Width,
Display_YStart,
Display_Height,
Display_Phosphor,
Emulation_HmoveBlanks
};
/**
This class maintains a sorted collection of properties. The objects
are maintained in a binary search tree sorted by md5, since this is
@ -143,8 +117,6 @@ class PropertiesSet
bool save;
};
void loadInternalDefaults();
/**
Insert a node in the bst, keeping the tree sorted.
@ -177,13 +149,6 @@ class PropertiesSet
*/
void printNode(TreeNode *node);
/**
Get the default properties object to use for other properties objects
@return The default properties object
*/
static const Properties& defaultProperties();
private:
// The root of the BST
TreeNode* myRoot;
@ -192,10 +157,7 @@ class PropertiesSet
uInt32 mySize;
// The default properties set
const Properties* myDefaultProperties;
// Default properties to use for properties objects
static Properties ourDefaultProperties;
Properties myCurrentProperties;
};
#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: Settings.cxx,v 1.77 2006-03-01 14:26:40 stephena Exp $
// $Id: Settings.cxx,v 1.78 2006-03-05 01:18:42 stephena Exp $
//============================================================================
#include <cassert>
@ -27,7 +27,7 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Settings::Settings(OSystem* osystem)
: myOSystem(osystem)
: myOSystem(osystem)
{
// Add this settings object to the OSystem
myOSystem->attach(this);

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: Switches.cxx,v 1.4 2005-09-22 22:10:57 stephena Exp $
// $Id: Switches.cxx,v 1.5 2006-03-05 01:18:42 stephena Exp $
//============================================================================
#include "Event.hxx"
@ -25,7 +25,7 @@ Switches::Switches(const Event& event, const Properties& properties)
: myEvent(event),
mySwitches(0xFF)
{
if(properties.get("Console.RightDifficulty", true) == "B")
if(properties.get(Console_RightDifficulty) == "B")
{
mySwitches &= ~0x80;
}
@ -34,7 +34,7 @@ Switches::Switches(const Event& event, const Properties& properties)
mySwitches |= 0x80;
}
if(properties.get("Console.LeftDifficulty", true) == "B")
if(properties.get(Console_LeftDifficulty) == "B")
{
mySwitches &= ~0x40;
}
@ -43,7 +43,7 @@ Switches::Switches(const Event& event, const Properties& properties)
mySwitches |= 0x40;
}
if(properties.get("Console.TelevisionType", true) == "COLOR")
if(properties.get(Console_TelevisionType) == "COLOR")
{
mySwitches |= 0x08;
}

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: TIA.cxx,v 1.65 2005-12-17 01:23:07 stephena Exp $
// $Id: TIA.cxx,v 1.66 2006-03-05 01:18:42 stephena Exp $
//============================================================================
#include <cassert>
@ -137,8 +137,8 @@ void TIA::reset()
// Reset pixel pointer and drawing flag
myFramePointer = myCurrentFrameBuffer;
myYStart = atoi(myConsole.properties().get("Display.YStart").c_str());
myHeight = atoi(myConsole.properties().get("Display.Height").c_str());
myYStart = atoi(myConsole.properties().get(Display_YStart).c_str());
myHeight = atoi(myConsole.properties().get(Display_Height).c_str());
// Calculate color clock offsets for starting and stoping frame drawing
myStartDisplayOffset = 228 * myYStart;
@ -218,12 +218,12 @@ void TIA::reset()
myDumpDisabledCycle = 0;
myAllowHMOVEBlanks =
(myConsole.properties().get("Emulation.HmoveBlanks", true) == "YES");
(myConsole.properties().get(Emulation_HmoveBlanks) == "YES");
myFrameXStart = atoi(myConsole.properties().get("Display.XStart").c_str());
myFrameWidth = atoi(myConsole.properties().get("Display.Width").c_str());
myFrameYStart = atoi(myConsole.properties().get("Display.YStart").c_str());
myFrameHeight = atoi(myConsole.properties().get("Display.Height").c_str());
myFrameXStart = atoi(myConsole.properties().get(Display_XStart).c_str());
myFrameWidth = atoi(myConsole.properties().get(Display_Width).c_str());
myFrameYStart = atoi(myConsole.properties().get(Display_YStart).c_str());
myFrameHeight = atoi(myConsole.properties().get(Display_Height).c_str());
// Make sure frameHeight is no less than 190 pixels
// This is a hack for the onscreen menus
@ -237,7 +237,7 @@ void TIA::reset()
myFrameWidth = 160;
}
if(myConsole.properties().get("Display.Format", true) == "PAL")
if(myConsole.properties().get(Display_Format) == "PAL")
{
myColorLossEnabled = true;
myMaximumNumberOfScanlines = 342;
@ -688,8 +688,8 @@ void TIA::updateScanlineByTrace(int target)
const uInt32* TIA::palette() const
{
// See which palette we should be using
string type = mySettings.getString("palette");
string format = myConsole.properties().get("Display.Format", true);
const string& type = mySettings.getString("palette");
const string& format = myConsole.properties().get(Display_Format);
if(type == "standard")
return (format == "PAL") ? ourPALPalette : ourNTSCPalette;

View File

@ -786,6 +786,7 @@
"Cartridge.Manufacturer" "Parker Bros"
"Cartridge.ModelNo" "PB5340"
"Cartridge.Rarity" "Uncommon"
"Cartridge.Type" "E0"
""
"Cartridge.MD5" "0890a5b089191f45d0f08dd1e3235687"
@ -9080,6 +9081,7 @@
"Cartridge.Manufacturer" "Activision"
"Cartridge.ModelNo" "AB-035-04"
"Cartridge.Rarity" "Rare"
"Cartridge.Type" "DPC"
"Display.Height" "192"
"Display.Width" "152"
"Display.XStart" "8"
@ -12650,6 +12652,7 @@
"Cartridge.ModelNo" "4L-2737"
"Cartridge.Note" "Set right difficulty to 'A' for Booster-Grip in both ports"
"Cartridge.Rarity" "Uncommon"
"Cartridge.Type" "FASC"
"Console.RightDifficulty" "A"
"Controller.Left" "Booster-Grip"
"Controller.Right" "Booster-Grip"
@ -14612,6 +14615,7 @@
"Cartridge.Manufacturer" "Parker Bros"
"Cartridge.ModelNo" "PB5080"
"Cartridge.Rarity" "Rare"
"Cartridge.Type" "E0"
"Display.Height" "180"
"Display.YStart" "47"
"Display.Phosphor" "Yes"
@ -15688,6 +15692,7 @@
"Cartridge.Manufacturer" "Parker Bros"
"Cartridge.ModelNo" "PB5320"
"Cartridge.Rarity" "Uncommon"
"Cartridge.Type" "E0"
"Display.Height" "206"
"Display.YStart" "37"
""
@ -16132,6 +16137,7 @@
"Cartridge.Manufacturer" "Parker Bros"
"Cartridge.ModelNo" "PB5370"
"Cartridge.Rarity" "Common"
"Cartridge.Type" "E0"
"Display.Phosphor" "Yes"
""
@ -18115,7 +18121,7 @@
"Cartridge.MD5" "df5cc5cccdc140eb7107f5b8adfacda1"
"Cartridge.Name" "Lumberman by Cracker Jack Productions (Pac-Man Hack)"
"Cartidge.Note" "Hack of Pac-Man (1981) (Atari)"
"Cartridge.Note" "Hack of Pac-Man (1981) (Atari)"
"Cartridge.Manufacturer" "Cracker Jack Productions"
"Cartridge.Rarity" "New Release (Hack)"
"Cartridge.Type" "4K"
@ -20998,4 +21004,3 @@
"Display.Width" "144"
"Display.XStart" "8"
""

View File

@ -13,12 +13,14 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: EventMappingWidget.cxx,v 1.13 2006-03-02 13:10:53 stephena Exp $
// $Id: EventMappingWidget.cxx,v 1.14 2006-03-05 01:18:42 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#include <sstream>
#include "OSystem.hxx"
#include "Widget.hxx"
#include "StringListWidget.hxx"
@ -127,11 +129,12 @@ void EventMappingWidget::startRemapping()
myCancelMapButton->setEnabled(true);
// And show a message indicating which key is being remapped
string buf = "Select action for '" +
EventHandler::ourActionList[ myActionSelected ].action +
"' event";
ostringstream buf;
buf << "Select action for '"
<< EventHandler::ourActionList[ myActionSelected ].action
<< "' event";
myKeyMapping->setColor(kTextColorEm);
myKeyMapping->setLabel(buf);
myKeyMapping->setLabel(buf.str());
// Make sure that this widget receives all events,
// and they aren't handled anywhere else
@ -180,9 +183,10 @@ void EventMappingWidget::drawKeyMapping()
{
if(myActionSelected >= 0)
{
string buf = "Action: " + EventHandler::ourActionList[ myActionSelected ].key;
ostringstream buf;
buf << "Action: " << EventHandler::ourActionList[ myActionSelected ].key;
myKeyMapping->setColor(kTextColor);
myKeyMapping->setLabel(buf);
myKeyMapping->setLabel(buf.str());
}
}

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: GameInfoDialog.cxx,v 1.23 2006-02-22 17:38:04 stephena Exp $
// $Id: GameInfoDialog.cxx,v 1.24 2006-03-05 01:18:42 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -113,7 +113,7 @@ GameInfoDialog::GameInfoDialog(
myType = new PopUpWidget(myTab, font, xpos+lwidth, ypos,
pwidth, lineHeight, "", 0, 0);
for(i = 0; i < 21; ++i)
myType->appendEntry(ourCartridgeList[i].name, i+1);
myType->appendEntry(ourCartridgeList[i][0], i+1);
wid.push_back(myType);
// Add items for tab 0
@ -178,7 +178,7 @@ GameInfoDialog::GameInfoDialog(
myLeftController = new PopUpWidget(myTab, font, xpos+lwidth, ypos,
pwidth, lineHeight, "", 0, 0);
for(i = 0; i < 5; ++i)
myLeftController->appendEntry(ourControllerList[i].name, i+1);
myLeftController->appendEntry(ourControllerList[i][0], i+1);
wid.push_back(myLeftController);
ypos += lineHeight + 3;
@ -187,7 +187,7 @@ GameInfoDialog::GameInfoDialog(
myRightController = new PopUpWidget(myTab, font, xpos+lwidth, ypos,
pwidth, lineHeight, "", 0, 0);
for(i = 0; i < 5; ++i)
myRightController->appendEntry(ourControllerList[i].name, i+1);
myRightController->appendEntry(ourControllerList[i][0], i+1);
wid.push_back(myRightController);
// Add items for tab 2
@ -289,25 +289,25 @@ void GameInfoDialog::loadConfig()
int i;
// Cartridge properties
s = myGameProperties->get("Cartridge.Name");
s = myGameProperties->get(Cartridge_Name);
myName->setEditString(s);
s = myGameProperties->get("Cartridge.MD5");
s = myGameProperties->get(Cartridge_MD5);
myMD5->setLabel(s);
s = myGameProperties->get("Cartridge.Manufacturer");
s = myGameProperties->get(Cartridge_Manufacturer);
myManufacturer->setEditString(s);
s = myGameProperties->get("Cartridge.ModelNo");
s = myGameProperties->get(Cartridge_ModelNo);
myModelNo->setEditString(s);
s = myGameProperties->get("Cartridge.Rarity");
s = myGameProperties->get(Cartridge_Rarity);
myRarity->setEditString(s);
s = myGameProperties->get("Cartridge.Note");
s = myGameProperties->get(Cartridge_Note);
myNote->setEditString(s);
s = myGameProperties->get("Cartridge.Sound", true);
s = myGameProperties->get(Cartridge_Sound);
if(s == "MONO")
mySound->setSelectedTag(1);
else if(s == "STEREO")
@ -315,17 +315,17 @@ void GameInfoDialog::loadConfig()
else
mySound->setSelectedTag(0);
s = myGameProperties->get("Cartridge.Type", true);
s = myGameProperties->get(Cartridge_Type);
for(i = 0; i < 21; ++i)
{
if(s == ourCartridgeList[i].comparitor)
if(s == ourCartridgeList[i][1])
break;
}
i = (i == 21) ? 0: i + 1;
myType->setSelectedTag(i);
// Console properties
s = myGameProperties->get("Console.LeftDifficulty", true);
s = myGameProperties->get(Console_LeftDifficulty);
if(s == "B")
myLeftDiff->setSelectedTag(1);
else if(s == "A")
@ -333,7 +333,7 @@ void GameInfoDialog::loadConfig()
else
myLeftDiff->setSelectedTag(0);
s = myGameProperties->get("Console.RightDifficulty", true);
s = myGameProperties->get(Console_RightDifficulty);
if(s == "B")
myRightDiff->setSelectedTag(1);
else if(s == "A")
@ -341,7 +341,7 @@ void GameInfoDialog::loadConfig()
else
myRightDiff->setSelectedTag(0);
s = myGameProperties->get("Console.TelevisionType", true);
s = myGameProperties->get(Console_TelevisionType);
if(s == "COLOR")
myTVType->setSelectedTag(1);
else if(s == "BLACKANDWHITE")
@ -349,7 +349,7 @@ void GameInfoDialog::loadConfig()
else
myTVType->setSelectedTag(0);
s = myGameProperties->get("Console.SwapPorts", true);
s = myGameProperties->get(Console_SwapPorts);
if(s == "YES")
mySwapPorts->setSelectedTag(1);
else if(s == "NO")
@ -358,26 +358,26 @@ void GameInfoDialog::loadConfig()
mySwapPorts->setSelectedTag(0);
// Controller properties
s = myGameProperties->get("Controller.Left", true);
s = myGameProperties->get(Controller_Left);
for(i = 0; i < 5; ++i)
{
if(s == ourControllerList[i].comparitor)
if(s == ourControllerList[i][1])
break;
}
i = (i == 5) ? 0: i + 1;
myLeftController->setSelectedTag(i);
s = myGameProperties->get("Controller.Right", true);
s = myGameProperties->get(Controller_Right);
for(i = 0; i < 5; ++i)
{
if(s == ourControllerList[i].comparitor)
if(s == ourControllerList[i][1])
break;
}
i = (i == 5) ? 0: i + 1;
myRightController->setSelectedTag(i);
// Display properties
s = myGameProperties->get("Display.Format", true);
s = myGameProperties->get(Display_Format);
if(s == "NTSC")
myFormat->setSelectedTag(1);
else if(s == "PAL")
@ -385,19 +385,19 @@ void GameInfoDialog::loadConfig()
else
myFormat->setSelectedTag(0);
s = myGameProperties->get("Display.XStart");
s = myGameProperties->get(Display_XStart);
myXStart->setEditString(s);
s = myGameProperties->get("Display.Width");
s = myGameProperties->get(Display_Width);
myWidth->setEditString(s);
s = myGameProperties->get("Display.YStart");
s = myGameProperties->get(Display_YStart);
myYStart->setEditString(s);
s = myGameProperties->get("Display.Height");
s = myGameProperties->get(Display_Height);
myHeight->setEditString(s);
s = myGameProperties->get("Display.Phosphor", true);
s = myGameProperties->get(Display_Phosphor);
if(s == "YES")
myPhosphor->setSelectedTag(1);
else if(s == "NO")
@ -405,7 +405,7 @@ void GameInfoDialog::loadConfig()
else
myPhosphor->setSelectedTag(0);
s = myGameProperties->get("Emulation.HmoveBlanks", true);
s = myGameProperties->get(Emulation_HmoveBlanks);
if(s == "YES")
myHmoveBlanks->setSelectedTag(1);
else if(s == "NO")
@ -424,30 +424,30 @@ void GameInfoDialog::saveConfig()
// Cartridge properties
s = myName->getEditString();
myGameProperties->set("Cartridge.Name", s);
myGameProperties->set(Cartridge_Name, s);
s = myManufacturer->getEditString();
myGameProperties->set("Cartridge.Manufacturer", s);
myGameProperties->set(Cartridge_Manufacturer, s);
s = myModelNo->getEditString();
myGameProperties->set("Cartridge.ModelNo", s);
myGameProperties->set(Cartridge_ModelNo, s);
s = myRarity->getEditString();
myGameProperties->set("Cartridge.Rarity", s);
myGameProperties->set(Cartridge_Rarity, s);
s = myNote->getEditString();
myGameProperties->set("Cartridge.Note", s);
myGameProperties->set(Cartridge_Note, s);
tag = mySound->getSelectedTag();
s = (tag == 1) ? "Mono" : "Stereo";
myGameProperties->set("Cartridge.Sound", s);
myGameProperties->set(Cartridge_Sound, s);
tag = myType->getSelectedTag();
for(i = 0; i < 21; ++i)
{
if(i == tag-1)
{
myGameProperties->set("Cartridge.Type", ourCartridgeList[i].comparitor);
myGameProperties->set(Cartridge_Type, ourCartridgeList[i][1]);
break;
}
}
@ -455,19 +455,19 @@ void GameInfoDialog::saveConfig()
// Console properties
tag = myLeftDiff->getSelectedTag();
s = (tag == 1) ? "B" : "A";
myGameProperties->set("Console.LeftDifficulty", s);
myGameProperties->set(Console_LeftDifficulty, s);
tag = myRightDiff->getSelectedTag();
s = (tag == 1) ? "B" : "A";
myGameProperties->set("Console.RightDifficulty", s);
myGameProperties->set(Console_RightDifficulty, s);
tag = myTVType->getSelectedTag();
s = (tag == 1) ? "Color" : "BlackAndWhite";
myGameProperties->set("Console.TelevisionType", s);
myGameProperties->set(Console_TelevisionType, s);
tag = mySwapPorts->getSelectedTag();
s = (tag == 1) ? "Yes" : "No";
myGameProperties->set("Console.SwapPorts", s);
myGameProperties->set(Console_SwapPorts, s);
// Controller properties
tag = myLeftController->getSelectedTag();
@ -475,7 +475,7 @@ void GameInfoDialog::saveConfig()
{
if(i == tag-1)
{
myGameProperties->set("Controller.Left", ourControllerList[i].name);
myGameProperties->set(Controller_Left, ourControllerList[i][0]);
break;
}
}
@ -485,7 +485,7 @@ void GameInfoDialog::saveConfig()
{
if(i == tag-1)
{
myGameProperties->set("Controller.Right", ourControllerList[i].name);
myGameProperties->set(Controller_Right, ourControllerList[i][0]);
break;
}
}
@ -493,27 +493,27 @@ void GameInfoDialog::saveConfig()
// Display properties
tag = myFormat->getSelectedTag();
s = (tag == 1) ? "NTSC" : "PAL";
myGameProperties->set("Display.Format", s);
myGameProperties->set(Display_Format, s);
s = myXStart->getEditString();
myGameProperties->set("Display.XStart", s);
myGameProperties->set(Display_XStart, s);
s = myWidth->getEditString();
myGameProperties->set("Display.Width", s);
myGameProperties->set(Display_Width, s);
s = myYStart->getEditString();
myGameProperties->set("Display.YStart", s);
myGameProperties->set(Display_YStart, s);
s = myHeight->getEditString();
myGameProperties->set("Display.Height", s);
myGameProperties->set(Display_Height, s);
tag = myPhosphor->getSelectedTag();
s = (tag == 1) ? "Yes" : "No";
myGameProperties->set("Display.Phosphor", s);
myGameProperties->set(Display_Phosphor, s);
tag = myHmoveBlanks->getSelectedTag();
s = (tag == 1) ? "Yes" : "No";
myGameProperties->set("Emulation.HmoveBlanks", s);
myGameProperties->set(Emulation_HmoveBlanks, s);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -534,24 +534,18 @@ void GameInfoDialog::handleCommand(CommandSender* sender, int cmd,
}
}
// FIXME - the following should be handled in a better way
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#ifndef _WIN32_WCE
const PropType GameInfoDialog::ourControllerList[5] = {
const char* GameInfoDialog::ourControllerList[5][2] = {
{ "Booster-Grip", "BOOSTER-GRIP" },
{ "Driving", "DRIVING" },
{ "Keyboard", "KEYBOARD" },
{ "Paddles", "PADDLES" },
{ "Joystick", "JOYSTICK" }
};
#else
const PropType GameInfoDialog::ourControllerList[5];
#endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#ifndef _WIN32_WCE
const PropType GameInfoDialog::ourCartridgeList[21] = {
{ "Auto-detect", "AUTO-DETECT" },
const char* GameInfoDialog::ourCartridgeList[21][2] = {
{ "Auto-detect", "AUTO-DETECT" },
{ "2K (2K Atari)", "2K" },
{ "3E (32K Tigervision)", "3E" },
{ "3F (512K Tigervision)", "3F" },
@ -573,6 +567,3 @@ const PropType GameInfoDialog::ourCartridgeList[21] = {
{ "MC (C. Wilkson Megacart)", "MC" },
{ "UA (8K UA Ltd.)", "UA" }
};
#else
const PropType GameInfoDialog::ourCartridgeList[21];
#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: GameInfoDialog.hxx,v 1.15 2006-02-22 17:38:04 stephena Exp $
// $Id: GameInfoDialog.hxx,v 1.16 2006-03-05 01:18:42 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -34,12 +34,6 @@ class Properties;
#include "Dialog.hxx"
#include "Command.hxx"
// Structure used for cartridge and controller types
struct PropType {
string name;
string comparitor;
};
class GameInfoDialog : public Dialog, public CommandSender
{
public:
@ -86,14 +80,20 @@ class GameInfoDialog : public Dialog, public CommandSender
PopUpWidget* myPhosphor;
PopUpWidget* myHmoveBlanks;
// Structure used for cartridge and controller types
struct PropType {
const char* name;
const char* comparitor;
};
/** Game properties for currently loaded ROM */
Properties* myGameProperties;
/** Holds static strings for Cartridge type */
static const PropType ourCartridgeList[21];
static const char* ourCartridgeList[21][2];
/** Holds static strings for Controller type */
static const PropType ourControllerList[5];
static const char* ourControllerList[5][2];
};
#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: LauncherDialog.cxx,v 1.39 2006-02-22 17:38:04 stephena Exp $
// $Id: LauncherDialog.cxx,v 1.40 2006-03-05 01:18:42 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -283,8 +283,8 @@ void LauncherDialog::loadListFromDisk()
// from the PropertiesSet (stella.pro)
md5 = MD5FromFile(rom);
instance()->propSet().getMD5(md5, props);
name = props.get("Cartridge.Name");
note = props.get("Cartridge.Note");
name = props.get(Cartridge_Name);
note = props.get(Cartridge_Note);
// Indicate that this ROM doesn't have a properties entry
myGameList->appendGame(rom, name, note);

328
stella/src/tools/Btrees.pm Normal file
View File

@ -0,0 +1,328 @@
package Btrees;
$VERSION=1.00;
require 5.000;
require Exporter;
=head1 NAME
Btrees - Binary trees using the AVL balancing method.
=head1 SYNOPSIS
# yes, do USE the package ...
use Btrees;
# no constructors
# traverse a tree and invoke a function
traverse( $tree, $func );
# add a node in a balanced tree, rebalancing if required
($tree, $node) = bal_tree_add( $tree, $val, $cmp )
=head1 DESCRIPTION
Btrees uses the AVL balancing method, by G. M. Adelson-Velskii
and E.M. Landis. Bit scavenging, as done in low level languages like
C, is not used for height balancing since this is too expensive for
an interpreter. Instead the actual height of each subtree is stored
at each node. A null pointer has a height of zero. A leaf a height of
1. A nonleaf a height of 1 greater than the height of its two children.
=head1 AUTHOR
Ron Squiers (ron@broadcom.com). Adapted from "Mastering Algorithms with
Perl" by Jon Orwant, Jarkko Hietaniemi & John Macdonald. Copyright
1999 O'Reilly and Associates, Inc. All right reserved. ISBN: 1-56592-398-7
=cut
@ISA = qw(Exporter);
@EXPORT = qw( bal_tree_add label_tree );
#########################################
#
# Method: label_tree
#
# label_tree( $tree, $func );
#
sub label_tree {
my $tree = shift or return undef;
my $func = shift or return undef;
$tree->{index} = 0;
# Label all nodes with their respective indices
sub label_node {
my $tree = shift;
&$func( $tree );
if (defined $tree->{left}) {
$tree->{left}->{index} = 2 * $tree->{index} + 1;
}
if (defined $tree->{right}) {
$tree->{right}->{index} = 2 * $tree->{index} + 2;
}
}
preorder_traverse( $tree, \&label_node );
}
#########################################
#
# Method: inorder_traverse
#
# Traverse $tree in order, calling $func() for each element.
# in turn
# inorder_traverse( $tree, $func );
#
sub inorder_traverse {
my $tree = shift or return; # skip undef pointers
my $func = shift;
inorder_traverse( $tree->{left}, $func );
&$func( $tree );
inorder_traverse( $tree->{right}, $func );
}
#########################################
#
# Method: preorder_traverse
#
# Traverse $tree in preorder form, calling $func() for each element.
# in turn
# preorder_traverse( $tree, $func );
#
sub preorder_traverse {
my $tree = shift or return; # skip undef pointers
my $func = shift;
&$func( $tree );
preorder_traverse( $tree->{left}, $func );
preorder_traverse( $tree->{right}, $func );
}
#########################################
#
# Method: bal_tree_add
#
# Search $tree looking for a node that has the value $val,
# add it if it does not already exist.
# If provided, $cmp compares values instead of <=>.
#
# ($tree, $node) = bal_tree_add( $tree, $val, $cmp )
# the return values:
# $tree points to the (possible new or changed) subtree that
# has resulted from the add operation.
# $node points to the (possibly new) node that contains $val
#
sub bal_tree_add {
my( $tree, $val, $cmp) = @_;
my $result;
unless ( $tree ) {
$result = {
left => undef,
right => undef,
val => $val,
index => -1,
height => 1
};
return( $result, $result );
}
my $relation = defined $cmp
? $cmp->( $val, $tree->{val} )
: $val <=> $tree->{val};
### Stop when the desired node if found.
return ( $tree, $tree ) if $relation == 0;
### Add to the correct subtree.
if( $relation < 0 ) {
($tree->{left}, $result) =
bal_tree_add ( $tree->{left}, $val, $cmp );
} else {
($tree->{right}, $result) =
bal_tree_add ( $tree->{right}, $val, $cmp );
}
### Make sure that this level is balanced, return the
### (possibly changed) top and the (possibly new) selected node.
return ( balance_tree( $tree ), $result );
}
#########################################
#
# Method: balance_tree
#
# Balance a potentially out of balance tree
#
# the return values:
# $tree points to the balanced tree root
#
sub balance_tree {
### An empty tree is balanced already.
my $tree = shift or return undef;
### An empty link is height 0.
my $lh = defined $tree->{left} && $tree->{left}{height};
my $rh = defined $tree->{right} && $tree->{right}{height};
### Rebalance if needed, return the (possibly changed) root.
if ( $lh > 1+$rh ) {
return swing_right( $tree );
} elsif ( $lh+1 < $rh ) {
return swing_left( $tree );
} else {
### Tree is either perfectly balanced or off by one.
### Just fix its height.
set_height( $tree );
return $tree;
}
}
#########################################
#
# Method: set_height
#
# Set height of a node
#
sub set_height {
my $tree = shift;
my $p;
### get heights, an undef node is height 0.
my $lh = defined ( $p = $tree->{left} ) && $p->{height};
my $rh = defined ( $p = $tree->{right} ) && $p->{height};
$tree->{height} = $lh < $rh ? $rh+1 : $lh+1;
}
#########################################
#
# Method: $tree = swing_left( $tree )
#
# Change t to r or rl
# / \ / \ / \
# l r t rr t r
# / \ / \ / \ / \
# rl rr l rl l rll rlr rr
# / \ / \
# rll rlr rll rlr
#
# t and r must both exist.
# The second form is used if height of rl is greater than height of rr
# (since the form would then lead to the height of t at least 2 more
# than the height of rr).
#
# changing to the second form is done in two steps, with first a move_right(r)
# and then a move_left(t), so it goes:
#
# Change t to t and then to rl
# / \ / \ / \
# l r l rl t r
# / \ / \ / \ / \
# rl rr rll r l rll rlr rr
# / \ / \
# rll rlr rlr rr
#
sub swing_left {
my $tree = shift;
my $r = $tree->{right}; # must exist
my $rl = $r->{left}; # might exist
my $rr = $r->{right}; # might exist
my $l = $tree->{left}; # might exist
### get heights, an undef node has height 0
my $lh = $l && $l->{height} || 0;
my $rlh = $rl && $rl->{height} || 0;
my $rrh = $rr && $rr->{height} || 0;
if ( $rlh > $rrh ) {
$tree->{right} = move_right( $r );
}
return move_left( $tree );
}
# and the opposite swing
sub swing_right {
my $tree = shift;
my $l = $tree->{left}; # must exist
my $lr = $l->{right}; # might exist
my $ll = $l->{left}; # might exist
my $r = $tree->{right}; # might exist
### get heights, an undef node has height 0
my $rh = $r && $r->{height} || 0;
my $lrh = $lr && $lr->{height} || 0;
my $llh = $ll && $ll->{height} || 0;
if ( $lrh > $llh ) {
$tree->{left} = move_left( $l );
}
return move_right( $tree );
}
#########################################
#
# Method: $tree = move_left( $tree )
#
# Change t to r
# / \ / \
# l r t rr
# / \ / \
# rl rr l rl
#
# caller has determined that t and r both exist
# (l can be undef, so can one of rl and rr)
#
sub move_left {
my $tree = shift;
my $r = $tree->{right};
my $rl = $r->{left};
$tree->{right} = $rl;
$r->{left} = $tree;
set_height( $tree );
set_height( $r );
return $r;
}
#########################################
#
# Method: $tree = move_right( $tree )
#
# Change t to l
# / \ / \
# l r ll t
# / \ / \
# ll lr lr r
#
# caller has determined that t and l both exist
# (r can be undef, so can one of ll and lr)
#
sub move_right {
my $tree = shift;
my $l = $tree->{left};
my $lr = $l->{right};
$tree->{left} = $lr;
$l->{right} = $tree;
set_height( $tree );
set_height( $l );
return $l;
}
#########################################
# That's all folks ...
#########################################
#
1; # so that use() returns true

213
stella/src/tools/create_props.pl Executable file
View File

@ -0,0 +1,213 @@
#!/usr/bin/perl
use Btrees;
my @props = ();
my @propset = ();
my @propset_ordered = ();
my %proptype = (
"Cartridge.MD5" => 0,
"Cartridge.Manufacturer" => 1,
"Cartridge.ModelNo" => 2,
"Cartridge.Name" => 3,
"Cartridge.Note" => 4,
"Cartridge.Rarity" => 5,
"Cartridge.Sound" => 6,
"Cartridge.Type" => 7,
"Console.LeftDifficulty" => 8,
"Console.RightDifficulty" => 9,
"Console.TelevisionType" => 10,
"Console.SwapPorts" => 11,
"Controller.Left" => 12,
"Controller.Right" => 13,
"Display.Format" => 14,
"Display.XStart" => 15,
"Display.Width" => 16,
"Display.YStart" => 17,
"Display.Height" => 18,
"Display.Phosphor" => 19,
"Emulation.HmoveBlanks" => 20
);
my @prop_defaults = (
"",
"",
"",
"Untitled",
"",
"",
"MONO",
"AUTO-DETECT",
"B",
"B",
"COLOR",
"NO",
"JOYSTICK",
"JOYSTICK",
"NTSC",
"0",
"160",
"34",
"210",
"NO",
"YES"
);
@props = ();
while(($key, $value) = each(%proptype)) {
$props[$value] = "";
}
print "@ARGV\n";
usage() if @ARGV != 2;
# Must provide input and output files
open(INFILE, "$ARGV[0]");
open(OUTFILE, ">$ARGV[1]");
# Parse the properties file into an array of property objects
foreach $line (<INFILE>) {
chomp $line;
# Start a new item
if ($line =~ /^""/) {
push @propset, [ @props ];
undef @props;
while(($key, $value) = each(%proptype)) {
$props[$value] = "";
}
} elsif ($line !~ /^$/) {
($key, $value) = ($line =~ m/"(.*)" "(.*)"/);
if (defined $proptype{$key}) {
$index = $proptype{$key};
$props[$index] = $value;
} else {
print "Invalid key = \'$key\' for md5 = \'$props[0]\', ignoring ...\n";
}
}
}
# Fill the AVL tree with property indices
my $tree;
for($i = 0; $i < @propset; $i++) {
my $value = $propset[$i][$proptype{'Cartridge.MD5'}];
# printf "Adding $value to tree\n";
($tree, $node) = bal_tree_add($tree, $i, \&compare);
}
printf "\n";
# Fill the results tree with the appropriate number of items
my $height = $tree->{height};
my $size = 2 ** $height - 1;
printf "Tree has height = $height, output BST array will have size = $size\n";
for($i = 0; $i < $size; $i++) {
$propset_ordered[$i] = -1;
}
# Label the tree nodes by index into a BST array
label_tree($tree, \&store);
printf "\n";
# Construct the output file in C++ format
# Walk the results array and print each item
# This array will now contain the original tree converted to a BST in array format
print OUTFILE "#ifndef DEF_PROPS_HXX\n";
print OUTFILE "#define DEF_PROPS_HXX\n";
print OUTFILE "\n";
print OUTFILE "/**\n";
print OUTFILE " This code is generated using the 'create_props.pl' script,\n";
print OUTFILE " located in the src/tools directory. All properties changes\n";
print OUTFILE " should be made in stella.pro, and then this file should be\n";
print OUTFILE " regenerated and the application recompiled.\n";
print OUTFILE "*/\n";
print OUTFILE "static const char* DefProps[][" . keys( %proptype ) . "] = {\n";
for ($i = 0; $i < @propset_ordered; $i++) {
my $idx = $propset_ordered[$i];
if ($idx != -1) {
print OUTFILE get_prop($idx);
} else {
print OUTFILE blank_prop();
}
if ($i+1 < @propset_ordered) {
print OUTFILE ", ";
}
print OUTFILE "\n";
}
print OUTFILE "};\n";
print OUTFILE "\n";
print OUTFILE "#endif\n";
close(INFILE);
close(OUTFILE);
sub usage {
print "create_props.pl <INPUT STELLA PROPS> <OUTPUT C++ header>\n";
exit(0);
}
sub compare {
my ($first, $second) = @_;
my $first_md5 = $propset[$first][$proptype{'Cartridge.MD5'}];
my $second_md5 = $propset[$second][$proptype{'Cartridge.MD5'}];
if ($first_md5 lt $second_md5) {
return -1;
} elsif ($first_md5 gt $second_md5) {
return 1;
} else {
return 0;
}
}
sub store {
my $tree = shift;
$propset_ordered[$tree->{index}] = $tree->{val};
}
sub get_prop {
my $idx = shift;
my $arr = $propset[$idx];
my @array = @$arr;
my $result = " { ";
my @items = ();
for (my $i = 0; $i < @array; $i++) {
if($prop_defaults[$i] ne $array[$i]) {
push(@items, "\"$array[$i]\"");
} else {
push(@items, "\"\"");
}
}
$result .= join(", ", @items);
$result .= " }";
return $result;
}
sub blank_prop {
my $arr = $propset[$idx];
my @array = @$arr;
my $result = " { ";
my @items = ();
for my $key ( keys %proptype) {
push(@items, "\"\"");
}
$result .= join(", ", @items);
$result .= " }";
return $result;
}

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.15 2006-01-15 20:46:20 stephena Exp $
// $Id: OSystemUNIX.cxx,v 1.16 2006-03-05 01:18:42 stephena Exp $
//============================================================================
#include <SDL.h>
@ -157,9 +157,9 @@ void OSystemUNIX::mainLoop()
cout << numberOfFrames << " total frames drawn\n";
cout << framesPerSecond << " frames/second\n";
cout << endl;
cout << "Cartridge Name: " << myConsole->properties().get("Cartridge.Name");
cout << "Cartridge Name: " << myConsole->properties().get(Cartridge_Name);
cout << endl;
cout << "Cartridge MD5: " << myConsole->properties().get("Cartridge.MD5");
cout << "Cartridge MD5: " << myConsole->properties().get(Cartridge_MD5);
cout << endl << endl;
}
}