Mercurial > repos > blastem
changeset 2644:c5c9498ff279
Implement integer scaling
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 28 Feb 2025 22:40:18 -0800 |
parents | 57345f6e18f3 |
children | 620f30af9fdc |
files | default.cfg nuklear_ui/blastem_nuklear.c render_sdl.c |
diffstat | 3 files changed, 39 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/default.cfg Wed Feb 26 23:43:58 2025 -0800 +++ b/default.cfg Fri Feb 28 22:40:18 2025 -0800 @@ -307,6 +307,8 @@ scanlines off vsync off fullscreen off + #forces an integer ratio between the emulated height and the height on screen + integer_scaling off #setting gl to off, will force use of the SDL2 fallback renderer #this is useful for those running on machines with Open GL 2.0 unavailable #so the warning doesn't display on startup
--- a/nuklear_ui/blastem_nuklear.c Wed Feb 26 23:43:58 2025 -0800 +++ b/nuklear_ui/blastem_nuklear.c Fri Feb 28 22:40:18 2025 -0800 @@ -2186,6 +2186,7 @@ settings_toggle(context, "Fullscreen", "video\0fullscreen\0", 0); settings_toggle(context, "Open GL", "video\0gl\0", 1); settings_toggle(context, "Scanlines", "video\0scanlines\0", 0); + settings_toggle(context, "Integer Scaling", "video\0integer_scaling\0", 0); selected_vsync = settings_dropdown_ex(context, "VSync", vsync_opts, vsync_opt_names, num_vsync_opts, selected_vsync, "video\0vsync\0"); settings_int_input(context, "Windowed Width", "video\0width\0", "640"); nk_label(context, "Shader", NK_TEXT_LEFT);
--- a/render_sdl.c Wed Feb 26 23:43:58 2025 -0800 +++ b/render_sdl.c Fri Feb 28 22:40:18 2025 -0800 @@ -620,25 +620,52 @@ main_clip.h = main_height; main_clip.x = main_clip.y = 0; if (config_aspect() > 0.0f) { + char *integer_scaling_str = tern_find_path_default(config, "video\0integer_scaling\0", (tern_val){.ptrval = "off"}, TVAL_PTR).ptrval; + uint8_t integer_scaling = !strcmp(integer_scaling_str, "on"); float aspect = (float)main_width / main_height; - if (fabs(aspect - config_aspect()) < 0.01f) { + if (!integer_scaling && fabs(aspect - config_aspect()) < 0.01f) { //close enough for government work return; } + uint32_t height, scale; + if (integer_scaling) { + height = render_emulated_height(); + if (aspect >= config_aspect()) { + scale = main_height / height; + } else { + uint32_t aspect_height = 0.5f + (float)main_width / config_aspect(); + scale = aspect_height / height; + } + } #ifndef DISABLE_OPENGL if (render_gl) { - for (int i = 0; i < 4; i++) - { - if (aspect > config_aspect()) { - vertex_data[i*2] *= config_aspect()/aspect; - } else { - vertex_data[i*2+1] *= aspect/config_aspect(); + if (integer_scaling) { + float vscale = ((float)(scale * height)) / (float)main_height; + float hscale = (config_aspect() * (float)(scale * height)) / (float)main_width; + for (int i = 0; i < 4; i++) + { + vertex_data[i*2] *= hscale; + vertex_data[i*2+1] *= vscale; + } + } else { + for (int i = 0; i < 4; i++) + { + if (aspect > config_aspect()) { + vertex_data[i*2] *= config_aspect()/aspect; + } else { + vertex_data[i*2+1] *= aspect/config_aspect(); + } } } } else { #endif - main_clip.w = aspect > config_aspect() ? config_aspect() * (float)main_height : main_width; - main_clip.h = aspect > config_aspect() ? main_height : main_width / config_aspect(); + if (integer_scaling) { + main_clip.h = height * scale; + main_clip.w = main_clip.h * config_aspect(); + } else { + main_clip.w = aspect > config_aspect() ? config_aspect() * (float)main_height : main_width; + main_clip.h = aspect > config_aspect() ? main_height : main_width / config_aspect(); + } main_clip.x = (main_width - main_clip.w) / 2; main_clip.y = (main_height - main_clip.h) / 2; #ifndef DISABLE_OPENGL