Commit Graph

234 Commits

Author SHA1 Message Date
Matthew Stanley 67757efac4 feat(runtime): add CHD discs and mod-owned loading modes 2026-08-03 22:32:17 -07:00
Matthew Stanley 5176e40037 build: isolate the SDL3 entry point implementation
SDL_main.h is a single-header implementation in SDL3. Include it only from the translation unit that owns main so MinGW emits one WinMain instead of one per SDL-using source.
2026-08-01 10:43:59 -07:00
Matthew Stanley c264a704ec debug: generalize Crash Bash boot write watch
Extract the useful diagnostic from PR #13 into an opt-in, title-agnostic boot
write-range trace with TCP-queryable context.

Co-authored-by: NyperYuhgard <93950153+NyperYuhgard@users.noreply.github.com>
2026-08-01 02:15:34 -07:00
luisg0c 65b499f79a test(recompiler): register l2_structural_test and reachable_discovery_test
Both targets are defined unconditionally and every build produces them, but
neither had an add_test() entry, so neither could run and neither could fail.

This is the same gap the codegen tests below them had before they were wired
in, and docs/TESTING.md states the rule directly: "an unregistered test cannot
fail, and a test that cannot fail is not a test."

Both were run manually before being registered and both pass. They are
self-contained -- no BIOS profile, no generated C, no psxrecomp-game -- so
unlike the neighbouring tests they need no WORKING_DIRECTORY.

    l2_structural_test        -> L2 structural: 239/239 ok
    reachable_discovery_test  -> ALL PASS

ctest -N goes 33 -> 35, so the three places that state the count are updated
to match. Note they said 29, which was already stale before this change.
2026-07-31 15:42:55 -07:00
Matt Stanley cb0c00f397 Merge pull request #86 from luisg0c/fix/persist-dir-host-independent-path-check
fix(config): validate overlay_capture_persist_dir independent of host path grammar
2026-07-31 15:40:21 -07:00
Matthew Stanley 987c6eeced Revert "Merge pull request #87 from mstan/feat/ui-5p"
This reverts commit e01347cbca, reversing
changes made to 60cb60eee6.
2026-07-31 15:37:57 -07:00
Alex Vanderveen 1b3bd66eca rollback checklist doc 2026-07-29 22:11:05 -04:00
Alex Vanderveen 3da61df355 Revert "ok"
This reverts commit b836f2198c.
2026-07-29 03:18:10 -04:00
Alex Vanderveen b836f2198c ok 2026-07-29 03:15:42 -04:00
Alex Vanderveen 070fc805c4 Merge origin/master into feat/ui-5p.
Keep 5p/ICE netplay host + lobby client; take master's cycle batching,
SDL3 defaults, and dropped vendored lib/recomp-ui.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-28 20:17:14 -04:00
Matthew Stanley 9aa5466da7 Add per-game audio buffer target 2026-07-28 12:23:06 -07:00
Matthew Stanley a292a7c136 Add activation-only widescreen cull margin 2026-07-28 11:08:03 -07:00
Matthew Stanley 106e31d6e9 Make SDL3 the default runtime backend 2026-07-28 09:22:28 -07:00
luisg0c 4ced15faf4 fix(config): validate overlay_capture_persist_dir independent of host path grammar
std::filesystem answers by the *host* path grammar, so this guard meant
different things on different hosts.

Under POSIX, "C:/outside" is a relative path whose first component is
literally "C:", a backslash is an ordinary filename character, and
"\\server\share" is a single relative component -- so Windows-authored
absolute paths and backslash ".." traversals were accepted. Under Windows,
a rooted "/outside" has no root name, so operator/ drops the project root's
relative path and the result lands at the drive root; and a drive-relative
"C:foo" is not absolute at all, yet replaces the whole path when the project
sits on another drive.

Scan the raw config bytes under both separator conventions instead, and
reject an embedded NUL. TOML forbids a raw NUL byte but allows the \u0000
escape that produces one, and the runtime hands this value on as a C string
(runtime/src/main.cpp:5236-5241 -> overlay_capture.c:230), so
"..\u0000keep" validated as a four-byte component and then truncated to ".."
at the point of use, escaping the project. Validating what the consumer
actually sees closes that gap.

