Difference between revisions of "RwBinaryStream"

From GTAMods Wiki
Jump to navigation Jump to search
m
 
m (req del)
 
(31 intermediate revisions by one other user not shown)
Line 1: Line 1:
 
+
{{request-delete}}
  
 
==Reading Binary Streams==
 
==Reading Binary Streams==
 
RwStreams are heirarchical streams of sections. Every section consists of:
 
RwStreams are heirarchical streams of sections. Every section consists of:
 
 
* (gauranteed) RwHeader  
 
* (gauranteed) RwHeader  
* (gauranteed) RwData child section
+
* (gauranteed) RwData child section (the contents are specific to the section type, see definitions below.)
 
* (optional) Children sections
 
* (optional) Children sections
 +
The RwHeader contains the size (sectionSize member) of all the data and children (and their data and children).
 +
This allows you to either skip the entire section and it's children by advancing the stream pointer, or
 +
to know when you have parsed all it's children by comparing the stream pointer to the address of the section
 +
RwHeader added to the sectionSize.
 +
 +
 +
===Simple Pseudo C++ Code to read a Binary Stream===
 +
<font color="green">//-----------------------------------------------------------------------</font>
 +
<font color="green">// The RwSection is a base class from which all RwType classes derive</font>
 +
 +
RwSection * ReadSection(FileStream * stream, RwSection * parent)
 +
{
 +
<font color="green">//-----------------------------------------------------------------------</font>
 +
<font color="green">// read the header</font>
 +
 +
RwHeader header = ReadRwHeader(stream);
 +
 +
<font color="green">//-----------------------------------------------------------------------</font>
 +
<font color="green">// create the section - the type returned is based on header.sectionType</font>
 +
<font color="green">// the reason the parent is passed in is because if the section is an</font>
 +
<font color="green">// rwDATA what data it reads is dependant on the parent's sectionType and</font>
 +
<font color="green">// also the number of rwDATA children the parent already has read</font>
 +
 +
RwSection * section = CreateAppropriateSection(stream, header.sectionType, parent);
 +
 +
<font color="green">//-----------------------------------------------------------------------</font>
 +
<font color="green">// recursively read the children</font>
 +
 +
u8 * endOfSection = stream.GetPosition() + header.sectionSize;
 +
while(stream.GetPosition() < endOfSection)
 +
{
 +
RwSection * childSection = ReadSection(stream, section)
 +
section->AddChild(childSection);
 +
}
 +
 +
<font color="green">//-----------------------------------------------------------------------</font>
 +
<font color="green">// return the newly created section</font>
 +
 +
return section;
 +
}
 +
  
 
===RwType===
 
===RwType===
Line 31: Line 71:
 
     rwPLUGIN_BINMESH = 0x50e,
 
     rwPLUGIN_BINMESH = 0x50e,
 
  };
 
  };
 +
  
 
===RwHeader===
 
===RwHeader===
 
  struct RwHeader
 
  struct RwHeader
 
  {
 
  {
     s32 sectionType; // RwType
+
     s32 sectionType; <font color="green">// RwType</font>
 
     s32 sectionSize;
 
     s32 sectionSize;
 
     u8 unknown[2];
 
     u8 unknown[2];
Line 41: Line 82:
 
  };
 
  };
  
==Dff Files==
 
Top level section is always a single RwClump.
 
===RwClump section===
 
=====VersionNumber(s) 0, 2048=====
 
* Gauranteed
 
* First and only data
 
struct RwClump_RwData
 
{
 
    s32 objectCount;
 
};
 
  
=====VersionNumber(s) 3074, 4099, 6147=====
+
==RwClump==
 +
===Possible Children===
 +
* RwFrameList
 +
* RwGeometryList
 +
* RwAtomic
 +
 
 +
 
 +
===RwData (1st, gauranteed)===
 +
{| style="width:95%" border="1" cellpadding="2" cellspacing="0"
 +
! style="width:14%" | Data type !! style="width:16%" | Name !! style="width:13%" | Version number !! style="width:21%" | Condition !! Notes
 +
|-
 +
| u32 || objectCount || all || ||
 +
|- style="background:cyan"
 +
| u8[8]|| unknown || style="background:yellow" | 3074, 4099, 6147 || ||
 +
|}
 +
 
 +
 
 +
===RwData (2nd and subsequent, optional)===
 +
{| style="width:95%" border="1" cellpadding="2" cellspacing="0"
 +
! style="width:14%" | Data type !! style="width:16%" | Name !! style="width:13%" | Version number !! style="width:21%" | Condition !! Notes
 +
|- style="background:cyan"
 +
| u8[4] || unknown || style="background:yellow" | 3074, 4099, 6147 || ||
 +
|}
 +
 
 +
 
 +
==RwGeometryList==
 +
===Possible Children===
 +
* RwGeometry
 +
 
 +
 
 +
===RwData (1st, gauranteed)===
 +
{| style="width:95%" border="1" cellpadding="2" cellspacing="0"
 +
! style="width:14%" | Data type !! style="width:16%" | Name !! style="width:13%" | Version number !! style="width:21%" | Condition !! Notes
 +
|-
 +
| u32 || geometryCount || all || ||
 +
|}
 +
 
 +
