Gears-C/src/game.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::