This repository contains a loader of the Android release of Zenonia 3,
based on the Android SO Loader by TheFloW. The loader provides
a tailored, minimalistic Android-like environment to run the official ARMv6
game executable on the PS Vita.
Disclaimer
ZENONIA 3 is a registered trademark of Gamevil. The work
presented in this repository is not "official" or produced or sanctioned by
the owner(s) of the aforementioned trademark or any other registered trademark
mentioned in this repository.
This software does not contain the original code, executables, assets, or
other non-redistributable parts of the original game product. The authors of
this work do not promote or condone piracy in any way. To launch and play
the game on their PS Vita device, users must possess their own legally obtained
copy of the game in form of an .apk file.
Setup Instructions (For Players)
In order to properly install the game, you'll have to follow these steps
precisely:
(Recommended) Make sure that you are either on 3.60 enso or 3.65 enso firmware
version. Other versions may work too, but no support are provided for them! If
you experience any issues apart from described in the
<a href="#known-issues">Known Issues</a> section, please upgrade or downgrade
your firmware before asking for support.
Install or update kubridge and FdFix by copying
kubridge.skprx and fd_fix.skprx to your taiHEN plugins folder
(usually ) and adding two entries to your under :
Make sure you have libshacccg.suprx in the ur0:/data/ folder on your
console. If you don't, use ShaRKBR33D to get it quickly and easily.
<u>Legally</u> obtain your copy of Zenonia 3 in a form
of an .apk file. The only supported version is 1.0.2 — other versions
ship a different libgameDSO.so (different code/offsets) and will crash:
| Field | Value |
|-----------------|----------------------------------------------|
| Version name | 1.0.2 (versionCode 102) |
| Package | com.gamevil.zenonia3.global.multilingual |
| APK SHA-1 | 09c3994cbb89fa7bd7db3d3b27e53b8079396520 |
| libgameDSO.so SHA-1 | 97cf9cd00fed65e5cb424a3f474ce8a884b098b3 |
You can verify the version inside the APK's AndroidManifest.xml
(android:versionName="1.0.2") or by comparing the SHA-1 of
lib/armeabi/libgameDSO.so with the one above.
Once set up and run on the console, the file structure in ux0:data/zenonia3/ will look like this (as seen in VitaShell):
ux0:data/zenonia3/
├── assets/ # Game assets and data (extracted from APK assets/)
├── drawable/ # UI images and drawables (extracted from APK res/drawable/)
├── html/ # Help / About HTML pages (extracted from APK assets/html/)
├── logs/ # Debug logs created at runtime (log_<timestamp>.txt)
├── sound/ # Game audio, sound effects, and music
├── libgameDSO.so # Original ARMv6 native binary (from APK lib/armeabi/libgameDSO.so)
├── option.sav # (Runtime) Game configuration and options save
├── Save0.dat # (Runtime) Player save file
├── _uiButton_0 # (Runtime) Touch/UI layout cache
├── _uiButton_1 # (Runtime) Touch/UI layout cache
├── _uiButton_2 # (Runtime) Touch/UI layout cache
├── _uiButton_3 # (Runtime) Touch/UI layout cache
└── _uiDpad # (Runtime) Virtual D-pad layout cache
Controls
| Button | Action |
|:-------------------:|:----------------------------------------|
| | Move Left / Right |
| | Move Up / Down |
| | Action / Attack / OK |
| | Back / Cancel / Menu |
| | Map / Quick Item |
| | Skip / Special |
| | Save |
| + | Show / Hide virtual on-screen buttons |
| + | Quit Game |
FAQ
❓ As soon as I run the app, I get "An error has occured in the following
application. (C2-12828-1)" message. What to do?<br>
❕ Most likely, it means that after updating/installing the kubridge plugin, you
didn't reboot your console. Reboot is required after any modifications in kernel
plugins.
Another possibility is that you are using some conflicting or too heavy plugins
and kubridge can not run correctly. Try disabling everything but the most
necessary kernel plugins, reboot, and try again.
❓ The game crashes on boot / right after the logo, but my plugins are fine
and other Android ports work.<br>
❕ Almost always a wrong game version. Only Zenonia 3 v1.0.2 is supported —
check the libgameDSO.so SHA-1 listed in the
<a href="#setup-instructions-for-players">Setup Instructions</a>. Also make sure
ux0:data/zenonia3/ does not contain leftover files from another version
(especially sound/ and assets/).
❓ Any other question?<br>
❕ Check the following "Known Issues" section. If nothing there looks like the
problem you're having, please post a new issue, and I'll try my best
to help you.
Known Issues
Invisible Text: In-game text and UI text are currently invisible. The font rendering engine (GFA stubs) requires a custom bitmap/TrueType implementation that is still pending.
Menu I/O Load: The menu re-reads certain assets (like Title.pzx) from the disk continuously on input events, which might cause slight loading delays.
Build Instructions (For Developers)
In order to build the loader, you'll need a vitasdk
build fully compiled with softfp usage. The easiest way to obtain one is
following the instructions on https://vitasdk.org/ while replacing the URL in
this command:
git clone https://github.com/vitasdk/vdpm
Like this:
git clone https://github.com/vitasdk-softfp/vdpm
All the required libraries should get installed automatically if you follow the
installation process from https://vitasdk.org/.
After all these requirements are met, fetch the vendored vitaGL/vitaShaRK submodules once
(built from source with this project's own flags/versions instead of the vitasdk-wide ones):
git submodule update --init
Then compile the loader with the following commands:
cmake -Bbuild .
cmake --build build
Also note that this CMakeLists has two "convenience targets". While developing,
I highly recommed using them, like this:
cmake --build build --target send # Build, upload eboot.bin and run (requires vitacompanion)
cmake --build build --target dump # Fetch latest coredump and parse
For more information and build options, read the CMakeLists.txt.
Performance Tuning (For Developers)
The game's software framebuffer upload (RGB565 → the GPU, several times per frame) and the
Q16.16 fixed-point vertex/color/texcoord conversion are the two hottest per-frame paths in the
loader, and can each be built with a different strategy for A/B testing on real hardware. These
are exposed as CMake options (see CMakeLists.txt for the full rationale of each):
RGB565_CONVERT_MODE (SCALAR | LUT | NEON | NATIVE) — how the 400×240 software
framebuffer gets from RGB565 to the GPU. SCALAR is the original per-pixel integer-division
conversion; LUT is a precomputed-table version of the exact same math; NEON is a SIMD
bit-replication version (≈1 LSB different from SCALAR/LUT, imperceptible); NATIVE skips
the CPU conversion entirely and uploads the RGB565 data straight to the GPU, which reads it
natively.
OPTIMIZE_NEON_FIXED (ON/OFF) — NEON SIMD instead of a scalar loop for the Q16.16 →
float vertex/color/texcoord conversion. Independent of RGB565_CONVERT_MODE above.
LOCK_FPS_30 (ON/OFF) — caps the framerate at a stable 30fps (2 vblanks per frame,
vitaGL's own vsync disabled in favor of a manual sceDisplayWaitVblankStartMulti(2)) instead of
vitaGL's default single-vblank vsync. Fixes a ~40-60fps jitter that otherwise shows up whenever
the frame renders fast enough to land right on the vblank boundary — most notably with
RGB565_CONVERT_MODE=NATIVE.
porting_tools/build/build_and_install.sh (option 5 of manage_vita.py) asks for all three
interactively and tags the exported VPK with the chosen combination
(e.g. zenonia_3_NATIVE_neonfixed-OFF_fps30-ON.vpk), so multiple builds can be installed and
compared side by side without overwriting each other.
Confirmed on real hardware as the most stable combination:RGB565_CONVERT_MODE=NATIVE +
OPTIMIZE_NEON_FIXED=OFF + LOCK_FPS_30=ON — native RGB565 texture upload (no CPU conversion),
scalar Q16.16 conversion, and the manual 30fps cap. These are now the defaults in
CMakeLists.txt, so a plain ./build.sh run already produces
build/zenonia_3.vpk in this configuration — it's the definitive release build. Use
porting_tools/build/build_and_install.sh (option 5 of manage_vita.py) instead if you want to
override any of the three and compare a differently-tagged VPK side by side.