aboutsummaryrefslogtreecommitdiff
path: root/engines/titanic/support
diff options
context:
space:
mode:
authorPaul Gilbert2016-11-28 22:50:22 -0500
committerPaul Gilbert2016-11-28 22:50:22 -0500
commit8b4a1a7660415979d5b4830100ecc188bbcb5105 (patch)
tree5614ebfc5a6e7b5112f2e51f8151a08b1df8c589 /engines/titanic/support
parent8c453693914b9141277908a5c1d0b184d7ac9a9b (diff)
downloadscummvm-rg350-8b4a1a7660415979d5b4830100ecc188bbcb5105.tar.gz
scummvm-rg350-8b4a1a7660415979d5b4830100ecc188bbcb5105.tar.bz2
scummvm-rg350-8b4a1a7660415979d5b4830100ecc188bbcb5105.zip
TITANIC: Transparency in movie frames now working
Turns out the movie frames didn't need to be 32-bit, it just needed custom copying code to replace transparent pixels with the transparency color, so when blitted to the screen, the pixels aren't drawn.
Diffstat (limited to 'engines/titanic/support')
-rw-r--r--engines/titanic/support/avi_surface.cpp56
-rw-r--r--engines/titanic/support/avi_surface.h10
-rw-r--r--engines/titanic/support/mouse_cursor.cpp2
-rw-r--r--engines/titanic/support/movie.cpp5
-rw-r--r--engines/titanic/support/screen_manager.h8
5 files changed, 58 insertions, 23 deletions
diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp
index 8ed87a2340..d05ad64e8c 100644
--- a/engines/titanic/support/avi_surface.cpp
+++ b/engines/titanic/support/avi_surface.cpp
@@ -265,6 +265,33 @@ void AVISurface::setupDecompressor() {
}
}
+void AVISurface::copyMovieFrame(const Graphics::Surface &src, Graphics::ManagedSurface &dest) {
+ assert(src.w == dest.w && src.h == dest.h);
+
+ if (src.format.bytesPerPixel == 1) {
+ Graphics::Surface *s = src.convertTo(dest.format, _decoder->getPalette());
+ dest.blitFrom(*s);
+ s->free();
+ delete s;
+ } else {
+ byte a, r, g, b;
+ assert(src.format.bytesPerPixel == 4 && dest.format.bytesPerPixel == 2);
+ uint16 transPixel = _videoSurface->getTransparencyColor();
+
+ for (uint y = 0; y < src.h; ++y) {
+ const uint32 *pSrc = (const uint32 *)src.getBasePtr(0, y);
+ uint16 *pDest = (uint16 *)dest.getBasePtr(0, y);
+
+ for (uint x = 0; x < src.w; ++x, ++pSrc, ++pDest) {
+ src.format.colorToARGB(*pSrc, a, r, g, b);
+ assert(a == 0 || a == 0xff);
+
+ *pDest = (a == 0) ? transPixel : dest.format.RGBToColor(r, g, b);
+ }
+ }
+ }
+}
+
uint AVISurface::getWidth() const {
return _decoder->getWidth();
}
@@ -309,23 +336,22 @@ bool AVISurface::renderFrame() {
// Make a copy of each decoder's video frame
for (int idx = 0; idx < _streamCount; ++idx) {
- const Graphics::Surface *frame = (idx == 0) ?
- _decoder->decodeNextFrame() : _decoder->decodeNextTransparency();
+ const Graphics::Surface *frame;
- if (!_movieFrameSurface[idx]) {
- // Setup frame surface
- _movieFrameSurface[idx] = new Graphics::ManagedSurface(_decoder->getWidth(), _decoder->getHeight(),
- _decoder->getVideoTrack(idx).getPixelFormat());
- }
+ if (idx == 0) {
+ frame = _decoder->decodeNextFrame();
+ if (!_movieFrameSurface[0])
+ _movieFrameSurface[0] = new Graphics::ManagedSurface(_decoder->getWidth(), _decoder->getHeight(),
+ g_system->getScreenFormat());
- if (_movieFrameSurface[idx]->format == frame->format) {
- _movieFrameSurface[idx]->blitFrom(*frame);
+ copyMovieFrame(*frame, *_movieFrameSurface[0]);
} else {
- Graphics::Surface *s = frame->convertTo(_movieFrameSurface[idx]->format,
- _decoder->getPalette());
- _movieFrameSurface[idx]->blitFrom(*s);
- s->free();
- delete s;
+ frame = _decoder->decodeNextTransparency();
+ if (!_movieFrameSurface[1])
+ _movieFrameSurface[1] = new Graphics::ManagedSurface(_decoder->getWidth(), _decoder->getHeight(),
+ Graphics::PixelFormat::createFormatCLUT8());
+
+ _movieFrameSurface[1]->blitFrom(*frame);
}
}
@@ -397,7 +423,7 @@ Graphics::ManagedSurface *AVISurface::duplicateTransparency() const {
return nullptr;
} else {
Graphics::ManagedSurface *dest = new Graphics::ManagedSurface(_movieFrameSurface[1]->w,
- _movieFrameSurface[1]->h, _movieFrameSurface[1]->format);
+ _movieFrameSurface[1]->h, Graphics::PixelFormat::createFormatCLUT8());
dest->blitFrom(*_movieFrameSurface[1]);
return dest;
}
diff --git a/engines/titanic/support/avi_surface.h b/engines/titanic/support/avi_surface.h
index 855732f5cb..4ee6cc6e0b 100644
--- a/engines/titanic/support/avi_surface.h
+++ b/engines/titanic/support/avi_surface.h
@@ -78,6 +78,16 @@ private:
* Sets up for video decompression
*/
void setupDecompressor();
+
+ /**
+ * Copys a movie frame into a local 16-bit frame surface
+ * @param src Source raw movie frame
+ * @param dest Destination 16-bit copy of the frame
+ * @remarks The important thing this methods different from a straight
+ * copy is that any pixels marked as fully transparent are replaced with
+ * the special transparent color value.
+ */
+ void copyMovieFrame(const Graphics::Surface &src, Graphics::ManagedSurface &dest);
protected:
/**
* Start playback at the specified frame
diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp
index e72e928e67..6300f65a3b 100644
--- a/engines/titanic/support/mouse_cursor.cpp
+++ b/engines/titanic/support/mouse_cursor.cpp
@@ -74,7 +74,7 @@ void CMouseCursor::loadCursorImages() {
CURSOR_DATA[idx][3]);
// Create the surface
- CVideoSurface *surface = _screenManager->createSurface(CURSOR_SIZE, CURSOR_SIZE, 16);
+ CVideoSurface *surface = _screenManager->createSurface(CURSOR_SIZE, CURSOR_SIZE);
_cursors[idx]._videoSurface = surface;
// Open the cursors video and move to the given frame
diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp
index 5e59ed747b..8863e94e14 100644
--- a/engines/titanic/support/movie.cpp
+++ b/engines/titanic/support/movie.cpp
@@ -88,8 +88,7 @@ OSMovie::OSMovie(const CResourceKey &name, CVideoSurface *surface) :
_field28 = 0;
_field2C = 0;
- surface->resize(_aviSurface.getWidth(), _aviSurface.getHeight(),
- _aviSurface.getBitDepth() == 32 ? 32 : 16);
+ surface->resize(_aviSurface.getWidth(), _aviSurface.getHeight());
_aviSurface.setVideoSurface(surface);
}
@@ -119,7 +118,7 @@ void OSMovie::play(uint startFrame, uint endFrame, uint initialFrame, uint flags
void OSMovie::playCutscene(const Rect &drawRect, uint startFrame, uint endFrame) {
if (!_movieSurface)
- _movieSurface = CScreenManager::_screenManagerPtr->createSurface(600, 340, 16);
+ _movieSurface = CScreenManager::_screenManagerPtr->createSurface(600, 340, 32);
// Set a new event target whilst the clip plays, so standard scene drawing isn't called
CEventTarget eventTarget;
diff --git a/engines/titanic/support/screen_manager.h b/engines/titanic/support/screen_manager.h
index 0da8e0daf3..a7c929fb5f 100644
--- a/engines/titanic/support/screen_manager.h
+++ b/engines/titanic/support/screen_manager.h
@@ -185,12 +185,12 @@ public:
/**
* Resize the passed surface
*/
- virtual void resizeSurface(CVideoSurface *surface, int width, int height, int bpp) = 0;
+ virtual void resizeSurface(CVideoSurface *surface, int width, int height, int bpp = 16) = 0;
/**
* Creates a surface of a given size
*/
- virtual CVideoSurface *createSurface(int w, int h, int bpp) = 0;
+ virtual CVideoSurface *createSurface(int w, int h, int bpp = 16) = 0;
/**
* Creates a surface from a specified resource
@@ -367,12 +367,12 @@ public:
/**
* Resize the passed surface
*/
- virtual void resizeSurface(CVideoSurface *surface, int width, int height, int bpp);
+ virtual void resizeSurface(CVideoSurface *surface, int width, int height, int bpp = 16);
/**
* Creates a surface of a given size
*/
- virtual CVideoSurface *createSurface(int w, int h, int bpp);
+ virtual CVideoSurface *createSurface(int w, int h, int bpp = 16);
/**
* Creates a surface from a specified resource