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
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// 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
|
// Based on code from ScummVM - Scumm Interpreter
|
||||||
// Copyright (C) 2002-2004 The ScummVM project
|
// 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)
|
Array<T>(const Array<T>& array) : _capacity(0), _size(0), _data(0)
|
||||||
{
|
{
|
||||||
_size = array._size;
|
_size = array._size;
|
||||||
_capacity = _size + 32;
|
_capacity = _size + 128;
|
||||||
_data = new T[_capacity];
|
_data = new T[_capacity];
|
||||||
for(int i = 0; i < _size; i++)
|
for(int i = 0; i < _size; i++)
|
||||||
_data[i] = array._data[i];
|
_data[i] = array._data[i];
|
||||||
|
@ -115,7 +115,7 @@ class Array
|
||||||
if (_data)
|
if (_data)
|
||||||
delete [] _data;
|
delete [] _data;
|
||||||
_size = array._size;
|
_size = array._size;
|
||||||
_capacity = _size + 32;
|
_capacity = _size + 128;
|
||||||
_data = new T[_capacity];
|
_data = new T[_capacity];
|
||||||
for(int i = 0; i < _size; i++)
|
for(int i = 0; i < _size; i++)
|
||||||
_data[i] = array._data[i];
|
_data[i] = array._data[i];
|
||||||
|
@ -177,7 +177,7 @@ class Array
|
||||||
return;
|
return;
|
||||||
|
|
||||||
T *old_data = _data;
|
T *old_data = _data;
|
||||||
_capacity = new_len + 32;
|
_capacity = new_len + 128;
|
||||||
_data = new T[_capacity];
|
_data = new T[_capacity];
|
||||||
|
|
||||||
if (old_data)
|
if (old_data)
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// 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>
|
#include <iostream>
|
||||||
|
@ -43,7 +43,7 @@ bool Deserializer::open(const string& fileName)
|
||||||
close();
|
close();
|
||||||
myStream = new ifstream(fileName.c_str(), ios::in | ios::binary);
|
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)
|
long Deserializer::getLong(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// 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
|
#ifndef DESERIALIZER_HXX
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
return.
|
return.
|
||||||
|
|
||||||
@author Stephen Anthony
|
@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
|
class Deserializer
|
||||||
{
|
{
|
||||||
|
@ -65,6 +65,11 @@ class Deserializer
|
||||||
*/
|
*/
|
||||||
void close(void);
|
void close(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Answers whether the deserializer is currently opened
|
||||||
|
*/
|
||||||
|
bool isOpen(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Reads a long value from the current input stream.
|
Reads a long value from the current input stream.
|
||||||
|
|
||||||
|
|
|
@ -13,15 +13,16 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// 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 "Event.hxx"
|
||||||
|
#include "Serializer.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Event::Event()
|
Event::Event()
|
||||||
: myNumberOfTypes(Event::LastType),
|
: myNumberOfTypes(Event::LastType),
|
||||||
myEventRecordFlag(true)
|
myEventRecordFlag(false)
|
||||||
{
|
{
|
||||||
// Set all of the events to 0 / false to start with
|
// Set all of the events to 0 / false to start with
|
||||||
clear();
|
clear();
|
||||||
|
@ -30,27 +31,6 @@ Event::Event()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
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();
|
myEventHistory.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,3 +86,15 @@ void Event::nextFrame()
|
||||||
myEventHistory.push_back(-1);
|
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
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// 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
|
#ifndef EVENT_HXX
|
||||||
#define EVENT_HXX
|
#define EVENT_HXX
|
||||||
|
|
||||||
class Event;
|
class Event;
|
||||||
|
class Serializer;
|
||||||
|
|
||||||
#include "Array.hxx"
|
#include "Array.hxx"
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@author Bradford W. Mott
|
@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
|
class Event
|
||||||
{
|
{
|
||||||
|
@ -105,11 +106,6 @@ class Event
|
||||||
*/
|
*/
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
|
||||||
/**
|
|
||||||
Returns the history for this event
|
|
||||||
*/
|
|
||||||
virtual const IntArray& history() { return myEventHistory; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Start/stop recording events to the event history
|
Start/stop recording events to the event history
|
||||||
|
|
||||||
|
@ -122,6 +118,19 @@ class Event
|
||||||
*/
|
*/
|
||||||
virtual void nextFrame();
|
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:
|
protected:
|
||||||
// Number of event types there are
|
// Number of event types there are
|
||||||
const Int32 myNumberOfTypes;
|
const Int32 myNumberOfTypes;
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// 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>
|
#include <algorithm>
|
||||||
|
@ -33,6 +33,8 @@
|
||||||
#include "CommandMenu.hxx"
|
#include "CommandMenu.hxx"
|
||||||
#include "Launcher.hxx"
|
#include "Launcher.hxx"
|
||||||
#include "GuiUtils.hxx"
|
#include "GuiUtils.hxx"
|
||||||
|
#include "Deserializer.hxx"
|
||||||
|
#include "Serializer.hxx"
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
|
|
||||||
#ifdef DEVELOPER_SUPPORT
|
#ifdef DEVELOPER_SUPPORT
|
||||||
|
@ -139,6 +141,8 @@ EventHandler::EventHandler(OSystem* osystem)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
EventHandler::~EventHandler()
|
EventHandler::~EventHandler()
|
||||||
{
|
{
|
||||||
|
stopRecording();
|
||||||
|
|
||||||
if(myEvent)
|
if(myEvent)
|
||||||
delete myEvent;
|
delete myEvent;
|
||||||
|
|
||||||
|
@ -524,6 +528,18 @@ void EventHandler::poll(uInt32 time)
|
||||||
myOSystem->createConsole();
|
myOSystem->createConsole();
|
||||||
break;
|
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
|
case SDLK_END: // Ctrl-End increases Width
|
||||||
myOSystem->console().changeWidth(1);
|
myOSystem->console().changeWidth(1);
|
||||||
break;
|
break;
|
||||||
|
@ -1682,22 +1698,26 @@ inline bool EventHandler::eventIsAnalog(Event::Type event)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void EventHandler::saveState()
|
void EventHandler::saveState()
|
||||||
{
|
{
|
||||||
// Do a state save using the System
|
|
||||||
string md5 = myOSystem->console().properties().get("Cartridge.MD5");
|
string md5 = myOSystem->console().properties().get("Cartridge.MD5");
|
||||||
ostringstream buf;
|
ostringstream buf;
|
||||||
buf << myOSystem->stateDir() << BSPF_PATH_SEPARATOR << md5 << ".st" << myLSState;
|
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("");
|
buf.str("");
|
||||||
if(result == 1)
|
if(myOSystem->console().system().saveState(md5, out))
|
||||||
buf << "State " << myLSState << " saved";
|
buf << "State " << myLSState << " saved";
|
||||||
else if(result == 2)
|
else
|
||||||
buf << "Error saving state " << myLSState;
|
|
||||||
else if(result == 3)
|
|
||||||
buf << "Invalid state " << myLSState << " file";
|
buf << "Invalid state " << myLSState << " file";
|
||||||
|
|
||||||
|
out.close();
|
||||||
myOSystem->frameBuffer().showMessage(buf.str());
|
myOSystem->frameBuffer().showMessage(buf.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1723,22 +1743,28 @@ void EventHandler::changeState()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void EventHandler::loadState()
|
void EventHandler::loadState()
|
||||||
{
|
{
|
||||||
// Do a state save using the System
|
|
||||||
string md5 = myOSystem->console().properties().get("Cartridge.MD5");
|
string md5 = myOSystem->console().properties().get("Cartridge.MD5");
|
||||||
ostringstream buf;
|
ostringstream buf;
|
||||||
buf << myOSystem->stateDir() << BSPF_PATH_SEPARATOR << md5 << ".st" << myLSState;
|
buf << myOSystem->stateDir() << BSPF_PATH_SEPARATOR << md5 << ".st" << myLSState;
|
||||||
|
|
||||||
int result = myOSystem->console().system().loadState(buf.str(), md5);
|
// Make sure the file can be opened for reading
|
||||||
|
Deserializer in;
|
||||||
// Print appropriate message
|
if(!in.open(buf.str()))
|
||||||
buf.str("");
|
{
|
||||||
if(result == 1)
|
buf.str("");
|
||||||
buf << "State " << myLSState << " loaded";
|
|
||||||
else if(result == 2)
|
|
||||||
buf << "Error loading state " << myLSState;
|
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";
|
buf << "Invalid state " << myLSState << " file";
|
||||||
|
|
||||||
|
in.close();
|
||||||
myOSystem->frameBuffer().showMessage(buf.str());
|
myOSystem->frameBuffer().showMessage(buf.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1806,6 +1832,50 @@ void EventHandler::takeSnapshot()
|
||||||
#endif
|
#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)
|
void EventHandler::setPaddleMode(uInt32 num, bool showmessage)
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// 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
|
#ifndef EVENTHANDLER_HXX
|
||||||
|
@ -26,6 +26,7 @@
|
||||||
#include "Array.hxx"
|
#include "Array.hxx"
|
||||||
#include "Control.hxx"
|
#include "Control.hxx"
|
||||||
#include "StringList.hxx"
|
#include "StringList.hxx"
|
||||||
|
#include "Serializer.hxx"
|
||||||
|
|
||||||
class Console;
|
class Console;
|
||||||
class OSystem;
|
class OSystem;
|
||||||
|
@ -90,7 +91,7 @@ struct Stella_Joystick {
|
||||||
mapping can take place.
|
mapping can take place.
|
||||||
|
|
||||||
@author Stephen Anthony
|
@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
|
class EventHandler
|
||||||
{
|
{
|
||||||
|
@ -220,12 +221,27 @@ class EventHandler
|
||||||
/**
|
/**
|
||||||
Save state to explicit state number (debugger uses this)
|
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)
|
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'
|
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)
|
// Indicates the current state of the system (ie, which mode is current)
|
||||||
State myState;
|
State myState;
|
||||||
|
|
||||||
|
// The serializer to use for saving eventstreams
|
||||||
|
Serializer myEventStream;
|
||||||
|
|
||||||
// Indicates current overlay object
|
// Indicates current overlay object
|
||||||
DialogContainer* myOverlay;
|
DialogContainer* myOverlay;
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// 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>
|
#include <iostream>
|
||||||
|
@ -43,7 +43,7 @@ bool Serializer::open(const string& fileName)
|
||||||
close();
|
close();
|
||||||
myStream = new ofstream(fileName.c_str(), ios::out | ios::binary);
|
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)
|
void Serializer::putLong(long value)
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// 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
|
#ifndef SERIALIZER_HXX
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
Boolean values are written using a special pattern.
|
Boolean values are written using a special pattern.
|
||||||
|
|
||||||
@author Stephen Anthony
|
@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
|
class Serializer
|
||||||
{
|
{
|
||||||
|
@ -66,6 +66,11 @@ class Serializer
|
||||||
*/
|
*/
|
||||||
void close(void);
|
void close(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Answers whether the serializer is currently opened
|
||||||
|
*/
|
||||||
|
bool isOpen(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Writes a long value to the current output stream.
|
Writes a long value to the current output stream.
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// 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>
|
#include <assert.h>
|
||||||
|
@ -54,10 +54,6 @@ System::System(uInt16 n, uInt16 m)
|
||||||
setPageAccess(page, access);
|
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)
|
// Bus starts out unlocked (in other words, peek() changes myDataBusState)
|
||||||
myDataBusLocked = false;
|
myDataBusLocked = false;
|
||||||
}
|
}
|
||||||
|
@ -76,12 +72,6 @@ System::~System()
|
||||||
|
|
||||||
// Free my page access table
|
// Free my page access table
|
||||||
delete[] myPageAccessTable;
|
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)
|
bool System::save(Serializer& out)
|
||||||
{
|
{
|
||||||
string name = "System";
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
out.putString(name);
|
out.putString("System");
|
||||||
out.putLong(myCycles);
|
out.putLong(myCycles);
|
||||||
}
|
}
|
||||||
catch(char *msg)
|
catch(char *msg)
|
||||||
|
@ -149,7 +137,7 @@ bool System::save(Serializer& out)
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
cerr << "Unknown error in save state for " << name << endl;
|
cerr << "Unknown error in save state for \'System\'" << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,11 +147,9 @@ bool System::save(Serializer& out)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool System::load(Deserializer& in)
|
bool System::load(Deserializer& in)
|
||||||
{
|
{
|
||||||
string name = "System";
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(in.getString() != name)
|
if(in.getString() != "System")
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
myCycles = (uInt32) in.getLong();
|
myCycles = (uInt32) in.getLong();
|
||||||
|
@ -175,7 +161,7 @@ bool System::load(Deserializer& in)
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
cerr << "Unknown error in load state for " << name << endl;
|
cerr << "Unknown error in load state for \'System\'" << endl;
|
||||||
return false;
|
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
|
// Open the file as a new Serializer
|
||||||
if(!serializer->open(fileName))
|
if(!out.isOpen())
|
||||||
{
|
return false;
|
||||||
serializer->close();
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepend the state file with the md5sum of this cartridge
|
// Prepend the state file with the md5sum of this cartridge
|
||||||
// This is the first defensive check for an invalid state file
|
// This is the first defensive check for an invalid state file
|
||||||
serializer->putString(md5sum);
|
out.putString(md5sum);
|
||||||
|
|
||||||
// First save state for this system
|
// First save state for this system
|
||||||
if(!save(*serializer))
|
if(!save(out))
|
||||||
{
|
return false;
|
||||||
serializer->close();
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next, save state for the CPU
|
// Next, save state for the CPU
|
||||||
if(!myM6502->save(*serializer))
|
if(!myM6502->save(out))
|
||||||
{
|
return false;
|
||||||
serializer->close();
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now save the state of each device
|
// Now save the state of each device
|
||||||
for(uInt32 i = 0; i < myNumberOfDevices; ++i)
|
for(uInt32 i = 0; i < myNumberOfDevices; ++i)
|
||||||
{
|
if(!myDevices[i]->save(out))
|
||||||
if(!myDevices[i]->save(*serializer))
|
return false;
|
||||||
{
|
|
||||||
serializer->close();
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
serializer->close();
|
return true; // success
|
||||||
return 1; // 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
|
// Open the file as a new Deserializer
|
||||||
if(!deserializer->open(fileName))
|
if(!in.isOpen())
|
||||||
{
|
return false;
|
||||||
deserializer->close();
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look at the beginning of the state file. It should contain the md5sum
|
// 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.
|
// of the current cartridge. If it doesn't, this state file is invalid.
|
||||||
if(deserializer->getString() != md5sum)
|
if(in.getString() != md5sum)
|
||||||
{
|
return false;
|
||||||
deserializer->close();
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// First load state for this system
|
// First load state for this system
|
||||||
if(!load(*deserializer))
|
if(!load(in))
|
||||||
{
|
return false;
|
||||||
deserializer->close();
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next, load state for the CPU
|
// Next, load state for the CPU
|
||||||
if(!myM6502->load(*deserializer))
|
if(!myM6502->load(in))
|
||||||
{
|
return false;
|
||||||
deserializer->close();
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now load the state of each device
|
// Now load the state of each device
|
||||||
for(uInt32 i = 0; i < myNumberOfDevices; ++i)
|
for(uInt32 i = 0; i < myNumberOfDevices; ++i)
|
||||||
{
|
if(!myDevices[i]->load(in))
|
||||||
if(!myDevices[i]->load(*deserializer))
|
return false;
|
||||||
{
|
|
||||||
deserializer->close();
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deserializer->close();
|
return true; // success
|
||||||
return 1; // success
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// 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
|
#ifndef SYSTEM_HXX
|
||||||
|
@ -47,7 +47,7 @@ class Deserializer;
|
||||||
dynamic code for that page of memory.
|
dynamic code for that page of memory.
|
||||||
|
|
||||||
@author Bradford W. Mott
|
@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
|
class System
|
||||||
{
|
{
|
||||||
|
@ -118,25 +118,23 @@ class System
|
||||||
Saves the current state of Stella to the given file. Calls
|
Saves the current state of Stella to the given file. Calls
|
||||||
save on every device and CPU attached to this system.
|
save on every device and CPU attached to this system.
|
||||||
|
|
||||||
@param out The serializer device to save to.
|
@param md5sum MD5 of the current ROM
|
||||||
@return The result of the save. Error codes as follows:
|
@param out The serializer device to save to
|
||||||
1 success
|
|
||||||
2 file could not be opened for read/write
|
@return False on any errors, else true
|
||||||
3 invalid state file
|
|
||||||
*/
|
*/
|
||||||
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
|
Loads the current state of Stella from the given file. Calls
|
||||||
load on every device and CPU attached to this system.
|
load on every device and CPU attached to this system.
|
||||||
|
|
||||||
@param in The deserializer device to load from.
|
@param md5sum MD5 of the current ROM
|
||||||
@return The result of the load. Error codes as follows:
|
@param in The deserializer device to load from
|
||||||
1 success
|
|
||||||
2 file could not be opened for read/write
|
@return False on any errors, else true
|
||||||
3 invalid state file
|
|
||||||
*/
|
*/
|
||||||
int loadState(const string& fileName, const string& md5sum);
|
bool loadState(const string& md5sum, Deserializer& in);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -359,12 +357,6 @@ class System
|
||||||
// debugger is active.
|
// debugger is active.
|
||||||
bool myDataBusLocked;
|
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:
|
private:
|
||||||
// Copy constructor isn't supported by this class so make it private
|
// Copy constructor isn't supported by this class so make it private
|
||||||
System(const System&);
|
System(const System&);
|
||||||
|
|
Loading…
Reference in New Issue