diff options
| author | Loek Le Blansch <loek@pipeframe.xyz> | 2024-10-24 10:52:21 +0200 | 
|---|---|---|
| committer | Loek Le Blansch <loek@pipeframe.xyz> | 2024-10-24 10:52:21 +0200 | 
| commit | 39054829fa69bcfa2b468015dc3852a2f8deac9f (patch) | |
| tree | e7726d90fb3c23a15919360dd10bdf709e7e087a /src/crepe/api | |
| parent | dd9940720cde6975f79d65e08075687c47f0aec6 (diff) | |
| parent | 5447ddd896eb49ea9fd9f9191a277fd1d5730aa3 (diff) | |
merge master into loek/config
Diffstat (limited to 'src/crepe/api')
29 files changed, 555 insertions, 16 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..a53ace5 --- /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..083fd9d --- /dev/null +++ b/src/crepe/api/AssetManager.hpp @@ -0,0 +1,23 @@ +#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 b512d27..35b8d83 100644 --- a/src/crepe/api/AudioSource.cpp +++ b/src/crepe/api/AudioSource.cpp @@ -1,7 +1,8 @@ -#include "AudioSource.h" +#include <memory>  #include "../Sound.h" -#include <memory> + +#include "AudioSource.h"  using namespace crepe::api; diff --git a/src/crepe/api/AudioSource.h b/src/crepe/api/AudioSource.h index 2d26cda..7980212 100644 --- a/src/crepe/api/AudioSource.h +++ b/src/crepe/api/AudioSource.h @@ -2,8 +2,8 @@  #include <memory> -#include "Asset.h" -#include "Component.h" +#include "../Asset.h" +#include "../Component.h"  namespace crepe {  class Sound; diff --git a/src/crepe/api/BehaviorScript.cpp b/src/crepe/api/BehaviorScript.cpp index 1f236b4..e69de29 100644 --- a/src/crepe/api/BehaviorScript.cpp +++ b/src/crepe/api/BehaviorScript.cpp @@ -1,8 +0,0 @@ -#include "../util/log.h" - -#include "BehaviorScript.h" -#include "Script.h" - -using namespace crepe::api; - -BehaviorScript::BehaviorScript() { dbg_trace(); } diff --git a/src/crepe/api/BehaviorScript.h b/src/crepe/api/BehaviorScript.h index 6ce6798..cb37a78 100644 --- a/src/crepe/api/BehaviorScript.h +++ b/src/crepe/api/BehaviorScript.h @@ -2,7 +2,7 @@  #include <memory> -#include "Component.h" +#include "../Component.h"  #include "Script.h"  namespace crepe { @@ -17,7 +17,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..6fdf605 100644 --- a/src/crepe/api/BehaviorScript.hpp +++ b/src/crepe/api/BehaviorScript.hpp @@ -3,6 +3,7 @@  #include <type_traits>  #include "../util/log.h" +  #include "BehaviorScript.h"  namespace crepe::api { diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt index 2181b30..f262019 100644 --- a/src/crepe/api/CMakeLists.txt +++ b/src/crepe/api/CMakeLists.txt @@ -2,6 +2,15 @@ target_sources(crepe PUBLIC  	# AudioSource.cpp  	BehaviorScript.cpp  	Script.cpp +	GameObject.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 @@ -9,5 +18,13 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES  	BehaviorScript.h  	Config.h  	Script.h +	GameObject.h +	GameObject.hpp +	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/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..36d91ef --- /dev/null +++ b/src/crepe/api/Color.h @@ -0,0 +1,36 @@ +#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 index f47f45b..24b5529 100644 --- a/src/crepe/api/Config.h +++ b/src/crepe/api/Config.h @@ -26,7 +26,7 @@ public:  		 * Only messages with equal or higher priority than this value will be  		 * logged.  		 */ -		util::log_level level = util::log_level::INFO; +		util::LogLevel level = util::LogLevel::INFO;  		/**  		 * \brief Colored log output  		 * 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.cpp b/src/crepe/api/GameObject.cpp new file mode 100644 index 0000000..b167187 --- /dev/null +++ b/src/crepe/api/GameObject.cpp @@ -0,0 +1,7 @@ +#include "GameObject.h" + +using namespace crepe::api; +using namespace std; + +GameObject::GameObject(uint32_t id, string name, string tag, int layer) +	: id(id), name(name), tag(tag), active(true), layer(layer) {} diff --git a/src/crepe/api/GameObject.h b/src/crepe/api/GameObject.h new file mode 100644 index 0000000..57508c5 --- /dev/null +++ b/src/crepe/api/GameObject.h @@ -0,0 +1,24 @@ +#pragma once + +#include <cstdint> +#include <string> + +namespace crepe::api { + +class GameObject { +public: +	GameObject(uint32_t id, std::string name, std::string tag, int layer); + +	template <typename T, typename... Args> +	T & add_component(Args &&... args); + +	uint32_t id; +	std::string name; +	std::string tag; +	bool active; +	int layer; +}; + +} // namespace crepe::api + +#include "GameObject.hpp" diff --git a/src/crepe/api/GameObject.hpp b/src/crepe/api/GameObject.hpp new file mode 100644 index 0000000..3c7e867 --- /dev/null +++ b/src/crepe/api/GameObject.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "../ComponentManager.h" + +#include "GameObject.h" + +namespace crepe::api { + +template <typename T, typename... Args> +T & GameObject::add_component(Args &&... args) { +	auto & mgr = ComponentManager::get_instance(); +	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 new file mode 100644 index 0000000..ebf9fb9 --- /dev/null +++ b/src/crepe/api/Rigidbody.cpp @@ -0,0 +1,8 @@ +#include "Rigidbody.h" + +using namespace crepe::api; + +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 new file mode 100644 index 0000000..6079a76 --- /dev/null +++ b/src/crepe/api/Rigidbody.h @@ -0,0 +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(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; +	BodyType body_type; +}; + +} // namespace crepe::api diff --git a/src/crepe/api/Sprite.cpp b/src/crepe/api/Sprite.cpp new file mode 100644 index 0000000..806f147 --- /dev/null +++ b/src/crepe/api/Sprite.cpp @@ -0,0 +1,20 @@ +#include <cstdint> +#include <memory> + +#include "api/Texture.h" +#include "util/log.h" + +#include "Component.h" +#include "Sprite.h" + +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() { dbg_trace(); } diff --git a/src/crepe/api/Sprite.h b/src/crepe/api/Sprite.h new file mode 100644 index 0000000..b06125e --- /dev/null +++ b/src/crepe/api/Sprite.h @@ -0,0 +1,32 @@ +#pragma once + +#include <SDL2/SDL_rect.h> +#include <cstdint> +#include <memory> + +#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(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..c17ae34 --- /dev/null +++ b/src/crepe/api/Transform.h @@ -0,0 +1,26 @@ +#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 |