Jelajahi Sumber

[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
Fierelier 8 jam lalu
induk
melakukan
3fd0b46215
3 mengubah file dengan 74 tambahan dan 3 penghapusan
  1. 7 1
      docs/README-ps2.md
  2. 31 0
      include/SDL3/SDL_hints.h
  3. 36 2
      src/render/ps2/SDL_render_ps2.c

+ 7 - 1
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();`.

+ 31 - 0
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.
  *

+ 36 - 2
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;