Commit Graph

1232 Commits

Author SHA1 Message Date
Alex Vanderveen edc1695983 windows patches 2026-08-07 17:33:28 -04:00
Alex Vanderveen 302f2a3177 Merge branch 'integrate/game-codegen-hooks-into-rollback' of https://github.com/mstan/psxrecomp into integrate/game-codegen-hooks-into-rollback 2026-08-07 16:42:44 -04:00
Alex Vanderveen 46540c77d2 Windows scheduling paths 2026-08-07 16:42:43 -04:00
Alex Vanderveen 5920efb89d Windows scheduling paths 2026-08-07 16:42:06 -04:00
Alex Vanderveen 2e3e7365db CI hardening 2026-08-07 16:13:55 -04:00
Alex Vanderveen a3ee822742 Merge branch 'integrate/game-codegen-hooks-into-rollback' of https://github.com/mstan/psxrecomp into integrate/game-codegen-hooks-into-rollback 2026-08-07 14:53:57 -04:00
Alex Vanderveen 5748a228a4 hardening toolchain and build 2026-08-07 14:53:56 -04:00
Alex Vanderveen 7d73e6a247 hardening toolchain and build 2026-08-07 14:53:43 -04:00
Alex Vanderveen 346e627f3e toolchain + CI + wizard hardening 2026-08-07 14:33:43 -04:00
Alex Vanderveen 4aa919a06f setup wizard hardening 2026-08-07 14:06:23 -04:00
Alex Vanderveen 6a62730141 CI hardening 2026-08-07 12:57:28 -04:00
Alex Vanderveen 162a930512 codegen + bios launcher patch 2026-08-07 12:36:28 -04:00
Alex Vanderveen 2917936f6d Heal broken toolchain caches during ensure / rebuild.
Probe cmake --version; if the cache or latest pointer is unusable, clear
the bad pointer and stamp, then re-download (or install from zip) so
Generate & rebuild can recover without manual cleanup.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-07 12:27:50 -04:00
Alex Vanderveen 85ab30a0ba Find RetComM latest toolchain packs on Linux/macOS.
Install into versioned <tag>/ with latest as a pointer (not extract-into-
latest), honor RETCOMM_DATA_HOME/TOOLCHAIN_CACHE, and search both XDG and
~/.local/share so install.sh packs resolve during ensure/rebuild.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-07 12:19:58 -04:00
Alex Vanderveen 06c153d16f Include cpu_state.h in netplay RB stubs for AppleClang.
Setup-host builds without PSX_HAS_RECOMP_NET assign CPUState in
psx_netplay_rb_cpu_for_present_digest; a forward decl is not enough.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-07 11:56:11 -04:00
Alex Vanderveen 8451cd200f Merge branch 'integrate/game-codegen-hooks-into-rollback' of https://github.com/mstan/psxrecomp into integrate/game-codegen-hooks-into-rollback 2026-08-07 11:29:52 -04:00
Alex Vanderveen 598e3887a4 toolchain patch 2026-08-07 11:29:50 -04:00
Alex Vanderveen 11b82c23e8 toolchain patch 2026-08-07 11:29:44 -04:00
Alex Vanderveen 4cdccf58c1 multitap enhancements 2026-08-07 10:19:12 -04:00
Alex Vanderveen 33c9901497 buiild with ICE 2026-08-07 03:56:32 -04:00
Alex Vanderveen 67aaae8a75 buiild with ICE 2026-08-07 03:56:04 -04:00
Alex Vanderveen 7940137d0d bump setup script 2026-08-07 03:42:37 -04:00
Alex Vanderveen 03a187374c GH & CI patch automation 2026-08-07 03:25:11 -04:00
Alex Vanderveen c959cb81e0 Merge branch 'integrate/game-codegen-hooks-into-rollback' of https://github.com/mstan/psxrecomp into integrate/game-codegen-hooks-into-rollback 2026-08-07 03:24:40 -04:00
Alex Vanderveen bea16e3ad2 -DPSXRECOMP_ALLOW_NO_BIOS=ON 2026-08-07 03:24:34 -04:00
Alex Vanderveen ca3de47924 bump sub 2026-08-07 03:11:37 -04:00
Alex Vanderveen 09d94214af GH reorder 2026-08-07 03:08:40 -04:00
Alex Vanderveen 5170fedf5a Update recomp-net 2026-08-07 02:13:55 -04:00
Alex Vanderveen a79619462e update script 2026-08-07 02:04:55 -04:00
Alex Vanderveen 33d2253cc1 new build wizard 2026-08-07 01:45:36 -04:00
Alex Vanderveen 2112b91474 new URL 2026-08-07 01:43:25 -04:00
Alex Vanderveen 480fcad652 new build wizard 2026-08-07 01:43:04 -04:00
Alex Vanderveen 209f3e0cfb fix merge: wire mod APIs and pick_runtime_file cli flags
Include mod_plugins/mod_runtime and restore master’s four-arg file picker
so the integrate←master merge builds.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-06 22:55:43 -04:00
Alex Vanderveen 94cb3807a9 Merge origin/master into integrate/game-codegen-hooks-into-rollback
Keep rollback/netplay multiplayer routing, dual-raster GL present, and TOC
fingerprints while taking master's CHD support, mod load acceleration,
adaptive widescreen, and geometry/perspective APIs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-06 22:50:38 -04:00
Alex Vanderveen 8e274238da fix OSD 2026-08-06 22:39:36 -04:00
Alex Vanderveen 9b72328afa SFU preferred 2026-08-06 22:08:09 -04:00
Alex Vanderveen 4073e2311c rollback + fmv + connectivity 2026-08-06 20:34:50 -04:00
Alex Vanderveen 36e0d92c8b vram FMV hack gated for rollback 2026-08-06 00:53:03 -04:00
Alex Vanderveen 652be7ba02 rollback FMV patches and overlay 2026-08-06 00:52:14 -04:00
Matt Stanley 11ddfe62bc Merge pull request #105 from mstan/fix/autocompile-loud-degrade
autocompile: report a degraded (interpreter-only) run on a channel that exists
2026-08-05 19:38:29 -07:00
Matthew Stanley ab87cb8ef4 autocompile: report a degraded (interpreter-only) run on a channel that exists
A misconfigured overlay_autocompile_cmd silently degrades an entire session to
the interpreter. The diagnosis machinery for this already existed and was good
— autocompile_report_broken_once() fires after 3 consecutive failures and
explains exactly what to check — but it writes to fprintf(stdout), and the
shipped runtime links -mwindows: a GUI-subsystem binary with no console. The
warning is emitted into nothing on precisely the builds people run.

