[Scummvm-git-logs] scummvm master -> 8b4a1a7660415979d5b4830100ecc188bbcb5105

dreammaster dreammaster at scummvm.org
Tue Nov 29 04:52:07 CET 2016


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
8b4a1a7660 TITANIC: Transparency in movie frames now working


Commit: 8b4a1a7660415979d5b4830100ecc188bbcb5105
    https://github.com/scummvm/scummvm/commit/8b4a1a7660415979d5b4830100ecc188bbcb5105
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2016-11-28T22:50:22-05:00

Commit Message:
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.

Changed paths:
    engines/titanic/game_manager.cpp
    engines/titanic/star_control/surface_fader_base.cpp
    engines/titanic/support/avi_surface.cpp
    engines/titanic/support/avi_surface.h
    engines/titanic/support/mouse_cursor.cpp
    engines/titanic/support/movie.cpp
    engines/titanic/support/screen_manager.h


diff --git a/engines/titanic/game_manager.cpp b/engines/titanic/game_manager.cpp
index d554067..9e107c9 100644
--- a/engines/titanic/game_manager.cpp
+++ b/engines/titanic/game_manager.cpp
@@ -39,7 +39,7 @@ CGameManager::CGameManager(CProjectItem *project, CGameView *gameView, Audio::Mi
 
 	CTimeEventInfo::_nextId = 0;
 	_movie = nullptr;
-	_movieSurface = CScreenManager::_screenManagerPtr->createSurface(600, 340, 16);
+	_movieSurface = CScreenManager::_screenManagerPtr->createSurface(600, 340);
 	_project->setGameManager(this);
 	g_vm->_filesManager->setGameManager(this);
 }
@@ -264,7 +264,7 @@ void CGameManager::viewChange() {
 	delete _movieSurface;
 
 	_movie = nullptr;
-	_movieSurface = CScreenManager::_screenManagerPtr->createSurface(600, 340, 16);
+	_movieSurface = CScreenManager::_screenManagerPtr->createSurface(600, 340);
 	_trueTalkManager.clear();
 
 	for (CTreeItem *treeItem = _project; treeItem; treeItem = treeItem->scan(_project))
diff --git a/engines/titanic/star_control/surface_fader_base.cpp b/engines/titanic/star_control/surface_fader_base.cpp
index 57754c1..fb17fb1 100644
--- a/engines/titanic/star_control/surface_fader_base.cpp
+++ b/engines/titanic/star_control/surface_fader_base.cpp
@@ -49,7 +49,7 @@ bool CSurfaceFaderBase::setupSurface(CScreenManager *screenManager, CVideoSurfac
 		delete _videoSurface;
 	}
 
-	_videoSurface = screenManager->createSurface(width, height, 16);
+	_videoSurface = screenManager->createSurface(width, height);
 	return true;
 }
 
diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp
index 8ed87a2..d05ad64 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 855732f..4ee6cc6 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 e72e928..6300f65 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 5e59ed7..8863e94 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 0da8e0d..a7c929f 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





More information about the Scummvm-git-logs mailing list