Repository navigation
Pack the FUComplete build as its own Android app, PokeeFUC - #3
Oddity-git wants to merge 38 commits into
Conversation
An Android build directory configured with MHFU_TITLE=FUC now packs PokeeFUC: application id io.github.teamgdb.pokeefuc, PokeeFUC on the launcher, pokeefuc-<version>-android-arm64.apk. It installs beside Pokee with its own storage. The Java code keeps one package; build_apk.sh renames the manifest package with aapt2 and packs a copy of the resources with the title's name, and the manifest names the activity in full so it is found under either id. An unknown title is refused. From Yakumo's packer: sources and classes are passed as arrays, the keystore password reaches apksigner through the environment, the APK carries Pokee's, Dear ImGui's, tiny-AES-c's and xxHash's licences, zip leaves out directory records, aapt2 does not crunch the icons again, and ANDROID_BUILD_TOOLS_VERSION / ANDROID_COMPILE_SDK_VERSION pick SDK versions. android_packaging_tests.py runs build_apk.sh against stand-in SDK tools. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hyrco8tLuU7Jb5hpCUJdH3
On Android 11 and later the app asks for the surface frame rate the Frame rate setting presents at (Match display: the display's own), so a phone that switches between 60, 90 and 120 Hz can show 90 or 120. ANativeWindow_setFrameRate is looked up at run time, so the APK still loads on Android 10, where nothing is asked. MHFU_NO_DISPLAY_RATE_REQUEST leaves the display as it was. The rate comes from pacing::requested_rate, which wanted_rate now uses before its Vsync cap. Ported from Yakumo with its loader tests. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hyrco8tLuU7Jb5hpCUJdH3
They run a shell script, so coverage.py measures nothing in them, and the coverage pipeline test's fixture repository has no copy to run. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hyrco8tLuU7Jb5hpCUJdH3
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hyrco8tLuU7Jb5hpCUJdH3
The NDK links shared libraries with --no-undefined, so the two fixture modules failed to link in the Android test build. They leave the framework's symbols to the loader, as the overlay libraries already do with -z undefs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hyrco8tLuU7Jb5hpCUJdH3
ld64 refuses a bundle with undefined symbols; the fixtures take the framework's from the test executable when loaded, so they link with -undefined dynamic_lookup. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hyrco8tLuU7Jb5hpCUJdH3
macOS's bash 3.2 takes an empty array for an unset variable under set -u, so build_apk.sh stopped with 'class_files[@]: unbound variable' when javac made no classes (the packaging tests' stand-in made none). The script now counts the sources and classes and says which is missing; the stand-in javac writes a class. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hyrco8tLuU7Jb5hpCUJdH3
The HUD scale replay and overlay swap tests read fixtures from host paths compiled into them, which do not exist on the emulator. CTest now names both directories through the environment, the tests prefer that value, and the Android runner copies any directory a test's environment names inside the checkout or the build to the device and rewrites the value. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hyrco8tLuU7Jb5hpCUJdH3
Both branches taught the overlay test fixtures to leave host symbols to the loader on Android and macOS; the FUComplete branch's wording is kept. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hyrco8tLuU7Jb5hpCUJdH3
macOS temporary directories sit behind a symlink, and the runner pushes the resolved directory. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hyrco8tLuU7Jb5hpCUJdH3
The coverage build sets only the C++ compiler to Clang, so the KTX2 decoder's zstd C source went to the system cc with Clang-only flags and the build stopped. The flags now apply per language when that language's compiler is Clang. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hyrco8tLuU7Jb5hpCUJdH3
The FUComplete branch fixed the same two things this branch had: the Android runner now copies the overlay and HUD fixtures itself, and the coverage flags apply to C++ only. Its versions are kept, and this branch's environment-based fixture copying is dropped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hyrco8tLuU7Jb5hpCUJdH3
…to claude/project-thread-yl4vev
Under Fill the 2D interface is pulled into a PSP-shaped box in the middle of the screen, which on a phone leaves wide empty bands beside the clock, the bars, the map and the item bar. "Interface at the edges" (video.hud_edges, MHFU_HUD_EDGES) moves each quest HUD quad out by the gap the fit left: the clock, the bars and the party list to the left, the map and the item bar to the right. The side is judged from the game's own rectangle of each quad, so a bar's end cap stays with its bar, and what sits in the middle stays. Only draws filed by game_task's quest HUD move; menus and names over hunters keep their place. A draw's scissor moves with it, or takes in where its quads landed when they went different ways. It is on by default on Android and off on the desktop. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hyrco8tLuU7Jb5hpCUJdH3
cppcheck followed place_at_edges into quad_bounds with an empty copy and reported an out-of-bounds read the size guard already prevents. A one-vertex copy keeps the mismatch case. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hyrco8tLuU7Jb5hpCUJdH3
|
Two checks fail on files this PR doesn't change, the same way they did on #2:
I don't have the means to re-run jobs from here. I'm keeping the PR watched. Generated by Claude Code |
…ole at the edges Under Fill on a screen wider than the PSP's, the 2D interface is pulled toward the centre before the HUD sizes run, so scale_quads compared fitted positions against rectangles in the game's pixels. Only the map, which is told by its texture, was still recognised; on a phone's 2.2:1 screen every other piece kept the game's size. scale_fitted_quads sizes a fitted draw in the game's pixels and fits again only the vertices that moved. video.hud_edges moved each quad to its own side, so a window or a line of text reaching over the middle (the start menu's help box, the item box) was torn in two. A draw now moves only when all its quads go the same way. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hyrco8tLuU7Jb5hpCUJdH3
|
Project coverage and 80% diff failed on I ran the same coverage locally with The merged lines' coverage belongs to #1, which is where they came from. Nothing is ported here, because no fix exists yet. Generated by Claude Code |
…cal-android-build # Conflicts: # profiles/mhfu/host/settings/settings.cpp
…cal-android-build
"Interface at the edges" judged every quad by its rectangle alone, so the item box's top edge and a loot notice's letters were also pushed to a side and tore away from the rest of their window. The quad now has to be one of the quest HUD pieces (map, vitals, item bar, sharpness, weapon, bowgun) as well as wholly on one side; a menu or a notice stays in one piece. Turning the setting off fixed both, which confirmed the edge move as the cause. Tests cover the item box's top edge, a notice's letters and an item bar.
The piece filter that keeps menus and notices still would also have left the sliding window and panels drawn inside the area-map slot behind while the map moved. They are not map marks, so they are allowed by their slot instead; notices over that slot are still excluded. Tests cover both.
Frame interpolation writes the blended vertices of skinned draws, and their lighting blocks, into a scratch area of the vertex buffer during replay, after the game frame's own flush has run. On a cached but non-coherent vertex memory type, which a phone can choose, nothing made those writes visible to the GPU: the replays read stale vertices and the models burst into stretched triangles. The scratch range is now flushed when the present is submitted. Coherent memory is unaffected; the flush is a no-op there.
…cal-android-build
…cal-android-build
…cal-android-build
…cal-android-build
…cal-android-build
…cal-android-build
…cal-android-build
…cal-android-build
…cal-android-build
…cal-android-build
…cal-android-build
…cal-android-build
…cal-android-build
…cal-android-build
…cal-android-build
Requested by Oddity-git · project thread
This replaces #2. It's the same commits, moved to a branch named
android-port.Changes
Before: Pokee already had an Android app (SDL activity,
build_apk.sh,release_android.sh), but it only ever packedio.github.teamgdb.pokee. An Android build of the FUComplete title (MHFU_TITLE=FUC) would have produced an APK with Pokee's id and name, replacing a Pokee install and its data. On a wide phone screen the quest HUD stayed in a PSP-shaped box in the middle.After: an Android build directory configured with
-DMHFU_TITLE=FUCpacks PokeeFUC: application idio.github.teamgdb.pokeefuc, PokeeFUC on the launcher,pokeefuc-<version>-android-arm64.apk. It installs beside Pokee with its own storage and saves. On Android 11+ the app also asks the system for the display rate the Frame rate setting presents at, as Yakumo's Android app does. With Aspect ratio set to Fill, the quest HUD can sit at the screen's sides ("Interface at the edges",video.hud_edges/MHFU_HUD_EDGES). This is on by default on Android and off on desktop.How:
build_apk.shreadsMHFU_TITLEfrom the build'sCMakeCache.txt, renames the manifest package withaapt2 link --rename-manifest-package, and packs a copy ofres/with the title'sapp_name. An unknown title is refused.release_android.shnames the APK after the title.build_apk.sh(same MIT licence and contributors): Java sources and classes are passed as arrays, and the keystore password reachesapksignerthrough the environment. The APK packs the Pokee, Dear ImGui, tiny-AES-c and xxHash licences, has no directory records in the zip, uses--no-crunch, and honoursANDROID_BUILD_TOOLS_VERSION/ANDROID_COMPILE_SDK_VERSION.platform/android_display.*callsANativeWindow_setFrameRate, looked up at run time so the APK still loads on Android 10.MHFU_NO_DISPLAY_RATE_REQUEST=1turns the request off.hud_scale::place_at_edgesmoves each quest-HUD quad on the left or right of the PSP frame out by the fit gap. Middle pieces stay where they are. The renderer then moves the scissor or widens it.Stacked on #1 (the FUComplete build), so its base is that branch.
Related issues
Replaces #2.
Validation
python3 profiles/mhfu/tests/android_packaging_tests.py(7 pass). Headless test build andctestpass, including the new edge cases inmhfu_settings_tests. clang-format 21.1.8 reports nothing on the changed lines.6123b48:pokeefuc-0.3.1-123-g6123b48-android-arm64.apk, with 300 overlay libraries, arm64-v8a and Android 10+. The signature verifies, it contains no game files, and every import exists on Android 29. An earlier build from this branch ran FUComplete on the owner's phone.Not verified
item_sets.cpp:555,vertex_cache_tests.cpp:73,vertex_hold.hpp:94).Checklist
Generated by Claude Code