aboutsummaryrefslogtreecommitdiff
path: root/src/crepe/facade
diff options
context:
space:
mode:
authorheavydemon21 <nielsstunnebrink1@gmail.com>2024-12-06 10:44:42 +0100
committerheavydemon21 <nielsstunnebrink1@gmail.com>2024-12-06 10:44:42 +0100
commitd5f63024ebed7df2fff8e016bd1c7c26f8fdfa27 (patch)
treeb26e35cb0482d04a33cc96d97ba21c21d0012229 /src/crepe/facade
parent9cde6875186b335c75eafa6402f0957cd4252c76 (diff)
parent1f4e961d7f9d6887c807cac1a362f2d178b0860b (diff)
Merge branch 'master' into decoupling
Diffstat (limited to 'src/crepe/facade')
-rw-r--r--src/crepe/facade/SDLContext.cpp240
-rw-r--r--src/crepe/facade/SDLContext.h100
2 files changed, 290 insertions, 50 deletions
diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp
index 86969ed..72b4e42 100644
--- a/src/crepe/facade/SDLContext.cpp
+++ b/src/crepe/facade/SDLContext.cpp
@@ -1,13 +1,17 @@
#include <SDL2/SDL.h>
+#include <SDL2/SDL_blendmode.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_keycode.h>
#include <SDL2/SDL_rect.h>
#include <SDL2/SDL_render.h>
#include <SDL2/SDL_surface.h>
#include <SDL2/SDL_video.h>
+#include <array>
#include <cmath>
#include <cstddef>
+#include <cstdint>
#include <functional>
+#include <iostream>
#include <memory>
#include <stdexcept>
@@ -15,9 +19,11 @@
#include "../api/Config.h"
#include "../api/Sprite.h"
#include "../api/Texture.h"
+#include "../manager/EventManager.h"
#include "../util/Log.h"
#include "SDLContext.h"
+#include "api/Color.h"
#include "types.h"
using namespace crepe;
@@ -72,25 +78,141 @@ SDLContext::~SDLContext() {
IMG_Quit();
SDL_Quit();
}
-void SDLContext::handle_events(bool & running) {
- //TODO: wouter i need events
- /*
- SDL_Event event;
- SDL_PollEvent(&event);
- switch (event.type) {
- case SDL_QUIT:
- running = false;
- break;
- case SDL_KEYDOWN:
- triggerEvent(KeyPressedEvent(getCustomKey(event.key.keysym.sym)));
- break;
- case SDL_MOUSEBUTTONDOWN:
- int x, y;
- SDL_GetMouseState(&x, &y);
- triggerEvent(MousePressedEvent(x, y));
- break;
+
+Keycode SDLContext::sdl_to_keycode(SDL_Keycode sdl_key) {
+ static const std::array<Keycode, SDL_NUM_SCANCODES> LOOKUP_TABLE = [] {
+ std::array<Keycode, SDL_NUM_SCANCODES> table{};
+ table.fill(Keycode::NONE);
+
+ table[SDL_SCANCODE_SPACE] = Keycode::SPACE;
+ table[SDL_SCANCODE_APOSTROPHE] = Keycode::APOSTROPHE;
+ table[SDL_SCANCODE_COMMA] = Keycode::COMMA;
+ table[SDL_SCANCODE_MINUS] = Keycode::MINUS;
+ table[SDL_SCANCODE_PERIOD] = Keycode::PERIOD;
+ table[SDL_SCANCODE_SLASH] = Keycode::SLASH;
+ table[SDL_SCANCODE_0] = Keycode::D0;
+ table[SDL_SCANCODE_1] = Keycode::D1;
+ table[SDL_SCANCODE_2] = Keycode::D2;
+ table[SDL_SCANCODE_3] = Keycode::D3;
+ table[SDL_SCANCODE_4] = Keycode::D4;
+ table[SDL_SCANCODE_5] = Keycode::D5;
+ table[SDL_SCANCODE_6] = Keycode::D6;
+ table[SDL_SCANCODE_7] = Keycode::D7;
+ table[SDL_SCANCODE_8] = Keycode::D8;
+ table[SDL_SCANCODE_9] = Keycode::D9;
+ table[SDL_SCANCODE_SEMICOLON] = Keycode::SEMICOLON;
+ table[SDL_SCANCODE_EQUALS] = Keycode::EQUAL;
+ table[SDL_SCANCODE_A] = Keycode::A;
+ table[SDL_SCANCODE_B] = Keycode::B;
+ table[SDL_SCANCODE_C] = Keycode::C;
+ table[SDL_SCANCODE_D] = Keycode::D;
+ table[SDL_SCANCODE_E] = Keycode::E;
+ table[SDL_SCANCODE_F] = Keycode::F;
+ table[SDL_SCANCODE_G] = Keycode::G;
+ table[SDL_SCANCODE_H] = Keycode::H;
+ table[SDL_SCANCODE_I] = Keycode::I;
+ table[SDL_SCANCODE_J] = Keycode::J;
+ table[SDL_SCANCODE_K] = Keycode::K;
+ table[SDL_SCANCODE_L] = Keycode::L;
+ table[SDL_SCANCODE_M] = Keycode::M;
+ table[SDL_SCANCODE_N] = Keycode::N;
+ table[SDL_SCANCODE_O] = Keycode::O;
+ table[SDL_SCANCODE_P] = Keycode::P;
+ table[SDL_SCANCODE_Q] = Keycode::Q;
+ table[SDL_SCANCODE_R] = Keycode::R;
+ table[SDL_SCANCODE_S] = Keycode::S;
+ table[SDL_SCANCODE_T] = Keycode::T;
+ table[SDL_SCANCODE_U] = Keycode::U;
+ table[SDL_SCANCODE_V] = Keycode::V;
+ table[SDL_SCANCODE_W] = Keycode::W;
+ table[SDL_SCANCODE_X] = Keycode::X;
+ table[SDL_SCANCODE_Y] = Keycode::Y;
+ table[SDL_SCANCODE_Z] = Keycode::Z;
+ table[SDL_SCANCODE_LEFTBRACKET] = Keycode::LEFT_BRACKET;
+ table[SDL_SCANCODE_BACKSLASH] = Keycode::BACKSLASH;
+ table[SDL_SCANCODE_RIGHTBRACKET] = Keycode::RIGHT_BRACKET;
+ table[SDL_SCANCODE_GRAVE] = Keycode::GRAVE_ACCENT;
+ table[SDL_SCANCODE_ESCAPE] = Keycode::ESCAPE;
+ table[SDL_SCANCODE_RETURN] = Keycode::ENTER;
+ table[SDL_SCANCODE_TAB] = Keycode::TAB;
+ table[SDL_SCANCODE_BACKSPACE] = Keycode::BACKSPACE;
+ table[SDL_SCANCODE_INSERT] = Keycode::INSERT;
+ table[SDL_SCANCODE_DELETE] = Keycode::DELETE;
+ table[SDL_SCANCODE_RIGHT] = Keycode::RIGHT;
+ table[SDL_SCANCODE_LEFT] = Keycode::LEFT;
+ table[SDL_SCANCODE_DOWN] = Keycode::DOWN;
+ table[SDL_SCANCODE_UP] = Keycode::UP;
+ table[SDL_SCANCODE_PAGEUP] = Keycode::PAGE_UP;
+ table[SDL_SCANCODE_PAGEDOWN] = Keycode::PAGE_DOWN;
+ table[SDL_SCANCODE_HOME] = Keycode::HOME;
+ table[SDL_SCANCODE_END] = Keycode::END;
+ table[SDL_SCANCODE_CAPSLOCK] = Keycode::CAPS_LOCK;
+ table[SDL_SCANCODE_SCROLLLOCK] = Keycode::SCROLL_LOCK;
+ table[SDL_SCANCODE_NUMLOCKCLEAR] = Keycode::NUM_LOCK;
+ table[SDL_SCANCODE_PRINTSCREEN] = Keycode::PRINT_SCREEN;
+ table[SDL_SCANCODE_PAUSE] = Keycode::PAUSE;
+ table[SDL_SCANCODE_F1] = Keycode::F1;
+ table[SDL_SCANCODE_F2] = Keycode::F2;
+ table[SDL_SCANCODE_F3] = Keycode::F3;
+ table[SDL_SCANCODE_F4] = Keycode::F4;
+ table[SDL_SCANCODE_F5] = Keycode::F5;
+ table[SDL_SCANCODE_F6] = Keycode::F6;
+ table[SDL_SCANCODE_F7] = Keycode::F7;
+ table[SDL_SCANCODE_F8] = Keycode::F8;
+ table[SDL_SCANCODE_F9] = Keycode::F9;
+ table[SDL_SCANCODE_F10] = Keycode::F10;
+ table[SDL_SCANCODE_F11] = Keycode::F11;
+ table[SDL_SCANCODE_F12] = Keycode::F12;
+ table[SDL_SCANCODE_KP_0] = Keycode::KP0;
+ table[SDL_SCANCODE_KP_1] = Keycode::KP1;
+ table[SDL_SCANCODE_KP_2] = Keycode::KP2;
+ table[SDL_SCANCODE_KP_3] = Keycode::KP3;
+ table[SDL_SCANCODE_KP_4] = Keycode::KP4;
+ table[SDL_SCANCODE_KP_5] = Keycode::KP5;
+ table[SDL_SCANCODE_KP_6] = Keycode::KP6;
+ table[SDL_SCANCODE_KP_7] = Keycode::KP7;
+ table[SDL_SCANCODE_KP_8] = Keycode::KP8;
+ table[SDL_SCANCODE_KP_9] = Keycode::KP9;
+ table[SDL_SCANCODE_LSHIFT] = Keycode::LEFT_SHIFT;
+ table[SDL_SCANCODE_LCTRL] = Keycode::LEFT_CONTROL;
+ table[SDL_SCANCODE_LALT] = Keycode::LEFT_ALT;
+ table[SDL_SCANCODE_LGUI] = Keycode::LEFT_SUPER;
+ table[SDL_SCANCODE_RSHIFT] = Keycode::RIGHT_SHIFT;
+ table[SDL_SCANCODE_RCTRL] = Keycode::RIGHT_CONTROL;
+ table[SDL_SCANCODE_RALT] = Keycode::RIGHT_ALT;
+ table[SDL_SCANCODE_RGUI] = Keycode::RIGHT_SUPER;
+ table[SDL_SCANCODE_MENU] = Keycode::MENU;
+
+ return table;
+ }();
+
+ if (sdl_key < 0 || sdl_key >= SDL_NUM_SCANCODES) {
+ return Keycode::NONE;
+ }
+
+ return LOOKUP_TABLE[sdl_key];
+}
+
+MouseButton SDLContext::sdl_to_mousebutton(Uint8 sdl_button) {
+ static const std::array<MouseButton, 5> MOUSE_BUTTON_LOOKUP_TABLE = [] {
+ std::array<MouseButton, 5> table{};
+ table.fill(MouseButton::NONE);
+
+ table[SDL_BUTTON_LEFT] = MouseButton::LEFT_MOUSE;
+ table[SDL_BUTTON_RIGHT] = MouseButton::RIGHT_MOUSE;
+ table[SDL_BUTTON_MIDDLE] = MouseButton::MIDDLE_MOUSE;
+ table[SDL_BUTTON_X1] = MouseButton::X1_MOUSE;
+ table[SDL_BUTTON_X2] = MouseButton::X2_MOUSE;
+
+ return table;
+ }();
+
+ if (sdl_button >= MOUSE_BUTTON_LOOKUP_TABLE.size()) {
+ // Return NONE for invalid or unmapped button
+ return MouseButton::NONE;
}
- */
+
+ return MOUSE_BUTTON_LOOKUP_TABLE[sdl_button];
}
void SDLContext::clear_screen() { SDL_RenderClear(this->game_renderer.get()); }
@@ -151,6 +273,7 @@ void SDLContext::draw(const RenderContext & ctx) {
double angle = ctx.angle + data.angle_offset;
+ this->set_color_texture(ctx.sprite.sprite_image, ctx.sprite.color);
SDL_RenderCopyExF(this->game_renderer.get(), ctx.sprite.texture.texture.get(), &srcrect,
&dstrect, angle, NULL, render_flip);
}
@@ -236,16 +359,79 @@ SDLContext::texture_from_path(const std::string & path) {
std::unique_ptr<SDL_Texture, std::function<void(SDL_Texture *)>> img_texture;
img_texture = {tmp_texture, [](SDL_Texture * texture) { SDL_DestroyTexture(texture); }};
+ SDL_SetTextureBlendMode(img_texture.get(), SDL_BLENDMODE_BLEND);
return img_texture;
}
-int SDLContext::get_width(const Texture & ctx) const {
- int w;
- SDL_QueryTexture(ctx.texture.get(), NULL, NULL, &w, NULL);
- return w;
-}
-int SDLContext::get_height(const Texture & ctx) const {
- int h;
- SDL_QueryTexture(ctx.texture.get(), NULL, NULL, NULL, &h);
- return h;
+
+ivec2 SDLContext::get_size(const Texture & ctx) {
+ ivec2 size;
+ SDL_QueryTexture(ctx.texture.get(), NULL, NULL, &size.x, &size.y);
+ return size;
}
+
void SDLContext::delay(int ms) const { SDL_Delay(ms); }
+
+std::vector<SDLContext::EventData> SDLContext::get_events() {
+ std::vector<SDLContext::EventData> event_list;
+ SDL_Event event;
+ while (SDL_PollEvent(&event)) {
+ switch (event.type) {
+ case SDL_QUIT:
+ event_list.push_back(EventData{
+ .event_type = SDLContext::EventType::SHUTDOWN,
+ });
+ break;
+ case SDL_KEYDOWN:
+ event_list.push_back(EventData{
+ .event_type = SDLContext::EventType::KEYDOWN,
+ .key = sdl_to_keycode(event.key.keysym.scancode),
+ .key_repeat = (event.key.repeat != 0),
+ });
+ break;
+ case SDL_KEYUP:
+ event_list.push_back(EventData{
+ .event_type = SDLContext::EventType::KEYUP,
+ .key = sdl_to_keycode(event.key.keysym.scancode),
+ });
+ break;
+ case SDL_MOUSEBUTTONDOWN:
+ event_list.push_back(EventData{
+ .event_type = SDLContext::EventType::MOUSEDOWN,
+ .mouse_button = sdl_to_mousebutton(event.button.button),
+ .mouse_position = {event.button.x, event.button.y},
+ });
+ break;
+ case SDL_MOUSEBUTTONUP: {
+ int x, y;
+ SDL_GetMouseState(&x, &y);
+ event_list.push_back(EventData{
+ .event_type = SDLContext::EventType::MOUSEUP,
+ .mouse_button = sdl_to_mousebutton(event.button.button),
+ .mouse_position = {event.button.x, event.button.y},
+ });
+ } break;
+
+ case SDL_MOUSEMOTION: {
+ event_list.push_back(
+ EventData{.event_type = SDLContext::EventType::MOUSEMOVE,
+ .mouse_position = {event.motion.x, event.motion.y},
+ .rel_mouse_move = {event.motion.xrel, event.motion.yrel}});
+ } break;
+
+ case SDL_MOUSEWHEEL: {
+ event_list.push_back(EventData{
+ .event_type = SDLContext::EventType::MOUSEWHEEL,
+ .mouse_position = {event.motion.x, event.motion.y},
+ // TODO: why is this needed?
+ .scroll_direction = event.wheel.y < 0 ? -1 : 1,
+ .scroll_delta = event.wheel.preciseY,
+ });
+ } break;
+ }
+ }
+ return event_list;
+}
+void SDLContext::set_color_texture(const Texture & texture, const Color & color) {
+ SDL_SetTextureColorMod(texture.texture.get(), color.r, color.g, color.b);
+ SDL_SetTextureAlphaMod(texture.texture.get(), color.a);
+}
diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h
index d662bee..dfdaa56 100644
--- a/src/crepe/facade/SDLContext.h
+++ b/src/crepe/facade/SDLContext.h
@@ -1,5 +1,6 @@
#pragma once
+#include <SDL2/SDL.h>
#include <SDL2/SDL_keycode.h>
#include <SDL2/SDL_rect.h>
#include <SDL2/SDL_render.h>
@@ -8,18 +9,21 @@
#include <functional>
#include <memory>
#include <string>
-
-#include "../api/Camera.h"
-#include "../api/Sprite.h"
-
+#include <utility>
+
+#include "api/Camera.h"
+#include "api/Color.h"
+#include "api/Event.h"
+#include "api/KeyCodes.h"
+#include "api/Sprite.h"
+#include "api/Texture.h"
+#include "api/Transform.h"
#include "types.h"
namespace crepe {
-// TODO: SDL_Keycode is defined in a header not distributed with crepe, which means this
-// typedef is unusable when crepe is packaged. Wouter will fix this later.
-typedef SDL_Keycode CREPE_KEYCODES;
-
+class LoopManager;
+class InputSystem;
/**
* \class SDLContext
* \brief Facade for the SDL library
@@ -46,6 +50,29 @@ public:
};
public:
+ //! EventType enum for passing eventType
+ enum EventType {
+ NONE = 0,
+ MOUSEDOWN,
+ MOUSEUP,
+ MOUSEMOVE,
+ MOUSEWHEEL,
+ KEYUP,
+ KEYDOWN,
+ SHUTDOWN,
+
+ };
+ //! EventData struct for passing event data from facade
+ struct EventData {
+ SDLContext::EventType event_type = SDLContext::EventType::NONE;
+ Keycode key = Keycode::NONE;
+ bool key_repeat = false;
+ MouseButton mouse_button = MouseButton::NONE;
+ ivec2 mouse_position = {-1, -1};
+ int scroll_direction = -1;
+ float scroll_delta = INFINITY;
+ ivec2 rel_mouse_move = {-1, -1};
+ };
/**
* \brief Gets the singleton instance of SDLContext.
* \return Reference to the SDLContext instance.
@@ -58,13 +85,40 @@ public:
SDLContext & operator=(SDLContext &&) = delete;
private:
- //! will only use handle_events
- friend class LoopManager;
+ //! will only use get_events
+ friend class InputSystem;
/**
- * \brief Handles SDL events such as window close and input.
- * \param running Reference to a boolean flag that controls the main loop.
+ * \brief Retrieves a list of all events from the SDL context.
+ *
+ * This method retrieves all the events from the SDL context that are currently
+ * available. It is primarily used by the InputSystem to process various
+ * input events such as mouse clicks, mouse movements, and keyboard presses.
+ *
+ * \return Events that occurred since last call to `get_events()`
*/
- void handle_events(bool & running);
+ std::vector<SDLContext::EventData> get_events();
+
+ /**
+ * \brief Converts an SDL key code to the custom Keycode type.
+ *
+ * This method maps an SDL key code to the corresponding `Keycode` enum value,
+ * which is used internally by the system to identify the keys.
+ *
+ * \param sdl_key The SDL key code to convert.
+ * \return The corresponding `Keycode` value or `Keycode::NONE` if the key is unrecognized.
+ */
+ Keycode sdl_to_keycode(SDL_Keycode sdl_key);
+
+ /**
+ * \brief Converts an SDL mouse button code to the custom MouseButton type.
+ *
+ * This method maps an SDL mouse button code to the corresponding `MouseButton`
+ * enum value, which is used internally by the system to identify mouse buttons.
+ *
+ * \param sdl_button The SDL mouse button code to convert.
+ * \return The corresponding `MouseButton` value or `MouseButton::NONE` if the key is unrecognized
+ */
+ MouseButton sdl_to_mousebutton(Uint8 sdl_button);
private:
//! Will only use delay
@@ -109,18 +163,11 @@ private:
std::unique_ptr<SDL_Texture, std::function<void(SDL_Texture *)>>
texture_from_path(const std::string & path);
/**
- * \brief Gets the width of a texture.
+ * \brief Gets the size of a texture.
* \param texture Reference to the Texture object.
- * \return Width of the texture as an integer.
+ * \return Width and height of the texture as an integer.
*/
- int get_width(const Texture & texture) const;
-
- /**
- * \brief Gets the height of a texture.
- * \param texture Reference to the Texture object.
- * \return Height of the texture as an integer.
- */
- int get_height(const Texture & texture) const;
+ ivec2 get_size(const Texture & ctx);
private:
//! Will use draw,clear_screen, present_screen, camera.
@@ -170,6 +217,13 @@ private:
* \return sdl rectangle to draw a dst image to draw on the screen
*/
SDL_FRect get_dst_rect(const DstRect & ctx) const;
+ /**
+ * \brief Set an additional color value multiplied into render copy operations.
+ *
+ * \param texture the given texture to adjust
+ * \param color the color data for the texture
+ */
+ void set_color_texture(const Texture & texture, const Color & color);
private:
//! sdl Window