# Havoc file formats (reverse-engineered) All offsets/sizes verified against the retail data set (Reality Bytes, Inc., 1995). ## Binaries | File | Type | Notes | |---|---|---| | `HAVOC.EXE` | PE32 i386, GUI | Imports `DDRAW`, `DSOUND`, `WINMM`, `WSOCK32`, `GDI32`, `USER32`, `KERNEL32`. **No Direct3D** — 3D is a software rasterizer drawing into a DirectDraw surface. Contains a CD-presence check ("...Extra Player CD..."). | | `LAUNCHER.EXE` | PE32 i386, GUI | Front-end menu (see `havoc_9` screenshot). | | `SETUP.EXE` | PE32 i386, GUI | Config/setup. | | `DIRECTX/` | DX5-era | Ships 16-bit `DSETUP16.DLL`/`DDRAW16.DLL` — the 16-bit installer path is what breaks on 64-bit Windows, not the game itself. | ## `.FF` — "FlashFile" archive ✅ implemented in `tools/ff_extract.py` Used by `MUSIC.FF`, `SOUND.FF`, `OBJECTS.FF`, `INTRFACE.FF`. Built by the bundled DOS tool `FFCREATE.EXE` (found inside `MUSIC.FF`/`SOUND.FF`). ``` uint32 file_count (little-endian) repeat file_count: uint32 absolute_offset (little-endian, from start of .FF) char[] name (NUL-terminated, variable length) entry size = next_offset - this_offset ``` Notes: - The table may contain a trailing empty-name entry — skip it. - Entry payloads are raw and self-describing (e.g. `RIFF`/`WAVE`, `MZ`, bitmaps). ### Archive contents | Archive | Count | Entry kinds | |---|---|---| | `MUSIC.FF` | 116 | `WAVE.DAT` PCM segments, `PLST.DAT` playlists, `FFCREATE.EXE` | | `SOUND.FF` | 65 | `WAVE.DAT` sound effects, `FFCREATE.EXE` | | `OBJECTS.FF` | 526 | `ASND.DAT` … (enemy/pickup models + object sounds — format TBD) | | `INTRFACE.FF` | 547 | `BitB.dat` cockpit/HUD/menu bitmaps — format TBD | ## Music: `WAVE` segments + `PLST` playlists ✅ - `WAVE.DAT` — standard `RIFF`/`WAVE`, PCM **mono, 22050 Hz, 8-bit**. - `PLST.DAT` — a song = an ordered sequence of WAVE segments. **Payload is big-endian** (note: the `.FF` table around it is little-endian — mixed by design): ``` uint16 segment_count (big-endian; how many WAVE segments belong to this group) uint16 step_count (big-endian) uint16[step_count] sequence (big-endian; 1-based segment index) ``` Segment resolution: a playlist named `PLST` has base id = `int(id, 16)`; **step value N maps to wave id `base + N - 1`** (e.g. `PLST07D1` step 2 → `WAVE07D2`). Concatenating the referenced segments' PCM reproduces the song exactly (verified by ear). ## World data (`WORLDS/`) — TODO (3D terrain) Per-level sets `` = 01..06 plus `N`/`N2` variants (biomes: desert, snow/ice, lava, ocean). | Pattern | Guess | Status | |---|---|---| | `MAP.MAP` | tile/heightmap grid, 1 byte per cell | layout confirmed (byte grid); dims TBD | | `LAND.DAT` | terrain geometry/tile defs | TBD | | `GRAFIX0N.DAT` | terrain/texture tilesets | TBD | | `STUF.DAT` | entity placement (contains `Item` records) | TBD | ## Other top-level data — TODO | File | Notes | |---|---| | `BIGFILE.DAT` (64 MB) | starts `Copyright 1995, Reality Bytes, Inc.` then embedded `RIFF` data — bulk audio/stream pool | | `STRDATA.DAT` | length-prefixed UI string table (`Out of memory.`, `Not enough disk space.`, …) | | `HAVOC.ICO` | 32×32 4-bit icon |