From b5c7b4a162a780980b3ecacf0edd49541888a0a8 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 24 Sep 2014 02:27:30 +0200 Subject: Move more SDL-specific things to the view --- src/CMakeLists.txt | 2 +- src/control/ImageLoader.cpp | 59 ------------------------------------------ src/control/ImageLoader.hpp | 62 --------------------------------------------- src/control/MapContext.cpp | 15 ++--------- src/control/MapContext.hpp | 9 ++----- src/control/RPGEdit.cpp | 2 +- src/control/RPGEdit.hpp | 1 - src/view/MapView.cpp | 31 +++++++++++++---------- src/view/MapView.hpp | 10 ++++---- src/view/SpriteCache.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++ src/view/SpriteCache.hpp | 62 +++++++++++++++++++++++++++++++++++++++++++++ src/view/Window.hpp | 8 ++++++ 12 files changed, 159 insertions(+), 163 deletions(-) delete mode 100644 src/control/ImageLoader.cpp delete mode 100644 src/control/ImageLoader.hpp create mode 100644 src/view/SpriteCache.cpp create mode 100644 src/view/SpriteCache.hpp (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 71fc6e2..54836d0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,11 +3,11 @@ link_directories(${SDL2_LIBRARY_DIRS}) add_executable(rpgedit rpgedit.cpp - control/ImageLoader.cpp control/MapContext.cpp control/RPGEdit.cpp model/Map.cpp view/MapView.cpp + view/SpriteCache.cpp ) set_target_properties(rpgedit PROPERTIES COMPILE_FLAGS "-std=c++11 -Wall ${SDL2_CFLAGS_OTHER}") set_target_properties(rpgedit PROPERTIES LINK_FLAGS "${SDL2_LDFLAGS_OTHER}") diff --git a/src/control/ImageLoader.cpp b/src/control/ImageLoader.cpp deleted file mode 100644 index 2e78087..0000000 --- a/src/control/ImageLoader.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - Copyright (c) 2014, Matthias Schiffer - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "ImageLoader.hpp" - -#include - - -namespace RPGEdit { - -namespace Control { - -std::unique_ptr ImageLoader::load(const std::string &name) { - std::string filename = "../resources/" + name + ".png"; - - SDL_Surface *surface = IMG_Load(filename.c_str()); - - return std::unique_ptr(surface, SDL_Surface_deleter()); -} - -SDL_Surface * ImageLoader::get(const std::string &name) { - std::unique_ptr &surface = tiles[name]; - - if (!surface) - surface = load(name); - - if (!surface) - tiles.erase(tiles.find(name)); - - return surface.get(); -} - - -} - -} diff --git a/src/control/ImageLoader.hpp b/src/control/ImageLoader.hpp deleted file mode 100644 index 36ae7cd..0000000 --- a/src/control/ImageLoader.hpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (c) 2014, Matthias Schiffer - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#pragma once - -#include -#include - -#include - - -namespace RPGEdit { - -namespace Control { - -class ImageLoader { -private: - class SDL_Surface_deleter { - public: - void operator()(SDL_Surface *surface) { - SDL_FreeSurface(surface); - } - }; - - std::unordered_map> tiles; - - std::unique_ptr load(const std::string &name); - -public: - SDL_Surface * get(const std::string &name); - - void clear() { - tiles.clear(); - } -}; - -} - -} diff --git a/src/control/MapContext.cpp b/src/control/MapContext.cpp index a981e8a..5c715db 100644 --- a/src/control/MapContext.cpp +++ b/src/control/MapContext.cpp @@ -31,19 +31,8 @@ namespace RPGEdit { namespace Control { -MapContext::MapContext(EventBus *eventBus0, InputHandler *inputHandler0, ImageLoader *imageLoader0, const std::shared_ptr &map0) - : eventBus(eventBus0), inputHandler(inputHandler0), imageLoader(imageLoader0), map(map0) { - const std::vector &tileset = map->getTileset(); - - tiles.resize(tileset.size()); - for (size_t i = 0; i < tileset.size(); i++) - tiles[i] = imageLoader->get("tile/" + tileset[i]); - - std::deque> &mapEntities = map->getEntities(); - - for (const std::shared_ptr &entity : mapEntities) - entities[entity->getName()] = imageLoader->get("entity/" + entity->getName()); - +MapContext::MapContext(EventBus *eventBus0, InputHandler *inputHandler0, const std::shared_ptr &map0) + : eventBus(eventBus0), inputHandler(inputHandler0), map(map0) { inputHandler->registerListener( [this] (uint16_t key, bool pressed, uint64_t time) { if (pressed) diff --git a/src/control/MapContext.hpp b/src/control/MapContext.hpp index 446ca10..0612dd3 100644 --- a/src/control/MapContext.hpp +++ b/src/control/MapContext.hpp @@ -27,7 +27,6 @@ #pragma once #include "EventBus.hpp" -#include "ImageLoader.hpp" #include "InputHandler.hpp" #include "../model/Map.hpp" #include "../view/MapView.hpp" @@ -44,13 +43,9 @@ class MapContext { private: EventBus *const eventBus; InputHandler *const inputHandler; - ImageLoader *const imageLoader; std::shared_ptr map; - std::vector tiles; - std::map entities; - uint64_t totalTicks = 0; void movePlayer(Model::Direction dir, uint64_t time); @@ -58,14 +53,14 @@ private: void keyPressed(uint16_t key, uint64_t time); public: - MapContext(EventBus *eventBus0, InputHandler *inputHandler0, ImageLoader *imageLoader0, const std::shared_ptr &map0); + MapContext(EventBus *eventBus0, InputHandler *inputHandler0, const std::shared_ptr &map0); Model::Position getViewPosition(uint64_t time) { return map->getPlayerEntity()->getPosition(time); } std::shared_ptr initView(const std::shared_ptr &window) { - return std::make_shared(window, map, tiles, entities); + return std::make_shared(window, map); } }; diff --git a/src/control/RPGEdit.cpp b/src/control/RPGEdit.cpp index 0c55a6b..0f31468 100644 --- a/src/control/RPGEdit.cpp +++ b/src/control/RPGEdit.cpp @@ -110,7 +110,7 @@ void RPGEdit::eventLoop() { void RPGEdit::run() { std::shared_ptr map = Model::Map::load("test"); - ctx = std::make_shared(&eventBus, &inputHandler, &tileLoader, map); + ctx = std::make_shared(&eventBus, &inputHandler, map); window = std::make_shared(); mapView = ctx->initView(window); diff --git a/src/control/RPGEdit.hpp b/src/control/RPGEdit.hpp index 8b5e697..4279f10 100644 --- a/src/control/RPGEdit.hpp +++ b/src/control/RPGEdit.hpp @@ -46,7 +46,6 @@ private: EventBus eventBus; InputHandler inputHandler; - ImageLoader tileLoader; std::shared_ptr ctx; diff --git a/src/view/MapView.cpp b/src/view/MapView.cpp index 5e55290..4938c5d 100644 --- a/src/view/MapView.cpp +++ b/src/view/MapView.cpp @@ -32,9 +32,7 @@ namespace RPGEdit { namespace View { MapView::MapView(const std::shared_ptr &window0, - const std::shared_ptr &map0, - const std::vector &tiles, - const std::map &entities) + const std::shared_ptr &map0) : window(window0), map(map0) { uint32_t rmask, gmask, bmask, amask; @@ -50,10 +48,14 @@ MapView::MapView(const std::shared_ptr &window0, amask = 0xff000000; #endif - SDL_Surface *surface = SDL_CreateRGBSurface(0, getTileSize()*tiles.size(), getTileSize(), 32, rmask, gmask, bmask, amask); + const std::vector &tileset = map->getTileset(); + + SDL_Surface *surface = SDL_CreateRGBSurface(0, getTileSize()*tileset.size(), getTileSize(), 32, rmask, gmask, bmask, amask); SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE); - for (size_t i = 0; i < tiles.size(); i++) { + SpriteCache *spriteCache = window->getSpriteCache(); + + for (size_t i = 0; i < tileset.size(); i++) { SDL_Rect rect = { .x = int(getTileSize()*i), .y = 0, @@ -61,21 +63,22 @@ MapView::MapView(const std::shared_ptr &window0, .h = 0, }; - SDL_BlitSurface(tiles[i], nullptr, surface, &rect); - } + SDL_BlitSurface(spriteCache->get("tile", tileset[i]), nullptr, surface, &rect); + } - tileTexture = SDL_CreateTextureFromSurface(window->getRenderer(), surface); + tiles = SDL_CreateTextureFromSurface(window->getRenderer(), surface); SDL_FreeSurface(surface); - for (const std::pair &entity : entities) { - entityTextures[entity.first] = SDL_CreateTextureFromSurface(window->getRenderer(), entity.second); + for (auto &entity : map->getEntities()) { + const std::string &name = entity->getName(); + entities[name] = SDL_CreateTextureFromSurface(window->getRenderer(), spriteCache->get("entity", name)); } } MapView::~MapView() { - SDL_DestroyTexture(tileTexture); + SDL_DestroyTexture(tiles); - for (const std::pair &entity : entityTextures) + for (const std::pair &entity : entities) SDL_DestroyTexture(entity.second); } @@ -115,7 +118,7 @@ void MapView::render(float centerX, float centerY, uint64_t time) { .h = tilePixels, }; - SDL_RenderCopy(window->getRenderer(), tileTexture, &src, &dst); + SDL_RenderCopy(window->getRenderer(), tiles, &src, &dst); } } @@ -137,7 +140,7 @@ void MapView::render(float centerX, float centerY, uint64_t time) { .h = tilePixels, }; - SDL_RenderCopy(window->getRenderer(), entityTextures[entity->getName()], &src, &dst); + SDL_RenderCopy(window->getRenderer(), entities[entity->getName()], &src, &dst); } } diff --git a/src/view/MapView.hpp b/src/view/MapView.hpp index 7f83006..e764297 100644 --- a/src/view/MapView.hpp +++ b/src/view/MapView.hpp @@ -31,6 +31,7 @@ #include #include +#include namespace RPGEdit { @@ -41,8 +42,9 @@ class MapView { private: std::shared_ptr window; std::shared_ptr map; - SDL_Texture *tileTexture; - std::map entityTextures; + + SDL_Texture *tiles; + std::map entities; int getTileSize() { return 32; @@ -50,9 +52,7 @@ private: public: MapView(const std::shared_ptr &window0, - const std::shared_ptr &map0, - const std::vector &tiles, - const std::map &entities); + const std::shared_ptr &map0); ~MapView(); void render(float centerX, float centerY, uint64_t time); diff --git a/src/view/SpriteCache.cpp b/src/view/SpriteCache.cpp new file mode 100644 index 0000000..82f669f --- /dev/null +++ b/src/view/SpriteCache.cpp @@ -0,0 +1,61 @@ +/* + Copyright (c) 2014, Matthias Schiffer + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include "SpriteCache.hpp" + +#include + + +namespace RPGEdit { + +namespace View { + +std::unique_ptr SpriteCache::load(const std::string &name) { + std::string filename = "../resources/sprite/" + name + ".png"; + + SDL_Surface *surface = IMG_Load(filename.c_str()); + + return std::unique_ptr(surface, SDL_Surface_deleter()); +} + +SDL_Surface * SpriteCache::get(const std::string &type, const std::string &name) { + std::string id = type + "/" + name; + + std::unique_ptr &surface = sprites[id]; + + if (!surface) + surface = load(id); + + if (!surface) + sprites.erase(sprites.find(id)); + + return surface.get(); +} + + +} + +} diff --git a/src/view/SpriteCache.hpp b/src/view/SpriteCache.hpp new file mode 100644 index 0000000..c08ba6f --- /dev/null +++ b/src/view/SpriteCache.hpp @@ -0,0 +1,62 @@ +/* + Copyright (c) 2014, Matthias Schiffer + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#pragma once + +#include +#include + +#include + + +namespace RPGEdit { + +namespace View { + +class SpriteCache { +private: + class SDL_Surface_deleter { + public: + void operator()(SDL_Surface *surface) { + SDL_FreeSurface(surface); + } + }; + + std::unordered_map> sprites; + + std::unique_ptr load(const std::string &name); + +public: + SDL_Surface * get(const std::string &type, const std::string &name); + + void clear() { + sprites.clear(); + } +}; + +} + +} diff --git a/src/view/Window.hpp b/src/view/Window.hpp index f53a9a0..8c4c7a7 100644 --- a/src/view/Window.hpp +++ b/src/view/Window.hpp @@ -26,6 +26,8 @@ #pragma once +#include "SpriteCache.hpp" + #include #include @@ -37,6 +39,8 @@ namespace View { class Window { private: + SpriteCache spriteCache; + SDL_Window *window; SDL_Renderer *renderer; @@ -51,6 +55,10 @@ public: SDL_DestroyWindow(window); } + SpriteCache * getSpriteCache() { + return &spriteCache; + } + SDL_Renderer * getRenderer() { return renderer; } -- cgit v1.2.3