mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-27 02:32:02 -04:00
Scale widescreen cull margin to the display width; keep ratio sites on the 320 basis
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
+57
-15
@@ -716,6 +716,8 @@ int gpu_ws_netplay_local_viewport_width(void) {
|
||||
* unconditionally so a probe can sweep the cull margin live (0 = force 4:3
|
||||
* cull while still stretching; large = over-draw) at a fixed camera position.
|
||||
* -1 = normal computed margin. */
|
||||
static uint32_t gpu_h_display_width(void);
|
||||
static int ws_px_to_320(int px);
|
||||
static int ws_margin_override = -1;
|
||||
static int ws_cull_guard_pixels = 0;
|
||||
static int ws_activation_guard_pixels = 0;
|
||||
@@ -1169,7 +1171,7 @@ void gpu_ws_set_cull_scale_sites(const uint32_t *addresses,
|
||||
* (x < half*z/H) widens to the live view by scaling the bound by
|
||||
* (half + margin) / half. 64-bit intermediate; saturates to int32. */
|
||||
int32_t psx_ws_cull_scale(int32_t bound, int32_t half_extent) {
|
||||
const int32_t margin = psx_ws_x_margin();
|
||||
const int32_t margin = psx_ws_x_margin_320();
|
||||
if (margin <= 0 || half_extent <= 0) return bound;
|
||||
int64_t v = (int64_t)bound * (int64_t)(half_extent + margin) / half_extent;
|
||||
if (v > INT32_MAX) v = INT32_MAX;
|
||||
@@ -1225,7 +1227,7 @@ void gpu_ws_set_angle_sites(const uint32_t *addresses,
|
||||
|
||||
uint32_t psx_ws_angle_widen(uint32_t vanilla) {
|
||||
ws_angle_calls++;
|
||||
const int margin = psx_ws_x_margin();
|
||||
const int margin = psx_ws_x_margin_320();
|
||||
if (margin <= 0) {
|
||||
ws_angle_43_identity++;
|
||||
return vanilla;
|
||||
@@ -1448,7 +1450,7 @@ uint32_t psx_ws_aspect_cone_result(uint32_t site_address, uint32_t vanilla,
|
||||
|
||||
ws_aspect_cone_calls++;
|
||||
site->calls++;
|
||||
const int total_margin = psx_ws_x_margin();
|
||||
const int total_margin = psx_ws_x_margin_320();
|
||||
if (total_margin <= 0) {
|
||||
ws_aspect_cone_43_identity++;
|
||||
site->identity_43++;
|
||||
@@ -1473,8 +1475,8 @@ uint32_t psx_ws_aspect_cone_result(uint32_t site_address, uint32_t vanilla,
|
||||
}
|
||||
|
||||
const int visible_margin =
|
||||
(total_margin > ws_cull_guard_pixels)
|
||||
? total_margin - ws_cull_guard_pixels : 0;
|
||||
(total_margin > ws_px_to_320(ws_cull_guard_pixels))
|
||||
? total_margin - ws_px_to_320(ws_cull_guard_pixels) : 0;
|
||||
const int32_t fx =
|
||||
(int16_t)psx_read_half(ws_aspect_cone_forward_addr + 0u);
|
||||
const int32_t fz =
|
||||
@@ -1493,7 +1495,7 @@ uint32_t psx_ws_aspect_cone_result(uint32_t site_address, uint32_t vanilla,
|
||||
!in_visible && !in_guard && state->active &&
|
||||
psx_ws_aspect_cone_contains(
|
||||
x, z, y, fx, fz, fy, threshold,
|
||||
total_margin + (int)ws_aspect_cone_hysteresis_pixels);
|
||||
total_margin + ws_px_to_320((int)ws_aspect_cone_hysteresis_pixels));
|
||||
|
||||
if (!in_visible && !in_guard && !in_hysteresis) {
|
||||
state->active = 0;
|
||||
@@ -1546,6 +1548,18 @@ void gpu_ws_set_local_view_only(int on) { ws_local_view_only = on ? 1 : 0; }
|
||||
void gpu_ws_set_local_view_scope(int on) { ws_local_view_scope = on ? 1 : 0; }
|
||||
int gpu_ws_local_view_only(void) { return ws_local_view_only; }
|
||||
|
||||
/* Half of the game's current horizontal display width (160 for 320 modes). */
|
||||
static int ws_cull_half_width(void) {
|
||||
int src_w = 0;
|
||||
uint32_t w;
|
||||
if (ws_local_viewport_layout(NULL, &src_w, NULL, NULL))
|
||||
w = (uint32_t)src_w;
|
||||
else
|
||||
w = gpu_h_display_width();
|
||||
if (w < 64u) w = 320u;
|
||||
return (int)(w / 2u);
|
||||
}
|
||||
|
||||
int psx_ws_x_margin(void) {
|
||||
if (ws_local_view_only && !ws_local_view_scope) return 0;
|
||||
if (ws_margin_override >= 0) return ws_margin_override;
|
||||
@@ -1564,10 +1578,28 @@ int psx_ws_x_margin(void) {
|
||||
return ws_nw_configured_offset() * (ws_view_camera_addr ? 2 : 1)
|
||||
+ ws_cull_guard_pixels;
|
||||
if (!ws_active()) return 0;
|
||||
return (160 * (ws_xden - ws_xnum) + ws_xnum / 2) / ws_xnum
|
||||
/* The reveal is a fraction of the game's own half-width: a 512-wide mode
|
||||
* (Army Men in-game) hides 256*(1/s-1) px per side, not the 160*(1/s-1)
|
||||
* a 320 mode does. The screen-X compares live in that mode's pixels. */
|
||||
return (ws_cull_half_width() * (ws_xden - ws_xnum) + ws_xnum / 2) / ws_xnum
|
||||
+ ws_cull_guard_pixels;
|
||||
}
|
||||
|
||||
/* A pixel quantity of the current display mode on the 320-pixel basis. */
|
||||
static int ws_px_to_320(int px) {
|
||||
const int half = ws_cull_half_width();
|
||||
return half == 160 ? px : (int)(((int64_t)px * 160 + half / 2) / half);
|
||||
}
|
||||
|
||||
/* The same margin on the 320-pixel basis. Camera-space frustum angles, aspect
|
||||
* cones, scaled bounds and gameplay-field scalers are ratios authored against
|
||||
* a 160-pixel half-screen; they must not grow with the display mode. */
|
||||
int psx_ws_x_margin_320(void) {
|
||||
const int m = psx_ws_x_margin();
|
||||
const int half = ws_cull_half_width();
|
||||
return half == 160 ? m : (int)(((int64_t)m * 160 + half / 2) / half);
|
||||
}
|
||||
|
||||
int psx_ws_activation_margin(void) {
|
||||
const int margin = psx_ws_x_margin();
|
||||
return margin > 0 ? margin + ws_activation_guard_pixels : 0;
|
||||
@@ -1575,7 +1607,7 @@ int psx_ws_activation_margin(void) {
|
||||
|
||||
int32_t psx_ws_player_x_bound(int32_t vanilla)
|
||||
{
|
||||
const int margin = psx_ws_x_margin();
|
||||
const int margin = psx_ws_x_margin_320();
|
||||
if (margin <= 0) return vanilla;
|
||||
return (int32_t)(((int64_t)vanilla * (320 + 2 * margin)) / 320);
|
||||
}
|
||||
@@ -4536,12 +4568,10 @@ int gpu_display_is_depth24(void) {
|
||||
return (int)(display_depth & 1u);
|
||||
}
|
||||
|
||||
void gpu_get_display_info(GpuDisplayInfo* out) {
|
||||
out->display_x = display_area_x;
|
||||
out->display_y = display_area_y;
|
||||
out->depth24 = (int)(display_depth & 1u);
|
||||
out->disabled = (int)display_disabled;
|
||||
|
||||
/* Visible horizontal pixel width (GP1(08h) mode + GP1(06h) range). Shared by
|
||||
* gpu_get_display_info and the widescreen cull margin, which is called per
|
||||
* vertex and must not pay for the vertical layout. */
|
||||
static uint32_t gpu_h_display_width(void) {
|
||||
/* Dot-clock divider from GP1(08h) hres (PSX-SPX graphicsprocessingunitgpu,
|
||||
* "Horizontal Timings", Dotclocks: /10, /8, /7, /5, /4). */
|
||||
uint32_t cycles;
|
||||
@@ -4565,6 +4595,18 @@ void gpu_get_display_info(GpuDisplayInfo* out) {
|
||||
if (w == 0u) w = 4u;
|
||||
}
|
||||
|
||||
if (w > 640) w = 640;
|
||||
return w;
|
||||
}
|
||||
|
||||
void gpu_get_display_info(GpuDisplayInfo* out) {
|
||||
out->display_x = display_area_x;
|
||||
out->display_y = display_area_y;
|
||||
out->depth24 = (int)(display_depth & 1u);
|
||||
out->disabled = (int)display_disabled;
|
||||
|
||||
uint32_t w = gpu_h_display_width();
|
||||
|
||||
/* DuckStation GetFullDisplayResolution: clamp Y1/Y2 to the broadcast
|
||||
* active region before taking the difference. Unclamped Y2 past the
|
||||
* active end (common overscan programming) includes a flickering junk
|
||||
@@ -4590,7 +4632,7 @@ void gpu_get_display_info(GpuDisplayInfo* out) {
|
||||
* of the video — do not reintroduce it. Right-edge junk is a separate
|
||||
* present/filter issue, not a reason to shrink CRTC width. */
|
||||
|
||||
/* Clamp to sane maximums */
|
||||
/* Clamp to sane maximums (gpu_h_display_width clamps too) */
|
||||
if (w > 640) w = 640;
|
||||
if (out->depth24) {
|
||||
if (screen_h > PSX_DISPLAY_PRESENT_MAX_HEIGHT)
|
||||
|
||||
Reference in New Issue
Block a user