aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2015-07-21 19:55:34 -0400
committerPaul Gilbert2015-07-21 19:55:34 -0400
commit60a4a8560494e1e8e038a0a09b9c4144fc354d69 (patch)
tree44836164beab3c320682d95c526d3a703f29310a
parentc38d8d9617dbea00eb9343233796b80955a0f564 (diff)
downloadscummvm-rg350-60a4a8560494e1e8e038a0a09b9c4144fc354d69.tar.gz
scummvm-rg350-60a4a8560494e1e8e038a0a09b9c4144fc354d69.tar.bz2
scummvm-rg350-60a4a8560494e1e8e038a0a09b9c4144fc354d69.zip
SHERLOCK: RT: Implement credits
-rw-r--r--engines/sherlock/tattoo/tattoo.cpp164
-rw-r--r--engines/sherlock/tattoo/tattoo.h17
-rw-r--r--engines/sherlock/tattoo/tattoo_user_interface.cpp4
3 files changed, 181 insertions, 4 deletions
diff --git a/engines/sherlock/tattoo/tattoo.cpp b/engines/sherlock/tattoo/tattoo.cpp
index f6dd156ac3..f3be655f56 100644
--- a/engines/sherlock/tattoo/tattoo.cpp
+++ b/engines/sherlock/tattoo/tattoo.cpp
@@ -39,13 +39,14 @@ TattooEngine::TattooEngine(OSystem *syst, const SherlockGameDescription *gameDes
_fastMode = false;
_allowFastMode = true;
_transparentMenus = true;
+ _creditSpeed = 4;
}
TattooEngine::~TattooEngine() {
}
void TattooEngine::showOpening() {
- // TODO
+ // No implementation - opening is done using in-game scenes
}
void TattooEngine::initialize() {
@@ -158,16 +159,171 @@ void TattooEngine::loadInventory() {
inv.push_back(InventoryItem(0, inv8, invDesc8, "_LANT02I"));
}
+void TattooEngine::initCredits() {
+ Common::SeekableReadStream *stream = _res->load("credits.txt");
+ int spacing = _screen->fontHeight() * 2;
+ int yp = _screen->h();
+
+ _creditsActive = true;
+ _creditLines.clear();
+
+ while (stream->pos() < stream->size()) {
+ Common::String line = stream->readLine();
+
+ if (line.hasPrefix("Scroll Speed")) {
+ const char *p = line.c_str() + 12;
+ while ((*p < '0') || (*p > '9'))
+ p++;
+
+ _creditSpeed = atoi(p);
+ } else if (line.hasPrefix("Y Spacing")) {
+ const char *p = line.c_str() + 12;
+ while ((*p < '0') || (*p > '9'))
+ p++;
+
+ spacing = atoi(p) + _screen->fontHeight() + 1;
+ } else {
+ int width = _screen->stringWidth(line) + 2;
+
+ _creditLines.push_back(CreditLine(line, Common::Point((_screen->w() - width) / 2 + 1, yp), width));
+ yp += spacing;
+ }
+ }
+
+ // Post-processing for finding split lines
+ for (int l = 0; l < (int)_creditLines.size(); ++l) {
+ CreditLine &cl = _creditLines[l];
+ const char *p = strchr(cl._line.c_str(), '-');
+
+ if (p != nullptr && p[1] == '>') {
+ cl._line2 = Common::String(p + 3);
+ cl._line = Common::String(cl._line.c_str(), p);
+
+ int width = cl._width;
+ int width1 = _screen->stringWidth(cl._line);
+ int width2 = _screen->stringWidth(cl._line2);
+
+ int c = 1;
+ for (int l1 = l + 1; l1 < (int)_creditLines.size(); ++l1) {
+ if ((p = strchr(_creditLines[l1]._line.c_str(), '-')) != nullptr) {
+ if (p[1] == '>') {
+ Common::String line1 = Common::String(_creditLines[l1]._line.c_str(), p);
+ Common::String line2 = Common::String(p + 3);
+
+ width1 = MAX(width1, _screen->stringWidth(line1));
+
+ if (_screen->stringWidth(line2) > width2)
+ width2 = _screen->stringWidth(line2);
+ ++c;
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
+ width = width1 + width2 + _screen->widestChar();
+ width1 += _screen->widestChar();
+
+ for (int l1 = l; l1 < l + c; ++l1) {
+ _creditLines[l1]._width = width;
+ _creditLines[l1]._xOffset = width1;
+ }
+
+ l += c - 1;
+ }
+ }
+
+ delete stream;
+}
+
void TattooEngine::drawCredits() {
- // TODO
+ Common::Rect screenRect(0, 0, _screen->w(), _screen->h());
+
+ for (uint idx = 0; idx < _creditLines.size() && _creditLines[idx]._position.y < _screen->h(); ++idx) {
+ if (screenRect.contains(_creditLines[idx]._position)) {
+ if (_creditLines[idx]._position.x >= 65536) {
+ int x1 = _creditLines[idx]._position.x;
+ int x2 = x1 + _creditLines[idx]._xOffset;
+ const Common::String &line1 = _creditLines[idx]._line;
+ const Common::String &line2 = _creditLines[idx]._line2;
+
+ _screen->writeString(line1, Common::Point(x1 - 1, _creditLines[idx]._position.y - 1), 0);
+ _screen->writeString(line1, Common::Point(x1, _creditLines[idx]._position.y - 1), 0);
+ _screen->writeString(line1, Common::Point(x1 + 1, _creditLines[idx]._position.y - 1), 0);
+
+ _screen->writeString(line1, Common::Point(x1 - 1, _creditLines[idx]._position.y), 0);
+ _screen->writeString(line1, Common::Point(x1 + 1, _creditLines[idx]._position.y), 0);
+
+ _screen->writeString(line1, Common::Point(x1 - 1, _creditLines[idx]._position.y + 1), 0);
+ _screen->writeString(line1, Common::Point(x1, _creditLines[idx]._position.y + 1), 0);
+ _screen->writeString(line1, Common::Point(x1 + 1, _creditLines[idx]._position.y + 1), 0);
+
+ _screen->writeString(line1, Common::Point(x1, _creditLines[idx]._position.y), INFO_TOP);
+
+ _screen->writeString(line2, Common::Point(x2 - 1, _creditLines[idx]._position.y - 1), 0);
+ _screen->writeString(line2, Common::Point(x2, _creditLines[idx]._position.y - 1), 0);
+ _screen->writeString(line2, Common::Point(x2 + 1, _creditLines[idx]._position.y - 1), 0);
+
+ _screen->writeString(line2, Common::Point(x2 - 1, _creditLines[idx]._position.y), 0);
+ _screen->writeString(line2, Common::Point(x2 + 1, _creditLines[idx]._position.y), 0);
+
+ _screen->writeString(line2, Common::Point(x2 - 1, _creditLines[idx]._position.y + 1), 0);
+ _screen->writeString(line2, Common::Point(x2, _creditLines[idx]._position.y + 1), 0);
+ _screen->writeString(line2, Common::Point(x2 + 1, _creditLines[idx]._position.y + 1), 0);
+
+ _screen->writeString(line2, Common::Point(x2, _creditLines[idx]._position.y), INFO_TOP);
+ } else {
+ _screen->writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x - 1, _creditLines[idx]._position.y - 1), 0);
+ _screen->writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x, _creditLines[idx]._position.y - 1), 0);
+ _screen->writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x + 1, _creditLines[idx]._position.y - 1), 0);
+
+ _screen->writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x - 1, _creditLines[idx]._position.y), 0);
+ _screen->writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x + 1, _creditLines[idx]._position.y), 0);
+
+ _screen->writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x - 1, _creditLines[idx]._position.y + 1), 0);
+ _screen->writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x, _creditLines[idx]._position.y + 1), 0);
+ _screen->writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x + 1, _creditLines[idx]._position.y + 1), 0);
+
+ _screen->writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x, _creditLines[idx]._position.y), INFO_TOP);
+ }
+ }
+ }
}
void TattooEngine::blitCredits() {
- // TODO
+ Common::Rect screenRect(0, -_creditSpeed, _screen->w(), _screen->h() + _creditSpeed);
+
+ for (uint idx = 0; idx < _creditLines.size(); ++idx) {
+ if (screenRect.contains(_creditLines[idx]._position)) {
+ Common::Rect r(_creditLines[idx]._width, _screen->fontHeight() + 2);
+ r.moveTo(_creditLines[idx]._position.x, _creditLines[idx]._position.y - 1);
+
+ _screen->restoreBackground(r);
+ }
+
+ _creditLines[idx]._position.y -= _creditSpeed;
+ }
}
void TattooEngine::eraseCredits() {
- // TODO
+ Common::Rect screenRect(0, -_creditSpeed, _screen->w(), _screen->h() + _creditSpeed);
+
+ for (uint idx = 0; idx = _creditLines.size(); ++idx) {
+ if (screenRect.contains(_creditLines[idx]._position)) {
+ Common::Rect r(_creditLines[idx]._width, _screen->fontHeight() + 2);
+ r.moveTo(_creditLines[idx]._position.x, _creditLines[idx]._position.y - 1 + _creditSpeed);
+
+ _screen->restoreBackground(r);
+ }
+ }
+
+ if (!screenRect.contains(_creditLines[_creditLines.size() - 1]._position)) {
+ _creditLines.clear();
+ _creditsActive = false;
+ setFlags(!3000);
+ }
}
void TattooEngine::doHangManPuzzle() {
diff --git a/engines/sherlock/tattoo/tattoo.h b/engines/sherlock/tattoo/tattoo.h
index 4c7977bd35..a9798dce41 100644
--- a/engines/sherlock/tattoo/tattoo.h
+++ b/engines/sherlock/tattoo/tattoo.h
@@ -51,9 +51,21 @@ enum {
FLAG_ALT_MAP_MUSIC = 525
};
+struct CreditLine {
+ Common::Point _position;
+ int _xOffset;
+ int _width;
+ Common::String _line, _line2;
+
+ CreditLine(const Common::String &line, const Common::Point &pt, int width) :
+ _line(line), _position(pt), _width(width), _xOffset(0) {}
+};
+
class TattooEngine : public SherlockEngine {
private:
Darts _darts;
+ Common::Array<CreditLine> _creditLines;
+ int _creditSpeed;
/**
* Loads the initial palette for the game
@@ -86,6 +98,11 @@ public:
virtual ~TattooEngine();
/**
+ * Initialize and load credit data for display
+ */
+ void initCredits();
+
+ /**
* Draw credits on the screen
*/
void drawCredits();
diff --git a/engines/sherlock/tattoo/tattoo_user_interface.cpp b/engines/sherlock/tattoo/tattoo_user_interface.cpp
index cf93ce20c5..ec1ba131b4 100644
--- a/engines/sherlock/tattoo/tattoo_user_interface.cpp
+++ b/engines/sherlock/tattoo/tattoo_user_interface.cpp
@@ -238,6 +238,10 @@ void TattooUserInterface::handleInput() {
_vm->_canLoadSave = false;
_keyState.keycode = Common::KEYCODE_INVALID;
+ // Check for credits starting
+ if (_vm->readFlags(3000) && !vm._creditsActive)
+ vm.initCredits();
+
// Check the mouse positioning
if (events.isCursorVisible())
_bgFound = scene.findBgShape(mousePos);