Move more SDL-specific things to the view

This commit is contained in:
Matthias Schiffer 2014-09-24 02:27:30 +02:00
parent ea8840291c
commit b5c7b4a162
12 changed files with 51 additions and 55 deletions

View file

Before

Width:  |  Height:  |  Size: 734 B

After

Width:  |  Height:  |  Size: 734 B

View file

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -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}")

View file

@ -31,19 +31,8 @@ namespace RPGEdit {
namespace Control {
MapContext::MapContext(EventBus *eventBus0, InputHandler *inputHandler0, ImageLoader *imageLoader0, const std::shared_ptr<const Model::Map> &map0)
: eventBus(eventBus0), inputHandler(inputHandler0), imageLoader(imageLoader0), map(map0) {
const std::vector<std::string> &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<std::shared_ptr<Model::Entity>> &mapEntities = map->getEntities();
for (const std::shared_ptr<Model::Entity> &entity : mapEntities)
entities[entity->getName()] = imageLoader->get("entity/" + entity->getName());
MapContext::MapContext(EventBus *eventBus0, InputHandler *inputHandler0, const std::shared_ptr<const Model::Map> &map0)
: eventBus(eventBus0), inputHandler(inputHandler0), map(map0) {
inputHandler->registerListener(
[this] (uint16_t key, bool pressed, uint64_t time) {
if (pressed)

View file

@ -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<const Model::Map> map;
std::vector<SDL_Surface *> tiles;
std::map<std::string, SDL_Surface *> 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<const Model::Map> &map0);
MapContext(EventBus *eventBus0, InputHandler *inputHandler0, const std::shared_ptr<const Model::Map> &map0);
Model::Position getViewPosition(uint64_t time) {
return map->getPlayerEntity()->getPosition(time);
}
std::shared_ptr<View::MapView> initView(const std::shared_ptr<View::Window> &window) {
return std::make_shared<View::MapView>(window, map, tiles, entities);
return std::make_shared<View::MapView>(window, map);
}
};

View file

@ -110,7 +110,7 @@ void RPGEdit::eventLoop() {
void RPGEdit::run() {
std::shared_ptr<Model::Map> map = Model::Map::load("test");
ctx = std::make_shared<MapContext>(&eventBus, &inputHandler, &tileLoader, map);
ctx = std::make_shared<MapContext>(&eventBus, &inputHandler, map);
window = std::make_shared<View::Window>();
mapView = ctx->initView(window);

View file

@ -46,7 +46,6 @@ private:
EventBus eventBus;
InputHandler inputHandler;
ImageLoader tileLoader;
std::shared_ptr<MapContext> ctx;

View file

@ -32,9 +32,7 @@ namespace RPGEdit {
namespace View {
MapView::MapView(const std::shared_ptr<Window> &window0,
const std::shared_ptr<const Model::Map> &map0,
const std::vector<SDL_Surface *> &tiles,
const std::map<std::string, SDL_Surface *> &entities)
const std::shared_ptr<const Model::Map> &map0)
: window(window0), map(map0) {
uint32_t rmask, gmask, bmask, amask;
@ -50,10 +48,14 @@ MapView::MapView(const std::shared_ptr<Window> &window0,
amask = 0xff000000;
#endif
SDL_Surface *surface = SDL_CreateRGBSurface(0, getTileSize()*tiles.size(), getTileSize(), 32, rmask, gmask, bmask, amask);
const std::vector<std::string> &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<Window> &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<std::string, SDL_Surface *> &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<std::string, SDL_Texture *> &entity : entityTextures)
for (const std::pair<std::string, SDL_Texture *> &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);
}
}

View file

@ -31,6 +31,7 @@
#include <cmath>
#include <map>
#include <unordered_set>
namespace RPGEdit {
@ -41,8 +42,9 @@ class MapView {
private:
std::shared_ptr<Window> window;
std::shared_ptr<const Model::Map> map;
SDL_Texture *tileTexture;
std::map<std::string, SDL_Texture *> entityTextures;
SDL_Texture *tiles;
std::map<std::string, SDL_Texture *> entities;
int getTileSize() {
return 32;
@ -50,9 +52,7 @@ private:
public:
MapView(const std::shared_ptr<Window> &window0,
const std::shared_ptr<const Model::Map> &map0,
const std::vector<SDL_Surface *> &tiles,
const std::map<std::string, SDL_Surface *> &entities);
const std::shared_ptr<const Model::Map> &map0);
~MapView();
void render(float centerX, float centerY, uint64_t time);

View file

@ -24,31 +24,33 @@
*/
#include "ImageLoader.hpp"
#include "SpriteCache.hpp"
#include <SDL_image.h>
namespace RPGEdit {
namespace Control {
namespace View {
std::unique_ptr<SDL_Surface, ImageLoader::SDL_Surface_deleter> ImageLoader::load(const std::string &name) {
std::string filename = "../resources/" + name + ".png";
std::unique_ptr<SDL_Surface, SpriteCache::SDL_Surface_deleter> 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<SDL_Surface, SDL_Surface_deleter>(surface, SDL_Surface_deleter());
}
SDL_Surface * ImageLoader::get(const std::string &name) {
std::unique_ptr<SDL_Surface, SDL_Surface_deleter> &surface = tiles[name];
SDL_Surface * SpriteCache::get(const std::string &type, const std::string &name) {
std::string id = type + "/" + name;
std::unique_ptr<SDL_Surface, SDL_Surface_deleter> &surface = sprites[id];
if (!surface)
surface = load(name);
surface = load(id);
if (!surface)
tiles.erase(tiles.find(name));
sprites.erase(sprites.find(id));
return surface.get();
}

View file

@ -34,9 +34,9 @@
namespace RPGEdit {
namespace Control {
namespace View {
class ImageLoader {
class SpriteCache {
private:
class SDL_Surface_deleter {
public:
@ -45,15 +45,15 @@ private:
}
};
std::unordered_map<std::string, std::unique_ptr<SDL_Surface, SDL_Surface_deleter>> tiles;
std::unordered_map<std::string, std::unique_ptr<SDL_Surface, SDL_Surface_deleter>> sprites;
std::unique_ptr<SDL_Surface, SDL_Surface_deleter> load(const std::string &name);
public:
SDL_Surface * get(const std::string &name);
SDL_Surface * get(const std::string &type, const std::string &name);
void clear() {
tiles.clear();
sprites.clear();
}
};

View file

@ -26,6 +26,8 @@
#pragma once
#include "SpriteCache.hpp"
#include <utility>
#include <SDL.h>
@ -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;
}