* build: add an iOS arm64 target
Selects iOS before macOS, since APPLE is true for both and the macOS
branch would otherwise claim an iOS configure and pick a memory backend
that cannot compile there.
Third-party libraries are pinned static on Apple targets. aurora picks
shared ones whenever BUILD_SHARED_LIBS is merely undefined, and its
extern/ tree unsets the cache entry while working around xxhash, so
passing it on the command line only survives one configure. On iOS that
was fatal rather than untidy: libpng linked as a dylib with an @rpath
into the build tree, which dyld cannot resolve inside a bundle.
User state lives in the container's Documents rather than a name-scoped
Application Support directory, so Config.toml sits beside the game data
a relative dvd_root resolves against, and both are reachable over file
sharing.
(cherry picked from commit ad7231fca3d55c5d7d1807c5accb6874d702111f)
(cherry picked from commit 76cc9594e02d5a858c0848b4b4e4e5a585151cc0)
(cherry picked from commit 80a6b53abd699942178fde2f16010d54dba9952b)
* ios: resolve the flat guest base at runtime
No fixed base works on every device. Probing an iPhone 17 Pro and an
iPad Pro M5 with the same 24-candidate sweep gave disjoint sets of free
4 GiB windows - 448 GiB only, against 12, 16, 20, 24, 32 and 48 GiB -
and the extended-virtual-addressing entitlement changed neither map. So
iOS takes whatever the kernel offers and publishes it, while every other
target keeps its compile-time constant.
The backend is the macOS one adapted twice over: <mach/mach_vm.h> is not
in the iOS SDK, so the vm_* calls are used instead, and the backing store
is an anonymous mapping rather than a file in /tmp, which the sandbox
denies.
g_requiresCheckedAccess is set from the real page size. Apple Silicon's
16 KiB host pages are coarser than the 4 KiB guest page, so page
protection alone cannot be relied on.
(cherry picked from commit 0677b83ed45e8b59d779d37cad172c737daf08eb)
(cherry picked from commit 9a8a80ffd4c3f87652e37208fc88afd0a94e6cf8)
(cherry picked from commit 2b7707e6226ee20a6c0564c0f9bbcdd06b511061)
* ios: pick a display explicitly and survive a second scene
A bare SDL_WINDOWPOS_CENTERED does not say which display it means. With
an external screen attached that left the window sized for one display
and the surface for another, which played audio over a black screen.
The primary display is now named outright and its bounds used.
SDL calls SDL_main from scene:willConnectToSession:, once per connecting
scene, and iOS creates a second scene when a display is attached. That
re-entered main while the first call was still inside the game loop: the
data sections reloaded, no static constructors ran the second time, and
aurora then failed to create a window. Declaring
UIApplicationSupportsMultipleScenes=false does not prevent the extra
scene, so the guard belongs here.
(cherry picked from commit d8b984cfbb8521f06776ae765131452c4380e473)
(cherry picked from commit d20895a98739c11f97de1222834859e2a55e3516)
(cherry picked from commit 492f57ef5122305b0ab63258a5a4efe960f5abc9)
* ios: add on-screen touch controls
A touch device has no pad and no F10, so without these it boots to a
screen nothing can drive.
The overlay polls SDL's finger list rather than using ImGui widgets,
whose SDL backend collapses touch to one emulated mouse - steering,
accelerating and drifting all happen at once. Input merges into
PAD__Read_HLE only when port 0 has no real pad, so a controller always
wins, and the overlay hides itself while one is attached.
Positions are held as a distance from a screen edge in units of screen
height. A fraction of width lands somewhere different on a 1.45:1 iPad
and a 2.17:1 iPhone. The d-pad is one cross with the direction taken
from the dominant axis, and the stick keeps the finger that grabbed it
until that finger lifts, so sliding past the gate does not drop steering
mid-corner.
Buttons use Zacksly's GameCube icons, CC BY 3.0, with attribution beside
them in the bundle. The dark backing is each glyph's own silhouette
tinted black, so the d-pad and the triggers are not given a disc they do
not have. They are decoded up front: doing it lazily made the frame the
controls appear on pay for every decode at once.
Tapping the FPS readout opens the settings bar, which is otherwise
unreachable - and the readout's tap target is cleared before the early
return when FPS display is off, or a stale rectangle keeps swallowing
taps meant for the fallback menu button.
PADIsInputBlocked comes back to aurora; it went with the WUP-028 revert
and the overlay needs it to avoid driving the guest while the bar is up.
(cherry picked from commit 79d3de3c0b9c883ff2ec34a5964498a475e91240)
(cherry picked from commit cf7a8edb3405d4f7d7fd189d19cdb2f746b190f9)
(cherry picked from commit 360261208c95616ec81d8f8c3d69efc3c776c54b)
* ios: build an unsigned ipa
CMake bundles iOS targets with its own default Info.plist, whose
CFBundleIdentifier is empty and which carries none of the iOS keys, so
what came out of the build could not be installed. It now gets a real
plist and is packaged as an .ipa.
Unsigned on purpose: AltStore, SideStore and LiveContainer sign on the
device with the user's own Apple ID, so anything applied here would only
be replaced. WiiCompiled.entitlements is a template for signing by hand,
which those tools ignore.
Packaging runs after the asset copies rather than before, or the archive
gets the binary and nothing else. The touch directory is cleared before
it is copied, since copy_directory merges and a removed icon would
otherwise be shipped.
(cherry picked from commit 5ce43949dbf27abff6782bc41e3be0ede3ac135b)
(cherry picked from commit 633e3e0aa2f7ea116741f27ec46e9c743be9cf9a)
(cherry picked from commit a4ae6f2e8bdf11596a89dca9607aba92713184be)
* docs: document the iOS build
Covers building the .ipa, sideloading it, the one entitlement the app
needs, and where the game data goes.
The configure line is the one that works: without CMAKE_SYSTEM_PROCESSOR
the Dawn package URL comes out as dawn-ios-.tar.gz and the build fails
on a 404.
(cherry picked from commit 08eefad3fd1cb5e8f79a144ac119bc65852e33e6)
(cherry picked from commit b7cd38e07eefc8af4c1c60ca411c009eec4e212a)
(cherry picked from commit 5a1650ef194f9da4ae8a68f1a9779b16ee118ca8)
* ios: stub out Discord presence
It connects over a Unix socket to a local Discord client, which iOS does
not have, so it can only ever fail and back off. Stubbed rather than left
retrying.
(cherry picked from commit 69aa5e5c297abe65188d391748b8fb11c57337d2)
* build: keep the macOS host tests off iOS and give the audit target libpng
The macOS test executables were gated on MKW_PLATFORM_MACOS, which iOS also sets, so a full iOS build tried to compile guest_flat_memory_macos.cpp against an SDK with no <mach/mach_vm.h>. The products-off audit compile picked up the touch overlay sources without the PNG include path.
* ios: tidy the touch decode and pad merge after review
The row-pointer buffer now lives in PngReader so a libpng longjmp cannot skip its destructor. PAD__Read_HLE no longer uses the port 0 error code to decide whether touch applies; keyboard bindings report PAD_ERR_NONE with no controller attached, and TouchPad::Read already checks for a physical pad.
* docs: tag the iOS build fence as sh
* ios: pin the CPU baseline instead of tuning for the build host
-mcpu=native tuned the phone binary for whichever Mac compiled it, and upstream clang rejects the flag outright when cross-compiling. iOS 17 implies the A12 and later.
* build: cross-compile the iOS products from Linux
* use online sdk instead of mac sdk to build on linux
* build: ios platform identifier
* build: build the ios ipa on windows too
* fix: strap cover ends too early on slower devices
* ci: compile the ios runtime on a linux runner
* docs: note the entitlement needed on devices with less than 4gb ram
* 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>