Commit Graph

39 Commits

Author SHA1 Message Date
Alex Vanderveen 209970cfe5 self-build: loop breaker, install-folder preflight, boot-EXE name lint
Follow-ups to the marker-skew hardening, closing the remaining legs of
the generate+build loop class:

- Loop breaker: host_prepare_generate stamps a successful generate into
  .psxrecomp_last_generate at the project root. When apply() is about to
  reopen the wizard because sources are missing and the stamp is recent,
  the wizard's prepare note becomes a diagnostic naming exactly which
  gate is unmet (the expected *_dispatch.c and/or the BIOS backends) and
  what generated/ actually contains, instead of silently asking for
  another round. The stamp is dropped once sources are visible so a much
  later manual wipe of generated/ reads as a fresh first run.

- Preflight: generate now refuses up front when the project root sits
  under the Windows temp directory (Explorer's run-from-inside-the-ZIP
  extraction, which evaporates) or is not writable, with instructions,
  instead of failing downstream in ways that present as the same loop.

- CI lint: tools/ci/check_boot_exe.sh cross-checks the three baked
  copies of the boot-EXE name (game.toml boot_exe/exe, CMakeLists
  GEN_MARKER, codegen_setup.c gen_marker_relpath) and the setup-release
  template gains a fail-fast "Lint boot-EXE name consistency" step, so a
  skew fails the maintainer's release instead of the player's install.
  op_emit_ci_workflow's step-name drift detection flags older titles
  automatically. Script is bash-3.2-clean for macOS runners; verified
  against fixture repos (consistent / skewed / boot_exe override /
  single-source) and real ports - where it immediately caught
  Tomba2Recomp's placeholder gen_marker_relpath ("SLUS_01234" vs
  SCUS_944.54), a live instance of the reported loop.

Both gitignore templates learn the new sidecar names.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KfPHUBEYiSCwaGiwRc8ea7
2026-09-01 11:00:29 -04:00
Alex Vanderveen 5b197d45df self-build: fail loudly on marker skew instead of looping generate+build
A boot-exe name skew between game.toml, codegen_setup.c's
gen_marker_relpath, and CMakeLists' GEN_MARKER used to loop the setup
wizard forever with every stage green: generate accepted any
*_dispatch.c and reported ok, the rebuild silently produced another
setup host (REQUIRE_GAME_C defaults OFF and nothing set it), and the
Windows deferred helper relaunched it straight back into first-run
setup. Reported by self-build users on ports whose three baked
@BOOT_EXE@ copies disagree.

Make each stage assert what the next one gates on:

- cmd_rebuild now configures with -DPSXRECOMP_REQUIRE_GAME_C=ON and the
  canonical -DPSXRECOMP_FORCE_SETUP_HOST=OFF (the legacy BPE_ alias only
  maps ON). Defaults precede --cmake-extra so a deliberate override
  still wins via cmake's last-one-wins.
- generate errors when the produced dispatch name differs from the
  expected marker, naming both; the setup host passes
  --gen-marker <basename of gen_marker_relpath> so generate checks the
  exact name the launcher and CMake will later demand.
- The Windows deferred helper re-resolves the exe from
  psxrecomp_exe_name-<target>.txt after the build (the pre-build guess
  goes stale on a title rename) and verifies marker + exe exist before
  relaunching, pausing with a report-to-maintainer message otherwise.
  Relaunch/heal and both failure gates exercised under Wine cmd.

Multi-disc titles keep a single boot EXE (update_disc_set.py only
maintains discs/disc_serials), so the strict name check is safe there.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KfPHUBEYiSCwaGiwRc8ea7
2026-09-01 10:43:44 -04:00
Alex Vanderveen 8f3645c2bc Merge pull request #268 from mstan/master
upstream
2026-08-29 21:07:42 -04:00
Alex Vanderveen d28bab6574 setup: write the located disc set into game.toml, closing the wizard gap
Records the wizard's disc picks where the runtime actually looks, so a
standalone-wizard install reaches the same end state as a RetComM build.

The gap this closes. The runtime's hot-swap roster is built from
game.toml [game] discs (game_discs = gc.discs). disc.cfg is the
mounted-image cache and read_cached_path() takes only its first line via
std::getline. So the previous commit -- which taught the wizard to ASK
for every disc and write them all to disc.cfg -- recorded discs 2..N
where nothing reads them for the roster. The player located three images
and still got a one-disc roster.

Nothing in the standalone path wrote [game] discs. The tooling that does
lives in retcomm-studio, which is why the RetComM path produced a working
3-disc config and the wizard could not.

  tools/new_project_layout/probe_disc.py       synced forward
  tools/new_project_layout/verify_disc_set.py  vendored (new here)

