Commit Graph

253 Commits

Author SHA1 Message Date
Matthew Stanley bcda320f9c Anchor GTE-projected HUD pieces by translation; expose recent-GTE-projection query
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 14:12:26 -07:00
Aliet Exposito Garcia 1c4731bb14 feat: add configurable widescreen sxy culling support
Some PlayStation 1 titles implement trivial rejection by folding the sign bits of projected vertex screen coordinates across triangle or quad primitives with a chain of AND instructions. Without adjusting these checks during widescreen presentation, geometry in the newly revealed horizontal area is still rejected by the original 4:3 bounds. Rather than embedding title specific instruction patterns directly into the recompiler, this introduces a generalized `[[widescreen.cull.sxy]]` configuration schema within `game.toml`.

Game configurations can now declare multi vertex trivial rejection sequences by their exact AND instruction words, vertex registers and the branch that consumes the result. The loader derives the expected chain from those words and rejects any other shape. Each AND keeps its original value except for the horizontal sign bit, which survives only while that vertex lies beyond the revealed left edge, so vertical and right side rejection are preserved and 4:3 output is bit identical. Shifted coordinate lower edge comparisons reuse the existing `screen_x_sites` handling through a new `slti rt, x, 0` form instead of adding a separate site family.

Full parity is maintained between recompiled code and the dirty RAM interpreter by sharing the same runtime helper and validating every fold and consumer instruction word on both paths, leaving mismatching overlay variants untouched. This eliminates hardcoded game logic from the recompiler while giving titles clean geometry retention in expanded aspect ratios.
2026-10-24 12:28:38 -07:00
Matthew Stanley 182073bca9 Integrate current master and complete GPU fixture APIs 2026-10-22 15:35:38 -07:00
Shokunin 67200909e4 PGXP: keep full depth and unclamped XY for far geometry 2026-10-22 15:26:53 -07:00
Yves 510560e599 Preserve precise eye poses and clip near-camera geometry
Co-authored-by: Yves <calibratedbeats@gmail.com>
2026-10-23 05:45:20 +08:00
Alexandros Mandravillis e3705227b5 Document runtime provenance and hardware references (#731) 2026-10-22 14:23:14 -07:00
PeriBluGaming b285f08f16 Widescreen: honor screen_x_sites in the dirty-RAM interpreter (#728) 2026-10-21 14:45:40 -07:00
Zap0xfce2 1b778616b7 feat(widescreen): continue framebuffer-feedback sprites into native-wide bands (#692)
* feat(widescreen): continue framebuffer-feedback sprites into native-wide bands

Titles tag a 15-bit sprite that copies a framebuffer 1:1 (gpu_ws_tag_feedback_rect / psx_mod_tag_feedback_rect). Where it touches the draw area's edge, gpu.c emits band spans and the new optional backend op wide_feedback_rect (GL incl. render thread, software) samples the source buffer's wide surface. Band texels count as bit 15 set, as the centre does once the trail blends.

The software rasterizer now writes the texel's bit 15 into the framebuffer, and wide_full can dump the surface alpha ("alpha":1).

* fix(widescreen): quantise band feedback like packed VRAM

The centre samples 5-bit packed VRAM each frame; the band copy read the 8-bit wide surface and modulated with /128, so the bands drifted ~3 grey levels brighter and left a step at the 4:3 edge. Truncate like PACK_FS and modulate like TEX_FS.

* Reject fully clipped sprites before extending feedback margins

* Complete isolated resident and PGXP fixture collaborators

* Preserve existing line endings in the review fixes

---------

Co-authored-by: Matthew Stanley <1379tech@gmail.com>
2026-10-19 11:44:13 -07:00
Zap0xfce2 339007ecf1 feat(widescreen): screen_x_sites band form for sltu with the width in a register
Renderers that test a 16-bit screen X with an unsigned compare against a width kept in a register (often a loaded clip bound) reject every negative X, so widening the bound only reveals the right band. A screen_x site on sltu now routes through psx_ws_cull_sltu_band: -4m <= (int16)SX < W while widened, identity at 4:3. Four margins keep large near polygons whose corners all lie past one margin; an unbounded left side overflowed a renderer's fixed primitive lists. Covered by ws_cull_screen_x_hi_codegen_test; documented in WIDESCREEN.md.
2026-10-16 11:27:59 +02:00
Matthew Stanley a36754b7ee feat(renderer): allow guarded opaque sprite backgrounds in native wide 2026-10-14 12:11:10 -07:00
Matthew Stanley 12f98480b3 Preserve explicit GPU hold output state before the first held VBlank 2026-10-14 11:21:57 -07:00
Shokunin 0d096e2858 GPU: carry the depth24 held-VBlank flag in the snap; executable hold regression
Review follow-up on #661 (#636):
- test_depth24_present_hold_vblank.py reads sources as UTF-8 (cp1252 on
  native Windows Python raised UnicodeDecodeError).
- The present skip is now guest state: set at guest VBlank, read (not
  consumed) by the present and packed into the GPU snap's hold word (bit 8;
  older snaps derive it from the count). The executable test showed the
  host-side latch made the present of a restored tick differ from live on
  the last held VBlank (hold 0, skip 1), exposing stale trailing FMV
  columns after a rollback load.
- Depth24 scanout staging and trailing-column blanking move from main.cpp
  into gpu_depth24_stage_scanout (gpu.c), so the test renders through the
  same code every CPU depth24 present runs.
- New depth24_present_hold_exec_test: drives real gpu.c through a 15-bit to
  24-bit FMV, GP1(07h) retargets and mode transitions; compares hold, skip,
  upload span and snapshot bytes across windowed/headless/deferred presents,
  rollback replay from every tick and disk loads, and checks staged frames
  never show stale movie pixels while the new movie stays visible.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 10:53:21 -07:00
Shokunin 594d365060 GPU: count the depth24 present hold down at guest VBlank
GP1(07h) arms s_d24_present_hold to skip a few Swaps after a depth24
display-band retarget. The hold is in the GPU snap, but it counted down
only at host present: a headless run (and any path that skips the present)
left it stuck, and a rollback snap load zeroed it. In R4's 4-seat rollback
self-test the replayed saves then differed from the live saves of the same
ticks in the GPU section (hold 3 live, 0 replay; #636).

The count now moves at guest VBlank (gpu_vblank_tick), which also latches
whether the following present skips its Swap; the present only consumes
that latch. A rollback snap load keeps the restored count. A disk
savestate load still clears it so the restored VRAM shows at once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 17:19:25 -07:00
Matt Stanley 6eaf078699 Merge pull request #584 from RetroPortingToolKit/feat/gl-dithering
GL: PS1 dithering by default (native grid), elective fine/off modes
2026-10-13 10:10:53 -07:00
Shokunin 023af6d9d4 GL: opt-in PS1 dithering ([video] dithering = off|on|scaled)
The OpenGL renderer has always drawn shaded and texture-modulated pixels
at 8 bits per channel with no dither pattern (true colour). That stays the
default. 'on' applies the PS1 4x4 offset matrix and 5-bit truncation per
internal-resolution pixel; 'scaled' puts the pattern on the native grid,
so it reads like the console at any scale and the native VRAM is the same
at every internal resolution.

GP0(E1h) bit 9 reaches the backend through a new optional facade hook
(gr_set_dither) recorded for the render thread and Smooth motion redraws.
With the mode off nothing flushes and no uniform changes. Flat, raw and
other 5-bit-exact pixels are never touched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 02:18:29 -07:00
Matthew Stanley 8ff0495577 display_ring_get: decode whole display (480i, depth24) from the frame's VRAM snapshot
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-11 23:47:13 -07:00
Matthew Stanley 7dfef44598 Reconcile current master with validated X4 co-op support for PR23 playtest 2026-10-10 20:49:35 -07:00
Matthew Stanley ddbb979f18 fix: enable camera-plane clipping with native-wide projection correction 2026-10-10 00:48:17 -07:00
Matthew Stanley 37d3ab3e38 PGXP: track packets in mod guest regions and keep validated depth through the seam clamp
Enhancement arenas (GPU DMA aperture, Expansion-1 mod memory) were untracked, so Crash widescreen drew every vertex native with no depth. Adds depth stats/clear causes to pgxp, depth to pgxp_tri_ring, input_route_start at_frame, integer number keys in game.toml.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-09 13:20:27 -07:00
Matthew Stanley 8fff59f82c Agree trusted camera options and isolate local render transactions 2026-10-09 04:33:12 -07:00
Matthew Stanley 0662437c56 Merge commit '2b517f3a0529742647b4c12c1a6f3d4818b29d84' into integrate/pr558plus-fixes-20261008
# Conflicts:
#	runtime/include/gpu_render.h
#	runtime/src/gpu_gl_renderer.c
#	runtime/src/gpu_render.c
#	runtime/tests/gpu_hd_texture_stubs.inc
#	runtime/tests/test_gl_hd_texture_pack.c
2026-10-08 10:59:40 -07:00
Matthew Stanley eba5b86325 Integrate latest shared runtime with serial renderer and resident loading work
# Conflicts:
#	runtime/CMakeLists.txt
#	runtime/runtime.cmake
#	runtime/src/gpu.c
#	runtime/src/gpu_gl_renderer.c
#	runtime/src/memory.c
#	runtime/tests/run_gl_texture_filter.py
#	runtime/tests/test_gpu_gp0_history_guard.py
#	runtime/tests/test_savestate_status_protocol.py
2026-10-08 05:40:53 -07:00
Shokunin 2b517f3a05 HD + render thread: keep the A0 hold across HD activation and savestate loads
Track an open GP0(A0) upload in the renderer whatever the HD state
(facade gr_vram_upload_begin/commit/set_open): HD activation mid-A0
waits for the commit instead of reading the FBO over received words,
and a full-VRAM load no longer ends the hold; gpu.c restores it from
gp0_state on load and ends it on GP1(01h). Sync the render thread
before flushing dumps or reading HD diagnostics, suppress dumps from
generated frames, use _putenv on MinGW, drop a stale log. Adversarial
fixtures for both cases in full-VRAM and high-resolution-window modes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 03:41:54 -07:00
Shokunin dc2cd301d3 PGXP depth: no cost when off; render-thread-safe setters; Smooth motion honours depth
- gpu.c sends gr_set_depth_triangle only while a PGXP renderer feature is
  on (gl_renderer_pgxp_render_wanted): no RTH_DEPTH per triangle otherwise.
- The SZ rides in the textured vertex's unused colour alpha, so TEXV stays
  26 floats for every title.
- gl_renderer_set_pgxp_depth / _threshold / pgxp_render_stats sync with a
  live render thread (GL_RT_SYNC) like their neighbours.
- A depth-mode change is its own batch-break reason (7); batch_diag returns
  all eight reasons.
- Smooth-motion in-between frames replay RTH_DEPTH and test depth from
  their own clear; gl_frame_gen_test gains a PGXP pass (overlapping 3D
  triangles out of painter order) where the in-between frame must match
  the real one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 02:38:58 -07:00
Shokunin 2a36efcacb PGXP depth buffer for opaque 3D polygons (opt-in)
[video] pgxp_depth_buffer (default off; PSX_PGXP_DEPTH overrides) and
pgxp_depth_threshold. gpu.c hands the GL backend each triangle's GTE SZ when
all three vertices are dataflow-precise (gr_set_depth_triangle); the backend
draws those opaque triangles with a LEQUAL depth test and write. 2D,
unproven, semi-transparent polygons, lines and rectangles never test or
write. Depth mode is a batch key and rides in every high-resolution-window,
native-wide and render-thread replay command. Clears are colourless
depth-only draws through the flat batch: after a drawing-area change or a
fill, and when the average SZ rises by the threshold (4096, as DuckStation).
Generated (Smooth motion) frames draw without depth.

Docs: ENHANCEMENTS.md G1.14.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 02:38:41 -07:00
Matthew Stanley 7bcb11916a GPU packet keys keep the enhancement aperture apart from the main RAM it aliases
The UI prepass re-read aperture node payloads through the RAM-folded key, so
THPS2's relocated prim arena discarded the HUD squash every frame.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit fd6267e952)
2026-10-07 18:20:59 -07:00
Matthew Stanley 12036fab6e ws_ui_groups: count why a UI prepass was discarded
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit edd67d848e)
2026-10-07 18:20:59 -07:00
Matthew Stanley c55ddc4f29 Widescreen HUD size: proportional option shrinks the auto-UI HUD beyond 16:9
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 41a9889566)
2026-10-07 18:20:59 -07:00
Matthew Stanley 9af4abb94f Widescreen prepass: validate DMA nodes through an address index, not a scan per node
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 1ba6c41595)
2026-10-07 18:20:58 -07:00
Matthew Stanley 4b4fddb769 Present finite 2D backdrop scenes at 4:3 in native-wide
A full-screen rect backdrop that stops short of the reveal vetoes polygon overhang (Tomba village, beads-eio.4.28).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-07 17:46:17 -07:00
Shokunin 7b741b10f4 Frame generation: shared corners are one vertex; no motion rounding
The remaining tunnel cracks came from vertex sources, not from missing
depth: 46 % of R4 lookups were marked ambiguous because the same 3D point
is projected several times per frame (corners shared by separate meshes,
other functions), so those vertices fell back to a triangle-mean guess.
- The same point projected again is one vertex (the smaller identity, so
  the choice does not follow draw order).
