Add custom viewport + integer scale mode.

This commit is contained in:
Themaister 2013-04-20 12:48:33 +02:00
parent 7120e5842d
commit 4f7d3b5ea0
2 changed files with 138 additions and 66 deletions

View File

@ -220,7 +220,11 @@ rgui_handle_t *rgui_init(void)
// before it's configured.
rarch_viewport_t *custom = &g_extern.console.screen.viewports.custom_vp;
if (driver.video_data && (!custom->width || !custom->height))
{
driver.video->viewport_info(driver.video_data, custom);
aspectratio_lut[ASPECT_RATIO_CUSTOM].value =
(float)custom->width / custom->height;
}
return rgui;
}
@ -1376,16 +1380,23 @@ static int rgui_viewport_iterate(rgui_handle_t *rgui, rgui_action_t action)
unsigned menu_type = 0;
rgui_list_get_last(rgui->menu_stack, NULL, &menu_type);
struct retro_game_geometry *geom = &g_extern.system.av_info.geometry;
int stride_x = g_settings.video.scale_integer ?
geom->base_width : 1;
int stride_y = g_settings.video.scale_integer ?
geom->base_height : 1;
switch (action)
{
case RGUI_ACTION_UP:
if (menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT)
{
custom->y -= 1;
custom->height += 1;
custom->y -= stride_y;
custom->height += stride_y;
}
else
custom->height -= 1;
else if (custom->height >= (unsigned)stride_y)
custom->height -= stride_y;
if (driver.video_poke->apply_state_changes)
driver.video_poke->apply_state_changes(driver.video_data);
break;
@ -1393,11 +1404,13 @@ static int rgui_viewport_iterate(rgui_handle_t *rgui, rgui_action_t action)
case RGUI_ACTION_DOWN:
if (menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT)
{
custom->y += 1;
custom->height -= 1;
custom->y += stride_y;
if (custom->height >= stride_y)
custom->height -= stride_y;
}
else
custom->height += 1;
custom->height += stride_y;
if (driver.video_poke->apply_state_changes)
driver.video_poke->apply_state_changes(driver.video_data);
break;
@ -1405,11 +1418,12 @@ static int rgui_viewport_iterate(rgui_handle_t *rgui, rgui_action_t action)
case RGUI_ACTION_LEFT:
if (menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT)
{
custom->x -= 1;
custom->width += 1;
custom->x -= stride_x;
custom->width += stride_x;
}
else
custom->width -= 1;
else if (custom->width >= (unsigned)stride_x)
custom->width -= stride_x;
if (driver.video_poke->apply_state_changes)
driver.video_poke->apply_state_changes(driver.video_data);
break;
@ -1417,11 +1431,13 @@ static int rgui_viewport_iterate(rgui_handle_t *rgui, rgui_action_t action)
case RGUI_ACTION_RIGHT:
if (menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT)
{
custom->x += 1;
custom->width -= 1;
custom->x += stride_x;
if (custom->width >= (unsigned)stride_x)
custom->width -= stride_x;
}
else
custom->width += 1;
custom->width += stride_x;
if (driver.video_poke->apply_state_changes)
driver.video_poke->apply_state_changes(driver.video_data);
break;
@ -1429,34 +1445,46 @@ static int rgui_viewport_iterate(rgui_handle_t *rgui, rgui_action_t action)
case RGUI_ACTION_CANCEL:
rgui_list_pop(rgui->menu_stack, &rgui->selection_ptr);
if (menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT_2)
rgui_list_push(rgui->menu_stack, "", RGUI_SETTINGS_CUSTOM_VIEWPORT,
{
rgui_list_push(rgui->menu_stack, "",
RGUI_SETTINGS_CUSTOM_VIEWPORT,
rgui->selection_ptr);
}
break;
case RGUI_ACTION_OK:
rgui_list_pop(rgui->menu_stack, &rgui->selection_ptr);
if (menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT)
rgui_list_push(rgui->menu_stack, "", RGUI_SETTINGS_CUSTOM_VIEWPORT_2,
if (menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT
&& !g_settings.video.scale_integer)
{
rgui_list_push(rgui->menu_stack, "",
RGUI_SETTINGS_CUSTOM_VIEWPORT_2,
rgui->selection_ptr);
}
break;
case RGUI_ACTION_START:
#ifdef GEKKO
if (menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT)
if (!g_settings.video.scale_integer)
{
custom->width += custom->x;
custom->height += custom->y;
custom->x = 0;
custom->y = 0;
rarch_viewport_t vp;
driver.video->viewport_info(driver.video_data, &vp);
if (menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT)
{
custom->width += custom->x;
custom->height += custom->y;
custom->x = 0;
custom->y = 0;
}
else
{
custom->width = vp.full_width - custom->x;
custom->height = vp.full_height - custom->y;
}
if (driver.video_poke->apply_state_changes)
driver.video_poke->apply_state_changes(driver.video_data);
}
else
{
custom->width = win_width - custom->x;
custom->height = win_height - custom->y;
}
#endif
if (driver.video_poke->apply_state_changes)
driver.video_poke->apply_state_changes(driver.video_data);
break;
case RGUI_ACTION_SETTINGS:
@ -1476,16 +1504,45 @@ static int rgui_viewport_iterate(rgui_handle_t *rgui, rgui_action_t action)
render_text(rgui);
const char *base_msg = NULL;
if (menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT)
base_msg = "Set Upper-Left Corner";
else if (menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT_2)
base_msg = "Set Bottom-Right Corner";
char msg[64];
snprintf(msg, sizeof(msg), "%s (%d, %d : %4ux%4u)",
base_msg, custom->x, custom->y, custom->width, custom->height);
if (g_settings.video.scale_integer)
{
custom->x = 0;
custom->y = 0;
custom->width = ((custom->width + geom->base_width - 1) / geom->base_width) * geom->base_width;
custom->height = ((custom->height + geom->base_height - 1) / geom->base_height) * geom->base_height;
base_msg = "Set scale";
snprintf(msg, sizeof(msg), "%s (%4ux%4u, %u x %u scale)",
base_msg,
custom->width, custom->height,
custom->width / geom->base_width,
custom->height / geom->base_height);
}
else
{
if (menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT)
base_msg = "Set Upper-Left Corner";
else if (menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT_2)
base_msg = "Set Bottom-Right Corner";
snprintf(msg, sizeof(msg), "%s (%d, %d : %4ux%4u)",
base_msg, custom->x, custom->y, custom->width, custom->height);
}
render_messagebox(rgui, msg);
if (!custom->width)
custom->width = stride_x;
if (!custom->height)
custom->height = stride_y;
aspectratio_lut[ASPECT_RATIO_CUSTOM].value =
(float)custom->width / custom->height;
if (driver.video_poke->apply_state_changes)
driver.video_poke->apply_state_changes(driver.video_data);
return 0;
}
@ -1569,6 +1626,8 @@ static int rgui_settings_iterate(rgui_handle_t *rgui, rgui_action_t action)
// Start with something sane.
rarch_viewport_t *custom = &g_extern.console.screen.viewports.custom_vp;
driver.video->viewport_info(driver.video_data, custom);
aspectratio_lut[ASPECT_RATIO_CUSTOM].value =
(float)custom->width / custom->height;
g_settings.video.aspect_ratio_idx = ASPECT_RATIO_CUSTOM;
if (driver.video_poke->set_aspect_ratio)

View File

@ -128,40 +128,53 @@ void gfx_set_dwm(void)
void gfx_scale_integer(struct rarch_viewport *vp, unsigned width, unsigned height, float aspect_ratio, bool keep_aspect)
{
// Use system reported sizes as these define the geometry for the "normal" case.
unsigned base_height = g_extern.system.av_info.geometry.base_height;
// Account for non-square pixels.
// This is sort of contradictory with the goal of integer scale,
// but it is desirable in some cases.
// If square pixels are used, base_height will be equal to g_extern.system.av_info.base_height.
unsigned base_width = (unsigned)roundf(base_height * aspect_ratio);
int padding_x = 0;
int padding_y = 0;
unsigned padding_x = 0;
unsigned padding_y = 0;
// Make sure that we don't get 0x scale ...
if (width >= base_width && height >= base_height)
if (g_settings.video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
{
if (keep_aspect) // X/Y scale must be same.
{
unsigned max_scale = min(width / base_width, height / base_height);
padding_x = width - base_width * max_scale;
padding_y = height - base_height * max_scale;
}
else // X/Y can be independent, each scaled as much as possible.
{
padding_x = width % base_width;
padding_y = height % base_height;
}
}
const struct rarch_viewport *custom =
&g_extern.console.screen.viewports.custom_vp;
width -= padding_x;
height -= padding_y;
padding_x = width - custom->width;
padding_y = height - custom->height;
width = custom->width;
height = custom->height;
}
else
{
// Use system reported sizes as these define the geometry for the "normal" case.
unsigned base_height = g_extern.system.av_info.geometry.base_height;
// Account for non-square pixels.
// This is sort of contradictory with the goal of integer scale,
// but it is desirable in some cases.
// If square pixels are used, base_height will be equal to g_extern.system.av_info.base_height.
unsigned base_width = (unsigned)roundf(base_height * aspect_ratio);
// Make sure that we don't get 0x scale ...
if (width >= base_width && height >= base_height)
{
if (keep_aspect) // X/Y scale must be same.
{
unsigned max_scale = min(width / base_width, height / base_height);
padding_x = width - base_width * max_scale;
padding_y = height - base_height * max_scale;
}
else // X/Y can be independent, each scaled as much as possible.
{
padding_x = width % base_width;
padding_y = height % base_height;
}
}
width -= padding_x;
height -= padding_y;
}
vp->width = width;
vp->height = height;
vp->x = padding_x >> 1;
vp->y = padding_y >> 1;
vp->x = padding_x / 2;
vp->y = padding_y / 2;
}
struct aspect_ratio_elem aspectratio_lut[ASPECT_RATIO_END] = {