diff options
author | Filippos Karapetis | 2009-01-07 21:19:00 +0000 |
---|---|---|
committer | Filippos Karapetis | 2009-01-07 21:19:00 +0000 |
commit | 2772a7aaf13b83f8bdb5c27bd0b519127950de20 (patch) | |
tree | a451f67fafdf6641b601b281bf9088820f13e63e /graphics/video/video_player.cpp | |
parent | 1395d3ba639ac543dc8f982aafb99781cdb4afbb (diff) | |
download | scummvm-rg350-2772a7aaf13b83f8bdb5c27bd0b519127950de20.tar.gz scummvm-rg350-2772a7aaf13b83f8bdb5c27bd0b519127950de20.tar.bz2 scummvm-rg350-2772a7aaf13b83f8bdb5c27bd0b519127950de20.zip |
Further merging of the SMK and DXA players (the FLIC player is not done yet):
- Added a new class, VideoPlayer(), from which both the SMK and the DXA player inherit. This class provides generic functions and public methods for the inherited video classes. Default implementations have been made for these public methods, and the virtual ones can be overriden in inherited classes
- There is now a default implementation of the function that sets the video palette
- A basic video player for inherited classes has been added with method playVideo(). This is able to play a fullscreen non-interactive video, which can be skipped with events set by the caller. Postprocessing methods, which draw upon each frame (e.g. subtitles) can be done by implementing performPostProcessing()
- The FTA2 movie player now uses the new playVideo() method
- The new video player code is compatible with the old one (i.e. no changes to the existing engine code are necessary), but it's now possible to reduce engine code for video playing considerably
svn-id: r35772
Diffstat (limited to 'graphics/video/video_player.cpp')
-rw-r--r-- | graphics/video/video_player.cpp | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/graphics/video/video_player.cpp b/graphics/video/video_player.cpp new file mode 100644 index 0000000000..5fc2c72fbf --- /dev/null +++ b/graphics/video/video_player.cpp @@ -0,0 +1,216 @@ +/* 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. + * + * $URL$ + * $Id$ + * + */ + +#include "common/archive.h" +#include "common/events.h" +#include "common/system.h" +#include "common/util.h" +#include "common/array.h" +#include "common/endian.h" + +#include "graphics/video/video_player.h" +#include "graphics/surface.h" + +namespace Graphics { + +VideoPlayer::VideoPlayer() : _fileStream(0), _skipVideo(false) { +} + +VideoPlayer::~VideoPlayer() { + closeFile(); +} + +int VideoPlayer::getWidth() { + if (!_fileStream) + return 0; + return _videoInfo.width; +} + +int VideoPlayer::getHeight() { + if (!_fileStream) + return 0; + return _videoInfo.height; +} + +int32 VideoPlayer::getCurFrame() { + if (!_fileStream) + return -1; + return _videoInfo.currentFrame; +} + +int32 VideoPlayer::getFrameCount() { + if (!_fileStream) + return 0; + return _videoInfo.frameCount; +} + +int32 VideoPlayer::getFrameRate() { + if (!_fileStream) + return 0; + return _videoInfo.frameRate; +} + +int32 VideoPlayer::getFrameDelay() { + if (!_fileStream) + return 0; + return _videoInfo.frameDelay; +} + +int32 VideoPlayer::getAudioLag() { + if (!_fileStream) + return 0; + + /* No audio. + Calculate the lag by how much time has gone by since the first frame + and how much time *should* have passed. + */ + int32 audioTime = (g_system->getMillis() - _videoInfo.startTime) * 100; + int32 videoTime = _videoInfo.currentFrame * getFrameDelay(); + + return videoTime - audioTime; +} + +uint32 VideoPlayer::getFrameWaitTime() { + int32 waitTime = (getFrameDelay() + getAudioLag()) / 100; + + if (waitTime < 0) + return 0; + + return waitTime; +} + +bool VideoPlayer::loadFile(const char *fileName) { + return false; +} + +void VideoPlayer::closeFile() { +} + +void VideoPlayer::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) { + uint h = getHeight(); + uint w = getWidth(); + + byte *src = _videoFrameBuffer; + dst += y * pitch + x; + + do { + memcpy(dst, src, w); + dst += pitch; + src += w; + } while (--h); +} + +void VideoPlayer::setPalette(byte *pal) { + for (int i = 0; i < 256; i++) { + _videoPalette[i * 4 + 0] = *pal++; + _videoPalette[i * 4 + 1] = *pal++; + _videoPalette[i * 4 + 2] = *pal++; + _videoPalette[i * 4 + 3] = 0; + } + + g_system->setPalette(_videoPalette, 0, 256); +} + +bool VideoPlayer::decodeNextFrame() { + return false; +} + +void VideoPlayer::performPostProcessing(byte *screen) { +} + +void VideoPlayer::processVideoEvents(Common::List<Common::Event> *stopEvents) { + Common::Event curEvent; + Common::EventManager *eventMan = g_system->getEventManager(); + + // Process events, and skip video if esc is pressed + while (eventMan->pollEvent(curEvent)) { + if (curEvent.type == Common::EVENT_RTL || curEvent.type == Common::EVENT_QUIT) { + _skipVideo = true; + } + + for (Common::List<Common::Event>::const_iterator iter = stopEvents->begin(); iter != stopEvents->end(); iter++) { + if (curEvent.type == iter->type) { + if (iter->type == Common::EVENT_KEYDOWN || iter->type == Common::EVENT_KEYUP) { + if (curEvent.kbd.keycode == iter->kbd.keycode) { + _skipVideo = true; + break; + } + } else { + _skipVideo = true; + break; + } + } + } + } +} + +bool VideoPlayer::playVideo(const char *filename, Common::List<Common::Event> *stopEvents) { + _skipVideo = false; + debug(0, "Playing video %s", filename); + + if (!loadFile(filename)) { + warning("Failed to load video file %s", filename); + return false; + } + + while (getCurFrame() < getFrameCount() && !_skipVideo) { + processVideoEvents(stopEvents); + + uint32 startTime = 0; + decodeNextFrame(); + + Graphics::Surface *screen = g_system->lockScreen(); + copyFrameToBuffer((byte *)screen->pixels, + (g_system->getWidth() - getWidth()) / 2, + (g_system->getHeight() - getHeight()) / 2, + g_system->getWidth()); + performPostProcessing((byte *)screen->pixels); + g_system->unlockScreen(); + + uint32 waitTime = getFrameWaitTime(); + + if (!waitTime) { + warning("dropped frame %i", getCurFrame()); + continue; + } + + // Update the screen + g_system->updateScreen(); + + startTime = g_system->getMillis(); + + // Wait before showing the next frame + while (g_system->getMillis() < startTime + waitTime && !_skipVideo) { + processVideoEvents(stopEvents); + g_system->delayMillis(10); + } + } + + closeFile(); + + return true; +} + +} // End of namespace Graphics |