Skip to content

Match 600+ P2 functions & VU0/splice foundations#263

Draft
lindskogen wants to merge 125 commits into
TheOnlyZac:mainfrom
lindskogen:fable
Draft

Match 600+ P2 functions & VU0/splice foundations#263
lindskogen wants to merge 125 commits into
TheOnlyZac:mainfrom
lindskogen:fable

Conversation

@lindskogen

Copy link
Copy Markdown
Contributor

Brings the P2 decomp from 2567 → 1890 remaining INCLUDE_ASM stubs (~677 functions newly matched) across 118 source files / 23 headers, plus the supporting struct, SIMD, and tooling work to make those matches possible. Every change is verified against the ground-truth checksum (out/SCUS_971.98: OK).

Highlights

  • Engine base structs — SO padded to its real 0x550. ALO/LO remain intentionally truncated; subclasses lay out own fields from 0x550 and reach base fields via STRUCT_OFFSET.
  • VU0 / SIMD foundation — VU_VECTOR/VU_FLOAT fixed to 128-bit quadwords; VU0 inline-asm idiom established (CalculateWaterCurrent, UpdateWaterBounds, ClipVismapSphereOneHop), unblocking the water/clip math.
  • Splice subsystem — large bif/eval/frame/sidebag/ref progress (RefOp BIFs, matrix/vec ops, CFrame, CSidebag node lists); Splice crosses 20%.
  • Fully-decompiled units — sort.c (HeapSort), pipe.c, frzg.c.
  • Broad leaf/accessor coverage — getters/setters and small helpers across alo, so, sw, sound, mpeg, screen, rog, jt, crv, stepguard, and ~100 other units.

Symbol & comment cleanup (final commit)

  • SetAMRegister and OnDifficultyPlayerDeath keep extern "C" — both pass match.sh per-symbol but fail the full checksum when converted (caller-side uchar narrowing / a GCC 2.95 register-allocation flip); documented as load-bearing exceptions.
  • Trimmed decomp/tooling-explanation, AI-process, and TODO/blocker comments; condensed the "kept wrapped (unwrapping breaks the checksum)" notes to one line. Struct-field annotations and Doxygen retained.

Notes for reviewers

  • Some functions remain wrapped in #ifdef SKIP_ASM on purpose (they match per-symbol but mis-size a still-asm neighbor); the one-line notes say why.

Verification

./scripts/build.sh → out/SCUS_971.98: OK.

lindskogen and others added 30 commits June 5, 2026 22:35
scripts/decomp_lhf_draft.workflow.js fans out parallel read-only agents that
draft matching C for batches of tiny leaf functions. scripts/decomp_apply_drafts.py
verifies each draft in isolation (instructions + relocations vs the asm), rejects
ones that grow non-.text sections (rodata-layout ripple) or whose raw FUN_ symbol
has asm callers, then applies the byte-exact matches and renames FUN_ symbols.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
AddWaterExternalAccelerations dispatches through the SO vtable (offset 0x128)
via STRUCT_OFFSET; FUN_001ef830 clears zpd.cploThrow. Annotate the remaining
INCLUDE_ASM stubs with why they're deferred (VU0 SIMD, or permuter-class
codegen for PostWaterLoad/HandleWaterMessage).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Small getters/setters and helpers on ALO/SO/SW: interact/look-at/throb/ack
accessors, FInflictSoZap, UpdateSoPosWorldPrev, and SW list/world helpers.
Base-struct fields past the truncated structs are reached via STRUCT_OFFSET.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Small wrappers/getters/setters across act, chkpnt, cplcy, difficulty, dmas,
path, po, puffer, pzo, rog, sb, sensor, stepguard, and xform, drafted by the
batch workflow and verified byte-exact (instructions + relocations).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
VU_VECTOR was a 2-byte stub { ushort data; }, so passing it by value compiled
to lhu instead of lq. It is a 128-bit VU quadword passed in a single 128-bit GP
register, so define it as { qword data; } (TImode, 16 bytes, 16-aligned). Kept
as a struct named VU_VECTOR to preserve the 9VU_VECTOR by-value mangling.

