TITANIC: Making the AVISurface frameInfo a video surface

This commit is contained in:
Paul Gilbert 2016-07-12 08:38:26 -04:00
parent c458c3c9b7
commit 513723c82d
10 changed files with 129 additions and 63 deletions

View File

@ -275,7 +275,7 @@ bool CGameObject::checkPoint(const Point &pt, bool ignore40, bool visibleOnly) {
}
Common::Point pixelPos = pt - _bounds;
if (_surface->_blitStyleFlag) {
if (_surface->_transBlitFlag) {
pixelPos.y = ((_bounds.height() - _bounds.top) / 2) * 2 - pixelPos.y;
}

View File

@ -57,7 +57,7 @@ void CGameView::createSurface(const CResourceKey &key) {
// Create a fresh surface
CScreenManager::setCurrent();
_surface = CScreenManager::_currentScreenManagerPtr->createSurface(key);
_surface->_blitFlag = true;
_surface->_fastBlitFlag = true;
}
void CGameView::drawView() {

View File

@ -21,11 +21,20 @@
*/
#include "titanic/support/avi_surface.h"
#include "titanic/support/screen_manager.h"
#include "titanic/support/video_surface.h"
#include "video/avi_decoder.h"
namespace Titanic {
Video::AVIDecoder::AVIVideoTrack &AVIDecoder::getVideoTrack() {
for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++)
if ((*it)->getTrackType() == Track::kTrackTypeVideo)
return *static_cast<AVIVideoTrack *>(*it);
error("Could not find video track");
}
/**
* Track filter for AVIDecoder that filters out any secondary video track
*/
@ -43,21 +52,19 @@ static bool secondaryTrackSelect(bool isVideo, int trackCounter) {
AVISurface::AVISurface(const CResourceKey &key) {
_videoSurface = nullptr;
_field4 = 0;
_field8 = 0;
_currentPos = 0;
_priorFrame = 0;
_streamCount = 0;
_frameInfo = nullptr;
_movieFrameSurface[0] = _movieFrameSurface[1] = nullptr;
_isPlaying = false;
// Create a decoder for the audio (if any) and primary video track
_decoders[0] = new Video::AVIDecoder(Audio::Mixer::kPlainSoundType, primaryTrackSelect);
_decoders[0] = new AVIDecoder(Audio::Mixer::kPlainSoundType, primaryTrackSelect);
if (!_decoders[0]->loadFile(key.getString()))
error("Could not open video - %s", key.getString().c_str());
// Create a decoder for any secondary video track
Video::AVIDecoder *decoder2 = new Video::AVIDecoder(Audio::Mixer::kPlainSoundType, secondaryTrackSelect);
AVIDecoder *decoder2 = new AVIDecoder(Audio::Mixer::kPlainSoundType, secondaryTrackSelect);
if (decoder2->loadFile(key.getString())) {
_decoders[1] = decoder2;
} else {
@ -67,8 +74,9 @@ AVISurface::AVISurface(const CResourceKey &key) {
AVISurface::~AVISurface() {
if (_videoSurface)
_videoSurface->_blitStyleFlag = false;
delete _frameInfo;
_videoSurface->_transBlitFlag = false;
delete _movieFrameSurface[0];
delete _movieFrameSurface[1];
delete _decoders[0];
delete _decoders[1];
}
@ -187,7 +195,37 @@ bool AVISurface::handleEvents(CMovieEventList &events) {
void AVISurface::setVideoSurface(CVideoSurface *surface) {
_videoSurface = surface;
warning("TODO: Get video track list from video decoder");
// Handling for secondary video stream
if (_decoders[1]) {
const Common::String &streamName = _decoders[1]->getVideoTrack().getName();
if (streamName == "mask0") {
_videoSurface->_transparencyMode = TRANS_MASK0;
} else if (streamName == "mask255") {
_videoSurface->_transparencyMode = TRANS_MASK255;
} else if (streamName == "alpha0") {
_videoSurface->_transparencyMode = TRANS_ALPHA0;
} else if (streamName == "alpha255") {
_videoSurface->_transparencyMode = TRANS_ALPHA255;
}
}
setupDecompressor();
}
void AVISurface::setupDecompressor() {
for (int idx = 0; idx < 2; ++idx) {
if (!_decoders[idx])
continue;
AVIDecoder &decoder = *_decoders[idx];
// Setup frame surface
_movieFrameSurface[idx] = CScreenManager::_screenManagerPtr->createSurface(decoder.getWidth(), decoder.getHeight());
// TODO: See whether this simplified form of original works
if (idx == 2)
_videoSurface->_transBlitFlag = true;
}
}
uint AVISurface::getWidth() const {
@ -260,9 +298,14 @@ void AVISurface::setFrameRate(double rate) {
}
}
void *AVISurface::duplicateFrameInfo() const {
// TODO
return nullptr;
CVideoSurface *AVISurface::getSecondarySurface() {
return _streamCount <= 1 ? nullptr : _movieFrameSurface[1];
}
CVideoSurface *AVISurface::duplicateSecondaryFrame() const {
// TODO: Make this cleaner
OSVideoSurface *src = dynamic_cast<OSVideoSurface *>(_movieFrameSurface[1]);
return new OSVideoSurface(*src);
}
} // End of namespace Titanic

View File

@ -37,22 +37,35 @@ enum MovieFlag {
MOVIE_REVERSE = 8, MOVIE_GAMESTATE = 0x10
};
class AVIDecoder : public Video::AVIDecoder {
public:
AVIDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType, SelectTrackFn trackFn = nullptr) :
Video::AVIDecoder(soundType, trackFn) {}
AVIDecoder(const Common::Rational &frameRateOverride, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType,
SelectTrackFn trackFn = nullptr) : Video::AVIDecoder(frameRateOverride, soundType, trackFn) {}
Video::AVIDecoder::AVIVideoTrack &getVideoTrack();
};
class AVISurface {
private:
Video::AVIDecoder *_decoders[2];
AVIDecoder *_decoders[2];
CVideoSurface *_videoSurface;
int _field4;
int _field8;
int _currentPos;
int _priorFrame;
CMovieRangeInfoList _movieRangeInfo;
int _streamCount;
void *_frameInfo;
CVideoSurface *_movieFrameSurface[2];
private:
/**
* Render a frame to the video surface
*/
bool renderFrame();
/**
* Sets up for video decompression
*/
void setupDecompressor();
protected:
/**
* Change the frame with ??? checking
@ -132,9 +145,10 @@ public:
*/
void setFrameRate(double rate);
const void *getFrameInfo() const {
return _streamCount <= 1 ? nullptr : _frameInfo;
}
/**
* Returns the surface for the secondary video track frame, if present
*/
CVideoSurface *getSecondarySurface();
/**
* Get a reference to the movie range info list
@ -144,9 +158,9 @@ public:
}
/**
* Duplicate the frame info
* Duplicates the secondary frame, if the movie has a second video track
*/
void *duplicateFrameInfo() const;
CVideoSurface *duplicateSecondaryFrame() const;
};
} // End of namespace Titanic

View File

@ -50,6 +50,11 @@ static const int CURSOR_DATA[NUM_CURSORS][4] = {
{ 15, 138, 20, 28 }
};
CMouseCursor::CursorEntry::~CursorEntry() {
delete _videoSurface;
delete _frameSurface;
}
CMouseCursor::CMouseCursor(CScreenManager *screenManager) :
_screenManager(screenManager), _cursorId(CURSOR_HOURGLASS),
_setCursorCount(0), _fieldE4(0), _fieldE8(0) {
@ -80,9 +85,9 @@ void CMouseCursor::loadCursorImages() {
OSMovie movie(key, surface);
movie.setFrame(idx);
void *frameInfo = movie.duplicateFrameInfo();
_cursors[idx]._frameInfo = frameInfo;
surface->setMovieFrameInfo(frameInfo);
CVideoSurface *frameSurface = movie.duplicateFrame();
_cursors[idx]._frameSurface = frameSurface;
surface->setMovieFrameSurface(frameSurface);
}
}

View File

@ -54,11 +54,11 @@ class CVideoSurface;
class CMouseCursor {
struct CursorEntry {
CVideoSurface *_videoSurface;
void *_frameInfo;
CVideoSurface *_frameSurface;
Common::Point _centroid;
CursorEntry() : _videoSurface(nullptr), _frameInfo(nullptr) {}
~CursorEntry() { delete _frameInfo; }
CursorEntry() : _videoSurface(nullptr), _frameSurface(nullptr) {}
~CursorEntry();
};
private:
CScreenManager *_screenManager;

View File

@ -159,7 +159,7 @@ void OSMovie::addEvent(int frameNumber, CGameObject *obj) {
void OSMovie::setFrame(uint frameNumber) {
_aviSurface.setFrame(frameNumber);
_videoSurface->setMovieFrame(frameNumber);
_videoSurface->setMovieFrameSurface(_aviSurface.getSecondarySurface());
}
bool OSMovie::handleEvents(CMovieEventList &events) {
@ -175,12 +175,12 @@ bool OSMovie::handleEvents(CMovieEventList &events) {
_frameTime1 += _frameTime2;
_aviSurface.handleEvents(events);
_videoSurface->setMovieFrameInfo(_aviSurface.getFrameInfo());
_videoSurface->setMovieFrameSurface(_aviSurface.getSecondarySurface());
if (_field14) {
while (_frameTime1 >= time && events.empty()) {
_aviSurface.handleEvents(events);
_videoSurface->setMovieFrameInfo(_aviSurface.getFrameInfo());
_videoSurface->setMovieFrameSurface(_aviSurface.getSecondarySurface());
_frameTime1 += _frameTime2;
}
@ -217,8 +217,8 @@ void OSMovie::setFrameRate(double rate) {
_aviSurface.setFrameRate(rate);
}
void *OSMovie::duplicateFrameInfo() const {
return _aviSurface.duplicateFrameInfo();
CVideoSurface *OSMovie::duplicateFrame() const {
return _aviSurface.duplicateSecondaryFrame();
}
} // End of namespace Titanic

View File

@ -133,9 +133,9 @@ public:
virtual void setFrameRate(double rate) = 0;
/**
* Creates a duplicate of the frame info
* Creates a duplicate of the movie's frame
*/
virtual void *duplicateFrameInfo() const = 0;
virtual CVideoSurface *duplicateFrame() const = 0;
/**
* Removes the movie from the list of currently playing movies
@ -233,7 +233,7 @@ public:
/**
* Creates a duplicate of the frame info
*/
virtual void *duplicateFrameInfo() const;
virtual CVideoSurface *duplicateFrame() const;
};
} // End of namespace Titanic

View File

@ -31,8 +31,8 @@ int CVideoSurface::_videoSurfaceCounter = 0;
CVideoSurface::CVideoSurface(CScreenManager *screenManager) :
_screenManager(screenManager), _rawSurface(nullptr), _movie(nullptr),
_pendingLoad(false), _blitStyleFlag(false), _blitFlag(false),
_movieFrameInfo(nullptr), _transparencyMode(TRANS_DEFAULT), _field48(0), _field50(1) {
_pendingLoad(false), _transBlitFlag(false), _fastBlitFlag(false),
_movieFrameSurface(nullptr), _transparencyMode(TRANS_DEFAULT), _field48(0), _field50(1) {
_videoSurfaceNum = _videoSurfaceCounter++;
}
@ -52,10 +52,10 @@ void CVideoSurface::blitFrom(const Point &destPos, CVideoSurface *src, const Rec
Rect srcBounds, destBounds;
clipBounds(srcBounds, destBounds, src, srcRect, &destPos);
if (_blitStyleFlag)
blitRect2(srcBounds, destBounds, src);
if (_transBlitFlag)
transBlitRect(srcBounds, destBounds, src);
else
blitRect1(srcBounds, destBounds, src);
blitRect(srcBounds, destBounds, src);
}
}
@ -128,21 +128,25 @@ void CVideoSurface::clipBounds(Rect &srcRect, Rect &destRect,
error("Invalid rect");
}
void CVideoSurface::blitRect1(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) {
void CVideoSurface::blitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) {
src->lock();
lock();
// TODO: Do it like the original does it
_rawSurface->transBlitFrom(*src->_rawSurface, srcRect, destRect,
getTransparencyColor());
if (_fastBlitFlag) {
_rawSurface->transBlitFrom(*src->_rawSurface, srcRect, destRect,
getTransparencyColor());
return;
}
// TODO
src->unlock();
unlock();
}
void CVideoSurface::blitRect2(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) {
void CVideoSurface::transBlitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) {
// TODO: Do it like the original does it
blitRect1(srcRect, destRect, src);
blitRect(srcRect, destRect, src);
}
uint CVideoSurface::getTransparencyColor() {
@ -471,7 +475,7 @@ const CMovieRangeInfoList *OSVideoSurface::getMovieRangeInfo() const {
}
void OSVideoSurface::flipVertically(bool needsLock) {
if (!loadIfReady() || !_blitStyleFlag)
if (!loadIfReady() || !_transBlitFlag)
return;
if (needsLock)
@ -490,7 +494,7 @@ void OSVideoSurface::flipVertically(bool needsLock) {
Common::copy(lineBuffer, lineBuffer + pitch, line1P);
}
_blitStyleFlag = false;
_transBlitFlag = false;
if (needsLock)
unlock();
}
@ -537,8 +541,8 @@ void OSVideoSurface::transPixelate() {
unlock();
}
void *OSVideoSurface::dupMovieFrameInfo() const {
return _movie ? _movie->duplicateFrameInfo() : nullptr;
CVideoSurface *OSVideoSurface::dupMovieFrame() const {
return _movie ? _movie->duplicateFrame() : nullptr;
}
int OSVideoSurface::freeSurface() {

View File

@ -54,15 +54,15 @@ private:
void clipBounds(Rect &srcRect, Rect &destRect, CVideoSurface *srcSurface,
const Rect *subRect = nullptr, const Point *destPos = nullptr);
void blitRect1(const Rect &srcRect, const Rect &destRect, CVideoSurface *src);
void blitRect2(const Rect &srcRect, const Rect &destRect, CVideoSurface *src);
void blitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src);
void transBlitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src);
protected:
static int _videoSurfaceCounter;
protected:
CScreenManager *_screenManager;
Graphics::ManagedSurface *_rawSurface;
bool _pendingLoad;
const void *_movieFrameInfo;
CVideoSurface *_movieFrameSurface;
int _field48;
int _videoSurfaceNum;
int _field50;
@ -70,8 +70,8 @@ protected:
public:
CMovie *_movie;
DirectDrawSurface *_ddSurface;
bool _blitFlag;
bool _blitStyleFlag;
bool _fastBlitFlag;
bool _transBlitFlag;
CResourceKey _resourceKey;
TransparencyMode _transparencyMode;
public:
@ -258,9 +258,9 @@ public:
virtual bool proc45();
/**
* Duplicates movie frame info
*/
virtual void *dupMovieFrameInfo() const = 0;
* Duplicates movie frame surface
*/
virtual CVideoSurface *dupMovieFrame() const = 0;
/**
* Frees the underlying surface
@ -285,11 +285,11 @@ public:
/**
*
*/
void setMovieFrameInfo(const void *frameInfo) { _movieFrameInfo = frameInfo; }
void setMovieFrameSurface(CVideoSurface *frameSurface) { _movieFrameSurface = frameSurface; }
/**
*/
const void *getMovieFrameInfo() const { return _movieFrameInfo; }
CVideoSurface *getMovieFrameSurface() const { return _movieFrameSurface; }
/**
* Get the pixels associated with the surface. Only valid when the
@ -497,9 +497,9 @@ public:
virtual void transPixelate();
/**
* Duplicates movie frame info
* Duplicates movie frame surface
*/
virtual void *dupMovieFrameInfo() const;
virtual CVideoSurface *dupMovieFrame() const;
/**