recompiler/src/config_loader.h carries the contract next to the field and
still described the old, narrower rule; docs/AOT_OVERLAY_PLAN.md carries the
only prose statement of it. Both now match what is enforced. Note the doc
claims identical accept/reject across hosts, not identical meaning: a value
like "nested\dir" is accepted everywhere but still names different things.

The registered recompiler_patch_test assertion "parser rejects absolute
capture history directory" failed on POSIX before this; the suite is now
33/33 on macOS arm64.
2026-07-28 10:48:37 -03:00
Alex Vanderveen 227d395823 ICE optimizations, connectivity, latency polling, save/loadstate performance 2026-07-28 00:16:30 -04:00
Matthew Stanley 5ec343ab4f fix(bios): make the boot-skip flag mean the same thing on every BIOS
`bios_hle` (default on) is the player-facing "skip the BIOS and go
straight to the game" flag, and it did nothing under the bundled
OpenBIOS: choosing OpenBIOS sat the player in the boot animation while
the identical build on retail SCPH-1001 went straight to the game.

Root cause was ordering, not policy. The tier has two axes with
different per-image requirements:

  * boot-skip     needs only `shell_entry_phys`, works under pure LLE
                  (nothing is synthesized — the shell call just returns
                  immediately), so any image exporting it can skip
  * kernel-call    needs `deliver_event_ret`, the kernel's own
                  DeliverEvent `$ra`, or a delivered callback returns to
                  the wrong PC

main.cpp correctly refused the call axis on an image without
`deliver_event_ret` by assigning `bios_hle = false` — and then derived
`boot_skip` from that already-mutated flag. OpenBIOS omits
`deliver_event_ret` (B0 semantics unvalidated) but DOES export
`shell_entry_phys`, so an available skip was cancelled by an unrelated
refusal, and one flag meant two things depending on a BIOS detail no
player can see.

Both axes are now decided by one pure, dependency-free function,
`psx_bios_hle_plan()` (runtime/src/bios_hle_plan.c): the boot decision
reads the REQUESTED `bios_hle`, each axis is gated on only the anchor it
needs, and refusals are reported at startup instead of downgrading
silently. `psx_bios_hle_configure()` clamps `boot_skip` to
`shell_entry_phys != 0` as a backstop so the banner and `hle_dump`
cannot overstate what can fire. The main.cpp local is renamed
`bios_hle_requested` and is no longer written back from the plan — the
`session_reboot` path re-enters that block, so folding a refusal into
the request would have made a netplay rematch differ from first launch.

Also in this pass:

* A BIOS profile's `[runtime]` block was parsed into
  `BiosConfig::runtime` and read by NOTHING, and bios/OpenBIOS.toml
  carried an inert `bios_hle = false` there that read as the reason HLE
  was off on OpenBIOS. It was not. `load_bios_config` now REJECTS
  `[runtime]` in a BIOS profile: a profile states facts about an image,
  never preferences.
* `psx_icache_fastpath_test` had been unbuildable ("redefinition of
  `psx_advance_cycles`" — the test's counting stub vs the header's
  `static inline`), which blocked every runtime test registered after
  it. It now builds with `PSX_OVERLAY_DLL_BUILD=1`, the seam
  psx_cycles.h already provides for a TU supplying its own advance.

Tests: new `bios_hle_plan_test` pins the matrix, including a 64-case
sweep asserting the boot decision is independent of
`deliver_event_ret` and the call decision independent of
`shell_entry_phys`. Runtime ctest 15/15, recompiler ctest 30/30.

