diff --git a/src/Animation.hpp b/src/Animation.hpp index f7a39bc..430e61f 100644 --- a/src/Animation.hpp +++ b/src/Animation.hpp @@ -51,8 +51,22 @@ public: */ void frame_length(float length); - void play(float = 0.0f, bool = false); - void play_once(float = 0.0f); + /*! + * Turn the play state to on, causing the animation's callback to run once every frame length. If a delay is given, wait before running. If + * the play_once flag is set to true, only play the callback once after the delay. + * + * @param delay Amount of seconds to delay before running + * @param play_once If true, only run the callback once instead of once every frame length + */ + void play(float delay = 0.0f, bool play_once = false); + + /*! + * Run the animation's callback only once, optionally after a specified delay. If no delay is specified, it will run immediately. + * + * @param delay Amount of seconds to delay before running + */ + void play_once(float delay = 0.0f); + void pause(); void unpause(); void reset(); diff --git a/src/Configuration.cpp b/src/Configuration.cpp index ef3f5cb..96c4356 100644 --- a/src/Configuration.cpp +++ b/src/Configuration.cpp @@ -50,7 +50,8 @@ void Configuration::set_defaults() {"fluid resize", false}, {"default font path", "BPmono.ttf"}, {"default font size", 16}, - {"use play button", false} + {"use play button", false}, + {"fullscreen", false} }; config["audio"] = { {"default-sfx-root", "resource/sfx"}, @@ -143,32 +144,10 @@ void Configuration::merge(const nlohmann::json& incoming) void Configuration::merge(const fs::path& path) { + merge(json_from_file(path)); + #ifndef __ANDROID__ - /* Can't check for file existence in an Android APK */ - if (fs::exists(path)) - { -#endif - /* Load JSON to a string and check for validity. */ - std::string contents = sb::file_to_string(path); - if (nlohmann::json::accept(contents)) - { - merge(nlohmann::json::parse(contents)); - } - else - { - std::ostringstream message; - message << "Invalid JSON at " << path; - sb::Log::log(message, sb::Log::WARN); - } -#ifndef __ANDROID__ - config_file_modification_time = fs::last_write_time(path); - } - else - { - std::ostringstream message; - message << "File not found: " << path; - sb::Log::log(message, sb::Log::WARN); - } + config_file_modification_time = fs::last_write_time(path); #endif } @@ -182,6 +161,51 @@ void Configuration::merge(const char* path) merge(fs::path(path)); } +nlohmann::json Configuration::json_from_file(const fs::path& path) +{ + nlohmann::json json; + +#ifndef __ANDROID__ + /* Can't check for file existence in an Android APK */ + if (fs::exists(path)) + { +#endif + /* Load JSON to a string and check for validity. */ + std::string contents = sb::file_to_string(path); + if (nlohmann::json::accept(contents)) + { + json = nlohmann::json::parse(contents); + } + else + { + std::ostringstream message; + message << "Invalid JSON at " << path; + sb::Log::log(message, sb::Log::WARN); + } + +#ifndef __ANDROID__ + } + else + { + std::ostringstream message; + message << "File not found: " << path; + sb::Log::log(message, sb::Log::WARN); + } +#endif + + return json; +} + +nlohmann::json Configuration::json_from_file(const std::string& path) +{ + return json_from_file(fs::path(path)); +} + +nlohmann::json Configuration::json_from_file(const char* path) +{ + return json_from_file(fs::path(path)); +} + void Configuration::enable_auto_refresh(const fs::path& file_to_refresh) { #ifndef __ANDROID__ diff --git a/src/Configuration.hpp b/src/Configuration.hpp index d9b5b86..ecbf40d 100644 --- a/src/Configuration.hpp +++ b/src/Configuration.hpp @@ -161,15 +161,33 @@ public: void merge(const fs::path& path); /*! - * @overload void Configuration::merge(fs::path path) + * @overload void Configuration::merge(const fs::path& path) */ void merge(const std::string& path); /*! - * @overload void Configuration::merge(fs::path path) + * @overload void Configuration::merge(const fs::path& path) */ void merge(const char* path); + /*! + * Open the JSON file at a given path and return the contents as a JSON object. + * + * @param path Filesystem path to a JSON file + * @return A nlohmann::json object containing the contents of the given file + */ + static nlohmann::json json_from_file(const fs::path& path); + + /*! + * @overload Configuration::json_from_file(const fs::path&) + */ + static nlohmann::json json_from_file(const std::string& path); + + /*! + * @overload Configuration::json_from_file(const fs::path&) + */ + static nlohmann::json json_from_file(const char* path); + /*! * Enable auto refresh. Auto refresh watches the file at the given path for changes and loads them automatically at every interval * specified in the configuration under "configuration" -> "auto-refresh-interval". diff --git a/src/Game.cpp b/src/Game.cpp index f1d5741..1498224 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -135,9 +135,11 @@ Game::Game() #endif /* Create a window with dimensions set in the config, centered, and flagged to be usable in OpenGL context */ + Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; + if (configuration()("display", "fullscreen")) flags |= SDL_WINDOW_FULLSCREEN; _window = SDL_CreateWindow( configuration()["display"]["title"].get_ref().c_str(), SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, window_size.x, window_size.y, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); + SDL_WINDOWPOS_CENTERED, window_size.x, window_size.y, flags); if (_window == nullptr) { sb::Log::sdl_error("Could not create window"); diff --git a/src/Pad.hpp b/src/Pad.hpp index 32c65f0..20e9a13 100644 --- a/src/Pad.hpp +++ b/src/Pad.hpp @@ -107,6 +107,14 @@ namespace sb _plane = plane; } + /*! + * @return Constant reference to the pad's plane object + */ + const sb::Plane& plane() const + { + return _plane; + } + /*! * Rotate the pad around its center by 90 degrees. If a count is given, rotate by 90 degrees that many times, so for example, * a count of 3 will be a 270 degree rotation. If the count is negative, rotate -90 degrees. diff --git a/src/Text.cpp b/src/Text.cpp index d8e2868..1288dd1 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -22,6 +22,18 @@ void Text::content(const std::string& content) refresh(); } +void Text::content(char content) +{ + _content = ""; + _content += content; + refresh(); +} + +const std::string& Text::content() const +{ + return _content; +} + void Text::foreground(const Color& foreground) { _foreground = foreground; @@ -55,7 +67,8 @@ void Text::scaling_quality(GLint quality) void Text::refresh() { /* Render the text with transparent background as RGBA pixel data using the SDL image library. */ - std::shared_ptr blended {TTF_RenderText_Blended(_font.get(), _content.c_str(), _foreground), SDL_FreeSurface}; + // std::shared_ptr blended {TTF_RenderText_Blended(_font.get(), _content.c_str(), _foreground), SDL_FreeSurface}; + std::shared_ptr blended {TTF_RenderText_Blended_Wrapped(_font.get(), _content.c_str(), _foreground, 3000), SDL_FreeSurface}; if (!blended) { Log::sdl_error("Could not create text"); diff --git a/src/Text.hpp b/src/Text.hpp index a7cd2e2..3a8789c 100644 --- a/src/Text.hpp +++ b/src/Text.hpp @@ -66,6 +66,16 @@ namespace sb */ void content(const std::string& content); + /*! + * @param content Single character to be used for text content + */ + void content(char content); + + /*! + * @return Text content to be displayed + */ + const std::string& content() const; + /*! * @param foreground text color */ diff --git a/src/Timer.cpp b/src/Timer.cpp index 157429c..927c98b 100644 --- a/src/Timer.cpp +++ b/src/Timer.cpp @@ -40,6 +40,11 @@ float sb::Timer::elapsed() const return _elapsed; } +void sb::Timer::elapsed(float seconds) +{ + _elapsed = seconds; +} + float sb::Timer::frame() const { return frame_duration; diff --git a/src/Timer.hpp b/src/Timer.hpp index 25f0bb0..f0b222b 100644 --- a/src/Timer.hpp +++ b/src/Timer.hpp @@ -76,6 +76,11 @@ namespace sb */ float elapsed() const; + /*! + * @param time Set the clock to a certain amount of seconds + */ + void elapsed(float seconds); + /*! * @return length of the previous frame in seconds */