338 lines
6.9 KiB
C
338 lines
6.9 KiB
C
// ::Game::Globals::Start::
|
|
|
|
// TEMP
|
|
|
|
u32 selected_rect = 0;
|
|
b8 mouse_pressed = false;
|
|
b8 mouse_clicked = false;
|
|
i16 mouse_prev_pos_x = 0;
|
|
i16 mouse_prev_pos_y = 0;
|
|
i16 mouse_pos_x = 0;
|
|
i16 mouse_pos_y = 0;
|
|
|
|
// ::Game::Globals::End::
|
|
|
|
|
|
|
|
// ::Game::Init::Functions::Start::
|
|
|
|
static void InitializeGame(Arena *arena, GameContext *ctx, Arena *ctx_arena)
|
|
{
|
|
Assert(InitRenderer(arena), "Failed to initialize the renderer");
|
|
|
|
ctx->gui.vertices = MakeArray(ctx_arena, GUIVertex, 128);
|
|
ctx->gui.vertices_len = 0;
|
|
ctx->gui.indices = MakeArray(ctx_arena, u32, 768);
|
|
ctx->gui.indices_len = 0;
|
|
ctx->gui.instance_count = 0;
|
|
|
|
ctx->windows = MakeArray(ctx_arena, GUIWindow, 32);
|
|
ctx->window_len = 0;
|
|
|
|
ctx->buttons = MakeArray(ctx_arena, GUIButton, 64);
|
|
ctx->btn_len = 0;
|
|
|
|
ctx->arena = arena;
|
|
}
|
|
|
|
static void DestroyGame()
|
|
{
|
|
DestroyRenderer();
|
|
}
|
|
|
|
// ::Game::Init::Functions::End::
|
|
|
|
|
|
|
|
// ::Game::GameLoop::Functions::Start::
|
|
|
|
static void RunCycle(GameContext *ctx, GameInput *inputs, u32 i_count)
|
|
{
|
|
ResetBufferQueue();
|
|
|
|
PrepareGUICtx(ctx);
|
|
|
|
HandleInputs(inputs, i_count);
|
|
|
|
if (UIButton(ctx, "Show 2", 150.0f, 150.0f, 200.0f, 200.0f))
|
|
{
|
|
UIWindow(ctx, "Window 2", 500.0f, 500.0f, 600.0f, 600.0f);
|
|
}
|
|
|
|
if (UIButton(ctx, "Show 1", 50.0f, 50.0f, 100.0f, 100.0f))
|
|
{
|
|
UIWindow(ctx, "Window 1", 200.0f, 200.0f, 400.0f, 400.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 = MakeArray(ctx->arena, RenderBuffer, 1);
|
|
vertex_buffer->type = RENDER_BUFFER_TYPE_VERTEX;
|
|
vertex_buffer->size = sizeof(GUIVertex) * ctx->gui.vertices_len;
|
|
|
|
RenderBuffer *index_buffer = MakeArray(ctx->arena, RenderBuffer, 1);
|
|
index_buffer->type = RENDER_BUFFER_TYPE_INDEX,
|
|
index_buffer->size = sizeof(u32) * ctx->gui.indices_len,
|
|
|
|
CreateAndUploadToBuffer(vertex_buffer, ctx->gui.vertices);
|
|
CreateAndUploadToBuffer(index_buffer, ctx->gui.indices);
|
|
|
|
WaitForBufferQueue();
|
|
|
|
BeginFrame();
|
|
|
|
BindPipeline(PIPELINE_GUI, PIPELINE_TYPE_GRAPHICS);
|
|
|
|
SetPushConstants(&ctx->pc);
|
|
|
|
BindVertexBuffer(vertex_buffer);
|
|
BindIndexBuffer(index_buffer);
|
|
|
|
DrawIndexed(6, ctx->gui.instance_count);
|
|
|
|
FinishFrame();
|
|
|
|
FreeBuffers(vertex_buffer, 1);
|
|
FreeBuffers(index_buffer, 1);
|
|
|
|
ctx->gui.vertices_len = 0;
|
|
ctx->gui.indices_len = 0;
|
|
ctx->gui.instance_count = 0;
|
|
ArenaFree(ctx->arena);
|
|
}
|
|
|
|
// ::Game::GameLoop::Functions::End::
|
|
|
|
|
|
|
|
// ::Game::Inputs::Functions::Start::
|
|
|
|
static void HandleInputs(GameInput *inputs, u32 count)
|
|
{
|
|
mouse_clicked = false;
|
|
|
|
for (u32 i = 0; i < count; i++)
|
|
{
|
|
if (inputs[i].type == GI_KEYBOARD)
|
|
{
|
|
if (inputs[i].kb_code == KB_1)
|
|
{
|
|
selected_rect = 0;
|
|
break;
|
|
}
|
|
else if (inputs[i].kb_code == KB_2)
|
|
{
|
|
selected_rect = 1;
|
|
break;
|
|
}
|
|
else if (inputs[i].kb_code == KB_3)
|
|
{
|
|
selected_rect = 2;
|
|
break;
|
|
}
|
|
else if (inputs[i].kb_code == KB_4)
|
|
{
|
|
selected_rect = 3;
|
|
break;
|
|
}
|
|
}
|
|
else if (inputs[i].type == GI_MOUSE)
|
|
{
|
|
if (inputs[i].m_code == M_LEFT_CLICK)
|
|
{
|
|
mouse_pressed = inputs[i].pressed;
|
|
if (!inputs[i].pressed)
|
|
mouse_clicked = true;
|
|
}
|
|
}
|
|
else if (inputs[i].type == GI_MOTION)
|
|
{
|
|
mouse_prev_pos_x = mouse_pos_x;
|
|
mouse_prev_pos_y = mouse_pos_y;
|
|
mouse_pos_x = inputs[i].motion_ev.x;
|
|
mouse_pos_y = inputs[i].motion_ev.y;
|
|
}
|
|
}
|
|
}
|
|
|
|
// ::Game::Inputs::Functions::End::
|
|
|
|
|
|
|
|
// ::Game::GUI::Functions::Start::
|
|
|
|
static inline void PrepareGUICtx(GameContext *ctx)
|
|
{
|
|
ctx->gui.has_grabbed = false;
|
|
}
|
|
|
|
static b32 UIButton(GameContext *ctx, char *label, f32 x0, f32 y0, f32 x1, f32 y1)
|
|
{
|
|
GUIButton *btn = NULL;
|
|
u64 id = HashFromString(String8CStr(label));
|
|
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 = HashFromString(String8CStr(title));
|
|
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 DrawRect(GUIContext *ctx, Vec2 p0, Vec2 p1, Vec4 col)
|
|
{
|
|
ctx->vertices[ctx->vertices_len].p0 = p0;
|
|
ctx->vertices[ctx->vertices_len].p1 = p1;
|
|
ctx->vertices[ctx->vertices_len].col = col;
|
|
|
|
ctx->vertices_len += 1;
|
|
|
|
ctx->indices[ctx->indices_len] = ctx->indices_len;
|
|
ctx->indices[ctx->indices_len+1] = ctx->indices_len+1;
|
|
ctx->indices[ctx->indices_len+2] = ctx->indices_len+2;
|
|
ctx->indices[ctx->indices_len+3] = ctx->indices_len+1;
|
|
ctx->indices[ctx->indices_len+4] = ctx->indices_len+2;
|
|
ctx->indices[ctx->indices_len+5] = ctx->indices_len+3;
|
|
|
|
ctx->indices_len += 6;
|
|
|
|
ctx->instance_count += 1;
|
|
}
|
|
|
|
// ::Game::GUI::Functions::End::
|