diff options
Diffstat (limited to 'engines/sherlock/user_interface.cpp')
-rw-r--r-- | engines/sherlock/user_interface.cpp | 2330 |
1 files changed, 2 insertions, 2328 deletions
diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 5858daffc5..9fff7cc999 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -22,64 +22,11 @@ #include "sherlock/user_interface.h" #include "sherlock/sherlock.h" -#include "sherlock/settings.h" +#include "sherlock/scalpel/scalpel_user_interface.h" +#include "sherlock/tattoo/tattoo_user_interface.h" namespace Sherlock { -// Main user interface menu control locations -const int MENU_POINTS[12][4] = { - { 13, 153, 72, 165 }, - { 13, 169, 72, 181 }, - { 13, 185, 72, 197 }, - { 88, 153, 152, 165 }, - { 88, 169, 152, 181 }, - { 88, 185, 152, 197 }, - { 165, 153, 232, 165 }, - { 165, 169, 232, 181 }, - { 165, 185, 233, 197 }, - { 249, 153, 305, 165 }, - { 249, 169, 305, 181 }, - { 249, 185, 305, 197 } -}; - -// Inventory control locations */ -const int INVENTORY_POINTS[8][3] = { - { 4, 50, 29 }, - { 52, 99, 77 }, - { 101, 140, 123 }, - { 142, 187, 166 }, - { 189, 219, 198 }, - { 221, 251, 234 }, - { 253, 283, 266 }, - { 285, 315, 294 } -}; - -const char COMMANDS[13] = "LMTPOCIUGJFS"; -const char INVENTORY_COMMANDS[9] = { "ELUG-+,." }; -const char *const PRESS_KEY_FOR_MORE = "Press any Key for More."; -const char *const PRESS_KEY_TO_CONTINUE = "Press any Key to Continue."; - -const char *const MOPEN[] = { - "This cannot be opened", "It is already open", "It is locked", "Wait for Watson", " ", "." -}; -const char *const MCLOSE[] = { - "This cannot be closed", "It is already closed", "The safe door is in the way" -}; -const char *const MMOVE[] = { - "This cannot be moved", "It is bolted to the floor", "It is too heavy", "The other crate is in the way" -}; -const char *const MPICK[] = { - "Nothing of interest here", "It is bolted down", "It is too big to carry", "It is too heavy", - "I think a girl would be more your type", "Those flowers belong to Penny", "She's far too young for you!", - "I think a girl would be more your type!", "Government property for official use only" -}; -const char *const MUSE[] = { - "You can't do that", "It had no effect", "You can't reach it", "OK, the door looks bigger! Happy?", - "Doors don't smoke" -}; - - - UserInterface *UserInterface::init(SherlockEngine *vm) { if (vm->getGameID() == GType_SerratedScalpel) return new Scalpel::ScalpelUserInterface(vm); @@ -106,2277 +53,4 @@ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { _lookHelp = 0; } -/*----------------------------------------------------------------*/ - -namespace Scalpel { - -ScalpelUserInterface::ScalpelUserInterface(SherlockEngine *vm): UserInterface(vm) { - _controls = new ImageFile("menu.all"); - _controlPanel = new ImageFile("controls.vgs"); - _keyPress = '\0'; - _lookHelp = 0; - _bgFound = 0; - _oldBgFound = -1; - _help = _oldHelp = 0; - _key = _oldKey = '\0'; - _temp = _oldTemp = 0; - _oldLook = 0; - _keyboardInput = false; - _pause = false; - _cNum = 0; - _find = 0; - _oldUse = 0; -} - -ScalpelUserInterface::~ScalpelUserInterface() { - delete _controls; - delete _controlPanel; -} - -void ScalpelUserInterface::reset() { - _oldKey = -1; - _help = _oldHelp = -1; - _oldTemp = _temp = -1; -} - -void ScalpelUserInterface::drawInterface(int bufferNum) { - Screen &screen = *_vm->_screen; - - if (bufferNum & 1) - screen._backBuffer1.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y)); - if (bufferNum & 2) - screen._backBuffer2.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y)); - if (bufferNum == 3) - screen._backBuffer2.fillRect(0, INFO_LINE, SHERLOCK_SCREEN_WIDTH, INFO_LINE + 10, INFO_BLACK); -} - -void ScalpelUserInterface::handleInput() { - Events &events = *_vm->_events; - Inventory &inv = *_vm->_inventory; - People &people = *_vm->_people; - Scene &scene = *_vm->_scene; - Screen &screen = *_vm->_screen; - Talk &talk = *_vm->_talk; - - if (_menuCounter) - whileMenuCounter(); - - Common::Point pt = events.mousePos(); - _bgFound = scene.findBgShape(Common::Rect(pt.x, pt.y, pt.x + 1, pt.y + 1)); - _keyPress = '\0'; - - // Check kbd and set the mouse released flag if Enter or space is pressed. - // Otherwise, the pressed _key is stored for later use - if (events.kbHit()) { - Common::KeyState keyState = events.getKey(); - _keyPress = keyState.ascii; - - if (keyState.keycode == Common::KEYCODE_x && keyState.flags & Common::KBD_ALT) { - _vm->quitGame(); - events.pollEvents(); - return; - } - } - - // Do button highlighting check - if (!talk._scriptMoreFlag) { // Don't if scripts are running - if (((events._rightPressed || events._rightReleased) && _helpStyle) || - (!_helpStyle && !_menuCounter)) { - // Handle any default commands if we're in STD_MODE - if (_menuMode == STD_MODE) { - if (pt.y < CONTROLS_Y && - (events._rightPressed || (!_helpStyle && !events._released)) && - (_bgFound != -1) && (_bgFound < 1000) && - (scene._bgShapes[_bgFound]._defaultCommand || - !scene._bgShapes[_bgFound]._description.empty())) { - // If there is no default command, so set it to Look - if (scene._bgShapes[_bgFound]._defaultCommand) - _help = scene._bgShapes[_bgFound]._defaultCommand - 1; - else - _help = 0; - - // Reset 'help' if it is an invalid command - if (_help > 5) - _help = -1; - } else if (pt.y < CONTROLS_Y && - ((events._rightReleased && _helpStyle) || (events._released && !_helpStyle)) && - (_bgFound != -1 && _bgFound < 1000) && - (scene._bgShapes[_bgFound]._defaultCommand || - !scene._bgShapes[_bgFound]._description.empty())) { - // If there is no default command, set it to Look - if (scene._bgShapes[_bgFound]._defaultCommand) - _menuMode = (MenuMode)scene._bgShapes[_bgFound]._defaultCommand; - else - _menuMode = LOOK_MODE; - events._released = true; - events._pressed = events._oldButtons = false; - _help = _oldHelp = -1; - - if (_menuMode == LOOK_MODE) { - // Set the flag to tell the game that this was a right-click - // call to look and should exit without the look button being pressed - _lookHelp = true; - } - } else { - _help = -1; - } - - // Check if highlighting a different button than last time - if (_help != _oldHelp) { - // If another button was highlighted previously, restore it - if (_oldHelp != -1) - restoreButton(_oldHelp); - - // If we're highlighting a new button, then draw it pressed - if (_help != -1) - depressButton(_help); - - _oldHelp = _help; - } - - if (_bgFound != _oldBgFound || _oldBgFound == -1) { - _infoFlag = true; - clearInfo(); - - if (_help != -1 && !scene._bgShapes[_bgFound]._description.empty() - && scene._bgShapes[_bgFound]._description[0] != ' ') - screen.print(Common::Point(0, INFO_LINE + 1), - INFO_FOREGROUND, "%s", scene._bgShapes[_bgFound]._description.c_str()); - - _oldBgFound = _bgFound; - } - } else { - // We're not in STD_MODE - // If there isn't a window open, then revert back to STD_MODE - if (!_windowOpen && events._rightReleased) { - // Restore all buttons - for (int idx = 0; idx < 12; ++idx) - restoreButton(idx); - - _menuMode = STD_MODE; - _key = _oldKey = -1; - _temp = _oldTemp = _lookHelp = _invLookFlag = 0; - events.clearEvents(); - } - } - } - } - - // Reset the old bgshape number if the mouse button is released, so that - // it can e re-highlighted when we come back here - if ((events._rightReleased && _helpStyle) || (events._released && !_helpStyle)) - _oldBgFound = -1; - - // Do routines that should be done before input processing - switch (_menuMode) { - case LOOK_MODE: - if (!_windowOpen) { - if (events._released && _bgFound >= 0 && _bgFound < 1000) { - if (!scene._bgShapes[_bgFound]._examine.empty()) - examine(); - } else { - lookScreen(pt); - } - } - break; - - case MOVE_MODE: - case OPEN_MODE: - case CLOSE_MODE: - case PICKUP_MODE: - lookScreen(pt); - break; - - case TALK_MODE: - if (!_windowOpen) { - bool personFound; - - if (_bgFound >= 1000) { - personFound = false; - if (!events._released) - lookScreen(pt); - } else { - personFound = _bgFound != -1 && scene._bgShapes[_bgFound]._aType == PERSON; - } - - if (events._released && personFound) - talk.talk(_bgFound); - else if (personFound) - lookScreen(pt); - else if (_bgFound < 1000) - clearInfo(); - } - break; - - case USE_MODE: - case GIVE_MODE: - case INV_MODE: - if (inv._invMode == INVMODE_LOOK || inv._invMode == INVMODE_USE || inv._invMode == INVMODE_GIVE) { - if (pt.y > CONTROLS_Y) - lookInv(); - else - lookScreen(pt); - } - break; - - default: - break; - } - - // - // Do input processing - // - if (events._pressed || events._released || events._rightPressed || _keyPress || _pause) { - if (((events._released && (_helpStyle || _help == -1)) || (events._rightReleased && !_helpStyle)) && - (pt.y <= CONTROLS_Y) && (_menuMode == STD_MODE)) { - // The mouse was clicked in the playing area with no action buttons down. - // Check if the mouse was clicked in a script zone. If it was, - // then execute the script. Otherwise, walk to the given position - if (scene.checkForZones(pt, SCRIPT_ZONE) != 0 || - scene.checkForZones(pt, NOWALK_ZONE) != 0) { - // Mouse clicked in script zone - events._pressed = events._released = false; - } else { - people._walkDest = pt; - people._allowWalkAbort = false; - people.goAllTheWay(); - } - - if (_oldKey != -1) { - restoreButton(_oldTemp); - _oldKey = -1; - } - } - - // Handle action depending on selected mode - switch (_menuMode) { - case LOOK_MODE: - if (_windowOpen) - doLookControl(); - break; - - case MOVE_MODE: - doMiscControl(ALLOW_MOVE); - break; - - case TALK_MODE: - if (_windowOpen) - doTalkControl(); - break; - - case OPEN_MODE: - doMiscControl(ALLOW_OPEN); - break; - - case CLOSE_MODE: - doMiscControl(ALLOW_CLOSE); - break; - - case PICKUP_MODE: - doPickControl(); - break; - - case USE_MODE: - case GIVE_MODE: - case INV_MODE: - doInvControl(); - break; - - case FILES_MODE: - doEnvControl(); - break; - - default: - break; - } - - // As long as there isn't an open window, do main input processing. - // Windows are opened when in TALK, USE, INV, and GIVE modes - if ((!_windowOpen && !_menuCounter && pt.y > CONTROLS_Y) || - _keyPress) { - if (events._pressed || events._released || _pause || _keyPress) - doMainControl(); - } - - if (pt.y < CONTROLS_Y && events._pressed && _oldTemp != (int)(_menuMode - 1) && _oldKey != -1) - restoreButton(_oldTemp); - } -} - -void ScalpelUserInterface::depressButton(int num) { - Screen &screen = *_vm->_screen; - Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]); - - ImageFrame &frame = (*_controls)[num]; - screen._backBuffer1.transBlitFrom(frame, pt); - screen.slamArea(pt.x, pt.y, pt.x + frame._width, pt.y + frame._height); -} - -void ScalpelUserInterface::restoreButton(int num) { - Screen &screen = *_vm->_screen; - Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]); - Graphics::Surface &frame = (*_controls)[num]._frame; - - screen._backBuffer1.blitFrom(screen._backBuffer2, pt, - Common::Rect(pt.x, pt.y, pt.x + 90, pt.y + 19)); - screen.slamArea(pt.x, pt.y, pt.x + frame.w, pt.y + frame.h); - - if (!_menuCounter) { - _infoFlag = true; - clearInfo(); - } -} - -void ScalpelUserInterface::pushButton(int num) { - Events &events = *_vm->_events; - _oldKey = -1; - - if (!events._released) { - if (_oldHelp != -1) - restoreButton(_oldHelp); - if (_help != -1) - restoreButton(_help); - - depressButton(num); - events.wait(6); - } - - restoreButton(num); -} - -void ScalpelUserInterface::toggleButton(int num) { - Screen &screen = *_vm->_screen; - - if (_menuMode != (MenuMode)(num + 1)) { - _menuMode = (MenuMode)(num + 1); - _oldKey = COMMANDS[num]; - _oldTemp = num; - - if (_keyboardInput) { - if (_oldHelp != -1 && _oldHelp != num) - restoreButton(_oldHelp); - if (_help != -1 && _help != num) - restoreButton(_help); - - _keyboardInput = false; - - ImageFrame &frame = (*_controls)[num]; - Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]); - screen._backBuffer1.transBlitFrom(frame, pt); - screen.slamArea(pt.x, pt.y, pt.x + frame._width, pt.y + frame._height); - } - } else { - _menuMode = STD_MODE; - _oldKey = -1; - restoreButton(num); - } -} - -void ScalpelUserInterface::clearInfo() { - if (_infoFlag) { - _vm->_screen->vgaBar(Common::Rect(16, INFO_LINE, SHERLOCK_SCREEN_WIDTH - 19, - INFO_LINE + 10), INFO_BLACK); - _infoFlag = false; - _oldLook = -1; - } -} - -void ScalpelUserInterface::clearWindow() { - if (_windowOpen) { - _vm->_screen->vgaBar(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, - SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND); - } -} - -void ScalpelUserInterface::whileMenuCounter() { - if (!(--_menuCounter) || _vm->_events->checkInput()) { - _menuCounter = 0; - _infoFlag = true; - clearInfo(); - } -} - -void ScalpelUserInterface::examine() { - Events &events = *_vm->_events; - Inventory &inv = *_vm->_inventory; - People &people = *_vm->_people; - Scene &scene = *_vm->_scene; - Talk &talk = *_vm->_talk; - Common::Point pt = events.mousePos(); - - if (pt.y < (CONTROLS_Y + 9)) { - Object &obj = scene._bgShapes[_bgFound]; - - if (obj._lookcAnim != 0) { - int canimSpeed = ((obj._lookcAnim & 0xe0) >> 5) + 1; - scene._cAnimFramePause = obj._lookFrames; - _cAnimStr = obj._examine; - _cNum = (obj._lookcAnim & 0x1f) - 1; - - scene.startCAnim(_cNum, canimSpeed); - } else if (obj._lookPosition.y != 0) { - // Need to walk to the object to be examined - people.walkToCoords(Common::Point(obj._lookPosition.x, obj._lookPosition.y * 100), obj._lookFacing); - } - - if (!talk._talkToAbort) { - _cAnimStr = obj._examine; - if (obj._lookFlag) - _vm->setFlags(obj._lookFlag); - } - } else { - // Looking at an inventory item - _cAnimStr = inv[_selector]._examine; - if (inv[_selector]._lookFlag) - _vm->setFlags(inv[_selector]._lookFlag); - } - - if (_invLookFlag) { - // Don't close the inventory window when starting an examine display, since its - // window will slide up to replace the inventory display - _windowOpen = false; - _menuMode = LOOK_MODE; - } - - if (!talk._talkToAbort) { - if (!scene._cAnimFramePause) - printObjectDesc(_cAnimStr, true); - else - // description was already printed in startCAnimation - scene._cAnimFramePause = 0; - } -} - -void ScalpelUserInterface::lookScreen(const Common::Point &pt) { - Events &events = *_vm->_events; - Inventory &inv = *_vm->_inventory; - Scene &scene = *_vm->_scene; - Screen &screen = *_vm->_screen; - Common::Point mousePos = events.mousePos(); - int temp; - Common::String tempStr; - - // Don't display anything for right button command - if ((events._rightPressed || events._rightPressed) && !events._pressed) - return; - - if (mousePos.y < CONTROLS_Y && (temp = _bgFound) != -1) { - if (temp != _oldLook) { - _infoFlag = true; - clearInfo(); - - if (temp < 1000) - tempStr = scene._bgShapes[temp]._description; - else - tempStr = scene._bgShapes[temp - 1000]._description; - - _infoFlag = true; - clearInfo(); - - // Only print description if there is one - if (!tempStr.empty() && tempStr[0] != ' ') { - // If inventory is active and an item is selected for a Use or Give action - if ((_menuMode == INV_MODE || _menuMode == USE_MODE || _menuMode == GIVE_MODE) && - (inv._invMode == INVMODE_USE || inv._invMode == INVMODE_GIVE)) { - int width1 = 0, width2 = 0; - int x, width; - if (inv._invMode == INVMODE_USE) { - // Using an object - x = width = screen.stringWidth("Use "); - - if (temp < 1000 && scene._bgShapes[temp]._aType != PERSON) - // It's not a person, so make it lowercase - tempStr.setChar(tolower(tempStr[0]), 0); - - x += screen.stringWidth(tempStr); - - // If we're using an inventory object, add in the width - // of the object name and the " on " - if (_selector != -1) { - width1 = screen.stringWidth(inv[_selector]._name); - x += width1; - width2 = screen.stringWidth(" on "); - x += width2; - } - - // If the line will be too long, keep cutting off characters - // until the string will fit - while (x > 280) { - x -= screen.charWidth(tempStr.lastChar()); - tempStr.deleteLastChar(); - } - - int xStart = (SHERLOCK_SCREEN_WIDTH - x) / 2; - screen.print(Common::Point(xStart, INFO_LINE + 1), - INFO_FOREGROUND, "Use "); - - if (_selector != -1) { - screen.print(Common::Point(xStart + width, INFO_LINE + 1), - TALK_FOREGROUND, "%s", inv[_selector]._name.c_str()); - screen.print(Common::Point(xStart + width + width1, INFO_LINE + 1), - INFO_FOREGROUND, " on "); - screen.print(Common::Point(xStart + width + width1 + width2, INFO_LINE + 1), - INFO_FOREGROUND, "%s", tempStr.c_str()); - } else { - screen.print(Common::Point(xStart + width, INFO_LINE + 1), - INFO_FOREGROUND, "%s", tempStr.c_str()); - } - } else if (temp >= 0 && temp < 1000 && _selector != -1 && - scene._bgShapes[temp]._aType == PERSON) { - // Giving an object to a person - width1 = screen.stringWidth(inv[_selector]._name); - x = width = screen.stringWidth("Give "); - x += width1; - width2 = screen.stringWidth(" to "); - x += width2; - x += screen.stringWidth(tempStr); - - // Ensure string will fit on-screen - while (x > 280) { - x -= screen.charWidth(tempStr.lastChar()); - tempStr.deleteLastChar(); - } - - int xStart = (SHERLOCK_SCREEN_WIDTH - x) / 2; - screen.print(Common::Point(xStart, INFO_LINE + 1), - INFO_FOREGROUND, "Give "); - screen.print(Common::Point(xStart + width, INFO_LINE + 1), - TALK_FOREGROUND, "%s", inv[_selector]._name.c_str()); - screen.print(Common::Point(xStart + width + width1, INFO_LINE + 1), - INFO_FOREGROUND, " to "); - screen.print(Common::Point(xStart + width + width1 + width2, INFO_LINE + 1), - INFO_FOREGROUND, "%s", tempStr.c_str()); - } - } else { - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", tempStr.c_str()); - } - - _infoFlag = true; - _oldLook = temp; - } - } - } else { - clearInfo(); - } -} - -void ScalpelUserInterface::lookInv() { - Events &events = *_vm->_events; - Inventory &inv = *_vm->_inventory; - Screen &screen = *_vm->_screen; - Common::Point mousePos = events.mousePos(); - - if (mousePos.x > 15 && mousePos.x < 314 && mousePos.y > (CONTROLS_Y1 + 11) - && mousePos.y < (SHERLOCK_SCREEN_HEIGHT - 2)) { - int temp = (mousePos.x - 6) / 52 + inv._invIndex; - if (temp < inv._holdings) { - if (temp < inv._holdings) { - clearInfo(); - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, - "%s", inv[temp]._description.c_str()); - _infoFlag = true; - _oldLook = temp; - } - } else { - clearInfo(); - } - } else { - clearInfo(); - } -} - -void ScalpelUserInterface::doEnvControl() { - Events &events = *_vm->_events; - SaveManager &saves = *_vm->_saves; - Scene &scene = *_vm->_scene; - Screen &screen = *_vm->_screen; - Talk &talk = *_vm->_talk; - Common::Point mousePos = events.mousePos(); - static const char ENV_COMMANDS[7] = "ELSUDQ"; - - byte color; - - _key = _oldKey = -1; - _keyboardInput = false; - int found = saves.getHighlightedButton(); - - if (events._pressed || events._released) { - events.clearKeyboard(); - - // Check for a filename entry being highlighted - if ((events._pressed || events._released) && mousePos.y > (CONTROLS_Y + 10)) { - int found1 = 0; - for (_selector = 0; (_selector < ONSCREEN_FILES_COUNT) && !found1; ++_selector) - if (mousePos.y > (CONTROLS_Y + 11 + _selector * 10) && mousePos.y < (CONTROLS_Y + 21 + _selector * 10)) - found1 = 1; - - if (_selector + saves._savegameIndex - 1 < MAX_SAVEGAME_SLOTS + (saves._envMode != SAVEMODE_LOAD)) - _selector = _selector + saves._savegameIndex - 1; - else - _selector = -1; - - if (!found1) - _selector = -1; - } - - // Handle selecting buttons, if any - saves.highlightButtons(found); - - if (found == 0 || found == 5) - saves._envMode = SAVEMODE_NONE; - } - - if (_keyPress) { - _key = toupper(_keyPress); - - // Escape _key will close the dialog - if (_key == Common::KEYCODE_ESCAPE) - _key = 'E'; - - if (_key == 'E' || _key == 'L' || _key == 'S' || _key == 'U' || _key == 'D' || _key == 'Q') { - const char *chP = strchr(ENV_COMMANDS, _key); - int btnIndex = !chP ? -1 : chP - ENV_COMMANDS; - saves.highlightButtons(btnIndex); - _keyboardInput = true; - - if (_key == 'E' || _key == 'Q') { - saves._envMode = SAVEMODE_NONE; - } else if (_key >= '1' && _key <= '9') { - _keyboardInput = true; - _selector = _key - '1'; - if (_selector >= MAX_SAVEGAME_SLOTS + (saves._envMode == SAVEMODE_LOAD ? 0 : 1)) - _selector = -1; - - if (saves.checkGameOnScreen(_selector)) - _oldSelector = _selector; - } else { - _selector = -1; - } - } - } - - if (_selector != _oldSelector) { - if (_oldSelector != -1 && _oldSelector >= saves._savegameIndex && _oldSelector < (saves._savegameIndex + ONSCREEN_FILES_COUNT)) { - screen.print(Common::Point(6, CONTROLS_Y + 12 + (_oldSelector - saves._savegameIndex) * 10), - INV_FOREGROUND, "%d.", _oldSelector + 1); - screen.print(Common::Point(24, CONTROLS_Y + 12 + (_oldSelector - saves._savegameIndex) * 10), - INV_FOREGROUND, "%s", saves._savegames[_oldSelector].c_str()); - } - - if (_selector != -1) { - screen.print(Common::Point(6, CONTROLS_Y + 12 + (_selector - saves._savegameIndex) * 10), - TALK_FOREGROUND, "%d.", _selector + 1); - screen.print(Common::Point(24, CONTROLS_Y + 12 + (_selector - saves._savegameIndex) * 10), - TALK_FOREGROUND, "%s", saves._savegames[_selector].c_str()); - } - - _oldSelector = _selector; - } - - if (events._released || _keyboardInput) { - if ((found == 0 && events._released) || _key == 'E') { - banishWindow(); - _windowBounds.top = CONTROLS_Y1; - - events._pressed = events._released = _keyboardInput = false; - _keyPress = '\0'; - } else if ((found == 1 && events._released) || _key == 'L') { - saves._envMode = SAVEMODE_LOAD; - if (_selector != -1) { - saves.loadGame(_selector + 1); - } - } else if ((found == 2 && events._released) || _key == 'S') { - saves._envMode = SAVEMODE_SAVE; - if (_selector != -1) { - if (saves.checkGameOnScreen(_selector)) - _oldSelector = _selector; - - if (saves.promptForDescription(_selector)) { - saves.saveGame(_selector + 1, saves._savegames[_selector]); - - banishWindow(1); - _windowBounds.top = CONTROLS_Y1; - _key = _oldKey = -1; - _keyPress = '\0'; - _keyboardInput = false; - } else { - if (!talk._talkToAbort) { - screen._backBuffer1.fillRect(Common::Rect(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, - SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y + 20 + (_selector - saves._savegameIndex) * 10), INV_BACKGROUND); - screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), INV_FOREGROUND, - "%d.", _selector + 1); - screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), INV_FOREGROUND, - "%s", saves._savegames[_selector].c_str()); - - screen.slamArea(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, 311, 10); - _selector = _oldSelector = -1; - } - } - } - } else if (((found == 3 && events._released) || _key == 'U') && saves._savegameIndex) { - bool moreKeys; - do { - saves._savegameIndex--; - screen._backBuffer1.fillRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, - SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND); - - for (int idx = saves._savegameIndex; idx < (saves._savegameIndex + ONSCREEN_FILES_COUNT); ++idx) { - color = INV_FOREGROUND; - if (idx == _selector && idx >= saves._savegameIndex && idx < (saves._savegameIndex + ONSCREEN_FILES_COUNT)) - color = TALK_FOREGROUND; - - screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, "%d.", idx + 1); - screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, "%s", saves._savegames[idx].c_str()); - } - - screen.slamRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT)); - - color = !saves._savegameIndex ? COMMAND_NULL : COMMAND_FOREGROUND; - screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), color, true, "Up"); - color = (saves._savegameIndex == MAX_SAVEGAME_SLOTS - ONSCREEN_FILES_COUNT) ? COMMAND_NULL : COMMAND_FOREGROUND; - screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), color, true, "Down"); - - // Check whether there are more pending U keys pressed - moreKeys = false; - if (events.kbHit()) { - Common::KeyState keyState = events.getKey(); - - _key = toupper(keyState.keycode); - moreKeys = _key == 'U'; - } - } while ((saves._savegameIndex) && moreKeys); - } else if (((found == 4 && events._released) || _key == 'D') && saves._savegameIndex < (MAX_SAVEGAME_SLOTS - ONSCREEN_FILES_COUNT)) { - bool moreKeys; - do { - saves._savegameIndex++; - screen._backBuffer1.fillRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, - SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND); - - for (int idx = saves._savegameIndex; idx < (saves._savegameIndex + ONSCREEN_FILES_COUNT); ++idx) { - if (idx == _selector && idx >= saves._savegameIndex && idx < (saves._savegameIndex + ONSCREEN_FILES_COUNT)) - color = TALK_FOREGROUND; - else - color = INV_FOREGROUND; - - screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, - "%d.", idx + 1); - screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, - "%s", saves._savegames[idx].c_str()); - } - - screen.slamRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT)); - - color = (!saves._savegameIndex) ? COMMAND_NULL : COMMAND_FOREGROUND; - screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), color, true, "Up"); - - color = (saves._savegameIndex == MAX_SAVEGAME_SLOTS - ONSCREEN_FILES_COUNT) ? COMMAND_NULL : COMMAND_FOREGROUND; - screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), color, true, "Down"); - - // Check whether there are more pending D keys pressed - moreKeys = false; - if (events.kbHit()) { - Common::KeyState keyState; - _key = toupper(keyState.keycode); - - moreKeys = _key == 'D'; - } - } while (saves._savegameIndex < (MAX_SAVEGAME_SLOTS - ONSCREEN_FILES_COUNT) && moreKeys); - } else if ((found == 5 && events._released) || _key == 'Q') { - clearWindow(); - screen.print(Common::Point(0, CONTROLS_Y + 20), INV_FOREGROUND, "Are you sure you wish to Quit ?"); - screen.vgaBar(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y + 10), BORDER_COLOR); - - screen.makeButton(Common::Rect(112, CONTROLS_Y, 160, CONTROLS_Y + 10), 136 - screen.stringWidth("Yes") / 2, "Yes"); - screen.makeButton(Common::Rect(161, CONTROLS_Y, 209, CONTROLS_Y + 10), 184 - screen.stringWidth("No") / 2, "No"); - screen.slamArea(112, CONTROLS_Y, 97, 10); - - do { - scene.doBgAnim(); - - if (talk._talkToAbort) - return; - - events.pollEventsAndWait(); - events.setButtonState(); - mousePos = events.mousePos(); - - if (events.kbHit()) { - Common::KeyState keyState = events.getKey(); - _key = toupper(keyState.keycode); - - if (_key == 'X' && (keyState.flags & Common::KBD_ALT) != 0) { - _vm->quitGame(); - events.pollEvents(); - return; - } - - if (_key == Common::KEYCODE_ESCAPE) - _key = 'N'; - - if (_key == Common::KEYCODE_RETURN || _key == ' ') { - events._pressed = false; - events._released = true; - events._oldButtons = 0; - _keyPress = '\0'; - } - } - - if (events._pressed || events._released) { - if (mousePos.x > 112 && mousePos.x < 159 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 9)) - color = COMMAND_HIGHLIGHTED; - else - color = COMMAND_FOREGROUND; - screen.buttonPrint(Common::Point(136, CONTROLS_Y), color, true, "Yes"); - - if (mousePos.x > 161 && mousePos.x < 208 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 9)) - color = COMMAND_HIGHLIGHTED; - else - color = COMMAND_FOREGROUND; - screen.buttonPrint(Common::Point(184, CONTROLS_Y), color, true, "No"); - } - - if (mousePos.x > 112 && mousePos.x < 159 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 9) && events._released) - _key = 'Y'; - - if (mousePos.x > 161 && mousePos.x < 208 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 9) && events._released) - _key = 'N'; - } while (!_vm->shouldQuit() && _key != 'Y' && _key != 'N'); - - if (_key == 'Y') { - _vm->quitGame(); - events.pollEvents(); - return; - } else { - screen.buttonPrint(Common::Point(184, CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "No"); - banishWindow(1); - _windowBounds.top = CONTROLS_Y1; - _key = -1; - } - } else { - if (_selector != -1) { - // Are we already in Load mode? - if (saves._envMode == SAVEMODE_LOAD) { - saves.loadGame(_selector + 1); - } else if (saves._envMode == SAVEMODE_SAVE || saves.isSlotEmpty(_selector)) { - // We're already in save mode, or pointing to an empty save slot - if (saves.checkGameOnScreen(_selector)) - _oldSelector = _selector; - - if (saves.promptForDescription(_selector)) { - saves.saveGame(_selector + 1, saves._savegames[_selector]); - banishWindow(); - _windowBounds.top = CONTROLS_Y1; - _key = _oldKey = -1; - _keyPress = '\0'; - _keyboardInput = false; - } else { - if (!talk._talkToAbort) { - screen._backBuffer1.fillRect(Common::Rect(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, - 317, CONTROLS_Y + 20 + (_selector - saves._savegameIndex) * 10), INV_BACKGROUND); - screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), - INV_FOREGROUND, "%d.", _selector + 1); - screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), - INV_FOREGROUND, "%s", saves._savegames[_selector].c_str()); - screen.slamArea(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, 311, 10); - _selector = _oldSelector = -1; - } - } - } - } - } - } -} - -void ScalpelUserInterface::doInvControl() { - Events &events = *_vm->_events; - Inventory &inv = *_vm->_inventory; - Scene &scene = *_vm->_scene; - Screen &screen = *_vm->_screen; - Talk &talk = *_vm->_talk; - int colors[8]; - Common::Point mousePos = events.mousePos(); - - _key = _oldKey = -1; - _keyboardInput = false; - - // Check whether any inventory slot is highlighted - int found = -1; - Common::fill(&colors[0], &colors[8], (int)COMMAND_FOREGROUND); - for (int idx = 0; idx < 8; ++idx) { - Common::Rect r(INVENTORY_POINTS[idx][0], CONTROLS_Y1, - INVENTORY_POINTS[idx][1], CONTROLS_Y1 + 10); - if (r.contains(mousePos)) { - found = idx; - break; - } - } - - if (events._pressed || events._released) { - events.clearKeyboard(); - - if (found != -1) - // If a slot highlighted, set its color - colors[found] = COMMAND_HIGHLIGHTED; - screen.buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1), colors[0], true, "Exit"); - - if (found >= 0 && found <= 3) { - screen.buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1), colors[1], true, "Look"); - screen.buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1), colors[2], true, "Use"); - screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1), colors[3], true, "Give"); - inv._invMode = (InvMode)found; - _selector = -1; - } - - if (inv._invIndex) { - screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), colors[4], "^^"); - screen.print(Common::Point(INVENTORY_POINTS[5][2], CONTROLS_Y1 + 1), colors[5], "^"); - } - - if ((inv._holdings - inv._invIndex) > 6) { - screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1), colors[6], "_"); - screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1), colors[7], "__"); - } - - bool flag = false; - if (inv._invMode == INVMODE_LOOK || inv._invMode == INVMODE_USE || inv._invMode == INVMODE_GIVE) { - Common::Rect r(15, CONTROLS_Y1 + 11, 314, SHERLOCK_SCREEN_HEIGHT - 2); - if (r.contains(mousePos)) { - _selector = (mousePos.x - 6) / 52 + inv._invIndex; - if (_selector < inv._holdings) - flag = true; - } - } - - if (!flag && mousePos.y >(CONTROLS_Y1 + 11)) - _selector = -1; - } - - if (_keyPress) { - _key = toupper(_keyPress); - - if (_key == Common::KEYCODE_ESCAPE) - // Escape will also 'E'xit out of inventory display - _key = 'E'; - - if (_key == 'E' || _key == 'L' || _key == 'U' || _key == 'G' - || _key == '-' || _key == '+') { - InvMode temp = inv._invMode; - - const char *chP = strchr(INVENTORY_COMMANDS, _key); - inv._invMode = !chP ? INVMODE_INVALID : (InvMode)(chP - INVENTORY_COMMANDS); - inv.invCommands(true); - - inv._invMode = temp; - _keyboardInput = true; - if (_key == 'E') - inv._invMode = INVMODE_EXIT; - _selector = -1; - } else { - _selector = -1; - } - } - - if (_selector != _oldSelector) { - if (_oldSelector != -1) { - // Un-highlight - if (_oldSelector >= inv._invIndex && _oldSelector < (inv._invIndex + 6)) - inv.highlight(_oldSelector, BUTTON_MIDDLE); - } - - if (_selector != -1) - inv.highlight(_selector, 235); - - _oldSelector = _selector; - } - - if (events._released || _keyboardInput) { - if ((found == 0 && events._released) || _key == 'E') { - inv.freeInv(); - _infoFlag = true; - clearInfo(); - banishWindow(false); - _key = -1; - events.clearEvents(); - events.setCursor(ARROW); - } else if ((found == 1 && events._released) || (_key == 'L')) { - inv._invMode = INVMODE_LOOK; - } else if ((found == 2 && events._released) || (_key == 'U')) { - inv._invMode = INVMODE_USE; - } else if ((found == 3 && events._released) || (_key == 'G')) { - inv._invMode = INVMODE_GIVE; - } else if (((found == 4 && events._released) || _key == ',') && inv._invIndex) { - if (inv._invIndex >= 6) - inv._invIndex -= 6; - else - inv._invIndex = 0; - - screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), - COMMAND_HIGHLIGHTED, "^^"); - inv.freeGraphics(); - inv.loadGraphics(); - inv.putInv(SLAM_DISPLAY); - inv.invCommands(true); - } else if (((found == 5 && events._released) || _key == '-') && inv._invIndex > 0) { - --inv._invIndex; - screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1), COMMAND_HIGHLIGHTED, "^"); - inv.freeGraphics(); - inv.loadGraphics(); - inv.putInv(SLAM_DISPLAY); - inv.invCommands(true); - } else if (((found == 6 && events._released) || _key == '+') && (inv._holdings - inv._invIndex) > 6) { - ++inv._invIndex; - screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1), COMMAND_HIGHLIGHTED, "_"); - inv.freeGraphics(); - inv.loadGraphics(); - inv.putInv(SLAM_DISPLAY); - inv.invCommands(true); - } else if (((found == 7 && events._released) || _key == '.') && (inv._holdings - inv._invIndex) > 6) { - inv._invIndex += 6; - if ((inv._holdings - 6) < inv._invIndex) - inv._invIndex = inv._holdings - 6; - - screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1), COMMAND_HIGHLIGHTED, "_"); - inv.freeGraphics(); - inv.loadGraphics(); - inv.putInv(SLAM_DISPLAY); - inv.invCommands(true); - } else { - // If something is being given, make sure it's being given to a person - if (inv._invMode == INVMODE_GIVE) { - if (_bgFound != -1 && scene._bgShapes[_bgFound]._aType == PERSON) - _find = _bgFound; - else - _find = -1; - } else { - _find = _bgFound; - } - - if ((mousePos.y < CONTROLS_Y1) && (inv._invMode == INVMODE_LOOK) && (_find >= 0) && (_find < 1000)) { - if (!scene._bgShapes[_find]._examine.empty() && - scene._bgShapes[_find]._examine[0] >= ' ') - inv.refreshInv(); - } else if (_selector != -1 || _find >= 0) { - // Selector is the inventory object that was clicked on, or selected. - // If it's -1, then no inventory item is highlighted yet. Otherwise, - // an object in the scene has been clicked. - - if (_selector != -1 && inv._invMode == INVMODE_LOOK - && mousePos.y >(CONTROLS_Y1 + 11)) - inv.refreshInv(); - - if (talk._talkToAbort) - return; - - // Now check for the Use and Give actions. If inv_mode is INVMODE_GIVE, - // that means GIVE is in effect, _selector is the object being - // given, and _find is the target. - // The same applies to USE, except if _selector is -1, then USE - // is being tried on an object in the scene without an inventory - // object being highlighted first. - - if ((inv._invMode == INVMODE_USE || (_selector != -1 && inv._invMode == INVMODE_GIVE)) && _find >= 0) { - events._pressed = events._released = false; - _infoFlag = true; - clearInfo(); - - int tempSel = _selector; // Save the selector - _selector = -1; - - inv.putInv(SLAM_DISPLAY); - _selector = tempSel; // Restore it - InvMode tempMode = inv._invMode; - inv._invMode = INVMODE_USE55; - inv.invCommands(true); - - _infoFlag = true; - clearInfo(); - banishWindow(false); - _key = -1; - - inv.freeInv(); - - bool giveFl = (tempMode >= INVMODE_GIVE); - if (_selector >= 0) - // Use/Give inv object with scene object - checkUseAction(&scene._bgShapes[_find]._use[0], inv[_selector]._name, MUSE, _find, giveFl); - else - // Now inv object has been highlighted - checkUseAction(&scene._bgShapes[_find]._use[0], "*SELF*", MUSE, _find, giveFl); - - _selector = _oldSelector = -1; - } - } - } - } -} - -void ScalpelUserInterface::doLookControl() { - Events &events = *_vm->_events; - Inventory &inv = *_vm->_inventory; - Screen &screen = *_vm->_screen; - - _key = _oldKey = -1; - _keyboardInput = (_keyPress != '\0'); - - if (events._released || events._rightReleased || _keyboardInput) { - // Is an inventory object being looked at? - if (!_invLookFlag) { - // Is there any remaining text to display? - if (!_descStr.empty()) { - printObjectDesc(_descStr, false); - } else if (!_lookHelp) { - // Need to close the window and depress the Look button - Common::Point pt(MENU_POINTS[0][0], MENU_POINTS[0][1]); - screen._backBuffer2.blitFrom((*_controls)[0], pt); - banishWindow(true); - - _windowBounds.top = CONTROLS_Y1; - _key = _oldKey = COMMANDS[LOOK_MODE - 1]; - _temp = _oldTemp = 0; - _menuMode = LOOK_MODE; - events.clearEvents(); - - // Restore UI - drawInterface(); - } else { - events.setCursor(ARROW); - banishWindow(true); - _windowBounds.top = CONTROLS_Y1; - _key = _oldKey = -1; - _temp = _oldTemp = 0; - _menuMode = STD_MODE; - events.clearEvents(); - } - } else { - // Looking at an inventory object - // Backup the user interface - Surface tempSurface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y1); - tempSurface.blitFrom(screen._backBuffer2, Common::Point(0, 0), - Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); - - inv.drawInventory(INVENTORY_DONT_DISPLAY); - banishWindow(true); - - // Restore the ui - screen._backBuffer2.blitFrom(tempSurface, Common::Point(0, CONTROLS_Y1)); - - _windowBounds.top = CONTROLS_Y1; - _key = _oldKey = COMMANDS[LOOK_MODE - 1]; - _temp = _oldTemp = 0; - events.clearEvents(); - _invLookFlag = false; - _menuMode = INV_MODE; - _windowOpen = true; - } - } -} - -void ScalpelUserInterface::doMainControl() { - Events &events = *_vm->_events; - Inventory &inv = *_vm->_inventory; - SaveManager &saves = *_vm->_saves; - Common::Point pt = events.mousePos(); - - if ((events._pressed || events._released) && pt.y > CONTROLS_Y) { - events.clearKeyboard(); - _key = -1; - - // Check whether the mouse is in any of the command areas - for (_temp = 0; (_temp < 12) && (_key == -1); ++_temp) { - Common::Rect r(MENU_POINTS[_temp][0], MENU_POINTS[_temp][1], - MENU_POINTS[_temp][2], MENU_POINTS[_temp][3]); - if (r.contains(pt)) - _key = COMMANDS[_temp]; - } - --_temp; - } else if (_keyPress) { - // Keyboard control - _keyboardInput = true; - - if (_keyPress >= 'A' && _keyPress <= 'Z') { - const char *c = strchr(COMMANDS, _keyPress); - _temp = !c ? 12 : c - COMMANDS; - } else { - _temp = 12; - } - - if (_temp == 12) - _key = -1; - - if (events._rightPressed) { - _temp = 12; - _key = -1; - } - } else if (!events._released) { - _key = -1; - } - - // Check if the button being pointed to has changed - if (_oldKey != _key && !_windowOpen) { - // Clear the info line - _infoFlag = true; - clearInfo(); - - // If there was an old button selected, restore it - if (_oldKey != -1) { - _menuMode = STD_MODE; - restoreButton(_oldTemp); - } - - // If a new button is being pointed to, highlight it - if (_key != -1 && _temp < 12 && !_keyboardInput) - depressButton(_temp); - - // Save the new button selection - _oldKey = _key; - _oldTemp = _temp; - } - - if (!events._pressed && !_windowOpen) { - switch (_key) { - case 'L': - toggleButton(0); - break; - case 'M': - toggleButton(1); - break; - case 'T': - toggleButton(2); - break; - case 'P': - toggleButton(3); - break; - case 'O': - toggleButton(4); - break; - case 'C': - toggleButton(5); - break; - case 'I': - pushButton(6); - _selector = _oldSelector = -1; - _menuMode = INV_MODE; - inv.drawInventory(PLAIN_INVENTORY); - break; - case 'U': - pushButton(7); - _selector = _oldSelector = -1; - _menuMode = USE_MODE; - inv.drawInventory(USE_INVENTORY_MODE); - break; - case 'G': - pushButton(8); - _selector = _oldSelector = -1; - _menuMode = GIVE_MODE; - inv.drawInventory(GIVE_INVENTORY_MODE); - break; - case 'J': - pushButton(9); - _menuMode = JOURNAL_MODE; - journalControl(); - break; - case 'F': - pushButton(10); - - // Create a thumbnail of the current screen before the files dialog is shown, in case - // the user saves the game - saves.createThumbnail(); - - _selector = _oldSelector = -1; - - if (_vm->_showOriginalSavesDialog) { - // Show the original dialog - _menuMode = FILES_MODE; - saves.drawInterface(); - _windowOpen = true; - } else { - // Show the ScummVM GMM instead - _vm->_canLoadSave = true; - _vm->openMainMenuDialog(); - _vm->_canLoadSave = false; - } - break; - case 'S': - pushButton(11); - _menuMode = SETUP_MODE; - Settings::show(_vm); - break; - default: - break; - } - - _help = _oldHelp = _oldBgFound = -1; - } -} - -void ScalpelUserInterface::doMiscControl(int allowed) { - Events &events = *_vm->_events; - Scene &scene = *_vm->_scene; - Talk &talk = *_vm->_talk; - - if (events._released) { - _temp = _bgFound; - if (_bgFound != -1) { - // Only allow pointing to objects, not people - if (_bgFound < 1000) { - events.clearEvents(); - Object &obj = scene._bgShapes[_bgFound]; - - switch (allowed) { - case ALLOW_OPEN: - checkAction(obj._aOpen, MOPEN, _temp); - if (_menuMode != TALK_MODE && !talk._talkToAbort) { - _menuMode = STD_MODE; - restoreButton(OPEN_MODE - 1); - _key = _oldKey = -1; - } - break; - - case ALLOW_CLOSE: - checkAction(obj._aClose, MCLOSE, _temp); - if (_menuMode != TALK_MODE && !talk._talkToAbort) { - _menuMode = STD_MODE; - restoreButton(CLOSE_MODE - 1); - _key = _oldKey = -1; - } - break; - - case ALLOW_MOVE: - checkAction(obj._aMove, MMOVE, _temp); - if (_menuMode != TALK_MODE && !talk._talkToAbort) { - _menuMode = STD_MODE; - restoreButton(MOVE_MODE - 1); - _key = _oldKey = -1; - } - break; - - default: - break; - } - } - } - } -} - -void ScalpelUserInterface::doPickControl() { - Events &events = *_vm->_events; - Scene &scene = *_vm->_scene; - Talk &talk = *_vm->_talk; - - if (events._released) { - if ((_temp = _bgFound) != -1) { - events.clearEvents(); - - // Don't allow characters to be picked up - if (_bgFound < 1000) { - scene._bgShapes[_bgFound].pickUpObject(MPICK); - - if (!talk._talkToAbort && _menuMode != TALK_MODE) { - _key = _oldKey = -1; - _menuMode = STD_MODE; - restoreButton(PICKUP_MODE - 1); - } - } - } - } -} - -void ScalpelUserInterface::doTalkControl() { - Events &events = *_vm->_events; - Journal &journal = *_vm->_journal; - People &people = *_vm->_people; - Screen &screen = *_vm->_screen; - Sound &sound = *_vm->_sound; - Talk &talk = *_vm->_talk; - Common::Point mousePos = events.mousePos(); - - _key = _oldKey = -1; - _keyboardInput = false; - - if (events._pressed || events._released) { - events.clearKeyboard(); - - // Handle button printing - if (mousePos.x > 99 && mousePos.x < 138 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 10) && !_endKeyActive) - screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Exit"); - else if (_endKeyActive) - screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_FOREGROUND, true, "Exit"); - - if (mousePos.x > 140 && mousePos.x < 170 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 10) && talk._moreTalkUp) - screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Up"); - else if (talk._moreTalkUp) - screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_FOREGROUND, true, "Up"); - - if (mousePos.x > 181&& mousePos.x < 220 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 10) && talk._moreTalkDown) - screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Down"); - else if (talk._moreTalkDown) - screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_FOREGROUND, true, "Down"); - - bool found = false; - for (_selector = talk._talkIndex; _selector < (int)talk._statements.size() && !found; ++_selector) { - if (mousePos.y > talk._statements[_selector]._talkPos.top && - mousePos.y < talk._statements[_selector]._talkPos.bottom) - found = true; - } - --_selector; - if (!found) - _selector = -1; - } - - if (_keyPress) { - _key = toupper(_keyPress); - if (_key == Common::KEYCODE_ESCAPE) - _key = 'E'; - - // Check for number press indicating reply line - if (_key >= '1' && _key <= ('1' + (int)talk._statements.size() - 1)) { - for (uint idx = 0; idx < talk._statements.size(); ++idx) { - if (talk._statements[idx]._talkMap == (_key - '1')) { - // Found the given statement - _selector = idx; - _key = -1; - _keyboardInput = true; - break; - } - } - } else if (_key == 'E' || _key == 'U' || _key == 'D') { - _keyboardInput = true; - } else { - _selector = -1; - } - } - - if (_selector != _oldSelector) { - // Remove highlighting from previous line, if any - if (_oldSelector != -1) { - if (!((talk._talkHistory[talk._converseNum][_oldSelector] >> (_oldSelector & 7)) & 1)) - talk.talkLine(_oldSelector, talk._statements[_oldSelector]._talkMap, INV_FOREGROUND, - talk._statements[_oldSelector]._talkPos.top, true); - else - talk.talkLine(_oldSelector, talk._statements[_oldSelector]._talkMap, TALK_NULL, - talk._statements[_oldSelector]._talkPos.top, true); - } - - // Add highlighting to new line, if any - if (_selector != -1) - talk.talkLine(_selector, talk._statements[_selector]._talkMap, TALK_FOREGROUND, - talk._statements[_selector]._talkPos.top, true); - - _oldSelector = _selector; - } - - if (events._released || _keyboardInput) { - if (((Common::Rect(99, CONTROLS_Y, 138, CONTROLS_Y + 10).contains(mousePos) && events._released) - || _key == 'E') && _endKeyActive) { - talk.freeTalkVars(); - talk.pullSequence(); - banishWindow(); - _windowBounds.top = CONTROLS_Y1; - } else if (((Common::Rect(140, CONTROLS_Y, 179, CONTROLS_Y + 10).contains(mousePos) && events._released) - || _key == 'U') && talk._moreTalkUp) { - while (talk._statements[--talk._talkIndex]._talkMap == -1) - ; - screen._backBuffer1.fillRect(Common::Rect(5, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, - SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND); - talk.displayTalk(false); - - screen.slamRect(Common::Rect(5, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH - 5, SHERLOCK_SCREEN_HEIGHT - 2)); - } else if (((Common::Rect(181, CONTROLS_Y, 220, CONTROLS_Y + 10).contains(mousePos) && events._released) - || _key == 'D') && talk._moreTalkDown) { - do { - ++talk._talkIndex; - } while (talk._talkIndex < (int)talk._statements.size() && talk._statements[talk._talkIndex]._talkMap == -1); - - screen._backBuffer1.fillRect(Common::Rect(5, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, - SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND); - talk.displayTalk(false); - - screen.slamRect(Common::Rect(5, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH - 5, SHERLOCK_SCREEN_HEIGHT - 2)); - } else if (_selector != -1) { - screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_NULL, true, "Exit"); - screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, true, "Up"); - screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, true, "Down"); - - // If the reply is new, add it to the journal - if (!talk._talkHistory[talk._converseNum][_selector]) { - journal.record(talk._converseNum, _selector); - - // Add any Holmes point to Holmes' total, if any - if (talk._statements[_selector]._quotient) - people._holmesQuotient += talk._statements[_selector]._quotient; - } - - // Flag the response as having been used - talk._talkHistory[talk._converseNum][_selector] = true; - - clearWindow(); - screen.print(Common::Point(16, CONTROLS_Y + 12), TALK_FOREGROUND, "Sherlock Holmes"); - talk.talkLine(_selector + 128, talk._statements[_selector]._talkMap, COMMAND_FOREGROUND, CONTROLS_Y + 21, true); - - switch (talk._statements[_selector]._portraitSide & 3) { - case 0: - case 1: - people._portraitSide = 20; - break; - case 2: - people._portraitSide = 220; - break; - case 3: - people._portraitSide = 120; - break; - } - - // Check for flipping Holmes - if (talk._statements[_selector]._portraitSide & REVERSE_DIRECTION) - people._holmesFlip = true; - - talk._speaker = 0; - people.setTalking(0); - - if (!talk._statements[_selector]._voiceFile.empty() && sound._voices) { - sound.playSound(talk._statements[_selector]._voiceFile, WAIT_RETURN_IMMEDIATELY); - - // Set voices as an indicator for waiting - sound._voices = 2; - sound._speechOn = *sound._soundIsOn; - } else { - sound._speechOn = false; - } - - talk.waitForMore(talk._statements[_selector]._statement.size()); - if (talk._talkToAbort) - return; - - people.clearTalking(); - if (talk._talkToAbort) - return; - - while (!_vm->shouldQuit()) { - talk._scriptSelect = _selector; - talk._speaker = talk._talkTo; - talk.doScript(talk._statements[_selector]._reply); - - if (!talk._talkToAbort) { - if (!talk._talkStealth) - clearWindow(); - - if (!talk._statements[_selector]._modified.empty()) { - for (uint idx = 0; idx < talk._statements[_selector]._modified.size(); ++idx) { - _vm->setFlags(talk._statements[_selector]._modified[idx]); - } - - talk.setTalkMap(); - } - - // Check for another linked talk file - Common::String linkFilename = talk._statements[_selector]._linkFile; - if (!linkFilename.empty() && !talk._scriptMoreFlag) { - talk.freeTalkVars(); - talk.loadTalkFile(linkFilename); - - // Find the first new statement - int select = _selector = _oldSelector = -1; - for (uint idx = 0; idx < talk._statements.size() && select == -1; ++idx) { - if (!talk._statements[idx]._talkMap) - select = talk._talkIndex = idx; - } - - // See if the new statement is a stealth reply - talk._talkStealth = talk._statements[select]._statement.hasPrefix("^") ? 2 : 0; - - // Is the new talk file a standard file, reply first file, or a stealth file - if (!talk._statements[select]._statement.hasPrefix("*") && - !talk._statements[select]._statement.hasPrefix("^")) { - // Not a reply first file, so display the new selections - if (_endKeyActive) - screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_FOREGROUND, true, "Exit"); - else - screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_NULL, true, "Exit"); - - talk.displayTalk(true); - events.setCursor(ARROW); - break; - } else { - _selector = select; - - if (!talk._talkHistory[talk._converseNum][_selector]) - journal.record(talk._converseNum, _selector); - - talk._talkHistory[talk._converseNum][_selector] = true; - } - } else { - talk.freeTalkVars(); - talk.pullSequence(); - banishWindow(); - _windowBounds.top = CONTROLS_Y1; - break; - } - } else { - break; - } - } - - events._pressed = events._released = false; - events._oldButtons = 0; - talk._talkStealth = 0; - - // If a script was pushed onto the script stack, restore it - if (!talk._scriptStack.empty()) { - ScriptStackEntry stackEntry = talk._scriptStack.pop(); - talk._scriptName = stackEntry._name; - talk._scriptSaveIndex = stackEntry._currentIndex; - talk._scriptSelect = stackEntry._select; - } - } - } -} - -void ScalpelUserInterface::journalControl() { - Events &events = *_vm->_events; - Journal &journal = *_vm->_journal; - Scene &scene = *_vm->_scene; - Screen &screen = *_vm->_screen; - bool doneFlag = false; - - // Draw the journal screen - journal.drawInterface(); - - // Handle journal events - do { - _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; - _keyPress = '\0'; - _windowOpen = false; - _windowBounds.top = CONTROLS_Y1; - _key = -1; - _menuMode = STD_MODE; - - // Reset the palette - screen.setPalette(screen._cMap); - - screen._backBuffer1.blitFrom(screen._backBuffer2); - scene.updateBackground(); - screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); -} - -void ScalpelUserInterface::printObjectDesc(const Common::String &str, bool firstTime) { - Events &events = *_vm->_events; - Inventory &inv = *_vm->_inventory; - Screen &screen = *_vm->_screen; - Talk &talk = *_vm->_talk; - - if (str.hasPrefix("_")) { - _lookScriptFlag = true; - events.setCursor(MAGNIFY); - int savedSelector = _selector; - talk.talkTo(str.c_str() + 1); - _lookScriptFlag = false; - - if (talk._talkToAbort) { - events.setCursor(ARROW); - return; - } - - // Check if looking at an inventory object - if (!_invLookFlag) { - // See if this look was called by a right button click or not - if (!_lookHelp) { - // If it wasn't a right button click, then we need depress - // the look button before we close the window. So save a copy of the - // menu area, and draw the controls onto it - Surface tempSurface((*_controls)[0]._frame.w, (*_controls)[0]._frame.h); - Common::Point pt(MENU_POINTS[0][0], MENU_POINTS[0][1]); - - tempSurface.blitFrom(screen._backBuffer2, Common::Point(0, 0), - Common::Rect(pt.x, pt.y, pt.x + tempSurface.w(), pt.y + tempSurface.h())); - screen._backBuffer2.transBlitFrom((*_controls)[0], pt); - - banishWindow(1); - events.setCursor(MAGNIFY); - _windowBounds.top = CONTROLS_Y1; - _key = _oldKey = COMMANDS[LOOK_MODE - 1]; - _temp = _oldTemp = 0; - _menuMode = LOOK_MODE; - events.clearEvents(); - - screen._backBuffer2.blitFrom(tempSurface, pt); - } else { - events.setCursor(ARROW); - banishWindow(true); - _windowBounds.top = CONTROLS_Y1; - _key = _oldKey = -1; - _temp = _oldTemp = 0; - _menuMode = STD_MODE; - _lookHelp = 0; - events.clearEvents(); - } - } else { - // Looking at an inventory object - _selector = _oldSelector = savedSelector; - - // Reload the inventory graphics and draw the inventory - inv.loadInv(); - inv.putInv(SLAM_SECONDARY_BUFFER); - inv.freeInv(); - banishWindow(1); - - _windowBounds.top = CONTROLS_Y1; - _key = _oldKey = COMMANDS[INV_MODE - 1]; - _temp = _oldTemp = 0; - events.clearEvents(); - - _invLookFlag = 0; - _menuMode = INV_MODE; - _windowOpen = true; - } - - return; - } - - Surface &bb = *screen._backBuffer; - if (firstTime) { - // Only draw the border on the first call - _infoFlag = true; - clearInfo(); - - bb.fillRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, - CONTROLS_Y1 + 10), BORDER_COLOR); - bb.fillRect(Common::Rect(0, CONTROLS_Y + 10, 1, SHERLOCK_SCREEN_HEIGHT - 1), - BORDER_COLOR); - bb.fillRect(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y + 10, - SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); - bb.fillRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 1, SHERLOCK_SCREEN_WIDTH, - SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); - } - - // Clear background - bb.fillRect(Common::Rect(2, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH - 2, - SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND); - - _windowBounds.top = CONTROLS_Y; - events.clearEvents(); - - // Loop through displaying up to five lines - bool endOfStr = false; - const char *msgP = str.c_str(); - for (int lineNum = 0; lineNum < ONSCREEN_FILES_COUNT && !endOfStr; ++lineNum) { - int width = 0; - const char *lineStartP = msgP; - - // Determine how much can be displayed on the line - do { - width += screen.charWidth(*msgP++); - } while (width < 300 && *msgP); - - if (*msgP) - --msgP; - else - endOfStr = true; - - // If the line needs to be wrapped, scan backwards to find - // the end of the previous word as a splitting point - if (width >= 300) { - while (*msgP != ' ') - --msgP; - endOfStr = false; - } - - // Print out the line - Common::String line(lineStartP, msgP); - screen.gPrint(Common::Point(16, CONTROLS_Y + 12 + lineNum * 9), - INV_FOREGROUND, "%s", line.c_str()); - - if (!endOfStr) - // Start next line at start of the nxet word after space - ++msgP; - } - - // Handle display depending on whether all the message was shown - if (!endOfStr) { - screen.makeButton(Common::Rect(46, CONTROLS_Y, 272, CONTROLS_Y + 10), - (SHERLOCK_SCREEN_WIDTH - screen.stringWidth(PRESS_KEY_FOR_MORE)) / 2, - PRESS_KEY_FOR_MORE); - screen.gPrint(Common::Point((SHERLOCK_SCREEN_WIDTH - - screen.stringWidth(PRESS_KEY_FOR_MORE)) / 2, CONTROLS_Y), - COMMAND_FOREGROUND, "P"); - _descStr = msgP; - } else { - screen.makeButton(Common::Rect(46, CONTROLS_Y, 272, CONTROLS_Y + 10), - (SHERLOCK_SCREEN_WIDTH - screen.stringWidth(PRESS_KEY_TO_CONTINUE)) / 2, - PRESS_KEY_TO_CONTINUE); - screen.gPrint(Common::Point((SHERLOCK_SCREEN_WIDTH - - screen.stringWidth(PRESS_KEY_TO_CONTINUE)) / 2, CONTROLS_Y), - COMMAND_FOREGROUND, "P"); - _descStr = ""; - } - - if (firstTime) { - if (!_slideWindows) { - screen.slamRect(Common::Rect(0, CONTROLS_Y, - SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); - } else { - // Display the window - summonWindow(); - } - - _selector = _oldSelector = -1; - _windowOpen = true; - } else { - screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, - SHERLOCK_SCREEN_HEIGHT)); - } -} - -void ScalpelUserInterface::printObjectDesc() { - printObjectDesc(_cAnimStr, true); -} - -void ScalpelUserInterface::summonWindow(const Surface &bgSurface, bool slideUp) { - Events &events = *_vm->_events; - Screen &screen = *_vm->_screen; - - if (_windowOpen) - // A window is already open, so can't open another one - return; - - if (slideUp) { - // Gradually slide up the display of the window - for (int idx = 1; idx <= bgSurface.h(); idx += 2) { - screen._backBuffer->blitFrom(bgSurface, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - idx), - Common::Rect(0, 0, bgSurface.w(), idx)); - screen.slamRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - idx, - SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); - - events.delay(10); - } - } else { - // Gradually slide down the display of the window - for (int idx = 1; idx <= bgSurface.h(); idx += 2) { - screen._backBuffer->blitFrom(bgSurface, - Common::Point(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h()), - Common::Rect(0, bgSurface.h() - idx, bgSurface.w(), bgSurface.h())); - screen.slamRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h(), - SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - bgSurface.h() + idx)); - - events.delay(10); - } - } - - // Final display of the entire window - screen._backBuffer->blitFrom(bgSurface, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h()), - Common::Rect(0, 0, bgSurface.w(), bgSurface.h())); - screen.slamArea(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h(), bgSurface.w(), bgSurface.h()); - - _windowOpen = true; -} - -void ScalpelUserInterface::summonWindow(bool slideUp, int height) { - Screen &screen = *_vm->_screen; - - // Extract the window that's been drawn on the back buffer - Surface tempSurface(SHERLOCK_SCREEN_WIDTH, - (SHERLOCK_SCREEN_HEIGHT - height)); - Common::Rect r(0, height, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); - tempSurface.blitFrom(screen._backBuffer1, Common::Point(0, 0), r); - - // Remove drawn window with original user interface - screen._backBuffer1.blitFrom(screen._backBuffer2, - Common::Point(0, height), r); - - // Display the window gradually on-screen - summonWindow(tempSurface, slideUp); -} - -void ScalpelUserInterface::banishWindow(bool slideUp) { - Events &events = *_vm->_events; - Screen &screen = *_vm->_screen; - - if (_windowOpen) { - if (slideUp || !_slideWindows) { - // Slide window down - // Only slide the window if the window style allows it - if (_slideWindows) { - for (int idx = 2; idx < (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y); idx += 2) { - // Shift the window down by 2 lines - byte *pSrc = (byte *)screen._backBuffer1.getBasePtr(0, CONTROLS_Y + idx - 2); - byte *pSrcEnd = (byte *)screen._backBuffer1.getBasePtr(0, SHERLOCK_SCREEN_HEIGHT - 2); - byte *pDest = (byte *)screen._backBuffer1.getBasePtr(0, SHERLOCK_SCREEN_HEIGHT); - Common::copy_backward(pSrc, pSrcEnd, pDest); - - // Restore lines from the ui in the secondary back buffer - screen._backBuffer1.blitFrom(screen._backBuffer2, - Common::Point(0, CONTROLS_Y), - Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y + idx)); - - screen.slamArea(0, CONTROLS_Y + idx - 2, SHERLOCK_SCREEN_WIDTH, - SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y - idx + 2); - events.delay(10); - } - - // Restore final two old lines - screen._backBuffer1.blitFrom(screen._backBuffer2, - Common::Point(0, SHERLOCK_SCREEN_HEIGHT - 2), - Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 2, - SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); - screen.slamArea(0, SHERLOCK_SCREEN_HEIGHT - 2, SHERLOCK_SCREEN_WIDTH, 2); - } else { - // Restore old area to completely erase window - screen._backBuffer1.blitFrom(screen._backBuffer2, - Common::Point(0, CONTROLS_Y), - Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); - screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, - SHERLOCK_SCREEN_HEIGHT)); - } - } else { - // Slide the original user interface up to cover the dialog - for (int idx = 1; idx < (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y1); idx += 2) { - byte *pSrc = (byte *)screen._backBuffer2.getBasePtr(0, CONTROLS_Y1); - byte *pSrcEnd = (byte *)screen._backBuffer2.getBasePtr(0, CONTROLS_Y1 + idx); - byte *pDest = (byte *)screen._backBuffer1.getBasePtr(0, SHERLOCK_SCREEN_HEIGHT - idx); - Common::copy(pSrc, pSrcEnd, pDest); - - screen.slamArea(0, SHERLOCK_SCREEN_HEIGHT - idx, SHERLOCK_SCREEN_WIDTH, - SHERLOCK_SCREEN_HEIGHT); - events.delay(10); - } - - // Show entire final area - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(0, CONTROLS_Y1), - Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); - screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); - } - - _infoFlag = false; - _windowOpen = false; - } - - _menuMode = STD_MODE; -} - -void ScalpelUserInterface::checkUseAction(const UseType *use, const Common::String &invName, - const char *const messages[], int objNum, bool giveMode) { - Events &events = *_vm->_events; - Inventory &inv = *_vm->_inventory; - Scene &scene = *_vm->_scene; - Screen &screen = *_vm->_screen; - Talk &talk = *_vm->_talk; - bool printed = messages == nullptr; - - if (objNum >= 1000) { - // Holmes was specified, so do nothing - _infoFlag = true; - clearInfo(); - _infoFlag = true; - - // Display error message - _menuCounter = 30; - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "You can't do that to yourself."); - return; - } - - // Scan for target item - int targetNum = -1; - if (giveMode) { - for (int idx = 0; idx < USE_COUNT && targetNum == -1; ++idx) { - if ((use[idx]._target.equalsIgnoreCase("*GIVE*") || use[idx]._target.equalsIgnoreCase("*GIVEP*")) - && use[idx]._names[0].equalsIgnoreCase(invName)) { - // Found a match - targetNum = idx; - if (use[idx]._target.equalsIgnoreCase("*GIVE*")) - inv.deleteItemFromInventory(invName); - } - } - } else { - for (int idx = 0; idx < USE_COUNT && targetNum == -1; ++idx) { - if (use[idx]._target.equalsIgnoreCase(invName)) - targetNum = idx; - } - } - - if (targetNum != -1) { - // Found a target, so do the action - const UseType &action = use[targetNum]; - - events.setCursor(WAIT); - - if (action._useFlag) - _vm->setFlags(action._useFlag); - - if (action._cAnimNum != 99) { - if (action._cAnimNum == 0) - scene.startCAnim(9, action._cAnimSpeed); - else - scene.startCAnim(action._cAnimNum - 1, action._cAnimSpeed); - } - - if (!talk._talkToAbort) { - Object &obj = scene._bgShapes[objNum]; - for (int idx = 0; idx < NAMES_COUNT && !talk._talkToAbort; ++idx) { - if (obj.checkNameForCodes(action._names[idx], messages)) { - if (!talk._talkToAbort) - printed = true; - } - } - - // Print "Done..." as an ending, unless flagged for leaving scene or otherwise flagged - if (scene._goToScene != 1 && !printed && !talk._talkToAbort) { - _infoFlag = true; - clearInfo(); - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "Done..."); - _menuCounter = 25; - } - } - } else { - // Couldn't find target, so print error - _infoFlag = true; - clearInfo(); - - if (giveMode) { - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "No, thank you."); - } else if (messages == nullptr) { - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "You can't do that."); - } else { - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", messages[0]); - } - - _infoFlag = true; - _menuCounter = 30; - } - - events.setCursor(ARROW); -} - -void ScalpelUserInterface::checkAction(ActionType &action, const char *const messages[], int objNum) { - Events &events = *_vm->_events; - People &people = *_vm->_people; - Scene &scene = *_vm->_scene; - Screen &screen = *_vm->_screen; - Talk &talk = *_vm->_talk; - Common::Point pt(-1, -1); - - if (objNum >= 1000) - // Ignore actions done on characters - return; - - if (!action._cAnimSpeed) { - // Invalid action, to print error message - _infoFlag = true; - clearInfo(); - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", messages[action._cAnimNum]); - _infoFlag = true; - - // Set how long to show the message - _menuCounter = 30; - } else { - Object &obj = scene._bgShapes[objNum]; - - int cAnimNum; - if (action._cAnimNum == 0) - // Really a 10 - cAnimNum = 9; - else - cAnimNum = action._cAnimNum - 1; - - int dir = -1; - if (action._cAnimNum != 99) { - CAnim &anim = scene._cAnim[cAnimNum]; - - if (action._cAnimNum != 99) { - if (action._cAnimSpeed & REVERSE_DIRECTION) { - pt = anim._teleportPos; - dir = anim._teleportDir; - } else { - pt = anim._goto; - dir = anim._gotoDir; - } - } - } else { - pt = Common::Point(-1, -1); - dir = -1; - } - - // Has a value, so do action - // Show wait cursor whilst walking to object and doing action - events.setCursor(WAIT); - bool printed = false; - - for (int nameIdx = 0; nameIdx < NAMES_COUNT; ++nameIdx) { - if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2 - && toupper(action._names[nameIdx][1]) == 'W') { - if (obj.checkNameForCodes(Common::String(action._names[nameIdx].c_str() + 2), messages)) { - if (!talk._talkToAbort) - printed = true; - } - } - } - - bool doCAnim = true; - for (int nameIdx = 0; nameIdx < NAMES_COUNT; ++nameIdx) { - if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2) { - char ch = toupper(action._names[nameIdx][1]); - - if (ch == 'T' || ch == 'B') { - printed = true; - if (pt.x != -1) - // Holmes needs to walk to object before the action is done - people.walkToCoords(pt, dir); - - if (!talk._talkToAbort) { - // Ensure Holmes is on the exact intended location - people[AL]._position = pt; - people[AL]._sequenceNumber = dir; - people.gotoStand(people[AL]); - - talk.talkTo(action._names[nameIdx].c_str() + 2); - if (ch == 'T') - doCAnim = false; - } - } - } - } - - if (doCAnim && !talk._talkToAbort) { - if (pt.x != -1) - // Holmes needs to walk to object before the action is done - people.walkToCoords(pt, dir); - } - - for (int nameIdx = 0; nameIdx < NAMES_COUNT; ++nameIdx) { - if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2 - && toupper(action._names[nameIdx][1]) == 'F') { - if (obj.checkNameForCodes(action._names[nameIdx].c_str() + 2, messages)) { - if (!talk._talkToAbort) - printed = true; - } - } - } - - if (doCAnim && !talk._talkToAbort && action._cAnimNum != 99) - scene.startCAnim(cAnimNum, action._cAnimSpeed); - - if (!talk._talkToAbort) { - for (int nameIdx = 0; nameIdx < NAMES_COUNT && !talk._talkToAbort; ++nameIdx) { - if (obj.checkNameForCodes(action._names[nameIdx], messages)) { - if (!talk._talkToAbort) - printed = true; - } - } - - // Unless we're leaving the scene, print a "Done" message unless the printed flag has been set - if (scene._goToScene != 1 && !printed && !talk._talkToAbort) { - _infoFlag = true; - clearInfo(); - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "Done..."); - - // Set how long to show the message - _menuCounter = 30; - } - } - } - - // Reset cursor back to arrow - events.setCursor(ARROW); -} - -} - -/*----------------------------------------------------------------*/ - -namespace Tattoo { - -TattooUserInterface::TattooUserInterface(SherlockEngine *vm): UserInterface(vm) { - _menuBuffer = nullptr; - _invMenuBuffer = nullptr; -} - -void TattooUserInterface::handleInput() { - // TODO - _vm->_events->pollEventsAndWait(); -} - -void TattooUserInterface::doBgAnimRestoreUI() { - TattooScene &scene = *((TattooScene *)_vm->_scene); - Screen &screen = *_vm->_screen; - - // If _oldMenuBounds was set, then either a new menu has been opened or the current menu has been closed. - // Either way, we need to restore the area where the menu was displayed - if (_oldMenuBounds.width() > 0) - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_oldMenuBounds.left, _oldMenuBounds.top), - _oldMenuBounds); - - if (_oldInvMenuBounds.width() > 0) - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_oldInvMenuBounds.left, _oldInvMenuBounds.top), - _oldInvMenuBounds); - - if (_menuBuffer != nullptr) - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_menuBounds.left, _menuBounds.top), _menuBounds); - if (_invMenuBuffer != nullptr) - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_invMenuBounds.left, _invMenuBounds.top), _invMenuBounds); - - // If there is a Text Tag being display, restore the area underneath it - if (_oldTagBounds.width() > 0) - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_oldTagBounds.left, _oldTagBounds.top), - _oldTagBounds); - - // If there is an Inventory being shown, restore the graphics underneath it - if (_oldInvGraphicBounds.width() > 0) - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_oldInvGraphicBounds.left, _oldInvGraphicBounds.top), - _oldInvGraphicBounds); - - // If a canimation is active, restore the graphics underneath it - if (scene._activeCAnim._images != nullptr) - screen.restoreBackground(scene._activeCAnim._oldBounds); - - // If a canimation just ended, remove it's graphics from the backbuffer - if (scene._activeCAnim._removeBounds.width() > 0) - screen.restoreBackground(scene._activeCAnim._removeBounds); -} - -void TattooUserInterface::doScroll() { - Screen &screen = *_vm->_screen; - int oldScroll = screen._currentScroll; - - // If we're already at the target scroll position, nothing needs to be done - if (screen._targetScroll == screen._currentScroll) - return; - - screen._flushScreen = true; - if (screen._targetScroll > screen._currentScroll) { - screen._currentScroll += screen._scrollSpeed; - if (screen._currentScroll > screen._targetScroll) - screen._currentScroll = screen._targetScroll; - } else if (screen._targetScroll < screen._currentScroll) { - screen._currentScroll -= screen._scrollSpeed; - if (screen._currentScroll < screen._targetScroll) - screen._currentScroll = screen._targetScroll; - } - - if (_menuBuffer != nullptr) - _menuBounds.translate(screen._currentScroll - oldScroll, 0); - if (_invMenuBuffer != nullptr) - _invMenuBounds.translate(screen._currentScroll - oldScroll, 0); -} - -} // End of namespace Tattoo - } // End of namespace Sherlock |