diff options
Diffstat (limited to 'engines/titanic/support')
-rw-r--r-- | engines/titanic/support/avi_surface.cpp | 45 | ||||
-rw-r--r-- | engines/titanic/support/avi_surface.h | 41 | ||||
-rw-r--r-- | engines/titanic/support/direct_draw.cpp | 5 | ||||
-rw-r--r-- | engines/titanic/support/exe_resources.cpp | 6 | ||||
-rw-r--r-- | engines/titanic/support/exe_resources.h | 17 | ||||
-rw-r--r-- | engines/titanic/support/fixed_queue.h | 143 | ||||
-rw-r--r-- | engines/titanic/support/movie.cpp | 7 | ||||
-rw-r--r-- | engines/titanic/support/movie.h | 11 |
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; |