aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorMiroslav Remák2018-07-17 11:22:25 +0200
committerEugene Sandulenko2018-08-25 23:12:01 +0200
commitf94ff7aa8ec510de8dc353c9c2e079db5e05d5da (patch)
tree56a636e1fc16b7176c043d7579ecb38844e053e6 /engines
parentf70eb01061d3e5dd74ed8065d0435a4273d973dc (diff)
downloadscummvm-rg350-f94ff7aa8ec510de8dc353c9c2e079db5e05d5da.tar.gz
scummvm-rg350-f94ff7aa8ec510de8dc353c9c2e079db5e05d5da.tar.bz2
scummvm-rg350-f94ff7aa8ec510de8dc353c9c2e079db5e05d5da.zip
MUTATIONOFJB: Implement word wrapping for subtitles.
Diffstat (limited to 'engines')
-rw-r--r--engines/mutationofjb/font.cpp58
-rw-r--r--engines/mutationofjb/font.h13
-rw-r--r--engines/mutationofjb/tasks/saytask.cpp39
-rw-r--r--engines/mutationofjb/tasks/saytask.h4
4 files changed, 98 insertions, 16 deletions
diff --git a/engines/mutationofjb/font.cpp b/engines/mutationofjb/font.cpp
index 235c60a39e..4350b19850 100644
--- a/engines/mutationofjb/font.cpp
+++ b/engines/mutationofjb/font.cpp
@@ -27,9 +27,9 @@
namespace MutationOfJB {
-Font::Font(const Common::String &fileName, int horizSpacing, int vertSpacing) :
+Font::Font(const Common::String &fileName, int horizSpacing, int lineHeight) :
_horizSpacing(horizSpacing),
- _vertSpacing(vertSpacing) {
+ _lineHeight(lineHeight) {
load(fileName);
}
@@ -67,15 +67,14 @@ bool Font::load(const Common::String &fileName) {
}
}
- if (_vertSpacing == -1) {
- _vertSpacing = maxHeight;
+ if (_lineHeight == -1) {
+ _lineHeight = maxHeight;
}
return true;
}
-
-void Font::drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics::ManagedSurface &surf) {
+void Font::drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics::ManagedSurface &surf) const {
GlyphMap::iterator it = _glyphs.find(glyph);
if (it == _glyphs.end()) {
warning("Glyph %d not found", glyph);
@@ -99,13 +98,54 @@ void Font::drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics:
x += glyphSurface.w + _horizSpacing;
}
-void Font::drawString(const Common::String &str, uint8 baseColor, int16 x, int16 y, Graphics::ManagedSurface &surf) {
+int16 Font::getWidth(const Common::String &str) const {
+ int16 width = 0;
+ for (uint i = 0; i < str.size(); ++i) {
+ GlyphMap::iterator it = _glyphs.find(str[i]);
+ if (it == _glyphs.end()) {
+ continue;
+ }
+
+ width += it->_value.w + _horizSpacing;
+ }
+ return width;
+}
+
+int Font::getLineHeight() const {
+ return _lineHeight;
+}
+
+void Font::drawString(const Common::String &str, uint8 baseColor, int16 x, int16 y, Graphics::ManagedSurface &surf) const {
for (uint i = 0; i < str.size(); ++i) {
drawGlyph(str[i], baseColor, x, y, surf); // "x" is updated.
}
}
-uint8 Font::transformColor(uint8 baseColor, uint8 glyphColor) {
+void Font::wordWrap(const Common::String &str, int16 maxLineWidth, Common::Array<Common::String> &lines) const {
+ lines.push_back("");
+
+ for (Common::String::const_iterator it = str.begin(); it != str.end();) {
+ Common::String::const_iterator partStart = it;
+ it = Common::find(partStart, str.end(), ' ');
+ if (it != str.end()) {
+ while (*it == ' ' && it != str.end()) {
+ ++it;
+ }
+ }
+
+ Common::String part(partStart, it); // Word + following whitespace
+ Common::String line = lines.back() + part;
+ if (getWidth(line) <= maxLineWidth) {
+ // The part fits in the current line
+ lines.back() = line;
+ } else {
+ // The part must go to the next line
+ lines.push_back(part);
+ }
+ }
+}
+
+uint8 Font::transformColor(uint8 baseColor, uint8 glyphColor) const {
return baseColor + glyphColor - 0x10;
}
@@ -113,7 +153,7 @@ SystemFont::SystemFont() : Font("sysfnt.aft", 1, 7) {}
SpeechFont::SpeechFont() : Font("font1.aft", -1, -1) {}
-uint8 SpeechFont::transformColor(uint8 baseColor, uint8 glyphColor) {
+uint8 SpeechFont::transformColor(uint8 baseColor, uint8 glyphColor) const {
// Hack in original game.
if (glyphColor == 0x11) {
return 0xC0;
diff --git a/engines/mutationofjb/font.h b/engines/mutationofjb/font.h
index 5aa6a4fb78..a27303eb0d 100644
--- a/engines/mutationofjb/font.h
+++ b/engines/mutationofjb/font.h
@@ -37,17 +37,20 @@ class Font {
public:
Font(const Common::String &fileName, int horizSpacing, int vertSpacing);
virtual ~Font() {}
- void drawString(const Common::String &str, uint8 baseColor, int16 x, int16 y, Graphics::ManagedSurface &surf);
+ int getLineHeight() const;
+ int16 getWidth(const Common::String &text) const;
+ void drawString(const Common::String &str, uint8 baseColor, int16 x, int16 y, Graphics::ManagedSurface &surf) const;
+ void wordWrap(const Common::String &str, int16 maxLineWidth, Common::Array<Common::String> &lines) const;
protected:
- virtual uint8 transformColor(uint8 baseColor, uint8 glyphColor);
+ virtual uint8 transformColor(uint8 baseColor, uint8 glyphColor) const;
private:
- void drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics::ManagedSurface &surf);
+ void drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics::ManagedSurface &surf) const;
bool load(const Common::String &fileName);
int _horizSpacing;
- int _vertSpacing;
+ int _lineHeight;
typedef Common::HashMap<uint8, Graphics::ManagedSurface> GlyphMap;
GlyphMap _glyphs;
};
@@ -62,7 +65,7 @@ public:
SpeechFont();
protected:
- virtual uint8 transformColor(uint8 baseColor, uint8 glyphColor) override;
+ virtual uint8 transformColor(uint8 baseColor, uint8 glyphColor) const override;
};
}
diff --git a/engines/mutationofjb/tasks/saytask.cpp b/engines/mutationofjb/tasks/saytask.cpp
index 2ef4cdf5df..fcef6c3211 100644
--- a/engines/mutationofjb/tasks/saytask.cpp
+++ b/engines/mutationofjb/tasks/saytask.cpp
@@ -27,6 +27,7 @@
#include "mutationofjb/game.h"
#include "mutationofjb/gamedata.h"
#include "mutationofjb/room.h"
+#include "mutationofjb/util.h"
#include "graphics/managed_surface.h"
#include "graphics/screen.h"
@@ -36,8 +37,7 @@ namespace MutationOfJB {
SayTask::SayTask(const Common::String &toSay, uint8 color) : _toSay(toSay), _color(color), _timer(1000) {}
void SayTask::start() {
-
- getTaskManager()->getGame().getAssets().getSpeechFont().drawString(_toSay, _color, 0, 0, getTaskManager()->getGame().getScreen());
+ drawSubtitle(_toSay, 160, 0, _color); // TODO: Respect PTALK and LTALK commands.
_timer.start();
setState(RUNNING);
}
@@ -52,4 +52,39 @@ void SayTask::update() {
}
}
+void SayTask::drawSubtitle(const Common::String &text, int16 talkX, int16 talkY, uint8 color) {
+ const int MAX_LINE_WIDTH = 250;
+
+ const Font &font = getTaskManager()->getGame().getAssets().getSpeechFont();
+
+ Common::Array<Common::String> lines;
+ font.wordWrap(text, MAX_LINE_WIDTH, lines);
+
+ int16 x = talkX;
+ int16 y = talkY - (lines.size() - 1) * font.getLineHeight() - 15; // Get the top y
+
+ // Clamp to screen edges
+ y = MAX<int16>(y, 3);
+ int16 maxWidth = 0;
+ for (uint i = 0; i < lines.size(); i++) {
+ int16 lineWidth = font.getWidth(lines[i]);
+ if (lineWidth > maxWidth) {
+ maxWidth = lineWidth;
+ }
+ x = MAX<int16>(x, 3 + lineWidth / 2);
+ x = MIN<int16>(x, 317 - lineWidth / 2);
+ }
+
+ // Draw lines
+ for (uint i = 0; i < lines.size(); i++) {
+ font.drawString(lines[i], color, x - font.getWidth(lines[i]) / 2, y + i * font.getLineHeight(), getTaskManager()->getGame().getScreen());
+ }
+
+ // Remember the area occupied by the text
+ _boundingBox.top = x - maxWidth / 2;
+ _boundingBox.left = y;
+ _boundingBox.setWidth(maxWidth);
+ _boundingBox.setHeight(lines.size() * font.getLineHeight());
+}
+
}
diff --git a/engines/mutationofjb/tasks/saytask.h b/engines/mutationofjb/tasks/saytask.h
index a7ac96d875..ef66f5beb4 100644
--- a/engines/mutationofjb/tasks/saytask.h
+++ b/engines/mutationofjb/tasks/saytask.h
@@ -24,6 +24,7 @@
#include "mutationofjb/timer.h"
+#include "common/rect.h"
#include "common/str.h"
namespace MutationOfJB {
@@ -36,9 +37,12 @@ public:
virtual void update() override;
private:
+ void drawSubtitle(const Common::String &text, int16 talkX, int16 talkY, uint8 color);
+
Common::String _toSay;
uint8 _color;
Timer _timer;
+ Common::Rect _boundingBox;
};
}