From da46fc9b35287237ad6f9336159703e605ef565c Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Sat, 30 Jan 2010 02:03:59 +0000 Subject: Add support for saving/loading Arrays/Strings in SCI32. It's possible to save a game in GK1 now via the console, but not load (yet). svn-id: r47696 --- engines/sci/engine/kernel.cpp | 2 +- engines/sci/engine/kfile.cpp | 6 +++ engines/sci/engine/savegame.cpp | 108 ++++++++++++++++++++++++++++++++++++++-- engines/sci/engine/savegame.h | 2 +- engines/sci/engine/segment.h | 4 +- 5 files changed, 115 insertions(+), 7 deletions(-) (limited to 'engines/sci') diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index b9a473f513..567c2b7d8d 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -284,7 +284,7 @@ SciKernelFunction kfunct_mappers[] = { /*60*/ DEFUN("SetMenu", kSetMenu, "i.*"), /*61*/ DEFUN("GetSaveFiles", kGetSaveFiles, "rrr"), /*62*/ DEFUN("GetCWD", kGetCWD, "r"), - /*63*/ DEFUN("CheckFreeSpace", kCheckFreeSpace, "r"), + /*63*/ DEFUN("CheckFreeSpace", kCheckFreeSpace, "r.*"), /*64*/ DEFUN("ValidPath", kValidPath, "r"), /*65*/ DEFUN("CoordPri", kCoordPri, "ii*"), /*66*/ DEFUN("StrAt", kStrAt, "rii*"), diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 038244768b..314135a443 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -425,6 +425,12 @@ reg_t kGetSaveDir(EngineState *s, int argc, reg_t *argv) { } reg_t kCheckFreeSpace(EngineState *s, int argc, reg_t *argv) { +#ifdef ENABLE_SCI32 + // TODO: SCI32 uses a parameter here. + if (argc > 1) + warning("kCheckFreeSpace called with %d parameter(s): %04x:%04x", argc, PRINT_REG(argv[1])); +#endif + Common::String path = s->_segMan->getString(argv[0]); debug(3, "kCheckFreeSpace(%s)", path.c_str()); diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 5764a056e0..848e2c3ebd 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -46,6 +46,10 @@ #include "sci/sound/music.h" #endif +#ifdef ENABLE_SCI32 +#include "sci/graphics/gui32.h" +#endif + namespace Sci { @@ -356,10 +360,11 @@ void EngineState::saveLoadWithSerializer(Common::Serializer &s) { s.skip(4, VER(12), VER(12)); // obsolete: used to be status_bar_foreground s.skip(4, VER(12), VER(12)); // obsolete: used to be status_bar_background - if (s.getVersion() >= 13) { + if (s.getVersion() >= 13 && _gui) { // Save/Load picPort as well (cause sierra sci also does this) int16 picPortTop, picPortLeft; Common::Rect picPortRect; + if (s.isSaving()) picPortRect = _gui->getPortPic(picPortTop, picPortLeft); @@ -422,6 +427,72 @@ void syncWithSerializer(Common::Serializer &s, Table::Entry &obj) { sync_reg_t(s, obj.value); } +#ifdef ENABLE_SCI32 +template <> +void syncWithSerializer(Common::Serializer &s, Table >::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); + } else { + s.syncAsByte(type); + s.syncAsUint32LE(size); + 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); + + sync_reg_t(s, value); + + if (s.isLoading()) + obj.setValue(i, value); + } +} + +template <> +void syncWithSerializer(Common::Serializer &s, Table::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; + + if (s.isSaving()) + value = obj.getValue(i); + + s.syncAsByte(value); + + if (s.isLoading()) + obj.setValue(i, value); + } +} +#endif + template void sync_Table(Common::Serializer &s, T &obj) { s.syncAsSint32LE(obj.first_free); @@ -616,6 +687,22 @@ void SciMusic::saveLoadWithSerializer(Common::Serializer &s) { } #endif +#ifdef ENABLE_SCI32 +void ArrayTable::saveLoadWithSerializer(Common::Serializer &ser) { + if (ser.getVersion() < 18) + return; + + sync_Table(ser, *this); +} + +void StringTable::saveLoadWithSerializer(Common::Serializer &ser) { + if (ser.getVersion() < 18) + return; + + sync_Table(ser, *this); +} +#endif + #pragma mark - @@ -861,6 +948,12 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { // Create a new EngineState object retval = new EngineState(s->resMan, s->_kernel, s->_voc, s->_segMan, s->_gui, s->_audio); retval->_event = new SciEvent(); + +#ifdef ENABLE_SCI32 + // Copy the Gui32 pointer over to the new EngineState, if it exists + if (s->_gui32) + retval->_gui32 = s->_gui32; +#endif // Copy some old data retval->_soundCmd = s->_soundCmd; @@ -923,8 +1016,17 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { // Message state: retval->_msgState = new MessageState(retval->_segMan); - retval->_gui->resetEngineState(retval); - retval->_gui->init(retval->usesOldGfxFunctions()); +#ifdef ENABLE_SCI32 + if (retval->_gui32) { + retval->_gui32->resetEngineState(retval); + retval->_gui32->init(); + } else { +#endif + retval->_gui->resetEngineState(retval); + retval->_gui->init(retval->usesOldGfxFunctions()); +#ifdef ENABLE_SCI32 + } +#endif return retval; } diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h index 38dcd04619..a5828bbd8e 100644 --- a/engines/sci/engine/savegame.h +++ b/engines/sci/engine/savegame.h @@ -36,7 +36,7 @@ namespace Sci { struct EngineState; enum { - CURRENT_SAVEGAME_VERSION = 17, + CURRENT_SAVEGAME_VERSION = 18, MINIMUM_SAVEGAME_VERSION = 9 }; diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h index 82ffd785d6..ef1535a6b3 100644 --- a/engines/sci/engine/segment.h +++ b/engines/sci/engine/segment.h @@ -801,14 +801,14 @@ public: struct ArrayTable : public Table > { ArrayTable() : Table >(SEG_TYPE_ARRAY) {} - virtual void saveLoadWithSerializer(Common::Serializer &ser) {} + void saveLoadWithSerializer(Common::Serializer &ser); SegmentRef dereference(reg_t pointer); }; struct StringTable : public Table { StringTable() : Table(SEG_TYPE_STRING) {} - virtual void saveLoadWithSerializer(Common::Serializer &ser) {} + void saveLoadWithSerializer(Common::Serializer &ser); SegmentRef dereference(reg_t pointer); }; -- cgit v1.2.3