mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-15 06:08:35 +00:00
217 lines
7.9 KiB
C++
217 lines
7.9 KiB
C++
/* 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.height();
|
|
|
|
_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.width() - 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::close() {
|
|
_creditsActive = false;
|
|
_creditLines.clear();
|
|
}
|
|
|
|
void WidgetCredits::drawCredits() {
|
|
Screen &screen = *_vm->_screen;
|
|
Common::Rect screenRect(0, 0, screen.width(), screen.height());
|
|
Surface &bb1 = screen._backBuffer1;
|
|
|
|
for (uint idx = 0; idx < _creditLines.size() && _creditLines[idx]._position.y < screen.height(); ++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.width(), screen.height() + _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);
|
|
}
|
|
}
|
|
}
|
|
|
|
void WidgetCredits::eraseCredits() {
|
|
Screen &screen = *_vm->_screen;
|
|
Common::Rect screenRect(0, -_creditSpeed, screen.width(), screen.height() + _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);
|
|
screen.slamRect(r);
|
|
}
|
|
|
|
_creditLines[idx]._position.y -= _creditSpeed;
|
|
}
|
|
|
|
if (_creditLines[_creditLines.size() - 1]._position.y < -_creditSpeed) {
|
|
// Completely finished credits display. Note that the credits will still remain flagged as active,
|
|
// so that the user interface knows not to allow and standard scene interaction
|
|
_creditLines.clear();
|
|
}
|
|
}
|
|
|
|
} // End of namespace Tattoo
|
|
|
|
} // End of namespace Sherlock
|