This version is outdated by a newer approved version.DiffThis version (2020/05/19 12:49) was approved by zdimension.The Previously approved version (2020/05/19 12:33) is available.Diff

Miscellany

These are various odds and ends that do not fit into the earlier categories.

Version

Every level file begins with a uint32_t version number. This seems to be used by the engine to guarantee compatibility between various level editor versions and the game engine version. More generally, it can be used to determine what sort of level is being read.

Here are the known (observed) values for the version header:

  • 0x00000020 — Tomb Raider 1, Gold, Unfinished Business
  • 0x0000002D — Tomb Raider 2, Gold
  • 0xFF180038 — Tomb Raider 3, Gold, Gold Title level
  • 0xFF080038 — Tomb Raider 3 (Title level on Normal)
  • 0xFF180034 — Tomb Raider 3 (VICT.TR2 that only contains palette and atlases)
  • 0x00345254 (TR4 ) — Tomb Raider 4 and Tomb Raider 5
  • 0x63345254 (TR4c) — Tomb Raider 4 (demo versions)
Early TR4 demos (e.g. September 15 demo) have whole level file packed into a single zlib chunk. Therefore, there is no header.
TR5 version header is equal to TR4 version header. So there is no way to tell TR4 level from TR5 level judging only by this header — you need to check filename extension as well.
As it was noted, retail version of TR4 expects to load sound samples compressed in MS-ADPCM format, while TRLE version of TR4 loads uncompressed samples only. There is no way to tell retail version from TRLE version, as their version numbers are equal.

Palette

This consists of 256 [tr_colour] structs, one for each palette entry. However, the individual colour values range from 0 to 63; they must be multiplied by 4 (or bitshifted by 2 to the left) to get the correct values. Palette is used for all 8-bit colour, such as 8-bit textures.

TR1 only First entry in palette is treated as transparent colour used for textures with alpha testing. In later games, transparent colour was replaced by so-called “magenta transparency”, meaning that any pixel with red and blue values at maximum and green value at zero, is treated as completely transparent.

Object Textures

An object texture (or texture details in TRLE terms) keeps detailed information about each texture independently used in the game. While it’s not a texture image itself (these are kept inside texture atlases), it’s rather a reference to a particular texture in an atlas, kept with all other necessary information to display this texture.

Object Texture Vertex Structure

This sub-structure used by object textures specifies a vertex location in texture tile coordinates. The Xcoordinate and Ycoordinate are the actual coordinates of the vertex's pixel. If the object texture is used to specify a triangle, then the fourth vertex's values will all be zero.

