From bbbe69d73c6130717ae2bb1271d55657644b9c73 Mon Sep 17 00:00:00 2001 From: Piotr Krygier Date: Tue, 3 Mar 2026 11:26:43 +0100 Subject: [PATCH] Prepare for event system Moved stuff around. Create an entry point for RSE. Created base for events module Signed-off-by: Piotr Krygier --- events/meson.build | 17 ++++++ events/src/events_context.h | 37 +++++++++++ events/src/events_manager.c | 81 +++++++++++++++++++++++++ events/src/events_manager.h | 20 ++++++ graphics/rse_graphics.h | 9 ++- graphics/src/rse_graphics.c | 26 ++------ graphics/src/window.c | 12 +++- meson.build | 2 + red_scarf_engine/meson.build | 1 + red_scarf_engine/red_scarf_engine.h | 23 +++++++ red_scarf_engine/src/main.c | 28 ++------- red_scarf_engine/src/red_scarf_engine.c | 40 ++++++++++++ utilities/commons.h | 2 +- 13 files changed, 245 insertions(+), 53 deletions(-) create mode 100644 events/meson.build create mode 100644 events/src/events_context.h create mode 100644 events/src/events_manager.c create mode 100644 events/src/events_manager.h create mode 100644 red_scarf_engine/red_scarf_engine.h create mode 100644 red_scarf_engine/src/red_scarf_engine.c diff --git a/events/meson.build b/events/meson.build new file mode 100644 index 00000000..20d78d2f --- /dev/null +++ b/events/meson.build @@ -0,0 +1,17 @@ +rse_events_sources = [ + ] + +sdl3_dep = dependency('sdl3', + version : '>=3.4.0') + +rse_events_lib = shared_library( + 'rse_events', + rse_events_sources, + include_directories : [ + '../' + ], + dependencies : [ + ], + link_with: rse_utilities_lib, + install : true + ) diff --git a/events/src/events_context.h b/events/src/events_context.h new file mode 100644 index 00000000..016c35ca --- /dev/null +++ b/events/src/events_context.h @@ -0,0 +1,37 @@ +/** + * @file events_context.h + * @author Piotr Krygier (piotrkrygier@everyonencancode.xyz) + * @brief Events context for Red Scarf Engine + * @version 0.1 + * @date 2026-03-02 + * + * @copyright Copyright (c) 2026 + * + */ + +#ifndef EVENT_CONTEXT_H_ +#define EVENT_CONTEXT_H_ + +#include "SDL3/SDL_mouse.h" +#include "utilities/commons.h" + +struct mouse_event_data_t +{ + float x_pos; + float y_pos; + SDL_MouseButtonFlags mouse_buttons; +}; + +typedef rse_err_t (*rse_event_handler_t)(void*); + +struct event_handlers +{ + rse_event_handler_t mouse_event; +}; + +struct events_context +{ + struct event_handlers event_handlers; +}; + +#endif /* EVENT_CONTEXT_H_ */ diff --git a/events/src/events_manager.c b/events/src/events_manager.c new file mode 100644 index 00000000..d505482e --- /dev/null +++ b/events/src/events_manager.c @@ -0,0 +1,81 @@ +/** + * @file events_manager.c + * @author Piotr Krygier (piotrkrygier@everyonencancode.xyz) + * @brief Events manager for Red Scarf Engine + * @version 0.1 + * @date 2026-03-02 + * + * @copyright Copyright (c) 2026 + * + */ + +#include "events_manager.h" + +#include "SDL3/SDL_events.h" +#include "SDL3/SDL_mouse.h" +#include "events_context.h" +#include "utilities/commons.h" +#include "utilities/errors_common.h" + +static rse_err_t default_event(void* args) +{ + (void)args; + + return RSE_ERROR_NO_ERROR; +} + +static rse_err_t quit_event(void) +{ + return RSE_ERROR_NO_ERROR; +} + +static rse_err_t mouse_event(struct events_context* events_context) +{ + struct mouse_event_data_t mouse_data = {0}; + + mouse_data.mouse_buttons = SDL_GetMouseState(&mouse_data.x_pos, &mouse_data.y_pos); + + return events_context->event_handlers.mouse_event((void*)&mouse_data); +} + +rse_err_t events_init(struct events_context* events_context) +{ + events_context->event_handlers.mouse_event = default_event; + + return RSE_ERROR_NO_ERROR; +} + +rse_err_t events_set_event_handler(struct events_context* events_context, + enum RSE_EVENT_TYPE event_type, + rse_event_handler_t event_handler) +{ + switch (event_type) { + case RSE_EVENT_TYPE_MOUSE: + events_context->event_handlers.mouse_event = event_handler; + break; + default: + SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "Invalid event type provided"); + return RSE_ERROR_INVALID_PARAM; + } + + return RSE_ERROR_NO_ERROR; +} + +rse_err_t events_run(struct events_context* context) +{ + SDL_Event event; + rse_err_t status = RSE_ERROR_NO_ERROR; + + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_EVENT_QUIT: + STATUS_CHECK(quit_event()); + break; + case SDL_EVENT_MOUSE_BUTTON_DOWN: + STATUS_CHECK(mouse_event(context)); + break; + } + } + + return status; +} diff --git a/events/src/events_manager.h b/events/src/events_manager.h new file mode 100644 index 00000000..9c668912 --- /dev/null +++ b/events/src/events_manager.h @@ -0,0 +1,20 @@ +/** + * @file events_manager.h + * @author Piotr Krygier (piotrkrygier@everyonencancode.xyz) + * @brief Events manager for Red Scarf Engine + * @version 0.1 + * @date 2026-03-02 + * + * @copyright Copyright (c) 2026 + * + */ + +#ifndef EVENTS_MANAGER_H_ +#define EVENTS_MANAGER_H_ + +enum RSE_EVENT_TYPE { + RSE_EVENT_TYPE_MOUSE, +}; + + +#endif /* EVENTS_MANAGER_H_ */ diff --git a/graphics/rse_graphics.h b/graphics/rse_graphics.h index 5c0c3c08..5e23f4f6 100644 --- a/graphics/rse_graphics.h +++ b/graphics/rse_graphics.h @@ -1,10 +1,9 @@ #ifndef RSE_GRAPHICS_H #define RSE_GRAPHICS_H +#include "src/graphics_context.h" #include "utilities/commons.h" -struct rse_graphics_context_t; - /** * @brief Initializes graphics backend. This has to be called before any new mesh, texture or any other object is * added @@ -12,20 +11,20 @@ struct rse_graphics_context_t; * @param context Graphics context handle. Must be NULL! * @return rse_err_t RSE_ERROR_NO_ERROR on success */ -rse_err_t rse_graphics_init(struct rse_graphics_context_t** context); +rse_err_t rse_graphics_init(struct graphics_context_t* context); /** * @brief Runs graphics engine. This has to be called after all objects are added to the scene * * @return rse_err_t RSE_ERROR_NO_ERROR on success */ -int rse_graphics_run(void* arg); +rse_err_t rse_graphics_main_loop(struct graphics_context_t* context); /** * @brief Custom function for testing engine. TODO: Remove it whe releasing * */ -rse_err_t rse_graphics_test_function(struct rse_graphics_context_t* context); +rse_err_t rse_graphics_test_function(struct graphics_context_t* context); #endif /* RSE_GRAPHICS_H */ diff --git a/graphics/src/rse_graphics.c b/graphics/src/rse_graphics.c index 5a044d71..06d83c2d 100644 --- a/graphics/src/rse_graphics.c +++ b/graphics/src/rse_graphics.c @@ -106,32 +106,20 @@ static rse_err_t render_static_mesh(struct graphics_context_t* context, uint32_t return RSE_ERROR_NO_ERROR; } -rse_err_t rse_graphics_init(struct rse_graphics_context_t** context) +rse_err_t rse_graphics_init(struct graphics_context_t* context) { rse_err_t status = RSE_ERROR_NO_ERROR; - struct rse_graphics_context_t* ctx_ptr = NULL; - if (*context != NULL) { - SDL_LogCritical(SDL_LOG_CATEGORY_GPU, "Graphics already initialized!"); - return RSE_ERROR_ALREADY_INITIALIZED; - } - - rse_malloc(*context, sizeof(struct rse_graphics_context_t)); - ctx_ptr = *context; - rse_malloc(ctx_ptr->context, sizeof(struct graphics_context_t)); - rse_memset(ctx_ptr->context, 0, sizeof(struct graphics_context_t)); - - STATUS_CHECK(window_init(&ctx_ptr->context->window_handle, &ctx_ptr->context->is_framebuffer_resized)); - STATUS_CHECK(vulkan_init(ctx_ptr->context)); + STATUS_CHECK(window_init(&context->window_handle, &context->is_framebuffer_resized)); + STATUS_CHECK(vulkan_init(context)); return status; } #define TEXTURES_COUNT (2U) -rse_err_t rse_graphics_test_function(struct rse_graphics_context_t* rse_context) +rse_err_t rse_graphics_test_function(struct graphics_context_t* context) { rse_err_t status = RSE_ERROR_NO_ERROR; - struct graphics_context_t* context = rse_context->context; rse_id_t textures[TEXTURES_COUNT] = {0}; struct pipeline_t pipeline; rse_id_t descriptor_set_handle = 0; @@ -257,11 +245,9 @@ rse_err_t rse_graphics_test_function(struct rse_graphics_context_t* rse_context) return RSE_ERROR_NO_ERROR; } -int rse_graphics_run(void* arg) +rse_err_t rse_graphics_main_loop(struct graphics_context_t* context) { rse_err_t status = RSE_ERROR_NO_ERROR; - struct rse_graphics_context_t* rse_context = (struct rse_graphics_context_t*)arg; - struct graphics_context_t* context = rse_context->context; STATUS_CHECK(vulkan_run(context)); STATUS_CHECK(window_loop(context)); @@ -270,8 +256,6 @@ int rse_graphics_run(void* arg) window_terminate(context->window_handle); rse_free(context->debug_overlay.pixels); - rse_free(context); - rse_free(rse_context); return status; } diff --git a/graphics/src/window.c b/graphics/src/window.c index b9d6983c..e5342008 100644 --- a/graphics/src/window.c +++ b/graphics/src/window.c @@ -18,6 +18,7 @@ #include #include +#include "SDL3/SDL_log.h" #include "utilities/commons.h" #include "utilities/errors_common.h" #include "utilities/time_utils.h" @@ -43,7 +44,8 @@ rse_err_t window_init(SDL_Window** window_handle, bool* is_framebuffer_resized) { SDL_Init(SDL_INIT_VIDEO); // TODO: Move to initial phase of RSE initialization - (void)is_framebuffer_resized;; // TODO: Actually use this parameter? + (void)is_framebuffer_resized; + // TODO: Actually use this parameter? *window_handle = SDL_CreateWindow("RedScarfEngine", 1024, 768, SDL_WINDOW_VULKAN); @@ -65,8 +67,12 @@ rse_err_t window_loop(struct graphics_context_t* context) while (0 == done) { while (SDL_PollEvent(&event)) { - if (SDL_EVENT_QUIT == event.type) { - done = 1; + switch (event.type) { + case SDL_EVENT_QUIT: + done = 1; + break; + case SDL_EVENT_MOUSE_BUTTON_DOWN: + break; } } diff --git a/meson.build b/meson.build index 279f0eee..803f11ae 100644 --- a/meson.build +++ b/meson.build @@ -8,5 +8,7 @@ project('RedScarfEngine', subdir('utilities') subdir('graphics') +subdir('events') + subdir('red_scarf_engine') diff --git a/red_scarf_engine/meson.build b/red_scarf_engine/meson.build index c400b614..cb65ee1a 100644 --- a/red_scarf_engine/meson.build +++ b/red_scarf_engine/meson.build @@ -1,4 +1,5 @@ red_scarf_engine_srcs = [ + 'src/red_scarf_engine.c', 'src/main.c' ] diff --git a/red_scarf_engine/red_scarf_engine.h b/red_scarf_engine/red_scarf_engine.h new file mode 100644 index 00000000..9709fce0 --- /dev/null +++ b/red_scarf_engine/red_scarf_engine.h @@ -0,0 +1,23 @@ +/** + * @file red_scarf_engine.h + * @author Piotr Krygier (piotrkrygier@everyonencancode.xyz) + * @brief Red Scarf Engine main entry point + * @version 0.1 + * @date 2026-03-03 + * + * @copyright Copyright (c) 2026 + * + */ + +#ifndef RED_SCARF_ENGINE_H_ +#define RED_SCARF_ENGINE_H_ + +#include "utilities/commons.h" +#include "utilities/errors_common.h" + +typedef struct rse_context_t* rse_context; + +rse_err_t rse_init(rse_context* context); +rse_err_t rse_run(rse_context context); + +#endif /* RED_SCARF_ENGINE_H_ */ diff --git a/red_scarf_engine/src/main.c b/red_scarf_engine/src/main.c index 83d751b0..0a29450a 100644 --- a/red_scarf_engine/src/main.c +++ b/red_scarf_engine/src/main.c @@ -1,33 +1,15 @@ -#include -#include -#include "graphics/rse_graphics.h" -#include "utilities/errors_common.h" -#include "SDL3/SDL_thread.h" -#include "utilities/time_utils.h" - +#include "red_scarf_engine.h" int main(int argc, char** argv) { rse_err_t status = RSE_ERROR_NO_ERROR; - struct rse_graphics_context_t* context = NULL; - SDL_Thread* graphics_task = NULL; + rse_context context; + (void)argc; (void)argv; - SDL_SetLogPriorities(SDL_LOG_PRIORITY_VERBOSE); - - STATUS_CHECK(time_init()); - STATUS_CHECK(rse_graphics_init(&context)); - STATUS_CHECK(rse_graphics_test_function(context)); - - graphics_task = SDL_CreateThread(rse_graphics_run, "graphics_task", (void*) context); - - if (NULL == graphics_task) { - SDL_LogCritical(SDL_LOG_CATEGORY_GPU, "Failed to create graphics task"); - exit(1); - } - - SDL_WaitThread(graphics_task, NULL); + STATUS_CHECK(rse_init(&context)); + STATUS_CHECK(rse_run(context)); return 0; } diff --git a/red_scarf_engine/src/red_scarf_engine.c b/red_scarf_engine/src/red_scarf_engine.c new file mode 100644 index 00000000..b1fc76bb --- /dev/null +++ b/red_scarf_engine/src/red_scarf_engine.c @@ -0,0 +1,40 @@ +#include "red_scarf_engine.h" +#include "graphics/rse_graphics.h" +#include "graphics/src/graphics_context.h" +#include "utilities/commons.h" +#include "utilities/errors_common.h" +#include "utilities/time_utils.h" + +struct rse_context_t { + struct graphics_context_t graphics_context; +}; + +rse_err_t rse_init(rse_context* context) +{ + rse_err_t status = RSE_ERROR_NO_ERROR; + struct rse_context_t* rse_context = NULL; + + rse_malloc(*context, sizeof(struct rse_context_t)); + + rse_context = *context; + + SDL_SetLogPriorities(SDL_LOG_PRIORITY_VERBOSE); + + STATUS_CHECK(time_init()); + rse_graphics_init(&(rse_context->graphics_context)); + + return RSE_ERROR_NO_ERROR; +} + +rse_err_t rse_run(rse_context context) +{ + rse_err_t status = RSE_ERROR_NO_ERROR; + + STATUS_CHECK(rse_graphics_test_function(&context->graphics_context)); + + STATUS_CHECK(rse_graphics_main_loop(&context->graphics_context)); + + rse_free(context); + + return status; +} diff --git a/utilities/commons.h b/utilities/commons.h index 84781dd9..f3dfe427 100644 --- a/utilities/commons.h +++ b/utilities/commons.h @@ -22,7 +22,7 @@ */ #ifndef RSE_TEST #define rse_malloc(ptr, size) \ - ptr = malloc(size); \ + ptr = calloc(1, size); \ if (ptr == NULL) { \ SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "Memory allocation failure"); \ exit(1); \