diff --git a/main.cpp b/main.cpp index 05a24d1..50a7aa2 100644 --- a/main.cpp +++ b/main.cpp @@ -20,6 +20,7 @@ main(int argc, char *argv[]) registerNodeNamePlugin(); registerMeshPlugin(); + registerNativeDataPlugin(); Rw::Clump *c; ifstream in(argv[1], ios::binary); diff --git a/plugins.cpp b/plugins.cpp index 8c5a246..3d90fbd 100644 --- a/plugins.cpp +++ b/plugins.cpp @@ -8,10 +8,17 @@ #include "rwbase.h" #include "rwplugin.h" #include "rw.h" +#include "rwps2.h" using namespace std; using namespace Rw; +// +// Frame +// + +// Node Name + static void* createNodeName(void *object, int32 offset, int32) { @@ -70,6 +77,11 @@ registerNodeNamePlugin(void) (StreamGetSize)getSizeNodeName); } +// +// Geometry +// + +// Mesh static void readMesh(istream &stream, Rw::int32, void *object, int32, int32) @@ -169,4 +181,63 @@ registerMeshPlugin(void) (StreamGetSize)getSizeMesh); } +// Native Data +static void +readNativeData(istream &stream, int32 len, void *object, int32 o, int32 s) +{ + ChunkHeaderInfo header; + uint32 libid; + uint32 platform; + // ugly hack to find out platform + stream.seekg(-4, ios::cur); + libid = readUInt32(stream); + ReadChunkHeaderInfo(stream, &header); + if(header.type == ID_STRUCT && + LibraryIDPack(header.version, header.build) == libid){ + // must be PS2 or Xbox + platform = readUInt32(stream); + stream.seekg(-16, ios::cur); + if(platform == PLATFORM_PS2) + ReadNativeDataPS2(stream, len, object, o, s); + else if(platform == PLATFORM_XBOX) + stream.seekg(len, ios::cur); + }else + // OpenGL + // doesn't work always, some headers have wrong size + stream.seekg(len-12, ios::cur); +} + +static void +writeNativeData(ostream &stream, int32 len, void *object, int32 o, int32 s) +{ + Geometry *geometry = (Geometry*)object; + if(geometry->instData == NULL) + return; + if(geometry->instData->platform == PLATFORM_PS2) + WriteNativeDataPS2(stream, len, object, o, s); +} + +static int32 +getSizeNativeData(void *object, int32 offset, int32 size) +{ + Geometry *geometry = (Geometry*)object; + if(geometry->instData == NULL) + return -1; + if(geometry->instData->platform == PLATFORM_PS2) + return GetSizeNativeDataPS2(object, offset, size); + else if(geometry->instData->platform == PLATFORM_XBOX) + return -1; + else if(geometry->instData->platform == PLATFORM_OGL) + return -1; + return -1; +} + +void +registerNativeDataPlugin(void) +{ + Rw::Geometry::registerPlugin(0, 0x510, NULL, NULL, NULL); + Rw::Geometry::registerPluginStream(0x510, (StreamRead)readNativeData, + (StreamWrite)writeNativeData, + (StreamGetSize)getSizeNativeData); +} diff --git a/rw.h b/rw.h index 4c575a5..ca025e9 100644 --- a/rw.h +++ b/rw.h @@ -210,3 +210,4 @@ private: void registerNodeNamePlugin(void); void registerMeshPlugin(void); +void registerNativeDataPlugin(void); diff --git a/rwps2.h b/rwps2.h index 0ba80e1..1fa370e 100644 --- a/rwps2.h +++ b/rwps2.h @@ -6,7 +6,7 @@ struct PS2InstanceData uint32 dataSize; uint8 *data; Material *material; -} +}; struct PS2InstanceDataHeader : InstanceDataHeader { @@ -14,4 +14,8 @@ struct PS2InstanceDataHeader : InstanceDataHeader PS2InstanceData *instanceMeshes; }; +void ReadNativeDataPS2(std::istream &stream, int32 len, void *object, int32, int32); +void WriteNativeDataPS2(std::ostream &stream, int32 len, void *object, int32, int32); +int32 GetSizeNativeDataPS2(void *object, int32, int32); + }