mirror of https://github.com/stella-emu/stella.git
Changed Serializer/Deserializer API in preparation for event recording.
Pressing 'Ctrl e' now starts/stops event recording (key is temporary and will probably change). An state file is then generated containing the state when recording started, and the eventstream up to the point when recording stopped. Next I'll work on loading the event state file and replaying the events. This one is a little harder, since it has to override EventHandler::poll() and use events from the eventstream. Hopefully rudimentary support will be there by the end of the weekend. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@906 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
a1c490cd21
commit
3b5cd56ca4
|
@ -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: Array.hxx,v 1.1 2005-12-09 01:16:13 stephena Exp $
|
||||
// $Id: Array.hxx,v 1.2 2005-12-09 19:09:49 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2002-2004 The ScummVM project
|
||||
|
@ -45,7 +45,7 @@ class Array
|
|||
Array<T>(const Array<T>& array) : _capacity(0), _size(0), _data(0)
|
||||
{
|
||||
_size = array._size;
|
||||
_capacity = _size + 32;
|
||||
_capacity = _size + 128;
|
||||
_data = new T[_capacity];
|
||||
for(int i = 0; i < _size; i++)
|
||||
_data[i] = array._data[i];
|
||||
|
@ -115,7 +115,7 @@ class Array
|
|||
if (_data)
|
||||
delete [] _data;
|
||||
_size = array._size;
|
||||
_capacity = _size + 32;
|
||||
_capacity = _size + 128;
|
||||
_data = new T[_capacity];
|
||||
for(int i = 0; i < _size; i++)
|
||||
_data[i] = array._data[i];
|
||||
|
@ -177,7 +177,7 @@ class Array
|
|||
return;
|
||||
|
||||
T *old_data = _data;
|
||||
_capacity = new_len + 32;
|
||||
_capacity = new_len + 128;
|
||||
_data = new T[_capacity];
|
||||
|
||||
if (old_data)
|
||||
|
|
|
@ -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: Deserializer.cxx,v 1.5 2005-10-29 18:11:29 stephena Exp $
|
||||
// $Id: Deserializer.cxx,v 1.6 2005-12-09 19:09:49 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <iostream>
|
||||
|
@ -43,7 +43,7 @@ bool Deserializer::open(const string& fileName)
|
|||
close();
|
||||
myStream = new ifstream(fileName.c_str(), ios::in | ios::binary);
|
||||
|
||||
return (myStream && myStream->is_open());
|
||||
return isOpen();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -59,6 +59,12 @@ void Deserializer::close(void)
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Deserializer::isOpen(void)
|
||||
{
|
||||
return myStream && myStream->is_open();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
long Deserializer::getLong(void)
|
||||
{
|
||||
|
|
|
@ -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: Deserializer.hxx,v 1.6 2005-06-16 01:11:27 stephena Exp $
|
||||
// $Id: Deserializer.hxx,v 1.7 2005-12-09 19:09:49 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef DESERIALIZER_HXX
|
||||
|
@ -32,7 +32,7 @@
|
|||
return.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: Deserializer.hxx,v 1.6 2005-06-16 01:11:27 stephena Exp $
|
||||
@version $Id: Deserializer.hxx,v 1.7 2005-12-09 19:09:49 stephena Exp $
|
||||
*/
|
||||
class Deserializer
|
||||
{
|
||||
|
@ -65,6 +65,11 @@ class Deserializer
|
|||
*/
|
||||
void close(void);
|
||||
|
||||
/**
|
||||
Answers whether the deserializer is currently opened
|
||||
*/
|
||||
bool isOpen(void);
|
||||
|
||||
/**
|
||||
Reads a long value from the current input stream.
|
||||
|
||||
|
|
|
@ -13,15 +13,16 @@
|
|||
// 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.4 2005-12-09 01:16:13 stephena Exp $
|
||||
// $Id: Event.cxx,v 1.5 2005-12-09 19:09:49 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include "Event.hxx"
|
||||
#include "Serializer.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Event::Event()
|
||||
: myNumberOfTypes(Event::LastType),
|
||||
myEventRecordFlag(true)
|
||||
myEventRecordFlag(false)
|
||||
{
|
||||
// Set all of the events to 0 / false to start with
|
||||
clear();
|
||||
|
@ -30,27 +31,6 @@ Event::Event()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Event::~Event()
|
||||
{
|
||||
int events = 0, waits = 0, totalwaits = 0;
|
||||
cerr << "Event history contains " << myEventHistory.size()/2 << " events\n";
|
||||
for(unsigned int i = 0; i < myEventHistory.size(); ++i)
|
||||
{
|
||||
int tmp = myEventHistory[i];
|
||||
if(tmp < 0)
|
||||
{
|
||||
++waits;
|
||||
totalwaits += -tmp;
|
||||
}
|
||||
else
|
||||
++events;
|
||||
|
||||
cerr << tmp << " ";
|
||||
}
|
||||
cerr << endl
|
||||
<< "events pairs = " << events/2
|
||||
<< ", frame waits = " << waits
|
||||
<< ", total frame waits = " << totalwaits
|
||||
<< endl;
|
||||
|
||||
myEventHistory.clear();
|
||||
}
|
||||
|
||||
|
@ -106,3 +86,15 @@ void Event::nextFrame()
|
|||
myEventHistory.push_back(-1);
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Event::save(Serializer& out)
|
||||
{
|
||||
int size = myEventHistory.size();
|
||||
out.putString("EventStream");
|
||||
out.putLong(size);
|
||||
for(int i = 0; i < size; ++i)
|
||||
out.putLong(myEventHistory[i]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -13,20 +13,21 @@
|
|||
// 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.14 2005-12-09 01:16:13 stephena Exp $
|
||||
// $Id: Event.hxx,v 1.15 2005-12-09 19:09:49 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef EVENT_HXX
|
||||
#define EVENT_HXX
|
||||
|
||||
class Event;
|
||||
class Serializer;
|
||||
|
||||
#include "Array.hxx"
|
||||
#include "bspf.hxx"
|
||||
|
||||
/**
|
||||
@author Bradford W. Mott
|
||||
@version $Id: Event.hxx,v 1.14 2005-12-09 01:16:13 stephena Exp $
|
||||
@version $Id: Event.hxx,v 1.15 2005-12-09 19:09:49 stephena Exp $
|
||||
*/
|
||||
class Event
|
||||
{
|
||||
|
@ -105,11 +106,6 @@ class Event
|
|||
*/
|
||||
virtual void clear();
|
||||
|
||||
/**
|
||||
Returns the history for this event
|
||||
*/
|
||||
virtual const IntArray& history() { return myEventHistory; }
|
||||
|
||||
/**
|
||||
Start/stop recording events to the event history
|
||||
|
||||
|
@ -122,6 +118,19 @@ class Event
|
|||
*/
|
||||
virtual void nextFrame();
|
||||
|
||||
/**
|
||||
Answers if we're in recording mode
|
||||
*/
|
||||
virtual bool isRecording() { return myEventRecordFlag; }
|
||||
|
||||
/**
|
||||
Saves the current event history to the given Serializer
|
||||
|
||||
@param out The serializer device to save to.
|
||||
@return The result of the save. True on success, false on failure.
|
||||
*/
|
||||
virtual bool save(Serializer& out);
|
||||
|
||||
protected:
|
||||
// Number of event types there are
|
||||
const Int32 myNumberOfTypes;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: EventHandler.cxx,v 1.124 2005-12-09 01:16:13 stephena Exp $
|
||||
// $Id: EventHandler.cxx,v 1.125 2005-12-09 19:09:49 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -33,6 +33,8 @@
|
|||
#include "CommandMenu.hxx"
|
||||
#include "Launcher.hxx"
|
||||
#include "GuiUtils.hxx"
|
||||
#include "Deserializer.hxx"
|
||||
#include "Serializer.hxx"
|
||||
#include "bspf.hxx"
|
||||
|
||||
#ifdef DEVELOPER_SUPPORT
|
||||
|
@ -139,6 +141,8 @@ EventHandler::EventHandler(OSystem* osystem)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
EventHandler::~EventHandler()
|
||||
{
|
||||
stopRecording();
|
||||
|
||||
if(myEvent)
|
||||
delete myEvent;
|
||||
|
||||
|
@ -524,6 +528,18 @@ void EventHandler::poll(uInt32 time)
|
|||
myOSystem->createConsole();
|
||||
break;
|
||||
|
||||
// FIXME - these will be removed when a UI is added for event recording
|
||||
case SDLK_e: // Ctrl-e starts/stops event recording
|
||||
if(myEvent->isRecording())
|
||||
stopRecording();
|
||||
else
|
||||
startRecording();
|
||||
break;
|
||||
|
||||
case SDLK_l: // Ctrl-l loads a recording
|
||||
loadRecording();
|
||||
break;
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
case SDLK_END: // Ctrl-End increases Width
|
||||
myOSystem->console().changeWidth(1);
|
||||
break;
|
||||
|
@ -1682,22 +1698,26 @@ inline bool EventHandler::eventIsAnalog(Event::Type event)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EventHandler::saveState()
|
||||
{
|
||||
// Do a state save using the System
|
||||
string md5 = myOSystem->console().properties().get("Cartridge.MD5");
|
||||
ostringstream buf;
|
||||
buf << myOSystem->stateDir() << BSPF_PATH_SEPARATOR << md5 << ".st" << myLSState;
|
||||
|
||||
int result = myOSystem->console().system().saveState(buf.str(), md5);
|
||||
// Make sure the file can be opened for writing
|
||||
Serializer out;
|
||||
if(!out.open(buf.str()))
|
||||
{
|
||||
myOSystem->frameBuffer().showMessage("Error saving state file");
|
||||
return;
|
||||
}
|
||||
|
||||
// Print appropriate message
|
||||
// Do a state save using the System
|
||||
buf.str("");
|
||||
if(result == 1)
|
||||
if(myOSystem->console().system().saveState(md5, out))
|
||||
buf << "State " << myLSState << " saved";
|
||||
else if(result == 2)
|
||||
buf << "Error saving state " << myLSState;
|
||||
else if(result == 3)
|
||||
else
|
||||
buf << "Invalid state " << myLSState << " file";
|
||||
|
||||
out.close();
|
||||
myOSystem->frameBuffer().showMessage(buf.str());
|
||||
}
|
||||
|
||||
|
@ -1723,22 +1743,28 @@ void EventHandler::changeState()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EventHandler::loadState()
|
||||
{
|
||||
// Do a state save using the System
|
||||
string md5 = myOSystem->console().properties().get("Cartridge.MD5");
|
||||
ostringstream buf;
|
||||
buf << myOSystem->stateDir() << BSPF_PATH_SEPARATOR << md5 << ".st" << myLSState;
|
||||
|
||||
int result = myOSystem->console().system().loadState(buf.str(), md5);
|
||||
|
||||
// Print appropriate message
|
||||
buf.str("");
|
||||
if(result == 1)
|
||||
buf << "State " << myLSState << " loaded";
|
||||
else if(result == 2)
|
||||
// Make sure the file can be opened for reading
|
||||
Deserializer in;
|
||||
if(!in.open(buf.str()))
|
||||
{
|
||||
buf.str("");
|
||||
buf << "Error loading state " << myLSState;
|
||||
else if(result == 3)
|
||||
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());
|
||||
}
|
||||
|
||||
|
@ -1806,6 +1832,50 @@ void EventHandler::takeSnapshot()
|
|||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EventHandler::startRecording()
|
||||
{
|
||||
if(myEvent->isRecording())
|
||||
return;
|
||||
|
||||
string eventfile = /*myOSystem->baseDir() + BSPF_PATH_SEPARATOR +*/ "test.inp";
|
||||
myEventStream.close();
|
||||
if(!myEventStream.open(eventfile))
|
||||
{
|
||||
myOSystem->frameBuffer().showMessage("Error opening eventstream");
|
||||
return;
|
||||
}
|
||||
|
||||
// And save the current state to it
|
||||
string md5 = myOSystem->console().properties().get("Cartridge.MD5");
|
||||
myOSystem->console().system().saveState(md5, myEventStream);
|
||||
|
||||
myEvent->record(true);
|
||||
myOSystem->frameBuffer().showMessage("Recording started");
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EventHandler::stopRecording()
|
||||
{
|
||||
if(!myEvent->isRecording())
|
||||
return;
|
||||
|
||||
// Append the event history to the eventstream
|
||||
myEvent->save(myEventStream);
|
||||
|
||||
// And reset the state
|
||||
myEvent->record(false);
|
||||
myOSystem->frameBuffer().showMessage("Recording stopped");
|
||||
|
||||
myEventStream.close();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EventHandler::loadRecording()
|
||||
{
|
||||
cerr << "load recording!\n";
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EventHandler::setPaddleMode(uInt32 num, bool showmessage)
|
||||
{
|
||||
|
|
|
@ -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.62 2005-12-08 19:01:38 stephena Exp $
|
||||
// $Id: EventHandler.hxx,v 1.63 2005-12-09 19:09:49 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef EVENTHANDLER_HXX
|
||||
|
@ -26,6 +26,7 @@
|
|||
#include "Array.hxx"
|
||||
#include "Control.hxx"
|
||||
#include "StringList.hxx"
|
||||
#include "Serializer.hxx"
|
||||
|
||||
class Console;
|
||||
class OSystem;
|
||||
|
@ -90,7 +91,7 @@ struct Stella_Joystick {
|
|||
mapping can take place.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: EventHandler.hxx,v 1.62 2005-12-08 19:01:38 stephena Exp $
|
||||
@version $Id: EventHandler.hxx,v 1.63 2005-12-09 19:09:49 stephena Exp $
|
||||
*/
|
||||
class EventHandler
|
||||
{
|
||||
|
@ -220,12 +221,27 @@ class EventHandler
|
|||
/**
|
||||
Save state to explicit state number (debugger uses this)
|
||||
*/
|
||||
void saveState(int state);
|
||||
void saveState(int state);
|
||||
|
||||
/**
|
||||
Load state from explicit state number (debugger uses this)
|
||||
*/
|
||||
void loadState(int state);
|
||||
void loadState(int state);
|
||||
|
||||
/**
|
||||
Start recording event-stream to disk
|
||||
*/
|
||||
void startRecording();
|
||||
|
||||
/**
|
||||
Stop recording event-stream
|
||||
*/
|
||||
void stopRecording();
|
||||
|
||||
/**
|
||||
Load recorded event-stream into the system
|
||||
*/
|
||||
void loadRecording();
|
||||
|
||||
/**
|
||||
Sets the mouse to act as paddle 'num'
|
||||
|
@ -403,6 +419,9 @@ class EventHandler
|
|||
// Indicates the current state of the system (ie, which mode is current)
|
||||
State myState;
|
||||
|
||||
// The serializer to use for saving eventstreams
|
||||
Serializer myEventStream;
|
||||
|
||||
// Indicates current overlay object
|
||||
DialogContainer* myOverlay;
|
||||
|
||||
|
|
|
@ -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: Serializer.cxx,v 1.5 2005-06-16 01:11:28 stephena Exp $
|
||||
// $Id: Serializer.cxx,v 1.6 2005-12-09 19:09:49 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <iostream>
|
||||
|
@ -43,7 +43,7 @@ bool Serializer::open(const string& fileName)
|
|||
close();
|
||||
myStream = new ofstream(fileName.c_str(), ios::out | ios::binary);
|
||||
|
||||
return (myStream && myStream->is_open());
|
||||
return isOpen();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -59,6 +59,12 @@ void Serializer::close(void)
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Serializer::isOpen(void)
|
||||
{
|
||||
return myStream && myStream->is_open();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Serializer::putLong(long 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: Serializer.hxx,v 1.7 2005-06-16 01:11:28 stephena Exp $
|
||||
// $Id: Serializer.hxx,v 1.8 2005-12-09 19:09:49 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef SERIALIZER_HXX
|
||||
|
@ -33,7 +33,7 @@
|
|||
Boolean values are written using a special pattern.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: Serializer.hxx,v 1.7 2005-06-16 01:11:28 stephena Exp $
|
||||
@version $Id: Serializer.hxx,v 1.8 2005-12-09 19:09:49 stephena Exp $
|
||||
*/
|
||||
class Serializer
|
||||
{
|
||||
|
@ -66,6 +66,11 @@ class Serializer
|
|||
*/
|
||||
void close(void);
|
||||
|
||||
/**
|
||||
Answers whether the serializer is currently opened
|
||||
*/
|
||||
bool isOpen(void);
|
||||
|
||||
/**
|
||||
Writes a long value to the current output stream.
|
||||
|
||||
|
|
|
@ -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.13 2005-07-09 23:44:08 urchlay Exp $
|
||||
// $Id: System.cxx,v 1.14 2005-12-09 19:09:49 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -54,10 +54,6 @@ System::System(uInt16 n, uInt16 m)
|
|||
setPageAccess(page, access);
|
||||
}
|
||||
|
||||
// Set up (de)serializer in case we are asked to save/load state
|
||||
serializer = new Serializer();
|
||||
deserializer = new Deserializer();
|
||||
|
||||
// Bus starts out unlocked (in other words, peek() changes myDataBusState)
|
||||
myDataBusLocked = false;
|
||||
}
|
||||
|
@ -76,12 +72,6 @@ System::~System()
|
|||
|
||||
// Free my page access table
|
||||
delete[] myPageAccessTable;
|
||||
|
||||
// Free the serializer stuff
|
||||
if(serializer)
|
||||
delete serializer;
|
||||
if(deserializer)
|
||||
delete deserializer;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -135,11 +125,9 @@ void System::attach(TIA* tia)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool System::save(Serializer& out)
|
||||
{
|
||||
string name = "System";
|
||||
|
||||
try
|
||||
{
|
||||
out.putString(name);
|
||||
out.putString("System");
|
||||
out.putLong(myCycles);
|
||||
}
|
||||
catch(char *msg)
|
||||
|
@ -149,7 +137,7 @@ bool System::save(Serializer& out)
|
|||
}
|
||||
catch(...)
|
||||
{
|
||||
cerr << "Unknown error in save state for " << name << endl;
|
||||
cerr << "Unknown error in save state for \'System\'" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -159,11 +147,9 @@ bool System::save(Serializer& out)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool System::load(Deserializer& in)
|
||||
{
|
||||
string name = "System";
|
||||
|
||||
try
|
||||
{
|
||||
if(in.getString() != name)
|
||||
if(in.getString() != "System")
|
||||
return false;
|
||||
|
||||
myCycles = (uInt32) in.getLong();
|
||||
|
@ -175,7 +161,7 @@ bool System::load(Deserializer& in)
|
|||
}
|
||||
catch(...)
|
||||
{
|
||||
cerr << "Unknown error in load state for " << name << endl;
|
||||
cerr << "Unknown error in load state for \'System\'" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -217,91 +203,58 @@ const System::PageAccess& System::getPageAccess(uInt16 page)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
int System::saveState(const string& fileName, const string& md5sum)
|
||||
bool System::saveState(const string& md5sum, Serializer& out)
|
||||
{
|
||||
// Open the file as a new Serializer
|
||||
if(!serializer->open(fileName))
|
||||
{
|
||||
serializer->close();
|
||||
return 2;
|
||||
}
|
||||
if(!out.isOpen())
|
||||
return false;
|
||||
|
||||
// Prepend the state file with the md5sum of this cartridge
|
||||
// This is the first defensive check for an invalid state file
|
||||
serializer->putString(md5sum);
|
||||
out.putString(md5sum);
|
||||
|
||||
// First save state for this system
|
||||
if(!save(*serializer))
|
||||
{
|
||||
serializer->close();
|
||||
return 3;
|
||||
}
|
||||
if(!save(out))
|
||||
return false;
|
||||
|
||||
// Next, save state for the CPU
|
||||
if(!myM6502->save(*serializer))
|
||||
{
|
||||
serializer->close();
|
||||
return 3;
|
||||
}
|
||||
if(!myM6502->save(out))
|
||||
return false;
|
||||
|
||||
// Now save the state of each device
|
||||
for(uInt32 i = 0; i < myNumberOfDevices; ++i)
|
||||
{
|
||||
if(!myDevices[i]->save(*serializer))
|
||||
{
|
||||
serializer->close();
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
if(!myDevices[i]->save(out))
|
||||
return false;
|
||||
|
||||
serializer->close();
|
||||
return 1; // success
|
||||
return true; // success
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
int System::loadState(const string &fileName, const string& md5sum)
|
||||
bool System::loadState(const string& md5sum, Deserializer& in)
|
||||
{
|
||||
// Open the file as a new Deserializer
|
||||
if(!deserializer->open(fileName))
|
||||
{
|
||||
deserializer->close();
|
||||
return 2;
|
||||
}
|
||||
if(!in.isOpen())
|
||||
return false;
|
||||
|
||||
// Look at the beginning of the state file. It should contain the md5sum
|
||||
// of the current cartridge. If it doesn't, this state file is invalid.
|
||||
if(deserializer->getString() != md5sum)
|
||||
{
|
||||
deserializer->close();
|
||||
return 3;
|
||||
}
|
||||
if(in.getString() != md5sum)
|
||||
return false;
|
||||
|
||||
// First load state for this system
|
||||
if(!load(*deserializer))
|
||||
{
|
||||
deserializer->close();
|
||||
return 3;
|
||||
}
|
||||
if(!load(in))
|
||||
return false;
|
||||
|
||||
// Next, load state for the CPU
|
||||
if(!myM6502->load(*deserializer))
|
||||
{
|
||||
deserializer->close();
|
||||
return 3;
|
||||
}
|
||||
if(!myM6502->load(in))
|
||||
return false;
|
||||
|
||||
// Now load the state of each device
|
||||
for(uInt32 i = 0; i < myNumberOfDevices; ++i)
|
||||
{
|
||||
if(!myDevices[i]->load(*deserializer))
|
||||
{
|
||||
deserializer->close();
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
if(!myDevices[i]->load(in))
|
||||
return false;
|
||||
|
||||
deserializer->close();
|
||||
return 1; // success
|
||||
return true; // success
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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.hxx,v 1.11 2005-08-24 22:54:30 stephena Exp $
|
||||
// $Id: System.hxx,v 1.12 2005-12-09 19:09:49 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef SYSTEM_HXX
|
||||
|
@ -47,7 +47,7 @@ class Deserializer;
|
|||
dynamic code for that page of memory.
|
||||
|
||||
@author Bradford W. Mott
|
||||
@version $Id: System.hxx,v 1.11 2005-08-24 22:54:30 stephena Exp $
|
||||
@version $Id: System.hxx,v 1.12 2005-12-09 19:09:49 stephena Exp $
|
||||
*/
|
||||
class System
|
||||
{
|
||||
|
@ -118,25 +118,23 @@ class System
|
|||
Saves the current state of Stella to the given file. Calls
|
||||
save on every device and CPU attached to this system.
|
||||
|
||||
@param out The serializer device to save to.
|
||||
@return The result of the save. Error codes as follows:
|
||||
1 success
|
||||
2 file could not be opened for read/write
|
||||
3 invalid state file
|
||||
@param md5sum MD5 of the current ROM
|
||||
@param out The serializer device to save to
|
||||
|
||||
@return False on any errors, else true
|
||||
*/
|
||||
int saveState(const string& fileName, const string& md5sum);
|
||||
bool saveState(const string& md5sum, Serializer& out);
|
||||
|
||||
/**
|
||||
Loads the current state of Stella from the given file. Calls
|
||||
load on every device and CPU attached to this system.
|
||||
|
||||
@param in The deserializer device to load from.
|
||||
@return The result of the load. Error codes as follows:
|
||||
1 success
|
||||
2 file could not be opened for read/write
|
||||
3 invalid state file
|
||||
@param md5sum MD5 of the current ROM
|
||||
@param in The deserializer device to load from
|
||||
|
||||
@return False on any errors, else true
|
||||
*/
|
||||
int loadState(const string& fileName, const string& md5sum);
|
||||
bool loadState(const string& md5sum, Deserializer& in);
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -359,12 +357,6 @@ class System
|
|||
// debugger is active.
|
||||
bool myDataBusLocked;
|
||||
|
||||
// The serializer for the system. Used to save state.
|
||||
Serializer* serializer;
|
||||
|
||||
// The deserializer for the system. Used to load state.
|
||||
Deserializer* deserializer;
|
||||
|
||||
private:
|
||||
// Copy constructor isn't supported by this class so make it private
|
||||
System(const System&);
|
||||
|
|
Loading…
Reference in New Issue