Skip to content

Commit

Permalink
Add support for fullscreen + never grab mouse + resize window (#140)
Browse files Browse the repository at this point in the history
* Implement full-screen via ALT+ENTER

* Never grab mouse

* Allow resizable window + fix mouse when resizing/switching to full screen

* Keep aspect ratio of gl viewport when resizing window

* Fix mouse when resizing the window

* Fix off by one error
  • Loading branch information
madebr committed Sep 4, 2022
1 parent b3bdbb2 commit 8a21679
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 25 deletions.
64 changes: 57 additions & 7 deletions src/harness/io_platforms/sdl_gl.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ struct {
float x;
float y;
} sdl_window_scale;
int is_full_screen = 0;

tRenderer gl_renderer = {
GLRenderer_Init,
Expand All @@ -141,7 +142,11 @@ tRenderer gl_renderer = {
GLRenderer_BufferTexture,
GLRenderer_BufferMaterial,
GLRenderer_BufferModel,
GLRenderer_FlushBuffers
GLRenderer_FlushBuffers,
GLRenderer_GetRenderSize,
GLRenderer_GetWindowSize,
GLRenderer_SetWindowSize,
GLRenderer_GetViewport
};

tRenderer* Window_Create(char* title, int width, int height, int pRender_width, int pRender_height) {
Expand All @@ -161,17 +166,12 @@ tRenderer* Window_Create(char* title, int width, int height, int pRender_width,
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
width, height,
SDL_WINDOW_OPENGL);
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);

if (window == NULL) {
LOG_PANIC("Failed to create window");
}

// Don't grab the mouse when a debugger is present
if (!OS_IsDebuggerPresent()) {
SDL_SetRelativeMouseMode(SDL_TRUE);
}

sdl_window_scale.x = ((float)pRender_width) / width;
sdl_window_scale.y = ((float)pRender_height) / height;

Expand All @@ -192,14 +192,37 @@ tRenderer* Window_Create(char* title, int width, int height, int pRender_width,
return &gl_renderer;
}

// Checks whether the `flag_check` is the only modifier applied.
// e.g. is_only_modifier(event.key.keysym.mod, KMOD_ALT) returns true when only the ALT key was pressed
static int is_only_key_modifier(int modifier_flags, int flag_check) {
return (modifier_flags & flag_check) && (modifier_flags & (KMOD_CTRL | KMOD_SHIFT | KMOD_ALT | KMOD_GUI)) == (modifier_flags & flag_check);
}

void Window_PollEvents() {
SDL_Event event;
int dethrace_key;
int w_w, w_h;
int vp_x, vp_y;
int vp_w, vp_h;
int r_w, r_h;

while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYDOWN:
case SDL_KEYUP:
if (event.key.keysym.sym == SDLK_RETURN) {
if (event.key.type == SDL_KEYDOWN) {
if ((event.key.keysym.mod & (KMOD_CTRL | KMOD_SHIFT | KMOD_ALT | KMOD_GUI))) {
// Ignore keydown of RETURN when used together with some modifier
return;
}
} else if (event.key.type == SDL_KEYUP) {
if (is_only_key_modifier(event.key.keysym.mod, KMOD_ALT)) {
is_full_screen = !is_full_screen;
SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
}
}
}
dethrace_key = scancodes_sdl2dethrace[event.key.keysym.scancode];
if (dethrace_key == -1) {
LOG_WARN("unexpected scan code %s (%d)", SDL_GetScancodeName(event.key.keysym.scancode), event.key.keysym.scancode);
Expand All @@ -213,6 +236,18 @@ void Window_PollEvents() {
sdl_key_state[3] = sdl_key_state[2];
break;

case SDL_WINDOWEVENT:
switch (event.window.event) {
case SDL_WINDOWEVENT_SIZE_CHANGED:
SDL_GetWindowSize(window, &w_w, &w_h);
gl_renderer.SetWindowSize(w_w, w_h);
gl_renderer.GetViewport(&vp_x, &vp_y, &vp_w, &vp_h);
gl_renderer.GetRenderSize(&r_w, &r_h);
sdl_window_scale.x = (float)r_w / vp_w;
sdl_window_scale.y = (float)r_h / vp_h;
break;
}
break;
case SDL_QUIT:
LOG_PANIC("QuitGame");
break;
Expand Down Expand Up @@ -251,7 +286,22 @@ int Input_IsKeyDown(unsigned char scan_code) {
}

void Input_GetMousePosition(int* pX, int* pY) {
int vp_x, vp_y, vp_w, vp_h;

SDL_GetMouseState(pX, pY);
gl_renderer.GetViewport(&vp_x, &vp_y, &vp_w, &vp_h);
if (*pX < vp_x) {
*pX = vp_x;
} else if (*pX >= vp_x + vp_w) {
*pX = vp_x + vp_w - 1;
}
if (*pY < vp_y) {
*pY = vp_y;
} else if (*pY >= vp_y + vp_h) {
*pY = vp_y + vp_h - 1;
}
*pX -= vp_x;
*pY -= vp_y;
*pX *= sdl_window_scale.x;
*pY *= sdl_window_scale.y;
}
Expand Down
68 changes: 54 additions & 14 deletions src/harness/renderers/gl/gl_renderer.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,21 @@
extern float gCamera_hither;
extern float gCamera_yon;

GLuint screen_buffer_vao, screen_buffer_ebo;
GLuint screen_texture, palette_texture, depth_texture;
static GLuint screen_buffer_vao, screen_buffer_ebo;
static GLuint screen_texture, palette_texture, depth_texture;

GLuint shader_program_2d;
GLuint shader_program_3d;
GLuint framebuffer_id, framebuffer_texture = 0;
unsigned int rbo;
uint8_t gl_palette[4 * 256]; // RGBA
uint8_t* screen_buffer_flip_pixels;
uint16_t* depth_buffer_flip_pixels;
static GLuint shader_program_2d;
static GLuint shader_program_3d;
static GLuint framebuffer_id, framebuffer_texture = 0;
static uint8_t gl_palette[4 * 256]; // RGBA
static uint8_t* screen_buffer_flip_pixels;
static uint16_t* depth_buffer_flip_pixels;

int window_width, window_height, render_width, render_height;
static int window_width, window_height, render_width, render_height;
static int vp_x, vp_y, vp_width, vp_height;

br_pixelmap* last_shade_table = NULL;
int dirty_buffers = 0;
static br_pixelmap* last_shade_table = NULL;
static int dirty_buffers = 0;

struct {
GLuint pixels, pixels_transform;
Expand Down Expand Up @@ -177,12 +177,29 @@ void SetupFullScreenRectGeometry() {
glBindVertexArray(0);
}

void GLRenderer_Init(int width, int height, int pRender_width, int pRender_height) {
static void update_viewport() {
const float target_aspect_ratio = (float)render_width / render_height;
const float aspect_ratio = (float)window_width / window_height;

vp_width = window_width;
vp_height = window_height;
if (aspect_ratio != target_aspect_ratio) {
if (aspect_ratio > target_aspect_ratio) {
vp_width = window_height * target_aspect_ratio + .5f;
} else {
vp_height = window_width / target_aspect_ratio + .5f;
}
}
vp_x = (window_width - vp_width) / 2;
vp_y = (window_height - vp_height) / 2;
}

void GLRenderer_Init(int width, int height, int pRender_width, int pRender_height) {
window_width = width;
window_height = height;
render_width = pRender_width;
render_height = pRender_height;
update_viewport();

int maxTextureImageUnits;
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits);
Expand Down Expand Up @@ -339,7 +356,7 @@ void GLRenderer_EndScene() {
}

void GLRenderer_FullScreenQuad(uint8_t* screen_buffer, int width, int height) {
glViewport(0, 0, window_width, window_height);
glViewport(vp_x, vp_y, vp_width, vp_height);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_DEPTH_TEST);

Expand Down Expand Up @@ -637,3 +654,26 @@ void GLRenderer_FlushBuffers(br_pixelmap* color_buffer, br_pixelmap* depth_buffe
glClear(GL_COLOR_BUFFER_BIT);
dirty_buffers = 0;
}

void GLRenderer_GetRenderSize(int* width, int* height) {
*width = render_width;
*height = render_height;
}

void GLRenderer_GetWindowSize(int* width, int* height) {
*width = window_width;
*height = window_height;
}

void GLRenderer_SetWindowSize(int width, int height) {
window_width = width;
window_height = height;
update_viewport();
}

void GLRenderer_GetViewport(int* x, int* y, int* width, int* height) {
*x = vp_x;
*y = vp_y;
*width = vp_width;
*height = vp_height;
}
4 changes: 4 additions & 0 deletions src/harness/renderers/gl/gl_renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,9 @@ void GLRenderer_BufferMaterial(br_material* mat);
void GLRenderer_BufferModel(br_model* model);
void GLRenderer_ClearBuffers();
void GLRenderer_FlushBuffers(br_pixelmap* color_buffer, br_pixelmap* depth_buffer);
void GLRenderer_GetRenderSize(int* width, int* height);
void GLRenderer_GetWindowSize(int* width, int* height);
void GLRenderer_SetWindowSize(int width, int height);
void GLRenderer_GetViewport(int* x, int* y, int* width, int* height);

#endif
12 changes: 10 additions & 2 deletions src/harness/renderers/null.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ void Null_BufferTexture(br_pixelmap* pm) {}
void Null_BufferMaterial(br_material* mat) {}
void Null_BufferModel(br_model* model) {}
void Null_FlushBuffers(br_pixelmap* color_buffer, br_pixelmap* depth_buffer) {}
void Null_GetRenderSize(int* width, int* height) { *width = 640; *height = 480; }
void Null_GetWindowSize(int* width, int* height) { *width = 640; *height = 480; }
void Null_SetWindowSize(int width, int height) {}
void Null_GetViewportSize(int* x, int* y, int* width, int* height) { *x = 0; *y = 0; *width = 640; *height = 480; }

tRenderer null_renderer = {
Null_Init,
Expand All @@ -24,5 +28,9 @@ tRenderer null_renderer = {
Null_BufferTexture,
Null_BufferMaterial,
Null_BufferModel,
Null_FlushBuffers
};
Null_FlushBuffers,
Null_GetRenderSize,
Null_GetWindowSize,
Null_SetWindowSize,
Null_GetViewportSize
};
7 changes: 5 additions & 2 deletions src/harness/renderers/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ typedef struct tRenderer {
void (*BufferMaterial)(br_material* mat);
void (*BufferModel)(br_model* model);
void (*FlushBuffers)(br_pixelmap* color_buffer, br_pixelmap* depth_buffer);

void (*GetRenderSize)(int* width, int* height);
void (*GetWindowSize)(int* width, int* height);
void (*SetWindowSize)(int width, int height);
void (*GetViewport)(int* x, int* y, int* width, int* height);
} tRenderer;

#endif
#endif

0 comments on commit 8a21679

Please sign in to comment.