Both from retcomm-studio @ a2b71ed9 (MIT, (c) Alex Vanderveen; psxrecomp
is PolyForm-NC, so this is permissive-into-stricter and the notice is
recorded in THIRD_PARTY_ATTRIBUTION.md). psxrecomp's probe_disc.py was a
stale fork predating multi-disc support: 90 lines behind, with its only
8 unique lines being older revisions of the same functions, so the sync
drops nothing psxrecomp-specific. A single-disc project still emits
`disc = "..."` byte-identically to before.

update_disc_set.py is new, and is the piece neither repo had. probe_disc
--write-game-toml renders a COMPLETE game.toml, which is right when
scaffolding and destructive afterwards -- it would discard a live
project's [video], [controller], [widescreen], [netplay] and its
comments. This probes each located image, verifies them as one set, and
then edits ONLY disc / discs / disc_serials / required_disc_fps. It skips
any key whose value it already agrees with, so it does not reflow a
hand-formatted array and a re-run is a no-op. It refuses to write at all
when verify_disc_set rejects the set: images that are not one program are
a mistake to surface, not a config to record.

Generate runs it before invoking the CLI (the CLI reads game.toml).
Failure is reported and non-fatal -- Generate needs only the boot image,
and refusing to build because disc 3 could not be probed is worse than
building with a single-disc roster. Absent script (older SDK checkout) or
fewer than two located discs are both early returns, so single-disc
titles are untouched.

Verified against Final Fantasy VII's three real images:
  - from a single-disc game.toml, produces discs + disc_serials
    (SCUS-94163/64/65) + required_disc_fps identical to the values the
    RetComM path had already produced in that repo;
  - all 114 remaining lines of config and comments byte-for-byte intact;
  - a second run changes nothing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UWiDNcWuNtDWHE7Pnhq4jp
2026-08-29 19:12:37 -04:00
Alex Vanderveen d2f3e1df7c host: publish the disc roster to the setup wizard, and flush every disc
The runtime launcher has built a multi-disc roster from game.toml
[game] discs for a while. The SETUP host never did -- it did not read
that key at all -- so on a first run the wizard could not know a title
was a multi-disc set and asked for a single image. The other discs were
discovered missing much later, mid-game, at the first swap.

Read [game] discs in psxrecomp_codegen_host_apply and publish it as
gi.discs / gi.num_discs, matching the runtime's rule that a roster only
appears when there is more than one image. A single-disc title publishes
nothing and its wizard is byte-for-byte the page it was before.

The reader is ~60 lines rather than a TOML dependency: this host shells
out to Python for every real parse, and one array of strings does not
justify linking a parser. Only [game] discs is recognised; anything else
is skipped rather than guessed at. Relative entries are absolutised
against the project root, because the launcher existence-checks what we
publish and its cwd is not necessarily that root -- a relative path would
otherwise render as "missing" on a perfectly good install.

Implements persist_setup_discs (recomp-ui, appended additively to
RecompLauncherCGameInfo). disc.cfg becomes one path per line in disc
order. That is additive in the direction that matters: a reader taking
only the first line still gets disc 1, exactly what it got before. A slot
the player has not located is written as an EMPTY line rather than
skipped, so line N is always disc N and filling one in later cannot
renumber the others. Nothing located at all leaves any existing disc.cfg
alone instead of replacing it with blank lines.

The BIOS half delegates to host_persist_setup with rom_path NULL, which
runs its bios.cfg logic and skips its single-path disc write, so the two
entry points cannot drift on BIOS handling.

Verified against Final Fantasy VII's real 3-disc game.toml by driving
psxrecomp_codegen_host_apply directly: num_discs = 3, persist_setup_discs
set, all three absolute paths in disc order.

Requires the matching recomp-ui change to be visible; without it the
roster is published to a launcher that ignores the field, which is inert
rather than broken.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UWiDNcWuNtDWHE7Pnhq4jp
2026-08-29 19:12:37 -04:00
Alex Vanderveen cc448e20a1 build: let CMake own the runtime executable name
The runtime's filename was derived three times from three copies of the same
window title. runtime.cmake sets OUTPUT_NAME from
MAKE_C_IDENTIFIER(WINDOW_TITLE); psxrecomp_cli.py rebuilt it from --exe-name;
and the in-runtime self-compiler rebuilt it again from
codegen_setup.exe_basename. The rule is identical in all three, so they agree
right up until a game is renamed and only one copy is refreshed. After that the
build links <new>.exe while both consumers look for <old>.exe, and the failure
is reported as

    build succeeded but binary missing: ...\<old>.exe
    Build failed. Fix the errors above, then rebuild manually.

on a build that had no errors at all, with the executable sitting in the build
directory under the name CMake chose. Seen on Revelations: Persona, where CMake
emitted Revelations__Persona_Recompiled.exe and the setup host wanted
Revelations_Persona__Recompiled.exe — same algorithm, colon in a different
place in each side's copy of the title.

