Commit Graph
15 Commits
Author SHA1 Message Date
megboyzzandClaude 725ffbd8ed arm64: flat guest mapping, audio, crash reporting, self-extracting data
The run of work that took the translated build from "boots" to "playable".

Engine:
- Flat guest mapping replaces the software MMU on aarch64 hosts. A 4 GiB
  PROT_NONE reservation lets a 32-bit guest address zero-extend safely, so
  tcg_out_qemu_ld/st short-circuit before tcg_out_tlb_read and the prologue
  materialises the base into X28. Measured 1.24x (51 vs 41 fps, interleaved
  A/B). Note the base must be set BEFORE UC_INIT - Unicorn inits lazily, and
  setting it after uc_open silently falls back to softmmu.
- num_get<char> facet implemented, which was the real cause of the crash after
  the prologue race; a full race is now playable end to end.
- Thread-stack free list + ReleaseThreadEngine, fixing the arena leak that
  showed up as a black screen when entering a race. kMaxGuestThreads 16 -> 64.
- Real ARM32 FMOD now runs in-engine via the Java FMODAudioDevice bridge, with
  a per-thread JNIEnv. Two of the three blockers were our own single-image-era
  guards.

Host/app:
- Native crash handler: async-signal-safe, decodes the host fault back to a
  guest address, writes a report file and nothing else. CrashReportActivity
  picks it up on the NEXT launch, zips it, and offers to share. No backend, no
  automatic upload.
- Game data ships inside the APK and self-extracts on first launch, so a tester
  installs one file and plays. Copy-to-.part-then-rename, with a free-space
  check up front.
- EGL context preserved across pause, fixing black textures on resume.
- Navigation bar hidden and re-hidden on focus gain; volume keys reported as
  system keys, checked before the loading-state gate.
- x86_64 added to abiFilters: the ARM32 guest runs under tcg/i386 with no
  houdini in the path. The flat mapping is aarch64-only, so that host falls
  back to the software MMU - commented at the abiFilters line.

