Initial commit
This commit is contained in:
139
engines/agds/mjpgPlayer.cpp
Normal file
139
engines/agds/mjpgPlayer.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "agds/mjpgPlayer.h"
|
||||
#include "agds/agds.h"
|
||||
#include "agds/font.h"
|
||||
#include "agds/object.h"
|
||||
#include "agds/systemVariable.h"
|
||||
#include "common/debug.h"
|
||||
|
||||
namespace AGDS {
|
||||
|
||||
MJPGPlayer::MJPGPlayer(Common::SeekableReadStream *stream, const Common::String &subtitles) : _stream(stream), _firstFramePos(_stream->pos()), _framesPlayed(0), _nextSubtitleIndex(0) {
|
||||
uint pos = 0;
|
||||
while (pos < subtitles.size()) {
|
||||
auto next = subtitles.find('\n', pos);
|
||||
if (next == subtitles.npos)
|
||||
next = subtitles.size();
|
||||
Common::String line = subtitles.substr(pos, next - pos);
|
||||
|
||||
uint begin, end;
|
||||
int offset;
|
||||
if (sscanf(line.c_str(), "{%u}{%u}%n", &begin, &end, &offset) != 2) {
|
||||
warning("malformed subtitle line: %s", line.c_str());
|
||||
pos = next + 1;
|
||||
continue;
|
||||
}
|
||||
while (offset < static_cast<int>(line.size()) && line[offset] == ' ')
|
||||
++offset;
|
||||
|
||||
line = line.substr(offset);
|
||||
debug("subtitle line: %d-%d: %s", begin, end, line.c_str());
|
||||
Text::Lines lines;
|
||||
{
|
||||
uint lineBegin = 0;
|
||||
while (lineBegin < line.size()) {
|
||||
uint lineEnd = line.find('|', lineBegin);
|
||||
if (lineEnd == line.npos)
|
||||
lineEnd = line.size();
|
||||
lines.push_back(line.substr(lineBegin, lineEnd - lineBegin));
|
||||
lineBegin = lineEnd + 1;
|
||||
}
|
||||
}
|
||||
_subtitles.push_back({begin, end, lines});
|
||||
pos = next + 1;
|
||||
}
|
||||
}
|
||||
|
||||
MJPGPlayer::~MJPGPlayer() {}
|
||||
|
||||
void MJPGPlayer::rewind() {
|
||||
_framesPlayed = 0;
|
||||
_nextSubtitleIndex = 0;
|
||||
_stream->seek(_firstFramePos);
|
||||
}
|
||||
|
||||
const Graphics::Surface *MJPGPlayer::decodeFrame() {
|
||||
if (_stream->eos())
|
||||
return NULL;
|
||||
|
||||
uint32 size = _stream->readSint32LE();
|
||||
if (size == 0)
|
||||
return NULL;
|
||||
|
||||
if (_stream->eos())
|
||||
return NULL;
|
||||
Common::ScopedPtr<Common::SeekableReadStream> stream(_stream->readStream(size));
|
||||
const Graphics::Surface *surface = _decoder.decodeFrame(*stream);
|
||||
++_framesPlayed;
|
||||
return surface;
|
||||
}
|
||||
|
||||
void MJPGPlayer::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
|
||||
auto *surface = decodeFrame();
|
||||
if (surface) {
|
||||
Common::ScopedPtr<Graphics::Surface> scaled;
|
||||
{
|
||||
Common::ScopedPtr<Graphics::Surface> converted(surface->convertTo(engine.pixelFormat()));
|
||||
auto scaleW = 1.0f * backbuffer.w / converted->w;
|
||||
auto scaleH = 1.0f * backbuffer.h / converted->h;
|
||||
auto scale = MIN(scaleW, scaleH);
|
||||
|
||||
scaled.reset(converted->scale(converted->w * scale, converted->h * scale));
|
||||
converted->free();
|
||||
}
|
||||
|
||||
Common::Point dst((backbuffer.w - scaled->w) / 2, (backbuffer.h - scaled->h) / 2);
|
||||
Common::Rect srcRect(scaled->getRect());
|
||||
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
|
||||
backbuffer.copyRectToSurface(*scaled, dst.x, dst.y, srcRect);
|
||||
scaled->free();
|
||||
}
|
||||
|
||||
if (_subtitles.empty())
|
||||
return;
|
||||
|
||||
while (_nextSubtitleIndex < _subtitles.size() && _framesPlayed > _subtitles[_nextSubtitleIndex].end)
|
||||
++_nextSubtitleIndex;
|
||||
|
||||
if (_nextSubtitleIndex >= _subtitles.size() || _framesPlayed < _subtitles[_nextSubtitleIndex].begin)
|
||||
return;
|
||||
|
||||
auto font = engine.getFont(engine.getSystemVariable("tell_font")->getInteger());
|
||||
int baseX = engine.getSystemVariable("subtitle_x")->getInteger();
|
||||
int baseY = engine.getSystemVariable("subtitle_y")->getInteger();
|
||||
int maxWidth = engine.getSystemVariable("subtitle_width")->getInteger();
|
||||
|
||||
auto &lines = _subtitles[_nextSubtitleIndex].lines;
|
||||
for (auto &line : lines) {
|
||||
Text::Lines sublines;
|
||||
font->wordWrapText(line, maxWidth, sublines);
|
||||
for (auto &subline : sublines) {
|
||||
int w = font->getStringWidth(subline);
|
||||
int x = baseX - w / 2;
|
||||
font->drawString(&backbuffer, subline, x, baseY, backbuffer.w - x, 0);
|
||||
baseY += font->getFontHeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace AGDS
|
||||
Reference in New Issue
Block a user