From 722233fd0ddc4447b30f352f6b4bb19728d824fa Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sat, 23 Jan 2010 19:10:56 +0000 Subject: - Moved all of the parser-related variables inside the Vocabulary class - Moved the kSetSynonyms() function inside kscripts (as it's for script synonyms, not parser word synonyms) - The parser vocabulary is now only initialized for SCI0 and SCI01 games, which had a parser svn-id: r47483 --- engines/sci/engine/game.cpp | 9 ++--- engines/sci/engine/kevent.cpp | 3 +- engines/sci/engine/kparse.cpp | 74 +++++---------------------------------- engines/sci/engine/kscripts.cpp | 53 ++++++++++++++++++++++++++++ engines/sci/engine/savegame.cpp | 3 +- engines/sci/engine/state.cpp | 4 --- engines/sci/engine/state.h | 5 --- engines/sci/parser/said.cpp | 2 +- engines/sci/parser/said.y | 4 +-- engines/sci/parser/vocabulary.cpp | 4 +++ engines/sci/parser/vocabulary.h | 6 ++++ engines/sci/sci.cpp | 3 +- 12 files changed, 85 insertions(+), 85 deletions(-) diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp index d84df17117..b5e575e21d 100644 --- a/engines/sci/engine/game.cpp +++ b/engines/sci/engine/game.cpp @@ -263,8 +263,11 @@ int game_init(EngineState *s) { return 1; } - s->parserIsValid = false; // Invalidate parser - s->parser_event = NULL_REG; // Invalidate parser event + if (s->_voc) { + s->_voc->parserIsValid = false; // Invalidate parser + s->_voc->parser_event = NULL_REG; // Invalidate parser event + s->_voc->parser_base = make_reg(s->sys_strings_segment, SYS_STRING_PARSER_BASE); + } // Initialize menu TODO: Actually this should be another init() s->_gui->menuReset(); @@ -276,8 +279,6 @@ int game_init(EngineState *s) { str->_maxSize = MAX_PARSER_BASE; str->_value = (char *)calloc(MAX_PARSER_BASE, sizeof(char)); - s->parser_base = make_reg(s->sys_strings_segment, SYS_STRING_PARSER_BASE); - s->game_start_time = g_system->getMillis(); s->last_wait_time = s->game_start_time; diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp index 2761fdd112..5bc0f1105f 100644 --- a/engines/sci/engine/kevent.cpp +++ b/engines/sci/engine/kevent.cpp @@ -61,7 +61,8 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) { oldy = mousePos.y; curEvent = s->_event->get(mask); - s->parser_event = NULL_REG; // Invalidate parser event + if (s->_voc) + s->_voc->parser_event = NULL_REG; // Invalidate parser event PUT_SEL32V(segMan, obj, x, mousePos.x); PUT_SEL32V(segMan, obj, y, mousePos.y); diff --git a/engines/sci/engine/kparse.cpp b/engines/sci/engine/kparse.cpp index 5cb24f4fac..9b0455b655 100644 --- a/engines/sci/engine/kparse.cpp +++ b/engines/sci/engine/kparse.cpp @@ -62,7 +62,7 @@ reg_t kSaid(EngineState *s, int argc, reg_t *argv) { s->_voc->decipherSaidBlock(said_block); #endif - if (s->parser_event.isNull() || (GET_SEL32V(s->_segMan, s->parser_event, claimed))) { + if (s->_voc->parser_event.isNull() || (GET_SEL32V(s->_segMan, s->_voc->parser_event, claimed))) { return NULL_REG; } @@ -76,7 +76,7 @@ reg_t kSaid(EngineState *s, int argc, reg_t *argv) { s->r_acc = make_reg(0, 1); if (new_lastmatch != SAID_PARTIAL_MATCH) - PUT_SEL32V(s->_segMan, s->parser_event, claimed, 1); + PUT_SEL32V(s->_segMan, s->_voc->parser_event, claimed, 1); } else { return NULL_REG; @@ -84,64 +84,6 @@ reg_t kSaid(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } - -reg_t kSetSynonyms(EngineState *s, int argc, reg_t *argv) { - SegManager *segMan = s->_segMan; - reg_t object = argv[0]; - List *list; - Node *node; - int script; - int numSynonyms = 0; - - s->_voc->clearSynonyms(); - - list = s->_segMan->lookupList(GET_SEL32(segMan, object, elements)); - node = s->_segMan->lookupNode(list->first); - - while (node) { - reg_t objpos = node->value; - int seg; - - script = GET_SEL32V(segMan, objpos, number); - seg = s->_segMan->getScriptSegment(script); - - if (seg > 0) - numSynonyms = s->_segMan->getScript(seg)->getSynonymsNr(); - - if (numSynonyms) { - byte *synonyms = s->_segMan->getScript(seg)->getSynonyms(); - - if (synonyms) { - debugC(2, kDebugLevelParser, "Setting %d synonyms for script.%d\n", - numSynonyms, script); - - if (numSynonyms > 16384) { - error("Segtable corruption: script.%03d has %d synonyms", - script, numSynonyms); - /* We used to reset the corrupted value here. I really don't think it's appropriate. - * Lars */ - } else - for (int i = 0; i < numSynonyms; i++) { - synonym_t tmp; - tmp.replaceant = (int16)READ_LE_UINT16(synonyms + i * 4); - tmp.replacement = (int16)READ_LE_UINT16(synonyms + i * 4 + 2); - s->_voc->addSynonym(tmp); - } - } else - warning("Synonyms of script.%03d were requested, but script is not available", script); - - } - - node = s->_segMan->lookupNode(node->succ); - } - - debugC(2, kDebugLevelParser, "A total of %d synonyms are active now.\n", numSynonyms); - - return s->r_acc; -} - - - reg_t kParse(EngineState *s, int argc, reg_t *argv) { SegManager *segMan = s->_segMan; reg_t stringpos = argv[0]; @@ -151,10 +93,10 @@ reg_t kParse(EngineState *s, int argc, reg_t *argv) { reg_t event = argv[1]; Vocabulary *voc = s->_voc; - s->parser_event = event; + s->_voc->parser_event = event; bool res = voc->tokenizeString(words, string.c_str(), &error); - s->parserIsValid = false; /* not valid */ + s->_voc->parserIsValid = false; /* not valid */ if (res && !words.empty()) { s->_voc->synonymizeTokens(words); @@ -174,13 +116,13 @@ reg_t kParse(EngineState *s, int argc, reg_t *argv) { s->r_acc = make_reg(0, 1); PUT_SEL32V(segMan, event, claimed, 1); - invoke_selector(INV_SEL(s->_gameObj, syntaxFail, kStopOnInvalidSelector), 2, s->parser_base, stringpos); + invoke_selector(INV_SEL(s->_gameObj, syntaxFail, kStopOnInvalidSelector), 2, s->_voc->parser_base, stringpos); /* Issue warning */ debugC(2, kDebugLevelParser, "Tree building failed\n"); } else { - s->parserIsValid = true; + s->_voc->parserIsValid = true; PUT_SEL32V(segMan, event, claimed, 0); #ifdef DEBUG_PARSER @@ -193,11 +135,11 @@ reg_t kParse(EngineState *s, int argc, reg_t *argv) { s->r_acc = make_reg(0, 0); PUT_SEL32V(segMan, event, claimed, 1); if (error) { - s->_segMan->strcpy(s->parser_base, error); + s->_segMan->strcpy(s->_voc->parser_base, error); debugC(2, kDebugLevelParser, "Word unknown: %s\n", error); /* Issue warning: */ - invoke_selector(INV_SEL(s->_gameObj, wordFail, kStopOnInvalidSelector), 2, s->parser_base, stringpos); + invoke_selector(INV_SEL(s->_gameObj, wordFail, kStopOnInvalidSelector), 2, s->_voc->parser_base, stringpos); free(error); return make_reg(0, 1); /* Tell them that it didn't work */ } diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index 16ef002e66..73d440aea5 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -242,4 +242,57 @@ reg_t kRespondsTo(EngineState *s, int argc, reg_t *argv) { return make_reg(0, s->_segMan->isHeapObject(obj) && lookup_selector(s->_segMan, obj, selector, NULL, NULL) != kSelectorNone); } +reg_t kSetSynonyms(EngineState *s, int argc, reg_t *argv) { + SegManager *segMan = s->_segMan; + reg_t object = argv[0]; + List *list; + Node *node; + int script; + int numSynonyms = 0; + + list = s->_segMan->lookupList(GET_SEL32(segMan, object, elements)); + node = s->_segMan->lookupNode(list->first); + + while (node) { + reg_t objpos = node->value; + int seg; + + script = GET_SEL32V(segMan, objpos, number); + seg = s->_segMan->getScriptSegment(script); + + if (seg > 0) + numSynonyms = s->_segMan->getScript(seg)->getSynonymsNr(); + + if (numSynonyms) { + byte *synonyms = s->_segMan->getScript(seg)->getSynonyms(); + + if (synonyms) { + debugC(2, kDebugLevelParser, "Setting %d synonyms for script.%d\n", + numSynonyms, script); + + if (numSynonyms > 16384) { + error("Segtable corruption: script.%03d has %d synonyms", + script, numSynonyms); + /* We used to reset the corrupted value here. I really don't think it's appropriate. + * Lars */ + } else + for (int i = 0; i < numSynonyms; i++) { + synonym_t tmp; + tmp.replaceant = (int16)READ_LE_UINT16(synonyms + i * 4); + tmp.replacement = (int16)READ_LE_UINT16(synonyms + i * 4 + 2); + s->_voc->addSynonym(tmp); + } + } else + warning("Synonyms of script.%03d were requested, but script is not available", script); + + } + + node = s->_segMan->lookupNode(node->succ); + } + + debugC(2, kDebugLevelParser, "A total of %d synonyms are active now.\n", numSynonyms); + + return s->r_acc; +} + } // End of namespace Sci diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index bf188e1d43..bf8241ee86 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -898,7 +898,8 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { // static parser information: - retval->parser_base = make_reg(s->sys_strings_segment, SYS_STRING_PARSER_BASE); + if (retval->_voc) + retval->_voc->parser_base = make_reg(s->sys_strings_segment, SYS_STRING_PARSER_BASE); // Copy breakpoint information from current game instance retval->have_bp = s->have_bp; diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 96460ef69d..2e85bd3356 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -56,8 +56,6 @@ EngineState::EngineState(ResourceManager *res, Kernel *kernel, Vocabulary *voc, stack_base = 0; stack_top = 0; - parser_base = NULL_REG; - parser_event = NULL_REG; script_000 = 0; bp_list = 0; @@ -65,8 +63,6 @@ EngineState::EngineState(ResourceManager *res, Kernel *kernel, Vocabulary *voc, sys_strings_segment = 0; sys_strings = 0; - parserIsValid = false; - _gameObj = NULL_REG; gc_countdown = 0; diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index 17b635f8b9..c006c0e851 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -170,11 +170,6 @@ public: DirSeeker _dirseeker; - /* 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 */ - /* VM Information */ Common::List _executionStack; /**< The execution stack */ diff --git a/engines/sci/parser/said.cpp b/engines/sci/parser/said.cpp index 32bd1fcf8d..98e5db7299 100644 --- a/engines/sci/parser/said.cpp +++ b/engines/sci/parser/said.cpp @@ -2446,7 +2446,7 @@ int said(EngineState *s, byte *spec, bool verbose) { parse_tree_node_t *parse_tree_ptr = s->_voc->_parserNodes; - if (s->parserIsValid) { + if (s->_voc->parserIsValid) { if (said_parse_spec(spec)) { printf("Offending spec was: "); s->_voc->decipherSaidBlock(spec); diff --git a/engines/sci/parser/said.y b/engines/sci/parser/said.y index 1a3b2f52c8..9f30e56302 100644 --- a/engines/sci/parser/said.y +++ b/engines/sci/parser/said.y @@ -802,7 +802,7 @@ int said(EngineState *s, byte *spec, bool verbose) { parse_tree_node_t *parse_tree_ptr = s->_voc->_parser_nodes; - if (s->parserIsValid) { + if (s->_voc->parserIsValid) { if (said_parse_spec(s, spec)) { warning("Offending spec was: "); s->_voc->decipherSaidBlock(spec); @@ -830,7 +830,7 @@ int main (int argc, char *argv) { byte block[] = {0x01, 0x00, 0xf8, 0xf5, 0x02, 0x01, 0xf6, 0xf2, 0x02, 0x01, 0xf2, 0x01, 0x03, 0xff}; EngineState s; - s.parser_valid = 1; + s._voc->parser_valid = 1; said(&s, block); } #endif diff --git a/engines/sci/parser/vocabulary.cpp b/engines/sci/parser/vocabulary.cpp index 5ecea03899..0e84a34cfd 100644 --- a/engines/sci/parser/vocabulary.cpp +++ b/engines/sci/parser/vocabulary.cpp @@ -108,6 +108,10 @@ Vocabulary::Vocabulary(ResourceManager *resMan) : _resMan(resMan) { debug(2, "Assuming that this game does not use a parser."); _parserRules = NULL; } + + parser_base = NULL_REG; + parser_event = NULL_REG; + parserIsValid = false; } Vocabulary::~Vocabulary() { diff --git a/engines/sci/parser/vocabulary.h b/engines/sci/parser/vocabulary.h index 00b8780d1c..d624ccc3fb 100644 --- a/engines/sci/parser/vocabulary.h +++ b/engines/sci/parser/vocabulary.h @@ -32,6 +32,7 @@ #include "common/list.h" #include "sci/sci.h" +#include "sci/engine/vm_types.h" namespace Sci { @@ -313,6 +314,11 @@ private: public: // Accessed by said() parse_tree_node_t _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/sci.cpp b/engines/sci/sci.cpp index 7e428c4f89..37cb20acd3 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -137,7 +137,8 @@ Common::Error SciEngine::run() { _console = new Console(this); _kernel = new Kernel(_resMan, getGameID()); - _vocabulary = new Vocabulary(_resMan); + // Only SCI0 and SCI01 games used a parser + _vocabulary = (getSciVersion() <= SCI_VERSION_1_EGA) ? new Vocabulary(_resMan) : NULL; _audio = new AudioPlayer(_resMan); SegManager *segMan = new SegManager(_resMan); -- cgit v1.2.3