diff options
| author | Paul Gilbert | 2014-04-22 23:00:41 -0400 | 
|---|---|---|
| committer | Paul Gilbert | 2014-04-22 23:00:41 -0400 | 
| commit | 0e9e6cda40ee0bf739e6c7a6320a81307df7c8b9 (patch) | |
| tree | d69131833413f6bd75ef84e95c64cc54da568e8e | |
| parent | 3f1a49b567aac10fe8a195f7a2b8e07603470a72 (diff) | |
| download | scummvm-rg350-0e9e6cda40ee0bf739e6c7a6320a81307df7c8b9.tar.gz scummvm-rg350-0e9e6cda40ee0bf739e6c7a6320a81307df7c8b9.tar.bz2 scummvm-rg350-0e9e6cda40ee0bf739e6c7a6320a81307df7c8b9.zip | |
MADS: Beginnings of savegame synchronisation
| -rw-r--r-- | engines/mads/action.cpp | 8 | ||||
| -rw-r--r-- | engines/mads/action.h | 3 | ||||
| -rw-r--r-- | engines/mads/game.cpp | 34 | ||||
| -rw-r--r-- | engines/mads/game.h | 10 | ||||
| -rw-r--r-- | engines/mads/inventory.cpp | 63 | ||||
| -rw-r--r-- | engines/mads/inventory.h | 10 | ||||
| -rw-r--r-- | engines/mads/messages.cpp | 2 | ||||
| -rw-r--r-- | engines/mads/nebular/nebular_scenes2.cpp | 2 | ||||
| -rw-r--r-- | engines/mads/player.cpp | 72 | ||||
| -rw-r--r-- | engines/mads/player.h | 9 | ||||
| -rw-r--r-- | engines/mads/rails.cpp | 17 | ||||
| -rw-r--r-- | engines/mads/rails.h | 7 | ||||
| -rw-r--r-- | engines/mads/scene.cpp | 5 | ||||
| -rw-r--r-- | engines/mads/scene.h | 5 | 
14 files changed, 204 insertions, 43 deletions
| diff --git a/engines/mads/action.cpp b/engines/mads/action.cpp index 9d496d5ebf..03c0c1ed8a 100644 --- a/engines/mads/action.cpp +++ b/engines/mads/action.cpp @@ -29,6 +29,14 @@  namespace MADS { +void ActionDetails::synchronize(Common::Serializer &s) { +	s.syncAsUint16LE(_verbId); +	s.syncAsUint16LE(_objectNameId); +	s.syncAsUint16LE(_indirectObjectId); +} + +/*------------------------------------------------------------------------*/ +  MADSAction::MADSAction(MADSEngine *vm) : _vm(vm) {  	clear();  	_statusTextIndex = -1; diff --git a/engines/mads/action.h b/engines/mads/action.h index 599fb0e4f9..c588a42324 100644 --- a/engines/mads/action.h +++ b/engines/mads/action.h @@ -24,6 +24,7 @@  #define MADS_ACTION_H  #include "common/scummsys.h" +#include "common/serializer.h"  #include "common/str.h"  namespace MADS { @@ -76,6 +77,8 @@ struct ActionDetails {  	int _verbId;  	int _objectNameId;  	int _indirectObjectId; + +	void synchronize(Common::Serializer &s);  };  struct ActionSavedFields { diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp index d3e3987d4e..3b591d7a9e 100644 --- a/engines/mads/game.cpp +++ b/engines/mads/game.cpp @@ -22,6 +22,7 @@  #include "common/scummsys.h"  #include "common/memstream.h" +#include "common/serializer.h"  #include "mads/mads.h"  #include "mads/compression.h"  #include "mads/game.h" @@ -45,7 +46,7 @@ Game::Game(MADSEngine *vm): _vm(vm), _surface(nullptr), _objects(vm),  		_scene(vm), _screenObjects(vm), _player(vm) {  	_sectionNumber = _priorSectionNumber = 0;  	_difficulty = DIFFICULTY_HARD; -	_saveSlot = -1; +	_serializer = nullptr;  	_statusFlag = 0;  	_sectionHandler = nullptr;  	_sectionNumber = 1; @@ -86,7 +87,6 @@ void Game::run() {  	case PROTECTION_FAIL:  		// Copy protection failed  		_scene._nextSceneId = 804; -		_saveSlot = -1;  		break;  	case PROTECTION_ESCAPE:  		// User escaped out of copy protection dialog @@ -102,7 +102,7 @@ void Game::run() {  	// Get the initial starting time for the first scene  	_scene._frameStartTime = _vm->_events->getFrameCounter(); -	if (_saveSlot == -1 && protectionResult != -1 && protectionResult != -2) { +	if (_serializer == nullptr && protectionResult != -1 && protectionResult != -2) {  		initSection(_sectionNumber);  		_statusFlag = true; @@ -118,11 +118,6 @@ void Game::run() {  	if (protectionResult != 1 && protectionResult != 2) {  		initialiseGlobals(); - -		if (_saveSlot != -1) { -			warning("TODO: loadGame(\"REX.SAV\", 210)"); -			_statusFlag = false; -		}  	}  	if (_statusFlag) @@ -131,6 +126,9 @@ void Game::run() {  void Game::gameLoop() {  	while (!_vm->shouldQuit() && _statusFlag) { +		if (_serializer) +			synchronize(*_serializer, true); +  		setSectionHandler();  		_sectionHandler->preLoadSection();  		initSection(_sectionNumber); @@ -248,7 +246,7 @@ void Game::sectionLoop() {  		_player.selectSeries();  		_player.updateFrame(); -		_player._visible3 = _player._visible; +		_player._beenVisible = _player._visible;  		_player._special = _scene.getDepthHighBits(_player._playerPos);  		_player._priorTimer = _scene._frameStartTime - _player._ticksAmount;  		_player.idle(); @@ -402,4 +400,22 @@ void Game::handleKeypress(const Common::Event &event) {  	warning("TODO: handleKeypress - %d", (int)event.kbd.keycode);  } +void Game::synchronize(Common::Serializer &s, bool phase1) { +	if (phase1) { +		s.syncAsUint16LE(_scene._nextSceneId); +		s.syncAsUint16LE(_scene._priorSceneId); + +		if (s.isLoading()) { +			_sectionNumber = _scene._nextSceneId / 100; +			_currentSectionNumber = _sectionNumber; +		} +	} else { +		s.syncAsByte(_difficulty); +		 +		_scene.synchronize(s); +		_objects.synchronize(s); +		_player.synchronize(s); +	} +} +  } // End of namespace MADS diff --git a/engines/mads/game.h b/engines/mads/game.h index 5bb7b31973..ad40fbdcc0 100644 --- a/engines/mads/game.h +++ b/engines/mads/game.h @@ -25,6 +25,7 @@  #include "common/scummsys.h"  #include "common/str-array.h" +#include "common/serializer.h"  #include "mads/scene.h"  #include "mads/game_data.h"  #include "mads/globals.h" @@ -72,12 +73,12 @@ private:  protected:  	MADSEngine *_vm;  	MSurface *_surface; -	int _saveSlot;  	int _statusFlag;  	Common::StringArray _quotes;  	bool _quoteEmergency;  	bool _vocabEmergency;  	bool _anyEmergency; +	Common::Serializer *_serializer;  	/**  	 * Constructor @@ -170,6 +171,13 @@ public:  	 */  	virtual void step() = 0; +	/** +	 * Synchronise the game data +	 * @param s			Serializer +	 * @param phase1	If true, it's synchronising the basic scene information +	 */ +	virtual void synchronize(Common::Serializer &s, bool phase1); +  	// DEPRECATED: ScummVM re-implementation keeps all the quotes loaded, so the methods below are stubs  	void clearQuotes() {}  	void loadQuoteRange(int startNum, int endNum) {} diff --git a/engines/mads/inventory.cpp b/engines/mads/inventory.cpp index bb65430bb1..abd281dcc8 100644 --- a/engines/mads/inventory.cpp +++ b/engines/mads/inventory.cpp @@ -26,42 +26,57 @@  namespace MADS { -void InventoryObject::load(Common::SeekableReadStream &f) { -	_descId = f.readUint16LE(); -	_roomNumber = f.readUint16LE(); -	_article = f.readByte(); -	_vocabCount = f.readByte(); +void InventoryObject::synchronize(Common::Serializer &s) { +	s.syncAsUint16LE(_descId); +	s.syncAsUint16LE(_roomNumber); +	s.syncAsByte(_article); +	s.syncAsByte(_vocabCount);  	for (int i = 0; i < 3; ++i) { -		_vocabList[i]._verbType = (VerbType)f.readByte(); -		_vocabList[i]._prepType = (PrepType)f.readByte(); -		_vocabList[i]._vocabId = f.readUint16LE(); +		s.syncAsByte(_vocabList[i]._verbType); +		s.syncAsByte(_vocabList[i]._prepType); +		s.syncAsUint16LE( _vocabList[i]._vocabId);  	} -	f.skip(4);	// field12 -	f.read(&_mutilateString[0], 10); -	f.skip(16); +	s.skip(4);	// field12 +	s.syncBytes((byte *)&_mutilateString[0], 10); +	s.skip(16);  }  /*------------------------------------------------------------------------*/  void InventoryObjects::load() {  	File f("*OBJECTS.DAT"); +	Common::Serializer s(&f, nullptr); -	// Get the total numer of inventory objects -	int count = f.readUint16LE(); -	reserve(count); - -	// Read in each object -	for (int i = 0; i < count; ++i) { -		InventoryObject obj; -		obj.load(f); -		push_back(obj); +	// Load the objects data +	synchronize(s); +} -		// If it's for the player's inventory, add the index to the inventory list -		if (obj._roomNumber == PLAYER_INVENTORY) { -			_inventoryList.push_back(i); -			assert(_inventoryList.size() <= 32); +void InventoryObjects::synchronize(Common::Serializer &s) { +	int count = size(); +	s.syncAsUint16LE(count); + +	if (s.isSaving()) { +		// Store the data for each object in the inventory lsit +		for (int idx = 0; idx < count; ++idx) +			(*this)[idx].synchronize(s); +	} else { +		clear(); +		_inventoryList.clear(); +		reserve(count); + +		// Read in each object +		for (int i = 0; i < count; ++i) { +			InventoryObject obj; +			obj.synchronize(s); +			push_back(obj); + +			// If it's for the player's inventory, add the index to the inventory list +			if (obj._roomNumber == PLAYER_INVENTORY) { +				_inventoryList.push_back(i); +				assert(_inventoryList.size() <= 32); +			}  		}  	}  } diff --git a/engines/mads/inventory.h b/engines/mads/inventory.h index 5c2f925e57..5e3ecd6a69 100644 --- a/engines/mads/inventory.h +++ b/engines/mads/inventory.h @@ -25,6 +25,7 @@  #include "common/scummsys.h"  #include "common/array.h" +#include "common/serializer.h"  namespace MADS { @@ -49,9 +50,9 @@ public:  	const byte *_objFolder;		// ???  	/** -	 * Loads the data for a given object +	 * Synchronizes the data for a given object  	 */ -	void load(Common::SeekableReadStream &f); +	void synchronize(Common::Serializer &s);  };  class InventoryObjects: public Common::Array<InventoryObject> { @@ -72,6 +73,11 @@ public:  	void load();  	/** +	* Synchronize the objects list in a savegame +	*/ +	void synchronize(Common::Serializer &s); + +	/**  	 * Returns the inventory item from the player's inventory  	 */  	InventoryObject &getItem(int itemIndex) { diff --git a/engines/mads/messages.cpp b/engines/mads/messages.cpp index 46b05c1413..2f59a67359 100644 --- a/engines/mads/messages.cpp +++ b/engines/mads/messages.cpp @@ -203,7 +203,7 @@ void KernelMessages::processText(int msgIndex) {  	Player &player = _vm->_game->_player;  	if (msg._flags & KMSG_PLAYER_TIMEOUT) { -		if (player._visible3) { +		if (player._beenVisible) {  			SpriteAsset &asset = *_vm->_game->_scene._sprites[player._spritesStart + player._spritesIdx];  			MSprite *frame = asset.getFrame(player._frameNumber - 1); diff --git a/engines/mads/nebular/nebular_scenes2.cpp b/engines/mads/nebular/nebular_scenes2.cpp index 5054fbef0d..7491ed1479 100644 --- a/engines/mads/nebular/nebular_scenes2.cpp +++ b/engines/mads/nebular/nebular_scenes2.cpp @@ -339,7 +339,7 @@ void Scene202::setup() {  }  void Scene202::enter() { -	_game._player._visible3 = true; +	_game._player._beenVisible = true;  	_globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('b', 0));  	_globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('b', 1));  	_globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('b', 2)); diff --git a/engines/mads/player.cpp b/engines/mads/player.cpp index cc482c0608..3b727b397e 100644 --- a/engines/mads/player.cpp +++ b/engines/mads/player.cpp @@ -48,7 +48,7 @@ Player::Player(MADSEngine *vm): _vm(vm) {  	_priorVisible = false;  	_needToWalk = false;  	_readyToWalk = false; -	_visible3 = false; +	_beenVisible = false;  	_loadsFirst = false;  	_loadedFirst = false;  	_walkAnywhere = false; @@ -337,7 +337,7 @@ void Player::update() {  		}  	} -	_visible3 = _visible; +	_beenVisible |= _visible;  	_priorVisible = _visible;  	_forceRefresh = false;  } @@ -691,4 +691,72 @@ void Player::releasePlayerSprites() {  	_spritesChanged = true;  } +void Player::synchronize(Common::Serializer &s) { +	s.syncAsByte(_visible); +	s.syncAsByte(_priorVisible); +	s.syncAsByte(_beenVisible); +	s.syncAsByte(_moving); +	s.syncAsByte(_stepEnabled); +	s.syncAsSint16LE(_playerPos.x); +	s.syncAsSint16LE(_playerPos.y); +	s.syncAsSint16LE(_targetPos.x); +	s.syncAsSint16LE(_targetPos.y); +	s.syncAsSint16LE(_posChange.x); +	s.syncAsSint16LE(_posChange.y); +	s.syncAsSint16LE(_posDiff.x); +	s.syncAsSint16LE(_posDiff.y); +	s.syncAsSint16LE(_xDirection); +	s.syncAsSint16LE(_yDirection); +	s.syncAsUint16LE(_facing); +	s.syncAsUint16LE(_targetFacing); +	s.syncAsByte(_spritesChanged); +	s.syncAsByte(_walkAnywhere); +	s.syncAsByte(_walkOffScreen); +	s.syncAsSint16LE(_ticksAmount); +	s.syncAsSint16LE(_centerOfGravity); +	s.syncAsUint16LE(_walkOffScreenSceneId); +	s.syncAsByte(_needToWalk); +	s.syncAsByte(_readyToWalk); +	s.syncAsUint16LE(_prepareWalkFacing); +	s.syncAsSint16LE(_prepareWalkPos.x); +	s.syncAsSint16LE(_prepareWalkPos.y); + +	s.syncAsByte(_mirror); +	s.syncAsUint16LE(_frameCount); +	s.syncAsSint16LE(_frameListIndex); +	s.syncAsSint16LE(_distAccum); +	s.syncAsSint16LE(_pixelAccum); +	s.syncAsSint16LE(_deltaDistance); +	 +	for (int i = 0; i < 12; ++i) { +		s.syncAsSint16LE(_stopWalkerList[i]); +		s.syncAsSint16LE(_stopWalkerTrigger[i]); +	} +	s.syncAsSint16LE(_stopWalkerIndex); +	s.syncAsSint16LE(_totalDistance); +	s.syncAsSint16LE(_frameNumber); +	s.syncAsSint16LE(_special); +	s.syncAsSint16LE(_velocity); +	s.syncAsSint16LE(_scalingVelocity); +	s.syncAsSint16LE(_upcomingTrigger); +	s.syncAsSint16LE(_trigger); +	s.syncAsSint16LE(_currentDepth); +	s.syncAsSint16LE(_currentScale); + +	int count; +	char ch; +	if (s.isSaving()) { +		count = _spritesPrefix.size(); +		s.syncAsUint16LE(count); +		s.syncBytes((byte *)_spritesPrefix.c_str(), count); +	} else { +		s.syncAsSint16LE(count); +		_spritesPrefix.clear(); +		for (int i = 0; i < count; ++i) { +			s.syncAsByte(ch); +			_spritesPrefix += ch; +		}			 +	} +} +  } // End of namespace MADS diff --git a/engines/mads/player.h b/engines/mads/player.h index 6df1159ad4..97fc3e75cd 100644 --- a/engines/mads/player.h +++ b/engines/mads/player.h @@ -25,6 +25,7 @@  #include "common/scummsys.h"  #include "common/str.h" +#include "common/serializer.h"  namespace MADS { @@ -110,7 +111,7 @@ public:  	bool _spritesChanged;  	bool _visible;  	bool _priorVisible; -	bool _visible3; +	bool _beenVisible;  	bool _walkAnywhere;  	int _frameNumber;  	bool _loadsFirst; @@ -122,7 +123,6 @@ public:  	Common::Point _prepareWalkPos;  	bool _moving;  	int _walkOffScreen, _walkOffScreenSceneId; -	int _next;  	int _special;  	int _ticksAmount;  	uint32 _priorTimer; @@ -211,6 +211,11 @@ public:  	*/  	void releasePlayerSprites(); +	/** +	 * Serialize the data of the player +	 */ +	void synchronize(Common::Serializer &s); +  	static void preloadSequences(const Common::String &prefix, int level) {  		// No implementation in ScummVM  	} diff --git a/engines/mads/rails.cpp b/engines/mads/rails.cpp index 105a85366a..00f7f4cdbc 100644 --- a/engines/mads/rails.cpp +++ b/engines/mads/rails.cpp @@ -263,5 +263,22 @@ int Rails::getRouteFlags(const Common::Point &src, const Common::Point &dest) {  	return result;  } +void Rails::synchronize(Common::Serializer &s) { +	s.syncAsSint16LE(_routeLength); +	s.syncAsSint16LE(_next); +	 +	int count = _routeIndexes.size(); +	if (s.isSaving()) { +		for (int i = 0; i < count; ++i) +			s.syncAsUint16LE(_routeIndexes[i]); +	} else { +		_routeIndexes.clear(); +		for (int i = 0; i < count; ++i) { +			int v = 0; +			s.syncAsUint16LE(v); +			_routeIndexes.push(v); +		} +	} +}  } // End of namespace MADS diff --git a/engines/mads/rails.h b/engines/mads/rails.h index 6338aeab97..4014491e25 100644 --- a/engines/mads/rails.h +++ b/engines/mads/rails.h @@ -26,6 +26,7 @@  #include "common/scummsys.h"  #include "common/array.h"  #include "common/rect.h" +#include "common/serializer.h"  #include "common/stack.h"  #include "mads/msurface.h" @@ -60,7 +61,6 @@ private:  	int _depthStyle;  	int _routeLength;  	int _next; -	int _routeOffset;  	int _tempRoute[MAX_ROUTE_NODES];  	Common::Stack<int> _routeIndexes;  private: @@ -122,6 +122,11 @@ public:  	void resetNext() { _next = 0; }  	int  getNext() { return _next; } + +	/** +	 * Synchronize the data for the route +	 */ +	void synchronize(Common::Serializer &s);  };  } // End of namespace MADS diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp index 9d0332e600..239a91c585 100644 --- a/engines/mads/scene.cpp +++ b/engines/mads/scene.cpp @@ -681,4 +681,9 @@ void Scene::freeAnimation() {  	_freeAnimationFlag = false;  } +void Scene::synchronize(Common::Serializer &s) { +	_action._activeAction.synchronize(s); +	_rails.synchronize(s); +} +  } // End of namespace MADS diff --git a/engines/mads/scene.h b/engines/mads/scene.h index eb84fbd814..48b01b2acb 100644 --- a/engines/mads/scene.h +++ b/engines/mads/scene.h @@ -233,6 +233,11 @@ public:  	 * Frees any currently active animation for the scene  	 */  	void freeAnimation(); + +	/** +	* Synchronise the game +	*/ +	void synchronize(Common::Serializer &s);  };  } // End of namespace MADS | 
