aboutsummaryrefslogtreecommitdiff
path: root/engines/agi
diff options
context:
space:
mode:
Diffstat (limited to 'engines/agi')
-rw-r--r--engines/agi/agi.cpp72
-rw-r--r--engines/agi/agi.h12
-rw-r--r--engines/agi/keyboard.cpp26
-rw-r--r--engines/agi/module.mk1
-rw-r--r--engines/agi/predictive.cpp617
5 files changed, 60 insertions, 668 deletions
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp
index e9c9645768..8218d82a05 100644
--- a/engines/agi/agi.cpp
+++ b/engines/agi/agi.cpp
@@ -46,6 +46,8 @@
#include "agi/keyboard.h"
#include "agi/menu.h"
+#include "gui/predictivedialog.h"
+
namespace Agi {
void AgiEngine::allowSynthetic(bool allow) {
@@ -58,9 +60,25 @@ void AgiEngine::processEvents() {
while (_eventMan->pollEvent(event)) {
switch (event.type) {
- case Common::EVENT_PREDICTIVE_DIALOG:
- if (_predictiveDialogRunning)
- break;
+ case Common::EVENT_PREDICTIVE_DIALOG: {
+ GUI::PredictiveDialog _predictiveDialog;
+ _predictiveDialog.runModal();
+ strcpy(_predictiveResult, _predictiveDialog.getResult());
+ if (strcmp(_predictiveResult, "")) {
+ if (_game.inputMode == INPUT_NORMAL) {
+ strcpy((char *)_game.inputBuffer, _predictiveResult);
+ handleKeys(KEY_ENTER);
+ } else if (_game.inputMode == INPUT_GETSTRING) {
+ strcpy(_game.strings[_stringdata.str], _predictiveResult);
+ newInputMode(INPUT_NORMAL);
+ _gfx->printCharacter(_stringdata.x + strlen(_game.strings[_stringdata.str]) + 1,
+ _stringdata.y, ' ', _game.colorFg, _game.colorBg);
+ } else if (_game.inputMode == INPUT_NONE) {
+ for (int n = 0; _predictiveResult[n]; n++)
+ keyEnqueue(_predictiveResult[n]);
+ }
+ }
+ /*
if (predictiveDialog()) {
if (_game.inputMode == INPUT_NORMAL) {
strcpy((char *)_game.inputBuffer, _predictiveResult);
@@ -75,6 +93,8 @@ void AgiEngine::processEvents() {
keyEnqueue(_predictiveResult[n]);
}
}
+ */
+ }
break;
case Common::EVENT_LBUTTONDOWN:
key = BUTTON_LEFT;
@@ -131,65 +151,46 @@ void AgiEngine::processEvents() {
switch (key = event.kbd.keycode) {
case Common::KEYCODE_LEFT:
case Common::KEYCODE_KP4:
- if (_predictiveDialogRunning && key == Common::KEYCODE_KP4)
- key = event.kbd.ascii;
- else if (_allowSynthetic || !event.synthetic)
+ if (_allowSynthetic || !event.synthetic)
key = KEY_LEFT;
break;
case Common::KEYCODE_RIGHT:
case Common::KEYCODE_KP6:
- if (_predictiveDialogRunning && key == Common::KEYCODE_KP6)
- key = event.kbd.ascii;
- else if (_allowSynthetic || !event.synthetic)
+ if (_allowSynthetic || !event.synthetic)
key = KEY_RIGHT;
break;
case Common::KEYCODE_UP:
case Common::KEYCODE_KP8:
- if (_predictiveDialogRunning && key == Common::KEYCODE_KP8)
- key = event.kbd.ascii;
- else if (_allowSynthetic || !event.synthetic)
+ if (_allowSynthetic || !event.synthetic)
key = KEY_UP;
break;
case Common::KEYCODE_DOWN:
case Common::KEYCODE_KP2:
- if (_predictiveDialogRunning && key == Common::KEYCODE_KP2)
- key = event.kbd.ascii;
- else if (_allowSynthetic || !event.synthetic)
+ if (_allowSynthetic || !event.synthetic)
key = KEY_DOWN;
break;
case Common::KEYCODE_PAGEUP:
case Common::KEYCODE_KP9:
- if (_predictiveDialogRunning && key == Common::KEYCODE_KP9)
- key = event.kbd.ascii;
- else if (_allowSynthetic || !event.synthetic)
+ if (_allowSynthetic || !event.synthetic)
key = KEY_UP_RIGHT;
break;
case Common::KEYCODE_PAGEDOWN:
case Common::KEYCODE_KP3:
- if (_predictiveDialogRunning && key == Common::KEYCODE_KP3)
- key = event.kbd.ascii;
- else if (_allowSynthetic || !event.synthetic)
+ if (_allowSynthetic || !event.synthetic)
key = KEY_DOWN_RIGHT;
break;
case Common::KEYCODE_HOME:
case Common::KEYCODE_KP7:
- if (_predictiveDialogRunning && key == Common::KEYCODE_KP7)
- key = event.kbd.ascii;
- else if (_allowSynthetic || !event.synthetic)
+ if (_allowSynthetic || !event.synthetic)
key = KEY_UP_LEFT;
break;
case Common::KEYCODE_END:
case Common::KEYCODE_KP1:
- if (_predictiveDialogRunning && key == Common::KEYCODE_KP1)
- key = event.kbd.ascii;
- else if (_allowSynthetic || !event.synthetic)
+ if (_allowSynthetic || !event.synthetic)
key = KEY_DOWN_LEFT;
break;
case Common::KEYCODE_KP5:
- if (_predictiveDialogRunning)
- key = event.kbd.ascii;
- else
- key = KEY_STATIONARY;
+ key = KEY_STATIONARY;
break;
case Common::KEYCODE_PLUS:
key = '+';
@@ -218,7 +219,7 @@ void AgiEngine::processEvents() {
case Common::KEYCODE_F6:
key = 0x4000;
break;
- case Common::KEYCODE_F7:
+ case Common::KEYCODE_F7:
key = 0x4100;
break;
case Common::KEYCODE_F8:
@@ -575,10 +576,6 @@ AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBas
_oldMode = INPUT_NONE;
- _predictiveDialogRunning = false;
- _predictiveDictText = NULL;
- _predictiveDictLine = NULL;
- _predictiveDictLineCount = 0;
_firstSlot = 0;
resetControllers();
@@ -684,9 +681,6 @@ AgiEngine::~AgiEngine() {
_gfx->deinitMachine();
delete _gfx;
delete _console;
-
- free(_predictiveDictLine);
- free(_predictiveDictText);
}
Common::Error AgiBase::init() {
diff --git a/engines/agi/agi.h b/engines/agi/agi.h
index 55b4805022..1e2b617040 100644
--- a/engines/agi/agi.h
+++ b/engines/agi/agi.h
@@ -43,6 +43,7 @@
#include "agi/logic.h"
#include "agi/sound.h"
+#include "gui/predictivedialog.h"
namespace Common {
class RandomSource;
@@ -1078,7 +1079,6 @@ public:
void clearPrompt(bool useBlackBg = false);
void clearLines(int, int, int);
void flushLines(int, int);
- bool predictiveDialog();
private:
void printStatus(const char *message, ...) GCC_PRINTF(2, 3);
@@ -1088,16 +1088,6 @@ private:
void loadDict();
bool matchWord();
- // Predictive dialog
- // TODO: Move this to a separate class
- char *_predictiveDictText;
- char **_predictiveDictLine;
- int32 _predictiveDictLineCount;
- char *_predictiveDictActLine;
- Common::String _currentCode;
- Common::String _currentWord;
- int _wordNumber;
- bool _predictiveDialogRunning;
public:
char _predictiveResult[40];
diff --git a/engines/agi/keyboard.cpp b/engines/agi/keyboard.cpp
index a7f15c16fb..b7e52f4dc3 100644
--- a/engines/agi/keyboard.cpp
+++ b/engines/agi/keyboard.cpp
@@ -133,6 +133,19 @@ int AgiEngine::handleController(int key) {
if (key == BUTTON_LEFT &&
(int)_mouse.y >= _game.lineUserInput * CHAR_LINES &&
(int)_mouse.y <= (_game.lineUserInput + 1) * CHAR_LINES) {
+ GUI::PredictiveDialog _predictiveDialog;
+ _predictiveDialog.runModal();
+ strcpy(_predictiveResult, _predictiveDialog.getResult());
+ if (strcmp(_predictiveResult, "")) {
+ if (_game.inputMode == INPUT_NONE) {
+ for (int n = 0; _predictiveResult[n]; n++)
+ keyEnqueue(_predictiveResult[n]);
+ } else {
+ strcpy((char *)_game.inputBuffer, _predictiveResult);
+ handleKeys(KEY_ENTER);
+ }
+ }
+ /*
if (predictiveDialog()) {
if (_game.inputMode == INPUT_NONE) {
for (int n = 0; _predictiveResult[n]; n++)
@@ -142,6 +155,7 @@ int AgiEngine::handleController(int key) {
handleKeys(KEY_ENTER);
}
}
+ */
return true;
}
@@ -217,6 +231,17 @@ void AgiEngine::handleGetstring(int key) {
case BUTTON_LEFT:
if ((int)_mouse.y >= _stringdata.y * CHAR_LINES &&
(int)_mouse.y <= (_stringdata.y + 1) * CHAR_LINES) {
+ GUI::PredictiveDialog _predictiveDialog;
+ _predictiveDialog.runModal();
+ strcpy(_predictiveResult, _predictiveDialog.getResult());
+ if (strcmp(_predictiveResult, "")) {
+ strcpy(_game.strings[_stringdata.str], _predictiveResult);
+ newInputMode(INPUT_NORMAL);
+ _gfx->printCharacter(_stringdata.x + strlen(_game.strings[_stringdata.str]) + 1,
+ _stringdata.y, ' ', _game.colorFg, _game.colorBg);
+ return;
+ }
+ /*
if (predictiveDialog()) {
strcpy(_game.strings[_stringdata.str], _predictiveResult);
newInputMode(INPUT_NORMAL);
@@ -224,6 +249,7 @@ void AgiEngine::handleGetstring(int key) {
_stringdata.y, ' ', _game.colorFg, _game.colorBg);
return;
}
+ */
}
break;
case KEY_ENTER:
diff --git a/engines/agi/module.mk b/engines/agi/module.mk
index 68d86f7b2e..331a10c16e 100644
--- a/engines/agi/module.mk
+++ b/engines/agi/module.mk
@@ -28,7 +28,6 @@ MODULE_OBJS := \
preagi_mickey.o \
preagi_troll.o \
preagi_winnie.o \
- predictive.o \
saveload.o \
sound.o \
sound_2gs.o \
diff --git a/engines/agi/predictive.cpp b/engines/agi/predictive.cpp
deleted file mode 100644
index 4bb378934d..0000000000
--- a/engines/agi/predictive.cpp
+++ /dev/null
@@ -1,617 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "agi/agi.h"
-#include "agi/graphics.h"
-#include "agi/keyboard.h"
-
-#include "common/config-manager.h"
-#include "common/textconsole.h"
-
-#ifdef __DS__
-#include "wordcompletion.h"
-#endif
-
-namespace Agi {
-
-enum {
- kModePre = 0,
- kModeNum = 1,
- kModeAbc = 2
-};
-
-enum {
- MAXLINELEN = 80,
- MAXWORDLEN = 24
-};
-
-uint8 countWordsInString(char *str) {
- // Count the number of (space separated) words in the given string.
- char *ptr;
-
- if (!str)
- return 0;
-
- ptr = strchr(str, ' ');
- if (!ptr) {
- debug("Invalid dictionary line");
- return 0;
- }
-
- uint8 num = 1;
- ptr++;
- while ((ptr = strchr(ptr, ' '))) {
- ptr++;
- num++;
- }
- return num;
-}
-
-void bringWordtoTop(char *str, int wordnum) {
- // This function reorders the words on the given pred.dic line
- // by moving the word at position 'wordnum' to the front (that is, right behind
- // right behind the numerical code word at the start of the line).
- Common::Array<Common::String> words;
- char buf[MAXLINELEN];
-
- if (!str)
- return;
- strncpy(buf, str, MAXLINELEN);
- buf[MAXLINELEN - 1] = 0;
- char *word = strtok(buf, " ");
- if (!word) {
- debug("Invalid dictionary line");
- return;
- }
-
- words.push_back(word);
- while ((word = strtok(NULL, " ")) != NULL)
- words.push_back(word);
- words.insert_at(1, words.remove_at(wordnum + 1));
-
- Common::String tmp;
- for (uint8 i = 0; i < words.size(); i++)
- tmp += words[i] + " ";
- tmp.deleteLastChar();
- memcpy(str, tmp.c_str(), strlen(str));
-}
-
-bool AgiEngine::predictiveDialog() {
- uint8 x;
- int y;
- int bx[17], by[17];
- Common::String prefix;
- char temp[MAXWORDLEN + 1], repeatcount[MAXWORDLEN];
- AgiBlock tmpwindow;
- bool navigationwithkeys = false;
-
- const char *buttonStr[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" };
- const char *buttons[] = {
- "(1)'-.&", "(2)abc", "(3)def",
- "(4)ghi", "(5)jkl", "(6)mno",
- "(7)pqrs", "(8)tuv", "(9)wxyz",
- "(#)next", "add",
- "<",
- "Cancel", "OK",
- "(*)Pre", "(0) ", NULL
- };
- const int colors[] = {
- 15, 0, 15, 0, 15, 0,
- 15, 0, 15, 0, 15, 0,
- 15, 0, 15, 0, 15, 0,
- 15, 12, 15, 12,
- 15, 0,
- 15, 0, 15, 0,
- 14, 0, 15, 0, 0, 0
- };
- const char *modes[] = { "(*)Pre", "(*)123", "(*)Abc" };
-
- // FIXME: Move this to a more appropriate place.
- if (!_predictiveDictText) {
- loadDict();
- if (!_predictiveDictText)
- return false;
- }
- _predictiveDictActLine = NULL;
- uint8 numMatchingWords = 0;
-
- _predictiveDialogRunning = true;
- _system->setFeatureState(OSystem::kFeatureDisableKeyFiltering, true);
-
- memset(repeatcount, 0, sizeof(repeatcount));
-
- // show the predictive dialog.
- // if another window is already in display, save its state into tmpwindow
- memset(&tmpwindow, 0, sizeof(tmpwindow));
- tmpwindow.active = false;
- if (_game.window.active)
- memcpy(&tmpwindow, &(_game.window), sizeof(AgiBlock));
- drawWindow(50, 40, 269, 159);
- _gfx->drawRectangle(62, 54, 249, 66, MSG_BOX_TEXT);
- _gfx->flushBlock(62, 54, 249, 66);
-
- bx[15] = 73; // Zero/space
- by[15] = 120;
- bx[9] = 110; // next
- by[9] = 120;
- bx[10] = 172; // add
- by[10] = 120;
- bx[14] = 200; // Mode
- by[14] = 120;
- bx[11] = 252; // Backspace
- by[11] = 57;
- bx[12] = 180; // Cancel
- by[12] = 140;
- bx[13] = 240; // OK
- by[13] = 140;
-
- x = 73;
- y = 75;
- for (int i = 0; i < 9; i++) {
- bx[i] = x;
- by[i] = y;
- x += 60;
- if (i % 3 == 2) {
- y += 15;
- x = 73;
- }
- }
-
- clearKeyQueue();
-
- prefix.clear();
- _currentCode.clear();
- _currentWord.clear();
- _wordNumber = 0;
-
- int mode = kModePre;
-
- bool needRefresh = true;
- int active = -1, lastactive = 0;
- bool rc = false;
- bool closeDialog = false;
- bool enterPredictiveResult = false;
- while (!closeDialog && !shouldQuit()) {
- if (needRefresh) {
- for (int i = 0; buttons[i]; i++) {
- int color1 = colors[i * 2];
- int color2 = colors[i * 2 + 1];
-
- if (i == 9 && !((mode != kModeAbc && _predictiveDictActLine && numMatchingWords > 1)
- || (mode == kModeAbc && _currentWord.size() && _currentWord.lastChar() != ' '))) { // Next
- color2 = 7;
- }
-
- // needs fixing, or remove it!
- bool _addIsActive = false; // FIXME: word adding is not implemented
- if (i == 10 && !_addIsActive) { // Add
- color2 = 7;
- }
- if (i == 14) {
- _gfx->drawDefaultStyleButton(bx[i], by[i], modes[mode], i == active, 0, color1, color2);
- } else {
- _gfx->drawDefaultStyleButton(bx[i], by[i], buttons[i], i == active, 0, color1, color2);
- }
- }
-
- Common::strlcpy(temp, prefix.c_str(), sizeof(temp));
- Common::strlcat(temp, _currentWord.c_str(), sizeof(temp));
-
- for (int i = prefix.size() + _currentCode.size(); i < MAXWORDLEN; i++)
- temp[i] = ' ';
- temp[MAXWORDLEN] = 0;
-
- printText(temp, 0, 8, 7, MAXWORDLEN, 15, 0);
- _gfx->flushBlock(62, 54, 249, 66);
-
- if (active >= 0 && !navigationwithkeys) {
- // provide visual feedback only when not navigating with the arrows
- // so that the user can see the active button.
- active = -1;
- needRefresh = true;
- } else
- needRefresh = false;
-
- _gfx->doUpdate();
- }
-
- bool processkey = false;
-
- pollTimer();
- int key = doPollKeyboard();
- switch (key) {
- case KEY_ENTER:
- if (navigationwithkeys) {
- // when the user has utilized arrow key navigation,
- // interpret enter as 'click' on the active button
- active = lastactive;
- } else {
- // else it is a shortcut for 'Ok'
- active = 13;
- }
- processkey = true;
- break;
- case KEY_ESCAPE:
- rc = false;
- closeDialog = true;
- break;
- case BUTTON_LEFT:
- navigationwithkeys = false;
- for (int i = 0; buttons[i]; i++) {
- if (_gfx->testButton(bx[i], by[i], buttons[i])) {
- active = i;
- processkey = true;
- break;
- }
- }
- break;
- case KEY_BACKSPACE:
- active = 11;
- processkey = true;
- break;
- case '#':
- active = 9;
- processkey = true;
- break;
- case '*':
- active = 14;
- processkey = true;
- break;
- case 0x09: // Tab
- navigationwithkeys = true;
- debugC(3, kDebugLevelText, "Focus change");
- lastactive = active = lastactive + 1;
- active %= ARRAYSIZE(buttons) - 1;
- needRefresh = true;
- break;
- case KEY_LEFT:
- navigationwithkeys = true;
- if (lastactive == 0 || lastactive == 3 || lastactive == 6)
- active = lastactive + 2;
- else if (lastactive == 9)
- active = 15;
- else if (lastactive == 11)
- active = 11;
- else if (lastactive == 12)
- active = 13;
- else if (lastactive == 14)
- active = 10;
- else
- active = lastactive - 1;
- lastactive = active;
- needRefresh = true;
- break;
- case KEY_RIGHT:
- navigationwithkeys = true;
- if (lastactive == 2 || lastactive == 5 || lastactive == 8)
- active = lastactive - 2;
- else if (lastactive == 10)
- active = 14;
- else if (lastactive == 11)
- active = 11;
- else if (lastactive == 13)
- active = 12;
- else if (lastactive == 15)
- active = 9;
- else
- active = lastactive + 1;
- lastactive = active;
- needRefresh = true;
- break;
- case KEY_UP:
- navigationwithkeys = true;
- if (lastactive <= 2)
- active = 11;
- else if (lastactive == 9 || lastactive == 10)
- active = lastactive - 2;
- else if (lastactive == 11)
- active = 13;
- else if (lastactive == 14)
- active = 8;
- else if (lastactive == 15)
- active = 6;
- else
- active = lastactive - 3;
- lastactive = active;
- needRefresh = true;
- break;
- case KEY_DOWN:
- navigationwithkeys = true;
- if (lastactive == 6)
- active = 15;
- else if (lastactive == 7 || lastactive == 8)
- active = lastactive + 2;
- else if (lastactive == 11)
- active = 0;
- else if (lastactive == 12 || lastactive == 13)
- active = 11;
- else if (lastactive == 14 || lastactive == 15)
- active = lastactive - 2;
- else
- active = lastactive + 3;
- lastactive = active;
- needRefresh = true;
- break;
- default:
- // handle numeric buttons
- if (key >= '1' && key <= '9') {
- active = key - '1';
- processkey = true;
- } else if (key == '0') {
- active = 15;
- processkey = true;
- }
- break;
- }
-
- if (processkey && !closeDialog) {
- if (active >= 0) {
- needRefresh = true;
- lastactive = active;
- if (active == 15 && mode != kModeNum) { // Space
- // bring MRU word at the top of the list when changing words
- if (mode == kModePre && _predictiveDictActLine && numMatchingWords > 1 && _wordNumber != 0)
- bringWordtoTop(_predictiveDictActLine, _wordNumber);
- strncpy(temp, _currentWord.c_str(), _currentCode.size());
- temp[_currentCode.size()] = 0;
- prefix += temp;
- prefix += " ";
- _currentCode.clear();
- _currentWord.clear();
- numMatchingWords = 0;
- memset(repeatcount, 0, sizeof(repeatcount));
- } else if (active < 9 || active == 11 || active == 15) { // number or backspace
- if (active == 11) { // backspace
- if (_currentCode.size()) {
- repeatcount[_currentCode.size() - 1] = 0;
- _currentCode.deleteLastChar();
- } else {
- if (prefix.size())
- prefix.deleteLastChar();
- }
- } else if (prefix.size() + _currentCode.size() < MAXWORDLEN - 1) { // don't overflow the dialog line
- if (active == 15) { // zero
- _currentCode += buttonStr[9];
- } else {
- _currentCode += buttonStr[active];
- }
- }
-
- switch (mode) {
- case kModeNum:
- _currentWord = _currentCode;
- break;
- case kModePre:
- if (!matchWord() && _currentCode.size()) {
- _currentCode.deleteLastChar();
- matchWord();
- }
- numMatchingWords = countWordsInString(_predictiveDictActLine);
- break;
- case kModeAbc:
- for (x = 0; x < _currentCode.size(); x++)
- if (_currentCode[x] >= '1')
- temp[x] = buttons[_currentCode[x] - '1'][3 + repeatcount[x]];
- temp[_currentCode.size()] = 0;
- _currentWord = temp;
- }
- } else if (active == 9) { // next
- if (mode == kModePre) {
- if (_predictiveDictActLine && numMatchingWords > 1) {
- _wordNumber = (_wordNumber + 1) % numMatchingWords;
- char tmp[MAXLINELEN];
- strncpy(tmp, _predictiveDictActLine, MAXLINELEN);
- tmp[MAXLINELEN - 1] = 0;
- char *tok = strtok(tmp, " ");
- for (uint8 i = 0; i <= _wordNumber; i++)
- tok = strtok(NULL, " ");
- _currentWord = Common::String(tok, _currentCode.size());
- }
- } else if (mode == kModeAbc){
- x = _currentCode.size();
- if (x) {
- if (_currentCode.lastChar() == '1' || _currentCode.lastChar() == '7' || _currentCode.lastChar() == '9')
- repeatcount[x - 1] = (repeatcount[x - 1] + 1) % 4;
- else
- repeatcount[x - 1] = (repeatcount[x - 1] + 1) % 3;
- if (_currentCode.lastChar() >= '1')
- _currentWord.setChar(buttons[_currentCode[x - 1] - '1'][3 + repeatcount[x - 1]], x-1);
- }
- }
- } else if (active == 10) { // add
- debug(0, "add");
- } else if (active == 13) { // Ok
- // bring MRU word at the top of the list when ok'ed out of the dialog
- if (mode == kModePre && _predictiveDictActLine && numMatchingWords > 1 && _wordNumber != 0)
- bringWordtoTop(_predictiveDictActLine, _wordNumber);
- rc = true;
- enterPredictiveResult = true;
- closeDialog = true;
- } else if (active == 14) { // Mode
- mode++;
- if (mode > kModeAbc)
- mode = kModePre;
-
- // truncate current input at mode change
- strncpy(temp, _currentWord.c_str(), _currentCode.size());
- temp[_currentCode.size()] = 0;
- prefix += temp;
- _currentCode.clear();
- _currentWord.clear();
- memset(repeatcount, 0, sizeof(repeatcount));
- _predictiveDictActLine = NULL;
- } else {
- enterPredictiveResult = true;
- closeDialog = true;
- }
- }
- }
- }
-
- if (enterPredictiveResult) {
- Common::strlcpy(_predictiveResult, prefix.c_str(), sizeof(_predictiveResult));
- Common::strlcat(_predictiveResult, _currentWord.c_str(), sizeof(_predictiveResult));
- }
-
- // if another window was shown, bring it up again
- if (!tmpwindow.active)
- closeWindow();
- else {
- _gfx->restoreBlock(_game.window.x1, _game.window.y1,
- _game.window.x2, _game.window.y2, _game.window.buffer);
-
- free(_game.window.buffer);
- memcpy(&(_game.window), &tmpwindow, sizeof(AgiBlock));
- _gfx->doUpdate();
- }
-
- _system->setFeatureState(OSystem::kFeatureDisableKeyFiltering, false);
- _predictiveDialogRunning = false;
-
- return rc;
-}
-
-void AgiEngine::loadDict() {
- Common::File inFile;
- int lines = 0;
-
- ConfMan.registerDefault("predictive_dictionary", "pred.dic");
-
- uint32 time1 = _system->getMillis();
- Common::String inFileName(ConfMan.get("predictive_dictionary"));
- if (!inFile.open(inFileName))
- return;
-
- char *ptr;
- int size = inFile.size();
-
- _predictiveDictText = (char *)malloc(size + 1);
- if (!_predictiveDictText) {
- warning("Not enough memory to load the predictive dictionary");
- return;
- }
- inFile.read(_predictiveDictText, size);
- _predictiveDictText[size] = 0;
- uint32 time2 = _system->getMillis();
- debug("Time to read %s: %d bytes, %d ms", inFileName.c_str(), size, time2-time1);
- inFile.close();
-
- ptr = _predictiveDictText;
- lines = 1;
- while ((ptr = strchr(ptr, '\n'))) {
- lines++;
- ptr++;
- }
-
- _predictiveDictLine = (char **)calloc(1, sizeof(char *) * lines);
- if (_predictiveDictLine == NULL) {
- warning("Cannot allocate memory for line index buffer");
- return;
- }
- _predictiveDictLine[0] = _predictiveDictText;
- ptr = _predictiveDictText;
- int i = 1;
- while ((ptr = strchr(ptr, '\n'))) {
- *ptr = 0;
- ptr++;
-#ifdef __DS__
- // Pass the line on to the DS word list
- DS::addAutoCompleteLine(_predictiveDictLine[i - 1]);
-#endif
- _predictiveDictLine[i++] = ptr;
- }
- if (_predictiveDictLine[lines - 1][0] == 0)
- lines--;
-
- _predictiveDictLineCount = lines;
- debug("Loaded %d lines", _predictiveDictLineCount);
-
- // FIXME: We use binary search on _predictiveDictLine, yet we make no attempt
- // to ever sort this array (except for the DS port). That seems risky, doesn't it?
-
-#ifdef __DS__
- // Sort the DS word completion list, to allow for a binary chop later (in the ds backend)
- DS::sortAutoCompleteWordList();
-#endif
-
- uint32 time3 = _system->getMillis();
- debug("Time to parse pred.dic: %d, total: %d", time3-time2, time3-time1);
-}
-
-bool AgiEngine::matchWord() {
- // If no text has been entered, then there is no match.
- if (_currentCode.empty())
- return false;
-
- // If the currently entered text is too long, it cannot match anything.
- if (_currentCode.size() > MAXWORDLEN)
- return false;
-
- // 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 + " ";
-
- // Perform a binary search on the dictionary.
- int hi = _predictiveDictLineCount - 1;
- int lo = 0;
- int line = 0;
- while (lo <= hi) {
- line = (lo + hi) / 2;
- int cmpVal = strncmp(_predictiveDictLine[line], code.c_str(), code.size());
- if (cmpVal > 0)
- hi = line - 1;
- else if (cmpVal < 0)
- lo = line + 1;
- else {
- 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], _currentCode.c_str(), _currentCode.size())) {
- char tmp[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 {
- return false;
- }
-}
-
-} // End of namespace Agi