Saltar al contenido
PORTSNATIVE.
InicioCatálogo
Juegos WebEmuladoresHerramientasNovedades
PORTSNATIVE.

Un catálogo para descubrir ports y proyectos relacionados. Enlazamos a las fuentes oficiales y no alojamos archivos de los juegos originales.

ExplorarCatálogoMi lista
InformaciónNosotrosProponer un portSoporteApoyo y donacionesAviso legal
© 2026 PortsNative
Volver al catálogo
Tomba!
PORTSNATIVE

Tomba!

PORT NATIVOPLATAFORMASWINDOWSALPHA

Tomba!

TecnologíaPort Nativo C/C++ (Reimplementación de Motor)

Disponible paraWindows

Ver proyecto oficial

Sobre el proyecto

Tomba! es un videojuego de plataformas, acción y aventura creado por Whoopee Camp Co. Ltd. y publicado por Sony Computer Entertainment para la consola de videojuego PlayStation. Fue lanzado en 1997 para Japón y en 1998 para Norteamérica y la región PAL. Tombi! también contó con una secuela titulada Tombi! 2: The Evil Swine Return en 1999. También ha sido lanzado en PlayStation Network por MonkeyPaw Games. La saga es fue idea del creador de juegosTokuro Fujiwara, quien creó los videojuegos Ghosts'n Goblins y Mega Man.

2 versiones de Tomba!

Estás viendo: Tomba!

Tomba!github.com/hansbonini/psx_tomba
Windows
Actual
TombaRecompgithub.com/mstan/TombaRecomp
Windows
Linux
macOS
›

Información oficial del proyecto

README original del autor (en inglés)Abrir en GitHub ↗

Tomba! PSX Decompilation

<div align="center"> <img src="https://github.com/hansbonini/psx_tomba/blob/main/docs/assets/logo.png?raw=true" alt="Tomba! Logo" width="400"/>

Discord Progress License Platform

</div>

A decompilation of Tomba! for the original PlayStation, also released as Ore! Tomba in Japan and Tombi! in Europe. The goal is C source code that compiles back into byte-identical executables for every retail release. That source code supports:

  • 🔧 Modding: patches, translations and enhancements built on real source code
  • 📖 Study: how a late-90s PlayStation game was programmed
  • 🌍 Preservation: keeping the game's code understandable for the future

🌍 Supported Versions

All four releases build from the same sources and are checked byte for byte.

RegionSerialVERSIONExecutablesSHA1 of the main executable
🇺🇸 NTSC-USCUS-94236scus_942.36 (default)SCUS_942.36 and the code overlays SYSTEM/OPTSUB00.BIN, X00–X1881cbc79f0230aeb4252e058039f47ac95a777f5a
🇯🇵 NTSC-JSLPS-01144slps_011.44SLPS_011.4407d577698ad31ec1a69b9d7b80a7c3f90b650888
🇪🇺 PAL (En/Fr/De/It/Nl)SCES-01330sces_013.30SCES_013.30 and EXE/MAIN0.EXE–MAIN8.EXE1d98c6595a49bd8063c906221df1eaa854964cb1
🇪🇺 PAL (En/Es/Pt/Sv/Da)SCES-01331sces_013.31SCES_013.31 and EXE/MAIN0.EXE–MAIN8.EXEf6c383514e5d8367d2eed06400315cf6dd57ef6b

On the European discs, SCES_013.3x is only the language menu. The game itself is EXE/MAINn.EXE, with one executable per language. The checksums of every file are in config/<VERSION>/checksum.sha.

US is the reference release: functions are decompiled there first. The other releases reuse every object that is the same in their executable. See How the versions share code.

📊 Progress

Live progress is tracked on decomp.dev from the objdiff report that CI publishes on every push to main.

Overall Psy-Q SDK Functions

Scope (US)Matched code
Overall, overlays included38.3%
Main game code (main)78.0%
Psy-Q SDK (sdk)88.0%
Shared overlay engine and X00 area (x00)77.0%

Local report from 2026-10-14. The badges are live; this table will drift.

Matched code is weighted by bytes, so a 1200-byte state machine counts for more than a three-line accessor. The other Xnn area modules have barely started, which is why the overall number is far below the main executable's.

Note: the game links PSY-Q libraries from mixed SDK versions (for example libpad 4.2 alongside 4.3), so signature matching is done per object, not per SDK release.

🛠️ Toolchain

ComponentVersion / SourceRole
splat0.35.2 (pinned)Splitting and disassembly
spimdisasm1.36.0 (pinned)MIPS disassembly backend
gcc 2.7.2-psxtools/gcc-2.7.2-psx/Original-era C compiler (cc1)
maspsxtools/maspsx/ASPSX 2.56 assembler emulation
binutils-mips-linux-gnudistro packageAssembler and linker
objdifftools/objdiff/Per-object diffing and progress reports
decomp-permutermake permuter-setupSearch for near-matches
m2ctools/m2c/First-pass assembly-to-C
mkpsxisotools/mkpsxiso/Disc extraction (dumpsxiso) and rebuild
armipstools/armips/armips (not bundled)Standalone patches in patch/

