Skip to content

Releases

v1.0.0-beta.9 — visible failures, verified patches, versioned archives

Choose a tag to compare

@springah springah released this 26 Jul 02:15

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)

Choose a tag to compare

@springah springah released this 26 Jul 00:51

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

v1.0.0-beta.7 Pre-release
Pre-release

Choose a tag to compare

@springah springah released this 22 Jul 21:44

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_scale now 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.75 remains available for GPU-bound devices.
  • gl_threaded now 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_filter config key (linear/nearest) for the upscale filter when render_scale < 1. Env override CT_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

Choose a tag to compare

@springah springah released this 19 Jul 05:27

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)

Choose a tag to compare

@springah springah released this 13 Jul 09:39

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_scale in config.txt (1 = native/off) or the CT_RENDER_SCALE environment 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=1 to trace file access rates in log.txt; CT_IOBUF_KB tunes 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

Choose a tag to compare

@springah springah released this 29 Jun 11:33

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

Pre-release

Choose a tag to compare

@springah springah released this 27 Jun 04:56

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 own resources.bin: SNES sprites, button prompts, UI colours, icons. Ships no assets. .ctp format 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

Pre-release

Choose a tag to compare

@springah springah released this 26 Jun 12:14

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.so
  • lib/arm64-v8a/libc++_shared.so
  • the entire assets/ folder

Install

  1. Extract ct_pm.zip into your ports folder (/roms/ports/ or /userdata/roms/ports/ depending on your CFW).
  2. Copy the three items above from your APK into ports/ct/, so you end up with:
    • ports/ct/libchrono.so
    • ports/ct/libc++_shared.so
    • ports/ct/assets/ (with resources.bin, the .dat cutscenes, etc.)
  3. 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,opacity
  • CT_FONT_SCALE — UI font size (default 1.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! 🐸