From 7166c9b831f9c6a50ba42272682b776d01e5703e Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Tue, 2 Feb 2021 13:01:35 -0500 Subject: Map rendering Works but I don't want to use Tileson so I'm gonna change that Mainly bc Tileson requires std::filesystem, which my clang is too old for apparently, and while I can use gcc instead I just want to not, I suppose. Also Tileson's API is very weird RE const correctness? Idk. And also being able to parse the tmx files rather than exporting to json would be preferable. --- src/game.h | 9 ++++++++ src/main.cpp | 2 ++ src/renderer.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/renderer.h | 6 ++++++ 4 files changed, 80 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/game.h b/src/game.h index 274ef2e..e5976b1 100644 --- a/src/game.h +++ b/src/game.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "sprite.h" struct Input { @@ -54,10 +55,18 @@ public: } } + void loadMapFromFile(std::string_view filename) { + tson::Tileson t; + map_ = t.parse(fs::path(filename)); + } + + tson::Map* getMap() const { return map_.get(); } + private: std::vector sprites_; std::set> spritesByY_; + std::unique_ptr map_; }; #endif /* end of include guard: GAME_H_E6F1396E */ diff --git a/src/main.cpp b/src/main.cpp index ea8d8f4..df0bfff 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,6 +8,8 @@ void loop(Renderer& renderer) { Game game; Input keystate; + game.loadMapFromFile("../res/map1.json"); + int lucasSprite = game.addSprite(Sprite("../res/lucas_anim.txt", renderer)); int kumaSprite = game.addSprite(Sprite("../res/kuma_anim.txt", renderer)); int dusterSprite = game.addSprite(Sprite("../res/duster_anim.txt", renderer)); diff --git a/src/renderer.cpp b/src/renderer.cpp index 931e699..45b9045 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -29,7 +29,56 @@ Renderer::Renderer() { } } +texture_ptr Renderer::renderMapLayer(const tson::Layer& layer) { + texture_ptr canvas( + SDL_CreateTexture( + ren_.get(), + SDL_PIXELFORMAT_RGBA8888, + SDL_TEXTUREACCESS_TARGET, + layer.getMap()->getSize().x * layer.getMap()->getTileSize().x, + layer.getMap()->getSize().y * layer.getMap()->getTileSize().y)); + + SDL_SetTextureBlendMode(canvas.get(), SDL_BLENDMODE_BLEND); + + SDL_SetRenderTarget(ren_.get(), canvas.get()); + SDL_SetRenderDrawBlendMode(ren_.get(), SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(ren_.get(), 255, 255, 255, 0); + SDL_RenderClear(ren_.get()); + + for (auto& [pos, tileObject] : layer.getTileObjects()) { + int x = tileObject.getPosition().x; + int y = tileObject.getPosition().y; + tson::Rect tileDestRect = tileObject.getDrawingRect(); + SDL_Rect srcRect { tileDestRect.x, tileDestRect.y, tileDestRect.width, tileDestRect.height }; + SDL_Rect destRect { + x, y, tileObject.getTile()->getTileSize().x, tileObject.getTile()->getTileSize().y }; + + SDL_RendererFlip flip = SDL_FLIP_NONE; + if (tileObject.getTile()->hasFlipFlags(tson::TileFlipFlags::Horizontally | tson::TileFlipFlags::Vertically)) { + flip = static_cast(SDL_FLIP_HORIZONTAL | SDL_FLIP_VERTICAL); + } else if (tileObject.getTile()->hasFlipFlags(tson::TileFlipFlags::Horizontally)) { + flip = SDL_FLIP_HORIZONTAL; + } else if (tileObject.getTile()->hasFlipFlags(tson::TileFlipFlags::Vertically)) { + flip = SDL_FLIP_VERTICAL; + } + SDL_RenderCopyEx(ren_.get(), textures_[tilesetTexId_].get(), &srcRect, &destRect, 0, nullptr, flip); + } + + return canvas; +} + void Renderer::render(Game& game) { + if (tilesetTexId_ == -1) { + tilesetTexId_ = loadImageFromFile(game.getMap()->getTileset("fromRom")->getImage().c_str()); + } + + if (!renLay1_) { + renLay1_ = renderMapLayer(*game.getMap()->getLayer("Layer 1")); + } + if (!renLay0_) { + renLay0_ = renderMapLayer(*game.getMap()->getLayer("Layer 0")); + } + texture_ptr canvas( SDL_CreateTexture( ren_.get(), @@ -38,16 +87,22 @@ void Renderer::render(Game& game) { CANVAS_WIDTH, CANVAS_HEIGHT)); - if (!canvas) - { + if (!canvas) { throw sdl_error(); } + + SDL_SetRenderTarget(ren_.get(), canvas.get()); SDL_SetRenderDrawBlendMode(ren_.get(), SDL_BLENDMODE_NONE); SDL_SetRenderDrawColor(ren_.get(), 255, 255, 255, 255); SDL_RenderClear(ren_.get()); + { + SDL_Rect dest { -80, -80, game.getMap()->getSize().x * game.getMap()->getTileSize().x, game.getMap()->getSize().y * game.getMap()->getTileSize().y }; + SDL_RenderCopy(ren_.get(), renLay1_.get(), nullptr, &dest); + } + for (const Sprite& sprite : game.getSpritesByY() | game.spriteView()) { const SpriteFrame& frame = sprite.getFrame(); const SDL_Rect& src = frame.srcRect; @@ -55,6 +110,11 @@ void Renderer::render(Game& game) { SDL_RenderCopy(ren_.get(), textures_.at(sprite.getTextureId()).get(), &src, &dest); } + { + SDL_Rect dest { -80, -80, game.getMap()->getSize().x * game.getMap()->getTileSize().x, game.getMap()->getSize().y * game.getMap()->getTileSize().y }; + SDL_RenderCopy(ren_.get(), renLay0_.get(), nullptr, &dest); + } + SDL_SetRenderTarget(ren_.get(), nullptr); SDL_RenderCopy(ren_.get(), canvas.get(), nullptr, nullptr); SDL_RenderPresent(ren_.get()); @@ -68,6 +128,7 @@ int Renderer::loadImageFromFile(std::string_view filename) { } texture_ptr tex = texture_ptr(SDL_CreateTextureFromSurface(ren_.get(), pfs.get())); + //SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND); int texId = textures_.size(); textures_.push_back(std::move(tex)); diff --git a/src/renderer.h b/src/renderer.h index abedb62..9573d8c 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -7,6 +7,7 @@ #include #include #include +#include class Game; @@ -121,12 +122,17 @@ public: private: + texture_ptr renderMapLayer(const tson::Layer& layer); + sdl_wrapper sdl_; img_wrapper img_; window_ptr win_; renderer_ptr ren_; std::vector textures_; + int tilesetTexId_ = -1; + texture_ptr renLay0_; + texture_ptr renLay1_; }; #endif /* end of include guard: RENDERER_H_6A58EC30 */ -- cgit 1.4.1