mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 05:38:56 +00:00
TOON: add support for cutscene subtitles
This commit is contained in:
parent
fd7efe4fb6
commit
83285746b0
@ -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++;
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
97
engines/toon/subtitles.cpp
Normal file
97
engines/toon/subtitles.cpp
Normal file
@ -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;
|
||||
}
|
||||
|
||||
}
|
59
engines/toon/subtitles.h
Normal file
59
engines/toon/subtitles.h
Normal file
@ -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
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user