diff options
Diffstat (limited to 'src')
34 files changed, 255 insertions, 246 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b7d63d7..696856c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,8 +15,6 @@ find_package(GTest REQUIRED) find_package(whereami REQUIRED) find_library(BERKELEY_DB db) find_library(FONTCONFIG_LIB fontconfig) -find_package(segvcatch REQUIRED) -find_package(segvcatch REQUIRED) add_library(crepe SHARED) add_executable(test_main EXCLUDE_FROM_ALL) @@ -33,7 +31,6 @@ target_link_libraries(crepe PUBLIC ${BERKELEY_DB} PUBLIC whereami PUBLIC ${FONTCONFIG_LIB} - PUBLIC segvcatch ) add_subdirectory(crepe) diff --git a/src/crepe/api/Animator.cpp b/src/crepe/api/Animator.cpp index 5ac0617..c558d86 100644 --- a/src/crepe/api/Animator.cpp +++ b/src/crepe/api/Animator.cpp @@ -36,12 +36,24 @@ void Animator::pause() { this->active = false; } void Animator::stop() { this->active = false; - this->data.frame = this->data.cycle_start; + this->data.col = 0; + this->data.row = 0; } void Animator::set_fps(int fps) { this->data.fps = fps; } void Animator::set_cycle_range(int start, int end) { - this->data.cycle_start = start; - this->data.cycle_end = end; + this->data.cycle_start = start, this->data.cycle_end = end; } +void Animator::set_anim(int col) { + Animator::Data & ctx = this->data; + this->spritesheet.mask.x = ctx.row = 0; + ctx.col = col; + this->spritesheet.mask.y = ctx.col * this->spritesheet.mask.h; +} + +void Animator::next_anim() { + Animator::Data & ctx = this->data; + ctx.row = ++ctx.row % this->grid_size.x; + this->spritesheet.mask.x = ctx.row * this->spritesheet.mask.w; +} diff --git a/src/crepe/api/Animator.h b/src/crepe/api/Animator.h index 8be693e..95539d3 100644 --- a/src/crepe/api/Animator.h +++ b/src/crepe/api/Animator.h @@ -1,7 +1,7 @@ #pragma once -#include "../types.h" #include "../manager/LoopTimerManager.h" +#include "../types.h" #include "Component.h" #include "Sprite.h" @@ -23,15 +23,16 @@ public: struct Data { //! frames per second for animation unsigned int fps = 1; - //! The current frame being shown - unsigned int frame = 0; - + //! The current col being animated. + unsigned int col = 0; + //! The current row being animated. + unsigned int row = 0; //! should the animation loop bool looping = false; //! starting frame for cycling unsigned int cycle_start = 0; //! end frame for cycling (-1 = use last frame) - unsigned int cycle_end = -1; + int cycle_end = -1; }; public: @@ -60,6 +61,14 @@ public: * \param end of row animation */ void set_cycle_range(int start, int end); + /** + * \brief select which column to animate from + * + * \param col animation column + */ + void set_anim(int col); + //! will go to the next animaiton of current row + void next_anim(); public: /** @@ -91,11 +100,14 @@ private: //! The maximum number of rows and columns inside the spritesheet const uvec2 grid_size; + // the time elapsed from a frame duration + duration_t elapsed_time = {}; + + // frame counter + unsigned int frame = 0; + //! Uses the spritesheet friend AnimatorSystem; - - //! Elasped time since last frame change - duration_t elapsed; }; } // namespace crepe diff --git a/src/crepe/api/BehaviorScript.h b/src/crepe/api/BehaviorScript.h index 52cf259..3909b96 100644 --- a/src/crepe/api/BehaviorScript.h +++ b/src/crepe/api/BehaviorScript.h @@ -48,8 +48,6 @@ public: BehaviorScript & set_script(Args &&... args); protected: - //! Script type name - std::string name = "unknown script"; //! Script instance std::unique_ptr<Script> script = nullptr; //! ScriptSystem needs direct access to the script instance diff --git a/src/crepe/api/BehaviorScript.hpp b/src/crepe/api/BehaviorScript.hpp index 218f27c..353d5e2 100644 --- a/src/crepe/api/BehaviorScript.hpp +++ b/src/crepe/api/BehaviorScript.hpp @@ -11,7 +11,6 @@ template <class T, typename... Args> BehaviorScript & BehaviorScript::set_script(Args &&... args) { static_assert(std::is_base_of<Script, T>::value); this->script = std::unique_ptr<Script>(new T(std::forward<Args>(args)...)); - this->name = typeid(T).name(); this->script->game_object_id = this->game_object_id; this->script->active = this->active; diff --git a/src/crepe/api/Button.cpp b/src/crepe/api/Button.cpp index 40153c9..8eadd89 100644 --- a/src/crepe/api/Button.cpp +++ b/src/crepe/api/Button.cpp @@ -2,7 +2,10 @@ namespace crepe { -Button::Button(game_object_id_t id, const vec2 & dimensions, const vec2 & offset) - : UIObject(id, dimensions, offset) {} +Button::Button( + game_object_id_t id, const vec2 & dimensions, const Data & data, const vec2 & offset +) + : UIObject(id, dimensions, offset), + data(data) {} } // namespace crepe diff --git a/src/crepe/api/Button.h b/src/crepe/api/Button.h index d42527e..e986c04 100644 --- a/src/crepe/api/Button.h +++ b/src/crepe/api/Button.h @@ -1,8 +1,7 @@ #pragma once -#include <functional> +#include "../types.h" -#include "Event.h" #include "UIObject.h" namespace crepe { @@ -21,14 +20,24 @@ namespace crepe { */ class Button : public UIObject { public: + struct Data { + //! variable indicating if transform is relative to camera(false) or world(true) + bool world_space = false; + }; + +public: /** * \brief Constructs a Button with the specified game object ID and dimensions. * * \param id The unique ID of the game object associated with this button. * \param dimensions The width and height of the UIObject * \param offset The offset relative this GameObjects Transform + * \param data additional data the button has */ - Button(game_object_id_t id, const vec2 & dimensions, const vec2 & offset); + Button( + game_object_id_t id, const vec2 & dimensions, const Data & data, + const vec2 & offset = {0, 0} + ); /** * \brief Get the maximum number of instances for this component * @@ -38,6 +47,9 @@ public: */ virtual int get_instances_max() const { return 1; } +public: + Data data; + private: //! friend relation hover variable friend class InputSystem; diff --git a/src/crepe/api/Color.cpp b/src/crepe/api/Color.cpp index 6858aa8..d0e3b35 100644 --- a/src/crepe/api/Color.cpp +++ b/src/crepe/api/Color.cpp @@ -10,3 +10,5 @@ const Color Color::BLACK {0x00, 0x00, 0x00}; const Color Color::CYAN {0x00, 0xff, 0xff}; const Color Color::YELLOW {0xff, 0xff, 0x00}; const Color Color::MAGENTA {0xff, 0x00, 0xff}; +const Color Color::GREY {0x80, 0x80, 0x80}; +const Color Color::GOLD {249, 205, 91}; diff --git a/src/crepe/api/Color.h b/src/crepe/api/Color.h index 84edb5c..dbfd0ed 100644 --- a/src/crepe/api/Color.h +++ b/src/crepe/api/Color.h @@ -18,6 +18,8 @@ struct Color { static const Color MAGENTA; static const Color YELLOW; static const Color BLACK; + static const Color GREY; + static const Color GOLD; }; } // namespace crepe diff --git a/src/crepe/api/Config.h b/src/crepe/api/Config.h index 32f1a2e..7475528 100644 --- a/src/crepe/api/Config.h +++ b/src/crepe/api/Config.h @@ -86,7 +86,7 @@ struct Config final { * This config option is the font size at which all fonts will be loaded initially. * */ - unsigned int size = 16; + unsigned int size = 500; } font; //! Configuration for click tolerance. struct { diff --git a/src/crepe/api/Engine.cpp b/src/crepe/api/Engine.cpp index bf3f50c..0bbe51f 100644 --- a/src/crepe/api/Engine.cpp +++ b/src/crepe/api/Engine.cpp @@ -1,7 +1,4 @@ -#include <segvcatch.h> - #include "../util/Log.h" -#include "../facade/SignalCatch.h" #include "Engine.h" @@ -9,8 +6,6 @@ using namespace crepe; using namespace std; int Engine::main() noexcept { - SignalCatch signal_catch; - try { this->setup(); } catch (const exception & e) { @@ -42,39 +37,32 @@ void Engine::setup() { void Engine::loop() { LoopTimerManager & timer = this->loop_timer; + SystemManager & systems = this->system_manager; while (this->game_running) { timer.update(); while (timer.get_lag() >= timer.get_fixed_delta_time()) { try { - this->fixed_update(); + systems.fixed_update(); } catch (const exception & e) { Log::logf( - Log::Level::WARNING, "Uncaught exception in fixed update function: {}", + Log::Level::WARNING, "Uncaught exception in fixed update function: {}\n", e.what() ); } + timer.advance_fixed_elapsed_time(); } try { - this->frame_update(); + systems.frame_update(); + this->scene_manager.load_next_scene(); } catch (const exception & e) { Log::logf( - Log::Level::WARNING, "Uncaught exception in frame update function: {}", + Log::Level::WARNING, "Uncaught exception in frame update function: {}\n", e.what() ); } + timer.enforce_frame_rate(); } } - -void Engine::fixed_update() { - this->system_manager.fixed_update(); - this->loop_timer.advance_fixed_elapsed_time(); -} - -void Engine::frame_update() { - this->system_manager.frame_update(); - this->loop_timer.enforce_frame_rate(); -} - diff --git a/src/crepe/api/Engine.h b/src/crepe/api/Engine.h index 23acfb4..452a856 100644 --- a/src/crepe/api/Engine.h +++ b/src/crepe/api/Engine.h @@ -46,11 +46,6 @@ private: */ void loop(); - //! Fixed update function - void fixed_update(); - //! Frame update function - void frame_update(); - //! Game loop condition bool game_running = true; diff --git a/src/crepe/api/Sprite.cpp b/src/crepe/api/Sprite.cpp index 0107c7b..3c77e2e 100644 --- a/src/crepe/api/Sprite.cpp +++ b/src/crepe/api/Sprite.cpp @@ -19,3 +19,16 @@ Sprite::Sprite(game_object_id_t id, const Asset & texture, const Sprite::Data & } Sprite::~Sprite() { dbg_trace(); } + +unique_ptr<Component> Sprite::save() const { return unique_ptr<Component>(new Sprite(*this)); } + +void Sprite::restore(const Component & snapshot) { + *this = static_cast<const Sprite &>(snapshot); +} + +Sprite & Sprite::operator=(const Sprite & snapshot) { + this->active = snapshot.active; + this->data = snapshot.data; + this->mask = snapshot.mask; + return *this; +} diff --git a/src/crepe/api/Sprite.h b/src/crepe/api/Sprite.h index ef65f64..3565bed 100644 --- a/src/crepe/api/Sprite.h +++ b/src/crepe/api/Sprite.h @@ -42,10 +42,10 @@ public: FlipSettings flip; //! Layer sorting level of the sprite - const int sorting_in_layer = 0; + int sorting_in_layer = 0; //! Order within the sorting layer - const int order_in_layer = 0; + int order_in_layer = 0; /** * \brief width and height of the sprite in game units @@ -110,16 +110,21 @@ private: */ float aspect_ratio = 0; -public: - struct Mask { - unsigned w = 0; - unsigned h = 0; - unsigned x = 0; - unsigned y = 0; + struct Rect { + int w = 0; + int h = 0; + int x = 0; + int y = 0; }; //! Render area of the sprite this will also be adjusted by the AnimatorSystem if an Animator // object is present in GameObject. this is in sprite pixels - Mask mask; + Rect mask; + +protected: + virtual std::unique_ptr<Component> save() const; + Sprite(const Sprite &) = default; + virtual void restore(const Component & snapshot); + virtual Sprite & operator=(const Sprite &); }; } // namespace crepe diff --git a/src/crepe/api/Text.cpp b/src/crepe/api/Text.cpp index b24f0ac..e5cc39d 100644 --- a/src/crepe/api/Text.cpp +++ b/src/crepe/api/Text.cpp @@ -1,12 +1,27 @@ +#include "../types.h" + #include "Text.h" using namespace crepe; +using namespace std; Text::Text( - game_object_id_t id, const vec2 & dimensions, const vec2 & offset, - const std::string & font_family, const Data & data, const std::string & text + game_object_id_t id, const vec2 & dimensions, const std::string & font_family, + const Data & data, const vec2 & offset, const std::string & text ) : UIObject(id, dimensions, offset), text(text), data(data), font_family(font_family) {} + +unique_ptr<Component> Text::save() const { return unique_ptr<Component>(new Text(*this)); } + +void Text::restore(const Component & snapshot) { *this = static_cast<const Text &>(snapshot); } + +Text & Text::operator=(const Text & snapshot) { + this->active = snapshot.active; + this->data = snapshot.data; + this->text = snapshot.text; + this->font_family = snapshot.font_family; + return *this; +} diff --git a/src/crepe/api/Text.h b/src/crepe/api/Text.h index 0289b85..859490e 100644 --- a/src/crepe/api/Text.h +++ b/src/crepe/api/Text.h @@ -3,6 +3,8 @@ #include <optional> #include <string> +#include "../types.h" + #include "Asset.h" #include "Color.h" #include "UIObject.h" @@ -17,22 +19,8 @@ class Text : public UIObject { public: //! Text data that does not have to be set in the constructor struct Data { - /** - * \brief fontsize for text rendering - * - * \note this is not the actual font size that is loaded in. - * - * Since SDL_TTF requires the font size when loading in the font it is not possible to switch the font size. - * The default font size that is loaded is set in the Config. - * Instead this value is used to upscale the font texture which can cause blurring or distorted text when upscaling or downscaling too much. - */ - unsigned int font_size = 16; - - //! Layer sorting level of the text - const int sorting_in_layer = 0; - - //! Order within the sorting text - const int order_in_layer = 0; + //! variable indicating if transform is relative to camera(false) or world(true) + bool world_space = false; //! Label text color. Color text_color = Color::BLACK; @@ -49,8 +37,8 @@ public: * \param font Optional font asset that can be passed or left empty. */ Text( - game_object_id_t id, const vec2 & dimensions, const vec2 & offset, - const std::string & font_family, const Data & data, const std::string & text = "" + game_object_id_t id, const vec2 & dimensions, const std::string & font_family, + const Data & data, const vec2 & offset = {0, 0}, const std::string & text = "" ); //! Label text. @@ -61,6 +49,12 @@ public: std::optional<Asset> font; //! Data instance Data data; + +protected: + virtual std::unique_ptr<Component> save() const; + Text(const Text &) = default; + virtual void restore(const Component & snapshot); + virtual Text & operator=(const Text &); }; } // namespace crepe diff --git a/src/crepe/api/UIObject.h b/src/crepe/api/UIObject.h index f1318ab..0d9b1f7 100644 --- a/src/crepe/api/UIObject.h +++ b/src/crepe/api/UIObject.h @@ -15,13 +15,11 @@ public: * \param dimensions width and height of the UIObject * \param offset Offset relative to the GameObject Transform */ - UIObject(game_object_id_t id, const vec2 & dimensions, const vec2 & offset); + UIObject(game_object_id_t id, const vec2 & dimensions, const vec2 & offset = {0, 0}); //! Width and height of the UIObject vec2 dimensions; //! Position offset relative to this GameObjects Transform vec2 offset; - //! variable indicating if transform is relative to camera(false) or world(true) - bool world_space = false; }; } // namespace crepe diff --git a/src/crepe/api/Vector2.h b/src/crepe/api/Vector2.h index 52e1bb6..6613641 100644 --- a/src/crepe/api/Vector2.h +++ b/src/crepe/api/Vector2.h @@ -1,5 +1,7 @@ #pragma once +#include <format> + namespace crepe { //! 2D vector @@ -11,55 +13,55 @@ struct Vector2 { T y = 0; //! Subtracts another vector from this vector and returns the result. - Vector2 operator-(const Vector2<T> & other) const; + Vector2<T> operator-(const Vector2<T> & other) const; //! Subtracts a scalar value from both components of this vector and returns the result. - Vector2 operator-(T scalar) const; + Vector2<T> operator-(T scalar) const; //! Adds another vector to this vector and returns the result. - Vector2 operator+(const Vector2<T> & other) const; + Vector2<T> operator+(const Vector2<T> & other) const; //! Adds a scalar value to both components of this vector and returns the result. - Vector2 operator+(T scalar) const; + Vector2<T> operator+(T scalar) const; //! Multiplies this vector by another vector element-wise and returns the result. - Vector2 operator*(const Vector2<T> & other) const; + Vector2<T> operator*(const Vector2<T> & other) const; //! Multiplies this vector by a scalar and returns the result. - Vector2 operator*(T scalar) const; + Vector2<T> operator*(T scalar) const; //! Divides this vector by another vector element-wise and returns the result. - Vector2 operator/(const Vector2<T> & other) const; + Vector2<T> operator/(const Vector2<T> & other) const; //! Divides this vector by a scalar and returns the result. - Vector2 operator/(T scalar) const; + Vector2<T> operator/(T scalar) const; //! Adds another vector to this vector and updates this vector. - Vector2 & operator+=(const Vector2<T> & other); + Vector2<T> & operator+=(const Vector2<T> & other); //! Adds a scalar value to both components of this vector and updates this vector. - Vector2 & operator+=(T other); + Vector2<T> & operator+=(T other); //! Subtracts another vector from this vector and updates this vector. - Vector2 & operator-=(const Vector2<T> & other); + Vector2<T> & operator-=(const Vector2<T> & other); //! Subtracts a scalar value from both components of this vector and updates this vector. - Vector2 & operator-=(T other); + Vector2<T> & operator-=(T other); //! Multiplies this vector by another vector element-wise and updates this vector. - Vector2 & operator*=(const Vector2<T> & other); + Vector2<T> & operator*=(const Vector2<T> & other); //! Multiplies this vector by a scalar and updates this vector. - Vector2 & operator*=(T other); + Vector2<T> & operator*=(T other); //! Divides this vector by another vector element-wise and updates this vector. - Vector2 & operator/=(const Vector2<T> & other); + Vector2<T> & operator/=(const Vector2<T> & other); //! Divides this vector by a scalar and updates this vector. - Vector2 & operator/=(T other); + Vector2<T> & operator/=(T other); //! Returns the negation of this vector. - Vector2 operator-() const; + Vector2<T> operator-() const; //! Checks if this vector is equal to another vector. bool operator==(const Vector2<T> & other) const; @@ -89,12 +91,20 @@ struct Vector2 { T distance_squared(const Vector2<T> & other) const; //! Returns the perpendicular vector to this vector. - Vector2 perpendicular() const; + Vector2<T> perpendicular() const; //! Checks if both components of the vector are NaN. bool is_nan() const; + + //! Rotate this vector clockwise by \c deg degrees + Vector2<T> rotate(float deg) const; }; } // namespace crepe +template <typename T> +struct std::formatter<crepe::Vector2<T>> : std::formatter<std::string> { + format_context::iterator format(crepe::Vector2<T> vec, format_context & ctx) const; +}; + #include "Vector2.hpp" diff --git a/src/crepe/api/Vector2.hpp b/src/crepe/api/Vector2.hpp index e195760..30441d2 100644 --- a/src/crepe/api/Vector2.hpp +++ b/src/crepe/api/Vector2.hpp @@ -168,4 +168,19 @@ bool Vector2<T>::is_nan() const { return std::isnan(x) && std::isnan(y); } +template <class T> +Vector2<T> Vector2<T>::rotate(float deg) const { + float rad = -deg / 180 * M_PI; + return { + x * std::cos(rad) - y * std::sin(rad), + x * std::sin(rad) + y * std::cos(rad), + }; +} + } // namespace crepe + +template <typename T> +std::format_context::iterator +std::formatter<crepe::Vector2<T>>::format(crepe::Vector2<T> vec, format_context & ctx) const { + return formatter<string>::format(std::format("{{{}, {}}}", vec.x, vec.y), ctx); +} diff --git a/src/crepe/facade/CMakeLists.txt b/src/crepe/facade/CMakeLists.txt index 4873e8d..243ae46 100644 --- a/src/crepe/facade/CMakeLists.txt +++ b/src/crepe/facade/CMakeLists.txt @@ -6,7 +6,6 @@ target_sources(crepe PUBLIC DB.cpp FontFacade.cpp Font.cpp - SignalCatch.cpp ) target_sources(crepe PUBLIC FILE_SET HEADERS FILES @@ -17,6 +16,5 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES DB.h FontFacade.h Font.h - SignalCatch.h ) diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 859f966..6c93fb2 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -69,8 +69,6 @@ SDLContext::SDLContext(Mediator & mediator) { throw runtime_error(format("SDL_ttf initialization failed: {}", TTF_GetError())); } - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); - mediator.sdl_context = *this; } @@ -174,6 +172,7 @@ SDL_FRect SDLContext::get_dst_rect(const DestinationRectangleData & ctx) const { } void SDLContext::draw(const RenderContext & ctx) { + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2"); const Sprite::Data & data = ctx.sprite.data; SDL_RendererFlip render_flip = (SDL_RendererFlip) ((SDL_FLIP_HORIZONTAL * data.flip.flip_x) @@ -206,6 +205,7 @@ void SDLContext::draw(const RenderContext & ctx) { } void SDLContext::draw_text(const RenderText & data) { + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); const Text & text = data.text; const Font & font = data.font; @@ -235,9 +235,16 @@ void SDLContext::draw_text(const RenderText & data) { = {tmp_font_texture, [](SDL_Texture * texture) { SDL_DestroyTexture(texture); }}; vec2 size = text.dimensions * cam_aux_data.render_scale * data.transform.scale; - vec2 screen_pos = (absoluut_pos - cam_aux_data.cam_pos + (cam_aux_data.zoomed_viewport) / 2 - ) * cam_aux_data.render_scale - - size / 2 + cam_aux_data.bar_size; + vec2 screen_pos = absoluut_pos; + if (text.data.world_space) { + screen_pos = (screen_pos - cam_aux_data.cam_pos + (cam_aux_data.zoomed_viewport) / 2) + * cam_aux_data.render_scale + - size / 2 + cam_aux_data.bar_size; + } else { + screen_pos + = (screen_pos + (cam_aux_data.zoomed_viewport) / 2) * cam_aux_data.render_scale + - size / 2 + cam_aux_data.bar_size; + } SDL_FRect dstrect { .x = screen_pos.x, diff --git a/src/crepe/facade/SignalCatch.cpp b/src/crepe/facade/SignalCatch.cpp deleted file mode 100644 index ad92d28..0000000 --- a/src/crepe/facade/SignalCatch.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include <stdexcept> - -#include "SignalCatch.h" - -using namespace crepe; -using namespace std; - -SignalCatch::SignalCatch() { - segvcatch::init_segv(&SignalCatch::segv); - segvcatch::init_fpe(&SignalCatch::fpe); -} - -SignalCatch::~SignalCatch() { - segvcatch::init_segv(); - segvcatch::init_fpe(); -} - -void SignalCatch::segv() { - throw runtime_error("segmentation fault"); -} - -void SignalCatch::fpe() { - throw domain_error("floating point exception"); -} - diff --git a/src/crepe/facade/SignalCatch.h b/src/crepe/facade/SignalCatch.h deleted file mode 100644 index 4562215..0000000 --- a/src/crepe/facade/SignalCatch.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include <segvcatch.h> - -namespace crepe { - -class SignalCatch { -public: - SignalCatch(); - ~SignalCatch(); - -private: - static void segv(); - static void fpe(); - -public: - SignalCatch(const SignalCatch &) = delete; - SignalCatch(SignalCatch &&) = delete; - SignalCatch & operator=(const SignalCatch &) = delete; - SignalCatch & operator=(SignalCatch &&) = delete; -}; - -} - diff --git a/src/crepe/manager/SystemManager.cpp b/src/crepe/manager/SystemManager.cpp index c8f4f3d..eabc022 100644 --- a/src/crepe/manager/SystemManager.cpp +++ b/src/crepe/manager/SystemManager.cpp @@ -31,25 +31,17 @@ SystemManager::SystemManager(Mediator & mediator) : Manager(mediator) { this->mediator.system_manager = *this; } -void SystemManager::fixed_update() noexcept { - for (SystemEntry & entry : this->system_order) { - if (!entry.system.active) continue; - try { - entry.system.fixed_update(); - } catch (const exception & e) { - Log::logf(Log::Level::WARNING, "Uncaught exception in {} fixed update: {}", entry.name, e.what()); - } +void SystemManager::fixed_update() { + for (System & system : this->system_order) { + if (!system.active) continue; + system.fixed_update(); } } -void SystemManager::frame_update() noexcept { - for (SystemEntry & entry : this->system_order) { - if (!entry.system.active) continue; - try { - entry.system.frame_update(); - } catch (const exception & e) { - Log::logf(Log::Level::WARNING, "Uncaught exception in {} frame update: {}", entry.name, e.what()); - } +void SystemManager::frame_update() { + for (System & system : this->system_order) { + if (!system.active) continue; + system.frame_update(); } } diff --git a/src/crepe/manager/SystemManager.h b/src/crepe/manager/SystemManager.h index 7b862a3..614d90c 100644 --- a/src/crepe/manager/SystemManager.h +++ b/src/crepe/manager/SystemManager.h @@ -26,14 +26,14 @@ public: * * Updates the game state based on the elapsed time since the last frame. */ - void frame_update() noexcept; + void frame_update(); /** * \brief Fixed update executed at a fixed rate. * * This function updates physics and game logic based on LoopTimer's fixed_delta_time. */ - void fixed_update() noexcept; + void fixed_update(); private: /** @@ -43,20 +43,13 @@ private: * constructor of \c SystemManager using SystemManager::load_system. */ std::unordered_map<std::type_index, std::unique_ptr<System>> systems; - //! Internal ordered system list entry - struct SystemEntry { - //! System instance reference - System & system; - //! System name - std::string name; - }; /** * \brief Collection of System instances * * This map holds System instances indexed by the system's class typeid. It is filled in the * constructor of \c SystemManager using SystemManager::load_system. */ - std::vector<SystemEntry> system_order; + std::vector<std::reference_wrapper<System>> system_order; /** * \brief Initialize a system * \tparam T System type (must be derivative of \c System) diff --git a/src/crepe/manager/SystemManager.hpp b/src/crepe/manager/SystemManager.hpp index a4c11e3..addd274 100644 --- a/src/crepe/manager/SystemManager.hpp +++ b/src/crepe/manager/SystemManager.hpp @@ -38,10 +38,7 @@ void SystemManager::load_system() { throw runtime_error(format("SystemManager: {} is already initialized", type.name())); System * system = new T(this->mediator); this->systems[type] = unique_ptr<System>(system); - this->system_order.push_back(SystemEntry{ - .system = *this->systems[type], - .name = type.name(), - }); + this->system_order.push_back(*this->systems[type]); } } // namespace crepe diff --git a/src/crepe/system/AnimatorSystem.cpp b/src/crepe/system/AnimatorSystem.cpp index 467d2a2..143d5d6 100644 --- a/src/crepe/system/AnimatorSystem.cpp +++ b/src/crepe/system/AnimatorSystem.cpp @@ -1,7 +1,8 @@ +#include <chrono> + #include "../api/Animator.h" #include "../manager/ComponentManager.h" #include "../manager/LoopTimerManager.h" -#include <chrono> #include "AnimatorSystem.h" @@ -13,30 +14,31 @@ void AnimatorSystem::frame_update() { LoopTimerManager & timer = this->mediator.loop_timer; RefVector<Animator> animations = mgr.get_components_by_type<Animator>(); - duration_t elapsed = timer.get_delta_time(); - - for (Animator & animator : animations) { - if (!animator.active) continue; + duration_t elapsed_time = timer.get_delta_time(); - Animator::Data & data = animator.data; - if (animator.data.fps == 0) continue; + for (Animator & a : animations) { + if (!a.active) continue; + if (a.data.fps == 0) continue; - if (animator.data.cycle_end == -1) - animator.data.cycle_end = animator.grid_size.x * animator.grid_size.y; + Animator::Data & ctx = a.data; - animator.elapsed += elapsed; - duration_t frame_duration = 1000ms / animator.data.fps; + a.elapsed_time += elapsed_time; + duration_t frame_duration = 1000ms / ctx.fps; - if (animator.elapsed > frame_duration) { - animator.elapsed = 0ms; - animator.data.frame++; - - if (animator.data.looping && animator.data.frame >= animator.data.cycle_end) - animator.data.frame = animator.data.cycle_start; + int cycle_end = (ctx.cycle_end == -1) ? a.grid_size.x : ctx.cycle_end; + if (a.elapsed_time >= frame_duration) { + a.elapsed_time = 0ms; + a.frame++; + if (a.frame == cycle_end) { + a.frame = ctx.cycle_start; + if (!ctx.looping) { + a.active = false; + continue; + } + } } - Sprite::Mask & mask = animator.spritesheet.mask; - mask.x = animator.data.frame % animator.grid_size.x * mask.w; - mask.y = animator.data.frame / animator.grid_size.x * mask.h; + ctx.row = ctx.cycle_start + a.frame; + a.spritesheet.mask.x = ctx.row * a.spritesheet.mask.w; } } diff --git a/src/crepe/system/AudioSystem.cpp b/src/crepe/system/AudioSystem.cpp index d4e8b9f..3c2232f 100644 --- a/src/crepe/system/AudioSystem.cpp +++ b/src/crepe/system/AudioSystem.cpp @@ -36,6 +36,8 @@ void AudioSystem::diff_update(AudioSource & component, Sound & resource) { if (component.oneshot_play) { component.voice = context.play(resource); + context.set_loop(component.voice, component.loop); + context.set_volume(component.voice, component.volume); component.oneshot_play = false; } if (component.oneshot_stop) { diff --git a/src/crepe/system/InputSystem.cpp b/src/crepe/system/InputSystem.cpp index b4a0633..be7eda6 100644 --- a/src/crepe/system/InputSystem.cpp +++ b/src/crepe/system/InputSystem.cpp @@ -1,8 +1,8 @@ #include "../api/Button.h" +#include "../api/Config.h" #include "../facade/SDLContext.h" #include "../manager/ComponentManager.h" #include "../manager/EventManager.h" -#include "util/Log.h" #include "InputSystem.h" @@ -213,10 +213,10 @@ bool InputSystem::is_mouse_inside_button( const Transform & cam_transform ) { vec2 actual_pos = transform.position + button.offset; - if (!button.world_space) { + if (!button.data.world_space) { actual_pos += cam_transform.position; } - vec2 half_dimensions = button.dimensions / 2; + vec2 half_dimensions = button.dimensions * transform.scale / 2; return mouse_pos.x >= actual_pos.x - half_dimensions.x && mouse_pos.x <= actual_pos.x + half_dimensions.x diff --git a/src/crepe/system/InputSystem.h b/src/crepe/system/InputSystem.h index 37311cc..be62367 100644 --- a/src/crepe/system/InputSystem.h +++ b/src/crepe/system/InputSystem.h @@ -1,12 +1,9 @@ #pragma once -#include "../api/Config.h" -#include "../facade/EventData.h" - #include "../api/Event.h" #include "../api/Metadata.h" +#include "../facade/EventData.h" #include "../types.h" -#include "../util/OptionalRef.h" #include "System.h" diff --git a/src/crepe/system/ScriptSystem.cpp b/src/crepe/system/ScriptSystem.cpp index 411a9a3..ed0c7cc 100644 --- a/src/crepe/system/ScriptSystem.cpp +++ b/src/crepe/system/ScriptSystem.cpp @@ -32,21 +32,10 @@ void ScriptSystem::update( if (script == nullptr) continue; if (!script->initialized) { - try { - script->init(); - script->initialized = true; - } catch (const exception & e) { - Log::logf(Log::Level::WARNING, "Disabled script \"{}\" due to exception in init function: {}", behavior_script.name, e.what()); - behavior_script.active = false; - } + script->init(); + script->initialized = true; } - try { - (*script.*update_function)(delta_time); - } catch (const exception & e) { - // TODO: discern between fixed/frame update - Log::logf(Log::Level::WARNING, "Disabled script \"{}\" due to exception in update function: {}", behavior_script.name, e.what()); - behavior_script.active = false; - } + (*script.*update_function)(delta_time); } } diff --git a/src/example/rendering_particle.cpp b/src/example/rendering_particle.cpp index 7942fce..e6b31a7 100644 --- a/src/example/rendering_particle.cpp +++ b/src/example/rendering_particle.cpp @@ -7,8 +7,8 @@ #include <crepe/api/Button.h> #include <crepe/api/Camera.h> #include <crepe/api/Color.h> +#include <crepe/api/Engine.h> #include <crepe/api/GameObject.h> -#include <crepe/api/LoopManager.hpp> #include <crepe/api/ParticleEmitter.h> #include <crepe/api/Rigidbody.h> #include <crepe/api/Sprite.h> @@ -27,7 +27,7 @@ public: Color color(255, 255, 255, 255); - Asset img {"asset/texture/square.png"}; + Asset img {"asset/spritesheet/pokemon_spritesheet.png"}; Sprite & test_sprite = game_object.add_component<Sprite>( img, @@ -36,24 +36,24 @@ public: .flip = Sprite::FlipSettings {false, false}, .sorting_in_layer = 2, .order_in_layer = 2, - .size = {1, 1}, + .size = {1, 0}, .angle_offset = 0, .position_offset = {0, 1}, .world_space = false, } ); - //auto & emitter = game_object.add_component<ParticleEmitter>(test_sprite, ParticleEmitter::Data{}); - Sprite & test_sprite1 = game_object.add_component<Sprite>( - img, - Sprite::Data { - .color = color, - .size = {1, 1}, - .position_offset = {0, -1}, - .world_space = false, + auto & anim = game_object.add_component<Animator>( + test_sprite, ivec2 {56, 56}, uvec2 {4, 4}, + Animator::Data { + .looping = 0, } ); + anim.set_anim(1); + anim.pause(); + anim.next_anim(); + auto & cam = game_object.add_component<Camera>( ivec2 {1280, 720}, vec2 {5, 5}, Camera::Data { @@ -61,22 +61,14 @@ public: .postion_offset = {1000, 1000}, } ); - - /* - game_object.add_component<Text>(vec2{1, 1}, vec2{0, -0.5}, "ComicSansMS", - Text::Data{.text_color = Color::RED}, "test TEST"); - - game_object.add_component<Text>(vec2{1, 1}, vec2{0, 0.5}, "ComicSansMS", - Text::Data{.text_color = Color::BLACK}, "TEST test"); - */ } string get_name() const { return "TestScene"; }; }; int main(int argc, char * argv[]) { - LoopManager engine; + Engine engine; engine.add_scene<TestScene>(); - engine.start(); + engine.main(); return 0; } diff --git a/src/test/AudioTest.cpp b/src/test/AudioTest.cpp index 3844c73..e548221 100644 --- a/src/test/AudioTest.cpp +++ b/src/test/AudioTest.cpp @@ -60,6 +60,8 @@ TEST_F(AudioTest, Play) { InSequence seq; EXPECT_CALL(context, play(_)).Times(0); + EXPECT_CALL(context, set_loop(_, _)).Times(0); + EXPECT_CALL(context, set_volume(_, _)).Times(0); component.play(); } @@ -67,6 +69,8 @@ TEST_F(AudioTest, Play) { InSequence seq; EXPECT_CALL(context, play(_)).Times(1); + EXPECT_CALL(context, set_loop(_, _)).Times(1); + EXPECT_CALL(context, set_volume(_, _)).Times(1); system.fixed_update(); } } @@ -146,6 +150,9 @@ TEST_F(AudioTest, PlayOnActive) { InSequence seq; EXPECT_CALL(context, play(_)).Times(1); + EXPECT_CALL(context, set_loop(_, _)).Times(1); + EXPECT_CALL(context, set_volume(_, _)).Times(1); + component.active = true; system.fixed_update(); } @@ -156,6 +163,8 @@ TEST_F(AudioTest, PlayImmediately) { component.play(); EXPECT_CALL(context, play(_)).Times(1); + EXPECT_CALL(context, set_volume(_, _)).Times(1); + EXPECT_CALL(context, set_loop(_, _)).Times(1); system.fixed_update(); } diff --git a/src/test/Vector2Test.cpp b/src/test/Vector2Test.cpp index 1e21af9..b17f95a 100644 --- a/src/test/Vector2Test.cpp +++ b/src/test/Vector2Test.cpp @@ -1,6 +1,7 @@ #include <gtest/gtest.h> #include <crepe/api/Vector2.h> +#include <crepe/types.h> using namespace crepe; @@ -530,3 +531,12 @@ TEST_F(Vector2Test, Perpendicular) { EXPECT_FLOAT_EQ(result4.x, -4.0f); EXPECT_FLOAT_EQ(result4.y, 3.0f); } + +TEST_F(Vector2Test, Rotate) { + vec2 foo {0, 1}; + + foo = foo.rotate(90); + const float GOOD_ENOUGH = 0.001; + EXPECT_NEAR(foo.x, 1, GOOD_ENOUGH); + EXPECT_NEAR(foo.y, 0, GOOD_ENOUGH); +} |