Difference between revisions of "RwBinaryStream"

From GTAMods Wiki
Jump to navigation Jump to search
m
m
Line 1: Line 1:
 
 
 
==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 (the contents are specific to the section type, see definitions below.)
 
* (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).  
 
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  
 
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
 
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.
 
RwHeader added to the sectionSize.
 
 
===Simple Pseudo C++ Code to read a Binary Stream===
 
===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)
 
  RwSection * ReadSection(FileStream * stream, RwSection * parent)
 
  {
 
  {
  // read the header
+
  <font color="green">//-----------------------------------------------------------------------</font>
 +
<font color="green">// read the header</font>
 +
 
  RwHeader header = ReadRwHeader(stream);
 
  RwHeader header = ReadRwHeader(stream);
 
 
 
 
  // create the section - the type returned is based on header.sectionType
+
  <font color="green">//-----------------------------------------------------------------------</font>
  // the reason the parent is passed in is because if the section is an
+
<font color="green">// create the section - the type returned is based on header.sectionType</font>
  // rwDATA what data it reads is dependant on the parent
+
  <font color="green">// the reason the parent is passed in is because if the section is an</font>
  RwSection * section = CreateAppropriateSection(stream, header.sectionType, parent->GetSectionType());
+
  <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>
 
 
 
 
// rescursivly read the children
 
 
  u8 * endOfSection = stream.GetPosition() + header.sectionSize;
 
  u8 * endOfSection = stream.GetPosition() + header.sectionSize;
 
  while(stream.GetPosition() < endOfSection)
 
  while(stream.GetPosition() < endOfSection)
Line 31: Line 36:
 
  section->AddChild(childSection);
 
  section->AddChild(childSection);
 
  }
 
  }
 +
 +
<font color="green">//-----------------------------------------------------------------------</font>
 +
<font color="green">// return the newly created section</font>
 
 
 
 
 
  return section;
 
  return section;
 
  }
 
  }
 
 
===RwType===
 
===RwType===
 
  enum
 
  enum
Line 58: Line 65:
 
     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];
 
     s16 versionNumber;
 
     s16 versionNumber;
 
  };
 
  };
 
 
==Dff Files==
 
==Dff Files==
 
Top level section is always a single RwClump.
 
Top level section is always a single RwClump.
Line 78: Line 83:
 
     s32 objectCount;
 
     s32 objectCount;
 
  };  
 
  };  
 
 
=====VersionNumber(s) 3074, 4099, 6147=====
 
=====VersionNumber(s) 3074, 4099, 6147=====
 
 
* Gauranteed
 
* Gauranteed
 
* First data
 
* First data
Line 88: Line 91:
 
     u8 unknown[8];
 
     u8 unknown[8];
 
  };
 
  };
 
 
* Optional
 
* Optional
 
* Second and subsequent data
 
* Second and subsequent data
Line 95: Line 97:
 
     u8 unknown[4];
 
     u8 unknown[4];
 
  };
 
  };
 
 
==Txd Files==
 
==Txd Files==
 
Top level section is always a single RwTexdict.
 
Top level section is always a single RwTexdict.

Revision as of 02:47, 29 May 2007

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;
};

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
  • Gauranteed
  • First data
struct RwClump_RwData
{
    s32 objectCount;
    u8 unknown[8];
};
  • Optional
  • Second and subsequent data
struct RwClump_RwData
{
    u8 unknown[4];
};

Txd Files

Top level section is always a single RwTexdict.