int setting_uint_action_left_custom_viewport_height( void *data, bool wraparound) { video_viewport_t vp; struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); video_viewport_t *custom = video_viewport_get_custom(); settings_t *settings = config_get_ptr(); struct retro_game_geometry *geom = (struct retro_game_geometry*) &av_info->geometry; if (!settings || !av_info) return -1; video_driver_get_viewport_info(&vp); if (custom->height <= 1) custom->height = 1; else if (settings->bools.video_scale_integer) { if (custom->height > geom->base_height) custom->height -= geom->base_height; } else custom->height -= 1; aspectratio_lut[ASPECT_RATIO_CUSTOM].value = (float)custom->width / custom->height; return 0; }
static int action_ok_custom_viewport(const char *path, const char *label, unsigned type, size_t idx) { menu_displaylist_info_t info = {0}; int ret = 0; video_viewport_t *custom = video_viewport_get_custom(); menu_handle_t *menu = menu_driver_get_ptr(); settings_t *settings = config_get_ptr(); if (!menu) return -1; info.list = menu->menu_list->menu_stack; info.type = MENU_SETTINGS_CUSTOM_VIEWPORT; info.directory_ptr = idx; strlcpy(info.label, "custom_viewport_1", sizeof(info.label)); ret = menu_displaylist_push_list(&info, DISPLAYLIST_GENERIC); video_driver_viewport_info(custom); aspectratio_lut[ASPECT_RATIO_CUSTOM].value = (float)custom->width / custom->height; settings->video.aspect_ratio_idx = ASPECT_RATIO_CUSTOM; event_command(EVENT_CMD_VIDEO_SET_ASPECT_RATIO); return ret; }
static void sdl_refresh_viewport(sdl2_video_t *vid) { int win_w, win_h; settings_t *settings = config_get_ptr(); SDL_GetWindowSize(vid->window, &win_w, &win_h); vid->vp.x = 0; vid->vp.y = 0; vid->vp.width = win_w; vid->vp.height = win_h; vid->vp.full_width = win_w; vid->vp.full_height = win_h; if (settings->video.scale_integer) video_viewport_get_scaled_integer(&vid->vp, win_w, win_h, video_driver_get_aspect_ratio(), vid->video.force_aspect); else if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { const struct video_viewport *custom = (const struct video_viewport*)video_viewport_get_custom(); if (custom) { vid->vp.x = custom->x; vid->vp.y = custom->y; vid->vp.width = custom->width; vid->vp.height = custom->height; } } else if (vid->video.force_aspect) { float delta; float device_aspect = (float)win_w / win_h; float desired_aspect = video_driver_get_aspect_ratio(); if (fabsf(device_aspect - desired_aspect) < 0.0001f) { /* 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.0f) / 2.0f + 0.5f; vid->vp.x = (int)roundf(win_w * (0.5f - delta)); vid->vp.width = (unsigned)roundf(2.0f * win_w * delta); } else { delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; vid->vp.y = (int)roundf(win_h * (0.5f - delta)); vid->vp.height = (unsigned)roundf(2.0f * win_h * delta); } } vid->should_resize = false; sdl_refresh_renderer(vid); }
void video_viewport_reset_custom(void) { struct video_viewport *custom_vp = video_viewport_get_custom(); if (!custom_vp) return; custom_vp->width = 0; custom_vp->height = 0; custom_vp->x = 0; custom_vp->y = 0; }
static bool xdk_renderchain_init(void *data, const void *_video_info, void *dev_data, const void *final_viewport_data, const void *info_data, bool rgb32 ) { unsigned width, height; d3d_video_t *d3d = (d3d_video_t*)data; LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)d3d->dev; const video_info_t *video_info = (const video_info_t*)_video_info; const LinkInfo *link_info = (const LinkInfo*)info_data; xdk_renderchain_t *chain = (xdk_renderchain_t*)d3d->renderchain_data; unsigned fmt = (rgb32) ? RETRO_PIXEL_FORMAT_XRGB8888 : RETRO_PIXEL_FORMAT_RGB565; struct video_viewport *custom_vp = video_viewport_get_custom(); (void)final_viewport_data; if (!xdk_renderchain_init_shader(d3d, NULL)) return false; video_driver_get_size(&width, &height); chain->dev = (LPDIRECT3DDEVICE)dev_data; //chain->video_info = video_info; chain->pixel_size = (fmt == RETRO_PIXEL_FORMAT_RGB565) ? 2 : 4; chain->tex_w = link_info->tex_w; chain->tex_h = link_info->tex_h; if (!renderchain_create_first_pass(d3d, video_info)) return false; /* FIXME */ if (custom_vp->width == 0) custom_vp->width = width; if (custom_vp->height == 0) custom_vp->height = height; return true; }
static void d3d_calculate_rect(void *data, unsigned *width, unsigned *height, int *x, int *y, bool force_full, bool allow_rotate) { float device_aspect = (float)*width / *height; d3d_video_t *d3d = (d3d_video_t*)data; settings_t *settings = config_get_ptr(); video_driver_get_size(width, height); gfx_ctx_translate_aspect(&device_aspect, *width, *height); *x = 0; *y = 0; if (settings->video.scale_integer && !force_full) { struct video_viewport vp = {0}; video_viewport_get_scaled_integer(&vp, *width, *height, video_driver_get_aspect_ratio(), d3d->keep_aspect); *x = vp.x; *y = vp.y; *width = vp.width; *height = vp.height; } else if (d3d->keep_aspect && !force_full) { float desired_aspect = video_driver_get_aspect_ratio(); #if defined(HAVE_MENU) if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { video_viewport_t *custom = video_viewport_get_custom(); if (custom) { *x = custom->x; *y = custom->y; *width = custom->width; *height = custom->height; } } else #endif { float delta; if (fabsf(device_aspect - desired_aspect) < 0.0001f) { /* 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.0f) / 2.0f + 0.5f; *x = int(roundf(*width * (0.5f - delta))); *width = unsigned(roundf(2.0f * (*width) * delta)); } else { delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; *y = int(roundf(*height * (0.5f - delta))); *height = unsigned(roundf(2.0f * (*height) * delta)); } } } }
static void vita2d_gfx_set_viewport(void *data, unsigned viewport_width, unsigned viewport_height, bool force_full, bool allow_rotate) { gfx_ctx_aspect_t aspect_data; unsigned width, height; int x = 0; int y = 0; float device_aspect = (float)viewport_width / viewport_height; struct video_ortho ortho = {0, 1, 1, 0, -1, 1}; settings_t *settings = config_get_ptr(); vita_video_t *vita = (vita_video_t*)data; video_driver_get_size(&width, &height); aspect_data.aspect = &device_aspect; aspect_data.width = viewport_width; aspect_data.height = viewport_height; video_context_driver_translate_aspect(&aspect_data); if (settings->video.scale_integer && !force_full) { video_viewport_get_scaled_integer(&vita->vp, viewport_width, viewport_height, video_driver_get_aspect_ratio(), vita->keep_aspect); viewport_width = vita->vp.width; viewport_height = vita->vp.height; } else if (vita->keep_aspect && !force_full) { float desired_aspect = video_driver_get_aspect_ratio(); #if defined(HAVE_MENU) if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { const struct video_viewport *custom = video_viewport_get_custom(); /* Vukan has top-left origin viewport. */ x = custom->x; y = custom->y; viewport_width = custom->width; viewport_height = custom->height; } else #endif { float delta; if (fabsf(device_aspect - desired_aspect) < 0.0001f) { /* 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.0f) / 2.0f + 0.5f; x = (int)roundf(viewport_width * (0.5f - delta)); viewport_width = (unsigned)roundf(2.0f * viewport_width * delta); } else { delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; y = (int)roundf(viewport_height * (0.5f - delta)); viewport_height = (unsigned)roundf(2.0f * viewport_height * delta); } } vita->vp.x = x; vita->vp.y = y; vita->vp.width = viewport_width; vita->vp.height = viewport_height; } else { vita->vp.x = 0; vita->vp.y = 0; vita->vp.width = viewport_width; vita->vp.height = viewport_height; } vita2d_set_projection(vita, &ortho, allow_rotate); /* Set last backbuffer viewport. */ if (!force_full) { vita->vp.width = viewport_width; vita->vp.height = viewport_height; } #if 0 vita->vp.x = (float)vita->vp.x; vita->vp.y = (float)vita->vp.y; vita->vp.width = (float)vita->vp.width; vita->vp.height = (float)vita->vp.height; vita->vp.minDepth = 0.0f; vita->vp.maxDepth = 1.0f; RARCH_LOG("Setting viewport @ %ux%u\n", viewport_width, viewport_height); #endif }
static void vita2d_gfx_update_viewport(vita_video_t* vita) { int x = 0; int y = 0; float device_aspect = ((float)PSP_FB_WIDTH) / PSP_FB_HEIGHT; float width = PSP_FB_WIDTH; float height = PSP_FB_HEIGHT; settings_t *settings = config_get_ptr(); if (settings->video.scale_integer) { video_viewport_get_scaled_integer(&vita->vp, PSP_FB_WIDTH, PSP_FB_HEIGHT, video_driver_get_aspect_ratio(), vita->keep_aspect); width = vita->vp.width; height = vita->vp.height; } else if (vita->keep_aspect) { float desired_aspect = video_driver_get_aspect_ratio(); if ( (vita->rotation == ORIENTATION_VERTICAL) || (vita->rotation == ORIENTATION_FLIPPED_ROTATED)) { device_aspect = 1.0 / device_aspect; width = PSP_FB_HEIGHT; height = PSP_FB_WIDTH; } #if defined(HAVE_MENU) if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { struct video_viewport *custom = video_viewport_get_custom(); if (custom) { x = custom->x; y = custom->y; width = custom->width; height = custom->height; } } else #endif { float delta; if ((fabsf(device_aspect - desired_aspect) < 0.0001f)) { /* 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.0f) / 2.0f + 0.5f; x = (int)roundf(width * (0.5f - delta)); width = (unsigned)roundf(2.0f * width * delta); } else { delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; y = (int)roundf(height * (0.5f - delta)); height = (unsigned)roundf(2.0f * height * delta); } if ( (vita->rotation == ORIENTATION_VERTICAL) || (vita->rotation == ORIENTATION_FLIPPED_ROTATED) ) { x = (PSP_FB_WIDTH - width) * 0.5f; y = (PSP_FB_HEIGHT - height) * 0.5f; } } vita->vp.x = x; vita->vp.y = y; vita->vp.width = width; vita->vp.height = height; } else { vita->vp.x = vita->vp.y = 0; vita->vp.width = width; vita->vp.height = height; } vita->vp.width += vita->vp.width&0x1; vita->vp.height += vita->vp.height&0x1; vita->should_resize = false; }
void init_video(void) { unsigned max_dim, scale, width, height; video_viewport_t *custom_vp = NULL; const input_driver_t *tmp = NULL; const struct retro_game_geometry *geom = NULL; video_info_t video = {0}; static uint16_t dummy_pixels[32] = {0}; driver_t *driver = driver_get_ptr(); global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); init_video_filter(video_state.pix_fmt); event_command(EVENT_CMD_SHADER_DIR_INIT); if (av_info) geom = (const struct retro_game_geometry*)&av_info->geometry; max_dim = max(geom->max_width, geom->max_height); scale = next_pow2(max_dim) / RARCH_SCALE_BASE; scale = max(scale, 1); if (video_state.filter.filter) scale = video_state.filter.scale; /* Update core-dependent aspect ratio values. */ video_viewport_set_square_pixel(geom->base_width, geom->base_height); video_viewport_set_core(); video_viewport_set_config(); /* Update CUSTOM viewport. */ custom_vp = video_viewport_get_custom(); if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { float default_aspect = aspectratio_lut[ASPECT_RATIO_CORE].value; aspectratio_lut[ASPECT_RATIO_CUSTOM].value = (custom_vp->width && custom_vp->height) ? (float)custom_vp->width / custom_vp->height : default_aspect; } video_driver_set_aspect_ratio_value( aspectratio_lut[settings->video.aspect_ratio_idx].value); if (settings->video.fullscreen) { width = settings->video.fullscreen_x; height = settings->video.fullscreen_y; } else { if (settings->video.force_aspect) { /* Do rounding here to simplify integer scale correctness. */ unsigned base_width = roundf(geom->base_height * video_driver_get_aspect_ratio()); width = roundf(base_width * settings->video.scale); } else width = roundf(geom->base_width * settings->video.scale); height = roundf(geom->base_height * settings->video.scale); } if (width && height) RARCH_LOG("Video @ %ux%u\n", width, height); else RARCH_LOG("Video @ fullscreen\n"); driver->display_type = RARCH_DISPLAY_NONE; driver->video_display = 0; driver->video_window = 0; if (!init_video_pixel_converter(RARCH_SCALE_BASE * scale)) { RARCH_ERR("Failed to initialize pixel converter.\n"); rarch_fail(1, "init_video()"); } video.width = width; video.height = height; video.fullscreen = settings->video.fullscreen; video.vsync = settings->video.vsync && !global->system.force_nonblock; video.force_aspect = settings->video.force_aspect; #ifdef GEKKO video.viwidth = settings->video.viwidth; video.vfilter = settings->video.vfilter; #endif video.smooth = settings->video.smooth; video.input_scale = scale; video.rgb32 = video_state.filter.filter ? video_state.filter.out_rgb32 : (video_state.pix_fmt == RETRO_PIXEL_FORMAT_XRGB8888); tmp = (const input_driver_t*)driver->input; /* Need to grab the "real" video driver interface on a reinit. */ find_video_driver(); #ifdef HAVE_THREADS if (settings->video.threaded && !video_state.hw_render_callback.context_type) { /* Can't do hardware rendering with threaded driver currently. */ RARCH_LOG("Starting threaded video driver ...\n"); if (!rarch_threaded_video_init(&driver->video, &driver->video_data, &driver->input, &driver->input_data, driver->video, &video)) { RARCH_ERR("Cannot open threaded video driver ... Exiting ...\n"); rarch_fail(1, "init_video()"); } } else #endif driver->video_data = driver->video->init(&video, &driver->input, &driver->input_data); if (!driver->video_data) { RARCH_ERR("Cannot open video driver ... Exiting ...\n"); rarch_fail(1, "init_video()"); } driver->video_poke = NULL; if (driver->video->poke_interface) driver->video->poke_interface(driver->video_data, &driver->video_poke); if (driver->video->viewport_info && (!custom_vp->width || !custom_vp->height)) { /* Force custom viewport to have sane parameters. */ custom_vp->width = width; custom_vp->height = height; video_driver_viewport_info(custom_vp); } video_driver_set_rotation( (settings->video.rotation + global->system.rotation) % 4); video_driver_suppress_screensaver(settings->ui.suspend_screensaver_enable); if (!driver->input) init_video_input(tmp); event_command(EVENT_CMD_OVERLAY_DEINIT); event_command(EVENT_CMD_OVERLAY_INIT); video_driver_cached_frame_set(&dummy_pixels, 4, 4, 8); #if defined(PSP) video_driver_set_texture_frame(&dummy_pixels, false, 1, 1, 1.0f); #endif }
static int action_iterate_menu_viewport(char *s, size_t len, const char *label, unsigned action, uint32_t hash) { int stride_x = 1, stride_y = 1; menu_displaylist_info_t info = {0}; struct retro_game_geometry *geom = NULL; const char *base_msg = NULL; unsigned type = 0; video_viewport_t *custom = video_viewport_get_custom(); menu_display_t *disp = menu_display_get_ptr(); menu_navigation_t *nav = menu_navigation_get_ptr(); menu_list_t *menu_list = menu_list_get_ptr(); settings_t *settings = config_get_ptr(); struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); if (!menu_list) return -1; menu_list_get_last_stack(menu_list, NULL, NULL, &type, NULL); geom = (struct retro_game_geometry*)&av_info->geometry; if (settings->video.scale_integer) { stride_x = geom->base_width; stride_y = geom->base_height; } switch (action) { case MENU_ACTION_UP: if (type == MENU_SETTINGS_CUSTOM_VIEWPORT) { custom->y -= stride_y; custom->height += stride_y; } else if (custom->height >= (unsigned)stride_y) custom->height -= stride_y; event_command(EVENT_CMD_VIDEO_APPLY_STATE_CHANGES); break; case MENU_ACTION_DOWN: if (type == MENU_SETTINGS_CUSTOM_VIEWPORT) { custom->y += stride_y; if (custom->height >= (unsigned)stride_y) custom->height -= stride_y; } else custom->height += stride_y; event_command(EVENT_CMD_VIDEO_APPLY_STATE_CHANGES); break; case MENU_ACTION_LEFT: if (type == MENU_SETTINGS_CUSTOM_VIEWPORT) { custom->x -= stride_x; custom->width += stride_x; } else if (custom->width >= (unsigned)stride_x) custom->width -= stride_x; event_command(EVENT_CMD_VIDEO_APPLY_STATE_CHANGES); break; case MENU_ACTION_RIGHT: if (type == MENU_SETTINGS_CUSTOM_VIEWPORT) { custom->x += stride_x; if (custom->width >= (unsigned)stride_x) custom->width -= stride_x; } else custom->width += stride_x; event_command(EVENT_CMD_VIDEO_APPLY_STATE_CHANGES); break; case MENU_ACTION_CANCEL: menu_entry_go_back(); if (hash == MENU_LABEL_CUSTOM_VIEWPORT_2) { info.list = menu_list->menu_stack; info.type = MENU_SETTINGS_CUSTOM_VIEWPORT; info.directory_ptr = nav->selection_ptr; menu_displaylist_push_list(&info, DISPLAYLIST_INFO); } break; case MENU_ACTION_OK: menu_list_flush_stack(menu_list, NULL, 49); if (type == MENU_SETTINGS_CUSTOM_VIEWPORT && !settings->video.scale_integer) { info.list = menu_list->menu_stack; strlcpy(info.label, menu_hash_to_str(MENU_LABEL_CUSTOM_VIEWPORT_2), sizeof(info.label)); info.type = 0; info.directory_ptr = nav->selection_ptr; menu_displaylist_push_list(&info, DISPLAYLIST_INFO); } break; case MENU_ACTION_START: if (!settings->video.scale_integer) { video_viewport_t vp; video_driver_viewport_info(&vp); if (type == MENU_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; } event_command(EVENT_CMD_VIDEO_APPLY_STATE_CHANGES); } break; case MENU_ACTION_MESSAGE: if (disp) disp->msg_force = true; break; default: break; } menu_list_get_last_stack(menu_list, NULL, &label, &type, NULL); if (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(s, len, "%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 (type == MENU_SETTINGS_CUSTOM_VIEWPORT) base_msg = menu_hash_to_str(MENU_LABEL_VALUE_CUSTOM_VIEWPORT_1); else if (hash == MENU_LABEL_CUSTOM_VIEWPORT_2) base_msg = menu_hash_to_str(MENU_LABEL_VALUE_CUSTOM_VIEWPORT_2); snprintf(s, len, "%s (%d, %d : %4ux%4u)", base_msg, custom->x, custom->y, custom->width, custom->height); } 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; event_command(EVENT_CMD_VIDEO_APPLY_STATE_CHANGES); return 0; }
static void psp_update_viewport(psp1_video_t* psp) { int x = 0; int y = 0; float device_aspect = ((float)SCEGU_SCR_WIDTH) / SCEGU_SCR_HEIGHT; float width = SCEGU_SCR_WIDTH; float height = SCEGU_SCR_HEIGHT; settings_t *settings = config_get_ptr(); if (settings->video.scale_integer) { video_viewport_get_scaled_integer(&psp->vp, SCEGU_SCR_WIDTH, SCEGU_SCR_HEIGHT, video_driver_get_aspect_ratio(), psp->keep_aspect); width = psp->vp.width; height = psp->vp.height; } else if (psp->keep_aspect) { float delta; float desired_aspect = video_driver_get_aspect_ratio(); #if defined(HAVE_MENU) if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { struct video_viewport *custom = video_viewport_get_custom(); if (custom) { x = custom->x; y = custom->y; width = custom->width; height = custom->height; } } else #endif { if ((fabsf(device_aspect - desired_aspect) < 0.0001f) || (fabsf((16.0/9.0) - desired_aspect) < 0.02f)) { /* 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.0f) / 2.0f + 0.5f; x = (int)roundf(width * (0.5f - delta)); width = (unsigned)roundf(2.0f * width * delta); } else { delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; y = (int)roundf(height * (0.5f - delta)); height = (unsigned)roundf(2.0f * height * delta); } } psp->vp.x = x; psp->vp.y = y; psp->vp.width = width; psp->vp.height = height; } else { psp->vp.x = psp->vp.y = 0; psp->vp.width = width; psp->vp.height = height; } psp->vp.width += psp->vp.width&0x1; psp->vp.height += psp->vp.height&0x1; psp_set_screen_coords(psp->frame_coords, psp->vp.x, psp->vp.y, psp->vp.width, psp->vp.height, psp->rotation); psp->should_resize = false; }
/** * video_viewport_get_scaled_integer: * @vp : Viewport handle * @width : Width. * @height : Height. * @aspect_ratio : Aspect ratio (in float). * @keep_aspect : Preserve aspect ratio? * * Gets viewport scaling dimensions based on * scaled integer aspect ratio. **/ void video_viewport_get_scaled_integer(struct video_viewport *vp, unsigned width, unsigned height, float aspect_ratio, bool keep_aspect) { int padding_x = 0, padding_y = 0; settings_t *settings = config_get_ptr(); if (!vp) return; if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { struct video_viewport *custom = video_viewport_get_custom(); if (custom) { padding_x = width - custom->width; padding_y = height - custom->height; width = custom->width; height = custom->height; } } else { unsigned base_width; /* Use system reported sizes as these define the * geometry for the "normal" case. */ struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); unsigned base_height = av_info ? av_info->geometry.base_height : 0; if (base_height == 0) base_height = 1; /* 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 * system->av_info.base_height. */ 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 / 2; vp->y = padding_y / 2; }
static void wiiu_gfx_update_viewport(wiiu_video_t* wiiu) { int x = 0; int y = 0; float width = wiiu->vp.full_width; float height = wiiu->vp.full_height; settings_t *settings = config_get_ptr(); float desired_aspect = video_driver_get_aspect_ratio(); if(wiiu->rotation & 0x1) desired_aspect = 1.0 / desired_aspect; if (settings->video.scale_integer) { video_viewport_get_scaled_integer(&wiiu->vp, wiiu->vp.full_width, wiiu->vp.full_height, desired_aspect, wiiu->keep_aspect); } else if (wiiu->keep_aspect) { #if defined(HAVE_MENU) if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { struct video_viewport *custom = video_viewport_get_custom(); if (custom) { x = custom->x; y = custom->y; width = custom->width; height = custom->height; } } else #endif { float delta; float device_aspect = ((float)wiiu->vp.full_width) / wiiu->vp.full_height; if (fabsf(device_aspect - desired_aspect) < 0.0001f) { /* 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.0f) / 2.0f + 0.5f; x = (int)roundf(width * (0.5f - delta)); width = (unsigned)roundf(2.0f * width * delta); } else { delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; y = (int)roundf(height * (0.5f - delta)); height = (unsigned)roundf(2.0f * height * delta); } } wiiu->vp.x = x; wiiu->vp.y = y; wiiu->vp.width = width; wiiu->vp.height = height; } else { wiiu->vp.x = wiiu->vp.y = 0; wiiu->vp.width = width; wiiu->vp.height = height; } float scale_w = wiiu->color_buffer.surface.width / 854.0; float scale_h = wiiu->color_buffer.surface.height / 480.0; wiiu_set_position(wiiu->position, &wiiu->color_buffer, wiiu->vp.x * scale_w, wiiu->vp.y * scale_h, (wiiu->vp.x + wiiu->vp.width) * scale_w, (wiiu->vp.y + wiiu->vp.height) * scale_h); wiiu->should_resize = false; DEBUG_LINE(); }
static void ctr_update_viewport(ctr_video_t* ctr) { int x = 0; int y = 0; float device_aspect = ((float)ctr->vp.full_width) / ctr->vp.full_height; float width = ctr->vp.full_width; float height = ctr->vp.full_height; settings_t *settings = config_get_ptr(); if (settings->video.scale_integer) { video_viewport_get_scaled_integer(&ctr->vp, ctr->vp.full_width, ctr->vp.full_height, video_driver_get_aspect_ratio(), ctr->keep_aspect); width = ctr->vp.width; height = ctr->vp.height; } else if (ctr->keep_aspect) { #if defined(HAVE_MENU) if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { struct video_viewport *custom = video_viewport_get_custom(); if (custom) { x = custom->x; y = custom->y; width = custom->width; height = custom->height; } } else #endif { float delta; float desired_aspect = video_driver_get_aspect_ratio(); if (fabsf(device_aspect - desired_aspect) < 0.0001f) { /* 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.0f) / 2.0f + 0.5f; x = (int)roundf(width * (0.5f - delta)); width = (unsigned)roundf(2.0f * width * delta); } else { delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; y = (int)roundf(height * (0.5f - delta)); height = (unsigned)roundf(2.0f * height * delta); } } ctr->vp.x = x; ctr->vp.y = y; ctr->vp.width = width; ctr->vp.height = height; } else { ctr->vp.x = ctr->vp.y = 0; ctr->vp.width = width; ctr->vp.height = height; } ctr_set_screen_coords(ctr); ctr->should_resize = false; }