DO/New PRJ Notes
From Dark Omen Wiki
(→Header) |
m (New PRJ Notes moved to Dark Omen:New PRJ Notes) |
||
(9 intermediate revisions not shown) | |||
Line 10: | Line 10: | ||
'BASE': Indicates the terrain mesh to use | 'BASE': Indicates the terrain mesh to use | ||
'WATR': Indicates the water mesh to use (if any) | 'WATR': Indicates the water mesh to use (if any) | ||
- | 'FURN': Describes the position of external meshes (buildings, trees etc) | + | 'FURN': Lists the filenames for external meshes (buildings, trees etc) |
+ | 'INST': Describes the position of external meshes (buildings, trees etc) | ||
'TERR': The terrain heightmap, used for collision detection with the ground | 'TERR': The terrain heightmap, used for collision detection with the ground | ||
and possibly has other uses | and possibly has other uses | ||
Line 34: | Line 35: | ||
unsigned int lengthOfFilenameString; | unsigned int lengthOfFilenameString; | ||
unsigned char filename[BASE.lengthOfFilenameString]; | unsigned char filename[BASE.lengthOfFilenameString]; | ||
+ | } | ||
+ | |||
+ | The minimum length of the filename is 1, since it is always null-terminated | ||
+ | |||
+ | ==='WATR'=== | ||
+ | |||
+ | This section is similar to the BASE section: | ||
+ | |||
+ | struct WATR | ||
+ | { | ||
+ | unsigned char ID[4]; // = 'WATR' | ||
+ | unsigned int lengthOfFilenameString; | ||
+ | unsigned char filename[WATR.lengthOfFilenameString]; | ||
+ | } | ||
+ | |||
+ | Again, the minimum length of the filename is 1, since it is always null-terminated | ||
+ | |||
+ | ==='FURN'=== | ||
+ | |||
+ | This section lists the filenames of any external meshes used in this level. | ||
+ | |||
+ | struct FURN | ||
+ | { | ||
+ | unsigned char ID[4]; // = 'FURN' | ||
+ | unsigned int sizeOfCharBuffer; // size of the buffer that the app must allocate to store the list | ||
+ | unsigned int externalMeshCount; // number of external meshes used | ||
+ | struct emesh | ||
+ | { | ||
+ | unsigned int lengthOfFilenameString; | ||
+ | unsigned char filename[emesh.lengthOfFilenameString]; | ||
+ | } ExternalMeshList[FURN.externalMeshCount]; | ||
+ | } | ||
+ | |||
+ | Presumably, the original Dark Omen code would: | ||
+ | |||
+ | # allocate a buffer to hold all the string data | ||
+ | # create an array of pointers to char, one for each filename | ||
+ | # load each string into the buffer and set the appropriate pointer to the start of the associated string | ||
+ | |||
+ | Which would explain the slightly strange format. | ||
+ | |||
+ | ==='INST'=== | ||
+ | |||
+ | The INST section looks like this: | ||
+ | |||
+ | struct INST | ||
+ | { | ||
+ | unsigned char ID[4]; // = 'INST' | ||
+ | unsigned int sizeOfFollowingData; | ||
+ | unsigned int instanceCount; | ||
+ | unsigned int instanceSize; // i.e. the size of the meshInst struct = 154 (see below) | ||
+ | |||
+ | struct meshInst | ||
+ | { | ||
+ | // Presumably editor data | ||
+ | // | ||
+ | unsigned int ID_prev; | ||
+ | unsigned int ID_next; | ||
+ | unsigned int isSelected; | ||
+ | unsigned int toExcludeFromTerrain; | ||
+ | |||
+ | // Position and extent data | ||
+ | // | ||
+ | unsigned int PositionX, PositionY, PositionZ; // Stored in 22.10 fixed point. i.e. divide by 1024.0f before use | ||
+ | unsigned int OrientationA, OrientationB, OrientationC; // Stored in 20.12 fixed point. i.e. divide by 4096.0f before use | ||
+ | unsigned int MinX, MinY, MinZ; // Stored in 22.10 fixed point. i.e. divide by 1024.0f before use | ||
+ | unsigned int MaxX, MaxY, MaxZ; // Stored in 22.10 fixed point. i.e. divide by 1024.0f before use | ||
+ | |||
+ | unsigned int meshIndex; | ||
+ | unsigned int unused1; // not needed for saved files | ||
+ | |||
+ | // Mesh Instance Attributes | ||
+ | // | ||
+ | unsigned int attackable; | ||
+ | unsigned int toughness; | ||
+ | unsigned int wounds; | ||
+ | unsigned int unused2; // padding? | ||
+ | unsigned int ownedByUnitID; | ||
+ | unsigned int isBurning; | ||
+ | |||
+ | // More editor properties | ||
+ | // | ||
+ | unsigned int sfxRef; | ||
+ | unsigned int gfxRef; | ||
+ | unsigned int isLocked; | ||
+ | unsigned int excludeFromShadow; | ||
+ | unsigned int excludeFromWalk; | ||
+ | unsigned int magicItemRef; | ||
+ | unsigned int particleEffectRef; | ||
+ | |||
+ | |||
+ | unsigned int deadMeshIndex; // mesh to use when the instance is killed | ||
+ | unsigned int unused3; // not needed for saved files | ||
+ | |||
+ | unsigned int light; | ||
+ | unsigned int lightRadius; | ||
+ | unsigned int lightAmbient; | ||
+ | |||
+ | unsigned int unused4; // padding? | ||
+ | unsigned int unused5; // padding? | ||
+ | |||
+ | } MeshInstances[INST.instanceCount]; | ||
} | } |
Current revision as of 15:54, 29 January 2009
Contents |
PRJ File format
The PRJ file format represents the world data (as opposed to the mission-specific data) for a Dark Omen battle.
Overall Structure
The Overall structure of a PRJ File is shown below. It is made up of sections, which appear in this order:
Header: The string "Dark Omen Battle File 1.10 " (32 bytes in total, padded with spaces) 'BASE': Indicates the terrain mesh to use 'WATR': Indicates the water mesh to use (if any) 'FURN': Lists the filenames for external meshes (buildings, trees etc) 'INST': Describes the position of external meshes (buildings, trees etc) 'TERR': The terrain heightmap, used for collision detection with the ground and possibly has other uses 'ATTR': Attribute flags for parts of the terrain 'EXCL': Unknown function at present 'MUSC': The music to use for this level 'TRAC': Camera tracks for the intro 'EDIT': Unknown function at present
Block Formats
Header
The header merely consists of the string "Dark Omen Battle File 1.10 ", which is used to identify the PRJ format.
'BASE'
The base section looks like this:
struct BASE { unsigned char ID[4]; // = 'BASE' unsigned int lengthOfFilenameString; unsigned char filename[BASE.lengthOfFilenameString]; }
The minimum length of the filename is 1, since it is always null-terminated
'WATR'
This section is similar to the BASE section:
struct WATR { unsigned char ID[4]; // = 'WATR' unsigned int lengthOfFilenameString; unsigned char filename[WATR.lengthOfFilenameString]; }
Again, the minimum length of the filename is 1, since it is always null-terminated
'FURN'
This section lists the filenames of any external meshes used in this level.
struct FURN { unsigned char ID[4]; // = 'FURN' unsigned int sizeOfCharBuffer; // size of the buffer that the app must allocate to store the list unsigned int externalMeshCount; // number of external meshes used struct emesh { unsigned int lengthOfFilenameString; unsigned char filename[emesh.lengthOfFilenameString]; } ExternalMeshList[FURN.externalMeshCount]; }
Presumably, the original Dark Omen code would:
- allocate a buffer to hold all the string data
- create an array of pointers to char, one for each filename
- load each string into the buffer and set the appropriate pointer to the start of the associated string
Which would explain the slightly strange format.
'INST'
The INST section looks like this:
struct INST { unsigned char ID[4]; // = 'INST' unsigned int sizeOfFollowingData; unsigned int instanceCount; unsigned int instanceSize; // i.e. the size of the meshInst struct = 154 (see below) struct meshInst { // Presumably editor data // unsigned int ID_prev; unsigned int ID_next; unsigned int isSelected; unsigned int toExcludeFromTerrain; // Position and extent data // unsigned int PositionX, PositionY, PositionZ; // Stored in 22.10 fixed point. i.e. divide by 1024.0f before use unsigned int OrientationA, OrientationB, OrientationC; // Stored in 20.12 fixed point. i.e. divide by 4096.0f before use unsigned int MinX, MinY, MinZ; // Stored in 22.10 fixed point. i.e. divide by 1024.0f before use unsigned int MaxX, MaxY, MaxZ; // Stored in 22.10 fixed point. i.e. divide by 1024.0f before use unsigned int meshIndex; unsigned int unused1; // not needed for saved files // Mesh Instance Attributes // unsigned int attackable; unsigned int toughness; unsigned int wounds; unsigned int unused2; // padding? unsigned int ownedByUnitID; unsigned int isBurning; // More editor properties // unsigned int sfxRef; unsigned int gfxRef; unsigned int isLocked; unsigned int excludeFromShadow; unsigned int excludeFromWalk; unsigned int magicItemRef; unsigned int particleEffectRef; unsigned int deadMeshIndex; // mesh to use when the instance is killed unsigned int unused3; // not needed for saved files unsigned int light; unsigned int lightRadius; unsigned int lightAmbient; unsigned int unused4; // padding? unsigned int unused5; // padding? } MeshInstances[INST.instanceCount]; }