diff options
-rw-r--r-- | engines/sci/engine/kernel.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/kernel.h | 1 | ||||
-rw-r--r-- | engines/sci/engine/kmisc.cpp | 37 | ||||
-rw-r--r-- | engines/sci/engine/savegame.cpp | 4 | ||||
-rw-r--r-- | engines/sci/engine/state.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/state.h | 7 |
6 files changed, 52 insertions, 1 deletions
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index 27bed5b9d9..82171dc91d 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -324,6 +324,7 @@ SciKernelFunction kfunct_mappers[] = { DEFUN("GetMessage", kGetMessage, "iiir"), DEFUN("DoAudio", kDoAudio, ".*"), DEFUN("DoSync", kDoSync, ".*"), + DEFUN("MemorySegment", kMemorySegment, "iri*"), DEFUN("ResCheck", kResCheck, "iii*"), DEFUN("SetQuitStr", kSetQuitStr, "r"), DEFUN("ShowMovie", kShowMovie, "..*"), @@ -370,7 +371,6 @@ SciKernelFunction kfunct_mappers[] = { // Stub functions /*09*/ DEFUN("Show", kShow, "i"), DEFUN("ShiftScreen", kShiftScreen, ".*"), - DEFUN("MemorySegment", kMemorySegment, ".*"), DEFUN("ListOps", kListOps, ".*"), DEFUN("ATan", kATan, ".*"), DEFUN("MergePoly", kMergePoly, ".*"), diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index baff486443..06822f4b5b 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -387,6 +387,7 @@ reg_t kGetMessage(EngineState *s, int argc, reg_t *argv); reg_t kMessage(EngineState *s, int argc, reg_t *argv); reg_t kDoAudio(EngineState *s, int argc, reg_t *argv); reg_t kDoSync(EngineState *s, int argc, reg_t *argv); +reg_t kMemorySegment(EngineState *s, int argc, reg_t *argv); reg_t kResCheck(EngineState *s, int argc, reg_t *argv); reg_t kSetQuitStr(EngineState *s, int argc, reg_t *argv); reg_t kShowMovie(EngineState *s, int argc, reg_t *argv); diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index 229dcb8367..50be5509d7 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -121,6 +121,43 @@ reg_t kMemoryInfo(EngineState *s, int argc, reg_t *argv) { return NULL_REG; } +enum kMemorySegmentFunc { + K_MEMORYSEGMENT_SAVE_DATA = 0, + K_MEMORYSEGMENT_RESTORE_DATA = 1 +}; + +reg_t kMemorySegment(EngineState *s, int argc, reg_t *argv) { + // MemorySegment provides access to a 256-byte block of memory that remains + // intact across restarts and restores + + switch (argv[0].toUint16()) { + case K_MEMORYSEGMENT_SAVE_DATA: { + if (argc < 3) + error("Insufficient number of arguments passed to MemorySegment"); + uint16 size = argv[2].toUint16(); + + if (!size) + size = s->_segMan->strlen(argv[1]) + 1; + + if (size > EngineState::kMemorySegmentMax) + size = EngineState::kMemorySegmentMax; + + s->_memorySegmentSize = size; + + // We assume that this won't be called on pointers + s->_segMan->memcpy(s->_memorySegment, argv[1], size); + break; + } + case K_MEMORYSEGMENT_RESTORE_DATA: + s->_segMan->memcpy(argv[1], s->_memorySegment, s->_memorySegmentSize); + break; + default: + error("Unknown MemorySegment operation %04x", argv[0].toUint16()); + } + + return argv[1]; +} + reg_t kFlushResources(EngineState *s, int argc, reg_t *argv) { run_gc(s); debugC(2, kDebugLevelRoom, "Entering room number %d", argv[0].toUint16()); diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 9c0fd9dc47..9d36914c4a 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -952,6 +952,10 @@ void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { // Copy some old data retval->_soundCmd = s->_soundCmd; + // Copy memory segment + retval->_memorySegmentSize = s->_memorySegmentSize; + memcpy(retval->_memorySegment, s->_memorySegment, s->_memorySegmentSize); + retval->saveLoadWithSerializer(ser); // FIXME: Error handling? #ifdef USE_OLD_MUSIC_FUNCTIONS diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 81d9fe9449..a773894254 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -84,6 +84,8 @@ EngineState::EngineState(ResourceManager *res, Kernel *kernel, Vocabulary *voc, _sci21KernelType = SCI_VERSION_NONE; #endif + _memorySegmentSize = 0; + _usesCdTrack = Common::File::exists("cdaudio.map"); _soundCmd = 0; diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index 299e6ac1d6..9d7a7a5ab4 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -140,6 +140,10 @@ public: EngineState(ResourceManager *res, Kernel *kernel, Vocabulary *voc, SegManager *segMan, SciGui *gui, AudioPlayer *audio); virtual ~EngineState(); + enum { + kMemorySegmentMax = 256 + }; + virtual void saveLoadWithSerializer(Common::Serializer &ser); kLanguage getLanguage(); @@ -287,6 +291,9 @@ public: MessageState *_msgState; + uint _memorySegmentSize; + byte _memorySegment[kMemorySegmentMax]; + EngineState *successor; /**< Successor of this state: Used for restoring */ Common::String getLanguageString(const char *str, kLanguage lang) const; |