diff options
author | max-001 <maxsmits21@kpnmail.nl> | 2024-12-17 15:43:49 +0100 |
---|---|---|
committer | max-001 <maxsmits21@kpnmail.nl> | 2024-12-17 15:43:49 +0100 |
commit | 4dd30ea92296892c9a9bd94787531d6a1319d8ac (patch) | |
tree | 5df2de26f7f6f3170c06c77d8ae21ce635217356 /src/crepe/facade | |
parent | 6e92c59b3364b00eb15c310120b93acc83ca504e (diff) | |
parent | a8ccf7fe8662086bb223aa4eafd0f85e717d16cf (diff) |
Merge remote-tracking branch 'origin/master' into jaro/collision-system-handeling
Diffstat (limited to 'src/crepe/facade')
-rw-r--r-- | src/crepe/facade/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/crepe/facade/EventData.h | 54 | ||||
-rw-r--r-- | src/crepe/facade/Font.cpp | 21 | ||||
-rw-r--r-- | src/crepe/facade/Font.h | 42 | ||||
-rw-r--r-- | src/crepe/facade/FontFacade.cpp | 43 | ||||
-rw-r--r-- | src/crepe/facade/FontFacade.h | 34 | ||||
-rw-r--r-- | src/crepe/facade/SDLContext.cpp | 268 | ||||
-rw-r--r-- | src/crepe/facade/SDLContext.h | 182 |
8 files changed, 475 insertions, 173 deletions
diff --git a/src/crepe/facade/CMakeLists.txt b/src/crepe/facade/CMakeLists.txt index 0598e16..243ae46 100644 --- a/src/crepe/facade/CMakeLists.txt +++ b/src/crepe/facade/CMakeLists.txt @@ -4,6 +4,8 @@ target_sources(crepe PUBLIC SoundContext.cpp SDLContext.cpp DB.cpp + FontFacade.cpp + Font.cpp ) target_sources(crepe PUBLIC FILE_SET HEADERS FILES @@ -12,5 +14,7 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES SoundContext.h SDLContext.h DB.h + FontFacade.h + Font.h ) diff --git a/src/crepe/facade/EventData.h b/src/crepe/facade/EventData.h new file mode 100644 index 0000000..a7526b4 --- /dev/null +++ b/src/crepe/facade/EventData.h @@ -0,0 +1,54 @@ +#pragma once +#include "../api/KeyCodes.h" +#include "../types.h" +namespace crepe { +//! EventType enum for passing eventType +enum EventType { + NONE = 0, + MOUSE_DOWN, + MOUSE_UP, + MOUSE_MOVE, + MOUSE_WHEEL, + KEY_UP, + KEY_DOWN, + SHUTDOWN, + WINDOW_MINIMIZE, + WINDOW_MAXIMIZE, + WINDOW_FOCUS_GAIN, + WINDOW_FOCUS_LOST, + WINDOW_MOVE, + WINDOW_RESIZE, + WINDOW_EXPOSE, +}; + +//! Struct for storing key data. +struct KeyData { + Keycode key = Keycode::NONE; + bool key_repeat = false; +}; + +//! Struct for storing mouse data. +struct MouseData { + MouseButton mouse_button = MouseButton::NONE; + ivec2 mouse_position = {-1, -1}; + int scroll_direction = -1; + float scroll_delta = INFINITY; + ivec2 rel_mouse_move = {-1, -1}; +}; + +//! Struct for storing window data. +struct WindowData { + ivec2 move_delta; + ivec2 resize_dimension; +}; + +//! EventData struct for passing event data from facade +struct EventData { + EventType event_type = EventType::NONE; + union { + KeyData key_data; + MouseData mouse_data; + WindowData window_data; + } data; +}; +} // namespace crepe diff --git a/src/crepe/facade/Font.cpp b/src/crepe/facade/Font.cpp new file mode 100644 index 0000000..771002f --- /dev/null +++ b/src/crepe/facade/Font.cpp @@ -0,0 +1,21 @@ +#include <SDL2/SDL_ttf.h> + +#include "../api/Asset.h" +#include "../api/Config.h" + +#include "Font.h" + +using namespace std; +using namespace crepe; + +Font::Font(const Asset & src, Mediator & mediator) : Resource(src, mediator) { + const Config & config = Config::get_instance(); + const std::string FONT_PATH = src.get_path(); + TTF_Font * loaded_font = TTF_OpenFont(FONT_PATH.c_str(), config.font.size); + if (loaded_font == NULL) { + throw runtime_error(format("Font: {} (path: {})", TTF_GetError(), FONT_PATH)); + } + this->font = {loaded_font, [](TTF_Font * close_font) { TTF_CloseFont(close_font); }}; +} + +TTF_Font * Font::get_font() const { return this->font.get(); } diff --git a/src/crepe/facade/Font.h b/src/crepe/facade/Font.h new file mode 100644 index 0000000..b208d96 --- /dev/null +++ b/src/crepe/facade/Font.h @@ -0,0 +1,42 @@ +#pragma once + +#include <SDL2/SDL_ttf.h> +#include <memory> + +#include "../Resource.h" +#include "../api/Config.h" + +namespace crepe { + +class Asset; +/** + * \brief Resource for managing font creation and destruction + * + * This class is a wrapper around an SDL_ttf font instance, encapsulating font loading and usage. + * It loads a font from an Asset and manages its lifecycle. The font is automatically unloaded + * when this object is destroyed. + */ +class Font : public Resource { + +public: + /** + * \param src The Asset containing the font file path and metadata to load the font. + * \param mediator The Mediator object used for managing the SDL context or related systems. + */ + Font(const Asset & src, Mediator & mediator); + /** + * \brief Gets the underlying TTF_Font resource. + * + * This function returns the raw pointer to the SDL_ttf TTF_Font object that represents + * the loaded font. This can be used with SDL_ttf functions to render text. + * + * \return The raw TTF_Font object wrapped in a unique pointer. + */ + TTF_Font * get_font() const; + +private: + //! The SDL_ttf font object with custom deleter. + std::unique_ptr<TTF_Font, std::function<void(TTF_Font *)>> font = nullptr; +}; + +} // namespace crepe diff --git a/src/crepe/facade/FontFacade.cpp b/src/crepe/facade/FontFacade.cpp new file mode 100644 index 0000000..87f95ab --- /dev/null +++ b/src/crepe/facade/FontFacade.cpp @@ -0,0 +1,43 @@ +#include <fontconfig/fontconfig.h> +#include <functional> +#include <memory> +#include <stdexcept> +#include <string> + +#include "FontFacade.h" + +using namespace std; +using namespace crepe; + +FontFacade::FontFacade() { + if (!FcInit()) throw runtime_error("Failed to initialize Fontconfig."); +} + +FontFacade::~FontFacade() { FcFini(); } + +Asset FontFacade::get_font_asset(const string & font_family) { + FcPattern * raw_pattern + = FcNameParse(reinterpret_cast<const FcChar8 *>(font_family.c_str())); + if (raw_pattern == NULL) throw runtime_error("Failed to create font pattern."); + + unique_ptr<FcPattern, function<void(FcPattern *)>> pattern{ + raw_pattern, [](FcPattern * p) { FcPatternDestroy(p); }}; + + FcConfig * config = FcConfigGetCurrent(); + if (config == NULL) throw runtime_error("Failed to get current Fontconfig configuration."); + + FcResult result; + FcPattern * raw_matched_pattern = FcFontMatch(config, pattern.get(), &result); + if (raw_matched_pattern == NULL) throw runtime_error("No matching font found."); + + unique_ptr<FcPattern, function<void(FcPattern *)>> matched_pattern + = {raw_matched_pattern, [](FcPattern * p) { FcPatternDestroy(p); }}; + + FcChar8 * file_path = nullptr; + FcResult res = FcPatternGetString(matched_pattern.get(), FC_FILE, 0, &file_path); + if (res != FcResultMatch || file_path == NULL) + throw runtime_error("Failed to get font file path."); + + string font_file_path = reinterpret_cast<const char *>(file_path); + return Asset(font_file_path); +} diff --git a/src/crepe/facade/FontFacade.h b/src/crepe/facade/FontFacade.h new file mode 100644 index 0000000..9761070 --- /dev/null +++ b/src/crepe/facade/FontFacade.h @@ -0,0 +1,34 @@ +#pragma once + +#include <memory> + +#include "../api/Asset.h" + +namespace crepe { + +/** + * + * \brief Font facade class for converting font family names to absolute file paths + * + */ +class FontFacade { +public: + FontFacade(); + ~FontFacade(); + FontFacade(const FontFacade & other) = delete; + FontFacade & operator=(const FontFacade & other) = delete; + FontFacade(FontFacade && other) noexcept = delete; + FontFacade & operator=(FontFacade && other) noexcept = delete; + /** + * + * \brief Facade function to convert a font_family into an asset. + * + * This function uses the FontConfig library to convert a font family name (Arial, Inter, Helvetica) and converts it to the font source path. + * This function returns a default font path if the font_family name doesnt exist or cant be found + * \param font_family Name of the font family name. + * \return Asset with filepath to the corresponding font. + */ + Asset get_font_asset(const std::string & font_family); +}; + +} // namespace crepe diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index a1a6f97..4818c96 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -6,6 +6,7 @@ #include <SDL2/SDL_rect.h> #include <SDL2/SDL_render.h> #include <SDL2/SDL_surface.h> +#include <SDL2/SDL_ttf.h> #include <SDL2/SDL_video.h> #include <array> #include <cmath> @@ -31,6 +32,9 @@ using namespace std; SDLContext::SDLContext(Mediator & mediator) { dbg_trace(); + if (TTF_Init() == -1) { + throw runtime_error(format("SDL_ttf initialization failed: {}", TTF_GetError())); + } if (SDL_Init(SDL_INIT_VIDEO) != 0) { throw runtime_error(format("SDLContext: SDL_Init error: {}", SDL_GetError())); } @@ -72,121 +76,27 @@ SDLContext::~SDLContext() { // thread that SDL_Init() was called on? This has caused problems for me // before. IMG_Quit(); + TTF_Quit(); SDL_Quit(); } -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; +Keycode SDLContext::sdl_to_keycode(SDL_Scancode sdl_key) { + if (!lookup_table.contains(sdl_key)) return Keycode::NONE; + return lookup_table.at(sdl_key); +} - return table; - }(); +const keyboard_state_t & SDLContext::get_keyboard_state() { + SDL_PumpEvents(); + const Uint8 * current_state = SDL_GetKeyboardState(nullptr); - if (sdl_key < 0 || sdl_key >= SDL_NUM_SCANCODES) { - return Keycode::NONE; - } + for (int i = 0; i < SDL_NUM_SCANCODES; ++i) { - return LOOKUP_TABLE[sdl_key]; + Keycode key = sdl_to_keycode(static_cast<SDL_Scancode>(i)); + if (key != Keycode::NONE) { + this->keyboard_state[key] = current_state[i] != 0; + } + } + return this->keyboard_state; } MouseButton SDLContext::sdl_to_mousebutton(Uint8 sdl_button) { @@ -364,8 +274,8 @@ ivec2 SDLContext::get_size(const Texture & ctx) { return size; } -std::vector<SDLContext::EventData> SDLContext::get_events() { - std::vector<SDLContext::EventData> event_list; +std::vector<EventData> SDLContext::get_events() { + std::vector<EventData> event_list; SDL_Event event; const CameraAuxiliaryData & cam = this->cam_aux_data; while (SDL_PollEvent(&event)) { @@ -374,61 +284,135 @@ std::vector<SDLContext::EventData> SDLContext::get_events() { mouse_pos.y = (event.button.y - cam.bar_size.y) / cam.render_scale.y; switch (event.type) { case SDL_QUIT: - event_list.push_back(EventData{ - .event_type = SDLContext::EventType::SHUTDOWN, - }); + event_list.push_back({.event_type = 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), + .event_type = EventType::KEY_DOWN, + .data = { + .key_data = { + .key = this->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), + .event_type = EventType::KEY_UP, + .data = { + .key_data = { + .key = this->sdl_to_keycode(event.key.keysym.scancode), + .key_repeat = event.key.repeat != 0, + }, + }, }); break; + case SDL_MOUSEBUTTONDOWN: event_list.push_back(EventData{ - .event_type = SDLContext::EventType::MOUSEDOWN, - .mouse_button = sdl_to_mousebutton(event.button.button), - .mouse_position = mouse_pos, + .event_type = EventType::MOUSE_DOWN, + .data = { + .mouse_data = { + .mouse_button = this->sdl_to_mousebutton(event.button.button), + .mouse_position = mouse_pos, + }, + }, }); break; - case SDL_MOUSEBUTTONUP: { - int x, y; - SDL_GetMouseState(&x, &y); + case SDL_MOUSEBUTTONUP: event_list.push_back(EventData{ - .event_type = SDLContext::EventType::MOUSEUP, - .mouse_button = sdl_to_mousebutton(event.button.button), - .mouse_position = mouse_pos, + .event_type = EventType::MOUSE_UP, + .data = { + .mouse_data = { + .mouse_button = this->sdl_to_mousebutton(event.button.button), + .mouse_position = mouse_pos, + }, + }, }); - } break; + break; - case SDL_MOUSEMOTION: { - event_list.push_back( - EventData{.event_type = SDLContext::EventType::MOUSEMOVE, - .mouse_position = mouse_pos, - .rel_mouse_move = {event.motion.xrel, event.motion.yrel}}); - } break; + case SDL_MOUSEMOTION: + event_list.push_back(EventData{ + .event_type = EventType::MOUSE_MOVE, + .data = { + .mouse_data = { + .mouse_position = mouse_pos, + .rel_mouse_move = {event.motion.xrel, event.motion.yrel}, + }, + }, + }); + break; - case SDL_MOUSEWHEEL: { + case SDL_MOUSEWHEEL: event_list.push_back(EventData{ - .event_type = SDLContext::EventType::MOUSEWHEEL, - .mouse_position = mouse_pos, - // TODO: why is this needed? - .scroll_direction = event.wheel.y < 0 ? -1 : 1, - .scroll_delta = event.wheel.preciseY, + .event_type = EventType::MOUSE_WHEEL, + .data = { + .mouse_data = { + .mouse_position = mouse_pos, + .scroll_direction = event.wheel.y < 0 ? -1 : 1, + .scroll_delta = event.wheel.preciseY, + }, + }, }); - } break; + break; + case SDL_WINDOWEVENT: + this->handle_window_event(event.window, event_list); + break; } } + return event_list; } + +void SDLContext::handle_window_event(const SDL_WindowEvent & window_event, + std::vector<EventData> & event_list) { + switch (window_event.event) { + case SDL_WINDOWEVENT_EXPOSED: + event_list.push_back(EventData{EventType::WINDOW_EXPOSE}); + break; + case SDL_WINDOWEVENT_RESIZED: + event_list.push_back(EventData{ + .event_type = EventType::WINDOW_RESIZE, + .data = { + .window_data = { + .resize_dimension = {window_event.data1, window_event.data2} + }, + }, + }); + break; + case SDL_WINDOWEVENT_MOVED: + event_list.push_back(EventData{ + .event_type = EventType::WINDOW_MOVE, + .data = { + .window_data = { + .move_delta = {window_event.data1, window_event.data2} + }, + }, + }); + break; + + case SDL_WINDOWEVENT_MINIMIZED: + event_list.push_back(EventData{EventType::WINDOW_MINIMIZE}); + break; + case SDL_WINDOWEVENT_MAXIMIZED: + event_list.push_back(EventData{EventType::WINDOW_MAXIMIZE}); + break; + case SDL_WINDOWEVENT_FOCUS_GAINED: + event_list.push_back(EventData{EventType::WINDOW_FOCUS_GAIN}); + break; + case SDL_WINDOWEVENT_FOCUS_LOST: + event_list.push_back(EventData{EventType::WINDOW_FOCUS_LOST}); + break; + } +} + void SDLContext::set_color_texture(const Texture & texture, const Color & color) { SDL_SetTextureColorMod(texture.get_img(), color.r, color.g, color.b); SDL_SetTextureAlphaMod(texture.get_img(), color.a); } + +Asset SDLContext::get_font_from_name(const std::string & font_family) { + return this->font_facade.get_font_asset(font_family); +} diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index bcadf87..b687f87 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -9,17 +9,20 @@ #include <functional> #include <memory> #include <string> +#include <unordered_map> +#include "../types.h" #include "api/Camera.h" #include "api/Color.h" #include "api/KeyCodes.h" #include "api/Sprite.h" #include "api/Transform.h" - #include "types.h" -namespace crepe { +#include "EventData.h" +#include "FontFacade.h" +namespace crepe { class Texture; class Mediator; @@ -69,29 +72,11 @@ 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. + */ + static SDLContext & get_instance(); public: SDLContext(const SDLContext &) = delete; @@ -122,18 +107,25 @@ public: * * \return Events that occurred since last call to `get_events()` */ - std::vector<SDLContext::EventData> get_events(); - + std::vector<EventData> get_events(); /** - * \brief Converts an SDL key code to the custom Keycode type. + * \brief Fills event_list with triggered window events * - * This method maps an SDL key code to the corresponding `Keycode` enum value, + * This method checks if any window events are triggered and adds them to the event_list. + * + */ + void handle_window_event(const SDL_WindowEvent & window_event, + std::vector<EventData> & event_list); + /** + * \brief Converts an SDL scan code to the custom Keycode type. + * + * This method maps an SDL scan 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. + * \param sdl_key The SDL scan code to convert. * \return The corresponding `Keycode` value or `Keycode::NONE` if the key is unrecognized. */ - Keycode sdl_to_keycode(SDL_Keycode sdl_key); + Keycode sdl_to_keycode(SDL_Scancode sdl_key); /** * \brief Converts an SDL mouse button code to the custom MouseButton type. @@ -145,6 +137,16 @@ public: * \return The corresponding `MouseButton` value or `MouseButton::NONE` if the key is unrecognized */ MouseButton sdl_to_mousebutton(Uint8 sdl_button); + /** + * \brief Gets the current state of the keyboard. + * + * Updates the internal keyboard state by checking the current key states using + * SDL's `SDL_GetKeyboardState()`, and returns a reference to the `keyboard_state_t`. + * + * \return A constant reference to the `keyboard_state_t`, which holds the state + * of each key (true = pressed, false = not pressed). + */ + const keyboard_state_t & get_keyboard_state(); public: /** @@ -240,6 +242,124 @@ private: * - this is defined in this class because get_events() needs this information aswell */ CameraAuxiliaryData cam_aux_data; + +private: + //! instance of the font_facade + FontFacade font_facade{}; + +public: + /** + * \brief Function to Get asset from font_family + * + * This function uses the FontFacade function to convert a font_family to an asset. + * + * \param font_family name of the font style that needs to be used (will return an asset with default font path of the font_family doesnt exist) + * + * \return asset with the font style absolute path + */ + Asset get_font_from_name(const std::string & font_family); + //! variable to store the state of each key (true = pressed, false = not pressed) + keyboard_state_t keyboard_state; + //! lookup table for converting SDL_SCANCODES to Keycodes + const std::unordered_map<SDL_Scancode, Keycode> lookup_table + = {{SDL_SCANCODE_SPACE, Keycode::SPACE}, + {SDL_SCANCODE_APOSTROPHE, Keycode::APOSTROPHE}, + {SDL_SCANCODE_COMMA, Keycode::COMMA}, + {SDL_SCANCODE_MINUS, Keycode::MINUS}, + {SDL_SCANCODE_PERIOD, Keycode::PERIOD}, + {SDL_SCANCODE_SLASH, Keycode::SLASH}, + {SDL_SCANCODE_0, Keycode::D0}, + {SDL_SCANCODE_1, Keycode::D1}, + {SDL_SCANCODE_2, Keycode::D2}, + {SDL_SCANCODE_3, Keycode::D3}, + {SDL_SCANCODE_4, Keycode::D4}, + {SDL_SCANCODE_5, Keycode::D5}, + {SDL_SCANCODE_6, Keycode::D6}, + {SDL_SCANCODE_7, Keycode::D7}, + {SDL_SCANCODE_8, Keycode::D8}, + {SDL_SCANCODE_9, Keycode::D9}, + {SDL_SCANCODE_SEMICOLON, Keycode::SEMICOLON}, + {SDL_SCANCODE_EQUALS, Keycode::EQUAL}, + {SDL_SCANCODE_A, Keycode::A}, + {SDL_SCANCODE_B, Keycode::B}, + {SDL_SCANCODE_C, Keycode::C}, + {SDL_SCANCODE_D, Keycode::D}, + {SDL_SCANCODE_E, Keycode::E}, + {SDL_SCANCODE_F, Keycode::F}, + {SDL_SCANCODE_G, Keycode::G}, + {SDL_SCANCODE_H, Keycode::H}, + {SDL_SCANCODE_I, Keycode::I}, + {SDL_SCANCODE_J, Keycode::J}, + {SDL_SCANCODE_K, Keycode::K}, + {SDL_SCANCODE_L, Keycode::L}, + {SDL_SCANCODE_M, Keycode::M}, + {SDL_SCANCODE_N, Keycode::N}, + {SDL_SCANCODE_O, Keycode::O}, + {SDL_SCANCODE_P, Keycode::P}, + {SDL_SCANCODE_Q, Keycode::Q}, + {SDL_SCANCODE_R, Keycode::R}, + {SDL_SCANCODE_S, Keycode::S}, + {SDL_SCANCODE_T, Keycode::T}, + {SDL_SCANCODE_U, Keycode::U}, + {SDL_SCANCODE_V, Keycode::V}, + {SDL_SCANCODE_W, Keycode::W}, + {SDL_SCANCODE_X, Keycode::X}, + {SDL_SCANCODE_Y, Keycode::Y}, + {SDL_SCANCODE_Z, Keycode::Z}, + {SDL_SCANCODE_LEFTBRACKET, Keycode::LEFT_BRACKET}, + {SDL_SCANCODE_BACKSLASH, Keycode::BACKSLASH}, + {SDL_SCANCODE_RIGHTBRACKET, Keycode::RIGHT_BRACKET}, + {SDL_SCANCODE_GRAVE, Keycode::GRAVE_ACCENT}, + {SDL_SCANCODE_ESCAPE, Keycode::ESCAPE}, + {SDL_SCANCODE_RETURN, Keycode::ENTER}, + {SDL_SCANCODE_TAB, Keycode::TAB}, + {SDL_SCANCODE_BACKSPACE, Keycode::BACKSPACE}, + {SDL_SCANCODE_INSERT, Keycode::INSERT}, + {SDL_SCANCODE_DELETE, Keycode::DELETE}, + {SDL_SCANCODE_RIGHT, Keycode::RIGHT}, + {SDL_SCANCODE_LEFT, Keycode::LEFT}, + {SDL_SCANCODE_DOWN, Keycode::DOWN}, + {SDL_SCANCODE_UP, Keycode::UP}, + {SDL_SCANCODE_PAGEUP, Keycode::PAGE_UP}, + {SDL_SCANCODE_PAGEDOWN, Keycode::PAGE_DOWN}, + {SDL_SCANCODE_HOME, Keycode::HOME}, + {SDL_SCANCODE_END, Keycode::END}, + {SDL_SCANCODE_CAPSLOCK, Keycode::CAPS_LOCK}, + {SDL_SCANCODE_SCROLLLOCK, Keycode::SCROLL_LOCK}, + {SDL_SCANCODE_NUMLOCKCLEAR, Keycode::NUM_LOCK}, + {SDL_SCANCODE_PRINTSCREEN, Keycode::PRINT_SCREEN}, + {SDL_SCANCODE_PAUSE, Keycode::PAUSE}, + {SDL_SCANCODE_F1, Keycode::F1}, + {SDL_SCANCODE_F2, Keycode::F2}, + {SDL_SCANCODE_F3, Keycode::F3}, + {SDL_SCANCODE_F4, Keycode::F4}, + {SDL_SCANCODE_F5, Keycode::F5}, + {SDL_SCANCODE_F6, Keycode::F6}, + {SDL_SCANCODE_F7, Keycode::F7}, + {SDL_SCANCODE_F8, Keycode::F8}, + {SDL_SCANCODE_F9, Keycode::F9}, + {SDL_SCANCODE_F10, Keycode::F10}, + {SDL_SCANCODE_F11, Keycode::F11}, + {SDL_SCANCODE_F12, Keycode::F12}, + {SDL_SCANCODE_KP_0, Keycode::KP0}, + {SDL_SCANCODE_KP_1, Keycode::KP1}, + {SDL_SCANCODE_KP_2, Keycode::KP2}, + {SDL_SCANCODE_KP_3, Keycode::KP3}, + {SDL_SCANCODE_KP_4, Keycode::KP4}, + {SDL_SCANCODE_KP_5, Keycode::KP5}, + {SDL_SCANCODE_KP_6, Keycode::KP6}, + {SDL_SCANCODE_KP_7, Keycode::KP7}, + {SDL_SCANCODE_KP_8, Keycode::KP8}, + {SDL_SCANCODE_KP_9, Keycode::KP9}, + {SDL_SCANCODE_LSHIFT, Keycode::LEFT_SHIFT}, + {SDL_SCANCODE_LCTRL, Keycode::LEFT_CONTROL}, + {SDL_SCANCODE_LALT, Keycode::LEFT_ALT}, + {SDL_SCANCODE_LGUI, Keycode::LEFT_SUPER}, + {SDL_SCANCODE_RSHIFT, Keycode::RIGHT_SHIFT}, + {SDL_SCANCODE_RCTRL, Keycode::RIGHT_CONTROL}, + {SDL_SCANCODE_RALT, Keycode::RIGHT_ALT}, + {SDL_SCANCODE_RGUI, Keycode::RIGHT_SUPER}, + {SDL_SCANCODE_MENU, Keycode::MENU}}; }; } // namespace crepe |