From db9b8676f993b4c4f837148c95f6a09d7c4324c5 Mon Sep 17 00:00:00 2001 From: Martin Donlon Date: Wed, 8 Jun 2022 01:40:06 -0700 Subject: [PATCH] video: Removed loop from vscale calculations, calculate max horizontal and (#636) vertical scale and use the minimum. vscale_mode has been changed to make it more reliable. vscale_mode=4 - Generate modes that match the cores aspect ratio. Generally better, will work with more cores and produce most optimal resolutions, but will not be compatible with displays that always stretch the image to fill. vscale_mode=5 - Generate modes that match the original display aspect ratio, if the core needs a wider aspect then the resolution is not changed. Compatible with a wider range of displays. Updated INI with a clearer description. Removed mode 6 since it was not being used and adjusting display width doesn't enable integer horizontal scaling. uh undo --- MiSTer.ini | 5 ++--- cfg.cpp | 2 +- video.cpp | 56 ++++++++++++++++++++++++++++++++++++------------------ 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/MiSTer.ini b/MiSTer.ini index 5172b40..602532e 100644 --- a/MiSTer.ini +++ b/MiSTer.ini @@ -10,9 +10,8 @@ vscale_mode=0 ; 0 - scale to fit the screen height. ; 1 - use integer scale only. ; 2 - use 0.5 steps of scale. ; 3 - use 0.25 steps of scale. - ; 4 - integer resolution scaling, vertical only (option 1) - ; 5 - integer resolution scaling, vertical only (option 2) - ; 6 - integer resolution scaling, both axes + ; 4 - integer resolution scaling, use core aspect ratio + ; 5 - integer resolution scaling, maintain display aspect ratio vscale_border=0 ; set vertical border for TVs cutting the upper/bottom parts of screen (1-399) ;bootscreen=0 ; uncomment to disable boot screen of some cores like Minimig. ;mouse_throttle=10 ; 1-100 mouse speed divider. Useful for very sensitive mice diff --git a/cfg.cpp b/cfg.cpp index f364194..c15781d 100644 --- a/cfg.cpp +++ b/cfg.cpp @@ -50,7 +50,7 @@ static const ini_var_t ini_vars[] = { "KBD_NOMOUSE", (void*)(&(cfg.kbd_nomouse)), UINT8, 0, 1 }, { "MOUSE_THROTTLE", (void*)(&(cfg.mouse_throttle)), UINT8, 1, 100 }, { "BOOTSCREEN", (void*)(&(cfg.bootscreen)), UINT8, 0, 1 }, - { "VSCALE_MODE", (void*)(&(cfg.vscale_mode)), UINT8, 0, 6 }, + { "VSCALE_MODE", (void*)(&(cfg.vscale_mode)), UINT8, 0, 5 }, { "VSCALE_BORDER", (void*)(&(cfg.vscale_border)), UINT16, 0, 399 }, { "RBF_HIDE_DATECODE", (void*)(&(cfg.rbf_hide_datecode)), UINT8, 0, 1 }, { "MENU_PAL", (void*)(&(cfg.menu_pal)), UINT8, 0, 1 }, diff --git a/video.cpp b/video.cpp index 22f9975..863564c 100644 --- a/video.cpp +++ b/video.cpp @@ -1660,14 +1660,19 @@ static void video_resolution_adjust(const VideoInfo *vi, vmode_custom_t *vm) const uint32_t core_height = vi->fb_en ? vi->fb_height : vi->rotated ? vi->width : vi->height; const uint32_t core_width = vi->fb_en ? vi->fb_width : vi->rotated ? vi->height : vi->width; - if (w == 0 || h == 0 || core_height == 0) return; + if (w == 0 || h == 0 || core_height == 0 || core_width == 0) + { + printf("video_resolution_adjust: invalid core or display sizes. Not adjusting resolution.\n"); + return; + } int scale_h = h / core_height; - int scale_w = w / core_width; - if (!scale_h) return; + if (!scale_h) + { + printf("video_resolution_adjust: display height less than core height. Not adjusting resolution.\n"); + return; + } - int disp_h = h; - int disp_w = w; int ary = vi->ary; int arx = vi->arx; if (!ary || !arx) @@ -1676,27 +1681,40 @@ static void video_resolution_adjust(const VideoInfo *vi, vmode_custom_t *vm) arx = w; } - if (cfg.vscale_mode == 4 || cfg.vscale_mode == 5) + int scale_w = (w * ary) / (core_height * arx); + if (!scale_w) { - int scale; - for (scale = scale_h; scale > 0; scale--) - { - disp_h = core_height * scale; - disp_w = (disp_h * arx) / ary; - if (disp_w <= w) break; - } - if (scale == 0) return; // could not find a scale + printf("video_resolution_adjust: display width less than core width. Not adjusting resolution.\n"); + return; + } - if (cfg.vscale_mode == 5) disp_w = w; + int scale = scale_h > scale_w ? scale_w : scale_h; + + int disp_h = core_height * scale; + int core_ar_width = (disp_h * arx) / ary; + int disp_ar_width = (disp_h * w) / h; + int disp_w; + + if (cfg.vscale_mode == 5) + { + if (disp_ar_width < core_ar_width) + { + printf("video_resolution_adjust: ideal width %d wider than aspect restricted width %dx%d. Not adjusting resolution.\n", core_ar_width, disp_ar_width, disp_h); + return; + } + disp_w = disp_ar_width; + printf("video_resolution_adjust: using display aspect ratio - "); } else { - if (!scale_w) return; - int scale = (scale_h < scale_w) ? scale_h : scale_w; - disp_h = core_height * scale; - disp_w = core_width * scale; + disp_w = core_ar_width; + printf("video_resolution_adjust: using core aspect ratio - "); } + disp_w = (disp_w + 7) & ~0x7; // round up to 8 + + printf("scale x%d, %dx%d.\n", scale, disp_w, disp_h); + float refresh = 1000000.0 / ((vm->item[1] + vm->item[2] + vm->item[3] + vm->item[4])*(vm->item[5] + vm->item[6] + vm->item[7] + vm->item[8]) / vm->Fpix); video_calculate_cvt(disp_w, disp_h, refresh, vm->param.rb, vm); setPLL(vm->Fpix, vm);