From 3fd0b46215edb263a21989ff93ea080c1c5a1f59 Mon Sep 17 00:00:00 2001 From: Fierelier Date: Sun, 21 Sep 2025 14:50:14 +0000 Subject: [PATCH] [SDL3] [PS2] Framebuffer resolution + 240p/480p + PAL support (#13993) * Do not override NTSC/PAL * Fix PS2 build instructions * Add PS2 GS hints Allows for switching between NTSC/PAL, progressive/interlaced, etc --- docs/README-ps2.md | 8 ++++++- include/SDL3/SDL_hints.h | 31 +++++++++++++++++++++++++++ src/render/ps2/SDL_render_ps2.c | 38 +++++++++++++++++++++++++++++++-- 3 files changed, 74 insertions(+), 3 deletions(-) diff --git a/docs/README-ps2.md b/docs/README-ps2.md index d35856531f..dbda4459db 100644 --- a/docs/README-ps2.md +++ b/docs/README-ps2.md @@ -11,11 +11,17 @@ Credit to ## Building To build SDL library for the PS2, make sure you have the latest PS2Dev status and run: ```bash -cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=$PS2DEV/ps2sdk/ps2dev.cmake +cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=$PS2DEV/share/ps2dev.cmake cmake --build build cmake --install build ``` +## Hints +- `SDL_HINT_PS2_GS_WIDTH`: Width of the framebuffer. Defaults to 640. +- `SDL_HINT_PS2_GS_HEIGHT`: Height of the framebuffer. Defaults to 448. +- `SDL_HINT_PS2_GS_PROGRESSIVE`: Whether to use progressive, instead of interlaced. Defaults to 0. +- `SDL_HINT_PS2_GS_MODE`: Regional standard of the signal. "NTSC" (60hz), "PAL" (50hz) or "" (the console's region, default). + ## Notes If you trying to debug a SDL app through [ps2client](https://github.com/ps2dev/ps2client) you need to avoid the IOP reset, otherwise you will lose the connection with your computer. So to avoid the reset of the IOP CPU, you need to call to the macro `SDL_PS2_SKIP_IOP_RESET();`. diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index b01073af28..385afcbd71 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -3185,6 +3185,37 @@ extern "C" { */ #define SDL_HINT_ROG_GAMEPAD_MICE_EXCLUDED "SDL_ROG_GAMEPAD_MICE_EXCLUDED" +/** + * Variable controlling the width of the PS2's framebuffer in pixels + * + * By default, this variable is "640" + */ +#define SDL_HINT_PS2_GS_WIDTH "SDL_PS2_GS_WIDTH" + +/** + * Variable controlling the height of the PS2's framebuffer in pixels + * + * By default, this variable is "448" + */ +#define SDL_HINT_PS2_GS_HEIGHT "SDL_PS2_GS_HEIGHT" + +/** + * Variable controlling whether the signal is interlaced or progressive + * + * - "0": Image is interlaced. (default) + * - "1": Image is progressive + */ +#define SDL_HINT_PS2_GS_PROGRESSIVE "SDL_PS2_GS_PROGRESSIVE" + +/** + * Variable controlling the video mode of the console + * + * - "": Console-native. (default) + * - "NTSC": 60hz region + * - "PAL": 50hz region + */ +#define SDL_HINT_PS2_GS_MODE "SDL_PS2_GS_MODE" + /** * A variable controlling which Dispmanx layer to use on a Raspberry PI. * diff --git a/src/render/ps2/SDL_render_ps2.c b/src/render/ps2/SDL_render_ps2.c index f2b9ddae2c..36261a8a6b 100644 --- a/src/render/ps2/SDL_render_ps2.c +++ b/src/render/ps2/SDL_render_ps2.c @@ -655,8 +655,42 @@ static bool PS2_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_P gsGlobal = gsKit_init_global_custom(RENDER_QUEUE_OS_POOLSIZE, RENDER_QUEUE_PER_POOLSIZE); - gsGlobal->Mode = GS_MODE_NTSC; - gsGlobal->Height = 448; + // GS interlaced/progressive + if (SDL_GetHintBoolean(SDL_HINT_PS2_GS_PROGRESSIVE, false)) { + gsGlobal->Interlace = GS_NONINTERLACED; + } else { + gsGlobal->Interlace = GS_INTERLACED; + } + + // GS width/height + gsGlobal->Width = 0; + gsGlobal->Height = 0; + const char *hint = SDL_GetHint(SDL_HINT_PS2_GS_WIDTH); + if (hint) { + gsGlobal->Width = SDL_atoi(hint); + } + hint = SDL_GetHint(SDL_HINT_PS2_GS_HEIGHT); + if (hint) { + gsGlobal->Height = SDL_atoi(hint); + } + if (gsGlobal->Width <= 0) { + gsGlobal->Width = 640; + } + if (gsGlobal->Height <= 0) { + gsGlobal->Height = 448; + } + + // GS region + hint = SDL_GetHint(SDL_HINT_PS2_GS_MODE); + if (hint) { + if (SDL_strcasecmp(SDL_GetHint(SDL_HINT_PS2_GS_MODE), "NTSC") == 0) { + gsGlobal->Mode = GS_MODE_NTSC; + } + + if (SDL_strcasecmp(SDL_GetHint(SDL_HINT_PS2_GS_MODE), "PAL") == 0) { + gsGlobal->Mode = GS_MODE_PAL; + } + } gsGlobal->PSM = GS_PSM_CT24; gsGlobal->PSMZ = GS_PSMZ_16S;