Skip to content

Android port, piece 3: the game code built on the device, and the movies - #614

Merged
peiikai merged 3 commits into
beta_6from
android-ffmpeg
Nov 7, 2026
Merged

peiikai merged 3 commits into
beta_6from
android-ffmpeg

Conversation

@peiikai

@peiikai peiikai commented Nov 7, 2026

Copy link
Copy Markdown
Owner

Stacked on #612: it targets #612's branch, so the diff shows only this work. Once #612 is merged, switch the base to beta_6. Ported from mamcjr's LASRecompAndroid (MIT). With this the game boots on Android. Desktop builds are unchanged.

Building the game code on the device

  • The start screen builds the game code from the player's own extracted files, as on the desktop (runtime/gamebuild.c). Nothing from the game ships.
  • android/deps/build_gen_deps.sh builds, from pinned sources:
    • Python 3.14 for Android (python.org)
    • capstone, unicorn and lz4, built with the NDK
    • zig 0.17.0 for aarch64, the desktop's version
  • Android only runs programs from the app's native library folder, so Python's launcher and zig ship there as lib*.so.
  • The rest (Python's library, zig's library, the generator, the headers) ships as assets/gen.zip. The app unpacks it once per install or update, and the build waits for that if needed.
  • gamebuild.c on Android: the generator runs with --dyn-base, and zig compiles for aarch64-linux-musl, linking -nostdlib against libmain.so.
  • gamelib.c loads the library from a copy in internal storage, since shared storage is mounted noexec.

Movies

  • build_deps.sh builds FFmpeg 9.0.2 with the desktop's LGPL-only configuration and the same not-GPL check.
  • The app links it and builds movie.c. Without it, the game crashed at its title movie, and the start screen had no background.

CI

  • The Android job builds the builder too.
  • The APK check allows the new libraries and looks inside gen.zip file by file, so only the builder's own files can ship there.

Tested on the arm64 Android 15 emulator

  • The generator wrote the main program (538 files, 86,669 functions) in 38 s and the SDK in 10 s.
  • The full build took 1316 s on 4 cores.
  • The library loaded, the start screen shows its background, and Play runs the opening movie at 60 fps.

Known

  • On the emulator, a 283 MB pipeline cache written by a crashed run hung its GPU bridge (gfxstream) when loaded at the next start.
  • The emulator also logs some "pipeline creation failed: -3".
  • Both still need a check on a real phone.

🤖 Generated with Claude Code

peiikai and others added 2 commits November 7, 2026 16:24
The setup builds the game code on the device from the player's own extracted
game files, as on the desktop (runtime/gamebuild.c), with the bundled
generator and compiler. From LASRecompAndroid by mamcjr (MIT).

- android/deps/build_gen_deps.sh: Python 3.14 for Android (python.org),
  capstone, unicorn and lz4 built with the NDK, their bindings (lz4.block
  through liblz4: android/gen/lz4), and zig 0.17.0 for aarch64 Linux (the
  desktop's version). Pinned sources and checksums.
- The APK: Python's launcher, libpython, the native libraries and zig as
  lib*.so in nativeLibraryDir (the only place Android runs programs from);
  the rest as assets/gen.zip, unpacked by the activity into internal
  storage once per install or update, on its own thread (the build waits).
- gamebuild.c on Android: those tools and their environment, the generator
  with --dyn-base, zig for aarch64-linux-musl, linked -nostdlib against
  libmain.so. Flags in the app's CMake (GAMELIB_CFLAGS / GAMELIB_SHARED),
  with -dag-maps-huge-region=500 and no UBSan / stack protector.
- gamelib.c: the library is loaded from a copy in internal storage (shared
  storage is mounted noexec), made again when the built one changed.
- CI: the Android job builds the builder too; the APK check allows its
  files and looks inside gen.zip file by file.

Tested on the arm64 Android 15 emulator: the generator wrote main (538
files, 86,669 functions) in 38 s and sdk in 10 s, the build finished in
1316 s on 4 cores, and the library loaded and the game booted until the
title movie (movie.c needs FFmpeg, not on Android yet).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The game crashed at its title movie on Android: runtime/hle/movie.c (the
game's movie player, on FFmpeg) was left out of the app, so movie::Extractor
stayed a stub and the game read an object that was never made. The start
screen's background frame (the title movie's) was missing for the same
reason.

- android/deps/build_deps.sh builds FFmpeg 9.0.2 for arm64 with the desktop
  builds' LGPL-only configuration (tools/linux/build_deps.sh), unversioned
  library names (Android loads shipped libraries by exact name), and the
  same not-GPL check. Cross settings from LASRecompAndroid by mamcjr (MIT).
- The app links avcodec / avformat / avutil / swscale and builds movie.c;
  the LARECOMP_NO_FFMPEG guards are gone. CI's APK check allows the four
  libraries.

Tested on the arm64 Android 15 emulator: the start screen shows its
background, and Play runs the opening movie at 60 fps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@peiikai
peiikai changed the base branch from android-storage to beta_6 November 7, 2026 22:55
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@peiikai
peiikai merged commit 7797504 into beta_6 Nov 7, 2026
6 checks passed
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.

1 participant