summaryrefslogtreecommitdiffstats
path: root/src/view/SpriteCache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/SpriteCache.cpp')
-rw-r--r--src/view/SpriteCache.cpp83
1 files changed, 74 insertions, 9 deletions
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 <cstring>
+
#include <SDL_image.h>
@@ -33,26 +35,89 @@ namespace RPGEdit {
namespace View {
-std::unique_ptr<SDL_Surface, SpriteCache::SDL_Surface_deleter> 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<SDL_Surface, SDL_Surface_deleter>(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<uint8_t *>(base->pixels);
+ uint8_t *dst = reinterpret_cast<uint8_t *>(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<SDL_Surface, SDL_Surface_deleter> &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();
}