Validated on Ape Escape (SCUS-94423) built against this framework with
both backends linked, headless, all four cases:

  OpenBIOS default   bios_boot=skip to game; route=2 fire at vec 0x30000
                     ra=0xBFC06EA8 (the continuation OpenBIOS.toml
                     documents); in-game on screen
  retail default     bios_boot=skip to game; route=2 at vec 0x30000
                     ra=0xBFC0702C; in-game on screen; differs only in
                     bios_backend=HLE (LLE fallback)
  PSX_BIOS_HLE=0     bios_boot=real intro; ring empty (no hook)
  KEEP_INTRO=1       bios_boot=real intro; ring empty

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 16:36:48 -07:00
Matthew Stanley ed0b45b1c7 docs(translation): fix the two stale references in STRING_TRANSLATION.md
Correcting my own earlier claim: this document is NOT wrong about the table
format. Its translations.json references all sit inside section 1, titled
'Prior art: the n64recomp PMS-J mechanism', and under Appendix A's 'n64recomp
prior art' heading. Section 3.3 correctly documents the PSX format as
translations/tsumu.toml with schema/default_lang/[[entry]], which matches
Tsumu's shipped table exactly. I grepped for translations.json, saw the hits,
and called the doc stale without reading their context.

Two references were genuinely wrong:

- Section 3 called the module 'proposed location: runtime/src/text_xlate.c'.
  It shipped, as text_xlate.cpp. Corrected the extension, marked it shipped,
  and noted the section is written in the future tense throughout.
- Appendix A pointed psxrecomp hook points at
  F:\Projects\psxrecomp\_wt-tsumu\psxrecomp\, a worktree that no longer
  exists. Made the paths repo-relative and added the shipped module and its
  entry points to the list.

Every in-repo file path the document cites now resolves.
2026-07-27 15:50:26 -07:00
Matthew Stanley d16beb16b2 docs(readme): lead with maturity, games, and shipped features
The README opened by explaining what a static recompiler is and how to run the
CLI, and buried the fact that eight titles actually run on it. Restructure so
the catalogue and the shipped features come first, and the build instructions
follow the pitch rather than preceding it.

- Hero: reposition as a general-purpose PS1 static recompiler, plus a 3x2
  screenshot grid of the six playable titles.
- Games: add Xenogears (github.com/OpokXeno/xenogears-recomp), marked
  community, per issue #83; note the author also contributed widescreen
  cull-site work upstream. Per-title notes now name widescreen support.
- New sections: Widescreen (16:9 / 21:9 / adaptive, showing both a 2D sprite
  engine and 3D), Mods (versioned .psxmod packages over a verified stock image,
  with the launcher panel), on-the-fly localization (the Tsumu translation
  layer), and Renderers (OpenGL default, Vulkan experimental, software
  reference).
- Promote 'Do I need a PlayStation BIOS?' near the top: bundled MIT OpenBIOS
  means most players need no dump, which is the first question a newcomer has.
- Reorder: Games / What It Is / BIOS / features / how-to-build / the rest.
  No section was dropped; all 18 are still present.

Screenshots are sized to how they render (800px grid cells, 1280px hero shots)
rather than colour-quantised, so there is no visible loss: 11.6MB of captures
land as 4.6MB of assets. Netplay is deliberately not mentioned.

All image paths, internal anchors and relative file links verified to resolve.
2026-07-27 13:58:13 -07:00
Matthew Stanley 5aced6c306 test: register 21 written-but-unwired tests; document how to run them
Correction to an earlier claim of mine: ctest was NOT absent. recompiler/ and
runtime/ already had 21 add_test() calls between them and `ctest` ran 8 tests
green in the recompiler tree. My original survey used a quoted git-grep
pathspec that the shell passed literally, matched nothing, and I read the empty
result as "no test wiring anywhere". The real problem was narrower: partial
registration and zero documentation.

Of 61 first-party test sources (excluding 3 fixtures/harnesses), 37 were
referenced by no CMakeLists at all. Each was run by hand; 21 pass and are now
registered, taking the recompiler tree from 8 to 29 tests -- still under five
seconds, and still requiring no BIOS dump, no disc image, and no generated
code.

The 15 runtime source-invariant guards are registered from
recompiler/CMakeLists.txt rather than runtime/CMakeLists.txt, following the
existing dirty_text_continuation_guards precedent. They only read runtime
source, and the runtime tree cannot configure until a BIOS has been generated,
so registering them there would have made them unreachable from the only tree a
newcomer can build.

