mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
Preserve interlaced PAL scanout height
This commit is contained in:
@@ -5,6 +5,11 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* PAL active video is 288 lines per field and 576 rows when the interlaced
|
||||
* display bit is set. CPU presentation buffers must preserve that full
|
||||
* canvas even though PS1 VRAM itself remains 512 rows and wraps on access. */
|
||||
#define PSX_DISPLAY_PRESENT_MAX_HEIGHT 576u
|
||||
|
||||
typedef struct {
|
||||
uint32_t canvas_height;
|
||||
uint32_t canvas_origin_y;
|
||||
@@ -24,6 +29,12 @@ static inline uint32_t psx_display_present_height(
|
||||
return depth24 && canvas_height != 0u ? canvas_height : source_height;
|
||||
}
|
||||
|
||||
static inline uint32_t psx_display_interlaced_rows(
|
||||
uint32_t rows, int interlaced)
|
||||
{
|
||||
return interlaced ? rows * 2u : rows;
|
||||
}
|
||||
|
||||
/* Preserve the legacy default for an unset/degenerate GP1(07h) range. A
|
||||
* programmed increasing range that has no active-video intersection owns a
|
||||
* zero height instead, so presentation fails closed to black. */
|
||||
|
||||
+8
-5
@@ -3232,10 +3232,11 @@ void gpu_get_display_info(GpuDisplayInfo* out) {
|
||||
uint32_t screen_origin_y = vertical.valid ? vertical.canvas_origin_y : 0u;
|
||||
uint32_t screen_source_skip_y = vertical.valid ? vertical.source_skip_y : 0u;
|
||||
if (vres) {
|
||||
h *= 2; /* 480i */
|
||||
screen_h *= 2;
|
||||
screen_origin_y *= 2;
|
||||
screen_source_skip_y *= 2;
|
||||
h = psx_display_interlaced_rows(h, 1);
|
||||
screen_h = psx_display_interlaced_rows(screen_h, 1);
|
||||
screen_origin_y = psx_display_interlaced_rows(screen_origin_y, 1);
|
||||
screen_source_skip_y = psx_display_interlaced_rows(
|
||||
screen_source_skip_y, 1);
|
||||
}
|
||||
|
||||
/* 24-bit scanout uses the same CRTC pixel width as 15-bit (DuckStation /
|
||||
@@ -3247,7 +3248,9 @@ void gpu_get_display_info(GpuDisplayInfo* out) {
|
||||
|
||||
/* Clamp to sane maximums */
|
||||
if (w > 640) w = 640;
|
||||
if (screen_h > 512) screen_h = 512;
|
||||
const uint32_t max_screen_h = out->depth24
|
||||
? PSX_DISPLAY_PRESENT_MAX_HEIGHT : 512u;
|
||||
if (screen_h > max_screen_h) screen_h = max_screen_h;
|
||||
if (screen_origin_y > screen_h) screen_origin_y = screen_h;
|
||||
if (h > screen_h - screen_origin_y) h = screen_h - screen_origin_y;
|
||||
|
||||
|
||||
+13
-10
@@ -393,9 +393,8 @@ static void apply_offline_pad_count(int game_players, bool multitap_enabled)
|
||||
n = 2;
|
||||
g_offline_pad_count = n;
|
||||
}
|
||||
/* ARGB8888 staging buffer. Sized for the active internal resolution:
|
||||
* 640*scale x 512*scale. Allocated once the supersampling scale is known
|
||||
* (sized for the native 640x512 when supersampling is off). */
|
||||
/* ARGB8888 staging buffer. The 576-row maximum preserves the full interlaced
|
||||
* PAL active canvas. Allocated once the supersampling scale is known. */
|
||||
static uint32_t* sdl_pixel_buf = nullptr;
|
||||
|
||||
typedef void (*ModFrameHook)(void);
|
||||
@@ -1880,7 +1879,8 @@ static int ensure_sw_sdl_present(void) {
|
||||
sdl_renderer,
|
||||
SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
640 * tex_scale, 512 * tex_scale);
|
||||
640 * tex_scale,
|
||||
(int)PSX_DISPLAY_PRESENT_MAX_HEIGHT * tex_scale);
|
||||
if (!sdl_texture) {
|
||||
std::fprintf(stderr,
|
||||
"psxrecomp: netplay SW present: SDL_CreateTexture failed: %s\n",
|
||||
@@ -1893,7 +1893,8 @@ static int ensure_sw_sdl_present(void) {
|
||||
if (!sdl_pixel_buf) {
|
||||
const int tex_scale = netplay_cpu_auth_gpu() ? 1 : g_video_scale;
|
||||
sdl_pixel_buf = (uint32_t*)std::malloc(
|
||||
(size_t)640 * tex_scale * 512 * tex_scale * sizeof(uint32_t));
|
||||
(size_t)640 * tex_scale * PSX_DISPLAY_PRESENT_MAX_HEIGHT *
|
||||
tex_scale * sizeof(uint32_t));
|
||||
if (!sdl_pixel_buf) {
|
||||
std::fprintf(stderr, "psxrecomp: netplay SW present: staging alloc failed\n");
|
||||
return -1;
|
||||
@@ -7294,7 +7295,7 @@ static NetplayVblankEpilogue sdl_vblank_present_body(void) {
|
||||
* show that as a thin white strip; Wayland may not). Pad one black row
|
||||
* so any residual linear fringe is black, matching the letterbox. */
|
||||
const int tex_scale = netplay_cpu_auth_gpu() ? 1 : g_video_scale;
|
||||
const int tex_h = 512 * tex_scale;
|
||||
const int tex_h = (int)PSX_DISPLAY_PRESENT_MAX_HEIGHT * tex_scale;
|
||||
if (src_w > 0 && src_h > 0 && src_h < tex_h) {
|
||||
static uint32_t s_black_pad[640 * 4]; /* covers g_video_scale <= 4 */
|
||||
const int pad_cap = (int)(sizeof(s_black_pad) / sizeof(s_black_pad[0]));
|
||||
@@ -13706,12 +13707,13 @@ session_reboot:
|
||||
}
|
||||
}
|
||||
|
||||
/* Staging buffer + backing texture are sized for the internal resolution
|
||||
* (640x512 native, times the supersampling factor). Netplay: 1×. */
|
||||
/* Staging buffer + backing texture preserve the 576-row interlaced PAL
|
||||
* canvas, times the supersampling factor. Netplay: 1×. */
|
||||
{
|
||||
const int tex_scale = netplay_cpu_auth_gpu() ? 1 : g_video_scale;
|
||||
sdl_pixel_buf = (uint32_t*)std::malloc(
|
||||
(size_t)640 * tex_scale * 512 * tex_scale * sizeof(uint32_t));
|
||||
(size_t)640 * tex_scale * PSX_DISPLAY_PRESENT_MAX_HEIGHT *
|
||||
tex_scale * sizeof(uint32_t));
|
||||
if (!sdl_pixel_buf) {
|
||||
std::fprintf(stderr, "failed to allocate %dx staging buffer\n", tex_scale);
|
||||
return 1;
|
||||
@@ -13724,7 +13726,8 @@ session_reboot:
|
||||
sdl_renderer,
|
||||
SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
640 * tex_scale, 512 * tex_scale
|
||||
640 * tex_scale,
|
||||
(int)PSX_DISPLAY_PRESENT_MAX_HEIGHT * tex_scale
|
||||
);
|
||||
if (!sdl_texture) {
|
||||
std::fprintf(stderr, "SDL_CreateTexture failed: %s\n", SDL_GetError());
|
||||
|
||||
@@ -17,6 +17,9 @@ static void test_present_height(void)
|
||||
assert(psx_display_present_height(0, 225, 288) == 225);
|
||||
assert(psx_display_present_height(1, 225, 288) == 288);
|
||||
assert(psx_display_present_height(1, 225, 0) == 225);
|
||||
assert(psx_display_interlaced_rows(288, 0) == 288);
|
||||
assert(psx_display_interlaced_rows(288, 1) ==
|
||||
PSX_DISPLAY_PRESENT_MAX_HEIGHT);
|
||||
|
||||
PsxDisplayVerticalLayout unset = psx_display_vertical_layout(0, 100, 100);
|
||||
assert(!unset.range_set);
|
||||
|
||||
Reference in New Issue
Block a user