diff options
author | RichieSams | 2013-09-15 14:41:45 -0500 |
---|---|---|
committer | RichieSams | 2013-09-15 15:00:54 -0500 |
commit | 36a0b666b3096da5a7ef169c598897be1cb06078 (patch) | |
tree | 9d280f21fd388f53235ed28e6f2328e7e05f2fec /engines/zvision | |
parent | 3986f333eff094d3104feae263b42e6e9ed85968 (diff) | |
download | scummvm-rg350-36a0b666b3096da5a7ef169c598897be1cb06078.tar.gz scummvm-rg350-36a0b666b3096da5a7ef169c598897be1cb06078.tar.bz2 scummvm-rg350-36a0b666b3096da5a7ef169c598897be1cb06078.zip |
ZVISION: Add better alpha support for blitting
Instead of blitting directly to the working window, we cache the alpha pixels,
then blit directly to the backbuffer instead of to the working window. This
ensures that if the alpha'd content changes, the old changes won't appear
in any new frames
Diffstat (limited to 'engines/zvision')
-rw-r--r-- | engines/zvision/render_manager.cpp | 49 | ||||
-rw-r--r-- | engines/zvision/render_manager.h | 13 |
2 files changed, 54 insertions, 8 deletions
diff --git a/engines/zvision/render_manager.cpp b/engines/zvision/render_manager.cpp index 62580323d3..72fa5d3fc6 100644 --- a/engines/zvision/render_manager.cpp +++ b/engines/zvision/render_manager.cpp @@ -98,11 +98,37 @@ void RenderManager::renderBackbufferToScreen() { // TODO: Add menu rendering + // Render alpha entries + processAlphaEntries(); + if (!_backBufferDirtyRect.isEmpty()) { _system->copyRectToScreen(_backBuffer.getBasePtr(_backBufferDirtyRect.left, _backBufferDirtyRect.top), _backBuffer.pitch, _backBufferDirtyRect.left, _backBufferDirtyRect.top, _backBufferDirtyRect.width(), _backBufferDirtyRect.height()); } } +void RenderManager::processAlphaEntries() { + for (Common::List<AlphaDataEntry>::iterator iter = _alphaDataEntries.begin(); iter != _alphaDataEntries.end(); iter++) { + uint32 destOffset = 0; + uint32 sourceOffset = 0; + uint16 *backbufferPtr = (uint16 *)_backBuffer.getBasePtr((*iter).destX + _workingWindow.left, (*iter).destY + _workingWindow.top); + uint16 *entryPtr = (uint16 *)(*iter).data->getPixels(); + + for (int32 y = 0; y < (*iter).height; y++) { + for (int32 x = 0; x < (*iter).width; x++) { + uint16 color = entryPtr[sourceOffset + x]; + if (color != (*iter).alphaColor) { + backbufferPtr[destOffset + x] = color; + } + } + + destOffset += _workingWidth; + sourceOffset += (*iter).width; + } + + _backBufferDirtyRect.extend(Common::Rect((*iter).destX + _workingWindow.left, (*iter).destY + _workingWindow.top, (*iter).destX + _workingWindow.left + (*iter).width, (*iter).destY + _workingWindow.top + (*iter).height)); + } +} + void RenderManager::clearWorkingWindowTo555Color(uint16 color) { uint32 workingWindowSize = _workingWidth * _workingHeight; byte r, g, b; @@ -295,24 +321,31 @@ void RenderManager::copyRectToWorkingWindow(const uint16 *buffer, int32 destX, i } void RenderManager::copyRectToWorkingWindow(const uint16 *buffer, int32 destX, int32 destY, int32 imageWidth, int32 width, int32 height, int16 alphaColor) { - uint32 destOffset = 0; + AlphaDataEntry entry; + entry.alphaColor = alphaColor; + entry.data = new Graphics::Surface(); + entry.data->create(width, height, _pixelFormat); + entry.destX = destX; + entry.destY = destY; + entry.width = width; + entry.height = height; + uint32 sourceOffset = 0; - uint16 *workingWindowBufferPtr = (uint16 *)_workingWindowBuffer.getBasePtr(destX, destY); + uint32 destOffset = 0; + uint16 *surfacePtr = (uint16 *)entry.data->getPixels(); for (int32 y = 0; y < height; y++) { for (int32 x = 0; x < width; x++) { - uint16 color = buffer[sourceOffset + x]; - if (color != alphaColor) { - workingWindowBufferPtr[destOffset + x] = color; - } + surfacePtr[destOffset + x] = buffer[sourceOffset + x]; } - destOffset += _workingWidth; + destOffset += width; sourceOffset += imageWidth; } - _workingWindowDirtyRect.extend(Common::Rect(destX, destY, destX + width, destY + height)); + _alphaDataEntries.push_back(entry); } + void RenderManager::copyWorkingWindowSubRectToSurface(Graphics::Surface *destSurface, uint16 destX, uint16 destY, Common::Rect subRect) const { uint32 destOffset = 0; uint32 sourceOffset = 0; diff --git a/engines/zvision/render_manager.h b/engines/zvision/render_manager.h index ce5c774917..f6106b39a3 100644 --- a/engines/zvision/render_manager.h +++ b/engines/zvision/render_manager.h @@ -49,6 +49,16 @@ public: ~RenderManager(); private: + struct AlphaDataEntry { + Graphics::Surface *data; + uint16 alphaColor; + uint16 destX; + uint16 destY; + uint16 width; + uint16 height; + }; + +private: OSystem *_system; const Graphics::PixelFormat _pixelFormat; @@ -56,6 +66,7 @@ private: // It's used for panorama/tilt warping and for clearing the workingWindow to a single color Graphics::Surface _workingWindowBuffer; Graphics::Surface _backBuffer; + Common::List<AlphaDataEntry> _alphaDataEntries; Common::Rect _workingWindowDirtyRect; Common::Rect _backBufferDirtyRect; @@ -108,6 +119,8 @@ public: */ void renderBackbufferToScreen(); + void processAlphaEntries(); + void copyRectToWorkingWindow(const uint16 *buffer, int32 destX, int32 destY, int32 imageWidth, int32 width, int32 height); void copyRectToWorkingWindow(const uint16 *buffer, int32 destX, int32 destY, int32 imageWidth, int32 width, int32 height, int16 alphaColor); |