Home · The story · Walkthrough · Gallery · Français
Everything found while reverse engineering Maupiti Island (Lankhor, PC version): how the programs work, every file format, and the evidence. These pages reveal the plot.
Status. The containers, the LZ/Huffman codec, the
fonts and the text encoding are decoded. All 1,589 game strings are in
game-text.txt, in the seven banks MAUPITI1.EXE
uses. The image format is ported and checked against the game's own
code, and every scene renders (scenes/). The speech engine
is ported. The structure and main rules of MAUPITI1.EXE are
mapped, including the winning route, though parts of its scripted
reactions and some of the 51 INT 0FEh services aren't.
| Chapter | Subject |
|---|---|
| The two programs | How maup.exe and MAUPITI1.EXE share the
work, start up and talk through INT 0FEh. |
| Game logic | Commands, time, conversations, what decides each sentence, sympathy, the ending. |
| File formats, scenes and palettes | Archives, the image format, how a scene is layered, the exact VGA palette system. |
| The compression codec | Adaptive Huffman and LZ77. |
| Video | Pages, the sprite sheet, blitters, adapter code. |
| Text and fonts | Glyph coding, 5-bit strings, text banks, proportional fonts. |
| Speech | The famous voice: data, driver rules, playback, and a text-to-speech tool. |
| Naming | Names across the IDA and Binary Ninja databases. |
| Refuted claims | What was believed and then disproved. |
| Open questions | What is still unknown. |
The gallery has every scene, the portraits, documents and object icons, and all the sounds.
| Base | Rule |
|---|---|
| IDA EA, used throughout these docs | EA = file offset + 0xF800 |
Binary Ninja address (maup.exe.bndb, flat file
map) |
BN = EA - 0xF800, which is the file offset |
DS: offset |
EA = 0x1A420 + offset (image paragraph
0xA42) |
far target seg:ofs in the file |
EA = 0x10000 + seg*16 + ofs; segments are
image-relative |
| runtime address | load-dependent; DS = 298Ch was only true in one
captured session |
MAUPITI1.EXE has its own base,
EA = file offset + 0xEA00.
Generated from the game's own tables.
| File | Contents |
|---|---|
| Dialogue | Every answer for each character and question, and what changes it |
| Actions | Per room and zone: each verb's reply, objects, containers |
| Topic unlocks | What unlocks each conversation topic |
| Timed events | Messages and scene changes by time |
| Schedule | Where each character is, every half-hour |
| Rooms | Room exits and travel costs |
| Questionnaire | The final quiz, with every answer |
| Documents | Every readable object with its pages, the newspapers, the piano's tunes |
| All game text | The 1,589 decoded strings, including period language that is offensive today |
| Font atlas | Both fonts, as text |
Record 0x2A
entries |
Each entry of the game data table, with its callers |
maup.exe
symbols |
All names, with addresses |
MAUPITI1.EXE
symbols |
All names, with addresses |
| Script | Use |
|---|---|
maup_parse.py |
Container and codec reader: selftest,
extract-all --dir-out maupiti_out |
tools/verify_docs.py |
Checks the docs' main byte-level claims |
tools/render_font.py |
Regenerates font-atlas-99.txt |
tools/mauptext.py |
Decodes strings: --out docs/game-text.txt |
tools/decode_image.py |
Image decoder to PNG: G3.CON 0x27 2 out.png, or
G1.CON 0x1A 0 out.png --room (needs Pillow) |
tools/m1calls.py |
Reads MAUPITI1.EXE as named calls with arguments:
0x1EBC8 0x1EF37 |
tools/game_logic.py |
Regenerates logic/ from record
0x2A |
tools/build_site.py |
Rebuilds the website in ../site/ from these docs and
the game's files |
tools/render_scene.py |
Renders a scene with all its overlays, at any time |
tools/verify_image.py |
Compares the image decoder with the game's own code in an emulator
(needs unicorn) |
tools/maup_speech.py |
Speaks any French text in the game's voice |
tools/verify_speech.py |
Compares that tool with the game's own code in an emulator (needs
unicorn) |
tools/m1index.py |
Lists MAUPITI1.EXE functions with callers and
tables |
tools/rec2a.py |
Splits record 0x2A and lists who uses each entry |
tools/disasm.py |
ndisasm by EA: 0x11590 0x116A0; add
--m1 for MAUPITI1.EXE |
tools/m1xref.py |
MAUPITI1.EXE far and near callers, and INT 0FEh
stubs |
tools/unlzexe91.py |
Unpacks MAUPITI1.olz and compares it to
MAUPITI1.EXE |