aboutsummaryrefslogtreecommitdiff
path: root/engines/sherlock
diff options
context:
space:
mode:
authorPaul Gilbert2015-06-26 19:42:54 -0400
committerPaul Gilbert2015-06-26 19:42:54 -0400
commit47a3080af2ec686957ee813a309fb7704bd31dd8 (patch)
tree5945f606de913e3753368e3dc3d1a6460d970fd1 /engines/sherlock
parent53e65d2e94b068e3cea3b588dcb32c698499382e (diff)
downloadscummvm-rg350-47a3080af2ec686957ee813a309fb7704bd31dd8.tar.gz
scummvm-rg350-47a3080af2ec686957ee813a309fb7704bd31dd8.tar.bz2
scummvm-rg350-47a3080af2ec686957ee813a309fb7704bd31dd8.zip
SHERLOCK: RT: Code for positioning text windows over characters
Diffstat (limited to 'engines/sherlock')
-rw-r--r--engines/sherlock/tattoo/tattoo_talk.cpp2
-rw-r--r--engines/sherlock/tattoo/widget_text.cpp101
-rw-r--r--engines/sherlock/tattoo/widget_text.h11
3 files changed, 101 insertions, 13 deletions
diff --git a/engines/sherlock/tattoo/tattoo_talk.cpp b/engines/sherlock/tattoo/tattoo_talk.cpp
index ec75b31329..4868ef5ae0 100644
--- a/engines/sherlock/tattoo/tattoo_talk.cpp
+++ b/engines/sherlock/tattoo/tattoo_talk.cpp
@@ -195,7 +195,7 @@ void TattooTalk::talkInterface(const byte *&str) {
// Display the text window
ui.banishWindow();
- ui._textWidget.load(s);
+ ui._textWidget.load(s, _speaker);
ui._textWidget.summonWindow();
_wait = true;
}
diff --git a/engines/sherlock/tattoo/widget_text.cpp b/engines/sherlock/tattoo/widget_text.cpp
index ace4fd43ca..5c2e7e087f 100644
--- a/engines/sherlock/tattoo/widget_text.cpp
+++ b/engines/sherlock/tattoo/widget_text.cpp
@@ -21,6 +21,8 @@
*/
#include "sherlock/tattoo/widget_text.h"
+#include "sherlock/tattoo/tattoo_people.h"
+#include "sherlock/tattoo/tattoo_scene.h"
#include "sherlock/tattoo/tattoo_user_interface.h"
#include "sherlock/tattoo/tattoo.h"
@@ -31,7 +33,7 @@ namespace Tattoo {
WidgetText::WidgetText(SherlockEngine *vm) : WidgetBase(vm) {
}
-void WidgetText::load(const Common::String &str) {
+void WidgetText::load(const Common::String &str, int speaker) {
Screen &screen = *_vm->_screen;
Talk &talk = *_vm->_talk;
TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
@@ -62,19 +64,100 @@ void WidgetText::load(const Common::String &str) {
width += _surface.charWidth(*strP++);
}
- Common::Rect bounds(width, height);
- bounds.translate(ui._lookPos.x - width / 2, ui._lookPos.y - height / 2);
- load(str, bounds);
+ _bounds = Common::Rect(width, height);
+
+ if (speaker == -1) {
+ // No speaker specified, so center window on look position
+ _bounds.translate(ui._lookPos.x - width / 2, ui._lookPos.y - height / 2);
+ } else {
+ // Speaker specified, so center the window above them
+ centerWindowOnSpeaker(speaker);
+ }
+ }
+
+ render(str);
+}
+
+void WidgetText::centerWindowOnSpeaker(int speaker) {
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ Common::Point pt;
+
+ bool flag = _vm->readFlags(76);
+ if (people[HOLMES]._type == CHARACTER && ((speaker == HOLMES && flag) || (speaker == WATSON && !flag))) {
+ // Place the window centered above the player
+ pt.x = people[HOLMES]._position.x / FIXED_INT_MULTIPLIER - _bounds.width() / 2;
+
+ int scaleVal = scene.getScaleVal(people[HOLMES]._position);
+ if (scaleVal == SCALE_THRESHOLD) {
+ pt.x += people[HOLMES].frameWidth() / 2;
+ pt.y = people[HOLMES]._position.y / FIXED_INT_MULTIPLIER - people[HOLMES].frameHeight()
+ - _bounds.height() - _surface.fontHeight();
+ } else {
+ pt.x += people[HOLMES]._imageFrame->sDrawXSize(scaleVal) / 2;
+ pt.y = people[HOLMES]._position.y / FIXED_INT_MULTIPLIER - people[HOLMES]._imageFrame->sDrawYSize(scaleVal)
+ - _bounds.height() - _surface.fontHeight();
+ }
} else {
- load(str, _bounds);
+ pt.y = -1;
+
+ // Check each NPC to see if they are the one that is talking
+ for (int idx = 1; idx < MAX_CHARACTERS; ++idx) {
+ if (people[idx]._type == CHARACTER) {
+ if (!scumm_strnicmp(people[idx]._npcName.c_str(), people._characters[speaker]._portrait, 4)) {
+ // Place the window above the player
+ pt.x = people[idx]._position.x / FIXED_INT_MULTIPLIER - _bounds.width() / 2;
+
+ int scaleVal = scene.getScaleVal(people[idx]._position);
+ if (scaleVal == SCALE_THRESHOLD) {
+ pt.x += people[idx].frameWidth() / 2;
+ pt.y = people[idx]._position.y / FIXED_INT_MULTIPLIER - people[idx].frameHeight()
+ - _bounds.height() - _surface.fontHeight();
+ }
+ else {
+ pt.x += people[idx]._imageFrame->sDrawXSize(scaleVal) / 2;
+ pt.y = people[idx]._position.y / FIXED_INT_MULTIPLIER - people[idx]._imageFrame->sDrawYSize(scaleVal)
+ - _bounds.height() - _surface.fontHeight();
+ }
+
+ if (pt.y < 0)
+ pt.y = 0;
+ break;
+ }
+ }
+ }
+
+ if (pt.y == -1) {
+ for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) {
+ Object &obj = scene._bgShapes[idx];
+
+ if (obj._type == ACTIVE_BG_SHAPE && !scumm_strnicmp(obj._name.c_str(), people._characters[speaker]._portrait, 4)) {
+ // Place the window centered above the character
+ pt.x = obj._position.x - _bounds.width() / 2;
+ pt.y = obj._position.y - _bounds.height() - _surface.fontHeight();
+ if (pt.y < 0)
+ pt.y = 0;
+ if (obj._scaleVal == SCALE_THRESHOLD)
+ pt.x += obj.frameWidth() / 2;
+ else
+ pt.x += obj._imageFrame->sDrawXSize(obj._scaleVal) / 2;
+
+ break;
+ }
+ }
+ }
+
+ if (pt.y == -1) {
+ pt.x = SHERLOCK_SCREEN_WIDTH / 2 - _bounds.width() / 2;
+ pt.y = SHERLOCK_SCREEN_HEIGHT / 2 - _bounds.height() / 2;
+ }
}
}
-void WidgetText::load(const Common::String &str, const Common::Rect &bounds) {
+void WidgetText::render(const Common::String &str) {
Common::StringArray lines;
- _remainingText = splitLines(str, lines, bounds.width() - _surface.widestChar() * 2,
- bounds.height() / (_surface.fontHeight() + 1));
- _bounds = bounds;
+ _remainingText = splitLines(str, lines, _bounds.width() - _surface.widestChar() * 2,
+ _bounds.height() / (_surface.fontHeight() + 1));
// Allocate a surface for the window
_surface.create(_bounds.width(), _bounds.height());
diff --git a/engines/sherlock/tattoo/widget_text.h b/engines/sherlock/tattoo/widget_text.h
index e77342531e..f027bdae9f 100644
--- a/engines/sherlock/tattoo/widget_text.h
+++ b/engines/sherlock/tattoo/widget_text.h
@@ -35,9 +35,14 @@ namespace Tattoo {
class WidgetText: public WidgetBase {
private:
/**
- * Display the passed text in a window of the given bounds
+ * Center the area the dialog will be drawn on above a given speaker
*/
- void load(const Common::String &str, const Common::Rect &bounds);
+ void centerWindowOnSpeaker(int speaker);
+
+ /**
+ * Build up the text dialog based on the previously set bounds
+ */
+ void render(const Common::String &str);
public:
Common::String _remainingText;
public:
@@ -47,7 +52,7 @@ public:
/**
* Load the data for the text window
*/
- void load(const Common::String &str);
+ void load(const Common::String &str, int speaker = -1);
};
class WidgetMessage : public WidgetBase {