Repository navigation
Releases
v1.0.0-beta.9 — visible failures, verified patches, versioned archives
First release of the 1.0 preparation work. Nothing here changes how the game plays — it
changes what happens when something goes wrong, and what you get in the box.
You can now see what went wrong
The port ships no game data by design, so the missing-files screen is the first thing most
people ever see — and it was printing to a place the frontend swallows, which meant a blank
screen for fifteen seconds and no explanation. It now draws a real on-screen dialog telling
you exactly which files are missing and where to put them.
If the game crashes, you get a dialog pointing at log.txt instead of being dropped back to
the menu in silence. And log.txt now opens with the build it came from, so a bug report
can be tied to a specific binary.
The archive says what it is
Release archives now carry their version in the filename (ct-1.0.0-beta.9.zip), so a
downloaded file can be identified without opening it.
The archive also finally contains the screenshot and gameinfo.xml that its own metadata
had been referencing all along — previously both were silently omitted, so the port showed
up in the Ports list with no art. Packaging now fails loudly rather than quietly shipping
without them. The screenshot is a real gameplay frame.
Safety: the runtime patches verify themselves
The port applies a small number of instruction-level patches to the game engine, all gated
on a fingerprint check that confirms it is the supported v2.1.5 library. Two gaps closed:
Ten of those patches were writing without checking what they were overwriting. They were
marked as targeting zero-filled padding, and that region is not padding — it is dead code.
They now verify the exact instruction they expect, and skip themselves if it isn't there.
Separately, the warnings this checking produces did not exist in release builds at all — the
logging call they used compiles to nothing outside debug builds. A skipped patch now says so
in log.txt.
Documentation
The README now explains how to install the port, and how to quit it. Start + Select
quits the game; there is no in-game exit, and the alternative — powering the device off
mid-game — is the thing most likely to cost you a save. That was previously documented
nowhere.
The supported-system list has been narrowed to what has actually been tested. All testing to
date is on Knulli, on a TrimUI Smart Pro and two Anbernic devices. Other PortMaster systems
are expected to work but are untested; that is now stated rather than implied.
This archive contains no game data. You supply libchrono.so, libc++_shared.so and
assets/ from your own legally-owned Chrono Trigger Android APK (v2.1.5) — an APK is a ZIP,
so you can rename and open it. See the README for the walkthrough.
v1.0.0-beta.8 — sharper pixel art (force_nearest)
Sharper pixel art, a safety fix to the language patch, and a documentation pass.
Crisper art — force_nearest, on by default
The port previously had render_filter, but that only ever affected its own final upscale
blit. The softness you actually saw came from the engine sampling its own textures
bilinearly at a fractional zoom.
force_nearest rewrites every texture filter the engine sets to NEAREST, and stamps it at
texture creation. It is enforced at the GL boundary rather than by patching the game's
texture-creation sites, because that alone is provably not enough: GL's default magnification
filter is GL_LINEAR, so any texture created outside those paths samples linear regardless,
and runtime setAntiAliasTexParameters calls can turn it back on afterwards. The wrapper is
registered on all three resolution paths, so nothing escapes it.
On by default after an on-device A/B. Set force_nearest 0 in config.txt for the older,
softer bilinear look — at 1 the pixel art is crisp, but deliberately-softened stretched
backgrounds go blocky. It is a taste call, so the switch is there.
Safety — the language patch is now version-gated
The two writes that force the UI language (getCurrentLanguage and
getLocalizeResourcePath) are as build-specific as anything else the port patches, but they
were going in blind: no check of the existing instruction, and outside the v2.1.5 fingerprint
gate that the surrounding code already used. A libchrono.so that was not v2.1.5 but still
exported those two symbols would have taken two silent code-corrupting writes — exactly what
the fingerprint check exists to prevent.
They now go through the same verified path as the other runtime patches, so a mismatch skips
the site instead of overwriting it, and the startup warning names the language override among
the fixes that get disabled on an unrecognised library.
Documentation
A pass over claims that had drifted from the code: the Linux backend was still described as a
skeleton with input and env unimplemented (both have been complete for a while); a
fully-executed bring-up plan was still written as a to-do list; CT_LOG and the other
diagnostic environment variables were undocumented; CT_FONT_SCALE's stated default was the
launcher's rather than the binary's; and language auto-detect reads LC_ALL, then
LC_MESSAGES, then LANG, not just LANG.
LICENSE now carries its own copyright line and scope-carves the CC BY-NC-SA font and the
LGPL FFmpeg libraries, so the tree is no longer blanket-labelled MIT. The Multiverse
submission notes were rewritten against the current repo, since the one they described has
been archived.
Also corrected: the engine's 16:9 design resolution is 568×320, not the 640×360 stated
before, so 720p is roughly a 2.25× scale rather than an exact 2×.
This archive contains no game data. You supply libchrono.so, libc++_shared.so and
assets/ from your own legally-owned Chrono Trigger Android APK (v2.1.5). See the README.
v1.0.0-beta.7
Highlights
Shader binary cache (shader_cache, on by default) — the engine recreates its GL programs from the same sources on every scene change, paying a driver compile+link stall at each scene entry. The loader now caches the driver's compiled program binaries on disk (shadercache/) and serves relinks from there, so after the first visit everything loads pre-compiled. Verified on PowerVR GE8300 (TrimUI) and Mali-G31 (Anbernic H700); self-disables on drivers without GL_OES_get_program_binary.
Retuned defaults (from on-device testing)
render_scalenow defaults to 1 (native) — the engine's 640×360 design space maps cleanly onto 16:9 panels (720p is an exact 2×), and with the shader cache the scene-entry hitches that lower resolutions were masking are gone.0.75remains available for GPU-bound devices.gl_threadednow defaults to 0 — mesa's glthread is a no-op on blob drivers and measurably adds input latency on panfrost/Mali devices.
Also
- New
render_filterconfig key (linear/nearest) for the upscale filter whenrender_scale< 1. Env overrideCT_RENDER_FILTER. - README: documented the new keys and defaults.
As always the zip contains no game data — you supply libchrono.so, libc++_shared.so and assets/ from your own Chrono Trigger v2.1.5 APK.
v1.0.0-beta.6 — ct_nx sync: runtime patches, correctness, input remap
A large sync from the sibling ct_nx (Switch) fork — runtime engine patches, correctness/quality fixes, and configurable input. Verified on-device (TrimUI, canonical CT Android v2.1.5 libchrono).
Runtime engine patches
On by default; each write is verified against the expected instruction and only applied on the supported v2.1.5 libchrono (a different build safely skips them). Disable any one in config.txt (set 0).
- cursor_fix — white-on-dark menu selection instead of the mobile cream colour-invert.
- remove_mobile_ui — hide the on-screen touch overlays (field/world-map/title buttons, per-menu back/close, race + colour prompts); movement defaults to Walk.
- controller_glyphs —
<BTN_*>button-prompt glyphs. - fix_diagonal_movement — smooth the field diagonal-movement stutter.
Correctness / quality
- Fix the in-game TIME clock saving as 99:59 under some fullscreen setups (the window can start focused).
- FMV: drain the H.264 decoder at clip end — the fade-to-black tail is no longer cut.
- mesa/GLES tuning:
mesa_glthread+MESA_NO_ERROR+ a 16-bit depth buffer (gl_threaded/gl_no_error, both on by default). - language
default: auto-detect the UI language from the system$LANG(regional variants collapse; English fallback).
Input
- Remap ZL / ZR / Start / Select via
config.txt(key_zl/key_zr/key_start/key_select→a b x y l r zl zr start select menu none). - right_stick_mirror toggle.
You supply your own Chrono Trigger Android v2.1.5 libchrono.so / libc++_shared.so / assets/ — never shipped. See the README.
v1.0.0-beta.4 — reduced-resolution rendering (performance)
Changes
- Big performance win on GPU-bound handhelds — the game now renders at a reduced internal resolution (default 0.75× ≈ 960×540 on a 720p panel, 44% fewer pixels per frame) and is upscaled to the panel in a single filtered pass. Heavy field/battle scenes run markedly smoother on devices like the TrimUI Smart Pro. FMV cutscenes and the name-entry keyboard still render at full panel resolution. Tune or disable with
render_scaleinconfig.txt(1 = native/off) or theCT_RENDER_SCALEenvironment variable. - Faster scene loads — the engine reopens its resource archive for nearly every file access; those reopens are now served from a small stream pool (a boot went from 168 opens to 2).
- I/O diagnostics — set
CT_IOLOG=1to trace file access rates inlog.txt;CT_IOBUF_KBtunes the archive read buffer.
Install the ct_pm.zip into your device's ports/ via PortMaster (or unzip into /roms/ports/). You supply libchrono.so / libc++_shared.so / assets from your own Chrono Trigger v2.1.5 APK — no copyrighted game data is shipped.
v1.0.0-beta.3 — right-stick mirror + timed-wait fix
Changes
- Right analog stick now mirrors the left — either stick moves the character (the right stick previously did nothing).
- Internal timed-wait fix — translate newlib's ETIMEDOUT to bionic's so a condition-variable timeout can't terminate the engine (no-op on glibc, shared with the Switch build).
Install the ct_pm.zip into your device's ports/ via PortMaster (or unzip into /roms/ports/). You supply libchrono.so / libc++_shared.so / assets from your own Chrono Trigger v2.1.5 APK — no copyrighted game data is shipped.
v1.0.0-beta.2 — pixel-art mod support
ct_pm beta.2. Changes over beta.1:
- Optional pixel-art mod support (
tools/pixeldemaster/) — re-skin Chrono Trigger with Pixel Demaster (by Shiryu) by repacking your ownresources.bin: SNES sprites, button prompts, UI colours, icons. Ships no assets..ctpformat via River Nyxx's CT_Explore. - Glyph-cache text perf fix — text rendering now caches per-glyph, so dialogue forming while you move no longer hitches (the binary differs from beta.1 for this).
- README + credits.
You supply the game: your own legally-owned Chrono Trigger v2.1.5 Android APK (libchrono.so + libc++_shared.so + assets/). See the README.
v1.0.0-beta.1 — first public beta
First public beta of the Chrono Trigger PortMaster port (aarch64 Linux handhelds). Plays end-to-end — boot, saving, FMV cutscenes — with a SNES-style text drop-shadow, quiet logging, and SD-card-friendly writes.
⚠️ You must supply your own game files
None are included. From your own legally-owned Chrono Trigger Android APK (v2.1.5) you need:
lib/arm64-v8a/libchrono.solib/arm64-v8a/libc++_shared.so- the entire
assets/folder
Install
- Extract
ct_pm.zipinto your ports folder (/roms/ports/or/userdata/roms/ports/depending on your CFW). - Copy the three items above from your APK into
ports/ct/, so you end up with:ports/ct/libchrono.soports/ct/libc++_shared.soports/ct/assets/(withresources.bin, the.datcutscenes, etc.)
- Launch Chrono Trigger from PortMaster. (The launcher tells you if any game files are missing.)
Tested
✅ Knulli on TrimUI Smart Pro, Anbernic RG40XX-V, Anbernic RG35XX-SP.
❓ Other CFW untested — testers wanted! AmberELEC / ArkOS / ROCKNIX / muOS — please report how it goes on your device.
Knobs (optional, in Chrono Trigger.sh)
CT_TEXT_SHADOW— text drop-shadow:1,1,0.7(default) ·off·auto·dx,dy,opacityCT_FONT_SCALE— UI font size (default1.5)CT_LOG=1— re-enable verbose logging for bug reports
Known (beta)
- No store screenshot yet (cosmetic — PortMaster shows a placeholder).
- Not yet in the PortMaster / Multiverse catalog.
Reporting a bug? Include your device + CFW, what you were doing, and — if it crashed — relaunch with CT_LOG=1 and grab ports/ct/log.txt. Thanks for testing! 🐸