aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2016-11-26 10:53:47 -0500
committerPaul Gilbert2016-11-26 15:25:20 -0500
commit63ec47e62f23e310786168cd596667015b2d2523 (patch)
tree0b5aca8f248a3d2c9e81a3411192dbd3ecc9894c
parent4e06799122c0b763d2a44f0ce46d2ab186bdab5d (diff)
downloadscummvm-rg350-63ec47e62f23e310786168cd596667015b2d2523.tar.gz
scummvm-rg350-63ec47e62f23e310786168cd596667015b2d2523.tar.bz2
scummvm-rg350-63ec47e62f23e310786168cd596667015b2d2523.zip
TITANIC: Add support for 32-bit surfaces
Some of the game videos have alpha levels, which are lost if the surfaces are converted to 16-bit. This adds better support for creating 32-bit video surfaces, so the information won't be lost
-rw-r--r--engines/titanic/game_manager.cpp4
-rw-r--r--engines/titanic/star_control/surface_fader_base.cpp2
-rw-r--r--engines/titanic/support/avi_surface.cpp8
-rw-r--r--engines/titanic/support/avi_surface.h6
-rw-r--r--engines/titanic/support/direct_draw.cpp8
-rw-r--r--engines/titanic/support/direct_draw.h2
-rw-r--r--engines/titanic/support/direct_draw_surface.cpp8
-rw-r--r--engines/titanic/support/direct_draw_surface.h6
-rw-r--r--engines/titanic/support/image_decoders.cpp4
-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.cpp8
-rw-r--r--engines/titanic/support/screen_manager.h8
-rw-r--r--engines/titanic/support/text_cursor.cpp2
-rw-r--r--engines/titanic/support/video_surface.cpp55
-rw-r--r--engines/titanic/support/video_surface.h8
16 files changed, 66 insertions, 70 deletions
diff --git a/engines/titanic/game_manager.cpp b/engines/titanic/game_manager.cpp
index 9e107c92b9..d554067717 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);
+ _movieSurface = CScreenManager::_screenManagerPtr->createSurface(600, 340, 16);
_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);
+ _movieSurface = CScreenManager::_screenManagerPtr->createSurface(600, 340, 16);
_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 fb17fb1f31..57754c1ba4 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);
+ _videoSurface = screenManager->createSurface(width, height, 16);
return true;
}
diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp
index 2a671156e0..8ed87a2340 100644
--- a/engines/titanic/support/avi_surface.cpp
+++ b/engines/titanic/support/avi_surface.cpp
@@ -36,7 +36,7 @@ Video::AVIDecoder::AVIVideoTrack &AVIDecoder::getVideoTrack(uint idx) {
return *track;
}
-AVISurface::AVISurface(const CResourceKey &key) {
+AVISurface::AVISurface(const CResourceKey &key) : _movieName(key.getString()) {
_videoSurface = nullptr;
_streamCount = 0;
_movieFrameSurface[0] = _movieFrameSurface[1] = nullptr;
@@ -51,7 +51,7 @@ AVISurface::AVISurface(const CResourceKey &key) {
// Create a decoder
_decoder = new AVIDecoder(Audio::Mixer::kPlainSoundType);
- if (!_decoder->loadFile(key.getString()))
+ if (!_decoder->loadFile(_movieName))
error("Could not open video - %s", key.getString().c_str());
_streamCount = _decoder->videoTrackCount();
@@ -437,4 +437,8 @@ void AVISurface::playCutscene(const Rect &r, uint startFrame, uint endFrame) {
stop();
}
+uint AVISurface::getBitDepth() const {
+ return _decoder->getVideoTrack(0).getBitCount();
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/support/avi_surface.h b/engines/titanic/support/avi_surface.h
index 2a4b321f0f..855732f5cb 100644
--- a/engines/titanic/support/avi_surface.h
+++ b/engines/titanic/support/avi_surface.h
@@ -67,6 +67,7 @@ private:
bool _isReversed;
int _currentFrame;
uint32 _priorFrameTime;
+ Common::String _movieName;
private:
/**
* Render a frame to the video surface
@@ -203,6 +204,11 @@ public:
* Plays an interruptable cutscene
*/
void playCutscene(const Rect &r, uint startFrame, uint endFrame);
+
+ /**
+ * Returns the pixel depth of the movie in bits
+ */
+ uint getBitDepth() const;
};
} // End of namespace Titanic
diff --git a/engines/titanic/support/direct_draw.cpp b/engines/titanic/support/direct_draw.cpp
index 8e510861ae..faed140ea7 100644
--- a/engines/titanic/support/direct_draw.cpp
+++ b/engines/titanic/support/direct_draw.cpp
@@ -47,7 +47,7 @@ void DirectDraw::diagnostics() {
DirectDrawSurface *DirectDraw::createSurfaceFromDesc(const DDSurfaceDesc &desc) {
DirectDrawSurface *surface = new DirectDrawSurface();
- surface->create(desc._w, desc._h);
+ surface->create(desc._w, desc._h, desc._bpp);
return surface;
}
@@ -82,15 +82,15 @@ void DirectDrawManager::initFullScreen() {
_mainSurface = new DirectDrawSurface();
_mainSurface->create(g_vm->_screen);
_backSurfaces[0] = new DirectDrawSurface();
- _backSurfaces[0]->create(_directDraw._width, _directDraw._height);
+ _backSurfaces[0]->create(_directDraw._width, _directDraw._height, 32);
}
-DirectDrawSurface *DirectDrawManager::createSurface(int w, int h, int surfaceNum) {
+DirectDrawSurface *DirectDrawManager::createSurface(int w, int h, int bpp, int surfaceNum) {
if (surfaceNum)
return nullptr;
assert(_mainSurface);
- return _directDraw.createSurfaceFromDesc(DDSurfaceDesc(w, h));
+ return _directDraw.createSurfaceFromDesc(DDSurfaceDesc(w, h, bpp));
}
} // End of namespace Titanic
diff --git a/engines/titanic/support/direct_draw.h b/engines/titanic/support/direct_draw.h
index 08ead6d798..8370191648 100644
--- a/engines/titanic/support/direct_draw.h
+++ b/engines/titanic/support/direct_draw.h
@@ -87,7 +87,7 @@ public:
/**
* Create a surface
*/
- DirectDrawSurface *createSurface(int w, int h, int surfaceNum);
+ DirectDrawSurface *createSurface(int w, int h, int bpp, int surfaceNum);
};
} // End of namespace Titanic
diff --git a/engines/titanic/support/direct_draw_surface.cpp b/engines/titanic/support/direct_draw_surface.cpp
index 9ebda15b0e..126cebfaeb 100644
--- a/engines/titanic/support/direct_draw_surface.cpp
+++ b/engines/titanic/support/direct_draw_surface.cpp
@@ -38,8 +38,12 @@ void DirectDrawSurface::create(Graphics::ManagedSurface *surface) {
_disposeAfterUse = DisposeAfterUse::NO;
}
-void DirectDrawSurface::create(int w, int h) {
- Graphics::PixelFormat pixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
+void DirectDrawSurface::create(int w, int h, int bpp) {
+ assert(bpp == 16 || bpp == 32);
+ Graphics::PixelFormat pixelFormat = (bpp == 32) ?
+ Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0) :
+ Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
+
_surface = new Graphics::ManagedSurface(w, h, pixelFormat);
_disposeAfterUse = DisposeAfterUse::YES;
}
diff --git a/engines/titanic/support/direct_draw_surface.h b/engines/titanic/support/direct_draw_surface.h
index af19e369d2..82749afffa 100644
--- a/engines/titanic/support/direct_draw_surface.h
+++ b/engines/titanic/support/direct_draw_surface.h
@@ -35,10 +35,12 @@ class TitanicEngine;
struct DDSurfaceDesc {
int _w;
int _h;
+ int _bpp;
int _flags;
int _caps;
- DDSurfaceDesc(int w, int h) : _w(w), _h(h), _flags(0x1006), _caps(64) {}
+ DDSurfaceDesc(int w, int h, int bpp) : _w(w), _h(h), _bpp(bpp),
+ _flags(0x1006), _caps(64) {}
};
class DirectDrawSurface {
@@ -52,7 +54,7 @@ public:
/**
* Create a surface
*/
- void create(int w, int h);
+ void create(int w, int h, int bpp);
/**
* Create a surface based on a passed surface
diff --git a/engines/titanic/support/image_decoders.cpp b/engines/titanic/support/image_decoders.cpp
index 2dba66fbb3..3819b85116 100644
--- a/engines/titanic/support/image_decoders.cpp
+++ b/engines/titanic/support/image_decoders.cpp
@@ -36,7 +36,7 @@ void CJPEGDecode::decode(OSVideoSurface &surface, const CString &name) {
// Resize the surface if necessary
if (!surface.hasSurface() || surface.getWidth() != srcSurf->w
|| surface.getHeight() != srcSurf->h)
- surface.recreate(srcSurf->w, srcSurf->h);
+ surface.recreate(srcSurf->w, srcSurf->h, 16);
// Convert the decoded surface to the correct pixel format, and then copy it over
surface.lock();
@@ -64,7 +64,7 @@ void CTargaDecode::decode(OSVideoSurface &surface, const CString &name) {
// Resize the surface if necessary
if (!surface.hasSurface() || surface.getWidth() != srcSurf->w
|| surface.getHeight() != srcSurf->h)
- surface.recreate(srcSurf->w, srcSurf->h);
+ surface.recreate(srcSurf->w, srcSurf->h, 16);
// Convert the decoded surface to the correct pixel format, and then copy it over
surface.lock();
diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp
index 6300f65a3b..e72e928e67 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);
+ CVideoSurface *surface = _screenManager->createSurface(CURSOR_SIZE, CURSOR_SIZE, 16);
_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 c26e4eb3c4..5e59ed747b 100644
--- a/engines/titanic/support/movie.cpp
+++ b/engines/titanic/support/movie.cpp
@@ -88,7 +88,8 @@ OSMovie::OSMovie(const CResourceKey &name, CVideoSurface *surface) :
_field28 = 0;
_field2C = 0;
- surface->resize(_aviSurface.getWidth(), _aviSurface.getHeight());
+ surface->resize(_aviSurface.getWidth(), _aviSurface.getHeight(),
+ _aviSurface.getBitDepth() == 32 ? 32 : 16);
_aviSurface.setVideoSurface(surface);
}
@@ -118,7 +119,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);
+ _movieSurface = CScreenManager::_screenManagerPtr->createSurface(600, 340, 16);
// 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.cpp b/engines/titanic/support/screen_manager.cpp
index 2a675394b5..553486d094 100644
--- a/engines/titanic/support/screen_manager.cpp
+++ b/engines/titanic/support/screen_manager.cpp
@@ -293,13 +293,13 @@ void OSScreenManager::clearSurface(SurfaceNum surfaceNum, Rect *bounds) {
_directDrawManager._backSurfaces[surfaceNum]->fill(bounds, 0);
}
-void OSScreenManager::resizeSurface(CVideoSurface *surface, int width, int height) {
- DirectDrawSurface *ddSurface = _directDrawManager.createSurface(width, height, 0);
+void OSScreenManager::resizeSurface(CVideoSurface *surface, int width, int height, int bpp) {
+ DirectDrawSurface *ddSurface = _directDrawManager.createSurface(width, height, bpp, 0);
surface->setSurface(this, ddSurface);
}
-CVideoSurface *OSScreenManager::createSurface(int w, int h) {
- DirectDrawSurface *ddSurface = _directDrawManager.createSurface(w, h, 0);
+CVideoSurface *OSScreenManager::createSurface(int w, int h, int bpp) {
+ DirectDrawSurface *ddSurface = _directDrawManager.createSurface(w, h, bpp, 0);
return new OSVideoSurface(this, ddSurface);
}
diff --git a/engines/titanic/support/screen_manager.h b/engines/titanic/support/screen_manager.h
index f88928af8b..0da8e0daf3 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) = 0;
+ virtual void resizeSurface(CVideoSurface *surface, int width, int height, int bpp) = 0;
/**
* Creates a surface of a given size
*/
- virtual CVideoSurface *createSurface(int w, int h) = 0;
+ virtual CVideoSurface *createSurface(int w, int h, int bpp) = 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);
+ virtual void resizeSurface(CVideoSurface *surface, int width, int height, int bpp);
/**
* Creates a surface of a given size
*/
- virtual CVideoSurface *createSurface(int w, int h);
+ virtual CVideoSurface *createSurface(int w, int h, int bpp);
/**
* Creates a surface from a specified resource
diff --git a/engines/titanic/support/text_cursor.cpp b/engines/titanic/support/text_cursor.cpp
index 5c7593ba68..1da98c1cf7 100644
--- a/engines/titanic/support/text_cursor.cpp
+++ b/engines/titanic/support/text_cursor.cpp
@@ -32,7 +32,7 @@ CTextCursor::CTextCursor(CScreenManager *screenManager) :
_backRenderSurface(nullptr), _frontRenderSurface(nullptr),
_blinkDelay(300), _size(2, 10), _priorBlinkTime(0),
_cursorR(0), _cursorG(0), _cursorB(0), _mode(-1) {
- _surface = screenManager->createSurface(10, 10);
+ _surface = screenManager->createSurface(10, 10, 16);
}
CTextCursor::~CTextCursor() {
diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp
index 7455e8cfef..e24063188d 100644
--- a/engines/titanic/support/video_surface.cpp
+++ b/engines/titanic/support/video_surface.cpp
@@ -158,25 +158,9 @@ void CVideoSurface::blitRect(const Rect &srcRect, const Rect &destRect, CVideoSu
if (src->lock()) {
const Graphics::ManagedSurface *srcSurface = src->_rawSurface;
Graphics::ManagedSurface *destSurface = _rawSurface;
- Graphics::Surface destArea = destSurface->getSubArea(destRect);
const uint transColor = src->getTransparencyColor();
- const uint16 *srcPtr = (const uint16 *)srcSurface->getBasePtr(
- srcRect.left, srcRect.top);
- uint16 *destPtr = (uint16 *)destArea.getBasePtr(0, 0);
-
- for (int yCtr = 0; yCtr < srcRect.height(); ++yCtr,
- srcPtr += src->getPitch() / 2,
- destPtr += destArea.pitch / 2) {
- // Prepare for copying the line
- const uint16 *lineSrcP = srcPtr;
- uint16 *lineDestP = destPtr;
-
- for (int srcX = srcRect.left; srcX < srcRect.right; ++srcX, ++lineSrcP, ++lineDestP) {
- if (*lineSrcP != transColor)
- *lineDestP = *lineSrcP;
- }
- }
+ destSurface->transBlitFrom(*srcSurface, srcRect, destRect, transColor);
src->unlock();
}
@@ -190,28 +174,22 @@ void CVideoSurface::flippedBlitRect(const Rect &srcRect, const Rect &destRect, C
transBlitRect(srcRect, destRect, src, true);
} else if (lock()) {
if (src->lock()) {
- const Graphics::ManagedSurface *srcSurface = src->_rawSurface;
+ Graphics::ManagedSurface *srcSurface = src->_rawSurface;
Graphics::ManagedSurface *destSurface = _rawSurface;
- Graphics::Surface destArea = destSurface->getSubArea(destRect);
+ const Graphics::Surface srcArea = srcSurface->getSubArea(srcRect);
const uint transColor = src->getTransparencyColor();
- const uint16 *srcPtr = (const uint16 *)srcSurface->getBasePtr(
- srcRect.left, srcRect.top);
- uint16 *destPtr = (uint16 *)destArea.getBasePtr(0, destArea.h - 1);
-
- for (int yCtr = 0; yCtr < srcRect.height(); ++yCtr,
- srcPtr += src->getPitch() / 2,
- destPtr -= destArea.pitch / 2) {
- // Prepare for copying the line
- const uint16 *lineSrcP = srcPtr;
- uint16 *lineDestP = destPtr;
-
- for (int srcX = srcRect.left; srcX < srcRect.right; ++srcX, ++lineSrcP, ++lineDestP) {
- if (*lineSrcP != transColor)
- *lineDestP = *lineSrcP;
- }
+ // Vertically flip the source area
+ Graphics::ManagedSurface flippedArea(srcArea.w, srcArea.h, srcArea.format);
+ for (int y = 0; y < srcArea.h; ++y) {
+ const byte *pSrc = (const byte *)srcArea.getBasePtr(0, y);
+ byte *pDest = (byte *)flippedArea.getBasePtr(0, flippedArea.h - y - 1);
+ Common::copy(pSrc, pSrc + srcArea.pitch, pDest);
}
+ destSurface->transBlitFrom(flippedArea,
+ Common::Point(destRect.left, destRect.top), transColor);
+
src->unlock();
}
@@ -221,6 +199,7 @@ void CVideoSurface::flippedBlitRect(const Rect &srcRect, const Rect &destRect, C
void CVideoSurface::transBlitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src, bool flipFlag) {
assert(srcRect.width() == destRect.width() && srcRect.height() == destRect.height());
+ assert(src->getPixelDepth() == 2);
if (lock()) {
if (src->lock()) {
@@ -442,18 +421,18 @@ int OSVideoSurface::getBpp() {
return getPixelDepth();
}
-void OSVideoSurface::recreate(int width, int height) {
+void OSVideoSurface::recreate(int width, int height, int bpp) {
freeSurface();
- _screenManager->resizeSurface(this, width, height);
+ _screenManager->resizeSurface(this, width, height, bpp);
if (_ddSurface)
_videoSurfaceCounter += _ddSurface->getSize();
}
-void OSVideoSurface::resize(int width, int height) {
+void OSVideoSurface::resize(int width, int height, int bpp) {
if (!_ddSurface || _ddSurface->getWidth() != width ||
_ddSurface->getHeight() != height)
- recreate(width, height);
+ recreate(width, height, bpp);
}
void OSVideoSurface::detachSurface() {
diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h
index 390e70bc33..77b9e61ad7 100644
--- a/engines/titanic/support/video_surface.h
+++ b/engines/titanic/support/video_surface.h
@@ -176,12 +176,12 @@ public:
/**
* Recreates the surface
*/
- virtual void recreate(int width, int height) = 0;
+ virtual void recreate(int width, int height, int bpp = 16) = 0;
/**
* Resizes the surface
*/
- virtual void resize(int width, int height) = 0;
+ virtual void resize(int width, int height, int bpp = 16) = 0;
/**
* Detachs the underlying raw surface
@@ -423,12 +423,12 @@ public:
/**
* Recreates the surface with the designated size
*/
- virtual void recreate(int width, int height);
+ virtual void recreate(int width, int height, int bpp = 16);
/**
* Resizes the surface
*/
- virtual void resize(int width, int height);
+ virtual void resize(int width, int height, int bpp = 16);
/**
* Detachs the underlying raw surface