Make windows close-able with the window buttons
A window can now be closed by clicking on the X in the title bar. The input controller is already running in its own thread, calling the handler-functions given to it on an event's arrival.
This commit is contained in:
parent
3ddac3bfe0
commit
44885e161d
|
@ -7,12 +7,16 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include <voxula/internals/utility.h>
|
||||
#include <voxula/internals/window.h>
|
||||
|
||||
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
|
||||
|
|
|
@ -1,7 +1,47 @@
|
|||
#include <voxula/internals/core.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
|
||||
#ifndef VOXULA_WINDOW_H
|
||||
#define VOXULA_WINDOW_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <threads.h>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <voxula/internals/utility.h>
|
||||
|
||||
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
|
|
@ -1,3 +1,4 @@
|
|||
{module}/inc-c
|
||||
{module-folder}/utility/inc-c
|
||||
{module-folder}/ecs/inc-c
|
||||
{dependencies}/inc-c
|
|
@ -0,0 +1,164 @@
|
|||
#include <voxula/internals/window.h>
|
||||
#include <glad/glad.h>
|
||||
|
||||
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);
|
||||
}
|
Loading…
Reference in New Issue