RRM Format (Mythos Software)
The RRM Format is a container for room-specific data in The Lost Files of Sherlock Holmes: The Case of the Serrated Scalpel.
File format
Header
The header has this format:
Data type | Name | Description |
---|---|---|
char[32] | magicText | "\r\n\nHOLMES RESOURCE FILE V2.1\r\n\n\x1A" |
BYTE[7] | magicBytes | The same in all files: 00 14 9C 0E 74 50 05. Unknown meaning. |
BYTE | isPacked | 09 = unpacked, 0A = packed. |
UINT32LE | dirOffset | Offset of the directory, described below. |
Animations
The header is followed by zero or more animation offsets and data:
Data type | Name | Description |
---|---|---|
UINT32LE[nAnims] | animOffsets | Offsets to VGS data for animations. |
VGSChunk[nAnims] | anims | Animations in the Visage format. |
nAnims is found in the directory that follows. RRM files are not parsed sequentially.
Directory
The directory gives total numbers or sizes of various resources.
Data Type | Name | Description |
---|---|---|
UINT16LE | nObjects | Number of logical room objects, defined below. |
UINT16LE | nSprites | Number of VGS chunks associated with room objects. |
UINT16LE | nAnims | Number of VGS chunks in the previous section. |
UINT16LE | textSize | Size of the text block below, containing object descriptions. |
UINT16LE | sequencesSize | Size of the sequence block below, defining sprite frame orders. |
UINT16LE | unknown | Always zero. |
Sprites are persistent graphics for room objects, typically lasting the duration of play in the room. Animations are typically used for one-off events.
Sprite Definitions
Next comes a table defining the sprites:
Data Type | Name | Description |
---|---|---|
SPRITEDEF[nObjects] | spriteDefs | See below for SPRITEDEF definition. |
Note that there are nObjects SPRITEDEFs not nSprites. There are always at least as many objects as there are sprites, and the table is null-padded.
DataType | Name | Description |
---|---|---|
UINT32LE | spriteSize | Size of the VGS chunk for this sprite. |
UINT8 | numFrames | Number of frames in the sprite. |
char[9] | spriteName | Internal name of the sprite. |
Object Data
Objects are the game's most complex data structure and will be defined later on this page. For now, they will be viewed simply as 569-byte chunks. They and their remaining associated data follow:
DataType | Name | Description |
---|---|---|
OBJECTDEF[nObjects] | objects | Logical room objects. |
char[textSize] | objectText | ASCIIZ descriptions used when looking at an object. |
BYTE[sequencesSize] | sequenceBlock | Object sequences, defined later on this page. |
VGSChunk[nSprites] | sprites | VGS chunks for sprites defined in the SPRITEDEFs. |
The VGS chunks for sprites can be read sequentially using the size field in the SPRITEDEFs.
Animation Structures
Next come structures defining the behaviour of animations:
DataType | Name | Description |
---|---|---|
ANIMDEF[nAnims] | animDefs | See below. |
DataType | Name | Description |
---|---|---|
char[12] | name | Name of the animation structure. |
BYTE[30] | sequence | Sequence defining frame order, etc. Sequences are defined later. |
UINT16LE | x | Topleft coordinate for first animation frame. |
UINT16LE | y | |
UINT32LE | size | Size of VGS chunk in the block near the top of the file. |
UINT16LE | state | Related to state field of objects, explained later. |
UINT8 | drawOptions | Related to drawOptions field of objects, explained later. |
HPOS | startPos | Holmes' standing position when the animation begins. |
HPOS | endPos | Holmes' standing position when the animation ends. |
HPOS is a type also used elsewhere in this file. It defines a 'stance' for Holmes:
DataType | Name | Description |
---|---|---|
UINT16LE | x | Screen coordinate * 100 |
UINT16LE | y | |
UINT16LE | loopNum | Index into Holmes' list of lists of frames, to be added here later. Essentially, the direction he is facing and whether he is walking or standing still. |
The game does coordinate calculations internally in multiples of 100, for example the centre of the screen would be 16000x10000. This was presumably done to avoid floating point in diagonal move deltas.
Pathing Data
Next comes a number of data structures defining how Holmes moves around the room.
DataType | Name | Description |
---|---|---|
UINT16LE | boxBlockSize | Size of the following block of BOXDEFs. Let nBoxes = boxBlockSize / 10. |
BOXDEF[nBoxes] | boxDefs | Boxes as defined below. |
BOXDEF is defined as follows:
DataType | Name | Description |
---|---|---|
UINT16LE | x | Coordinates defining a walkable area on the screen. |
UINT16LE | y | |
UINT16LE | w | |
UINT16LE | h | |
UINT16LE | flags | Unknown purpose. |
A magic byte 0xFE follows, and then a lookup table and waypoints data chunk:
DataType | Name | Description |
INT16LE[nBoxes][nBoxes] | lookup | See below for explanation. |
UINT16LE | waypointsSize | Size of following waypoints data chunk. |
BYTE[waypointsSize] | waypoints | Waypoints data chunk. |
This data is used when Holmes tries to walk from one box to another. The boxes may not be connected and require travel through other boxes. Let src be the index of the box he is in, and dest be the index of the destination box. lookup[src][dest] where src is a column in the table will yield an index into the waypoints chunk. A waypoints entry looks like this:
DataType | Name | Description |
UINT8 | nWaypoints | Number of waypoints that follow. |
WAYPOINT[nWaypoints] | waypoints | List of screen coordinates that Holmes should walk towards on his path from src to dest. Each coordinate is UINT16LE x, UINT8 y. |
Note that all entries on the main diagonal of the lookup matrix are 0, and at offset 0 in the waypoints block is a set of 0 waypoints, because there is no path needed from a box to itself. Additionally, all entries below the main diagonal are -1, indicating a redundant entry. This is because paths are reversible and the upper half contains all data needed.
Next come the exit boxes:
DataType | Name | Description |
---|---|---|
UINT8 | nExitDefs | Number of following EXITDEFs. |
EXITDEF[nExitDefs] | exitDefs | Exits as defined below. |
EXITDEF is defined as follows:
DataType | Name | Description |
---|---|---|
UINT16LE | x | Coordinates defining a walkable area on the screen. |
UINT16LE | y | |
UINT16LE | w | |
UINT16LE | h | |
UINT16LE | roomNum | Destination room number. |
UINT16LE | unknown | Always 1. |
UINT16LE | destX | Holmes' position on entering the new room. |
UINT16LE | destY | |
UINT16LE | destLoop | Holmes' animation loop on entering the new room. |
Walking on an EXITDEF area causes Holmes to leave the room.
Concluding the pathing data, Holmes' starting position in the room:
DataType | Name | Description |
HPOS | startPos | Holmes' starting position on entering the current room. |
Sounds
A list of sound effects follows.
DataType | Name | Description |
UINT8 | nSoundDefs | Number of sound effect names that follow. |
char[nSoundDefs][9] | soundDefs | 8-byte sound effect name, padded with nulls, followed by byte 09. The sound effect is found in the LIB archive SND.SND |
Room object sequences, defined later on this page, can cause a sound effect to be played by index into this list.
Palette and Background
The remainder of the .RRM consists of a 768-byte VGA Palette and a 320x138 background image.
The palette is required to construct the animations and sprites earlier in the file. The programmer may choose between parsing through the file and constructing the animations and sprites later, or seeking to the end of the file immediately, since the palette is always at the fixed offset of EOF - (320 * 138 + 768).
Object Structure
Objects are logical entities in a room that affect gameplay. They may have an associated sprite, or they may have not and function as an invisible trigger area. Still other objects may have no spatial meaning and represent state transitions.
Objects always occupy 569 bytes. Many fields only have meaning at runtime.
FARPTR in the DataType column refers to a 32-bit memory location composed of UINT16LE offset, UINT16LE segment. These runtime fields are included for completeness.
Offset | DataType | Name | Description |
0 | char[12] | name | Internal ASCIIZ object name. |
12 | char[41] | hoverText | ASCIIZ text shown on the status line when the player hovers over the object. |
53 | FARPTR | textPtr | runtime: pointer to ASCIIZ text description. |
57 | FARPTR | seqPtr | Initially, the first UINT16LE in this field holds the offset of this object's sequence data in the room sequenceBlock. runtime: afterwards, the field is used as a FARPTR to the sequence. |
61 | FARPTR | spritePtr | runtime: pointer to VGS sprite for the object. |
65 | FARPTR | framePtr | runtime: pointer to current sprite frame. |
69 | BYTE | unknown | always 0 |
70 | BYTE | unknown | always 0 |
71 | UINT16LE | seqIndex | runtime: current position in the object's sequence. |
73 | UINT16LE | unknown | always 0 |
75 | UINT16LE | x | Topleft screen coordinate of the object. |
77 | UINT16LE | y | |
79 | INT16LE | deltaX | runtime: position delta for moving object. |
81 | INT16LE | deltaY | |
83 | UINT16LE | state | These values occur in the .RRM: 4: active, with sprite 6: active, without sprite 7: inactive |
85 | UINT16LE | frameX | runtime: dimensions of the current sprite frame. |
87 | UINT16LE | frameY | |
89 | UINT16LE | frameWidth | |
91 | UINT16LE | frameHeight | |
93 | BYTE[4] | unknown | always 0 |
97 | UINT8 | intBehave | encodes various things that happen when the user interacts with the object. |
98 | UINT8 | defBehave | default interaction, as an index into the menu commands (1=Look, 2=Talk, 3=Move, etc.) |
99 | INT16LE[3] | flags | story progress flags, to be described elsewhere. |
105 | UINT16LE | hoverX | Area occupied by an object with no sprite. 0,0 for objects with sprites. |
107 | UINT16LE | hoverY | |
109 | UINT16LE | unknown | always 0 |
111 | UINT8 | spriteNum | If 0, the object has no sprite. If > 0, subtract 1 and use as index into room sprite list. |
112 | UINT16LE | spriteFrames | Number of frames in the object's sprite. |
114 | BYTE | drawOptions | Bitfield controlling drawing of the object's sprite. The following bits are known so far: 0 and 2: OR these bits together and interpret as a number from 0..3 representing drawing layer, with 0 as backmost and 3 as frontmost. 1: if 1, the sprite is mirrored. |
115 | ACTIONDEF | openAction | Behaviour when opening the object. See below for ACTIONDEF. |
165 | BYTE | onCollision | Unknown value encoding what to do when Holmes collides with the object. |
166 | BYTE | unknown | unknown purpose |
167 | BYTE | seqRepCounter | runtime: counts how many times the object's sequence's current loop has repeated. |
168 | UINT16LE | approachX | Holmes walks to this position when approaching an object to interact with it. |
170 | UINT8 | approachY | |
171 | UINT8 | approachLoop | |
172 | BYTE | unknown | unknown purpose |
173 | ACTIONDEF | closeAction | Behaviour when closing the object. See below for ACTIONDEF. |
223 | UINT8 | seqPrevIndex | runtime: previous sequence loop position, saved by sequence call command. |
224 | UINT8 | seqFinalFrame | runtime: final frame of sequence shorthand iterator, to be defined later in sequence section. |
225 | UINT16LE | textOffset | Offset of object's ASCIIZ description text in room textBlock, used when Holmes uses Look interaction on the object. |
227 | UINT8 | seqLoopCounter | runtime: number of times a called sequence loop has repeated. |
228 | UINT16LE | seqSize | Size of object's sequence data in the room sequenceBlock. |
230 | BYTE | unknown | always 0 |
231 | ACTIONDEF | moveAction | Behaviour when moving the object. See below for ACTIONDEF. |
281 | BYTE[8] | unknown | always 0 |
289 | ACTIONDEF2[4] | extraActions | See below for ACTIONDEF2. |
ACTIONDEF handles open, close, move actions. It is defined as follows:
DataType | Name | Description |
BYTE | animNum | Animation number to play when interacting. 99 means a TLK script is to be loaded. |
BYTE | unknown | unknown purpose |
char[4][12] | names | Names of other room objects to toggle or TLK scripts to load. |
ACTIONDEF2 handles other actions like pickup. It is defined as follows:
DataType | Name | Description |
BYTE | animNum | Animation number to play when interacting. 99 means a TLK script is to be loaded. |
BYTE | unknown | unknown purpose |
char[4][12] | names | Names of other room objects to toggle or TLK scripts to load. |
INT16LE | flag | story progress flag, either a prerequisite for or result of the action. |
BYTE[6] | unknown | always 0 |
char[12] | lastName | Always contains either a TLK script name, or special tags like *SELF*, *PICKUP*. |
Sequence Structure
Coming soon.
Credits
This file format was reverse engineered by Ceidwad. If you find this information helpful in a project you're working on, please give credit where credit is due. (A link back to this wiki would be nice too!)