aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sherlock/people.cpp1
-rw-r--r--engines/sherlock/people.h1
-rw-r--r--engines/sherlock/talk.h4
-rw-r--r--engines/sherlock/user_interface.cpp254
4 files changed, 258 insertions, 2 deletions
diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp
index 5c7f9ef506..e6a4eeed0f 100644
--- a/engines/sherlock/people.cpp
+++ b/engines/sherlock/people.cpp
@@ -203,6 +203,7 @@ People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) {
_portraitSide = 0;
_speakerFlip = false;
_holmesFlip = false;
+ _homesQuotient = 0;
}
People::~People() {
diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h
index ba870d041d..601fe6006b 100644
--- a/engines/sherlock/people.h
+++ b/engines/sherlock/people.h
@@ -81,6 +81,7 @@ public:
int _portraitSide;
bool _speakerFlip;
bool _holmesFlip;
+ int _homesQuotient;
public:
People(SherlockEngine *vm);
~People();
diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h
index 1a7dd587da..c4b5fe46d2 100644
--- a/engines/sherlock/talk.h
+++ b/engines/sherlock/talk.h
@@ -79,8 +79,10 @@ struct TalkSequences {
};
class SherlockEngine;
+class UserInterface;
class Talk {
+ friend class UserInterface;
private:
Common::Array<TalkSequences> STILL_SEQUENCES;
Common::Array<TalkSequences> TALK_SEQUENCES;
@@ -97,7 +99,6 @@ private:
int _converseNum;
int _talkStealth;
int _talkToFlag;
- bool _moreTalkUp, _moreTalkDown;
int _scriptSaveIndex;
int _scriptCurrentIndex;
private:
@@ -117,6 +118,7 @@ public:
int _talkTo;
int _scriptMoreFlag;
Common::String _scriptName;
+ bool _moreTalkUp, _moreTalkDown;
public:
Talk(SherlockEngine *vm);
void setSequences(const byte *talkSequences, const byte *stillSequences,
diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp
index 9104c761a0..70f284c359 100644
--- a/engines/sherlock/user_interface.cpp
+++ b/engines/sherlock/user_interface.cpp
@@ -1222,8 +1222,260 @@ void UserInterface::doPickControl() {
}
}
+/**
+ * Handles input when in talk mode. It highlights the buttons and available statements,
+ * and handles allowing the user to click on them
+ */
void UserInterface::doTalkControl() {
- // TODO
+ Events &events = *_vm->_events;
+ Journal &journal = *_vm->_journal;
+ People &people = *_vm->_people;
+ Screen &screen = *_vm->_screen;
+ Sound &sound = *_vm->_sound;
+ Talk &talk = *_vm->_talk;
+ UserInterface &ui = *_vm->_ui;
+ Common::Point mousePos = events.mousePos();
+ int select;
+
+ _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 (_keycode != Common::KEYCODE_INVALID) {
+ _key = toupper(_keycode);
+ 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);
+ }
+
+ if (events._released || _keyboardInput) {
+ if (_endKeyActive && ((mousePos.x > 99 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 10)
+ && talk._moreTalkUp && events._released) || _key == 'E')) {
+ talk.freeTalkVars();
+ talk.pullSequence();
+ banishWindow();
+ _windowBounds.top = CONTROLS_Y1;
+ } else if ((mousePos.x > 140 && mousePos.x < 179 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 10)
+ && talk._moreTalkUp && events._released) || (talk._moreTalkUp && _key == 'U')) {
+ 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 ((mousePos.x > 181 && mousePos.x < 220 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 10)
+ && talk._moreTalkDown && events._released) || (talk._moreTalkDown && _key == 'D')) {
+ 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._homesQuotient += 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);
+
+ // Set voices as an indicator for waiting
+ sound._voices = 2;
+ sound._speechOn = *sound._soundIsOn;
+ } else {
+ sound._speechOn = false;
+ }
+
+ // Set the _scriptCurrentIndex so if the statement is irrupted, the entire
+ // reply will be shown when it's restarted
+ talk._scriptCurrentIndex = 0;
+ 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
+ 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()) {
+ SequenceEntry seqEntry = talk._scriptStack.pop();
+// talk._scriptName = seqEntry.
+ // TODO
+ }
+ }
+ }
}
void UserInterface::journalControl() {