Merged Eric Wing's overscan patch.

Fixes Bugzilla #2799.
Ryan C. Gordon 2017-06-06 14:06:40 -04:00
commit 9288983682
2 changed files with 71 additions and 14 deletions

View File

@ -118,6 +118,17 @@ extern "C" {
*/ */
#define SDL_HINT_RENDER_DIRECT3D11_DEBUG "SDL_RENDER_DIRECT3D11_DEBUG" #define SDL_HINT_RENDER_DIRECT3D11_DEBUG "SDL_RENDER_DIRECT3D11_DEBUG"
/**
* \brief A variable controlling the scaling policy for SDL_RenderSetLogicalSize.
*
* This variable can be set to the following values:
* "0" or "letterbox" - Uses letterbox/sidebars to fit the entire rendering on screen
* "1" or "overscan" - Will zoom the rendering so it fills the entire screen, allowing edges to be drawn offscreen
*
* By default letterbox is used
*/
#define SDL_HINT_RENDER_LOGICAL_SIZE_MODE "SDL_HINT_RENDER_LOGICAL_SIZE_MODE"
/** /**
* \brief A variable controlling the scaling quality * \brief A variable controlling the scaling quality
* *

View File

@ -1156,6 +1156,9 @@ UpdateLogicalSize(SDL_Renderer *renderer)
float real_aspect; float real_aspect;
float scale; float scale;
SDL_Rect viewport; SDL_Rect viewport;
/* 0 is for letterbox, 1 is for overscan */
int scale_policy = 0;
const char *hint = SDL_GetHint(SDL_HINT_RENDER_LOGICAL_SIZE_MODE);
if (!renderer->logical_w || !renderer->logical_h) { if (!renderer->logical_w || !renderer->logical_h) {
return 0; return 0;
@ -1164,6 +1167,23 @@ UpdateLogicalSize(SDL_Renderer *renderer)
return -1; return -1;
} }
if (!hint) {
scale_policy = 0;
} else if ( *hint == '1' || SDL_strcasecmp(hint, "overscan") == 0) {
/* Unfortunately, Direct3D 9 does't support negative viewport numbers
which the main overscan implementation relies on.
D3D11 does support negative values and uses a different id string
so overscan will work for D3D11.
*/
if(SDL_strcasecmp("direct3d", SDL_GetCurrentVideoDriver())) {
scale_policy = 0;
} else {
scale_policy = 1;
}
} else {
scale_policy = 0;
}
want_aspect = (float)renderer->logical_w / renderer->logical_h; want_aspect = (float)renderer->logical_w / renderer->logical_h;
real_aspect = (float)w / h; real_aspect = (float)w / h;
@ -1187,21 +1207,47 @@ UpdateLogicalSize(SDL_Renderer *renderer)
scale = (float)w / renderer->logical_w; scale = (float)w / renderer->logical_w;
SDL_RenderSetViewport(renderer, NULL); SDL_RenderSetViewport(renderer, NULL);
} else if (want_aspect > real_aspect) { } else if (want_aspect > real_aspect) {
/* We want a wider aspect ratio than is available - letterbox it */ if (scale_policy == 1) {
scale = (float)w / renderer->logical_w; /* We want a wider aspect ratio than is available -
viewport.x = 0; zoom so logical height matches the real height
viewport.w = w; and the width will grow off the screen
viewport.h = (int)SDL_ceil(renderer->logical_h * scale); */
viewport.y = (h - viewport.h) / 2; scale = (float)h / renderer->logical_h;
SDL_RenderSetViewport(renderer, &viewport); viewport.y = 0;
viewport.h = h;
viewport.w = (int)SDL_ceil(renderer->logical_w * scale);
viewport.x = (w - viewport.w) / 2;
SDL_RenderSetViewport(renderer, &viewport);
} else {
/* We want a wider aspect ratio than is available - letterbox it */
scale = (float)w / renderer->logical_w;
viewport.x = 0;
viewport.w = w;
viewport.h = (int)SDL_ceil(renderer->logical_h * scale);
viewport.y = (h - viewport.h) / 2;
SDL_RenderSetViewport(renderer, &viewport);
}
} else { } else {
/* We want a narrower aspect ratio than is available - use side-bars */ if (scale_policy == 1) {
scale = (float)h / renderer->logical_h; /* We want a narrower aspect ratio than is available -
viewport.y = 0; zoom so logical width matches the real width
viewport.h = h; and the height will grow off the screen
viewport.w = (int)SDL_ceil(renderer->logical_w * scale); */
viewport.x = (w - viewport.w) / 2; scale = (float)w / renderer->logical_w;
SDL_RenderSetViewport(renderer, &viewport); viewport.x = 0;
viewport.w = w;
viewport.h = (int)SDL_ceil(renderer->logical_h * scale);
viewport.y = (h - viewport.h) / 2;
SDL_RenderSetViewport(renderer, &viewport);
} else {
/* We want a narrower aspect ratio than is available - use side-bars */
scale = (float)h / renderer->logical_h;
viewport.y = 0;
viewport.h = h;
viewport.w = (int)SDL_ceil(renderer->logical_w * scale);
viewport.x = (w - viewport.w) / 2;
SDL_RenderSetViewport(renderer, &viewport);
}
} }
/* Set the new scale */ /* Set the new scale */