From 767f40a61952892d60d204ecaaffa07e7e396d28 Mon Sep 17 00:00:00 2001 From: heavydemon21 Date: Thu, 14 Nov 2024 10:05:08 +0100 Subject: color paremeter in sprite works --- src/crepe/facade/SDLContext.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src/crepe/facade/SDLContext.h') diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index c4392bd..5b5ee3e 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -145,6 +146,28 @@ private: */ void camera(const Camera & camera); + /** + * \brief changes the texture rbg values with the given parameters + * it sets the allowed color inside a image. So if all the colors are 255 (MAXIMUM) + * it will show the given texture. however if the one of the colors is reduced it will reduce the + * + * + * \param texture the given texture to adjust + * \param r Red color + * \param g Green color + * \param b Blue color + */ + void set_rbg_texture(const std::shared_ptr& texture, const uint8_t& r, const uint8_t& g, const uint8_t& b); + + + /** + * \brief Modifies the transparency of the given texture + * + * \param texture modify the given texture alpha channel + * \param alpha alpha channel + */ + void set_alpha_texture(const std::shared_ptr& texture, const uint8_t& alpha); + private: //! sdl Window std::unique_ptr> game_window; -- cgit v1.2.3 From 210ff1309aa545aa3574d991acc7734a1f268b8e Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Mon, 18 Nov 2024 16:12:12 +0100 Subject: added keycode conversion --- src/crepe/facade/SDLContext.cpp | 126 ++++++++++++++++++++++++++++++++++++++- src/crepe/facade/SDLContext.h | 2 + src/crepe/system/InputSystem.cpp | 0 src/crepe/system/InputSystem.h | 14 +++++ 4 files changed, 139 insertions(+), 3 deletions(-) create mode 100644 src/crepe/system/InputSystem.cpp create mode 100644 src/crepe/system/InputSystem.h (limited to 'src/crepe/facade/SDLContext.h') diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 83e91f8..bd2d33b 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -10,12 +10,15 @@ #include #include #include +#include #include "../api/Sprite.h" #include "../api/Texture.h" #include "../api/Transform.h" +#include "../api/EventManager.h" #include "../util/Log.h" + #include "SDLContext.h" using namespace crepe; @@ -80,8 +83,8 @@ SDLContext::~SDLContext() { } void SDLContext::handle_events(bool & running) { + EventManager& event_manager = EventManager::get_instance(); //TODO: wouter i need events - /* SDL_Event event; SDL_PollEvent(&event); switch (event.type) { @@ -89,7 +92,10 @@ void SDLContext::handle_events(bool & running) { running = false; break; case SDL_KEYDOWN: - triggerEvent(KeyPressedEvent(getCustomKey(event.key.keysym.sym))); + event_manager.trigger_event(KeyPressEvent{ + .key = this->sdl_to_keycode(event.key.keysym.sym), + .repeat = event.key.repeat + }); break; case SDL_MOUSEBUTTONDOWN: int x, y; @@ -97,7 +103,121 @@ void SDLContext::handle_events(bool & running) { triggerEvent(MousePressedEvent(x, y)); break; } - */ +} + + +Keycode SDLContext::sdl_to_keycode(SDL_Keycode sdl_key) { + static const std::array LOOKUP_TABLE = [] { + std::array table{}; + table.fill(Keycode::NONE); // Default to NONE for unmapped keys + + 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]; } void SDLContext::clear_screen() { SDL_RenderClear(this->game_renderer.get()); } diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index 007092b..ef7161b 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -8,6 +8,7 @@ #include #include "../api/Sprite.h" +#include "../api/KeyCodes.h" #include "../api/Transform.h" #include "api/Camera.h" @@ -53,6 +54,7 @@ private: * \param running Reference to a boolean flag that controls the main loop. */ void handle_events(bool & running); + Keycode sdl_to_keycode(SDL_Keycode sdlKey); private: //! Will only use get_ticks diff --git a/src/crepe/system/InputSystem.cpp b/src/crepe/system/InputSystem.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/crepe/system/InputSystem.h b/src/crepe/system/InputSystem.h new file mode 100644 index 0000000..642035f --- /dev/null +++ b/src/crepe/system/InputSystem.h @@ -0,0 +1,14 @@ +#pragma once + +#include "System.h" + +namespace crepe { + +class InputSystem : public System { +public: + using System::System; + void update() override; + void +}; + +} // namespace crepe -- cgit v1.2.3 From 92e83ded2b6afb26082d7661c28af1d9d4e950a2 Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Mon, 18 Nov 2024 16:55:21 +0100 Subject: added mouse and key event triggering --- src/crepe/api/Event.h | 16 ++++++ src/crepe/api/LoopManager.h | 13 ++--- src/crepe/facade/SDLContext.cpp | 114 ++++++++++++++++++++++++++++++++-------- src/crepe/facade/SDLContext.h | 1 + src/example/events.cpp | 4 +- src/example/gameloop.cpp | 33 ++++++++++++ 6 files changed, 151 insertions(+), 30 deletions(-) (limited to 'src/crepe/facade/SDLContext.h') diff --git a/src/crepe/api/Event.h b/src/crepe/api/Event.h index d5ddf0a..ef6a791 100644 --- a/src/crepe/api/Event.h +++ b/src/crepe/api/Event.h @@ -87,6 +87,10 @@ public: //! Y-coordinate of the mouse position at the time of the event. int mouse_y = 0; + // Relative movement in x + int rel_x; + // Relative movement in y + int rel_y; }; /** @@ -113,3 +117,15 @@ public: class ShutDownEvent : public Event { public: }; + +class MouseScrollEvent : public Event { +public: + //! X-coordinate of the mouse position at the time of the event. + int scroll_x = 0; + + //! Y-coordinate of the mouse position at the time of the event. + int scroll_y = 0; + + int direction = 0; +}; + diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h index f6904be..b18c9d1 100644 --- a/src/crepe/api/LoopManager.h +++ b/src/crepe/api/LoopManager.h @@ -10,6 +10,12 @@ namespace crepe { class LoopManager { public: void start(); + /** + * \brief Set game running variable + * + * \param running running (false = game shutdown, true = game running) + */ + void set_running(bool running); LoopManager(); private: @@ -53,12 +59,7 @@ private: * This function updates physics and game logic based on LoopTimer's fixed_delta_time. */ void fixed_update(); - /** - * \brief Set game running variable - * - * \param running running (false = game shutdown, true = game running) - */ - void set_running(bool running); + /** * \brief Function for executing render-related systems. * diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index bd2d33b..8a02f4c 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -82,34 +82,84 @@ SDLContext::~SDLContext() { SDL_Quit(); } -void SDLContext::handle_events(bool & running) { - EventManager& event_manager = EventManager::get_instance(); - //TODO: wouter i need events - SDL_Event event; - SDL_PollEvent(&event); - switch (event.type) { - case SDL_QUIT: - running = false; - break; - case SDL_KEYDOWN: - event_manager.trigger_event(KeyPressEvent{ - .key = this->sdl_to_keycode(event.key.keysym.sym), - .repeat = event.key.repeat - }); - break; - case SDL_MOUSEBUTTONDOWN: - int x, y; - SDL_GetMouseState(&x, &y); - triggerEvent(MousePressedEvent(x, y)); - break; - } +void SDLContext::handle_events(bool &running) { + EventManager& event_manager = EventManager::get_instance(); + SDL_Event event; + + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + running = false; + event_manager.trigger_event(ShutDownEvent{}); + break; + + case SDL_KEYDOWN: + std::cout << "keyDown: " << event.key.keysym.sym << std::endl; + event_manager.trigger_event(KeyPressEvent{ + .repeat = event.key.repeat, + .key = this->sdl_to_keycode(event.key.keysym.scancode) + }); + break; + + case SDL_KEYUP: + event_manager.trigger_event(KeyReleaseEvent{ + .key = this->sdl_to_keycode(event.key.keysym.scancode), + }); + break; + + case SDL_MOUSEBUTTONDOWN: + { + int x, y; + SDL_GetMouseState(&x, &y); + event_manager.trigger_event(MousePressEvent{ + .mouse_x = x, + .mouse_y = y, + .button = this->sdl_to_mousebutton(event.button.button) + }); + } + break; + + case SDL_MOUSEBUTTONUP: + { + int x, y; + SDL_GetMouseState(&x, &y); + event_manager.trigger_event(MouseReleaseEvent{ + .mouse_x = x, + .mouse_y = y, + .button = this->sdl_to_mousebutton(event.button.button) + }); + } + break; + + case SDL_MOUSEMOTION: + event_manager.trigger_event(MouseMoveEvent{ + .mouse_x = event.motion.x, + .mouse_y = event.motion.y, + .rel_x = event.motion.xrel, + .rel_y = event.motion.yrel + }); + break; + + case SDL_MOUSEWHEEL: + event_manager.trigger_event(MouseScrollEvent{ + .scroll_x = event.wheel.x, + .scroll_y = event.wheel.y, + .direction = (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED ? -1 : 1) + }); + break; + + // Add more events as needed for your application. + } + } } + Keycode SDLContext::sdl_to_keycode(SDL_Keycode sdl_key) { static const std::array LOOKUP_TABLE = [] { std::array table{}; - table.fill(Keycode::NONE); // Default to NONE for unmapped keys + // Default to NONE for unmapped keys + table.fill(Keycode::NONE); table[SDL_SCANCODE_SPACE] = Keycode::SPACE; table[SDL_SCANCODE_APOSTROPHE] = Keycode::APOSTROPHE; @@ -219,7 +269,27 @@ Keycode SDLContext::sdl_to_keycode(SDL_Keycode sdl_key) { return LOOKUP_TABLE[sdl_key]; } +MouseButton SDLContext::sdl_to_mousebutton(Uint8 sdl_button) { + static const std::array MOUSE_BUTTON_LOOKUP_TABLE = [] { + std::array table{}; + table.fill(MouseButton::NONE); // Default to NONE for unmapped buttons + + 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]; // Return mapped button +} void SDLContext::clear_screen() { SDL_RenderClear(this->game_renderer.get()); } void SDLContext::present_screen() { SDL_RenderPresent(this->game_renderer.get()); } diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index ef7161b..cce2fb6 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -55,6 +55,7 @@ private: */ void handle_events(bool & running); Keycode sdl_to_keycode(SDL_Keycode sdlKey); + MouseButton sdl_to_mousebutton(Uint8 sdl_button); private: //! Will only use get_ticks diff --git a/src/example/events.cpp b/src/example/events.cpp index 6431c67..1b9ea45 100644 --- a/src/example/events.cpp +++ b/src/example/events.cpp @@ -56,12 +56,12 @@ public: bool on_key_pressed(const KeyPressEvent & event) override { std::cout << "TestKeyListener: Key Pressed - Code: " << static_cast(event.key) << std::endl; - return true; // Return true if the listener should remain active + return false; } bool on_key_released(const KeyReleaseEvent & event) override { std::cout << "TestKeyListener: Key Released - Code: " << static_cast(event.key) << std::endl; - return true; + return false; } }; int main() { diff --git a/src/example/gameloop.cpp b/src/example/gameloop.cpp index a676f20..d45b3ce 100644 --- a/src/example/gameloop.cpp +++ b/src/example/gameloop.cpp @@ -1,7 +1,40 @@ +#include #include "crepe/api/LoopManager.h" +#include +#include +#include +#include using namespace crepe; +class TestKeyListener : public IKeyListener { +public: + bool on_key_pressed(const KeyPressEvent & event) override { + std::cout << "TestKeyListener: Key Pressed - Code: " << static_cast(event.key) + << std::endl; + if(event.key == Keycode::ESCAPE){ + + } + return false; + } + bool on_key_released(const KeyReleaseEvent & event) override { + std::cout << "TestKeyListener: Key Released - Code: " << static_cast(event.key) + << std::endl; + return false; + } +}; +bool on_key_pressed(const KeyPressEvent & event){ + std::cout << "TestKeyListener: Key Pressed - Code: " << static_cast(event.key) + << std::endl; + if(event.key == Keycode::ESCAPE){ + return true; + } + return false; + } int main() { LoopManager gameloop; + TestKeyListener key_listener; + EventManager::get_instance().subscribe(on_key_pressed); gameloop.start(); + + return 1; } -- cgit v1.2.3 From 6287d4e9068d8bd27a9e62643f54adb69e84befd Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Sun, 24 Nov 2024 22:08:49 +0100 Subject: input facade --- src/crepe/api/LoopManager.cpp | 4 +- src/crepe/facade/SDLContext.cpp | 78 ++++++++++++++++++++++++++++++++++- src/crepe/facade/SDLContext.h | 36 ++++++++++++++--- src/crepe/system/InputSystem.cpp | 87 ++++++++++++++++++++++++++++++++-------- src/crepe/system/InputSystem.h | 7 +++- src/test/inputTest.cpp | 53 ++++++++++++++++++++++++ src/test/loopTimerTest.cpp | 32 +++++++++++++++ 7 files changed, 272 insertions(+), 25 deletions(-) create mode 100644 src/test/inputTest.cpp create mode 100644 src/test/loopTimerTest.cpp (limited to 'src/crepe/facade/SDLContext.h') diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index a64366f..af306c0 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -6,6 +6,7 @@ #include "../system/PhysicsSystem.h" #include "../system/RenderSystem.h" #include "../system/ScriptSystem.h" +#include "../system/InputSystem.h" #include "LoopManager.h" #include "LoopTimer.h" @@ -20,10 +21,11 @@ LoopManager::LoopManager() { this->load_system(); this->load_system(); this->load_system(); + this->load_system(); } void LoopManager::process_input() { - SDLContext::get_instance().handle_events(this->game_running); + this->get_system().update(); } void LoopManager::start() { diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 43ef3f1..3fb7f05 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -92,7 +92,6 @@ void SDLContext::handle_events(bool &running) { running = false; event_manager.trigger_event(ShutDownEvent{}); break; - case SDL_KEYDOWN: event_manager.trigger_event(KeyPressEvent{ .repeat = event.key.repeat, @@ -146,7 +145,6 @@ void SDLContext::handle_events(bool &running) { .direction = (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED ? -1 : 1) }); break; - } } } @@ -365,3 +363,79 @@ int SDLContext::get_height(const Texture & ctx) const { return h; } void SDLContext::delay(int ms) const { SDL_Delay(ms); } + +std::vector SDLContext::get_events(){ + std::vector event_list; + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + event_list.push_back(EventData{ + .event_type = SDLContext::Event::SHUTDOWN, + }); + break; + case SDL_KEYDOWN: + event_list.push_back(EventData{ + .event_type = SDLContext::Event::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::Event::KEYUP, + .key = sdl_to_keycode(event.key.keysym.scancode), + }); + break; + case SDL_MOUSEBUTTONDOWN: + { + int x,y; + SDL_GetMouseState(&x, &y); + event_list.push_back(EventData{ + .event_type = SDLContext::Event::MOUSEDOWN, + .mouse_button = sdl_to_mousebutton(event.button.button), + .mouse_position = {x,y}, + }); + } + break; + case SDL_MOUSEBUTTONUP: + { + int x,y; + SDL_GetMouseState(&x, &y); + event_list.push_back(EventData{ + .event_type = SDLContext::Event::MOUSEUP, + .mouse_button = sdl_to_mousebutton(event.button.button), + .mouse_position = {x,y}, + }); + } + break; + + case SDL_MOUSEMOTION: + { + int x,y; + SDL_GetMouseState(&x, &y); + event_list.push_back(EventData{ + .event_type = SDLContext::Event::MOUSEMOVE, + .mouse_position = {x,y}, + }); + } + break; + + case SDL_MOUSEWHEEL: + { + int x, y; + SDL_GetMouseState(&x, &y); + + event_list.push_back(EventData{ + .event_type = SDLContext::Event::MOUSEWHEEL, + .mouse_position = {event.motion.x,event.motion.y}, + .wheel_delta = event.wheel.y, + .rel_mouse_move {event.motion.yrel,event.motion.xrel}, + }); + } + break; + } + } + return event_list; +} + diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index cce2fb6..dcd7440 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -1,5 +1,5 @@ #pragma once - +#include #include #include #include @@ -10,6 +10,8 @@ #include "../api/Sprite.h" #include "../api/KeyCodes.h" #include "../api/Transform.h" +#include "../api/Vector2.h" +#include "../api/Event.h" #include "api/Camera.h" // FIXME: this needs to be removed @@ -20,11 +22,11 @@ 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; +//typedef SDL_Keycode CREPE_KEYCODES; class Texture; class LoopManager; - +class InputSystem; /** * \class SDLContext * \brief Facade for the SDL library @@ -35,6 +37,26 @@ class LoopManager; class SDLContext { public: + enum Event{ + NONE = 0, + MOUSEDOWN, + MOUSEUP, + MOUSEMOVE, + MOUSEWHEEL, + KEYUP, + KEYDOWN, + SHUTDOWN + + }; + struct EventData { + SDLContext::Event event_type = SDLContext::Event::NONE; + Keycode key = Keycode::NONE; + bool key_repeat = false; + MouseButton mouse_button = MouseButton::NONE; + std::pair mouse_position = {-1,-1}; + int wheel_delta = -1; + std::pair rel_mouse_move = {-1,-1}; + }; /** * \brief Gets the singleton instance of SDLContext. * \return Reference to the SDLContext instance. @@ -48,15 +70,18 @@ public: private: //! will only use handle_events - friend class LoopManager; + 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. */ void handle_events(bool & running); + std::vector get_events(); + + Keycode get_key(); + Keycode get_mouse(); Keycode sdl_to_keycode(SDL_Keycode sdlKey); MouseButton sdl_to_mousebutton(Uint8 sdl_button); - private: //! Will only use get_ticks friend class AnimatorSystem; @@ -153,4 +178,5 @@ private: SDL_Rect viewport = {0, 0, 640, 480}; }; + } // namespace crepe diff --git a/src/crepe/system/InputSystem.cpp b/src/crepe/system/InputSystem.cpp index b7a86f4..c61a80f 100644 --- a/src/crepe/system/InputSystem.cpp +++ b/src/crepe/system/InputSystem.cpp @@ -2,26 +2,86 @@ #include "../api/Button.h" #include "../api/EventManager.h" #include "../api/Transform.h" +#include "../facade/SDLContext.h" #include "../api/Event.h" #include "system/InputSystem.h" using namespace crepe; -InputSystem::InputSystem(ComponentManager &component_manager) - : System(component_manager) { - auto &event_manager = EventManager::get_instance(); - event_manager.subscribe([this](const MouseClickEvent &event) { - return this->handle_click(event); - }); - - event_manager.subscribe([this](const MouseMoveEvent &event) { - return this->handle_move(event); - }); -} void InputSystem::update() { + EventManager& event_mgr = EventManager::get_instance(); + std::vector event_list = SDLContext::get_instance().get_events(); + + for (SDLContext::EventData event : event_list) { + switch (event.event_type) { + case SDLContext::Event::KEYDOWN: { + event_mgr.queue_event(KeyPressEvent{ + .key = event.key, + .repeat = event.key_repeat, + }); + break; + } + case SDLContext::Event::KEYUP: { + event_mgr.queue_event(KeyReleaseEvent{ + .key = event.key, + }); + break; + } + case SDLContext::Event::MOUSEDOWN: { + event_mgr.queue_event(MousePressEvent{ + .mouse_x = event.mouse_position.first, + .mouse_y = event.mouse_position.second, + .button = event.mouse_button, + }); + break; + } + case SDLContext::Event::MOUSEMOVE: { + event_mgr.queue_event(MouseMoveEvent{ + .mouse_x = event.mouse_position.first, + .mouse_y = event.mouse_position.second, + .rel_x = event.rel_mouse_move.first, + .rel_y = event.rel_mouse_move.second, + }); + break; + } + case SDLContext::Event::MOUSEUP: { + event_mgr.queue_event(MouseReleaseEvent{ + .mouse_x = event.mouse_position.first, + .mouse_y = event.mouse_position.second, + .button = event.mouse_button, + }); + int delta_x = event.mouse_position.first - last_mouse_down_position.first; + int delta_y = event.mouse_position.second - last_mouse_down_position.second; + if (last_mouse_button == event.mouse_button && + std::abs(delta_x) <= click_tolerance && + std::abs(delta_y) <= click_tolerance) { + event_mgr.queue_event(MouseClickEvent{ + .mouse_x = event.mouse_position.first, + .mouse_y = event.mouse_position.second, + .button = event.mouse_button, + }); + } + break; + } + case SDLContext::Event::MOUSEWHEEL: { + event_mgr.queue_event(MouseScrollEvent{ + .scroll_x = event.mouse_position.first, + .scroll_y = event.mouse_position.second, + .direction = event.wheel_delta, + }); + break; + } + case SDLContext::Event::SHUTDOWN: { + event_mgr.queue_event(ShutDownEvent{}); + break; + } + default: + break; + } + } } bool InputSystem::handle_click(const MouseClickEvent &event) { @@ -45,8 +105,3 @@ bool InputSystem::handle_click(const MouseClickEvent &event) { return false; } -bool InputSystem::handle_move(const MouseMoveEvent &event) { - - ComponentManager &mgr = this->component_manager; - -} diff --git a/src/crepe/system/InputSystem.h b/src/crepe/system/InputSystem.h index c50d928..231aa45 100644 --- a/src/crepe/system/InputSystem.h +++ b/src/crepe/system/InputSystem.h @@ -7,8 +7,13 @@ namespace crepe { class InputSystem : public System { public: using System::System; - InputSystem(ComponentManager & component_manager); void update() override; + void process_events(); + +private: + std::pair last_mouse_down_position{-1, -1}; + MouseButton last_mouse_button = MouseButton::NONE; + const int click_tolerance = 5; bool handle_click(const MouseClickEvent &event); bool handle_move(const MouseMoveEvent &event); bool handle_key_press(const KeyPressEvent &event); diff --git a/src/test/inputTest.cpp b/src/test/inputTest.cpp new file mode 100644 index 0000000..0f02410 --- /dev/null +++ b/src/test/inputTest.cpp @@ -0,0 +1,53 @@ +#include +#include +#include "system/InputSystem.h" +#include "api/EventManager.h" +#include "api/KeyCodes.h" +#include +#include + +using namespace std; +using namespace std::chrono_literals; +using namespace crepe; + +class InputTest : public ::testing::Test { +public: +InputSystem input_system; +EventManager& event_manager = EventManager::get_instance(); +protected: + void SetUp() override { + } + + void TearDown() override { + + } +void simulate_mouse_click(int mouse_x, int mouse_y, Uint8 mouse_button) { + SDL_Event event; + + // Simulate Mouse Button Down event + SDL_zero(event); + event.type = SDL_MOUSEBUTTONDOWN; + event.button.x = mouse_x; + event.button.y = mouse_y; + event.button.button = mouse_button; + SDL_PushEvent(&event); + SDL_zero(event); + event.type = SDL_MOUSEBUTTONUP; + event.button.x = mouse_x; + event.button.y = mouse_y; + event.button.button = mouse_button; + SDL_PushEvent(&event); +} + +}; + +TEST_F(InputTest, KeyDown) { + + SDL_Event event; + SDL_zero(event); + event.type = SDL_MOUSEBUTTONDOWN; + event.button.x = 10; + event.button.y = 10; + event.button.button = mouse_bu; + SDL_PushEvent(&event); // Push event into the SDL event queue +} diff --git a/src/test/loopTimerTest.cpp b/src/test/loopTimerTest.cpp new file mode 100644 index 0000000..a3b1646 --- /dev/null +++ b/src/test/loopTimerTest.cpp @@ -0,0 +1,32 @@ +#define private public +#define protected public +#include "api/LoopManager.h" +#include "api/LoopTimer.h" +#include +#include + +using namespace std; +using namespace std::chrono_literals; +using namespace crepe; + +class LoopTimerTest : public ::testing::Test { +public: +LoopTimer loop_timer = LoopTimer::get_instance(); +protected: + void SetUp() override { + loop_timer.start(); + } + + void TearDown() override { + + } +}; +TEST_F(LoopTimerTest, TestDeltaTime) { + auto start_time = std::chrono::steady_clock::now(); + + loop_timer.update(); + double delta_time = loop_timer.get_delta_time(); + + auto elapsed_time = std::chrono::steady_clock::now() - start_time; + EXPECT_LE(delta_time, std::chrono::duration(elapsed_time).count()); +} -- cgit v1.2.3 From 327154fd428e0798eea544d9f073f8e1293aa158 Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Mon, 25 Nov 2024 10:38:18 +0100 Subject: most test working --- src/crepe/api/Button.h | 3 +- src/crepe/api/EventManager.hpp | 2 +- src/crepe/api/UiObject.h | 4 +- src/crepe/facade/SDLContext.cpp | 86 +-------------- src/crepe/facade/SDLContext.h | 4 +- src/crepe/system/CMakeLists.txt | 2 + src/crepe/system/InputSystem.cpp | 125 +++++++++++++-------- src/crepe/system/InputSystem.h | 17 ++- src/test/CMakeLists.txt | 1 + src/test/EventTest.cpp | 66 ++++++----- src/test/inputTest.cpp | 231 ++++++++++++++++++++------------------- 11 files changed, 266 insertions(+), 275 deletions(-) (limited to 'src/crepe/facade/SDLContext.h') diff --git a/src/crepe/api/Button.h b/src/crepe/api/Button.h index 9b1341f..709854a 100644 --- a/src/crepe/api/Button.h +++ b/src/crepe/api/Button.h @@ -1,3 +1,4 @@ +#pragma once #include #include "Component.h" @@ -6,7 +7,7 @@ namespace crepe { class Button : public UiObject{ public: - Button(); + Button(game_object_id_t id) : UiObject(id){}; bool interactable = true; bool is_toggle = false; bool is_pressed = false; diff --git a/src/crepe/api/EventManager.hpp b/src/crepe/api/EventManager.hpp index a5f4556..3eae90a 100644 --- a/src/crepe/api/EventManager.hpp +++ b/src/crepe/api/EventManager.hpp @@ -1,5 +1,5 @@ #pragma once - +#include #include "EventManager.h" namespace crepe { diff --git a/src/crepe/api/UiObject.h b/src/crepe/api/UiObject.h index 1d7be69..82140a0 100644 --- a/src/crepe/api/UiObject.h +++ b/src/crepe/api/UiObject.h @@ -4,12 +4,14 @@ #include "api/EventHandler.h" namespace crepe { + class UiObject : public Component{ public: - UiObject(); + UiObject(game_object_id_t id) : Component(id){}; int width = 0; int height = 0; public: virtual int get_instances_max() const { return 1; } }; + } diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 1ef222c..f87cc61 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -76,75 +76,6 @@ SDLContext::~SDLContext() { SDL_Quit(); } -void SDLContext::handle_events(bool &running) { - EventManager& event_manager = EventManager::get_instance(); - SDL_Event event; - - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_QUIT: - running = false; - event_manager.trigger_event(ShutDownEvent{}); - break; - case SDL_KEYDOWN: - event_manager.trigger_event(KeyPressEvent{ - .repeat = (!event.key.repeat == 0), - .key = this->sdl_to_keycode(event.key.keysym.scancode) - }); - break; - - case SDL_KEYUP: - event_manager.trigger_event(KeyReleaseEvent{ - .key = this->sdl_to_keycode(event.key.keysym.scancode), - }); - break; - - case SDL_MOUSEBUTTONDOWN: - { - int x, y; - SDL_GetMouseState(&x, &y); - event_manager.trigger_event(MousePressEvent{ - .mouse_x = x, - .mouse_y = y, - .button = this->sdl_to_mousebutton(event.button.button) - }); - } - break; - - case SDL_MOUSEBUTTONUP: - { - int x, y; - SDL_GetMouseState(&x, &y); - event_manager.trigger_event(MouseReleaseEvent{ - .mouse_x = x, - .mouse_y = y, - .button = this->sdl_to_mousebutton(event.button.button) - }); - } - break; - - case SDL_MOUSEMOTION: - event_manager.trigger_event(MouseMoveEvent{ - .mouse_x = event.motion.x, - .mouse_y = event.motion.y, - .rel_x = event.motion.xrel, - .rel_y = event.motion.yrel - }); - break; - - case SDL_MOUSEWHEEL: - event_manager.trigger_event(MouseScrollEvent{ - .scroll_x = event.wheel.x, - .scroll_y = event.wheel.y, - .direction = (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED ? -1 : 1) - }); - break; - } - } -} - - - Keycode SDLContext::sdl_to_keycode(SDL_Keycode sdl_key) { static const std::array LOOKUP_TABLE = [] { std::array table{}; @@ -259,8 +190,8 @@ Keycode SDLContext::sdl_to_keycode(SDL_Keycode sdl_key) { return LOOKUP_TABLE[sdl_key]; } MouseButton SDLContext::sdl_to_mousebutton(Uint8 sdl_button) { - static const std::array MOUSE_BUTTON_LOOKUP_TABLE = [] { - std::array table{}; + static const std::array MOUSE_BUTTON_LOOKUP_TABLE = [] { + std::array table{}; table.fill(MouseButton::NONE); table[SDL_BUTTON_LEFT] = MouseButton::LEFT_MOUSE; @@ -409,7 +340,7 @@ std::vector SDLContext::get_events(){ event_list.push_back(EventData{ .event_type = SDLContext::Event::MOUSEDOWN, .mouse_button = sdl_to_mousebutton(event.button.button), - .mouse_position = {x,y}, + .mouse_position = {event.button.x,event.button.y}, }); } break; @@ -420,32 +351,27 @@ std::vector SDLContext::get_events(){ event_list.push_back(EventData{ .event_type = SDLContext::Event::MOUSEUP, .mouse_button = sdl_to_mousebutton(event.button.button), - .mouse_position = {x,y}, + .mouse_position = {event.button.x,event.button.y}, }); } break; case SDL_MOUSEMOTION: { - int x,y; - SDL_GetMouseState(&x, &y); event_list.push_back(EventData{ .event_type = SDLContext::Event::MOUSEMOVE, - .mouse_position = {x,y}, + .mouse_position = {event.button.x,event.button.y}, }); } break; case SDL_MOUSEWHEEL: { - int x, y; - SDL_GetMouseState(&x, &y); - event_list.push_back(EventData{ .event_type = SDLContext::Event::MOUSEWHEEL, .mouse_position = {event.motion.x,event.motion.y}, .wheel_delta = event.wheel.y, - .rel_mouse_move {event.motion.yrel,event.motion.xrel}, + .rel_mouse_move = {event.motion.yrel,event.motion.xrel}, }); } break; diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index 5b6b093..1b881d1 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -43,7 +44,7 @@ public: MOUSEWHEEL, KEYUP, KEYDOWN, - SHUTDOWN + SHUTDOWN, }; struct EventData { @@ -73,7 +74,6 @@ private: * \brief Handles SDL events such as window close and input. * \param running Reference to a boolean flag that controls the main loop. */ - void handle_events(bool & running); std::vector get_events(); Keycode get_key(); diff --git a/src/crepe/system/CMakeLists.txt b/src/crepe/system/CMakeLists.txt index d658b25..95f6e33 100644 --- a/src/crepe/system/CMakeLists.txt +++ b/src/crepe/system/CMakeLists.txt @@ -6,6 +6,7 @@ target_sources(crepe PUBLIC CollisionSystem.cpp RenderSystem.cpp AnimatorSystem.cpp + InputSystem.cpp ) target_sources(crepe PUBLIC FILE_SET HEADERS FILES @@ -15,4 +16,5 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES CollisionSystem.h RenderSystem.h AnimatorSystem.h + InputSystem.h ) diff --git a/src/crepe/system/InputSystem.cpp b/src/crepe/system/InputSystem.cpp index c61a80f..4560411 100644 --- a/src/crepe/system/InputSystem.cpp +++ b/src/crepe/system/InputSystem.cpp @@ -1,7 +1,7 @@ #include "ComponentManager.h" -#include "../api/Button.h" + #include "../api/EventManager.h" -#include "../api/Transform.h" + #include "../facade/SDLContext.h" #include "../api/Event.h" @@ -14,32 +14,67 @@ using namespace crepe; void InputSystem::update() { EventManager& event_mgr = EventManager::get_instance(); std::vector event_list = SDLContext::get_instance().get_events(); - + for (SDLContext::EventData event : event_list) { switch (event.event_type) { case SDLContext::Event::KEYDOWN: { - event_mgr.queue_event(KeyPressEvent{ + event_mgr.queue_event(KeyPressEvent{ + .repeat = event.key_repeat, .key = event.key, - .repeat = event.key_repeat, }); break; } case SDLContext::Event::KEYUP: { - event_mgr.queue_event(KeyReleaseEvent{ + event_mgr.queue_event(KeyReleaseEvent{ .key = event.key, }); break; } case SDLContext::Event::MOUSEDOWN: { - event_mgr.queue_event(MousePressEvent{ + event_mgr.queue_event(MousePressEvent{ .mouse_x = event.mouse_position.first, .mouse_y = event.mouse_position.second, .button = event.mouse_button, }); + last_mouse_down_position = {event.mouse_position.first,event.mouse_position.second}; + last_mouse_button = event.mouse_button; break; } + case SDLContext::Event::MOUSEUP: { + MouseReleaseEvent mouse_release_event = MouseReleaseEvent{ + .mouse_x = event.mouse_position.first, + .mouse_y = event.mouse_position.second, + .button = event.mouse_button, + }; + event_mgr.queue_event(mouse_release_event); + + // Calculate deltas for click detection + int delta_x = event.mouse_position.first - last_mouse_down_position.first; + int delta_y = event.mouse_position.second - last_mouse_down_position.second; + + // Ensure last_mouse_button is properly set and matches the current mouse button + if (last_mouse_button == event.mouse_button && + std::abs(delta_x) <= click_tolerance && + std::abs(delta_y) <= click_tolerance) { + std::cout << "Click registered at (" << event.mouse_position.first + << ", " << event.mouse_position.second << ") with button " + << static_cast(event.mouse_button) << std::endl; + + event_mgr.queue_event(MouseClickEvent{ + .mouse_x = event.mouse_position.first, + .mouse_y = event.mouse_position.second, + .button = event.mouse_button, + }); + + this->handle_click(mouse_release_event); + } else { + std::cout << "Mouse release did not register as a click." << std::endl; + } + + break; + } case SDLContext::Event::MOUSEMOVE: { - event_mgr.queue_event(MouseMoveEvent{ + event_mgr.queue_event(MouseMoveEvent{ .mouse_x = event.mouse_position.first, .mouse_y = event.mouse_position.second, .rel_x = event.rel_mouse_move.first, @@ -47,27 +82,9 @@ void InputSystem::update() { }); break; } - case SDLContext::Event::MOUSEUP: { - event_mgr.queue_event(MouseReleaseEvent{ - .mouse_x = event.mouse_position.first, - .mouse_y = event.mouse_position.second, - .button = event.mouse_button, - }); - int delta_x = event.mouse_position.first - last_mouse_down_position.first; - int delta_y = event.mouse_position.second - last_mouse_down_position.second; - if (last_mouse_button == event.mouse_button && - std::abs(delta_x) <= click_tolerance && - std::abs(delta_y) <= click_tolerance) { - event_mgr.queue_event(MouseClickEvent{ - .mouse_x = event.mouse_position.first, - .mouse_y = event.mouse_position.second, - .button = event.mouse_button, - }); - } - break; - } + case SDLContext::Event::MOUSEWHEEL: { - event_mgr.queue_event(MouseScrollEvent{ + event_mgr.queue_event(MouseScrollEvent{ .scroll_x = event.mouse_position.first, .scroll_y = event.mouse_position.second, .direction = event.wheel_delta, @@ -75,7 +92,7 @@ void InputSystem::update() { break; } case SDLContext::Event::SHUTDOWN: { - event_mgr.queue_event(ShutDownEvent{}); + event_mgr.queue_event(ShutDownEvent{}); break; } default: @@ -84,24 +101,44 @@ void InputSystem::update() { } } -bool InputSystem::handle_click(const MouseClickEvent &event) { +void InputSystem::handle_click(const MouseReleaseEvent event) { ComponentManager &mgr = this->component_manager; - std::vector> buttons = - mgr.get_components_by_type