From 95171100beba7bc36ae4421652f6c4fbb34774a8 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Wed, 23 Oct 2024 22:26:05 +0200 Subject: rename SdlContext -> SDLContext --- src/crepe/SDLContext.cpp | 150 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 src/crepe/SDLContext.cpp (limited to 'src/crepe/SDLContext.cpp') diff --git a/src/crepe/SDLContext.cpp b/src/crepe/SDLContext.cpp new file mode 100644 index 0000000..5a93679 --- /dev/null +++ b/src/crepe/SDLContext.cpp @@ -0,0 +1,150 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "api/Sprite.h" +#include "api/Texture.h" +#include "api/Transform.h" +#include "util/log.h" + +#include "SDLContext.h" + +using namespace crepe; + +SDLContext & SDLContext::get_instance() { + static SDLContext instance; + return instance; +} + +void SDLContext::handle_events(bool & running) { + SDL_Event event; + while (SDL_PollEvent(&event)) { + if (event.type == SDL_QUIT) { + running = false; + } + } +} + +SDLContext::~SDLContext() { + dbg_trace(); + + if (this->game_renderer != nullptr) + SDL_DestroyRenderer(this->game_renderer); + + if (this->game_window != nullptr) { + SDL_DestroyWindow(this->game_window); + } + + IMG_Quit(); + SDL_Quit(); +} + +void SDLContext::clear_screen() { SDL_RenderClear(this->game_renderer); } + +SDLContext::SDLContext() { + dbg_trace(); + + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() + << std::endl; + return; + } + + this->game_window = SDL_CreateWindow( + "Crepe Game Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + 1920, 1080, SDL_WINDOW_SHOWN); + if (!this->game_window) { + std::cerr << "Window could not be created! SDL_Error: " + << SDL_GetError() << std::endl; + } + + this->game_renderer + = SDL_CreateRenderer(this->game_window, -1, SDL_RENDERER_ACCELERATED); + if (!this->game_renderer) { + std::cerr << "Renderer could not be created! SDL_Error: " + << SDL_GetError() << std::endl; + SDL_DestroyWindow(this->game_window); + return; + } + + int img_flags = IMG_INIT_PNG; + if (!(IMG_Init(img_flags) & img_flags)) { + std::cout << "SDL_image could not initialize! SDL_image Error: " + << IMG_GetError() << std::endl; + } +} + +void SDLContext::present_screen() { SDL_RenderPresent(this->game_renderer); } + +void SDLContext::draw(const api::Sprite & sprite, + const api::Transform & transform) { + + static SDL_RendererFlip render_flip + = (SDL_RendererFlip) ((SDL_FLIP_HORIZONTAL * sprite.flip.flip_x) + | (SDL_FLIP_VERTICAL * sprite.flip.flip_y)); + + int w, h; + SDL_QueryTexture(sprite.sprite_image->texture, NULL, NULL, &w, &h); + // needs maybe camera for position + SDL_Rect dstrect = { + .x = static_cast(transform.position.x), + .y = static_cast(transform.position.y), + .w = static_cast(w * transform.scale), + .h = static_cast(h * transform.scale), + }; + + double degrees = transform.rotation * 180 / M_PI; + SDL_RenderCopyEx(this->game_renderer, sprite.sprite_image->texture, NULL, + &dstrect, degrees, NULL, render_flip); +} + +/* +SDL_Texture * SDLContext::setTextureFromPath(const char * path, SDL_Rect & clip, + const int row, const int col) { + dbg_trace(); + + SDL_Surface * tmp = IMG_Load(path); + if (!tmp) { + std::cerr << "Error surface " << IMG_GetError << std::endl; + } + + clip. + w = tmp->w / col; + clip.h = tmp->h / row; + + SDL_Texture * CreatedTexture + = SDL_CreateTextureFromSurface(this->game_renderer, tmp); + + if (!CreatedTexture) { + std::cerr << "Error could not create texture " << IMG_GetError + << std::endl; + } + SDL_FreeSurface(tmp); + + return CreatedTexture; +} +*/ + +SDL_Texture * SDLContext::texture_from_path(const char * path) { + dbg_trace(); + + SDL_Surface * tmp = IMG_Load(path); + if (!tmp) { + std::cerr << "Error surface " << IMG_GetError << std::endl; + } + SDL_Texture * created_texture + = SDL_CreateTextureFromSurface(this->game_renderer, tmp); + + if (!created_texture) { + std::cerr << "Error could not create texture " << IMG_GetError + << std::endl; + } + SDL_FreeSurface(tmp); + + return created_texture; +} -- cgit v1.2.3 From 5447ddd896eb49ea9fd9f9191a277fd1d5730aa3 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Thu, 24 Oct 2024 10:46:32 +0200 Subject: add PR #9 comments as code comments --- src/crepe/Asset.cpp | 3 ++- src/crepe/Particle.h | 2 ++ src/crepe/SDLApp.cpp | 4 ++++ src/crepe/SDLContext.cpp | 8 ++++++++ src/crepe/api/Color.cpp | 1 + src/crepe/api/Color.h | 2 ++ src/crepe/api/Force.cpp | 4 ++++ src/crepe/api/ParticleEmitter.cpp | 8 +++++--- src/crepe/api/Rigidbody.h | 1 + src/crepe/api/Texture.h | 3 +++ src/crepe/api/Transform.h | 13 +++++++++---- src/example/asset_manager.cpp | 8 +++++++- src/example/particle.cpp | 1 + 13 files changed, 49 insertions(+), 9 deletions(-) (limited to 'src/crepe/SDLContext.cpp') diff --git a/src/crepe/Asset.cpp b/src/crepe/Asset.cpp index 3cbed0b..8a2a11c 100644 --- a/src/crepe/Asset.cpp +++ b/src/crepe/Asset.cpp @@ -5,7 +5,8 @@ using namespace crepe; Asset::Asset(const std::string & src) { - //this->src = std::filesystem::canonical(src); + // FIXME: restore this + // this->src = std::filesystem::canonical(src); this->src = src; this->file = std::ifstream(this->src, std::ios::in | std::ios::binary); } diff --git a/src/crepe/Particle.h b/src/crepe/Particle.h index 6f689bd..21e691d 100644 --- a/src/crepe/Particle.h +++ b/src/crepe/Particle.h @@ -7,6 +7,8 @@ namespace crepe { class Particle { public: Position position; + // FIXME: `Position` is an awkward name for a 2D vector. See FIXME comment in + // api/Transform.h for fix proposal. Position velocity; float lifespan; bool active; diff --git a/src/crepe/SDLApp.cpp b/src/crepe/SDLApp.cpp index f408595..c6ddeaa 100644 --- a/src/crepe/SDLApp.cpp +++ b/src/crepe/SDLApp.cpp @@ -6,10 +6,12 @@ SDLApp::SDLApp(int window_width, int window_height) : window_width(window_width), window_height(window_height), window(nullptr), renderer(nullptr) {} +// FIXME: why is there clean_up and ~SDLApp? SDLApp::~SDLApp() { clean_up(); } bool SDLApp::initialize() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { + // FIXME: throw exception std::cerr << "SDL Initialization Error: " << SDL_GetError() << std::endl; return false; @@ -19,12 +21,14 @@ bool SDLApp::initialize() { SDL_WINDOWPOS_CENTERED, window_width, window_height, SDL_WINDOW_SHOWN); if (!window) { + // FIXME: throw exception std::cerr << "Window Creation Error: " << SDL_GetError() << std::endl; return false; } renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); if (!renderer) { + // FIXME: throw exception std::cerr << "Renderer Creation Error: " << SDL_GetError() << std::endl; return false; } diff --git a/src/crepe/SDLContext.cpp b/src/crepe/SDLContext.cpp index 5a93679..8bc5bc6 100644 --- a/src/crepe/SDLContext.cpp +++ b/src/crepe/SDLContext.cpp @@ -40,6 +40,9 @@ SDLContext::~SDLContext() { SDL_DestroyWindow(this->game_window); } + // TODO: how are we going to ensure that these are called from the same + // thread that SDL_Init() was called on? This has caused problems for me + // before. IMG_Quit(); SDL_Quit(); } @@ -48,8 +51,10 @@ void SDLContext::clear_screen() { SDL_RenderClear(this->game_renderer); } SDLContext::SDLContext() { dbg_trace(); + // FIXME: read window defaults from config manager if (SDL_Init(SDL_INIT_VIDEO) < 0) { + // FIXME: throw exception std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl; return; @@ -59,6 +64,7 @@ SDLContext::SDLContext() { "Crepe Game Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1920, 1080, SDL_WINDOW_SHOWN); if (!this->game_window) { + // FIXME: throw exception std::cerr << "Window could not be created! SDL_Error: " << SDL_GetError() << std::endl; } @@ -66,6 +72,7 @@ SDLContext::SDLContext() { this->game_renderer = SDL_CreateRenderer(this->game_window, -1, SDL_RENDERER_ACCELERATED); if (!this->game_renderer) { + // FIXME: throw exception std::cerr << "Renderer could not be created! SDL_Error: " << SDL_GetError() << std::endl; SDL_DestroyWindow(this->game_window); @@ -74,6 +81,7 @@ SDLContext::SDLContext() { int img_flags = IMG_INIT_PNG; if (!(IMG_Init(img_flags) & img_flags)) { + // FIXME: throw exception std::cout << "SDL_image could not initialize! SDL_image Error: " << IMG_GetError() << std::endl; } diff --git a/src/crepe/api/Color.cpp b/src/crepe/api/Color.cpp index 71592da..fb5bd1a 100644 --- a/src/crepe/api/Color.cpp +++ b/src/crepe/api/Color.cpp @@ -11,6 +11,7 @@ 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; diff --git a/src/crepe/api/Color.h b/src/crepe/api/Color.h index 207434e..36d91ef 100644 --- a/src/crepe/api/Color.h +++ b/src/crepe/api/Color.h @@ -4,6 +4,8 @@ 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(); diff --git a/src/crepe/api/Force.cpp b/src/crepe/api/Force.cpp index 98649c1..e359adc 100644 --- a/src/crepe/api/Force.cpp +++ b/src/crepe/api/Force.cpp @@ -6,6 +6,10 @@ 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(direction) * (M_PI / 180.0f); force_x = static_cast( diff --git a/src/crepe/api/ParticleEmitter.cpp b/src/crepe/api/ParticleEmitter.cpp index 2e07562..0b3a9ee 100644 --- a/src/crepe/api/ParticleEmitter.cpp +++ b/src/crepe/api/ParticleEmitter.cpp @@ -18,9 +18,11 @@ ParticleEmitter::ParticleEmitter(uint32_t game_object_id, std::srand( static_cast(std::time(nullptr))); // initialize random seed std::cout << "Create emitter" << std::endl; - min_angle = (360 + angle - (angleOffset % 360)) % 360; // calculate minAngle - max_angle = (360 + angle + (angleOffset % 360)) % 360; // calculate maxAngle - position.x = 400; + // 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(); diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h index 05cbb03..6079a76 100644 --- a/src/crepe/api/Rigidbody.h +++ b/src/crepe/api/Rigidbody.h @@ -6,6 +6,7 @@ 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, diff --git a/src/crepe/api/Texture.h b/src/crepe/api/Texture.h index 7a2c755..f8481e3 100644 --- a/src/crepe/api/Texture.h +++ b/src/crepe/api/Texture.h @@ -1,5 +1,8 @@ #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 #include diff --git a/src/crepe/api/Transform.h b/src/crepe/api/Transform.h index 7b74e43..c17ae34 100644 --- a/src/crepe/api/Transform.h +++ b/src/crepe/api/Transform.h @@ -9,13 +9,18 @@ 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(); - Point position; // Translation (shift) - double rotation; // Rotation, in radians - double scale; // Multiplication factoh + //! Translation (shift) + Point position; + //! Rotation, in radians + double rotation; + //! Multiplication factor + double scale; }; } // namespace crepe::api diff --git a/src/example/asset_manager.cpp b/src/example/asset_manager.cpp index 7aa4ffe..7e15d1f 100644 --- a/src/example/asset_manager.cpp +++ b/src/example/asset_manager.cpp @@ -8,12 +8,18 @@ using namespace crepe; using namespace crepe::api; int main() { - // this needs to be called before the asset manager otherwise the destructor of sdl is not in the right order + // this needs to be called before the asset manager otherwise the destructor + // of sdl is not in the right order { Texture test("../asset/texture/img.png"); } + // FIXME: make it so the issue described by the above comment is not possible + // (i.e. the order in which internal classes are instantiated should not + // impact the way the engine works). auto & mgr = AssetManager::get_instance(); { + // TODO: [design] the Sound class can't be directly included by the user as + // it includes SoLoud headers. auto bgm = mgr.cache("../mwe/audio/bgm.ogg"); auto sfx1 = mgr.cache("../mwe/audio/sfx1.wav"); auto sfx2 = mgr.cache("../mwe/audio/sfx2.wav"); diff --git a/src/example/particle.cpp b/src/example/particle.cpp index 943f83b..53fa213 100644 --- a/src/example/particle.cpp +++ b/src/example/particle.cpp @@ -27,6 +27,7 @@ int main(int argc, char * argv[]) { GameObject * game_object[1]; game_object[0] = new GameObject(0, "Name", "Tag", 0); + // FIXME: all systems are singletons, so this shouldn't even compile. ParticleSystem particle_system; unsigned int max_particles = 100; // maximum number of particles -- cgit v1.2.3