Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision |
fundamentals [2017/01/05 12:22] – [File Types] zdimension | trs:savegame:trs:fundamentals [2017/02/04 16:32] – ↷ Links adapted because of a move operation zdimension |
---|
===== File Types ===== | ===== File Types ===== |
| |
Tomb Raider is driven by various sets of files — [[file_formats|level files]], [[scripting_tr2_tr3|script]] [[scripting_tr4_tr5|files]], FMVs, [[sound#audio_tracks|audio tracks]] and [[sound#sound_files|sound files]]. In TR4 and TR5, there is also specific file type which contains cutscene data — [[cutseq|cutseq pack]]. | Tomb Raider is driven by various sets of files — [[trs:savegame:trs:file_formats|level files]], [[trs:scripting_tr2_tr3|script]] [[trs:scripting_tr4_tr5|files]], FMVs, [[trs:sound#audio_tracks|audio tracks]] and [[trs:sound#sound_files|sound files]]. In TR4 and TR5, there is also specific file type which contains cutscene data — [[trs:savegame:trs:cutseq|cutseq pack]]. |
| |
==== The Script Files ==== | ==== The Script Files ==== |
Since TR4, the level file is divided into //several chunks//, each of them being compressed with //zlib//. Usually, each chunk of compressed data is preceded by two 32-bit unsigned integers defining the //uncompressed size// of the chunk and the //compressed size// of the chunk. Therefore, the engine allocates an empty buffer equal to the //uncompressed size// of a specific chunk, and another buffer equal to the //compressed size//. The compressed data is loaded directly within it based on the //compressed size//. The compressed data is then decompressed into the result buffer and the buffer containing the compressed data is destroyed. In TR5, those chunks aren’t compressed anymore. | Since TR4, the level file is divided into //several chunks//, each of them being compressed with //zlib//. Usually, each chunk of compressed data is preceded by two 32-bit unsigned integers defining the //uncompressed size// of the chunk and the //compressed size// of the chunk. Therefore, the engine allocates an empty buffer equal to the //uncompressed size// of a specific chunk, and another buffer equal to the //compressed size//. The compressed data is loaded directly within it based on the //compressed size//. The compressed data is then decompressed into the result buffer and the buffer containing the compressed data is destroyed. In TR5, those chunks aren’t compressed anymore. |
| |
> **Note** | <note> |
> | It’s good to note the origins of level file extension. While it is obvious that TR2/TR4/TRC extensions specify abbreviations of the game name. ''%%.PHD%%'' is actually the initials of the //Lead Programmer// for Tomb Raider 1: //Paul Howard Douglas//. Looks like this programmer contributed a lot of the code during early development stages of Tomb Raider. This is suggested because the //phd// initials also became a prefix for several helper functions in the original source code, for instance: ''%%phd_sin%%'', ''%%phd_cos%%'' etc. Most likely, he was also responsible for developing the level file structure for Tomb Raider. |
> It’s good to note the origins of level file extension. While it is obvious that TR2/TR4/TRC extensions specify abbreviations of the game name. ''%%.PHD%%'' is actually the initials of the //Lead Programmer// for Tomb Raider 1: //Paul Howard Douglas//. Looks like this programmer contributed a lot of the code during early development stages of Tomb Raider. This is suggested because the //phd// initials also became a prefix for several helper functions in the original source code, for instance: ''%%phd_sin%%'', ''%%phd_cos%%'' etc. Most likely, he was also responsible for developing the level file structure for Tomb Raider. | </note> |
| |
==== FMVs (Full Motion Videos) ==== | ==== FMVs (Full Motion Videos) ==== |
There are certain cases where special caution must be paid. A multiplication $f = f_1 \cdot f_2$ must be calculated as | There are certain cases where special caution must be paid. A multiplication $f = f_1 \cdot f_2$ must be calculated as |
| |
$f = f_1 \cdot f_2 \Leftrightarrow (p_1/2^{16}) \cdot (p_1/2^{16}) \Leftrightarrow f = \frac{p_1 \cdot p_2}{2^{16}} \Leftrightarrow p \cdot 2^{16} = \frac{p_1 \cdot p_2}{2^{16}} \Leftrightarrow p = \frac{p_1 \cdot p_2}{2^{32}}$ | $f = f_1 \cdot f_2 \Leftrightarrow f = (p_1/2^{16}) \cdot (p_1/2^{16}) \Leftrightarrow f = p/2^{16} = \frac{p_1 \cdot p_2}{2^{32}} \Leftrightarrow p = \frac{p_1 \cdot p_2}{2^{16}}$ |
| |
==== Data Alignment ==== | ==== Data Alignment ==== |
The only difference is the extra field ''%%Effects%%''. It has this layout: | The only difference is the extra field ''%%Effects%%''. It has this layout: |
| |
* //Bit 0:// if set, face has //additive alpha blending// (same meaning that when the ''%%Attribute%%'' field of [[miscellany#tr_object_texture|[tr_object_texture]]] is 2, but this flag overrides it). | * //Bit 0:// if set, face has //additive alpha blending// (same meaning that when the ''%%Attribute%%'' field of [[trs:miscellany#tr_object_texture|[tr_object_texture]]] is 2, but this flag overrides it). |
| |
|{{:illustrations:face_blend.jpg?nolink|illustrations/face_blend.jpg}}|{{:illustrations:face_noblend.jpg?nolink|illustrations/face_noblend.jpg}}| | |{{:illustrations:face_blend.jpg?nolink|illustrations/face_blend.jpg}}|{{:illustrations:face_noblend.jpg?nolink|illustrations/face_noblend.jpg}}| |