added basic gui widgets
This commit is contained in:
parent
8dd01f9dfc
commit
ff07cbc572
@ -59,6 +59,13 @@ void RunThreadFunc(pthread_t *th, u32 *u, void *func)
|
|||||||
pthread_create(th, NULL, func, u);
|
pthread_create(th, NULL, func, u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define BIL 1000000000L
|
||||||
|
|
||||||
|
u64 GetDiff(struct timespec *start, struct timespec *end)
|
||||||
|
{
|
||||||
|
return BIL * (end->tv_sec - start->tv_sec) + end->tv_nsec - start->tv_nsec;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
u8 *mem = (u8 *)MemAllocZeroed(MB(64));
|
u8 *mem = (u8 *)MemAllocZeroed(MB(64));
|
||||||
|
|||||||
209
src/game.c
209
src/game.c
@ -8,11 +8,11 @@ static void InitializeGame(Arena *arena, GameContext *ctx, Arena *ctx_arena)
|
|||||||
ctx->gui.indices_len = 0;
|
ctx->gui.indices_len = 0;
|
||||||
ctx->gui.instance_count = 0;
|
ctx->gui.instance_count = 0;
|
||||||
|
|
||||||
ctx->window.p0.x = 0.0f;
|
ctx->windows = ArenaAlloc(ctx_arena, sizeof(GUIWindow) * 32);
|
||||||
ctx->window.p0.y = 0.0f;
|
ctx->window_len = 0;
|
||||||
|
|
||||||
ctx->window.p1.x = 100.0f;
|
ctx->buttons = ArenaAlloc(ctx_arena, sizeof(GUIButton) * 64);
|
||||||
ctx->window.p1.y = 100.0f;
|
ctx->btn_len = 0;
|
||||||
|
|
||||||
ctx->arena = arena;
|
ctx->arena = arena;
|
||||||
}
|
}
|
||||||
@ -24,6 +24,7 @@ static void DestroyGame()
|
|||||||
|
|
||||||
u32 selected_rect = 0;
|
u32 selected_rect = 0;
|
||||||
b8 mouse_pressed = false;
|
b8 mouse_pressed = false;
|
||||||
|
b8 mouse_clicked = false;
|
||||||
i16 mouse_prev_pos_x = 0;
|
i16 mouse_prev_pos_x = 0;
|
||||||
i16 mouse_prev_pos_y = 0;
|
i16 mouse_prev_pos_y = 0;
|
||||||
i16 mouse_pos_x = 0;
|
i16 mouse_pos_x = 0;
|
||||||
@ -31,6 +32,8 @@ i16 mouse_pos_y = 0;
|
|||||||
|
|
||||||
static void HandleInputs(GameInput *inputs, u32 count)
|
static void HandleInputs(GameInput *inputs, u32 count)
|
||||||
{
|
{
|
||||||
|
mouse_clicked = false;
|
||||||
|
|
||||||
for (u32 i = 0; i < count; i++)
|
for (u32 i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if (inputs[i].type == GI_KEYBOARD)
|
if (inputs[i].type == GI_KEYBOARD)
|
||||||
@ -59,7 +62,11 @@ static void HandleInputs(GameInput *inputs, u32 count)
|
|||||||
else if (inputs[i].type == GI_MOUSE)
|
else if (inputs[i].type == GI_MOUSE)
|
||||||
{
|
{
|
||||||
if (inputs[i].m_code == M_LEFT_CLICK)
|
if (inputs[i].m_code == M_LEFT_CLICK)
|
||||||
|
{
|
||||||
mouse_pressed = inputs[i].pressed;
|
mouse_pressed = inputs[i].pressed;
|
||||||
|
if (!inputs[i].pressed)
|
||||||
|
mouse_clicked = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (inputs[i].type == GI_MOTION)
|
else if (inputs[i].type == GI_MOTION)
|
||||||
{
|
{
|
||||||
@ -71,46 +78,188 @@ static void HandleInputs(GameInput *inputs, u32 count)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void PrepareGUICtx(GameContext *ctx)
|
||||||
|
{
|
||||||
|
ctx->gui.has_grabbed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 StrToU32(char *str)
|
||||||
|
{
|
||||||
|
u32 result = 0;
|
||||||
|
for (; *str != '\0'; str++)
|
||||||
|
{
|
||||||
|
result += (u32)(*str);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static b32 UIButton(GameContext *ctx, char *label, f32 x0, f32 y0, f32 x1, f32 y1)
|
||||||
|
{
|
||||||
|
GUIButton *btn = NULL;
|
||||||
|
u32 id = StrToU32(label) + (u32)(x0 + y0 + x1 + y1);
|
||||||
|
if (ctx->btn_len == 0)
|
||||||
|
{
|
||||||
|
ctx->buttons[0].p0.x = x0;
|
||||||
|
ctx->buttons[0].p0.y = y0;
|
||||||
|
ctx->buttons[0].p1.x = x1;
|
||||||
|
ctx->buttons[0].p1.y = y1;
|
||||||
|
ctx->buttons[0].id = id;
|
||||||
|
ctx->buttons[0].pressed = false;
|
||||||
|
ctx->buttons[0].pressed_prev = false;
|
||||||
|
|
||||||
|
btn = &ctx->buttons[0];
|
||||||
|
ctx->btn_len += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < ctx->btn_len; i++)
|
||||||
|
{
|
||||||
|
if (ctx->buttons[i].id == id)
|
||||||
|
{
|
||||||
|
btn = &ctx->buttons[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (btn == NULL)
|
||||||
|
{
|
||||||
|
ctx->btn_len += 1;
|
||||||
|
btn = &ctx->buttons[ctx->btn_len];
|
||||||
|
|
||||||
|
btn->p0.x = x0;
|
||||||
|
btn->p0.y = y0;
|
||||||
|
btn->p1.x = x1;
|
||||||
|
btn->p1.y = y1;
|
||||||
|
btn->id = id;
|
||||||
|
btn->pressed = false;
|
||||||
|
btn->pressed_prev = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert(btn != NULL, "button is null");
|
||||||
|
|
||||||
|
if (mouse_clicked
|
||||||
|
&& !ctx->gui.has_grabbed
|
||||||
|
&& mouse_pos_x > btn->p0.x
|
||||||
|
&& mouse_pos_x < btn->p1.x
|
||||||
|
&& mouse_pos_y > btn->p0.y
|
||||||
|
&& mouse_pos_y < btn->p1.y)
|
||||||
|
{
|
||||||
|
btn->pressed = !btn->pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawRect(&ctx->gui, btn->p0, btn->p1, (Vec4){ .r = 0.1f, .g = 0.9f, .b = 0.4f, .a = 1.0f });
|
||||||
|
|
||||||
|
return btn->pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static b32 UIWindow(GameContext *ctx, char *title, f32 x0, f32 y0, f32 x1, f32 y1)
|
||||||
|
{
|
||||||
|
GUIWindow *win = NULL;
|
||||||
|
u32 id = StrToU32(title) + (u32)(x0 + y0 + x1 + y1);
|
||||||
|
if (ctx->window_len == 0)
|
||||||
|
{
|
||||||
|
ctx->windows[0].p0.x = x0;
|
||||||
|
ctx->windows[0].p0.y = y0;
|
||||||
|
ctx->windows[0].p1.x = x1;
|
||||||
|
ctx->windows[0].p1.y = y1;
|
||||||
|
ctx->windows[0].id = id;
|
||||||
|
|
||||||
|
win = &ctx->windows[0];
|
||||||
|
ctx->window_len += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < ctx->window_len; i++)
|
||||||
|
{
|
||||||
|
if (ctx->windows[i].id == id)
|
||||||
|
{
|
||||||
|
win = &ctx->windows[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (win == NULL)
|
||||||
|
{
|
||||||
|
ctx->window_len += 1;
|
||||||
|
win = &ctx->windows[ctx->window_len];
|
||||||
|
|
||||||
|
win->p0.x = x0;
|
||||||
|
win->p0.y = y0;
|
||||||
|
win->p1.x = x1;
|
||||||
|
win->p1.y = y1;
|
||||||
|
win->id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert(win != NULL, "window is null");
|
||||||
|
|
||||||
|
if (mouse_pressed && !win->grabbed
|
||||||
|
&& mouse_pos_x > win->p0.x
|
||||||
|
&& mouse_pos_x < win->p1.x
|
||||||
|
&& mouse_pos_y > win->p0.y
|
||||||
|
&& mouse_pos_y < win->p1.y
|
||||||
|
&& !ctx->gui.has_grabbed)
|
||||||
|
{
|
||||||
|
win->grabbed = true;
|
||||||
|
ctx->gui.has_grabbed = true;
|
||||||
|
|
||||||
|
win->grabbed_pos.x = (f32)mouse_pos_x - win->p0.x;
|
||||||
|
win->grabbed_pos.y = (f32)mouse_pos_y - win->p0.y;
|
||||||
|
}
|
||||||
|
else if (!mouse_pressed && win->grabbed)
|
||||||
|
{
|
||||||
|
win->grabbed = false;
|
||||||
|
|
||||||
|
win->grabbed_pos.x = 0.0f;
|
||||||
|
win->grabbed_pos.y = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (win->grabbed)
|
||||||
|
{
|
||||||
|
f32 w = win->p1.x - win->p0.x;
|
||||||
|
f32 h = win->p1.y - win->p0.y;
|
||||||
|
|
||||||
|
win->p0.x = (f32)(mouse_pos_x) - win->grabbed_pos.x;
|
||||||
|
win->p0.y = (f32)(mouse_pos_y) - win->grabbed_pos.y;
|
||||||
|
win->p1.x = win->p0.x + w;
|
||||||
|
win->p1.y = win->p0.y + h;
|
||||||
|
|
||||||
|
ctx->gui.has_grabbed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawRect(&ctx->gui, win->p0, win->p1, (Vec4){ .r = 0.1f, .g = 0.3f, .b = 0.8f, .a = 1.0f });
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void RunCycle(GameContext *ctx, GameInput *inputs, u32 i_count)
|
static void RunCycle(GameContext *ctx, GameInput *inputs, u32 i_count)
|
||||||
{
|
{
|
||||||
__atomic_store_n(&renderer.vk.imm.job_count, 0, __ATOMIC_RELEASE);
|
__atomic_store_n(&renderer.vk.imm.job_count, 0, __ATOMIC_RELEASE);
|
||||||
__atomic_store_n(&renderer.vk.imm.remaining_count, 0, __ATOMIC_RELEASE);
|
__atomic_store_n(&renderer.vk.imm.remaining_count, 0, __ATOMIC_RELEASE);
|
||||||
|
|
||||||
GetViewportSize(&ctx->pc.res);
|
PrepareGUICtx(ctx);
|
||||||
|
|
||||||
HandleInputs(inputs, i_count);
|
HandleInputs(inputs, i_count);
|
||||||
|
|
||||||
if (mouse_pressed && !ctx->window.grabbed
|
if (UIButton(ctx, "Show 2", 150.0f, 150.0f, 200.0f, 200.0f))
|
||||||
&& mouse_pos_x > ctx->window.p0.x
|
|
||||||
&& mouse_pos_x < ctx->window.p1.x
|
|
||||||
&& mouse_pos_y > ctx->window.p0.y
|
|
||||||
&& mouse_pos_y < ctx->window.p1.y)
|
|
||||||
{
|
{
|
||||||
ctx->window.grabbed = true;
|
UIWindow(ctx, "Window 2", 500.0f, 500.0f, 600.0f, 600.0f);
|
||||||
|
|
||||||
ctx->window.grabbed_pos.x = (f32)mouse_pos_x - ctx->window.p0.x;
|
|
||||||
ctx->window.grabbed_pos.y = (f32)mouse_pos_y - ctx->window.p0.y;
|
|
||||||
}
|
|
||||||
else if (!mouse_pressed && ctx->window.grabbed)
|
|
||||||
{
|
|
||||||
ctx->window.grabbed = false;
|
|
||||||
|
|
||||||
ctx->window.grabbed_pos.x = 0.0f;
|
|
||||||
ctx->window.grabbed_pos.y = 0.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->window.grabbed)
|
if (UIButton(ctx, "Show 1", 50.0f, 50.0f, 100.0f, 100.0f))
|
||||||
{
|
{
|
||||||
f32 w = ctx->window.p1.x - ctx->window.p0.x;
|
UIWindow(ctx, "Window 1", 200.0f, 200.0f, 400.0f, 400.0f);
|
||||||
f32 h = ctx->window.p1.y - ctx->window.p0.y;
|
|
||||||
|
|
||||||
ctx->window.p0.x = (f32)(mouse_pos_x) - ctx->window.grabbed_pos.x;
|
|
||||||
ctx->window.p0.y = (f32)(mouse_pos_y) - ctx->window.grabbed_pos.y;
|
|
||||||
ctx->window.p1.x = ctx->window.p0.x + w;
|
|
||||||
ctx->window.p1.y = ctx->window.p0.y + h;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawRect(&ctx->gui, ctx->window.p0, ctx->window.p1, (Vec4){ .r = 0.1f, .g = 0.3f, .b = 0.8f, .a = 1.0f });
|
if (UIButton(ctx, "Show 3", 150.0f, 300.0f, 200.0f, 350.0f))
|
||||||
|
{
|
||||||
|
UIWindow(ctx, "Window 3", 250.0f, 500.0f, 400.0f, 650.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GetViewportSize(&ctx->pc.res);
|
||||||
|
|
||||||
|
|
||||||
RenderBuffer *vertex_buffer = ArenaAlloc(ctx->arena, sizeof(RenderBuffer));
|
RenderBuffer *vertex_buffer = ArenaAlloc(ctx->arena, sizeof(RenderBuffer));
|
||||||
vertex_buffer->type = RENDER_BUFFER_TYPE_VERTEX;
|
vertex_buffer->type = RENDER_BUFFER_TYPE_VERTEX;
|
||||||
|
|||||||
15
src/game.h
15
src/game.h
@ -5,15 +5,28 @@ typedef struct GUIWindow_t
|
|||||||
Vec2 p0;
|
Vec2 p0;
|
||||||
Vec2 p1;
|
Vec2 p1;
|
||||||
Vec2 grabbed_pos;
|
Vec2 grabbed_pos;
|
||||||
|
u32 id;
|
||||||
b8 grabbed;
|
b8 grabbed;
|
||||||
} GUIWindow;
|
} GUIWindow;
|
||||||
|
|
||||||
|
typedef struct GUIButton_t
|
||||||
|
{
|
||||||
|
Vec2 p0;
|
||||||
|
Vec2 p1;
|
||||||
|
u32 id;
|
||||||
|
b8 pressed;
|
||||||
|
b8 pressed_prev;
|
||||||
|
} GUIButton;
|
||||||
|
|
||||||
typedef struct GameContext_t
|
typedef struct GameContext_t
|
||||||
{
|
{
|
||||||
GUIContext gui;
|
GUIContext gui;
|
||||||
PushConst pc;
|
PushConst pc;
|
||||||
Arena *arena;
|
Arena *arena;
|
||||||
GUIWindow window;
|
GUIWindow *windows;
|
||||||
|
u32 window_len;
|
||||||
|
GUIButton *buttons;
|
||||||
|
u32 btn_len;
|
||||||
} GameContext;
|
} GameContext;
|
||||||
|
|
||||||
static void RunCycle(GameContext *ctx, GameInput *inputs, u32 i_count);
|
static void RunCycle(GameContext *ctx, GameInput *inputs, u32 i_count);
|
||||||
|
|||||||
@ -323,7 +323,7 @@ u8 *OSOpenFile(const char *)
|
|||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
b32 _ShouldQuit()
|
b32 ShouldQuit()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -201,7 +201,7 @@ void WaitForWindowEvent()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
b32 _ShouldQuit()
|
b32 ShouldQuit()
|
||||||
{
|
{
|
||||||
return global_quit;
|
return global_quit;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -255,4 +255,5 @@ typedef struct
|
|||||||
u32 *indices;
|
u32 *indices;
|
||||||
u32 indices_len;
|
u32 indices_len;
|
||||||
u32 instance_count;
|
u32 instance_count;
|
||||||
|
b8 has_grabbed;
|
||||||
} GUIContext;
|
} GUIContext;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user