SCI: Implement kMemorySegment().

svn-id: r47776
This commit is contained in:
Walter van Niftrik 2010-01-31 19:47:54 +00:00
parent 4acb18f6b9
commit a92bb6193b
6 changed files with 52 additions and 1 deletions

View file

@ -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, ".*"),

View file

@ -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);

View file

@ -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());

View file

@ -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

View file

@ -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;

View file

@ -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;