aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjohndoe1232018-05-17 05:27:28 +1000
committerEugene Sandulenko2018-07-20 06:43:33 +0000
commit25a303a52967220e8f838b4f185c2fc8f8092f47 (patch)
treef4c55670de542e2baefa5b354a85c0ef573f8a13
parentd5690d60256b163036076e80ce52917dfaca6784 (diff)
downloadscummvm-rg350-25a303a52967220e8f838b4f185c2fc8f8092f47.tar.gz
scummvm-rg350-25a303a52967220e8f838b4f185c2fc8f8092f47.tar.bz2
scummvm-rg350-25a303a52967220e8f838b4f185c2fc8f8092f47.zip
ILLUSIONS: BBDOU: Implement video player
(cherry picked from commit aab0b29)
-rw-r--r--engines/illusions/bbdou/bbdou_videoplayer.cpp109
-rw-r--r--engines/illusions/bbdou/bbdou_videoplayer.h52
-rw-r--r--engines/illusions/bbdou/illusions_bbdou.cpp18
-rw-r--r--engines/illusions/bbdou/illusions_bbdou.h7
-rw-r--r--engines/illusions/bbdou/scriptopcodes_bbdou.cpp7
-rw-r--r--engines/illusions/module.mk1
6 files changed, 191 insertions, 3 deletions
diff --git a/engines/illusions/bbdou/bbdou_videoplayer.cpp b/engines/illusions/bbdou/bbdou_videoplayer.cpp
new file mode 100644
index 0000000000..ba578904f2
--- /dev/null
+++ b/engines/illusions/bbdou/bbdou_videoplayer.cpp
@@ -0,0 +1,109 @@
+/* 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 "illusions/bbdou/illusions_bbdou.h"
+#include "illusions/bbdou/bbdou_videoplayer.h"
+#include "illusions/actor.h"
+#include "illusions/dictionary.h"
+#include "illusions/input.h"
+#include "illusions/screen.h"
+#include "engines/util.h"
+
+namespace Illusions {
+
+// BBDOUVideoPlayer
+
+BBDOUVideoPlayer::BBDOUVideoPlayer(IllusionsEngine_BBDOU *vm)
+ : _vm(vm), _videoDecoder(0), _callingThreadId(0), _objectId(0) {
+}
+
+BBDOUVideoPlayer::~BBDOUVideoPlayer() {
+ delete _videoDecoder;
+}
+
+void BBDOUVideoPlayer::start(uint32 videoId, uint32 objectId, uint32 priority, uint32 callingThreadId) {
+ debug(0, "BBDOUVideoPlayer::play(%08X, %08X, %d, %08X)", videoId, objectId, priority, callingThreadId);
+ notifyCallingThread();
+ _objectId = objectId;
+ _callingThreadId = callingThreadId;
+ Control *videoControl = _vm->_dict->getObjectControl(objectId);
+ videoControl->_flags |= 0x0008;
+ _vm->_input->discardAllEvents();
+ Common::String filename = Common::String::format("%08x.avi", videoId);
+ _videoDecoder = new Video::AVIDecoder();
+ if (!_videoDecoder->loadFile(filename)) {
+ delete _videoDecoder;
+ _videoDecoder = 0;
+ warning("Unable to open video %s", filename.c_str());
+ notifyCallingThread();
+ return;
+ }
+ _videoDecoder->start();
+}
+
+void BBDOUVideoPlayer::stop() {
+ _vm->_input->discardAllEvents();
+ delete _videoDecoder;
+ _videoDecoder = 0;
+ notifyCallingThread();
+ _objectId = 0;
+}
+
+void BBDOUVideoPlayer::update() {
+ if (_vm->_input->pollEvent(kEventAbort) || _videoDecoder->endOfVideo()) {
+ stop();
+ } else if (_videoDecoder->needsUpdate()) {
+ Control *videoControl = _vm->_dict->getObjectControl(_objectId);
+ const Graphics::Surface *frame = _videoDecoder->decodeNextFrame();
+ Graphics::Surface *backSurface = videoControl->_actor->_surface;
+ if (frame->format.bytesPerPixel == g_system->getScreenFormat().bytesPerPixel) {
+ const int width = MIN(frame->w, backSurface->w) * frame->format.bytesPerPixel;
+ const int height = MIN(frame->h, backSurface->h);
+ const byte *src = (const byte*)frame->getPixels();
+ byte *dest = (byte*)backSurface->getPixels();
+ for (int yc = 0; yc < height; ++yc) {
+ memcpy(dest, src, width);
+ src += frame->pitch;
+ dest += backSurface->pitch;
+ }
+ }
+ ActorType *actorType = _vm->_dict->findActorType(videoControl->_actorTypeId);
+ videoControl->_actor->_frameIndex = 1;
+ videoControl->_actor->_surfInfo = actorType->_surfInfo;
+ videoControl->appearActor();
+ videoControl->deactivateObject();
+ videoControl->_actor->_flags &= ~0x2000;
+ }
+}
+
+bool BBDOUVideoPlayer::isPlaying() const {
+ return _videoDecoder != 0;
+}
+
+void BBDOUVideoPlayer::notifyCallingThread() {
+ if (_callingThreadId != 0) {
+ _vm->notifyThreadId(_callingThreadId);
+ _callingThreadId = 0;
+ }
+}
+
+} // End of namespace Illusions
diff --git a/engines/illusions/bbdou/bbdou_videoplayer.h b/engines/illusions/bbdou/bbdou_videoplayer.h
new file mode 100644
index 0000000000..7ad149a5a1
--- /dev/null
+++ b/engines/illusions/bbdou/bbdou_videoplayer.h
@@ -0,0 +1,52 @@
+/* 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 ILLUSIONS_BBDOU_VIDEOPLAYER_H
+#define ILLUSIONS_BBDOU_VIDEOPLAYER_H
+
+#include "illusions/illusions.h"
+#include "video/avi_decoder.h"
+
+namespace Illusions {
+
+class IllusionsEngine_BBDOU;
+
+class BBDOUVideoPlayer {
+public:
+ BBDOUVideoPlayer(IllusionsEngine_BBDOU *vm);
+ ~BBDOUVideoPlayer();
+ void start(uint32 videoId, uint32 objectId, uint32 priority, uint32 callingThreadId);
+ void stop();
+ void update();
+ bool isPlaying() const;
+public:
+ IllusionsEngine_BBDOU *_vm;
+ Video::VideoDecoder *_videoDecoder;
+ uint32 _objectId;
+ int _priority;
+ uint32 _callingThreadId;
+ void notifyCallingThread();
+};
+
+} // End of namespace Illusions
+
+#endif // ILLUSIONS_BBDOU_VIDEOPLAYER_H
diff --git a/engines/illusions/bbdou/illusions_bbdou.cpp b/engines/illusions/bbdou/illusions_bbdou.cpp
index 0c16ad5959..52e41daede 100644
--- a/engines/illusions/bbdou/illusions_bbdou.cpp
+++ b/engines/illusions/bbdou/illusions_bbdou.cpp
@@ -21,6 +21,7 @@
*/
#include "illusions/bbdou/illusions_bbdou.h"
+#include "illusions/bbdou/bbdou_videoplayer.h"
#include "illusions/actor.h"
#include "illusions/camera.h"
#include "illusions/cursor.h"
@@ -166,6 +167,7 @@ Common::Error IllusionsEngine_BBDOU::run() {
_threads = new ThreadList(this);
_updateFunctions = new UpdateFunctions();
_soundMan = new SoundMan(this);
+ _videoPlayer = new BBDOUVideoPlayer(this);
_screen->setColorKey1(0xF81F);
@@ -215,6 +217,7 @@ Common::Error IllusionsEngine_BBDOU::run() {
delete _stack;
delete _scriptOpcodes;
+ delete _videoPlayer;
delete _soundMan;
delete _updateFunctions;
delete _threads;
@@ -279,6 +282,7 @@ void IllusionsEngine_BBDOU::initUpdateFunctions() {
UPDATEFUNCTION(50, 0, updateActors);
UPDATEFUNCTION(60, 0, updateSequences);
UPDATEFUNCTION(70, 0, updateGraphics);
+ UPDATEFUNCTION(70, 0, updateVideoPlayer);
UPDATEFUNCTION(90, 0, updateSprites);
UPDATEFUNCTION(120, 0, updateSoundMan);
}
@@ -314,6 +318,20 @@ uint32 IllusionsEngine_BBDOU::causeTrigger(uint32 sceneId, uint32 verbId, uint32
return causeThreadId;
}
+int IllusionsEngine_BBDOU::updateVideoPlayer(uint flags) {
+ if (_videoPlayer->isPlaying())
+ _videoPlayer->update();
+ return kUFNext;
+}
+
+void IllusionsEngine_BBDOU::playVideo(uint32 videoId, uint32 objectId, uint32 priority, uint32 callingThreadId) {
+ _videoPlayer->start(videoId, objectId, priority, callingThreadId);
+}
+
+bool IllusionsEngine_BBDOU::isVideoPlaying() {
+ return _videoPlayer->isPlaying();
+}
+
void IllusionsEngine_BBDOU::setDefaultTextCoords() {
WidthHeight dimensions;
dimensions._width = 480;
diff --git a/engines/illusions/bbdou/illusions_bbdou.h b/engines/illusions/bbdou/illusions_bbdou.h
index ddbb8278a4..f1843f716f 100644
--- a/engines/illusions/bbdou/illusions_bbdou.h
+++ b/engines/illusions/bbdou/illusions_bbdou.h
@@ -33,6 +33,7 @@ namespace Illusions {
class Dictionary;
class ScriptMan;
class ScriptStack;
+class BBDOUVideoPlayer;
struct ActiveScene {
uint32 _sceneId;
@@ -72,6 +73,8 @@ public:
uint32 _theThreadId;
uint32 _globalSceneId;
+ BBDOUVideoPlayer *_videoPlayer;
+
bool _walkthroughStarted;
void initInput();
@@ -83,6 +86,10 @@ public:
void causeDeclare(uint32 verbId, uint32 objectId2, uint32 objectId, TriggerFunctionCallback *callback);
uint32 causeTrigger(uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId, uint32 callingThreadId);
+ int updateVideoPlayer(uint flags);
+ void playVideo(uint32 videoId, uint32 objectId, uint32 priority, uint32 callingThreadId);
+ bool isVideoPlaying();
+
void setDefaultTextCoords();
void loadSpecialCode(uint32 resId);
diff --git a/engines/illusions/bbdou/scriptopcodes_bbdou.cpp b/engines/illusions/bbdou/scriptopcodes_bbdou.cpp
index e6a3dd6c2c..3a1b2486c4 100644
--- a/engines/illusions/bbdou/scriptopcodes_bbdou.cpp
+++ b/engines/illusions/bbdou/scriptopcodes_bbdou.cpp
@@ -792,11 +792,12 @@ void ScriptOpcodes_BBDOU::opPlayVideo(ScriptThread *scriptThread, OpCall &opCall
ARG_UINT32(objectId);
ARG_UINT32(videoId);
ARG_UINT32(priority);
- // TODO _vm->playVideo(videoId, objectId, value, opCall._threadId);
-
+#if 1 // TODO DEBUG Set to 0 to skip videos
+ _vm->playVideo(videoId, objectId, priority, opCall._threadId);
+#else
//DEBUG Resume calling thread, later done by the video player
_vm->notifyThreadId(opCall._callerThreadId);
-
+#endif
}
void ScriptOpcodes_BBDOU::opStackPop(ScriptThread *scriptThread, OpCall &opCall) {
diff --git a/engines/illusions/module.mk b/engines/illusions/module.mk
index d1272f4417..dc915c3cb1 100644
--- a/engines/illusions/module.mk
+++ b/engines/illusions/module.mk
@@ -9,6 +9,7 @@ MODULE_OBJS := \
bbdou/bbdou_foodctl.o \
bbdou/bbdou_inventory.o \
bbdou/bbdou_specialcode.o \
+ bbdou/bbdou_videoplayer.o \
bbdou/bbdou_triggerfunctions.o \
bbdou/illusions_bbdou.o \
bbdou/scriptopcodes_bbdou.o \