[Scummvm-cvs-logs] SF.net SVN: scummvm:[53883] scummvm/trunk/engines/lastexpress

littleboy at users.sourceforge.net littleboy at users.sourceforge.net
Wed Oct 27 21:20:20 CEST 2010


Revision: 53883
          http://scummvm.svn.sourceforge.net/scummvm/?rev=53883&view=rev
Author:   littleboy
Date:     2010-10-27 19:20:20 +0000 (Wed, 27 Oct 2010)

Log Message:
-----------
LASTEXPRESS: Implement game loading (last save entry only)

Modified Paths:
--------------
    scummvm/trunk/engines/lastexpress/debug.cpp
    scummvm/trunk/engines/lastexpress/game/menu.cpp
    scummvm/trunk/engines/lastexpress/game/menu.h
    scummvm/trunk/engines/lastexpress/game/savegame.cpp
    scummvm/trunk/engines/lastexpress/game/savegame.h
    scummvm/trunk/engines/lastexpress/game/sound.cpp
    scummvm/trunk/engines/lastexpress/game/state.h

Modified: scummvm/trunk/engines/lastexpress/debug.cpp
===================================================================
--- scummvm/trunk/engines/lastexpress/debug.cpp	2010-10-27 19:19:57 UTC (rev 53882)
+++ scummvm/trunk/engines/lastexpress/debug.cpp	2010-10-27 19:20:20 UTC (rev 53883)
@@ -121,7 +121,7 @@
 	SAFE_DELETE(_command);
 
 	if (_commandParams)
-		for (int i = 0; i < _numParams; i++)		
+		for (int i = 0; i < _numParams; i++)
 			free(_commandParams[i]);
 
 	free(_commandParams);
@@ -1109,9 +1109,7 @@
 		if (id == 0 || id > 6)
 			goto error;
 
