Kingdom Hearts: Chain of Memories (KH_COM_VITA)
Kingdom Hearts: Chain of Memories
Sobre el proyecto
Kingdom Hearts: Chain of Memories es un videojuego japonés creado exclusivamente para Game Boy Advance por Square Enix. El juego retoma la historia donde acaba Kingdom Hearts para PlayStation 2 y los primeros 50-60 días de Kingdom Hearts 358/2 Days. Su secuela inmediata es Kingdom Hearts II.
3 versiones de Kingdom Hearts: Chain of Memories
Estás viendo: Kingdom Hearts: Chain of Memories (KH_COM_VITA)
Información oficial del proyecto
KH_COM_VITA
A native PS Vita port of Kingdom Hearts: Chain of Memories (Game Boy Advance), built on top of the community decompilation of the game (Pheenoh/khcom).
The game's own C code is recompiled for the Vita's ARM CPU. The GBA hardware it talks to (video chip, DMA, interrupts, sound mixer, BIOS, save memory) is replaced by a platform layer written for the Vita. This is not an emulator: the game logic runs natively, and only the GBA's picture processor is reproduced in software.
This repository contains no game data and no decompiled game code. It only holds the Vita platform layer, the build tools, and a patch of the port's changes to the public decompilation. To build it you need your own legally dumped ROM of the game (USA; the European ROM is optional).
Status
Early and experimental (see port/vita/VERSION).
| Area | State |
|---|---|
| Boot, title screen, new game, story events, field | Working |
| Frame rate | Stable 60 fps on hardware (rendering takes ~3–6 ms per frame, split over two cores) |
| Battles | The first battle and its tutorial complete; later areas are being tested |
| Opening/ending movies (FMV) | Playing (the game's ARM decoder runs natively); Start skips a movie |
| Music and sound effects | Working: DirectSound channels and the GBA's four PSG ("Game Boy") channels |
| Saving | Working (ux0:data/khcom/khcom.sav), also written when the Vita suspends |
Features
- 16:9 widescreen, full 960x544: the scene is rendered 282 pixels wide instead of 240 (scaled x3.4), so it
fills the Vita's screen and shows more of the stage. The game keeps only a 240-pixel window of each
scrolling map in video memory, so the extra columns are drawn straight from the game's full map: the
scenery really continues past the original edges, and sprites stay visible there.
fit(original 3:2 with side bars) andstretchmodes are also available. - USA and European ROMs (the European one has English, French, German, Italian and Spanish) in the same VPK: the port detects the ROM and runs the matching version. Each version keeps its own saves.
- Port menu (Start + L + R), with five tabs (switch with L / R), saved to
config.ini:- PICTURE: Sharp pixels (every GBA pixel the same size and crisp at the 3.4x scale) and GBA colors (colours as on the GBA's screen), both on by default; Smooth edges (Scale2x, Scale3x or MMPX), off by default, applied to everything, sprites only or scenery only.
- CONTROLS: each control addition below can be turned off.
- GAME: the field HP display, the save bank, Wide menus (menus made for the GBA's screen stretched to fill 16:9 instead of showing bars) and Skip intro (start at the title menu).
- BOSSES: refight any boss of Sora's story already beaten, at its original strength or at an enemy level up to Sora's; no XP or rewards, and you return to where you were (won or lost).
- TUTORIALS: replay the two battle tutorials.
- Dialogue boxes fill the 16:9 screen once open, without distortion.
- 10 save slots: 5 banks of the game's 2 slots (
khcom.sav,khcom2.sav…khcom5.sav), switched in the menu without restarting. - Triangle = L + R together (stock a card / sleight), without pressing both shoulder buttons.
- Square = dodge roll: rolls toward the direction you are holding, or the way the character faces. On the GBA this needs a double tap on the D-pad. Works for Sora and Riku.
- Right stick for the cards: left / right = L / R (previous / next card), up = L + R (stock / sleight).
- Return the stocked cards to the hand (Sora), which the GBA version can't do: hold the rear touch pad or the right stick down (0.5–2 s, 1 s by default), or tap the rear touch pad twice; a bar under the stocked cards fills up while holding. The cards go back to their places in the deck and the cursor stays where it was.
- Moogle points notice: picking up moogle points on the field shows the amount in the bottom-right corner, then your total.
- Left analog stick works as the D-pad.
- Uses three CPU cores: game logic on core 0 and rendering on cores 1 and 2 (audio also runs on core 2).
Controls
| Vita | GBA |
|---|---|
| D-pad / left stick | D-pad |
| Cross / Circle | A / B (swap with swap_ab=1) |
| L / R | L / R |
| Triangle | L + R (stock / sleight) |
| Square | Dodge roll |
| Right stick | Left / right: L / R; up: L + R; down held: unstock the cards |
| Rear touch pad, held or tapped twice | Unstock the cards |
| Start / Select | Start / Select |
| Start + L + R | Port menu |
Installing on the Vita
libshacccg.suprxis required (the Vita's shader compiler, used by vitaGL). Extract it on your own console following this guide; it must end up atur0:data/libshacccg.suprx. It is Sony software and is not distributed here.- Copy the built
khcom_vX.XX.XX.vpkto the Vita (e.g. with VitaShell over FTP/USB) and install it. - Recommended: the kubridge kernel plugin
(
ur0:tai/kubridge.skprxunder*KERNELinur0:tai/config.txt, then reboot). With it, the port handles the game's reads/writes through NULL pointers and raw GBA addresses the way the GBA does instead of crashing (see "How it works"). Without it the game still runs, but those spots crash. The log saysfault handler: activewhen it is in use. Use a current release: older kubridge versions lack functions the port needs, and the handler stays off with them. Ifux0:tai/config.txtexists, taiHEN reads it instead ofur0:tai/config.txt. - Copy your own ROM dump of Kingdom Hearts: Chain of Memories to
ux0:data/khcom/rom.gba(create the folder if needed; any*.gbafile in that folder with the right checksum also works). It must be the unmodified cartridge dump: USA, SHA-110729bd884f8fdca7a310b6d606c52e46657aa48, or Europe, SHA-18db73586cdb11b3795907edebf43228dbcd3e6b2.rom.gbais used first; otherwise the USA ROM wins when both are in the folder. At every launch the port checks it and loads the game's graphics, text, music and movies from it (about 1–2 s); without it a message explains where to put it. - Run it. On first launch it creates the rest of
ux0:data/khcom/:
| File | Purpose |
|---|---|
rom.gba | Your ROM dump (you copy it) |
config.ini | display=wide|fit|stretch, filter=linear|nearest, swap_ab=0|1, and the menu's choices: upscale=off|scale2x|scale3x|mmpx, upscale_target=all|sprites|scenery, touch_unstock=off|hold|double_tap|both, unstock_hold=0.5|1|1.5|2, sharp, gba_colors, square_dodge, triangle_lr, right_stick, field_hud, wide_menus=0|1|2 (bars, stretched, art), hd_text, fast_text, smooth_audio, skip_intro (0|1), save_bank=1-5 |
khcom.sav | Save data (the GBA's SRAM), save bank 1; khcom2.sav … khcom5.sav are banks 2–5. The European version uses khcom_eu.sav … khcom_eu5.sav |
log.txt | Startup trace and a status line with frame timings every second |
log_prev.txt | The previous run's log (kept when you relaunch after a crash) |
The VPK itself carries no data from the game: the ROM supplies it at startup (see "How it works").
Building
Tested on macOS (Apple Silicon). Linux works with the equivalent packages.
Requirements
- VitaSDK with vitaGL:
For the Vita3K emulator, build it withgit clone https://github.com/Rinnegatamante/vitaGL && cd vitaGL make HAVE_GLSL_SUPPORT=1 && make installNO_SPLASHSCREEN=1instead: the vitaGL splash screen uses a second GPU context, which Vita3K does not support. git,ninja,python3withpyyamlandpillow(LiveArea images)arm-none-eabi-binutils(used for the reference GBA build)libpngandpkg-config(for the decomp'sgbagfxtool)- agbcc and the decomp's legacy toolchain (see step 3)
- Your own ROM dump: Kingdom Hearts: Chain of Memories (USA),
B8CE, SHA-110729bd884f8fdca7a310b6d606c52e46657aa48; optionally the European one,B8CP, SHA-18db73586cdb11b3795907edebf43228dbcd3e6b2, to include the European version
1. Set up the source tree
git clone https://github.com/ggdrn/KH_COM_VITA.git
cd KH_COM_VITA
scripts/setup.sh # creates ./khcom: the decomp at the right commit + this port
# after working in khcom/: scripts/export_from_khcom.sh brings the port's code back here
cd khcom
python3 -m venv .venv && .venv/bin/pip install pyyaml pillow -r requirements.txt
export PATH="$PWD/.venv/bin:$PATH"
cp /path/to/your/rom.gba roms/B8CE.gba
cp /path/to/your/european/rom.gba roms/B8CP.gba # optional
2. Extract the game's assets from your ROM
sh tools/fetch_gbagfx.sh # builds gbagfx (needs libpng)
python3 tools/extract_assets.py # add "eu" to also extract the European ROM's assets
3. Build the reference GBA ROM
The Vita build reads the GBA build's symbol table to map ROM addresses to their new locations, so the
original ROM must be built once. Follow the decomp's README to install agbcc and run
python3 tools/setup_legacy_toolchain.py, then:
tools/vita/check_gba_match.sh # must print "OK: build/us/com_us.gba matches"
tools/vita/check_gba_match.sh eu # with the European ROM: "OK: build/eu/com_eu.gba matches"
Notes for macOS:
- The legacy binutils 2.10 build breaks if the path contains spaces. Build it in a directory without
spaces and copy
tools/legacy/back. - On 64-bit hosts the legacy assembler fails on
m4a_1.sand the legacy linker cannot link the runtime libraries.check_gba_match.shworks around both by assembling that file with the modernarm-none-eabi-asand linking witharm-none-eabi-ld. The result still matches the original ROM.
4. Build the Vita port
export VITASDK=/path/to/vitasdk # or install it at ~/Developer/vitasdk
python3 tools/vita/configure_vita.py
ninja -f build.vita.ninja
The VPK is written to build/vita/khcom_vX.XX.XX.vpk. It holds the USA executable and, when
roms/B8CP.gba is present, the European one (eboot_eu.self), which the USA executable starts when the
player's ROM is European. After the first configure, ninja re-runs the
configure step by itself when port/vita/VERSION or the build script changes.
How it works
A file-by-file guide, the build/runtime flow and the conventions for changing the code are in docs/ARCHITECTURE.md.
| Piece | Where | What it does |
|---|---|---|
| Build | tools/vita/configure_vita.py | Compiles the decomp's C with PLATFORM_VITA and agbcc-compatible struct layout (-mstructure-size-boundary=32, 4-byte-aligned 64-bit integers); assembles the data units as-is; replaces the GBA-only assembly (crt0, BIOS calls, m4a mixer) with the platform layer |
| ROM symbols | configure_vita.py, fix_abs_symbols.py | Fixed ROM addresses from symbols.txt become relocatable linker aliases; a generated table (romxlate.c) maps GBA ROM addresses to Vita addresses for pointers stored in binary data |
| ROM data at runtime | tools/vita/strip_rom_data.py, audit_rom_free.py, port/vita/host/vita_rom.c | The game's data units and the decomp's constant C tables are linked into writable sections. After linking, every byte that equals the ROM is zeroed (only relocated pointer words stay) and rommap.bin records where each run comes from in the ROM; the build checks each run against the ROM, rebuilds the original executable from the stripped one to prove it, and fails if samples of the ROM can still be found in it. At startup the port verifies the player's ROM (SHA-1) and copies the runs back before any game code runs |
| Hardware | port/vita/game/gba_system.c | Emulated IO registers, palette, VRAM, OAM and SRAM; DMA; interrupt dispatch; BIOS calls; the per-frame scanline/IRQ loop |
| Sound | port/vita/game/m4a_port.c, host/vita_audio.c | The m4a sequencer and mixer (originally ARM/Thumb assembly) rewritten in C, resampled to 48 kHz for sceAudioOut |
| Video | port/vita/host/ppu.c, vita_render.c, vita_video.c, scale2x.c, scale3x.c, mmpx.c | Scanline renderer for the GBA picture processor (tile/affine/bitmap backgrounds, sprites, windows, blending, mosaic), run on three cores in chunks of lines, optional upscalers (NEON), presented with vitaGL |
| Widescreen | port/vita/game/widescreen.c, ppu.c | Captures each streamed map's camera after VBlank; the renderer fetches the widescreen margins from the full map |
| Input | port/vita/host/vita_input.c, dodge hooks in src/btl/btl.c, unstock in src/card/card_card.c | Button mapping, Triangle → L+R, Square → dodge roll, right stick card controls, unstock (rear touch / right stick down) |
| Port menu and overlays | port/vita/host/vita_menu.c, vita_notice.c, vita_text.c | Start + L + R menu (picture, control and game options, boss practice, tutorials), moogle points notice, unstock progress bar |
| Boss practice | port/vita/game/boss_practice.c, hooks in src/map/map.c, src/btl/ | Starts a beaten boss like an encounter, saves and restores the game state around it, scales enemy HP/attack to the chosen level |
| GBA-style faults | port/vita/host/vita_fault.c | With kubridge, a data-abort handler decodes the faulting Thumb-2 load/store and performs it as the GBA would: BIOS-region reads return the BIOS open-bus value, writes there are dropped, raw GBA addresses are translated. Each emulated site is logged once |
| Freeze watchdog | port/vita/host/vita_fault.c | If the game loop stops for 5 s, logs the state and forces a crash dump so a freeze can be located |
| Decomp changes | patches/khcom-vita.patch | Hardware addresses routed through macros that still expand to the original values on GBA, plus Vita-only fixes. The GBA build still produces a byte-identical ROM |
Debugging
ux0:data/khcom/log.txtshows the startup steps, every game mode change and per-second timings (logic,render,present, worst frame), plusfault:lines for accesses emulated by the fault handler andwatchdog:lines when the game freezes.FaultInit=in the log gives the module load address.- When the game crashes the Vita writes
ux0:data/psp2core-*.psp2dmp. Wait until the file no longer ends in.tmpbefore copying it (a partial.tmpstill holds the thread registers), then run:
It prints each thread's registers and the source line of the crash.python3 tools/vita/parse_core.py psp2core-....psp2dmp
Legal
Kingdom Hearts is © Disney and Square Enix. This project is not affiliated with them. No ROM, extracted asset
or decompiled game code is included in this repository. The decompilation it builds on is a separate project
(Pheenoh/khcom, CC0), fetched by scripts/setup.sh. You must own the game
and dump your own copy to build this port.
License
The code in this repository (the Vita platform layer, the build tools and the patch) is released under the MIT License. It does not cover the game, its data, or the decompilation, which keeps its own CC0 license.
