mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-03 09:23:37 +00:00
SCI: Add basic debugging command for 'said'
svn-id: r50991
This commit is contained in:
parent
4595b8818a
commit
921c9a8e33
@ -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");
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user