diff options
Diffstat (limited to 'src/crepe/api')
30 files changed, 554 insertions, 47 deletions
diff --git a/src/crepe/api/AssetManager.cpp b/src/crepe/api/AssetManager.cpp new file mode 100644 index 0000000..560df6c --- /dev/null +++ b/src/crepe/api/AssetManager.cpp @@ -0,0 +1,17 @@ +#include "util/log.h" + +#include "AssetManager.h" + +using namespace crepe::api; + +AssetManager & AssetManager::get_instance() { + static AssetManager instance; + return instance; +} + +AssetManager::~AssetManager() { + dbg_trace(); + this->asset_cache.clear(); +} + +AssetManager::AssetManager() { dbg_trace(); } diff --git a/src/crepe/api/AssetManager.h b/src/crepe/api/AssetManager.h new file mode 100644 index 0000000..3e72a49 --- /dev/null +++ b/src/crepe/api/AssetManager.h @@ -0,0 +1,35 @@ +#pragma once + +#include <any> +#include <memory> +#include <string> +#include <unordered_map> + +namespace crepe::api { + +class AssetManager { + +private: + std::unordered_map<std::string, std::any> asset_cache; + +private: + AssetManager(); + virtual ~AssetManager(); + +public: + AssetManager(const AssetManager &) = delete; + AssetManager(AssetManager &&) = delete; + AssetManager & operator=(const AssetManager &) = delete; + AssetManager & operator=(AssetManager &&) = delete; + + static AssetManager & get_instance(); + +public: + template <typename asset> + std::shared_ptr<asset> cache(const std::string & file_path, + bool reload = false); +}; + +} // namespace crepe::api + +#include "AssetManager.hpp" diff --git a/src/crepe/api/AssetManager.hpp b/src/crepe/api/AssetManager.hpp new file mode 100644 index 0000000..468724c --- /dev/null +++ b/src/crepe/api/AssetManager.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include "AssetManager.h" + +namespace crepe::api { + +template <typename asset> +std::shared_ptr<asset> AssetManager::cache(const std::string & file_path, + bool reload) { + auto it = asset_cache.find(file_path); + + if (!reload && it != asset_cache.end()) { + return std::any_cast<std::shared_ptr<asset>>(it->second); + } + + std::shared_ptr<asset> new_asset + = std::make_shared<asset>(file_path.c_str()); + + asset_cache[file_path] = new_asset; + + return new_asset; +} + +} // namespace crepe::api diff --git a/src/crepe/api/AudioSource.cpp b/src/crepe/api/AudioSource.cpp index bb067dc..35b8d83 100644 --- a/src/crepe/api/AudioSource.cpp +++ b/src/crepe/api/AudioSource.cpp @@ -1,9 +1,9 @@ #include <memory> -#include "AudioSource.h" - #include "../Sound.h" +#include "AudioSource.h" + using namespace crepe::api; AudioSource::AudioSource(std::unique_ptr<Asset> audio_clip) { diff --git a/src/crepe/api/BehaviorScript.cpp b/src/crepe/api/BehaviorScript.cpp index 84bfd4c..e69de29 100644 --- a/src/crepe/api/BehaviorScript.cpp +++ b/src/crepe/api/BehaviorScript.cpp @@ -1,7 +0,0 @@ -#include "../util/log.h" - -#include "BehaviorScript.h" - -using namespace crepe::api; - -BehaviorScript::BehaviorScript() { dbg_trace(); } diff --git a/src/crepe/api/BehaviorScript.h b/src/crepe/api/BehaviorScript.h index 25d3cc5..6133cc8 100644 --- a/src/crepe/api/BehaviorScript.h +++ b/src/crepe/api/BehaviorScript.h @@ -3,7 +3,6 @@ #include <memory> #include "../Component.h" -#include "Script.h" namespace crepe { class ScriptSystem; @@ -17,7 +16,7 @@ class Script; class BehaviorScript : public Component { protected: friend class crepe::ComponentManager; - BehaviorScript(); + using Component::Component; public: virtual ~BehaviorScript() = default; diff --git a/src/crepe/api/BehaviorScript.hpp b/src/crepe/api/BehaviorScript.hpp index a6bd81c..2a3502f 100644 --- a/src/crepe/api/BehaviorScript.hpp +++ b/src/crepe/api/BehaviorScript.hpp @@ -3,7 +3,9 @@ #include <type_traits> #include "../util/log.h" + #include "BehaviorScript.h" +#include "Script.h" namespace crepe::api { @@ -12,6 +14,7 @@ BehaviorScript & BehaviorScript::set_script() { static_assert(std::is_base_of<Script, T>::value); dbg_trace(); Script * s = new T(); + s->parent = this; this->script = std::unique_ptr<Script>(s); return *this; } diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt index ae92f3d..0bb1263 100644 --- a/src/crepe/api/CMakeLists.txt +++ b/src/crepe/api/CMakeLists.txt @@ -3,19 +3,29 @@ target_sources(crepe PUBLIC BehaviorScript.cpp Script.cpp GameObject.cpp - Collider.cpp Rigidbody.cpp + Force.cpp + ParticleEmitter.cpp + Transform.cpp + Color.cpp + Texture.cpp + AssetManager.cpp Sprite.cpp ) target_sources(crepe PUBLIC FILE_SET HEADERS FILES # AudioSource.h BehaviorScript.h + Config.h Script.h + Script.hpp GameObject.h GameObject.hpp - Collider.h Rigidbody.h Sprite.h + Point.h + Color.h + Texture.h + AssetManager.h + AssetManager.hpp ) - diff --git a/src/crepe/api/CircleCollider.h b/src/crepe/api/CircleCollider.h new file mode 100644 index 0000000..762574b --- /dev/null +++ b/src/crepe/api/CircleCollider.h @@ -0,0 +1,13 @@ +#pragma once +#include "../Collider.h" + +namespace crepe::api { + +class CircleCollider : public Collider { +public: + CircleCollider(uint32_t game_object_id, int radius) + : Collider(game_object_id), radius(radius) {} + int radius; +}; + +} // namespace crepe::api diff --git a/src/crepe/api/Collider.cpp b/src/crepe/api/Collider.cpp deleted file mode 100644 index 6370a42..0000000 --- a/src/crepe/api/Collider.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Collider.h" - -using namespace crepe::api; - -Collider::Collider(int size) : size(size) {} diff --git a/src/crepe/api/Collider.h b/src/crepe/api/Collider.h deleted file mode 100644 index 72d8e77..0000000 --- a/src/crepe/api/Collider.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "../Component.h" - -namespace crepe::api { - -class Collider : public Component { -public: - Collider(int size); - - int size; -}; - -} // namespace crepe::api diff --git a/src/crepe/api/Color.cpp b/src/crepe/api/Color.cpp new file mode 100644 index 0000000..fb5bd1a --- /dev/null +++ b/src/crepe/api/Color.cpp @@ -0,0 +1,34 @@ +#include "Color.h" + +using namespace crepe::api; + +Color Color::white = Color(255, 255, 255, 0); +Color Color::red = Color(255, 0, 0, 0); +Color Color::green = Color(0, 255, 0, 0); +Color Color::blue = Color(0, 0, 255, 0); +Color Color::black = Color(0, 0, 0, 0); +Color Color::cyan = Color(0, 255, 255, 0); +Color Color::yellow = Color(255, 255, 0, 0); +Color Color::magenta = Color(255, 0, 255, 0); + +// FIXME: do we really need double precision for color values? +Color::Color(double red, double green, double blue, double alpha) { + this->a = alpha; + this->r = red; + this->g = green; + this->b = blue; +}; + +const Color & Color::get_white() { return Color::white; }; + +const Color & Color::get_red() { return Color::red; }; +const Color & Color::get_green() { return Color::green; }; +const Color & Color::get_blue() { return Color::blue; }; + +const Color & Color::get_black() { return Color::black; }; + +const Color & Color::get_cyan() { return Color::cyan; }; + +const Color & Color::get_yellow() { return Color::yellow; }; + +const Color & Color::get_magenta() { return Color::magenta; }; diff --git a/src/crepe/api/Color.h b/src/crepe/api/Color.h new file mode 100644 index 0000000..e818de4 --- /dev/null +++ b/src/crepe/api/Color.h @@ -0,0 +1,37 @@ +#pragma once + +namespace crepe::api { + +class Color { + + // FIXME: can't these colors be defined as a `static constexpr const Color` + // instead? + +public: + Color(double red, double green, double blue, double alpha); + static const Color & get_white(); + static const Color & get_red(); + static const Color & get_green(); + static const Color & get_blue(); + static const Color & get_cyan(); + static const Color & get_magenta(); + static const Color & get_yellow(); + static const Color & get_black(); + +private: + double r; + double g; + double b; + double a; + + static Color white; + static Color red; + static Color green; + static Color blue; + static Color cyan; + static Color magenta; + static Color yellow; + static Color black; +}; + +} // namespace crepe::api diff --git a/src/crepe/api/Config.h b/src/crepe/api/Config.h new file mode 100644 index 0000000..8a7f268 --- /dev/null +++ b/src/crepe/api/Config.h @@ -0,0 +1,40 @@ +#pragma once + +#include "../util/log.h" + +namespace crepe::api { + +class Config { +private: + Config() = default; + +public: + ~Config() = default; + +public: + //! Retrieve handle to global Config instance + static Config & get_instance() { + static Config instance; + return instance; + } + +public: + //! Logging-related settings + struct { + /** + * \brief Log level + * + * Only messages with equal or higher priority than this value will be + * logged. + */ + util::LogLevel level = util::LogLevel::INFO; + /** + * \brief Colored log output + * + * Enables log coloring using ANSI escape codes. + */ + bool color = true; + } log; +}; + +} // namespace crepe::api diff --git a/src/crepe/api/Force.cpp b/src/crepe/api/Force.cpp new file mode 100644 index 0000000..e359adc --- /dev/null +++ b/src/crepe/api/Force.cpp @@ -0,0 +1,21 @@ +#include <cmath> + +#include "Force.h" + +namespace crepe::api { + +Force::Force(uint32_t game_object_id, uint32_t magnitude, uint32_t direction) + : Component(game_object_id) { + // TODO: A standard angle unit should be established for the entire engine + // and assumed to be the default everywhere. Only conversion functions should + // explicitly contain the unit (i.e. `deg_to_rad()` & `rad_to_deg()`) + + // Convert direction from degrees to radians + float radian_direction = static_cast<float>(direction) * (M_PI / 180.0f); + force_x = static_cast<int32_t>( + std::round(magnitude * std::cos(radian_direction))); + force_y = static_cast<int32_t>( + std::round(magnitude * std::sin(radian_direction))); +} + +} // namespace crepe::api diff --git a/src/crepe/api/Force.h b/src/crepe/api/Force.h new file mode 100644 index 0000000..8da9a00 --- /dev/null +++ b/src/crepe/api/Force.h @@ -0,0 +1,17 @@ +#pragma once + +#include <cstdint> + +#include "../Component.h" + +namespace crepe::api { + +class Force : public Component { +public: + Force(uint32_t game_object_id, uint32_t magnitude, uint32_t direction); + + int32_t force_x; + int32_t force_y; +}; + +} // namespace crepe::api diff --git a/src/crepe/api/GameObject.hpp b/src/crepe/api/GameObject.hpp index 8295ea3..3c7e867 100644 --- a/src/crepe/api/GameObject.hpp +++ b/src/crepe/api/GameObject.hpp @@ -9,7 +9,7 @@ namespace crepe::api { template <typename T, typename... Args> T & GameObject::add_component(Args &&... args) { auto & mgr = ComponentManager::get_instance(); - return mgr.add_component<T>(id, std::forward<Args>(args)...); + return mgr.add_component<T>(this->id, std::forward<Args>(args)...); } } // namespace crepe::api diff --git a/src/crepe/api/ParticleEmitter.cpp b/src/crepe/api/ParticleEmitter.cpp new file mode 100644 index 0000000..0b3a9ee --- /dev/null +++ b/src/crepe/api/ParticleEmitter.cpp @@ -0,0 +1,37 @@ +#include <ctime> +#include <iostream> + +#include "Particle.h" +#include "ParticleEmitter.h" + +using namespace crepe; + +ParticleEmitter::ParticleEmitter(uint32_t game_object_id, + uint32_t max_particles, uint32_t emission_rate, + uint32_t speed, uint32_t speed_offset, + uint32_t angle, uint32_t angleOffset, + float begin_lifespan, float end_lifespan) + : Component(game_object_id), max_particles(max_particles), + emission_rate(emission_rate), speed(speed), speed_offset(speed_offset), + position{0, 0}, begin_lifespan(begin_lifespan), + end_lifespan(end_lifespan) { + std::srand( + static_cast<uint32_t>(std::time(nullptr))); // initialize random seed + std::cout << "Create emitter" << std::endl; + // FIXME: Why do these expressions start with `360 +`, only to be `% 360`'d + // right after? This does not make any sense to me. + min_angle = (360 + angle - (angleOffset % 360)) % 360; + max_angle = (360 + angle + (angleOffset % 360)) % 360; + position.x = 400; // FIXME: what are these magic values? + position.y = 400; + for (size_t i = 0; i < max_particles; i++) { + this->particles.emplace_back(); + } +} + +ParticleEmitter::~ParticleEmitter() { + std::vector<Particle>::iterator it = this->particles.begin(); + while (it != this->particles.end()) { + it = this->particles.erase(it); + } +} diff --git a/src/crepe/api/ParticleEmitter.h b/src/crepe/api/ParticleEmitter.h new file mode 100644 index 0000000..2e2e95b --- /dev/null +++ b/src/crepe/api/ParticleEmitter.h @@ -0,0 +1,42 @@ +#pragma once + +#include <cstdint> +#include <vector> + +#include "Component.h" +#include "Particle.h" + +namespace crepe { + +class ParticleEmitter : public Component { +public: + ParticleEmitter(uint32_t game_object_id, uint32_t max_particles, + uint32_t emission_rate, uint32_t speed, + uint32_t speed_offset, uint32_t angle, uint32_t angleOffset, + float begin_lifespan, float end_lifespan); + ~ParticleEmitter(); + + //! position of the emitter + Position position; + //! maximum number of particles + uint32_t max_particles; + //! rate of particle emission + uint32_t emission_rate; + //! base speed of the particles + uint32_t speed; + //! offset for random speed variation + uint32_t speed_offset; + //! min angle of particle emission + uint32_t min_angle; + //! max angle of particle emission + uint32_t max_angle; + //! begin Lifespan of particle (only visual) + float begin_lifespan; + //! begin Lifespan of particle + float end_lifespan; + + //! collection of particles + std::vector<Particle> particles; +}; + +} // namespace crepe diff --git a/src/crepe/api/Point.h b/src/crepe/api/Point.h new file mode 100644 index 0000000..b47b7e6 --- /dev/null +++ b/src/crepe/api/Point.h @@ -0,0 +1,11 @@ +#pragma once + +namespace crepe::api { + +class Point { +public: + double x; + double y; +}; + +} // namespace crepe::api diff --git a/src/crepe/api/Rigidbody.cpp b/src/crepe/api/Rigidbody.cpp index 98d1d60..ebf9fb9 100644 --- a/src/crepe/api/Rigidbody.cpp +++ b/src/crepe/api/Rigidbody.cpp @@ -2,5 +2,7 @@ using namespace crepe::api; -Rigidbody::Rigidbody(int mass, int gravityScale, int bodyType) - : mass(mass), gravity_scale(gravityScale), body_type(bodyType) {} +Rigidbody::Rigidbody(uint32_t game_object_id, int mass, int gravity_scale, + BodyType bodyType) + : Component(game_object_id), mass(mass), gravity_scale(gravity_scale), + body_type(bodyType) {} diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h index 6cae579..6079a76 100644 --- a/src/crepe/api/Rigidbody.h +++ b/src/crepe/api/Rigidbody.h @@ -1,16 +1,30 @@ #pragma once +#include <cstdint> + #include "../Component.h" namespace crepe::api { +// FIXME: can't this enum be defined inside the class declaration of Rigidbody? +enum class BodyType { + //! Does not move (e.g. walls, ground ...) + STATIC, + //! Moves and responds to forces (e.g. player, physics objects ...) + DYNAMIC, + //! Moves but does not respond to forces (e.g. moving platforms ...) + KINEMATIC, +}; + class Rigidbody : public Component { public: - Rigidbody(int mass, int gravityScale, int bodyType); - + Rigidbody(uint32_t game_object_id, int mass, int gravity_scale, + BodyType body_type); + int32_t velocity_x; + int32_t velocity_y; int mass; int gravity_scale; - int body_type; + BodyType body_type; }; } // namespace crepe::api diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h index 0036d1f..59e6ec0 100644 --- a/src/crepe/api/Script.h +++ b/src/crepe/api/Script.h @@ -1,11 +1,15 @@ #pragma once +#include <vector> + namespace crepe { class ScriptSystem; } namespace crepe::api { +class BehaviorScript; + class Script { friend class crepe::ScriptSystem; @@ -16,6 +20,19 @@ protected: // implemented as member methods in derivative user script classes and // registered in init(), otherwise this class will balloon in size with each // added event. + +protected: + template <typename T> + T & get_component(); + + template <typename T> + std::vector<std::reference_wrapper<T>> get_components(); + +private: + friend class crepe::api::BehaviorScript; + BehaviorScript * parent = nullptr; }; } // namespace crepe::api + +#include "Script.hpp" diff --git a/src/crepe/api/Script.hpp b/src/crepe/api/Script.hpp new file mode 100644 index 0000000..8004fe3 --- /dev/null +++ b/src/crepe/api/Script.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include "../ComponentManager.h" + +#include "BehaviorScript.h" +#include "Script.h" + +namespace crepe::api { + +template <typename T> +T & Script::get_component() { + std::vector<std::reference_wrapper<T>> all_components + = this->get_components<T>(); + if (all_components.size() < 1) throw nullptr; // TODO + + return all_components.back().get(); +} + +template <typename T> +std::vector<std::reference_wrapper<T>> Script::get_components() { + ComponentManager & mgr = ComponentManager::get_instance(); + return mgr.get_components_by_id<T>(this->parent->game_object_id); +} + +} // namespace crepe::api diff --git a/src/crepe/api/Sprite.cpp b/src/crepe/api/Sprite.cpp index aa7dbb0..806f147 100644 --- a/src/crepe/api/Sprite.cpp +++ b/src/crepe/api/Sprite.cpp @@ -1,8 +1,20 @@ -#include <string> +#include <cstdint> +#include <memory> +#include "api/Texture.h" +#include "util/log.h" + +#include "Component.h" #include "Sprite.h" -using namespace crepe::api; using namespace std; +using namespace crepe; +using namespace crepe::api; + +Sprite::Sprite(uint32_t id, shared_ptr<Texture> image, const Color & color, + const FlipSettings & flip) + : Component(id), color(color), flip(flip), sprite_image(image) { + dbg_trace(); +} -Sprite::Sprite(string path) : path(path) {} +Sprite::~Sprite() { dbg_trace(); } diff --git a/src/crepe/api/Sprite.h b/src/crepe/api/Sprite.h index 580f825..b06125e 100644 --- a/src/crepe/api/Sprite.h +++ b/src/crepe/api/Sprite.h @@ -1,16 +1,32 @@ #pragma once -#include <string> +#include <SDL2/SDL_rect.h> +#include <cstdint> +#include <memory> -#include "../Component.h" +#include "api/Color.h" +#include "api/Texture.h" + +#include "Component.h" namespace crepe::api { +struct FlipSettings { + bool flip_x = 1; + bool flip_y = 1; +}; + class Sprite : public Component { -public: - Sprite(std::string path); - std::string path; +public: + Sprite(uint32_t game_id, std::shared_ptr<Texture> image, + const Color & color, const FlipSettings & flip); + ~Sprite(); + std::shared_ptr<Texture> sprite_image; + Color color; + FlipSettings flip; + uint8_t sorting_in_layer; + uint8_t order_in_layer; }; } // namespace crepe::api diff --git a/src/crepe/api/Texture.cpp b/src/crepe/api/Texture.cpp new file mode 100644 index 0000000..481ef7c --- /dev/null +++ b/src/crepe/api/Texture.cpp @@ -0,0 +1,32 @@ +#include <SDL2/SDL_render.h> + +#include "util/log.h" + +#include "Asset.h" +#include "SDLContext.h" +#include "Texture.h" + +using namespace crepe::api; +using namespace std; + +Texture::Texture(unique_ptr<Asset> res) { + dbg_trace(); + this->load(std::move(res)); +} + +Texture::Texture(const char * src) { + dbg_trace(); + this->load(make_unique<Asset>(src)); +} + +Texture::~Texture() { + dbg_trace(); + if (this->texture != nullptr) { + SDL_DestroyTexture(this->texture); + } +} + +void Texture::load(unique_ptr<Asset> res) { + SDLContext & ctx = SDLContext::get_instance(); + this->texture = ctx.texture_from_path(res->canonical()); +} diff --git a/src/crepe/api/Texture.h b/src/crepe/api/Texture.h new file mode 100644 index 0000000..f8481e3 --- /dev/null +++ b/src/crepe/api/Texture.h @@ -0,0 +1,33 @@ +#pragma once + +// FIXME: this header can't be included because this is an API header, and SDL2 +// development headers won't be bundled with crepe. Why is this facade in the +// API namespace? +#include <SDL2/SDL_render.h> +#include <memory> + +#include "Asset.h" + +namespace crepe { +class SDLContext; +} + +namespace crepe::api { + +class Texture { + +public: + Texture(const char * src); + Texture(std::unique_ptr<Asset> res); + ~Texture(); + +private: + void load(std::unique_ptr<Asset> res); + +private: + SDL_Texture * texture = nullptr; + + friend class crepe::SDLContext; +}; + +} // namespace crepe::api diff --git a/src/crepe/api/Transform.cpp b/src/crepe/api/Transform.cpp new file mode 100644 index 0000000..626cd67 --- /dev/null +++ b/src/crepe/api/Transform.cpp @@ -0,0 +1,15 @@ +#include <cstdint> + +#include "api/Point.h" +#include "util/log.h" + +#include "Component.h" +#include "Transform.h" + +using namespace crepe::api; + +Transform::Transform(uint32_t game_id, Point & point, double rot, double scale) + : Component(game_id), position(point), rotation(rot), scale(scale) { + dbg_trace(); +} +Transform::~Transform() { dbg_trace(); } diff --git a/src/crepe/api/Transform.h b/src/crepe/api/Transform.h new file mode 100644 index 0000000..c69ec61 --- /dev/null +++ b/src/crepe/api/Transform.h @@ -0,0 +1,27 @@ +#pragma once + +#include <cstdint> + +#include "api/Point.h" + +#include "Component.h" + +namespace crepe::api { + +class Transform : public Component { + // FIXME: What's the difference between the `Point` and `Position` + // classes/structs? How about we replace both with a universal `Vec2` that + // works similar (or the same) as those found in GLSL? + +public: + Transform(uint32_t id, Point &, double, double); + ~Transform(); + //! Translation (shift) + Point position; + //! Rotation, in radians + double rotation; + //! Multiplication factor + double scale; +}; + +} // namespace crepe::api |