Three tests are deliberately NOT registered because they fail today. Wiring a
known-red test would recreate exactly what took CI off pull requests. Detail is
in docs/TESTING.md; briefly:

  test_interpreter_perf_guards.py    asserts psx_devices_mmio_sync invalidates
      the inline cycle limit. It does not. The function delegates either to
      psx_devices_service_to_now() (which clears g_psx_cycle_fast_limit,
      psx_cycles.c:161) or to psx_devices_recompute_deadline() (:153-157),
      and that second branch never clears it. Needs a timing owner: the guard
      may have found a real hole, or the invariant may have moved. The guard is
      itself partly stale -- it still names s_next_service_cycle, since renamed
      to psx_next_service_cycle.
  test_runtime_perf_diag_guards.py   asserts a substring no longer present in
      the runtime source.
  test_overlay_pair_dedup_runtime.py needs its companion harness built; not a
      source-only guard.

New docs/TESTING.md covers running the suite, running one test, what each group
needs, the known-failing three, and why fixtures must not be registered. It
also records two traps that cost time here: parallel builds can crash cc1plus
on config_loader.cpp under memory pressure (retry with -j 1, it is not a code
error), and the codegen tests need an ABSOLUTE recompiler path -- a relative one
passes their os.path.isfile check and then fails inside subprocess.run on
Windows with WinError 2, which reads as a broken test.

Linked from CONTRIBUTING.md (above the existing manual regression checklist,
noting the suite does not tell you whether a game still runs) and from
docs/BUILDING.md.

Verified: clean configure + build, ctest 29/29 pass in 4.08s.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 11:49:31 -07:00
Matthew Stanley 9ad18ded0d docs: correct six statements that contradict the code
These are not stale-by-omission; each asserts something the code does not do,
and each was verified against the implementation before editing.

docs/BUILDING.md
  - PSX_ENABLE_VULKAN was documented "off by default" in two places. It
    defaults ON (runtime/runtime.cmake:778). Corrected both, and noted that
    the build option being ON does not make Vulkan the runtime renderer.
  - Removed the PSX_BUILD_COSIM row: no option() for it exists anywhere in
    the tree. Replaced with PSX_NETPLAY, which is real (runtime.cmake:194).
  - Step 2 (regenerate BIOS) was labelled "(Optional)". It is required before
    the first runtime build: step 3 configures psx-runtime from
    generated/OpenBIOS_full.c and fails at configure time without it
    ("Cannot find source file" / "No SOURCES given to target"). Regenerating
    the *retail* backend remains genuinely optional; that distinction is now
    explicit.
  - "This repository has no required git submodules" contradicted .gitmodules
    (recomp-ui, lib/recomp-net) and README's --recurse-submodules clone.
    Replaced with a table of which submodule each build option needs.

docs/ARCHITECTURE.md
  - Same Vulkan default correction.
  - Removed the claim that BIOS and game configs merge with "game wins on
    scalar keys". No such merge exists: load_bios_config is called only from
    the recompiler front-ends (main_bios.cpp, and main_psx.cpp solely to build
    the BiosAddressModel) and never from runtime/src/main.cpp.

docs/config_schema.md
  - Same merge claim, stated in more detail. Replaced with the actual runtime
    precedence: env > CLI > settings.toml > game.toml > compiled default.

docs/STRING_TRANSLATION.md
  - Header said "SPEC (design only - no implementation yet)" above a shipped
    feature: runtime/src/text_xlate.cpp (~970 lines), initialised from
    main.cpp, configured via [localization]. Marked IMPLEMENTED and added the
    public entry points.

docs/FEATURES.md
  - Layer A (dynamic DLL overlay loading) was headed "SHELVED". It is the live
    production dispatch path: overlay_loader.c is ~4,400 lines with 15
    LoadLibrary sites, last modified 2026-07-26, and COMPILING_OVERLAYS.md
    documents shipping the resulting .dll shards in releases. Added a status
    banner and kept the original account as history, since the CRC-keying
    dead ends it records are still worth reading.

