Make it so the 'crop overscan' option crops and centers according to the vertical and horizontal display ranges (fixes PAL overscan issues in particular).

This commit is contained in:
ds22x 2021-09-29 21:03:55 +02:00
parent fe1fb69d8d
commit cde89c9d35
4 changed files with 55 additions and 20 deletions

View File

@ -1091,9 +1091,9 @@ struct retro_core_option_v2_definition option_defs_us[] = {
},
{
BEETLE_OPT(crop_overscan),
"Crop Horizontal Overscan",
"Crop Overscan",
NULL,
"By default, the renderers add horizontal padding (pillarboxes on either side of the image) to emulate the same black bars generated in analog video output by real PSX hardware. Enabling this option removes horizontal padding.",
"By default, the renderers add padding (pillarboxes on either side of the image for NTSC, on all sides for PAL) to emulate the same black bars generated in analog video output by real PSX hardware. Enabling this option removes that padding.",
NULL,
"video",
{

View File

@ -33,6 +33,8 @@
#include "gpu_sprite.cpp"
#include "gpu_line.cpp"
extern bool crop_overscan;
/*
GPU display timing master clock is nominally 53.693182 MHz for NTSC PlayStations, and 53.203425 MHz for PAL PlayStations.
@ -1478,9 +1480,9 @@ int32_t GPU_Update(const int32_t sys_timestamp)
else
{
const unsigned int FirstVisibleLine =
GPU.LineVisFirst + (GPU.HardwarePALType ? 20 : 16);
GPU.LineVisFirst + (crop_overscan ? GPU.VertStart : (GPU.HardwarePALType ? 20 : 16));
const unsigned int VisibleLineCount =
GPU.LineVisLast + 1 - GPU.LineVisFirst; //HardwarePALType ? 288 : 240;
(crop_overscan ? (GPU.VertEnd - GPU.VertStart) - ((GPU.HardwarePALType ? 287 : 239) - GPU.LineVisLast) - GPU.LineVisFirst : GPU.LineVisLast + 1 - GPU.LineVisFirst); //HardwarePALType ? 288 : 240;
TIMER_SetHRetrace(false);
@ -1674,7 +1676,7 @@ int32_t GPU_Update(const int32_t sys_timestamp)
&& GPU.scanline < (FirstVisibleLine + VisibleLineCount))
{
int32 fb_x = GPU.DisplayFB_XStart * 2;
int32 dx_start = GPU.HorizStart, dx_end = GPU.HorizEnd;
int32 dx_start = (crop_overscan ? 608 : GPU.HorizStart), dx_end = GPU.HorizEnd;
int32 dest_line =
((GPU.scanline - FirstVisibleLine) << GPU.espec->InterlaceOn)
+ GPU.espec->InterlaceField;

View File

@ -795,7 +795,7 @@ Renderer::DisplayRect Renderer::compute_display_rect()
{
// Horizontal crop amount is currently hardcoded. Future improvement could allow adjusting this.
display_width = (2560/clock_div) - render_state.image_crop;
left_offset = floor(((render_state.horiz_start + render_state.offset_cycles - 608) / (double) clock_div) - (render_state.image_crop / 2));
left_offset = floor((render_state.offset_cycles / (double) clock_div) - (render_state.image_crop / 2));
}
else
{
@ -805,15 +805,31 @@ Renderer::DisplayRect Renderer::compute_display_rect()
unsigned display_height;
int upper_offset;
if (render_state.is_pal)
if (render_state.crop_overscan)
{
display_height = render_state.slend_pal - render_state.slstart_pal + 1;
upper_offset = render_state.vert_start - 20 - render_state.slstart_pal;
if (render_state.is_pal)
{
display_height = (render_state.vert_end - render_state.vert_start) - (287 - render_state.slend_pal) - render_state.slstart_pal;
upper_offset = 0 - render_state.slstart_pal;
}
else
{
display_height = (render_state.vert_end - render_state.vert_start) - (239 - render_state.slend) - render_state.slstart;
upper_offset = 0 - render_state.slstart;
}
}
else
{
display_height = render_state.slend - render_state.slstart + 1;
upper_offset = render_state.vert_start - 16 - render_state.slstart;
if (render_state.is_pal)
{
display_height = render_state.slend_pal - render_state.slstart_pal + 1;
upper_offset = render_state.vert_start - 20 - render_state.slstart_pal;
}
else
{
display_height = render_state.slend - render_state.slstart + 1;
upper_offset = render_state.vert_start - 16 - render_state.slstart;
}
}
display_height *= (render_state.is_480i ? 2 : 1);
upper_offset *= (render_state.is_480i ? 2 : 1);

View File

@ -1586,8 +1586,7 @@ static GlDisplayRect compute_gl_display_rect(GlRenderer *renderer)
{
width = (uint32_t) ((2560/clock_div) - renderer->image_crop);
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) - (renderer->image_crop / 2));
x = floor((offset_cycles / (double) clock_div) - (renderer->image_crop / 2));
}
else
{
@ -1599,17 +1598,35 @@ static GlDisplayRect compute_gl_display_rect(GlRenderer *renderer)
uint32_t height;
int32_t y;
if (renderer->config.is_pal)
if (renderer->crop_overscan)
{
int h = renderer->last_scanline_pal - renderer->initial_scanline_pal + 1;
height = (h < 0 ? 0 : (uint32_t) h);
y = (308 - renderer->config.display_area_vrange[1]) + (renderer->last_scanline_pal - 287);
if (renderer->config.is_pal)
{
int h = (renderer->config.display_area_vrange[1] - renderer->config.display_area_vrange[0]) - (287 - renderer->last_scanline_pal) - renderer->initial_scanline_pal;
height = (h < 0 ? 0 : (uint32_t) h);
y = renderer->last_scanline_pal - 287;
}
else
{
int h = (renderer->config.display_area_vrange[1] - renderer->config.display_area_vrange[0]) - (239 - renderer->last_scanline) - renderer->initial_scanline;
height = (h < 0 ? 0 : (uint32_t) h);
y = renderer->last_scanline - 239;
}
}
else
{
int h = renderer->last_scanline - renderer->initial_scanline + 1;
height = (h < 0 ? 0 : (uint32_t) h);
y = (256 - renderer->config.display_area_vrange[1]) + (renderer->last_scanline - 239);
if (renderer->config.is_pal)
{
int h = renderer->last_scanline_pal - renderer->initial_scanline_pal + 1;
height = (h < 0 ? 0 : (uint32_t) h);
y = (308 - renderer->config.display_area_vrange[1]) + (renderer->last_scanline_pal - 287);
}
else
{
int h = renderer->last_scanline - renderer->initial_scanline + 1;
height = (h < 0 ? 0 : (uint32_t) h);
y = (256 - renderer->config.display_area_vrange[1]) + (renderer->last_scanline - 239);
}
}
height *= (renderer->config.is_480i ? 2 : 1);
y *= (renderer->config.is_480i ? 2 : 1);