aboutsummaryrefslogtreecommitdiff
path: root/engines/toon
diff options
context:
space:
mode:
authorBLooperZ2019-08-01 00:21:07 +0300
committerEugene Sandulenko2019-11-18 02:02:14 +0100
commit83285746b0cbaa7223592fa008af22b31484e0d6 (patch)
tree098748cb88cfc67cd39982e0f4fabaee69ec03df /engines/toon
parentfd7efe4fb6fd07b4c3831cbe0082027b9782f919 (diff)
downloadscummvm-rg350-83285746b0cbaa7223592fa008af22b31484e0d6.tar.gz
scummvm-rg350-83285746b0cbaa7223592fa008af22b31484e0d6.tar.bz2
scummvm-rg350-83285746b0cbaa7223592fa008af22b31484e0d6.zip
TOON: add support for cutscene subtitles
Diffstat (limited to 'engines/toon')
-rw-r--r--engines/toon/font.cpp4
-rw-r--r--engines/toon/font.h2
-rw-r--r--engines/toon/module.mk3
-rw-r--r--engines/toon/movie.cpp40
-rw-r--r--engines/toon/movie.h3
-rw-r--r--engines/toon/subtitles.cpp97
-rw-r--r--engines/toon/subtitles.h59
-rw-r--r--engines/toon/toon.cpp13
-rw-r--r--engines/toon/toon.h3
9 files changed, 217 insertions, 7 deletions
diff --git a/engines/toon/font.cpp b/engines/toon/font.cpp
index 9b08e432fc..29dbf40b8b 100644
--- a/engines/toon/font.cpp
+++ b/engines/toon/font.cpp
@@ -191,7 +191,7 @@ void FontRenderer::setFontColor(int32 fontColor1, int32 fontColor2, int32 fontCo
_currentFontColor[3] = fontColor3;
}
-void FontRenderer::renderMultiLineText(int16 x, int16 y, const Common::String &origText, int32 mode) {
+void FontRenderer::renderMultiLineText(int16 x, int16 y, const Common::String &origText, int32 mode, Graphics::Surface& frame) {
debugC(5, kDebugFont, "renderMultiLineText(%d, %d, %s, %d)", x, y, origText.c_str(), mode);
// divide the text in several lines
@@ -289,7 +289,7 @@ void FontRenderer::renderMultiLineText(int16 x, int16 y, const Common::String &o
while (*line) {
byte curChar = textToFont(*line);
- if (curChar != 32) _currentFont->drawFontFrame(_vm->getMainSurface(), curChar, curX + _vm->state()->_currentScrollValue, curY, _currentFontColor);
+ if (curChar != 32) _currentFont->drawFontFrame(frame, curChar, curX + _vm->state()->_currentScrollValue, curY, _currentFontColor);
curX = curX + MAX<int32>(_currentFont->getFrameWidth(curChar) - 2, 0);
//height = MAX(height, _currentFont->getFrameHeight(curChar));
line++;
diff --git a/engines/toon/font.h b/engines/toon/font.h
index bbbccd09c8..48d4b8531d 100644
--- a/engines/toon/font.h
+++ b/engines/toon/font.h
@@ -35,7 +35,7 @@ public:
void setFont(Animation *font);
void computeSize(const Common::String &origText, int16 *retX, int16 *retY);
void renderText(int16 x, int16 y, const Common::String &origText, int32 mode);
- void renderMultiLineText(int16 x, int16 y, const Common::String &origText, int32 mode);
+ void renderMultiLineText(int16 x, int16 y, const Common::String &origText, int32 mode, Graphics::Surface& frame);
void setFontColorByCharacter(int32 characterId);
void setFontColor(int32 fontColor1, int32 fontColor2, int32 fontColor3);
protected:
diff --git a/engines/toon/module.mk b/engines/toon/module.mk
index 7796203d00..411b8e7ddf 100644
--- a/engines/toon/module.mk
+++ b/engines/toon/module.mk
@@ -20,7 +20,8 @@ MODULE_OBJS := \
state.o \
text.o \
tools.o \
- toon.o
+ toon.o \
+ subtitles.o
# This module can be built as a plugin
ifeq ($(ENABLE_TOON), DYNAMIC_PLUGIN)
diff --git a/engines/toon/movie.cpp b/engines/toon/movie.cpp
index 498e4021e2..634135d813 100644
--- a/engines/toon/movie.cpp
+++ b/engines/toon/movie.cpp
@@ -31,6 +31,7 @@
#include "toon/audio.h"
#include "toon/movie.h"
#include "toon/toon.h"
+#include "toon/subtitles.h"
namespace Toon {
@@ -67,6 +68,7 @@ Movie::Movie(ToonEngine *vm , ToonstruckSmackerDecoder *decoder) {
_vm = vm;
_playing = false;
_decoder = decoder;
+ _subtitle = new SubtitleRenderer(_vm);
}
Movie::~Movie() {
@@ -87,6 +89,7 @@ void Movie::play(const Common::String &video, int32 flags) {
_vm->getAudioManager()->setMusicVolume(0);
if (!_decoder->loadFile(video.c_str()))
error("Unable to play video %s", video.c_str());
+ _subtitle->load(video.c_str());
playVideo(isFirstIntroVideo);
_vm->flushPalette(true);
if (flags & 1)
@@ -103,6 +106,7 @@ void Movie::playVideo(bool isFirstIntroVideo) {
while (!_vm->shouldQuit() && !_decoder->endOfVideo()) {
if (_decoder->needsUpdate()) {
const Graphics::Surface *frame = _decoder->decodeNextFrame();
+ byte unused = 0;
if (frame) {
if (_decoder->isLowRes()) {
// handle manually 2x scaling here
@@ -115,9 +119,31 @@ void Movie::playVideo(bool isFirstIntroVideo) {
} else {
_vm->_system->copyRectToScreen(frame->getPixels(), frame->pitch, 0, 0, frame->w, frame->h);
+ int32 currentFrame = _decoder->getCurFrame();
+
+ int len = frame->w * frame->h;
+ byte pixels[310000] = {0};
+ memcpy(pixels, frame->getPixels(), len);
+ for (byte i = 1; i < 256; i++)
+ {
+ int j;
+ for (j = 0; j < len; j++) {
+ if (pixels[j] == i) {
+ break;
+ }
+ }
+
+ if (j == len && i != 255) {
+ unused = i;
+ break;
+ }
+ }
+
+ _subtitle->render(*frame, currentFrame, unused);
+
// WORKAROUND: There is an encoding glitch in the first intro video. This hides this using the adjacent pixels.
if (isFirstIntroVideo) {
- int32 currentFrame = _decoder->getCurFrame();
+ // int32 currentFrame = _decoder->getCurFrame();
if (currentFrame >= 956 && currentFrame <= 1038) {
debugC(1, kDebugMovie, "Triggered workaround for glitch in first intro video...");
_vm->_system->copyRectToScreen(frame->getBasePtr(frame->w-188, 123), frame->pitch, frame->w-188, 124, 188, 1);
@@ -128,7 +154,17 @@ void Movie::playVideo(bool isFirstIntroVideo) {
}
}
}
- _vm->_system->getPaletteManager()->setPalette(_decoder->getPalette(), 0, 256);
+
+ byte palette[768] = {0};
+ memcpy(palette, _decoder->getPalette(), 768);
+
+ if (unused) {
+ palette[3 * unused] = 0xff;
+ palette[3 * unused + 1] = 0xff;
+ palette[3 * unused + 2] = 0x0;
+ }
+
+ _vm->_system->getPaletteManager()->setPalette(palette, 0, 256);
_vm->_system->updateScreen();
}
diff --git a/engines/toon/movie.h b/engines/toon/movie.h
index 54d4fd4dc7..4bbd0a9afb 100644
--- a/engines/toon/movie.h
+++ b/engines/toon/movie.h
@@ -28,6 +28,8 @@
namespace Toon {
+class SubtitleRenderer;
+
class ToonstruckSmackerDecoder : public Video::SmackerDecoder {
public:
ToonstruckSmackerDecoder();
@@ -57,6 +59,7 @@ protected:
ToonEngine *_vm;
ToonstruckSmackerDecoder *_decoder;
bool _playing;
+ SubtitleRenderer *_subtitle;
};
} // End of namespace Toon
diff --git a/engines/toon/subtitles.cpp b/engines/toon/subtitles.cpp
new file mode 100644
index 0000000000..1349778753
--- /dev/null
+++ b/engines/toon/subtitles.cpp
@@ -0,0 +1,97 @@
+/* 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 "common/debug.h"
+#include "common/rect.h"
+#include "common/system.h"
+
+#include "toon/subtitles.h"
+
+namespace Toon {
+SubtitleRenderer::SubtitleRenderer(ToonEngine *vm) : _vm(vm) {
+ _subSurface = new Graphics::Surface();
+ _subSurface->create(TOON_SCREEN_WIDTH, TOON_SCREEN_HEIGHT, Graphics::PixelFormat::createFormatCLUT8());
+ _hasSubtitles = false;
+}
+
+SubtitleRenderer::~SubtitleRenderer() {
+}
+
+
+void SubtitleRenderer::render(const Graphics::Surface& frame, uint32 frameNumber, char color) {
+ if (!_hasSubtitles || _index > _last) {
+ return;
+ }
+
+ _subSurface->copyFrom(frame);
+ // char strf[384] = {0};
+ // sprintf(strf, "Time passed: %d", frameNumber);
+ // _vm->drawCostumeLine(0, 0, strf, _subSurface);
+ // _vm->_system->copyRectToScreen(_subSurface->getBasePtr(0, 0), _subSurface->pitch, 0, 0, _subSurface->w, _subSurface->h);
+
+ if (frameNumber > _tw[_index].fend) {
+ _index++;
+ if (_index > _last) {
+ return;
+ }
+ _currentLine = (char*)_fileData + _tw[_index].foffset;
+ }
+
+ if (frameNumber < _tw[_index].fstart) {
+ return;
+ }
+
+ _vm->drawCustomText(TOON_SCREEN_WIDTH / 2, TOON_SCREEN_HEIGHT, _currentLine, _subSurface, color);
+ _vm->_system->copyRectToScreen(_subSurface->getBasePtr(0, 0), _subSurface->pitch, 0, 0, _subSurface->w, _subSurface->h);
+}
+
+bool SubtitleRenderer::load(const Common::String &video) {
+ warning(video.c_str());
+
+ _hasSubtitles = false;
+ _index = 0;
+
+ char srtfile[20] = {0};
+ strcpy(srtfile, video.c_str());
+ int ln = strlen(srtfile);
+ srtfile[ln - 3] = 't';
+ srtfile[ln - 2] = 's';
+ srtfile[ln - 1] = 's';
+
+ uint32 fileSize = 0;
+ uint8 *fileData = _vm->resources()->getFileData(srtfile, &fileSize);
+ if (!fileData) {
+ return false;
+ }
+
+ uint32 numOflines = *((uint32*) fileData);
+ uint32 idx_size = numOflines * sizeof(TimeWindow);
+ memcpy(_tw, sizeof(numOflines) + fileData, idx_size);
+ _fileData = sizeof(numOflines) + fileData + idx_size;
+ _last = numOflines - 1;
+
+ _currentLine = (char*)_fileData + _tw[0].foffset;
+ _hasSubtitles = true;
+ return _hasSubtitles;
+}
+
+} \ No newline at end of file
diff --git a/engines/toon/subtitles.h b/engines/toon/subtitles.h
new file mode 100644
index 0000000000..7eb7fe12f0
--- /dev/null
+++ b/engines/toon/subtitles.h
@@ -0,0 +1,59 @@
+/* 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.
+ *
+ */
+
+#ifndef TOON_SUBTITLES_H
+#define TOON_SUBTITLES_H
+
+#include "toon/toon.h"
+#include "graphics/surface.h"
+
+namespace Toon {
+
+typedef struct {
+ uint32 fstart;
+ uint32 fend;
+ uint32 foffset;
+} TimeWindow;
+
+class SubtitleRenderer {
+public:
+ SubtitleRenderer(ToonEngine *vm);
+ ~SubtitleRenderer();
+
+ bool load(const Common::String &video);
+ void render(const Graphics::Surface& frame, uint32 frameNumber, char color);
+protected:
+ ToonEngine *_vm;
+ Graphics::Surface* _subSurface;
+ bool _hasSubtitles;
+
+ char* _lines[384];
+ TimeWindow _tw[384];
+ uint8 *_fileData;
+ uint16 _index;
+ uint16 _last;
+ char* _currentLine;
+};
+
+} // End of namespace Toon
+
+#endif \ No newline at end of file
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp
index 46132a4fd2..4d2578ee59 100644
--- a/engines/toon/toon.cpp
+++ b/engines/toon/toon.cpp
@@ -3290,7 +3290,18 @@ void ToonEngine::drawConversationLine() {
if (_currentTextLine && _showConversationText) {
_fontRenderer->setFontColorByCharacter(_currentTextLineCharacterId);
_fontRenderer->setFont(_currentFont);
- _fontRenderer->renderMultiLineText(_currentTextLineX, _currentTextLineY, _currentTextLine, 0);
+ _fontRenderer->renderMultiLineText(_currentTextLineX, _currentTextLineY, _currentTextLine, 0, *_mainSurface);
+ }
+}
+
+void ToonEngine::drawCustomText(int16 x, int16 y, char* line, Graphics::Surface* frame, char color) {
+ if (line) {
+ byte col = color; // 0xce
+ _fontRenderer->setFontColor(0, col, col);
+ //_fontRenderer->setFontColorByCharacter(_currentTextLineCharacterId);
+ _gameState->_currentScrollValue = 0;
+ _fontRenderer->setFont(_currentFont);
+ _fontRenderer->renderMultiLineText(x, y, line, 0, *frame);
}
}
diff --git a/engines/toon/toon.h b/engines/toon/toon.h
index efb473fef8..cbabaff129 100644
--- a/engines/toon/toon.h
+++ b/engines/toon/toon.h
@@ -33,6 +33,7 @@
#include "toon/state.h"
#include "toon/picture.h"
#include "toon/anim.h"
+#include "toon/subtitles.h"
#include "toon/movie.h"
#include "toon/font.h"
#include "toon/text.h"
@@ -212,6 +213,8 @@ public:
void waitForScriptStep();
void doMagnifierEffect();
+ void drawCustomText(int16 x, int16 y, char* line, Graphics::Surface* frame, char color);
+
bool canSaveGameStateCurrently();
bool canLoadGameStateCurrently();
void pauseEngineIntern(bool pause);