diff options
author | Einar Johan Trøan Sømåen | 2013-01-24 14:33:08 +0100 |
---|---|---|
committer | Einar Johan Trøan Sømåen | 2013-01-24 15:11:28 +0100 |
commit | 519821b53b16f263cf911a125ff846a9d8cd22d9 (patch) | |
tree | 8b7fe8b8ac16213cceb988911c75b9bafccfeb29 /engines/wintermute | |
parent | 0143a5d938fc314d19f2ddcac2192a49a790cb6a (diff) | |
download | scummvm-rg350-519821b53b16f263cf911a125ff846a9d8cd22d9.tar.gz scummvm-rg350-519821b53b16f263cf911a125ff846a9d8cd22d9.tar.bz2 scummvm-rg350-519821b53b16f263cf911a125ff846a9d8cd22d9.zip |
WINTERMUTE: Further improve UITiledImage-drawing.
Diffstat (limited to 'engines/wintermute')
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(); |