Add horizontal offset option to GL and VK

This commit is contained in:
ggdrt 2019-11-19 15:46:38 -08:00
parent 26da9f0188
commit 49828593ce
5 changed files with 107 additions and 4 deletions

View File

@ -3455,6 +3455,9 @@ bool retro_load_game(const struct retro_game_info *info)
option_display.key = BEETLE_OPT(pgxp_texture);
environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
option_display.key = BEETLE_OPT(image_offset_cycles);
environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
break;
}
case RSX_OPENGL:

View File

@ -420,6 +420,66 @@ struct retro_core_option_definition option_defs_us[] = {
},
"disabled"
},
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) || defined(HAVE_VULKAN)
{
BEETLE_OPT(image_offset_cycles),
"Horizontal Image Offset (GPU Cycles)",
"Specify number of GPU cycles to offset image by. Positive values move image to the right, negative values move image to the left.",
{
{ "-24", NULL },
{ "-23", NULL },
{ "-22", NULL },
{ "-21", NULL },
{ "-20", NULL },
{ "-19", NULL },
{ "-18", NULL },
{ "-17", NULL },
{ "-16", NULL },
{ "-15", NULL },
{ "-14", NULL },
{ "-13", NULL },
{ "-12", NULL },
{ "-11", NULL },
{ "-10", NULL },
{ "-9", NULL },
{ "-8", NULL },
{ "-7", NULL },
{ "-6", NULL },
{ "-5", NULL },
{ "-4", NULL },
{ "-3", NULL },
{ "-2", NULL },
{ "-1", NULL },
{ "0", NULL },
{ "+1", NULL },
{ "+2", NULL },
{ "+3", NULL },
{ "+4", NULL },
{ "+5", NULL },
{ "+6", NULL },
{ "+7", NULL },
{ "+8", NULL },
{ "+9", NULL },
{ "+10", NULL },
{ "+11", NULL },
{ "+12", NULL },
{ "+13", NULL },
{ "+14", NULL },
{ "+15", NULL },
{ "+16", NULL },
{ "+17", NULL },
{ "+18", NULL },
{ "+19", NULL },
{ "+20", NULL },
{ "+21", NULL },
{ "+22", NULL },
{ "+23", NULL },
{ "+24", NULL },
{ NULL, NULL},
},
"0"
},
#endif
{
BEETLE_OPT(analog_calibration),
"Analog Self-Calibration",

View File

@ -703,12 +703,12 @@ Renderer::DisplayRect Renderer::compute_display_rect()
{
// Horizontal crop amount is currently hardcoded. Future improvement could allow adjusting this.
display_width = 2560/clock_div;
left_offset = (render_state.horiz_start - 608) / (int) clock_div;
left_offset = floor((render_state.horiz_start + render_state.offset_cycles - 608) / (double) clock_div);
}
else
{
display_width = 2800/clock_div;
left_offset = (render_state.horiz_start - 488) / (int) clock_div;
left_offset = floor((render_state.horiz_start + render_state.offset_cycles - 488) / (double) clock_div);
}
unsigned display_height;

View File

@ -110,6 +110,9 @@ public:
WidthMode width_mode = WidthMode::WIDTH_MODE_320;
bool crop_overscan = false;
// Experimental horizontal offset feature
int offset_cycles = 0;
int slstart = 0;
int slend = 239;
@ -209,6 +212,11 @@ public:
render_state.crop_overscan = crop_overscan;
}
void set_horizontal_offset_cycles(int offset_cycles)
{
render_state.offset_cycles = offset_cycles;
}
void set_visible_scanlines(int slstart, int slend, int slstart_pal, int slend_pal)
{
// May need bounds checking to reject bad inputs. Currently assume all inputs are valid.

View File

@ -2,6 +2,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <boolean.h>
#include <libretro.h>
@ -348,6 +349,9 @@ struct GlRenderer {
/* When true we perform no horizontal padding */
bool crop_overscan;
/* Experimental offset feature */
int32_t image_offset_cycles;
/* Scanline core options */
int32_t initial_scanline;
int32_t initial_scanline_pal;
@ -1244,6 +1248,13 @@ static bool GlRenderer_new(GlRenderer *renderer, DrawConfig config)
crop_overscan = false;
}
int32_t image_offset_cycles = 0;
var.key = BEETLE_OPT(image_offset_cycles);
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{
image_offset_cycles = atoi(var.value);
}
int32_t initial_scanline = 0;
var.key = BEETLE_OPT(initial_scanline);
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
@ -1441,6 +1452,7 @@ static bool GlRenderer_new(GlRenderer *renderer, DrawConfig config)
renderer->internal_upscaling = upscaling;
renderer->internal_color_depth = depth;
renderer->crop_overscan = crop_overscan;
renderer->image_offset_cycles = image_offset_cycles;
renderer->curr_width_mode = WIDTH_MODE_320;
renderer->initial_scanline = initial_scanline;
renderer->last_scanline = last_scanline;
@ -1572,12 +1584,16 @@ static GlDisplayRect compute_gl_display_rect(GlRenderer *renderer)
if (renderer->crop_overscan)
{
width = (uint32_t) (2560/clock_div);
x = ((int32_t) renderer->config.display_area_hrange[0] - 608) / clock_div;
int32_t offset_cycles = renderer->image_offset_cycles;
int32_t h_start = (int32_t) renderer->config.display_area_hrange[0];
x = floor((h_start - 608 + offset_cycles) / (double) clock_div);
}
else
{
width = (uint32_t) (2800/clock_div);
x = ((int32_t) renderer->config.display_area_hrange[0] - 488) / clock_div;
int32_t offset_cycles = renderer->image_offset_cycles;
int32_t h_start = (int32_t) renderer->config.display_area_hrange[0];
x = floor((h_start - 488 + offset_cycles) / (double) clock_div);
}
uint32_t height;
@ -1700,6 +1716,13 @@ static bool retro_refresh_variables(GlRenderer *renderer)
crop_overscan = false;
}
int32_t image_offset_cycles;
var.key = BEETLE_OPT(image_offset_cycles);
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{
image_offset_cycles = atoi(var.value);
}
int32_t initial_scanline = 0;
var.key = BEETLE_OPT(initial_scanline);
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
@ -1862,6 +1885,7 @@ static bool retro_refresh_variables(GlRenderer *renderer)
renderer->internal_color_depth = depth;
renderer->filter_type = filter;
renderer->crop_overscan = crop_overscan;
renderer->image_offset_cycles = image_offset_cycles;
renderer->initial_scanline = initial_scanline;
renderer->last_scanline = last_scanline;
renderer->initial_scanline_pal = initial_scanline_pal;
@ -3058,6 +3082,7 @@ static bool mdec_yuv;
static vector<function<void ()>> defer;
static dither_mode dither_mode = DITHER_NATIVE;
static bool crop_overscan;
static int image_offset_cycles;
static int initial_scanline;
static int last_scanline;
static int initial_scanline_pal;
@ -3271,6 +3296,12 @@ static void rsx_vulkan_refresh_variables(void)
crop_overscan = false;
}
var.key = BEETLE_OPT(image_offset_cycles);
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{
image_offset_cycles = atoi(var.value);
}
var.key = BEETLE_OPT(initial_scanline);
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{
@ -3327,6 +3358,7 @@ static void rsx_vulkan_finalize_frame(const void *fb, unsigned width,
renderer->set_adaptive_smoothing(adaptive_smoothing);
renderer->set_dither_native_resolution(dither_mode == DITHER_NATIVE);
renderer->set_horizontal_overscan_cropping(crop_overscan);
renderer->set_horizontal_offset_cycles(image_offset_cycles);
renderer->set_visible_scanlines(initial_scanline, last_scanline, initial_scanline_pal, last_scanline_pal);
if (renderer->get_scanout_mode() == Renderer::ScanoutMode::BGR24)