aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2016-07-09 11:32:15 -0400
committerPaul Gilbert2016-07-15 19:27:33 -0400
commitcc9bf88ed56a4c5fbb14c05d30395b1688f5ebe7 (patch)
tree7a3a9a9fb8f0ce6fa15ab71a12c1144893c45811
parent341cf1866168a8e270ed08b38cd43aa83387ea5a (diff)
downloadscummvm-rg350-cc9bf88ed56a4c5fbb14c05d30395b1688f5ebe7.tar.gz
scummvm-rg350-cc9bf88ed56a4c5fbb14c05d30395b1688f5ebe7.tar.bz2
scummvm-rg350-cc9bf88ed56a4c5fbb14c05d30395b1688f5ebe7.zip
TITANIC: Major implementation of OSMovie and AVISurface classes
-rw-r--r--engines/titanic/core/game_object.cpp112
-rw-r--r--engines/titanic/core/game_object.h30
-rw-r--r--engines/titanic/events.cpp23
-rw-r--r--engines/titanic/events.h7
-rw-r--r--engines/titanic/game/computer.cpp2
-rw-r--r--engines/titanic/game_manager.cpp68
-rw-r--r--engines/titanic/messages/messages.h4
-rw-r--r--engines/titanic/sound/sound_manager.cpp4
-rw-r--r--engines/titanic/sound/sound_manager.h15
-rw-r--r--engines/titanic/support/avi_surface.cpp185
-rw-r--r--engines/titanic/support/avi_surface.h110
-rw-r--r--engines/titanic/support/mouse_cursor.cpp12
-rw-r--r--engines/titanic/support/mouse_cursor.h2
-rw-r--r--engines/titanic/support/movie.cpp245
-rw-r--r--engines/titanic/support/movie.h132
-rw-r--r--engines/titanic/support/movie_event.cpp33
-rw-r--r--engines/titanic/support/movie_event.h18
-rw-r--r--engines/titanic/support/movie_range_info.cpp42
-rw-r--r--engines/titanic/support/movie_range_info.h20
-rw-r--r--engines/titanic/support/video_surface.cpp23
-rw-r--r--engines/titanic/support/video_surface.h58
21 files changed, 759 insertions, 386 deletions
diff --git a/engines/titanic/core/game_object.cpp b/engines/titanic/core/game_object.cpp
index dcc66f569d..78b91c3375 100644
--- a/engines/titanic/core/game_object.cpp
+++ b/engines/titanic/core/game_object.cpp
@@ -85,12 +85,14 @@ void CGameObject::save(SimpleFile *file, int indent) {
_movieRangeInfoList.destroyContents();
if (_surface) {
- Common::List<CMovieRangeInfo *> rangeList = _surface->getMovieRangeInfo();
+ const CMovieRangeInfoList *rangeList = _surface->getMovieRangeInfo();
- for (Common::List<CMovieRangeInfo *>::const_iterator i = rangeList.begin();
- i != rangeList.end(); ++i) {
- CMovieRangeInfo *rangeInfo = new CMovieRangeInfo(*i);
- rangeInfo->_frameNumber = (i == rangeList.begin()) ? getMovieFrame() : -1;
+ if (rangeList) {
+ for (CMovieRangeInfoList::const_iterator i = rangeList->begin();
+ i != rangeList->end(); ++i) {
+ CMovieRangeInfo *rangeInfo = new CMovieRangeInfo(*i);
+ rangeInfo->_initialFrame = (i == rangeList->begin()) ? getMovieFrame() : -1;
+ }
}
}
@@ -403,21 +405,6 @@ void CGameObject::loadFrame(int frameNumber) {
makeDirty();
}
-void CGameObject::playMovie(int v1, int v2) {
- if (_surface && !_resource.empty()) {
- loadResource(_resource);
- _resource.clear();
- }
-
- if (_surface && _surface->loadIfReady()) {
- if (_surface->_movie) {
- disableMouse();
- _surface->_movie->play(_bounds, v1, v2);
- enableMouse();
- }
- }
-}
-
void CGameObject::processMoveRangeInfo() {
for (CMovieRangeInfoList::iterator i = _movieRangeInfoList.begin(); i != _movieRangeInfoList.end(); ++i)
(*i)->process(this);
@@ -518,23 +505,53 @@ void CGameObject::petSetRemoteTarget() {
pet->setRemoteTarget(this);
}
-void CGameObject::playMovie(uint startFrame, uint endFrame, uint flags) {
+void CGameObject::playMovie(uint flags) {
_frameNumber = -1;
+
+ if (_surface && !_resource.empty()) {
+ loadResource(_resource);
+ _resource.clear();
+ }
+
+ CGameObject *obj = (flags & MOVIE_NO_OBJECT) ? nullptr : this;
+ if (_surface) {
+ _surface->playMovie(flags, obj);
+ if (flags & MOVIE_GAMESTATE)
+ getGameManager()->_gameState.addMovie(_surface->_movie);
+ }
+}
+
+void CGameObject::playMovie(int startFrame, int endFrame, uint flags) {
+ _frameNumber = -1;
+
if (!_surface) {
if (!_resource.empty())
loadResource(_resource);
_resource.clear();
}
+ CGameObject *obj = (flags & MOVIE_NO_OBJECT) ? nullptr : this;
if (_surface) {
- // TODO: Figure out where to do this legitimately
- OSMovie *movie = static_cast<OSMovie *>(_surface->_movie);
- if (movie)
- movie->_gameObject = this;
+ _surface->playMovie(startFrame, endFrame, flags, obj);
+ if (flags & MOVIE_GAMESTATE)
+ getGameManager()->_gameState.addMovie(_surface->_movie);
+ }
+}
+
- _surface->playMovie(startFrame, endFrame, flags, flags != 0);
+void CGameObject::playMovie(int startFrame, int endFrame, int initialFrame, uint flags) {
+ _frameNumber = -1;
- if (flags & 0x10)
+ if (!_surface) {
+ if (!_resource.empty())
+ loadResource(_resource);
+ _resource.clear();
+ }
+
+ CGameObject *obj = (flags & MOVIE_NO_OBJECT) ? nullptr : this;
+ if (_surface) {
+ _surface->playMovie(startFrame, endFrame, initialFrame, flags, obj);
+ if (flags & MOVIE_GAMESTATE)
getGameManager()->_gameState.addMovie(_surface->_movie);
}
}
@@ -565,28 +582,6 @@ void CGameObject::playRandomClip(const char **names, uint flags) {
playClip(name, flags);
}
-void CGameObject::playMovie(uint flags) {
- _frameNumber = -1;
- if (!_surface && !_resource.empty()) {
- loadResource(_resource);
- _resource.clear();
- }
-
- CVideoSurface *surface = (flags & 4) ? _surface : nullptr;
- if (_surface) {
- _surface->playMovie(flags, surface);
-
- // TODO: Figure out where to do this legitimately
- OSMovie *movie = static_cast<OSMovie *>(_surface->_movie);
- if (movie)
- movie->_gameObject = this;
-
- if (flags & 0x10) {
- getGameManager()->_gameState.addMovie(_surface->_movie);
- }
- }
-}
-
void CGameObject::savePosition() {
_savedPos = _bounds;
}
@@ -1109,17 +1104,6 @@ bool CGameObject::clipExistsByEnd(const CString &name, int endFrame) const {
return _movieClips.existsByEnd(name, endFrame);
}
-void CGameObject::checkPlayMovie(int fieldC, int field10, int frameNumber, int flags) {
- if (!_surface && !_resource.empty())
- loadResource(_resource);
-
- if (_surface ) {
- _surface->proc35(fieldC, field10, frameNumber, flags, (flags & CLIPFLAG_4) ? this : nullptr);
- if (flags & CLIPFLAG_PLAY)
- getGameManager()->_gameState.addMovie(_surface->_movie);
- }
-}
-
void CGameObject::petClear() const {
CPetControl *petControl = getPetControl();
if (petControl)
@@ -1235,14 +1219,14 @@ void CGameObject::setMovie14(int v) {
_surface->_movie->_field14 = v;
}
-void CGameObject::surface38(int v1, int v2) {
+void CGameObject::movieEvent(int frameNumber) {
if (_surface)
- _surface->proc38(v1, v2);
+ _surface->addMovieEvent(frameNumber, this);
}
-void CGameObject::surface38(int v1) {
+void CGameObject::movieEvent() {
if (_surface)
- _surface->proc38(-1, v1);
+ _surface->addMovieEvent(-1, this);
}
int CGameObject::getClipDuration(const CString &name, int frameRate) const {
diff --git a/engines/titanic/core/game_object.h b/engines/titanic/core/game_object.h
index 20059539d9..58ae4c6123 100644
--- a/engines/titanic/core/game_object.h
+++ b/engines/titanic/core/game_object.h
@@ -294,11 +294,6 @@ protected:
Point getControid() const;
/**
- * Plays a movie
- */
- void playMovie(int v1, int v2);
-
- /**
* Play an arbitrary clip
*/
void playClip(const CString &name, uint flags);
@@ -561,11 +556,6 @@ public:
virtual bool isPet() const;
/**
- * Play the movie specified in _resource
- */
- void playMovie(uint startFrame, uint endFrame, uint flags);
-
- /**
* Checks the passed point is validly in the object,
* with extra checking of object flags status
*/
@@ -582,9 +572,14 @@ public:
void playMovie(uint flags);
/**
- * Checks and plays a pending clip
+ * Play the movie specified in _resource
+ */
+ void playMovie(int startFrame, int endFrame, uint flags);
+
+ /**
+ * Play the movie specified in _resource
*/
- void checkPlayMovie(int fieldC, int field10, int frameNumber, int flags);
+ void playMovie(int startFrame, int endFrame, int initialFrame, uint flags);
/**
* Returns true if the object has a currently active movie
@@ -842,9 +837,16 @@ public:
/*--- CVideoSurface Methods ---*/
- void surface38(int v1, int v2);
+ /**
+ * Signal a movie event for the given frame
+ */
+ void movieEvent(int frameNumber);
- void surface38(int v1);
+ /**
+ * Signal a movie event at the end of all currently
+ * playing ranges
+ */
+ void movieEvent();
};
} // End of namespace Titanic
diff --git a/engines/titanic/events.cpp b/engines/titanic/events.cpp
index 590107336c..ff425abcde 100644
--- a/engines/titanic/events.cpp
+++ b/engines/titanic/events.cpp
@@ -235,4 +235,27 @@ void Events::sleep(uint time) {
}
}
+bool Events::waitForPress(uint expiry) {
+ uint32 delayEnd = g_system->getMillis() + expiry;
+
+ while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd) {
+ g_system->delayMillis(10);
+ checkForNextFrameCounter();
+
+ Common::Event event;
+ if (g_system->getEventManager()->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_LBUTTONDOWN:
+ case Common::EVENT_MBUTTONDOWN:
+ case Common::EVENT_KEYDOWN:
+ return true;
+ default:
+ break;
+ }
+ }
+ }
+
+ return false;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/events.h b/engines/titanic/events.h
index 4638056e8c..ab3d755535 100644
--- a/engines/titanic/events.h
+++ b/engines/titanic/events.h
@@ -104,12 +104,17 @@ public:
*/
bool isSpecialPressed(SpecialButtons btn) const { return _specialButtons; }
+ uint getSpecialButtons() const { return _specialButtons; }
+
/**
* Sleep for a specified period of time
*/
void sleep(uint time);
- uint getSpecialButtons() const { return _specialButtons; }
+ /**
+ * Wait for a mouse or keypress
+ */
+ bool waitForPress(uint expiry);
};
} // End of namespace Titanic
diff --git a/engines/titanic/game/computer.cpp b/engines/titanic/game/computer.cpp
index e3f9430f3e..90574997b1 100644
--- a/engines/titanic/game/computer.cpp
+++ b/engines/titanic/game/computer.cpp
@@ -91,7 +91,7 @@ bool CComputer::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
}
bool CComputer::MovieEndMsg(CMovieEndMsg *msg) {
- if (msg->_value2 == 90) {
+ if (msg->_endFrame == 90) {
playSound("a#32.wav", 100, 0, 0);
playSound("a#33.wav", 100, 0, 0);
playSound("a#31.wav", 100, 0, 0);
diff --git a/engines/titanic/game_manager.cpp b/engines/titanic/game_manager.cpp
index 7e8531fe68..84306b42e3 100644
--- a/engines/titanic/game_manager.cpp
+++ b/engines/titanic/game_manager.cpp
@@ -192,36 +192,48 @@ void CGameManager::update() {
}
void CGameManager::updateMovies() {
- // TODO: Make this more like the original, if I can figuring out
- // what's it doing with temporary lists and the OSMovie methods
- for (CMovieList::iterator i = CMovie::_activeMovies->begin();
- i != CMovie::_activeMovies->end(); ) {
- OSMovie *movie = static_cast<OSMovie *>(*i);
- assert(movie && movie->_gameObject);
-
- movie->update();
- switch (movie->getState()) {
- case MOVIE_FINISHED: {
- CMovieEndMsg endMsg;
- endMsg.execute(movie->_gameObject);
-
- i = CMovie::_activeMovies->erase(i);
- delete movie;
- continue;
- }
-
- case MOVIE_FRAME: {
- CMovieFrameMsg frameMsg;
- frameMsg.execute(movie->_gameObject);
+ bool repeatFlag;
+ do {
+ repeatFlag = false;
+
+ for (CMovieList::iterator i = CMovie::_playingMovies->begin();
+ i != CMovie::_playingMovies->end(); ) {
+ CMovie *movie = *i;
+ if (movie->_state)
+ continue;
+
+ CMovieEventList eventsList;
+ if (!movie->handleEvents(eventsList))
+ movie->removeFromPlayingMovies();
+
+ while (!eventsList.empty()) {
+ CMovieEvent *movieEvent = eventsList.front();
+
+ switch (movieEvent->_type) {
+ case MET_MOVIE_END: {
+ CMovieEndMsg endMsg(movieEvent->_startFrame, movieEvent->_endFrame);
+ endMsg.execute(movieEvent->_gameObject);
+ break;
+ }
+
+ case MET_FRAME: {
+ CMovieFrameMsg frameMsg(movieEvent->_initialFrame, 0);
+ frameMsg.execute(movieEvent->_gameObject);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ eventsList.remove(movieEvent);
+ }
+
+ repeatFlag = true;
+ movie->_state = MSTATE_1;
break;
}
-
- default:
- break;
- }
-
- ++i;
- }
+ } while (repeatFlag);
}
void CGameManager::updateDiskTicksCount() {
diff --git a/engines/titanic/messages/messages.h b/engines/titanic/messages/messages.h
index 278fac1fbd..de5d0bdcc0 100644
--- a/engines/titanic/messages/messages.h
+++ b/engines/titanic/messages/messages.h
@@ -264,8 +264,8 @@ MESSAGE0(CMaitreDDefeatedMsg);
MESSAGE0(CMaitreDHappyMsg);
MESSAGE1(CMissiveOMatActionMsg, int, value, 0);
MESSAGE0(CMoveToStartPosMsg);
-MESSAGE2(CMovieEndMsg, int, value1, 0, int, value2, 0);
-MESSAGE2(CMovieFrameMsg, int, value1, 0, int, value2, 0);
+MESSAGE2(CMovieEndMsg, int, startFrame, 0, int, endFrame, 0);
+MESSAGE2(CMovieFrameMsg, int, frameNumber, 0, int, value2, 0);
MESSAGE0(CMusicHasStartedMsg);
MESSAGE0(CMusicHasStoppedMsg);
MESSAGE0(CMusicSettingChangedMsg);
diff --git a/engines/titanic/sound/sound_manager.cpp b/engines/titanic/sound/sound_manager.cpp
index 05a924f352..440d74ade5 100644
--- a/engines/titanic/sound/sound_manager.cpp
+++ b/engines/titanic/sound/sound_manager.cpp
@@ -100,8 +100,8 @@ void QSoundManager::WaveMixPump() {
warning("TODO");
}
-int QSoundManager::proc18() const {
- warning("TODO");
+bool QSoundManager::movieStarted() const {
+ // TODO
return 0;
}
diff --git a/engines/titanic/sound/sound_manager.h b/engines/titanic/sound/sound_manager.h
index ac4ac1ef9f..942124e796 100644
--- a/engines/titanic/sound/sound_manager.h
+++ b/engines/titanic/sound/sound_manager.h
@@ -59,7 +59,12 @@ public:
virtual bool isActive(int handle) const { return false; }
virtual int proc16() const { return 0; }
virtual void WaveMixPump() {}
- virtual int proc18() const { return 0; }
+
+ /**
+ * Called when a movie with audio is started
+ */
+ virtual bool movieStarted() const { return false; }
+
virtual void setMusicPercent(double percent) { _musicPercent = percent; }
virtual void setSpeechPercent(double percent) { _speechPercent = percent; }
virtual void setMasterPercent(double percent) { _masterPercent = percent; }
@@ -128,7 +133,13 @@ public:
virtual bool isActive(int handle) const;
virtual int proc16();
virtual void WaveMixPump();
- virtual int proc18() const;
+
+
+ /**
+ * Called when a movie with audio is started
+ */
+ virtual bool movieStarted() const;
+
virtual void proc19(int v);
virtual void proc20(int v);
virtual void proc21(int v);
diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp
index f6f63a7f1d..47127fe83b 100644
--- a/engines/titanic/support/avi_surface.cpp
+++ b/engines/titanic/support/avi_surface.cpp
@@ -21,12 +21,197 @@
*/
#include "titanic/support/avi_surface.h"
+#include "titanic/support/video_surface.h"
#include "video/avi_decoder.h"
namespace Titanic {
AVISurface::AVISurface(const CResourceKey &key) {
+
// TODO
+/*
+Video::AVIDecoder *decoder = new Video::AVIDecoder();
+decoder->ignoreSecondaryVideoTracks();
+_video = decoder;
+_field14 = 1;
+
+if (!_video->loadFile(name.getString()))
+error("Could not open video - %s", name.getString().c_str());
+*/
+}
+
+AVISurface::~AVISurface() {
+ if (_videoSurface)
+ _videoSurface->_blitStyleFlag = false;
+ delete _frameInfo;
+}
+
+bool AVISurface::play(uint flags, CGameObject *obj) {
+ if (flags & MOVIE_REVERSE)
+ return play(_decoder->getFrameCount() - 1, 0, flags, obj);
+ else
+ return play(0, _decoder->getFrameCount() - 1, flags, obj);
+}
+
+bool AVISurface::play(int startFrame, int endFrame, uint flags, CGameObject *obj) {
+ if (flags & MOVIE_STOP_PREVIOUS)
+ stop();
+
+ return play(startFrame, endFrame, -1, flags, obj);
+}
+
+bool AVISurface::play(int startFrame, int endFrame, int initialFrame, uint flags, CGameObject *obj) {
+ CMovieRangeInfo *info = new CMovieRangeInfo();
+ info->_startFrame = startFrame;
+ info->_endFrame = endFrame;
+ info->_isReversed = endFrame < startFrame;
+ info->_isFlag1 = flags & MOVIE_1;
+
+ if (obj) {
+ CMovieEvent *me = new CMovieEvent();
+ me->_type = MET_MOVIE_END;
+ me->_startFrame = startFrame;
+ me->_endFrame = endFrame;
+ me->_initialFrame = 0;
+ me->_gameObject = obj;
+
+ info->addEvent(me);
+ }
+
+ _movieRangeInfo.push_back(info);
+
+ if (_movieRangeInfo.size() == 1) {
+ changeFrame(initialFrame);
+ } else {
+ return true;
+ }
+}
+
+void AVISurface::stop() {
+ _isPlaying = false;
+ _decoder->stop();
+ _movieRangeInfo.destroyContents();
+}
+
+bool AVISurface::changeFrame(int frameNumber) {
+ if (_isPlaying)
+ return false;
+
+ if (frameNumber == -1)
+ // Default to starting frame of first movie range
+ frameNumber = _movieRangeInfo.front()->_startFrame;
+
+ seekToFrame(frameNumber);
+ renderFrame();
+
+ _isPlaying = true;
+ return true;
+}
+
+void AVISurface::seekToFrame(uint frameNumber) {
+ _decoder->seekToFrame(frameNumber);
+ _priorFrame = frameNumber;
+}
+
+bool AVISurface::handleEvents(CMovieEventList &events) {
+ if (!_isPlaying)
+ return true;
+
+ CMovieRangeInfo *info = _movieRangeInfo.front();
+ _currentPos += info->_isReversed ? -1 : 1;
+ if ((info->_isReversed && _currentPos < info->_endFrame) ||
+ (!info->_isReversed && _currentPos > info->_endFrame)) {
+ if (info->_isFlag1) {
+ info->getMovieEnd(events);
+ _movieRangeInfo.remove(info);
+ delete info;
+
+ if (_movieRangeInfo.empty()) {
+ // NO more ranges, so stop playback
+ stop();
+ } else {
+ // Not empty, so move onto new first one
+ info = _movieRangeInfo.front();
+ _currentPos = info->_startFrame;
+ }
+ } else {
+ _currentPos = info->_startFrame;
+ }
+ }
+
+ if (_isPlaying) {
+ // SInce movie ranges can change the position in the movie,
+ // ensure the decoder is kept in sync
+ seekToFrame(_currentPos);
+
+ info->getMovieFrame(events, _currentPos);
+ return renderFrame();
+ } else {
+ return false;
+ }
+}
+
+void AVISurface::setVideoSurface(CVideoSurface *surface) {
+ _videoSurface = surface;
+
+ warning("TODO: Get video track list from video decoder");
+}
+
+uint AVISurface::getWidth() const {
+ return _decoder->getWidth();
+}
+
+uint AVISurface::getHeight() const {
+ return _decoder->getHeight();
+}
+
+void AVISurface::setFrame(int frameNumber) {
+ // If playback was in process, stop it
+ if (_isPlaying)
+ stop();
+
+ // Ensure the frame number is valid
+ if (frameNumber >= _decoder->getFrameCount())
+ frameNumber = _decoder->getFrameCount() - 1;
+
+ seekToFrame(frameNumber);
+ renderFrame();
+}
+
+int AVISurface::getFrame() const {
+ return _decoder->getCurFrame();
+}
+
+bool AVISurface::renderFrame() {
+ // Check there's a frame ready for
+ assert(_videoSurface);
+ if (!_decoder->needsUpdate())
+ return false;
+
+ // Get the frame to render, and draw it on the surface
+ const Graphics::Surface *frame = _decoder->decodeNextFrame();
+ _videoSurface->blitFrom(Point(0, 0), frame);
+ return false;
+}
+
+bool AVISurface::addEvent(int frameNumber, CGameObject *obj) {
+ if (!_movieRangeInfo.empty()) {
+ CMovieRangeInfo *tail = _movieRangeInfo.back();
+ if (frameNumber == -1)
+ frameNumber = tail->_startFrame;
+
+ CMovieEvent *me = new CMovieEvent();
+ me->_type = MET_FRAME;
+ me->_startFrame = 0;
+ me->_endFrame = 0;
+ me->_initialFrame = frameNumber;
+ me->_gameObject = obj;
+ tail->addEvent(me);
+
+ return _movieRangeInfo.size() == 1 && frameNumber == _priorFrame;
+ }
+
+ return false;
}
} // End of namespace Titanic
diff --git a/engines/titanic/support/avi_surface.h b/engines/titanic/support/avi_surface.h
index 248f2c5ab3..48c8169e78 100644
--- a/engines/titanic/support/avi_surface.h
+++ b/engines/titanic/support/avi_surface.h
@@ -23,33 +23,121 @@
#ifndef TITANIC_AVI_SURFACE_H
#define TITANIC_AVI_SURFACE_H
-#include "video/video_decoder.h"
+#include "video/avi_decoder.h"
#include "titanic/core/resource_key.h"
#include "titanic/support/movie_range_info.h"
namespace Titanic {
class CSoundManager;
+class CVideoSurface;
+
+enum MovieFlag {
+ MOVIE_1 = 1, MOVIE_STOP_PREVIOUS = 2, MOVIE_NO_OBJECT = 4,
+ MOVIE_REVERSE = 8, MOVIE_GAMESTATE = 0x10
+};
class AVISurface {
private:
+ Video::AVIDecoder *_decoder;
+ CVideoSurface *_videoSurface;
int _field4;
int _field8;
- int _fieldC;
- int _field10;
- int _frame;
+ int _currentPos;
+ int _priorFrame;
CMovieRangeInfoList _movieRangeInfo;
- int _field28;
- int _field2C;
- int _field30;
- int _field34;
- int _field38;
+ int _streamCount;
+ void *_frameInfo;
+private:
+ /**
+ * Render a frame to the video surface
+ */
+ bool renderFrame();
+protected:
+ /**
+ * Change the frame with ??? checking
+ */
+ virtual bool changeFrame(int frameNumber);
+
+ /**
+ * Seeks to a given frame number in the video
+ */
+ virtual void seekToFrame(uint frameNumber);
+public:
CSoundManager *_soundManager;
- // TODO: Lots more fields
+ bool _hasAudio;
+ bool _isPlaying;
+ double _frameRate;
public:
AVISurface(const CResourceKey &key);
+ ~AVISurface();
+
+ /**
+ * Start playing the loaded AVI video
+ */
+ virtual bool play(uint flags, CGameObject *obj);
+
+ /**
+ * Start playing the loaded AVI video
+ */
+ virtual bool play(int startFrame, int endFrame, uint flags, CGameObject *obj);
+
+ /**
+ * Start playing the loaded AVI video
+ */
+ virtual bool play(int startFrame, int endFrame, int initialFrame, uint flags, CGameObject *obj);
+
+ /**
+ * Stop the currently playing video
+ */
+ virtual void stop();
+
+ /**
+ * Handle any movie events relevent for the frame
+ */
+ virtual bool handleEvents(CMovieEventList &events);
+
+ /**
+ * Set the video surface the AVI Surface will render on
+ */
+ void setVideoSurface(CVideoSurface *surface);
+
+ /**
+ * Get the width of the video
+ */
+ uint getWidth() const;
+
+ /**
+ * Get the height of the video
+ */
+ uint getHeight() const;
+
+ /**
+ * Set the current frame
+ */
+ void setFrame(int frameNumber);
+
+ /**
+ * Gets the current frame
+ */
+ int getFrame() const;
+
+ /**
+ * Add a movie event
+ */
+ bool addEvent(int frameNumber, CGameObject *obj);
+
+ const void *getFrameInfo() const {
+ return _streamCount <= 1 ? nullptr : _frameInfo;
+ }
+
+ /**
+ * Get a reference to the movie range info list
+ */
+ const CMovieRangeInfoList *getMovieRangeInfo() const {
+ return &_movieRangeInfo;
+ }
-
};
} // End of namespace Titanic
diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp
index d87e7a499b..721088f086 100644
--- a/engines/titanic/support/mouse_cursor.cpp
+++ b/engines/titanic/support/mouse_cursor.cpp
@@ -91,15 +91,17 @@ void CMouseCursor::loadCursorImages() {
// Create the surface
CVideoSurface *surface = _screenManager->createSurface(64, 64);
_cursors[idx]._videoSurface = surface;
-
+/*
Common::SeekableReadStream *stream = new Common::MemoryReadStream(
movieData, f.size(), DisposeAfterUse::NO);
OSMovie movie(stream, surface);
movie.setFrame(idx);
-
- _cursors[idx]._ptrUnknown = movie.proc21();
- surface->set40(_cursors[idx]._ptrUnknown);
- }
+
+ int frameNum = movie.proc21();
+ _cursors[idx]._frameNumber = frameNum;
+ surface->setMovieFrame(frameNum);
+*/
+ }
}
void CMouseCursor::show() {
diff --git a/engines/titanic/support/mouse_cursor.h b/engines/titanic/support/mouse_cursor.h
index 55e0cb4da5..168a7be539 100644
--- a/engines/titanic/support/mouse_cursor.h
+++ b/engines/titanic/support/mouse_cursor.h
@@ -54,7 +54,7 @@ class CVideoSurface;
class CMouseCursor {
struct CursorEntry {
CVideoSurface *_videoSurface;
- void *_ptrUnknown;
+ int _frameNumber;
Common::Point _centroid;
};
private:
diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp
index 6a79c02a3e..338396ff96 100644
--- a/engines/titanic/support/movie.cpp
+++ b/engines/titanic/support/movie.cpp
@@ -20,42 +20,51 @@
*
*/
-#include "video/avi_decoder.h"
-#include "titanic/sound/sound_manager.h"
#include "titanic/support/movie.h"
+#include "titanic/support/avi_surface.h"
+#include "titanic/sound/sound_manager.h"
+#include "titanic/messages/messages.h"
#include "titanic/titanic.h"
namespace Titanic {
-CMovieList *CMovie::_activeMovies;
+#define CLIP_WIDTH 600
+#define CLIP_WIDTH_REDUCED (CLIP_WIDTH / 2)
+#define CLIP_HEIGHT 340
+#define CLIP_HEIGHT_REDUCED (CLIP_HEIGHT / 2)
+
+CMovieList *CMovie::_playingMovies;
+CVideoSurface *CMovie::_movieSurface;
-CMovie::CMovie() : ListItem(), _state(MOVIE_STOPPED), _field10(0),
+CMovie::CMovie() : ListItem(), _state(MSTATE_0), _field10(0),
_field14(0) {
}
CMovie::~CMovie() {
- removeFromActiveMovies();
+ removeFromPlayingMovies();
}
void CMovie::init() {
- _activeMovies = new CMovieList();
+ _playingMovies = new CMovieList();
+ _movieSurface = nullptr;
}
void CMovie::deinit() {
- delete _activeMovies;
+ delete _playingMovies;
+ delete _movieSurface;
}
-void CMovie::addToActiveMovies() {
+void CMovie::addToPlayingMovies() {
if (!isActive())
- _activeMovies->push_back(this);
+ _playingMovies->push_back(this);
}
-void CMovie::removeFromActiveMovies() {
- _activeMovies->remove(this);
+void CMovie::removeFromPlayingMovies() {
+ _playingMovies->remove(this);
}
bool CMovie::isActive() const {
- return _activeMovies->contains(this);
+ return _playingMovies->contains(this);
}
bool CMovie::get10() {
@@ -70,156 +79,148 @@ bool CMovie::get10() {
/*------------------------------------------------------------------------*/
OSMovie::OSMovie(const CResourceKey &name, CVideoSurface *surface) :
- _videoSurface(surface), _gameObject(nullptr), _endFrame(-1) {
- Video::AVIDecoder *decoder = new Video::AVIDecoder();
- _video = decoder;
- _field14 = 1;
-
- if (!_video->loadFile(name.getString()))
- error("Could not open video - %s", name.getString().c_str());
-}
+ _aviSurface(name), _videoSurface(surface) {
+ _field18 = 0;
+ _field24 = 0;
+ _field28 = 0;
+ _field2C = 0;
+ _ticksStart = 0;
+ _frameTime1 = 0;
+ _frameTime2 = 17066;
-OSMovie::OSMovie(Common::SeekableReadStream *stream, CVideoSurface *surface) :
- _videoSurface(surface), _gameObject(nullptr), _endFrame(-1) {
- _video = new Video::AVIDecoder();
- if (!_video->loadStream(stream))
- error("Could not parse movie stream");
+ surface->resize(_aviSurface.getWidth(), _aviSurface.getHeight());
+ _aviSurface.setVideoSurface(surface);
}
OSMovie::~OSMovie() {
- delete _video;
}
-void OSMovie::play(uint flags, CVideoSurface *surface) {
- uint endFrame = _video->getFrameCount();
- play(0, endFrame, 0, 0);
-}
+void OSMovie::play(uint flags, CGameObject *obj) {
+ _aviSurface.play(flags, obj);
-void OSMovie::play(uint startFrame, uint endFrame, int v3, bool v4) {
- warning("TODO: OSMovie::play properly");
+ if (_aviSurface._isPlaying)
+ movieStarted();
+}
- _video->start();
- _video->seekToFrame(startFrame);
- _endFrame = endFrame;
+void OSMovie::play(uint startFrame, uint endFrame, uint flags, CGameObject *obj) {
+ _aviSurface.play(startFrame, endFrame, flags, obj);
- addToActiveMovies();
- _state = MOVIE_NONE;
+ if (_aviSurface._isPlaying)
+ movieStarted();
}
-void OSMovie::play(const Rect &rect, int v1, int v2) {
- warning("TODO: OSMovie::play 3");
-}
+void OSMovie::play(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj) {
+ _aviSurface.play(startFrame, endFrame, initialFrame, flags, obj);
-void OSMovie::playClip(const Rect &rect, uint startFrame, uint endFrame) {
- warning("TODO: OSMovie::playClip");
+ if (_aviSurface._isPlaying)
+ movieStarted();
}
-void OSMovie::proc11() {
- warning("TODO: OSMovie::proc11");
-}
+void OSMovie::playClip(const Point &drawPos, uint startFrame, uint endFrame) {
+ if (!_movieSurface)
+ _movieSurface = CScreenManager::_screenManagerPtr->createSurface(600, 340);
+
+ bool widthLess = _videoSurface->getWidth() < 600;
+ bool heightLess = _videoSurface->getHeight() < 340;
+ Rect r(drawPos.x, drawPos.y,
+ drawPos.x + widthLess ? CLIP_WIDTH_REDUCED : CLIP_WIDTH,
+ drawPos.y + heightLess ? CLIP_HEIGHT_REDUCED : CLIP_HEIGHT
+ );
-void OSMovie::proc12(int v1, int v2, int frameNumber, int flags, CGameObject *obj) {
- warning("TODO: OSMovie::proc12");
+ uint timePerFrame = 1000 / _aviSurface._frameRate;
+
+ for (; endFrame >= startFrame; ++startFrame) {
+ // Set the frame
+ _aviSurface.setFrame(startFrame);
+
+ // TODO: See if we need to do anything further here. The original had a bunch
+ // of calls and using of the _movieSurface; perhaps to allow scaling down
+ // videos to half-size
+ if (widthLess || heightLess)
+ warning("Not properly reducing clip size: %d %d", r.width(), r.height());
+
+ // Wait for the next frame, unless the user interrupts the clip
+ if (g_vm->_events->waitForPress(timePerFrame))
+ break;
+ }
}
void OSMovie::stop() {
- _video->stop();
- _state = MOVIE_STOPPED;
+ _aviSurface.stop();
+ removeFromPlayingMovies();
}
-void OSMovie::proc14() {
- warning("TODO: OSMovie::proc14");
+void OSMovie::addEvent(int frameNumber, CGameObject *obj) {
+ if (_aviSurface.addEvent(frameNumber, obj)) {
+ CMovieFrameMsg frameMsg(frameNumber, 0);
+ frameMsg.execute(obj);
+ }
}
void OSMovie::setFrame(uint frameNumber) {
- _video->seekToFrame(frameNumber);
- decodeFrame();
+ _aviSurface.setFrame(frameNumber);
+ _videoSurface->setMovieFrame(frameNumber);
}
-void OSMovie::proc16() {
- warning("TODO: OSMovie::proc16");
-}
+bool OSMovie::handleEvents(CMovieEventList &events) {
+ if (!_aviSurface._isPlaying)
+ return false;
-const Common::List<CMovieRangeInfo *> OSMovie::getMovieRangeInfo() const {
- warning("TODO: OSMovie::getMovieRangeInfo");
- return Common::List<CMovieRangeInfo *>();
-}
+ int time = (g_vm->_events->getTicksCount() + ((_ticksStart << 24) - _ticksStart)) << 8;
+ if (time < _frameTime1)
+ return _aviSurface._isPlaying;
-void OSMovie::setSoundManager(CSoundManager *soundManager) {
-// if (_aviSurface)
-// _aviSurface->_field3C = soundManager;
+ if (!_field14 && (time - _frameTime1) > (_frameTime2 * 2))
+ _frameTime1 = time;
- warning("TODO: OSMovie::proc18");
-}
+ _frameTime1 += _frameTime2;
+ _aviSurface.handleEvents(events);
+ _videoSurface->setMovieFrameInfo(_aviSurface.getFrameInfo());
-int OSMovie::getFrame() {
- assert(_video);
- return _video->getCurFrame();
-}
+ if (_field14) {
+ while (_frameTime1 >= time && events.empty()) {
+ _aviSurface.handleEvents(events);
+ _videoSurface->setMovieFrameInfo(_aviSurface.getFrameInfo());
-void OSMovie::proc20() {
- warning("TODO: OSMovie::proc20");
-}
-
-void *OSMovie::proc21() {
- warning("TODO: OSMovie::proc21");
- return nullptr;
-}
-
-MovieState OSMovie::getState() {
- if (!_video)
- _state = MOVIE_STOPPED;
- return _state;
-}
-
-void OSMovie::update() {
- if (_state != MOVIE_STOPPED) {
- if (_video->isPlaying()) {
- if (_video->getCurFrame() >= _endFrame) {
- _video->stop();
- _state = MOVIE_FINISHED;
- } else if (_video->needsUpdate()) {
- decodeFrame();
- _state = MOVIE_FRAME;
- } else {
- _state = MOVIE_NONE;
- }
- } else {
- _state = MOVIE_STOPPED;
+ _frameTime1 += _frameTime2;
}
}
+
+ return _aviSurface._isPlaying;
+}
+
+const CMovieRangeInfoList *OSMovie::getMovieRangeInfo() const {
+ return _aviSurface.getMovieRangeInfo();
}
-void OSMovie::decodeFrame() {
- const Graphics::Surface *frame = _video->decodeNextFrame();
- OSVideoSurface *videoSurface = static_cast<OSVideoSurface *>(_videoSurface);
- assert(videoSurface);
+void OSMovie::setSoundManager(CSoundManager *soundManager) {
+ _aviSurface._soundManager = soundManager;
+}
- // If the video surface doesn't yet have an underlying surface, create it
- if (!videoSurface->hasSurface())
- videoSurface->recreate(frame->w, frame->h);
+int OSMovie::getFrame() const {
+ return _aviSurface.getFrame();
+}
- // Lock access to the surface
- videoSurface->lock();
- assert(videoSurface->_rawSurface);
+void OSMovie::movieStarted() {
+ _frameTime1 = _frameTime2 = 256000.0 / _aviSurface._frameRate;
+ _ticksStart = g_vm->_events->getTicksCount();
- if (frame->format == videoSurface->_rawSurface->format) {
- // Matching format, so we can copy straight from the video frame
- videoSurface->_rawSurface->blitFrom(*frame);
- } else {
- // Different formats so we have to convert it first
- Graphics::Surface *s = frame->convertTo(videoSurface->_rawSurface->format);
- videoSurface->_rawSurface->blitFrom(*s);
+ if (_aviSurface._hasAudio)
+ _aviSurface._soundManager->movieStarted();
- s->free();
- delete s;
- }
+ // Register the movie in the playing list
+ addToPlayingMovies();
+ _field10 = 1;
+}
- // Unlock the surface
- videoSurface->unlock();
+void OSMovie::proc20() {
+ // TODO
+}
- if (_gameObject)
- _gameObject->makeDirty();
+int OSMovie::proc21() {
+ // TODO
+ return 0;
}
+
} // End of namespace Titanic
diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h
index 7abca6bbc0..c839c882ca 100644
--- a/engines/titanic/support/movie.h
+++ b/engines/titanic/support/movie.h
@@ -27,12 +27,13 @@
#include "video/video_decoder.h"
#include "titanic/core/list.h"
#include "titanic/core/resource_key.h"
+#include "titanic/support/avi_surface.h"
#include "titanic/support/movie_range_info.h"
namespace Titanic {
enum MovieState {
- MOVIE_STOPPED = -1, MOVIE_NONE = 0, MOVIE_FINISHED = 1, MOVIE_FRAME = 2
+ MSTATE_0 = 0, MSTATE_1 = 1
};
class CGameObject;
@@ -46,22 +47,17 @@ public:
class CMovie : public ListItem {
protected:
- MovieState _state;
- int _field10;
-protected:
- /**
- * Adds the movie to the active movies list
- */
- void addToActiveMovies();
-
/**
- * Removes the movie from the active movies list
+ * Adds the movie to the list of currently playing movies
*/
- void removeFromActiveMovies();
+ void addToPlayingMovies();
public:
+ MovieState _state;
+ int _field10;
int _field14;
public:
- static CMovieList *_activeMovies;
+ static CMovieList *_playingMovies;
+ static CVideoSurface *_movieSurface;
/**
* Initializes statics
@@ -77,41 +73,49 @@ public:
virtual ~CMovie();
/**
- * Plays the movie
+ * Starts playing the movie
*/
- virtual void play(uint flags, CVideoSurface *surface) = 0;
+ virtual void play(uint flags, CGameObject *obj) = 0;
/**
- * Plays the movie
+ * Starts playing the movie
*/
- virtual void play(uint startFrame, uint endFrame, int v3, bool v4) = 0;
+ virtual void play(uint startFrame, uint endFrame, uint flags, CGameObject *obj) = 0;
/**
- * Plays the movie
+ * Starts playing the movie
*/
- virtual void play(const Rect &rect, int v1, int v2) = 0;
+ virtual void play(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj) = 0;
/**
* Plays a sub-section of a movie
*/
- virtual void playClip(const Rect &rect, uint startFrame, uint endFrame) = 0;
+ virtual void playClip(const Point &drawPos, uint startFrame, uint endFrame) = 0;
- virtual void proc11() = 0;
- virtual void proc12(int v1, int v2, int frameNumber, int flags, CGameObject *obj) = 0;
-
/**
* Stops the movie
*/
virtual void stop() = 0;
- virtual void proc14() = 0;
+ /**
+ * Add a playback event
+ */
+ virtual void addEvent(int frameNumber, CGameObject *obj) = 0;
+
+ /**
+ * Set the current frame number
+ */
virtual void setFrame(uint frameNumber) = 0;
- virtual void proc16() = 0;
+
+ /**
+ * Handle any pending movie events
+ */
+ virtual bool handleEvents(CMovieEventList &events) = 0;
/**
* Return any movie range info associated with the movie
*/
- virtual const Common::List<CMovieRangeInfo *> getMovieRangeInfo() const = 0;
+ virtual const CMovieRangeInfoList *getMovieRangeInfo() const = 0;
/**
* Set the sound manager reference
@@ -121,94 +125,102 @@ public:
/**
* Get the current movie frame
*/
- virtual int getFrame() = 0;
+ virtual int getFrame() const = 0;
virtual void proc20() = 0;
- virtual void *proc21() = 0;
+ virtual int proc21() = 0;
+
+ /**
+ * Removes the movie from the list of currently playing movies
+ */
+ void removeFromPlayingMovies();
+ /**
+ * Returns true if the movie is currently active
+ */
bool isActive() const;
bool get10();
-
- virtual MovieState getState() = 0;
- virtual void update() = 0;
};
class OSMovie : public CMovie {
private:
- Video::VideoDecoder *_video;
+ AVISurface _aviSurface;
CVideoSurface *_videoSurface;
- int _endFrame;
-
+ int _field18;
+ int _field24;
+ int _field28;
+ int _field2C;
+ int _ticksStart;
+ int _frameTime1;
+ int _frameTime2;
+private:
/**
- * Decodes the next frame
+ * Called when a movie is started playing
*/
- void decodeFrame();
-public:
- CGameObject *_gameObject;
+ void movieStarted();
public:
OSMovie(const CResourceKey &name, CVideoSurface *surface);
- OSMovie(Common::SeekableReadStream *stream, CVideoSurface *surface);
virtual ~OSMovie();
/**
- * Plays the movie
+ * Starts playing the movie
*/
- virtual void play(uint flags, CVideoSurface *surface);
+ virtual void play(uint flags, CGameObject *obj);
/**
- * Plays the movie
+ * Starts playing the movie
*/
- virtual void play(uint startFrame, uint endFrame, int v3, bool v4);
+ virtual void play(uint startFrame, uint endFrame, uint flags, CGameObject *obj);
/**
- * Plays the movie
+ * Starts playing the movie
*/
- virtual void play(const Rect &rect, int v1, int v2);
+ virtual void play(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj);
/**
* Plays a sub-section of a movie
*/
- virtual void playClip(const Rect &rect, uint startFrame, uint endFrame);
-
- virtual void proc11();
- virtual void proc12(int v1, int v2, int frameNumber, int flags, CGameObject *obj);
+ virtual void playClip(const Point &drawPos, uint startFrame, uint endFrame);
/**
* Stops the movie
*/
virtual void stop();
- virtual void proc14();
+ /**
+ * Add a playback event
+ */
+ virtual void addEvent(int eventId, CGameObject *obj);
/**
* Set the current frame number
*/
virtual void setFrame(uint frameNumber);
- virtual void proc16();
+ /**
+ * Handle any pending movie events
+ */
+ virtual bool handleEvents(CMovieEventList &events);
/**
- * Return any movie range info associated with the movie
+ * Get the current frame number
*/
- virtual const Common::List<CMovieRangeInfo *> getMovieRangeInfo() const;
+ virtual int getFrame() const;
/**
- * Set the sound manager reference
+ * Return any movie range info associated with the movie
*/
- virtual void setSoundManager(CSoundManager *soundManager);
+ virtual const CMovieRangeInfoList *getMovieRangeInfo() const;
/**
- * Get the current movie frame
+ * Set the sound manager reference
*/
- virtual int getFrame();
+ virtual void setSoundManager(CSoundManager *soundManager);
virtual void proc20();
- virtual void *proc21();
-
+ virtual int proc21();
- virtual MovieState getState();
- virtual void update();
};
} // End of namespace Titanic
diff --git a/engines/titanic/support/movie_event.cpp b/engines/titanic/support/movie_event.cpp
index 870a06fe6f..5f8a6da019 100644
--- a/engines/titanic/support/movie_event.cpp
+++ b/engines/titanic/support/movie_event.cpp
@@ -21,27 +21,29 @@
*/
#include "titanic/support/movie_event.h"
+#include "titanic/core/game_object.h"
namespace Titanic {
-CMovieEvent::CMovieEvent() : ListItem(), _fieldC(0), _field10(0),
- _field14(0), _field1C(0) {
+CMovieEvent::CMovieEvent() : ListItem(), _type(MET_PLAY), _startFrame(0),
+ _endFrame(0), _initialFrame(0), _gameObject(nullptr) {
}
CMovieEvent::CMovieEvent(const CMovieEvent *src) {
- _fieldC = src->_fieldC;
- _field10 = src->_field10;
- _field14 = src->_field14;
- _field18 = src->_field18;
- _field1C = src->_field1C;
+ _type = src->_type;
+ _startFrame = src->_startFrame;
+ _endFrame = src->_endFrame;
+ _initialFrame = src->_initialFrame;
+ _gameObject = src->_gameObject;
}
void CMovieEvent::save(SimpleFile *file, int indent) {
file->writeNumberLine(0, indent);
- file->writeNumberLine(_fieldC, indent + 1);
- file->writeNumberLine(_field10, indent + 1);
- file->writeNumberLine(_field14, indent + 1);
- file->writeNumberLine(_field1C, indent + 1);
+ file->writeNumberLine(_startFrame, indent + 1);
+ file->writeNumberLine(_endFrame, indent + 1);
+ error("FIXME: Original save/loaded object pointer");
+ // file->writeNumberLine(_gameObject, indent + 1);
+ file->writeNumberLine(_initialFrame, indent + 1);
ListItem::save(file, indent);
}
@@ -49,10 +51,11 @@ void CMovieEvent::save(SimpleFile *file, int indent) {
void CMovieEvent::load(SimpleFile *file) {
int val = file->readNumber();
if (!val) {
- _fieldC = file->readNumber();
- _field10 = file->readNumber();
- _field14 = file->readNumber();
- _field1C = file->readNumber();
+ _startFrame = file->readNumber();
+ _endFrame = file->readNumber();
+ file->readNumber();
+ error("FIXME: Original save/loaded object pointer");
+ _initialFrame = file->readNumber();
}
ListItem::load(file);
diff --git a/engines/titanic/support/movie_event.h b/engines/titanic/support/movie_event.h
index ed72e2d349..af93c76a31 100644
--- a/engines/titanic/support/movie_event.h
+++ b/engines/titanic/support/movie_event.h
@@ -27,13 +27,17 @@
namespace Titanic {
+enum MovieEventType { MET_PLAY = 0, MET_MOVIE_END = 1, MET_FRAME = 2 };
+
+class CGameObject;
+
class CMovieEvent : public ListItem {
public:
- int _fieldC;
- int _field10;
- int _field14;
- int _field18;
- int _field1C;
+ MovieEventType _type;
+ int _startFrame;
+ int _endFrame;
+ CGameObject *_gameObject;
+ int _initialFrame;
public:
CMovieEvent();
CMovieEvent(const CMovieEvent *src);
@@ -53,6 +57,10 @@ public:
class CMovieEventList : public List<CMovieEvent> {
};
+class CSharedMovieEventList : public Common::List<CMovieEvent> {
+};
+
+
} // End of namespace Titanic
#endif /* TITANIC_MOVIE_EVENT_H */
diff --git a/engines/titanic/support/movie_range_info.cpp b/engines/titanic/support/movie_range_info.cpp
index e6b28ce4e8..4c62539864 100644
--- a/engines/titanic/support/movie_range_info.cpp
+++ b/engines/titanic/support/movie_range_info.cpp
@@ -34,11 +34,11 @@ CMovieRangeInfo::~CMovieRangeInfo() {
}
CMovieRangeInfo::CMovieRangeInfo(const CMovieRangeInfo *src) : ListItem() {
- _fieldC = src->_fieldC;
- _field10 = src->_field10;
- _frameNumber = src->_frameNumber;
_startFrame = src->_startFrame;
_endFrame = src->_endFrame;
+ _initialFrame = src->_initialFrame;
+ _isReversed = src->_isReversed;
+ _isFlag1 = src->_isFlag1;
// Duplicate the events list
for (CMovieEventList::const_iterator i = _events.begin();
@@ -49,38 +49,38 @@ CMovieRangeInfo::CMovieRangeInfo(const CMovieRangeInfo *src) : ListItem() {
void CMovieRangeInfo::save(SimpleFile *file, int indent) {
file->writeNumberLine(0, indent);
- file->writeNumberLine(_fieldC, indent + 1);
- file->writeNumberLine(_field10, indent + 1);
- file->writeNumberLine(_frameNumber, indent + 1);
- file->writeNumberLine(_endFrame, indent + 1);
file->writeNumberLine(_startFrame, indent + 1);
+ file->writeNumberLine(_endFrame, indent + 1);
+ file->writeNumberLine(_initialFrame, indent + 1);
+ file->writeNumberLine(_isFlag1, indent + 1);
+ file->writeNumberLine(_isReversed, indent + 1);
_events.save(file, indent + 1);
}
void CMovieRangeInfo::load(SimpleFile *file) {
int val = file->readNumber();
if (!val) {
- _fieldC = file->readNumber();
- _field10 = file->readNumber();
- _frameNumber = file->readNumber();
- _endFrame = file->readNumber();
_startFrame = file->readNumber();
+ _endFrame = file->readNumber();
+ _initialFrame = file->readNumber();
+ _isFlag1 = file->readNumber();
+ _isReversed = file->readNumber();
_events.load(file);
}
}
-void CMovieRangeInfo::get1(CMovieEventList &list) {
+void CMovieRangeInfo::getMovieEnd(CMovieEventList &list) {
for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) {
CMovieEvent *movieEvent = *i;
- if (movieEvent->_fieldC == 1)
+ if (movieEvent->_type == MET_MOVIE_END)
list.push_back(new CMovieEvent(movieEvent));
}
}
-void CMovieRangeInfo::get2(CMovieEventList &list, int val) {
+void CMovieRangeInfo::getMovieFrame(CMovieEventList &list, int frameNumber) {
for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) {
CMovieEvent *movieEvent = *i;
- if (movieEvent->_fieldC == 2 && movieEvent->_field1C == val)
+ if (movieEvent->_type == MET_FRAME && movieEvent->_initialFrame == frameNumber)
list.push_back(new CMovieEvent(movieEvent));
}
}
@@ -88,24 +88,24 @@ void CMovieRangeInfo::get2(CMovieEventList &list, int val) {
void CMovieRangeInfo::process(CGameObject *owner) {
int flags = 0;
if (_endFrame)
- flags |= CLIPFLAG_HAS_END_FRAME;
+ flags |= MOVIE_1;
if (_startFrame)
- flags |= CLIPFLAG_HAS_START_FRAME;
+ flags |= MOVIE_REVERSE;
for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) {
CMovieEvent *movieEvent = *i;
- if (!movieEvent->_fieldC) {
+ if (!movieEvent->_type == MET_PLAY) {
flags |= CLIPFLAG_PLAY;
break;
}
}
- owner->checkPlayMovie(_fieldC, _field10, _frameNumber, flags);
+ owner->playMovie(_startFrame, _endFrame, _initialFrame, flags);
for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) {
CMovieEvent *movieEvent = *i;
- if (!movieEvent->_fieldC)
- owner->surface38(movieEvent->_field1C);
+ if (movieEvent->_type == MET_PLAY)
+ owner->movieEvent(movieEvent->_initialFrame);
}
}
diff --git a/engines/titanic/support/movie_range_info.h b/engines/titanic/support/movie_range_info.h
index be04975cbf..b8186e6f7e 100644
--- a/engines/titanic/support/movie_range_info.h
+++ b/engines/titanic/support/movie_range_info.h
@@ -34,11 +34,11 @@ class CGameObject;
class CMovieRangeInfo : public ListItem {
public:
- int _fieldC;
- int _field10;
- int _frameNumber;
- uint _startFrame;
- uint _endFrame;
+ int _startFrame;
+ int _endFrame;
+ int _initialFrame;
+ bool _isReversed;
+ bool _isFlag1;
CMovieEventList _events;
public:
CMovieRangeInfo();
@@ -60,9 +60,15 @@ public:
*/
void addEvent(CMovieEvent *movieEvent) { _events.push_back(movieEvent); }
- void get1(CMovieEventList &list);
+ /**
+ * Get any movie end events for the range
+ */
+ void getMovieEnd(CMovieEventList &list);
- void get2(CMovieEventList &list, int val);
+ /**
+ * Get any movie frame events for a specified frame number
+ */
+ void getMovieFrame(CMovieEventList &list, int frameNumber);
void process(CGameObject *owner);
};
diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp
index 0335e7d9b1..fc7db30391 100644
--- a/engines/titanic/support/video_surface.cpp
+++ b/engines/titanic/support/video_surface.cpp
@@ -32,7 +32,7 @@ int CVideoSurface::_videoSurfaceCounter = 0;
CVideoSurface::CVideoSurface(CScreenManager *screenManager) :
_screenManager(screenManager), _rawSurface(nullptr), _movie(nullptr),
_pendingLoad(false), _blitStyleFlag(false), _blitFlag(false),
- _field40(nullptr), _field44(4), _field48(0), _field50(1) {
+ _movieFrameInfo(nullptr), _transparencyMode(TRANS_DEFAULT), _field48(0), _field50(1) {
_videoSurfaceNum = _videoSurfaceCounter++;
}
@@ -427,22 +427,22 @@ void OSVideoSurface::clear() {
}
-void OSVideoSurface::playMovie(uint flags, CVideoSurface *surface) {
+void OSVideoSurface::playMovie(uint flags, CGameObject *obj) {
if (loadIfReady() && _movie)
- _movie->play(flags, surface);
+ _movie->play(flags, obj);
_ddSurface->fill(nullptr, 0);
}
-void OSVideoSurface::playMovie(uint startFrame, uint endFrame, int v3, bool v4) {
+void OSVideoSurface::playMovie(uint startFrame, uint endFrame, uint flags, CGameObject *obj) {
if (loadIfReady() && _movie) {
- _movie->play(startFrame, endFrame, v3, v4);
+ _movie->play(startFrame, endFrame, flags, obj);
}
}
-void OSVideoSurface::proc35(int v1, int v2, int frameNumber, int flags, CGameObject *owner) {
+void OSVideoSurface::playMovie(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj) {
if (loadIfReady() && _movie) {
- _movie->proc12(v1, v2, frameNumber, flags, owner);
+ _movie->play(startFrame, endFrame, initialFrame, flags, obj);
}
}
@@ -456,16 +456,17 @@ void OSVideoSurface::setMovieFrame(uint frameNumber) {
_movie->setFrame(frameNumber);
}
-void OSVideoSurface::proc38(int v1, int v2) {
- warning("OSVideoSurface::proc38");
+void OSVideoSurface::addMovieEvent(int frameNumber, CGameObject *obj) {
+ if (_movie)
+ _movie->addEvent(frameNumber, obj);
}
void OSVideoSurface::proc39(int v1, int v2) {
warning("OSVideoSurface::proc39");
}
-const Common::List<CMovieRangeInfo *> OSVideoSurface::getMovieRangeInfo() const {
- return _movie ? _movie->getMovieRangeInfo() : Common::List<CMovieRangeInfo *>();
+const CMovieRangeInfoList *OSVideoSurface::getMovieRangeInfo() const {
+ return _movie ? _movie->getMovieRangeInfo() : nullptr;
}
bool OSVideoSurface::loadIfReady() {
diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h
index 37afccf9e1..3521be6336 100644
--- a/engines/titanic/support/video_surface.h
+++ b/engines/titanic/support/video_surface.h
@@ -35,6 +35,11 @@
namespace Titanic {
+enum TransparencyMode {
+ TRANS_MASK0 = 0, TRANS_MASK255 = 1, TRANS_ALPHA0 = 2,
+ TRANS_ALPHA255 = 3, TRANS_DEFAULT = 4
+};
+
class CScreenManager;
class CJPEGDecode;
class CTargaDecode;
@@ -57,8 +62,7 @@ protected:
CScreenManager *_screenManager;
Graphics::ManagedSurface *_rawSurface;
bool _pendingLoad;
- void *_field40;
- int _field44;
+ const void *_movieFrameInfo;
int _field48;
int _videoSurfaceNum;
int _field50;
@@ -69,6 +73,7 @@ public:
bool _blitFlag;
bool _blitStyleFlag;
CResourceKey _resourceKey;
+ TransparencyMode _transparencyMode;
public:
CVideoSurface(CScreenManager *screenManager);
virtual ~CVideoSurface();
@@ -190,15 +195,19 @@ public:
* Plays a movie, loading it from the specified _resource
* if not already loaded
*/
- virtual void playMovie(uint flags, CVideoSurface *surface) = 0;
+ virtual void playMovie(uint flags, CGameObject *obj) = 0;
/**
* Plays a movie, loading it from the specified _resource
* if not already loaded
*/
- virtual void playMovie(uint startFrame, uint endFrame, int v3, bool v4) = 0;
+ virtual void playMovie(uint startFrame, uint endFrame, uint flags, CGameObject *obj) = 0;
- virtual void proc35(int v1, int v2, int frameNumber, int flags, CGameObject *owner) = 0;
+ /**
+ * Plays a movie, loading it from the specified _resource
+ * if not already loaded
+ */
+ virtual void playMovie(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj) = 0;
/**
* Stops any movie currently attached to the surface
@@ -206,18 +215,21 @@ public:
virtual void stopMovie() = 0;
/**
- * Sets the movie to the specified frame number
+ * Set the current movie frame number
*/
virtual void setMovieFrame(uint frameNumber) = 0;
- virtual void proc38(int v1, int v2) = 0;
+ /**
+ * Adds a movie playback event
+ */
+ virtual void addMovieEvent(int eventId, CGameObject *obj) = 0;
virtual void proc39(int v1, int v2) = 0;
/**
* Return any movie range info associated with the surface's movie
*/
- virtual const Common::List<CMovieRangeInfo *> getMovieRangeInfo() const = 0;
+ virtual const CMovieRangeInfoList *getMovieRangeInfo() const = 0;
/**
* Loads the surface's resource if there's one pending
@@ -257,8 +269,19 @@ public:
*/
void blitFrom(const Point &destPos, const Graphics::Surface *src);
- void set40(void *v) { _field40 = v; }
+ /**
+ *
+ */
+ void setMovieFrameInfo(const void *frameInfo) { _movieFrameInfo = frameInfo; }
+
+ /**
+ */
+ const void *getMovieFrameInfo() const { return _movieFrameInfo; }
+ /**
+ * Get the pixels associated with the surface. Only valid when the
+ * surface has been locked for access
+ */
uint16 *getPixels() { return (uint16 *)_rawSurface->getPixels(); }
/**
@@ -400,15 +423,19 @@ public:
* Plays a movie, loading it from the specified _resource
* if not already loaded
*/
- virtual void playMovie(uint flags, CVideoSurface *surface);
+ virtual void playMovie(uint flags, CGameObject *obj);
/**
* Plays a movie, loading it from the specified _resource
* if not already loaded
*/
- virtual void playMovie(uint startFrame, uint endFrame, int v3, bool v4);
+ virtual void playMovie(uint startFrame, uint endFrame, uint flags, CGameObject *obj);
- virtual void proc35(int v1, int v2, int frameNumber, int flags, CGameObject *owner);
+ /**
+ * Plays a movie, loading it from the specified _resource
+ * if not already loaded
+ */
+ virtual void playMovie(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj);
/**
* Stops any movie currently attached to the surface
@@ -420,14 +447,17 @@ public:
*/
virtual void setMovieFrame(uint frameNumber);
- virtual void proc38(int v1, int v2);
+ /**
+ * Adds a movie playback event
+ */
+ virtual void addMovieEvent(int frameNumber, CGameObject *obj);
virtual void proc39(int v1, int v2);
/**
* Return any movie range info associated with the surface's movie
*/
- virtual const Common::List<CMovieRangeInfo *> getMovieRangeInfo() const;
+ virtual const CMovieRangeInfoList *getMovieRangeInfo() const;
/**
* Loads the surface's resource if there's one pending