Ignore rules added for app/translated/ (611 MB of signed release APK, which
also carries the bundled OBB) and ostream_repro/build/.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-22 23:17:47 +03:00
megboyzzandClaude 75270898e9 Stop double-presenting every frame (task #47)
The engine synthesized an eglSwapBuffers on each detected frame boundary.
That duplicated the present Android's GLSurfaceView already performs after
every onDrawFrame return, so every frame reached the screen twice - the
second time from a buffer still holding the PREVIOUS frame.

The whole mechanism rested on a premise recorded 2026-09-18 and never
verified live: that nativeOnResume runs the guest's persistent loop on the
GLThread and never returns, leaving the framework unable to present. An
entry/exit counter added to GameRenderer.onDrawFrame shows that is false -
it returns every frame (entries=698 exits=697, the gap being the call in
flight). Rates match 1:1:

    synthetic swaps  12.98/s   (SWAPMARK, one line per swap)
    onDrawFrame      12.69/s   (so the framework swapped 12.69/s too)

The user saw this as the car jumping forward then back along its path.
Frame-by-frame the race clock stepped 1:10.06 -> 1:10.03 -> 1:10.09 ->
1:10.06, with presents arriving in pairs 10-20ms apart at a 218ms period -
exactly the synthetic swap period.

Letting the framework present is also what the real game does: libapp.so
cannot present at all (only EGL import is eglGetProcAddress; the string
"eglSwapBuffers" is absent from the binary), and on the A9 all 2,736
eglSwapBuffers calls in 46s came from Android's own framework.

Measured after, on the Pixel 6a:

    frame interval median  89ms -> 17ms
                   p90    217ms -> 19ms
                   max    316ms -> 24ms
    synthetic swaps          0 (verified, not merely absent from view)
    onDrawFrame      12.69 -> 12.39/s (throughput deliberately unchanged)

User verdict: "Сейчас очень плавно". Throughput is untouched - this fixes
presentation, not the ~7x simulation deficit.

Kept behind kSynthesizeSwap rather than deleted: the 2026-09-18 symptom it
was built for (screen cycling between stale loading screen, black, and the
real scene) was diagnosed under the false premise above, so its actual
cause is still open.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-19 15:25:37 +03:00
megboyzzandClaude d5e6037fc7 Stable checkpoint: game reaches playable 3D gameplay on ARM64
Verified live on a Pixel 6a: the game passes its EULA, loads the prologue
and renders real 3D gameplay, with zero heap exhaustion, zero faults and
zero rejected frees over a full session.

Root causes fixed in this state, each backed by a measurement (details and
the list of refuted theories live in ARM64_TRANSLATION_LAYER.md):

* JNI varargs float->double promotion. C promotes float to double in any
  varargs call and every Call*Method form is varargs, so reading one 4-byte
  slot yielded the double's always-zero low half. EVERY float argument
  passed to Java was silently becoming 0; text was just where it showed.

* GuestHeap ~4x memory overhead. Power-of-two size classes carving the full
  class, plus segregated free lists that could never share memory between
  sizes. Reworked to exact sizing with O(log n) best-fit reuse and splitting
  (deliberately not a linear scan - this allocator already had an O(n) perf
  cliff in its history). Peak live now 207MB against the real A9's 199MB,
  fragmentation ~2.5MB. Also fixed: realloc reading past the old block on
  shrink, a 32-bit overflow in calloc, and drifting payload alignment.

* Unbounded FMOD fake-handle leak into the never-freeing permanent arena,
  which is why enlarging that arena had not helped.

* Frame presentation, corrected against A9 ground truth: the real frame has
  three default-framebuffer colour clears and ONE present at the end; this
  engine had been presenting on each of them.

Load-time acceleration (zlib_accel.cpp): host zlib now serves inflate and
crc32, the latter measured by the block profiler as the single hottest guest
routine at 17.7%. Streams are only taken over when this layer saw their own
inflateInit2_, so unknown streams (libpng's, among others) still run the
original emulated path.

name_lookup_accel.cpp is present but its hook is NOT registered - it crashed
on bad assumptions about guest table lifetime and is kept as a starting
point, with both mistakes recorded in its comments.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-19 02:12:03 +03:00
megboyzzandClaude Sonnet 5 cde392870e Add LAN car_select flow: real event handling, GameEvents JNI bridge, live car/upgrade/color capture, Compose UI example
Fixes the synthetic car_select jump for cold sessions, makes the loadout
exit chain safe for real (non-synthetic) events, and adds a native->Kotlin
GameEvents bridge (onMapLoaded/onRaceStarted/onRaceEnded/onUpgradesAccepted/
onCarSelected) so both the UI layer and a future native RatNet client can
learn what the player picked - car id, accepted upgrades, and paint color
(name + RGBA) are all resolved live from the game's own engine state
rather than a static extracted table, so they stay correct for any car
added later. Includes a Jetpack Compose overlay as a worked example of a
UI-side GameEventListener consumer.

Full investigation history, root causes, and the several dead ends ruled
out along the way are documented in PROGRESS.md (cont. 30-63b).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 15:30:21 +03:00
megboyzz 1cd5547b04 Начало savemanager 2025-09-05 18:38:01 +03:00
megboyzz 8c0276c562 Более менее стабильная версия 2025-08-28 12:49:40 +03:00
megboyzz 3cc802a9ea Rename .java to .kt 2025-08-28 12:49:40 +03:00
megboyzz 8951489609 Отключил х86 исправил ипут на Waydroid 2025-08-26 12:22:46 +03:00
megboyzz 38665f3545 Удаление лишних комментариев /* loaded from: classes.dex */ 2025-08-22 20:33:43 +03:00
megboyzz 6dd4612a88 Добавил mpcore 2025-04-06 20:23:24 +03:00
megboyzz ea29c5a3fc Вырезание ресурсов 2025-03-31 21:50:19 +03:00
megboyzz 3b16cf38db Рабочий первый рабочий коммит 2025-03-31 21:19:55 +03:00
megboyzz 4b7a924752 Перенос с маленькими правками 2025-03-30 18:08:41 +03:00
megboyzz 0134f6d689 Перенос с маленькими правками 2025-03-30 18:07:34 +03:00
megboyzz 72f40cc560 Начало репака 128 версии 2025-03-30 15:14:17 +03:00