aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/wintermute/base/gfx/base_surface.h2
-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.cpp18
-rw-r--r--engines/wintermute/base/gfx/osystem/base_surface_osystem.h2
-rw-r--r--engines/wintermute/base/gfx/osystem/render_ticket.cpp68
-rw-r--r--engines/wintermute/graphics/transform_struct.cpp15
-rw-r--r--engines/wintermute/graphics/transform_struct.h7
-rw-r--r--engines/wintermute/ui/ui_tiled_image.cpp27
9 files changed, 107 insertions, 82 deletions
diff --git a/engines/wintermute/base/gfx/base_surface.h b/engines/wintermute/base/gfx/base_surface.h
index 42fd593f61..a53748e9aa 100644
--- a/engines/wintermute/base/gfx/base_surface.h
+++ b/engines/wintermute/base/gfx/base_surface.h
@@ -56,7 +56,7 @@ public:
virtual bool display(int x, int y, Rect32 rect, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) = 0;
virtual bool displayTransform(int x, int y, Rect32 rect, Rect32 newRect, const TransformStruct &transform) = 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 repeatLastDisplayOp(int offsetX, int offsetY, int numTimesX, int numTimesY) = 0;
+ virtual bool displayTiled(int x, int y, Rect32 rect, 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 37f577d202..b8e35d9724 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
@@ -55,7 +55,6 @@ BaseRenderOSystem::BaseRenderOSystem(BaseGame *inGame) : BaseRenderer(inGame) {
_lastFrameIter = _renderQueue.end();
_needsFlip = true;
_skipThisFrame = false;
- _previousTicket = nullptr;
_borderLeft = _borderRight = _borderTop = _borderBottom = 0;
_ratioX = _ratioY = 1.0f;
@@ -265,7 +264,6 @@ void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::S
ticket->_transform._rgbaMod = _colorMod;
ticket->_wantsDraw = true;
_renderQueue.push_back(ticket);
- _previousTicket = ticket;
drawFromSurface(ticket);
return;
}
@@ -296,7 +294,6 @@ void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::S
drawFromSurface(compareTicket);
} else {
drawFromQueuedTicket(it);
- _previousTicket = compareTicket;
}
return;
}
@@ -305,57 +302,13 @@ void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::S
RenderTicket *ticket = new RenderTicket(owner, surf, srcRect, dstRect, transform);
if (!_disableDirtyRects) {
drawFromTicket(ticket);
- _previousTicket = ticket;
} else {
ticket->_wantsDraw = true;
_renderQueue.push_back(ticket);
- _previousTicket = ticket;
drawFromSurface(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 (!_disableDirtyRects && *_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;
-
- TransformStruct temp = TransformStruct(kDefaultZoomX, kDefaultZoomY, kDefaultAngle, kDefaultHotspotX, kDefaultHotspotY, BLEND_NORMAL, kDefaultRgbaMod, false, false, kDefaultOffsetX, kDefaultOffsetY);
-
- 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, temp);
- 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;
@@ -614,7 +567,6 @@ void BaseRenderOSystem::endSaveLoad() {
delete ticket;
}
_lastAddedTicket = _renderQueue.begin();
- _previousTicket = nullptr;
// HACK: After a save the buffer will be drawn before the scripts get to update it,
// so just skip this single frame.
_skipThisFrame = true;
diff --git a/engines/wintermute/base/gfx/osystem/base_render_osystem.h b/engines/wintermute/base/gfx/osystem/base_render_osystem.h
index fd5d33622e..a6634d9acc 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.h
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.h
@@ -111,7 +111,6 @@ public:
virtual bool endSpriteBatch() override;
void endSaveLoad();
void drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, TransformStruct &transform);
- void repeatLastDraw(int offsetX, int offsetY, int numTimesX, int numTimesY);
BaseSurface *createSurface() override;
private:
/**
@@ -130,7 +129,6 @@ private:
Common::Rect *_dirtyRect;
Common::List<RenderTicket *> _renderQueue;
RenderQueueIterator _lastAddedTicket;
- RenderTicket *_previousTicket;
bool _needsFlip;
uint32 _drawNum; ///< The global number of the current draw-operation.
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
index e04af45dd9..67d8f3f425 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
@@ -381,6 +381,14 @@ bool BaseSurfaceOSystem::displayTransform(int x, int y, Rect32 rect, Rect32 newR
}
//////////////////////////////////////////////////////////////////////////
+bool BaseSurfaceOSystem::displayTiled(int x, int y, Rect32 rect, int numTimesX, int numTimesY) {
+ assert(numTimesX > 0 && numTimesY > 0);
+ TransformStruct transform(numTimesX, numTimesY);
+ return drawSprite(x, y, &rect, nullptr, transform);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect, TransformStruct transform) {
BaseRenderOSystem *renderer = static_cast<BaseRenderOSystem *>(_gameRef->_renderer);
@@ -424,8 +432,8 @@ bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect,
position.setWidth(newRect->width());
position.setHeight(newRect->height());
} else {
- position.setWidth((int16)((float)srcRect.width() * transform._zoom.x / kDefaultZoomX));
- position.setHeight((int16)((float)srcRect.height() * transform._zoom.y / kDefaultZoomY));
+ position.setWidth((int16)((float)srcRect.width() * transform._zoom.x / kDefaultZoomX) * transform._numTimesX);
+ position.setHeight((int16)((float)srcRect.height() * transform._zoom.y / kDefaultZoomY) * transform._numTimesY);
}
renderer->modTargetRect(&position);
@@ -441,12 +449,6 @@ bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect,
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);
- return STATUS_OK;
-}
-
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 340a5a5ffc..67f45f66db 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
@@ -58,7 +58,7 @@ public:
bool display(int x, int y, Rect32 rect, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
bool displayZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha = kDefaultRgbaMod, bool transparent = false, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
bool displayTransform(int x, int y, Rect32 rect, Rect32 newRect, const TransformStruct &transform) override;
- bool repeatLastDisplayOp(int offsetX, int offsetY, int numTimesX, int numTimesY) override;
+ virtual bool displayTiled(int x, int y, Rect32 rect, int numTimesX, int numTimesY);
virtual bool putSurface(const Graphics::Surface &surface, bool hasAlpha = false) override;
/* 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.cpp b/engines/wintermute/base/gfx/osystem/render_ticket.cpp
index 006dd77e18..11a4921f97 100644
--- a/engines/wintermute/base/gfx/osystem/render_ticket.cpp
+++ b/engines/wintermute/base/gfx/osystem/render_ticket.cpp
@@ -50,13 +50,19 @@ RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *s
memcpy(_surface->getBasePtr(0, i), surf->getBasePtr(srcRect->left, srcRect->top + i), srcRect->width() * _surface->format.bytesPerPixel);
}
// Then scale it if necessary
+ //
+ // NB: The numTimesX/numTimesY properties don't yet mix well with
+ // scaling and rotation, but there is no need for that functionality at
+ // the moment.
if (_transform._angle != kDefaultAngle) {
TransparentSurface src(*_surface, false);
Graphics::Surface *temp = src.rotoscale(transform);
_surface->free();
delete _surface;
_surface = temp;
- } else if (dstRect->width() != srcRect->width() || dstRect->height() != srcRect->height()) {
+ } else if ((dstRect->width() != srcRect->width() ||
+ dstRect->height() != srcRect->height()) &&
+ _transform._numTimesX * _transform._numTimesY == 1) {
TransparentSurface src(*_surface, false);
Graphics::Surface *temp = src.scale(dstRect->width(), dstRect->height());
_surface->free();
@@ -109,7 +115,19 @@ void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface) const {
src._alphaMode = _owner->getAlphaType();
}
}
- src.blit(*_targetSurface, _dstRect.left, _dstRect.top, _transform._flip, &clipRect, _transform._rgbaMod, clipRect.width(), clipRect.height());
+
+ int y = _dstRect.top;
+ int w = _dstRect.width() / _transform._numTimesX;
+ int h = _dstRect.height() / _transform._numTimesY;
+
+ for (int ry = 0; ry < _transform._numTimesY; ++ry) {
+ int x = _dstRect.left;
+ for (int rx = 0; rx < _transform._numTimesX; ++rx) {
+ src.blit(*_targetSurface, x, y, _transform._flip, &clipRect, _transform._rgbaMod, clipRect.width(), clipRect.height());
+ x += w;
+ }
+ y += h;
+ }
}
void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface, Common::Rect *dstRect, Common::Rect *clipRect) const {
@@ -118,8 +136,8 @@ void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface, Common::Rect
if (!clipRect) {
doDelete = true;
clipRect = new Common::Rect();
- clipRect->setWidth(getSurface()->w);
- clipRect->setHeight(getSurface()->h);
+ clipRect->setWidth(getSurface()->w * _transform._numTimesX);
+ clipRect->setHeight(getSurface()->h * _transform._numTimesY);
}
if (_owner) {
@@ -129,7 +147,47 @@ void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface, Common::Rect
src._alphaMode = _owner->getAlphaType();
}
}
- src.blit(*_targetSurface, dstRect->left, dstRect->top, _transform._flip, clipRect, _transform._rgbaMod, clipRect->width(), clipRect->height(), _transform._blendMode);
+
+ if (_transform._numTimesX * _transform._numTimesY == 1) {
+
+ src.blit(*_targetSurface, dstRect->left, dstRect->top, _transform._flip, clipRect, _transform._rgbaMod, clipRect->width(), clipRect->height(), _transform._blendMode);
+
+ } else {
+
+ // clipRect is a subrect of the full numTimesX*numTimesY rect
+ Common::Rect subRect;
+
+ int y = 0;
+ int w = getSurface()->w;
+ int h = getSurface()->h;
+ assert(w == _dstRect.width() / _transform._numTimesX);
+ assert(h == _dstRect.height() / _transform._numTimesY);
+
+ int basex = dstRect->left - clipRect->left;
+ int basey = dstRect->top - clipRect->top;
+
+ for (int ry = 0; ry < _transform._numTimesY; ++ry) {
+ int x = 0;
+ for (int rx = 0; rx < _transform._numTimesX; ++rx) {
+
+ subRect.left = x;
+ subRect.top = y;
+ subRect.setWidth(w);
+ subRect.setHeight(w);
+
+ if (subRect.intersects(*clipRect)) {
+ subRect.clip(*clipRect);
+ subRect.translate(-x, -y);
+ src.blit(*_targetSurface, basex + x + subRect.left, basey + y + subRect.top, _transform._flip, &subRect, _transform._rgbaMod, subRect.width(), subRect.height(), _transform._blendMode);
+
+ }
+
+ x += w;
+ }
+ y += h;
+ }
+ }
+
if (doDelete) {
delete clipRect;
}
diff --git a/engines/wintermute/graphics/transform_struct.cpp b/engines/wintermute/graphics/transform_struct.cpp
index 643c6b413f..822c06f42f 100644
--- a/engines/wintermute/graphics/transform_struct.cpp
+++ b/engines/wintermute/graphics/transform_struct.cpp
@@ -35,6 +35,8 @@ void TransformStruct::init(Point32 zoom, uint32 angle, Point32 hotspot, bool alp
_flip += TransparentSurface::FLIP_H * mirrorX;
_flip += TransparentSurface::FLIP_V * mirrorY;
_offset = offset;
+ _numTimesX = 1;
+ _numTimesY = 1;
}
TransformStruct::TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 hotspotX, int32 hotspotY, TSpriteBlendMode blendMode, uint32 rgbaMod, bool mirrorX, bool mirrorY, int32 offsetX, int32 offsetY) {
@@ -83,6 +85,19 @@ TransformStruct::TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 h
Point32(kDefaultOffsetX, kDefaultOffsetY));
}
+TransformStruct::TransformStruct(int32 numTimesX, int32 numTimesY) {
+ init(Point32(kDefaultZoomX, kDefaultZoomY),
+ kDefaultAngle,
+ Point32(kDefaultHotspotX, kDefaultHotspotY),
+ false,
+ BLEND_NORMAL,
+ kDefaultRgbaMod,
+ false, false,
+ Point32(kDefaultOffsetX, kDefaultOffsetY));
+ _numTimesX = numTimesX;
+ _numTimesY = numTimesY;
+}
+
TransformStruct::TransformStruct() {
init(Point32(kDefaultZoomX, kDefaultZoomY),
kDefaultAngle,
diff --git a/engines/wintermute/graphics/transform_struct.h b/engines/wintermute/graphics/transform_struct.h
index 90a4c1f846..d5a03ea331 100644
--- a/engines/wintermute/graphics/transform_struct.h
+++ b/engines/wintermute/graphics/transform_struct.h
@@ -51,6 +51,7 @@ public:
TransformStruct(float zoomX, float zoomY, uint32 angle, int32 hotspotX, int32 hotspotY, TSpriteBlendMode blendMode, uint32 alpha, bool mirrorX = false, bool mirrorY = false, int32 offsetX = 0, int32 offsetY = 0);
TransformStruct(int32 zoomX, int32 zoomY, TSpriteBlendMode blendMode, uint32 alpha, bool mirrorX = false, bool mirrorY = false);
TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 hotspotX = 0, int32 hotspotY = 0);
+ TransformStruct(int32 numTimesX, int32 numTimesY);
TransformStruct();
Point32 _zoom; ///< Zoom; 100 = no zoom
@@ -61,6 +62,8 @@ public:
TSpriteBlendMode _blendMode;
uint32 _rgbaMod; ///< RGBa
Point32 _offset;
+ int32 _numTimesX;
+ int32 _numTimesY;
bool getMirrorX() const;
bool getMirrorY() const;
@@ -72,7 +75,9 @@ public:
compare._offset == _offset &&
compare._alphaDisable == _alphaDisable &&
compare._rgbaMod == _rgbaMod &&
- compare._blendMode == _blendMode
+ compare._blendMode == _blendMode &&
+ compare._numTimesX == _numTimesX &&
+ compare._numTimesY == _numTimesY
);
}
diff --git a/engines/wintermute/ui/ui_tiled_image.cpp b/engines/wintermute/ui/ui_tiled_image.cpp
index de4b86a6dd..7c28c139f4 100644
--- a/engines/wintermute/ui/ui_tiled_image.cpp
+++ b/engines/wintermute/ui/ui_tiled_image.cpp
@@ -75,8 +75,6 @@ bool UITiledImage::display(int x, int y, int width, int height) {
int nuColumns = (width - (_middleLeft.right - _middleLeft.left) - (_middleRight.right - _middleRight.left)) / tileWidth;
int nuRows = (height - (_upMiddle.bottom - _upMiddle.top) - (_downMiddle.bottom - _downMiddle.top)) / tileHeight;
- int col, row;
-
_gameRef->_renderer->startSpriteBatch();
// top left/right
@@ -88,27 +86,24 @@ bool UITiledImage::display(int x, int y, int width, int height) {
_image->_surface->displayTrans(x + (_upLeft.right - _upLeft.left) + nuColumns * tileWidth, y + (_upMiddle.bottom - _upMiddle.top) + nuRows * tileHeight, _downRight);
// left/right
- int yyy = y + (_upMiddle.bottom - _upMiddle.top);
- for (row = 0; row < nuRows; row++) {
- _image->_surface->displayTrans(x, yyy, _middleLeft);
- _image->_surface->displayTrans(x + (_middleLeft.right - _middleLeft.left) + nuColumns * tileWidth, yyy, _middleRight);
- yyy += tileWidth;
+ if (nuRows > 0) {
+ int yyy = y + (_upMiddle.bottom - _upMiddle.top);
+ _image->_surface->displayTiled(x, yyy, _middleLeft, 1, nuRows);
+ _image->_surface->displayTiled(x + (_middleLeft.right - _middleLeft.left) + nuColumns * tileWidth, yyy, _middleRight, 1, nuRows);
}
// top/bottom
- int xxx = x + (_upLeft.right - _upLeft.left);
- for (col = 0; col < nuColumns; col++) {
- _image->_surface->displayTrans(xxx, y, _upMiddle);
- _image->_surface->displayTrans(xxx, y + (_upMiddle.bottom - _upMiddle.top) + nuRows * tileHeight, _downMiddle);
- xxx += tileWidth;
+ if (nuColumns > 0) {
+ int xxx = x + (_upLeft.right - _upLeft.left);
+ _image->_surface->displayTiled(xxx, y, _upMiddle, nuColumns, 1);
+ _image->_surface->displayTiled(xxx, y + (_upMiddle.bottom - _upMiddle.top) + nuRows * tileHeight, _downMiddle, nuColumns, 1);
}
// tiles
if (nuRows > 0 && nuColumns > 0) {
- yyy = y + (_upMiddle.bottom - _upMiddle.top);
- xxx = x + (_upLeft.right - _upLeft.left);
- _image->_surface->displayTrans(xxx, yyy, _middleMiddle);
- _image->_surface->repeatLastDisplayOp(tileWidth, tileWidth, nuColumns, nuRows);
+ int yyy = y + (_upMiddle.bottom - _upMiddle.top);
+ int xxx = x + (_upLeft.right - _upLeft.left);
+ _image->_surface->displayTiled(xxx, yyy, _middleMiddle, nuColumns, nuRows);
}
_gameRef->_renderer->endSpriteBatch();