-		if (!getSaveLoad()->loadGame((GameId)(id - 1)))
-			DebugPrintf("Error loading game with id=%d", id);
-
+		getSaveLoad()->loadGame((GameId)(id - 1));
 	} else {
 error:
 		DebugPrintf("Syntax: loadgame <id> (id=1-6)\n");

Modified: scummvm/trunk/engines/lastexpress/game/menu.cpp
===================================================================
--- scummvm/trunk/engines/lastexpress/game/menu.cpp	2010-10-27 19:19:57 UTC (rev 53882)
+++ scummvm/trunk/engines/lastexpress/game/menu.cpp	2010-10-27 19:20:20 UTC (rev 53883)
@@ -360,7 +360,7 @@
 	_gameId(kGameBlue), _hasShownStartScreen(false), _hasShownIntro(false),
 	_isShowingCredits(false), _isGameStarted(false), _isShowingMenu(false),
 	_creditsSequenceIndex(0), _checkHotspotsTicks(15),  _mouseFlags(Common::EVENT_INVALID), _lastHotspot(NULL),
-	_currentTime(kTimeNone), _lowerTime(kTimeNone), _time(kTimeNone), _currentIndex(0), _index(0), _savegameIndex(0), _delta(0), _handleTimeDelta(false) {
+	_currentTime(kTimeNone), _lowerTime(kTimeNone), _time(kTimeNone), _currentIndex(0), _index(0), _lastIndex(0), _delta(0), _handleTimeDelta(false) {
 
 	_clock = new Clock(_engine);
 	_trainLine = new TrainLine(_engine);
@@ -661,8 +661,8 @@
 			if (_isGameStarted) {
 				showFrame(kOverlayEggButtons, kButtonContinue, true);
 
-				if (_savegameIndex == _index) {
-					showFrame(kOverlayTooltip, getSaveLoad()->isGameFinished(_index, _savegameIndex) ? kTooltipViewGameEnding : kTooltipContinueGame, true);
+				if (_lastIndex == _index) {
+					showFrame(kOverlayTooltip, getSaveLoad()->isGameFinished(_index, _lastIndex) ? kTooltipViewGameEnding : kTooltipContinueGame, true);
 				} else {
 					showFrame(kOverlayTooltip, kTooltipContinueRewoundGame, true);
 				}
@@ -830,7 +830,7 @@
 
 	//////////////////////////////////////////////////////////////////////////
 	case kMenuForwardGame:
-		if (_savegameIndex <= _index || _currentTime > _time) {
+		if (_lastIndex <= _index || _currentTime > _time) {
 			hideOverlays();
 			break;
 		}
@@ -1087,11 +1087,11 @@
 	}
 
 	// Init savegame & menu values
-	_savegameIndex = getSaveLoad()->init(_gameId, true);
-	_lowerTime = getSaveLoad()->getTime(_savegameIndex);
+	_lastIndex = getSaveLoad()->init(_gameId, true);
+	_lowerTime = getSaveLoad()->getTime(_lastIndex);
 
 	if (useSameIndex)
-		_index = _savegameIndex;
+		_index = _lastIndex;
 
 	//if (!getGlobalTimer())
 	//	_index3 = 0;
@@ -1112,26 +1112,20 @@
 	}
 }
 
+// Start a game (or load an existing savegame)
 void Menu::startGame() {
-	// TODO: Clear train sequences & savegame headers
+	getSaveLoad()->clear();
 
-	if (0 /* test for temp filename */ ) {
-		if (_savegameIndex == _index)
+	if (_lastIndex == _index) {
+		setGlobalTimer(0);
+		if (_index) {
 			getSaveLoad()->loadGame(_gameId);
-		else
-			getSaveLoad()->loadGame2(_gameId);
-	} else {
-		if (_savegameIndex == _index) {
-			setGlobalTimer(0);
-			if (_index) {
-				getSaveLoad()->loadGame(_gameId);
-			} else {
-				getLogic()->resetState();
-				getEntities()->setup(true, kEntityPlayer);
-			}
 		} else {
-			getSaveLoad()->loadGame2(_gameId);
+			getLogic()->resetState();
+			getEntities()->setup(true, kEntityPlayer);
 		}
+	} else {
+		getSaveLoad()->loadGame(_gameId, _index);
 	}
 }
 
@@ -1152,7 +1146,7 @@
 	_trainLine->clear();
 
 	// Clear loaded savegame data
-	getSaveLoad()->clearHeaders();
+	getSaveLoad()->clear(true);
 
 	init(false, kSavegameTypeIndex, 0);
 }
@@ -1367,7 +1361,7 @@
 			if (searchEntry) {
 				uint32 currentIndex = _index;
 
-				if (_savegameIndex >= _index) {
+				if (_lastIndex >= _index) {
 					do {
 						// Calculate new delta
 						int32 newDelta = (uint32)getSaveLoad()->getTime(currentIndex) - time1;
@@ -1378,7 +1372,7 @@
 						}
 
 						++currentIndex;
-					} while (currentIndex <= _savegameIndex);
+					} while (currentIndex <= _lastIndex);
 				}
 			} else {
 				index = _index + 1;
@@ -1409,7 +1403,7 @@
 		}
 
 		++index;
-	} while (_savegameIndex >= index);
+	} while (_lastIndex >= index);
 
 	_currentIndex = entryIndex;
 	updateTime(getSaveLoad()->getTime(entryIndex));
@@ -1424,10 +1418,10 @@
 }
 
 void Menu::forwardTime() {
-	if (_savegameIndex <= _index)
+	if (_lastIndex <= _index)
 		return;
 
-	_currentIndex = _savegameIndex;
+	_currentIndex = _lastIndex;
 	updateTime(getSaveLoad()->getTime(_currentIndex));
 }
 

Modified: scummvm/trunk/engines/lastexpress/game/menu.h
===================================================================
--- scummvm/trunk/engines/lastexpress/game/menu.h	2010-10-27 19:19:57 UTC (rev 53882)
+++ scummvm/trunk/engines/lastexpress/game/menu.h	2010-10-27 19:20:20 UTC (rev 53883)
@@ -183,7 +183,7 @@
 
 	uint32 _currentIndex; // current savegame entry
 	uint32 _index;
-	uint32 _savegameIndex;
+	uint32 _lastIndex;
 	uint32 _delta;
 	bool _handleTimeDelta;
 

