Difference between revisions of "RwBinaryStream"

From GTAMods Wiki
Jump to navigation Jump to search
m
m
Line 1: Line 1:
==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===
 
<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===
 
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; <font color="green">// RwType</font>
 
    s32 sectionSize;
 
    u8 unknown[2];
 
    s16 versionNumber;
 
};
 
==Dff Files==
 
Top level section is always a single RwClump.
 
===RwClump section RwData===
 
=====VersionNumber(s) 0, 2048=====
 
* Gauranteed, first and only data in the RwClump
 
s32 objectCount = stream->ReadS32();
 
=====VersionNumber(s) 3074, 4099, 6147=====
 
* Gauranteed, first data in the RwClump
 
s32 objectCount = stream->ReadS32();
 
stream->SkipUnknownU8s(8);
 
* Optional, second and subsequent data in the RwClump
 
stream->SkipUnknownU8s(4);
 
 
===RwGeometry section RwData===
 
===RwGeometry section RwData===
 
=====VersionNumber(s) 0, 2048, 3074=====
 
=====VersionNumber(s) 0, 2048, 3074=====
Line 123: Line 37:
 
  }
 
  }
 
  }
 
  }
==Txd Files==
 
Top level section is always a single RwTexdict.
 

Revision as of 03:35, 29 May 2007

RwGeometry section RwData

VersionNumber(s) 0, 2048, 3074
  • Gauranteed, first and only data in the RwGeometryList
abc def ghi
jkl mno pqr
stu vwx yz
u16 flags = stream->ReadU16();
stream->SkipUnknownU8s(2);

s32 triangleCount = stream->ReadS32();
s32 vertexCount = stream->ReadS32();
s32 morphTargetCount = stream->ReadS32();

if(versionNumber == 0 || versionNumber == 2048 || versionNumber == 3074)
{
	u32 ambientRgba = stream->ReadU32();
	u32 diffuseRgba = stream->ReadU32();
	u32 specularRgba = stream->ReadU32();
}

if(flags & rwGEOM_COLOR)
	u32 colorsRgba[vertexCount] = stream->readU32(vertexCount);

if(flags & rwGEOM_TEXTURE)
{
	f32 uvs[vertexCount * 2];
	for(int idx = 0; idx < vertexCount; ++idx)
	{
		uvs[idx * 2 + 0] = stream->readF32();
		uvs[idx * 2 + 1] = stream->readF32();
	}
}