No description
  • Shell 82.8%
  • Python 17.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Benjamin Collins ec4f6f030d Linux: record that the AppImage build is now verified end-to-end
The previous commit fixed the icon step but could only verify the icon logic
in isolation — it was written on macOS, which can't run ldd bundling,
appimagetool, or a Linux PPSSPPSDL. That gap is now closed.

Ran on Ubuntu 24.04 x86_64 (16 cores): build-ppsspp-sdl.sh links PPSSPPSDL
clean at 1059/1059, and build-appimage.sh completes with exit 0 — the run
that previously died at the missing-icon cp. Output is a 1.4 GB
PSP2i-x86_64.AppImage.

The ImageMagick 6 `convert` branch is what actually ran there (that box has
convert but not magick), so all three icon paths have now been exercised on
a platform that has them: magick and ffmpeg on macOS, convert on Linux. Each
produces the same correct 256x256 padded icon.

Launched headless under xvfb-run, the AppImage self-mounts, boots the bundled
game data from inside the mount, survives a 60s run without crashing,
isolates its memstick under the test HOME, seeds NPJH50332.ini, and logs zero
occurrences of the extracted-ISO warning.

No download happened: appimagetool was already cached at /tmp/appimagetool,
so the script's wget fallback never fired.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-28 00:55:00 -05:00
gamedata/psp2i-en macOS: self-contained PSP2i.app, and silence the extracted-ISO boot warning 2026-07-28 00:32:11 -05:00
packaging Linux: record that the AppImage build is now verified end-to-end 2026-07-28 00:55:00 -05:00
ppsspp@4309d222c9 Bump ppsspp submodule to official-cheatset build 2026-07-27 15:29:21 -05:00
scripts Bump ppsspp submodule to offline-assets build; add build-android.sh 2026-07-27 12:43:10 -05:00
tools Add eboot_cheat_bake.py — static CWCheat -> EBOOT patcher (decomp rung 1) 2026-07-27 16:43:16 -05:00
.gitignore Linux: generate the AppImage icon instead of copying a file that never existed 2026-07-28 00:43:21 -05:00
.gitmodules Add PPSSPP fork as submodule at ppsspp/ (branch psp2i) 2026-07-27 03:34:27 -05:00
README.md docs: state standalone objectives, output priority, and Forgejo/asset policy 2026-07-27 02:49:35 -05:00

psp2i-standalone — Phantasy Star Portable 2 Infinity, natively

Turning Phantasy Star Portable 2 Infinity (PSP, 2011) into a native executable that runs without an ISO or an emulator — and, along the way, building enough understanding of the engine to retool it.


Objectives (in priority order)

The point of this repo is a standalone PSP2i — the game running on its own, with no ISO and no emulator to launch. Everything else is in service of that.

  1. Android APK that boots straight into PSP2i. The highest-value output: a single installable that opens directly to the game, nothing else in front of it.
  2. Desktop builds — Windows, Linux, and macOS. Also genuinely valuable. Same native runtime, different shells around it.
  3. Decompilation — a later aspiration, not a prerequisite. Once the game runs standalone, the goal is to start decompiling it to learn how it works, get some form of source into version control, and from there make changes and recompile. This is a follow-on to a working standalone build, not a blocker for it (see "static recompilation" below for why that ordering is cheap).

Honest framing: this one is for love, not leverage

The other two repos (psz-re, psz-melonmix) exist to unblock psz-godot. This one does not. It contributes nothing to the Phantasy Star Zero remake and should not be prioritised as if it did.

What it is: the best-isolated project of the three. Self-contained C/C++, no dependency on anyone's taste, and an unusually strong automated oracle (see below). It is well suited to running unattended in the background while attention is elsewhere.

Prioritise accordingly. Nothing here is urgent.


Approach: static recompilation, not decompilation

The original plan was "decompile PSP2i, then slowly work back and retool it." There is a much cheaper path.

sal063/PSP-recompilation-project demonstrates static recompilation of PSP titles: rather than recovering human-readable C that a person maintains, it mechanically translates the game's MIPS machine code into C, then links that against a native runtime. Its pipeline is:

  1. Relocate the PRX/ELF to its target virtual base address
  2. Map library imports to HLE (high-level emulation) functions
  3. Generate C from MIPS instructions
  4. Compile against a native runtime — custom scheduler, HLE kernel, audio/video decoders, and an SDL3 + Vulkan renderer written from scratch

The difference in cost is enormous. Decompilation requires a human to understand every function before it can be rewritten. Static recompilation requires understanding only the boundaries — the syscall/library surface — and gets a running native binary immediately, with fidelity improving as HLE coverage improves.

That inverts the schedule. You get a native, playable, hackable binary early, and decompile selectively afterwards, only where you actually want to change behaviour. Retooling the game — the actual goal — never required a complete decomp.

Note the licensing consequence: that project is GPL-2.0-or-later because it reuses PPSSPP code (sceMpeg runtime, system fonts). Any fork or derivation inherits that. Plan for it rather than discovering it late.


