Commit Graph

171 Commits

Author SHA1 Message Date
Alexandros Mandravillis eb12cb2411 Fix zero-BIOS MSVC registry build 2026-08-31 09:16:14 +03:00
Alexandros Mandravillis 8af48ae986 runtime: slice GPU linked-list DMA 2026-08-30 23:17:24 +03:00
Matt Stanley 3aeef99f47 Merge pull request #258 from mstan/fix/hermetic-toolchain-deps
build: find dependencies the hermetic toolchain can actually compile
2026-08-29 16:35:17 -07:00
Matthew Stanley 9ebd8b374d build: publish final runtime executable name 2026-08-29 16:29:05 -07:00
Alex Vanderveen 9e829086aa build: find dependencies the hermetic toolchain can actually compile
A fresh Final Fantasy 7 scaffold failed to build with SDL3/SDL.h file not
found on every translation unit that includes psx_sdl.h, even though CMake
had reported "using prebuilt/system SDL3".

cmake-clang-v1 compiles against its own sysroot and never searches the host
/usr/include:

  #include <...> search starts here:
   .../v1.0.14/sysroot/usr/include/...
  End of search list.

so a host package can be found and still be unusable. Two paths hit that.

SDL3: the toolchain ships a compatible SDL3 under deps/lib/cmake/SDL3, and
runtime.cmake already prefers it — but only via _PSX_TOOLCHAIN_PREFIX_HINTS,
which was built purely from RETCOMM_TOOLCHAIN_DIR and friends. The setup
wizard passes -DCMAKE_C_COMPILER=<toolchain>/bin/cc without exporting any of
them, so the hint list was empty and find_package fell through to
/usr/lib/cmake/SDL3. The compiler's own location is the hint that cannot be
forgotten, so it is now derived from CMAKE_C_COMPILER as well.

Vulkan: find_path landed on /usr/include, and CMake drops that directory from
include lists (adding it explicitly would disturb the system header order), so
the -I never reached the compiler at all. The block already knows how to build
gpu_vk_renderer.c as an inert stub when Vulkan is absent; it just never got
there, because "found" was decided by a path existing rather than by the header
compiling.

Both now verify before they believe, via a _psx_header_compiles() helper that
actually compiles the header. It takes LIBRARIES for an imported target and
INCLUDES for a bare directory, and the distinction is load-bearing: the first
attempt read INTERFACE_INCLUDE_DIRECTORIES off SDL3::SDL3, which is NOTFOUND
because SDL3 carries its headers on a transitive SDL3::Headers target, so the
check rejected a perfectly good SDL3. Asking through CMAKE_REQUIRED_LIBRARIES
resolves the interface transitively and discriminates correctly: the
toolchain's SDL3 passes, the host's SDL3 under this compiler fails.

Vulkan falls back to the stub it already had. SDL3 fails loudly instead,
naming the toolchain copy to point SDL3_DIR at — silently switching to
FetchContent there would collide with the SDL3::SDL3 target find_package has
already defined, and a wrong SDL is worse than a stopped configure.

Verified on the Final Fantasy 7 project that surfaced this: from a clean build
directory, with no overrides and with every toolchain environment variable
unset, configure selects the toolchain's SDL3, reports the Vulkan stub with the
reason, and psx-runtime builds and links (321/321).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017AwqKPQFnK3x7xQbK4PQKj
2026-08-29 00:27:06 -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
Matt Stanley 645253e7e5 Merge pull request #254 from Alexbeav/eagle-codex/t41-freeze-watchdog
runtime: bound automatic freeze dumps
2026-08-28 19:00:11 -07:00
Alexandros Mandravillis 0153fe13ef runtime: bound automatic freeze dumps 2026-08-29 04:33:56 +03:00
tetrisgm 3bf7bf1361 auto_ui_squash: join on submission order; instrument the silent gates
Three changes, one fix and two pieces of visibility.

1. ws_ui_group_assign gains a third join: consecutive in the ordering-table
walk AND touching. WipEout 3's speed/shield readout ends at x=288 and the
meter bar it belongs to starts at x=306 with a different CLUT, so neither
shared columns nor a matching key could join them. The readout stood alone,
its bbox midpoint 256.5 landed in the middle third against a screen centre of
254, and it stayed pinned near centre while its own meters went to the right
edge -- a 2 px gap in 4:3 opening to 159 framebuffer pixels at 32:9.

No anchor threshold can fix that: the genuinely centred "pit ... check"
message sits FARTHER RIGHT (midpoint 300.5) than the mis-anchored readout, so
any threshold reaching the readout drags the message with it. Submission order
is the only signal that separates them, and the array already carries it.

