diff --git a/stella/src/debugger/Debugger.cxx b/stella/src/debugger/Debugger.cxx index 45d8dad4a..422c535a4 100644 --- a/stella/src/debugger/Debugger.cxx +++ b/stella/src/debugger/Debugger.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: Debugger.cxx,v 1.115 2007-09-03 18:37:22 stephena Exp $ +// $Id: Debugger.cxx,v 1.116 2007-09-23 17:04:17 stephena Exp $ //============================================================================ #include "bspf.hxx" @@ -29,6 +29,7 @@ #include "Settings.hxx" #include "DebuggerDialog.hxx" #include "DebuggerParser.hxx" +#include "StateManager.hxx" #include "Console.hxx" #include "System.hxx" @@ -671,13 +672,13 @@ const string Debugger::dumpTIA() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Debugger::saveState(int state) { - myOSystem->eventHandler().saveState(state); + myOSystem->state().saveState(state); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Debugger::loadState(int state) { - myOSystem->eventHandler().loadState(state); + myOSystem->state().loadState(state); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stella/src/emucore/Event.cxx b/stella/src/emucore/Event.cxx index 4d8d5bd19..b95d45c79 100644 --- a/stella/src/emucore/Event.cxx +++ b/stella/src/emucore/Event.cxx @@ -13,16 +13,14 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Event.cxx,v 1.11 2007-01-01 18:04:47 stephena Exp $ +// $Id: Event.cxx,v 1.12 2007-09-23 17:04:17 stephena Exp $ //============================================================================ #include "Event.hxx" -#include "EventStreamer.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Event::Event(EventStreamer* ev) - : myNumberOfTypes(Event::LastType), - myEventStreamer(ev) +Event::Event() + : myNumberOfTypes(Event::LastType) { // Set all of the events to 0 / false to start with, // including analog paddle events. Doing it this way @@ -50,12 +48,6 @@ Int32 Event::get(Type type) const void Event::set(Type type, Int32 value) { myValues[type] = value; - -/* FIXME - add full functionality at some point - // Add to history if we're in recording mode - if(myEventStreamer->isRecording()) - myEventStreamer->addEvent(type, value); -*/ } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stella/src/emucore/Event.hxx b/stella/src/emucore/Event.hxx index 1385767cc..c4a247884 100644 --- a/stella/src/emucore/Event.hxx +++ b/stella/src/emucore/Event.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Event.hxx,v 1.28 2007-01-30 17:13:07 stephena Exp $ +// $Id: Event.hxx,v 1.29 2007-09-23 17:04:17 stephena Exp $ //============================================================================ #ifndef EVENT_HXX @@ -22,11 +22,10 @@ #include "bspf.hxx" class Event; -class EventStreamer; /** @author Bradford W. Mott - @version $Id: Event.hxx,v 1.28 2007-01-30 17:13:07 stephena Exp $ + @version $Id: Event.hxx,v 1.29 2007-09-23 17:04:17 stephena Exp $ */ class Event { @@ -88,9 +87,9 @@ class Event public: /** - Create a new event object and use the given eventstreamer + Create a new event object */ - Event(EventStreamer* ev); + Event(); /** Destructor @@ -119,9 +118,6 @@ class Event // Array of values associated with each event type Int32 myValues[LastType]; - - // The eventstreamer to record events to - EventStreamer* myEventStreamer; }; #endif diff --git a/stella/src/emucore/EventHandler.cxx b/stella/src/emucore/EventHandler.cxx index fe817514c..bcd2a0900 100644 --- a/stella/src/emucore/EventHandler.cxx +++ b/stella/src/emucore/EventHandler.cxx @@ -14,7 +14,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.209 2007-09-20 00:13:35 stephena Exp $ +// $Id: EventHandler.cxx,v 1.210 2007-09-23 17:04:17 stephena Exp $ //============================================================================ #include @@ -24,10 +24,8 @@ #include "CommandMenu.hxx" #include "Console.hxx" -#include "Deserializer.hxx" #include "DialogContainer.hxx" #include "Event.hxx" -#include "EventStreamer.hxx" #include "FrameBuffer.hxx" #include "FSNode.hxx" #include "Launcher.hxx" @@ -35,11 +33,10 @@ #include "OSystem.hxx" #include "PropsSet.hxx" #include "ScrollBarWidget.hxx" -#include "Serializer.hxx" #include "Settings.hxx" #include "Snapshot.hxx" #include "Sound.hxx" -#include "System.hxx" +#include "StateManager.hxx" #include "EventHandler.hxx" @@ -62,10 +59,8 @@ EventHandler::EventHandler(OSystem* osystem) : myOSystem(osystem), myEvent(NULL), - myEventStreamer(NULL), myOverlay(NULL), myState(S_NONE), - myLSState(0), myGrabMouseFlag(false), myUseLauncherFlag(false), myAllowAllDirectionsFlag(false), @@ -73,11 +68,8 @@ EventHandler::EventHandler(OSystem* osystem) myPaddleMode(0), myPaddleThreshold(0) { - // Create the streamer used for accessing eventstreams/recordings - myEventStreamer = new EventStreamer(myOSystem); - // Create the event object which will be used for this handler - myEvent = new Event(myEventStreamer); + myEvent = new Event(); // Erase the key mapping array for(int i = 0; i < SDLK_LAST; ++i) @@ -125,7 +117,6 @@ EventHandler::EventHandler(OSystem* osystem) EventHandler::~EventHandler() { delete myEvent; - delete myEventStreamer; #ifdef JOYSTICK_SUPPORT if(SDL_WasInit(SDL_INIT_JOYSTICK) & SDL_INIT_JOYSTICK) @@ -165,9 +156,10 @@ void EventHandler::reset(State state) { setEventState(state); - myLSState = 0; myEvent->clear(); + myOSystem->state().reset(); + if(myState == S_LAUNCHER) myUseLauncherFlag = true; @@ -183,8 +175,6 @@ void EventHandler::reset(State state) setPaddleSpeed(1, myOSystem->settings().getInt("p1speed")); setPaddleSpeed(2, myOSystem->settings().getInt("p2speed")); setPaddleSpeed(3, myOSystem->settings().getInt("p3speed")); - -// myEventStreamer->reset(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -357,6 +347,7 @@ void EventHandler::mapStelladaptors(const string& sa1, const string& sa2) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EventHandler::poll(uInt32 time) { +// FIXME - change this to use StateManager stuff // Check if we have an event from the eventstreamer // TODO - should we lock out input from the user while getting synthetic events? // int type, value; @@ -846,6 +837,7 @@ void EventHandler::poll(uInt32 time) // Tell the eventstreamer that another frame has finished // This is used for event recording // myEventStreamer->nextFrame(); +// FIXME - change this to use StateManager stuff } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1176,15 +1168,15 @@ void EventHandler::handleEvent(Event::Type event, int state) return; case Event::SaveState: - if(state) saveState(); + if(state) myOSystem->state().saveState(); return; case Event::ChangeState: - if(state) changeState(); + if(state) myOSystem->state().changeState(); return; case Event::LoadState: - if(state) loadState(); + if(state) myOSystem->state().loadState(); return; case Event::TakeSnapshot: @@ -2022,101 +2014,6 @@ inline bool EventHandler::isJitter(int paddle, int value) return jitter; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandler::saveState() -{ - const string& name = myOSystem->console().properties().get(Cartridge_Name); - const string& md5 = myOSystem->console().properties().get(Cartridge_MD5); - - ostringstream buf; - buf << myOSystem->stateDir() << BSPF_PATH_SEPARATOR - << name << ".st" << myLSState; - - // Make sure the file can be opened for writing - Serializer out; - if(!out.open(buf.str())) - { - myOSystem->frameBuffer().showMessage("Error saving state file"); - return; - } - - // Do a state save using the System - buf.str(""); - if(myOSystem->console().system().saveState(md5, out)) - { - buf << "State " << myLSState << " saved"; - if(myOSystem->settings().getBool("autoslot")) - { - changeState(false); // don't show a message for state change - buf << ", switching to slot " << myLSState; - } - } - else - buf << "Error saving state " << myLSState; - - out.close(); - myOSystem->frameBuffer().showMessage(buf.str()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandler::saveState(int state) -{ - myLSState = state; - saveState(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandler::changeState(bool show) -{ - myLSState = (myLSState + 1) % 10; - - // Print appropriate message - if(show) - { - ostringstream buf; - buf << "Changed to slot " << myLSState; - myOSystem->frameBuffer().showMessage(buf.str()); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandler::loadState() -{ - const string& name = myOSystem->console().properties().get(Cartridge_Name); - const string& md5 = myOSystem->console().properties().get(Cartridge_MD5); - - ostringstream buf; - buf << myOSystem->stateDir() << BSPF_PATH_SEPARATOR - << name << ".st" << myLSState; - - // Make sure the file can be opened for reading - Deserializer in; - if(!in.open(buf.str())) - { - buf.str(""); - buf << "Error loading state " << myLSState; - myOSystem->frameBuffer().showMessage(buf.str()); - return; - } - - // Do a state load using the System - buf.str(""); - if(myOSystem->console().system().loadState(md5, in)) - buf << "State " << myLSState << " loaded"; - else - buf << "Invalid state " << myLSState << " file"; - - in.close(); - myOSystem->frameBuffer().showMessage(buf.str()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandler::loadState(int state) -{ - myLSState = state; - loadState(); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EventHandler::takeSnapshot() { diff --git a/stella/src/emucore/EventHandler.hxx b/stella/src/emucore/EventHandler.hxx index 7221b38c1..0ea97b84c 100644 --- a/stella/src/emucore/EventHandler.hxx +++ b/stella/src/emucore/EventHandler.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: EventHandler.hxx,v 1.103 2007-09-03 18:37:22 stephena Exp $ +// $Id: EventHandler.hxx,v 1.104 2007-09-23 17:04:17 stephena Exp $ //============================================================================ #ifndef EVENTHANDLER_HXX @@ -62,7 +62,7 @@ enum EventMode { mapping can take place. @author Stephen Anthony - @version $Id: EventHandler.hxx,v 1.103 2007-09-03 18:37:22 stephena Exp $ + @version $Id: EventHandler.hxx,v 1.104 2007-09-23 17:04:17 stephena Exp $ */ class EventHandler { @@ -191,16 +191,6 @@ class EventHandler */ void quit() { handleEvent(Event::Quit, 1); } - /** - Save state to explicit state number (debugger uses this) - */ - void saveState(int state); - - /** - Load state from explicit state number (debugger uses this) - */ - void loadState(int state); - /** Sets the mouse to act as paddle 'num' @@ -454,9 +444,6 @@ class EventHandler */ inline bool isJitter(int paddle, int value); - void saveState(); - void changeState(bool show = true); - void loadState(); void setEventState(State state); private: @@ -538,9 +525,6 @@ class EventHandler // Indicates the current state of the system (ie, which mode is current) State myState; - // Indicates the current state to use for state loading/saving - uInt32 myLSState; - // Indicates whether the mouse cursor is grabbed bool myGrabMouseFlag; diff --git a/stella/src/emucore/EventStreamer.cxx b/stella/src/emucore/EventStreamer.cxx deleted file mode 100644 index ba9775476..000000000 --- a/stella/src/emucore/EventStreamer.cxx +++ /dev/null @@ -1,200 +0,0 @@ -//============================================================================ -// -// SSSS tt lll lll -// SS SS tt ll ll -// SS tttttt eeee ll ll aaaa -// SSSS tt ee ee ll ll aa -// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" -// SS SS tt ee ll ll aa aa -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team -// -// 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.9 2007-09-03 18:37:22 stephena Exp $ -//============================================================================ - -#include "bspf.hxx" - -#include "Console.hxx" -#include "EventHandler.hxx" -#include "Event.hxx" -#include "OSystem.hxx" -#include "System.hxx" -#include "EventStreamer.hxx" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -EventStreamer::EventStreamer(OSystem* osystem) - : myOSystem(osystem), - myEventWriteFlag(false), - myEventReadFlag(false), - myFrameCounter(-1), - myEventPos(0) -{ -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -EventStreamer::~EventStreamer() -{ - stopRecording(); - - myEventHistory.clear(); - myStreamReader.close(); - myStreamWriter.close(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventStreamer::reset() -{ -//cerr << "EventStreamer::reset()\n"; - myEventWriteFlag = false; - myEventReadFlag = false; - myFrameCounter = -1; - myEventPos = 0; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EventStreamer::startRecording() -{ - string eventfile = /*myOSystem->baseDir() + BSPF_PATH_SEPARATOR +*/ "test.inp"; - if(!myStreamWriter.open(eventfile)) - return false; - - // And save the current state to it - string md5 = myOSystem->console().properties().get(Cartridge_MD5); - if(!myOSystem->console().system().saveState(md5, myStreamWriter)) - return false; - myEventHistory.clear(); - - reset(); - return myEventWriteFlag = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EventStreamer::stopRecording() -{ - if(!myStreamWriter.isOpen() || !myEventWriteFlag) - return false; - - // Append the event history to the eventstream - int size = myEventHistory.size(); - - try - { - myStreamWriter.putString("EventStream"); - myStreamWriter.putInt(size); - for(int i = 0; i < size; ++i) - myStreamWriter.putInt(myEventHistory[i]); - } - catch(char *msg) - { - cerr << msg << endl; - return false; - } - catch(...) - { - cerr << "Error saving eventstream" << endl; - return false; - } - - myStreamWriter.close(); - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EventStreamer::loadRecording() -{ -cerr << "EventStreamer::loadRecording()\n"; - string eventfile = /*myOSystem->baseDir() + BSPF_PATH_SEPARATOR +*/ "test.inp"; - if(!myStreamReader.open(eventfile)) - return false; - - // Load ROM state - string md5 = myOSystem->console().properties().get(Cartridge_MD5); - if(!myOSystem->console().system().loadState(md5, myStreamReader)) - return false; - - try - { - if(myStreamReader.getString() != "EventStream") - return false; - - // Now load the event stream - myEventHistory.clear(); - int size = myStreamReader.getInt(); - for(int i = 0; i < size; ++i) - myEventHistory.push_back(myStreamReader.getInt()); - } - catch(char *msg) - { - cerr << msg << endl; - return false; - } - catch(...) - { - cerr << "Error loading eventstream" << endl; - return false; - } - - reset(); - myEventReadFlag = myEventHistory.size() > 0; - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventStreamer::addEvent(int type, int value) -{ - if(myEventWriteFlag) - { - myEventHistory.push_back(type); - myEventHistory.push_back(value); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EventStreamer::pollEvent(int& type, int& value) -{ - if(!myEventReadFlag) - return false; - - bool status = false; - - // Read a new event from the stream when we've waited the appropriate - // number of frames - ++myFrameCounter; - if(myFrameCounter >= 0) - { - int first = myEventHistory[myEventPos++]; - if(first < 0) - { - myFrameCounter = first; - cerr << "wait " << -myFrameCounter << " frames\n"; - } - else if(myEventPos < (int)myEventHistory.size()) - { - type = first; - value = myEventHistory[myEventPos++]; -cerr << "type = " << type << ", value = " << value << endl; - status = true; - } - } - - myEventReadFlag = myEventPos < (int)myEventHistory.size() - 2; - return status; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventStreamer::nextFrame() -{ - if(myEventWriteFlag) - { - int idx = myEventHistory.size() - 1; - if(idx >= 0 && myEventHistory[idx] < 0) - --myEventHistory[idx]; - else - myEventHistory.push_back(-1); - } -} diff --git a/stella/src/emucore/EventStreamer.hxx b/stella/src/emucore/EventStreamer.hxx deleted file mode 100644 index 33a417ee5..000000000 --- a/stella/src/emucore/EventStreamer.hxx +++ /dev/null @@ -1,131 +0,0 @@ -//============================================================================ -// -// SSSS tt lll lll -// SS SS tt ll ll -// SS tttttt eeee ll ll aaaa -// SSSS tt ee ee ll ll aa -// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" -// SS SS tt ee ll ll aa aa -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team -// -// See the file "license" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -// -// $Id: EventStreamer.hxx,v 1.5 2007-01-01 18:04:48 stephena Exp $ -//============================================================================ - -#ifndef EVENTSTREAMER_HXX -#define EVENTSTREAMER_HXX - -#include "Array.hxx" -#include "Deserializer.hxx" -#include "Serializer.hxx" - -class OSystem; - -/** - This class takes care of event streams, which consist of a ROM state - file and appended event data. This appended data is defined as a - string of integers which are grouped as follows: - - event; event ; ... ; -framewait; event ... ; -framewait; ... - - 'event' consists of type/value pairs (each event in Stella is an - enumerated type with an associated value) - 'framewait' is the number of frames to wait until executing all - the following events - - The EventStreamer can load and save eventstream recordings. When in - 'save' mode, all events are queued from the Event class, and appended to - the ROM state when recording was started. - - When in 'load' mode, the ROM state is loaded from the eventstream, and - the appended event data is available in a queue for polling. - It's the responsibility of the calling object (most likely the EventHandler) - to poll for data; this class simply makes the queued events available in - the correct order at the correct time. - - @author Stephen Anthony - @version $Id: EventStreamer.hxx,v 1.5 2007-01-01 18:04:48 stephena Exp $ -*/ -class EventStreamer -{ - public: - /** - Create a new event streamer object - */ - EventStreamer(OSystem* osystem); - - /** - Destructor - */ - virtual ~EventStreamer(); - - public: - /** - Start recording event-stream to disk - */ - bool startRecording(); - - /** - Stop recording event-stream - */ - bool stopRecording(); - - /** - Load recorded event-stream into the system - */ - bool loadRecording(); - - /** - Adds the given event to the event history - */ - void addEvent(int type, int value); - - /** - Gets the next event from the event history - */ - bool pollEvent(int& type, int& value); - - /** - Answers if we're in recording mode - */ - bool isRecording() { return myEventWriteFlag; } - - /** - Indicate that a new frame has been processed - */ - void nextFrame(); - - /** - Reset to base state (not saving or loading an eventstream) - */ - void reset(); - - private: - - private: - // Global OSystem object - OSystem* myOSystem; - - // Indicates if we're in save/write or load/read mode - bool myEventWriteFlag; - bool myEventReadFlag; - - // Current frame count (used for waiting while polling) - int myFrameCounter; - - // Current position in the event history queue - int myEventPos; - - // Stores the history/record of all events that have been set - IntArray myEventHistory; - - // Serializer classes used to save/load the eventstream - Serializer myStreamWriter; - Deserializer myStreamReader; -}; - -#endif diff --git a/stella/src/emucore/OSystem.cxx b/stella/src/emucore/OSystem.cxx index a9f01c63c..243db3fc6 100644 --- a/stella/src/emucore/OSystem.cxx +++ b/stella/src/emucore/OSystem.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: OSystem.cxx,v 1.110 2007-09-03 18:37:22 stephena Exp $ +// $Id: OSystem.cxx,v 1.111 2007-09-23 17:04:17 stephena Exp $ //============================================================================ #include @@ -21,6 +21,8 @@ #include #include +#include "bspf.hxx" + #include "MediaFactory.hxx" #ifdef DEBUGGER_SUPPORT @@ -43,10 +45,11 @@ #include "Font.hxx" #include "StellaFont.hxx" #include "ConsoleFont.hxx" -#include "bspf.hxx" -#include "OSystem.hxx" #include "Widget.hxx" #include "Console.hxx" +#include "StateManager.hxx" + +#include "OSystem.hxx" #define MAX_ROM_SIZE 512 * 1024 @@ -63,6 +66,7 @@ OSystem::OSystem() myLauncher(NULL), myDebugger(NULL), myCheatManager(NULL), + myStateManager(NULL), myQuitLoop(false), myRomFile(""), myFeatures(""), @@ -144,8 +148,10 @@ OSystem::~OSystem() delete myCheatManager; #endif + delete myStateManager; delete myPropSet; delete myEventHandler; + } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -183,6 +189,7 @@ bool OSystem::create() #ifdef DEBUGGER_SUPPORT myDebugger = new Debugger(this); #endif + myStateManager = new StateManager(this); // Create the sound object; the sound subsystem isn't actually // opened until needed, so this is non-blocking (on those systems diff --git a/stella/src/emucore/OSystem.hxx b/stella/src/emucore/OSystem.hxx index 2c9238e9a..57e2ddc01 100644 --- a/stella/src/emucore/OSystem.hxx +++ b/stella/src/emucore/OSystem.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: OSystem.hxx,v 1.58 2007-09-12 00:57:51 stephena Exp $ +// $Id: OSystem.hxx,v 1.59 2007-09-23 17:04:17 stephena Exp $ //============================================================================ #ifndef OSYSTEM_HXX @@ -30,6 +30,7 @@ class Properties; class PropertiesSet; class Settings; class Sound; +class StateManager; class VideoDialog; namespace GUI { @@ -54,7 +55,7 @@ typedef Common::Array ResolutionList; other objects belong. @author Stephen Anthony - @version $Id: OSystem.hxx,v 1.58 2007-09-12 00:57:51 stephena Exp $ + @version $Id: OSystem.hxx,v 1.59 2007-09-23 17:04:17 stephena Exp $ */ class OSystem { @@ -148,6 +149,13 @@ class OSystem */ inline Launcher& launcher(void) const { return *myLauncher; } + /** + Get the state manager of the system. + + @return The statemanager object + */ + inline StateManager& state(void) const { return *myStateManager; } + #ifdef DEBUGGER_SUPPORT /** Get the ROM debugger of the system. @@ -473,6 +481,9 @@ class OSystem // Pointer to the CheatManager object CheatManager* myCheatManager; + // Pointer to the StateManager object + StateManager* myStateManager; + // Maximum dimensions of the desktop area uInt32 myDesktopWidth, myDesktopHeight; diff --git a/stella/src/emucore/StateManager.cxx b/stella/src/emucore/StateManager.cxx new file mode 100644 index 000000000..b9b0ab14d --- /dev/null +++ b/stella/src/emucore/StateManager.cxx @@ -0,0 +1,151 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team +// +// See the file "license" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +// +// $Id: StateManager.cxx,v 1.1 2007-09-23 17:04:17 stephena Exp $ +//============================================================================ + +#include + +#include "OSystem.hxx" +#include "Serializer.hxx" +#include "Deserializer.hxx" +#include "Settings.hxx" +#include "Console.hxx" +#include "System.hxx" + +#include "StateManager.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +StateManager::StateManager(OSystem* osystem) + : myOSystem(osystem), + myCurrentSlot(0) +{ + reset(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +StateManager::~StateManager() +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void StateManager::loadState(int slot) +{ + if(&myOSystem->console()) + { + if(slot < 0) slot = myCurrentSlot; + + const string& name = myOSystem->console().properties().get(Cartridge_Name); + const string& md5 = myOSystem->console().properties().get(Cartridge_MD5); + + ostringstream buf; + buf << myOSystem->stateDir() << BSPF_PATH_SEPARATOR + << name << ".st" << slot; + + // Make sure the file can be opened for reading + Deserializer in; + if(!in.open(buf.str())) + { + buf.str(""); + buf << "Error loading state " << slot; + myOSystem->frameBuffer().showMessage(buf.str()); + return; + } + + // Do a state load using the System + buf.str(""); + if(myOSystem->console().system().loadState(md5, in)) + buf << "State " << slot << " loaded"; + else + buf << "Invalid state " << slot << " file"; + + in.close(); + myOSystem->frameBuffer().showMessage(buf.str()); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void StateManager::saveState(int slot) +{ + if(&myOSystem->console()) + { + if(slot < 0) slot = myCurrentSlot; + + const string& name = myOSystem->console().properties().get(Cartridge_Name); + const string& md5 = myOSystem->console().properties().get(Cartridge_MD5); + + ostringstream buf; + buf << myOSystem->stateDir() << BSPF_PATH_SEPARATOR + << name << ".st" << slot; + + // Make sure the file can be opened for writing + Serializer out; + if(!out.open(buf.str())) + { + myOSystem->frameBuffer().showMessage("Error saving state file"); + return; + } + + // Do a state save using the System + buf.str(""); +//int start = myOSystem->getTicks(); + if(myOSystem->console().system().saveState(md5, out)) + { +//int end = myOSystem->getTicks(); +//cerr << "ticks to save a state slot: " << (end - start) << endl; + + buf << "State " << slot << " saved"; + if(myOSystem->settings().getBool("autoslot")) + { + myCurrentSlot = (slot + 1) % 10; + buf << ", switching to slot " << slot; + } + } + else + buf << "Error saving state " << slot; + + out.close(); + myOSystem->frameBuffer().showMessage(buf.str()); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void StateManager::changeState() +{ + myCurrentSlot = (myCurrentSlot + 1) % 10; + + // Print appropriate message + ostringstream buf; + buf << "Changed to slot " << myCurrentSlot; + myOSystem->frameBuffer().showMessage(buf.str()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void StateManager::reset() +{ + myCurrentSlot = 0; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +StateManager::StateManager(const StateManager&) +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +StateManager& StateManager::operator = (const StateManager&) +{ + assert(false); + return *this; +} diff --git a/stella/src/emucore/StateManager.hxx b/stella/src/emucore/StateManager.hxx new file mode 100644 index 000000000..a11821efa --- /dev/null +++ b/stella/src/emucore/StateManager.hxx @@ -0,0 +1,85 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team +// +// See the file "license" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +// +// $Id: StateManager.hxx,v 1.1 2007-09-23 17:04:17 stephena Exp $ +//============================================================================ + +#ifndef STATE_MANAGER_HXX +#define STATE_MANAGER_HXX + +class OSystem; + +/** + This class provides an interface to all things related to emulation state. + States can be loaded or saved here, as well as recorded, rewound, and later + played back. + + @author Stephen Anthony + @version $Id: StateManager.hxx,v 1.1 2007-09-23 17:04:17 stephena Exp $ +*/ +class StateManager +{ + public: + /** + Create a new statemananger class + */ + StateManager(OSystem* osystem); + + /** + Destructor + */ + virtual ~StateManager(); + + public: + /** + Load a state into the current system + + @param slot The state 'slot' to load state from + */ + void loadState(int slot = -1); + + /** + Save the current state from the system + + @param slot The state 'slot' to save into + */ + void saveState(int slot = -1); + + /** + Switches to the next higher state slot (circular queue style) + */ + void changeState(); + + /** + Resets manager to defaults + */ + void reset(); + + private: + // Copy constructor isn't supported by this class so make it private + StateManager(const StateManager&); + + // Assignment operator isn't supported by this class so make it private + StateManager& operator = (const StateManager&); + + private: + // The parent OSystem object + OSystem* myOSystem; + + // The current slot for load/save states + int myCurrentSlot; +}; + +#endif diff --git a/stella/src/emucore/m6502/src/System.cxx b/stella/src/emucore/m6502/src/System.cxx index 83286f817..7b4aabb2b 100644 --- a/stella/src/emucore/m6502/src/System.cxx +++ b/stella/src/emucore/m6502/src/System.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: System.cxx,v 1.21 2007-01-01 18:04:51 stephena Exp $ +// $Id: System.cxx,v 1.22 2007-09-23 17:04:17 stephena Exp $ //============================================================================ #include @@ -205,7 +205,6 @@ const System::PageAccess& System::getPageAccess(uInt16 page) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool System::saveState(const string& md5sum, Serializer& out) { - // Open the file as a new Serializer if(!out.isOpen()) return false; @@ -245,7 +244,6 @@ bool System::saveState(const string& md5sum, Serializer& out) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool System::loadState(const string& md5sum, Deserializer& in) { - // Open the file as a new Deserializer if(!in.isOpen()) return false; diff --git a/stella/src/emucore/module.mk b/stella/src/emucore/module.mk index 6ebfca95d..0c9e8dab9 100644 --- a/stella/src/emucore/module.mk +++ b/stella/src/emucore/module.mk @@ -32,7 +32,6 @@ MODULE_OBJS := \ src/emucore/Driving.o \ src/emucore/Event.o \ src/emucore/EventHandler.o \ - src/emucore/EventStreamer.o \ src/emucore/FrameBuffer.o \ src/emucore/FSNode.o \ src/emucore/Joystick.o \ @@ -49,6 +48,7 @@ MODULE_OBJS := \ src/emucore/Settings.o \ src/emucore/SpeakJet.o \ src/emucore/Switches.o \ + src/emucore/StateManager.o \ src/emucore/TIA.o \ src/emucore/TIASnd.o \ src/emucore/unzip.o \