diff options
author | Johannes Schickel | 2016-03-23 19:16:11 +0100 |
---|---|---|
committer | Johannes Schickel | 2016-03-25 01:15:26 +0100 |
commit | 77b5ce075a70f2f9c835fa085194a5a941f26459 (patch) | |
tree | 0b72e66fd527b54ef4e29158c39d3a271241c03f /engines/sci/engine/savegame.cpp | |
parent | 114ef5817fe661275f7cb99d490b72f1d287b30e (diff) | |
download | scummvm-rg350-77b5ce075a70f2f9c835fa085194a5a941f26459.tar.gz scummvm-rg350-77b5ce075a70f2f9c835fa085194a5a941f26459.tar.bz2 scummvm-rg350-77b5ce075a70f2f9c835fa085194a5a941f26459.zip |
SCI: Get rid of template hack for serialization.
The former template hack relied on specialized functions for various types. We
use a hand crafted set of functions for serialization functionality now.
Diffstat (limited to 'engines/sci/engine/savegame.cpp')
-rw-r--r-- | engines/sci/engine/savegame.cpp | 227 |
1 files changed, 112 insertions, 115 deletions
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index fcb65157d8..66e8101e9a 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -60,15 +60,121 @@ namespace Sci { #pragma mark - -// Experimental hack: Use syncWithSerializer to sync. By default, this assume -// the object to be synced is a subclass of Serializable and thus tries to invoke -// the saveLoadWithSerializer() method. But it is possible to specialize this -// template function to handle stuff that is not implementing that interface. -template<typename T> -void syncWithSerializer(Common::Serializer &s, T &obj) { +// These are serialization functions for various objects. + +void syncWithSerializer(Common::Serializer &s, Common::Serializable &obj) { obj.saveLoadWithSerializer(s); } +// FIXME: Object could implement Serializable to make use of the function +// above. +void syncWithSerializer(Common::Serializer &s, Object &obj) { + obj.saveLoadWithSerializer(s); +} + +void syncWithSerializer(Common::Serializer &s, reg_t &obj) { + // Segment and offset are accessed directly here + s.syncAsUint16LE(obj._segment); + s.syncAsUint16LE(obj._offset); +} + +void syncWithSerializer(Common::Serializer &s, synonym_t &obj) { + s.syncAsUint16LE(obj.replaceant); + s.syncAsUint16LE(obj.replacement); +} + +void syncWithSerializer(Common::Serializer &s, Class &obj) { + s.syncAsSint32LE(obj.script); + syncWithSerializer(s, obj.reg); +} + +void syncWithSerializer(Common::Serializer &s, SegmentObjTable<Clone>::Entry &obj) { + s.syncAsSint32LE(obj.next_free); + + syncWithSerializer(s, (Clone &)obj); +} + +void syncWithSerializer(Common::Serializer &s, SegmentObjTable<List>::Entry &obj) { + s.syncAsSint32LE(obj.next_free); + + syncWithSerializer(s, obj.first); + syncWithSerializer(s, obj.last); +} + +void syncWithSerializer(Common::Serializer &s, SegmentObjTable<Node>::Entry &obj) { + s.syncAsSint32LE(obj.next_free); + + syncWithSerializer(s, obj.pred); + syncWithSerializer(s, obj.succ); + syncWithSerializer(s, obj.key); + syncWithSerializer(s, obj.value); +} + +#ifdef ENABLE_SCI32 +void syncWithSerializer(Common::Serializer &s, SegmentObjTable<SciArray<reg_t> >::Entry &obj) { + s.syncAsSint32LE(obj.next_free); + + byte type = 0; + uint32 size = 0; + + if (s.isSaving()) { + type = (byte)obj.getType(); + size = obj.getSize(); + } + s.syncAsByte(type); + s.syncAsUint32LE(size); + if (s.isLoading()) { + obj.setType((int8)type); + + // HACK: Skip arrays that have a negative type + if ((int8)type < 0) + return; + + obj.setSize(size); + } + + for (uint32 i = 0; i < size; i++) { + reg_t value; + + if (s.isSaving()) + value = obj.getValue(i); + + syncWithSerializer(s, value); + + if (s.isLoading()) + obj.setValue(i, value); + } +} + +void syncWithSerializer(Common::Serializer &s, SegmentObjTable<SciString>::Entry &obj) { + s.syncAsSint32LE(obj.next_free); + + uint32 size = 0; + + if (s.isSaving()) { + size = obj.getSize(); + s.syncAsUint32LE(size); + } else { + s.syncAsUint32LE(size); + obj.setSize(size); + } + + for (uint32 i = 0; i < size; i++) { + char value = 0; + + if (s.isSaving()) + value = obj.getValue(i); + + s.syncAsByte(value); + + if (s.isLoading()) + obj.setValue(i, value); + } +} +#endif + +#pragma mark - + // By default, sync using syncWithSerializer, which in turn can easily be overloaded. template<typename T> struct DefaultSyncer : Common::BinaryFunction<Common::Serializer, T, void> { @@ -116,20 +222,6 @@ void syncArray(Common::Serializer &s, Common::Array<T> &arr) { sync(s, arr); } - -template<> -void syncWithSerializer(Common::Serializer &s, reg_t &obj) { - // Segment and offset are accessed directly here - s.syncAsUint16LE(obj._segment); - s.syncAsUint16LE(obj._offset); -} - -template<> -void syncWithSerializer(Common::Serializer &s, synonym_t &obj) { - s.syncAsUint16LE(obj.replaceant); - s.syncAsUint16LE(obj.replacement); -} - void SegManager::saveLoadWithSerializer(Common::Serializer &s) { if (s.isLoading()) { resetSegMan(); @@ -247,12 +339,6 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) { } -template<> -void syncWithSerializer(Common::Serializer &s, Class &obj) { - s.syncAsSint32LE(obj.script); - syncWithSerializer(s, obj.reg); -} - static void sync_SavegameMetadata(Common::Serializer &s, SavegameMetadata &obj) { s.syncString(obj.name); s.syncVersion(CURRENT_SAVEGAME_VERSION); @@ -331,95 +417,6 @@ void Object::saveLoadWithSerializer(Common::Serializer &s) { syncArray<reg_t>(s, _variables); } -template<> -void syncWithSerializer(Common::Serializer &s, SegmentObjTable<Clone>::Entry &obj) { - s.syncAsSint32LE(obj.next_free); - - syncWithSerializer<Object>(s, obj); -} - -template<> -void syncWithSerializer(Common::Serializer &s, SegmentObjTable<List>::Entry &obj) { - s.syncAsSint32LE(obj.next_free); - - syncWithSerializer(s, obj.first); - syncWithSerializer(s, obj.last); -} - -template<> -void syncWithSerializer(Common::Serializer &s, SegmentObjTable<Node>::Entry &obj) { - s.syncAsSint32LE(obj.next_free); - - syncWithSerializer(s, obj.pred); - syncWithSerializer(s, obj.succ); - syncWithSerializer(s, obj.key); - syncWithSerializer(s, obj.value); -} - -#ifdef ENABLE_SCI32 -template<> -void syncWithSerializer(Common::Serializer &s, SegmentObjTable<SciArray<reg_t> >::Entry &obj) { - s.syncAsSint32LE(obj.next_free); - - byte type = 0; - uint32 size = 0; - - if (s.isSaving()) { - type = (byte)obj.getType(); - size = obj.getSize(); - } - s.syncAsByte(type); - s.syncAsUint32LE(size); - if (s.isLoading()) { - obj.setType((int8)type); - - // HACK: Skip arrays that have a negative type - if ((int8)type < 0) - return; - - obj.setSize(size); - } - - for (uint32 i = 0; i < size; i++) { - reg_t value; - - if (s.isSaving()) - value = obj.getValue(i); - - syncWithSerializer(s, value); - - if (s.isLoading()) - obj.setValue(i, value); - } -} - -template<> -void syncWithSerializer(Common::Serializer &s, SegmentObjTable<SciString>::Entry &obj) { - s.syncAsSint32LE(obj.next_free); - - uint32 size = 0; - - if (s.isSaving()) { - size = obj.getSize(); - s.syncAsUint32LE(size); - } else { - s.syncAsUint32LE(size); - obj.setSize(size); - } - - for (uint32 i = 0; i < size; i++) { - char value = 0; - - if (s.isSaving()) - value = obj.getValue(i); - - s.syncAsByte(value); - - if (s.isLoading()) - obj.setValue(i, value); - } -} -#endif template<typename T> void sync_Table(Common::Serializer &s, T &obj) { |