aboutsummaryrefslogtreecommitdiff
path: root/engines/gob/videoplayer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/gob/videoplayer.cpp')
-rw-r--r--engines/gob/videoplayer.cpp399
1 files changed, 310 insertions, 89 deletions
diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp
index c3cecea318..e088646498 100644
--- a/engines/gob/videoplayer.cpp
+++ b/engines/gob/videoplayer.cpp
@@ -32,29 +32,117 @@
#include "gob/game.h"
#include "gob/palanim.h"
#include "gob/inter.h"
+#include "gob/map.h"
namespace Gob {
const char *VideoPlayer::_extensions[] = { "IMD", "VMD" };
-VideoPlayer::VideoPlayer(GobEngine *vm) : _vm(vm) {
- _curFile[0] = 0;
- _stream = 0;
+VideoPlayer::Video::Video(GobEngine *vm) : _vm(vm), _fileName(0), _stream(0), _video(0) {
+}
+
+VideoPlayer::Video::~Video() {
+ close();
+}
+
+bool VideoPlayer::Video::open(const char *fileName, Type which) {
+ close();
+
+ int16 handle = _vm->_dataIO->openData(fileName);
+
+ if (handle < 0) {
+ warning("Couldn't open video \"%s\": No such file", fileName);
+ return false;
+ }
+
+ _stream = _vm->_dataIO->openAsStream(handle, true);
+
+ if (which == kVideoTypeIMD) {
+ _video = new Imd();
+ } else if (which == kVideoTypeVMD) {
+ _video = new Vmd();
+ } else {
+ warning("Couldn't open video \"%s\": Invalid video Type", fileName);
+ close();
+ return false;
+ }
+
+ if (!_video->load(*_stream)) {
+ warning("While loading video \"%s\"", fileName);
+ close();
+ return false;
+ }
+
+ _fileName = new char[strlen(fileName) + 1];
+ strcpy(_fileName, fileName);
+
+ _defaultX = _video->getX();
+ _defaultY = _video->getY();
+
+ return true;
+}
+
+void VideoPlayer::Video::close() {
+ delete _video;
+ delete _stream;
+ delete[] _fileName;
+
_video = 0;
+ _stream = 0;
+ _fileName = 0;
+ memset(&_state, 0, sizeof(CoktelVideo::State));
+ _defaultX = _defaultY = 0;
+}
+
+bool VideoPlayer::Video::isOpen() const {
+ return (_video != 0);
+}
+
+const char *VideoPlayer::Video::getFileName() const {
+ return _fileName ? _fileName : "";
+}
+
+CoktelVideo *VideoPlayer::Video::getVideo() {
+ return _video;
+}
+
+const CoktelVideo *VideoPlayer::Video::getVideo() const {
+ return _video;
+}
+
+CoktelVideo::State VideoPlayer::Video::getState() const {
+ return _state;
+}
+
+int16 VideoPlayer::Video::getDefaultX() const {
+ return _defaultX;
+}
+
+int16 VideoPlayer::Video::getDefaultY() const {
+ return _defaultY;
+}
+
+CoktelVideo::State VideoPlayer::Video::nextFrame() {
+ if (_video)
+ _state = _video->nextFrame();
+
+ return _state;
+}
+
+VideoPlayer::VideoPlayer(GobEngine *vm) : _vm(vm) {
+ _primaryVideo = new Video(vm);
_backSurf = false;
_needBlit = false;
_noCursorSwitch = false;
}
VideoPlayer::~VideoPlayer() {
- closeVideo();
+ delete _primaryVideo;
+ for (uint i = 0; i < _videoSlots.size(); i++)
+ delete _videoSlots[i];
}
-bool VideoPlayer::openVideo(const char *video, int16 x, int16 y, int16 flags, Type which) {
- char fileName[256];
-
- strncpy0(fileName, video, 250);
-
+bool VideoPlayer::findFile(char *fileName, Type &which) {
char *extStart = strrchr(fileName, '.');
// There's no empty extension
if (extStart == (fileName + strlen(fileName) - 1)) {
@@ -112,33 +200,22 @@ bool VideoPlayer::openVideo(const char *video, int16 x, int16 y, int16 flags, Ty
}
- if (scumm_strnicmp(_curFile, fileName, strlen(fileName))) {
- closeVideo();
+ return true;
+}
- int16 handle = _vm->_dataIO->openData(fileName);
+bool VideoPlayer::primaryOpen(const char *videoFile, int16 x, int16 y,
+ int16 flags, Type which) {
- if (handle < 0) {
- warning("Couldn't open video \"%s\": No such file", fileName);
- return false;
- }
+ char fileName[256];
- _stream = _vm->_dataIO->openAsStream(handle, true);
+ strncpy0(fileName, videoFile, 250);
- if (which == kVideoTypeIMD) {
- _video = new Imd();
- } else if (which == kVideoTypeVMD) {
- _video = new Vmd();
- } else {
- warning("Couldn't open video \"%s\": Invalid video Type", fileName);
- closeVideo();
- return false;
- }
+ if (!findFile(fileName, which))
+ return false;
- if (!_video->load(*_stream)) {
- warning("While loading video \"%s\"", fileName);
- closeVideo();
+ if (scumm_strnicmp(_primaryVideo->getFileName(), fileName, strlen(fileName))) {
+ if (!_primaryVideo->open(fileName, which))
return false;
- }
// WORKAROUND: In some rare cases, the cursor should still be
// displayed while a video is playing.
@@ -153,53 +230,54 @@ bool VideoPlayer::openVideo(const char *video, int16 x, int16 y, int16 flags, Ty
_noCursorSwitch = true;
}
- strcpy(_curFile, fileName);
-
if (!(flags & kFlagNoVideo)) {
_backSurf = ((flags & kFlagFrontSurface) == 0);
SurfaceDesc::Ptr surf = _vm->_draw->_spritesArray[_backSurf ? 21 : 20];
- _video->setVideoMemory(surf->getVidMem(), surf->getWidth(), surf->getHeight());
+ _primaryVideo->getVideo()->setVideoMemory(surf->getVidMem(),
+ surf->getWidth(), surf->getHeight());
} else
- _video->setVideoMemory();
+ _primaryVideo->getVideo()->setVideoMemory();
_needBlit = ((flags & kFlagUseBackSurfaceContent) != 0) && ((flags & kFlagFrontSurface) != 0);
- _video->enableSound(*_vm->_mixer);
+ _primaryVideo->getVideo()->enableSound(*_vm->_mixer);
}
- if (!_video)
+ if (!_primaryVideo->isOpen())
return false;
- _video->setFrameRate(_vm->_util->getFrameRate());
- _video->setXY(x, y);
- WRITE_VAR(7, _video->getFramesCount());
+ _primaryVideo->getVideo()->setFrameRate(_vm->_util->getFrameRate());
+ _primaryVideo->getVideo()->setXY(x, y);
+ WRITE_VAR(7, _primaryVideo->getVideo()->getFramesCount());
return true;
}
-void VideoPlayer::play(int16 startFrame, int16 lastFrame, int16 breakKey,
+void VideoPlayer::primaryPlay(int16 startFrame, int16 lastFrame, int16 breakKey,
uint16 palCmd, int16 palStart, int16 palEnd,
int16 palFrame, int16 endFrame, bool fade, int16 reverseTo) {
- if (!_video)
+ if (!_primaryVideo->isOpen())
return;
+ CoktelVideo &video = *(_primaryVideo->getVideo());
+
breakKey = 27;
if (startFrame < 0)
- startFrame = _video->getCurrentFrame();
+ startFrame = video.getCurrentFrame();
if (lastFrame < 0)
- lastFrame = _video->getFramesCount() - 1;
+ lastFrame = video.getFramesCount() - 1;
if (palFrame < 0)
palFrame = startFrame;
if (endFrame < 0)
endFrame = lastFrame;
palCmd &= 0x3F;
- if (_video->getCurrentFrame() != startFrame) {
- if (_video->getFeatures() & CoktelVideo::kFeaturesSound)
- startFrame = _video->getCurrentFrame();
+ if (video.getCurrentFrame() != startFrame) {
+ if (video.getFeatures() & CoktelVideo::kFeaturesSound)
+ startFrame = video.getCurrentFrame();
else
- _video->seekFrame(startFrame);
+ video.seekFrame(startFrame);
}
_vm->_draw->_showCursor = _noCursorSwitch ? 3 : 0;
@@ -217,36 +295,177 @@ void VideoPlayer::play(int16 startFrame, int16 lastFrame, int16 breakKey,
}
if (!_noCursorSwitch)
- _video->waitEndFrame();
+ video.waitEndFrame();
startFrame++;
}
if (reverseTo >= 0) {
- int16 toFrame = _video->getFramesCount() - reverseTo;
- for (int i = _video->getCurrentFrame(); i >= toFrame; i--) {
- _video->seekFrame(i, SEEK_SET, true);
+ int16 toFrame = video.getFramesCount() - reverseTo;
+ for (int i = video.getCurrentFrame(); i >= toFrame; i--) {
+ video.seekFrame(i, SEEK_SET, true);
if (doPlay(i, breakKey, 0, 0, 0, 0, 0)) {
_vm->_palAnim->fade(0, -2, 0);
memset((char *) _vm->_draw->_vgaPalette, 0, 768);
}
if (!_noCursorSwitch)
- _video->waitEndFrame();
+ video.waitEndFrame();
}
}
}
-int16 VideoPlayer::getFramesCount() const {
- if (!_video)
- return 0;
+void VideoPlayer::primaryClose() {
+ _primaryVideo->close();
+}
+
+int VideoPlayer::slotOpen(const char *videoFile, Type which) {
+ Video *video = new Video(_vm);
+ char fileName[256];
+
+ strncpy0(fileName, videoFile, 250);
+
+ if (!findFile(fileName, which)) {
+ delete video;
+ return -1;
+ }
+
+ if (!video->open(fileName, which)) {
+ delete video;
+ return -1;
+ }
+
+ video->getVideo()->setVideoMemory();
+ video->getVideo()->disableSound();
+
+ _videoSlots.push_back(video);
- return _video->getFramesCount();
+ WRITE_VAR(7, video->getVideo()->getFramesCount());
+
+ return _videoSlots.size() - 1;
+}
+
+void VideoPlayer::slotPlay(int slot, int16 frame) {
+ if ((slot < 0) || (((uint) slot) >= _videoSlots.size()))
+ return;
+
+ CoktelVideo &video = *(_videoSlots[slot]->getVideo());
+
+ if (frame < 0)
+ frame = video.getCurrentFrame();
+
+ if (frame >= video.getFramesCount())
+ return;
+
+ if (video.getCurrentFrame() != frame)
+ video.seekFrame(frame);
+
+ _videoSlots[slot]->nextFrame();
+ WRITE_VAR(11, frame);
+}
+
+void VideoPlayer::slotClose(int slot) {
+ if ((slot < 0) || (((uint) slot) >= _videoSlots.size()))
+ return;
+
+ delete _videoSlots[slot];
+ _videoSlots.remove_at(slot);
+}
+
+void VideoPlayer::slotCopyFrame(int slot, byte *dest,
+ uint16 left, uint16 top, uint16 width, uint16 height,
+ uint16 x, uint16 y, uint16 pitch, int16 transp) {
+
+ if ((slot < 0) || (((uint) slot) >= _videoSlots.size()))
+ return;
+
+ _videoSlots[slot]->getVideo()->copyCurrentFrame(dest,
+ left, top, width, height, x, y, pitch, transp);
+}
+
+void VideoPlayer::slotCopyPalette(int slot, int16 palStart, int16 palEnd) {
+ if ((slot < 0) || (((uint) slot) >= _videoSlots.size()))
+ return;
+
+ copyPalette(*(_videoSlots[slot]->getVideo()), palStart, palEnd);
+}
+
+bool VideoPlayer::slotIsOpen(int slot) const {
+ if ((slot >= 0) && (((uint) slot) < _videoSlots.size()))
+ return true;
+
+ return false;
}
-int16 VideoPlayer::getCurrentFrame() const {
- if (!_video)
- return 0;
+const VideoPlayer::Video *VideoPlayer::getVideoBySlot(int slot) const {
+ if (slot < 0) {
+ if (_primaryVideo->isOpen())
+ return _primaryVideo;
+ } else if (((uint) slot) < _videoSlots.size())
+ return _videoSlots[slot];
- return _video->getCurrentFrame();
+ return 0;
+}
+
+uint16 VideoPlayer::getFlags(int slot) const {
+ const Video *video = getVideoBySlot(slot);
+
+ if (video)
+ return video->getVideo()->getFlags();
+
+ return 0;
+}
+
+int16 VideoPlayer::getFramesCount(int slot) const {
+ const Video *video = getVideoBySlot(slot);
+
+ if (video)
+ return video->getVideo()->getFramesCount();
+
+ return 0;
+}
+
+int16 VideoPlayer::getCurrentFrame(int slot) const {
+ const Video *video = getVideoBySlot(slot);
+
+ if (video)
+ return video->getVideo()->getCurrentFrame();
+
+ return 0;
+}
+
+int16 VideoPlayer::getWidth(int slot) const {
+ const Video *video = getVideoBySlot(slot);
+
+ if (video)
+ return video->getVideo()->getWidth();
+
+ return 0;
+}
+
+int16 VideoPlayer::getHeight(int slot) const {
+ const Video *video = getVideoBySlot(slot);
+
+ if (video)
+ return video->getVideo()->getHeight();
+
+ return 0;
+}
+
+int16 VideoPlayer::getDefaultX(int slot) const {
+ const Video *video = getVideoBySlot(slot);
+
+ if (video)
+ return video->getDefaultX();
+
+ return 0;
+}
+
+int16 VideoPlayer::getDefaultY(int slot) const {
+ const Video *video = getVideoBySlot(slot);
+
+ if (video)
+ return video->getDefaultY();
+
+ return 0;
}
bool VideoPlayer::doPlay(int16 frame, int16 breakKey,
@@ -260,7 +479,7 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey,
_vm->_draw->_applyPal = true;
if (palCmd >= 4)
- copyPalette(palStart, palEnd);
+ copyPalette(*(_primaryVideo->getVideo()), palStart, palEnd);
}
if (modifiedPal && (palCmd == 8) && !_backSurf)
@@ -270,7 +489,7 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey,
if (_needBlit)
_vm->_draw->forceBlit();
- CoktelVideo::State state = _video->nextFrame();
+ CoktelVideo::State state = _primaryVideo->nextFrame();
WRITE_VAR(11, frame);
if (_needBlit)
@@ -285,7 +504,7 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey,
}
if (state.flags & CoktelVideo::kStatePalette) {
- copyPalette(palStart, palEnd);
+ copyPalette(*(_primaryVideo->getVideo()), palStart, palEnd);
if (!_backSurf)
_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
@@ -311,7 +530,7 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey,
_vm->_util->processInput();
if (_vm->_quitRequested) {
- _video->disableSound();
+ _primaryVideo->getVideo()->disableSound();
return true;
}
@@ -321,7 +540,7 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey,
_vm->_inter->storeKey(_vm->_util->checkKey());
if (VAR(0) == (unsigned) breakKey) {
- _video->disableSound();
+ _primaryVideo->getVideo()->disableSound();
return true;
}
}
@@ -329,26 +548,37 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey,
return false;
}
-void VideoPlayer::copyPalette(int16 palStart, int16 palEnd) {
- if ((palStart == -1) || (palEnd == -1))
- memcpy((char *) _vm->_global->_pPaletteDesc->vgaPal,
- _video->getPalette(), 768);
- else
- memcpy(((char *) (_vm->_global->_pPaletteDesc->vgaPal)) +
- palStart * 3, _video->getPalette() + palStart * 3,
+void VideoPlayer::copyPalette(CoktelVideo &video, int16 palStart, int16 palEnd) {
+ if ((palStart != -1) && (palEnd != -1))
+ memcpy(((char *) (_vm->_global->_pPaletteDesc->vgaPal)) + palStart * 3,
+ video.getPalette() + palStart * 3,
(palEnd - palStart + 1) * 3);
+ else
+ memcpy((char *) _vm->_global->_pPaletteDesc->vgaPal, video.getPalette(), 768);
}
-void VideoPlayer::writeVideoInfo(const char *video, int16 varX, int16 varY,
+void VideoPlayer::writeVideoInfo(const char *videoFile, int16 varX, int16 varY,
int16 varFrames, int16 varWidth, int16 varHeight) {
- if (openVideo(video)) {
- WRITE_VAR_OFFSET(varX, _video->getX());
- WRITE_VAR_OFFSET(varY, _video->getY());
- WRITE_VAR_OFFSET(varFrames, _video->getFramesCount());
- WRITE_VAR_OFFSET(varWidth, _video->getWidth());
- WRITE_VAR_OFFSET(varHeight, _video->getHeight());
- closeVideo();
+ if (primaryOpen(videoFile)) {
+ int16 x, y, width, height;
+
+ if ((VAR_OFFSET(varX) != 0xFFFFFFFF) ||
+ !_primaryVideo->getVideo()->getAnchor(1, 2, x, y, width, height)) {
+
+ x = _primaryVideo->getVideo()->getX();
+ y = _primaryVideo->getVideo()->getY();
+ width = _primaryVideo->getVideo()->getWidth();
+ height = _primaryVideo->getVideo()->getHeight();
+ }
+
+ WRITE_VAR_OFFSET(varX, x);
+ WRITE_VAR_OFFSET(varY, y);
+ WRITE_VAR_OFFSET(varFrames, _primaryVideo->getVideo()->getFramesCount());
+ WRITE_VAR_OFFSET(varWidth, width);
+ WRITE_VAR_OFFSET(varHeight, height);
+
+ primaryClose();
} else {
WRITE_VAR_OFFSET(varX, -1);
WRITE_VAR_OFFSET(varY, -1);
@@ -358,13 +588,4 @@ void VideoPlayer::writeVideoInfo(const char *video, int16 varX, int16 varY,
}
}
-void VideoPlayer::closeVideo() {
- delete _video;
- delete _stream;
-
- _video = 0;
- _stream = 0;
- *_curFile = 0;
-}
-
} // End of namespace Gob