From 7d2f15d8212f088950385cfc4ec91059b728c95c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 13 Jun 2015 14:53:50 -0400 Subject: SHERLOCK: RT: Implemented doStandardControl --- .../sherlock/scalpel/scalpel_user_interface.cpp | 132 ---------------- engines/sherlock/scalpel/scalpel_user_interface.h | 5 - engines/sherlock/tattoo/tattoo_scene.h | 2 +- engines/sherlock/tattoo/tattoo_user_interface.cpp | 168 ++++++++++++++++++++- engines/sherlock/tattoo/tattoo_user_interface.h | 58 +++++++ engines/sherlock/user_interface.cpp | 134 ++++++++++++++++ engines/sherlock/user_interface.h | 5 + 7 files changed, 365 insertions(+), 139 deletions(-) diff --git a/engines/sherlock/scalpel/scalpel_user_interface.cpp b/engines/sherlock/scalpel/scalpel_user_interface.cpp index 843a109cf0..5dcaf3121d 100644 --- a/engines/sherlock/scalpel/scalpel_user_interface.cpp +++ b/engines/sherlock/scalpel/scalpel_user_interface.cpp @@ -2167,138 +2167,6 @@ void ScalpelUserInterface::checkUseAction(const UseType *use, const Common::Stri 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; - Point32 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._teleport[0]; - dir = anim._teleport[0]._facing; - } else { - pt = anim._goto[0]; - dir = anim._goto[0]._facing; - } - } - } else { - pt = Point32(-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[HOLMES].walkToCoords(pt, dir); - - if (!talk._talkToAbort) { - // Ensure Holmes is on the exact intended location - people[HOLMES]._position = pt; - people[HOLMES]._sequenceNumber = dir; - people[HOLMES].gotoStand(); - - 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[HOLMES].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); -} - } // End of namespace Scalpel } // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/scalpel_user_interface.h b/engines/sherlock/scalpel/scalpel_user_interface.h index 67ba42b5a2..2c93279415 100644 --- a/engines/sherlock/scalpel/scalpel_user_interface.h +++ b/engines/sherlock/scalpel/scalpel_user_interface.h @@ -139,11 +139,6 @@ private: void checkUseAction(const UseType *use, const Common::String &invName, const char *const messages[], int objNum, bool giveMode); - /** - * Called for OPEN, CLOSE, and MOVE actions are being done - */ - void checkAction(ActionType &action, const char *const messages[], int objNum); - /** * Print the previously selected object's decription */ diff --git a/engines/sherlock/tattoo/tattoo_scene.h b/engines/sherlock/tattoo/tattoo_scene.h index 8dab675cdb..427396d48b 100644 --- a/engines/sherlock/tattoo/tattoo_scene.h +++ b/engines/sherlock/tattoo/tattoo_scene.h @@ -49,7 +49,6 @@ private: int _arrowZone; int _maskCounter; Common::Point _maskOffset; - bool _labTableScene; byte _lookupTable[PALETTE_COUNT]; byte _lookupTable1[PALETTE_COUNT]; private: @@ -118,6 +117,7 @@ public: ImageFile *_mask, *_mask1; CAnimStream _activeCAnim; Common::Array _sceneTripCounters; + bool _labTableScene; public: TattooScene(SherlockEngine *vm); diff --git a/engines/sherlock/tattoo/tattoo_user_interface.cpp b/engines/sherlock/tattoo/tattoo_user_interface.cpp index dff759be3d..4fb4adb19a 100644 --- a/engines/sherlock/tattoo/tattoo_user_interface.cpp +++ b/engines/sherlock/tattoo/tattoo_user_interface.cpp @@ -39,6 +39,11 @@ TattooUserInterface::TattooUserInterface(SherlockEngine *vm): UserInterface(vm) _bgShape = nullptr; _personFound = false; _lockoutTimer = 0; + _fileMode = SAVEMODE_NONE; + _exitZone = -1; + _scriptZone = -1; + _arrowZone = _oldArrowZone = -1; + _activeObj = -1; } void TattooUserInterface::initScrollVars() { @@ -272,7 +277,132 @@ void TattooUserInterface::drawGrayAreas() { } void TattooUserInterface::doStandardControl() { - warning("TODO: ui control"); + TattooEngine &vm = *(TattooEngine *)_vm; + Events &events = *_vm->_events; + People &people = *_vm->_people; + TattooScene &scene = *(TattooScene *)_vm->_scene; + Talk &talk = *_vm->_talk; + Common::Point mousePos = events.mousePos(); + bool noDesc = false; + + // Don't do any input processing whilst the prolog is running + if (vm._runningProlog) + return; + + // Display the names of any Objects the cursor is pointing at + displayObjectNames(); + + switch (_keyState.keycode) { + case Common::KEYCODE_F5: + // Save game + turnTextOff(); + _fileMode = SAVEMODE_SAVE; + _menuBounds = Common::Rect(0, 0, 0, 0); + initFileMenu(); + return; + + case Common::KEYCODE_F7: + // Load game + turnTextOff(); + _fileMode = SAVEMODE_LOAD; + _menuBounds = Common::Rect(0, 0, 0, 0); + initFileMenu(); + return; + + case Common::KEYCODE_F1: + // Display journal + if (vm.readFlags(76)) { + turnTextOff(); + doJournal(); + + // See if we're in a Lab Table Room + _menuMode = (scene._labTableScene) ? LAB_MODE : STD_MODE; + return; + } + break; + + case Common::KEYCODE_TAB: + case Common::KEYCODE_F3: + // Display inventory + turnTextOff(); + doInventory(2); + return; + + case Common::KEYCODE_F4: + // Display options + turnTextOff(); + doControls(); + return; + + case Common::KEYCODE_F10: + // Quit menu + turnTextOff(); + _menuBounds = Common::Rect(-1, -1, -1, -1); + doQuitMenu(); + return; + + default: + break; + } + + // See if a mouse button was released + if (events._released || events._rightReleased) { + // See if the mouse was released in an exit (Arrow) zone. Unless it's also pointing at an object + // within the zone, in which case the object gets precedence + _exitZone = -1; + if (_arrowZone != -1 && events._released) + _exitZone = _arrowZone; + + // Turn any Text display off + if (_arrowZone == -1 || events._rightReleased) + turnTextOff(); + + if (_personFound) { + if (people[_bgFound - 1000]._description.empty() || people[_bgFound - 1000]._description.hasPrefix(" ")) + noDesc = true; + } else if (_bgFound != -1) { + if (people[_bgFound - 1000]._description.empty() || people[_bgFound - 1000]._description.hasPrefix(" ")) + noDesc = true; + } else { + noDesc = true; + } + + if (events._rightReleased) { + // Show the verbs menu for the highlighted object + activateVerbMenu(!noDesc); + } else if (_personFound || (_bgFound < 1000 && _bgShape->_aType == PERSON)) { + // The object found is a person (the default for people is TALK) + talk.talk(_bgFound); + _activeObj = -1; + } else if (!noDesc) { + // Either call the code to Look at it's Examine Field or call the Exit animation + // if the object is an exit, specified by the first four characters of the name being "EXIT" + Common::String name = _personFound ? people[_bgFound - 1000]._name : _bgShape->_name; + if (name.hasPrefix("EXIT")) { + lookAtObject(); + } else { + // Run the Exit animation and set which scene to go to next + for (int idx = 0; idx < 6; ++idx) { + if (!_bgShape->_use[idx]._verb.compareToIgnoreCase("Open")) { + checkAction(_bgShape->_use[idx], _bgFound); + _activeObj = -1; + } + } + } + } else { + // See if there are any Script Zones where they clicked + if (scene.checkForZones(mousePos, _scriptZone) != 0) { + // Mouse click in a script zone + events._pressed = events._released = false; + } else if (scene.checkForZones(mousePos, NOWALK_ZONE) != 0) { + events._pressed = events._released = false; + } else { + // Walk to where the mouse was clicked + people._walkDest = Common::Point(mousePos.x + _currentScroll.x, mousePos.y); + people[HOLMES].goAllTheWay(); + } + } + } } void TattooUserInterface::doLookControl() { @@ -303,6 +433,42 @@ void TattooUserInterface::doLabControl() { warning("TODO: ui control"); } +void TattooUserInterface::displayObjectNames() { + // TODO +} + +void TattooUserInterface::initFileMenu() { + // TODO +} + +void TattooUserInterface::turnTextOff() { + // TODO +} + +void TattooUserInterface::doJournal() { + // TODO +} + +void TattooUserInterface::doInventory(int mode) { + // TODO +} + +void TattooUserInterface::doControls() { + // TODO +} + +void TattooUserInterface::doQuitMenu() { + // TODO +} + +void TattooUserInterface::activateVerbMenu(bool objectsOn) { + // TODO +} + +void TattooUserInterface::lookAtObject() { + // TODO +} + } // End of namespace Tattoo } // End of namespace Sherlock diff --git a/engines/sherlock/tattoo/tattoo_user_interface.h b/engines/sherlock/tattoo/tattoo_user_interface.h index c827b9ad75..ef56e5903a 100644 --- a/engines/sherlock/tattoo/tattoo_user_interface.h +++ b/engines/sherlock/tattoo/tattoo_user_interface.h @@ -24,6 +24,7 @@ #define SHERLOCK_TATTOO_UI_H #include "common/scummsys.h" +#include "sherlock/saveload.h" #include "sherlock/user_interface.h" namespace Sherlock { @@ -50,6 +51,11 @@ private: bool _personFound; int _lockoutTimer; Common::KeyState _keyState; + SaveMode _fileMode; + int _exitZone; + int _scriptZone; + int _arrowZone, _oldArrowZone; + int _activeObj; private: /** * Draws designated areas of the screen that are meant to be grayed out using grayscale colors @@ -96,6 +102,53 @@ private: * Handles input when the player is in the Lab Table scene */ void doLabControl(); + + /** + * If the mouse cursor is point at the cursor, then display the name of the object on the screen. + * If there is no object being pointed it, clear any previously displayed name + */ + void displayObjectNames(); + + /** + * Set up to display the Files menu + */ + void initFileMenu(); + + /** + * Turn off any active object description text + */ + void turnTextOff(); + + /** + * Handles displaying the journal + */ + void doJournal(); + + /** + * Put the game in inventory mode by opening the inventory dialog + */ + void doInventory(int mode); + + /** + * Handle the display of the options/setup menu + */ + void doControls(); + + /** + * Handle displaying the quit menu + */ + void doQuitMenu(); + + /** + * Turn on the command menu showing available actions that can be done on a given item + */ + void activateVerbMenu(bool objectsOn); + + /** + * Display the long description for an object stored in it's _examine field, in a window that + * will be shown at the bottom of the screen + */ + void lookAtObject(); public: Common::Point _currentScroll, _targetScroll; int _scrollSize, _scrollSpeed; @@ -129,6 +182,11 @@ public: * Draw the user interface onto the screen's back buffers */ virtual void drawInterface(int bufferNum = 3); + + + void checkAction(UseType &use, int objNum) { + // TODO: Get rid of this stub, and properly use the UserInterface method + } }; } // End of namespace Tattoo diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 9fff7cc999..8ab26aca62 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -53,4 +53,138 @@ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { _lookHelp = 0; } + +void UserInterface::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; + Point32 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._teleport[0]; + dir = anim._teleport[0]._facing; + } else { + pt = anim._goto[0]; + dir = anim._goto[0]._facing; + } + } + } else { + pt = Point32(-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[HOLMES].walkToCoords(pt, dir); + + if (!talk._talkToAbort) { + // Ensure Holmes is on the exact intended location + people[HOLMES]._position = pt; + people[HOLMES]._sequenceNumber = dir; + people[HOLMES].gotoStand(); + + 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[HOLMES].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); +} + + } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 7b79b53f6b..b416fd4665 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -60,6 +60,11 @@ protected: SherlockEngine *_vm; UserInterface(SherlockEngine *vm); + + /** + * Called for OPEN, CLOSE, and MOVE actions are being done + */ + void checkAction(ActionType &action, const char *const messages[], int objNum); public: MenuMode _menuMode; int _menuCounter; -- cgit v1.2.3