From 71296d6461bd8346793ff939b5d2e84d22c58dfa Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 22 Jul 2015 20:26:28 -0400 Subject: SHERLOCK: RT: Split TattooEngine code into separate widget classes --- engines/sherlock/tattoo/widget_credits.cpp | 210 +++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 engines/sherlock/tattoo/widget_credits.cpp (limited to 'engines/sherlock/tattoo/widget_credits.cpp') diff --git a/engines/sherlock/tattoo/widget_credits.cpp b/engines/sherlock/tattoo/widget_credits.cpp new file mode 100644 index 0000000000..dcb73b5adb --- /dev/null +++ b/engines/sherlock/tattoo/widget_credits.cpp @@ -0,0 +1,210 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "sherlock/tattoo/widget_credits.h" +#include "sherlock/tattoo/tattoo.h" + +namespace Sherlock { + +namespace Tattoo { + +WidgetCredits::WidgetCredits(SherlockEngine *vm) : _vm(vm) { + _creditSpeed = 4; + _creditsActive = false; +} + +void WidgetCredits::initCredits() { + Resources &res = *_vm->_res; + Screen &screen = *_vm->_screen; + 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 WidgetCredits::drawCredits() { + Screen &screen = *_vm->_screen; + Common::Rect screenRect(0, 0, screen.w(), screen.h()); + Surface &bb1 = screen._backBuffer1; + + for (uint idx = 0; idx < _creditLines.size() && _creditLines[idx]._position.y < screen.h(); ++idx) { + if (screenRect.contains(_creditLines[idx]._position)) { + if (!_creditLines[idx]._line2.empty()) { + 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; + + bb1.writeString(line1, Common::Point(x1 - 1, _creditLines[idx]._position.y - 1), 0); + bb1.writeString(line1, Common::Point(x1, _creditLines[idx]._position.y - 1), 0); + bb1.writeString(line1, Common::Point(x1 + 1, _creditLines[idx]._position.y - 1), 0); + + bb1.writeString(line1, Common::Point(x1 - 1, _creditLines[idx]._position.y), 0); + bb1.writeString(line1, Common::Point(x1 + 1, _creditLines[idx]._position.y), 0); + + bb1.writeString(line1, Common::Point(x1 - 1, _creditLines[idx]._position.y + 1), 0); + bb1.writeString(line1, Common::Point(x1, _creditLines[idx]._position.y + 1), 0); + bb1.writeString(line1, Common::Point(x1 + 1, _creditLines[idx]._position.y + 1), 0); + + bb1.writeString(line1, Common::Point(x1, _creditLines[idx]._position.y), INFO_TOP); + + bb1.writeString(line2, Common::Point(x2 - 1, _creditLines[idx]._position.y - 1), 0); + bb1.writeString(line2, Common::Point(x2, _creditLines[idx]._position.y - 1), 0); + bb1.writeString(line2, Common::Point(x2 + 1, _creditLines[idx]._position.y - 1), 0); + + bb1.writeString(line2, Common::Point(x2 - 1, _creditLines[idx]._position.y), 0); + bb1.writeString(line2, Common::Point(x2 + 1, _creditLines[idx]._position.y), 0); + + bb1.writeString(line2, Common::Point(x2 - 1, _creditLines[idx]._position.y + 1), 0); + bb1.writeString(line2, Common::Point(x2, _creditLines[idx]._position.y + 1), 0); + bb1.writeString(line2, Common::Point(x2 + 1, _creditLines[idx]._position.y + 1), 0); + + bb1.writeString(line2, Common::Point(x2, _creditLines[idx]._position.y), INFO_TOP); + } else { + bb1.writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x - 1, _creditLines[idx]._position.y - 1), 0); + bb1.writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x, _creditLines[idx]._position.y - 1), 0); + bb1.writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x + 1, _creditLines[idx]._position.y - 1), 0); + + bb1.writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x - 1, _creditLines[idx]._position.y), 0); + bb1.writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x + 1, _creditLines[idx]._position.y), 0); + + bb1.writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x - 1, _creditLines[idx]._position.y + 1), 0); + bb1.writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x, _creditLines[idx]._position.y + 1), 0); + bb1.writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x + 1, _creditLines[idx]._position.y + 1), 0); + + bb1.writeString(_creditLines[idx]._line, Common::Point(_creditLines[idx]._position.x, _creditLines[idx]._position.y), INFO_TOP); + } + } + } +} + +void WidgetCredits::blitCredits() { + Screen &screen = *_vm->_screen; + 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.slamRect(r); + } + + _creditLines[idx]._position.y -= _creditSpeed; + } +} + +void WidgetCredits::eraseCredits() { + Screen &screen = *_vm->_screen; + 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() + 3); + r.moveTo(_creditLines[idx]._position.x, _creditLines[idx]._position.y - 1 + _creditSpeed); + + screen.restoreBackground(r); + } + } + + if (_creditLines[_creditLines.size() - 1]._position.y < -_creditSpeed) { + _creditLines.clear(); + _creditsActive = false; + _vm->setFlags(!3000); + } +} + +} // End of namespace Tattoo + +} // End of namespace Sherlock -- cgit v1.2.3