Reworked state load and save, placing it in a new StateManager class,

and removing it from EventHandler.  For now, this is just a code
re-arrangment, but eventually state recording and rewinding will be added
to this new class as well.  Since this new class will now do the job of the
(buggy) EventStreamer code, that class has been removed.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1381 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2007-09-23 17:04:17 +00:00
parent 0f386e43b6
commit 938249cd71
13 changed files with 284 additions and 493 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: 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);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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);
*/
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

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: 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

View File

@ -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 <sstream>
@ -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()
{

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.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;

View File

@ -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);
}
}

View File

@ -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

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.110 2007-09-03 18:37:22 stephena Exp $
// $Id: OSystem.cxx,v 1.111 2007-09-23 17:04:17 stephena Exp $
//============================================================================
#include <cassert>
@ -21,6 +21,8 @@
#include <fstream>
#include <zlib.h>
#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

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: OSystem.hxx,v 1.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<Resolution> 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;

View File

@ -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 <sstream>
#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;
}

View File

@ -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

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: 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 <assert.h>
@ -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;

View File

@ -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 \