SHERLOCK: RT: Implemented doStandardControl

This commit is contained in:
Paul Gilbert 2015-06-13 14:53:50 -04:00
parent e16ae1a2e7
commit 7d2f15d821
7 changed files with 365 additions and 139 deletions

View File

@ -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

View File

@ -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
*/

View File

@ -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<SceneTripEntry> _sceneTripCounters;
bool _labTableScene;
public:
TattooScene(SherlockEngine *vm);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;