docs/BIOS_SELECTION.md
  - Claimed the identity gate checks "size, CRC32, SHA-256". It checks size
    and CRC32 only (bios_backend_for_file, main.cpp:1088-1089); image_sha256
    is recorded metadata and never enters the accept/reject decision.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 11:49:31 -07:00
Matthew Stanley bb5fccea51 fix: make FPS telemetry opt-in 2026-07-27 11:44:31 -07:00
Matthew Stanley 2696c391b8 feat: add aspect-aware world participation 2026-07-27 10:48:41 -07:00
Matthew Stanley fa408aae50 Merge trusted mod plugin support 2026-07-26 21:05:03 -07:00
Matthew Stanley 45dd4210cf Remove Tomba legacy hybrid controller path 2026-07-26 20:52:12 -07:00
Matthew Stanley 9683a1cf8c feat(mods): support mod-owned FMV skipping 2026-07-26 20:34:20 -07:00
Matthew Stanley 99abda239f feat(mods): add pre-runtime activation plugins 2026-07-26 20:18:00 -07:00
Matthew Stanley a4afb828ac feat(mods): add trusted static vblank plugins 2026-07-26 18:59:10 -07:00
Matthew Stanley 436fe14101 widescreen: support guarded object participation overrides 2026-07-25 23:24:41 -07:00
Matthew Stanley 05e569c121 runtime: add sparse guarded mod fields 2026-07-25 21:42:35 -07:00
Matthew Stanley ddf3ca8962 feat: add ordered mod values and MIPS pair patches 2026-07-25 21:14:28 -07:00
Matthew Stanley bd460f3ce1 fix: guard complete dynamic patch records 2026-07-25 21:14:28 -07:00
Matthew Stanley eb3b4db599 feat: add bounded integer mod patches 2026-07-25 21:14:28 -07:00
Matthew Stanley 82bb5a21af fix: compose compatible partial mod overlaps 2026-07-25 21:14:28 -07:00
Matthew Stanley 968c9c23ce feat: add feature-oriented mod resolution 2026-07-25 21:14:28 -07:00
Matthew Stanley 50d4f456bf fix: preserve independent mod toggles 2026-07-25 21:14:28 -07:00
Matthew Stanley 9ff287c1fa feat: support multi-option mod conditions 2026-07-25 21:14:28 -07:00
Matthew Stanley 6c1bd61a1f feat: derive modded discs from verified stock images 2026-07-25 21:14:27 -07:00
Matthew Stanley 316eaa44a7 feat: add versioned runtime mod packages 2026-07-25 21:14:27 -07:00
Matthew Stanley 4bf868da4f feat(bios): ship OpenBIOS as a runtime dependency 2026-07-25 18:11:57 -07:00
Matthew Stanley 986d8be94c Merge remote-tracking branch 'origin/master' into integrate/openbios-bundle
# Conflicts:
#	recompiler/src/full_function_emitter.cpp
#	recompiler/src/full_function_emitter.h
#	recompiler/src/main_bios.cpp
#	runtime/runtime.cmake
#	runtime/src/main.cpp
2026-07-25 12:31:05 -07:00
Matthew Stanley b8adb758d2 docs: specify BIOS selection — OpenBIOS by default, retail on request
Writes down the contract before implementing it, because one part is a
behaviour change someone would otherwise file as a bug.

The rule: no BIOS chosen -> OpenBIOS; a BIOS the player explicitly chose
-> that BIOS. A developer can require retail for a title with a verified
OpenBIOS incompatibility via [runtime] openbios = false.

"Chosen" means --bios or a launcher/settings pick, and nothing else.
Today resolve_bios_path() also searches directories near the executable,
so a stray SCPH1001.BIN would silently win even though the player never
asked — making behaviour depend on what happens to be on disk. Discovery
stops being a selection mechanism.

