diff --git a/stella/src/cheat/CheatManager.cxx b/stella/src/cheat/CheatManager.cxx index 273be20d3..404ba904d 100644 --- a/stella/src/cheat/CheatManager.cxx +++ b/stella/src/cheat/CheatManager.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: CheatManager.cxx,v 1.1 2005-11-11 21:44:18 stephena Exp $ +// $Id: CheatManager.cxx,v 1.2 2005-11-27 00:17:16 stephena Exp $ //============================================================================ #include "OSystem.hxx" @@ -33,16 +33,9 @@ CheatManager::CheatManager(OSystem* osystem) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CheatManager::~CheatManager() { - // Don't delete the items from per-frame list, since it will be done in - // the following loop - myPerFrameList.clear(); - - for(unsigned int i = 0; i < myCheatList.size(); i++) - { - cerr << myCheatList[i]->name() << ": " << myCheatList[i]->code() << endl; - delete myCheatList[i]; - } - myCheatList.clear(); + saveAllCheats(); + myCheatMap.clear(); + clear(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -132,10 +125,58 @@ void CheatManager::addPerFrame(Cheat* cheat, bool enable) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CheatManager::parse(const string& cheats) { - // FIXME - deal with comma-separated cheats cerr << "parsing cheats: " << cheats << endl; - add("TEST", cheats, true); + StringList s; + string::size_type lastPos = cheats.find_first_not_of(",", 0); + string::size_type pos = cheats.find_first_of(",", lastPos); + string cheat, name, code; + + // Split string by comma, getting each cheat + while(string::npos != pos || string::npos != lastPos) + { + // Get the next cheat + cheat = cheats.substr(lastPos, pos - lastPos); + + // Split cheat by colon, separating each part + string::size_type lastColonPos = cheat.find_first_not_of(":", 0); + string::size_type colonPos = cheat.find_first_of(":", lastColonPos); + while(string::npos != colonPos || string::npos != lastColonPos) + { + s.push_back(cheat.substr(lastColonPos, colonPos - lastColonPos)); + lastColonPos = cheat.find_first_not_of(":", colonPos); + colonPos = cheat.find_first_of(":", lastColonPos); + } + + // Account for variable number of items specified for cheat + switch(s.size()) + { + case 1: + name = s[0]; + code = name; + add(name, code, true); + break; + + case 2: + name = s[0]; + code = s[1]; + add(name, code, true); + break; + + case 3: + name = s[0]; + code = s[1]; + add(name, code, s[2] == "1"); + break; + } + s.clear(); + + lastPos = cheats.find_first_not_of(",", pos); + pos = cheats.find_first_of(",", lastPos); + } + + +// add("TEST", cheats, true); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -153,3 +194,81 @@ void CheatManager::enable(const string& code, bool enable) } } } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CheatManager::loadAllCheats() +{ + string cheatfile = myOSystem->baseDir() + BSPF_PATH_SEPARATOR + "stella.cht"; + ifstream in(cheatfile.c_str(), ios::in); + if(!in) + return; + + string line, md5, cheat; + string::size_type one, two, three, four; + + // Loop reading cheats + while(getline(in, line)) + { + if(line.length() == 0) + continue; + + one = line.find("\"", 0); + two = line.find("\"", one + 1); + three = line.find("\"", two + 1); + four = line.find("\"", three + 1); + + // Invalid line if it doesn't contain 4 quotes + if((one == string::npos) || (two == string::npos) || + (three == string::npos) || (four == string::npos)) + break; + + // Otherwise get the ms5sum and associated cheats + md5 = line.substr(one + 1, two - one - 1); + cheat = line.substr(three + 1, four - three - 1); + + myCheatMap.insert(make_pair(md5, cheat)); + } + + in.close(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CheatManager::saveAllCheats() +{ + string cheatfile = myOSystem->baseDir() + BSPF_PATH_SEPARATOR + "stella.cht"; + ofstream out(cheatfile.c_str(), ios::out); + if(!out) + return; + + CheatCodeMap::iterator iter; + for(iter = myCheatMap.begin(); iter != myCheatMap.end(); ++iter) + out << "\"" << iter->first << "\" " + << "\"" << iter->second << "\"" + << endl; + + out.close(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CheatManager::loadCheats(const string& md5sum) +{ + clear(); + + CheatCodeMap::iterator iter = myCheatMap.find(md5sum); + if(iter == myCheatMap.end()) + return; + + parse(iter->second); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CheatManager::clear() +{ + // Don't delete the items from per-frame list, since it will be done in + // the following loop + myPerFrameList.clear(); + + for(unsigned int i = 0; i < myCheatList.size(); i++) + delete myCheatList[i]; + myCheatList.clear(); +} diff --git a/stella/src/cheat/CheatManager.hxx b/stella/src/cheat/CheatManager.hxx index 2710be1ff..ac5c2019d 100644 --- a/stella/src/cheat/CheatManager.hxx +++ b/stella/src/cheat/CheatManager.hxx @@ -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: CheatManager.hxx,v 1.1 2005-11-11 21:44:18 stephena Exp $ +// $Id: CheatManager.hxx,v 1.2 2005-11-27 00:17:16 stephena Exp $ //============================================================================ #ifndef CHEAT_MANAGER_HXX #define CHEAT_MANAGER_HXX +#include + #include "OSystem.hxx" #include "bspf.hxx" #include "Array.hxx" @@ -26,6 +28,7 @@ #include "Cheat.hxx" typedef GUI::Array CheatList; +typedef map CheatCodeMap; /** This class provides an interface for performing all cheat operations @@ -33,7 +36,7 @@ typedef GUI::Array CheatList; the list of all cheats currently in use. @author Stephen Anthony - @version $Id: CheatManager.hxx,v 1.1 2005-11-11 21:44:18 stephena Exp $ + @version $Id: CheatManager.hxx,v 1.2 2005-11-27 00:17:16 stephena Exp $ */ class CheatManager { @@ -77,21 +80,40 @@ class CheatManager */ void enable(const string& code, bool enable); - /** - Clear all lists of all cheats. - */ - void clear(); - /** Returns the per-frame cheatlist (needed to evaluate cheats each frame) */ const CheatList& perFrame() { return myPerFrameList; } + /** + Load all cheats (for all ROMs) from disk to internal database. + */ + void loadAllCheats(); + + /** + Save all cheats (for all ROMs) in internal database to disk. + */ + void saveAllCheats(); + + /** + Load cheats for ROM with given MD5sum to cheatlist(s). + */ + void loadCheats(const string& md5sum); + + private: + /** + Clear all per-ROM cheats lists. + */ + void clear(); + private: OSystem* myOSystem; CheatList myCheatList; CheatList myPerFrameList; + + CheatCodeMap myCheatMap; + string myCheatFile; }; #endif diff --git a/stella/src/common/mainSDL.cxx b/stella/src/common/mainSDL.cxx index 4593bedcd..4e4fc1800 100644 --- a/stella/src/common/mainSDL.cxx +++ b/stella/src/common/mainSDL.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: mainSDL.cxx,v 1.54 2005-11-12 22:04:57 stephena Exp $ +// $Id: mainSDL.cxx,v 1.55 2005-11-27 00:17:16 stephena Exp $ //============================================================================ #include @@ -208,6 +208,20 @@ int main(int argc, char* argv[]) theOSystem->createLauncher(); else { +#ifdef CHEATCODE_SUPPORT + // Create internal cheat database for all ROMs + theOSystem->cheat().loadAllCheats(); + + // Set up any cheeetah code that was on the command line + // (and remove the key from the settings, so they won't get set again) + string cheats = theOSystem->settings().getString("cheat"); + if(cheats != "") + { + theOSystem->cheat().parse(cheats); + theOSystem->settings().setString("cheat", "", false); + } +#endif + theOSystem->createConsole(romfile); if(theOSystem->settings().getBool("holdreset")) @@ -219,17 +233,6 @@ int main(int argc, char* argv[]) if(theOSystem->settings().getBool("holdbutton0")) theOSystem->eventHandler().handleEvent(Event::JoystickZeroFire, 1); -#ifdef CHEATCODE_SUPPORT - // Set up any cheeetah code that was on the command line - // (and remove the key from the settings, so they won't get set again) - string cheats = theOSystem->settings().getString("cheat"); - if(cheats != "") - { - theOSystem->cheat().parse(cheats); - theOSystem->settings().setString("cheat", "", false); - } -#endif - #ifdef DEVELOPER_SUPPORT Debugger& dbg = theOSystem->debugger(); diff --git a/stella/src/emucore/Console.cxx b/stella/src/emucore/Console.cxx index 148d001b8..e61d43a63 100644 --- a/stella/src/emucore/Console.cxx +++ b/stella/src/emucore/Console.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Console.cxx,v 1.74 2005-10-19 00:59:51 stephena Exp $ +// $Id: Console.cxx,v 1.75 2005-11-27 00:17:16 stephena Exp $ //============================================================================ #include @@ -55,6 +55,10 @@ #include "Debugger.hxx" #endif +#ifdef CHEATCODE_SUPPORT + #include "CheatManager.hxx" +#endif + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Console::Console(const uInt8* image, uInt32 size, const string& md5, OSystem* osystem) @@ -211,6 +215,10 @@ Console::Console(const uInt8* image, uInt32 size, const string& md5, myOSystem->debugger().setConsole(this); myOSystem->debugger().initialize(); #endif + +#ifdef CHEATCODE_SUPPORT + myOSystem->cheat().loadCheats(md5); +#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -