aboutsummaryrefslogtreecommitdiff
path: root/engines/titanic/support
diff options
context:
space:
mode:
Diffstat (limited to 'engines/titanic/support')
-rw-r--r--engines/titanic/support/avi_surface.cpp45
-rw-r--r--engines/titanic/support/avi_surface.h41
-rw-r--r--engines/titanic/support/direct_draw.cpp5
-rw-r--r--engines/titanic/support/exe_resources.cpp6
-rw-r--r--engines/titanic/support/exe_resources.h17
-rw-r--r--engines/titanic/support/fixed_queue.h143
-rw-r--r--engines/titanic/support/movie.cpp7
-rw-r--r--engines/titanic/support/movie.h11
8 files changed, 257 insertions, 18 deletions
diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp
index bddbb9808e..4b60921e31 100644
--- a/engines/titanic/support/avi_surface.cpp
+++ b/engines/titanic/support/avi_surface.cpp
@@ -44,7 +44,7 @@ AVISurface::AVISurface(const CResourceKey &key) : _movieName(key.getString()) {
_videoSurface = nullptr;
_streamCount = 0;
_movieFrameSurface[0] = _movieFrameSurface[1] = nullptr;
- _framePixels = nullptr;
+ _framePixels = false;
_priorFrameTime = 0;
// Reset current frame. We need to keep track of frames separately from the decoder,
@@ -55,8 +55,15 @@ AVISurface::AVISurface(const CResourceKey &key) : _movieName(key.getString()) {
// Create a decoder
_decoder = new AVIDecoder();
- if (!_decoder->loadFile(_movieName))
+
+ // Load the video into it
+ if (_movieName == "y222.avi") {
+ // The y222.avi is the bells animation for the music room.
+ // It needs on the fly fixing for the video header
+ _decoder->loadStream(new y222());
+ } else if (!_decoder->loadFile(_movieName)) {
error("Could not open video - %s", key.getString().c_str());
+ }
_streamCount = _decoder->getTransparencyTrack() ? 2 : 1;
@@ -68,7 +75,6 @@ AVISurface::AVISurface(const CResourceKey &key) : _movieName(key.getString()) {
AVISurface::~AVISurface() {
if (_videoSurface)
_videoSurface->_flipVertically = false;
- delete _framePixels;
delete _movieFrameSurface[0];
delete _movieFrameSurface[1];
delete _decoder;
@@ -285,8 +291,7 @@ void AVISurface::setupDecompressor() {
}
if (!flag) {
- _framePixels = new Graphics::ManagedSurface(_decoder->getWidth(), _decoder->getHeight(),
- _decoder->getVideoTrack(0).getPixelFormat());
+ _framePixels = true;
} else if (idx == 0) {
// The original developers used a vertical flipped playback to indicate
// an incompatibility between source video and dest surface bit-depths,
@@ -486,6 +491,12 @@ bool AVISurface::playCutscene(const Rect &r, uint startFrame, uint endFrame) {
if (_currentFrame != ((int)startFrame - 1) || startFrame == 0) {
// Start video playback at the desired starting frame
+ if (startFrame > 0) {
+ // Give a chance for a key frame just prior to the start frame
+ // to be loaded first
+ setFrame(startFrame - 1);
+ }
+
setFrame(startFrame);
startAtFrame(startFrame);
_currentFrame = startFrame;
@@ -532,4 +543,28 @@ uint AVISurface::getBitDepth() const {
return _decoder->getVideoTrack(0).getBitCount();
}
+/*------------------------------------------------------------------------*/
+
+y222::y222() {
+ _innerStream = new File();
+ _innerStream->open("y222.avi");
+}
+
+y222::~y222() {
+ delete _innerStream;
+}
+
+uint32 y222::read(void *dataPtr, uint32 dataSize) {
+ int32 currPos = pos();
+ uint32 bytesRead = _innerStream->read(dataPtr, dataSize);
+
+ if (currPos <= 48 && (currPos + bytesRead) >= 52) {
+ byte *framesP = (byte *)dataPtr + (48 - currPos);
+ if (READ_LE_UINT32(framesP) == 1)
+ WRITE_LE_UINT32(framesP, 1085);
+ }
+
+ return bytesRead;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/support/avi_surface.h b/engines/titanic/support/avi_surface.h
index cb2e562d54..3ee8c38c5c 100644
--- a/engines/titanic/support/avi_surface.h
+++ b/engines/titanic/support/avi_surface.h
@@ -23,6 +23,7 @@
#ifndef TITANIC_AVI_SURFACE_H
#define TITANIC_AVI_SURFACE_H
+#include "common/stream.h"
#include "video/avi_decoder.h"
#include "graphics/managed_surface.h"
#include "titanic/core/resource_key.h"
@@ -41,6 +42,37 @@ enum MovieFlag {
MOVIE_WAIT_FOR_FINISH = 0x10 // Let finish before playing next movie for object
};
+/**
+ * This implements a special read stream for the y222.avi video
+ * that fixes that totalFrames field of the header from it's
+ * incorrect value of 1 to a correct 1085.
+ */
+class y222 : virtual public Common::SeekableReadStream {
+private:
+ File *_innerStream;
+public:
+ y222();
+ virtual ~y222();
+
+ virtual uint32 read(void *dataPtr, uint32 dataSize);
+ virtual bool eos() const { return _innerStream->eos(); }
+ virtual int32 pos() const { return _innerStream->pos(); }
+ virtual int32 size() const { return _innerStream->size(); }
+ virtual bool seek(int32 offset, int whence = SEEK_SET) {
+ return _innerStream->seek(offset, whence);
+ }
+ virtual bool skip(uint32 offset) {
+ return _innerStream->skip(offset);
+ }
+ virtual char *readLine(char *s, size_t bufSize) {
+ return _innerStream->readLine(s, bufSize);
+ }
+ virtual Common::String readLine() {
+ return _innerStream->readLine();
+ }
+};
+
+
class AVIDecoder : public Video::AVIDecoder {
public:
AVIDecoder() {}
@@ -72,7 +104,7 @@ private:
CMovieRangeInfoList _movieRangeInfo;
int _streamCount;
Graphics::ManagedSurface *_movieFrameSurface[2];
- Graphics::ManagedSurface *_framePixels;
+ bool _framePixels;
double _frameRate;
int _currentFrame, _priorFrame;
uint32 _priorFrameTime;
@@ -152,6 +184,13 @@ public:
}
/**
+ * Sets whether the video is playing (versus paused)
+ */
+ virtual void setPlaying(bool playingFlag) {
+ _decoder->pauseVideo(!playingFlag);
+ }
+
+ /**
* Handle any movie events relevent for the frame
*/
virtual bool handleEvents(CMovieEventList &events);
diff --git a/engines/titanic/support/direct_draw.cpp b/engines/titanic/support/direct_draw.cpp
index 71a90ad00d..9559480a3b 100644
--- a/engines/titanic/support/direct_draw.cpp
+++ b/engines/titanic/support/direct_draw.cpp
@@ -64,6 +64,8 @@ DirectDrawManager::DirectDrawManager(TitanicEngine *vm, bool windowed) {
void DirectDrawManager::initVideo(int width, int height, int bpp, int numBackSurfaces) {
debugC(DEBUG_BASIC, kDebugGraphics, "Initialising video surfaces");
+ assert(numBackSurfaces == 0);
+
_directDraw._width = width;
_directDraw._numBackSurfaces = numBackSurfaces;
_directDraw._height = height;
@@ -81,10 +83,9 @@ void DirectDrawManager::initFullScreen() {
_directDraw.setDisplayMode(_directDraw._width, _directDraw._height,
_directDraw._bpp, 0);
+ // Set up the main surface to point to the screen
_mainSurface = new DirectDrawSurface();
_mainSurface->create(g_vm->_screen);
- _backSurfaces[0] = new DirectDrawSurface();
- _backSurfaces[0]->create(_directDraw._width, _directDraw._height, 32);
}
DirectDrawSurface *DirectDrawManager::createSurface(int w, int h, int bpp, int surfaceNum) {
diff --git a/engines/titanic/support/exe_resources.cpp b/engines/titanic/support/exe_resources.cpp
index 2b2c9c7635..b216ea5c26 100644
--- a/engines/titanic/support/exe_resources.cpp
+++ b/engines/titanic/support/exe_resources.cpp
@@ -27,12 +27,12 @@
namespace Titanic {
CExeResources::CExeResources() : _owner(nullptr), _field4(0), _field8(0),
- _fieldC(0), _field10(0), _field14(0), _field18(0) {
+ _fieldC(0), _field10(0), _field14(0), _vocabMode(VOCAB_MODE_NONE) {
}
-void CExeResources::reset(CScriptHandler *owner, int val1, int val2) {
+void CExeResources::reset(CScriptHandler *owner, int val1, VocabMode vocabMode) {
_owner = owner;
- _field18 = val2;
+ _vocabMode = vocabMode;
}
} // End of namespace Titanic
diff --git a/engines/titanic/support/exe_resources.h b/engines/titanic/support/exe_resources.h
index 993c34db97..382df39984 100644
--- a/engines/titanic/support/exe_resources.h
+++ b/engines/titanic/support/exe_resources.h
@@ -29,6 +29,8 @@ class CScriptHandler;
enum FileHandle { HANDLE_STDIN = 0, HANDLE_STDOUT = 1, HANDLE_STDERR = 2 };
+enum VocabMode { VOCAB_MODE_NONE = 0, VOCAB_MODE_EN = 3, VOCAB_MODE_DE = 5 };
+
class CExeResources {
public:
CScriptHandler *_owner;
@@ -37,14 +39,21 @@ public:
int _fieldC;
int _field10;
int _field14;
- int _field18;
+ VocabMode _vocabMode;
public:
CExeResources();
- void reset(CScriptHandler *owner, int val1, int val2);
+ void reset(CScriptHandler *owner, int val1, VocabMode vocabMode);
+
+ /**
+ * Tests whether the vocab mode equals the passed mode
+ */
+ bool isVocabMode(int mode) const { return _vocabMode == mode; }
- bool is18Equals(int val) const { return _field18 == val; }
- int get18() const { return _field18; }
+ /**
+ * Returns the vocab mode
+ */
+ VocabMode getVocabMode() const { return _vocabMode; }
};
} // End of namespace Titanic
diff --git a/engines/titanic/support/fixed_queue.h b/engines/titanic/support/fixed_queue.h
new file mode 100644
index 0000000000..dbcbeb669c
--- /dev/null
+++ b/engines/titanic/support/fixed_queue.h
@@ -0,0 +1,143 @@
+/* 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 TITANIC_FIXED_QUEUE_H
+#define TITANIC_FIXED_QUEUE_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+
+namespace Titanic {
+
+/**
+ * Extremly simple fixed size queue class.
+ */
+template<class T, uint MAX_SIZE = 10>
+class FixedQueue {
+ typedef uint size_type;
+protected:
+ Common::Array<T> _data;
+ size_type _topIndex;
+public:
+ FixedQueue<T, MAX_SIZE>() : _topIndex(0) {
+ _data.reserve(MAX_SIZE);
+ }
+
+ /**
+ * Returns the size of the queue in use
+ */
+ size_type size() const { return _data.size() - _topIndex; }
+
+ /**
+ * Returns the amount of free remaining space in the queue
+ */
+ size_type freeSize() const { return MAX_SIZE - size(); }
+
+ /**
+ * Returns true if the queue is empty
+ */
+ bool empty() const {
+ return size() == 0;
+ }
+
+ /**
+ * Returns true if the queue is full
+ */
+ bool full() const {
+ return freeSize() == 0;
+ }
+
+ /**
+ * Clears the queue
+ */
+ void clear() {
+ _data.clear();
+ _topIndex = 0;
+ }
+
+ /**
+ * If the tail of the queue in use has reached the end of the internal
+ * array, pushes all pending data back to the start of the array
+ */
+ void compact() {
+ if (_data.size() == MAX_SIZE && _topIndex > 0) {
+ if (_topIndex < MAX_SIZE)
+ Common::copy(&_data[_topIndex], &_data[0] + MAX_SIZE, &_data[0]);
+ _data.resize(size());
+ _topIndex = 0;
+ }
+ }
+
+ /**
+ * Adds a value to the end of the queue
+ */
+ void push(const T &v) {
+ assert(size() < MAX_SIZE);
+ compact();
+ _data.push_back(v);
+ }
+
+ /**
+ * Returns the top value on the queue
+ */
+ const T &top() const {
+ assert(size() > 0);
+ return _data[_topIndex];
+ }
+
+ /**
+ * Returns the top value on the queue
+ */
+ T &top() {
+ assert(size() > 0);
+ return _data[_topIndex];
+ }
+
+ /**
+ * Pops the top value off the queue
+ */
+ T pop() {
+ T tmp = top();
+ ++_topIndex;
+ return tmp;
+ }
+
+ /**
+ * Returns values from within the queue without popping them
+ */
+ T &operator[](size_type i) {
+ assert(i < size());
+ return _data[_topIndex + i];
+ }
+
+ /**
+ * Returns values from within the queue without popping them
+ */
+ const T &operator[](size_type i) const {
+ assert(i < size());
+ return _data[_topIndex + i];
+ }
+};
+
+} // End of namespace Titanic
+
+#endif
diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp
index 56e7b7e6f2..8c130ddb6f 100644
--- a/engines/titanic/support/movie.cpp
+++ b/engines/titanic/support/movie.cpp
@@ -40,8 +40,7 @@ namespace Titanic {
CMovieList *CMovie::_playingMovies;
CVideoSurface *CMovie::_movieSurface;
-CMovie::CMovie() : ListItem(), _handled(false), _hasVideoFrame(false),
- _hasAudioTiming(false) {
+CMovie::CMovie() : ListItem(), _handled(false), _hasVideoFrame(false) {
}
CMovie::~CMovie() {
@@ -200,6 +199,10 @@ void OSMovie::setFrameRate(double rate) {
_aviSurface.setFrameRate(rate);
}
+void OSMovie::setPlaying(bool playingFlag) {
+ _aviSurface.setPlaying(playingFlag);
+}
+
Graphics::ManagedSurface *OSMovie::duplicateTransparency() const {
return _aviSurface.duplicateTransparency();
}
diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h
index cedf7c4d20..36a76654e4 100644
--- a/engines/titanic/support/movie.h
+++ b/engines/titanic/support/movie.h
@@ -50,7 +50,6 @@ protected:
public:
bool _handled;
bool _hasVideoFrame;
- bool _hasAudioTiming;
public:
static CMovieList *_playingMovies;
static CVideoSurface *_movieSurface;
@@ -139,6 +138,11 @@ public:
virtual void setFrameRate(double rate) = 0;
/**
+ * Sets whether the video is playing (versus paused)
+ */
+ virtual void setPlaying(bool playingFlag) = 0;
+
+ /**
* Creates a duplicate of the transparency surface
*/
virtual Graphics::ManagedSurface *duplicateTransparency() const = 0;
@@ -247,6 +251,11 @@ public:
virtual void setFrameRate(double rate);
/**
+ * Sets whether the video is playing (versus paused)
+ */
+ virtual void setPlaying(bool playingFlag);
+
+ /**
* Creates a duplicate of the transparency surface
*/
virtual Graphics::ManagedSurface *duplicateTransparency() const;