From de2ef2edc0ea277b4ea5db77a109199c18ff0dae Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Tue, 7 Dec 2010 00:47:05 +0000 Subject: 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 --- engines/sci/console.cpp | 16 ------------- engines/sci/engine/kernel.cpp | 1 - engines/sci/engine/kfile.cpp | 3 +-- engines/sci/engine/klists.cpp | 17 ++++++++++++-- engines/sci/engine/kparse.cpp | 4 ++-- engines/sci/engine/kstring.cpp | 38 +++++++++++-------------------- engines/sci/engine/savegame.cpp | 46 +++++++++++++++++--------------------- engines/sci/engine/seg_manager.cpp | 29 +++++++++++------------- engines/sci/engine/seg_manager.h | 24 +++++--------------- engines/sci/engine/segment.cpp | 28 ----------------------- engines/sci/engine/segment.h | 45 +------------------------------------ engines/sci/parser/vocabulary.cpp | 2 -- engines/sci/parser/vocabulary.h | 1 - engines/sci/sound/music.cpp | 2 +- 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 *array1 = s->_segMan->lookupArray(argv[1]); + //SciArray *array1 = !argv[1].isNull() ? s->_segMan->lookupArray(argv[1]) : s->_segMan->allocateArray(&arrayHandle); SciArray *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 *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 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 _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; -- cgit v1.2.3