Also recorded: why both BIOSes are compiled into one binary (a build
flavour per BIOS needed the same choice restated in three places that
nothing cross-checked, and it compiled cleanly when they disagreed); why
that is affordable (game C is byte-identical across profiles — verified
on Tomba!, Tomba! 2 and Ape Escape — so only the BIOS is duplicated, and
the two collide on just 22 symbols); that the developer setting is not
player-overridable; and that savestates are BIOS-specific and must be
refused across BIOSes, which is the one silent-corruption risk here.

README gets a player-facing version: you probably don't need a BIOS,
here's how to use your own, saves work either way, savestates don't mix.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 11:31:39 -07:00
Matthew Stanley bfa760f43b build: fail early with a clear message when recompiled game C is missing
The runtime links generated/<serial>_{full,dispatch}.c, produced by a separate
recompiler step run before the build. Those paths are marked GENERATED so cmake
configure succeeds before that step has run — which meant skipping generation
surfaced only as a raw "cc1: fatal error: <file>: No such file or directory"
deep in the build, with no hint that a step was skipped or what produces the file
(exactly the trap a from-source builder on a fresh checkout hits).

Add runtime/check_generated_sources.cmake and wire it into
psxrecomp_add_runtime_target as a build-time dependency of the runtime target:
a missing game source now aborts at build start with the files named and the
exact fix (build recompiler -> extract EXE -> generate -> rebuild), and configure
emits an early non-fatal warning. Framework-wide, so every game inherits it.

Also fix the docs/BUILDING.md "build and run a game" recompiler invocation (the
framework is a submodule at psxrecomp/, not ../psxrecomp/) and add the
recompiler-build step.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-24 09:36:14 -07:00
Henrique Guedes 6749b826d4 feat: OpenBIOS support — profile-driven BIOS recompilation
Adds PCSX-Redux's MIT-licensed OpenBIOS as a second BIOS the framework can
statically recompile, next to retail SCPH1001. Because OpenBIOS is
redistributable, a game verified against it ships its BIOS with the build —
players supply only a disc, and the launcher BIOS picker disappears.

The mechanism is general, not OpenBIOS-specific: every BIOS image gets a
bios/<STEM>.toml profile that is the single source of truth for its identity
and layout.

Recompiler
- bios/<STEM>.toml profiles: [program.image] (sha256 pin, redistributable
  flag), [recompiler.address_model] (boot-time ROM->RAM copy windows,
  kernel-bless window), install_slots, and [recompiler.runtime_exports]
  HLE anchors (0 = feature structurally unavailable on that BIOS).
- BiosAddressModel (new): validated model built from the profile, replacing
  ~9 hardcoded SCPH1001 window constants that had drifted apart across the
  emitter / discovery / game codegen. The emitted C normalize() derives
  from the same table. from_config rejects overlapping/misaligned windows
  and orderings where sequential folding != first-match. A CTest-registered
  equivalence test sweeps every RAM/ROM address against verbatim copies of
  the old helpers.
- Orphaned delay slots (the OpenBIOS-critical emitter fixes): jr/jalr
  slots are inlined before the jump resolves — previously their side
  effect was silently LOST (e.g. a case-return fragment's addiu $sp pop,
  which unwound a shifted frame and walked the exception handler's IntRP
  cursor into a wild dispatch). Orphaned branches resume at ds+4 on
  not-taken instead of re-executing the slot (a read-modify-write slot
  doubling twice broke OpenBIOS readPad). Jump targets latch pre-slot.
- MIPS-I load-delay modeling for dependent load pairs: the successor sees
  the pre-load value (OpenBIOS's cardfasttrack.s relies on it on purpose —
  "gotta break those bad emulators"). Unmodeled shapes warn at build time.
- Discovery hardening: branch-target dispatchability closure to fixpoint;
  jump tables placed at jr+8 no longer walked as code; cross-function
  continuations routed by an instruction->owner map.
- Signed MULT support (unreachable from the retail seed set; modern-GCC
  OpenBIOS emits it freely), latency-modeled like MULTU.
- Seeds from ELF symbol tables + data-section code-pointer harvest
  (tools/gen_bios_seeds_from_elf.py) — a source-built BIOS needs no
  disassembly pass. 646 OpenBIOS seeds, incl. 5 empirical dispatch-miss
  seeds.
