diff options
4 files changed, 38 insertions, 17 deletions
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp index c00dd56085..f1412157c3 100644 --- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp +++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp @@ -37,6 +37,7 @@ #include "graphics/decoders/jpeg.h" #include "graphics/decoders/tga.h" #include "engines/wintermute/graphics/transparent_surface.h" +#include "engines/wintermute/graphics/transform_tools.h" #include "graphics/pixelformat.h" #include "graphics/surface.h" #include "common/stream.h" @@ -418,8 +419,19 @@ 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) * transform._numTimesX); - position.setHeight((int16)((float)srcRect.height() * transform._zoom.y / kDefaultZoomY) * transform._numTimesY); + + Rect32 r; + r.top = 0; + r.left = 0; + r.setWidth(rect->width()); + r.setHeight(rect->height()); + + r = TransformTools::newRect(r, transform, 0); + + position.top = r.top + y; + position.left = r.left + x; + position.setWidth(r.width() * transform._numTimesX); + position.setHeight(r.height() * transform._numTimesY); } renderer->modTargetRect(&position); diff --git a/engines/wintermute/base/gfx/osystem/render_ticket.cpp b/engines/wintermute/base/gfx/osystem/render_ticket.cpp index 7a926c3e36..0fb68bc819 100644 --- a/engines/wintermute/base/gfx/osystem/render_ticket.cpp +++ b/engines/wintermute/base/gfx/osystem/render_ticket.cpp @@ -54,6 +54,9 @@ RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *s // 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. + // NB: Mirroring and rotation are probably done in the wrong order. + // (Mirroring should most likely be done before rotation. See also + // TransformTools.) if (_transform._angle != kDefaultAngle) { TransparentSurface src(*_surface, false); Graphics::Surface *temp = src.rotoscale(transform); @@ -71,14 +74,6 @@ RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *s } } else { _surface = nullptr; - - if (transform._angle != kDefaultAngle) { // Make sure comparison-tickets get the correct width - Rect32 newDstRect; - Point32 newHotspot; - newDstRect = TransformTools::newRect(_srcRect, transform, &newHotspot); - _dstRect.setWidth(newDstRect.right - newDstRect.left); - _dstRect.setHeight(newDstRect.bottom - newDstRect.top); - } } } diff --git a/engines/wintermute/graphics/transform_tools.cpp b/engines/wintermute/graphics/transform_tools.cpp index ebf9092aaa..dc92cdbbfd 100644 --- a/engines/wintermute/graphics/transform_tools.cpp +++ b/engines/wintermute/graphics/transform_tools.cpp @@ -26,11 +26,23 @@ namespace Wintermute { -FloatPoint TransformTools::transformPoint(const FloatPoint &point, const float rotate, const Point32 &zoom, const bool mirrorX, const bool mirrorY) { +FloatPoint TransformTools::transformPoint(FloatPoint point, const float rotate, const Point32 &zoom, const bool mirrorX, const bool mirrorY) { float rotateRad = rotate * M_PI / 180.0f; + float x = point.x; + float y = point.y; + x = (x * zoom.x) / kDefaultZoomX; + y = (y * zoom.y) / kDefaultZoomY; +#if 0 + // TODO: Mirroring should be done before rotation, but the blitting + // code does the inverse, so we match that for now. + if (mirrorX) + x *= -1; + if (mirrorY) + y *= -1; +#endif FloatPoint newPoint; - newPoint.x = (point.x * cos(rotateRad) - point.y * sin(rotateRad)) * zoom.x / kDefaultZoomX; - newPoint.y = (point.x * sin(rotateRad) + point.y * cos(rotateRad)) * zoom.y / kDefaultZoomY; + newPoint.x = x * cos(rotateRad) - y * sin(rotateRad); + newPoint.y = x * sin(rotateRad) + y * cos(rotateRad); if (mirrorX) { newPoint.x *= -1; } @@ -58,10 +70,12 @@ Rect32 TransformTools::newRect(const Rect32 &oldRect, const TransformStruct &tra float left = MIN(nw1.x, MIN(ne1.x, MIN(sw1.x, se1.x))); float right = MAX(nw1.x, MAX(ne1.x, MAX(sw1.x, se1.x))); - Rect32 res; - newHotspot->y = (uint32)(-floor(top)); - newHotspot->x = (uint32)(-floor(left)); + if (newHotspot) { + newHotspot->y = (uint32)(-floor(top)); + newHotspot->x = (uint32)(-floor(left)); + } + Rect32 res; res.top = (int32)(floor(top)) + transform._hotspot.y; res.bottom = (int32)(ceil(bottom)) + transform._hotspot.y; res.left = (int32)(floor(left)) + transform._hotspot.x; diff --git a/engines/wintermute/graphics/transform_tools.h b/engines/wintermute/graphics/transform_tools.h index c92b81fd11..9a73e3b69f 100644 --- a/engines/wintermute/graphics/transform_tools.h +++ b/engines/wintermute/graphics/transform_tools.h @@ -34,7 +34,7 @@ public: /** * Basic transform (scale + rotate) for a single point */ - static FloatPoint transformPoint(const FloatPoint &point, const float rotate, const Point32 &zoom, const bool mirrorX = false, const bool mirrorY = false); + static FloatPoint transformPoint(FloatPoint point, const float rotate, const Point32 &zoom, const bool mirrorX = false, const bool mirrorY = false); /** * @param &point the point on which the transform is to be applied |