From 3c0089e31e1392f38cfb0e13d7c4d395bad4f949 Mon Sep 17 00:00:00 2001 From: Tobia Tesan Date: Thu, 27 Jun 2013 15:47:05 +0200 Subject: WINTERMUTE: Introduce TransformTools --- engines/wintermute/base/base_sub_frame.cpp | 11 ++++ engines/wintermute/graphics/transform_tools.cpp | 75 +++++++++++++++++++++++++ engines/wintermute/graphics/transform_tools.h | 47 ++++++++++++++++ engines/wintermute/math/floatpoint.h | 52 +++++++++++++++++ engines/wintermute/math/floatrect.h | 52 ----------------- engines/wintermute/math/rect32.h | 3 +- engines/wintermute/module.mk | 1 + 7 files changed, 188 insertions(+), 53 deletions(-) create mode 100644 engines/wintermute/graphics/transform_tools.cpp create mode 100644 engines/wintermute/graphics/transform_tools.h create mode 100644 engines/wintermute/math/floatpoint.h delete mode 100644 engines/wintermute/math/floatrect.h (limited to 'engines') diff --git a/engines/wintermute/base/base_sub_frame.cpp b/engines/wintermute/base/base_sub_frame.cpp index d93cf667f1..d9620d3939 100644 --- a/engines/wintermute/base/base_sub_frame.cpp +++ b/engines/wintermute/base/base_sub_frame.cpp @@ -38,6 +38,8 @@ #include "engines/wintermute/base/gfx/base_renderer.h" #include "engines/wintermute/base/scriptables/script_value.h" #include "engines/wintermute/base/scriptables/script_stack.h" +#include "engines/wintermute/graphics/transform_tools.h" +#include "engines/wintermute/graphics/transform_struct.h" namespace Wintermute { @@ -256,6 +258,15 @@ bool BaseSubFrame::draw(int x, int y, BaseObject *registerOwner, float zoomX, fl } if (rotate != 0.0f) { + Point32 boxOffset, rotatedHotspot, hotspotOffset, newOrigin; + Point32 origin(x, y); + Rect32 oldRect = getRect(); + Point32 newHotspot; + TransformStruct transform = TransformStruct(zoomX, zoomY, rotate, _hotspotX, _hotspotY, blendMode, alpha, _mirrorX, _mirrorY, 0, 0); + Rect32 newRect = TransformTools::newRect (oldRect, transform, &newHotspot); + newOrigin = origin - newHotspot; + // When the transform functions are refactored to use TransformStruct this will be like: + // res = _surface->displayTransform(newOrigin.x, newOrigin.y, oldRect, newRect, transformStruct); res = _surface->displayTransform((int)(x - _hotspotX * (zoomX / 100)), (int)(y - _hotspotY * (zoomY / 100)), _hotspotX, _hotspotY, getRect(), zoomX, zoomY, alpha, rotate, blendMode, _mirrorX, _mirrorY); } else { if (zoomX == 100 && zoomY == 100) { diff --git a/engines/wintermute/graphics/transform_tools.cpp b/engines/wintermute/graphics/transform_tools.cpp new file mode 100644 index 0000000000..2390b86391 --- /dev/null +++ b/engines/wintermute/graphics/transform_tools.cpp @@ -0,0 +1,75 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + +#include "engines/wintermute/graphics/transform_tools.h" +#include + +namespace Wintermute { + + FloatPoint TransformTools::transformPoint(FloatPoint point, float rotate, Point32 zoom, bool mirrorX, bool mirrorY) { + /* + * Returns the coordinates for a point after rotation + */ + float rotateRad = rotate * M_PI / 180; + FloatPoint newPoint; + newPoint.x = (point.x * cos(rotateRad) - point.y * sin(rotateRad))*zoom.x/100; + newPoint.y = (point.x * sin(rotateRad) + point.y * cos(rotateRad))*zoom.y/100; + if (mirrorX) newPoint.x *= -1; + if (mirrorY) newPoint.y *= -1; + /* + * I apply the textbook formula, but first I reverse the Y-axis, otherwise + * I'd be performing a rotation in the wrong direction + */ + return newPoint; + } + + Rect32 TransformTools::newRect (Rect32 oldRect, TransformStruct transform, Point32 *newHotspot) { + Point32 nw(oldRect.left, oldRect.top); + Point32 ne(oldRect.right, oldRect.top); + Point32 sw(oldRect.left, oldRect.bottom); + Point32 se(oldRect.right, oldRect.bottom); + + FloatPoint nw1, ne1, sw1, se1; + + nw1 = transformPoint(nw - transform._hotspot, transform._angle, transform._zoom); + ne1 = transformPoint(ne - transform._hotspot, transform._angle, transform._zoom); + sw1 = transformPoint(sw - transform._hotspot, transform._angle, transform._zoom); + se1 = transformPoint(se - transform._hotspot, transform._angle, transform._zoom); + + float top = MIN(nw1.y, MIN(ne1.y, MIN(sw1.y, se1.y))); + float bottom = MAX(nw1.y, MAX(ne1.y, MAX(sw1.y, se1.y))); + 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 = -floor(top); + newHotspot->x = -floor(left); + + res.top = floor(top) + transform._hotspot.y; + res.bottom = ceil(bottom) + transform._hotspot.y; + res.left = floor(left) + transform._hotspot.x; + res.right = ceil(right) + transform._hotspot.x; + + return res; + } +} diff --git a/engines/wintermute/graphics/transform_tools.h b/engines/wintermute/graphics/transform_tools.h new file mode 100644 index 0000000000..fbc0653e64 --- /dev/null +++ b/engines/wintermute/graphics/transform_tools.h @@ -0,0 +1,47 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef WINTERMUTE_TRANSFORMTOOLS_H +#define WINTERMUTE_TRANSFORMTOOLS_H + +#include "engines/wintermute/math/rect32.h" +#include "engines/wintermute/math/floatpoint.h" +#include "engines/wintermute/graphics/transform_struct.h" + +namespace Wintermute { +class TransformTools { +public: + /** + * Basic transform (scale + rotate) for a single point + */ + static FloatPoint transformPoint(FloatPoint point, float rotate, Point32 zoom, bool mirrorX = false, bool mirrorY = false); + + /** + * Takes a rectangle, a transform and a pointer to a point, "newHotspot". + * In return you get the smallest rect that can contain the transformed sprite + * and, as a side-effect, "newHotspot" will tell you where the hotspot will + * have ended up in the new rect, for centering. + */ + static Rect32 newRect (Rect32 oldRect, TransformStruct transform, Point32 *newHotspot); +}; +} // end of namespace Wintermute +#endif diff --git a/engines/wintermute/math/floatpoint.h b/engines/wintermute/math/floatpoint.h new file mode 100644 index 0000000000..bf194d8437 --- /dev/null +++ b/engines/wintermute/math/floatpoint.h @@ -0,0 +1,52 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef WINTERMUTE_FLOATPOINT_H +#define WINTERMUTE_FLOATPOINT_H + +namespace Wintermute { + +struct FloatPoint { + float x; + float y; + FloatPoint() : x(0), y(0) {} + FloatPoint(float x1, float y1) : x(x1), y(y1) {} + bool operator==(const FloatPoint &p) const { return x == p.x && y == p.y; } + bool operator!=(const FloatPoint &p) const { return x != p.x || y != p.y; } + FloatPoint operator+(const FloatPoint &delta) const { return FloatPoint (x + delta.x, y + delta.y); } + FloatPoint operator-(const FloatPoint &delta) const { return FloatPoint (x - delta.x, y - delta.y); } + + FloatPoint& operator+=(const FloatPoint &delta) { + x += delta.x; + y += delta.y; + return *this; + } + FloatPoint& operator-=(const FloatPoint &delta) { + x -= delta.x; + y -= delta.y; + return *this; + } +}; + +} // end of namespace Wintermute + +#endif diff --git a/engines/wintermute/math/floatrect.h b/engines/wintermute/math/floatrect.h deleted file mode 100644 index f8eb3827fd..0000000000 --- a/engines/wintermute/math/floatrect.h +++ /dev/null @@ -1,52 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef WINTERMUTE_FLOATRECT_H -#define WINTERMUTE_FLOATRECT_H - -namespace Wintermute { - -struct FloatPoint { - float x; - float y; - FloatPoint() : x(0), y(0) {} - FloatPoint(float x1, float y1) : x(x1), y(y1) {} - bool operator==(const FloatPoint &p) const { return x == p.x && y == p.y; } - bool operator!=(const FloatPoint &p) const { return x != p.x || y != p.y; } - FloatPoint operator+(const FloatPoint &delta) const { return FloatPoint (x + delta.x, y + delta.y); } - FloatPoint operator-(const FloatPoint &delta) const { return FloatPoint (x - delta.x, y - delta.y); } - - FloatPoint& operator+=(const FloatPoint &delta) { - x += delta.x; - y += delta.y; - return *this; - } - FloatPoint& operator-=(const FloatPoint &delta) { - x -= delta.x; - y -= delta.y; - return *this; - } -}; - -} // end of namespace Wintermute - -#endif diff --git a/engines/wintermute/math/rect32.h b/engines/wintermute/math/rect32.h index 6618a51e91..d44655311c 100644 --- a/engines/wintermute/math/rect32.h +++ b/engines/wintermute/math/rect32.h @@ -24,7 +24,8 @@ #define WINTERMUTE_RECT32_H #include "common/system.h" -#include "engines/wintermute/math/floatrect.h" +#include "engines/wintermute/math/floatpoint.h" +#include "common/rect.h" namespace Wintermute { diff --git a/engines/wintermute/module.mk b/engines/wintermute/module.mk index d1edced818..95f9ba2ffb 100644 --- a/engines/wintermute/module.mk +++ b/engines/wintermute/module.mk @@ -90,6 +90,7 @@ MODULE_OBJS := \ base/timer.o \ detection.o \ graphics/transform_struct.o \ + graphics/transform_tools.o \ graphics/transparent_surface.o \ math/math_util.o \ math/matrix4.o \ -- cgit v1.2.3