* Scope Kamek bl-patch LR-continuation detection to genuine skip-return targets
Fix crash from Kamek skip-return hooks (Item Rain crash) (#182) added every
Kamek BranchLink patch target to lrContinuationCallTargets unconditionally,
with no filter analogous to the RetroWfcHookSetsLinkRegister check already
used for RetroWFC hooks. Since bl is the ordinary PowerPC call instruction,
this made the codegen treat effectively every patched call in the mod as a
potential skip-return hook, forcing conservative handling (full register
reload, disabled resident-call fast paths, local LR-continuation dispatch
tables) onto thousands of calls that just return normally.
For Retro Rewind this inflated total translated mod size by +42%
(1,414,327 -> 2,005,284 lines), concentrated in ~10 unrelated overlay
functions that happened to call a patched target, and was enough to make
one aggregate build shard pathologically slow to compile (hangs Linux CI).
Instead, only mark a bl target as LR-continuation-aware if a lightweight
discovery-only decode of its own body actually finds evidence of
skip-return behavior via DiscoverLrRelativeIndirectJumpOffsets. Falls back
to the conservative (old) behavior if a target can't be statically
analyzed, so no skip-return case is silently missed.
Verified against the real Retro Rewind mod: total mod size returns to
1,416,350 lines (+0.14% vs. pre-fix, down from +42%), all 6 genuinely new
continuation functions from the original fix are preserved, zero
functions lost, and all 609 existing translator tests still pass.
* Distinguish exhausted from truncated LR-relative offset search
CodeRabbit flagged that TargetExhibitsLrSkipReturn (added in ad2d4e7) treated
an empty DiscoverLrRelativeIndirectJumpOffsets result as a verified "this
target never skip-returns," but the analysis silently drops any path state
once more than MaxStatesPerInstruction (16) distinct states reach one
instruction - a bctr/return on a dropped state can never contribute its
offset, so an empty result could be an incomplete search rather than a real
negative. Treating every capped case as "skip-return possible" outright was
rejected as too broad a fallback given how conservative/expensive that path
already is.
Instead: raise MaxStatesPerInstruction 16 -> 512 (an arbitrary conservative
bound to begin with, not something correctness depended on) so genuinely
branchy functions have far more headroom to reach an exhaustive answer, and
give DiscoverLrRelativeIndirectJumpOffsets an optional onStateCapExceeded
callback that fires exactly when a state is dropped. TargetExhibitsLrSkipReturn
now only falls back to the conservative "treat as skip-return" answer when
the search both found nothing and the cap was actually hit during that run -
not whenever the cap merely exists - so a target is trusted as clean once the
search genuinely exhausts it.
Verified: all 609 translator tests pass, and a full translate-mod run against
the real Retro Rewind mod produces byte-for-byte identical output to the
prior fix (same 4,065 functions, 1,416,350 total lines) - confirming the
16-state cap was never actually the limiting factor in practice and this
change is a pure safety-net closure, not a behavior change for this mod.
* Add LR continuation regression tests
* Refine LR continuation hook analysis
---------
Co-authored-by: patchzyy <64382339+patchzyy@users.noreply.github.com>
fixes https://github.com/patchzyy/Wiicompiled/issues/159
previous requirement for ubuntu 24.04+ libstdc++ inherited from dawn prebuilds now dropped to ubuntu 22.04+ libstdc++ like the rest of the prebuilds
also add all architectures to the URL_HASH check since the dawn tag doesn't change but the binaries have
translate-recursive now starts at 0x800060A4 (__start) to match recomp.yml and system_bridge.h. The payload curl uses rwfc.net/api/wfc/payload like the rest of the guide, since nas.play.rwfc.net does not answer over https.
Co-authored-by: devangpratap <devangpratap@proton.me>
* fix: Kamek LR-continuation hook discovery and dispatch
* test: cover branching Kamek LR continuations
* review fix
* another review fix
fix: get the new tests to pass
test: expose LR restore and loop continuation regressions
* Update translator/src/Translator.Core/Mods/ContinuationPlanner.cs
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* test: cover continuation regressions from the new path-sensitive planner
* Update translator/src/Translator.Core/Mods/ContinuationPlanner.cs
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* test: cover continuation regressions from the new path-sensitive planner
* fix: preserve LR continuation analysis across large handlers and clobbers
* fix: track LR-relative r1 across update-form stack stores
* Harden LR-relative continuation test coverage
* Fix LR/SP continuation state tracking
---------
Co-authored-by: patchzyy <64382339+patchzyy@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Fix already downloaded toolchain re-use
the following mv command would move $work into $toolchain_dir if the $toolchain_dir folder already existed.
* resolve z-fighting
ProcessSleepTimers popped every due timer into a private vector and then
resumed the sleepers in a loop. OSResumeThread re-enters SelectThread, which
can switch fibers away mid-loop, so the timers still in that vector were
gone from gSleepTimers while their threads stayed parked (Ready, suspended,
no timer). The reconciler healed them 100ms later and the stale-timer drop
fired when the original fiber eventually resumed.
Pop one due timer at a time straight from the shared table instead, so any
timer not yet processed stays visible to every other pump while this call
is switched away.
Co-authored-by: jordanblakepp <slamuelrose2002@gmail.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* caching a little bit
* provide CMake with the explicit path to sccache.exe
* map ACTIONS_RESULTS_URL to ACTIONS_CACHE_URL so sccache can upload the
files...
* i removed the parallel oops
* small change
* doing a little bit of flag editing
* update sccache and cache nuget stuff
* treat empty mkw save as missing
first-run format zero-fills rksys.dat before any real save; a quit before
the first save left an all-zero file that read back as corrupt and trapped
the user in a delete/recreate loop. read opens now treat an all-zero
rksys.dat as absent (a real save always begins with the RKSD0006 header),
so the game recreates it from scratch. also ignore native build output.
* shorten
* I dont really want to change this to be honest.
* extra safety
---------
Co-authored-by: patchzyy <64382339+patchzyy@users.noreply.github.com>
two upstream LLVM bugs currently prevent building on some of the newest distros. There is no current LLVM release that works on them so we are pending fixes from LLVM
https://github.com/patchzyy/Wiicompiled/issues/136
* Add Dolphin-compatible input expressions and GCPadNew.ini import
Rebased onto current main; addresses both CodeRabbit reviews on #89.
- Expression engine matching Dolphin's semantics: doubles rather than
booleans, 0.5 press threshold, & as min, | as max, and the functions if,
min, max, clamp, abs, sqrt, pow, sin, cos, tan, deadzone, timer, toggle,
hold, tap, pulse and smooth. Timing uses a steady clock in seconds, as
Dolphin does, so a copied expression behaves identically.
- Expressions bind to the GameCube buttons and triggers, combined with the
existing button mapping rather than replacing it, and are skipped while
the settings overlay holds input.
- Import reads [GCPadN] from the Dolphin config directory or from
GCPadNew.ini beside the executable. Stick axes are not expression driven
and keep their normal mapping.
- Fixes#74: a digital button bound to L or R now reports a fully pulled
analog trigger, plus a PlayStation preset and a vibration toggle.
Review fixes: config paths round-trip through RuntimeConfigFile::PathToUtf8
and PathFromUtf8 so non-ASCII paths open correctly on Windows, and the
duplicated exists branch is gone; the tap count is clamped before the
unsigned conversion; the expression editor uses resizable storage via
ImGuiInputTextFlags_CallbackResize so a long expression cannot be saved
truncated; clamp bounds are ordered before std::clamp; <cstdlib> is included
for std::strtod; non-finite values are rejected at the evaluator boundary as
well as at the deadzone and timer divisions; and InputBindings::Reload() runs
from InitializeRuntimeSettings rather than the vibration handler.
runtime/tests/test_expr.cpp covers operator precedence, each stateful
function and every case raised in review.
Third review round: smooth() guards NaN as well as infinity so a zero rate
cannot latch a non-finite value in node state; division evaluates both operands
so stateful functions in the left subtree still update when the divisor is zero;
the expression editor clears stale errors when the port changes; and
runtime/tests/test_expr.cpp is registered with CTest as mkw_input_expr_tests,
following the existing test targets.
* Update runtime/src/input_expr.cpp
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Update runtime/src/input_expr.cpp
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Update runtime/src/input_expr.cpp
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Linux Appimage: statically prebuild Aurora (and all its dependencies)
adds symlinks to the compiler locations in a static path that way rebuilds do not think that the compiler path has changed between appimage install commands
* Update package.yml
* Update Launcher/build-appimage.sh
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Bluetooth Wii Remote support: the game reads a real Wii Remote through KPAD
Enable SDL3's HIDAPI Wii driver and hand a paired Wii Remote (bare or with
Nunchuk) to the game as a real Wii Remote: WPADProbe reports CORE/FREESTYLE
and KPADRead fills KPADStatus[0] from SDL every frame (buttons, accelerometer
in KPAD's g frame, Nunchuk stick and accelerometer), while the GameCube pad
view of that port reports no controller. The game's own motion code then
handles wheelies, tricks and Wii Wheel steering. Classic Controllers and
Wii U Pro Controllers keep going through the GameCube pad path with a default
button table picked by name.
SDL's Wii driver drops a remote on a failed Bluetooth read or when the
Nunchuk is plugged or unplugged and never re-adds it, so the runtime keeps
rescanning (Dolphin style) while no Wii controller is present by toggling the
driver hint off and, a few frames later, on again; a dropped remote is back
within 1-2 s. Settings live in the F10 overlay under Wii Remotes (Bluetooth)
and in Config.toml (wii_remotes, wii_continuous_scan).
* Fix Wii U Pro / Classic Controller ZL and ZR not registering
SDL's Wii driver reports ZL/ZR as the LEFT_TRIGGER/RIGHT_TRIGGER analog
axes, never as digital shoulder buttons. Binding them to
LEFT_SHOULDER/RIGHT_SHOULDER meant they never fired and also disabled
aurora's own analog-trigger fallback (a button table entry for
PAD_TRIGGER_L/R marks the trigger as "handled", even when the bound
digital button never actually presses). Leaving them unbound lets the
default axis mapping drive them like every other analog-trigger pad.
Reported by an end-to-end tester connecting a real Classic Controller to
a Wii Remote.
* Wii Remotes menu: live raw D-pad/ZL/ZR readout for Classic Controller / Wii U Pro
Diagnostic aid for a reported issue where the Classic Controller's D-pad
does not do anything in-game (no wheelies). Shows what SDL itself sees so
a driver-level problem (nothing lights up) can be told apart from a
mapping problem (it lights up but the game does not react).
* Fix Classic Controller D-pad input
* Address CodeRabbit review on PR #73
- PADRead: hide KPAD-served ports even while input is blocked so the port
error state does not flip when the overlay opens/closes.
- WPADProbe: run the Wii Remote rescan state machine before probing so a
reconnect probe before the next PADRead can see the remote.
- EnsureSensors: only cache the gamepad id once every accelerometer enabled,
so a failed activation is retried.
- ConfigureSdlHints: reset the in-flight rescan bookkeeping.
- Settings overlay: disable "Rescan now" while Wii Remotes are turned off.
* Bluetooth Wii Remote: fix wheel steering, native Classic Controller, extension hot-swap
Accelerometer
- The SDL -> KPAD conversion negated the wrong axis: SDL's z is the remote's
+Y (towards the user), so KPAD acc is (-wiiX, -wiiZ, +wiiY). Fixes mirrored
Wii Wheel steering.
- Drop reports whose accelerometer bytes arrive zeroed (+-5.12 g on every axis,
a few times a minute over Bluetooth) and repeat the last good sample; they
read as a full-lock steer plus a 9 g shake.
- One-button zero-point calibration in the overlay (remote flat, buttons up),
stored in Config.toml as wii_accel_offset_x/y/z. SDL's read of the remote's
factory calibration times out over Bluetooth and falls back to a nominal
zero point, which left a per-axis bias of up to ~0.3 g on the tested remote.
- Live accelerometer readout and an optional per-frame CSV trace
(wii_accel_trace = true) for debugging.
Classic Controller through KPAD/WPAD
- WPADProbe reports WPAD_DEV_CLASSIC; KPADRead fills ex_status.cl and
KPADGetUnifiedWpadStatus the raw WPADCLStatus (WPAD_CL_BUTTON_* bits, sticks
in the SDK's signed -512..511 range, triggers), so the game shows the Classic
layout and icons and no button mapping is involved. Ports served through KPAD
are hidden from PADRead; only the Wii U Pro Controller stays a GameCube pad.
Extension hot-swap
- SDL's Wii driver destroys the joystick on an extension change but keeps the
HID handle open, and HIDAPI never re-creates a joystick for such a device.
Patch the vendored SDL at configure time (AuroraSDL3Patches.cmake, wired into
AuroraSDL3Provider.cmake for both the downloaded tarball and a pre-provided
FETCHCONTENT_SOURCE_DIR_SDL) so the joystick is rebuilt in place with the new
extension type, without touching the Bluetooth handle.
- Keep a vanished remote's channel alive with neutral input for up to 3 s while
SDL re-creates the joystick, so the game never sees a disconnection. The
driver-hint rescan stays as a fallback for real drops, starting 3 s after
the loss, and also runs from the overlay's per-frame Draw. Log rescans.
Mappings / overlay
- Do not apply the shared positional [controller] bindings to Wii pads: that
override is what made a Classic Controller's A/B and X/Y look swapped.
- Raw D-pad fallback also for the Wii U Pro Controller; overlay readouts read
joystick buttons directly (SDL's generated HIDAPI mapping expects a hat).
- Overlay: Classic Controller readout, accelerometer readout and calibration.
- README: Bluetooth Wii Remote section and known limitations.
* Review pass on the Wii Remote input path
- EffectiveKind: stop bridging an extension swap once a different controller
has taken the port, and note that everything touching the scanner state runs
on the guest thread.
- KPADGetUnifiedWpadStatus: fill every requested entry (the SDK returns `count`
recent samples), capped at KPAD's 16 read buffers.
- IsKpadKind gets internal linkage; the calibration accessors get their
comments; clarify why Draw() also runs Poll().
* Drop the dead Classic-Controller-as-GameCube-pad matching
A Wii Remote with a Classic Controller is served through KPAD and its port is
hidden from PADRead, so the name matches that once gave it a GameCube button
table and the raw D-pad fallback could never take effect any more. Both now
match only the Wii U Pro Controller, and the default table is renamed
accordingly (g_defaultButtonsWiiUPro).
---------
Co-authored-by: LOL <andresguerra2k26@gmail.com>
Co-authored-by: Nick <89667145+Nick1232345@users.noreply.github.com>