Observed cost: a fresh worktree ran 100% interpreted for a whole session
(runs=8 fails=8 shard_ok=0, dispatch_native=0) because game.toml named a
recompiler path the documented build recipe does not produce. The only symptom
was "it feels slow", and it invalidated a performance A/B before anyone thought
to query the counters by hand.

Three changes:

- Validate the command's path arguments at CONFIGURE time. The existing check
  resolves only the first token (the interpreter); it never looked at
  --recompiler, which is the argument that actually breaks — it is hardcoded
  per-title and disagrees with where the recipe builds. Paths now resolve
  against the child's working directory and are checked before any compile is
  attempted, rather than the truth emerging after three failed spawns.
  Advisory, not fatal: the runtime still runs exactly as before, just not
  silently.

- Record WHY in one string, exposed as degraded/degraded_reason in
  autocompile_status over the TCP debug server. Rule 3's answer rather than
  more printing. Keeps the FIRST cause, which is the useful one.

- Stamp it into psx_last_run_report.json. This is the part that prevents a
  repeat: a field you have to query is a field nobody queries. A degraded run
  now says so in its own artifact, so "was that measurement valid?" is
  answerable after the fact instead of having to be suspected.

test_autocompile_degraded (new, registered in CTest) builds the real failure
shape and asserts it is caught at configure time, that the reason names the
offending flag, that the first cause is retained, and that the reason is
escaped so it cannot break the JSON for every consumer.

Also fixes a pre-existing %d/LONG format mismatch on last_exit that this
change's argument shuffle surfaced; warnings on autocompile.c go 2 -> 1 (the
remaining array-bounds one in watch_thread is pre-existing and untouched).

