From cc82727f5bb5f9ada526ac52941c9fbee2573629 Mon Sep 17 00:00:00 2001 From: Margen67 Date: Sat, 12 Dec 2020 02:18:40 -0800 Subject: [PATCH] Fix #256 (Widescreen hack aspect ratio setting) Adds an option to set the aspect ratio of the widescreen hack. Choices: 16:10 16:9 (default) 21:9 32:9 --- beetle_psx_globals.c | 1 + beetle_psx_globals.h | 1 + libretro.cpp | 29 +++++++++++++++++++++++++++++ libretro_core_options.h | 13 +++++++++++++ libretro_core_options_intl.h | 13 +++++++++++++ mednafen/psx/gte.cpp | 24 +++++++++++++++++++++--- rsx/rsx_intf.cpp | 17 ++++++++++++++--- rsx/rsx_intf.h | 3 ++- rsx/rsx_lib_gl.cpp | 28 ++++++++++++++++------------ rsx/rsx_lib_vulkan.cpp | 5 ++++- 10 files changed, 114 insertions(+), 20 deletions(-) diff --git a/beetle_psx_globals.c b/beetle_psx_globals.c index 57dedcc8..18e4c04f 100644 --- a/beetle_psx_globals.c +++ b/beetle_psx_globals.c @@ -4,6 +4,7 @@ bool content_is_pal = false; uint8_t widescreen_hack; +uint8_t widescreen_hack_aspect_ratio_setting; uint8_t psx_gpu_upscale_shift; uint8_t psx_gpu_upscale_shift_hw; int line_render_mode; diff --git a/beetle_psx_globals.h b/beetle_psx_globals.h index aecfbd7f..65452d57 100644 --- a/beetle_psx_globals.h +++ b/beetle_psx_globals.h @@ -16,6 +16,7 @@ extern "C" { extern bool content_is_pal; extern uint8_t widescreen_hack; +extern uint8_t widescreen_hack_aspect_ratio_setting; extern uint8_t psx_gpu_upscale_shift; extern uint8_t psx_gpu_upscale_shift_hw; extern int line_render_mode; diff --git a/libretro.cpp b/libretro.cpp index c9e15111..b22dea07 100644 --- a/libretro.cpp +++ b/libretro.cpp @@ -3179,6 +3179,35 @@ static void check_variables(bool startup) widescreen_hack = false; } + var.key = BEETLE_OPT(widescreen_hack_aspect_ratio); + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (!strcmp(var.value, "16:10")) + { + if (!startup && widescreen_hack_aspect_ratio_setting != 0) + has_new_geometry = true; + widescreen_hack_aspect_ratio_setting = 0; + } + else if (!strcmp(var.value, "16:9")) + { + if (!startup && widescreen_hack_aspect_ratio_setting != 1) + has_new_geometry = true; + widescreen_hack_aspect_ratio_setting = 1; + } + else if (!strcmp(var.value, "21:9")) // 64:27 + { + if (!startup && widescreen_hack_aspect_ratio_setting != 2) + has_new_geometry = true; + widescreen_hack_aspect_ratio_setting = 2; + } + else if (!strcmp(var.value, "32:9")) + { + if (!startup && widescreen_hack_aspect_ratio_setting != 3) + has_new_geometry = true; + widescreen_hack_aspect_ratio_setting = 3; + } + } + var.key = BEETLE_OPT(pal_video_timing_override); if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { diff --git a/libretro_core_options.h b/libretro_core_options.h index 3d456588..b4f4e560 100644 --- a/libretro_core_options.h +++ b/libretro_core_options.h @@ -581,6 +581,19 @@ struct retro_core_option_definition option_defs_us[] = { }, "disabled" }, + { + BEETLE_OPT(widescreen_hack_aspect_ratio), + "Widescreen Mode Hack Aspect Ratio", + "The aspect ratio that's used by the Widescreen Mode Hack.", + { + { "16:10", NULL }, + { "16:9", NULL }, + { "21:9", NULL }, // 64:27 + { "32:9", NULL }, + { NULL, NULL }, + }, + "16:9" + }, { BEETLE_OPT(pal_video_timing_override), "PAL (European) Video Timing Override", diff --git a/libretro_core_options_intl.h b/libretro_core_options_intl.h index 13c88365..2e8fb5df 100644 --- a/libretro_core_options_intl.h +++ b/libretro_core_options_intl.h @@ -400,6 +400,19 @@ struct retro_core_option_definition option_defs_it[] = { }, "disabled" }, + { + BEETLE_OPT(widescreen_hack_aspect_ratio), + "Widescreen Mode Hack Aspect Ratio", + "The aspect ratio that's used by the Widescreen Mode Hack.", + { + { "16:10", NULL }, + { "16:9", NULL }, + { "21:9", NULL }, // 64:27 + { "32:9", NULL }, + { NULL, NULL }, + }, + "16:9" + }, { BEETLE_OPT(crop_overscan), "Taglia Overscan Orizzontale", diff --git a/mednafen/psx/gte.cpp b/mednafen/psx/gte.cpp index 642cd0e4..9a705ea6 100644 --- a/mednafen/psx/gte.cpp +++ b/mednafen/psx/gte.cpp @@ -164,6 +164,7 @@ static uint32_t Reg23; /* Register 23: 32bit read/write but not used for // end DR extern "C" unsigned char widescreen_hack; +extern "C" unsigned char widescreen_hack_aspect_ratio_setting; static INLINE uint8_t Sat5(int16_t cc) { @@ -1184,7 +1185,24 @@ static INLINE void check_mac_overflow(int64_t value) static INLINE void TransformXY(int64_t h_div_sz, float precise_h_div_sz, float precise_z) { - MAC[0] = F((int64_t)OFX + IR1 * h_div_sz * ((widescreen_hack) ? 0.75 : 1.00)) >> 16; + float widescreen_hack_aspect_ratio; + switch(widescreen_hack_aspect_ratio_setting) + { + case 0: // 16:10 + widescreen_hack_aspect_ratio = 0.80f; + break; + case 1: // 16:9 (default) + widescreen_hack_aspect_ratio = 0.75f; + break; + case 2: // 21:9 (64:27) + widescreen_hack_aspect_ratio = 0.55f; + break; + case 3: // 32:9 + widescreen_hack_aspect_ratio = 0.37f; + break; + } + + MAC[0] = F((int64_t)OFX + IR1 * h_div_sz * ((widescreen_hack) ? widescreen_hack_aspect_ratio : 1.00)) >> 16; XY_FIFO[3].X = Lm_G(0, MAC[0]); MAC[0] = F((int64_t)OFY + IR2 * h_div_sz) >> 16; @@ -1201,11 +1219,11 @@ static INLINE void TransformXY(int64_t h_div_sz, float precise_h_div_sz, float p float fofy = ((float)OFY / (float)(1 << 16)); /* Project X and Y onto the plane */ - int64_t screen_x = (int64_t)OFX + IR1 * h_div_sz * ((widescreen_hack) ? 0.75 : 1.00); + int64_t screen_x = (int64_t)OFX + IR1 * h_div_sz * ((widescreen_hack) ? widescreen_hack_aspect_ratio : 1.00); int64_t screen_y = (int64_t)OFY + IR2 * h_div_sz; /* Increased precision calculation (sub-pixel precision) */ - float precise_x = fofx + ((float)IR1 * precise_h_div_sz) * ((widescreen_hack) ? 0.75 : 1.00); + float precise_x = fofx + ((float)IR1 * precise_h_div_sz) * ((widescreen_hack) ? widescreen_hack_aspect_ratio : 1.00); float precise_y = fofy + ((float)IR2 * precise_h_div_sz); uint32 value = *((uint32*)&XY_FIFO[3]); diff --git a/rsx/rsx_intf.cpp b/rsx/rsx_intf.cpp index 5befe763..debf2c4a 100644 --- a/rsx/rsx_intf.cpp +++ b/rsx/rsx_intf.cpp @@ -91,7 +91,7 @@ void rsx_intf_get_system_av_info(struct retro_system_av_info *info) info->geometry.aspect_ratio = rsx_common_get_aspect_ratio(content_is_pal, crop_overscan, MDFN_GetSettingI(content_is_pal ? "psx.slstartp" : "psx.slstart"), MDFN_GetSettingI(content_is_pal ? "psx.slendp" : "psx.slend"), - aspect_ratio_setting, false, widescreen_hack); + aspect_ratio_setting, false, widescreen_hack, widescreen_hack_aspect_ratio_setting); break; case RSX_OPENGL: #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) @@ -876,7 +876,8 @@ double rsx_common_get_timing_fps(void) float rsx_common_get_aspect_ratio(bool pal_content, bool crop_overscan, int first_visible_scanline, int last_visible_scanline, - int aspect_ratio_setting, bool vram_override, bool widescreen_override) + int aspect_ratio_setting, bool vram_override, bool widescreen_override, + int widescreen_hack_aspect_ratio_setting) { // Current assumptions // A fixed percentage of width is cropped when crop_overscan is true @@ -892,7 +893,17 @@ float rsx_common_get_aspect_ratio(bool pal_content, bool crop_overscan, return 2.0 / 1.0; if (widescreen_override) - return 16.0 / 9.0; + switch(widescreen_hack_aspect_ratio_setting) + { + case 0: + return (16.0 / 10.0); + case 1: + return (16.0 / 9.0); + case 2: + return (/*21.0 / 9.0*/ 64.0 / 27.0); + case 3: + return (32.0 / 9.0); + } float ar = (4.0 / 3.0); diff --git a/rsx/rsx_intf.h b/rsx/rsx_intf.h index 8a8b1986..7cb1a9db 100644 --- a/rsx/rsx_intf.h +++ b/rsx/rsx_intf.h @@ -173,6 +173,7 @@ double rsx_common_get_timing_fps(void); float rsx_common_get_aspect_ratio(bool pal_content, bool crop_overscan, int first_visible_scanline, int last_visible_scanline, - int aspect_ratio_setting, bool vram_override, bool widescreen_override); + int aspect_ratio_setting, bool vram_override, bool widescreen_override, + int widescreen_hack_aspect_ratio_setting); #endif /*__RSX_H__*/ diff --git a/rsx/rsx_lib_gl.cpp b/rsx/rsx_lib_gl.cpp index 7101926c..e9c45c06 100644 --- a/rsx/rsx_lib_gl.cpp +++ b/rsx/rsx_lib_gl.cpp @@ -359,6 +359,7 @@ static RetroGl static_renderer; static bool has_software_fb = false; extern "C" unsigned char widescreen_hack; +extern "C" unsigned char widescreen_hack_aspect_ratio_setting; extern "C" bool content_is_pal; extern "C" int aspect_ratio_setting; @@ -1666,7 +1667,8 @@ static void bind_libretro_framebuffer(GlRenderer *renderer) renderer->initial_scanline, content_is_pal ? renderer->last_scanline_pal : renderer->last_scanline, - aspect_ratio_setting, renderer->display_vram, widescreen_hack); + aspect_ratio_setting, renderer->display_vram, widescreen_hack, + widescreen_hack_aspect_ratio_setting); environ_cb(RETRO_ENVIRONMENT_SET_GEOMETRY, &geometry); @@ -2211,16 +2213,17 @@ extern "C" bool currently_interlaced; static struct retro_system_av_info get_av_info(VideoClock std) { struct retro_system_av_info info; - unsigned int max_width = 0; - unsigned int max_height = 0; - uint8_t upscaling = 1; - bool widescreen_hack = false; - bool display_vram = false; - bool crop_overscan = false; - int initial_scanline_ntsc = 0; - int last_scanline_ntsc = 239; - int initial_scanline_pal = 0; - int last_scanline_pal = 287; + unsigned int max_width = 0; + unsigned int max_height = 0; + uint8_t upscaling = 1; + bool widescreen_hack = false; + int widescreen_hack_aspect_ratio = 2; + bool display_vram = false; + bool crop_overscan = false; + int initial_scanline_ntsc = 0; + int last_scanline_ntsc = 239; + int initial_scanline_pal = 0; + int last_scanline_pal = 287; /* This function currently queries core options rather than checking GlRenderer state; possible to refactor? */ @@ -2290,7 +2293,8 @@ static struct retro_system_av_info get_av_info(VideoClock std) info.geometry.aspect_ratio = rsx_common_get_aspect_ratio(std, crop_overscan, std ? initial_scanline_pal : initial_scanline_ntsc, std ? last_scanline_pal : last_scanline_ntsc, - aspect_ratio_setting, display_vram, widescreen_hack); + aspect_ratio_setting, display_vram, widescreen_hack, + widescreen_hack_aspect_ratio_setting); info.timing.fps = rsx_common_get_timing_fps(); info.timing.sample_rate = SOUND_FREQUENCY; diff --git a/rsx/rsx_lib_vulkan.cpp b/rsx/rsx_lib_vulkan.cpp index ef56edb4..68d9ef5e 100644 --- a/rsx/rsx_lib_vulkan.cpp +++ b/rsx/rsx_lib_vulkan.cpp @@ -29,6 +29,8 @@ static unsigned scaling = 4; // Declare extern as workaround for now to avoid variable // naming conflicts with beetle_psx_globals.h extern "C" uint8_t widescreen_hack; +extern "C" uint8_t widescreen_hack_aspect_ratio; +extern "C" uint8_t widescreen_hack_aspect_ratio_setting; extern "C" bool content_is_pal; extern "C" int filter_mode; extern "C" bool currently_interlaced; @@ -219,7 +221,7 @@ void rsx_vulkan_get_system_av_info(struct retro_system_av_info *info) info->geometry.aspect_ratio = rsx_common_get_aspect_ratio(content_is_pal, crop_overscan, content_is_pal ? initial_scanline_pal : initial_scanline, content_is_pal ? last_scanline_pal : last_scanline, - aspect_ratio_setting, show_vram, widescreen_hack); + aspect_ratio_setting, show_vram, widescreen_hack, widescreen_hack_aspect_ratio_setting); // Set retro_system_timing info->timing.fps = rsx_common_get_timing_fps(); @@ -249,6 +251,7 @@ void rsx_vulkan_refresh_variables(void) bool old_show_vram = show_vram; bool old_crop_overscan = crop_overscan; bool old_widescreen_hack = widescreen_hack; + unsigned old_widescreen_hack_aspect_ratio = widescreen_hack_aspect_ratio; bool visible_scanlines_changed = false; var.key = BEETLE_OPT(internal_resolution);