diff --git a/BloomFramework/BloomFramework.vcxproj b/BloomFramework/BloomFramework.vcxproj index 3f120d53..8f97e7ef 100644 --- a/BloomFramework/BloomFramework.vcxproj +++ b/BloomFramework/BloomFramework.vcxproj @@ -95,7 +95,7 @@ true BLOOMFRAMEWORK_EXPORT;%(PreprocessorDefinitions) false - $(ProjectDir)\include\;..\entt\src\;%(AdditionalIncludeDirectories) + $(ProjectDir)\include\;$(ProjectDir)\..\entt\src\;%(AdditionalIncludeDirectories) /Zc:__cplusplus %(AdditionalOptions) stdcpp17 Caret @@ -113,7 +113,7 @@ true true BLOOMFRAMEWORK_EXPORT;%(PreprocessorDefinitions) - $(ProjectDir)\include\;..\entt\src\;%(AdditionalIncludeDirectories) + $(ProjectDir)\include\;$(ProjectDir)\..\entt\src\;%(AdditionalIncludeDirectories) /Zc:__cplusplus %(AdditionalOptions) stdcpp17 Caret @@ -134,7 +134,7 @@ true true BLOOMFRAMEWORK_EXPORT;%(PreprocessorDefinitions) - $(ProjectDir)\include\;..\entt\src\;%(AdditionalIncludeDirectories) + $(ProjectDir)\include\;$(ProjectDir)\..\entt\src\;%(AdditionalIncludeDirectories) /Zc:__cplusplus %(AdditionalOptions) stdcpp17 Caret @@ -155,7 +155,7 @@ true true BLOOMFRAMEWORK_EXPORT;%(PreprocessorDefinitions) - $(ProjectDir)\include\;..\entt\src\;%(AdditionalIncludeDirectories) + $(ProjectDir)\include\;$(ProjectDir)\..\entt\src\;%(AdditionalIncludeDirectories) /Zc:__cplusplus %(AdditionalOptions) stdcpp17 Caret @@ -215,7 +215,6 @@ - @@ -224,14 +223,13 @@ - - - - - + + + + @@ -241,10 +239,10 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - + + + + diff --git a/BloomFramework/BloomFramework.vcxproj.filters b/BloomFramework/BloomFramework.vcxproj.filters index 2f9c77f8..083c886c 100644 --- a/BloomFramework/BloomFramework.vcxproj.filters +++ b/BloomFramework/BloomFramework.vcxproj.filters @@ -33,9 +33,6 @@ - - Source Files - Source Files\Audio @@ -54,9 +51,6 @@ Source Files - - Source Files - Source Files\Audio diff --git a/BloomFramework/include/Audio/Audio.h b/BloomFramework/include/Audio/Audio.h index d583c127..099e010a 100644 --- a/BloomFramework/include/Audio/Audio.h +++ b/BloomFramework/include/Audio/Audio.h @@ -1,20 +1,16 @@ #pragma once - -#include "Exception.h" #include "MusicStore.h" #include "MusicQueue.h" -#include "SoundChunk.h" #include "SoundStore.h" #include "SoundPlayer.h" #include "SoundChannel.h" -#include "AudioDefine.h" namespace bloom::audio { class Music { public: - static Music & instance(); + static Music& instance(); - void push(const std::filesystem::path & filePath, int plays = 1, bool ignoreInfinitePlayback = false, int fadeInMs = 0) { + void push(const std::filesystem::path& filePath, int plays = 1, bool ignoreInfinitePlayback = false, int fadeInMs = 0) { queue.add(store.load(filePath), plays, ignoreInfinitePlayback, fadeInMs); } @@ -37,12 +33,12 @@ namespace bloom::audio { private: Music() = default; ~Music() = default; - Music(const Music &) = delete; - Music(Music &&) = delete; - Music& operator=(const Music &) = delete; + Music(const Music&) = delete; + Music(Music&&) = delete; + Music& operator=(const Music&) = delete; }; - Music & Music::instance() { + Music& Music::instance() { static Music music_instance; return music_instance; } @@ -50,27 +46,27 @@ namespace bloom::audio { class Sounds { public: - static Sounds & instance(); + static Sounds& instance(); - int add(const std::filesystem::path & filePath) { + int add(const std::filesystem::path& filePath) { players.emplace_back(std::make_unique(store.load(filePath))); return (static_cast(players.size()) - 1); } void stopAll() { - for (auto & p : players) { + for (auto& p : players) { p->stop(); } } void pauseAll() { - for (auto & p : players) { + for (auto& p : players) { p->pause(); } } void resumeAll() { - for (auto & p : players) { + for (auto& p : players) { p->resume(); } } @@ -85,7 +81,7 @@ namespace bloom::audio { SoundChannel::optimize(); } - SoundPlayerPtr & operator[](size_t off) { + SoundPlayerPtr& operator[](size_t off) { return players[off]; } @@ -95,18 +91,18 @@ namespace bloom::audio { private: Sounds() = default; ~Sounds() = default; - Sounds(const Sounds &) = delete; - Sounds(Sounds &&) = delete; - Sounds& operator=(const Sounds &) = delete; + Sounds(const Sounds&) = delete; + Sounds(Sounds&&) = delete; + Sounds& operator=(const Sounds&) = delete; }; - Sounds & Sounds::instance() { + Sounds& Sounds::instance() { static Sounds sounds_instance; return sounds_instance; } - Music & music = Music::instance(); - Sounds & sounds = Sounds::instance(); + Music& music = Music::instance(); + Sounds& sounds = Sounds::instance(); using MusicFull = Music; using SoundFull = Sounds; diff --git a/BloomFramework/include/Audio/AudioDefine.h b/BloomFramework/include/Audio/AudioDefine.h index d06fcef2..336c515f 100644 --- a/BloomFramework/include/Audio/AudioDefine.h +++ b/BloomFramework/include/Audio/AudioDefine.h @@ -1,3 +1,3 @@ #pragma once -#define BLOOM_AUDIO_INFINITE_REPEAT -1 \ No newline at end of file +constexpr auto BLOOM_AUDIO_INFINITE_REPEAT = -1; \ No newline at end of file diff --git a/BloomFramework/include/Audio/MusicQueue.h b/BloomFramework/include/Audio/MusicQueue.h index 32fc7cb8..eece0439 100644 --- a/BloomFramework/include/Audio/MusicQueue.h +++ b/BloomFramework/include/Audio/MusicQueue.h @@ -1,5 +1,4 @@ #pragma once - #include #include "MusicTrack.h" @@ -36,6 +35,6 @@ namespace bloom::audio { bool m_infinitePlayback = true; static void next_track(); - static MusicQueue * s_currentQueuePtr; + static MusicQueue* s_currentQueuePtr; }; } \ No newline at end of file diff --git a/BloomFramework/include/Audio/MusicStore.h b/BloomFramework/include/Audio/MusicStore.h index 689aef5e..55b971f8 100644 --- a/BloomFramework/include/Audio/MusicStore.h +++ b/BloomFramework/include/Audio/MusicStore.h @@ -1,5 +1,4 @@ #pragma once - #include #include "stdIncludes.h" #include "MusicTrack.h" @@ -7,10 +6,10 @@ namespace bloom::audio { class BLOOMFRAMEWORK_API MusicStore { public: - TrackPtr load(const std::filesystem::path & filePath); - TrackPtr find(const std::filesystem::path & filePath); - TrackPtr find(std::nothrow_t, const std::filesystem::path & filePath) noexcept; - void unload(const std::filesystem::path & filePath); + TrackPtr load(const std::filesystem::path& filePath); + TrackPtr find(const std::filesystem::path& filePath); + TrackPtr find(std::nothrow_t, const std::filesystem::path& filePath) noexcept; + void unload(const std::filesystem::path& filePath); void unloadAll(); private: diff --git a/BloomFramework/include/Audio/MusicTrack.h b/BloomFramework/include/Audio/MusicTrack.h index 0cdc3a87..49a6f2f8 100644 --- a/BloomFramework/include/Audio/MusicTrack.h +++ b/BloomFramework/include/Audio/MusicTrack.h @@ -1,15 +1,14 @@ #pragma once - #include "stdIncludes.h" namespace bloom::audio { class BLOOMFRAMEWORK_API MusicTrack { public: MusicTrack() {} - MusicTrack(const std::filesystem::path & filePath); + MusicTrack(const std::filesystem::path& filePath); ~MusicTrack(); - void load(const std::filesystem::path & filePath); + void load(const std::filesystem::path& filePath); void play(int plays = 1, int fadeIn = 0); bool tryPlay(int plays = 1, int fadeIn = 0); void pause(); @@ -21,7 +20,7 @@ namespace bloom::audio { static bool isPaused(); private: - Mix_Music * m_track = nullptr; + Mix_Music* m_track = nullptr; }; using Track = MusicTrack; diff --git a/BloomFramework/include/Audio/SoundChannel.h b/BloomFramework/include/Audio/SoundChannel.h index 197ec6c4..9759b9ef 100644 --- a/BloomFramework/include/Audio/SoundChannel.h +++ b/BloomFramework/include/Audio/SoundChannel.h @@ -1,5 +1,4 @@ #pragma once - #include #include #include "stdIncludes.h" @@ -7,7 +6,7 @@ namespace bloom::audio { class BLOOMFRAMEWORK_API SoundChannel { public: - SoundChannel(SoundChannel * objThisPtr); + SoundChannel(SoundChannel* objThisPtr); ~SoundChannel(); static void optimize(); diff --git a/BloomFramework/include/Audio/SoundChunk.h b/BloomFramework/include/Audio/SoundChunk.h index 08cbe514..a21cd05f 100644 --- a/BloomFramework/include/Audio/SoundChunk.h +++ b/BloomFramework/include/Audio/SoundChunk.h @@ -1,5 +1,4 @@ #pragma once - #include "stdIncludes.h" namespace bloom::audio { @@ -9,11 +8,11 @@ namespace bloom::audio { friend class SoundPlayer; public: - SoundChunk(const std::filesystem::path & filePath, bool ignoreChecks = false); + SoundChunk(const std::filesystem::path& filePath, bool ignoreChecks = false); ~SoundChunk(); private: - Mix_Chunk * m_chunk = nullptr; + Mix_Chunk* m_chunk = nullptr; }; using SoundChunkPtr = std::shared_ptr; diff --git a/BloomFramework/include/Audio/SoundPlayer.h b/BloomFramework/include/Audio/SoundPlayer.h index 66bfad36..65a89145 100644 --- a/BloomFramework/include/Audio/SoundPlayer.h +++ b/BloomFramework/include/Audio/SoundPlayer.h @@ -1,5 +1,4 @@ #pragma once - #include #include #include "stdIncludes.h" diff --git a/BloomFramework/include/Audio/SoundStore.h b/BloomFramework/include/Audio/SoundStore.h index c2c58407..c999e59a 100644 --- a/BloomFramework/include/Audio/SoundStore.h +++ b/BloomFramework/include/Audio/SoundStore.h @@ -1,5 +1,4 @@ #pragma once - #include #include "stdIncludes.h" #include "SoundChunk.h" @@ -7,10 +6,10 @@ namespace bloom::audio { class BLOOMFRAMEWORK_API SoundStore { public: - SoundChunkPtr load(const std::filesystem::path & filePath); - SoundChunkPtr find(const std::filesystem::path & filePath); - SoundChunkPtr find(std::nothrow_t, const std::filesystem::path & filePath) noexcept; - void unload(const std::filesystem::path & filePath); + SoundChunkPtr load(const std::filesystem::path& filePath); + SoundChunkPtr find(const std::filesystem::path& filePath); + SoundChunkPtr find(std::nothrow_t, const std::filesystem::path& filePath) noexcept; + void unload(const std::filesystem::path& filePath); void unloadAll(); private: diff --git a/BloomFramework/include/Components/Components.h b/BloomFramework/include/Components/Components.h index de711fff..b218307e 100644 --- a/BloomFramework/include/Components/Components.h +++ b/BloomFramework/include/Components/Components.h @@ -1,5 +1,4 @@ #pragma once - #include "Position.h" #include "Size.h" #include "Sprite.h" diff --git a/BloomFramework/include/Components/Position.h b/BloomFramework/include/Components/Position.h index 58ec6e49..c808e4d8 100644 --- a/BloomFramework/include/Components/Position.h +++ b/BloomFramework/include/Components/Position.h @@ -2,7 +2,8 @@ namespace bloom::components { struct Position { - Position(int x = 0, int y = 0) : x(x), y(y) {} + Position() : x(0), y(0) {} + Position(int x, int y) : x(x), y(y) {} int x, y; }; diff --git a/BloomFramework/include/Components/Size.h b/BloomFramework/include/Components/Size.h index db5af32c..bbb4cda7 100644 --- a/BloomFramework/include/Components/Size.h +++ b/BloomFramework/include/Components/Size.h @@ -2,8 +2,9 @@ namespace bloom::components { struct Size { - Size(int w = 1, int h = 1) : w(w), h(h) {} + Size() : w(0), h(0) {} + Size(int w, int h) : w(w), h(h) {} int w, h; }; -} \ No newline at end of file +} diff --git a/BloomFramework/include/Exception.h b/BloomFramework/include/Exception.h index b486b37b..dbbea485 100644 --- a/BloomFramework/include/Exception.h +++ b/BloomFramework/include/Exception.h @@ -1,7 +1,5 @@ #pragma once - #include -#include #include namespace bloom { diff --git a/BloomFramework/include/Framework.h b/BloomFramework/include/Framework.h index 865e9cd8..cedab383 100644 --- a/BloomFramework/include/Framework.h +++ b/BloomFramework/include/Framework.h @@ -1,5 +1,4 @@ #pragma once - #include "stdIncludes.h" #include "Audio/Audio.h" #include "Exception.h" @@ -11,4 +10,4 @@ #include "Systems/Systems.h" #include "Graphics/Font.h" #include "Graphics/FontStore.h" -#include "Graphics/SpriteText.h" +#include "Graphics/SpriteText.h" \ No newline at end of file diff --git a/BloomFramework/include/Game.h b/BloomFramework/include/Game.h index 251d5185..c48518ac 100644 --- a/BloomFramework/include/Game.h +++ b/BloomFramework/include/Game.h @@ -1,61 +1,138 @@ #pragma once - #include "stdIncludes.h" #include "Graphics/TextureStore.h" #include "Timer.h" +#include "Components/Size.h" +#include "Components/Position.h" namespace bloom { class BLOOMFRAMEWORK_API Game { - using TextureStore = bloom::graphics::TextureStore; - friend TextureStore::TextureStore(Game & object); - public: - Game(int width, int height, int windowFlags = NULL, int rendererFlags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); - Game(std::nothrow_t, int width, int height, int windowFlags = NULL, int rendererFlags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); + /** + * @param windowSize Required window size + * @param flags Window and renderer flags + */ + Game(components::Size windowSize, const std::pair& flags = { 0, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC }); + //Game(std::nothrow_t, components::Size windowSize, const std::pair& flags = { SDL_WINDOW_FULLSCREEN, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC }); ~Game(); - static void initialize(Uint32 initFlags = SDL_INIT_EVERYTHING, - int mixerFrequency = 44100, Uint16 mixerformat = MIX_DEFAULT_FORMAT, int mixerChannels = 2, int mixerChunksize = 2048, + /** + * @brief Initializes SDL subsystems and modules with certain parameters + * + * @param initFlags Subsystems that need to be initialized + * @param mixerParams Frequency, format, number of channels and chunk size needed to init SDL_Mixer + * @param imageFlags Flags of image formats to be used, all by default + */ + static void initialize(uint32_t initFlags = SDL_INIT_EVERYTHING, + const std::tuple& mixerParams = { 44100, MIX_DEFAULT_FORMAT , 2, 2048 }, int imageFlags = IMG_INIT_JPG | IMG_INIT_PNG | IMG_INIT_TIF | IMG_INIT_WEBP); + /** + * @brief Cleans up initialized SDL subsystems and modules + */ + static bool exit(); + - void create(const std::string & title, int xpos, int ypos); + /** + * @brief Creates a window with certain parameters + * + * @param title Window title + * @param pos Window position + */ + void create(std::string_view title, components::Position pos); + + /** + * @brief Updates timer + */ void update(); + + /** + * @brief Clears the window and fills it with the current color + */ void clear(); - void delay(int intervalMs); + + /** + * @brief Hangs the window for the specified time (in milliseconds) + */ + static void delay(int intervalMs); + + /** + * @brief Updates the screen with any rendering performed since the previous call + */ void render(); + + /** + * @brief Destroys renderer and window + */ void destroy(); + + /** + * @brief Gets the last event and handles it (at least QuitEvent) + */ void handleEvents(); - bool isRunning(); + /** + * @brief Hides the current window + */ void hideWindow(); + + /** + * @brief Shows the current window + */ void showWindow(); - void setColor(const SDL_Color & color); - void setColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a); + void setColor(const SDL_Color& color); + //void setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a); + + bool isRunning() const { + return m_isRunning; + } + + SDL_Color getColor() const { + return m_color; + } + + //void getColor(uint8_t& r, uint8_t& g, uint8_t& b, uint8_t& a) const { + // r = m_color.r; g = m_color.g; b = m_color.b; a = m_color.a; + //} + + int getWindowWidth() const { + return m_windowSize.w; + } + + int getWindowHeight() const { + return m_windowSize.h; + } + + components::Size getWindowSize() const { + return m_windowSize; + } + + SDL_Event getEvent() const { + return m_event; + } - SDL_Color getColor(); - void getColor(Uint8 & r, Uint8 & g, Uint8 & b, Uint8 & a); - int getScreenWidth(); - int getScreenHeight(); - SDL_Event getEvent(); - SDL_Renderer * getRenderer(); + /** + * @brief THIS IS AN INTERNAL FUNCTION, DON'T CALL IT! + */ + SDL_Renderer*& _getRenderer() { + return m_renderer; + } - TextureStore textures = TextureStore(m_renderer); - Timer timer; + graphics::TextureStore textures{ m_renderer }; + Timer timer; protected: - SDL_Renderer * m_renderer = nullptr; - SDL_Window * m_window = nullptr; - int m_screenWidth, m_screenHeight; - const int m_windowFlags, m_rendererFlags; - SDL_Color m_color; - SDL_Event m_event; - bool m_isRunning; + SDL_Renderer* m_renderer{ nullptr }; + SDL_Window* m_window{ nullptr }; + components::Size m_windowSize; + const int c_windowFlags, c_rendererFlags; + SDL_Color m_color{}; + SDL_Event m_event{}; + bool m_isRunning; private: - static void exit(); - static int m_runningInstancesQnt; + static int s_runningInstancesQnt; }; } \ No newline at end of file diff --git a/BloomFramework/include/GameObject.h b/BloomFramework/include/GameObject.h index 11cda53c..3a3ef3d5 100644 --- a/BloomFramework/include/GameObject.h +++ b/BloomFramework/include/GameObject.h @@ -1,5 +1,4 @@ #pragma once - #include "stdIncludes.h" #include "Components/Components.h" #include "Game.h" @@ -15,20 +14,26 @@ namespace bloom { * * The destructor will automatically destroy the entity from the registry when GameObject gets out of scope. */ - class BLOOMFRAMEWORK_API GameObject { - using Position = bloom::components::Position; - + class GameObject { public: - GameObject(entt::DefaultRegistry & registry, Game *& gameInstance); - ~GameObject(); + GameObject(entt::registry& registry, Game*& gameInstance) : m_registry(registry), c_gameInstance(gameInstance) { + m_entity = m_registry.create(); + m_registry.assign(m_entity); + m_registry.assign(m_entity); + } + + virtual ~GameObject() { + if (m_registry.valid(m_entity)) + m_registry.destroy(m_entity); + } virtual void init() = 0; - uint32_t getEntityID(); + uint32_t getEntityID() const { return m_entity; } protected: - entt::DefaultRegistry & m_registry; - Game *& m_gameInstance; + entt::registry& m_registry; + Game* const& c_gameInstance; uint32_t m_entity; }; } \ No newline at end of file diff --git a/BloomFramework/include/Graphics/Animation.h b/BloomFramework/include/Graphics/Animation.h index 8fbb445d..3bf23389 100644 --- a/BloomFramework/include/Graphics/Animation.h +++ b/BloomFramework/include/Graphics/Animation.h @@ -2,34 +2,39 @@ #include "stdIncludes.h" #include "Sprite.h" - namespace bloom::graphics { class BLOOMFRAMEWORK_API Animation { public: Animation() = default; - Animation(const std::initializer_list & initList) : animationFrames{ initList } {} - Animation(const Animation & other) = default; - Animation(Animation && other) = default; - Animation& operator=(const Animation & other) = default; - Animation& operator=(Animation && other) = default; + Animation(const std::initializer_list& initList) : animationFrames{ initList } {} + Animation(const Animation&) = default; + Animation(Animation&&) = default; + Animation& operator=(const Animation&) = default; + Animation& operator=(Animation&&) = default; ~Animation() = default; Sprite update(double deltaTime); - void stop() { m_currentFrame = 0; m_lastUpdateTime = 0.0; } + void stop() { + m_currentFrame = 0; + m_lastUpdateTime = 0.0; + } - void setFPS(double fps) { m_frameTime = (1000.0 / std::fabs(fps)); } - void setFrameTime(double miliseconds) { m_frameTime = std::fabs(miliseconds); } + void setFrameTime(double ms) { + m_frameTime = ms; + } + void setFPS(double fps) { + setFrameTime(1000.0 / fps); + } - std::vector animationFrames; // Frames must be inserted in order. - // std::unordered_map animationFrames; // Frames can be inserted in any order as long as the correct number is given. + std::vector animationFrames; private: - double m_lastUpdateTime = 0.0; size_t m_currentFrame = 0; + double m_lastUpdateTime = 0.0; double m_frameTime = 0.0; }; using AnimationPtr = std::shared_ptr; -} +} \ No newline at end of file diff --git a/BloomFramework/include/Graphics/AnimationSet.h b/BloomFramework/include/Graphics/AnimationSet.h index fc82a34d..75b8e549 100644 --- a/BloomFramework/include/Graphics/AnimationSet.h +++ b/BloomFramework/include/Graphics/AnimationSet.h @@ -1,21 +1,31 @@ #pragma once -#include #include "stdIncludes.h" #include "Animation.h" namespace bloom::graphics { class BLOOMFRAMEWORK_API AnimationSet { public: - AnimationPtr changeCurrent(const std::string & setName); + AnimationPtr changeCurrent(const std::string& setName); - inline void add(const std::string & setName, const Animation & animation); - inline void add(const std::string & setName, AnimationPtr animation); + void add(const std::string& setName, const Animation& animation) { + m_sets.try_emplace(setName, std::make_shared(animation)); + } - void remove(const std::string & setName) { m_sets.erase(setName); } + void add(const std::string& setName, AnimationPtr animationPtr) { + m_sets.try_emplace(setName, animationPtr); + } - void clear() { m_sets.clear(); } + void remove(const std::string& setName) { + m_sets.erase(setName); + } - AnimationPtr getCurrent() const { return m_current; } + void clear() { + m_sets.clear(); + } + + AnimationPtr getCurrent() const { + return m_current; + } private: std::unordered_map m_sets; diff --git a/BloomFramework/include/Graphics/Drawable.h b/BloomFramework/include/Graphics/Drawable.h index f8ffaa9f..b7bbf4a5 100644 --- a/BloomFramework/include/Graphics/Drawable.h +++ b/BloomFramework/include/Graphics/Drawable.h @@ -1,18 +1,18 @@ #pragma once - #include #include "stdIncludes.h" namespace bloom::graphics { class BLOOMFRAMEWORK_API Drawable { public: - Drawable(SDL_Renderer* targetRenderer); - virtual ~Drawable() = 0; + virtual ~Drawable(); virtual void render(std::optional srcRect, SDL_Rect destRect, SDL_RendererFlip flip = SDL_FLIP_NONE); protected: - SDL_Renderer* const c_renderer; + explicit Drawable(SDL_Renderer* const& targetRenderer); + + SDL_Renderer* const& c_renderer; SDL_Texture* m_texture = nullptr; }; } \ No newline at end of file diff --git a/BloomFramework/include/Graphics/Font.h b/BloomFramework/include/Graphics/Font.h index b23dfa4c..3178c761 100644 --- a/BloomFramework/include/Graphics/Font.h +++ b/BloomFramework/include/Graphics/Font.h @@ -1,5 +1,5 @@ #pragma once - +#include #include "stdIncludes.h" namespace bloom::graphics { @@ -22,18 +22,31 @@ namespace bloom::graphics { Font(const std::filesystem::path& fontPath, const FontStyle& style = FontStyle{}); ~Font(); - std::string getFamilyName() const; - std::string getStyleName() const; - int getPointSize() const { return m_style.pointSize; } - bool isFixedWidth() const { return TTF_FontFaceIsFixedWidth(m_font); } + std::string getFamilyName() const { + const char* fontName = TTF_FontFaceFamilyName(m_font); + return fontName ? std::string{ fontName } : std::string{}; + } + + std::string getStyleName() const { + const char* fontStyle = TTF_FontFaceStyleName(m_font); + return fontStyle ? std::string{ fontStyle } : std::string{}; + } + + int getPointSize() const { + return m_style.pointSize; + } + + bool isMonospaced() const { + return TTF_FontFaceIsFixedWidth(m_font); + } private: - void initFont(); + Font(const std::filesystem::path& fontPath, FontStyle style, std::optional pointSize, std::optional fontFaceIndex); - operator TTF_Font*() const { return m_font; } + operator TTF_Font* () const { return m_font; } TTF_Font* m_font = nullptr; - FontStyle m_style{}; + FontStyle m_style; }; using FontPtr = std::shared_ptr; diff --git a/BloomFramework/include/Graphics/FontStore.h b/BloomFramework/include/Graphics/FontStore.h index 33aeab14..bd9e2dee 100644 --- a/BloomFramework/include/Graphics/FontStore.h +++ b/BloomFramework/include/Graphics/FontStore.h @@ -1,5 +1,4 @@ #pragma once - #include "stdIncludes.h" #include "Font.h" @@ -9,15 +8,25 @@ namespace bloom::graphics { FontStore() = default; FontPtr load(const std::filesystem::path& filePath, size_t presetNumber, FontStyle style = FontStyle{}); - FontPtr find(size_t presetNumber) const noexcept; - void unload(size_t presetNumber); - void clear() noexcept; - FontPtr operator[](size_t key) const noexcept; + FontPtr find(size_t presetNumber) const noexcept { + const auto fontIt = m_store.find(presetNumber); + return fontIt != m_store.end() ? fontIt->second : FontPtr{}; + } + + void unload(size_t presetNumber) { + m_store.erase(presetNumber); + } + + void clear() noexcept { + m_store.clear(); + } + + FontPtr operator[](size_t key) const noexcept { + return find(key); + } private: std::unordered_map m_store; }; -} - - +} \ No newline at end of file diff --git a/BloomFramework/include/Graphics/Sprite.h b/BloomFramework/include/Graphics/Sprite.h index 3ed58cd6..8e5c9198 100644 --- a/BloomFramework/include/Graphics/Sprite.h +++ b/BloomFramework/include/Graphics/Sprite.h @@ -1,5 +1,4 @@ #pragma once - #include #include #include "TextureStore.h" diff --git a/BloomFramework/include/Graphics/SpriteText.h b/BloomFramework/include/Graphics/SpriteText.h index 79d14583..2319c199 100644 --- a/BloomFramework/include/Graphics/SpriteText.h +++ b/BloomFramework/include/Graphics/SpriteText.h @@ -1,5 +1,4 @@ #pragma once - #include "stdIncludes.h" #include "Drawable.h" #include "Font.h" @@ -7,9 +6,9 @@ namespace bloom::graphics { struct TextStyle { enum class BlendingMode { - normal = 0, - shaded = 1, - blended = 2 + normal, + shaded, + blended } blendingMode = BlendingMode::normal; SDL_Color foregroundColor = { 255, 255, 255, 0 }; SDL_Color backgroundColor = { 0, 0, 0, 0 }; @@ -17,15 +16,23 @@ namespace bloom::graphics { class BLOOMFRAMEWORK_API SpriteText : public Drawable { public: - SpriteText(SDL_Renderer* targetRenderer, std::shared_ptr fontPtr, std::string_view text = std::string_view{}, TextStyle style = TextStyle{}); + SpriteText(SDL_Renderer* const& targetRenderer, std::shared_ptr fontPtr, std::string_view text = std::string_view{}, TextStyle style = TextStyle{}); ~SpriteText() = default; void render(std::optional srcRect, SDL_Point destPoint, SDL_RendererFlip flip = SDL_FLIP_NONE); - int getTextHeight() const { return m_height; } - int getTextWidth() const { return m_width; } + int getTextHeight() const { + return m_height; + } + + int getTextWidth() const { + return m_width; + } + + std::string getText() const { + return m_text; + } - std::string getText() const { return m_text; } void setText(std::string_view newText) { if (m_text != newText) { m_text = newText; @@ -33,7 +40,10 @@ namespace bloom::graphics { } } - TextStyle getStyle() const { return m_style; } + TextStyle getStyle() const { + return m_style; + } + void setStyle(const TextStyle& newStyle) { m_style = newStyle; m_refreshRequired = true; diff --git a/BloomFramework/include/Graphics/Texture.h b/BloomFramework/include/Graphics/Texture.h index e8c38d37..9294629c 100644 --- a/BloomFramework/include/Graphics/Texture.h +++ b/BloomFramework/include/Graphics/Texture.h @@ -1,5 +1,4 @@ #pragma once - #include #include "stdIncludes.h" #include "Drawable.h" @@ -7,7 +6,7 @@ namespace bloom::graphics { class BLOOMFRAMEWORK_API Texture : public Drawable { public: - explicit Texture(SDL_Renderer* targetRenderer, const std::filesystem::path& filePath, std::optional colorKey = std::nullopt); + explicit Texture(SDL_Renderer* const& targetRenderer, const std::filesystem::path& filePath, std::optional colorKey = std::nullopt); }; using TexturePtr = std::shared_ptr; diff --git a/BloomFramework/include/Graphics/TextureStore.h b/BloomFramework/include/Graphics/TextureStore.h index 0f3354d2..78158dd2 100644 --- a/BloomFramework/include/Graphics/TextureStore.h +++ b/BloomFramework/include/Graphics/TextureStore.h @@ -1,5 +1,4 @@ #pragma once - #include #include #include "stdIncludes.h" @@ -11,18 +10,27 @@ namespace bloom { namespace graphics { class BLOOMFRAMEWORK_API TextureStore { public: - TextureStore(SDL_Renderer *& renderer); - TextureStore(Game & renderer); + TextureStore(SDL_Renderer* const& renderer); + TextureStore(Game& object); + + TexturePtr load(const std::filesystem::path& filePath, std::optional colorKey = std::nullopt); + + TexturePtr find(const std::filesystem::path& filePath) const noexcept { + const auto textureIt = m_store.find(filePath.u8string()); + return textureIt != m_store.end() ? textureIt->second : TexturePtr{}; + } - TexturePtr load(const std::filesystem::path & filePath, std::optional colorKey = std::nullopt); - TexturePtr at(const std::filesystem::path & filePath) const; - TexturePtr find(const std::filesystem::path & filePath) const noexcept; - void unload(const std::filesystem::path & filePath); + void unload(const std::filesystem::path& filePath) { + if (const auto textureIt = m_store.find(filePath.u8string()); textureIt != m_store.end()) + m_store.erase(textureIt); + } - TexturePtr operator[](const std::filesystem::path & key) const noexcept; + TexturePtr operator[](const std::filesystem::path& key) const noexcept { + return find(key); + } private: - SDL_Renderer *& m_renderer; + SDL_Renderer* const& c_renderer; std::unordered_map m_store; }; } diff --git a/BloomFramework/include/Screen.h b/BloomFramework/include/Screen.h deleted file mode 100644 index 09851308..00000000 --- a/BloomFramework/include/Screen.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include "stdIncludes.h" -#include "Game.h" - -namespace bloom { - class BLOOMFRAMEWORK_API Screen { - public: - Screen(Game& gameInstance); - void handleInput(); - void render(); - - private: - // std::vector gameObjects; // GameObject not implemented yet. - entt::DefaultRegistry registry; - Game& _gameInstance; - }; -} \ No newline at end of file diff --git a/BloomFramework/include/Systems/AnimationSystem.h b/BloomFramework/include/Systems/AnimationSystem.h index 852f7246..cb5a2663 100644 --- a/BloomFramework/include/Systems/AnimationSystem.h +++ b/BloomFramework/include/Systems/AnimationSystem.h @@ -1,5 +1,4 @@ #pragma once - #include "stdIncludes.h" #include "Components/Components.h" #include "DefaultSystem.h" @@ -12,15 +11,13 @@ namespace bloom::systems { using System::DefaultSystem; public: - void update(std::optional deltaTime = 0.0) override { + void update(double deltaTime = 0.0) override { m_registry.view().each( - [&](auto entity, AnimationPtr& anim) { - if (m_registry.has(entity)) { - AnimationPtr newAnim = m_registry.get(entity).getCurrent(); - if (newAnim) - anim = newAnim; - } - m_registry.replace(entity, anim->update(deltaTime.value())); + [this, deltaTime](auto entity, AnimationPtr& animation) { + if (m_registry.has(entity)) + if (auto currentAnimation = m_registry.get(entity).getCurrent(); currentAnimation) + animation = currentAnimation; + m_registry.replace(entity, animation->update(deltaTime)); } ); } diff --git a/BloomFramework/include/Systems/DefaultSystem.h b/BloomFramework/include/Systems/DefaultSystem.h index 12237040..9fcfc25f 100644 --- a/BloomFramework/include/Systems/DefaultSystem.h +++ b/BloomFramework/include/Systems/DefaultSystem.h @@ -1,17 +1,20 @@ #pragma once - -#include #include "stdIncludes.h" namespace bloom::systems { class DefaultSystem { public: - DefaultSystem(entt::DefaultRegistry & registry) : m_registry(registry) {}; + DefaultSystem(entt::registry& registry) : m_registry(registry) {} + DefaultSystem(const DefaultSystem&) = default; + DefaultSystem(DefaultSystem&&) = default; + DefaultSystem& operator=(const DefaultSystem&) = delete; + DefaultSystem& operator=(DefaultSystem&&) = delete; + virtual ~DefaultSystem() = default; - virtual void update(std::optional deltaTime = std::nullopt) = 0; + virtual void update(double deltaTime = 0.0) = 0; protected: - entt::DefaultRegistry & m_registry; + entt::registry& m_registry; }; using System = DefaultSystem; diff --git a/BloomFramework/include/Systems/RenderSystem.h b/BloomFramework/include/Systems/RenderSystem.h index 4f3dc912..67a2d481 100644 --- a/BloomFramework/include/Systems/RenderSystem.h +++ b/BloomFramework/include/Systems/RenderSystem.h @@ -1,5 +1,4 @@ #pragma once - #include "stdIncludes.h" #include "Components/Components.h" #include "DefaultSystem.h" @@ -12,17 +11,11 @@ namespace bloom::systems { using System::DefaultSystem; public: - void update(std::optional deltaTime = std::nullopt) override { + void update(double = 0.0) override { m_registry.view().each( - [](auto entity, Position & pos, Size& size, Sprite & spr) { - SDL_Rect destRect{ - static_cast(pos.x), - static_cast(pos.y), - static_cast(size.w), - static_cast(size.h) - }; - spr.texture->render(spr.srcRect, destRect); - }); + [](auto, Position& position, Size& size, Sprite& sprite) { + sprite.texture->render(sprite.srcRect, SDL_Rect{ position.x, position.y, size.w, size.h }); + }); } }; } \ No newline at end of file diff --git a/BloomFramework/include/Systems/Systems.h b/BloomFramework/include/Systems/Systems.h index e34cdb7a..0d92ca42 100644 --- a/BloomFramework/include/Systems/Systems.h +++ b/BloomFramework/include/Systems/Systems.h @@ -1,5 +1,4 @@ #pragma once - #include "DefaultSystem.h" #include "RenderSystem.h" #include "AnimationSystem.h" \ No newline at end of file diff --git a/BloomFramework/include/Timer.h b/BloomFramework/include/Timer.h index 2d7a1707..3ee34923 100644 --- a/BloomFramework/include/Timer.h +++ b/BloomFramework/include/Timer.h @@ -1,21 +1,39 @@ #pragma once - #include "stdIncludes.h" namespace bloom { - class BLOOMFRAMEWORK_API Timer { + class Timer { public: - Timer(); + Timer() : m_startTicks(SDL_GetPerformanceCounter()), m_timerTicks(m_startTicks) {} + + static uint32_t totalLifetime() { + return SDL_GetTicks(); + } + + void restart() { + m_timerTicks = SDL_GetPerformanceCounter(); + } + + [[deprecated("This function is deprecated. Use `restart()` instead")]] + void start() { + restart(); + } + + double split() const { + return (static_cast(SDL_GetPerformanceCounter() - m_timerTicks) / static_cast(SDL_GetPerformanceFrequency() / 1000.0)); + } - static Uint32 totalLifetime(); + double lap() { + const auto oldTicks = m_timerTicks; + m_timerTicks = SDL_GetPerformanceCounter(); + return (static_cast(m_timerTicks - oldTicks) / static_cast(SDL_GetPerformanceFrequency() / 1000.0)); + } - void start(); - void restart(); - double split(); - double lap(); - double objectLifetime(); + double objectLifetime() const { + return (static_cast(SDL_GetPerformanceCounter() - m_startTicks) / static_cast(SDL_GetPerformanceFrequency() / 1000.0)); + } private: - Uint64 m_startTicks, m_timerTicks; + uint64_t m_startTicks, m_timerTicks; }; } \ No newline at end of file diff --git a/BloomFramework/include/stdIncludes.h b/BloomFramework/include/stdIncludes.h index d5016ddd..a0947a34 100644 --- a/BloomFramework/include/stdIncludes.h +++ b/BloomFramework/include/stdIncludes.h @@ -3,7 +3,7 @@ #ifdef BLOOMFRAMEWORK_EXPORT #define BLOOMFRAMEWORK_API __declspec(dllexport) -#else +#else #define BLOOMFRAMEWORK_API __declspec(dllimport) #endif diff --git a/BloomFramework/packages.config b/BloomFramework/packages.config index c1628208..74fbd709 100644 --- a/BloomFramework/packages.config +++ b/BloomFramework/packages.config @@ -1,9 +1,9 @@  - - - - + + + + diff --git a/BloomFramework/src/Game.cpp b/BloomFramework/src/Game.cpp index 4d47bc3d..92644942 100644 --- a/BloomFramework/src/Game.cpp +++ b/BloomFramework/src/Game.cpp @@ -1,100 +1,91 @@ #include "Game.h" #include "Exception.h" -namespace bloom { - int Game::m_runningInstancesQnt = 0; - - Game::Game(int width, int height, int windowFlags, int rendererFlags) : - m_screenWidth(width), - m_screenHeight(height), - m_windowFlags(windowFlags), - m_rendererFlags(rendererFlags), - m_isRunning(false) - { - if (SDL_WasInit(0) == 0) - initialize(); - - if ((windowFlags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP)) == SDL_WINDOW_FULLSCREEN) - throw Exception{ "Game", "SDL_WINDOW_FULLSCREEN flag is used. \ - This can lead to graphic oddities when using hardware acceleration! Use SDL_WINDOW_FULLSCREEN_DESKTOP flag instead." }; +#define CHECK_IMG_FORMAT_FAILED(format) if (failed & IMG_INIT_##format) \ +std::clog << "Failed to initialize " << #format << " format support" << std::endl; - m_runningInstancesQnt++; - } +namespace bloom { + int Game::s_runningInstancesQnt = 0; - Game::Game(std::nothrow_t, int width, int height, int windowFlags, int rendererFlags) : - m_screenWidth(width), - m_screenHeight(height), - m_windowFlags(windowFlags), - m_rendererFlags(rendererFlags), + Game::Game(components::Size windowSize, const std::pair& flags) : + m_windowSize(windowSize), + c_windowFlags(flags.first), + c_rendererFlags(flags.second), m_isRunning(false) { - if (SDL_WasInit(0) == 0) - initialize(); - - if ((windowFlags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN) - std::clog << "[Game] SDL_WINDOW_FULLSCREEN flag is used. This can lead to graphic oddities when using hardware acceleration!" << std::endl; + ++s_runningInstancesQnt; } - Game::~Game() { destroy(); - m_runningInstancesQnt--; - if (m_runningInstancesQnt <= 0) - exit(); + --s_runningInstancesQnt; + //if (s_runningInstancesQnt <= 0) + // exit(); } - void Game::initialize(Uint32 initFlags, - int mixerFrequency, Uint16 mixerFormat, int mixerChannels, int mixerChunksize, + void Game::initialize(uint32_t initFlags, + const std::tuple& mixerParams, int imageFlags) { // Initialize SDL - if (SDL_Init(initFlags) < 0) + if (SDL_Init(initFlags)) throw Exception{ "Game::initialize", SDL_GetError() }; - std::clog << "Subsystems initialized!" << std::endl; + std::clog << "SDL initialized" << std::endl; // Initialize SDL_mixer - if (Mix_OpenAudio(mixerFrequency, mixerFormat, mixerChannels, mixerChunksize) < 0) + if (Mix_OpenAudio(std::get<0>(mixerParams), std::get<1>(mixerParams), + std::get<2>(mixerParams), std::get<3>(mixerParams))) throw Exception{ "Game::initialize", SDL_GetError() }; - std::clog << "SDL_mixer initialized." << std::endl; - - int isCapture = 0; - int n = SDL_GetNumAudioDevices(isCapture); - std::clog << "Audio devices: " << n << std::endl; - for (int i = 0; i < n; i++) { - auto name = SDL_GetAudioDeviceName(i, isCapture); - std::clog << "Audio: " << name << std::endl; - } + std::clog << "SDL_mixer initialized" << std::endl; + + const auto n = SDL_GetNumAudioDevices(false); + std::clog << "The number of audio devices: " << n << std::endl; + for (auto i = 0; i < n; ++i) + std::clog << "Audio device #" << i + 1 << ": " << SDL_GetAudioDeviceName(i, false) << std::endl; // Initialize SDL_ttf - if (TTF_Init() != 0) + if (TTF_Init()) throw Exception{ "Game::initialize", SDL_GetError() }; - std::clog << "SDL_ttf initialized." << std::endl; + std::clog << "SDL_ttf initialized" << std::endl; // Initialize SDL_image - if (IMG_Init(imageFlags) != imageFlags) - throw Exception{ "Game::initialize", SDL_GetError() }; - std::clog << "SDL_image initialized." << std::endl; + if (const auto formats = IMG_Init(imageFlags); formats != imageFlags) { + if (!formats) + throw Exception{ "Game::initialize", SDL_GetError() }; + std::clog << "Not all image formats have been initialized successfully" << std::endl; + const auto failed = formats ^ imageFlags; + CHECK_IMG_FORMAT_FAILED(JPG); + CHECK_IMG_FORMAT_FAILED(PNG); + CHECK_IMG_FORMAT_FAILED(TIF); + CHECK_IMG_FORMAT_FAILED(WEBP); + } + std::clog << "SDL_image initialized" << std::endl; } - void Game::exit() { - IMG_Quit(); - TTF_Quit(); - Mix_Quit(); - SDL_Quit(); + bool Game::exit() { + // Prevent the SDL from being unloaded if there is at least one alive object + if (!s_runningInstancesQnt) { + IMG_Quit(); + TTF_Quit(); + Mix_Quit(); + SDL_Quit(); + return true; + } + return false; } - void Game::create(std::string const& title, int xpos, int ypos) { - m_window = SDL_CreateWindow(title.c_str(), xpos, ypos, m_screenWidth, m_screenHeight, m_windowFlags); - if (m_window == nullptr) + void Game::create(std::string_view title, components::Position pos) { + m_window = SDL_CreateWindow(title.data(), pos.x, pos.y, m_windowSize.w, m_windowSize.h, c_windowFlags); + if (!m_window) throw Exception{ "Game::initialize", SDL_GetError() }; - std::clog << "Window created with width of " << m_screenWidth << " and height of " << m_screenHeight << "." << std::endl; + std::clog << "Window created with width of " << m_windowSize.w << " and height of " << m_windowSize.h << std::endl; - m_renderer = SDL_CreateRenderer(m_window, -1, m_rendererFlags); - if (m_renderer == nullptr) + m_renderer = SDL_CreateRenderer(m_window, -1, c_rendererFlags); + if (!m_renderer) throw Exception{ "Game::initialize", SDL_GetError() }; std::clog << "Renderer initialized." << std::endl; m_isRunning = true; - std::clog << "Game is now running!" << std::endl; + std::clog << "Game is now running" << std::endl; } void Game::handleEvents() { @@ -122,14 +113,10 @@ namespace bloom { void Game::destroy() { SDL_DestroyRenderer(m_renderer); - SDL_DestroyWindow(m_window); m_renderer = nullptr; + SDL_DestroyWindow(m_window); m_window = nullptr; - std::clog << "Window destroyed!" << std::endl; - } - - bool Game::isRunning() { - return m_isRunning; + std::clog << "Window destroyed" << std::endl; } void Game::hideWindow() { @@ -140,37 +127,8 @@ namespace bloom { SDL_ShowWindow(m_window); } - void Game::setColor(const SDL_Color & color) { + void Game::setColor(const SDL_Color& color) { m_color = color; SDL_SetRenderDrawColor(m_renderer, m_color.r, m_color.g, m_color.b, m_color.a); } - - void Game::setColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a) { - m_color = { r, g, b, a }; - SDL_SetRenderDrawColor(m_renderer, m_color.r, m_color.g, m_color.b, m_color.a); - } - - SDL_Color Game::getColor() { - return m_color; - } - - void Game::getColor(Uint8 & r, Uint8 & g, Uint8 & b, Uint8 & a) { - r = m_color.r; g = m_color.g; b = m_color.b; a = m_color.a; - } - - int Game::getScreenHeight() { - return m_screenHeight; - } - - int Game::getScreenWidth() { - return m_screenWidth; - } - - SDL_Event Game::getEvent() { - return m_event; - } - SDL_Renderer * Game::getRenderer() - { - return m_renderer; - } } \ No newline at end of file diff --git a/BloomFramework/src/GameObject.cpp b/BloomFramework/src/GameObject.cpp deleted file mode 100644 index 5f4a46ee..00000000 --- a/BloomFramework/src/GameObject.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "GameObject.h" - -namespace bloom { - GameObject::GameObject(entt::DefaultRegistry & registry, Game *& gameInstance) : m_registry(registry), m_gameInstance(gameInstance) { - m_entity = m_registry.create(); - m_registry.assign(m_entity, 0, 0); - } - - GameObject::~GameObject() { - m_registry.destroy(m_entity); - } - - uint32_t GameObject::getEntityID() { - return m_entity; - } -} \ No newline at end of file diff --git a/BloomFramework/src/Graphics/Animation.cpp b/BloomFramework/src/Graphics/Animation.cpp index 719aa715..9e0acf66 100644 --- a/BloomFramework/src/Graphics/Animation.cpp +++ b/BloomFramework/src/Graphics/Animation.cpp @@ -7,7 +7,7 @@ namespace bloom::graphics { throw Exception{ "Animation::update", "There are no any frames" }; m_lastUpdateTime += deltaTime; if (m_lastUpdateTime > m_frameTime) { - m_currentFrame = (m_currentFrame + static_cast(m_lastUpdateTime / m_frameTime + 0.5)) % animationFrames.size(); + m_currentFrame = (m_currentFrame + static_cast(m_lastUpdateTime / m_frameTime)) % animationFrames.size(); m_lastUpdateTime = std::fmod(m_lastUpdateTime, m_frameTime); } return animationFrames[m_currentFrame]; diff --git a/BloomFramework/src/Graphics/AnimationSet.cpp b/BloomFramework/src/Graphics/AnimationSet.cpp index 0dad4b3d..3fe464fb 100644 --- a/BloomFramework/src/Graphics/AnimationSet.cpp +++ b/BloomFramework/src/Graphics/AnimationSet.cpp @@ -2,24 +2,16 @@ #include "Exception.h" namespace bloom::graphics { - AnimationPtr AnimationSet::changeCurrent(const std::string & setName) { - auto it = m_sets.find(setName); - if (it == m_sets.end()) + AnimationPtr AnimationSet::changeCurrent(const std::string& setName) { + const auto setIt = m_sets.find(setName); + if (setIt == m_sets.end()) throw Exception{ "AnimationSet::changeCurrent", "Set doesn't exist" }; - if (m_current != it->second) { + if (m_current != setIt->second) { if (m_current) m_current->stop(); - m_current = it->second; + m_current = setIt->second; } return m_current; } - - inline void AnimationSet::add(const std::string & setName, const Animation & animation) { - m_sets.try_emplace(setName, std::make_shared(animation)); - } - - inline void AnimationSet::add(const std::string & setName, AnimationPtr animationPtr) { - m_sets.try_emplace(setName, animationPtr); - } } \ No newline at end of file diff --git a/BloomFramework/src/Graphics/Drawable.cpp b/BloomFramework/src/Graphics/Drawable.cpp index cf71cc36..6084ddc8 100644 --- a/BloomFramework/src/Graphics/Drawable.cpp +++ b/BloomFramework/src/Graphics/Drawable.cpp @@ -2,7 +2,7 @@ #include "Exception.h" namespace bloom::graphics { - Drawable::Drawable(SDL_Renderer* targetRenderer) : c_renderer(targetRenderer) { + Drawable::Drawable(SDL_Renderer* const& targetRenderer) : c_renderer(targetRenderer) { if (!c_renderer) throw Exception{ "Drawable", "targetRenderer can not be nullptr" }; } diff --git a/BloomFramework/src/Graphics/Font.cpp b/BloomFramework/src/Graphics/Font.cpp index 1a65c0d2..a3660981 100644 --- a/BloomFramework/src/Graphics/Font.cpp +++ b/BloomFramework/src/Graphics/Font.cpp @@ -3,60 +3,45 @@ #include "Graphics/SpriteText.h" namespace bloom::graphics { - Font::Font(const std::filesystem::path& fontPath, int pointSize) { + Font::Font(const std::filesystem::path& fontPath, FontStyle style, std::optional pointSize, std::optional fontFaceIndex) : + m_style(style) + { if (!std::filesystem::exists(fontPath)) throw Exception{ "Font", "Font file doesn't exist" }; - m_font = TTF_OpenFont(fontPath.u8string().c_str(), pointSize); - if (!m_font) - throw Exception{"Font", TTF_GetError() }; - m_style.pointSize = pointSize; - initFont(); - } + if (pointSize) + m_style.pointSize = pointSize.value(); - Font::Font(const std::filesystem::path& fontPath, int pointSize, long fontFaceIndex) { - if (!std::filesystem::exists(fontPath)) - throw Exception{ "Font", "Font file doesn't exist" }; + if (fontFaceIndex) + m_font = TTF_OpenFontIndex(fontPath.u8string().c_str(), pointSize.value_or(m_style.pointSize), fontFaceIndex.value()); + else + m_font = TTF_OpenFont(fontPath.u8string().c_str(), pointSize.value_or(m_style.pointSize)); - m_font = TTF_OpenFontIndex(fontPath.u8string().c_str(), pointSize, fontFaceIndex); - if (!m_font) - throw Exception{ "Font", TTF_GetError()}; - m_style.pointSize = pointSize; - initFont(); - } - - Font::Font(const std::filesystem::path& fontPath, const FontStyle& style) : m_style(style) { - if (!std::filesystem::exists(fontPath)) - throw Exception{ "Font", "Font file doesn't exist" }; - - m_font = TTF_OpenFont(fontPath.u8string().c_str(), m_style.pointSize); if (!m_font) throw Exception{ "Font", TTF_GetError() }; - initFont(); - } - Font::~Font() { - if (m_font) { - TTF_CloseFont(m_font); - m_font = nullptr; - } - } - - void Font::initFont() { TTF_SetFontStyle(m_font, m_style.fontStyle); TTF_SetFontHinting(m_font, m_style.hinting); TTF_SetFontKerning(m_font, static_cast(m_style.allowKerning)); TTF_SetFontOutline(m_font, m_style.outlineWidth); } + Font::Font(const std::filesystem::path& fontPath, int pointSize) : + Font(fontPath.u8string().c_str(), FontStyle{}, pointSize, std::nullopt) + {} - std::string Font::getFamilyName() const { - const char* fontName = TTF_FontFaceFamilyName(m_font); - return fontName ? std::string{ fontName } : std::string{}; - } + Font::Font(const std::filesystem::path& fontPath, int pointSize, long fontFaceIndex) : + Font(fontPath.u8string().c_str(), FontStyle{}, pointSize, fontFaceIndex) + {} - std::string Font::getStyleName() const { - const char* fontStyle = TTF_FontFaceStyleName(m_font); - return fontStyle ? std::string{ fontStyle } : std::string{}; + Font::Font(const std::filesystem::path& fontPath, const FontStyle& style) : + Font(fontPath.u8string().c_str(), style, std::nullopt, std::nullopt) + {} + + Font::~Font() { + if (m_font) { + TTF_CloseFont(m_font); + m_font = nullptr; + } } } \ No newline at end of file diff --git a/BloomFramework/src/Graphics/FontStore.cpp b/BloomFramework/src/Graphics/FontStore.cpp index 31d329ae..66a40c76 100644 --- a/BloomFramework/src/Graphics/FontStore.cpp +++ b/BloomFramework/src/Graphics/FontStore.cpp @@ -2,31 +2,11 @@ namespace bloom::graphics { FontPtr FontStore::load(const std::filesystem::path& filePath, size_t presetNumber, FontStyle style) { - if (auto fontIt = m_store.find(presetNumber); fontIt != m_store.end()) { - //std::clog << "[FontStore::load] font preset with that name already exists, returning that instead" << std::endl; - return fontIt->second; - } + if (auto fontPtr = find(presetNumber); fontPtr) + return fontPtr; FontPtr ptr = std::make_shared(filePath, style); m_store.emplace(presetNumber, ptr); return ptr; } - - FontPtr FontStore::find(size_t presetNumber) const noexcept { - if (auto fontIt = m_store.find(presetNumber); fontIt != m_store.end()) - return fontIt->second; - return FontPtr{}; - } - - void FontStore::unload(size_t presetNumber) { - m_store.erase(presetNumber); - } - - void FontStore::clear() noexcept { - m_store.clear(); - } - - FontPtr FontStore::operator[](size_t key) const noexcept { - return find(key); - } } \ No newline at end of file diff --git a/BloomFramework/src/Graphics/SpriteText.cpp b/BloomFramework/src/Graphics/SpriteText.cpp index 3b2b911a..b3933289 100644 --- a/BloomFramework/src/Graphics/SpriteText.cpp +++ b/BloomFramework/src/Graphics/SpriteText.cpp @@ -2,7 +2,7 @@ #include "Graphics/SpriteText.h" namespace bloom::graphics { - SpriteText::SpriteText(SDL_Renderer* targetRenderer, std::shared_ptr fontPtr, std::string_view text, TextStyle style) : + SpriteText::SpriteText(SDL_Renderer* const& targetRenderer, std::shared_ptr fontPtr, std::string_view text, TextStyle style) : Drawable(targetRenderer), m_fontPtr(std::move(fontPtr)), m_text(text), @@ -48,7 +48,7 @@ namespace bloom::graphics { m_texture = SDL_CreateTextureFromSurface(c_renderer, textSurface); SDL_FreeSurface(textSurface); if (!m_texture) - throw Exception{ "SpriteText::refreshTexture", SDL_GetError()}; + throw Exception{ "SpriteText::refreshTexture", SDL_GetError() }; SDL_QueryTexture(m_texture, nullptr, nullptr, &m_width, &m_height); m_refreshRequired = false; diff --git a/BloomFramework/src/Graphics/Texture.cpp b/BloomFramework/src/Graphics/Texture.cpp index 21c98bf8..372e7e65 100644 --- a/BloomFramework/src/Graphics/Texture.cpp +++ b/BloomFramework/src/Graphics/Texture.cpp @@ -2,7 +2,7 @@ #include "Exception.h" namespace bloom::graphics { - Texture::Texture(SDL_Renderer* targetRenderer, const std::filesystem::path& filePath, std::optional colorKey) : Drawable(targetRenderer) { + Texture::Texture(SDL_Renderer* const& targetRenderer, const std::filesystem::path& filePath, std::optional colorKey) : Drawable(targetRenderer) { //Load image at specified path SDL_Surface* loadedSurface = IMG_Load(filePath.u8string().c_str()); if (!loadedSurface) @@ -17,4 +17,4 @@ namespace bloom::graphics { if (!m_texture) throw Exception{ "Texture", SDL_GetError() }; } -} +} \ No newline at end of file diff --git a/BloomFramework/src/Graphics/TextureStore.cpp b/BloomFramework/src/Graphics/TextureStore.cpp index 08067cb1..738fa910 100644 --- a/BloomFramework/src/Graphics/TextureStore.cpp +++ b/BloomFramework/src/Graphics/TextureStore.cpp @@ -3,42 +3,20 @@ #include "Game.h" namespace bloom::graphics { - TextureStore::TextureStore(SDL_Renderer *& renderer) : m_renderer(renderer) {} + TextureStore::TextureStore(SDL_Renderer* const& renderer) : c_renderer(renderer) {} - TextureStore::TextureStore(Game & object) : m_renderer(object.m_renderer) {} + TextureStore::TextureStore(Game& object) : c_renderer(object._getRenderer()) {} - TexturePtr TextureStore::load(const std::filesystem::path & filePath, std::optional colorKey) { + TexturePtr TextureStore::load(const std::filesystem::path& filePath, std::optional colorKey) { if (!std::filesystem::exists(filePath)) throw Exception{ "TextureStore::load", "File \"" + filePath.u8string() + "\" not exists" }; // Check if texture of the same path is loaded. If so, return shared_ptr of texture. - if (auto textureIt = m_store.find(filePath.u8string()); textureIt != m_store.end()) + if (const auto textureIt = m_store.find(filePath.u8string()); textureIt != m_store.end()) return textureIt->second; - TexturePtr ptr = std::make_shared(m_renderer, filePath, colorKey); + TexturePtr ptr = std::make_shared(c_renderer, filePath, colorKey); m_store.emplace(filePath.u8string(), ptr); return ptr; } - - TexturePtr TextureStore::at(const std::filesystem::path & filePath) const { - if (auto textureIt = m_store.find(filePath.u8string()); textureIt != m_store.end()) - return textureIt->second; - throw Exception{ "TextureStore::at", "File \"" + filePath.u8string() + "\" not loaded" }; - } - - TexturePtr TextureStore::find(const std::filesystem::path & filePath) const noexcept { - if (auto textureIt = m_store.find(filePath.u8string()); textureIt != m_store.end()) - return textureIt->second; - else - return nullptr; - } - - void TextureStore::unload(const std::filesystem::path & filePath) { - if (auto textureIt = m_store.find(filePath.u8string()); textureIt != m_store.end()) - m_store.erase(textureIt); // We can't dispose the actual Texture since others may still be using it. - } - - TexturePtr TextureStore::operator[](const std::filesystem::path & key) const noexcept { - return find(key); - } -} +} \ No newline at end of file diff --git a/BloomFramework/src/Timer.cpp b/BloomFramework/src/Timer.cpp deleted file mode 100644 index 01be3980..00000000 --- a/BloomFramework/src/Timer.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "Timer.h" - -namespace bloom { - Timer::Timer() : m_startTicks(SDL_GetPerformanceCounter()), m_timerTicks(m_startTicks) {} - - Uint32 Timer::totalLifetime() { - return SDL_GetTicks(); - } - - void Timer::start() { - m_timerTicks = SDL_GetPerformanceCounter(); - } - - void Timer::restart() { - start(); - } - - double Timer::split() { - return (static_cast(SDL_GetPerformanceCounter() - m_timerTicks) * 1000.0 / static_cast(SDL_GetPerformanceFrequency())); - } - - double Timer::lap() { - Uint64 oldTicks = m_timerTicks; - m_timerTicks = SDL_GetPerformanceCounter(); - return (static_cast(m_timerTicks - oldTicks) * 1000.0 / static_cast(SDL_GetPerformanceFrequency())); - } - - double Timer::objectLifetime() { - return (static_cast(SDL_GetPerformanceCounter() - m_startTicks) * 1000.0 / SDL_GetPerformanceFrequency()); - } -} \ No newline at end of file diff --git a/Test Bench/GameObjectTest/AnimationChangerSystem.h b/Test Bench/GameObjectTest/AnimationChangerSystem.h index 66ebed54..813655cd 100644 --- a/Test Bench/GameObjectTest/AnimationChangerSystem.h +++ b/Test Bench/GameObjectTest/AnimationChangerSystem.h @@ -1,9 +1,9 @@ #pragma once - +#include #include "Framework.h" /* - Crap system just to test if shit works, don't mind the hard coded fuckery here. + Crap system just to test if shit works, don't mind the hard coded duckery here. Definitely shouldn't be in bloom::systems. */ @@ -13,19 +13,19 @@ class AnimationChangerSystem : public bloom::systems::System { using bloom::systems::System::DefaultSystem; public: - void update(std::optional deltaTime = std::nullopt) override { - counter = (counter + 1) % 100; - if (counter == 0) { + void update(double = 0.0) override { + m_counter = (m_counter + 1) % 100; + if (m_counter == 0) { m_registry.view().each( - [&](auto entity, AnimationSet& animSet) { - animSet.changeCurrent(animations[rand() % 4]); + [&](auto, AnimationSet& set) { + set.changeCurrent(c_animations[rand() % 4]); } ); } } private: - int counter = 99; - std::vector animations{ + int m_counter = 99; + const std::array c_animations{ "up", "down", "left", diff --git a/Test Bench/GameObjectTest/NoRandomComponent.h b/Test Bench/GameObjectTest/NoRandomComponent.h deleted file mode 100644 index c57862ca..00000000 --- a/Test Bench/GameObjectTest/NoRandomComponent.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct NoRandomPos {}; \ No newline at end of file diff --git a/Test Bench/GameObjectTest/RandomComponent.h b/Test Bench/GameObjectTest/RandomComponent.h new file mode 100644 index 00000000..41131567 --- /dev/null +++ b/Test Bench/GameObjectTest/RandomComponent.h @@ -0,0 +1,3 @@ +#pragma once + +struct RandomPos {}; \ No newline at end of file diff --git a/Test Bench/GameObjectTest/RandomizerSystem.h b/Test Bench/GameObjectTest/RandomizerSystem.h index 238d97a0..6f82968e 100644 --- a/Test Bench/GameObjectTest/RandomizerSystem.h +++ b/Test Bench/GameObjectTest/RandomizerSystem.h @@ -1,31 +1,22 @@ #pragma once - #include "Framework.h" -#include "NoRandomComponent.h" +#include "RandomComponent.h" class RandomPositionSystem : public bloom::systems::System { using Position = bloom::components::Position; using bloom::systems::System::DefaultSystem; public: - void update(std::optional deltaTime = std::nullopt) override { - m_registry.view().each( - [this](auto entity, Position & pos) { - if (!m_registry.has(entity)) { - pos.x = rand() % 672; - pos.y = rand() % 472; - } - }); + void update(double = 0.0) override { + update(672, 472); } - void update(int frameWidth, int frameHeight, std::optional dt = std::nullopt) - { - m_registry.view().each( - [this, frameWidth, frameHeight](auto entity, Position & pos) { - if (!m_registry.has(entity)) { + void update(int frameWidth, int frameHeight, double = 0.0) { + m_registry.view().each( + [frameWidth, frameHeight](auto, Position& pos, RandomPos) { pos.x = rand() % frameWidth; pos.y = rand() % frameHeight; } - }); + ); } }; \ No newline at end of file diff --git a/Test Bench/GameObjectTest/TestAnimatedGameObject.h b/Test Bench/GameObjectTest/TestAnimatedGameObject.h index 194716d4..f83bf41f 100644 --- a/Test Bench/GameObjectTest/TestAnimatedGameObject.h +++ b/Test Bench/GameObjectTest/TestAnimatedGameObject.h @@ -1,7 +1,5 @@ #pragma once - #include "Framework.h" -#include "NoRandomComponent.h" class TestAnimChar : public bloom::GameObject { using Position = bloom::components::Position; @@ -15,10 +13,10 @@ class TestAnimChar : public bloom::GameObject { public: void init() override {} - void init(const std::filesystem::path texturePath = "Assets/TestChar.png") { + void init(const std::filesystem::path& texturePath = "Assets/TestChar.png") { m_registry.replace(m_entity, 50, 50); - m_registry.assign(m_entity, 256, 256); - auto tmp = m_gameInstance->textures.load(texturePath); + m_registry.replace(m_entity, 256, 256); + auto tmp = c_gameInstance->textures.load(texturePath); m_registry.assign(m_entity, tmp, SDL_Rect{ 0,32,32,32 }); @@ -70,6 +68,5 @@ class TestAnimChar : public bloom::GameObject { m_registry.assign(m_entity, animSet); m_registry.assign(m_entity, up); - m_registry.assign(m_entity); } }; \ No newline at end of file diff --git a/Test Bench/GameObjectTest/TestGameObject.h b/Test Bench/GameObjectTest/TestGameObject.h index b430ed4b..f0f365f5 100644 --- a/Test Bench/GameObjectTest/TestGameObject.h +++ b/Test Bench/GameObjectTest/TestGameObject.h @@ -1,7 +1,6 @@ #pragma once - #include "Framework.h" -#include "NoRandomComponent.h" +#include "RandomComponent.h" class TestChar : public bloom::GameObject { using Position = bloom::components::Position; @@ -14,21 +13,21 @@ class TestChar : public bloom::GameObject { void init(bloom::graphics::TexturePtr texturePtr, SDL_Rect pos_and_size = SDL_Rect{ 50,50, 256, 256 }, std::optional srcRect = std::nullopt) { m_registry.replace(m_entity, pos_and_size.x, pos_and_size.y); - m_registry.assign(m_entity, pos_and_size.w, pos_and_size.h); + m_registry.replace(m_entity, pos_and_size.w, pos_and_size.h); m_registry.assign(m_entity, texturePtr, srcRect); } - void init(SDL_Rect pos_and_size = SDL_Rect{ 50,50, 256, 256 }, const std::filesystem::path texturePath = "Assets/TestChar.png", std::optional srcRect = std::nullopt) { - auto tmp = m_gameInstance->textures.load(texturePath); + void init(SDL_Rect pos_and_size = SDL_Rect{ 50,50, 256, 256 }, const std::filesystem::path& texturePath = "Assets/TestChar.png", std::optional srcRect = std::nullopt) { + auto tmp = c_gameInstance->textures.load(texturePath); init(tmp, pos_and_size, srcRect); } void disableRandomPos() { - m_registry.assign(m_entity); + m_registry.reset(m_entity); } void enableRandomPos() { - m_registry.reset(m_entity); + m_registry.assign(m_entity); } }; \ No newline at end of file diff --git a/Test Bench/Test Bench.vcxproj b/Test Bench/Test Bench.vcxproj index 3d2f00c2..810f16b1 100644 --- a/Test Bench/Test Bench.vcxproj +++ b/Test Bench/Test Bench.vcxproj @@ -207,7 +207,7 @@ - + @@ -215,10 +215,10 @@ - - - - + + + + @@ -228,10 +228,10 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - + + + + diff --git a/Test Bench/Test Bench.vcxproj.filters b/Test Bench/Test Bench.vcxproj.filters index 95773fdd..89ec4528 100644 --- a/Test Bench/Test Bench.vcxproj.filters +++ b/Test Bench/Test Bench.vcxproj.filters @@ -40,9 +40,6 @@ Header Files - - Header Files - Header Files @@ -52,5 +49,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/Test Bench/getExePath.h b/Test Bench/getExePath.h index 8aff6c8f..98cdc5ae 100644 --- a/Test Bench/getExePath.h +++ b/Test Bench/getExePath.h @@ -1,5 +1,4 @@ #pragma once - #include #include diff --git a/Test Bench/main.cpp b/Test Bench/main.cpp index 724b913e..1674fbef 100644 --- a/Test Bench/main.cpp +++ b/Test Bench/main.cpp @@ -59,10 +59,9 @@ void test_drawer(const std::filesystem::path& dataDir) { const int framedelay = 1000 / 60; Uint32 framestart; - - game = new Game(WINDOW_WIDTH, WINDOW_HEIGHT); + game = new Game({ WINDOW_WIDTH, WINDOW_HEIGHT }); try { - game->create("Bloom Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); + game->create("Bloom Test", { SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED }); } catch (Exception & e) { std::cerr << e.what() << std::endl; @@ -91,7 +90,7 @@ void test_drawer(const std::filesystem::path& dataDir) { constexpr size_t UI_font = 0; fonts.load(fontPath, UI_font); - auto renderer = game->getRenderer(); + auto renderer = game->_getRenderer(); // Test SpriteText(NFont) bloom::graphics::SpriteText testText(renderer, fonts[UI_font], "Hello, World!"); { @@ -115,38 +114,37 @@ void test_drawer(const std::filesystem::path& dataDir) { game->delay(500); // Test Game Object - entt::DefaultRegistry testRegistry; + entt::registry testRegistry; AnimationChangerSystem animChangerTest(testRegistry); bloom::systems::AnimationSystem animSysTest(testRegistry); bloom::systems::RenderSystem renderSysTest(testRegistry); - //game->textures.load(spriteSheetPath, SDL_Color{ 64, 176, 104, 113 }); - //game->textures.load(testCharPath, SDL_Color{ 144,168,0,0 }); TestChar testSprite = TestChar(testRegistry, game); testSprite.init(SDL_Rect{ 0, 0, 128, 128 }, spriteSheetPath, SDL_Rect{ 0,0,32,32 }); + testSprite.enableRandomPos(); renderSysTest.update(); game->render(); TestChar testSprite2 = TestChar(testRegistry, game); testSprite2.init(SDL_Rect{ 128, 0, 128, 128 }, testCharPath, SDL_Rect{ 0, 0, 32, 32 }); + testSprite2.enableRandomPos(); renderSysTest.update(); game->render(); TestChar testGO = TestChar(testRegistry, game); testGO.init(SDL_Rect{ 50, 50, 192, 192 }, testCharPath, SDL_Rect{ 64, 96, 32, 32 }); - testGO.disableRandomPos(); renderSysTest.update(); game->render(); - // Randomizes position of entities(excluding those with `NoRandomPos` Component. + // Randomizes position of entities (which has `RandomPos` component) RandomPositionSystem randomizer(testRegistry); TestAnimChar testAnim(testRegistry, game); testAnim.init(testCharPath); // Test SpriteText2 std::string deltaTimeText{ "fps: " }; - + // If manual control of entities is required, this is the method to do so. - auto & testGOpos = testRegistry.get(testGO.getEntityID()); + auto& testGOpos = testRegistry.get(testGO.getEntityID()); - auto & testGOsize = testRegistry.get(testGO.getEntityID()); + auto& testGOsize = testRegistry.get(testGO.getEntityID()); int testX = rstep(10), testY = rstep(10); while (game->isRunning()) { @@ -205,6 +203,7 @@ int main(int argc, char* argv[]) { sounds[1]->play(); std::this_thread::sleep_for(3s); sounds.clear(); + delete game; return 0; } \ No newline at end of file diff --git a/Test Bench/packages.config b/Test Bench/packages.config index c1628208..74fbd709 100644 --- a/Test Bench/packages.config +++ b/Test Bench/packages.config @@ -1,9 +1,9 @@  - - - - + + + + diff --git a/entt b/entt index f71a4d53..85152bac 160000 --- a/entt +++ b/entt @@ -1 +1 @@ -Subproject commit f71a4d5381659d0218980929b969362b4d0ddbd3 +Subproject commit 85152bac3462c95e7be02cd4077bef8fc56de804