summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2011-07-12 03:55:01 +0300
committerAndrei Karas <akaras@inbox.ru>2011-07-16 22:47:14 +0300
commitd0e6d477d245610288ab622ecf47426a9dcbc400 (patch)
treee998d168d8eb4397602021b3b1411f80cc1466a9
parent68b1e0ec82321757f2a29792d38d7eabb7d2cf98 (diff)
downloadmanaplus-d0e6d477d245610288ab622ecf47426a9dcbc400.tar.gz
manaplus-d0e6d477d245610288ab622ecf47426a9dcbc400.tar.bz2
manaplus-d0e6d477d245610288ab622ecf47426a9dcbc400.tar.xz
manaplus-d0e6d477d245610288ab622ecf47426a9dcbc400.zip
Add tiles caching for software mode.
-rw-r--r--src/graphics.cpp49
-rw-r--r--src/graphics.h8
-rw-r--r--src/graphicsvertexes.cpp10
-rw-r--r--src/graphicsvertexes.h18
-rw-r--r--src/map.cpp174
-rw-r--r--src/map.h54
6 files changed, 289 insertions, 24 deletions
diff --git a/src/graphics.cpp b/src/graphics.cpp
index d63c27324..88e88a905 100644
--- a/src/graphics.cpp
+++ b/src/graphics.cpp
@@ -26,6 +26,7 @@
#include "graphicsvertexes.h"
#include "log.h"
+#include "map.h"
#include "resources/image.h"
#include "resources/imageloader.h"
@@ -569,6 +570,49 @@ void Graphics::calcImagePattern(GraphicsVertexes* vert,
vert->incPtr(1);
}
+void Graphics::calcTile(ImageVertexes *vert, int x, int y)
+{
+ // Check that preconditions for blitting are met.
+ if (!vert || !vert->image || !vert->image->mSDLSurface)
+ return;
+
+ const Image *image = vert->image;
+
+ x += mClipStack.top().xOffset;
+ y += mClipStack.top().yOffset;
+
+ DoubleRect *rect = new DoubleRect();
+
+ rect->dst.x = static_cast<short>(x);
+ rect->dst.y = static_cast<short>(y);
+ rect->src.x = static_cast<short>(image->mBounds.x);
+ rect->src.y = static_cast<short>(image->mBounds.y);
+ rect->src.w = static_cast<Uint16>(image->mBounds.w);
+ rect->src.h = static_cast<Uint16>(image->mBounds.h);
+ if (SDL_FakeUpperBlit(image->mSDLSurface, &rect->src,
+ mTarget, &rect->dst) == 1)
+ {
+ vert->sdl.push_back(rect);
+ }
+ else
+ {
+ delete rect;
+ }
+}
+
+void Graphics::drawTile(ImageVertexes *vert)
+{
+ Image *img = vert->image;
+ DoubleRects *rects = &vert->sdl;
+ DoubleRects::iterator it = rects->begin();
+ DoubleRects::iterator it_end = rects->end();
+ while (it != it_end)
+ {
+ SDL_LowerBlit(img->mSDLSurface, &(*it)->src, mTarget, &(*it)->dst);
+ ++ it;
+ }
+}
+
void Graphics::updateScreen()
{
if (mDoubleBuffer)
@@ -845,3 +889,8 @@ void Graphics::fillRectangle(const gcn::Rectangle& rectangle)
SDL_FillRect(mTarget, &rect, color);
}
}
+
+void Graphics::drawMapLayer(MapLayer *layer)
+{
+
+}
diff --git a/src/graphics.h b/src/graphics.h
index 40db25c5d..d6e5f774c 100644
--- a/src/graphics.h
+++ b/src/graphics.h
@@ -35,6 +35,8 @@
class GraphicsVertexes;
class Image;
+class ImageVertexes;
+class MapLayer;
struct SDL_Surface;
@@ -202,6 +204,10 @@ class Graphics : public gcn::SDLGraphics
int x, int y,
int w, int h);
+ virtual void calcTile(ImageVertexes *vert, int x, int y);
+
+ virtual void drawTile(ImageVertexes *vert);
+
virtual void drawImageRect2(GraphicsVertexes* vert,
const ImageRect &imgRect);
@@ -263,6 +269,8 @@ class Graphics : public gcn::SDLGraphics
bool getRedraw()
{ return mRedraw; }
+ void drawMapLayer(MapLayer *layer);
+
int mWidth;
int mHeight;
diff --git a/src/graphicsvertexes.cpp b/src/graphicsvertexes.cpp
index 68e60ea1d..d905b8b64 100644
--- a/src/graphicsvertexes.cpp
+++ b/src/graphicsvertexes.cpp
@@ -165,3 +165,13 @@ std::vector<DoubleRect*> *GraphicsVertexes::getRectsSDL()
{
return &sdl[mPtr].mList;
}
+
+ImageVertexes::~ImageVertexes()
+{
+ delete_all(sdl);
+ sdl.clear();
+#ifdef USE_OPENGL
+ delete_all(ogl);
+ ogl.clear();
+#endif
+}
diff --git a/src/graphicsvertexes.h b/src/graphicsvertexes.h
index c462de976..73346d08c 100644
--- a/src/graphicsvertexes.h
+++ b/src/graphicsvertexes.h
@@ -105,6 +105,24 @@ class OpenGLGraphicsVertexes
};
#endif
+typedef std::vector<DoubleRect*> DoubleRects;
+
+class ImageVertexes
+{
+ public:
+ ImageVertexes() : image(0)
+ { }
+
+ ~ImageVertexes();
+
+ Image *image;
+ DoubleRects sdl;
+
+#ifdef USE_OPENGL
+ std::vector<OpenGLGraphicsVertexes*> ogl;
+#endif
+};
+
class GraphicsVertexes
{
public:
diff --git a/src/map.cpp b/src/map.cpp
index 6e978d5dc..66bdbd4bc 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -26,6 +26,7 @@
#include "client.h"
#include "configuration.h"
#include "graphics.h"
+#include "graphicsvertexes.h"
#include "log.h"
#include "particle.h"
#include "simpleanimation.h"
@@ -130,6 +131,8 @@ MapLayer::~MapLayer()
{
config.removeListener("highlightAttackRange", this);
delete[] mTiles;
+ delete_all(mTempRows);
+ mTempRows.clear();
}
void MapLayer::optionChanged(const std::string &value)
@@ -151,12 +154,12 @@ Image* MapLayer::getTile(int x, int y) const
return mTiles[x + y * mWidth];
}
-void MapLayer::draw(Graphics *graphics, int startX, int startY,
- int endX, int endY, int scrollX, int scrollY,
- int debugFlags) const
+void MapLayer::updateSDL(Graphics *graphics, int startX, int startY,
+ int endX, int endY, int scrollX, int scrollY,
+ int debugFlags)
{
- if (!player_node)
- return;
+ delete_all(mTempRows);
+ mTempRows.clear();
startX -= mX;
startY -= mY;
@@ -179,6 +182,91 @@ void MapLayer::draw(Graphics *graphics, int startX, int startY,
for (int y = startY; y < endY; y++)
{
+ MapRowVertexes *row = new MapRowVertexes();
+ mTempRows.push_back(row);
+
+ Image *lastImage = 0;
+ ImageVertexes *imgVert = 0;
+
+ const int yWidth = y * mWidth;
+ const int py0 = y * 32 + dy;
+
+ for (int x = startX; x < endX; x++)
+ {
+ const int tilePtr = x + yWidth;
+ Image *img = mTiles[tilePtr];
+ if (img)
+ {
+ const int px = x * 32 + dx;
+ const int py = py0 - img->mBounds.h;
+ if (flag || img->mBounds.h <= 32)
+ {
+ if (lastImage != img)
+ {
+ imgVert = new ImageVertexes();
+ imgVert->image = img;
+ row->images.push_back(imgVert);
+ lastImage = img;
+ }
+ graphics->calcTile(imgVert, px, py);
+ }
+ }
+ }
+ }
+}
+
+void MapLayer::drawSDL(Graphics *graphics, int startX, int startY,
+ int endX, int endY, int scrollX, int scrollY,
+ int debugFlags)
+{
+ MapRows::iterator rit = mTempRows.begin();
+ MapRows::iterator rit_end = mTempRows.end();
+ while (rit != rit_end)
+ {
+ MepRowImages *images = &(*rit)->images;
+ MepRowImages::iterator iit = images->begin();
+ MepRowImages::iterator iit_end = images->end();
+ while (iit != iit_end)
+ {
+ graphics->drawTile(*iit);
+ ++ iit;
+ }
+ ++ rit;
+ }
+}
+
+void MapLayer::updateOGL(Graphics *graphics, int startX, int startY,
+ int endX, int endY, int scrollX, int scrollY,
+ int debugFlags)
+{
+
+}
+
+void MapLayer::drawOGL(Graphics *graphics, int startX, int startY,
+ int endX, int endY, int scrollX, int scrollY,
+ int debugFlags)
+{
+ startX -= mX;
+ startY -= mY;
+ endX -= mX;
+ endY -= mY;
+
+ if (startX < 0)
+ startX = 0;
+ if (startY < 0)
+ startY = 0;
+ if (endX > mWidth)
+ endX = mWidth;
+ if (endY > mHeight)
+ endY = mHeight;
+
+ const int dx = (mX * 32) - scrollX;
+ const int dy = (mY * 32) - scrollY + 32;
+ const bool flag = (debugFlags != Map::MAP_SPECIAL
+ && debugFlags != Map::MAP_SPECIAL2);
+
+ for (int y = startY; y < endY; y++)
+ {
const int y32 = y * 32;
const int yWidth = y * mWidth;
@@ -431,7 +519,7 @@ Map::Map(int width, int height, int tileWidth, int tileHeight):
mHasWarps(false),
mDebugFlags(MAP_NORMAL),
mOnClosedList(1), mOnOpenList(2),
- mLastScrollX(0.0f), mLastScrollY(0.0f),
+ mLastAScrollX(0.0f), mLastAScrollY(0.0f),
mOverlayDetail(config.getIntValue("OverlayDetail")),
mOpacity(config.getFloatValue("guialpha")),
mPvp(0),
@@ -440,7 +528,11 @@ Map::Map(int width, int height, int tileWidth, int tileHeight):
mIndexedTilesetsSize(0),
mActorFixX(0),
mActorFixY(0),
- mFringeLayer(0)
+ mFringeLayer(0),
+ mLastX(-1),
+ mLastY(-1),
+ mLastScrollX(-1),
+ mLastScrollY(-1)
{
const int size = mWidth * mHeight;
@@ -593,6 +685,9 @@ void Map::update(int ticks)
void Map::draw(Graphics *graphics, int scrollX, int scrollY)
{
+ if (!player_node)
+ return;
+
// Calculate range of tiles which are on-screen
const int endPixelY = graphics->mHeight + scrollY + mTileHeight - 1
+ mMaxTileHeight - mTileHeight;
@@ -630,6 +725,25 @@ void Map::draw(Graphics *graphics, int scrollX, int scrollY)
Layers::const_iterator layeri = mLayers.begin();
bool overFringe = false;
+ int updateFlag = 0;
+
+ if (mLastX != startX || mLastY != startY)
+ {
+ // fill vectors
+ mLastX = startX;
+ mLastY = startY;
+ mLastScrollX = scrollX;
+ mLastScrollY = scrollY;
+ updateFlag = 1;
+ }
+ else if (mLastScrollX != scrollX || mLastScrollY != scrollY)
+ {
+ // update coords
+ mLastScrollX = scrollX;
+ mLastScrollY = scrollY;
+ updateFlag = 2;
+// updateMapLayer(this, endX, endY, debugFlags);
+ }
if (mDebugFlags == MAP_SPECIAL3 || mDebugFlags == MAP_BLACKWHITE)
{
@@ -657,8 +771,28 @@ void Map::draw(Graphics *graphics, int scrollX, int scrollY)
}
else
{
- (*layeri)->draw(graphics, startX, startY, endX, endY,
- scrollX, scrollY, mDebugFlags);
+ if (!mOpenGL)
+ {
+ if (updateFlag)
+ {
+ (*layeri)->updateSDL(graphics, startX, startY,
+ endX, endY, scrollX, scrollY, mDebugFlags);
+ }
+
+ (*layeri)->drawSDL(graphics, startX, startY, endX, endY,
+ scrollX, scrollY, mDebugFlags);
+ }
+ else
+ {
+ if (updateFlag)
+ {
+ (*layeri)->updateOGL(graphics, startX, startY,
+ endX, endY, scrollX, scrollY, mDebugFlags);
+ }
+
+ (*layeri)->drawOGL(graphics, startX, startY, endX, endY,
+ scrollX, scrollY, mDebugFlags);
+ }
}
}
}
@@ -812,16 +946,16 @@ void Map::updateAmbientLayers(float scrollX, float scrollY)
{
static int lastTick = tick_time; // static = only initialized at first call
- if (mLastScrollX == 0.0f && mLastScrollY == 0.0f)
+ if (mLastAScrollX == 0.0f && mLastAScrollY == 0.0f)
{
// First call - initialisation
- mLastScrollX = scrollX;
- mLastScrollY = scrollY;
+ mLastAScrollX = scrollX;
+ mLastAScrollY = scrollY;
}
// Update Overlays
- float dx = scrollX - mLastScrollX;
- float dy = scrollY - mLastScrollY;
+ float dx = scrollX - mLastAScrollX;
+ float dy = scrollY - mLastAScrollY;
int timePassed = get_elapsed_time(lastTick);
std::vector<AmbientLayer*>::iterator i;
@@ -831,8 +965,8 @@ void Map::updateAmbientLayers(float scrollX, float scrollY)
for (i = mForegrounds.begin(); i != mForegrounds.end(); ++i)
(*i)->update(timePassed, dx, dy);
- mLastScrollX = scrollX;
- mLastScrollY = scrollY;
+ mLastAScrollX = scrollX;
+ mLastAScrollY = scrollY;
lastTick = tick_time;
}
@@ -2066,4 +2200,10 @@ MapObjectList *ObjectsLayer::getAt(unsigned x, unsigned y)
if (x >= mWidth || y >= mHeight)
return 0;
return mTiles[x + y * mWidth];
-} \ No newline at end of file
+}
+
+MapRowVertexes::~MapRowVertexes()
+{
+ delete_all(images);
+ images.clear();
+}
diff --git a/src/map.h b/src/map.h
index 290145f05..6832ed008 100644
--- a/src/map.h
+++ b/src/map.h
@@ -41,6 +41,7 @@
class Animation;
class AmbientLayer;
class Graphics;
+class GraphicsVertexes;
class MapLayer;
class Particle;
class SimpleAnimation;
@@ -49,8 +50,22 @@ class SpecialLayer;
class MapItem;
class ObjectsLayer;
+struct ImageVertexes;
+
typedef std::vector<Tileset*> Tilesets;
typedef std::vector<MapLayer*> Layers;
+typedef std::vector<ImageVertexes*> MepRowImages;
+
+class MapRowVertexes
+{
+ public:
+ MapRowVertexes()
+ { }
+
+ ~MapRowVertexes();
+
+ MepRowImages images;
+};
/**
* A meta tile stores additional information about a location on a tile map.
@@ -156,11 +171,29 @@ class MapLayer: public ConfigListener
* The given actors are only drawn when this layer is the fringe
* layer.
*/
- void draw(Graphics *graphics,
- int startX, int startY,
- int endX, int endY,
- int scrollX, int scrollY,
- int mDebugFlags) const;
+ void drawOGL(Graphics *graphics,
+ int startX, int startY,
+ int endX, int endY,
+ int scrollX, int scrollY,
+ int mDebugFlags);
+
+ void drawSDL(Graphics *graphics,
+ int startX, int startY,
+ int endX, int endY,
+ int scrollX, int scrollY,
+ int mDebugFlags);
+
+ void updateOGL(Graphics *graphics,
+ int startX, int startY,
+ int endX, int endY,
+ int scrollX, int scrollY,
+ int mDebugFlags);
+
+ void updateSDL(Graphics *graphics,
+ int startX, int startY,
+ int endX, int endY,
+ int scrollX, int scrollY,
+ int mDebugFlags);
void drawFringe(Graphics *graphics,
int startX, int startY,
@@ -204,6 +237,8 @@ class MapLayer: public ConfigListener
// int *mTilesCount;
SpecialLayer *mSpecialLayer;
SpecialLayer *mTempLayer;
+ typedef std::vector<MapRowVertexes*> MapRows;
+ MapRows mTempRows;
};
/**
@@ -533,8 +568,8 @@ class Map : public Properties, public ConfigListener
// Overlay data
std::vector<AmbientLayer*> mBackgrounds;
std::vector<AmbientLayer*> mForegrounds;
- float mLastScrollX;
- float mLastScrollY;
+ float mLastAScrollX;
+ float mLastAScrollY;
// bool mSpritesUpdated;
// Particle effect data
@@ -567,6 +602,11 @@ class Map : public Properties, public ConfigListener
SpecialLayer *mTempLayer;
ObjectsLayer *mObjects;
MapLayer *mFringeLayer;
+
+ int mLastX;
+ int mLastY;
+ int mLastScrollX;
+ int mLastScrollY;
};