Technical appendix

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.

Chapters

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.

Images and sounds

The gallery has every scene, the portraits, documents and object icons, and all the sounds.

Address conventions

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.

Confidence labels

  • verified: read from the disassembly at the cited address, or checked against a file.
  • inferred: the best reading of the evidence, not proven.
  • unverified: inherited from earlier work and not re-checked.

Reference data

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

Tools

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