mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-07 11:22:45 +01:00
New method for reading RW files
This commit is contained in:
parent
011ecc4620
commit
7714e590cd
@ -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)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
bool render = false;
|
bool render = false, raw = false;
|
||||||
int c;
|
int c;
|
||||||
while ((c = getopt (argc, argv, "r")) != -1) {
|
while ((c = getopt (argc, argv, "rt")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'r':
|
case 'r':
|
||||||
render = true;
|
render = true;
|
||||||
break;
|
break;
|
||||||
|
case 't':
|
||||||
|
raw = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,6 +687,10 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
delete[] data;
|
delete[] data;
|
||||||
}
|
}
|
||||||
|
} if(raw) {
|
||||||
|
if(loadFile(argv[2], &data)) {
|
||||||
|
dumpGenericTree(data);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 1; i < argc; ++i) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
if ( ! loadFile(argv[i], &data))
|
if ( ! loadFile(argv[i], &data))
|
||||||
|
@ -23,6 +23,7 @@ namespace RW
|
|||||||
SID_Geometry = 0x000F,
|
SID_Geometry = 0x000F,
|
||||||
SID_Clump = 0x0010,
|
SID_Clump = 0x0010,
|
||||||
|
|
||||||
|
SID_TextureNative = 0x0015,
|
||||||
SID_TextureDictionary = 0x0016,
|
SID_TextureDictionary = 0x0016,
|
||||||
|
|
||||||
SID_GeometryList = 0x001A,
|
SID_GeometryList = 0x001A,
|
||||||
@ -229,6 +230,71 @@ namespace RW
|
|||||||
uint8_t palette[1024];
|
uint8_t palette[1024];
|
||||||
uint32_t rastersize;
|
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
|
#endif
|
Loading…
Reference in New Issue
Block a user