Gears-C/src/game.c

332 lines
6.6 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 gInit(gGameCtx *ctx)
{
Assert(rInit(), "Failed to initialize the renderer");
ctx->arena = ArenaCreateDebug(MB(16), __LINE__);
ctx->gui.vertices = MakeArray(ctx->arena, rUIVertex, 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, gWindowWidget, 32);
ctx->window_len = 0;
ctx->buttons = MakeArray(ctx->arena, gButtonWidget, 64);
ctx->btn_len = 0;
}
static void gDestroy()
{
rDestroy();
}
// ::Game::Init::Functions::End::
// ::Game::GameLoop::Functions::Start::
static void gFrameStartNew()
{
}
static void gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count)
{
ArenaFree(vFrameArena());
gPrepareGUICtx(ctx);
gHandleInputs(inputs, i_count);
rFrameBegin();
vTextureCleanUp();
u64 index = vFrameIndex();
rDescHandle yoder = rMeshLoad(MODEL_YODA);
ctx->pc.mesh_index = yoder.desc_index;
ModelMeta model_meta = apGetModelMeta(MODEL_YODA);
rViewportSize(&ctx->pc.res);
ctx->pc.time = (f32)pCPUTimerRead();
rawptr vert_buffer = rBufferGUIVertMapping();
rawptr idx_buffer = rBufferGUIIdxMapping();
MemCpy(vert_buffer, ctx->gui.vertices, sizeof(rUIVertex) * ctx->gui.vertices_len);
MemCpy(idx_buffer, ctx->gui.indices, sizeof(u32) * ctx->gui.indices_len);
vBufferQueueWait();
rPipelineBind(rPIPELINE_PBR, rPT_GRAPHICS);
rPushConstantsSet(&ctx->pc);
//rBufferBindGUIVertex();
//rBufferBindGUIIndex();
rBufferBindMesh(&ctx->pc, yoder);
rDrawIndexed(model_meta.i_count, 1);
rFrameFinish();
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 gHandleInputs(pGameInput *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 gPrepareGUICtx(gGameCtx *ctx)
{
ctx->gui.has_grabbed = false;
}
static b32 gButton(gGameCtx *ctx, char *label, f32 x0, f32 y0, f32 x1, f32 y1)
{
gButtonWidget *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;
}
//gRect(&ctx->gui, btn->p0, btn->p1, (Vec4){ .r = 0.1f, .g = 0.9f, .b = 0.4f, .a = 1.0f });
return btn->pressed;
}
static b32 gWindow(gGameCtx *ctx, char *title, f32 x0, f32 y0, f32 x1, f32 y1, rDescHandle handle)
{
gWindowWidget *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;
}
gRect(&ctx->gui, win->p0, win->p1, (Vec4){ .r = 0.1f, .g = 0.3f, .b = 0.8f, .a = 1.0f }, handle);
return true;
}
static void gRect(gUICtx *ctx, Vec2 p0, Vec2 p1, Vec4 col, rDescHandle handle)
{
ctx->vertices[ctx->vertices_len].p0 = p0;
ctx->vertices[ctx->vertices_len].p1 = p1;
ctx->vertices[ctx->vertices_len].col = col;
ctx->vertices[ctx->vertices_len].tex_idx = handle.desc_index;
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::