From dd65a80b1944133e8e82c68d0d805b33badeed09 Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Sat, 1 May 2021 20:49:23 +0300 Subject: [PATCH] Add menu option for filter method to use when scaling video. --- src/86box.c | 1 + src/config.c | 7 +++++++ src/include/86box/86box.h | 1 + src/include/86box/resource.h | 6 ++++-- src/include/86box/win_sdl.h | 6 +++--- src/win/86Box.rc | 5 +++++ src/win/win.c | 6 +++--- src/win/win_opengl.c | 23 +++++++++++++++++++++-- src/win/win_sdl.c | 16 +++++++++++++++- src/win/win_ui.c | 22 +++++++++++++++++++++- 10 files changed, 81 insertions(+), 12 deletions(-) diff --git a/src/86box.c b/src/86box.c index 9eefa039e..1f793673d 100644 --- a/src/86box.c +++ b/src/86box.c @@ -129,6 +129,7 @@ int video_fullscreen_scale = 0; /* (C) video */ int video_fullscreen_first = 0; /* (C) video */ int enable_overscan = 0; /* (C) video */ int force_43 = 0; /* (C) video */ +int video_filter_method = 1; /* (C) video */ int video_vsync = 0; /* (C) video */ int video_framerate = -1; /* (C) video */ char video_shader[512] = { '\0' }; /* (C) video */ diff --git a/src/config.c b/src/config.c index 4ec3eb5a6..66a624aba 100644 --- a/src/config.c +++ b/src/config.c @@ -464,6 +464,8 @@ load_general(void) video_fullscreen_first = config_get_int(cat, "video_fullscreen_first", 1); + video_filter_method = config_get_int(cat, "video_filter_method", 1); + force_43 = !!config_get_int(cat, "force_43", 0); scale = config_get_int(cat, "scale", 1); if (scale > 3) @@ -1879,6 +1881,11 @@ save_general(void) else config_set_int(cat, "video_fullscreen_first", video_fullscreen_first); + if (video_filter_method == 1) + config_delete_var(cat, "video_filter_method"); + else + config_set_int(cat, "video_filter_method", video_filter_method); + if (force_43 == 0) config_delete_var(cat, "force_43"); else diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 7359b5de6..e7f79b36f 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -90,6 +90,7 @@ extern int vid_cga_contrast, /* (C) video */ video_fullscreen_scale, /* (C) video */ enable_overscan, /* (C) video */ force_43, /* (C) video */ + video_filter_method, /* (C) video */ video_vsync, /* (C) video */ video_framerate, /* (C) video */ gfxcard; /* (C) graphics/video card */ diff --git a/src/include/86box/resource.h b/src/include/86box/resource.h index 2d3fe763c..c02e1d7ac 100644 --- a/src/include/86box/resource.h +++ b/src/include/86box/resource.h @@ -333,9 +333,11 @@ #define IDM_VID_GRAY_AMBER 40082 #define IDM_VID_GRAY_GREEN 40083 #define IDM_VID_GRAY_WHITE 40084 +#define IDM_VID_FILTER_NEAREST 40085 +#define IDM_VID_FILTER_LINEAR 40086 -#define IDM_MEDIA 40085 -#define IDM_DOCS 40086 +#define IDM_MEDIA 40087 +#define IDM_DOCS 40088 #ifdef USE_DISCORD #define IDM_DISCORD 40090 diff --git a/src/include/86box/win_sdl.h b/src/include/86box/win_sdl.h index cc61142be..aa082fe6c 100644 --- a/src/include/86box/win_sdl.h +++ b/src/include/86box/win_sdl.h @@ -11,10 +11,10 @@ * * * Authors: Fred N. van Kempen, - * Michael Drüing, + * Michael Drüing, * * Copyright 2018,2019 Fred N. van Kempen. - * Copyright 2018,2019 Michael Drüing. + * Copyright 2018,2019 Michael Drüing. * * Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the @@ -58,6 +58,6 @@ extern int sdl_pause(void); extern void sdl_resize(int x, int y); extern void sdl_enable(int enable); extern void sdl_set_fs(int fs); - +extern void sdl_reload(void); #endif /*WIN_SDL_H*/ diff --git a/src/win/86Box.rc b/src/win/86Box.rc index 09c50f2b6..87f4679a0 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -83,6 +83,11 @@ BEGIN MENUITEM "1.&5x", IDM_VID_SCALE_3X MENUITEM "&2x", IDM_VID_SCALE_4X END + POPUP "Filter method" + BEGIN + MENUITEM "&Nearest", IDM_VID_FILTER_NEAREST + MENUITEM "&Linear", IDM_VID_FILTER_LINEAR + END MENUITEM "Hi&DPI scaling", IDM_VID_HIDPI MENUITEM SEPARATOR MENUITEM "&Fullscreen\tCtrl+Alt+PageUP", IDM_VID_FULLSCREEN diff --git a/src/win/win.c b/src/win/win.c index 3afff8deb..1bff61fee 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -101,9 +101,9 @@ static const struct { void (*set_fs)(int fs); void (*reload)(void); } vid_apis[RENDERERS_NUM] = { - { "SDL_Software", 1, (int(*)(void*))sdl_inits, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, NULL }, - { "SDL_Hardware", 1, (int(*)(void*))sdl_inith, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, NULL }, - { "SDL_OpenGL", 1, (int(*)(void*))sdl_initho, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, NULL } + { "SDL_Software", 1, (int(*)(void*))sdl_inits, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload }, + { "SDL_Hardware", 1, (int(*)(void*))sdl_inith, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload }, + { "SDL_OpenGL", 1, (int(*)(void*))sdl_initho, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload } #if defined(DEV_BRANCH) && defined(USE_OPENGL) ,{ "OpenGL_Core", 1, (int(*)(void*))opengl_init, opengl_close, opengl_resize, opengl_pause, NULL, opengl_set_fs, opengl_reload} #else diff --git a/src/win/win_opengl.c b/src/win/win_opengl.c index 3aac702b7..c4e764af3 100644 --- a/src/win/win_opengl.c +++ b/src/win/win_opengl.c @@ -140,6 +140,8 @@ static struct int frametime; /* Frametime in microseconds, or -1 to sync with blitter */ char shaderfile[512]; /* Shader file path. Match the length of openfilestring in win_dialog.c */ int shaderfile_changed; /* Has shader file path changed. To prevent unnecessary shader recompilation. */ + int filter; /* 0 = Nearest, 1 = Linear */ + int filter_changed; /* Has filter changed. */ mutex_t* mutex; } options = { 0 }; @@ -353,8 +355,8 @@ static int initialize_glcontext(gl_identifiers* gl) glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, options.filter ? GL_LINEAR : GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, options.filter ? GL_LINEAR : GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, INIT_WIDTH, INIT_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); @@ -751,6 +753,14 @@ static void opengl_main(void* param) options.shaderfile_changed = 0; } + if (options.filter_changed) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, options.filter ? GL_LINEAR : GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, options.filter ? GL_LINEAR : GL_NEAREST); + + options.filter_changed = 0; + } + thread_release_mutex(options.mutex); } @@ -836,6 +846,9 @@ int opengl_init(HWND hwnd) options.vsync = video_vsync; options.frametime = framerate_to_frametime(video_framerate); strcpy_s(options.shaderfile, sizeof(options.shaderfile), video_shader); + options.shaderfile_changed = 0; + options.filter = video_filter_method; + options.filter_changed = 0; options.mutex = thread_create_mutex(); blit_info = (blit_info_t*)malloc(BUFFERCOUNT * sizeof(blit_info_t)); @@ -933,6 +946,12 @@ void opengl_reload(void) options.shaderfile_changed = 1; } + if (video_filter_method != options.filter) + { + options.filter = video_filter_method; + options.filter_changed = 1; + } + thread_release_mutex(options.mutex); SetEvent(sync_objects.reload); diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c index 1d9912316..bebad43dd 100644 --- a/src/win/win_sdl.c +++ b/src/win/win_sdl.c @@ -347,7 +347,7 @@ sdl_reinit_texture(void) if (sdl_flags & RENDERER_HARDWARE) { sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED); - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2"); + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0"); } else sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE); @@ -552,3 +552,17 @@ sdl_enable(int enable) SDL_UnlockMutex(sdl_mutex); } + +void +sdl_reload(void) +{ + if (sdl_flags & RENDERER_HARDWARE) + { + SDL_LockMutex(sdl_mutex); + + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0"); + sdl_reinit_texture(); + + SDL_UnlockMutex(sdl_mutex); + } +} \ No newline at end of file diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 326c1f87f..e5d8e6ba8 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -178,7 +178,8 @@ video_toggle_option(HMENU h, int *val, int id) } /* Recursively finds and deletes target submenu */ -int delete_submenu(HMENU parent, HMENU target) +static int +delete_submenu(HMENU parent, HMENU target) { for (int i = 0; i < GetMenuItemCount(parent); i++) { @@ -243,6 +244,14 @@ show_render_options_menu() #endif } +static void +video_set_filter_menu(HMENU menu) +{ + CheckMenuItem(menu, IDM_VID_FILTER_NEAREST, vid_api == 0 || video_filter_method == 0 ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(menu, IDM_VID_FILTER_LINEAR, vid_api != 0 && video_filter_method == 1 ? MF_CHECKED : MF_UNCHECKED); + EnableMenuItem(menu, IDM_VID_FILTER_NEAREST, vid_api == 0 ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(menu, IDM_VID_FILTER_LINEAR, vid_api == 0 ? MF_GRAYED : MF_ENABLED); +} static void ResetAllMenus(void) @@ -362,6 +371,8 @@ ResetAllMenus(void) CheckMenuItem(menuMain, IDM_VID_GRAYCT_601+video_graytype, MF_CHECKED); CheckMenuItem(menuMain, IDM_VID_GRAY_RGB+video_grayscale, MF_CHECKED); + video_set_filter_menu(menuMain); + #ifdef USE_DISCORD if (discord_loaded) CheckMenuItem(menuMain, IDM_DISCORD, enable_discord ? MF_CHECKED : MF_UNCHECKED); @@ -748,6 +759,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) CheckMenuItem(hmenu, IDM_VID_SDL_SW + vid_api, MF_UNCHECKED); plat_setvid(LOWORD(wParam) - IDM_VID_SDL_SW); CheckMenuItem(hmenu, IDM_VID_SDL_SW + vid_api, MF_CHECKED); + video_set_filter_menu(hmenu); config_save(); show_render_options_menu(); break; @@ -823,6 +835,14 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) config_save(); break; + case IDM_VID_FILTER_NEAREST: + case IDM_VID_FILTER_LINEAR: + video_filter_method = LOWORD(wParam) - IDM_VID_FILTER_NEAREST; + video_set_filter_menu(hmenu); + plat_vid_reload_options(); + config_save(); + break; + case IDM_VID_HIDPI: dpi_scale = !dpi_scale; CheckMenuItem(hmenu, IDM_VID_HIDPI, dpi_scale ? MF_CHECKED : MF_UNCHECKED);