From 153a6513bc945cd7bcf2dcf772fde6fd8b5ea304 Mon Sep 17 00:00:00 2001 From: Bernhard Schelling <14200249+schellingb@users.noreply.github.com> Date: Thu, 20 Jul 2023 02:43:23 +0900 Subject: [PATCH] Add new "Overscan Border Size" video option (#180) --- core_options.h | 10 +++++++- dosbox_pure_libretro.cpp | 50 +++++++++++++++++++++++++++++++++------- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/core_options.h b/core_options.h index 5e4c2fda..828710f4 100644 --- a/core_options.h +++ b/core_options.h @@ -459,11 +459,19 @@ static retro_core_option_v2_definition option_defs[] = { "dosbox_pure_aspect_correction", "Aspect Ratio Correction", NULL, - "When enabled, the core's aspect ratio is set to what a CRT monitor would display." "\n\n", NULL, //end of Video section + "When enabled, the core's aspect ratio is set to what a CRT monitor would display.", NULL, "Video", { { "false", "Off (default)" }, { "true", "On" } }, "false" }, + { + "dosbox_pure_overscan", + "Overscan Border Size", NULL, + "When enabled, show a border around the display. Some games use the color of the border to convey information." "\n\n", NULL, //end of Video section + "Video", + { { "0", "Off (default)" }, { "1", "Small" }, { "2", "Medium" }, { "3", "Large" } }, + "0" + }, // System { diff --git a/dosbox_pure_libretro.cpp b/dosbox_pure_libretro.cpp index 1326ce20..4f4ca7ef 100644 --- a/dosbox_pure_libretro.cpp +++ b/dosbox_pure_libretro.cpp @@ -77,8 +77,8 @@ static Bit16s dbp_content_year; static const Bit32s Cycles1981to1999[1+1999-1981] = { 900, 1400, 1800, 2300, 2800, 3800, 4800, 6300, 7800, 14000, 23800, 27000, 44000, 55000, 66800, 93000, 125000, 200000, 350000 }; // DOSBOX AUDIO/VIDEO -static Bit8u buffer_active; -static struct DBP_Buffer { Bit32u video[SCALER_MAXWIDTH * SCALER_MAXHEIGHT], width, height; float ratio; } dbp_buffers[2]; +static Bit8u buffer_active, dbp_overscan; +static struct DBP_Buffer { Bit32u video[SCALER_MAXWIDTH * SCALER_MAXHEIGHT], width, height, border_color; float ratio; } dbp_buffers[2]; enum { DBP_MAX_SAMPLES = 4096 }; // twice amount of mixer blocksize (96khz @ 30 fps max) static int16_t dbp_audio[DBP_MAX_SAMPLES * 2]; // stereo static double dbp_audio_remain; @@ -1289,26 +1289,53 @@ Bitu GFX_SetSize(Bitu width, Bitu height, Bitu flags, double scalex, double scal Bit8u* GFX_GetPixels() { - return (Bit8u*)dbp_buffers[buffer_active^1].video; + Bit8u* pixels = (Bit8u*)dbp_buffers[buffer_active^1].video; + if (dbp_overscan) + { + Bit32u w = (Bit32u)render.src.width, border = w * dbp_overscan / 160; + pixels += ((w + border * 2) * border + border) * 4; + } + return pixels; } bool GFX_StartUpdate(Bit8u*& pixels, Bitu& pitch) { if (dbp_state == DBPSTATE_BOOT) return false; DBP_FPSCOUNT(dbp_fpscount_gfxstart) + Bit32u full_width = (Bit32u)render.src.width, full_height = (Bit32u)render.src.height; DBP_Buffer& buf = dbp_buffers[buffer_active^1]; pixels = (Bit8u*)buf.video; - pitch = render.src.width * 4; - float ratio = (float)render.src.width / render.src.height; + if (dbp_overscan) + { + Bit32u border = full_width * dbp_overscan / 160; + full_width += border * 2; + full_height += border * 2; + pixels += (full_width * border + border) * 4; + } + pitch = full_width * 4; + + float ratio = (float)full_width / full_height; if (render.aspect) ratio /= (float)render.src.ratio; if (ratio < 1) ratio *= 2; //because render.src.dblw is not reliable if (ratio > 2) ratio /= 2; //because render.src.dblh is not reliable - if (buf.width != render.src.width || buf.height != render.src.height || buf.ratio != ratio) + if (buf.width != full_width || buf.height != full_height || buf.ratio != ratio) { - buf.width = (Bit32u)render.src.width; - buf.height = (Bit32u)render.src.height; + buf.width = full_width; + buf.height = full_height; buf.ratio = ratio; + buf.border_color = 0xDEADBEEF; // force refresh + } + + if (dbp_overscan) + { + Bit32u border_color = (Bit32u)GFX_GetRGB(vga.dac.rgb[vga.attr.overscan_color].red<<2, vga.dac.rgb[vga.attr.overscan_color].green<<2, vga.dac.rgb[vga.attr.overscan_color].blue<<2); + if (border_color != buf.border_color) + { + buf.border_color = border_color; + for (Bit32u* p = (Bit32u*)buf.video, *pEnd = p + full_width*full_height; p != pEnd;) *(p++) = border_color; + } } + return true; } @@ -2421,6 +2448,13 @@ static bool check_variables(bool is_startup = false) Variables::DosBoxSet("render", "aspect", retro_get_variable("dosbox_pure_aspect_correction", "false")); + unsigned char new_overscan = (unsigned char)atoi(retro_get_variable("dosbox_pure_overscan", "0")); + if (new_overscan != dbp_overscan) + { + for (DBP_Buffer& buf : dbp_buffers) buf.border_color = 0xDEADBEEF; // force refresh + dbp_overscan = new_overscan; + } + const char* sblaster_conf = retro_get_variable("dosbox_pure_sblaster_conf", "A220 I7 D1 H5"); static const char sb_attribs[] = { 'A', 'I', 'D', 'H' }; static const char* sb_props[] = { "sbbase", "irq", "dma", "hdma" };