Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

SFX Sound Effects File Format

Single-file container for all game sound effects, stored as MAIN.SFX in the SOUND directory. Does not include voice clips (those are in ENGLISH.RTX).

Overall Structure

FXHD section (44 bytes)
FXDT section (variable)
"END " (4 bytes)

Effects are stored sequentially with no offset table. The game references effects by their 0-based index in the file.

FXHD (Header Section)

44 bytes total. Section size word is big-endian; remaining fields are little-endian.

OffsetSizeTypeEndianNameDescription
0x004u32BEsection_sizePayload size excluding this field
0x0432[u8; 32]descriptionASCII string, set by internal tool “SoupFX”
0x244u32LEeffect_countNumber of sound effects (118 in MAIN.SFX)

FXDT (Data Section)

Begins with a big-endian u32 section size (excluding itself), followed immediately by sequential effect records.

Effect Record

27-byte header followed by raw PCM audio data.

All fields little-endian unless noted.

OffsetSizeTypeNameDescription
0x004u32type_idAudio type: 0 = 8-bit mono, 1 = 16-bit mono, 2 = 8-bit stereo (unused), 3 = 16-bit stereo
0x044u32bit_depth0 = 8-bit, 1 = 16-bit
0x084u32sample_rateAlways 11025 or 22050 Hz
0x0C1u8unused_0cAlways 64. Runtime behavior is driven by the surrounding 26-byte header block (0x000x19), with no separate per-field behavior for this byte. Likely a vestigial default volume value (64/127 ≈ 50% on the Miles Sound System scale).
0x0D1i8loop_flag0 = no loop, non-zero = enable looping. The engine checks only != 0; values -1 (0xFF) and -31 (0xE1) are functionally identical.
0x0E4u32loop_offsetByte offset into PCM data for loop restart point (always 0)
0x124u32loop_endSample count before looping (always 0xFFFFFFFF)
0x164u32data_lengthByte count of raw PCM data following this header
0x1A1u8reserved_1aPadding between header and PCM data. Always 0.
0x1Bvar[u8]pcm_dataRaw PCM audio: u8 samples for 8-bit, i16 LE samples for 16-bit

Loop Behavior

The engine checks only whether loop_flag is non-zero — the specific value is not interpreted.

  • loop_flag = 0: play once (non-looping effects)
  • loop_flag = -1 (0xFF): enable looping (used for ambient loops like fire, water, wind)
  • loop_flag = -31 (0xE1): enable looping (functionally identical to -1; only used on effect 117, the snake charmer tune)

loop_offset and loop_end appear to be unused features — always loop_offset = 0 and loop_end = 0xFFFFFFFF.

Runtime Effect Structure

The engine allocates a 34-byte (0x22) runtime structure per effect, reading 26 bytes (0x00–0x19) from the file. The remaining 8 bytes are computed at runtime:

Struct OffsetSizeSourceContents
0x00–0x1926FileHeader fields (type_id through data_length)
0x1A–0x1D4RuntimePointer to allocated PCM data buffer
0x1E–0x214RuntimeComputed duration value: (data_length << 8) / (sample_rate × bytes_per_sample × channels)
  • RTX — dialogue audio container. Uses the same 27-byte audio header structure (offsets 0x00–0x1A) as SFX effect records. SFX stores sound effects; RTX stores voice clips.

External References