aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippos Karapetis2010-12-07 00:47:05 +0000
committerFilippos Karapetis2010-12-07 00:47:05 +0000
commitde2ef2edc0ea277b4ea5db77a109199c18ff0dae (patch)
tree583d3d52482f25534487de0e8c38f2996dfef75d
parent8ca0b867e0f5127cf192b7cb7a7c12216a9545a4 (diff)
downloadscummvm-rg350-de2ef2edc0ea277b4ea5db77a109199c18ff0dae.tar.gz
scummvm-rg350-de2ef2edc0ea277b4ea5db77a109199c18ff0dae.tar.bz2
scummvm-rg350-de2ef2edc0ea277b4ea5db77a109199c18ff0dae.zip
SCI: Removed the system strings code and replaced it with a much more simplified version, thus greatly simplifying handling of system strings
svn-id: r54805
-rw-r--r--engines/sci/console.cpp16
-rw-r--r--engines/sci/engine/kernel.cpp1
-rw-r--r--engines/sci/engine/kfile.cpp3
-rw-r--r--engines/sci/engine/klists.cpp17
-rw-r--r--engines/sci/engine/kparse.cpp4
-rw-r--r--engines/sci/engine/kstring.cpp38
-rw-r--r--engines/sci/engine/savegame.cpp46
-rw-r--r--engines/sci/engine/seg_manager.cpp29
-rw-r--r--engines/sci/engine/seg_manager.h24
-rw-r--r--engines/sci/engine/segment.cpp28
-rw-r--r--engines/sci/engine/segment.h45
-rw-r--r--engines/sci/parser/vocabulary.cpp2
-rw-r--r--engines/sci/parser/vocabulary.h1
-rw-r--r--engines/sci/sound/music.cpp2
14 files changed, 71 insertions, 185 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 4d458a42c8..21364319b8 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -1616,10 +1616,6 @@ bool Console::cmdPrintSegmentTable(int argc, const char **argv) {
DebugPrintf("D data stack (%d)", (*(DataStack *)mobj)._capacity);
break;
- case SEG_TYPE_SYS_STRINGS:
- DebugPrintf("Y system string table");
- break;
-
case SEG_TYPE_LISTS:
DebugPrintf("L lists (%d)", (*(ListTable *)mobj).entries_used);
break;
@@ -1714,18 +1710,6 @@ bool Console::segmentInfo(int nr) {
}
break;
- case SEG_TYPE_SYS_STRINGS: {
- DebugPrintf("system string table - viewing currently disabled\n");
-#if 0
- SystemStrings *strings = &(mobj->data.sys_strings);
-
- for (int i = 0; i < SYS_STRINGS_MAX; i++)
- if (strings->strings[i].name)
- DebugPrintf(" %s[%d]=\"%s\"\n", strings->strings[i].name, strings->strings[i].max_size, strings->strings[i].value);
-#endif
- }
- break;
-
case SEG_TYPE_CLONES: {
CloneTable *ct = (CloneTable *)mobj;
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index 16534fbce9..e115fd109e 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -384,7 +384,6 @@ uint16 Kernel::findRegType(reg_t reg) {
break;
case SEG_TYPE_LOCALS:
case SEG_TYPE_STACK:
- case SEG_TYPE_SYS_STRINGS:
case SEG_TYPE_DYNMEM:
case SEG_TYPE_HUNK:
#ifdef ENABLE_SCI32
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index db8d7ec331..a2a2db1dff 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -370,8 +370,7 @@ reg_t kGetSaveDir(EngineState *s, int argc, reg_t *argv) {
if (argc > 0)
warning("kGetSaveDir called with %d parameter(s): %04x:%04x", argc, PRINT_REG(argv[0]));
#endif
-
- return make_reg(s->_segMan->getSysStringsSegment(), SYS_STRING_SAVEDIR);
+ return s->_segMan->getSaveDirPtr();
}
reg_t kCheckFreeSpace(EngineState *s, int argc, reg_t *argv) {
diff --git a/engines/sci/engine/klists.cpp b/engines/sci/engine/klists.cpp
index 329e5cd531..f1b7195b36 100644
--- a/engines/sci/engine/klists.cpp
+++ b/engines/sci/engine/klists.cpp
@@ -635,10 +635,18 @@ reg_t kArray(EngineState *s, int argc, reg_t *argv) {
return kString(s, argc, argv);
} else {
if (s->_segMan->getSegmentType(argv[1].segment) == SEG_TYPE_STRING ||
- s->_segMan->getSegmentType(argv[1].segment) == SEG_TYPE_SYS_STRINGS ||
s->_segMan->getSegmentType(argv[1].segment) == SEG_TYPE_SCRIPT) {
return kString(s, argc, argv);
}
+
+#if 0
+ if (op == 6) {
+ if (s->_segMan->getSegmentType(argv[3].segment) == SEG_TYPE_STRING ||
+ s->_segMan->getSegmentType(argv[3].segment) == SEG_TYPE_SCRIPT) {
+ return kString(s, argc, argv);
+ }
+ }
+#endif
}
switch (op) {
@@ -694,11 +702,16 @@ reg_t kArray(EngineState *s, int argc, reg_t *argv) {
return argv[1];
}
case 6: { // Cpy
+#if 0
if (argv[1].isNull() || argv[3].isNull()) {
warning("kArray(Cpy): Request to copy from or to a null pointer");
return NULL_REG;
}
+#endif
+
+ reg_t arrayHandle = argv[1];
SciArray<reg_t> *array1 = s->_segMan->lookupArray(argv[1]);
+ //SciArray<reg_t> *array1 = !argv[1].isNull() ? s->_segMan->lookupArray(argv[1]) : s->_segMan->allocateArray(&arrayHandle);
SciArray<reg_t> *array2 = s->_segMan->lookupArray(argv[3]);
uint32 index1 = argv[2].toUint16();
uint32 index2 = argv[4].toUint16();
@@ -716,7 +729,7 @@ reg_t kArray(EngineState *s, int argc, reg_t *argv) {
for (uint16 i = 0; i < count; i++)
array1->setValue(i + index1, array2->getValue(i + index2));
- return argv[1];
+ return arrayHandle;
}
case 7: // Cmp
// Not implemented in SSCI
diff --git a/engines/sci/engine/kparse.cpp b/engines/sci/engine/kparse.cpp
index 0b55c0fce7..786011a02d 100644
--- a/engines/sci/engine/kparse.cpp
+++ b/engines/sci/engine/kparse.cpp
@@ -97,7 +97,7 @@ reg_t kParse(EngineState *s, int argc, reg_t *argv) {
g_sci->checkVocabularySwitch();
Vocabulary *voc = g_sci->getVocabulary();
voc->parser_event = event;
- reg_t params[2] = { voc->parser_base, stringpos };
+ reg_t params[2] = { s->_segMan->getParserPtr(), stringpos };
ResultWordListList words;
bool res = voc->tokenizeString(words, string.c_str(), &error);
@@ -154,7 +154,7 @@ reg_t kParse(EngineState *s, int argc, reg_t *argv) {
// forgotten :)
writeSelectorValue(segMan, event, SELECTOR(claimed), 1);
if (error) {
- s->_segMan->strcpy(voc->parser_base, error);
+ s->_segMan->strcpy(s->_segMan->getParserPtr(), error);
debugC(2, kDebugLevelParser, "Word unknown: %s", error);
/* Issue warning: */
diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp
index 4a8e0f716b..ede7b02a37 100644
--- a/engines/sci/engine/kstring.cpp
+++ b/engines/sci/engine/kstring.cpp
@@ -706,34 +706,22 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) {
// A count of -1 means fill the rest of the array
uint32 count = argv[5].toSint16() == -1 ? string2Size - index2 + 1 : argv[5].toUint16();
-
- // We have a special case here for argv[1] being a system string
- if (argv[1].segment == s->_segMan->getSysStringsSegment()) {
- // Resize if necessary
- const uint16 sysStringId = argv[1].toUint16();
- SystemString *sysString = s->_segMan->getSystemString(sysStringId);
- assert(sysString);
- if ((uint32)sysString->_maxSize < index1 + count) {
- free(sysString->_value);
- sysString->_maxSize = index1 + count;
- sysString->_value = (char *)calloc(index1 + count, sizeof(char));
- }
+ reg_t strAddress = argv[1];
- strncpy(sysString->_value + index1, string2 + index2, count);
- } else {
- SciString *string1 = s->_segMan->lookupString(argv[1]);
+ SciString *string1 = s->_segMan->lookupString(argv[1]);
+ //SciString *string1 = !argv[1].isNull() ? s->_segMan->lookupString(argv[1]) : s->_segMan->allocateString(&strAddress);
- if (string1->getSize() < index1 + count)
- string1->setSize(index1 + count);
+ if (string1->getSize() < index1 + count)
+ string1->setSize(index1 + count);
- // Note: We're accessing from c_str() here because the
- // string's size ignores the trailing 0 and therefore
- // triggers an assert when doing string2[i + index2].
- for (uint16 i = 0; i < count; i++)
- string1->setValue(i + index1, string2[i + index2]);
- }
-
- } return argv[1];
+ // Note: We're accessing from c_str() here because the
+ // string's size ignores the trailing 0 and therefore
+ // triggers an assert when doing string2[i + index2].
+ for (uint16 i = 0; i < count; i++)
+ string1->setValue(i + index1, string2[i + index2]);
+
+ return strAddress;
+ }
case 7: { // Cmp
Common::String string1 = argv[1].isNull() ? "" : s->_segMan->getString(argv[1]);
Common::String string2 = argv[2].isNull() ? "" : s->_segMan->getString(argv[2]);
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 715b3b5127..2f87b4a72e 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -148,6 +148,23 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
if (type == SEG_TYPE_HUNK)
continue;
+ // Don't save or load the obsolete system string segments
+ if (type == 5) {
+ if (s.isSaving()) {
+ continue;
+ } else {
+ // Old saved game. Skip the data.
+ Common::String tmp;
+ for (int i = 0; i < 4; i++) {
+ s.syncString(tmp); // OBSOLETE: name
+ s.skip(4); // OBSOLETE: maxSize
+ s.syncString(tmp); // OBSOLETE: value
+ }
+ _heap[i] = NULL; // set as freed
+ continue;
+ }
+ }
+
if (s.isLoading())
mobj = SegmentObj::createSegmentObj(type);
@@ -484,32 +501,6 @@ void Script::saveLoadWithSerializer(Common::Serializer &s) {
s.syncAsSint32LE(_markedAsDeleted);
}
-static void sync_SystemString(Common::Serializer &s, SystemString &obj) {
- s.syncString(obj._name);
- s.syncAsSint32LE(obj._maxSize);
-
- // Sync obj._value. We cannot use syncCStr as we must make sure that
- // the allocated buffer has the correct size, i.e., obj._maxSize
- Common::String tmp;
- if (s.isSaving() && obj._value)
- tmp = obj._value;
- s.syncString(tmp);
- if (s.isLoading()) {
- if (!obj._maxSize) {
- obj._value = NULL;
- } else {
- //free(*str);
- obj._value = (char *)calloc(obj._maxSize, sizeof(char));
- strncpy(obj._value, tmp.c_str(), obj._maxSize);
- }
- }
-}
-
-void SystemStrings::saveLoadWithSerializer(Common::Serializer &s) {
- for (int i = 0; i < SYS_STRINGS_MAX; ++i)
- sync_SystemString(s, _strings[i]);
-}
-
void DynMem::saveLoadWithSerializer(Common::Serializer &s) {
s.syncAsSint32LE(_size);
s.syncString(_description);
@@ -891,6 +882,9 @@ void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
delete s->_msgState;
s->_msgState = new MessageState(s->_segMan);
+ // System strings:
+ s->_segMan->initSysStrings();
+
s->abortScriptProcessing = kAbortLoadGame;
// signal restored game to game scripts
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index 8e2a8865ff..7b2c6378ce 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -82,22 +82,19 @@ void SegManager::resetSegMan() {
}
void SegManager::initSysStrings() {
- _sysStrings = (SystemStrings *)allocSegment(new SystemStrings(), &_sysStringsSegId);
-
- // Allocate static buffer for savegame and CWD directories
- SystemString *strSaveDir = getSystemString(SYS_STRING_SAVEDIR);
- strSaveDir->_name = "savedir";
- strSaveDir->_maxSize = MAX_SAVE_DIR_SIZE;
- strSaveDir->_value = (char *)calloc(MAX_SAVE_DIR_SIZE, sizeof(char));
- // Set the savegame dir (actually, we set it to a fake value,
- // since we cannot let the game control where saves are stored)
- ::strcpy(strSaveDir->_value, "");
-
- // Allocate static buffer for the parser base
- SystemString *strParserBase = getSystemString(SYS_STRING_PARSER_BASE);
- strParserBase->_name = "parser-base";
- strParserBase->_maxSize = MAX_PARSER_BASE;
- strParserBase->_value = (char *)calloc(MAX_PARSER_BASE, sizeof(char));
+ if (getSciVersion() <= SCI_VERSION_1_1) {
+ // We need to allocate system strings in one segment, for compatibility reasons
+ allocDynmem(512, "system strings", &_saveDirPtr);
+ _parserPtr = make_reg(_saveDirPtr.segment, _saveDirPtr.offset + 256);
+#ifdef ENABLE_SCI32
+ } else {
+ SciString *saveDirString = allocateString(&_saveDirPtr);
+ saveDirString->setSize(256);
+ saveDirString->setValue(0, 0);
+
+ _parserPtr = NULL_REG; // no SCI2 game had a parser
+#endif
+ }
}
SegmentId SegManager::findFreeSegment() const {
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index 55dd39d89b..c3bf4ae2b6 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -438,22 +438,8 @@ public:
void setClassOffset(int index, reg_t offset) { _classTable[index].reg = offset; }
void resizeClassTable(uint32 size) { _classTable.resize(size); }
- /**
- * Obtains the system strings segment ID
- */
- SegmentId getSysStringsSegment() { return _sysStringsSegId; }
-
- /**
- * Get a pointer to the system string with the specified index,
- * or NULL if that index is invalid.
- *
- * This method is currently only used by kString().
- */
- SystemString *getSystemString(uint idx) const {
- if (idx >= SYS_STRINGS_MAX)
- return NULL;
- return &_sysStrings->_strings[idx];
- }
+ reg_t getSaveDirPtr() const { return _saveDirPtr; }
+ reg_t getParserPtr() const { return _parserPtr; }
#ifdef ENABLE_SCI32
SciArray<reg_t> *allocateArray(reg_t *addr);
@@ -480,9 +466,9 @@ private:
SegmentId _nodesSegId; ///< ID of the (a) node segment
SegmentId _hunksSegId; ///< ID of the (a) hunk segment
- /* System strings */
- SegmentId _sysStringsSegId;
- SystemStrings *_sysStrings;
+ // Statically allocated memory for system strings
+ reg_t _saveDirPtr;
+ reg_t _parserPtr;
#ifdef ENABLE_SCI32
SegmentId _arraysSegId;
diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp
index e40777755f..390e783329 100644
--- a/engines/sci/engine/segment.cpp
+++ b/engines/sci/engine/segment.cpp
@@ -52,9 +52,6 @@ SegmentObj *SegmentObj::createSegmentObj(SegmentType type) {
case SEG_TYPE_LOCALS:
mem = new LocalVariables();
break;
- case SEG_TYPE_SYS_STRINGS:
- mem = new SystemStrings();
- break;
case SEG_TYPE_STACK:
mem = new DataStack();
break;
@@ -99,9 +96,6 @@ const char *SegmentObj::getSegmentTypeName(SegmentType type) {
case SEG_TYPE_LOCALS:
return "locals";
break;
- case SEG_TYPE_SYS_STRINGS:
- return "strings";
- break;
case SEG_TYPE_STACK:
return "stack";
break;
@@ -201,28 +195,6 @@ SegmentRef DynMem::dereference(reg_t pointer) {
return ret;
}
-bool SystemStrings::isValidOffset(uint16 offset) const {
- return offset < SYS_STRINGS_MAX && !_strings[offset]._name.empty();
-}
-
-SegmentRef SystemStrings::dereference(reg_t pointer) {
- SegmentRef ret;
- ret.isRaw = true;
- ret.maxSize = _strings[pointer.offset]._maxSize;
- if (isValidOffset(pointer.offset))
- ret.raw = (byte *)(_strings[pointer.offset]._value);
- else {
- if (g_sci->getGameId() == GID_KQ5) {
- // This occurs in KQ5CD when interacting with certain objects
- } else {
- error("SystemStrings::dereference(): Attempt to dereference invalid pointer %04x:%04x", PRINT_REG(pointer));
- }
- }
-
- return ret;
-}
-
-
//-------------------- clones --------------------
Common::Array<reg_t> CloneTable::listAllOutgoingReferences(reg_t addr) const {
diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h
index aae4c9650c..9aaa3a4b08 100644
--- a/engines/sci/engine/segment.h
+++ b/engines/sci/engine/segment.h
@@ -64,7 +64,7 @@ enum SegmentType {
SEG_TYPE_CLONES = 2,
SEG_TYPE_LOCALS = 3,
SEG_TYPE_STACK = 4,
- SEG_TYPE_SYS_STRINGS = 5,
+ // 5 used to be system strings, now obsolete
SEG_TYPE_LISTS = 6,
SEG_TYPE_NODES = 7,
SEG_TYPE_HUNK = 8,
@@ -145,49 +145,6 @@ public:
}
};
-enum {
- SYS_STRINGS_MAX = 4,
-
- SYS_STRING_SAVEDIR = 0,
- SYS_STRING_PARSER_BASE = 1,
-
- MAX_PARSER_BASE = 64
-};
-
-struct SystemString {
- Common::String _name;
- int _maxSize;
- char *_value;
-};
-
-struct SystemStrings : public SegmentObj {
- SystemString _strings[SYS_STRINGS_MAX];
-
-public:
- SystemStrings() : SegmentObj(SEG_TYPE_SYS_STRINGS) {
- for (int i = 0; i < SYS_STRINGS_MAX; i++) {
- _strings[i]._maxSize = 0;
- _strings[i]._value = 0;
- }
- }
- ~SystemStrings() {
- for (int i = 0; i < SYS_STRINGS_MAX; i++) {
- SystemString *str = &_strings[i];
- if (!str->_name.empty()) {
- free(str->_value);
- str->_value = NULL;
-
- str->_maxSize = 0;
- }
- }
- }
-
- virtual bool isValidOffset(uint16 offset) const;
- virtual SegmentRef dereference(reg_t pointer);
-
- virtual void saveLoadWithSerializer(Common::Serializer &ser);
-};
-
struct LocalVariables : public SegmentObj {
int script_id; /**< Script ID this local variable block belongs to */
Common::Array<reg_t> _locals;
diff --git a/engines/sci/parser/vocabulary.cpp b/engines/sci/parser/vocabulary.cpp
index b1f928cdd9..8d59df5d58 100644
--- a/engines/sci/parser/vocabulary.cpp
+++ b/engines/sci/parser/vocabulary.cpp
@@ -75,7 +75,6 @@ Vocabulary::Vocabulary(ResourceManager *resMan, bool foreign) : _resMan(resMan),
loadAltInputs();
- parser_base = NULL_REG;
parser_event = NULL_REG;
parserIsValid = false;
}
@@ -89,7 +88,6 @@ Vocabulary::~Vocabulary() {
void Vocabulary::reset() {
parserIsValid = false; // Invalidate parser
parser_event = NULL_REG; // Invalidate parser event
- parser_base = make_reg(g_sci->getEngineState()->_segMan->getSysStringsSegment(), SYS_STRING_PARSER_BASE);
}
bool Vocabulary::loadParserWords() {
diff --git a/engines/sci/parser/vocabulary.h b/engines/sci/parser/vocabulary.h
index baf30a03d7..62ed2123eb 100644
--- a/engines/sci/parser/vocabulary.h
+++ b/engines/sci/parser/vocabulary.h
@@ -359,7 +359,6 @@ public:
ParseTreeNode _parserNodes[VOCAB_TREE_NODES]; /**< The parse tree */
// Parser data:
- reg_t parser_base; /**< Base address for the parser error reporting mechanism */
reg_t parser_event; /**< The event passed to Parse() and later used by Said() */
bool parserIsValid; /**< If something has been correctly parsed */
};
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index d72af2b006..afcf810dc2 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -343,7 +343,7 @@ int16 SciMusic::tryToOwnChannel(MusicEntry *caller, int16 bestChannel) {
}
// otherwise look for unused channel
for (int channelNr = _driverFirstChannel; channelNr < 15; channelNr++) {
- if (channelNr == 9) // never map to channel 9 (precussion)
+ if (channelNr == 9) // never map to channel 9 (percussion)
continue;
if (!_usedChannel[channelNr]) {
_usedChannel[channelNr] = caller;