==RwGeometry==
 +
===Possible Children===
 +
* RwMaterialList
 +
* ''In RwExtension''
 +
** RwBinMeshPlugin
 +
** RwMorphPlugin
 +
 
 +
 
 +
===RwData (1st, gauranteed)===
 +
{| style="width:95%" border="1" cellpadding="2" cellspacing="0"
 +
! style="width:14%" | Data type !! style="width:16%" | Name !! style="width:13%" | Version number !! style="width:21%" | Condition !! Notes
 +
|-
 +
| u16 || flags || all || ||
 +
|- style="background:cyan"
 +
| u8[2]|| unknown || all || ||
 +
|-
 +
| u32 || triangleCount || all || ||
 +
|-
 +
| u32 || vertexCount || all || ||
 +
|-
 +
| u32 || morphTargetCount || all || ||
 +
|-
 +
| u32 || ambientRgba || style="background:yellow" | 0, 2048, 3074 || ||
 +
|-
 +
| u32 || diffuseRgba || style="background:yellow" | 0, 2048, 3074 || ||
 +
|-
 +
| u32 || specularRgba || style="background:yellow" | 0, 2048, 3074 || ||
 +
|-
 +
| u32[vertexCount] || vertexRgba || all || style="background:yellow" | only if( flags & flags.COLOUR) ||
 +
|-
 +
| f32[vertexCount][2] || uvs || all || style="background:yellow" | only if( flags & flags.TEXTURE) || style="background:yellow" | For versions 0, 2048 and 3074 the u and v are swapped
 +
|-
 +
| u16[triangleCount][3] || faces || all || || style="background:yellow" | For every face, read 4 u16s. and ignore the 3rd
 +
|-
 +
| vector3 || boundingSpherePosition || all || ||
 +
|-
 +
| f32 || boundingSphereRadius || all || ||
 +
|- style="background:cyan"
 +
| u8[8]|| unknown || all || ||
 +
|-
 +
| vector3[vertexCount] || positions || all || ||
 +
|-
 +
| vector3[vertexCount] || normals || all || style="background:yellow" | only if( flags & flags.NORMALS) ||
 +
|}
 +
 
 +
 
 +
==RwMaterialList==
 +
===Possible Children===
 +
* RwMaterial
 +
 
 +
 
 +
===RwData (1st, gauranteed)===
 +
{| style="width:95%" border="1" cellpadding="2" cellspacing="0"
 +
! style="width:14%" | Data type !! style="width:16%" | Name !! style="width:13%" | Version number !! style="width:21%" | Condition !! Notes
 +
|-
 +
| u32 || materialCount || all || ||
 +
|- style="background:cyan"
 +
| u8[materialCount*4] || unknown || all || ||
 +
|}
 +
 
 +
 
 +
==RwMaterial==
 +
===Possible Children===
 +
* RwTexture
 +
 
 +
 
 +
===RwData (1st, gauranteed)===
 +
{| style="width:95%" border="1" cellpadding="2" cellspacing="0"
 +
! style="width:14%" | Data type !! style="width:16%" | Name !! style="width:13%" | Version number !! style="width:21%" | Condition !! Notes
 +
|- style="background:cyan"
 +
| u8[4] || unknown || all || ||
 +
|-
 +
| u32 || colorRgba || all || ||
 +
|- style="background:cyan"
 +
| u8[4] || unknown2 || all || ||
 +
|-
 +
| u32 || textureCount || all || ||
 +
|- style="background:cyan"
 +
| u8[12] || unknown3 || all || ||
 +
|}
 +
 
 +
 
 +
==RwTexture==
 +
===Possible Children===
 +
* RwString
 +
* ''In RwExtension''
 +
** RwSkyMipmapPlugin
 +
 
 +
 
 +
===RwData (1st, gauranteed)===
 +
{| style="width:95%" border="1" cellpadding="2" cellspacing="0"
 +
! style="width:14%" | Data type !! style="width:16%" | Name !! style="width:13%" | Version number !! style="width:21%" | Condition !! Notes
 +
|-
 +
| u16 || filterFlags || all || ||
 +
|- style="background:cyan"
 +
| u8[2] || unknown || all || ||
 +
|}
 +
 
  
* Gauranteed
+
==RwAtomic==
* First data
+
===Possible Children===
struct RwClump_RwData
+
* None
{
 
    s32 objectCount;
 
    u8 unknown[8];
 
};
 
  
* Optional
 
* Second and subsequent data
 
struct RwClump_RwData
 
{
 
    u8 unknown[4];
 
};
 
  
==Txd Files==
+
===RwData (1st, gauranteed)===
Top level section is always a single RwTexdict.
+
{| style="width:95%" border="1" cellpadding="2" cellspacing="0"
 +
! style="width:14%" | Data type !! style="width:16%" | Name !! style="width:13%" | Version number !! style="width:21%" | Condition !! Notes
 +
|-
 +
| u32 || frameIdx || all || ||
 +
|-
 +
| u32 || geometryIdx || all || ||
 +
|- style="background:cyan"
 +
| u8[8] || unknown || all || ||
 +
|}

