diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sherlock/journal.cpp | 392 | ||||
-rw-r--r-- | engines/sherlock/journal.h | 5 | ||||
-rw-r--r-- | engines/sherlock/scene.h | 4 | ||||
-rw-r--r-- | engines/sherlock/user_interface.cpp | 43 |
4 files changed, 438 insertions, 6 deletions
diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp index 140b766dca..b05cc03372 100644 --- a/engines/sherlock/journal.cpp +++ b/engines/sherlock/journal.cpp @@ -41,6 +41,12 @@ const int JOURNAL_POINTS[9][3] = { { 237, 313, 275 } }; +const int SEARCH_POINTS[3][3] = { + { 51, 123, 86 }, + { 124, 196, 159 }, + { 197, 269, 232 } +}; + /*----------------------------------------------------------------*/ Journal::Journal(SherlockEngine *vm): _vm(vm) { @@ -754,12 +760,12 @@ bool Journal::doJournal(int direction, int howFar) { if (++temp == maxLines) { // Move to next page do { - if (_index < (_journal.size() - 1) && lineNum < (LINES_PER_PAGE - 1)) { + if (_index < ((int)_journal.size() - 1) && lineNum < (LINES_PER_PAGE - 1)) { ++_index; maxLines = loadJournalFile(false); temp = 0; } else { - if (_index == (_journal.size() - 1)) + if (_index == ((int)_journal.size() - 1)) _down = false; endFlag = true; } @@ -787,4 +793,386 @@ void Journal::clearPage() { drawInterface(); } +/** + * Handle events whilst the journal is being displayed + */ +bool Journal::handleEvents(int key) { + Events &events = *_vm->_events; + Screen &screen = *_vm->_screen; + bool doneFlag = false; + Common::Point pt = events.mousePos(); + byte color; + enum Button { + BTN_NONE, BTN_EXIT, BTN_BACK10, BTN_UP, BTN_DOWN, BTN_AHEAD110, BTN_SEARCH, + BTN_FIRST_PAGE, BTN_LAST_PAGE, BTN_PRINT_TEXT + }; + Button found = BTN_NONE; + + if (events._pressed || events._released) { + // Exit button + if (pt.x > JOURNAL_POINTS[0][0] && pt.x < JOURNAL_POINTS[0][1] && pt.y >= JOURNAL_BUTTONS_Y && + pt.y < (JOURNAL_BUTTONS_Y + 10)) { + found = BTN_EXIT; + color = COMMAND_HIGHLIGHTED; + } else { + color = COMMAND_FOREGROUND; + } + screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), color, true, "Exit"); + + // Back 10 button + if (pt.x > JOURNAL_POINTS[1][0] && pt.x < JOURNAL_POINTS[1][1] && pt.y >= JOURNAL_BUTTONS_Y && + pt.y < (JOURNAL_BUTTONS_Y + 10) && _page > 1) { + found = BTN_BACK10; + screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, "Back 10"); + } else if (_page > 1) { + screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, "Back 10"); + } + + // Up button + if (pt.x > JOURNAL_POINTS[2][0] && pt.x < JOURNAL_POINTS[2][1] && pt.y >= JOURNAL_BUTTONS_Y && + pt.y < (JOURNAL_BUTTONS_Y + 10) && _up) { + found = BTN_UP; + screen.buttonPrint(Common::Point(JOURNAL_POINTS[2][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, "Up"); + } else if (_up) { + screen.buttonPrint(Common::Point(JOURNAL_POINTS[2][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, "Up"); + } + + // Down button + if (pt.x > JOURNAL_POINTS[3][0] && pt.x < JOURNAL_POINTS[3][1] && pt.y >= JOURNAL_BUTTONS_Y && + pt.y < (JOURNAL_BUTTONS_Y + 10) && _down) { + found = BTN_DOWN; + screen.buttonPrint(Common::Point(JOURNAL_POINTS[3][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, "Down"); + } else if (_down) { + screen.buttonPrint(Common::Point(JOURNAL_POINTS[3][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, "Down"); + } + + // Ahead 10 button + if (pt.x > JOURNAL_POINTS[4][0] && pt.x < JOURNAL_POINTS[4][1] && pt.y >= JOURNAL_BUTTONS_Y && + pt.y < (JOURNAL_BUTTONS_Y + 10) && _down) { + found = BTN_AHEAD110; + screen.buttonPrint(Common::Point(JOURNAL_POINTS[4][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, "Ahead 10"); + } else if (_down) { + screen.buttonPrint(Common::Point(JOURNAL_POINTS[4][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, "Ahead 10"); + } + + // Search button + if (pt.x > JOURNAL_POINTS[5][0] && pt.x < JOURNAL_POINTS[5][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) && + pt.y < (JOURNAL_BUTTONS_Y + 20) && !_journal.empty()) { + found = BTN_SEARCH; + color = COMMAND_HIGHLIGHTED; + } else if (_journal.empty()) { + color = COMMAND_NULL; + } else { + color = COMMAND_FOREGROUND; + } + screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), color, true, "Search"); + + // First Page button + if (pt.x > JOURNAL_POINTS[6][0] && pt.x < JOURNAL_POINTS[6][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) && + pt.y < (JOURNAL_BUTTONS_Y + 20) && _up) { + found = BTN_FIRST_PAGE; + color = COMMAND_HIGHLIGHTED; + } else if (_up) { + color = COMMAND_FOREGROUND; + } else { + color = COMMAND_NULL; + } + screen.buttonPrint(Common::Point(JOURNAL_POINTS[6][2], JOURNAL_BUTTONS_Y + 11), color, true, "First Page"); + + // Last Page button + if (pt.x > JOURNAL_POINTS[7][0] && pt.x < JOURNAL_POINTS[7][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) && + pt.y < (JOURNAL_BUTTONS_Y + 20) && _down) { + found = BTN_LAST_PAGE; + color = COMMAND_HIGHLIGHTED; + } else if (_down) { + color = COMMAND_FOREGROUND; + } else { + color = COMMAND_NULL; + } + screen.buttonPrint(Common::Point(JOURNAL_POINTS[7][2], JOURNAL_BUTTONS_Y + 11), color, true, "Last Page"); + + + // Print Text button + if (pt.x > JOURNAL_POINTS[8][0] && pt.x < JOURNAL_POINTS[8][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) && + pt.y < (JOURNAL_BUTTONS_Y + 20) && !_journal.empty()) { + found = BTN_PRINT_TEXT; + color = COMMAND_HIGHLIGHTED; + } else if (_journal.empty()) { + color = COMMAND_NULL; + } else { + color = COMMAND_FOREGROUND; + } + screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), color, true, "Print Text"); + } + + if (found == BTN_EXIT && events._released) + // Exit button pressed + doneFlag = true; + + if (((found == BTN_BACK10 && events._released) || key == 'B') && (_page > 1)) { + // Scrolll up 10 pages + if (_page < 11) + doJournal(1, (_page - 1) * LINES_PER_PAGE); + else + doJournal(1, 10 * LINES_PER_PAGE); + + doArrows(); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + } + + if (((found == BTN_UP && events._released) || key =='U') && _up) { + // Scroll up + doJournal(1, LINES_PER_PAGE); + doArrows(); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + } + + if (((found == BTN_DOWN && events._released) || key =='D') && _down) { + // Scroll down + doJournal(2, LINES_PER_PAGE); + doArrows(); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + } + + if (((found == BTN_AHEAD110 && events._released) || key == 'A') && _down) { + // Scroll down 10 pages + if ((_page + 10) > _maxPage) + doJournal(2, (_maxPage - _page) * LINES_PER_PAGE); + else + doJournal(2, 10 * LINES_PER_PAGE); + + doArrows(); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + } + + if (((found == BTN_SEARCH && events._released) || key == 'S') && !_journal.empty()) { + screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), COMMAND_FOREGROUND, true, "Search"); + bool notFound = false; + + int dir; + + do { + if ((dir = getFindName(notFound)) != 0) { + int savedIndex = _index; + int savedSub = _sub; + int savedPage = _page; + + if (doJournal(dir + 2, 1000 * LINES_PER_PAGE) == 0) { + _index = savedIndex; + _sub = savedSub; + _page = savedPage; + + clearPage(); + doJournal(0, 0); + notFound = true; + } else { + doneFlag = true; + } + + doArrows(); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + } else { + doneFlag = true; + } + } while (!doneFlag); + doneFlag = false; + } + + if (((found == BTN_FIRST_PAGE && events._released) || key == 'F') && _up) { + // First page + _index = _sub = 0; + _up = _down = false; + _page = 1; + + clearPage(); + doJournal(0, 0); + doArrows(); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + } + + if (((found == BTN_LAST_PAGE && events._released) || key == 'L') && _down) { + // Last page + if ((_page + 10) > _maxPage) + doJournal(2, (_maxPage - _page) * LINES_PER_PAGE); + else + doJournal(2, 1000 * LINES_PER_PAGE); + + doArrows(); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + } + + events.wait(2); + + return doneFlag; +} + +/** + * Show the search submenu + */ +int Journal::getFindName(bool printError) { + Events &events = *_vm->_events; + Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + int xp; + int yp = 174; + bool flag = false; + Common::String name; + enum Button { BTN_NONE, BTN_EXIT, BTN_BACKWARD, BTN_FORWARD }; + Button found = BTN_NONE; + int done = 0; + byte color; + + // Draw search panel + screen.makePanel(Common::Rect(6, 171, 313, 199)); + screen.makeButton(Common::Rect(SEARCH_POINTS[0][0], yp, SEARCH_POINTS[0][1], yp + 10), + SEARCH_POINTS[0][2] - screen.stringWidth("Exit") / 2, "Exit"); + screen.makeButton(Common::Rect(SEARCH_POINTS[1][0], yp, SEARCH_POINTS[1][1], yp + 10), + SEARCH_POINTS[1][2] - screen.stringWidth("Backward") / 2, "Backward"); + screen.makeButton(Common::Rect(SEARCH_POINTS[2][0], yp, SEARCH_POINTS[2][1], yp + 10), + SEARCH_POINTS[2][2] - screen.stringWidth("Forward") / 2, "Forward"); + + screen.gPrint(Common::Point(SEARCH_POINTS[0][2] - screen.stringWidth("Exit") / 2, yp), COMMAND_FOREGROUND, "E"); + screen.gPrint(Common::Point(SEARCH_POINTS[1][2] - screen.stringWidth("Backward") / 2, yp), COMMAND_FOREGROUND, "B"); + screen.gPrint(Common::Point(SEARCH_POINTS[2][2] - screen.stringWidth("Forward") / 2, yp), COMMAND_FOREGROUND, "F"); + + screen.fillRect(Common::Rect(12, 185, 307, 186), BUTTON_BOTTOM); + screen.vLine(12, 185, 195, BUTTON_BOTTOM); + screen.hLine(13, 195, 306, BUTTON_TOP); + screen.hLine(306, 186, 195, BUTTON_TOP); + + if (printError) { + screen.gPrint(Common::Point((SHERLOCK_SCREEN_WIDTH - screen.stringWidth("Text Not Found !")) / 2, 185), + INV_FOREGROUND, "Text Not Found !"); + } else if (!_find.empty()) { + // There's already a search term, display it already + screen.gPrint(Common::Point(15, 185), TALK_FOREGROUND, _find.c_str()); + name = _find; + } + + screen.slamArea(6, 171, 307, 28); + + if (printError) { + // Give time for user to see the message + for (int idx = 0; idx < 40 && !_vm->shouldQuit() && !events.kbHit() && !events._released; ++idx) { + events.pollEvents(); + events.setButtonState(); + + events.wait(2); + } + + events.clearKeyboard(); + screen.fillRect(Common::Rect(13, 186, 306, 195), BUTTON_MIDDLE); + + if (!_find.empty()) { + screen.gPrint(Common::Point(15, 185), TALK_FOREGROUND, _find.c_str()); + name = _find; + } + + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + } + + xp = 15 + screen.stringWidth(name); + yp = 186; + + do { + events._released = false; + found = BTN_NONE; + + while (!_vm->shouldQuit() && !events.kbHit() && !events._released) { + found = BTN_NONE; + if (talk._talkToAbort) + return 0; + + // Check if key or mouse button press has occurred + events.setButtonState(); + Common::Point pt = events.mousePos(); + + flag = !flag; + screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), flag ? INV_FOREGROUND : BUTTON_MIDDLE); + + if (events._pressed || events._released) { + if (pt.x > SEARCH_POINTS[0][0] && pt.x < SEARCH_POINTS[0][1] && pt.y > 174 && pt.y < 183) { + found = BTN_EXIT; + color = COMMAND_HIGHLIGHTED; + } else { + color = COMMAND_FOREGROUND; + } + screen.print(Common::Point(SEARCH_POINTS[0][2] - screen.stringWidth("Exit") / 2, 175), color, "Exit"); + + if (pt.x > SEARCH_POINTS[1][0] && pt.x < SEARCH_POINTS[1][1] && pt.y > 174 && pt.y < 183) { + found = BTN_BACKWARD; + color = COMMAND_HIGHLIGHTED; + } else { + color = COMMAND_FOREGROUND; + } + screen.print(Common::Point(SEARCH_POINTS[1][2] - screen.stringWidth("Backward") / 2, 175), color, "Backward"); + + if (pt.x > SEARCH_POINTS[2][0] && pt.x < SEARCH_POINTS[2][1] && pt.y > 174 && pt.y < 183) { + found = BTN_FORWARD; + color = COMMAND_HIGHLIGHTED; + } else { + color = COMMAND_FOREGROUND; + } + screen.print(Common::Point(SEARCH_POINTS[1][2] - screen.stringWidth("Forward") / 2, 175), color, "Forward"); + } + + events.wait(2); + } + + if (events.kbHit()) { + Common::KeyState keyState = events.getKey(); + + if (keyState.keycode == Common::KEYCODE_BACKSPACE && name.c_str() > 0) { + screen.vgaBar(Common::Rect(xp - screen.charWidth(name.lastChar()), yp, xp + 8, yp + 9), BUTTON_MIDDLE); + xp -= screen.charWidth(name.lastChar()); + screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), INV_FOREGROUND); + name.deleteLastChar(); + } + + if (keyState.keycode == Common::KEYCODE_RETURN) + done = 1; + + if (keyState.keycode == Common::KEYCODE_ESCAPE) { + screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), BUTTON_MIDDLE); + done = -1; + } + + if (keyState.keycode >= Common::KEYCODE_SPACE && keyState.keycode <= Common::KEYCODE_z + && keyState.keycode != Common::KEYCODE_AT && name.size() < 50 + && (xp + screen.charWidth(keyState.keycode)) < 296) { + screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), BUTTON_MIDDLE); + screen.print(Common::Point(xp, yp), TALK_FOREGROUND, "%c", (char)keyState.keycode); + xp += screen.charWidth((char)keyState.keycode); + name += (char)keyState.keycode; + } + } + + if (events._released) { + switch (found) { + case BTN_EXIT: + done = -1; break; + case BTN_BACKWARD: + done = 2; break; + case BTN_FORWARD: + done = 1; break; + default: + break; + } + } + } while (!done); + + if (done != -1) { + _find = name; + } else { + done = 0; + } + + // Redisplay the journal screen + clearPage(); + doJournal(0, 0); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + + return done; +} + } // End of namespace Sherlock diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h index 25f70b0e29..a5fe1e8d94 100644 --- a/engines/sherlock/journal.h +++ b/engines/sherlock/journal.h @@ -67,13 +67,16 @@ private: bool doJournal(int direction, int howFar); void clearPage(); -public: + + int getFindName(bool printError); public: Journal(SherlockEngine *vm); void record(int converseNum, int statementNum); void drawInterface(); + + bool handleEvents(int key); }; } // End of namespace Sherlock diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index cd64073621..3549325e8e 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -97,8 +97,6 @@ private: void transitionToScene(); - void updateBackground(); - void checkBgShapes(ImageFrame *frame, const Common::Point &pt); void saveSceneStatus(); @@ -167,6 +165,8 @@ public: int whichZone(const Common::Point &pt); int closestZone(const Common::Point &pt); + + void updateBackground(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 01b08ffd71..289bff814f 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -1127,10 +1127,51 @@ void UserInterface::doTalkControl() { } void UserInterface::journalControl() { + Events &events = *_vm->_events; Journal &journal = *_vm->_journal; - + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + int found; + bool doneFlag = false; + + // Draw the journal screen journal.drawInterface(); + // Handle journal events + do { + found = _key = -1; + events.setButtonState(); + + // Handle keypresses + if (events.kbHit()) { + Common::KeyState keyState = events.getKey(); + if (keyState.keycode == Common::KEYCODE_x && (keyState.flags & Common::KBD_ALT)) { + _vm->quitGame(); + return; + } else if (keyState.keycode == Common::KEYCODE_e || keyState.keycode == Common::KEYCODE_ESCAPE) { + doneFlag = true; + } else { + _key = toupper(keyState.keycode); + } + } + + if (!doneFlag) + doneFlag = journal.handleEvents(_key); + } while (!_vm->shouldQuit() && !doneFlag); + + // Finish up + _infoFlag = _keyboardInput = false; + _keycode = Common::KEYCODE_INVALID; + _windowOpen = false; + _windowBounds.top = CONTROLS_Y1; + _key = -1; + + // Reset the palette + screen.setPalette(screen._cMap); + + screen._backBuffer1.blitFrom(screen._backBuffer2); + scene.updateBackground(); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); // TODO } |