diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 5753276c5..5f2193568 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -118,6 +118,17 @@ extern "C" { */ #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 * diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 7cc1324e1..106862722 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -1156,6 +1156,9 @@ UpdateLogicalSize(SDL_Renderer *renderer) float real_aspect; float scale; 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) { return 0; @@ -1164,6 +1167,23 @@ UpdateLogicalSize(SDL_Renderer *renderer) 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; real_aspect = (float)w / h; @@ -1187,21 +1207,47 @@ UpdateLogicalSize(SDL_Renderer *renderer) scale = (float)w / renderer->logical_w; SDL_RenderSetViewport(renderer, NULL); } else if (want_aspect > real_aspect) { - /* 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); + if (scale_policy == 1) { + /* We want a wider aspect ratio than is available - + zoom so logical height matches the real height + and the width will grow off the screen + */ + 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); + } 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 { - /* 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); + if (scale_policy == 1) { + /* We want a narrower aspect ratio than is available - + zoom so logical width matches the real width + and the height will grow off the screen + */ + 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 { + /* 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 */