diff options
author | Andrei Karas <akaras@inbox.ru> | 2011-07-12 03:55:01 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2011-07-16 22:47:14 +0300 |
commit | d0e6d477d245610288ab622ecf47426a9dcbc400 (patch) | |
tree | e998d168d8eb4397602021b3b1411f80cc1466a9 | |
parent | 68b1e0ec82321757f2a29792d38d7eabb7d2cf98 (diff) | |
download | manaplus-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.cpp | 49 | ||||
-rw-r--r-- | src/graphics.h | 8 | ||||
-rw-r--r-- | src/graphicsvertexes.cpp | 10 | ||||
-rw-r--r-- | src/graphicsvertexes.h | 18 | ||||
-rw-r--r-- | src/map.cpp | 174 | ||||
-rw-r--r-- | src/map.h | 54 |
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(); +} @@ -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; }; |