From 9b91d6f3d0187e0daf29a262cf19ad08ba2b7cf5 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 26 Sep 2014 03:08:15 +0200 Subject: Add support for rotated sprites --- src/view/SpriteCache.cpp | 83 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 9 deletions(-) (limited to 'src/view/SpriteCache.cpp') diff --git a/src/view/SpriteCache.cpp b/src/view/SpriteCache.cpp index 82f669f..bd67346 100644 --- a/src/view/SpriteCache.cpp +++ b/src/view/SpriteCache.cpp @@ -26,6 +26,8 @@ #include "SpriteCache.hpp" +#include + #include @@ -33,26 +35,89 @@ namespace RPGEdit { namespace View { -std::unique_ptr SpriteCache::load(const std::string &name) { - std::string filename = "../resources/sprite/" + name + ".png"; +SpriteCache::sprite_value SpriteCache::load(const std::string &id) { + std::string filename = "../resources/sprite/" + id + ".png"; SDL_Surface *surface = IMG_Load(filename.c_str()); - return std::unique_ptr(surface, SDL_Surface_deleter()); + return sprite_value(surface, SDL_Surface_deleter()); +} + +SpriteCache::sprite_value SpriteCache::load(const std::string &id, unsigned rotation) { + if (!rotation) + return load(id); + + sprite_value &base = get(id, 0); + SDL_Surface *surface; + + SDL_LockSurface(base.get()); + + int w = base->w, h = base->h, d = base->format->BytesPerPixel, w2, h2; + + if (rotation == 2) { + w2 = w; + h2 = h; + } + else { + w2 = h; + h2 = w; + } + + surface = SDL_CreateRGBSurface(0, w2, h2, base->format->BitsPerPixel, + base->format->Rmask, base->format->Gmask, base->format->Bmask, base->format->Amask); + + SDL_LockSurface(surface); + + uint8_t *src = reinterpret_cast(base->pixels); + uint8_t *dst = reinterpret_cast(surface->pixels); + + for (int x = 0; x < w; x++) { + for (int y = 0; y < h; y++) { + int x2, y2; + + switch (rotation) { + case 1: + x2 = y; + y2 = w - x - 1; + break; + case 2: + x2 = w - x - 1; + y2 = h - y - 1; + break; + case 3: + x2 = h - y - 1; + y2 = x; + } + + std::memcpy(dst + d * (y2*w2 + x2), src + d * (y*w + x), d); + } + } + + SDL_UnlockSurface(surface); + SDL_UnlockSurface(base.get()); + + return sprite_value(surface, SDL_Surface_deleter()); } -SDL_Surface * SpriteCache::get(const std::string &type, const std::string &name) { - std::string id = type + "/" + name; +SpriteCache::sprite_value & SpriteCache::get(const std::string &id, unsigned rotation) { + sprite_key key(id, rotation); - std::unique_ptr &surface = sprites[id]; + sprite_value &surface = sprites[key]; if (!surface) - surface = load(id); + surface = load(id, rotation); if (!surface) - sprites.erase(sprites.find(id)); + sprites.erase(sprites.find(key)); + + return surface; +} + +SDL_Surface * SpriteCache::get(const std::string &type, const std::string &name, unsigned rotation) { + if (rotation >= 4) + return nullptr; - return surface.get(); + return get(type + "/" + name, rotation).get(); } -- cgit v1.2.3