Add Android Port#3
Merged
Merged
Conversation
Ports ClassicUI to Android as a shared library loaded by SDL's Java SDLActivity -- no JNI bootstrap, no bundled assets, no Java UI code beyond the SDLActivity subclass. PureSwift/Cairo and PureSwift/FontConfig (which the desktop SwiftUI- subset resolver ClassicUICore renders through via Silica) have no Android build: there is no prebuilt libcairo/libfontconfig for the NDK, and cross-building that whole stack from source is out of scope. So, like ports/3DS and ports/NDS (which hit the same wall under Embedded Swift, for different reasons), this port carries its own portable mini-core and software rasterizer instead of ClassicUICore: - Sources/ClassicUIAndroid/ClassicCore.swift is byte-for-byte identical to ports/3DS's -- the same menu/settings/Notes/Now Playing/navigation model, selection restore, and scroll windowing. - Renderer.swift is the same rasterizer adapted to 32bpp ARGB8888 (the console ports use RGB565/ARGB1555 for their LCD framebuffers; SDL's Android streaming texture takes ARGB8888 directly). - tools/gen_font.py is the same build-time Helvetica rasterizer. Unlike the console ports, this one shares PureSwift/SDL's SDL3Swift with the desktop SDL3Renderer: SDL3 has an official Android build (prebuilt .aar, vendored by scripts/fetch-sdl.sh) and cross-compiles cleanly with the Swift Android SDK. Input: gamepad (same A/B/D-pad/ X/Y/shoulder mapping as the other presenters), keyboard, and a three-band touch mapping (top third scrolls up, bottom third down, middle selects) for phones without a gamepad; the system Back gesture maps to Menu. Verified end to end: `swift build --swift-sdk aarch64-unknown-linux- android28` links a real arm64-v8a libClassicUIAndroid.so against the vendored SDL3 prebuilt, its Swift-runtime DT_NEED closure resolves cleanly against the Swift Android SDK (scripts/stage-jnilibs.sh), and `gradle assembleDebug` packages it with SDL's Java glue into a signed debug APK. Not yet run on a device or emulator.
Extend the 320x240 iPod baseline to fill the device's real aspect ratio (same adaptive-layout principle as the desktop renderer) instead of pinning the canvas to a fixed size and letterboxing the rest. The taller/wider dimension now just shows more content. Also size the SDL window request itself to the display's real bounds rather than the 320x240 baseline: on Android, SDL's Java glue uses the requested width/height for its own internal orientation/coordinate bookkeeping even though the activity is always fullscreen, and the earlier mismatch was producing visible artifacts during resize/orientation transitions.
ClassicRenderer.swift imports Cairo directly, not just through Silica, but ClassicUICore's target only declared Silica as a dependency -- a stricter toolchain now enforces that direct imports need their own explicit dependency declaration, breaking macOS/Linux CI. The Android workflow's font-generation step needs Pillow, which wasn't installed on the runner.
Xcode's bundled Swift 6.3.2 diverges from the swift.org release of the
same version on a typed-throws/existential edge case in Silica's
CGContext initializer ('any CGContext' cannot be constructed), which
doesn't reproduce with the swift.org toolchain locally or in a
matching Linux container. Installing it via swiftly, matching what the
Android workflow already does, keeps the macOS job on a toolchain that
actually builds this dependency graph.
Silica's master branch did a breaking multi-backend split upstream (CGContext became a protocol, with the concrete Cairo-backed type moved to a separate SilicaCairo library), which SwiftPM silently picked up as soon as Cairo was added as an explicit top-level dependency here, breaking ClassicRenderer.swift's direct Silica.CGContext(surface:size:) construction on both macOS and Linux. Pinning to the last commit before that split keeps the build working without a larger migration to the new multi-backend API.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Test plan