Latest revision as of 08:53, 13 October 2007

Delete.png This article has been requested for deletion
You may suggest different in the discussion page.

Reading Binary Streams

RwStreams are heirarchical streams of sections. Every section consists of:

  • (gauranteed) RwHeader
  • (gauranteed) RwData child section (the contents are specific to the section type, see definitions below.)
  • (optional) Children sections

The RwHeader contains the size (sectionSize member) of all the data and children (and their data and children). This allows you to either skip the entire section and it's children by advancing the stream pointer, or to know when you have parsed all it's children by comparing the stream pointer to the address of the section RwHeader added to the sectionSize.


Simple Pseudo C++ Code to read a Binary Stream

//-----------------------------------------------------------------------
// The RwSection is a base class from which all RwType classes derive

RwSection * ReadSection(FileStream * stream, RwSection * parent)
{
	//-----------------------------------------------------------------------
	// read the header
	
	RwHeader header = ReadRwHeader(stream);
	
	//-----------------------------------------------------------------------
	// create the section - the type returned is based on header.sectionType
	// the reason the parent is passed in is because if the section is an
	// rwDATA what data it reads is dependant on the parent's sectionType and
	// also the number of rwDATA children the parent already has read
	
	RwSection * section = CreateAppropriateSection(stream, header.sectionType, parent);
	
	//-----------------------------------------------------------------------
	// recursively read the children
	
	u8 * endOfSection = stream.GetPosition() + header.sectionSize;
	while(stream.GetPosition() < endOfSection)
	{
		RwSection * childSection = ReadSection(stream, section)
		section->AddChild(childSection);
	}
	
	//-----------------------------------------------------------------------
	// return the newly created section
	
	return section;
}


RwType

enum
{
    rwDATA = 1,
    rwSTRING = 2,
    rwEXTENSION = 3,
    rwTEXTURE = 6,
    rwMATERIAL = 7,
    rwMATERIALLIST = 8,
    rwFRAMELIST = 14,
    rwGEOMETRY = 15,
    rwCLUMP = 16,
    rwLIGHT = 18,
    rwATOMIC = 20,
    rwTEXTURENATIVE = 21,
    rwTEXDICT = 22,
    rwGEOMETRYLIST = 26,
    rwMATERIALSPLIT = 124,
    rwFRAME = 39056126,
    rwPLUGIN_PARTICLES = 0x118,
    rwPLUGIN_MATERIALEFFECTS = 0x120,
    rwPLUGIN_BINMESH = 0x50e,
};


RwHeader

struct RwHeader
{
    s32 sectionType; // RwType
    s32 sectionSize;
    u8 unknown[2];
    s16 versionNumber;
};


RwClump

Possible Children

  • RwFrameList
  • RwGeometryList
  • RwAtomic


RwData (1st, gauranteed)

Data type Name Version number Condition Notes
u32 objectCount all
u8[8] unknown 3074, 4099, 6147


RwData (2nd and subsequent, optional)

Data type Name Version number Condition Notes
u8[4] unknown 3074, 4099, 6147


RwGeometryList

Possible Children

  • RwGeometry


RwData (1st, gauranteed)

Data type Name Version number Condition Notes
u32 geometryCount all

RwGeometry

Possible Children

  • RwMaterialList
  • In RwExtension
    • RwBinMeshPlugin
    • RwMorphPlugin


RwData (1st, gauranteed)

Data type Name Version number Condition Notes
u16 flags all
u8[2] unknown all
u32 triangleCount all
u32 vertexCount all
u32 morphTargetCount all
u32 ambientRgba 0, 2048, 3074
u32 diffuseRgba 0, 2048, 3074
u32 specularRgba 0, 2048, 3074
u32[vertexCount] vertexRgba all only if( flags & flags.COLOUR)
f32[vertexCount][2] uvs all only if( flags & flags.TEXTURE) For versions 0, 2048 and 3074 the u and v are swapped
u16[triangleCount][3] faces all For every face, read 4 u16s. and ignore the 3rd
vector3 boundingSpherePosition all
f32 boundingSphereRadius all
u8[8] unknown all
vector3[vertexCount] positions all
vector3[vertexCount] normals all only if( flags & flags.NORMALS)


RwMaterialList

Possible Children

  • RwMaterial


RwData (1st, gauranteed)

Data type Name Version number Condition Notes
u32 materialCount all
u8[materialCount*4] unknown all


RwMaterial

Possible Children

  • RwTexture


RwData (1st, gauranteed)

Data type Name Version number Condition Notes
u8[4] unknown all
u32 colorRgba all
u8[4] unknown2 all
u32 textureCount all
u8[12] unknown3 all


RwTexture

Possible Children

  • RwString
  • In RwExtension
    • RwSkyMipmapPlugin


RwData (1st, gauranteed)

Data type Name Version number Condition Notes
u16 filterFlags all
u8[2] unknown all


RwAtomic

Possible Children

  • None


RwData (1st, gauranteed)

Data type Name Version number Condition Notes
u32 frameIdx all
u32 geometryIdx all
u8[8] unknown all