NOT done here, deliberately: the underlying cause is that every title's
game.toml hardcodes a build-directory path (Tomba 2 names a worktree-relative
dir the recipe never creates; MMX6 hardcodes an absolute path into one
checkout). Fixing that means having CMake record the real recompiler location
and touching six title repos — its own change. This one makes the failure
impossible to miss.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 19:37:45 -07:00
Alex Vanderveen c8f668cc9e Fix lobby relay rewrite via WS peer IP and harden rollback netplay.
Resolve stash conflict in psx_lobby_client by keeping getpeername-based
relay rewrite with the RFC1918-aware path, and land pending rollback
hookup/runtime changes.
2026-08-05 22:23:30 -04:00
Matthew Stanley ea1e34dce5 feat(video): perspective_texturing defaults OFF again
Reverses the default from a423bb9c. The feature stays exactly as merged and is
still opt-in from the launcher's Display panel; only the default changes.

Reasoning: "structurally safe" is not the same as "validated". Perspective UVs
cannot crack a mesh the way geometry_correction does — no vertex moves, and a
polygon without proven projection provenance just keeps the PS1's affine
interpolation — but the feature has only been looked at on ONE title and ONE
renderer (Ape Escape, OpenGL, supersampling 2). Defaulting it on quietly changed
texture mapping for every title and for Vulkan, none of which had an isolation
run. That is a departure from hardware output shipped without evidence, which is
not how the faithful floor is supposed to work.

So both [video] knobs now default off, for different reasons worth keeping
straight: geometry_correction because it is BROKEN at the coverage we can reach,
with no control anywhere; perspective_texturing because it is unvalidated beyond
one title, with a launcher control so players can turn it on.