splat and spimdisasm are pinned on purpose. The build assembles the code they generate, and their labels and rodata output change between releases, so an unpinned upgrade breaks the link in ways that look nothing like a code error.

📁 Project Structure

PSX_TOMBA/
├── src/                 # C sources shared by every release
│   ├── main/            #   game code
│   ├── psyq/            #   PSY-Q SDK
│   └── overlays/        #   code overlays (US): shared engine + area modules
├── include/             # headers (game.h, common.h, psyq/)
├── config/<VERSION>/    # splat configs and checksums of each release
├── symbols/<VERSION>/   # symbol tables of each release
├── asm/<VERSION>/       # disassembly generated by splat (not in git)
│   ├── nonmatchings/    #   functions still in assembly, used by INCLUDE_ASM
│   └── matchings/       #   functions already in C, for reference
├── linker/<VERSION>/    # generated linker scripts (not in git)
├── build/<VERSION>/     # objects of each release (not in git)
├── build/out/iso/       # rebuilt executables
├── iso/<VERSION>/       # extracted disc of each release (not in git)
├── patch/               # standalone armips patches (debug menus)
├── i18n/                # translation data
├── docs/                # technical documentation
├── tools/               # toolchain and project scripts
└── *.xml                # mkpsxiso disc layouts

🚀 Getting Started

Prerequisites

  • Linux or WSL: the bundled cc1 is a 32-bit Linux ELF binary
  • Python 3.8+ and Make
  • binutils-mips-linux-gnu and cpp-mips-linux-gnu

Setup

  1. Clone with submodules

    git clone --recurse-submodules https://github.com/hansbonini/psx_tomba.git
    cd psx_tomba
    
  2. Install the toolchain

    sudo apt-get install make binutils-mips-linux-gnu cpp-mips-linux-gnu
    python3 -m pip install splat64[mips]==0.35.2 spimdisasm==1.36.0
    

    Pin both. splat only asks for spimdisasm>=1.36.0,<2.0.0, so pip would otherwise pull a newer backend that produces different labels.

  3. Extract your disc

    Use a disc you legally own. Extract it with dumpsxiso (from mkpsxiso) into iso/<VERSION>. Pass the .bin image, not the .cue:

    dumpsxiso -x iso/scus_942.36 -s SCUS_94236.xml "Tomba! (USA).bin"
    

    Check the main executable against the SHA1 in the table above. Every offset in the project assumes those exact builds.

  4. Build and check

    make generate    # splat: disassembly and linker scripts
    make check       # build and compare with config/<VERSION>/checksum.sha
    

    Every target takes VERSION, and US is the default:

    make VERSION=slps_011.44 generate
    make VERSION=slps_011.44 check
    

    Every OK in the make check output means that file is byte-identical to the original.

Make Targets

TargetPurpose
make generateRun splat for every executable of VERSION
make build / make checkBuild; build and verify the checksums
make reportRe-split, build the objdiff baseline and write build/<VERSION>/progress.json
make regenerateRemove the asm, linker scripts and build of VERSION, then run splat again
make clean / make resetRemove the build of VERSION; also its asm and linker scripts
make permuter-import FUNC=… SRC=… / make permuter-run FUNC=…Search for near-matches with decomp-permuter
make patch_debug_sfx etc.Build the standalone debug patches in patch/

If you edit a header such as game.h, make does not rebuild the objects that include it. Remove build/<VERSION>/src before measuring.

🔀 How the Versions Share Code

There is one src/ for all releases. Each release has its own splat config, symbol tables, asm and build folder:

  • Only the asm differs per release. INCLUDE_ASM paths are relative (INCLUDE_ASM("nonmatchings/main/game/event", func)). The assembler looks them up in the asm folder of the executable being built (asm/<VERSION>, or asm/<VERSION>/exe/mainN for a European MAIN).

  • The C keeps the US names. Each executable of another release gets symbols/<VERSION>/<name>_symbol_addrs.txt, which places the US names at that executable's addresses. Names splat makes up there carry the serial as a suffix (D_80012345_slps01144), so they never clash with the US ones.

  • A function that differs in a release is kept in assembly there. The #if uses one macro per serial, which the Makefile defines from VERSION:

    #if defined(VERSION_SLPS_01144) || defined(VERSION_SCES_01330)
    INCLUDE_ASM("nonmatchings/main/render/camera", loadSpawnPosition);
    #else
    void loadSpawnPosition(void)
    {
        ...
    }
    #endif
    

    The macros are VERSION_SCUS_94236, VERSION_SLPS_01144, VERSION_SCES_01330 and VERSION_SCES_01331.