Simulated against seven captures spanning three aspects and two code states,
this forms three unions and changes exactly one anchor: [225,288] centre
becomes [225,486] right. The other two unions ([208,240]+[240,361],
[364,447]+[450,473]) are within an anchor. Confirmed in-race at 32:9: 7 runs,
lap readout left, speed readout and meters together on the right.

2. ws_ui_groups reports why primitives were NOT admitted to the partition.
Each gate in ws_ui_prepass_add is a silent return, so a primitive left at its
raw 4:3 X while its neighbours are squashed -- which is how a HUD mark ends up
stranded mid-screen -- was indistinguishable from one never drawn. In-race at
32:9: opcode 367, not_axis 410, everything else 0.

3. geom_correction reports perspective-UV arming with a real denominator.
perspective_triangles could previously only be compared against gp0_draw,
which counts untextured primitives that are correctly never armed, so it read
as a coverage figure without being one. texcorr.attempts counts exactly the
textured triangles reaching the predicate. In-race at 32:9: 199599 submitted,
96.15% armed, 3.85% rejected for a missing per-vertex Z, 0% for correction
disabled or a missing packet address.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit 572b9210d8)
2026-08-27 21:17:20 -07:00
Matthew Stanley 88f07bc9e3 runtime: keep temporal blending on the render thread 2026-08-27 13:21:17 -07:00
Alex Vanderveen 7efc712dd3 Windows/MinGW self-build: pin cxx_std_17 and stop capturing a structured binding
Two defects that only bite a MinGW C++17 build, both still live on master.

runtime.cmake declared only `c_std_11` on the runtime target, leaving the C++
dialect to whatever the parent project happened to set. A game CMakeLists that
omits CMAKE_CXX_STANDARD therefore compiled mod_packages.cpp as a pre-17
dialect. State the runtime's real requirement instead of inheriting it.

mod_packages.cpp captured a structured binding (`for (const auto& [id, ...])`
with `id` used inside a lambda). That is a C++20 extension; clang accepts it
silently, MinGW/GCC at C++17 rejects it. Bind the map entry to ordinary locals
before the lambda.

