diff --git a/.gitmodules b/.gitmodules index cfd1d7d..481588c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "lib/clooneljump"] path = lib/clooneljump url = https://bitbucket.org/King_DuckZ/clooneljump.git +[submodule "lib/better-enums"] + path = lib/better-enums + url = https://github.com/aantron/better-enums diff --git a/CMakeLists.txt b/CMakeLists.txt index 89cff21..a728ebe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,6 +60,7 @@ target_compile_definitions(${PROJECT_NAME} ) target_include_directories(${PROJECT_NAME} INTERFACE lib/kakoune + INTERFACE lib/better-enums ) add_subdirectory(lib/clooneljump/src/cloonelgraphics) diff --git a/lib/better-enums b/lib/better-enums new file mode 160000 index 0000000..37d8f98 --- /dev/null +++ b/lib/better-enums @@ -0,0 +1 @@ +Subproject commit 37d8f987ca939af846a2d29a8f8198f9bf3ac4b7 diff --git a/src/gamelib/character.cpp b/src/gamelib/character.cpp index c02df13..40a7341 100644 --- a/src/gamelib/character.cpp +++ b/src/gamelib/character.cpp @@ -25,6 +25,7 @@ #include "drawing_queue.hpp" #include "worldviewport.hpp" #include "texture.hpp" +#include "draw_layer_names.hpp" #include #include #include @@ -118,7 +119,7 @@ namespace curry { item.source = source_rect(); item.destination = destination_rect(parViewport.position()); item.texture = texture(); - parDQ.add_for_rendering(0 , std::move(item)); + parDQ.add_for_rendering(DrawaLayerNames::Background, std::move(item)); assert(not item.texture); } diff --git a/src/gamelib/draw_layer_names.hpp b/src/gamelib/draw_layer_names.hpp new file mode 100644 index 0000000..b3f7d11 --- /dev/null +++ b/src/gamelib/draw_layer_names.hpp @@ -0,0 +1,30 @@ +/* + Copyright 2016, 2017 Michele "King_DuckZ" Santullo + + This file is part of MyCurry. + + MyCurry is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + MyCurry is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with MyCurry. If not, see . +*/ + +#pragma once + +#include "enum.h" +#include + +namespace curry { + BETTER_ENUM(DrawaLayerNames, uint16_t, + Background, + Debug + ); +} //namespace curry diff --git a/src/gamelib/drawing_queue.cpp b/src/gamelib/drawing_queue.cpp index 053a7f9..a83bcf7 100644 --- a/src/gamelib/drawing_queue.cpp +++ b/src/gamelib/drawing_queue.cpp @@ -26,9 +26,15 @@ #include #include #include +#include +#include namespace curry { namespace { + typedef std::vector TextureList; + typedef std::vector LayerList; + typedef boost::container::flat_map LayerIdxMap; + #if !defined(NDEBUG) bool are_equal_rel (float parA, float parB, float parEpsilon) a_pure; @@ -93,9 +99,6 @@ namespace curry { DrawingQueue::ItemInfo& DrawingQueue::ItemInfo::operator=(ItemInfo&&) = default; struct DrawingQueue::LocalData { - typedef std::vector TextureList; - typedef std::vector LayerList; - explicit LocalData (cloonel::SDLMain* parSDLMain) : sdlmain(parSDLMain), screen_res(0.0f), @@ -104,6 +107,7 @@ namespace curry { } LayerList layers; + LayerIdxMap layer_idx_map; cloonel::SDLMain* sdlmain; vec2f screen_res; std::size_t def_layer_id; @@ -118,13 +122,19 @@ namespace curry { DrawingQueue::~DrawingQueue() noexcept = default; - std::size_t DrawingQueue::add_layer() { - m_local_data->layers.push_back(LocalData::TextureList()); - return m_local_data->layers.size() - 1; - } - - std::size_t DrawingQueue::default_layer_id() const { - return m_local_data->def_layer_id; + bool DrawingQueue::add_layer (uint16_t parName) { + auto& idx_map = m_local_data->layer_idx_map; + auto it_found = idx_map.lower_bound(parName); + assert(&*it_found != nullptr or idx_map.end() == it_found); + if (it_found != idx_map.end() and it_found->first == parName) { + return false; + } + else { + m_local_data->layers.push_back(TextureList()); + const auto new_layer_index = m_local_data->layers.size() - 1; + idx_map.insert(it_found, std::make_pair(parName, new_layer_index)); + return true; + } } void DrawingQueue::flush_to_renderer() { @@ -137,16 +147,17 @@ namespace curry { } } - void DrawingQueue::add_for_rendering (std::size_t parLayer, ItemInfo&& parItem) { + void DrawingQueue::add_for_rendering (uint16_t parName, ItemInfo&& parItem) { + const auto idx = m_local_data->layer_idx_map.at(parName); auto& layers = m_local_data->layers; - assert(parLayer < layers.size()); + assert(idx < layers.size()); assert(parItem.source.is_valid()); assert(parItem.destination.is_valid()); assert(parItem.texture); - layers[parLayer].push_back(std::move(parItem)); - assert(not layers[parLayer].empty()); - assert(layers[parLayer].back().source.is_valid()); - assert(layers[parLayer].back().destination.is_valid()); + layers[idx].push_back(std::move(parItem)); + assert(not layers[idx].empty()); + assert(layers[idx].back().source.is_valid()); + assert(layers[idx].back().destination.is_valid()); } void DrawingQueue::draw_clipped (Texture& parTexture, Rect parSrc, Rect parDest) { diff --git a/src/gamelib/drawing_queue.hpp b/src/gamelib/drawing_queue.hpp index a89b97d..32f5cf3 100644 --- a/src/gamelib/drawing_queue.hpp +++ b/src/gamelib/drawing_queue.hpp @@ -23,6 +23,7 @@ #include "rect.hpp" #include "sizenotifiable.hpp" #include +#include namespace cloonel { class SDLMain; @@ -39,10 +40,10 @@ namespace curry { DrawingQueue (cloonel::SDLMain* parSDLMain, const cloonel::DeferredRegister& parDeferredRegister); virtual ~DrawingQueue() noexcept; - std::size_t add_layer(); + bool add_layer (uint16_t parName); std::size_t default_layer_id() const; void flush_to_renderer(); - void add_for_rendering (std::size_t parLayer, ItemInfo&& parItem); + void add_for_rendering (uint16_t parName, ItemInfo&& parItem); private: void draw_clipped (Texture& parTexture, Rect parSrc, Rect parDest); diff --git a/src/gamelib/gamescenebase.cpp b/src/gamelib/gamescenebase.cpp index 7d01b2a..aa977e5 100644 --- a/src/gamelib/gamescenebase.cpp +++ b/src/gamelib/gamescenebase.cpp @@ -22,6 +22,7 @@ #include "sdlmain.hpp" #include "rect.hpp" #include "drawing_queue.hpp" +#include "draw_layer_names.hpp" #include #include #include @@ -78,6 +79,9 @@ namespace curry { m_wants_to_quit(false) { assert(m_sdlmain); + const bool layer_added = m_drawing_queue->add_layer(DrawaLayerNames::Background); + assert(layer_added); + static_cast(layer_added); } GameSceneBase::~GameSceneBase() noexcept = default; diff --git a/src/gamelib/ingamescene.cpp b/src/gamelib/ingamescene.cpp index 4540dd4..1ea5d93 100644 --- a/src/gamelib/ingamescene.cpp +++ b/src/gamelib/ingamescene.cpp @@ -80,10 +80,9 @@ namespace curry { inp.AddAction(ActionRight, Key(InputDevice_Keyboard, SDL_SCANCODE_RIGHT), "Move right"); inp.AddAction(ActionDown, Key(InputDevice_Keyboard, SDL_SCANCODE_DOWN), "Move down"); #if !defined(NDEBUG) - //TODO: client code should be able to register named layers so other - //parts of the code can try and request a layer without the need to pass - //dynamic ids around - m_local_data->debug_layer_id = drawing_queue().add_layer(); + const bool layer_added = drawing_queue().add_layer(DrawaLayerNames::Debug); + assert(layer_added); + static_cast(layer_added); #endif } @@ -135,7 +134,7 @@ namespace curry { Rect src_rect(src_rect_xy, src_rect_xy + tilesize); Rect dst_rect(pixel_pos, pixel_pos + tilesize); - this->draw(layer_id_def(), m_local_data->worldtiles, src_rect, dst_rect); + this->draw(DrawaLayerNames::Background, m_local_data->worldtiles, src_rect, dst_rect); } } m_local_data->character.draw(drawing_queue(), viewport); @@ -147,7 +146,7 @@ namespace curry { m_local_data->character.unload_textures(); } - void IngameScene::draw (std::size_t parLayer, Kakoune::SafePtr& parTexture, Rect parSrc, Rect parDest) { + void IngameScene::draw (DrawaLayerNames parLayer, Kakoune::SafePtr& parTexture, Rect parSrc, Rect parDest) { DrawingQueue::ItemInfo item{}; item.source = parSrc; item.destination = parDest; @@ -155,14 +154,4 @@ namespace curry { drawing_queue().add_for_rendering(parLayer, std::move(item)); assert(not item.texture); } - - std::size_t IngameScene::layer_id_def() const { - return drawing_queue().default_layer_id(); - } - -#if !defined(NDEBUG) - std::size_t IngameScene::layer_id_debug() const { - return m_local_data->debug_layer_id; - } -#endif } //namespace curry diff --git a/src/gamelib/ingamescene.hpp b/src/gamelib/ingamescene.hpp index 008433d..7ff398c 100644 --- a/src/gamelib/ingamescene.hpp +++ b/src/gamelib/ingamescene.hpp @@ -21,6 +21,7 @@ #include "gamescenebase.hpp" #include "safe_ptr.hh" +#include "draw_layer_names.hpp" #include #include @@ -40,11 +41,7 @@ namespace curry { virtual void on_prepare() override; virtual void on_destroy() noexcept override; virtual void on_update (float parDeltaT) override; - void draw (std::size_t parLayer, Kakoune::SafePtr& parTexture, Rect parSrc, Rect parDest); - std::size_t layer_id_def() const; -#if !defined(NDEBUG) - std::size_t layer_id_debug() const; -#endif + void draw (DrawaLayerNames parLayer, Kakoune::SafePtr& parTexture, Rect parSrc, Rect parDest); private: struct LocalData;