These files are generated, not edited by hand. Two scripts produce them:

ScriptWhat it does
tools/version_objects.pyFinds each US object in the other executables, function by function, and writes their splat subsegments with the US object names
tools/version_share.pyTurns the objects that can share the US source into C, writes the symbol tables, and rewrites the #if blocks in src/

After a change that affects other releases (a newly matched function, a renamed symbol), rebuild the US first: version_share.py reads the relocations of the US objects. Then run it with no arguments, because the #if blocks are only rewritten when every release is analysed. Finally run make VERSION=<serial> generate and make VERSION=<serial> check for each release.

An object stays in assembly in another release in these cases:

  • It has .data of its own in C. Its data is not split yet in that release.
  • It is split in two places in the executable. This happens with some European objects.
  • Its changed functions cannot be told apart. This happens with parts of the Japanese game code.
  • It is a libpad unit and one of its functions differs. These units are assembled by GNU as, which cannot take INCLUDE_ASM.

🤖 Continuous Integration

.github/workflows/build.yaml builds every release on each push to main. It runs make generate, make build and make report once per VERSION, then uploads each build/<VERSION>/progress.json. The runner image and the disassembly tools are pinned for the reason given in the Toolchain section.

🤝 How to Contribute

The most useful contribution is matching a function.

  1. Pick a function still under INCLUDE_ASM in src/.
  2. Write C for it, using asm/scus_942.36/nonmatchings/<object>/<function>.s as reference.
  3. Check it with make check, objdiff, or a scratch on decomp.me. tools/decompile.py extracts a function with its context and uploads it.
  4. When it matches, replace the INCLUDE_ASM line with the C and leave the original line commented above it, as everywhere else in the repository.
  5. Rebuild the other releases (see How the versions share code). If the function differs in a release, version_share.py adds the #if for you.

Other help is just as welcome:

  • 🔍 Naming: functions, data structures, execution flow
  • 📝 Documentation: file formats and engine behaviour in docs/
  • 🐛 Bugs: open an issue with the log and the steps to reproduce

Pull requests: fork, create a branch, commit, and open the PR against main.

🗺️ Game Areas

Area and section layout of the game data, for orientation in area-specific code:

IDAreaSections
AREA00Village of All Beginnings5
AREA01Dwarf Forest5
AREA02Dwarf Village6
AREA03Phoenix Mountain6
AREA04Haunted Mansion20
AREA05Baccus Village4
AREA06Motocross Segment3
AREA07Dwarf Forest (Purified)5
AREA08Baccus Lake4
AREA09Mushroom Village7
AREA10Deep Jungle9
AREA11Village of Civilization3
AREA12Haunted Mansion (Purified)20
AREA13Pig Island2
AREA14Evil Pigs8
AREA15Empty / Unused—
AREA16Village of Civilization — Clock Tower7
AREA17Village of Civilization — Iron Tower11
AREA18Village of Civilization — Y Crossing3
AREA19Hidden Village3

📚 Documentation

In this repository:

  • Environment setup
  • Game file formats
  • CD file loading
  • File analysis

Elsewhere:

  • Tomba.Club, the community wiki
  • PSX-SPX, hardware reference
  • PSY-Q documentation
  • Tomba! on TCRF
  • decomp.me, collaborative function matching

⚖️ Legal

This project is for education and preservation only.

  • No game assets or original code are distributed here.
  • You need your own legally owned copy of the game to build anything.
  • Tomba! is © Whoopee Camp / Sony Computer Entertainment.

🏆 Credits

  • Hans Bonini: project lead and main development

Tools: splat (ethteck), spimdisasm (Decompollaborate), maspsx (mkst), objdiff (encounter), mkpsxiso (Lameguy64), and the PSX.Dev community.

Special thanks:

  • zerovii: material and explanations about the WFM format
  • vervalkon: material and explanations about quad polygon coordinates and the GAM format
  • Xeeynamo: the Castlevania: SotN decompilation, used as reference
  • LAB313Ru: PSX loader for Ghidra
  • PCSX-Redux and DuckStation teams: emulators used for debugging and verification

📞 Community

  • 💬 Discord: Tomba.Club
  • 🌐 Website: hansbonini.com.br

<div align="center"> <strong>"Let's catch all the evil pigs!"</strong> — Tomba </div>
Leer guía oficial
CALIFICACIÓN
—
Cargando votos…
Publicidad

FICHA DEL PROYECTO

Tipo de proyecto
PORT NATIVO
Género
Plataformas
Estado
alpha
Plataforma de origen
—
Tecnología
Port Nativo C/C++ (Reimplementación de Motor)
Versión
—
Actualización
—

Plataformas de destino 1

Windows
Ver en GitHub
Publicidad