DO/PRJ
From Dark Omen Wiki
Bembelimen (Talk | contribs) (Add Category) |
Bembelimen (Talk | contribs) (Removed "Titleblatt" add a headline) |
||
Line 1: | Line 1: | ||
__TOC__ | __TOC__ | ||
- | + | ==Conventions and definitions:== | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | Conventions and definitions: | + | |
"Byte" signifies a 1-byte (8-bit) integer | "Byte" signifies a 1-byte (8-bit) integer |
Revision as of 02:15, 27 April 2008
Contents |
Conventions and definitions:
"Byte" signifies a 1-byte (8-bit) integer
"Long" signifies a Big-endian 4-byte (32-bit) integer (i.e. stored as "n¤¤¤")
"Array" denotes a literal sequence of characters
"String" denotes a sequence of characters ended with a NULL (0x00)
"¤" signifies a NULL (0x00)
"•" signifies a space (0x20)
The .PRJ Battle Project File Layout
The entry point of Dark Omen’s battle description is the .PRJ-file in each battle’s folder. It is a reasonable hypothesis that ".prj" stands for project, and just as reasonable that the name comes from an experimental phase or structure that happened to become the actual core, or that nobody could bother change the names to something more appropriate. Before delving into it, it is worth noting and keeping in mind that the PRJ format is really more or less a hack and is structurally and internally inconsistent, and contains several unconventional (not to say outright stupid) solutions.
Anyway, Dark Omen battles principally consist of a general description of the level (scene and battle) in the .prj-file, a .BTB-file ("BaTtle Boundaries"?) that specifies the deployment zone, a number of .M3D ("Model 3D"?) model files (the special format used in Dark Omen), and 8-bit 128x128 .BMP textures used by and specified in the M3D models.
The .PRJ-file is structured into a file format identification header and then into ten specialised blocks of binary data. The design of these blocks seems inspired by ignorance-friendly nested-block layouts (such as f.i. the .3DS file format) in that each block is systematically begun with a unique block ID header and block size value, thus apparently allowing blind/ignorant parsing, but since the implementation of the block size value is inconsistent the original Dark Omen code probably employs vanilla forward-parsing.
Project file general layout
Section | Notes | |
1 | "Dark•Omen•Battle•file•1.10••••••" | 32-byte file ID header |
2 | "BASE"-block | Map socket base and terrain block |
3 | "WATR"-block | Water mesh block |
4 | "FURN"-block | Meshes used ("furniture") block |
5 | "INST"-block | Furniture instances block |
6 | "TERR"-block | Terrain data entries block - this is the heightmap data, it means that the units don't fall through the ground mesh |
7 | "ATTR"-block | Block - Terrain attributes. This holds information about the type of terrain at each point. |
8 | "EXCL"-block | Block - Exclusions - unknown so far. Seems like it might have to do with Line of Sight |
9 | "MUSC"-block | Block - Music - the music file to play on this map |
10 | "TRAC"-block | Block - Camera track - this stores the camera sweep at the beginning of each match. |
11 | "EDIT"-block | Block - Assumed editor specific information. |
Data layout of subsections.
General block layout
Offset | Size | Type | Description |
0 | 4 | Array | Data block type identifier ("ID") |
4 | 4 | Long | Size of data block ("BSIZE", never less than 1) |
8 | BSIZE | … | Block data |
ID is one of these 4-character literals
- "BASE" – Map socket ("base", map cut-away edges)
- "WATR" – Waterline?
- "FURN" – 3D object on map ("Furniture")
- "INST" - ??
- "TERR" - ?? Terrain data ??
- ATTR
- EXCL
- MUSC
- TRAC
- EDIT
ID "BASE" block data layout
The BASE block layout is minimal with only a string as data. The "base" in a Dark Omen map is the terrain and the socket surrounding it. These are saved in two separate flies with identical names but different extensions.
Offset | Size | Type | Description |
0 | 4 | "BASE" | Base data block identifier |
4 | 4 | Long | Size of data block ("BSIZE", never less than 1) |
8 | BSIZE | String | Filename of socket mesh (generally "base.m3d") |
The socket has the filename as written in the data ("base.m3d"), while the terrain filename is obtained by replacing the extension with "m3x" ("base.m3x").
ID: "WATR" block data layout
Offset | Size | Type | Description |
0 | 4 | "WATR" | Water mesh data block identifier |
4 | 4 | Long | Size of data block ("BSIZE", never less than 1) |
8 | BSIZE | String | Filename of water mesh |
ID: "FURN" block data layout
The "FURN" (probably "FURNiture") block contains the file name of all 3D models used in the scene. These models are then referenced by number (1-based, where "0" indicated NO model is used) in INST entries (next section).
Offset | Size | Type | Description | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 4 | "FURN" | Water mesh data block identifier | |||||||||||||||
4 | 4 | Long | Size of data block less 4×F | |||||||||||||||
8 | 4 | Long | Number of furniture objects ("F") | |||||||||||||||
12 | BSIZE | Spec | List of filenames of furniture for map | |||||||||||||||
Repeat F times |
Notice that the BSIZE element of the FURN block is short by 4 × F bytes. The block size was calculated using only the length of the strings, and the size of the string length element was omitted.
ID: "INST" block data layout
The INST (probably "INSTances") block details the objects to be instantiated in the scene and their attributes. Instantiated scene entities seems to be called "furniture" in the Dark Omen source code.
Offset | Size | Type | Description |
0 | 4 | "INST" | Furniture instances data block identifier |
4 | 4 | Long | Size of data block less 8 ("BSIZE", never less than 1) |
8 | 4 | Long | Number of furniture object instances ("I") |
12 | 4 | Long | Size of each furniture instance ("FSIZE", always 152) |
I×FSIZE bytes: "Furniture" composite data records. See separate description below. |
Notice that the BSIZE element of the INST block is short by 8 bytes. The block size was calculated using only the data area of the furniture records, and number of objects and record size elements were omitted.
Furniture record layout and description
The furniture record seems to contain a mixture of data of relevance for game as well as of relevance only for a graphical level editor.
Notes:
- The position and extents vector items have been transformed into and stored as longs. To obtain the float values, divide each element in orientation by 1024.0f. Further note that the vector described in orientation has not been normalised, and can also be of 0 magnitude.
- The orientation vector item has been transformed into and stored as longs. To obtain the float values, divide each element in orientation by 4096.0f (divide again by 2∏ to obtain rotation in radians). Watch for
- The orientation vector is not normalised
- The orientation vector magnitude can be 0.
- The mesh_slot and dead_mesh_slot items refer to the filename specified in the FURN block, but "1" indicated the first model and "0" signifies that NO mesh is used.
# | Offset | Size | Type | Description |
0 | 0 | 4 | long | ID_prev; //void * |
1 | 4 | 4 | long | ID_next; //void * |
2 | 8 | 4 | long | selected; |
3 | 12 | 4 | long | exclude_from_terrain; |
4 6 | 16 | 12 | long[3] | Position (stored as longs: divide each element by 1024.0f) |
7 9 | 28 | 12 | long[3] | Orientation (stored as longs: divide each element by 4096.0f) |
10 12 | 40 | 12 | long[3] | Min extent (stored as longs: divide each element by 1024.0f) |
13 15 | 52 | 12 | long[3] | Max extent (stored as longs: divide each element by 1024.0f) |
16 | 64 | 4 | long | mesh_slot;// used to store a mesh slot number in the SAVED project |
17 | 68 | 4 | long | Mesh *pMesh; //long ID_mesh; //void * |
18 | 72 | 4 | long | make_attackable; |
19 | 76 | 4 | long | toughness;// used if the furniture is to be attackable |
20 | 80 | 4 | long | wounds; |
21 | 84 | 4 | long | Padding |
22 | 88 | 4 | long | owner_unit_index; |
23 | 92 | 4 | long | is_burning; |
24 | 96 | 4 | long | SFX_code; |
25 | 100 | 4 | long | GFX_code; |
26 | 104 | 4 | long | is_locked;// cannot be dragged while locked |
27 | 108 | 4 | long | exclude_from_terrain_shadow; |
28 | 112 | 4 | long | exclude_from_walk; |
29 | 116 | 4 | long | magic_item_code; |
30 | 120 | 4 | long | particle_effect_code; |
31 | 124 | 4 | long | dead_mesh_slot;// used to store a mesh slot number in the SAVED project |
32 | 128 | 4 | long | Mesh *pDeadMesh; //long dead_mesh; //void * |
33 | 132 | 4 | long | light; |
34 | 136 | 4 | long | light_radius; |
35 | 140 | 4 | long | light_ambient; |
36 | 144 | 4 | long | Padding |
37 | 148 | 4 | long | Padding |
ID: "TERR" data block layout
Offset | Size | Type | Description |
0 | 4 | "TERR" | TERR (terrain?) data block identifier |
4 | 4 | Long | Size of data block ("BSIZE", never less than 1) |
8 | 4 | Long | Number of TERR data entries ("T") |
12 | 4 | Long | Size of each TERR data entry ("TSIZE", always 200?) |
T×TSIZE bytes: composite data records. See separate description below. |
TERR Data record format not yet mapped!
ID: "ATTR" block data layout
from "Rob" [1]
I figured out a bit of the ATTR block: ATTR { char[4] ’ATTR’ long BLOCK_SIZE long WIDTH_OF_MAP long HEIGHT_OF_MAP } Then follows (width*height/2) bytes. Each tile has 4 bits of attributes and these are packed 2 to a byte. Then there are 64 bytes, of which I can’t make out much. It looks like this is line-of-sight / accessibility information. attributes are 0 for ’ordinary’ tiles, 2 for blocked ( i.e. unit can’t move there ), 8 for passable water (such as fords), 10 (8|2) for impassible water. There are probably more attribute values, its just a matter of looking at all the maps. I made a program which spits out the data as a bitmap, so I can just compare to the minimaps. |
The M3D 3D Object File Layout
The M3D format used by Dark Omen is a raw-data binary format to save a model consisting of a non-hierarchal array of meshes. It is intended for forward-parsing and do not contain block meta-data.
Render flags
M3D stored basic instructions on how the model is intended to be rendered in its filename.
//===================================================================== // Render flags // ------------ // // Render flags for a model are provided, believe it or not, in // the model<nowiki>’</nowiki>s filename. If the leading character is an underline // then the following is a hash for a binary attribute map where // // 00000 ( 0) = no flags // 00001 ( 1) = translucency (colour blending?) // 00010 ( 2) = animate texture UV coordinates // 00100 ( 4) = transparency (alpha blending?) // 10000 (16) = colour key transparency // // The hash depends on character // // <nowiki>’</nowiki>0<nowiki>’</nowiki>..<nowiki>’</nowiki>9<nowiki>’</nowiki>: flag <nowiki>|</nowiki>= char - 48 (==<nowiki>></nowiki> 0 .. 9) // <nowiki>’</nowiki>A<nowiki>’</nowiki>..<nowiki>’</nowiki>Z<nowiki>’</nowiki>: flag <nowiki>|</nowiki>= char - 55 (==<nowiki>></nowiki> 10 .. 35) // <nowiki>’</nowiki>a<nowiki>’</nowiki>..<nowiki>’</nowiki>z<nowiki>’</nowiki>: flag <nowiki>|</nowiki>= char - 87 (==<nowiki>></nowiki> 10 .. 35) // // The most common filename prefixes (actually, the only ones // present in Dark Omen) are: // // "_4": 00000100 (transparency) // "_6": 00000110 (transparecy and animated texture coordinates) // "_7": 00000111 (translucency, animated texture coordinates, and transparency) // "_K": 00010100 (transparency and colour keying) // //===============================================================
General layout
0 | 24 | File header | |
24 | 96 * n | Texture description | |
Sub-object description |
File header:
0 | 4 | Long | File ID |
4 | 4 | Long | Magic |
8 | 4 | Long | Version |
12 | 4 | Long | CRC |
16 | 4 | Long | NOT CRC |
20 | 2 | Short | # textures |
22 | 2 | Short | # sub-objects |
Texture description entry
0 | 64 | Char[64] | Filepath (ignored) |
64 | 32 | Char[32] | Texture filename |
3D Sub-object Description
char name[32]; // object name short parent; // parent index M3DPOINT pivot; // origin for heirarchy short vertices; // number of verts. short faces; // number of faces long flags; long spare1; long spare2;
Geometry
Geometry header List of faces List of vertices
Graphical effects
From filenames
Water movement, etc: animated texture coordinates Transparency Particle effects from settings in the INST block Water vapour (waterfalls etc) Dust Fire Explosions