aboutsummaryrefslogtreecommitdiff
path: root/engines/zvision
diff options
context:
space:
mode:
authorRichieSams2013-09-15 14:41:45 -0500
committerRichieSams2013-09-15 15:00:54 -0500
commit36a0b666b3096da5a7ef169c598897be1cb06078 (patch)
tree9d280f21fd388f53235ed28e6f2328e7e05f2fec /engines/zvision
parent3986f333eff094d3104feae263b42e6e9ed85968 (diff)
downloadscummvm-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.cpp49
-rw-r--r--engines/zvision/render_manager.h13
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);