Broken Sword Templars CLU

From XentaxWiki
Jump to: navigation, search


Format Specifications

To extract data from cluster files, the type of the cluster file has to be determined first. There are two known types: general data clusters and sound clusters. To process data clusters, a RIF file is needed.


The RIF file contains global information for all data cluster files.

// RIF header
uint32 {4} - Number of clusters

// for each cluster
uint32 {4} - Cluster ID
// for each cluster
uint8 {1}  - Cluster name length
char {31}  - Cluster name
uint32 {4} - Number of sections
// for each section
uint32 {4} - Section ID
// for each section
uint32 {4} - Number of files
// for each file
uint32 {4} - File ID
// for each file
uint32 {4} - File offset
uint32 {4} - File length

Data CLU

Data clusters contain no header of their own. Instead, the information read from the RIF (where the cluster in question can be identified by its file name prefix) is needed to process these files. The gained offset and length values can then be used to seek through the cluster file.

Sound CLU

To process sound clusters, the RIF file is not needed. Instead, these files have their own header:

// CLU header
uint32 {4} - Data offset
uint32 {4} - Index offset

This header is followed by some unknown data. At the index offset, the actual entry information array can be found. The number of entries can indirectly be computed via (Data offset - Index offset) div 8.

// for each entry
uint32 {4} - Data offset
uint32 {4} - Data size

The resulting sounds are expressed as PCM wave files with a standard RIFF header. However, the content of their data chunk has been RLE-compressed. Also, the size value of the RIFF chunk usually seems to be wrong and has to be fixed.

Sound data RLE variation

The compressed sound data does not follow a standard RLE scheme, but uses a certain variation. The decompression is easy nonetheless. In the following pseudo code, it is assumed that decompression takes place from InBuf to OutBuf.

while still data to decompress do

get (big endian!) int16 RunLen from InBuf
if RunLen < 0 then
copy the next int16 value from InBuf to OutBuf -RunLen times
copy RunLen int16 values from InBuf to OutBuf

MultiEx BMS

Not written yet

Supported Programs