diff options
author | Filippos Karapetis | 2010-12-24 14:47:47 +0000 |
---|---|---|
committer | Filippos Karapetis | 2010-12-24 14:47:47 +0000 |
commit | 9af30a25468f1e31432dda3dbcabd43febb1ae23 (patch) | |
tree | 7ffc988a5c1393d0fbd08f7cbba0dfd553c3f16b /engines/sci | |
parent | 938b63323897e9e673191e12e0339b2ec032a624 (diff) | |
download | scummvm-rg350-9af30a25468f1e31432dda3dbcabd43febb1ae23.tar.gz scummvm-rg350-9af30a25468f1e31432dda3dbcabd43febb1ae23.tar.bz2 scummvm-rg350-9af30a25468f1e31432dda3dbcabd43febb1ae23.zip |
SCI: Now saving/loading the list of synonyms (set by kSetSynonyms), like SSCI did
This is a more correct way of fixing bug #3037618 than in rev #55017.
- Changed replaceant/replacement to be uint16's (they're very small positive
values, usually smaller than 4096)
- Changed SynonymList to an Array (so that it can be saved/loaded)
- Removed the PQ2 script patch to Game::replay()
- Added savegame history
svn-id: r55032
Diffstat (limited to 'engines/sci')
-rw-r--r-- | engines/sci/engine/kparse.cpp | 4 | ||||
-rw-r--r-- | engines/sci/engine/savegame.cpp | 17 | ||||
-rw-r--r-- | engines/sci/engine/savegame.h | 24 | ||||
-rw-r--r-- | engines/sci/engine/script_patches.cpp | 29 | ||||
-rw-r--r-- | engines/sci/parser/vocabulary.h | 19 |
5 files changed, 54 insertions, 39 deletions
diff --git a/engines/sci/engine/kparse.cpp b/engines/sci/engine/kparse.cpp index 786011a02d..076ca59cdb 100644 --- a/engines/sci/engine/kparse.cpp +++ b/engines/sci/engine/kparse.cpp @@ -210,8 +210,8 @@ reg_t kSetSynonyms(EngineState *s, int argc, reg_t *argv) { } else for (int i = 0; i < numSynonyms; i++) { synonym_t tmp; - tmp.replaceant = (int16)READ_LE_UINT16(synonyms + i * 4); - tmp.replacement = (int16)READ_LE_UINT16(synonyms + i * 4 + 2); + tmp.replaceant = READ_LE_UINT16(synonyms + i * 4); + tmp.replacement = READ_LE_UINT16(synonyms + i * 4 + 2); voc->addSynonym(tmp); } } else diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index a4c059db5a..c5e3b355fe 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -43,6 +43,7 @@ #include "sci/graphics/helpers.h" #include "sci/graphics/palette.h" #include "sci/graphics/ports.h" +#include "sci/parser/vocabulary.h" #include "sci/sound/audio.h" #include "sci/sound/music.h" @@ -117,6 +118,12 @@ void syncWithSerializer(Common::Serializer &s, reg_t &obj) { 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(); @@ -288,12 +295,15 @@ void EngineState::saveLoadWithSerializer(Common::Serializer &s) { g_sci->_gfxPalette->saveLoadWithSerializer(s); } +void Vocabulary::saveLoadWithSerializer(Common::Serializer &s) { + syncArray<synonym_t>(s, _synonyms); +} + void LocalVariables::saveLoadWithSerializer(Common::Serializer &s) { s.syncAsSint32LE(script_id); syncArray<reg_t>(s, _locals); } - void Object::saveLoadWithSerializer(Common::Serializer &s) { s.syncAsSint32LE(_flags); syncWithSerializer(s, _pos); @@ -811,6 +821,7 @@ bool gamestate_save(EngineState *s, Common::WriteStream *fh, const char* savenam s->saveLoadWithSerializer(ser); // FIXME: Error handling? if (g_sci->_gfxPorts) g_sci->_gfxPorts->saveLoadWithSerializer(ser); + g_sci->getVocabulary()->saveLoadWithSerializer(ser); return true; } @@ -861,7 +872,6 @@ void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { s->reset(true); s->saveLoadWithSerializer(ser); // FIXME: Error handling? - // Now copy all current state information s->_segMan->reconstructStack(s); @@ -876,6 +886,9 @@ void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { if (g_sci->_gfxPorts) g_sci->_gfxPorts->saveLoadWithSerializer(ser); + if (ser.getVersion() >= 30) + g_sci->getVocabulary()->saveLoadWithSerializer(ser); + g_sci->_soundCmd->reconstructPlayList(); // Message state: diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h index 398a3e2da0..778b0bf137 100644 --- a/engines/sci/engine/savegame.h +++ b/engines/sci/engine/savegame.h @@ -35,8 +35,30 @@ namespace Sci { struct EngineState; +/* + * Savegame format history: + * + * Version - new/changed feature + * ============================= + * 30 - synonyms + * 29 - system strings + * 28 - heap + * 27 - script created windows + * 26 - play time + * 25 - palette intensity + * 24 - palvary + * 23 - script buffer and heap size + * 22 - game signature + * 21 - script local variables + * 20 - exports/synonyms + * 19 - exportsAreWide + * 18 - SCI32 arrays/strings + * 17 - sound + * + */ + enum { - CURRENT_SAVEGAME_VERSION = 29, + CURRENT_SAVEGAME_VERSION = 30, MINIMUM_SAVEGAME_VERSION = 14 }; diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 48bc945e0d..d5d6ff6189 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -719,32 +719,6 @@ const SciScriptSignature mothergoose256Signatures[] = { }; // =========================================================================== -// PQ2 does not call SetSynonyms in Game::replay() (i.e. when loading a game). -// This results in invalid synonyms in some rooms. We patch Game::replay() to -// call SetSynonyms properly, by replacing the kDoSoundResumeAfterRestore -// kernel call, which is a stub in ScummVM. Fixes bug #3037618. -const byte pq2SignatureReplay[] = { - 6, - 0x78, // push1 - 0x39, 0x07, // pushi 07 - 0x43, 0x31, 0x02, // callk DoSound[31] 02 - 0 -}; - -const uint16 pq2PatchReplay[] = { - 0x78, // push1 (parameter count) - 0x89, 0x06, // lsg 06 - 0x43, 0x26, 0x02, // callk SetSynonyms[26] 02 - PATCH_END -}; - -// script, description, magic DWORD, adjust -const SciScriptSignature pq2Signatures[] = { - { 994, "replay synonyms issue", 1, PATCH_MAGICDWORD(0x39, 0x07, 0x43, 0x31), -1, pq2SignatureReplay, pq2PatchReplay }, - SCI_SIGNATUREENTRY_TERMINATOR -}; - -// =========================================================================== // script 215 of qfg1vga pointBox::doit actually processes button-presses // during fighting with monsters. It strangely also calls kGetEvent. Because // the main User::doit also calls kGetEvent it's pure luck, where the event @@ -1222,9 +1196,6 @@ void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uin case GID_MOTHERGOOSE256: signatureTable = mothergoose256Signatures; break; - case GID_PQ2: - signatureTable = pq2Signatures; - break; case GID_QFG1VGA: signatureTable = qfg1vgaSignatures; break; diff --git a/engines/sci/parser/vocabulary.h b/engines/sci/parser/vocabulary.h index 62ed2123eb..3a0bccf5c7 100644 --- a/engines/sci/parser/vocabulary.h +++ b/engines/sci/parser/vocabulary.h @@ -34,6 +34,12 @@ #include "sci/sci.h" #include "sci/engine/vm_types.h" +namespace Common { + +class Serializer; + +} + namespace Sci { class ResourceManager; @@ -143,11 +149,11 @@ typedef Common::List<suffix_t> SuffixList; struct synonym_t { - int replaceant; /**< The word group to replace */ - int replacement; /**< The replacement word group for this one */ + uint16 replaceant; /**< The word group to replace */ + uint16 replacement; /**< The replacement word group for this one */ }; -typedef Common::List<synonym_t> SynonymList; +typedef Common::Array<synonym_t> SynonymList; struct AltInput { @@ -292,6 +298,11 @@ public: */ bool checkAltInput(Common::String& text, uint16& cursorPos); + /** + * Save/load vocabulary data + */ + virtual void saveLoadWithSerializer(Common::Serializer &ser); + private: /** * Loads all words from the main vocabulary. @@ -336,8 +347,6 @@ private: */ void freeAltInputs(); - - ResourceManager *_resMan; VocabularyVersions _vocabVersion; |