1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-09-15 06:52:34 +02:00

New method for reading RW files

This commit is contained in:
Daniel Evans 2013-06-30 16:41:17 +01:00
parent 011ecc4620
commit 7714e590cd
2 changed files with 170 additions and 2 deletions

View File

@ -569,15 +569,113 @@ void renderModel(char *data, size_t dataI)
}
}
void dumpBinaryStreamSection(BinaryStreamSection& parent, size_t depth, size_t maxdepth = 7)
{
std::cout << std::string(depth, ' ') << "ID(" << std::hex << int(parent.header.id) << ") ";
std::cout << "size(" << std::dec << int(parent.header.size) << "b) ";
std::cout << "version(" << std::hex << int(parent.header.versionid) << ") ";
size_t sectionOffset = 0, j = 0;
bool readchildren = false;
// Handle the specialised bits
switch(parent.header.id)
{
case RW::SID_Struct:
{
std::cout << "structure";
}
break;
case RW::SID_String:
{
std::cout << "string(\"" << std::string(parent.raw()) << "\")";
}
break;
case RW::SID_GeometryList:
{
auto list = parent.readStructure<BSGeometryList>();
std::cout << std::dec << "gcount(" << list.numgeometry << ")";
readchildren = true;
}
break;
case RW::SID_Geometry:
{
auto geometry = parent.readStructure<BSGeometry>();
std::cout << std::dec << "tcount(" << geometry.numtris << ") vcount(" << geometry.numverts << ")";
readchildren = true;
}
break;
case RW::SID_MaterialList:
{
auto list = parent.readStructure<BSMaterialList>();
std::cout << std::dec << "mcount(" << list.nummaterials << ")";
readchildren = true;
}
break;
case RW::SID_Material:
{
auto material = parent.readStructure<BSMaterial>();
std::cout << std::dec << "tcount(" << material.numtextures << ")";
readchildren = true;
}
break;
case RW::SID_Texture:
{
auto texture = parent.readStructure<BSTexture>();
std::cout << "texture";
readchildren = true;
}
break;
case RW::SID_TextureNative:
{
auto texture = parent.readStructure<BSTextureNative>();
std::cout << std::dec << "size(" << texture.width << "x" << texture.height << ") ";
std::cout << " format(" << std::hex << texture.rasterformat << ")";
}
break;
case RW::SID_Clump:
case RW::SID_TextureDictionary:
case RW::SID_Extension:
{
readchildren = true;
}
break;
default:
{
std::cout << "Unknown Section";
}
};
std::cout << std::endl;
if(readchildren)
{
while(parent.hasMoreData(sectionOffset) && (j++) < 10 && depth < maxdepth)
{
BinaryStreamSection sec = parent.getNextChildSection(sectionOffset);
dumpBinaryStreamSection(sec, depth+1);
}
}
}
void dumpGenericTree(char* data)
{
BinaryStreamSection root(data);
dumpBinaryStreamSection(root, 0);
}
int main(int argc, char** argv)
{
bool render = false;
bool render = false, raw = false;
int c;
while ((c = getopt (argc, argv, "r")) != -1) {
while ((c = getopt (argc, argv, "rt")) != -1) {
switch (c) {
case 'r':
render = true;
break;
case 't':
raw = true;
break;
}
}
@ -589,6 +687,10 @@ int main(int argc, char** argv)
delete[] data;
}
} if(raw) {
if(loadFile(argv[2], &data)) {
dumpGenericTree(data);
}
} else {
for (int i = 1; i < argc; ++i) {
if ( ! loadFile(argv[i], &data))

View File

@ -23,6 +23,7 @@ namespace RW
SID_Geometry = 0x000F,
SID_Clump = 0x0010,
SID_TextureNative = 0x0015,
SID_TextureDictionary = 0x0016,
SID_GeometryList = 0x001A,
@ -229,6 +230,71 @@ namespace RW
uint8_t palette[1024];
uint32_t rastersize;
};
/**
* Structure object
*/
class BinaryStreamSection
{
public:
/**
* Data pointer
*/
char* data;
/**
* Offset of this section in the data
*/
size_t offset;
/**
* The BSSectionHeader for the section
*/
BSSectionHeader header;
/**
* Structure header
*/
BSSectionHeader* structure;
BinaryStreamSection(char* data, size_t offset = 0)
: data(data), offset(offset), structure(nullptr)
{
header = *reinterpret_cast<BSSectionHeader*>(data+offset);
if(header.size > sizeof(structure))
{
structure = reinterpret_cast<BSSectionHeader*>(data+offset+sizeof(BSSectionHeader));
if(structure->id != SID_Struct)
{
structure = nullptr;
}
}
}
template<class T> T readStructure()
{
return *reinterpret_cast<T*>(data+offset+sizeof(BSSectionHeader)*2);
}
char* raw()
{
return data + offset + sizeof(BSSectionHeader);
}
bool hasMoreData(size_t length)
{
return (length) < (header.size);
}
BinaryStreamSection getNextChildSection(size_t& internalOffset)
{
size_t realOffset = internalOffset;
assert(realOffset < header.size);
BinaryStreamSection sec(data, offset + sizeof(BSSectionHeader) + realOffset);
internalOffset += sec.header.size + sizeof(BSSectionHeader);
return sec;
}
};
};
#endif