runtime.cmake now writes the OUTPUT_NAME it actually set to
<build-dir>/psxrecomp_exe_name-<target>.txt, and both consumers prefer that
over their own derivation. Written at configure time with file(WRITE) rather
than file(GENERATE): _psxrt_exe_name is a plain variable carrying no generator
expression and does not vary per configuration, so one fixed filename is
correct on multi-config generators too. The marker holds the name only, never a
path — the consumers already know their build directory and only ever got the
basename wrong.

A build tree without the marker still falls back to exe_basename, so older
trees and foreign build directories behave exactly as before.

The error messages were misleading in both directions and are now specific: a
name disagreement says the build succeeded and names both sides, while a
genuinely absent binary lists the executables that are present. The PGO
training path resolved the binary the same guessing way and now shares the
resolver.

Adds test_runtime_exe_name.py, which pins all four behaviours against the real
Revelations: Persona names, and relaxes the GAME_PROJECT_SETUP.md note that
previously just warned people to keep the two values in sync by hand.

Verified: the resolver against a real Ninja build tree whose OUTPUT_NAME and
marker were produced by the same two lines runtime.cmake uses, including the
exact stale-name case that failed in the wild; test_cli_project_packaging still
passes; the self-compiler change compiles clean. The runtime.cmake edit itself
was exercised in an isolated reproduction rather than a full runtime configure
— this checkout has no BIOS dump or generated game C to build one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017AwqKPQFnK3x7xQbK4PQKj
2026-08-28 23:48:56 -04:00
Matthew Stanley 1bc46e171d host: use portable case-insensitive compare for toolchain floor 2026-08-25 10:32:24 -07:00
Alex Vanderveen 05522e9c6a fix: default toolchain min-version floor 1.0.14 — stale pre-sysroot packs get replaced
The cache was accepted forever once any cmake ran: default min version was
empty, so a Deck (or any host) that cached a pre-sysroot pack (<=1.0.13)
never re-downloaded and kept compiling against host headers — absent on
stock SteamOS — with objects that mis-link after a pack upgrade
(__isoc23_strtoul).

Both resolvers now default the floor to 1.0.14, the first pack with the
Linux build sysroot. This is a framework floor, not a per-title pin:
RETCOMM_TOOLCHAIN_MIN_VERSION still overrides in either direction, and
"0" / "off" / "none" disables it (pre-floor behavior).

- tools/toolchain_pack.py: DEFAULT_MIN_VERSION in default_min_version();
  the ensure_toolchain stale-probe passes min_version="0" so its log line
  still sees below-floor packs.
- host: toolchain_min_version() mirrors the same default and disable
  tokens; below-floor caches now fail host_portable_cmake_ready and the
  wizard downloads /releases/latest.