Modified: scummvm/trunk/engines/lastexpress/game/savegame.cpp
===================================================================
--- scummvm/trunk/engines/lastexpress/game/savegame.cpp	2010-10-27 19:19:57 UTC (rev 53882)
+++ scummvm/trunk/engines/lastexpress/game/savegame.cpp	2010-10-27 19:20:20 UTC (rev 53883)
@@ -61,10 +61,8 @@
 }
 
 SaveLoad::~SaveLoad() {
-	clearHeaders();
+	clear(true);
 
-	SAFE_DELETE(_savegame);
-
 	//Zero passed pointers
 	_engine = NULL;
 }
@@ -115,7 +113,7 @@
 
 	// Reset cached entry headers if needed
 	if (resetHeaders) {
-		clearHeaders();
+		clear();
 
 		SavegameEntryHeader *entryHeader = new SavegameEntryHeader();
 		entryHeader->time = kTimeCityParis;
@@ -156,7 +154,7 @@
 		error("SaveLoad::loadStream: savegame stream is invalid");
 
 	// Load all savegame data
-	uint8* buf = new uint8[4096];
+	uint8* buf = new uint8[8192];
 	while (!save->eos() && !save->err()) {
 		uint32 count = save->read(buf, sizeof(buf));
 		if (count) {
@@ -175,11 +173,14 @@
 	_savegame->seek(0);
 }
 
-void SaveLoad::clearHeaders() {
+void SaveLoad::clear(bool clearStream) {
 	for (uint i = 0; i < _gameHeaders.size(); i++)
 		SAFE_DELETE(_gameHeaders[i]);
 
 	_gameHeaders.clear();
+
+	if (clearStream)
+		SAFE_DELETE(_savegame);
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -187,19 +188,41 @@
 //////////////////////////////////////////////////////////////////////////
 
 // Load game
-bool SaveLoad::loadGame(GameId id) {
+void SaveLoad::loadGame(GameId id) {
+	// Rewind current savegame
+	_savegame->seek(0);
 
-	if (!SaveLoad::isSavegamePresent(id))
-		return false;
+	// Validate main header
+	SavegameMainHeader header;
+	if (!loadMainHeader(_savegame, &header)) {
+		debugC(2, kLastExpressDebugSavegame, "SaveLoad::saveGame - Cannot load main header: %s", getFilename(getMenu()->getGameId()).c_str());
+		return;
+	}
 
-	//Common::InSaveFile *save = SaveLoad::openForLoading(id);
-	// Validate header
+	// Load the last entry
+	_savegame->seek(header.offsetEntry);
 
-	error("SaveLoad::loadgame: not implemented!");
+	SavegameType type = kSavegameTypeIndex;
+	EntityIndex entity = kEntityPlayer;
+	uint32 val = 0;
+	readEntry(&type, &entity, &val, header.keepIndex == 1);
+
+	// Setup last loading time
+	_gameTicksLastSavegame = getState()->timeTicks;
+
+	if (header.keepIndex) {
+		getSound()->clearQueue();
+
+		readEntry(&type, &entity, &val, false);
+	}
+
+	getEntities()->reset();
+	getEntities()->setup(false, entity);
 }
 
-bool SaveLoad::loadGame2(GameId id) {
-	error("SaveLoad::loadgame2: not implemented!");
+// Load a specific game entry
+void SaveLoad::loadGame(GameId id, uint32 index) {
+	error("SaveLoad::loadGame: not implemented! (only loading the last entry is working for now)");
 }
 
 // Save game
@@ -337,8 +360,6 @@
 	Common::Serializer ser(NULL, _savegame);
 	header.saveLoadWithSerializer(ser);
 
-	computeOffset();
-
 	// Write game data
 	WRITE_ENTRY("entity index", ser.syncAsUint32LE(entity), 4);
 	WRITE_ENTRY("state", getState()->saveLoadWithSerializer(ser), 4 + 4 + 4 + 4 + 1 + 4 + 4);
@@ -346,14 +367,14 @@
 	WRITE_ENTRY("positions", getEntities()->savePositions(ser), 4 * 1000);
 	WRITE_ENTRY("compartments", getEntities()->saveCompartments(ser), 4 * 16 * 2);
 	WRITE_ENTRY("progress", getProgress().saveLoadWithSerializer(ser), 4 * 128);
-	WRITE_ENTRY("events", getState()->saveEvents(ser), 512);
+	WRITE_ENTRY("events", getState()->syncEvents(ser), 512);
 	WRITE_ENTRY("inventory", getInventory()->saveLoadWithSerializer(ser), 7 * 32);
 	WRITE_ENTRY("objects", getObjects()->saveLoadWithSerializer(ser), 5 * 128);
 	WRITE_ENTRY("entities", getEntities()->saveLoadWithSerializer(ser), 1262 * 40);
 	WRITE_ENTRY("sound", getSound()->saveLoadWithSerializer(ser), 3 * 4 + getSound()->count() * 64);
 	WRITE_ENTRY("savepoints", getSavePoints()->saveLoadWithSerializer(ser), 128 * 16 + 4 + getSavePoints()->count() * 16);
 
-	header.offset = computeOffset(originalPosition);
+	header.offset = (uint32)_savegame->pos() - (originalPosition + 32);
 
 	// Add padding if necessary
 	while (header.offset & 0xF) {
@@ -376,10 +397,65 @@
 	_savegame->seek(endPosition);
 }
 
-void SaveLoad::readEntry(SavegameType type, EntityIndex entity, uint32 value) {
-	warning("SaveLoad::readEntry: not implemented!");
+void SaveLoad::readEntry(SavegameType *type, EntityIndex *entity, uint32 *val, bool keepIndex) {
+#define LOAD_ENTRY(name, func, val) { \
+	uint32 _prevPosition = (uint32)_savegame->pos(); \
+	func; \
+	uint32 _count = (uint32)_savegame->pos() - _prevPosition; \
+	debugC(kLastExpressDebugSavegame, "Savegame: Reading " #name ": %d bytes", _count); \
+	if (_count != val) \
+		error("SaveLoad::readEntry: Number of bytes read (%d) differ from expected count (%d)", _count, val); \
 }
 
+#define LOAD_ENTRY_ONLY(name, func) { \
+	uint32 _prevPosition = (uint32)_savegame->pos(); \
+	func; \
+	uint32 _count = (uint32)_savegame->pos() - _prevPosition; \
+	debugC(kLastExpressDebugSavegame, "Savegame: Reading " #name ": %d bytes", _count); \
+}
+
+	if (!type || !entity || !val)
+		error("SaveLoad::readEntry: Invalid parameters passed!");
+
+	// Load entry header
+	SavegameEntryHeader entry;
+	Common::Serializer ser(_savegame, NULL);
+	entry.saveLoadWithSerializer(ser);
+
+	if (!entry.isValid())
+		error("SaveLoad::readEntry: entry header is invalid!");
+
+	// Init type, entity & value
+	*type = entry.type;
+	*val = entry.value;
+
+	// Save position
+	uint32 originalPosition = (uint32)_savegame->pos();
+
+	// Load game data
+	LOAD_ENTRY("entity index", ser.syncAsUint32LE(*entity), 4);
+	LOAD_ENTRY("state", getState()->saveLoadWithSerializer(ser), 4 + 4 + 4 + 4 + 1 + 4 + 4);
+	LOAD_ENTRY("selected item", getInventory()->saveSelectedItem(ser), 4);
+	LOAD_ENTRY("positions", getEntities()->savePositions(ser), 4 * 1000);
+	LOAD_ENTRY("compartments", getEntities()->saveCompartments(ser), 4 * 16 * 2);
+	LOAD_ENTRY("progress", getProgress().saveLoadWithSerializer(ser), 4 * 128);
+	LOAD_ENTRY("events", getState()->syncEvents(ser), 512);
+	LOAD_ENTRY("inventory", getInventory()->saveLoadWithSerializer(ser), 7 * 32);
+	LOAD_ENTRY("objects", getObjects()->saveLoadWithSerializer(ser), 5 * 128);
+	LOAD_ENTRY("entities", getEntities()->saveLoadWithSerializer(ser), 1262 * 40);
+	LOAD_ENTRY_ONLY("sound", getSound()->saveLoadWithSerializer(ser));
+	LOAD_ENTRY_ONLY("savepoints", getSavePoints()->saveLoadWithSerializer(ser));
+
+	// Update chapter
+	getProgress().chapter = entry.chapter;
+
+	// Skip padding
+	uint32 offset = _savegame->pos() - originalPosition;
+	if (offset & 0xF) {
+		_savegame->seek((~offset & 0xF) + 1, SEEK_SET);
+	}
+}
+
 SaveLoad::SavegameEntryHeader *SaveLoad::getEntry(uint32 index) {
 	if (index >= _gameHeaders.size())
 		error("SaveLoad::getEntry: invalid index (was:%d, max:%d)", index, _gameHeaders.size() - 1);
@@ -387,14 +463,6 @@
 	return _gameHeaders[index];
 }
 
-uint32 SaveLoad::computeOffset(uint32 originalPosition) {
-	warning("SaveLoad::computePadding: not implemented!");
-	if (!_savegame)
-		error("SaveLoad::computeOffset: savegame stream is invalid");
-
-	return ((uint32)_savegame->pos() - (originalPosition + 32));
-}
-
 //////////////////////////////////////////////////////////////////////////
 // Checks
 //////////////////////////////////////////////////////////////////////////

Modified: scummvm/trunk/engines/lastexpress/game/savegame.h
===================================================================
--- scummvm/trunk/engines/lastexpress/game/savegame.h	2010-10-27 19:19:57 UTC (rev 53882)
+++ scummvm/trunk/engines/lastexpress/game/savegame.h	2010-10-27 19:20:20 UTC (rev 53883)
@@ -94,14 +94,15 @@
 
 	// Init
 	void create(GameId id);
-	void clearHeaders();
+	void clear(bool clearStream = false);
 	uint32 init(GameId id, bool resetHeaders);
 
 	// Save & Load
-	bool loadGame(GameId id);
-	bool loadGame2(GameId id);
+	void loadGame(GameId id);
+	void loadGame(GameId id, uint32 index);
 	void saveGame(SavegameType type, EntityIndex entity, uint32 value);
 
+	void loadVolumeBrightness();
 	void saveVolumeBrightness();
 
 	// Getting information
@@ -266,10 +267,10 @@
 	static bool loadMainHeader(Common::InSaveFile *stream, SavegameMainHeader *header);
 
 	// Entries
-	void writeEntry(SavegameType type, EntityIndex entity, uint32 value);
-	void readEntry(SavegameType type, EntityIndex entity, uint32 value);
+	void writeEntry(SavegameType type, EntityIndex entity, uint32 val);
+	void readEntry(SavegameType *type, EntityIndex *entity, uint32 *val, bool keepIndex);
+
 	SavegameEntryHeader *getEntry(uint32 index);
-	uint32 computeOffset(uint32 originalPosition = 0);
 
 	// Opening save files
 	static Common::String getFilename(GameId id);

Modified: scummvm/trunk/engines/lastexpress/game/sound.cpp
===================================================================
--- scummvm/trunk/engines/lastexpress/game/sound.cpp	2010-10-27 19:19:57 UTC (rev 53882)
+++ scummvm/trunk/engines/lastexpress/game/sound.cpp	2010-10-27 19:20:20 UTC (rev 53883)
@@ -541,7 +541,8 @@
 			}
 		}
 	} else {
-		error("Sound::saveLoadWithSerializer: not implemented!");
+		warning("Sound::saveLoadWithSerializer: not implemented!");
+		s.skip(numEntries * 64);
 	}
 }
 

Modified: scummvm/trunk/engines/lastexpress/game/state.h
===================================================================
--- scummvm/trunk/engines/lastexpress/game/state.h	2010-10-27 19:19:57 UTC (rev 53882)
+++ scummvm/trunk/engines/lastexpress/game/state.h	2010-10-27 19:20:20 UTC (rev 53883)
@@ -544,7 +544,7 @@
 			s.syncAsUint32LE(sceneBackup2);
 		}
 
-		void saveEvents(Common::Serializer &s) {
+		void syncEvents(Common::Serializer &s) {
 			for (uint i = 0; i < ARRAYSIZE(events); i++)
 				s.syncAsByte(events[i]);
 		}


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list