diff --git a/modules/core/inc-c/voxula/internals/core.h b/modules/core/inc-c/voxula/internals/core.h index cc94e23..0e03a73 100644 --- a/modules/core/inc-c/voxula/internals/core.h +++ b/modules/core/inc-c/voxula/internals/core.h @@ -7,12 +7,16 @@ #include #include +#include typedef struct vx_core vx_core_s; struct vx_core { vx_uuid_table_s *uuid_table; + vx_input_controller_s *input_controller; + vx_window_s *main_window; + bool running; }; #endif // VOXULA_CORE_H diff --git a/modules/core/src-c/main.c b/modules/core/src-c/main.c index 0baadb1..02845eb 100644 --- a/modules/core/src-c/main.c +++ b/modules/core/src-c/main.c @@ -1,7 +1,47 @@ #include +void vx_handle_window_close(vx_window_s *window, vx_window_event_s event) +{ + if(event.type == VX_WINDOW_EVENT_CLOSE) + { + vx_core_s *core = window->userdata; + core->input_controller->running = false; + vx_win_hide(core->main_window); + return; + } + if(event.type == VX_WINDOW_EVENT_QUIT) + { + vx_core_s *core = window->userdata;; + core->input_controller->running = false; + core->running = false; + } +} + int main(int argc, char **argv) { - puts("The build-system is working!"); - return -1; + if(argc > 1) + { + if( ! strcmp(argv[1], "--help")) + { + puts("The Voxula voxel-game engine."); + return 0; + } + } + vx_core_s core; + core.uuid_table = vx_new_uuid_table(); + core.input_controller = vx_new_input_controller(); + core.main_window = vx_new_window(core.input_controller); + core.main_window->fn_handle_input = vx_handle_window_close; + core.main_window->userdata = &core; + core.running = true; + vx_start_input_controller(core.input_controller); + while(core.running) + { + vx_win_show(core.main_window); + vx_win_present(core.main_window); + SDL_Delay(1000 / 30); + } + vx_free_window(core.main_window); + + return 0; } diff --git a/modules/window/inc-c/voxula/internals/window.h b/modules/window/inc-c/voxula/internals/window.h new file mode 100644 index 0000000..0e75699 --- /dev/null +++ b/modules/window/inc-c/voxula/internals/window.h @@ -0,0 +1,122 @@ + +#ifndef VOXULA_WINDOW_H +#define VOXULA_WINDOW_H + +#include +#include + +#include +#include + +typedef struct vx_input_controller vx_input_controller_s; +typedef struct vx_window vx_window_s; +typedef struct vx_window_event vx_window_event_s; + +typedef enum +{ + VX_WINDOW_EVENT_INVALID = 0, + + VX_WINDOW_EVENT_KEY_PRESS, + VX_WINDOW_EVENT_KEY_RELEASE, + + VX_WINDOW_EVENT_MOUSE_PRESS, + VX_WINDOW_EVENT_MOUSE_RELEASE, + VX_WINDOW_EVENT_MOUSE_MOVE, + VX_WINDOW_EVENT_MOUSE_SCROLL, + + VX_WINDOW_EVENT_CLOSE = 254, + VX_WINDOW_EVENT_QUIT = 255 + +} vx_window_event_e; + +typedef enum +{ + VX_KEY_MODIFIER_NONE = 0, + + VX_KEY_MODIFIER_LEFT_CONTROL = 1, + VX_KEY_MODIFIER_RIGHT_CONTROL = 1 << 1, + VX_KEY_MODIFIER_CONTROL = 1 | (1 << 1), + + VX_KEY_MODIFIER_LEFT_SHIFT = 1 << 2, + VX_KEY_MODIFIER_RIGHT_SHIFT = 1 << 3, + VX_KEY_MODIFIER_SHIFT = (1 << 2) | (1 << 3) + +} vx_key_modifier_e; + +struct vx_window_event +{ + vx_window_event_e type; + vx_window_s *association; + + union vx_window_event_union + { + struct vx_key_press + { + uint16_t modifiers; + uint32_t character; + } key_press; + + struct vx_key_release + { + uint16_t modifiers; + uint32_t character; + } key_release; + + struct vx_mouse_press + { + vx_vec2f_s position_change; + } mouse_press; + + struct vx_mouse_release + { + vx_vec2f_s position; + } mouse_release; + + struct vx_mouse_move + { + vx_vec2f_s position; + } mouse_move; + + struct vx_mouse_scroll + { + float amount; + } mouse_scroll; + } specifics; +}; + +struct vx_window +{ + vx_input_controller_s *controller; + SDL_Window *window; + SDL_GLContext gl_context; + void (*fn_handle_input)(vx_window_s *window, vx_window_event_s event); + void *userdata; +}; + +struct vx_input_controller +{ + uint32_t window_list_capacity; + uint32_t num_windows; + vx_window_s **windows; + + bool running; + thrd_t thread; +}; + +vx_input_controller_s * vx_new_input_controller(); +void vx_free_input_controller(vx_input_controller_s *controller); + +void vx_start_input_controller(vx_input_controller_s *controller); +void vx_stop_input_controller(vx_input_controller_s *controller); + +vx_window_s * vx_new_window(vx_input_controller_s *controller); +void vx_free_window(vx_window_s *window); + +void vx_win_set_title(vx_window_s *window, const char *title); +void vx_win_resize(vx_window_s *window, vx_vec2u_s size); +void vx_win_move(vx_window_s *window, vx_vec2i_s position); +void vx_win_show(vx_window_s *window); +void vx_win_hide(vx_window_s *window); +void vx_win_present(vx_window_s *window); + +#endif // VOXULA_WINDOW_H diff --git a/modules/window/includes.txt b/modules/window/includes.txt index e206f9f..dbdc404 100644 --- a/modules/window/includes.txt +++ b/modules/window/includes.txt @@ -1,3 +1,4 @@ {module}/inc-c {module-folder}/utility/inc-c -{module-folder}/ecs/inc-c \ No newline at end of file +{module-folder}/ecs/inc-c +{dependencies}/inc-c \ No newline at end of file diff --git a/modules/window/src-c/window.c b/modules/window/src-c/window.c new file mode 100644 index 0000000..0b8a3a4 --- /dev/null +++ b/modules/window/src-c/window.c @@ -0,0 +1,164 @@ +#include +#include + +vx_window_s * vx_find_window_with_id(vx_input_controller_s *controller, uint32_t window_id) +{ + uint32_t window_index = 0; + while(window_index < controller->num_windows) + { + if(window_id == SDL_GetWindowID(controller->windows[window_index]->window)) + { + return controller->windows[window_index]; + } + ++window_index; + } + return NULL; +} + +int vx_input_controller_mainloop(void *userdata) +{ + vx_input_controller_s *controller = userdata; + controller->running = true; + while(controller->running) + { + SDL_Event event; + while(SDL_PollEvent(&event)) + { + if(event.type == SDL_WINDOWEVENT_CLOSE) + { + vx_window_s *window = vx_find_window_with_id(controller, event.window.windowID); + if(window == NULL) + { + continue; + } + if(window->fn_handle_input == NULL) + { + continue; + } + vx_window_event_s quit_event; + quit_event.type = VX_WINDOW_EVENT_CLOSE; + quit_event.association = window; + window->fn_handle_input(window, quit_event); + } + if(event.type == SDL_QUIT) + { + vx_window_event_s quit_event; + quit_event.type = VX_WINDOW_EVENT_QUIT; + quit_event.association = NULL; + uint32_t window_index = 0; + while(window_index < controller->num_windows) + { + vx_window_s *window = controller->windows[window_index]; + window->fn_handle_input(window, quit_event); + ++window_index; + } + controller->running = false; + } + } + SDL_Delay(2); + } + return 0; +} + +vx_input_controller_s * vx_new_input_controller() +{ + vx_input_controller_s *controller = malloc(sizeof(vx_input_controller_s)); + controller->num_windows = 0; + controller->window_list_capacity = 8; + controller->windows = malloc(controller->window_list_capacity * sizeof(vx_window_s)); + thrd_create(&controller->thread, vx_input_controller_mainloop, controller); + + return controller; +} + +void vx_free_input_controller(vx_input_controller_s *controller) +{ + uint32_t window_index = 0; + while(window_index < controller->num_windows) + { + vx_window_s *window = controller->windows[window_index]; + vx_free_window(window); + ++window_index; + } + controller->running = false; + thrd_join(controller->thread, NULL); + free(controller->windows); + free(controller); +} + +void vx_start_input_controller(vx_input_controller_s *controller) +{ + controller->running = true; + thrd_detach(controller->thread); +} + +void vx_stop_input_controller(vx_input_controller_s *controller) +{ + controller->running = false; +} + +vx_window_s * vx_new_window(vx_input_controller_s *controller) +{ + vx_window_s *window = malloc(sizeof(vx_window_s)); + if(controller->window_list_capacity >= controller->num_windows) + { + controller->window_list_capacity *= 2; + controller->windows = realloc( + controller->windows, + controller->window_list_capacity + * sizeof(vx_window_s *) + ); + } + controller->windows[controller->num_windows++] = window; + window->controller = controller; + window->window = SDL_CreateWindow( + "Voxula Window", + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + 1200, + 750, + SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL + ); + window->gl_context = SDL_GL_CreateContext(window->window); + gladLoadGLLoader(SDL_GL_GetProcAddress); + gladLoadGL(); + + return window; +} + +void vx_free_window(vx_window_s *window) +{ + SDL_DestroyWindow(window->window); + SDL_GL_DeleteContext(window->gl_context); + free(window); +} + +void vx_win_set_title(vx_window_s *window, const char *title) +{ + SDL_SetWindowTitle(window->window, title); +} + +void vx_win_resize(vx_window_s *window, vx_vec2u_s size) +{ + SDL_SetWindowSize(window->window, size.x, size.y); +} + +void vx_win_move(vx_window_s *window, vx_vec2i_s position) +{ + SDL_SetWindowPosition(window->window, position.x, position.y); +} + +void vx_win_show(vx_window_s *window) +{ + SDL_ShowWindow(window->window); +} + +void vx_win_hide(vx_window_s *window) +{ + SDL_HideWindow(window->window); +} + +void vx_win_present(vx_window_s *window) +{ + SDL_GL_SwapWindow(window->window); +}