- Up to two different points on one pixel are kept; gpu.c picks the one
  projected by the same function as the triangle's other vertices, else
  the one nearest their depth.
- Per-vertex motion is no longer rounded to 1/8 px: at high internal
  scales the rounding opened hairlines along long T-junction seams.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 12:57:02 -07:00
Shokunin dc4197c053 Frame generation: in-between frames from an in-between camera
Pairing triangles of consecutive draw lists by key and draw order paired
the wrong ones whenever the game reordered, culled or switched LODs (R4:
a grandstand of one repeated texture turned into a staircase; on a
synthetic version 225 of 226 pairs were wrong). No primitive is paired by
draw order any more.

gte.cpp notes each RTPS/RTPT output (only while generation is on) with an
identity (issuing ra + model-space vertex), its camera-space position and
H, indexed by screen word; gpu.c records each polygon vertex's source
ahead of the triangle (RTH_FG_SRC, never drawn). Per view the camera
motion between the two frames is fitted from the paired camera-space
vertices (RANSAC + least squares); one real frame is redrawn from the
in-between camera: world vertices re-projected, vertices moving against
the world (cars) lerped in camera space, CPU-built vertices moved with
their triangle, HUD/2D unchanged. Moving forward the older frame is
redrawn; uncovered areas show the newer real frame. A verdict rejects
the generated frame (the real one shows) without projections, with few
pairs/inliers, or with a motion no camera makes. Real frames are
unchanged (gl_frame_gen_test).