struct tr_object_texture_vert // 4 bytes
{
    ufixed16 Xcoordinate;
    ufixed16 Ycoordinate;
};
Actual texture coordinade format was unknown before the end of 2017, when TE developer MontyTRC uncovered that used format is similar to fixed-point format used for fractional values in animation structures, yet it uses 2 bytes instead of 4 (i.e. one byte for whole part and another for fractional part). However, since classic TR games built with native tools produced only whole coordinates (e.g. 64×64, 16×32, and so on) and there was no occurence of seeing fractional coordinates in levels, for many years it was believed that low byte in each field must always be of specific value (not 0 as expected, but either 1 or 255 which is probably caused by rounding error in Core's native conversion tools).

Object Texture Structure (TR1-3)

It’s object texture structure itself. These, thee contents of ObjectTextures[], are used for specifying texture mapping for the world geometry and for mesh objects.

struct tr_object_texture  // 20 bytes
{
    uint16_t               Attribute;
    uint16_t               AtlasAndFlag;
    tr_object_texture_vert Vertices[4]; // The four corners of the texture
};

AtlasAndFlag is a combined field:

  • Bits 0..14 specify the texture atlas to use. On PC, the value should be between 0 and 63 (inclusive).
  • Bit 15: TR4 onlyTR5 only if set, it indicates that the texture is used on a triangle face.

Attribute specifies transparency mode (i.e. blending mode) used for face with this texture applied. There are several ones available:

  • 0 — Texture is all-opaque, and that transparency information is ignored.
  • 1 — Texture uses alpha testing, i.e. it may contain opaque and completely transparent regions. In 8-bit colour, index 0 is the transparent colour, while in 16-bit colour, the top bit (0x8000) is the alpha channel (1 = opaque, 0 = transparent). In 32-bit textures, transparency is specified by full magenta colour value (RGB = 255,0,255) — i.e. pixel has to be magenta to be transparent.
  • 2 — TR3 onlyTR4 onlyTR5 only Texture uses alpha blending with additive operation. No depth sorting is done on alpha-blended textures.
While blending modes 0, 1 and 2 were the only ones directly available for implementation in original level and animation editors, and therefore, only ones which can be encountered in object textures, there are actually several internal blending modes, which were primarily used for different sprite and particle types. These will be listed below:
  • 3 — Not implemented properly in PC version, but on PlayStation this type produces alpha blending with inversion operation, thus converting all the bright zones to dark, and dark zones to bright. This blending mode was used for smooth textured shadows, footprints and black smoke sprites. There is a remnant of this blending mode in the form of entity type named smoke emitter black.
  • 4 — Alpha-tested face without Z testing, i.e. depth information is ignored. Used for GUI elements (such as fonts) and skyboxes.
  • 5 — Unused. Possibly was used in PlayStation versions.
  • 6 — Wireframe mode. Used for “line particles”, such as gun sparks, water drops and laser beams. Possibly was also used for debug purposes.
  • 7 — TR4 onlyTR5 only Forced alpha value. It’s ordinary alpha-tested face, but alpha value for this face is overridden with global variable. Used to “fade out” specific meshes, like vanishing enemy bodies or Semerkhet ghost in “Tomb of Semerkhet” level.

Object Texture Structure (TR4-5)

The structure introduced many new fields in TR4, partly related to new bump mapping feature.

For bump mapping, TR4 used fairly simple approach, which was actually not a true bump mapping, but multitexturing with additive operation. Therefore, bump maps were not normal maps mainly used for bump-mapping nowadays, but simple monochrome heightmaps automatically generated by level editor. This is a test screenshot comparison demonstrating same scene with and without bump mapping:

illustrations/bump-no.jpgillustrations/bump-yes.jpg
Bump mapping turned off Bump mapping turned on

Assignment of bump maps happened inside level editor, where each texture piece could be marked as either level 1 or level 2 of the bump map effect. When the level was converted, all texture pieces with bumpmaps were placed into separate texture atlases after all other texture atlases, followed by the same amount of texture atlases with auto-generated bump maps arranged in the same manner as the original texture atlases. The number of bump map atlases was kept in a separate variable as well (see TR4 Level Format section).

So, when the engine rendered a face with a texture marked as bump-mapped, it rendered the original texture first, then it jumped to the texture atlas plus the number of bump-mapped texture atlases, and rendered one more texture pass on this face using the texture from the resulting texture atlas and the same UV coordinates.

struct tr4_object_texture // 38 bytes
{
    uint16_t               Attribute;
    uint16_t               AtlasAndFlag;
    uint16_t               NewFlags;
 
    tr_object_texture_vert Vertices[4]; // The four corners of the texture
 
    uint32_t               OriginalU;
    uint32_t               OriginalV;
    uint32_t               Width;     // Actually width-1
    uint32_t               Height;    // Actually height-1
};

NewFlags is a bit field with flags:

  • Bits 0..2 — Mapping correction. This value is used by internal AdjustUV function which crops the texture in specific way to prevent border bleeding issue happening because of texture atlas packing. Value meaning depends on texture face type (triangle or quad). For quads, only types 0 and 1 are actually used (0 being normal and 1 being mirrored quad texture), while other types (2-7) produce same result as 0. For triangles, all possible values (0-7) are used for each possible right triangle type (including mirrored coordinates):
illustrations/mapping-correction.png
Triangle mapping correction types. Orange shapes indicate normal (non-mirrored) texture coordinates, while blue shapes indicate mirrored ones. Mirrored coordinates mean that they are placed in counterclockwise order.
  • Bits 9..10 — Specifies bump mapping level (see above), so can be either 00 = 0 (no bump mapping), 01 = 1 (level 1) or 10 = 2 (level 2).
  • Bit 15 — If set, the texture is for a triangle/quad from a room geometry. If not set, the texture is for a static mesh or model.

Width and Height are helper values which specify width and height for a given object texture.

OriginalU and OriginalV are unused values, which seem to identify original UV coordinates of object texture in TRLE texture page listings. These coordinates are getting messed up when level is compiled, so one shouldn’t bother about parsing them correctly.

TR5 only There is also null uint16_t filler in the end of each [tr4_object_texture].

Animated Textures

Animated textures describe sets of object textures that are cycled through to produce texture animations; they are a set of int16_t’s with the following format (not a “real” C/C++ structure):

int16_t NumAnimatedTextures
 
virtual struct
{
    int16_t NumTextureIDs; // Actually, this is the number of texture ID's - 1.
    int16_t TextureIDs[NumTextureIDs + 1]; // offsets into ObjectTextures[], in animation order.
} AnimatedTextures[NumAnimatedTextures];

If a texture belongs to an animated-texture group, it will automatically be animated by the engine.

There are two types of animated textures — classic frames and UVRotate:

  • Classic frames: These are ordinary animated textures, and the only type displayed prior to TR4. It is simply a list of textures that are cycled through in an endless loop; they are normally used as geographic elements of the levels (e.g. water surface, bubbling lava, Atlantean flesh walls), but practically, Tomb Raider engines are capable of applying animated textures to mesh geometry (this feature is primarily used in custom levels). The speed (interval) of animation is hardcoded, and varies from version to version. While in TR1-2 textures were animated relatively slowly, in TR3 onwards they were sped up.
  • UV Rotate: Beginning from TR4, there is a new scheme for animated textures, called UVRotate. According to its name, it continuously shifts vertical texture coordinate while preserving texture size, which creates an effect of moving texture. For example, you can see it in action in TR4’s angkor1.tr4, room #76:
illustrations/uvrotate.jpg
In foreground, you can see alpha-blended waterfall object animated with UVRotate. In background, UVRotate animation is also applied to room mesh.

UVRotate mode is engaged by specifying UVRotate command in level script entry, which takes rotation speed as an argument, where speed is amount of pixel shift per each frame, considering fixed 30 FPS framerate (speed value may be negative, and in such cases pixel shift occurs in reverse direction). If such command is found (and argument is not zero — for example, UVRotate = 4), engine uses special variable value kept in level file, NumUVRotates, to determine if animation range belongs to UVRotate mode or classic frames mode. Then, if it belongs to UVRotate mode, each frame of this range is treated as individual rotating texture.

There is also special case when UVRotate texture mode is engaged. When a texture is applied to a model with specific ID (so-called waterfall objects), then it is also considered UVRotate animated texture, even if it doesn’t belong to animated texture range, but only if it is a texture applied to a first face in the first mesh of the model. If there are other textures applied to other faces of a waterfall object, they won’t be considered as UVRotate.

The speed of animation for waterfall objects is not affected by UVRotate script command. Instead, it is hardcoded value of 7.

Cameras and Sinks

This data block serves for two different purposes, albeit keeping the same structure for both. First purpose is to provide positions to switch the camera to using Camera trigger action, and the second purpose is to move Lara to specified position when she is underwater, and Underwater Current trigger action was used.

struct tr_camera // 16 bytes
{
    int32_t  x;
    int32_t  y;
    int32_t  z;
    int16_t  Room;
    uint16_t Flag;
};

X, Y and Z values are coordinates of a given camera or sink. When used with camera, it is an origin point of a camera. When used with sink, it is a point, towards which Lara is pushed.

Room value specifies the room where camera is placed. For sink cases, this value is used to define strength of the current which moves Lara underwater.

Flag value for cameras specifies whether it’s possible to breakout from fixed camera angle. If first bit of this field is set, camera becomes persistent, and it’s not possible to bypass it with look or draw weapon buttons. For sinks, Flag value contains Box index — which is used as pathfinding reference when Lara is pushed towards sink via underwater current trigger action.

Flyby Cameras

TR4 onlyTR5 only Flyby cameras are cinematic interludes, in which camera flies from one point to another using spline trajectory. Each point in such sequence is a single flyby camera, and current camera properties (position, direction, roll, FOV, speed, and some more) are calculated by interpolating corresponding values from such flyby camera points — for example, if camera 0 has speed value of 10, and camera 1 has speed value of 5, then speed will gradually change from 10 to 5 when moving from one to another.

struct tr4_flyby_camera  // 40 bytes
{
    int32_t  x;    // Camera position
    int32_t  y;
    int32_t  z;
    int32_t  dx;   // Camera angles (so called "look at" vector)
    int32_t  dy;
    int32_t  dz;
 
    uint8_t  Sequence;
    uint8_t  Index;
 
    uint16_t FOV;
    int16_t  Roll;
    uint16_t Timer;
    uint16_t Speed;
    uint16_t Flags;
 
    uint32_t Room_ID;
};

Sequence is a number of flyby camera “chain” this particular camera belongs to. Maximum amount of flyby sequences in single level is 8 (however, this limit was raised to 64 in TREP).

Index specifies order of the cameras in this particular sequence. Camera with index 0 will be first one in sequence, index 1 means camera will be second in sequence, and so on.

Room_ID should be valid for a given flyby camera, so it will display properly, as well as have the ability to activate heavy triggers.

FOV changes this particular camera’s field of view. The value is 182 times higher than the value entered in the TRLE.

Roll changes roll factor of a particular camera. When this parameter is not zero, camera will rotate either left or right along roll axis, creating so-called “dutch angle”. The value is 182 times higher than the value entered in the TRLE.

Timer field mainly used to stop camera movement for a given time (in game frames). As this parameter is temporal, it won’t be interpolated between two cameras.

Speed specifies movement speed for this particular camera. The value is 655 times higher than the value entered in the TRLE.

Flags is an array of bit flags specifying different camera options:

Hex Bit Description
0x0001 0 Make a cut to flyby from Lara camera position. Without it, it’ll pan smoothly.
0x0002 1 TR4 only Tracks specified entity position (from Entities[] array).
TR5 only Creates a vignette around the picture, giving impression of “subjective” camera.
0x0004 2 Infinitely loop sequence.
0x0008 3 Used only with first camera in a sequence: whole sequence is treated merely as a camera “rails”, and camera itself focuses on Lara, thus creating “tracking” camera. Best example is “tracking” view in ALEXHUB2.TR4, rooms #23 and #31.
0x0010 4 TR4 only Camera focuses on Lara’s last head position.
TR5 only For TR5, this flag is now used to hide Lara for this camera.
0x0020 5 Camera continuously focuses on Lara’s head, overriding own angle.
0x0040 6 Used only with last camera in a sequence: camera smoothly pans back to Lara camera position.
0x0080 7 When flyby arrives to this position, cuts to specific camera in same sequence. Next camera number is specified in Timer field of this camera.
0x0100 8 Stops camera movement for a given time (see Timer field).
0x0200 9 Disables look keypress breakout.
0x0400 10 Disables all Lara controls for all next camera points. Also engages widescreen bars to create cinematic feel.
0x0800 11 Overrides Bit 10 controls lock, enabling them back. Widescreen bars remain unaffected.
0x1000 12 TR5 only Make screen fade-in.
0x2000 13 TR5 only Make screen fade-out.
0x4000 14 Camera can activate heavy triggers, just like particular kinds of entities (boulders, pushables, etc.). When camera is moving right above heavy trigger sector, it will be activated.
0x8000 15 TR5 only TRLE for TR5 says this flag is used to make camera one-shot, but it’s not true. Actual one-shot flag is placed in extra uint16_t field at 0x0100 for flyby camera TrigAction.

Cinematic Frames

These are camera positionings and properties for cutscene frames. All the entity animations are specified separately, and they are not synced with actual camera positions.

TR1 only For each cutscene, game applies certain hardcoded set of parameters:
switch (CutLevelID) {
    case 0: // CUT1.PHD
        levelPosX = 36668;	// X pivot position
        levelPosZ = 63180;      // Z pivot position
        levelRotY = -23312;     // Y rotation
        trackID = 23;		// Audio track index
        break;
    case 1: // CUT2.PHD
        levelPosX = 51962;
        levelPosZ = 53760;
        levelRotY = 16380;
        trackID = 25;
        break;
    case 2: // CUT3.PHD
        levelRotY = 0x4000;     // Default rotation, 90 degrees
        FlipMap();		// Do a flipmap
        trackID = 24;
        break;
    case 3: // CUT4.PHD
        levelRotY = 0x4000;
        trackID = 22;
        break;
}

levelPosX, levelPosZ and levelRotY parameters are used, if defined, to set-up initial camera pivot position and Y axis rotation. If some of these parameters are not defined (which is the case for CUT3.PHD and CUT4.PHD), they are borrowed from X and Z position and Y rotation of entity with ID #77 (slot used for main cutscene actor, usually Lara). Also, same parameters are used as master model matrix (i. e. multiplied by them instead of using their own position and rotation) for models with IDs #77-79 (which are slots for cutscene actors).

struct tr_cinematic_frame // 16 bytes
{
    int16_t targetX; // Camera look at position about X axis, 
    int16_t targetY; // Camera look at position about Y axis
    int16_t target2; // Camera look at position about Z axis
    int16_t posZ;    // Camera position about Z axis
    int16_t posY;    // Camera position relative to something (see posZ)
    int16_t posX;    // Camera position relative to something (see posZ)
    int16_t fov;
    int16_t roll;    // Rotation about X axis
};

All target and pos parameters, as well as roll parameter, are encoded in the same manner as Angle parameter for [tr_entity] structure.

LightMap

A 32*256 array of uint8_t which is apparently for applying light to 8-bit colour, in some documentation called ColourMap. The current palette index and lighting value are used to calcuate an index to this table, which is a table of palette indices.

The Tomb Raider series' software rendering, like that of most real-time-3D games, uses 8-bit colour for speed and low bulk; however, there is the serious problem of how to do lighting with 8-bit colour, because doing it directly is computationally expensive. The usual solution is to arrange the palettes' colours in ramps, which the engine then follows in the appropriate directions. However, the TR series' palettes generally lack such neat ramps.

But the TR series has a more general solution, one that does not require palettes to have colour ramps. It uses precalculated lighting tables, the ColourMap objects. These contain translations of a colour value and a lighting value, listed by palette index. The translation goes as follows:

$n = ColourMap[256 \cdot k + i]$

where $i$ is the original palette index, $k$ is determined from the lighting value, and $n$ is the new palette index. The lighting index $k$ varies from $0$ to $31$, and the corresponding lighting value is $2 - k / 16$ for TR1 and $2 - (k + 1) / 16$ for TR2 and TR3.

This may be associated with the curious fact of the lighting values in the data files increasing in the “wrong” direction in TR1 and TR2, with $0$ being full brightness and greater values being darker.

Flipeffects

The Concept

As it was briefly mentioned earlier, flipeffect is a special pre-compiled routine which is called when some non-trivial event occurs.

The concept of flipeffect is somewhat similar to task, i.e. when some flipeffect is engaged, it could be flagged by engine to call every game frame (however, there are primarily one-shot flipeffects present). Such setup is needed for some complex flipeffect events, like flickering lights in TR1 Atlantis (see FLICKER_FX description), which stops automatically after some time.

If flipeffect is flagged to execute every game frame, this flag can only be unset by own current flipeffect code (when its task is done — for this purpose, special internal flip timer is used to count how much time have passed since flipeffect activation) or replaced by any other flipeffect call (however, newly called flipeffect doesn’t necessarily overwrite current flipeffect flag, so you can have one-shot flipeffect executed with another one queued for continuous execution). Ergo, it’s not possible to queue more than one _continuous flipeffect at a time, but it’s possible to have one one-shot and another continuous flipeffect executed every game frame.

Continuous flipeffects are mostly present in TR1 and TR2. In TR3, only two “legacy” continuous flipeffects remained, and in TR4 and TR5 there are no continuous flipeffects at all. However, there’s still legacy code that checks if there’s any continuous flipeffect queued.

Complete Flipeffect List

In this chapter, we’ll try to describe each flipeffect for every TR engine version. Given the fact that flipeffect listing changed from version to version, yet retaining common ones, the easiest way to lay them down is to create a table with flipeffect indexes corresponding to each game version.

There are some guidelines to flipeffect table:

  • It’s possible that same flipeffect goes under different names in different game versions. In this case, legacy flipeffect name will be preserved (for historical [sic] reasons), and description will point to a flipeffect with more recent name. Legacy flipeffect names would be colored in green.
  • Flipeffect names are directly brought from native SDK or debug listings, where available (namely TR1, TR2, and TR4). When native names are wrong (which happens in TR4 and TR5 listings), new ones will be coined. New flipeffect names would be colored in purple.
  • It’s possible that legacy flipeffect code could migrate to later engine version without changes, but could be broken due to missing code in another part of engine or changes in internal structures. In this case, flipeffect name would be colored in red.
  • If there’s an entry in engine’s flipeffect list, but no actual code for it, it would be marked as (-).
  • If actual flipeffect’s purpose is unknown, it would be marked as (?).
  • If flipeffect ought to be continuous, it will be marked in bold.
As mentioned here, flipeffect could be called in two ways — either by an entity via AnimCommand, or by trigger action. However, there are certain flipeffect which strictly require caller entity ID to work with (see effect descriptions for that). In such case, if flipeffect is called by trigger action, resulting outcome is undefined in original engine. The most sane way to deal with this situation is to pass an ID of entity which activated given trigger.

On contrary, some flipeffects may require certain trigger action and/or certain trigger type to be called at the moment. In such case, if flipeffect is called via AnimCommand, resulting outcome is undefined in original engine.

IndexTR1 TR2 TR3 TR4 TR5
0 TURN180 TURN180 TURN180 ROTATE_180 ROTATE_180
1 DINO_STOMP FLOOR_SHAKE FLOOR_SHAKE FLOOR_SHAKE FLOOR_SHAKE
2 LARA_NORMAL LARA_NORMAL LARA_NORMAL FLOOD_FX FLOOD_FX
3 LARA_BUBBLES LARA_BUBBLES LARA_BUBBLES LARA_BUBBLES LARA_BUBBLES
4 FINISH_LEVEL FINISH_LEVEL FINISH_LEVEL FINISH_LEVEL FINISH_LEVEL
5 EARTHQUAKE_FX FLOOD_FX FLOOD_FX ACTIVATE_CAMERA ACTIVATE_CAMERA
6 FLOOD_FX CHANDELIER_FXCHANDELIER_FXACTIVATE_KEY ACTIVATE_KEY
7 RAISINGBLOCK_FX RUBBLE_FX RUBBLE_FX RUBBLE_FX RUBBLE_FX
8 STAIRS2SLOPE_FXPISTON_FX PISTON_FX SWAP_CROWBAR SWAP_CROWBAR
9 SAND_FX CURTAIN_FX CURTAIN_FX - -
10 POWERUP_FX SETCHANGE_FX SETCHANGE_FX TIMER_FIELD_FXTIMER_FIELD_FX
11 EXPLOSION_FX EXPLOSION_FX EXPLOSION_FX EXPLOSION_FX EXPLOSION_FX
12 LARA_HANDSFREE LARA_HANDSFREE LARA_HANDSFREE LARA_HANDSFREE LARA_HANDSFREE
13 FLIP_MAP FLIP_MAP FLIP_MAP - -
14 DRAW_RIGHTGUN DRAW_RIGHTGUN DRAW_RIGHTGUN DRAW_RIGHTGUN -
15 CHAINBLOCK_FX DRAW_LEFTGUN DRAW_LEFTGUN DRAW_LEFTGUN -
16 FLICKER_FX - SHOOT_RIGHTGUN SHOOT_RIGHTGUN SHOOT_RIGHTGUN
17 - SHOOT_LEFTGUN SHOOT_LEFTGUN SHOOT_LEFTGUN
18 MESH_SWAP1 MESH_SWAP1 MESH_SWAP1 -
19 MESH_SWAP2 MESH_SWAP2 MESH_SWAP2 -
20 MESH_SWAP3 MESH_SWAP3 MESH_SWAP3 -
21 INV_ON INV_ON INV_ON INV_ON
22 INV_OFF INV_OFF INV_OFF INV_OFF
23 DYN_ON DYN_ON - -
24 DYN_OFF DYN_OFF - -
25 STATUE_FX STATUE_FX - -
26 RESET_HAIR RESET_HAIR RESET_HAIR RESET_HAIR
27 BOILER_FX BOILER_FX - -
28 ASSAULT_RESET ASSAULT_RESET SETFOG SETFOG
29 ASSAULT_STOP ASSAULT_STOP GHOSTTRAP -
30 ASSAULT_START ASSAULT_START LARALOCATION LARALOCATION
31 ASSAULT_FINISHED ASSAULT_FINISHED CLEARSCARABS RESET_TEST (?)
32 FOOTPRINT_FX FOOTPRINT_FX FOOTPRINT_FX
33 ASSAULT_PENALTY_8 - CLEAR_SPIDERS_PATCH (?)
34 RACETRACK_START - -
35 RACETRACK_RESET - -
36 RACETRACK_FINISHED - -
37 ASSAULT_PENALTY_30 - -
38 GYM_HINT_1 - -
39 GYM_HINT_2 - -
40 GYM_HINT_3 - -
41 GYM_HINT_4 - -
42 GYM_HINT_5 - -
43 GYM_HINT_6 POURSWAP_ON -
44 GYM_HINT_7 POURSWAP_OFF -
45 GYM_HINT_8 LARALOCATIONPAD LARALOCATIONPAD
46 GYM_HINT_9 KILLACTIVEBADDIES KILLACTIVEBADDIES
47 GYM_HINT_10 TUT_HINT_1
48 GYM_HINT_11 TUT_HINT_2
49 GYM_HINT_12 TUT_HINT_3
50 GYM_HINT_13 TUT_HINT_4
51 GYM_HINT_14 TUT_HINT_5
52 GYM_HINT_15 TUT_HINT_6
53 GYM_HINT_16 TUT_HINT_7
54 GYM_HINT_17 TUT_HINT_8
55 GYM_HINT_18 TUT_HINT_9
56 GYM_HINT_19 TUT_HINT_10
57 GYM_HINT_RESET TUT_HINT_11
58 TUT_HINT_12
In original engines, all flipeffects which name begins with LARA_ prefix automatically take Lara character as an entity to work with. Also, most flipeffects with _FX postfix are simple sound effect events.
  • ROTATE_180 — Rotates an entity 180 degrees around yaw axis and also around pitch axis for underwater cases. Mostly used in Lara roll animations. This flipeffect needs special approach if original animation frames are interpolated, because usually rotation is done on animation transition (e.g., frame 5 of Lara animation 48, which is second and final part of her roll movement). To prevent stray misaligned interpolated frames, this flipeffect must be performed only in the end of frame-to-frame interpolated sequence.
  • TURN180 — Same as ROTATE_180.
  • LARA_NORMAL — Resets certain internal Lara parameters to default ones, including movement modes, FOV and camera position.
  • FLOOR_SHAKE — If entity producing this effect is in less than 8 sector range, send shake effect to camera. Shake effect is a variable which is inversely proportional to entity distance, and, when sent to camera, makes it shake with corresponding amplitude gradually fading out. If there are multiple FLOOR_SHAKE events constantly occuring nearby camera, shake effect won’t accumulate, but rather overwrite previous value.
  • DINO_STOMP — Same as FLOOR_SHAKE.
  • LARA_BUBBLES — When underwater, emit bubble sound (ID #37) and produce bubble particle for Lara. Position of bubble is linked to model’s last mesh (which is headmesh in case of Lara).
  • FINISH_LEVEL — Same effect as TrigAction 0x07 — immediately loads next level. For TR4, (which requires explicit level index to jump), current level index is increased and passed as level index to jump to.
  • FLIP_MAP — Equal to TrigAction 0x03.
  • ACTIVATE_CAMERA — If there is a trigger type Key (SubFunction 0x03) being queued at the moment, and there are any Camera TrigActions (0x01) present in ActionList, these TrigActions will be forced to activate at a given frame of keyhole entity current animation, rather than at the ending frame of it. Works only for keyhole entities which have complex activation animations, not single-frame ones. It can be used to change camera POV before keyhole animation is finished.
  • ACTIVATE_KEY — Same as above, but works for Object TrigAction. That is, any entities to be activated from ActionList will be activated at a given frame of keyhole entity current animation, rather than at the ending frame of it. Can be used to activate entities before actual keyhole animation is finished.
  • LARA_HANDSFREE — Functionally removes any weapon from Lara’s hands. If called during holstering or unholstering operation, immediately aborts it. Note that holstering animation won’t be automatically performed, and weapon model meshswaps won’t be swapped back to normal hands.
  • DRAW_RIGHTGUN — Swaps given entity’s mesh #10 index with same mesh’s index from PISTOLS_ANIM model (model ID #1 in all TR versions). Calling this effect again swaps mesh #10 back to native. Used primarily in cutscenes to create an illusion of Lara getting pistol in her right hand.
  • DRAW_LEFTGUN — Swaps given entity’s mesh #13 index with same mesh’s index from PISTOLS_ANIM model (model ID #1 in all TR versions). Calling this effect again swaps mesh #13 back to native. Used primarily in cutscenes to create an illusion of Lara getting pistol in her left hand.
  • SHOOT_RIGHTGUN — Activates given entity’s muzzle flash effect and dynamic light near mesh #10. Muzzle flash position and orientation, as well as effect duration and intensity is hardcoded. Used primarily in cutscenes.
  • SHOOT_LEFTGUN — Activates given entity’s muzzle flash effect and dynamic light near mesh #13. Muzzle flash position and orientation, as well as effect duration and intensity is hardcoded. Used primarily in cutscenes.
  • MESH_SWAP1 — Swaps all given entity meshes with MESH_SWAP1 model meshes (model ID varies across TR versions). Each mesh is swapped only if source meshswap model mesh is not null, otherwise swap is ignored for a given mesh. Calling this flipeffect again swaps all meshes back to native. Used primarily in cutscenes.
  • MESH_SWAP2 — Swaps all given entity meshes with MESH_SWAP2 model meshes (model ID varies across TR versions). Each mesh is swapped only if source meshswap model mesh is not null, otherwise swap is ignored for a given mesh. Calling this flipeffect again swaps all meshes back to native. Used primarily in cutscenes.
  • MESH_SWAP3 — Swaps all given entity meshes with MESH_SWAP3 model meshes (model ID varies across TR versions). Each mesh is swapped only if source meshswap model mesh is not null, otherwise swap is ignored for a given mesh. Calling this flipeffect again swaps all meshes back to native. Used primarily in cutscenes.
  • SWAP_CROWBAR — Swaps given entity’s mesh #10 index with same mesh’s index from CROWBAR_ANIM model (either model ID #246 in TR4, or model ID #240 in TR5). Calling this flipeffect again swaps mesh #10 back to native. Used primarily in cutscenes to create an illusion of Lara getting crowbar in her hand.
  • POURSWAP_ON — Swaps given entity’s mesh #10 index with same mesh’s index from LARA_WATER_MESH model (TR4, modei ID #25). Used in Lara’s waterskin animations used in late TR4 levels with waterskin puzzle.
  • POURSWAP_OFF — Swaps given entity’s mesh #10 back to native. Used in Lara’s waterskin animations used in late TR4 levels with waterskin puzzle.
  • INV_ON — Hides given entity.
  • INV_OFF — Shows given entity, if it was hidden.
  • DYN_ON — Turns dynamic lights on for a given entity. Actual result is unclear.
  • DYN_OFF — Turns dynamic lights off for a given entity. Actual result is unclear.
  • RESET_HAIR — Presumably used to save Lara’s ponytail from potential stuck during cutscenes by resetting all hair parameters to “identity”.
  • SETFOG — When called by trigger action, changes global colour for volumetric fog effect. Takes TriggerSetup Timer field as an index into hardcoded RGB table of colours (see this section for more info). If specified index is 100, engine temporarily turns off volumetric fog effect (possibly, this was used for debug purposes).
  • GHOSTTRAP — Kills all the living WRAITH3 entities (model ID #88 in TR4) this way: the wraith starts falling towards given entity. Reaching it or not, the wraith will die if it hits the floor of the room.
  • CLEARSCARABS — Removes all swarms of scarabs currently wandering in level.
  • KILLACTIVEBADDIES — Disable and remove all active NPCs from level.
  • CLEAR_SPIDERS_PATCH — Present only in TR5. It seems it’s same as KILLACTIVEBADDIES, but some other processing is done. Never used in actual levels.
  • RESET_TEST — Present only in TR5. No visible or significant effect on gameplay. If there are any NPCs in level, then this flipeffect will fill certain memory zone with zero bytes. This flipeffect seems like last-minute fix-up for some memory leak bug. Used in RICH1.TRC level (The 13th Floor)
  • LARALOCATION — When activated, makes Guide NPC (TR4, model ID #37) or Von Croy NPC (TR4, model ID #39) to move to specific AI_FOLLOW object. Takes TriggerSetup Timer field as an index to search for such OCB within AI objects array. When AI_FOLLOW AI object with same OCB index is found, NPC is then directed to this AI_FOLLOW object. This flipeffect also stores this index in additional global variable which is used to prevent NPC to get back to AI_FOLLOW objects with lower OCB indexes that were already passed — for example, if NPC already passed AI_FOLLOW with OCB 2, he won’t return to AI_FOLLOW with OCB 1, even if he hasn’t been there before.
  • LARALOCATIONPAD — Same action as LARALOCATION, but with one difference - Timer field is checked for certain values to engage either specific soundtrack and/or cinematic dialogue with Von Croy NPC (for demonstration, look for Angkor Wat level walkthrough). This additional behaviour is hardcoded for TR4’s first level index only.
  • ASSAULT_RESET — Resets assault course clock (for ex., when Lara stepped out of assault course).
  • ASSAULT_STOP — Stops assault course clock.
  • ASSAULT_START — Starts assault course clock.
  • ASSAULT_FINISHED — Finishes assault course clock and fixes the record. Depending on record time, plays either unbeat record (“I’m sure you can do better”, track ID #24 in TR2) soundtrack or best record (“Gosh, that was my best time yet”, track ID #22 in TR2, #95 in TR3) soundtrack. Record time is hardcoded to 100 seconds in TR2 and to 180 seconds in TR3. In TR3, flipeffect also checks if all targets in shooting range were hit by Lara, and if not, applies penalty of 10 seconds for each unhit target. Also, TR3 lacks “unbeat record” soundtrack.
  • ASSAULT_PENALTY_8 — 8-second penalty for losing track on assault course.
  • ASSAULT_PENALTY_30 — 30-second penalty for losing track on assault course.
  • RACETRACK_START — Prepare racetrack timer for counting lap time. Only works when Lara is on a quadbike! As soon as quadbike leaves sector with this flipeffect, timer will start counting.
  • RACETRACK_RESET — Resets current lap time. Only works when Lara is on a quadbike!
  • RACETRACK_FINISHED — Finishes racetrack timer and fixes the record. Only works when Lara is on a quadbike!
  • GYM_HINT_1-19 — Sequence of Lara’s voice hints on how to complete gym training. Reason why these are activated via flipeffects rather than normal soundtrack is they must be engaged in predefined order, e.g. voice hint #8 can’t play before #7 was played, and so on.
  • GYM_HINT_RESET — Resets gym training progress, so all voice hints will be played once again.
  • TUT_HINT_1-12 — Sequence of Lara’s voice hints on how to complete tutorial on Streets of Rome (TR5). Setup is similar to GYM_HINT flipeffects, but seems that there’s no reset flipeffect to restart tutorial.
  • RAISINGBLOCK_FX — Plays global sound with ID 117. Used in TR1, Palace Midas.
  • CHAINBLOCK_FX — Plays global sounds with ID 173 and ID 33 with predefined interval. Used in TR1, Tomb of Tihocan.
  • EARTHQUAKE_FX — Shakes screen violently and plays sounds with ID 99 and 70 globally with predefined intervals. Used in TR1, Palace Midas.
  • STAIRS2SLOPE_FX — Plays global sound with ID 119 with predefined delay. Used in TR1, City of Khamoon.
  • SAND_FX — Plays global sounds with ID 161, 118 and 155 with predefined intervals. Used in TR1, City of Khamoon.
  • POWERUP_FX — Plays global sound with ID 155 for 1 second. Presumably used in TR1, one of the Atlantis levels, but never appears on map.
  • FLICKER_FX — Flips alternate rooms back and forth several times with predefined intervals, creating illusion of flickering light. Used in TR1, first room of Atlantis.
  • CHANDELIER_FX —  Plays global sound with ID 278 for 1 second. Used in TR2, Bartoli’s Hideout.
  • BOILER_FX — Plays global sound with ID 338. Used in TR2, Wreck of the Maria Doria.
  • PISTON_FX — Plays global sound with ID 190. Used in TR2, Living Quarters.
  • CURTAIN_FX — Plays global sound with ID 191. Used in TR2, Living Quarters.
  • SET_CHANGE_FX — Plays global sound with ID 330. Used in TR2, Opera House and Temple of Xian.
  • STATUE_FX — Plays global sound with ID 331. Used in TR2, Barkhang Monastery.
  • RUBBLE_FX — Plays global rumble sound FX and holds camera shake effect for some time, then finishes it with “shutting” sound. TR4 onlyTR5 only If there are any earthquake type objects in a level, engine engages same behaviour locally for these objects.
  • TIMER_FIELD_FX — If this flipeffect is called by trigger action, play global sound FX, taking TriggerSetup Timer field as a sound ID.
  • EXPLOSION_FX — Plays global explosion sound (ID #105) and produce full-screen flash graphical FX (TR3-5) or camera shake effect (TR1-2).
  • FLOOD_FX — Plays global flooding sound (TR1 — ID #81, TR2 — ID #79, TR3 — ID #163, TR4 — ID #238). Implementation differs from version to version — in TR1 and TR2 looped waterfall sound is used (which is then stopped by an engine after 1 second), while in TR3 and TR4 one-shot sound is engaged.
  • FOOTPRINT_FX — Plays random footprint sound effect, taking current block's material index into consideration. On PlayStation, also applies footprint sprite under left or right Lara foot (target foot is selected based on packed flag which is stored in animcommand argument — look here for details).
trs/miscellany.txt · Last modified: 2020/12/11 18:26 (external edit)
Back to top
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0