// ::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::