From 3744ec766ed8d2c15fd5cbb4ac3c241b852b6e69 Mon Sep 17 00:00:00 2001 From: ata4 Date: Sat, 2 Jan 2021 14:22:25 +0100 Subject: [PATCH] Added integer scaling option Might help with #81 --- src/core/n64video.h | 1 + src/output/vdac.c | 48 ++++++++++++++++++++++-------- src/plugin/mupen64plus/gfx_m64p.c | 3 ++ src/plugin/zilmar/config.c | 3 ++ src/plugin/zilmar/config.rc | Bin 8224 -> 8518 bytes src/plugin/zilmar/resource.h | Bin 1912 -> 2096 bytes 6 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/core/n64video.h b/src/core/n64video.h index aaf3f2c..42972bd 100644 --- a/src/core/n64video.h +++ b/src/core/n64video.h @@ -100,6 +100,7 @@ struct n64video_config bool hide_overscan; // crop to visible area if true bool vsync; // enable vsync if true bool exclusive; // run in exclusive mode when in fullscreen if true + bool integer_scaling; // one native pixel is displayed as a multiple of a screen pixel if true } vi; struct { enum dp_compat_profile compat; // multithreading compatibility mode diff --git a/src/output/vdac.c b/src/output/vdac.c index 400aa63..534172f 100644 --- a/src/output/vdac.c +++ b/src/output/vdac.c @@ -19,6 +19,7 @@ static bool m_fbo_enabled; static GLuint m_fbo; +static bool m_integer_scaling; static GLuint m_fbtex; static uint32_t m_fbtex_width; @@ -278,6 +279,9 @@ void vdac_init(struct n64video_config* config) // read with exact FB size in non-filtered modes m_rawtex_read = config->vi.mode != VI_MODE_NORMAL; + // save integer scaling flag, will be used later + m_integer_scaling = config->vi.integer_scaling; + // check if there was an error when using any of the commands above gl_check_errors(); } @@ -393,19 +397,37 @@ void vdac_sync(bool valid) return; } - int32_t hw = m_fbtex_height * win_width; - int32_t wh = m_fbtex_width * win_height; - - // add letterboxes or pillarboxes if the window has a different aspect ratio - // than the current display mode - if (hw > wh) { - int32_t w_max = wh / m_fbtex_height; - win_x += (win_width - w_max) / 2; - win_width = w_max; - } else if (hw < wh) { - int32_t h_max = hw / m_fbtex_width; - win_y += (win_height - h_max) / 2; - win_height = h_max; + if (m_integer_scaling) { + // get smallest integer scale that is at least 1 + uint32_t scale_x = (uint32_t)win_width < m_fbtex_width ? 1 : (uint32_t)win_width / m_fbtex_width; + uint32_t scale_y = (uint32_t)win_height < m_fbtex_height ? 1 : (uint32_t)win_height / m_fbtex_height; + uint32_t scale = scale_x > scale_y ? scale_x : scale_y; + + // get new window size (or rather viewport size in this context) + int32_t win_width_new = m_fbtex_width * scale; + int32_t win_height_new = m_fbtex_height * scale; + + // apply new size and offset + win_x = (win_width - win_width_new) / 2; + win_y = (win_height - win_height_new) / 2; + + win_width = win_width_new; + win_height = win_height_new; + } else { + int32_t hw = m_fbtex_height * win_width; + int32_t wh = m_fbtex_width * win_height; + + // add letterboxes or pillarboxes if the window has a different aspect ratio + // than the current display mode + if (hw > wh) { + int32_t w_max = wh / m_fbtex_height; + win_x += (win_width - w_max) / 2; + win_width = w_max; + } else if (hw < wh) { + int32_t h_max = hw / m_fbtex_width; + win_y += (win_height - h_max) / 2; + win_height = h_max; + } } if (m_fbo_enabled) { diff --git a/src/plugin/mupen64plus/gfx_m64p.c b/src/plugin/mupen64plus/gfx_m64p.c index c316d95..6aaacd7 100644 --- a/src/plugin/mupen64plus/gfx_m64p.c +++ b/src/plugin/mupen64plus/gfx_m64p.c @@ -33,6 +33,7 @@ #define KEY_VI_INTERP "ViInterpolation" #define KEY_VI_WIDESCREEN "ViWidescreen" #define KEY_VI_HIDE_OVERSCAN "ViHideOverscan" +#define KEY_VI_INTEGER_SCALING "ViIntegerScaling" #define KEY_DP_COMPAT "DpCompat" @@ -117,6 +118,7 @@ EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle _CoreLibHandle, void *Co ConfigSetDefaultInt(configVideoAngrylionPlus, KEY_VI_INTERP, config.vi.interp, "Scaling interpolation type (0=NN, 1=Linear)"); ConfigSetDefaultBool(configVideoAngrylionPlus, KEY_VI_WIDESCREEN, config.vi.widescreen, "Use anamorphic 16:9 output mode if True"); ConfigSetDefaultBool(configVideoAngrylionPlus, KEY_VI_HIDE_OVERSCAN, config.vi.hide_overscan, "Hide overscan area in filteded mode if True"); + ConfigSetDefaultBool(configVideoAngrylionPlus, KEY_VI_INTEGER_SCALING, config.vi.integer_scaling, "Display upscaled pixels as groups of 1x1, 2x2, 3x3, etc. if True"); ConfigSetDefaultInt(configVideoAngrylionPlus, KEY_DP_COMPAT, config.dp.compat, "Compatibility mode (0=Fast 1=Moderate 2=Slow"); ConfigSaveSection("Video-General"); @@ -204,6 +206,7 @@ EXPORT int CALL RomOpen (void) config.vi.interp = ConfigGetParamInt(configVideoAngrylionPlus, KEY_VI_INTERP); config.vi.widescreen = ConfigGetParamBool(configVideoAngrylionPlus, KEY_VI_WIDESCREEN); config.vi.hide_overscan = ConfigGetParamBool(configVideoAngrylionPlus, KEY_VI_HIDE_OVERSCAN); + config.vi.integer_scaling = ConfigGetParamBool(configVideoAngrylionPlus, KEY_VI_INTEGER_SCALING); config.dp.compat = ConfigGetParamInt(configVideoAngrylionPlus, KEY_DP_COMPAT); diff --git a/src/plugin/zilmar/config.c b/src/plugin/zilmar/config.c index 73f65b7..5733987 100644 --- a/src/plugin/zilmar/config.c +++ b/src/plugin/zilmar/config.c @@ -49,6 +49,7 @@ static HWND dlg_check_vi_widescreen; static HWND dlg_check_vi_overscan; static HWND dlg_check_vi_exclusive; static HWND dlg_check_vi_vsync; +static HWND dlg_check_vi_integer_scaling; static HWND dlg_combo_dp_compat; static HWND dlg_spin_workers; static HWND dlg_edit_workers; @@ -119,6 +120,7 @@ INT_PTR CALLBACK config_dialog_proc(HWND hwnd, UINT iMessage, WPARAM wParam, LPA CONFIG_DLG_INIT_CHECKBOX(IDC_CHECK_VI_OVERSCAN, dlg_check_vi_overscan, config.vi.hide_overscan); CONFIG_DLG_INIT_CHECKBOX(IDC_CHECK_VI_EXCLUSIVE, dlg_check_vi_exclusive, config.vi.exclusive); CONFIG_DLG_INIT_CHECKBOX(IDC_CHECK_VI_VSYNC, dlg_check_vi_vsync, config.vi.vsync); + CONFIG_DLG_INIT_CHECKBOX(IDC_CHECK_VI_INTEGER_SCALING, dlg_check_vi_integer_scaling, config.vi.integer_scaling); dlg_edit_workers = GetDlgItem(hwnd, IDC_EDIT_WORKERS); SetDlgItemInt(hwnd, IDC_EDIT_WORKERS, config.num_workers, FALSE); @@ -159,6 +161,7 @@ INT_PTR CALLBACK config_dialog_proc(HWND hwnd, UINT iMessage, WPARAM wParam, LPA config.vi.hide_overscan = SendMessage(dlg_check_vi_overscan, BM_GETCHECK, 0, 0); config.vi.exclusive = SendMessage(dlg_check_vi_exclusive, BM_GETCHECK, 0, 0); config.vi.vsync = SendMessage(dlg_check_vi_vsync, BM_GETCHECK, 0, 0); + config.vi.integer_scaling = SendMessage(dlg_check_vi_integer_scaling, BM_GETCHECK, 0, 0); config.dp.compat = SendMessage(dlg_combo_dp_compat, CB_GETCURSEL, 0, 0); config.parallel = SendMessage(dlg_check_multithread, BM_GETCHECK, 0, 0); config.num_workers = GetDlgItemInt(hwnd, IDC_EDIT_WORKERS, FALSE, FALSE); diff --git a/src/plugin/zilmar/config.rc b/src/plugin/zilmar/config.rc index d75159fb8c11851d94b1910db71cbb4aadd424e3..7575c1bcef9879dc7970d181a09d082c19b290b6 100644 GIT binary patch delta 202 zcmZ4BaLj1~4>z+RgVAPw?s`^cO9r#e69uf9fefR`=Y>|I|s-vW=Lj81hO)LYSJeQ3dt*bGWaos zFt{?f191>TJVP*pGlL_84+BWtok53zmw{_?qp0}g38EZeoWR2}*+o2v*NnjeC~LuB b03;13Uz8Eu{6WHniPZ=wV7l2-`Z)^#L9s4G delta 86 zcmX@+w7_8l4>z*`gTZEg?s`^c3kH+T69uf9feeGm=Y>11_K5|2Gh;_teH#zt^*PS delta 12 TcmdlW@PluI2