From 8c7cd344c7560e655c0cee3136905f64a0e9ac47 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Fri, 6 Jan 2012 23:26:08 +0100 Subject: AGI: Clean up predictive matching Specifically: * Don't enable the 'next' button in predictive mode when we don't have a full match. Doing this didn't make sense since you'd iterate over a seemingly arbitrary set of completions instead of all possible ones. * Do only a single binary search. * Fix the width of the mode button for mouse press detections. --- engines/agi/agi.h | 2 +- engines/agi/predictive.cpp | 36 +++++++++++++++++------------------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/engines/agi/agi.h b/engines/agi/agi.h index 28403964dd..e9923aba2e 100644 --- a/engines/agi/agi.h +++ b/engines/agi/agi.h @@ -1085,7 +1085,7 @@ private: void blitTextbox(const char *p, int y, int x, int len); void eraseTextbox(); void loadDict(); - bool matchWord(bool onlyExact = false); + bool matchWord(); // Predictive dialog // TODO: Move this to a separate class diff --git a/engines/agi/predictive.cpp b/engines/agi/predictive.cpp index 585a633bb0..e27a2e81f8 100644 --- a/engines/agi/predictive.cpp +++ b/engines/agi/predictive.cpp @@ -112,7 +112,7 @@ bool AgiEngine::predictiveDialog() { "(#)next", "add", "<", "Cancel", "OK", - "Pre", "(0) ", NULL + "(*)Pre", "(0) ", NULL }; const int colors[] = { 15, 0, 15, 0, 15, 0, @@ -556,7 +556,7 @@ void AgiEngine::loadDict() { debug("Time to parse pred.dic: %d, total: %d", time3-time2, time3-time1); } -bool AgiEngine::matchWord(bool onlyExact) { +bool AgiEngine::matchWord() { // If no text has been entered, then there is no match. if (_currentCode.empty()) return false; @@ -565,23 +565,13 @@ bool AgiEngine::matchWord(bool onlyExact) { if (_currentCode.size() > MAXWORDLEN) return false; - if (!onlyExact) { - // First always try an exact match. - bool ret = matchWord(true); - if (ret) - return true; - } - // The entries in the dictionary consist of a code, a space, and then // a space-separated list of words matching this code. // To exactly match a code, we therefore match the code plus the trailing // space in the dictionary. - Common::String code = _currentCode; - if (onlyExact) - code += " "; + Common::String code = _currentCode + " "; - // Perform a binary search on the dictionary to find an entry that has - // _currentCode as a prefix. + // Perform a binary search on the dictionary. int hi = _predictiveDictLineCount - 1; int lo = 0; int line = 0; @@ -593,24 +583,32 @@ bool AgiEngine::matchWord(bool onlyExact) { else if (cmpVal < 0) lo = line + 1; else { - hi = line; break; } } + bool partial = hi < lo; + if (partial) { + // Didn't find an exact match, but 'lo' now points to the first entry + // lexicographically greater than the current code, so that will + // be the first entry with the current code as a prefix, if it exists. + line = lo; + _predictiveDictActLine = NULL; + } else { + _predictiveDictActLine = _predictiveDictLine[line]; + } + _currentWord.clear(); _wordNumber = 0; - if (0 == strncmp(_predictiveDictLine[line], code.c_str(), code.size())) { - _predictiveDictActLine = _predictiveDictLine[line]; + if (0 == strncmp(_predictiveDictLine[line], _currentCode.c_str(), _currentCode.size())) { char tmp[MAXLINELEN]; - strncpy(tmp, _predictiveDictActLine, MAXLINELEN); + strncpy(tmp, _predictiveDictLine[line], MAXLINELEN); tmp[MAXLINELEN - 1] = 0; char *tok = strtok(tmp, " "); tok = strtok(NULL, " "); _currentWord = Common::String(tok, _currentCode.size()); return true; } else { - _predictiveDictActLine = NULL; return false; } } -- cgit v1.2.3