aboutsummaryrefslogtreecommitdiff
path: root/engines/zvision/render_manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/zvision/render_manager.cpp')
-rw-r--r--engines/zvision/render_manager.cpp125
1 files changed, 71 insertions, 54 deletions
diff --git a/engines/zvision/render_manager.cpp b/engines/zvision/render_manager.cpp
index 78fcf59a56..05536f3fbe 100644
--- a/engines/zvision/render_manager.cpp
+++ b/engines/zvision/render_manager.cpp
@@ -34,23 +34,28 @@
namespace ZVision {
-RenderManager::RenderManager(OSystem *system, const Common::Rect workingWindow)
- : _system(system),
- _workingWidth(workingWindow.width()),
- _workingHeight(workingWindow.height()),
- _workingWindow(workingWindow),
- _currentBackground(0),
- _backgroundWidth(0),
- _backgroundHeight(0),
- _backgroundInverseVelocity(0),
- _accumulatedVelocityMilliseconds(0),
- _renderTable(workingWindow.width(), workingWindow.height()) {
+RenderManager::RenderManager(OSystem *system, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat)
+ : _system(system),
+ _workingWidth(workingWindow.width()),
+ _workingHeight(workingWindow.height()),
+ _workingWindow(workingWindow),
+ _pixelFormat(pixelFormat),
+ _currentBackground(0),
+ _backgroundWidth(0),
+ _backgroundHeight(0),
+ _backgroundInverseVelocity(0),
+ _accumulatedVelocityMilliseconds(0),
+ _renderTable(workingWindow.width(), workingWindow.height()) {
+ _backbuffer.create(_workingWidth, _workingHeight, pixelFormat);
+ _warpedBackbuffer = new uint16[_workingWidth *_workingHeight];
}
RenderManager::~RenderManager() {
if (_currentBackground != 0) {
delete _currentBackground;
}
+
+ _backbuffer.free();
}
void RenderManager::update(uint deltaTimeInMillis) {
@@ -62,7 +67,7 @@ void RenderManager::update(uint deltaTimeInMillis) {
int absVelocity = abs(_backgroundInverseVelocity);
- uint numberOfSteps = 0;
+ int numberOfSteps = 0;
while (_accumulatedVelocityMilliseconds >= absVelocity) {
_accumulatedVelocityMilliseconds -= absVelocity;
numberOfSteps++;
@@ -70,17 +75,23 @@ void RenderManager::update(uint deltaTimeInMillis) {
// Choose the direction of movement using the sign of the velocity
moveBackground(_backgroundInverseVelocity < 0 ? -numberOfSteps : numberOfSteps);
+
+ // Warp the entire backbuffer
+ _renderTable.mutateImage((uint16 *)_backbuffer.getBasePtr(0, 0), _warpedBackbuffer, _workingWidth, _workingHeight);
+
+ // Blit the backbuffer to the screen
+ _system->copyRectToScreen(_backbuffer.getBasePtr(0, 0), _backbuffer.pitch, _workingWindow.left, _workingWindow.top, _backbuffer.w, _backbuffer.h);
}
-void RenderManager::renderSubRectToScreen(uint16 *buffer, uint32 imageWidth, uint32 imageHeight, uint32 horizontalPitch, uint32 destinationX, uint32 destinationY, Common::Rect subRectangle, bool wrap) {
+void RenderManager::renderSubRectToBackbuffer(Graphics::Surface &surface, uint32 destinationX, uint32 destinationY, Common::Rect subRectangle, bool wrap, bool isTransposed) {
if (wrap) {
- _backgroundWidth = imageWidth;
- _backgroundHeight = imageHeight;
+ _backgroundWidth = surface.w;
+ _backgroundHeight = surface.h;
}
// If subRect is empty, use the entire image
if (subRectangle.isEmpty())
- subRectangle = Common::Rect(subRectangle.left, subRectangle.top, subRectangle.left + imageWidth, subRectangle.top + imageHeight);
+ subRectangle = Common::Rect(subRectangle.left, subRectangle.top, subRectangle.left + surface.w, subRectangle.top + surface.h);
// Clip destRect to working window bounds
Common::Rect destRect(destinationX, destinationY, destinationX + subRectangle.width(), destinationY + subRectangle.height());
@@ -91,7 +102,7 @@ void RenderManager::renderSubRectToScreen(uint16 *buffer, uint32 imageWidth, uin
subRectangle.setHeight(destRect.height());
// Clip to image bounds
Common::Point subRectOrigOrigin(subRectangle.left, subRectangle.top);
- subRectangle.clip(imageWidth, imageHeight);
+ subRectangle.clip(surface.w, surface.h);
// If the image is to be wrapped, check if it's smaller than destRect
// If it is, then call renderSubRectToScreen with a subRect representing wrapping
@@ -110,7 +121,7 @@ void RenderManager::renderSubRectToScreen(uint16 *buffer, uint32 imageWidth, uin
wrapSubRect = Common::Rect(_backgroundWidth - subRectangle.width(), 0, _backgroundWidth - 1, subRectangle.bottom);
}
- renderSubRectToScreen(buffer, imageWidth, imageHeight, horizontalPitch, wrapDestX, wrapDestY, wrapSubRect, false);
+ renderSubRectToBackbuffer(surface, wrapDestX, wrapDestY, wrapSubRect, false, isTransposed);
} else if (wrap && subRectangle.height() < destRect.height()) {
uint32 wrapDestX;
uint32 wrapDestY;
@@ -126,32 +137,38 @@ void RenderManager::renderSubRectToScreen(uint16 *buffer, uint32 imageWidth, uin
wrapSubRect = Common::Rect(0, _backgroundHeight - subRectangle.height(), subRectangle.right, _backgroundHeight - 1);
}
- renderSubRectToScreen(buffer, imageWidth, imageHeight, horizontalPitch, wrapDestX, wrapDestY, wrapSubRect, false);
+ renderSubRectToBackbuffer(surface, wrapDestX, wrapDestY, wrapSubRect, false, isTransposed);
+ } else {
+ // Clip destRect to image bounds
+ destRect.translate(subRectangle.left - subRectOrigOrigin.x, subRectangle.top - subRectOrigOrigin.y);
+ destRect.setWidth(subRectangle.width());
+ destRect.setHeight(subRectangle.height());
}
- // Clip destRect to image bounds
- destRect.translate(subRectangle.left - subRectOrigOrigin.x, subRectangle.top - subRectOrigOrigin.y);
- destRect.setWidth(subRectangle.width());
- destRect.setHeight(subRectangle.height());
-
// Check all Rects for validity
if (!subRectangle.isValidRect() || subRectangle.isEmpty() || !destRect.isValidRect() || destRect.isEmpty())
return;
- if (_renderTable.getRenderState() == RenderTable::FLAT) {
- // Convert destRect to screen space by adding _workingWindowOffset
- _system->copyRectToScreen(buffer + subRectangle.top * horizontalPitch + subRectangle.left, horizontalPitch, destRect.left + _workingWindow.left, destRect.top + _workingWindow.top, destRect.width(), destRect.height());
+ if (isTransposed) {
+ copyTransposedRectToBackbuffer((uint16 *)surface.getBasePtr(subRectangle.left, subRectangle.right), surface.w, destRect.left, destRect.top, destRect.width(), destRect.height());
} else {
- uint16 *destBuffer = new uint16[destRect.width() * destRect.height()];
- _renderTable.mutateImage((uint16 *)buffer, destBuffer, imageWidth, imageHeight, subRectangle, destRect);
+ _backbuffer.copyRectToSurface(surface.getBasePtr(subRectangle.left, subRectangle.right), surface.pitch, destRect.left, destRect.top, destRect.width(), destRect.height());
+ }
+}
- // Convert destRect to screen space by adding _workingWindow offset
- _system->copyRectToScreen(destBuffer, subRectangle.width() * sizeof(uint16), destRect.left + _workingWindow.left, destRect.top + _workingWindow.top, destRect.width(), destRect.height());
- delete[] destBuffer;
+void RenderManager::copyTransposedRectToBackbuffer(const uint16 *buffer, int imageHeight, int x, int y, int width, int height) {
+ uint16 *dest = (uint16 *)_backbuffer.getBasePtr(x, y);
+
+ for (int x = 0; x < width; x++) {
+ int columnOffset = x * imageHeight;
+ for (int y = 0; y < height; y++) {
+ *dest = buffer[columnOffset + y];
+ dest++;
+ }
}
}
-void RenderManager::renderImageToScreen(const Common::String &fileName, uint32 destinationX, uint32 destinationY, Common::Rect subRectangle, bool wrap) {
+void RenderManager::renderImageToBackbuffer(const Common::String &fileName, uint32 destinationX, uint32 destinationY, Common::Rect subRectangle, bool wrap) {
Common::File file;
if (!file.open(fileName)) {
@@ -159,10 +176,10 @@ void RenderManager::renderImageToScreen(const Common::String &fileName, uint32 d
return;
}
- renderImageToScreen(file, destinationX, destinationY, subRectangle);
+ renderImageToBackbuffer(file, destinationX, destinationY, subRectangle);
}
-void RenderManager::renderImageToScreen(Common::SeekableReadStream &stream, uint32 destinationX, uint32 destinationY, Common::Rect subRectangle, bool wrap) {
+void RenderManager::renderImageToBackbuffer(Common::SeekableReadStream &stream, uint32 destinationX, uint32 destinationY, Common::Rect subRectangle, bool wrap) {
// Read the magic number
// Some files are true TGA, while others are TGZ
uint32 fileType;
@@ -179,17 +196,21 @@ void RenderManager::renderImageToScreen(Common::SeekableReadStream &stream, uint
byte *buffer = new byte[decompressedSize];
lzssStream.read(buffer, decompressedSize);
- uint32 horizontalPitch = imageWidth * sizeof(uint16);
+ uint32 pitch = imageWidth * sizeof(uint16);
+ bool isTransposed = _renderTable.getRenderState() == RenderTable::PANORAMA;
- // Panoramas are transposed
- // The actual data is transposed in mutateImage
- if (_renderTable.getRenderState() == RenderTable::PANORAMA || _renderTable.getRenderState() == RenderTable::TILT) {
- uint32 temp = imageHeight;
+ if (isTransposed) {
+ uint16 temp = imageHeight;
imageHeight = imageWidth;
imageWidth = temp;
}
- renderSubRectToScreen((uint16 *)buffer, imageWidth, imageHeight, horizontalPitch, destinationX, destinationY, subRectangle, wrap);
+ Graphics::Surface surface;
+ surface.init(imageWidth, imageHeight, pitch, buffer, _pixelFormat);
+
+ renderSubRectToBackbuffer(surface, destinationX, destinationY, subRectangle, wrap, isTransposed);
+
+ // We have to use delete[] instead of calling surface.free() because we created the memory with new[]
delete[] buffer;
} else {
// Reset the cursor
@@ -202,20 +223,16 @@ void RenderManager::renderImageToScreen(Common::SeekableReadStream &stream, uint
return;
}
- const Graphics::Surface *tgaSurface = tga.getSurface();
+ Graphics::Surface tgaSurface = *(tga.getSurface());
+ bool isTransposed = _renderTable.getRenderState() == RenderTable::PANORAMA;
- uint32 imageWidth = tgaSurface->w;
- uint32 imageHeight = tgaSurface->h;
-
- // Panoramas are transposed
- // The actual data is transposed in mutateImage
- if (_renderTable.getRenderState() == RenderTable::PANORAMA || _renderTable.getRenderState() == RenderTable::TILT) {
- uint32 temp = imageHeight;
- imageHeight = imageWidth;
- imageWidth = temp;
+ if (isTransposed) {
+ uint16 temp = tgaSurface.h;
+ tgaSurface.h = tgaSurface.w;
+ tgaSurface.w = temp;
}
- renderSubRectToScreen((uint16 *)tgaSurface->pixels, tgaSurface->w, tgaSurface->h, tgaSurface->pitch, destinationX, destinationY, subRectangle, wrap);
+ renderSubRectToBackbuffer(tgaSurface, destinationX, destinationY, subRectangle, wrap, isTransposed);
tga.destroy();
}
}
@@ -255,7 +272,7 @@ void RenderManager::setBackgroundImage(const Common::String &fileName) {
_currentBackground = file;
// Purposely make the subRectangle empty. renderImageToScreen will then set the width and height automatically.
- renderImageToScreen(*_currentBackground, 0, 0, Common::Rect(_backgroundOffset.x, _backgroundOffset.y, _backgroundOffset.x, _backgroundOffset.y), true);
+ renderImageToBackbuffer(*_currentBackground, 0, 0, Common::Rect(_backgroundOffset.x, _backgroundOffset.y, _backgroundOffset.x, _backgroundOffset.y), true);
}
void RenderManager::setBackgroundPosition(int offset) {
@@ -297,7 +314,7 @@ void RenderManager::moveBackground(int offset) {
_currentBackground->seek(0);
// Purposely make the subRectangle empty. renderImageToScreen will then set the width and height automatically.
- renderImageToScreen(*_currentBackground, 0, 0, Common::Rect(_backgroundOffset.x, _backgroundOffset.y, _backgroundOffset.x, _backgroundOffset.y), true);
+ renderImageToBackbuffer(*_currentBackground, 0, 0, Common::Rect(_backgroundOffset.x, _backgroundOffset.y, _backgroundOffset.x, _backgroundOffset.y), true);
}
} // End of namespace ZVision