aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/lastexpress/game/menu.cpp2
-rw-r--r--engines/lastexpress/game/savegame.cpp151
-rw-r--r--engines/lastexpress/game/savegame.h3
-rw-r--r--engines/lastexpress/game/savepoint.h2
-rw-r--r--engines/lastexpress/game/sound.cpp19
-rw-r--r--engines/lastexpress/game/sound.h1
6 files changed, 100 insertions, 78 deletions
diff --git a/engines/lastexpress/game/menu.cpp b/engines/lastexpress/game/menu.cpp
index a0d498fa1d..537162e6bf 100644
--- a/engines/lastexpress/game/menu.cpp
+++ b/engines/lastexpress/game/menu.cpp
@@ -1150,7 +1150,7 @@ void Menu::switchGame() {
_trainLine->clear();
// Clear loaded savegame data
- getSaveLoad()->clear();
+ getSaveLoad()->clearHeaders();
init(false, kSavegameTypeIndex, 0);
}
diff --git a/engines/lastexpress/game/savegame.cpp b/engines/lastexpress/game/savegame.cpp
index 923ced8ab2..7474245557 100644
--- a/engines/lastexpress/game/savegame.cpp
+++ b/engines/lastexpress/game/savegame.cpp
@@ -61,7 +61,7 @@ SaveLoad::SaveLoad(LastExpressEngine *engine) : _engine(engine), _savegame(NULL)
}
SaveLoad::~SaveLoad() {
- clear();
+ clearHeaders();
SAFE_DELETE(_savegame);
@@ -70,17 +70,19 @@ SaveLoad::~SaveLoad() {
}
void SaveLoad::initStream() {
- SAFE_DELETE(_savegame);
-
+ delete _savegame;
_savegame = new SavegameStream();
}
void SaveLoad::flushStream(GameId id) {
Common::OutSaveFile *save = openForSaving(id);
if (!save)
- error("SaveLoad::initSave: Cannot init savegame (%s)!", getFilename(id).c_str());
+ error("SaveLoad::flushStream: cannot open savegame (%s)!", getFilename(id).c_str());
+
+ if (!_savegame)
+ error("SaveLoad::flushStream: savegame stream is invalid");
- save->write(_savegame->getData(), _savegame->size());
+ save->write(_savegame->getData(), (uint32)_savegame->size());
delete save;
}
@@ -101,28 +103,10 @@ void SaveLoad::create(GameId id) {
uint32 SaveLoad::init(GameId id, bool resetHeaders) {
initStream();
- // Open savegame and check size
- Common::InSaveFile *save = openForLoading(id);
- if (save->size() < 32)
- error("SaveLoad::init - Savegame seems to be corrupted (not enough data: %i bytes)", save->size());
-
- // Load all savegame data
- uint8* buf = new uint8[4096];
- while (!save->eos() && !save->err()) {
- uint32 count = save->read(buf, sizeof(buf));
- if (count) {
- uint32 w = _savegame->write(buf, count);
- assert (w == count);
- }
- }
- if (save->err())
- error("SaveLoad::init - Error reading savegame");
- delete[] buf;
- _savegame->seek(0);
-
- SAFE_DELETE(save);
+ // Load game data
+ loadStream(id);
- // Load the main header
+ // Get the main header
Common::Serializer ser(_savegame, NULL);
SavegameMainHeader mainHeader;
mainHeader.saveLoadWithSerializer(ser);
@@ -131,7 +115,7 @@ uint32 SaveLoad::init(GameId id, bool resetHeaders) {
// Reset cached entry headers if needed
if (resetHeaders) {
- clear();
+ clearHeaders();
SavegameEntryHeader *entryHeader = new SavegameEntryHeader();
entryHeader->time = kTimeCityParis;
@@ -163,7 +147,35 @@ uint32 SaveLoad::init(GameId id, bool resetHeaders) {
return mainHeader.count;
}
-void SaveLoad::clear() {
+void SaveLoad::loadStream(GameId id) {
+ Common::InSaveFile *save = openForLoading(id);
+ if (save->size() < 32)
+ error("SaveLoad::init - Savegame seems to be corrupted (not enough data: %i bytes)", save->size());
+
+ if (!_savegame)
+ error("SaveLoad::loadStream: savegame stream is invalid");
+
+ // Load all savegame data
+ uint8* buf = new uint8[4096];
+ while (!save->eos() && !save->err()) {
+ uint32 count = save->read(buf, sizeof(buf));
+ if (count) {
+ uint32 w = _savegame->write(buf, count);
+ assert (w == count);
+ }
+ }
+
+ if (save->err())
+ error("SaveLoad::init - Error reading savegame");
+
+ delete[] buf;
+ delete save;
+
+ // Move back to the beginning of the stream
+ _savegame->seek(0);
+}
+
+void SaveLoad::clearHeaders() {
for (uint i = 0; i < _gameHeaders.size(); i++)
SAFE_DELETE(_gameHeaders[i]);
@@ -184,8 +196,6 @@ bool SaveLoad::loadGame(GameId id) {
// Validate header
error("SaveLoad::loadgame: not implemented!");
-
- return false;
}
bool SaveLoad::loadGame2(GameId id) {
@@ -204,6 +214,9 @@ void SaveLoad::saveGame(SavegameType type, EntityIndex entity, uint32 value) {
return;
}
+ if (!_savegame)
+ error("SaveLoad::saveGame: savegame stream is invalid");
+
// Validate the current entry if it exists
if (header.count > 0) {
_savegame->seek(header.offsetEntry);
@@ -232,7 +245,7 @@ void SaveLoad::saveGame(SavegameType type, EntityIndex entity, uint32 value) {
}
if (type != kSavegameTypeEvent2 && type != kSavegameTypeAuto)
- header.offsetEntry = _savegame->pos();
+ header.offsetEntry = (uint32)_savegame->pos();
// Write the savegame entry
writeEntry(type, entity, value);
@@ -244,7 +257,7 @@ void SaveLoad::saveGame(SavegameType type, EntityIndex entity, uint32 value) {
header.keepIndex = 1;
} else {
header.keepIndex = 0;
- header.offset = _savegame->pos();
+ header.offset = (uint32)_savegame->pos();
// Save ticks
_gameTicksLastSavegame = getState()->timeTicks;
@@ -267,31 +280,6 @@ void SaveLoad::saveVolumeBrightness() {
}
//////////////////////////////////////////////////////////////////////////
-// Static Members
-//////////////////////////////////////////////////////////////////////////
-
-// Check if a specific savegame exists
-bool SaveLoad::isSavegamePresent(GameId id) {
- if (g_system->getSavefileManager()->listSavefiles(getFilename(id)).size() == 0)
- return false;
-
- return true;
-}
-
-// Check if the game has been started in the specific savegame
-bool SaveLoad::isSavegameValid(GameId id) {
- if (!isSavegamePresent(id)) {
- debugC(2, kLastExpressDebugSavegame, "SaveLoad::isSavegameValid - Savegame does not exist: %s", getFilename(id).c_str());
- return false;
- }
-
- SavegameMainHeader header;
-
- Common::InSaveFile *save = openForLoading(id);
- return loadMainHeader(save, &header);
-}
-
-//////////////////////////////////////////////////////////////////////////
// Headers
//////////////////////////////////////////////////////////////////////////
bool SaveLoad::loadMainHeader(Common::InSaveFile *stream, SavegameMainHeader *header) {
@@ -323,24 +311,27 @@ bool SaveLoad::loadMainHeader(Common::InSaveFile *stream, SavegameMainHeader *he
// Entries
//////////////////////////////////////////////////////////////////////////
void SaveLoad::writeEntry(SavegameType type, EntityIndex entity, uint32 value) {
-#define WRITE_ENTRY(name, func, expected) { \
- uint32 _prevPosition = _savegame->pos(); \
+#define WRITE_ENTRY(name, func, val) { \
+ uint32 _prevPosition = (uint32)_savegame->pos(); \
func; \
- uint32 _count = _savegame->pos() - _prevPosition; \
+ uint32 _count = (uint32)_savegame->pos() - _prevPosition; \
debugC(kLastExpressDebugSavegame, "Savegame: Writing " #name ": %d bytes", _count); \
- if (expected != 0 && _count != expected)\
- error("SaveLoad::writeEntry: Number of bytes written (%d) differ from expected count (%d)", _count, expected); \
+ if (_count != val)\
+ error("SaveLoad::writeEntry: Number of bytes written (%d) differ from expected count (%d)", _count, val); \
}
+ if (!_savegame)
+ error("SaveLoad::writeEntry: savegame stream is invalid");
+
SavegameEntryHeader header;
header.type = type;
- header.time = getState()->time;
+ header.time = (uint32)getState()->time;
header.chapter = getProgress().chapter;
header.value = value;
// Save position
- uint32 originalPosition = _savegame->pos();
+ uint32 originalPosition = (uint32)_savegame->pos();
// Write header
Common::Serializer ser(NULL, _savegame);
@@ -359,8 +350,8 @@ void SaveLoad::writeEntry(SavegameType type, EntityIndex entity, uint32 value) {
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), 0);
- WRITE_ENTRY("savepoints", getSavePoints()->saveLoadWithSerializer(ser), 0);
+ 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);
@@ -371,7 +362,7 @@ void SaveLoad::writeEntry(SavegameType type, EntityIndex entity, uint32 value) {
}
// Save end position
- uint32 endPosition = _savegame->pos();
+ uint32 endPosition = (uint32)_savegame->pos();
// Validate entry header
if (!header.isValid())
@@ -398,13 +389,37 @@ SaveLoad::SavegameEntryHeader *SaveLoad::getEntry(uint32 index) {
uint32 SaveLoad::computeOffset(uint32 originalPosition) {
warning("SaveLoad::computePadding: not implemented!");
+ if (!_savegame)
+ error("SaveLoad::computeOffset: savegame stream is invalid");
- return (_savegame->pos() - originalPosition - 32);
+ return ((uint32)_savegame->pos() - (originalPosition + 32));
}
//////////////////////////////////////////////////////////////////////////
// Checks
//////////////////////////////////////////////////////////////////////////
+
+// Check if a specific savegame exists
+bool SaveLoad::isSavegamePresent(GameId id) {
+ if (g_system->getSavefileManager()->listSavefiles(getFilename(id)).size() == 0)
+ return false;
+
+ return true;
+}
+
+// Check if the game has been started in the specific savegame
+bool SaveLoad::isSavegameValid(GameId id) {
+ if (!isSavegamePresent(id)) {
+ debugC(2, kLastExpressDebugSavegame, "SaveLoad::isSavegameValid - Savegame does not exist: %s", getFilename(id).c_str());
+ return false;
+ }
+
+ SavegameMainHeader header;
+
+ Common::InSaveFile *save = openForLoading(id);
+ return loadMainHeader(save, &header);
+}
+
bool SaveLoad::isGameFinished(uint32 menuIndex, uint32 savegameIndex) {
SavegameEntryHeader *data = getEntry(menuIndex);
diff --git a/engines/lastexpress/game/savegame.h b/engines/lastexpress/game/savegame.h
index 01b2542d12..c6a42fcb3e 100644
--- a/engines/lastexpress/game/savegame.h
+++ b/engines/lastexpress/game/savegame.h
@@ -94,7 +94,7 @@ public:
// Init
void create(GameId id);
- void clear();
+ void clearHeaders();
uint32 init(GameId id, bool resetHeaders);
// Save & Load
@@ -278,6 +278,7 @@ private:
// Savegame stream
void initStream();
+ void loadStream(GameId id);
void flushStream(GameId id);
};
diff --git a/engines/lastexpress/game/savepoint.h b/engines/lastexpress/game/savepoint.h
index 83fe2a6517..6b2c12751d 100644
--- a/engines/lastexpress/game/savepoint.h
+++ b/engines/lastexpress/game/savepoint.h
@@ -131,6 +131,8 @@ public:
*/
Common::String toString();
+ uint32 count() { return _savepoints.size(); }
+
private:
static const uint32 _savePointsMaxSize = 128;
diff --git a/engines/lastexpress/game/sound.cpp b/engines/lastexpress/game/sound.cpp
index 1bfba0ca4b..3c87978657 100644
--- a/engines/lastexpress/game/sound.cpp
+++ b/engines/lastexpress/game/sound.cpp
@@ -508,14 +508,8 @@ void SoundManager::saveLoadWithSerializer(Common::Serializer &s) {
s.syncAsUint32LE(_currentType);
// Compute the number of entries to save
- uint32 count = 0;
- if (s.isSaving()) {
- for (Common::List<SoundEntry *>::iterator i = _cache.begin(); i != _cache.end(); ++i)
- if ((*i)->name2.matchString("NISSND?"))
- ++count;
- }
-
- s.syncAsUint32LE(count);
+ uint32 numEntries = count();
+ s.syncAsUint32LE(numEntries);
// Save or load each entry data
if (s.isSaving()) {
@@ -551,6 +545,15 @@ void SoundManager::saveLoadWithSerializer(Common::Serializer &s) {
}
}
+uint32 SoundManager::count() {
+ uint32 numEntries = 0;
+ for (Common::List<SoundEntry *>::iterator i = _cache.begin(); i != _cache.end(); ++i)
+ if ((*i)->name2.matchString("NISSND?"))
+ ++numEntries;
+
+ return numEntries;
+}
+
//////////////////////////////////////////////////////////////////////////
// Game-related functions
//////////////////////////////////////////////////////////////////////////
diff --git a/engines/lastexpress/game/sound.h b/engines/lastexpress/game/sound.h
index d3b76b6dce..8c5c6aea0d 100644
--- a/engines/lastexpress/game/sound.h
+++ b/engines/lastexpress/game/sound.h
@@ -196,6 +196,7 @@ public:
// Serializable
void saveLoadWithSerializer(Common::Serializer &ser);
+ uint32 count();
private:
typedef int32 *SoundBuffer;