static void framebuffer_callback(GLFWwindow *window, int width, int height) { state.screen_width = width; state.screen_height = height; state.viewport.x = 0; state.viewport.y = 0; state.viewport.w = width; state.viewport.h = height; float current_aspect = (float)width / (float)height; float aspect_ratio = 4.f/3.f; if(current_aspect > aspect_ratio) { float new_width = height * aspect_ratio; state.viewport.x = (width - new_width) / 2; state.viewport.w = new_width; } else if(current_aspect < aspect_ratio) { float new_height = width / aspect_ratio; state.viewport.y = (height - new_height) / 2; state.viewport.h = new_height; } } static void toggle_fullscreen(bool enable) { static int windowed_x; static int windowed_y; static int windowed_width; static int windowed_height; if(enable) { // Save current windowed size and position glfwGetWindowPos(window, &windowed_x, &windowed_y); glfwGetWindowSize(window, &windowed_width, &windowed_height); GLFWmonitor *monitor = glfwGetPrimaryMonitor(); const GLFWvidmode *mode = glfwGetVideoMode(monitor); glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate); } else { // Restore to saved windowed position/size glfwSetWindowMonitor(window, 0, windowed_x, windowed_y, windowed_width, windowed_height, 0); // 0 = don't change refresh rate } } static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) { struct nes_state *nes_state = (struct nes_state*)glfwGetWindowUserPointer(window); if(action == GLFW_RELEASE) { switch(key) { case GLFW_KEY_F12: { state.toggle_crt_emulation = !state.toggle_crt_emulation; } break; case GLFW_KEY_F11: { if(!(mods & GLFW_MOD_SHIFT)) { if(state.fullscreen) { toggle_fullscreen(false); state.fullscreen = false; } else { toggle_fullscreen(true); state.fullscreen = true; } } else { #ifdef PROFILER state.overlay = !state.overlay; #endif } } break; default: break; } } }