Verified: Python — floor/override/disable semantics, real v1.0.10 pack
rejected and v1.0.14 accepted, an isolated cache holding only v1.0.10 no
longer resolves (visible again with floor disabled), full cache resolves
to v1.0.14. C — same matrix via a unit harness incl. manifest-less dirs;
both platform branches syntax-checked.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vc7zPEnfUFMhMtJzUEruyb
(cherry picked from commit 00f0a9a9bb)
2026-08-25 10:31:16 -07:00
Alex Vanderveen eefa4a9efd fix: SteamOS self-build — wire pack sysroot into CMake, surface CLI failure lines
Stock SteamOS (Steam Deck) has no /usr/include and no GL dev symlinks, so
the wizard rebuild died at recomp-ui's find_package(OpenGL REQUIRED) with
"Could NOT find OpenGL (missing: OPENGL_INCLUDE_DIR)" — reported to the
user only as "psxrecomp rebuild failed (exit 1)" (recomp-ui issue #34).
The cmake-clang-v1 >=1.0.14 pack already bundles a jammy sysroot with GL
headers and a legacy libGL.so stub, but only clang.cfg used it; CMake's
find_* still searched the host.

- psxrecomp_cli: when the active pack carries sysroot/usr/include (Linux),
  pass -DCMAKE_SYSROOT=<pack>/sysroot -DOpenGL_GL_PREFERENCE=LEGACY to both
  the game and the emitters configure. LEGACY is required: the sysroot has
  legacy libGL.so + GL/gl.h but no GLVND dev files (glx.h/libOpenGL.so/
  libGLX.so), so the GLVND path cannot complete and OpenGL::GL would never
  be created. Skipped when the caller already sets CMAKE_SYSROOT.
- codegen host: run_cli_posix/run_cli_win now route the child's stderr
  into the progress pipe and keep a last-lines capture (CliTail); on
  failure err_msg carries the most recent error-looking line — JSON
  progress rows contribute their message, raw rows (compiler output,
  Python tracebacks) contribute as-is. Exit-3 disc-verify text unchanged.

Verified against a stock-SteamOS simulation (bwrap: tmpfs over
/usr/include, GL dev symlinks removed) using the shipped v1.0.14 pack:
configure previously failed exactly as on the Deck; with the sysroot args
FindOpenGL resolves from the pack, the build links, and the binary runs.
CliTail paths exercised with real compact-JSON rows and raw stderr.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vc7zPEnfUFMhMtJzUEruyb
(cherry picked from commit 0bb45442f8)
2026-08-25 10:31:16 -07:00
Alex Vanderveen 2a020f285c Bios regen hotfix 2026-08-10 08:10:06 -04:00
Alex Vanderveen 6c0d343077 Fix Windows setup installs: require_generated cmdline + BIOS picker.
Pass generated shard paths via a SOURCES_FILE so cmake -P is not killed by
CreateProcess's ~8191-char limit, and keep has_bios on for OpenBIOS-only
setup SDKs so the first-run wizard still offers SCPH1001.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-09 22:57:18 -04:00
Alex Vanderveen 9689ad40dd shrink 0's and use explicit portable toolchain python 2026-08-08 22:50:17 -04:00
Alex Vanderveen d1d063d293 codegen + bios launcher patch 2026-08-08 14:10:06 -04:00
Alex Vanderveen cd13726a47 toolchain clean old packs 2026-08-07 20:19:18 -04:00
Alex Vanderveen 5748a228a4 hardening toolchain and build 2026-08-07 14:53:56 -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 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 480fcad652 new build wizard 2026-08-07 01:43:04 -04:00
Alex Vanderveen 652be7ba02 rollback FMV patches and overlay 2026-08-06 00:52:14 -04:00
Alex Vanderveen 2f7a2d6026 new 3+p architecture 2026-08-05 19:07:06 -04:00
Alex Vanderveen 9d3dcdd78e Update psxrecomp_codegen_host.c 2026-08-03 15:03:11 -04:00
Alex Vanderveen c19618adc6 BIOS handling 2026-08-03 14:44:17 -04:00
Alex Vanderveen 384e9bdf68 fix: pass staged disc/BIOS to generate; skip redundant SCPH1001 regen.
Codegen host hands g_wizard_bios (or OpenBIOS clear) to the CLI with
--disc/--bios. CLI skips SCPH1001 emit when the backend already exists.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-03 09:06:31 -04:00
Alex Vanderveen f1f892049e fix: persist absolute BIOS paths across generate/relaunch.
Relative bios.cfg / settings picks like bios/SCPH1001.BIN broke after
rebuild when cwd was build/; launcher verify also ignored exe-anchored
resolve. Absolutize sidecars, hydrate from bios.cfg, and resolve in
ae_bios_verify.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-03 08:07:02 -04:00
Alex Vanderveen 06b6bab192 Merge integrate/game-codegen-hooks-into-rollback into fix/setup-sidecar-persist-relaunch.
Keep wizard BIOS memory + sidecar writes to project root/build, and restore
NULL bios_path leave-untouched persist semantics from the sidecar PR.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-03 07:29:36 -04:00
Alex Vanderveen 3428829090 Require cmake-clang-v1 1.0.4 for Linux IPO linking.
Floor ensure-toolchain at 1.0.4 (libxml2 + clang.cfg -fuse-ld=lld) and
prepend pack lib/ to LD_LIBRARY_PATH when activating the toolchain.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-03 07:20:31 -04:00
Alex Vanderveen 92e78fd4f3 Persist disc.cfg/bios.cfg to project root and build/ on generate/relaunch.
Setup-host cwd and the rebuilt binary directory often differ on Windows;
resolve --bios from those sidecars and chdir to the project root before
exec on POSIX so relaunch sees the same picks.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-03 07:09:08 -04:00
Alex Vanderveen a4df2514de Update psxrecomp_codegen_host.c 2026-08-03 07:04:48 -04:00
Alex Vanderveen d35024ef23 codegen toolchain shared dir with retcomm 2026-08-03 02:54:19 -04:00
Alex Vanderveen db24f79db5 toolchain patch windows 2026-08-01 14:09:49 -04:00
Alex Vanderveen 3e46b5f033 windows host-native toolchain download 2026-08-01 12:57:13 -04:00
Alex Vanderveen f46bcaae85 windows toolchain patch 2026-08-01 10:36:07 -04:00
Alex Vanderveen fc7246ac3e windows toolchain path issue 2026-08-01 02:02:53 -04:00
Alex Vanderveen a67bcd5d79 Update psxrecomp_codegen_host.c 2026-08-01 01:15:02 -04:00
Alex Vanderveen 92c82adecc split toolchain from core game package 2026-08-01 01:03:44 -04:00
Alex Vanderveen 2f99cca345 migrate more tools into psxrecomp for building 2026-08-01 00:32:10 -04:00