aboutsummaryrefslogtreecommitdiff
path: root/engines/lastexpress/game/savegame.h
diff options
context:
space:
mode:
authorJulien Templier2010-10-26 00:41:42 +0000
committerJulien Templier2010-10-26 00:41:42 +0000
commitae2c4b7cd209b310ae9e01edafa9613c06ff421f (patch)
treee686f651a78fd7997a050e48f8300099ae333229 /engines/lastexpress/game/savegame.h
parent8217efc74a9b5066bd158e7fef5edd257aec9f16 (diff)
downloadscummvm-rg350-ae2c4b7cd209b310ae9e01edafa9613c06ff421f.tar.gz
scummvm-rg350-ae2c4b7cd209b310ae9e01edafa9613c06ff421f.tar.bz2
scummvm-rg350-ae2c4b7cd209b310ae9e01edafa9613c06ff421f.zip
LASTEXPRESS: Savegame support update
- Implement Menu::startGame() properly - Add stubs functions for game restart - Made savegame headers serializable and moved validity checks inside struct definition - Implement create/init savegame functions - Add SavegameStream to be able to read/write to the same memory stream - Add stubs for setup, writeEntry & loadEntry functions svn-id: r53841
Diffstat (limited to 'engines/lastexpress/game/savegame.h')
-rw-r--r--engines/lastexpress/game/savegame.h211
1 files changed, 162 insertions, 49 deletions
diff --git a/engines/lastexpress/game/savegame.h b/engines/lastexpress/game/savegame.h
index a5af760846..ecb976b38c 100644
--- a/engines/lastexpress/game/savegame.h
+++ b/engines/lastexpress/game/savegame.h
@@ -77,95 +77,208 @@
#include "lastexpress/shared.h"
#include "common/savefile.h"
+#include "common/serializer.h"
namespace LastExpress {
+// Savegame signatures
+#define SAVEGAME_SIGNATURE 0x12001200
+#define SAVEGAME_HEADER 0xE660E660
+
class LastExpressEngine;
class SaveLoad {
public:
- enum HeaderType {
- kHeaderTypeNone = 0,
- kHeaderType1 = 1,
- kHeaderType2 = 2,
- kHeaderType3 = 3,
- kHeaderType4 = 4,
- kHeaderType5 = 5
+ SaveLoad(LastExpressEngine *engine);
+ ~SaveLoad();
+
+ // Init
+ void create(GameId id);
+ void clear();
+ uint32 init(GameId id, bool resetHeaders);
+
+ // Save & Load
+ bool loadGame(GameId id);
+ bool loadGame2(GameId id);
+ void saveGame(SavegameType type, EntityIndex entity, uint32 value);
+
+ void saveVolumeBrightness();
+
+ // Getting information
+ static bool isSavegamePresent(GameId id);
+ static bool isSavegameValid(GameId id);
+
+ bool isGameFinished(uint32 menuIndex, uint32 savegameIndex);
+
+ // Accessors
+ TimeValue getTime(uint32 index) { return getEntry(index)->time; }
+ ChapterIndex getChapter(uint32 index) { return getEntry(index)->chapter; }
+ uint32 getValue(uint32 index) { return getEntry(index)->value; }
+ uint32 getLastSavegameTicks() const { return _gameTicksLastSavegame; }
+
+private:
+ class SavegameStream : public Common::MemoryWriteStreamDynamic, public Common::SeekableReadStream {
+ public:
+ SavegameStream() : MemoryWriteStreamDynamic(DisposeAfterUse::YES),
+ _eos(false) {}
+
+ int32 pos() const { return MemoryWriteStreamDynamic::pos(); }
+ int32 size() const { return MemoryWriteStreamDynamic::size(); }
+ bool seek(int32 offset, int whence = SEEK_SET) { return MemoryWriteStreamDynamic::seek(offset, whence); }
+ bool eos() const { return _eos; }
+ uint32 read(void *dataPtr, uint32 dataSize) {
+ if ((int32)dataSize > size() - pos()) {
+ dataSize = size() - pos();
+ _eos = true;
+ }
+ memcpy(dataPtr, getData() + pos(), dataSize);
+
+ seek(dataSize, SEEK_CUR);
+
+ return dataSize;
+ }
+ private:
+ bool _eos;
};
- struct SavegameMainHeader {
+ LastExpressEngine *_engine;
+
+ struct SavegameMainHeader : Common::Serializable {
uint32 signature;
- uint32 index;
- uint32 time;
- uint32 field_C;
- uint32 field_10;
+ uint32 count;
+ uint32 offset;
+ uint32 offsetEntry;
+ uint32 keepIndex;
int32 brightness;
int32 volume;
uint32 field_1C;
+
+ SavegameMainHeader() {
+ signature = SAVEGAME_SIGNATURE;
+ count = 0;
+ offset = 32;
+ offsetEntry = 32;
+ keepIndex = 0;
+ brightness = 3;
+ volume = 7;
+ field_1C = 9;
+ }
+
+ void saveLoadWithSerializer(Common::Serializer &s) {
+ s.syncAsUint32LE(signature);
+ s.syncAsUint32LE(count);
+ s.syncAsUint32LE(offset);
+ s.syncAsUint32LE(offsetEntry);
+ s.syncAsUint32LE(keepIndex);
+ s.syncAsUint32LE(brightness);
+ s.syncAsUint32LE(volume);
+ s.syncAsUint32LE(field_1C);
+ }
+
+ bool isValid() {
+ if (signature != SAVEGAME_SIGNATURE)
+ return false;
+
+ /* Check not needed as it can never be < 0
+ if (header.chapter < 0)
+ return false;*/
+
+ if (offset < 32)
+ return false;
+
+ if (offsetEntry < 32)
+ return false;
+
+ if (keepIndex != 1 && keepIndex != 0)
+ return false;
+
+ if (brightness < 0 || brightness > 6)
+ return false;
+
+ if (volume < 0 || volume > 7)
+ return false;
+
+ if (field_1C != 9)
+ return false;
+
+ return true;
+ }
};
- struct SavegameEntryHeader {
+ struct SavegameEntryHeader : Common::Serializable {
uint32 signature;
- HeaderType type;
- uint32 time;
+ SavegameType type;
+ TimeValue time;
int field_C;
ChapterIndex chapter;
- EventIndex event;
+ uint32 value;
int field_18;
int field_1C;
SavegameEntryHeader() {
signature = 0;
- type = kHeaderTypeNone;
- time = 0;
+ type = kSavegameTypeIndex;
+ time = kTimeNone;
field_C = 0;
chapter = kChapterAll;
- event = kEventNone;
+ value = 0;
field_18 = 0;
field_1C = 0;
}
- };
-
- SaveLoad(LastExpressEngine *engine);
- ~SaveLoad();
-
- // Save & Load
- bool loadGame(GameId id);
- void saveGame(SavegameType type, EntityIndex entity, uint32 value);
- void saveVolumeBrightness();
+ void saveLoadWithSerializer(Common::Serializer &s) {
+ s.syncAsUint32LE(signature);
+ s.syncAsUint32LE(type);
+ s.syncAsUint32LE(time);
+ s.syncAsUint32LE(field_C);
+ s.syncAsUint32LE(chapter);
+ s.syncAsUint32LE(value);
+ s.syncAsUint32LE(field_18);
+ s.syncAsUint32LE(field_1C);
+ }
- // Init
- void initSavegame(GameId id, bool resetHeaders);
- static void writeMainHeader(GameId id);
+ bool isValid() {
+ if (signature != SAVEGAME_HEADER)
+ return false;
- // Getting information
- static bool isSavegamePresent(GameId id);
- static bool isSavegameValid(GameId id);
+ if (type < kSavegameTypeTime || type > kSavegameTypeTickInterval)
+ return false;
- // Opening save files
- static Common::InSaveFile *openForLoading(GameId id);
- static Common::OutSaveFile *openForSaving(GameId id);
+ if (time < kTimeStartGame || time > kTimeCityConstantinople)
+ return false;
- // Headers
- static bool loadMainHeader(GameId id, SavegameMainHeader *header);
- SavegameEntryHeader *getEntry(uint32 index);
- void clearEntries();
+ if (field_C <= 0 || field_C >= 15)
+ return false;
- uint32 getLastSavegameTicks() const { return _gameTicksLastSavegame; }
+ /* No check for < 0, as it cannot happen normaly */
+ if (chapter == 0)
+ return false;
-private:
- LastExpressEngine *_engine;
+ return true;
+ }
+ };
- uint32 _gameTicksLastSavegame;
+ SavegameStream *_savegame;
Common::Array<SavegameEntryHeader *> _gameHeaders;
+ uint32 _gameTicksLastSavegame;
+
+ // Headers
+ static bool loadMainHeader(Common::InSaveFile *stream, SavegameMainHeader *header);
+ void loadEntryHeader(SavegameEntryHeader *header);
- static Common::String getSavegameName(GameId id);
+ // Entries
+ void writeEntry(SavegameType type, EntityIndex entity, uint32 value);
+ void readEntry(SavegameType type, EntityIndex entity, uint32 value);
+ SavegameEntryHeader *getEntry(uint32 index);
- static void loadEntryHeader(Common::InSaveFile *save, SavegameEntryHeader *header);
+ // Opening save files
+ static Common::String getFilename(GameId id);
+ static Common::InSaveFile *openForLoading(GameId id);
+ static Common::OutSaveFile *openForSaving(GameId id);
- static bool validateMainHeader(const SavegameMainHeader &header);
- static bool validateEntryHeader(const SavegameEntryHeader &header);
+ // Savegame stream
+ void initStream();
+ void flushStream(GameId id);
};
} // End of namespace LastExpress