SCUMM/Technical Reference/Index File
SCUMM Technical Reference → SCUMM index file
Introduction
Most of the information below are retrieved from the LucasHacks! site and from the Pascal source code of the IndexFileReader 1.2 (written by Ben Gorman (Bgbennyboy, http://quick.mixnmojo.com). In addition, ScummRevisited (written by Jimmi Thøgersen (Serge), http://www.mixnmojo.com/scumm/scummrev) turned out to be very useful in verifying the found offsets.
The SCUMM index file contains special information to allow quick random access to the resources in the other game files. It also includes the room names and some max limits for the game. The following filenames are used:
filename | SCUMM version |
---|---|
00.lfl / 000.lfl | V3/4 |
.000 | V5/6 |
.LA0 | V7/8 |
Version 1 to 3 use hardcoded offsets and cannot be treated that easily. For the other games, the index file can be used to determine the SCUMM version because there have been slight changes in each version.
- Version 4
- the 5th and 6th byte match RN or OR
- Version 5:
- RNAM xor'ed with 0x69 at the beginning of the file
- next 4 byte integer value xor'ed with 0x69 is > 9
- Version 6
- RNAM xor'ed with 0x69 at the beginning
- next 4 byte integer value xor'ed with 0x69 is 9 (actually it's the size of the chunk. In V6 games, no room names are stored so the size is 4 bytes (header) + 4 bytes (size) + 1 byte for the termination character).
- Version 7
- RNAM at the beginning of the file (not xor'ed this time)
- next 4 bytes result in BE integer 9 (actually applies only to Full Throttle)
- Version 7 or 8
- RNAM at the beginning of the file
- next 4 bytes integer is > 9
How to distinguish between version 7 and 8? Not by looking at the first bytes, but the the size of the chunks is usually bigger because a 4 byte integer is used to store the number of objects.
Conventions
As usual, the endianness (Wikipedia) is important. Unless stated, little endianess (LE) is used.
BE is used as abbreviation for big endianness.
A Chunk is a named part of the file, e.g. RNAM. Each chunk has a header that contains at least the chunk name and its size. The following chunks are available:
RNAM Room Names | In V5+ |
MAXS Maximum Values | In V5+ |
DROO Directory of Rooms | In V5+ |
DRSC Direcory of Room Scripts | In V8 |
DSCR Directory of Scripts | In V5+ |
DSOU Directory of Sounds | In V5+ |
DCOS Directory of Costumes | In V5+ |
DCHR Directory of Charsets | In V5+ |
DOBJ Directory of Objects | In V5+ |
AARY List of Arrays | In V6+ |
ANAM Animation Names? | In V7 |
RM Room Names | In V3/4 |
0R Directory Of Rooms | In V3/4 |
0S Directory Of Scripts? | In V3/4 |
0N Directory Of Sounds? | In V3/4 |
0C Directory Of Costumes? | In V3/4 |
0O Directory Of Objects? | In V3/4 |
Scumm 3/4
- File's aren't xor'ed
To read in the data, the following pseudo-code can be used:
Read Number of Items FROM 1 to "Number of Items" DO Read subvalue 1 Read subvalue 2 END
RN - Room names
Block Size (4 bytes) Block Name (2 bytes) #Room No (1 byte) #Room Name (9 bytes) XOR'ed with FF Blank (00) byte (1 byte) Marks end of chunk
0R - Directory of Rooms
Block Size (4 bytes) Block Name (2 bytes) No of items (2 bytes) File Number (1 byte) Offset (4 bytes)
File Number is interesting if a game is splitted on multiple disks. 0 means not used.
For Offset only the value 0 seems to be used.
0S - Directory of Scripts
Block Size (4 bytes) Block Name (2 bytes) No of items (2 bytes) Room Number (1 byte) Offset (4 bytes)
The global scripts are stored in this directory. The offsets are relative to the room.
0N - Directory of Sounds
Block Size (4 bytes) Block Name (2 bytes) No of items (2 bytes) Room Number (1 byte) Offset (4 bytes)
Similar to scripts but holds indexes for sounds.
0C - Directory of Costumes
Block Size (4 bytes) Block Name (2 bytes) No of items (2 bytes) Room Number (1 byte) Offset (4 bytes)
Similar to scripts but holds indexes of customes.
0O - Directory of Objects
Block Size (4 bytes) Block Name (2 bytes) No of items (2 bytes) Class data (3 bytes) Owner+state (1 byte)
The class data is LE. Class data can be as follows:
No Class = 0 kObjectClassYFlip = 18 kObjectClassXFlip = 19 kObjectClassNeverClip = 20 kObjectClassAlwaysClip = 21 kObjectClassIgnoreBoxes = 22 kObjectClassPlayer = 23 // Actor is controlled by the player kObjectClassUntouchable = 24
The Object owner and state are encoded in one byte. Example:
0xA2 → Owner = 0xA, State = 0x2
The pseudo decode code would be:
Owner = ( (Owner+state Byte) AND 0xF0) >> 4 State = (Owner+state Byte) AND 0x0F
Scumm 5
- The files are xor'ed with 0x69
RNAM - Room Names
Block Name (4 bytes) Block Size (4 bytes BE) #Room No (1 byte) #Room Name (9 bytes) XOR'ed with FF Blank (00) byte (1 byte) Marks end of chunk
MAXS
Block Name (4 bytes) Block Size (4 bytes BE) Variables (2 bytes) Unknown (2 bytes) Bit Variables (2 bytes) Local Objects (2 bytes) New Names? (2 bytes) Character Sets (2 bytes) Verbs? (2 bytes) Array? (2 bytes) Inventory Objects (2 bytes)
DROO - Directory of Rooms
Block Name (4 bytes) Block Size (4 bytes BE) No of items (2 bytes) *Room Number (1 byte) *Offset (4 bytes)
The flow how to read in this kind of information has changed slightly from V3/4.
Read "No of items" FROM 1 TO "No of items" DO Read "Room Number" END
FROM 1 TO "No of items" DO Read "Offset" END
First read in all room numbers, then read in all room offsets.
DSCR - Directory of Scripts
Block Name (4 bytes) Block Size (4 bytes BE) No of items (2 bytes) *Room Number (1 byte) *Offset (4 bytes)
Indexes for global scripts, see pseudo code above on how to read in the data.
DSOU - Directory of Sound
Block Name (4 bytes) Block Size (4 bytes BE) No of items (2 bytes) *Room Number (1 byte) *Offset (4 bytes)
Indexes for sound objects.
DCOS - Directory of Costumes
Block Name (4 bytes) Block Size (4 bytes BE) No of items (2 bytes) *Room Number (1 byte) *Offset (4 bytes)
Indexes for costumes
DCHR - Director of Charsets
Block Name (4 bytes) Block Size (4 bytes BE) No of items (2 bytes) *Room Number (1 byte) *Offset (4 bytes)
Indexes for charsets.
DOBJ - Directory of Objects
Block Name (4 bytes) Block Size (4 bytes BE) No of items (2 bytes) *Owner+state (1 byte) *Class data (4 bytes)
Information about objects. See remarks in V3/4 section how the owner+state value should be interpreted. Note that the index files stores ALL owner+state values, followed by ALL class data values.
Scumm 6
- Files are xor'ed with 0x69
RNAM - Room Names
Blank Byte(00) (1 byte)
No room names are stored.
MAXS
Block Name (4 bytes) Block Size (4 bytes BE) Variables (2 bytes) Unknown (2 bytes) Bit Variables (2 bytes) Local Objects (2 bytes) Arrays (2 bytes) Unknown (2 bytes) Verbs (2 bytes) Floating Objects (2 bytes) Inventory Objects (2 bytes) Rooms (2 bytes) Scripts (2 bytes) Sounds (2 bytes) Character Sets (2 bytes) Costumes (2 bytes) Global Objects (2 bytes)
DROO, DSCR, DSOU, DCOS, DCHR, DOBJ
All as in V5
AARY - Array
Block Name (4 bytes) Block Size (4 bytes BE) #Stop (2 bytes) Stops if 0x0000 #A (2 bytes) #B (2 bytes) #C (2 bytes) num=AARY no (itinerate through in loop) if c=1 then AARY=(num, 1, a, b) else AARY=(num, 1, a, b)
If stop=0 you dont seek past the 6 bytes of A,B,C you just start the loop again.
Scumm 7
- Files aren't xor'ed
RNAM - Room names
- As in V6 ?!?!?!
MAXS
Block Name (4 bytes) Block Size (4 bytes BE) Variables (2 bytes) Bit Variables (2 bytes) Unknown (2 bytes) Global Objects (2 bytes) Local Objects (2 bytes) New Names (2 bytes) Verbs (2 bytes) Floating Objects (2 bytes) Inventory Objects (2 bytes) Arrays (2 bytes) Rooms (2 bytes) Scripts (2 bytes) Sounds (2 bytes) Character Sets (2 bytes) Costumes (2 bytes)
DROO,DSCR,DSOU,DCOS,DCHR,DOBJ,AARY
All as in V5
ANAM - Animation Names
Block Name (4 bytes) Block Size (4 bytes BE) No of items (2 bytes #Name (8 bytes) #Blank (00) byte (1 byte) Blank (FF) byte (1 byte) Marks end of chunk
Scumm 8
RNAM - Room Names
As in V6 ?
MAXS
Block Name (4 bytes) Block Size (4 bytes BE) Variables (4 bytes) Bit Variables (4 bytes) Unknown (4 bytes) Scripts (4 bytes) Sounds (4 bytes) Character Sets (4 bytes) Costumes (4 bytes) Rooms (4 bytes) Unknown (4 bytes) Global Objects (4 bytes) Unknown (4 bytes) Local Objects (4 bytes) New Names (4 bytes) Floating Objects (4 bytes) Inventory Objects (4 bytes) Arrays (4 bytes) Verbs (4 bytes)
DROO - Directory of Rooms
Block Name (4 bytes) Block Size (4 bytes BE) No of items (4 bytes) *Room Number (1 byte) *Offset (2 bytes)
DRSC - Directory of Room Scripts
Block Name (4 bytes) Block Size (4 bytes BE) No of items (4 bytes) *Room Number (1 byte) *Offset (2 bytes)
DSCR - Directory of Scripts
Block Name (4 bytes) Block Size (4 bytes BE) No of items (4 bytes) *Room Number (1 byte) *Offset (2 bytes)
DSOU - Directory of Sound
Block Name (4 bytes) Block Size (4 bytes BE) No of items (4 bytes) *Room Number (1 byte) *Offset (2 bytes)
DCOS - Directory of Costumes
Block Name (4 bytes) Block Size (4 bytes BE) No of items (4 bytes) *Room Number (1 byte) *Offset (2 bytes)
DCHR - Directory of Charsets
Block Name (4 bytes) Block Size (4 bytes BE) No of items (4 bytes) *Room Number (1 byte) *Offset (2 bytes)
DOBJ,AARY
As in V7