Test now pins both defaults off and its converse case checks the direction that
actually matters — perspective_texturing alone must not drag geometry_correction
on with it, since that is precisely what the launcher checkbox does.
39/41 recompiler tests pass; mod_load_acceleration and release_zip were already
failing beforehand.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 18:58:07 -07:00
Matt Stanley d10aa240a3 Merge pull request #104 from mstan/feat/spu-fidelity-103
spu: reverb, noise, sweeps and SPU IRQ (closes #103); CAUSE.IP2 combinational (supersedes #102)
2026-08-05 18:34:11 -07:00
Matthew Stanley 66af5c8dfb docs: drop our redundant embed_spirv fix, record the autocompile interp trap
Master fixed the embed_spirv.py concurrency race independently and better
(tempfile.TemporaryDirectory cleans up on early-return error paths too), so the
rebase conflict was resolved in master's favour and our mkdtemp version
removed. This branch stays SPU-only.

Records the trap that invalidated the first Tomba 2 measurement: game.toml's
overlay_autocompile_cmd names a recompiler path, and when it is absent
autocompile fails every attempt, no shard is ever built, and the runtime
silently interprets everything. Tomba 2 expects a worktree-relative path the
documented build recipe does not produce; MMX6 hardcodes an absolute path into
the main repo that works only by luck of local layout. Check autocompile_status
before trusting any perf number from a fresh worktree.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 18:20:13 -07:00
Matthew Stanley 7e1421be7c docs: correct the Tomba 2 perf measurement (first attempt was interp-bound)
The first FMV A/B was run on a fresh worktree whose overlay shard cache was
cold AND whose autocompile could never work: game.toml points at
psxrecomp-v4/recompiler/build-t2/psxrecomp-game.exe while the documented build
recipe builds the recompiler at build-recompiler/ in the worktree root, so it
failed 8/8 with WinError 2 and the runtime silently ran interpreted
(dispatch_native = 0). The '40 fps / ~19 underruns per second' attributed to
master in the previous commit was that broken setup, not master.

Re-measured against the fully warm cache with the pre-SPU exe as a control in
the same worktree: interp_share 0.7813 vs 0.7775, exc_share 0.2386 vs 0.2381,
39.1 vs 38.0-38.4 fps. Identical within noise, so the DSP work is free.

Separately characterises the real pre-existing defect: the FMV is 96% native by
dispatch count but 78% interpreted by wall clock with 24% in exception
handling, even warm.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 18:16:17 -07:00
Matthew Stanley fe518e3031 docs: record SPU fidelity validation results and merge prerequisites
Measured, not asserted:
- BIOS LLE boot proves the reverb engine runs and rings down after the dry
  signal stops; noise LFSR observed shifting with correct parity feedback.
- Tomba 2 intro FMV A/B against the exact parent commit shows the added
  per-frame DSP work is performance-neutral (min p50 40.0 vs 40.3 fps) and
  does not starve the CD bus or the host sink. The FMV's 40 fps and its
  ~19/s host underruns are PRE-EXISTING on master.
- Records all ten places the documentation ran out as an oracle-comparison
  work list, and the two merge prerequisites (rebase onto moved master; bump
  recomp-ui to 99558ee or no title compiles).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 18:16:17 -07:00
Matthew Stanley 6e6a0b3ed8 spu: implement reverb, noise, sweeps and SPU IRQ; make CAUSE.IP2 combinational
Closes the four gaps named in issue #103 and lands the separable, verified
parts of PR #102. See docs/internal/SPU_FIDELITY_103.md for the per-piece
disposition and the oracle-verification queue.

SPU DSP (issue #103), clean-room from hardware documentation:

- Reverb: the documented 22050 Hz engine — vLIN/vRIN input, same-side and
  crossed different-side IIR reflections, 4-tap comb early echo, both
  all-pass filters, vLOUT/vROUT output, and the work-area address advance.
  Gated on SPUCNT bit 7 for WRITES only; reads, IRQ checks, address advance
  and output always run, as on hardware. Addressing is confined to
  [mBASE, 0x80000). Per-voice sends from EON, CD send from SPUCNT bits 0+2.
- Noise: 16-bit LFSR with the documented parity feedback, clocked at the
  SPUCNT bits 8-13 rate; NON voices substitute it for their ADPCM sample.
- Volume sweeps: all 24 voice L/R plus main L/R. Bit 15 selects sweep vs
  direct; sweep is a live envelope on the same rate machinery as ADSR, and a
  guest read of a sweeping register returns the live level.
- Capture buffers: CD L/R and voice 1/3 output written to SPU RAM, so a game
  that parks the IRQ address there still gets its interrupt.
- SPU IRQ (I_STAT bit 9): checked at every SPU RAM access class — FIFO, DMA
  both directions, ADPCM block fetch, capture writes, reverb work-area
  accesses — gated on SPUCNT bit 6, mirrored in SPUSTAT bit 6, acked by
  clearing SPUCNT bit 6.

The CD-only fast path in spu_render was removed rather than extended: the
SPU now has per-frame work that must run in every path, and an FMV (XA audio
with zero active voices) is exactly the CD-with-reverb case.

This is a clean-room implementation from the psx-spx/nocash register map and
documented algorithm. Beetle's source was deliberately not consulted: it is
GPL-2.0-or-later and this project is PolyForm Noncommercial. PR #16 was
parked for exactly that reason and PR #13's reverb was separately wrong (it
gated on bit 15 of dAPF1, an address offset, instead of SPUCNT bit 7). The
one place this knowingly deviates from hardware is the 22.05 -> 44.1 kHz
reconstruction filter, which the documentation does not specify; it is
isolated in a single function and flagged for oracle comparison.

CAUSE.IP2 (from PR #102):

IP2 is combinational on R3000A — it mirrors the interrupt line and falls the
instant the guest acks I_STAT or masks the source. It was being OR'd in at
delivery and never cleared, in TWO places (the compiled path and
psx_interpreter.c, the latter missed by PR #102), leaving a phantom pending
interrupt that can spin a kernel dispatcher looping on CAUSE.IP & SR.IM.
psx_irq_refresh_cause_ip2() is now the sole writer of bit 10, refreshed at
raise, I_STAT ack, I_MASK write, HLE context restore and power-on. Verified
against the Beetle oracle's irq.cpp/cpu.cpp rather than asserted, and
covered by test_cause_ip2_combinational.

Mid-dispatch audio pump (from PR #102), with a fix: routed through a gate
that mirrors sdl_audio_update's mute/sink decision. Pumping unconditionally
from the VBlank edge, as submitted, would have pushed real audio during every
turbo-load hard mute and defeated the freeze-in-place mute model.

SPU RAM DMA readback (from PR #102): DMA4 in the SPU->RAM direction wrote
literal zeros; SPU RAM is readable memory and titles carry state through it
across an Exec boundary.

Also fixes an unrelated build race found on the way: tools/embed_spirv.py
wrote its intermediate SPIR-V to <source>.spv, so the two runtime targets
that embed the same shaders raced on one path and one deleted the file the
other was reading.

Co-Authored-By: Alexandros Mandravillis <Alexbeav@live.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 18:16:16 -07:00
Matthew Stanley 42a69624b1 fix(tools,docs): diagnose unconfigured recompiler build dirs in regen_bios
A contributor bringing up a new title hit four dead-ends in a row, three of
which were the same missing step wearing different masks: `regen_bios.sh`
builds the BIOS emitter but never configures it, and nothing said so.

- "no recompiler build dir found (set PSXRECOMP_BIOS_BUILD)" pointed at an
  env var when a fresh clone has no CMake tree to point it at. Both discovery
  failure and an explicit override now name the actual missing step and print
  the configure command.
- Setting PSXRECOMP_BIOS_BUILD skipped the CMakeCache.txt check that discovery
  applies, so an unconfigured directory reached `cmake --build` and died with
  cmake's bare "Error: could not load cache". Validate the override too.
- A CMake configure that FAILS still writes CMakeCache.txt — the cache lands
  before the generate step, which never runs after a FATAL_ERROR. So "has a
  cache" did not mean "is buildable": the directory left behind by his failed
  SDL and BIOS-backend configures had a cache and no build.ninja, and the
  build reported only `ninja: error: loading 'build.ninja': GetLastError() =
  2`. Read the generator out of the cache, check for its build files, and say
  what happened. Discovery skips such a directory and keeps looking rather
  than selecting it and dying; an unrecognized generator falls through to
  cmake instead of inventing a failure.

All errors now go to stderr (the old one went to stdout).

Docs: the README's framework build block configured the recompiler and jumped
straight to the runtime build, omitting the required BIOS regen between them —
exactly the hole he fell into. It is now the same numbered 1/2/3 sequence
docs/BUILDING.md already used. BUILDING.md gains troubleshooting entries for
the two CMake half-configured-directory errors, the fresh-clone "No recompiled
BIOS backend available", and PSXRECOMP_BIOS_BUILD being resolved relative to
the framework root rather than the shell's cwd.

Verified: both new failure paths and the half-configured-directory case
reproduce and now self-explain; discovery precedence (build-t2 over build),
explicit-override precedence, Ninja/Makefiles/unknown generators, and a CRLF
cache all behave; end-to-end `regen_bios.sh --config bios/OpenBIOS.toml`
still emits (Dispatch entries: 3911).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 18:03:03 -07:00
Matthew Stanley a423bb9c2d feat(video): perspective_texturing defaults ON
The two PGXP-family knobs now default differently, on purpose.

geometry_correction stays OFF and stays out of the UI: it moves vertices, and at
the ~5% coverage a position-keyed lookup can reach (93% of lookups ambiguous), a
corrected triangle meets an uncorrected neighbour and their shared edge splits.
Partial coverage is a visible defect there, not a partial feature.

perspective_texturing has no such failure mode, which is why it can ship on. It
never moves a vertex — it only changes how UVs are interpolated inside a polygon
whose SWC2 projection provenance is already fully proven. A polygon that does not
qualify simply keeps the PS1's affine interpolation, so neighbours can never
disagree about a shared edge and coverage below 100% degrades to "some polygons
look better" rather than "meshes crack".

Layering is unchanged and the faithful path is still one key away:
[video] perspective_texturing = false in game.toml or settings.toml opts out, and
settings.toml still wins over game.toml. The launcher row seeds from this default,
so the checkbox now presents as ticked.

Test updated rather than deleted: it pins the DIFFERENCE between the two defaults,
and gains a converse case proving that naming geometry_correction alone does not
disturb perspective_texturing's new default. 38/41 recompiler tests pass; the 3
failures (mod_load_acceleration, release_zip, sdl3_main_single_include) were
already failing before this change.

Not visually validated at the new default: perspective textures were confirmed
clean on Ape Escape / OpenGL / supersampling 2 only. Vulkan and the other titles
inherit the default without an isolation run of their own.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 17:30:02 -07:00