aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sci/engine/kernel.cpp2
-rw-r--r--engines/sci/engine/kernel.h1
-rw-r--r--engines/sci/engine/kmisc.cpp37
-rw-r--r--engines/sci/engine/savegame.cpp4
-rw-r--r--engines/sci/engine/state.cpp2
-rw-r--r--engines/sci/engine/state.h7
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;