PSX_PRESENT_SHOT_BURST=N captures the next N composed frames, real and
generated, for checking in-between frames against their neighbours.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 12:57:02 -07:00
Matthew Stanley 62d5277174 Add guarded screen-space and tiled-strip widescreen tags 2026-10-07 12:06:57 -07:00
Matthew Stanley 3a11aea16d Refresh netplay validation against master retaining audited startup cache and local views 2026-10-07 11:59:16 -07:00
Matthew Stanley 7d0a18ebc6 Integrate netplay pad and own-view stack without dropping current-master behavior
Preserve negotiated content and dual-raster pass gates. Retain both fixture assertion sets and HD-off seams. Regenerate both BIOS with actual native emitter. Fix type-only rollback corrections and exclude extra-pad changes from digital-only promote gates.
2026-10-07 11:06:57 -07:00
Matthew Stanley c51f191c0b Merge reviewed render provenance and sky scheduler fix (PR546) 2026-10-07 10:48:15 -07:00
Matthew Stanley 77f3a90923 Preserve queued native frames and batch guarded GPU submission 2026-10-07 10:08:38 -07:00
Matthew Stanley ab4534455f Share bounded late OT replay and decoded framebuffer retargeting 2026-10-07 01:03:29 -07:00
Matthew Stanley 9e694d5c0a Retain header mismatch diagnostics on bounded OT walk 2026-10-07 00:02:55 -07:00
Matthew Stanley 6529c155a6 Keep existing GPU line endings during HUD integration 2026-10-06 23:57:28 -07:00
Matthew Stanley 4b0e5bd1db GPU packet keys keep the enhancement aperture apart from the main RAM it aliases
The UI prepass re-read aperture node payloads through the RAM-folded key, so
THPS2's relocated prim arena discarded the HUD squash every frame.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-06 23:56:07 -07:00
Matthew Stanley 37946ab43d ws_ui_groups: count why a UI prepass was discarded
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-06 23:55:44 -07:00
Matthew Stanley 308d7b9ca6 Widescreen HUD size: proportional option shrinks the auto-UI HUD beyond 16:9
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-06 23:55:19 -07:00
Matthew Stanley bceadc6124 Add DuckStation-compatible texture pack mod and gameplay dumping
Load modern texpage/texupload PNG replacements independently of DuckStation source. Integrate pack folders and options with mods, preserve native VRAM, and validate GL rendering, format matching, dump safety, and upload invalidation.
2026-10-06 23:24:47 -07:00
Matthew Stanley 20b0ea04bc Honor explicit HUD anchors in projection rendering 2026-10-06 21:49:56 -07:00
Matthew Stanley 58ccacc228 Restore GPU presentation provenance after render passes 2026-10-06 18:34:39 -07:00
Shokunin 33b842e97f netplay: per-player own-view mods, widescreen only inside the local view
A [[plugin]] may declare netplay = "local_view": it only changes what one
player sees. A netplay session now keeps the player's own features whose every
contribution is such a plugin (no writes, overlays or derived discs) instead of
clearing them, without saving state.toml. They activate as usual, but their
hooks run only inside psx_mod_render_local_view (psx_mod_local_view_scope) and
their vblank/savestate callbacks not at all. With such a plan the widescreen
cull margin is the stock 0 in the shared game and this peer's own margin only
inside the sandboxed own-view draw; squash is not used. The canonical frame,
snapshots and digests stay identical on every peer whatever each player chose,
so nothing is negotiated, and each keeps their own aspect.

Tests: netplay_view_mods_test (flag, plan filter, parked hooks, no vblank,
state.toml untouched), ws_local_view_margin_test (margin scope), render-pass
sandbox asserts the scope around a local view.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 14:17:26 -07:00
Matthew Stanley f9c7bb0a1c PGXP: carry precision through GTE-as-multiplier arithmetic and lwl/lwr word copies
Fixes Ape Escape terrain seams: CPU-built subdivision midpoints and lwl/lwr-copied
grid corners drew native next to precise neighbours. Adds pgxp_tri_ring/pgxp_store_ring.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-06 13:35:43 -07:00
Matthew Stanley a734cd9034 Record GPU list CPU holds, per-source exception cycles and recent C0 readbacks in always-on rings
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-05 22:52:52 -07:00
Matthew Stanley d247ce8b88 Add opt-in netplay local viewport width sites, fixed aspect and native-wide per-camera views
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-05 20:20:18 -07:00