From 6818da1566f2d4dc4b1726d89ee62ff3641f96d1 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 25 Nov 2016 14:58:07 -0330 Subject: [PATCH] Added savestate 'plumbing', for when the new TIA classes are finalized. Bumped lowest version of state file format to 4.8, to make sure old state files will not be loaded. --- src/emucore/StateManager.cxx | 2 +- src/emucore/tia/core_6502ts/Ball.cxx | 41 +++++++++++++- src/emucore/tia/core_6502ts/Ball.hxx | 12 ++++- src/emucore/tia/core_6502ts/FrameManager.cxx | 39 ++++++++++++++ src/emucore/tia/core_6502ts/FrameManager.hxx | 12 ++++- src/emucore/tia/core_6502ts/Missile.cxx | 39 ++++++++++++++ src/emucore/tia/core_6502ts/Missile.hxx | 10 +++- src/emucore/tia/core_6502ts/Player.cxx | 39 ++++++++++++++ src/emucore/tia/core_6502ts/Player.hxx | 10 +++- src/emucore/tia/core_6502ts/Playfield.cxx | 39 ++++++++++++++ src/emucore/tia/core_6502ts/Playfield.hxx | 10 +++- src/emucore/tia/core_6502ts/TIA.cxx | 57 +++++++++++++++++--- src/emucore/tia/core_6502ts/TIA.hxx | 42 +++++++++++---- 13 files changed, 326 insertions(+), 26 deletions(-) diff --git a/src/emucore/StateManager.cxx b/src/emucore/StateManager.cxx index e9a0e68e5..ad4dfe73d 100644 --- a/src/emucore/StateManager.cxx +++ b/src/emucore/StateManager.cxx @@ -30,7 +30,7 @@ #include "StateManager.hxx" -#define STATE_HEADER "03090100state" +#define STATE_HEADER "04080000state" #define MOVIE_HEADER "03030000movie" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/tia/core_6502ts/Ball.cxx b/src/emucore/tia/core_6502ts/Ball.cxx index b59d2c721..f22618462 100644 --- a/src/emucore/tia/core_6502ts/Ball.cxx +++ b/src/emucore/tia/core_6502ts/Ball.cxx @@ -150,4 +150,43 @@ void Ball::updateEnabled() myEnabled = myIsDelaying ? myEnabledOld : myEnabledNew; } -} // namespace TIA6502tsCore \ No newline at end of file +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TODO: implement this once the class is finalized +bool Ball::save(Serializer& out) const +{ + try + { + out.putString(name()); + + // TODO - save instance variables + } + catch(...) + { + cerr << "ERROR: TIA_Ball::save" << endl; + return false; + } + + return false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TODO: implement this once the class is finalized +bool Ball::load(Serializer& in) +{ + try + { + if(in.getString() != name()) + return false; + + // TODO - load instance variables + } + catch(...) + { + cerr << "ERROR: TIA_Ball::load" << endl; + return false; + } + + return false; +} + +} // namespace TIA6502tsCore diff --git a/src/emucore/tia/core_6502ts/Ball.hxx b/src/emucore/tia/core_6502ts/Ball.hxx index d7ac4eb2d..84c28933d 100644 --- a/src/emucore/tia/core_6502ts/Ball.hxx +++ b/src/emucore/tia/core_6502ts/Ball.hxx @@ -20,11 +20,12 @@ #ifndef TIA_6502TS_CORE_BALL #define TIA_6502TS_CORE_BALL +#include "Serializable.hxx" #include "bspf.hxx" namespace TIA6502tsCore { -class Ball +class Ball : public Serializable { public: @@ -58,6 +59,13 @@ class Ball void shuffleStatus(); + /** + Serializable methods (see that class for more information). + */ + bool save(Serializer& out) const override; + bool load(Serializer& in) override; + string name() const override { return "TIA_Ball"; } + public: uInt32 collision; @@ -96,4 +104,4 @@ class Ball } // namespace TIA6502tsCore -#endif // TIA_6502TS_CORE_BALL \ No newline at end of file +#endif // TIA_6502TS_CORE_BALL diff --git a/src/emucore/tia/core_6502ts/FrameManager.cxx b/src/emucore/tia/core_6502ts/FrameManager.cxx index 8b9f21ad1..1b6787607 100644 --- a/src/emucore/tia/core_6502ts/FrameManager.cxx +++ b/src/emucore/tia/core_6502ts/FrameManager.cxx @@ -241,4 +241,43 @@ void FrameManager::finalizeFrame() setState(State::overscan); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TODO: implement this once the class is finalized +bool FrameManager::save(Serializer& out) const +{ + try + { + out.putString(name()); + + // TODO - save instance variables + } + catch(...) + { + cerr << "ERROR: TIA_FrameManager::save" << endl; + return false; + } + + return false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TODO: implement this once the class is finalized +bool FrameManager::load(Serializer& in) +{ + try + { + if(in.getString() != name()) + return false; + + // TODO - load instance variables + } + catch(...) + { + cerr << "ERROR: TIA_FrameManager::load" << endl; + return false; + } + + return false; +} + } // namespace TIA6502tsCore diff --git a/src/emucore/tia/core_6502ts/FrameManager.hxx b/src/emucore/tia/core_6502ts/FrameManager.hxx index d4de1a0ab..def0277d8 100644 --- a/src/emucore/tia/core_6502ts/FrameManager.hxx +++ b/src/emucore/tia/core_6502ts/FrameManager.hxx @@ -21,11 +21,13 @@ #define TIA_6502TS_CORE_FRAME_MANAGER #include + +#include "Serializable.hxx" #include "bspf.hxx" namespace TIA6502tsCore { -class FrameManager +class FrameManager : public Serializable { public: @@ -40,7 +42,6 @@ class FrameManager FrameManager(); public: - void setHandlers(callback frameStartCallback, callback frameCompletionCallback); void reset(); @@ -61,6 +62,13 @@ class FrameManager uInt32 currentLine() const; + /** + Serializable methods (see that class for more information). + */ + bool save(Serializer& out) const override; + bool load(Serializer& in) override; + string name() const override { return "TIA_FrameManager"; } + private: enum State { diff --git a/src/emucore/tia/core_6502ts/Missile.cxx b/src/emucore/tia/core_6502ts/Missile.cxx index ddeb89106..294c7007a 100644 --- a/src/emucore/tia/core_6502ts/Missile.cxx +++ b/src/emucore/tia/core_6502ts/Missile.cxx @@ -131,4 +131,43 @@ uInt8 Missile::getPixel(uInt8 colorIn) const return collision ? colorIn : myColor; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TODO: implement this once the class is finalized +bool Missile::save(Serializer& out) const +{ + try + { + out.putString(name()); + + // TODO - save instance variables + } + catch(...) + { + cerr << "ERROR: TIA_Missile::save" << endl; + return false; + } + + return false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TODO: implement this once the class is finalized +bool Missile::load(Serializer& in) +{ + try + { + if(in.getString() != name()) + return false; + + // TODO - load instance variables + } + catch(...) + { + cerr << "ERROR: TIA_Missile::load" << endl; + return false; + } + + return false; +} + } // namespace TIA6502tsCore diff --git a/src/emucore/tia/core_6502ts/Missile.hxx b/src/emucore/tia/core_6502ts/Missile.hxx index b893105df..504c362c6 100644 --- a/src/emucore/tia/core_6502ts/Missile.hxx +++ b/src/emucore/tia/core_6502ts/Missile.hxx @@ -20,11 +20,12 @@ #ifndef TIA_6502TS_CORE_MISSILE #define TIA_6502TS_CORE_MISSILE +#include "Serializable.hxx" #include "bspf.hxx" namespace TIA6502tsCore { -class Missile +class Missile : public Serializable { public: Missile(uInt32 collisionMask); @@ -55,6 +56,13 @@ class Missile uInt8 getPixel(uInt8 colorIn) const; + /** + Serializable methods (see that class for more information). + */ + bool save(Serializer& out) const override; + bool load(Serializer& in) override; + string name() const override { return "TIA_Missile"; } + public: uInt32 collision; diff --git a/src/emucore/tia/core_6502ts/Player.cxx b/src/emucore/tia/core_6502ts/Player.cxx index aa19b8a15..552d9faa1 100644 --- a/src/emucore/tia/core_6502ts/Player.cxx +++ b/src/emucore/tia/core_6502ts/Player.cxx @@ -270,4 +270,43 @@ void Player::updatePattern() } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TODO: implement this once the class is finalized +bool Player::save(Serializer& out) const +{ + try + { + out.putString(name()); + + // TODO - save instance variables + } + catch(...) + { + cerr << "ERROR: TIA_Player::save" << endl; + return false; + } + + return false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TODO: implement this once the class is finalized +bool Player::load(Serializer& in) +{ + try + { + if(in.getString() != name()) + return false; + + // TODO - load instance variables + } + catch(...) + { + cerr << "ERROR: TIA_Player::load" << endl; + return false; + } + + return false; +} + } // namespace TIA6502tsCore diff --git a/src/emucore/tia/core_6502ts/Player.hxx b/src/emucore/tia/core_6502ts/Player.hxx index 72a80e279..c2ceee7b9 100644 --- a/src/emucore/tia/core_6502ts/Player.hxx +++ b/src/emucore/tia/core_6502ts/Player.hxx @@ -20,11 +20,12 @@ #ifndef TIA_6502TS_CORE_PLAYER #define TIA_6502TS_CORE_PLAYER +#include "Serializable.hxx" #include "bspf.hxx" namespace TIA6502tsCore { -class Player +class Player : public Serializable { public: Player(uInt32 collisionMask); @@ -61,6 +62,13 @@ class Player uInt8 getRespClock() const; + /** + Serializable methods (see that class for more information). + */ + bool save(Serializer& out) const override; + bool load(Serializer& in) override; + string name() const override { return "TIA_Player"; } + public: uInt32 collision; diff --git a/src/emucore/tia/core_6502ts/Playfield.cxx b/src/emucore/tia/core_6502ts/Playfield.cxx index 165454245..379d46d8f 100644 --- a/src/emucore/tia/core_6502ts/Playfield.cxx +++ b/src/emucore/tia/core_6502ts/Playfield.cxx @@ -152,4 +152,43 @@ void Playfield::applyColors() } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TODO: implement this once the class is finalized +bool Playfield::save(Serializer& out) const +{ + try + { + out.putString(name()); + + // TODO - save instance variables + } + catch(...) + { + cerr << "ERROR: TIA_Playfield::save" << endl; + return false; + } + + return false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TODO: implement this once the class is finalized +bool Playfield::load(Serializer& in) +{ + try + { + if(in.getString() != name()) + return false; + + // TODO - load instance variables + } + catch(...) + { + cerr << "ERROR: TIA_Playfield::load" << endl; + return false; + } + + return false; +} + } // namespace TIA6502tsCore diff --git a/src/emucore/tia/core_6502ts/Playfield.hxx b/src/emucore/tia/core_6502ts/Playfield.hxx index a46dc6fed..d57d92bec 100644 --- a/src/emucore/tia/core_6502ts/Playfield.hxx +++ b/src/emucore/tia/core_6502ts/Playfield.hxx @@ -20,11 +20,12 @@ #ifndef TIA_6502TS_CORE_PLAYFIELD #define TIA_6502TS_CORE_PLAYFIELD +#include "Serializable.hxx" #include "bspf.hxx" namespace TIA6502tsCore { -class Playfield +class Playfield : public Serializable { public: Playfield(uInt32 collisionMask); @@ -51,6 +52,13 @@ class Playfield uInt8 getPixel(uInt8 colorIn) const; + /** + Serializable methods (see that class for more information). + */ + bool save(Serializer& out) const override; + bool load(Serializer& in) override; + string name() const override { return "TIA_Playfield"; } + public: uInt32 collision; diff --git a/src/emucore/tia/core_6502ts/TIA.cxx b/src/emucore/tia/core_6502ts/TIA.cxx index ca5d6419f..adc140c67 100644 --- a/src/emucore/tia/core_6502ts/TIA.cxx +++ b/src/emucore/tia/core_6502ts/TIA.cxx @@ -141,17 +141,59 @@ void TIA::installDelegate(System& system, Device& device) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// TODO: stub bool TIA::save(Serializer& out) const { - return false; + try + { + out.putString(name()); + + // TODO - save instance variables + + // Save the state of each graphics object + if(!myPlayfield.save(out)) return false; + if(!myMissile0.save(out)) return false; + if(!myMissile1.save(out)) return false; + if(!myPlayer0.save(out)) return false; + if(!myPlayer1.save(out)) return false; + if(!myBall.save(out)) return false; + + // Save the sound sample stuff ... + mySound.save(out); + } + catch(...) + { + cerr << "ERROR: TIA::save" << endl; + return false; + } + + return false; // for now, until class is finalized } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// TODO: stub bool TIA::load(Serializer& in) { - return false; + try + { + if(in.getString() != name()) + return false; + + // TODO - load instance variables + + // Load the state of each graphics object + if(!myPlayfield.load(in)) return false; + if(!myMissile0.load(in)) return false; + if(!myMissile1.load(in)) return false; + if(!myPlayer0.load(in)) return false; + if(!myPlayer1.load(in)) return false; + if(!myBall.load(in)) return false; + } + catch(...) + { + cerr << "ERROR: TIA::load" << endl; + return false; + } + + return false; // for now, until class is finalized } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -463,19 +505,21 @@ bool TIA::loadDisplay(Serializer& in) return false; } -// TODO: stub +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIA::update() { mySystem->m6502().execute(25000); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TODO: add yoffset uInt8* TIA::currentFrameBuffer() const { return myCurrentFrameBuffer.get(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// TODO: stub +// TODO: add yoffset uInt8* TIA::previousFrameBuffer() const { return myPreviousFrameBuffer.get(); @@ -530,6 +574,7 @@ uInt32 TIA::clocksThisLine() const return 0; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // TODO: stub uInt32 TIA::scanlines() const { diff --git a/src/emucore/tia/core_6502ts/TIA.hxx b/src/emucore/tia/core_6502ts/TIA.hxx index 674a23e02..ae19b54d9 100644 --- a/src/emucore/tia/core_6502ts/TIA.hxx +++ b/src/emucore/tia/core_6502ts/TIA.hxx @@ -50,15 +50,6 @@ class TIA : public AbstractTIA void install(System& system) override; - bool save(Serializer& out) const override; - - bool load(Serializer& in) override; - - string name() const override - { - return "TIA"; - } - uInt8 peek(uInt16 address) override; bool poke(uInt16 address, uInt8 value) override; @@ -77,12 +68,18 @@ class TIA : public AbstractTIA uInt8* previousFrameBuffer() const override; + /** + Answers vertical info about the framebuffer (height and starting line) + */ uInt32 height() const override; - uInt32 ystart() const override; + /** + Changes the current Height/YStart properties. + Note that calls to these method(s) must be eventually followed by + ::frameReset() for the changes to take effect. + */ void setHeight(uInt32 height) override; - void setYStart(uInt32 ystart) override; void enableAutoFrame(bool enabled) override; @@ -119,6 +116,29 @@ class TIA : public AbstractTIA void setJitterRecoveryFactor(Int32 f) override; + /** + Save the current state of this device to the given Serializer. + + @param out The Serializer object to use + @return False on any errors, else true + */ + bool save(Serializer& out) const override; + + /** + Load the current state of this device from the given Serializer. + + @param in The Serializer object to use + @return False on any errors, else true + */ + bool load(Serializer& in) override; + + /** + Get a descriptor for the device name (used in error checking). + + @return The name of the object + */ + string name() const override { return "TIA"; } + private: enum HState {blank, frame};