Existing work — do not duplicate

Several repos already exist in this space. Read this table before starting anything.

Repo / path What it is State
kion/psp2i-android (Forgejo, private) Umbrella: PSP2i English Android recompile — PPSSPP fork, unpacker, tools, 6.7 GB game data via LFS The most advanced artefact
kion-dgl/psp2i-decomp Decompilation project scaffold; has a ppsspp/ dir and an "APK with bundled gamedata" commit 2 commits, early
dashgl/psp2i Browser model/animation viewer (JS) — bones, skinning, weapons Working, unrelated to the native goal
~/projects/psp-decompile/from-231/ Local working tree: ISOs, extracted/, fpb-extracted/, ppsspp-src/, Ghidra projects Where the data actually is
Agrathejagged/tenora-works PSU-family format library — FPB extractor, NBL/AFS/XNR/GIM/UVR parsers, MissionBuilder Reference implementation; check before writing any parser

Asset extraction is already done. FPB contents are extracted for all seven game versions (PSP1 JP/US, PSP2 JP/US, PSP2i JP/JP-demo/EN) — 2,523 to 4,941 files each. extract_fpb.py is a working Python port of the FPB extractor. XNJ → glTF conversion works end-to-end (NblDumpRebaseFile(0)XnjToGlb; the rebase step is mandatory and its omission was a previous blocker).

This repo's job is the native runtime, not re-extracting assets.


How an agent verifies its own work

The strongest oracle of the three repos, because PPSSPP ships a headless mode built for exactly this.

ppsspp-headless supports --graphics=software, --timeout, --compare, --screenshot, and --bench. That gives a genuine reference implementation to diff against:

  1. Reference capture. Run PPSSPP headless on the original ISO with a fixed input script; capture screenshots at fixed frames. This is ground truth.
  2. Differential testing. Run the same script against our native build. Compare frames. Divergence localises the bug to a specific frame, and usually to a specific unimplemented syscall.
  3. Boot progression. Track how far the native build gets before it diverges or crashes — a single monotonic number that measures real progress and cannot be argued with.
  4. HLE coverage. Count implemented vs. referenced library imports. Also monotonic, also machine-checkable.
  5. It builds and runs. CI, every commit.

Both (3) and (4) make good README badges and good agent objectives: "raise the boot-progression frame count" is unambiguous work.


Work breakdown

Phase 0 — consolidate

  • Inventory psp2i-android, psp2i-decomp, and from-231/ and write docs/inventory.md — what exists, what works, what is dead
  • Decide the base: fork PSP-recompilation-project, or build the recompiler fresh using it as reference. Record the decision and why.
  • Confirm the GPL position given PPSSPP-derived code
  • Stand up CI: build + headless smoke test

Phase 1 — reference harness

  • Scripted input playback against PPSSPP headless on the original ISO
  • Capture reference screenshots at fixed frames; commit hashes, not images
  • Frame-comparison harness reusable by the native build

Phase 2 — recompiler

  • Load and relocate PSP2i's EBOOT.BIN to its virtual base
  • Enumerate library imports; emit the HLE surface that must be implemented
  • MIPS → C translation for the main executable
  • Minimal native runtime: scheduler, memory map, HLE kernel stubs
  • First boot attempt; record the boot-progression number
  • Iterate HLE coverage, raising boot progression each time

Phase 3 — presentation

  • Renderer (SDL3 + Vulkan, per the reference project's approach)
  • Audio
  • Input / gamepad
  • Android target — the existing psp2i-android work is the head start here

Phase 4 — retooling (the actual goal)

  • Selectively decompile systems worth changing
  • Asset replacement pipeline
  • Network protocol reimplementation for multiplayer

Status

Not started as a native-recompilation effort. Substantial prerequisite work (asset extraction, format parsing, Android packaging) already exists in the repos listed above.

Why this lives on Forgejo (and why assets go in-tree)

This repo is hosted on the local Forgejo server, not GitHub, on purpose: so the game assets can be committed directly into the repo. Keeping the ISO, EBOOT, and extracted data in-tree makes the project trivial to clone and build with no side-channel asset fetch — ease of use, on a private server, over legal caution. That convenience is the whole reason for not using GitHub.

A public GitHub mirror can be published later, using .gitignore to strip the copyrighted game data. Treat the committed .gitignore as the GitHub-publish filter — the rules for what a public mirror omits — not as the policy for this Forgejo repo, where committing assets is the intent. (Note: as written, .gitignore still ignores extracted/, EBOOT.BIN, and ISOs, so adding assets here will need an explicit git add -f or a loosened ignore list.)


This is a private Forgejo repo and may contain committed game data (ISO / EBOOT / extracted assets) for convenience; it is not published. Any public mirror must strip that data via .gitignore, and contributors to a public fork supply their own legally obtained copy. Expect GPL-2.0-or-later if PPSSPP-derived code is used.