internal inline void monitor_key(GLFWwindow *window, u16 *key_state, i32 glfw_key, Input_Key haru_key) { u16& state = key_state[haru_key]; if (glfwGetKey(window, glfw_key) == GLFW_PRESS) { if (!(state & KEY_STATE_IS_DOWN)) state |= KEY_STATE_JUST_PRESSED; state |= KEY_STATE_IS_DOWN; } else if (glfwGetKey(window, glfw_key) == GLFW_RELEASE) { if (state & KEY_STATE_IS_DOWN) state |= KEY_STATE_JUST_RELEASED; state &= ~KEY_STATE_IS_DOWN; } } internal inline void monitor_mouse_btn(GLFWwindow *window, u16 *mouse_btn_state, i32 glfw_btn, Mouse_Button haru_btn) { u16& state = mouse_btn_state[haru_btn]; if (glfwGetMouseButton(window, glfw_btn) == GLFW_PRESS) { if (!(state & MOUSE_BTN_STATE_IS_DOWN)) state |= MOUSE_BTN_STATE_JUST_PRESSED; state |= MOUSE_BTN_STATE_IS_DOWN; } else if (glfwGetMouseButton(window, glfw_btn) == GLFW_RELEASE) { if (state & MOUSE_BTN_STATE_IS_DOWN) state |= MOUSE_BTN_STATE_JUST_RELEASED; state &= ~MOUSE_BTN_STATE_IS_DOWN; } } internal void run_main_loop(GLFWwindow *window, Arena *arena, App_State &app) { f32 delta_time; chr::time_point last_saved_time = chr::high_resolution_clock::now(); b8 running = true; while (running) { chr::time_point frame_start = chr::high_resolution_clock::now(); u64 time_since_prev_frame_us = chr::duration_cast(frame_start - last_saved_time).count(); delta_time = time_since_prev_frame_us * 0.000'001f; last_saved_time = frame_start; glfwPollEvents(); // Update window size { Window_Data &wdata = app.win_data; i32 prev_width = wdata.width; i32 prev_height = wdata.height; glfwGetWindowSize(window, &wdata.width, &wdata.height); wdata.size_just_changed = prev_width != wdata.width || prev_height != wdata.height; } ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS || glfwWindowShouldClose(window)) { running = false; break; } b32 focused = glfwGetWindowAttrib(window, GLFW_FOCUSED); if (focused) { // TODO Update keyboard / mouse // Update keyboard u16 *key_state = app.user_input.key_state; monitor_key(window, key_state, GLFW_KEY_Q, KEY_Q); monitor_key(window, key_state, GLFW_KEY_UP, KEY_UP); monitor_key(window, key_state, GLFW_KEY_DOWN, KEY_DOWN); monitor_key(window, key_state, GLFW_KEY_LEFT, KEY_LEFT); monitor_key(window, key_state, GLFW_KEY_RIGHT, KEY_RIGHT); monitor_key(window, key_state, GLFW_KEY_LEFT_ALT, KEY_ALT); monitor_key(window, key_state, GLFW_KEY_TAB, KEY_TAB); // Update mouse f64 mposx, mposy; glfwGetCursorPos(window, &mposx, &mposy); app.user_input.mouse_pos.x = (i32)mposx; app.user_input.mouse_pos.y = (i32)mposy; u16 *mouse_btn_state = app.user_input.mouse_btn_state; monitor_mouse_btn(window, mouse_btn_state, GLFW_MOUSE_BUTTON_LEFT, MOUSE_BTN_LEFT); monitor_mouse_btn(window, mouse_btn_state, GLFW_MOUSE_BUTTON_RIGHT, MOUSE_BTN_RIGHT); } update_and_render(arena, app, delta_time); ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); glfwSwapBuffers(window); } }