mirror of https://github.com/stella-emu/stella.git
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:
parent
0f386e43b6
commit
938249cd71
|
@ -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);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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);
|
||||
*/
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
Loading…
Reference in New Issue