- Stemmed outputs (<out_stem>_full.c / _dispatch.c) so two BIOSes coexist
  in one out_dir. tools/regen_bios.sh is profile-driven (--config).

Runtime
- psx_bios_image: the generated dispatch now self-describes the BIOS it
  was compiled from (identity: size/CRC32/SHA-256/wordsum; kernel-bless
  window; HLE anchors; bundled flag). Runtime SCPH1001 hardcodes removed.
- Launch check is a hard identity gate (a mismatched image under
  statically recompiled code is a guaranteed wild jump). Bundled builds
  hide the BIOS picker and treat a missing/tampered bundled image as an
  installation defect.
- Faithfulness fixes surfaced by OpenBIOS's tighter timing loops (all
  global, argued in code comments, regression-tested against SCPH1001):
  - SIO pad RX is cycle-paced like the memcard path (RX_RDY at
    shift-complete, ACK +170); total ack-IRQ latency unchanged.
    PSX_SIO_PAD_SYNC_RX=1 restores the legacy synchronous path for A/B.
  - SPUSTAT derived from SPUCNT instead of permanently-asserted busy.
  - GPUSTAT.13 (interlace field) alternates per vblank while interlaced,
    pinned 0 in progressive.
  - CD Init(0x0A) completes in ~3.9 ms instead of borrowing Beetle's
    34 ms Reset figure (OpenBIOS's short bounded retry loop livelocked).
  - Exception EPC guard accepts ROM-window block leaders, not just RAM.
- New TCP debug commands (documented in TCP_COMMANDS.md): bios_info,
  s3_smear_watch, callret_watch; write-trace ring gains $s0-$s5.

bios/openbios.bin is vendored (MIT — notice in bios/OpenBIOS.LICENSE,
attribution in THIRD_PARTY_ATTRIBUTION.md, source pin + build recipe in
bios/OpenBIOS.toml). The emitter fingerprint digest is now content-only:
existing generated/*.emitter.sha will read STALE once; re-run
tools/regen_bios.sh.
2026-07-23 17:10:23 -03:00
Matthew Stanley f86087ad94 Remove stale RmlUi launcher remnants 2026-07-23 00:29:22 -07:00
Alex Vanderveen 7cf9958135 FMV optimizations 2026-07-21 21:38:04 -07:00
Alex Vanderveen 0b890cdc13 lobby game version control 2026-07-21 21:38:04 -07:00
Alex Vanderveen 31015ceab1 feat: launcher polish and recomp-net lobby netplay
Wire MotK-style lobby (recomp-net submodule, WS client, match_caps),
netplay delay-sync, and launcher UX so host sim settings stay aligned
across peers.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 21:37:57 -07:00
Matthew Stanley e03c743e87 tools: add Linux macOS dev setup helper
Add a conservative source-checkout setup helper based on the Linux quick-start intent from PR #54.

The script builds the CLI/recompiler tools, refreshes BIOS C when a BIOS is present, and builds the BIOS-only runtime only when BIOS/generated sources are available. It deliberately leaves game project creation to the existing CLI generator.

Co-authored-by: Keeganator <keegan.pan@gmail.com>
2026-07-21 17:02:05 -07:00
Matthew Stanley c4517c3b7c docs: credit PR16 Vulkan source developer
Record that PR #61 reconstructed the reusable Vulkan work from Martin Penkava's PR #16 branch.

Co-authored-by: Martin Penkava <mpenkava1337@gmail.com>
2026-07-21 16:42:54 -07:00
Matthew Stanley 9228f32c00 runtime: keep Vulkan opt-in and remove old launcher
Remove the in-tree launcher implementation and its submodules now that game projects use recomp-ui for launcher support.

Keep Vulkan hidden from the launcher unless a game explicitly sets [video] offer_vulkan = true, and clamp stale Vulkan settings back to OpenGL when it is not offered.

Co-authored-by: Martin Penkava <mpenkava1337@gmail.com>
2026-07-21 16:31:36 -07:00