aboutsummaryrefslogtreecommitdiff
path: root/engines/wintermute
diff options
context:
space:
mode:
authorEinar Johan Trøan Sømåen2013-01-24 14:33:08 +0100
committerEinar Johan Trøan Sømåen2013-01-24 15:11:28 +0100
commit519821b53b16f263cf911a125ff846a9d8cd22d9 (patch)
tree8b7fe8b8ac16213cceb988911c75b9bafccfeb29 /engines/wintermute
parent0143a5d938fc314d19f2ddcac2192a49a790cb6a (diff)
downloadscummvm-rg350-519821b53b16f263cf911a125ff846a9d8cd22d9.tar.gz
scummvm-rg350-519821b53b16f263cf911a125ff846a9d8cd22d9.tar.bz2
scummvm-rg350-519821b53b16f263cf911a125ff846a9d8cd22d9.zip
WINTERMUTE: Further improve UITiledImage-drawing.
Diffstat (limited to 'engines/wintermute')
-rw-r--r--engines/wintermute/base/gfx/base_surface.h1
-rw-r--r--engines/wintermute/base/gfx/osystem/base_render_osystem.cpp48
-rw-r--r--engines/wintermute/base/gfx/osystem/base_render_osystem.h2
-rw-r--r--engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp5
-rw-r--r--engines/wintermute/base/gfx/osystem/base_surface_osystem.h1
-rw-r--r--engines/wintermute/base/gfx/osystem/render_ticket.h1
-rw-r--r--engines/wintermute/ui/ui_tiled_image.cpp11
7 files changed, 60 insertions, 9 deletions
diff --git a/engines/wintermute/base/gfx/base_surface.h b/engines/wintermute/base/gfx/base_surface.h
index ee53c03e77..1f6915ea37 100644
--- a/engines/wintermute/base/gfx/base_surface.h
+++ b/engines/wintermute/base/gfx/base_surface.h
@@ -55,6 +55,7 @@ public:
virtual bool display(int x, int y, Rect32 rect, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) = 0;
virtual bool displayZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha = 0xFFFFFFFF, bool transparent = false, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) = 0;
virtual bool displayTransform(int x, int y, int hotX, int hotY, Rect32 rect, float zoomX, float zoomY, uint32 alpha, float rotate, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) = 0;
+ virtual bool repeatLastDisplayOp(int offsetX, int offsetY, int numTimesX, int numTimesY) = 0;
virtual bool restore();
virtual bool create(const Common::String &filename, bool defaultCK, byte ckRed, byte ckGreen, byte ckBlue, int lifeTime = -1, bool keepLoaded = false) = 0;
virtual bool create(int width, int height);
diff --git a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
index d1884a5a1b..4030ea0659 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
@@ -54,6 +54,7 @@ BaseRenderOSystem::BaseRenderOSystem(BaseGame *inGame) : BaseRenderer(inGame) {
_spriteBatch = false;
_batchNum = 0;
_skipThisFrame = false;
+ _previousTicket = NULL;
_borderLeft = _borderRight = _borderTop = _borderBottom = 0;
_ratioX = _ratioY = 1.0f;
@@ -279,8 +280,9 @@ void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::S
if (owner) { // Fade-tickets are owner-less
RenderTicket compare(owner, NULL, srcRect, dstRect, mirrorX, mirrorY, disableAlpha);
compare._batchNum = _batchNum;
- if (_spriteBatch)
+ if (_spriteBatch) {
_batchNum++;
+ }
compare._colorMod = _colorMod;
RenderQueueIterator it;
// Avoid calling end() and operator* every time, when potentially going through
@@ -295,6 +297,7 @@ void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::S
drawFromSurface(compareTicket);
} else {
drawFromTicket(compareTicket);
+ _previousTicket = compareTicket;
}
return;
}
@@ -305,12 +308,53 @@ void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::S
if (!_disableDirtyRects) {
drawFromTicket(ticket);
drawFromSurface(ticket);
+ _previousTicket = ticket;
} else {
ticket->_wantsDraw = true;
_renderQueue.push_back(ticket);
}
}
+void BaseRenderOSystem::repeatLastDraw(int offsetX, int offsetY, int numTimesX, int numTimesY) {
+ if (_previousTicket && _lastAddedTicket != _renderQueue.end()) {
+ RenderTicket *origTicket = _previousTicket;
+
+ // Make sure drawSurface WILL start from the correct _lastAddedTicket
+ if (*_lastAddedTicket != origTicket) {
+ RenderQueueIterator it;
+ RenderQueueIterator endIterator = _renderQueue.end();
+ for (it = _renderQueue.begin(); it != endIterator; ++it) {
+ if ((*it) == _previousTicket) {
+ _lastAddedTicket = it;
+ break;
+ }
+ }
+ }
+ Common::Rect srcRect(0, 0, 0, 0);
+ srcRect.setWidth(origTicket->getSrcRect()->width());
+ srcRect.setHeight(origTicket->getSrcRect()->height());
+
+ Common::Rect dstRect = origTicket->_dstRect;
+ int initLeft = dstRect.left;
+ int initRight = dstRect.right;
+
+ for (int i = 0; i < numTimesY; i++) {
+ if (i == 0) {
+ dstRect.translate(offsetX, 0);
+ }
+ for (int j = (i == 0 ? 1 : 0); j < numTimesX; j++) {
+ drawSurface(origTicket->_owner, origTicket->getSurface(), &srcRect, &dstRect, false, false);
+ dstRect.translate(offsetX, 0);
+ }
+ dstRect.left = initLeft;
+ dstRect.right = initRight;
+ dstRect.translate(0, offsetY);
+ }
+ } else {
+ error("Repeat-draw failed (did you forget to draw something before this?)");
+ }
+}
+
void BaseRenderOSystem::invalidateTicket(RenderTicket *renderTicket) {
addDirtyRect(renderTicket->_dstRect);
renderTicket->_isValid = false;
@@ -359,6 +403,7 @@ void BaseRenderOSystem::drawFromTicket(RenderTicket *renderTicket) {
// Was drawn last round, still in the same order
if (_drawNum == renderTicket->_drawNum) {
_drawNum++;
+ ++_lastAddedTicket;
} else {
// Remove the ticket from the list
RenderQueueIterator it = _renderQueue.begin();
@@ -379,7 +424,6 @@ void BaseRenderOSystem::drawFromTicket(RenderTicket *renderTicket) {
// Is not in order, so readd it as if it was a new ticket
renderTicket->_drawNum = 0;
drawFromTicket(renderTicket);
- _lastAddedTicket = it;
}
}
}
diff --git a/engines/wintermute/base/gfx/osystem/base_render_osystem.h b/engines/wintermute/base/gfx/osystem/base_render_osystem.h
index 9c36edb573..2c89037183 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.h
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.h
@@ -81,6 +81,7 @@ public:
virtual bool endSpriteBatch();
void endSaveLoad();
void drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, bool mirrorX, bool mirrorY, bool disableAlpha = false);
+ void repeatLastDraw(int offsetX, int offsetY, int numTimesX, int numTimesY);
BaseSurface *createSurface();
private:
void addDirtyRect(const Common::Rect &rect);
@@ -93,6 +94,7 @@ private:
Common::Rect *_dirtyRect;
Common::List<RenderTicket *> _renderQueue;
RenderQueueIterator _lastAddedTicket;
+ RenderTicket *_previousTicket;
bool _needsFlip;
uint32 _drawNum;
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
index bee876bb65..bde9e6d3db 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
@@ -414,6 +414,11 @@ bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, float zoomX, flo
return STATUS_OK;
}
+bool BaseSurfaceOSystem::repeatLastDisplayOp(int offsetX, int offsetY, int numTimesX, int numTimesY) {
+ BaseRenderOSystem *renderer = static_cast<BaseRenderOSystem *>(_gameRef->_renderer);
+ renderer->repeatLastDraw(offsetX, offsetY, numTimesX, numTimesY);
+}
+
bool BaseSurfaceOSystem::putSurface(const Graphics::Surface &surface, bool hasAlpha) {
_loaded = true;
_surface->free();
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.h b/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
index 43422ef4e7..5bbfa27179 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
@@ -57,6 +57,7 @@ public:
bool display(int x, int y, Rect32 rect, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false);
bool displayZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha = 0xFFFFFFFF, bool transparent = false, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false);
bool displayTransform(int x, int y, int hotX, int hotY, Rect32 Rect, float zoomX, float zoomY, uint32 alpha, float rotate, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false);
+ bool repeatLastDisplayOp(int offsetX, int offsetY, int numTimesX, int numTimesY);
virtual bool putSurface(const Graphics::Surface &surface, bool hasAlpha = false);
/* static unsigned DLL_CALLCONV ReadProc(void *buffer, unsigned size, unsigned count, fi_handle handle);
static int DLL_CALLCONV SeekProc(fi_handle handle, long offset, int origin);
diff --git a/engines/wintermute/base/gfx/osystem/render_ticket.h b/engines/wintermute/base/gfx/osystem/render_ticket.h
index 19637a23d0..968b42b5e1 100644
--- a/engines/wintermute/base/gfx/osystem/render_ticket.h
+++ b/engines/wintermute/base/gfx/osystem/render_ticket.h
@@ -56,6 +56,7 @@ public:
BaseSurfaceOSystem *_owner;
bool operator==(RenderTicket &a);
+ const Common::Rect *getSrcRect() { return &_srcRect; }
private:
Graphics::Surface *_surface;
Common::Rect _srcRect;
diff --git a/engines/wintermute/ui/ui_tiled_image.cpp b/engines/wintermute/ui/ui_tiled_image.cpp
index 2b337330c7..03fef5ca05 100644
--- a/engines/wintermute/ui/ui_tiled_image.cpp
+++ b/engines/wintermute/ui/ui_tiled_image.cpp
@@ -104,14 +104,11 @@ bool UITiledImage::display(int x, int y, int width, int height) {
}
// tiles
- yyy = y + (_upMiddle.bottom - _upMiddle.top);
- for (row = 0; row < nuRows; row++) {
+ if (nuRows > 0 && nuColumns > 0) {
+ yyy = y + (_upMiddle.bottom - _upMiddle.top);
xxx = x + (_upLeft.right - _upLeft.left);
- for (col = 0; col < nuColumns; col++) {
- _image->_surface->displayTrans(xxx, yyy, _middleMiddle);
- xxx += tileWidth;
- }
- yyy += tileWidth;
+ _image->_surface->displayTrans(xxx, yyy, _middleMiddle);
+ _image->_surface->repeatLastDisplayOp(tileWidth, tileWidth, nuColumns, nuRows);
}
_gameRef->_renderer->endSpriteBatch();