summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBertram <bertram@cegetel.net>2009-07-27 01:02:27 +0200
committerBertram <bertram@cegetel.net>2009-07-27 01:02:27 +0200
commitfa1a3ab995f037ddf33817a1b2ce143130a457f8 (patch)
tree4cfc52364c271a9a318a2fee4b611514d7941476
parent7bc30f545784b26594803b559f1d76d5434027ea (diff)
downloadmana-fa1a3ab995f037ddf33817a1b2ce143130a457f8.tar.gz
mana-fa1a3ab995f037ddf33817a1b2ce143130a457f8.tar.bz2
mana-fa1a3ab995f037ddf33817a1b2ce143130a457f8.tar.xz
mana-fa1a3ab995f037ddf33817a1b2ce143130a457f8.zip
Added the ability to ask a ambient layer to keep its ratio when the resolution isn't the default.
You'll have to add this in map properties, for instance if you're want to keep ratio on overlay 0: <map version="1.0" orientation="orthogonal" width="128" height="128" tilewidth="32" tileheight="32"> <properties> ... <property name="overlay0keepratio" value="true"/> ... </properties> </map>
-rw-r--r--src/graphics.cpp42
-rw-r--r--src/graphics.h10
-rw-r--r--src/main.cpp3
-rw-r--r--src/map.cpp3
-rw-r--r--src/openglgraphics.cpp43
-rw-r--r--src/openglgraphics.h7
-rw-r--r--src/properties.h20
-rw-r--r--src/resources/ambientoverlay.cpp42
-rw-r--r--src/resources/ambientoverlay.h5
9 files changed, 165 insertions, 10 deletions
diff --git a/src/graphics.cpp b/src/graphics.cpp
index b84e0bf6..75db11f4 100644
--- a/src/graphics.cpp
+++ b/src/graphics.cpp
@@ -221,6 +221,48 @@ void Graphics::drawImagePattern(Image *image, int x, int y, int w, int h)
}
}
+void Graphics::drawRescaledImagePattern(Image *image, int x, int y,
+ int w, int h, int scaledWidth, int scaledHeight)
+{
+ // Check that preconditions for blitting are met.
+ if (!mScreen || !image) return;
+ if (!image->mImage) return;
+
+ if (scaledHeight == 0 || scaledWidth == 0) return;
+
+ Image *tmpImage = image->SDLgetScaledImage(scaledWidth, scaledHeight);
+ if (!tmpImage) return;
+
+ const int iw = tmpImage->getWidth();
+ const int ih = tmpImage->getHeight();
+
+ if (iw == 0 || ih == 0) return;
+
+ for (int py = 0; py < h; py += ih) // Y position on pattern plane
+ {
+ int dh = (py + ih >= h) ? h - py : ih;
+ int srcY = tmpImage->mBounds.y;
+ int dstY = y + py + mClipStack.top().yOffset;
+
+ for (int px = 0; px < w; px += iw) // X position on pattern plane
+ {
+ int dw = (px + iw >= w) ? w - px : iw;
+ int srcX = tmpImage->mBounds.x;
+ int dstX = x + px + mClipStack.top().xOffset;
+
+ SDL_Rect dstRect;
+ SDL_Rect srcRect;
+ dstRect.x = dstX; dstRect.y = dstY;
+ srcRect.x = srcX; srcRect.y = srcY;
+ srcRect.w = dw; srcRect.h = dh;
+
+ SDL_BlitSurface(tmpImage->mImage, &srcRect, mScreen, &dstRect);
+ }
+ }
+
+ delete tmpImage;
+}
+
void Graphics::drawImageRect(int x, int y, int w, int h,
Image *topLeft, Image *topRight,
Image *bottomLeft, Image *bottomRight,
diff --git a/src/graphics.h b/src/graphics.h
index eca7e1a5..b8e87af1 100644
--- a/src/graphics.h
+++ b/src/graphics.h
@@ -29,6 +29,9 @@ class ImageRect;
struct SDL_Surface;
+static const int defaultScreenWidth = 800;
+static const int defaultScreenHeight = 600;
+
/**
* 9 images defining a rectangle. 4 corners, 4 sides and a middle area. The
* topology is as follows:
@@ -143,6 +146,13 @@ class Graphics : public gcn::SDLGraphics
int w, int h);
/**
+ * Draw a pattern based on a rescaled version of the given image...
+ */
+ virtual void drawRescaledImagePattern(Image *image,
+ int x, int y, int w, int h,
+ int scaledWidth, int scaledHeight);
+
+ /**
* Draws a rectangle using images. 4 corner images, 4 side images and 1
* image for the inside.
*/
diff --git a/src/main.cpp b/src/main.cpp
index 6dd6ba6b..10145dfc 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -143,9 +143,6 @@ namespace
} listener;
}
-static const int defaultScreenWidth = 800;
-static const int defaultScreenHeight = 600;
-
static const int defaultSfxVolume = 100;
static const int defaultMusicVolume = 60;
diff --git a/src/map.cpp b/src/map.cpp
index 61fcdfe8..38c49112 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -218,11 +218,12 @@ void Map::initializeOverlays()
const float speedX = getFloatProperty(name + "scrollX");
const float speedY = getFloatProperty(name + "scrollY");
const float parallax = getFloatProperty(name + "parallax");
+ const bool keepRatio = getBoolProperty(name + "keepratio");
if (img)
{
mOverlays.push_back(
- new AmbientOverlay(img, parallax, speedX, speedY));
+ new AmbientOverlay(img, parallax, speedX, speedY, keepRatio));
// The AmbientOverlay takes control over the image.
img->decRef();
diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp
index 5c9e2049..4d66a919 100644
--- a/src/openglgraphics.cpp
+++ b/src/openglgraphics.cpp
@@ -277,6 +277,49 @@ void OpenGLGraphics::drawImagePattern(Image *image, int x, int y, int w, int h)
glColor4ub(mColor.r, mColor.g, mColor.b, mColor.a);
}
+void OpenGLGraphics::drawRescaledImagePattern(Image *image, int x, int y,
+ int w, int h,
+ int scaledWidth, int scaledHeight)
+{
+ if (!image)
+ return;
+
+ const int srcX = image->mBounds.x;
+ const int srcY = image->mBounds.y;
+
+ const int iw = scaledWidth;
+ const int ih = scaledHeight;
+ if (iw == 0 || ih == 0)
+ return;
+
+ glColor4f(1.0f, 1.0f, 1.0f, image->mAlpha);
+
+ glBindTexture(Image::mTextureType, image->mGLImage);
+
+ setTexturingAndBlending(true);
+
+ // Draw a set of textured rectangles
+ glBegin(GL_QUADS);
+
+ for (int py = 0; py < h; py += ih)
+ {
+ const int height = (py + ih >= h) ? h - py : ih;
+ const int dstY = y + py;
+ for (int px = 0; px < w; px += iw)
+ {
+ int width = (px + iw >= w) ? w - px : iw;
+ int dstX = x + px;
+
+ drawRescaledQuad(image, srcX, srcY, dstX, dstY,
+ width, height, scaledWidth, scaledHeight);
+ }
+ }
+
+ glEnd();
+
+ glColor4ub(mColor.r, mColor.g, mColor.b, mColor.a);
+}
+
void OpenGLGraphics::updateScreen()
{
glFlush();
diff --git a/src/openglgraphics.h b/src/openglgraphics.h
index 3553cac3..0bee48b4 100644
--- a/src/openglgraphics.h
+++ b/src/openglgraphics.h
@@ -59,6 +59,13 @@ class OpenGLGraphics : public Graphics
int x, int y,
int w, int h);
+ /**
+ * Draw a pattern based on a rescaled version of the given image...
+ */
+ void drawRescaledImagePattern(Image *image,
+ int x, int y, int w, int h,
+ int scaledWidth, int scaledHeight);
+
void updateScreen();
void _beginDraw();
diff --git a/src/properties.h b/src/properties.h
index a2ce5b88..75335377 100644
--- a/src/properties.h
+++ b/src/properties.h
@@ -74,6 +74,26 @@ class Properties
}
/**
+ * Gets a map property as a boolean.
+ *
+ * @param name The name of the property.
+ * @param def Default value, false by default.
+ * @return the value of the given property, or false when it doesn't
+ * exist.
+ */
+ float getBoolProperty(const std::string &name, bool def = false) const
+ {
+ PropertyMap::const_iterator i = mProperties.find(name);
+ bool ret = def;
+ if (i != mProperties.end())
+ {
+ if (i->second == "true")
+ ret = true;
+ }
+ return ret;
+ }
+
+ /**
* Returns whether a certain property is available.
*
* @param name The name of the property.
diff --git a/src/resources/ambientoverlay.cpp b/src/resources/ambientoverlay.cpp
index 93c7c3e1..8c851e2e 100644
--- a/src/resources/ambientoverlay.cpp
+++ b/src/resources/ambientoverlay.cpp
@@ -22,16 +22,41 @@
#include "resources/ambientoverlay.h"
#include "resources/image.h"
-
+#include "resources/resourcemanager.h"
#include "graphics.h"
AmbientOverlay::AmbientOverlay(Image *img, float parallax,
- float speedX, float speedY):
+ float speedX, float speedY, bool keepRatio):
mImage(img), mParallax(parallax),
mPosX(0), mPosY(0),
- mSpeedX(speedX), mSpeedY(speedY)
+ mSpeedX(speedX), mSpeedY(speedY),
+ mKeepRatio(keepRatio)
{
- mImage->incRef();
+
+ if (keepRatio && !mImage->isAnOpenGLOne()
+ && defaultScreenWidth != 0
+ && defaultScreenHeight != 0
+ && graphics->getWidth() != defaultScreenWidth
+ && graphics->getHeight() != defaultScreenHeight)
+ {
+ // Rescale the overlay to keep the ratio as if we were on
+ // the default resolution...
+ Image *rescaledOverlay = mImage->SDLgetScaledImage(
+ (int) mImage->getWidth() / defaultScreenWidth * graphics->getWidth(),
+ (int) mImage->getHeight() / defaultScreenHeight * graphics->getHeight());
+
+ if (rescaledOverlay)
+ {
+ // Replace the resource with the new one...
+ std::string idPath = mImage->getIdPath() + "_rescaled";
+ ResourceManager::getInstance()->addResource(idPath, rescaledOverlay);
+ mImage = rescaledOverlay;
+ }
+ else
+ mImage->incRef();
+ }
+ else
+ mImage->incRef();
}
AmbientOverlay::~AmbientOverlay()
@@ -66,6 +91,13 @@ void AmbientOverlay::update(int timePassed, float dx, float dy)
void AmbientOverlay::draw(Graphics *graphics, int x, int y)
{
- graphics->drawImagePattern(mImage,
+ if (!mImage->isAnOpenGLOne() || !mKeepRatio)
+ graphics->drawImagePattern(mImage,
(int) -mPosX, (int) -mPosY, x + (int) mPosX, y + (int) mPosY);
+ else
+ graphics->drawRescaledImagePattern(mImage,
+ (int) -mPosX, (int) -mPosY, x + (int) mPosX, y + (int) mPosY,
+ (int) mImage->getWidth() / defaultScreenWidth * graphics->getWidth(),
+ (int) mImage->getHeight() / defaultScreenHeight * graphics->getHeight());
+
}
diff --git a/src/resources/ambientoverlay.h b/src/resources/ambientoverlay.h
index 756d0eb7..f2d2e588 100644
--- a/src/resources/ambientoverlay.h
+++ b/src/resources/ambientoverlay.h
@@ -35,9 +35,11 @@ class AmbientOverlay
* @param parallax scroll factor based on camera position
* @param speedX scrolling speed in x-direction
* @param speedY scrolling speed in y-direction
+ * @param keepRatio rescale the image to keep
+ * the same ratio than in 800x600 resolution mode.
*/
AmbientOverlay(Image *img, float parallax,
- float speedX, float speedY);
+ float speedX, float speedY, bool keepRatio = false);
~AmbientOverlay();
@@ -52,6 +54,7 @@ class AmbientOverlay
float mPosY; /**< Current layer Y position. */
float mSpeedX; /**< Scrolling speed in X direction. */
float mSpeedY; /**< Scrolling speed in Y direction. */
+ bool mKeepRatio; /**< Keep overlay ratio on every resolution */
};
#endif