diff options
author | Willem Jan Palenstijn | 2010-07-18 13:31:05 +0000 |
---|---|---|
committer | Willem Jan Palenstijn | 2010-07-18 13:31:05 +0000 |
commit | 921c9a8e33733f119020abb5d99a1b509b119f69 (patch) | |
tree | 86f87e854530432b090ebc186d642979f0fe2e0f | |
parent | 4595b8818a862649d244687e57f15d0cce7d48c0 (diff) | |
download | scummvm-rg350-921c9a8e33733f119020abb5d99a1b509b119f69.tar.gz scummvm-rg350-921c9a8e33733f119020abb5d99a1b509b119f69.tar.bz2 scummvm-rg350-921c9a8e33733f119020abb5d99a1b509b119f69.zip |
SCI: Add basic debugging command for 'said'
svn-id: r50991
-rw-r--r-- | engines/sci/console.cpp | 117 | ||||
-rw-r--r-- | engines/sci/console.h | 1 |
2 files changed, 118 insertions, 0 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 0fec80fe1c..d91f257efe 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -93,6 +93,7 @@ Console::Console(SciEngine *engine) : GUI::Debugger(), DCmd_Register("sentence_fragments", WRAP_METHOD(Console, cmdSentenceFragments)); DCmd_Register("parse", WRAP_METHOD(Console, cmdParse)); DCmd_Register("set_parse_nodes", WRAP_METHOD(Console, cmdSetParseNodes)); + DCmd_Register("said", WRAP_METHOD(Console, cmdSaid)); // Resources DCmd_Register("diskdump", WRAP_METHOD(Console, cmdDiskDump)); DCmd_Register("hexdump", WRAP_METHOD(Console, cmdHexDump)); @@ -306,6 +307,7 @@ bool Console::cmdHelp(int argc, const char **argv) { DebugPrintf(" sentence_fragments - Shows the sentence fragments (used to build Parse trees)\n"); DebugPrintf(" parse - Parses a sequence of words and prints the resulting parse tree\n"); DebugPrintf(" set_parse_nodes - Sets the contents of all parse nodes\n"); + DebugPrintf(" said - Match a string against a said spec\n"); DebugPrintf("\n"); DebugPrintf("Resources:\n"); DebugPrintf(" diskdump - Dumps the specified resource to disk as a patch file\n"); @@ -1210,6 +1212,121 @@ bool Console::cmdParse(int argc, const char **argv) { return true; } +bool Console::cmdSaid(int argc, const char **argv) { + if (argc < 2) { + DebugPrintf("Matches a string against a said spec\n"); + DebugPrintf("Usage: %s <string> > & <said spec>\n", argv[0]); + DebugPrintf("<string> is a sequence of actual words.\n"); + DebugPrintf("<said spec> is a sequence of hex tokens.\n"); + return true; + } + + ResultWordList words; + char *error; + char string[1000]; + byte spec[1000]; + + int p; + // Construct the string + strcpy(string, argv[1]); + for (p = 2; p < argc && strcmp(argv[p],"&") != 0; p++) { + strcat(string, " "); + strcat(string, argv[p]); + } + + if (p >= argc-1) { + DebugPrintf("Matches a string against a said spec\n"); + DebugPrintf("Usage: %s <string> > & <said spec>\n", argv[0]); + DebugPrintf("<string> is a sequence of actual words.\n"); + DebugPrintf("<said spec> is a sequence of hex tokens.\n"); + return true; + } + + // TODO: Maybe turn this into a proper said spec compiler + unsigned int len = 0; + for (p++; p < argc; p++) { + if (strcmp(argv[p], ",") == 0) { + spec[len++] = 0xf0; + } else if (strcmp(argv[p], "&") == 0) { + spec[len++] = 0xf1; + } else if (strcmp(argv[p], "/") == 0) { + spec[len++] = 0xf2; + } else if (strcmp(argv[p], "(") == 0) { + spec[len++] = 0xf3; + } else if (strcmp(argv[p], ")") == 0) { + spec[len++] = 0xf4; + } else if (strcmp(argv[p], "[") == 0) { + spec[len++] = 0xf5; + } else if (strcmp(argv[p], "]") == 0) { + spec[len++] = 0xf6; + } else if (strcmp(argv[p], "#") == 0) { + spec[len++] = 0xf7; + } else if (strcmp(argv[p], "<") == 0) { + spec[len++] = 0xf8; + } else if (strcmp(argv[p], ">") == 0) { + spec[len++] = 0xf9; + } else if (strcmp(argv[p], "[<") == 0) { + spec[len++] = 0xf5; + spec[len++] = 0xf8; + } else if (strcmp(argv[p], "[/") == 0) { + spec[len++] = 0xf5; + spec[len++] = 0xf2; + } else if (strcmp(argv[p], "!*") == 0) { + spec[len++] = 0x0f; + spec[len++] = 0xfe; + } else if (strcmp(argv[p], "[!*]") == 0) { + spec[len++] = 0xf5; + spec[len++] = 0x0f; + spec[len++] = 0xfe; + spec[len++] = 0xf6; + } else { + unsigned int s = strtol(argv[p], 0, 16); + if (s >= 0xf0 && s <= 0xff) { + spec[len++] = s; + } else { + spec[len++] = s >> 8; + spec[len++] = s & 0xFF; + } + } + } + spec[len++] = 0xFF; + + printf("Matching '%s' against:", string); + _engine->getVocabulary()->decipherSaidBlock(spec); + + bool res = _engine->getVocabulary()->tokenizeString(words, string, &error); + if (res && !words.empty()) { + int syntax_fail = 0; + + _engine->getVocabulary()->synonymizeTokens(words); + + DebugPrintf("Parsed to the following blocks:\n"); + + for (ResultWordList::const_iterator i = words.begin(); i != words.end(); ++i) + DebugPrintf(" Type[%04x] Group[%04x]\n", i->_class, i->_group); + + if (_engine->getVocabulary()->parseGNF(words, true)) + syntax_fail = 1; // Building a tree failed + + if (syntax_fail) + DebugPrintf("Building a tree failed.\n"); + else { + _engine->getVocabulary()->dumpParseTree(); + _engine->getVocabulary()->parserIsValid = true; + + int ret = said(_engine->_gamestate, (byte*)spec, true); + DebugPrintf("kSaid: %s\n", (ret == SAID_NO_MATCH ? "No match" : "Match")); + } + + } else { + DebugPrintf("Unknown word: '%s'\n", error); + free(error); + } + + return true; +} + + bool Console::cmdParserNodes(int argc, const char **argv) { if (argc != 2) { DebugPrintf("Shows the specified number of nodes from the parse node tree\n"); diff --git a/engines/sci/console.h b/engines/sci/console.h index 51f02d7168..cb96944e01 100644 --- a/engines/sci/console.h +++ b/engines/sci/console.h @@ -65,6 +65,7 @@ private: bool cmdSentenceFragments(int argc, const char **argv); bool cmdParse(int argc, const char **argv); bool cmdSetParseNodes(int argc, const char **argv); + bool cmdSaid(int argc, const char **argv); // Resources bool cmdDiskDump(int argc, const char **argv); bool cmdHexDump(int argc, const char **argv); |