This resolves the long-standing 89.47% "single load mismatch" in
ClipVismapSphereOneHop, now matched as plain C. VU_VECTOR is only used by value
in signatures (never embedded), so the size change ripples nothing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
VU_FLOAT was a 2-byte stub { uint16_t data; }; like VU_VECTOR it is a 128-bit
VU scalar (the VU_FLOAT(float) ctor stores it with sq, and it is passed by value
in a single 128-bit GP register). Define it as { qword data; }. Used only by
value in signatures, so the size change ripples nothing; full checksum OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
VU_VECTOR was a 2-byte stub { ushort data; }, so passing it by value compiled
to lhu instead of lq. It is a 128-bit VU quadword passed in a single 128-bit GP
register, so define it as { qword data; } (TImode, 16 bytes, 16-aligned). Kept
as a struct named VU_VECTOR to preserve the 9VU_VECTOR by-value mangling.

This resolves the long-standing 89.47% "single load mismatch" in
ClipVismapSphereOneHop, now matched as plain C. VU_VECTOR is only used by value
in signatures (never embedded), so the size change ripples nothing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
VU_FLOAT was a 2-byte stub { uint16_t data; }; like VU_VECTOR it is a 128-bit
VU scalar (the VU_FLOAT(float) ctor stores it with sq, and it is passed by value
in a single 128-bit GP register). Define it as { qword data; }. Used only by
value in signatures, so the size change ripples nothing; full checksum OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Establish the inline-asm VU0 idiom on the small vector/scalar primitives,
building on the VU_VECTOR/VU_FLOAT 128-bit type fixes:

- VU_VECTOR(const VECTOR&) and VECTOR::operator=(VU_VECTOR): lq/sq quadword
  copies (plain C through the qword member).
- operator*(VU_FLOAT, VU_VECTOR): qmtc2.ni / vmulx.xyzw / qmfc2.ni via inline
  asm, with VU types passed by value in single 128-bit GP registers ($4/$5/$2,
  no extra moves).

