diff --git a/console/rgui/rgui.c b/console/rgui/rgui.c index 315f4fe9b4..d7bd41ee39 100644 --- a/console/rgui/rgui.c +++ b/console/rgui/rgui.c @@ -15,6 +15,7 @@ #include "rgui.h" #include "list.h" +#include "../rarch_console_video.h" #include #include #include @@ -335,6 +336,9 @@ static void render_text(rgui_handle_t *rgui) case RGUI_SETTINGS_VIDEO_GAMMA: snprintf(type_str, sizeof(type_str), "%d", g_console.gamma_correction); break; + case RGUI_SETTINGS_VIDEO_ASPECT_RATIO: + snprintf(type_str, sizeof(type_str), "%s", aspectratio_lut[g_console.aspect_ratio_index].name); + break; case RGUI_SETTINGS_VIDEO_ROTATION: { char rotate_msg[64]; @@ -469,6 +473,15 @@ static void rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t } } break; + case RGUI_SETTINGS_VIDEO_ASPECT_RATIO: + if (action == RGUI_ACTION_START) + rarch_settings_default(S_DEF_ASPECT_RATIO); + else if (action == RGUI_ACTION_LEFT) + rarch_settings_change(S_ASPECT_RATIO_DECREMENT); + else if (action == RGUI_ACTION_RIGHT) + rarch_settings_change(S_ASPECT_RATIO_INCREMENT); + video_set_aspect_ratio_func(g_console.aspect_ratio_index); + break; case RGUI_SETTINGS_VIDEO_ROTATION: if (action == RGUI_ACTION_START) { @@ -581,6 +594,7 @@ static void rgui_settings_populate_entries(rgui_handle_t *rgui) RGUI_MENU_ITEM("VI Trap filtering", RGUI_SETTINGS_VIDEO_SOFT_FILTER); #endif RGUI_MENU_ITEM("Gamma", RGUI_SETTINGS_VIDEO_GAMMA); + RGUI_MENU_ITEM("Aspect Ratio", RGUI_SETTINGS_VIDEO_ASPECT_RATIO); RGUI_MENU_ITEM("Rotation", RGUI_SETTINGS_VIDEO_ROTATION); RGUI_MENU_ITEM("Mute Audio", RGUI_SETTINGS_AUDIO_MUTE); RGUI_MENU_ITEM("Audio Control Rate", RGUI_SETTINGS_AUDIO_CONTROL_RATE); diff --git a/console/rgui/rgui.h b/console/rgui/rgui.h index ddf97874a4..476d310b12 100644 --- a/console/rgui/rgui.h +++ b/console/rgui/rgui.h @@ -41,6 +41,7 @@ typedef enum RGUI_SETTINGS_VIDEO_SOFT_FILTER, #endif RGUI_SETTINGS_VIDEO_GAMMA, + RGUI_SETTINGS_VIDEO_ASPECT_RATIO, RGUI_SETTINGS_VIDEO_ROTATION, RGUI_SETTINGS_AUDIO_MUTE, RGUI_SETTINGS_AUDIO_CONTROL_RATE, diff --git a/gx/gx_video.c b/gx/gx_video.c index b874ce22d7..84cb8d385c 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -17,6 +17,7 @@ #include "../driver.h" #include "../general.h" +#include "../console/rarch_console_video.h" #include "gx_video.h" #include #include @@ -45,6 +46,7 @@ struct uint8_t gx_fifo[256 * 1024] ATTRIBUTE_ALIGN(32); uint8_t display_list[1024] ATTRIBUTE_ALIGN(32); +uint16_t gx_width, gx_height; size_t display_list_size; float verts[16] ATTRIBUTE_ALIGN(32) = { @@ -84,6 +86,19 @@ float tex_coords_270[8] ATTRIBUTE_ALIGN(32) = { float *vertex_ptr = tex_coords; +void gx_set_aspect_ratio(void *data, unsigned aspectratio_idx) +{ + gx_video_t *gx = (gx_video_t*)driver.video_data; + + if (g_console.aspect_ratio_index == ASPECT_RATIO_AUTO) + rarch_set_auto_viewport(g_extern.frame_cache.width, g_extern.frame_cache.height); + + g_settings.video.aspect_ratio = aspectratio_lut[g_console.aspect_ratio_index].value; + g_settings.video.force_aspect = false; + gx->keep_aspect = true; + gx->should_resize = true; +} + static void retrace_callback(u32 retrace_count) { (void)retrace_count; @@ -205,6 +220,7 @@ static void *gx_init(const video_info_t *video, g_vsync = video->vsync; + gx->should_resize = true; return gx; } @@ -233,6 +249,8 @@ static void gx_start(void) build_disp_list(); g_vsync = true; + gx_width = mode->fbWidth; + gx_height = mode->efbHeight; } #define ASM_BLITTER @@ -414,6 +432,57 @@ static void update_texture(const uint32_t *src, GX_InvalidateTexAll(); } +static void gx_resize(gx_video_t *gx) +{ + unsigned x = 0, y = 0, width = gx_width, height = gx_height; + +#ifdef HW_RVL + VIDEO_SetTrapFilter(g_console.soft_display_filter_enable); +#endif + GX_SetDispCopyGamma(g_console.gamma_correction); + + if (gx->keep_aspect) + { + float desired_aspect = g_settings.video.aspect_ratio; + float device_aspect = CONF_GetAspectRatio() == CONF_ASPECT_4_3 ? 4.0 / 3.0 : 16.0 / 9.0; + float delta; + +#ifdef RARCH_CONSOLE + if (g_console.aspect_ratio_index == ASPECT_RATIO_CUSTOM) + { + // TODO + /*x = g_console.viewports.custom_vp.x; + y = g_console.viewports.custom_vp.y; + width = g_console.viewports.custom_vp.width; + height = g_console.viewports.custom_vp.height;*/ + } + else +#endif + { + if (fabs(device_aspect - desired_aspect) < 0.0001) + { + // If the aspect ratios of screen and desired aspect ratio are sufficiently equal (floating point stuff), + // assume they are actually equal. + } + else if (device_aspect > desired_aspect) + { + delta = (desired_aspect / device_aspect - 1.0) / 2.0 + 0.5; + x = (unsigned)(width * (0.5 - delta)); + width = (unsigned)(2.0 * width * delta); + } + else + { + delta = (device_aspect / desired_aspect - 1.0) / 2.0 + 0.5; + y = (unsigned)(height * (0.5 - delta)); + height = (unsigned)(2.0 * height * delta); + } + } + } + + GX_SetViewport(x, y, width, height, 0, 1); + gx->should_resize = false; +} + static bool gx_frame(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch, const char *msg) @@ -432,11 +501,7 @@ static bool gx_frame(void *data, const void *frame, if(should_resize) { -#ifdef HW_RVL - VIDEO_SetTrapFilter(g_console.soft_display_filter_enable); -#endif - GX_SetDispCopyGamma(g_console.gamma_correction); - gx->should_resize = false; + gx_resize(gx); } while (g_vsync && !g_draw_done) diff --git a/gx/gx_video.h b/gx/gx_video.h index 118f670ab2..996b12a7d1 100644 --- a/gx/gx_video.h +++ b/gx/gx_video.h @@ -20,9 +20,12 @@ typedef struct gx_video { bool menu_render; bool should_resize; + bool keep_aspect; uint32_t frame_count; uint32_t *menu_data; } gx_video_t; +void gx_set_aspect_ratio(void *data, unsigned aspectratio_idx); + #endif