Cherry-picked from ae9432a3 on feat/rbengine-bak, minus that commit's unrelated
lib/recomp-net submodule bump. Verified by building psx-runtime on Linux.
2026-08-25 12:24:05 -04:00
Alex Vanderveen db2c03e109 hotfix for offline build deps
(cherry picked from commit 986de03fcf)
2026-08-25 11:17:44 -04:00
Alex Vanderveen e0037d7433 cmake patch hardening for steamos
(cherry picked from commit 8e0cad4685)
2026-08-25 11:17:44 -04:00
Matt Stanley d1df20514f Merge pull request #206 from mstan/fix/pr199-headless-no-recomp-ui-setup-host
runtime: fix headless generated-game builds without recomp-ui
2026-08-24 17:26:39 -07:00
Matthew Stanley 69f851f0f3 runtime: omit setup host sources without recomp-ui 2026-08-24 17:25:24 -07:00
Matthew Stanley 9ba703e5ed Merge remote-tracking branch 'origin/master' into split/pr169-presentation-bezel
# Conflicts:
#	runtime/runtime.cmake
2026-08-24 15:16:40 -07:00
Matthew Stanley c8e3dac678 presentation: expose bezel artwork as a mod 2026-08-24 15:15:15 -07:00
Tomasz Finc 2bd2208c8b Fix psxrecomp_add_game_runtime for --no-recomp-ui headless builds
psxrecomp_add_game_runtime() (added in #110) is unusable with
PSX_RECOMP_UI=OFF and real generated game C linked — a documented,
supported config ("PSX_RECOMP_UI OFF for headless/generated builds",
BUILDING.md) that nothing currently exercises. Found while bringing up
a new title with recomp-ui intentionally left out initially.

Two independent breaks in that combination:

1. main.cpp calls psx_game_codegen_forward_if_built() from main()
   whenever PSX_HAS_GAME_CODEGEN is set (i.e. any time real game C is
   linked), but only *declares* it under the narrower RECOMP_LAUNCHER
   guard. Any no-launcher build with generated game C fails with
   "use of undeclared identifier". Introduced a precise
   PSX_HAS_CODEGEN_SETUP_HOST macro (set only when a codegen-setup
   host is actually linked) and re-guarded both the declaration and
   the call site on it instead of the mismatched pair of guards.

2. psxrecomp_codegen_host.c was unconditionally added to every game
   target's extras, but it unconditionally #includes recomp_launcher.h
   from the recomp-ui submodule. Any --no-recomp-ui build fails with
   "recomp_launcher.h file not found". Gated its inclusion on
   PSX_RECOMP_UI.

Verification:
- Built and ran a new title (headless: PSX_RECOMP_UI=OFF, real
  generated game C, no launcher) end to end: OpenBIOS -> game entry ->
  continuous gameplay, clean atexit shutdown, no crash.
- Regression-checked the one existing title that actually calls
  psxrecomp_add_game_runtime() (TombaRecomp; every other shipped title
  calls the lower-level psxrecomp_add_runtime_target directly and
  never reaches this code): built TombaRecomp's real production config
  (PSX_RECOMP_UI=ON, ENABLE_SETUP_WIZARD, recomp-ui launcher, mod
  catalog, setup-host/no-disc mode) against this branch via
  -DPSXRECOMP_ROOT override, no submodule surgery. Clean build, ran to
  the launcher with no regressions. Both changes are conditionally
  gated on flags Tomba always sets the opposite way, so this is
  expected and was confirmed empirically, not just by inspection.

Not covered by this PR: CMAKE_CXX_STANDARD 17 is also never inherited
by a game repo that include()s runtime.cmake directly (as opposed to
add_subdirectory()-ing runtime/CMakeLists.txt), which silently
compiles text_xlate.cpp's std::filesystem usage against whatever the
host compiler's default standard is. Six of seven other title repos
work around this by setting it themselves; happy to send a follow-up
if that's wanted here instead of per-repo.
2026-08-23 23:12:24 -07:00
tetrisgm d10d76563a release: allowlist title framework packages
(cherry picked from commit 03aba66423)
2026-08-23 13:19:09 -07:00
Henrique Guedes aebb11b3d8 build: link iphlpapi into Windows runtime targets
main.cpp includes iphlpapi.h and calls GetAdaptersAddresses for the
launcher's netplay local-address discovery, but no CMake file links the
library. MinGW builds link regardless; MSVC does not link iphlpapi
implicitly, so every MSVC runtime build fails at link with an
unresolved GetAdaptersAddresses.
2026-08-21 21:39:12 -03:00
Alexandros Mandravillis 73eb746479 fix(runtime): validate full AOT entry before straight-line handoff
The dirty-RAM interpreter reused a suffix-aware validity check when resuming generated code after a patched call site. If an entry prologue had been overwritten but its resume suffix still matched, execution could enter stale AOT code and fall through to another generated piece without redispatch.

Emit a whole-entry predicate for straight-line handoffs, retain suffix checks for explicit guest transfers, and fail closed for older generated dispatchers until regeneration.

Validated with the MGS PAL 6,875-frame route, manual codec-to-heliport gameplay, focused continuation-guard tests, and a current-upstream recompiler build.
2026-08-20 14:51:26 +03:00
Matthew Stanley d31ce5ac6d pgxp: framework-owned PGXP Precision mod, every game, default off
psx.enhancement.pgxp (game_id \"*\") in the builtin catalog: one Mods-page
toggle that arms sub-pixel vertex precision + perspective-correct
texturing with the user-validated defaults (tolerance clamp 0.5px), plus
a cpu-mode option. Default off = the faithful floor (G1.9). Fully
effective on PGXP-variant binaries; reduced-but-safe coverage elsewhere
(the always-emitted swc2 tier + interpreters, validate-on-read).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 20:52:21 -07:00
Matthew Stanley e3824b47f5 pgxp: auto-clone the _pgxp variant inside psxrecomp_add_runtime_target
Titles that call psxrecomp_add_runtime_target directly (Ape Escape)
never went through the game wrapper, so the variant only existed for
wrapper callers. The clone now replays ARGN recursively at the end of
the target builder itself under PSX_PGXP_VARIANT, which covers every
caller; the wrapper folds an existing clone into its tail config and
the framework CMakeLists drops its now-redundant explicit block.

First real-title census (Ape Escape, worktree build vs this framework,
memory-mode only, boot->title->attract): 79-90% dataflow hits per
10s window vs the 5.2% position-cache ceiling, 0 value mismatches,
0 truncation rejects, every dataflow hit carrying depth; residual
native is 2D HUD/sprite content that must stay native. The G1.9
census gate is passed; visual screenshot_hires A/B requires a windowed
run (headless has no hi-res mirror - scale:1 fallback).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 19:17:30 -07:00
Matthew Stanley 38bdeeaade pgxp: emit hook macros + dual build targets + flavor-namespaced caches (phase 2)
Emitter side of the value-propagation engine (ENHANCEMENTS.md G1.10):

- recompiler/src/pgxp_hook_emitter.{h,cpp} (new, in the codegen-hash
  surface): ONE hook grammar shared by BOTH emitters, wrapping loads/
  stores/COP2 transfers and precision-carrying ALU ops (moves, add/sub,
  or-merge, shifts, LUI, HI/LO, muldiv) with PGXP_*() macros. Clobberable
  sources are captured into locals before the statement. Precision-
  destroying ops (AND/XOR/SLT/...) are deliberately unhooked - validate-
  on-read drops their stale shadows for free.
- code_generator.cpp: central append in translate_instruction; LWC2/SWC2
  emissions capture the RAW loaded/stored word (a masked GTE register
  write must validate against the word as loaded).
- strict_translator.cpp: translate() wraps translate_impl()'s c_code with
  the shared grammar; deferred load-delay variants hook the psx_ldd temp.
- BIOS regenerated, fingerprints verified CHANGED (SCPH1001 + OpenBIOS;
  42.6k/12.2k macro sites). Base runtime + 33/33 tests green against it.
- Gating: macros expand only under -DPSX_PGXP=1. runtime.cmake grows a
  PGXP option on psxrecomp_add_runtime_target (defines PSX_PGXP=1 +
  PSX_OVERLAY_FLAVOR=2, _pgxp exe suffix) and PSX_PGXP_VARIANT to build
  the sibling target from the same generated tree (framework runtime +
  game wrapper). No ABI version bump needed: the appended PGXPHooks
  table is NULL-tolerant and the flavor half of the ABI tag rejects any
  host/DLL flavor mix.
- Shard caches: flavor folded into the cache tag (cg<V>_<hash>_gc<hash>
  _f<flavor>) in overlay_loader.c + compile_overlays.py so base and pgxp
  caches never share a directory; compile_overlays.py passes
  -DPSX_PGXP=1 when flavor bit 2 is set; overlay preamble forwards
  psx_pgxp_* through the table. PSX_OVERLAY_CODEGEN_VER 9 -> 10.
- Env overrides PSX_GEOMETRY_CORRECTION / PSX_PERSPECTIVE_TEXTURING /
  PSX_PGXP_CPU_MODE (validation path: free-running headless boots arm
  from the first vertex); census grew produced/swc2_stores and the pgxp
  verb reports suppress/active gate state.

Validated: PSXRecomp_pgxp.exe boots the recompiled BIOS with hooks armed
(engine active, per-vertex lookups flowing; the BIOS shell has no RTPS
content so produced=0 there is correct - coverage measurement moves to a
3D title in phase 3).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 19:03:36 -07:00
Matthew Stanley 2ba74f3b4b pgxp: land clean-room value-propagation engine (phases 0+1, issue #92)
The G1.2/G1.3 mechanism: per-word RAM/scratchpad + per-GPR + per-GTE-reg
shadows carrying sub-pixel projections BY PROVENANCE, validated against
the actual guest word on every read (never guessed from rounded position
- the measured 93.1%-ambiguous G1.4 dead end). Clean-room from psx-spx +
public design docs; vendored duckstation (CC BY-NC-ND) and beetle-psx
(GPL) trees remain black-box oracles only - no code ported.

- runtime/src/pgxp.cpp + pgxp.h: engine, per-vertex GetPreciseVertex
  (dataflow -> ambiguity-gated position cache -> native) with truncation
  agreement + tolerance safeguards; stats; test accessors.
- pgxp_hooks.h: 5-entry hook funnel; PGXP_*() macros no-op unless
  -DPSX_PGXP=1 (codegen-time gate over ONE generated tree); appended
  PGXPHooks* table member in OverlayCallbacks (ABI bump ships with the
  Phase-2 emitter change).
- Both interpreters wired: loads/stores/COP2 + precision-carrying
  arithmetic (moves, add/sub, or-merge, 16-bit shifts, LUI, HI/LO).
- gte.cpp: RTPS feeds the GTE reg shadows; retired s_precise_sxy FIFO,
  hashed s_precision_store, and plain-store invalidation (redundant
  under validate-on-read; store hot path gets 3 calls back).
- gpu.c: prepare_precise_triangle rewritten per-vertex; perspective UVs
  share the same provenance and compose per triangle.
- [video] pgxp_cpu_mode / pgxp_tolerance keys; TCP pgxp verb live-
  toggles geometry/texture/cpu_mode/tolerance; geom_correction census
  grew the pgxp dataflow counters (G1.9 gate metric).
- tests: new pgxp_test (registered); gte_register_access_test updated
  to precise invalidation contract. 33/33 enabled tests green.

Also fixed while landing (both broke a fresh master tree):
- runtime.cmake: once-only psx_game_version.txt stamp (multi-target
  file(GENERATE) collision broke every fresh single-config configure).
- test_overlay_capture_retry: SDL3 rot (SDL_SetMainReady gone, inverted
  SDL_Init check) -> psx_sdl_init.

Tracked as beads-eio.3.48; postmortem + this landing: ENHANCEMENTS.md
G1-G1.10.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 18:34:47 -07:00
Matthew Stanley cab7d00f9a Fix PSX launcher hotkeys and audio persistence 2026-08-14 15:22:29 -07:00
Alex Vanderveen a9a61b4d47 Merge origin/master into feat/rbengine.
Keep recomp-net at occupied_mask (d65918f); master's pin was an ancestor.
Brings in rewind/save-state controls from master.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-14 02:57:25 -04:00
Alex Vanderveen 904ef39073 zlib1.dll 2026-08-14 02:41:50 -04:00
Alex Vanderveen 94cd223249 FMV Heal patch and build optimizations for launcher 2026-08-13 12:55:41 -04:00
Alex Vanderveen 9253f229a1 fmv heal patch + appicon 2026-08-13 10:37:18 -04:00
Alex Vanderveen ae9e6a4e2b hotfix build error on ci 2026-08-12 22:00:46 -04:00
Alex Vanderveen d5b5a029fe hotfix ci template 2026-08-12 21:53:26 -04:00
Alex Vanderveen c4f412be17 project studio, harden prefetch sdl3 2026-08-12 16:49:03 -04:00
Matthew Stanley cee9b97239 Add PSX rewind and save-state controls 2026-08-12 11:12:24 -07:00
Alex Vanderveen 554476457f rewind support 2026-08-12 03:51:50 -04:00
Alex Vanderveen a73a5c1093 rewind feature 2026-08-12 02:42:30 -04:00
Alex Vanderveen 3acb8f6d59 Integrate retcomm-rbengine as shared rollback host policy.
Wire lib/retcomm-rbengine beside recomp-net and replace MotK in-tree sched,
hash_confirm, input hist, snap ring, and rb_post with thin PSX shims so the
ecosystem can share invent/pacing policy outside each title facade.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-11 23:52:31 -04:00
Alex Vanderveen 2207cd9a09 auto versioning CI releases 2026-08-11 22:05:20 -04:00
Alex Vanderveen 581d4e927c Merge origin/master into feat/legendofmanaetc
Resolve main.cpp by keeping ae_fill/rematch netplay bring-up and taking
master's mod-safe turbo_loads/skip_fmv apply (no pre-activation clobber).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-11 19:28:20 -04:00
Alex Vanderveen 61279a9d01 bios select and rematch pathing fix 2026-08-10 20:44:18 -04:00
Matt Stanley 52d6a5440d Merge pull request #127 from mstan/hotfix/windows-installations
Fix Windows setup installs: require_generated cmdline + BIOS picker.
2026-08-09 21:22:51 -07:00
Matthew Stanley 4f8f584ac6 fix(msvc): close issue 122 portability gaps 2026-08-09 21:06:23 -07: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
Matthew Stanley e5cb95b787 fix(build): link nd_intro_ot.c — PR #110 added the TU but never the source entry
083959df added runtime/src/nd_intro_ot.c + nd_intro_ot.h, and 02b08dae /
later commits call psx_nd_note_wood_batch_ot(), psx_nd_wood_batch_ot(),
psx_nd_note_sibling_ot_hint() and psx_nd_sibling_ot_hint() from gte.cpp and
debug_server.c. runtime.cmake keeps an explicit source list (no globbing), so
the TU was never compiled and every link failed with undefined references.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 15:04:00 -07:00
Alex Vanderveen 9689ad40dd shrink 0's and use explicit portable toolchain python 2026-08-08 22:50:17 -04:00
Alex Vanderveen 755e2440cb OSD and volume hotkey fix 2026-08-08 22:01:51 -04:00
Alex Vanderveen 069adf871e bump windows build errors 2026-08-08 21:10:11 -04:00
Alex Vanderveen 014f5581bf bump 2026-08-08 20:32:16 -04:00
Alex Vanderveen e8f96d75b5 SDL3 toolchain patch 2026-08-08 20:01:44 -04:00
Alex Vanderveen c31eb12dc1 setup wizard and launcher support 2026-08-08 14:10:49 -04:00