mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 10:19:47 -04:00
Preserve PGXP mod selection through renderer initialization
This commit is contained in:
@@ -733,6 +733,13 @@ some selections of one feature is a `[[requirement]]`, not a dependency.
|
||||
|
||||
## Implicit requirements across packages
|
||||
|
||||
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
|
||||
settings. Session start clears the selection before activating the new plan;
|
||||
the player's persistent settings remain unchanged. Explicit validation
|
||||
environment overrides still take precedence at renderer initialization.
|
||||
|
||||
Package format 7 lets a feature, while a condition on its own options holds,
|
||||
need a feature of **another** package:
|
||||
|
||||
|
||||
@@ -46,6 +46,9 @@ if(BUILD_TESTING)
|
||||
add_executable(mod_session_baseline_test tests/test_mod_session_baseline.c)
|
||||
target_include_directories(mod_session_baseline_test PRIVATE include)
|
||||
add_test(NAME mod_session_baseline_test COMMAND mod_session_baseline_test)
|
||||
add_executable(mod_pgxp_policy_test tests/test_mod_pgxp_policy.c)
|
||||
target_include_directories(mod_pgxp_policy_test PRIVATE include)
|
||||
add_test(NAME mod_pgxp_policy_test COMMAND mod_pgxp_policy_test)
|
||||
# Netplay: libjuice resolves from third_party/ with the network sealed,
|
||||
# and a recomp-net pinning another libjuice stops the configure.
|
||||
foreach(_psx_juice_case same other)
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef PSX_MOD_PGXP_POLICY_H
|
||||
#define PSX_MOD_PGXP_POLICY_H
|
||||
|
||||
/* Session overrides are independent of the player's persistent video config.
|
||||
* Renderer initialization resolves them again after activation, because GTE
|
||||
* and GPU initialization may reset the live correction flags. */
|
||||
typedef struct PSXModPgxpConfig {
|
||||
int geometry, textures, cpu;
|
||||
} PSXModPgxpConfig;
|
||||
typedef struct PSXModPgxpPolicy {
|
||||
int enabled, cpu; /* -1: no mod selection */
|
||||
} PSXModPgxpPolicy;
|
||||
static inline void psx_mod_pgxp_reset(PSXModPgxpPolicy* policy) {
|
||||
policy->enabled = policy->cpu = -1;
|
||||
}
|
||||
static inline void psx_mod_pgxp_select(PSXModPgxpPolicy* policy, int enabled, int cpu) {
|
||||
policy->enabled = enabled != 0;
|
||||
policy->cpu = cpu != 0;
|
||||
}
|
||||
static inline PSXModPgxpConfig psx_mod_pgxp_resolve(
|
||||
const PSXModPgxpPolicy* policy, PSXModPgxpConfig base) {
|
||||
if (policy->enabled >= 0) {
|
||||
base.geometry = base.textures = policy->enabled;
|
||||
base.cpu = policy->cpu;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
#endif
|
||||
@@ -138,6 +138,12 @@ uint32_t psx_mod_alloc_gpu_dma_memory(uint32_t size, uint32_t alignment);
|
||||
*/
|
||||
int psx_mod_set_main_ram_8mb(int enabled);
|
||||
|
||||
/* Session-owned precision selection, applied immediately and retained across
|
||||
* renderer initialization. Disabling a mod restores the player's base config
|
||||
* at the next session; explicit debug environment overrides still take priority.
|
||||
* Does not modify persistent settings or architectural GTE state. */
|
||||
void psx_mod_set_pgxp_precision(int enabled, int cpu_mode);
|
||||
|
||||
/* Current per-side widescreen reveal in native game pixels (zero at 4:3). */
|
||||
int32_t psx_mod_widescreen_x_margin(void);
|
||||
|
||||
|
||||
+25
-10
@@ -94,6 +94,7 @@ extern "C" void psx_event_step_conservative_env_init(void);
|
||||
#include "game_options.h"
|
||||
#include "mod_plugins.h"
|
||||
#include "mod_session_baseline.h"
|
||||
#include "mod_pgxp_policy.h"
|
||||
#include "mod_runtime.h"
|
||||
#include "mod_packages.h"
|
||||
#include "present_image_ring.h"
|
||||
@@ -1245,6 +1246,14 @@ static int g_video_geometry_correction = 0;
|
||||
static int g_video_perspective_texturing = 0;
|
||||
static int g_video_pgxp_cpu_mode = 0;
|
||||
static float g_video_pgxp_tolerance = 0.5f;
|
||||
static PSXModPgxpPolicy g_mod_pgxp_policy = {-1, -1};
|
||||
|
||||
extern "C" void psx_mod_set_pgxp_precision(int enabled, int cpu_mode) {
|
||||
psx_mod_pgxp_select(&g_mod_pgxp_policy, enabled, cpu_mode);
|
||||
gte_geometry_correction_set(enabled != 0);
|
||||
gpu_texture_correction_set(enabled != 0);
|
||||
pgxp_set_cpu_mode(cpu_mode != 0);
|
||||
}
|
||||
static int g_video_renderer = PSXRecompV4::DEFAULT_VIDEO_RENDERER;
|
||||
|
||||
/* Settings -> Display -> Internal resolution (internal_resolution.h). The
|
||||
@@ -1533,6 +1542,10 @@ extern "C" int psx_mod_set_adaptive_display_aspect(
|
||||
static PSXModSessionBaseline g_mod_owned_baseline;
|
||||
|
||||
static void reset_mod_owned_presentation(void) {
|
||||
psx_mod_pgxp_reset(&g_mod_pgxp_policy);
|
||||
gte_geometry_correction_set(g_video_geometry_correction);
|
||||
gpu_texture_correction_set(g_video_perspective_texturing);
|
||||
pgxp_set_cpu_mode(g_video_pgxp_cpu_mode);
|
||||
PSXModSessionScalars live;
|
||||
live.video_vsync = g_video_vsync;
|
||||
live.frame_interpolation = g_frame_interpolation;
|
||||
@@ -15933,15 +15946,17 @@ session_reboot:
|
||||
* corrections from process start so free-running (headless) boots can be
|
||||
* measured from the first projected vertex — a TCP toggle always arrives
|
||||
* after the interesting window. '0' = off, anything else = on. */
|
||||
PSXModPgxpConfig precision = psx_mod_pgxp_resolve(&g_mod_pgxp_policy,
|
||||
{g_video_geometry_correction, g_video_perspective_texturing, g_video_pgxp_cpu_mode});
|
||||
if (const char* e = std::getenv("PSX_GEOMETRY_CORRECTION"))
|
||||
g_video_geometry_correction = (*e && *e != '0') ? 1 : 0;
|
||||
precision.geometry = (*e && *e != '0') ? 1 : 0;
|
||||
if (const char* e = std::getenv("PSX_PERSPECTIVE_TEXTURING"))
|
||||
g_video_perspective_texturing = (*e && *e != '0') ? 1 : 0;
|
||||
precision.textures = (*e && *e != '0') ? 1 : 0;
|
||||
if (const char* e = std::getenv("PSX_PGXP_CPU_MODE"))
|
||||
g_video_pgxp_cpu_mode = (*e && *e != '0') ? 1 : 0;
|
||||
gte_geometry_correction_set(g_video_geometry_correction);
|
||||
gpu_texture_correction_set(g_video_perspective_texturing);
|
||||
pgxp_set_cpu_mode(g_video_pgxp_cpu_mode);
|
||||
precision.cpu = (*e && *e != '0') ? 1 : 0;
|
||||
gte_geometry_correction_set(precision.geometry);
|
||||
gpu_texture_correction_set(precision.textures);
|
||||
pgxp_set_cpu_mode(precision.cpu);
|
||||
pgxp_set_tolerance(g_video_pgxp_tolerance);
|
||||
/* Scanlines: env override wins over config, same as the corrections above,
|
||||
* so a headless/free-run boot can be captured with the effect armed from the
|
||||
@@ -15955,12 +15970,12 @@ session_reboot:
|
||||
}
|
||||
gl_renderer_set_scanlines(g_video_scanlines ? 1 : 0,
|
||||
g_video_scanline_strength);
|
||||
if (g_video_geometry_correction || g_video_perspective_texturing) {
|
||||
if (precision.geometry || precision.textures) {
|
||||
std::fprintf(stdout,
|
||||
"psxrecomp: geometry correction %s, perspective texturing %s%s\n",
|
||||
g_video_geometry_correction ? "on" : "off",
|
||||
g_video_perspective_texturing ? "on" : "off",
|
||||
(g_video_geometry_correction && requested_scale < 2)
|
||||
precision.geometry ? "on" : "off",
|
||||
precision.textures ? "on" : "off",
|
||||
(precision.geometry && requested_scale < 2)
|
||||
? " (needs [video] supersampling >= 2 to be visible)" : "");
|
||||
}
|
||||
/* Display aspect. Identity at the default 4:3. The present letterbox uses
|
||||
|
||||
@@ -21,10 +21,6 @@
|
||||
|
||||
#define PKG_PGXP "psx.enhancement.pgxp"
|
||||
|
||||
/* gte.cpp / gpu.c — the two correction toggles this mod arms. */
|
||||
extern void gte_geometry_correction_set(int enabled);
|
||||
extern void gpu_texture_correction_set(int enabled);
|
||||
|
||||
static int pgxp_option_flag(const char* feature, const char* id) {
|
||||
char text[16] = "";
|
||||
return psx_mod_option_value(PKG_PGXP, feature, id, text, sizeof text) &&
|
||||
@@ -32,9 +28,7 @@ static int pgxp_option_flag(const char* feature, const char* id) {
|
||||
}
|
||||
|
||||
static void builtin_pgxp_activate(void) {
|
||||
gte_geometry_correction_set(1);
|
||||
gpu_texture_correction_set(1); /* also arms the shadow engine */
|
||||
pgxp_set_cpu_mode(pgxp_option_flag("pgxp", "cpu_mode"));
|
||||
psx_mod_set_pgxp_precision(1, pgxp_option_flag("pgxp", "cpu_mode"));
|
||||
}
|
||||
|
||||
PSX_MOD_CONSTRUCTOR(psx_register_builtin_pgxp_plugin) {
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "mod_pgxp_policy.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void) {
|
||||
PSXModPgxpPolicy policy;
|
||||
PSXModPgxpConfig configured = {0, 0, 1};
|
||||
psx_mod_pgxp_reset(&policy);
|
||||
PSXModPgxpConfig live = psx_mod_pgxp_resolve(&policy, configured);
|
||||
assert(!live.geometry && !live.textures && live.cpu);
|
||||
|
||||
/* Activation before renderer initialization must survive re-resolution. */
|
||||
psx_mod_pgxp_select(&policy, 1, 0);
|
||||
live = psx_mod_pgxp_resolve(&policy, configured);
|
||||
assert(live.geometry && live.textures && !live.cpu);
|
||||
assert(!configured.geometry && !configured.textures && configured.cpu);
|
||||
|
||||
/* A later vanilla/netplay session inherits the player's config only. */
|
||||
psx_mod_pgxp_reset(&policy);
|
||||
live = psx_mod_pgxp_resolve(&policy, configured);
|
||||
assert(!live.geometry && !live.textures && live.cpu);
|
||||
configured.geometry = 1;
|
||||
live = psx_mod_pgxp_resolve(&policy, configured);
|
||||
assert(live.geometry && !live.textures && live.cpu);
|
||||
|
||||
psx_mod_pgxp_select(&policy, 0, 1);
|
||||
live = psx_mod_pgxp_resolve(&policy, configured);
|
||||
assert(!live.geometry && !live.textures && live.cpu);
|
||||
psx_mod_pgxp_select(&policy, 1, 1);
|
||||
live = psx_mod_pgxp_resolve(&policy, configured);
|
||||
assert(live.geometry && live.textures && live.cpu);
|
||||
puts("PGXP session policy passed");
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user