Adds the ctor/operator declarations to vec.h. VU_FLOAT(float) stays INCLUDE_ASM
for now (one scheduling instruction off). Full checksum OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
First water VU0 function matched: the vadd.xyzw combining the warp result is
emitted via inline asm (lqc2/lqc2/vadd.xyzw/sqc2) over VU_VECTOR stack locals;
the surrounding ConvertAloVec/CalculateAloTransformAdjust/WarpWrTransform calls
and the *pv/*pw quadword copies are plain C. Adds WATER::vecCurrent at 0x570 and
references the shared D_00248D30 rodata constant. Full checksum OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The sphere-bounds length (dot product + vsqrt) and the AABB vsub/vadd are
emitted as one VU0 inline-asm block over the GetWrBounds result and the SO
bounds fields (sRadiusBounds/unk_0x3d4/vecBoundsMin/vecBoundsMax). vsqrt has no
assembler mnemonic so it's a .word, like the original .s. Full checksum OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LSG's apos/anormal are 16-byte VU vectors; widen them to VECTOR4 and 16-align
the struct so sizeof(LSG) is the real 0x70 (au at 0x40/0x44, apos[1] at 0x10).
This is the key fix for water's clip-using functions: a typed LSG[16] clip
workspace now lands at frame 0x20 (after the edge vectors) instead of the base,
matching the original frame layout. No ripple — full checksum OK.

With that, UGetWaterSubmerged is written (VU0 vmulax/vmaddx transform, g_pjt
height logic, ClsgClipEdgeToBsp into LSG[16], float return) and ~95% matched;
kept under SKIP_ASM (asm still used by the real build) pending permuter work on
a few g_pjt-branch scheduling instructions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Byte-exact, checksum-green (out/SCUS_971.98: OK):
- PtnfnFromTn (tn): null-check ternary returning &D_00275980 or ptn+0x2F0
- FUN_0014c820 (crusher): indexed pointer into 0xB0-stride array
- extern "C" leaf accessors called by other asm via unmangled names:
  InitCplcy, FActiveCplcy, SetCpmanCpmt, FUN_001e4880, FUN_00145DD8,
  FUN_001c9a48

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Byte-exact, checksum-green:
- RetractLasen/ExtendLasen (sensor): +-1.0f/dt stored at 0xB08
- GetActvalScale (act): 3x qword copy ACTVAL+0x90 -> MATRIX3 rows
- SetLookerSgvr (shdanim): store 3 LOOKER field addrs into SGVR
- InvalidateSwXpForObject (bbmark): flags &= ~grfpva on pso->sw
- FUN_0014c838 (crusher): indexed append into 0x14-stride array

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
These showed t==c "DIFFER" in the dual-build only because their jal
targets a still-INCLUDE_ASM sibling (reloc-name artifact); the full
link is byte-identical (out/SCUS_971.98: OK):
- ImpactClue -> ImpactSo
- func_0015F658 -> func_0015F618
- AddStepCustomXps -> AddStepCustomXpsBase

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two tail-call wrappers whose raw C-linkage siblings needed forward
declarations (extern "C"). checksum-green (out/SCUS_971.98: OK):
- call_search_level_by_id -> search_level_by_id
- FUN_001d34e0 -> FUN_001bc4d8 (renamed FUN_001d34e0 -> mangled in
  symbol_addrs; it has no asm callers)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
UMaxCrv/SMaxCrv (crv): mpicvu/mpicvs[ccv-1]. TouchFlake/TouchBublet/
OnTrailRemove (rip): thin guarded/forwarding wrappers. All showed
"DIFFER" only via dual-build artifacts (trailing unsymboled JUNK
macros, and jal-to-external-sibling reloc names); full link is
byte-identical (out/SCUS_971.98: OK).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
checksum-green (out/SCUS_971.98: OK):
- GetActrefScale (act): explicit qword copy of MATRIX3 via loaded ptr
  (MATRIX3 is float[3][3], align-4; a plain *pmat=*p went unaligned)
- AddFrzgObject (frzg): cache coid in a local so it isn't reloaded
- FUN_001a93c8 (rwm, extern "C", has asm callers) + FUN_001a86f8
  (renamed to mangled; no asm callers)
- FUN_001cf138 (stephide, extern "C"): add 1000.0f loaded from
  D_00274E3C rather than materialized as an immediate

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two leaf functions; checksum-green (out/SCUS_971.98: OK):
- GetSuvCpdefi: tail-call forwarding to GetSoCpdefi
- SetAsegaSpeed: chained float multiply stored at 0x18

(match.sh's per-symbol check falsely reported DIFFER on both due to
flaky configure.py asm regeneration / trailing-junk artifacts; the
full-link checksum is the ground truth.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…CrvcCache/DuGetCrvSearchIncrement/MeasureCrvl)

checksum-green (out/SCUS_971.98: OK).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
checksum-green (out/SCUS_971.98: OK): UpdateSuvInternalXps, OidFromSmIsms,
PostFlyingEmit (+SgnCmpHp), InitDysh (wrapper to InitAlo), FUN_0014f900.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…harness

checksum-green (out/SCUS_971.98: OK). Accessors, wrappers and vtable-dispatch
leaves across 6 units; size/content-mismatched drafts auto-rejected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…F harness

checksum-green (out/SCUS_971.98: OK). Accessors, vtable-dispatch and
forwarding wrappers; size/content/data-growth mismatches auto-rejected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
checksum-green (out/SCUS_971.98: OK): PushCplookLookk, FUN_0014a8d0,
VacateCredit, SetLightHighlightColor, BreakClue, SetShadowFrustrumUp.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Tail wrapper FUN_001aea70(1, 0xFFFF); extern "C" fwd-decl of the raw
sibling; renamed FUN_001aec90 -> mangled (no asm callers). checksum-green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
grfrob bit tests on g_plsCur; '(x & 2) > 0' steers GCC to andi+sltu
(matching the ROM) instead of the shift-fold. Removed stale 80%% scratch.
checksum-green (out/SCUS_971.98: OK).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
lindskogen and others added 27 commits June 10, 2026 21:27
Builds the freeze group's MRG: allocates apalo, resolves each aoid via
PloFindSwChild, and registers the merge group with the SW.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s hook)

SetSoCameraStyle/EdgeGrab/NoGravity/Iceable/IgnoreLocked/NoXpsAll/Self/
Center, UpdateSoPosWorldPrev, AddSoXa, RemoveSoXa, PsoFindSoPhysHook,
SetSoConstraints, SendSoMessage — first compiled-C inroads into the so
unit, using the reversed SO layout (docs/SO_LAYOUT.md). DiscardSoXps is
declared via its literal truncated-mangled symbol since callers pass a
discard mode in $a1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ildSoPhysHook, ConstrFromCnstr)

CNSTR becomes an enum (mangles identically as 5CNSTR) so ConstrFromCnstr
can be defined; its table D_002746E0 holds (VECTOR*, CT) pairs.
OnSoRemove also matches per-symbol but is kept INCLUDE_ASM: enabling it
triggers an asm-emission bug that inflates the still-asm
TranslateSoToPosSafe by 0x14 bytes and fails the checksum (see comment).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
In-place heapsort with a unified build/extract sift loop. Matching hinged
on the rotated while + else-break shape (keeps the swap arm inline and
duplicates the bottom test) and a post-decrement on the last index.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
RefOpSetCar/RefOpSetCdr (sret passthrough into RefOpSetCadr with
BIFK_SetCar/SetCdr = 35/36), CFrame::FFindBinding (symid is unsigned
per the Uii mangling), CSidebag::FFindBinding and CSidebag::CloneTo
(the sidebag is a single pointer to 0x10-byte {n, CRef, next} nodes
allocated by FUN_0011C498 from g_splotheapUnk1; reached via
STRUCT_OFFSET to keep the placeholder class layout intact).

Splice: 19.44% -> 20.19% perfect (119 -> 124 functions).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Standard RefOp shape: stack CRef temp, setter, copy-construct into the
hidden sret. Cdr reads the private m_ppairNext via STRUCT_OFFSET.
Splice perfect match: 20.19% -> 20.90%.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…Coerce)

RefOpFloor/Truncate/Ceiling/Round/Modulo/SetMusicRegister plus
CRef::RefCoerceS32/F32 (ref.h signatures corrected to the sret form).
SetAMRegister bound by literal mangled name: ROM callers pass the second
arg unnarrowed. RefOpStopSound matches but stays wrapped (asm-emission
bug inflates the following still-asm function).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ame::CloneTo, RefEvalSymbol)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rtObject*)

CFrame/CSidebag Ref{Add,Set}Binding return CRef via sret (headers fixed).
RefOpAbs also matches (__builtin_abs gives the branchy abssi2) but stays
wrapped: unwrapping it inflates the still-asm RefOpPredictAnimationEffect
emission and fails the checksum (same bug as RefOpStopSound).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
HitTest pair: sret-temp wrappers over RefOpHitTestObjectsImpl with BIFK
113/114. DeferObjectUpdate needed a nested-scope named temp so the
coerced float survives the temp's destructor in $f20.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…w splice helpers)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…, sw splice setters, alo restore/lookat)

RenderSoSelf reverted: so.c emits +0x18 zero-fill on a still-asm neighbor when added (same pathology as OnSoRemove).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… sw splice ops)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…AG/exc, mpeg oids, bq CbFill, so wkr)

SetAloPosition/RotationSmooth reverted: scheduler diff vs ROM (false per-symbol match from flaky asm regen).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…oc/stop, sw oxa, act/actseg goals, mpeg)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…/jlo/mpeg cross-unit)

Fix game.h: UnlockEndgameCutscenesFromFgs & PchzFriendlyFromWid are raw symbols (extern C).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…and, dartgun/screen)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…coin/game/jt/blip/chkpnt)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…obj/jlo cross-unit)

game.h: reload_post_death is a raw symbol (extern C).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…turret/vifs/wr etc.)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… dartgun, sky/tv/ub etc.)

game.h: tally_world_completion is a raw symbol (extern C).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The previous commit (5a38764 "wip: more function matching") did not build
and, once made to build, produced a binary ~64% different from the ROM: it
"finished" 37 functions (deleted INCLUDE_ASM) of which most did not actually
match, plus left several compile/link breakages.

HEAD~1 (wave-9) builds byte-perfect, so the damage was isolated to that one
commit. This restores out/SCUS_971.98: OK by:

- Reverting all 37 finished functions to in-progress form (INCLUDE_ASM +
  #ifdef SKIP_ASM-wrapped C), preserving the C drafts as diff targets. The
  dual-build flagged 14 as matching, but 7 of those were false matches
  (size-shifters: ProjectActPose, UpdateBarrier, MatchCnvoScrollerToBeltSpeed,
  check_anticrack_antigrab, AddSwProxySource, InitTn, DrawWipe) and the rest
  caused residual rodata/assembler-state side effects, so all were reverted.
- Reverting two game.c switch functions (UnlockIntroCutsceneFromWid,
  DefeatBossFromWid) whose ROM jump tables dangle when built from C.
- Reverting header perturbations no longer needed (sw.h PFNFILTER, act.c
  clock.h include, difficulty.h extern "C") now that their callers are asm.
- Keeping harmless build-enabling decls (mpeg CMpegAudio::Update, shadow
  memset include) so the wrapped drafts still dual-build.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…dding)

Brings the two changes from decomp/p2-leaf-matches that fable did not already
have (its water.c STRUCT_OFFSET refactor and TODO cleanup were already present
and superseded). Both verified byte-identical to the prior green build.

- Name FUN_001c0c50/68 as GetAMRegister/UpdateAMRegister and drop extern "C"
  (the functions are already decompiled; rename only, mangled symbols, no asm
  callers depend on the raw names).
- Pad SO to its real 0x550 size (STRUCT_PADDING(160)) instead of carrying the
  0x2d0..0x550 base gap in each subclass: WATER drops its leading 160-pad and
  JT's pad goes 1090 -> 930, both keeping their fields at the same absolute
  offsets. This is the root-cause fix requested in the PR TheOnlyZac#257 review.
- Drop the verbose truncated-base / STRUCT_OFFSET explanatory comments in
  water.c per the same review (the STRUCT_OFFSET calls are self-documenting).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Remove the extern "C" shortcut from matched C++ functions by renaming their
symbol_addrs.txt entries to the GCC2-mangled form, so a plain C++ decl/def
emits the exact target symbol (manglings read from nm, not hand-computed).
Symbol renames are checksum-neutral (stripped ELF); splat regenerates asm
callers and linker scripts. 38 extern "C" removed, 0 added.

  - Data globals + __asm__ aliases: just drop extern "C" (C++ doesn't mangle
    namespace-scope variable names; the asm alias already forces the symbol).
  - Real-named free functions (OnRwmRemove, InitCplcy/FActiveCplcy/SetCpmanCpmt/
    InitCplook, SetCmLookAt/ResetCmLookAtSmooth, HandleJtGrfjtsc,
    SfxhMusicUnknown1/2, MvgkUnknown3/4, UnlockEndgameCutscenesFromFgs):
    pre-mangle + convert owning-header/caller decls to plain C++.
  - UpdateAloXfWorld: fix alo.h (it declared the literal mangled identifier),
    drop the so.c _UpdateAloXfWorld __asm__ alias, call it directly.

SetAMRegister and OnDifficultyPlayerDeath keep extern "C" -- both are
load-bearing: they pass match.sh per-symbol but fail the full checksum when
converted (caller-side uchar narrowing / a GCC 2.95 register-allocation flip).

Also trim decomp/tooling-explanation, AI-process, and TODO/blocker comments
this branch added; condense the load-bearing "kept wrapped (unwrapping breaks
the checksum)" notes to one line each. Struct-field annotations and Doxygen
kept.

Verified: out/SCUS_971.98: OK.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
These were local agent/tooling artifacts that don't belong in the repo. The
ignore patterns (CLAUDE.md, .claude/, docs/DECOMP_PROMPT.md, report_*.json)
move to .git/info/exclude so they stay ignored locally without being tracked;
.gitignore returns to its upstream form. CLAUDE.md stays on disk, untracked.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
origin/main's content is fully contained in fable (every main commit has a
patch-equivalent here), so this records the integration without changing the
tree. Verified: out/SCUS_971.98: OK.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@lindskogen lindskogen marked this pull request as draft June 22, 2026 22:15

@TheOnlyZac TheOnlyZac left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow that's a lot of code! it might a while to review this. The first and main thing I've noticed is that many functions are declared extern "C" in the P2 sources, but I think the P2 sources are all CPP (the only place I've seen C functions are the statically linked libraries).

@TheOnlyZac

TheOnlyZac commented Jun 23, 2026

Copy link
Copy Markdown
Owner

I'm actually getting build errors after configuring the project with the --objects flag (which builds with SKIP_ASM defined), I think because of the discrepancy between the C function declarations in the headers and the CPP function definitions in the source files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants