Merged Eric Wing's overscan patch. Fixes Bugzilla #2799.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
diff --git a/include/SDL_hints.h b/include/SDL_hints.h
index 5753276..5f21935 100644
--- a/include/SDL_hints.h
+++ b/include/SDL_hints.h
@@ -119,6 +119,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
*
* This variable can be set to the following values:
diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c
index 7cc1324..1068627 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 */