From 9ed9f70ec584d4038b22091fd9554349f05f57cd Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Sun, 8 Mar 2026 20:45:36 -0500 Subject: [PATCH] run-time window aspect ratio and font resize --- Makefile | 3 +- font/terminus_256x256_16x32.data | Bin 0 -> 65536 bytes include/font.h | 66 ++++++++++++++++++------------- include/opengl.h | 3 ++ include/test.h | 2 +- include/window.h | 13 ++++++ main.lua | 16 ++++++-- src/font.cpp | 35 +++++++++++++++- src/opengl.c | 24 ++++++++++- src/test.cpp | 37 +++++++++++------ src/window.cpp | 10 +++++ 11 files changed, 163 insertions(+), 46 deletions(-) create mode 100644 font/terminus_256x256_16x32.data create mode 100644 include/window.h create mode 100644 src/window.cpp diff --git a/Makefile b/Makefile index 151c32e..576d40b 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,8 @@ OBJS = \ src/gl.o \ src/opengl.o \ src/test.o \ - src/font.o + src/font.o \ + src/window.o all: test.so diff --git a/font/terminus_256x256_16x32.data b/font/terminus_256x256_16x32.data new file mode 100644 index 0000000000000000000000000000000000000000..2cd561d8d2b41dd780d2833f4bd5c1d94c4fa950 GIT binary patch literal 65536 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 literal 0 HcmV?d00001 diff --git a/include/font.h b/include/font.h index 718f912..fade51b 100644 --- a/include/font.h +++ b/include/font.h @@ -10,34 +10,44 @@ namespace font { int const glyph_height; }; - font_desc const ter_6x12 = { - .path = "font/terminus_128x64_6x12.data", - .texture_width = 128, - .texture_height = 64, - .glyph_width = 6, - .glyph_height = 12, - }; - font_desc const ter_8x16 = { - .path = "font/terminus_128x128_8x16.data", - .texture_width = 128, - .texture_height = 128, - .glyph_width = 8, - .glyph_height = 16, - }; - font_desc const ter_10x18 = { - .path = "font/terminus_256x128_10x18.data", - .texture_width = 256, - .texture_height = 128, - .glyph_width = 10, - .glyph_height = 18, - }; - font_desc const ter_12x24 = { - .path = "font/terminus_256x128_12x24.data", - .texture_width = 256, - .texture_height = 128, - .glyph_width = 12, - .glyph_height = 24, + font_desc const terminus[] = { + { + .path = "font/terminus_128x64_6x12.data", + .texture_width = 128, + .texture_height = 64, + .glyph_width = 6, + .glyph_height = 12, + }, + { + .path = "font/terminus_128x128_8x16.data", + .texture_width = 128, + .texture_height = 128, + .glyph_width = 8, + .glyph_height = 16, + }, + { + .path = "font/terminus_256x128_10x18.data", + .texture_width = 256, + .texture_height = 128, + .glyph_width = 10, + .glyph_height = 18, + }, + { + .path = "font/terminus_256x128_12x24.data", + .texture_width = 256, + .texture_height = 128, + .glyph_width = 12, + .glyph_height = 24, + }, + { + .path = "font/terminus_256x256_16x32.data", + .texture_width = 256, + .texture_height = 256, + .glyph_width = 16, + .glyph_height = 32, + }, }; + int const terminus_length = (sizeof (terminus)) / (sizeof (font_desc)); struct font { font_desc const * desc; @@ -52,5 +62,7 @@ namespace font { void load_element_buffer(); void load_shader(); font load_font(font_desc const& desc); + void load_fonts(font * const fonts, font_desc const * const descs, int length); + int best_font(font_desc const * const descs, int length); void draw_string(font const& font, char const * const s, int x, int y); } diff --git a/include/opengl.h b/include/opengl.h index 03483de..affe9d7 100644 --- a/include/opengl.h +++ b/include/opengl.h @@ -4,6 +4,9 @@ extern "C" { #endif +extern char const * g_source_path; +extern int g_source_path_length; + void * read_file(const char * filename, int * out_size); unsigned int compile_from_files(const char * vertex_path, diff --git a/include/test.h b/include/test.h index 46c64d2..fd9880f 100644 --- a/include/test.h +++ b/include/test.h @@ -4,7 +4,7 @@ extern "C" { #endif - void load(); + void load(const char * source_path); void draw_hud(); void draw(); void update(float lx, float ly, float rx, float ry, float tl, float tr, diff --git a/include/window.h b/include/window.h new file mode 100644 index 0000000..da18878 --- /dev/null +++ b/include/window.h @@ -0,0 +1,13 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + + extern float g_window_width; + extern float g_window_height; + void update_window(int width, int height); + +#ifdef __cplusplus +} +#endif diff --git a/main.lua b/main.lua index 6436a95..3e3035c 100644 --- a/main.lua +++ b/main.lua @@ -5,15 +5,17 @@ function init() joysticks = love.joystick.getJoysticks() ffi.cdef[[ -void load(); +void load(const char * source_path); +void update_window(int width, int height); void draw(); void draw_hud(); void update(float lx, float ly, float rx, float ry, float tl, float tr, int up, int down, int left, int right); ]] - test = ffi.load("./test.so") - test.load() - + local source_path = love.filesystem.getSource() + test = ffi.load(source_path .. "/test.so") + test.load(source_path) + print(love.filesystem.getWorkingDirectory()) end local update = function(dt) @@ -52,6 +54,12 @@ function love.run() end end + local width + local height + local flags + width, height, flags = love.window.getMode() + test.update_window(width, height) + local dt = love.timer.step() update(dt) diff --git a/src/font.cpp b/src/font.cpp index 949be10..527e567 100644 --- a/src/font.cpp +++ b/src/font.cpp @@ -7,6 +7,7 @@ #include "opengl.h" #include "font.h" +#include "window.h" namespace font { @@ -94,6 +95,38 @@ namespace font { }; } + static inline int min(int a, int b) + { + return a < b ? a : b; + } + + int best_font(font_desc const * const descs, int length) + { + int dimension = min(g_window_width, g_window_height); + int ideal_height = (16 * dimension) / 1024; + //printf("ideal_height: %d\n", ideal_height); + int nearest = dimension; + int nearest_ix = -1; + for (int i = 0; i < length; i++) { + font_desc const& desc = descs[i]; + int distance = abs(desc.glyph_height - ideal_height); + if (distance < nearest) { + nearest = distance; + nearest_ix = i; + } + } + assert(nearest_ix != -1); + //printf("selected %d\n", descs[nearest_ix].glyph_height); + return nearest_ix; + } + + void load_fonts(font * const fonts, font_desc const * const descs, int length) + { + for (int i = 0; i < length; i++) { + fonts[i] = load_font(descs[i]); + } + } + inline static XMFLOAT2 glyph_coordinate(font const& font, int ord) { int c = ord - 32; @@ -110,7 +143,7 @@ namespace font { XMMATRIX transform = XMMatrixScaling(font.desc->glyph_width, font.desc->glyph_height, 0) * XMMatrixTranslation(x, -y, 0) - * XMMatrixScaling(2.0f / 1024.0f, 2.0f / 1024.0f, 0) + * XMMatrixScaling(2.0f / g_window_width, 2.0f / g_window_height, 0) * XMMatrixTranslation(-1, 1, 0); XMFLOAT4X4 transformf; XMStoreFloat4x4(&transformf, transform); diff --git a/src/opengl.c b/src/opengl.c index 52699ed..2affe8f 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -7,8 +7,30 @@ #include "glad/gl.h" #include "opengl.h" -void * read_file(const char * filename, int * out_size) +char const * g_source_path = NULL; +int g_source_path_length = 0; + +char const * join_path(char * buf, const char * filename) { + if (filename[0] == '/') + return filename; + + int filename_length = strlen(filename); + assert(filename_length + g_source_path_length + 2 < 1024); + + memcpy(buf, g_source_path, g_source_path_length); + buf[g_source_path_length] = '/'; + + memcpy(&buf[g_source_path_length + 1], filename, filename_length); + buf[g_source_path_length + 1 + filename_length] = 0; + return buf; +} + +void * read_file(const char * r_filename, int * out_size) +{ + char tmp[1024]; + char const * filename = join_path(tmp, r_filename); + FILE * f = fopen(filename, "rb"); if (f == NULL) { fprintf(stderr, "fopen(%s): %s\n", filename, strerror(errno)); diff --git a/src/test.cpp b/src/test.cpp index b526dcc..d90df24 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -7,6 +7,7 @@ #include "directxmath/directxmath.h" #include "test.h" #include "font.h" +#include "window.h" #include "data.inc" @@ -249,10 +250,14 @@ struct view_state { view_state view_state; -font::font ter_8x16 = {}; +font::font * terminus_fonts; -void load() +void load(const char * source_path) { + g_source_path_length = strlen(source_path); + assert(source_path[g_source_path_length - 1] != '/'); + g_source_path = source_path; + fprintf(stderr, "getproc %p\n", SDL_GL_GetProcAddress); gladLoadGL((GLADloadfunc)SDL_GL_GetProcAddress); @@ -280,7 +285,9 @@ void load() font::load_element_buffer(); font::load_shader(); - ter_8x16 = font::load_font(font::ter_8x16); + + terminus_fonts = (font::font *)malloc((sizeof (font::font)) * font::terminus_length); + font::load_fonts(terminus_fonts, font::terminus, font::terminus_length); } float _ry = 0.0; @@ -314,7 +321,8 @@ static inline int popcount(int x) return __builtin_popcount(x); } -void asdf(char * const buf, char const * const label, char const * const format, float value) +template +void labeled_value(char * const buf, char const * const label, char const * const format, T value) { const int label_length = strlen(label); memcpy(buf, label, label_length); @@ -328,13 +336,20 @@ void draw_hud() float y = 10.0f; - asdf(buf, "fov: ", "%.3f", view_state.fov); - font::draw_string(ter_8x16, buf, 10, y); - y += ter_8x16.desc->glyph_height; + int font_ix = font::best_font(font::terminus, font::terminus_length); + font::font const& ter_best = terminus_fonts[font_ix]; - asdf(buf, "pitch: ", "%.9f", view_state.pitch); - font::draw_string(ter_8x16, buf, 10, y); - y += ter_8x16.desc->glyph_height; + labeled_value(buf, "fov: ", "%.3f", view_state.fov); + font::draw_string(ter_best, buf, 10, y); + y += ter_best.desc->glyph_height; + + labeled_value(buf, "pitch: ", "%.9f", view_state.pitch); + font::draw_string(ter_best, buf, 10, y); + y += ter_best.desc->glyph_height; + + labeled_value(buf, "font_height: ", "%d", ter_best.desc->glyph_height); + font::draw_string(ter_best, buf, 10, y); + y += ter_best.desc->glyph_height; } void draw() @@ -343,7 +358,7 @@ void draw() XMMATRIX view = XMMatrixLookAtRH(view_state.eye, at, view_state.up); float fov_angle_y = XMConvertToRadians(45 * view_state.fov); - float aspect_ratio = 1.0; + float aspect_ratio = g_window_width / g_window_height; float near_z = 1.0; float far_z = 0.1; XMMATRIX projection = XMMatrixPerspectiveFovRH(fov_angle_y, aspect_ratio, near_z, far_z); diff --git a/src/window.cpp b/src/window.cpp new file mode 100644 index 0000000..ed5d8d0 --- /dev/null +++ b/src/window.cpp @@ -0,0 +1,10 @@ +#include "window.h" + +float g_window_width = 1; +float g_window_height = 1; + +void update_window(int width, int height) +{ + g_window_width = width; + g_window_height = height; +}