Allow trusted graphics mods to request a session-only internal resolution

This commit is contained in:
Matthew Stanley
2026-10-08 21:33:46 -07:00
parent 4e758ff9fc
commit 320d94869c
8 changed files with 87 additions and 3 deletions
+7
View File
@@ -757,6 +757,13 @@ some selections of one feature is a `[[requirement]]`, not a dependency.
## Implicit requirements across packages
Trusted graphics plugins can call `psx_mod_set_internal_resolution(lines)` to
request a rendering height for their session. Values from 120 through 8192 use
the existing integer-scale resolver and backend allocation limits; zero clears
the request. `PSX_INTERNAL_RESOLUTION` takes precedence. The player's saved
resolution stays unchanged, and every new session clears the request before
its mod plan activates, including rematches and sessions without that mod.
The shared PGXP plugin uses `psx_mod_set_pgxp_precision(enabled, cpu_mode)`.
This stores a session selection as well as setting live correction flags, so
later renderer initialization cannot erase mod activation with the base video
+6
View File
@@ -1248,6 +1248,12 @@ if(BUILD_TESTING)
endif()
add_test(NAME render_pass_plan_test COMMAND render_pass_plan_test)
add_executable(mod_internal_resolution_test
tests/test_mod_internal_resolution.c
src/mod_internal_resolution.c)
target_include_directories(mod_internal_resolution_test PRIVATE include)
add_test(NAME mod_internal_resolution_test COMMAND mod_internal_resolution_test)
# Motion kit and per-frame driver for render-pass plugins: blending,
# identity matching, limits and the crossfade fallback, on mock RAM.
add_executable(render_pass_motion_test
+17
View File
@@ -0,0 +1,17 @@
#ifndef PSX_MOD_INTERNAL_RESOLUTION_H
#define PSX_MOD_INTERNAL_RESOLUTION_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Runtime session plumbing; plugins use mod_plugins.h. Zero means no request. */
uint32_t psx_mod_internal_resolution_request(void);
void psx_mod_internal_resolution_reset(void);
#ifdef __cplusplus
}
#endif
#endif
+7
View File
@@ -431,6 +431,13 @@ int psx_mod_set_adaptive_display_aspect(uint32_t max_numerator,
* title's setting before activation.
*/
int psx_mod_set_widescreen_hud_size(int proportional);
/* Request an internal rendering height for this mod session (120..8192).
* The existing resolution resolver selects an integer raster scale and the
* backend applies its normal allocation limits. Zero clears the request.
* Player settings are preserved, explicit PSX_INTERNAL_RESOLUTION overrides
* win, and each session clears this request before activating its committed
* mod plan. */
int psx_mod_set_internal_resolution(uint32_t target_lines);
/*
* Set the wall-clock cadence of simulated guest VBlanks. A value of zero
* removes frontend pacing; 60 and higher request that many native guest
+1
View File
@@ -472,6 +472,7 @@ set(PSXRECOMP_RUNTIME_SOURCES
${PSXRECOMP_ROOT}/runtime/src/game_options.c
${PSXRECOMP_ROOT}/runtime/src/mod_builtin_speed.c
${PSXRECOMP_ROOT}/runtime/src/mod_builtin_pgxp.c
${PSXRECOMP_ROOT}/runtime/src/mod_internal_resolution.c
${PSXRECOMP_ROOT}/runtime/src/mod_builtin_bezel.c
${PSXRECOMP_ROOT}/runtime/src/mod_builtin_ram.c
${PSXRECOMP_ROOT}/runtime/src/mod_builtin_hd_textures.c
+5 -3
View File
@@ -11,6 +11,7 @@
#include "mod_controller_source.h"
#include "window_size.h" /* default game-window size */
#include "internal_resolution.h" /* Settings -> Display -> Internal resolution */
#include "mod_internal_resolution.h"
#include "dynamic_resolution.h" /* [video] dynamic_resolution: the step controller */
#include "render_thread.h" /* rt_get_stats: queue backpressure (dynres) */
#include "psx_scheduler.h" /* psx_scheduler_run — deterministic TCB scheduler */
@@ -1362,11 +1363,11 @@ static int video_scale_ceiling(void) {
return g_video_renderer == 1 ? GL_MAX_INTERNAL_SCALE : SW_MAX_INTERNAL_SCALE;
}
/* The preset in effect this run: the environment override, else the
* configured one. */
/* Session priority: environment override, active mod request, player setting. */
static int effective_internal_resolution(void) {
const uint32_t mod_lines = psx_mod_internal_resolution_request();
return g_video_internal_res_env != PSX_IR_UNSET ? g_video_internal_res_env
: g_video_internal_res;
: mod_lines ? (int)mod_lines : g_video_internal_res;
}
/* Resolve the Internal resolution preset into g_video_scale. display_px_h is
@@ -1703,6 +1704,7 @@ extern "C" int psx_mod_set_adaptive_display_aspect(
static PSXModSessionBaseline g_mod_owned_baseline;
static void reset_mod_owned_presentation(void) {
psx_mod_internal_resolution_reset();
psx_local_mouse_clear();
PSXModSessionScalars live;
live.video_vsync = g_video_vsync;
+19
View File
@@ -0,0 +1,19 @@
#include "mod_plugins.h"
#include "mod_internal_resolution.h"
static uint32_t requested_lines;
int psx_mod_set_internal_resolution(uint32_t target_lines) {
if (target_lines && (target_lines < 120u || target_lines > 8192u))
return 0;
requested_lines = target_lines;
return 1;
}
uint32_t psx_mod_internal_resolution_request(void) {
return requested_lines;
}
void psx_mod_internal_resolution_reset(void) {
requested_lines = 0;
}
@@ -0,0 +1,25 @@
#include "mod_plugins.h"
#include "mod_internal_resolution.h"
#include <stdio.h>
#define CHECK(x) do { if (!(x)) { fprintf(stderr, "Failed: %s\n", #x); return 1; } } while (0)
int main(void) {
/* Disabled sessions retain the configured baseline; a later launch must
* not inherit an earlier active graphics mod's requested height. */
CHECK(psx_mod_internal_resolution_request() == 0u);
CHECK(psx_mod_set_internal_resolution(1080u));
CHECK(psx_mod_internal_resolution_request() == 1080u);
CHECK(!psx_mod_set_internal_resolution(119u));
CHECK(!psx_mod_set_internal_resolution(8193u));
CHECK(!psx_mod_set_internal_resolution(UINT32_MAX));
CHECK(psx_mod_internal_resolution_request() == 1080u);
psx_mod_internal_resolution_reset();
CHECK(psx_mod_internal_resolution_request() == 0u);
CHECK(psx_mod_set_internal_resolution(120u));
CHECK(psx_mod_set_internal_resolution(8192u));
CHECK(psx_mod_set_internal_resolution(0u));
CHECK(psx_mod_internal_resolution_request() == 0u);
puts("session-scoped mod resolution validation passed");
return 0;
}