diff --git a/TODO b/TODO index 40f4c56..9fa1b8b 100644 --- a/TODO +++ b/TODO @@ -14,19 +14,19 @@ Clump & related: texcoord - implement plugins: Clump - R* Collision + R* Collision 0x253F2FA Animation (old III dffs) Atomic - ((Particles)) - R* Pipeline Set + ((Particles)) 0x118 + R* Pipeline Set 0x253F2F3 Skin (old III dffs) Geometry - ((Morph)) - R* 2dfx + ((Morph)) 0x105 + R* 2dfx 0x253F2F8 Material - UV Anim + UV Anim 0x135 Texture - (Sky Mipmap Val) + (Sky Mipmap Val) 0x110 - PDS Pipelines diff --git a/dffwrite.cpp b/dffwrite.cpp index 330eff8..910c524 100644 --- a/dffwrite.cpp +++ b/dffwrite.cpp @@ -23,7 +23,7 @@ main(int argc, char *argv[]) rw::registerAtomicRightsPlugin(); rw::registerHAnimPlugin(); gta::registerNodeNamePlugin(); -// gta::registerBreakableModelPlugin(); + gta::registerBreakableModelPlugin(); gta::registerExtraVertColorPlugin(); rw::ps2::registerADCPlugin(); rw::ps2::registerPDSPlugin(); diff --git a/dumprwtree.cpp b/dumprwtree.cpp index 8e73137..fae0eca 100644 --- a/dumprwtree.cpp +++ b/dumprwtree.cpp @@ -131,7 +131,8 @@ main(int argc, char *argv[]) ChunkHeaderInfo header; readChunkHeaderInfo(&s, &header); - readchunk(&s, &header, 0); + if(argc == 2) + readchunk(&s, &header, 0); printf("%x %x %x\n", header.version, header.build, libraryIDPack(header.version, header.build)); diff --git a/src/geometry.cpp b/src/geometry.cpp index 8e8d2c9..0121cd1 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -24,6 +24,7 @@ Geometry::Geometry(int32 numVerts, int32 numTris, uint32 flags) this->numTriangles = numTris; this->numVertices = numVerts; this->numMorphTargets = 1; +printf("geometry: %X %X\n", this->numTriangles, this->numVertices); this->colors = NULL; for(int32 i = 0; i < this->numTexCoordSets; i++) diff --git a/src/plugins.cpp b/src/plugins.cpp index 5c2652b..f4e0372 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -159,6 +159,7 @@ readMesh(Stream *stream, int32 len, void *object, int32, int32) geo->meshHeader->flags = buf[0]; geo->meshHeader->numMeshes = buf[1]; geo->meshHeader->totalIndices = buf[2]; +printf("total: %X\n", geo->meshHeader->totalIndices); geo->meshHeader->mesh = new Mesh[geo->meshHeader->numMeshes]; Mesh *mesh = geo->meshHeader->mesh; bool hasData = len > 12+geo->meshHeader->numMeshes*8; @@ -339,7 +340,7 @@ registerNativeDataPlugin(void) // Skin // -SkinGlobals skinGlobals = { 0, NULL }; +SkinGlobals skinGlobals = { 0, { NULL } }; static void* createSkin(void *object, int32 offset, int32) @@ -637,7 +638,7 @@ getSizeAtomicMatFX(void *object, int32 offset, int32) // Material -MatFXGlobals matFXGlobals = { 0, 0, NULL }; +MatFXGlobals matFXGlobals = { 0, 0, { NULL } }; // TODO: Frames and Matrices? static void diff --git a/src/ps2.cpp b/src/ps2.cpp index 5c6e4bd..f529ddd 100644 --- a/src/ps2.cpp +++ b/src/ps2.cpp @@ -766,7 +766,7 @@ getSizeNativeSkin(void *object, int32 offset) } static void -skinInstanceCB(MatPipeline *pipe, Geometry *g, Mesh *m, uint8 **data, int32 n) +skinInstanceCB(MatPipeline *, Geometry *g, Mesh *m, uint8 **data, int32 n) { Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset); if(skin == NULL || n < 1) @@ -798,6 +798,8 @@ skinInstanceCB(MatPipeline *pipe, Geometry *g, Mesh *m, uint8 **data, int32 n) // ADC +// TODO: look at PC SA rccam.dff bloodrb.dff, Xbox csbigbear.dff + static void* createADC(void *object, int32 offset, int32) { @@ -812,40 +814,85 @@ copyADC(void *dst, void *src, int32 offset, int32) ADCData *dstadc = PLUGINOFFSET(ADCData, dst, offset); ADCData *srcadc = PLUGINOFFSET(ADCData, src, offset); dstadc->adcFormatted = srcadc->adcFormatted; + if(!dstadc->adcFormatted) + return dst; + dstadc->numBits = srcadc->numBits; + int32 size = dstadc->numBits+3 & ~3; + dstadc->adcBits = new int8[size]; + memcpy(dstadc->adcBits, srcadc->adcBits, size); return dst; } -// TODO: look at PC SA rccam.dff bloodrb.dff +static void* +destroyADC(void *object, int32 offset, int32) +{ + ADCData *adc = PLUGINOFFSET(ADCData, object, offset); + if(adc->adcFormatted) + delete[] adc->adcBits; + return object; +} static void readADC(Stream *stream, int32, void *object, int32 offset, int32) { ADCData *adc = PLUGINOFFSET(ADCData, object, offset); - stream->seek(12); - uint32 x = stream->readU32(); - assert(x == 0); + assert(findChunk(stream, ID_ADC, NULL, NULL)); + adc->numBits = stream->readI32(); + if(adc->numBits == 0){ + adc->adcFormatted = 0; + return; + } adc->adcFormatted = 1; + int32 size = adc->numBits+3 & ~3; + adc->adcBits = new int8[size]; + stream->read(adc->adcBits, size); + + Geometry *geometry = (Geometry*)object; + int ones = 0, zeroes = 0; + for(int i = 0; i < adc->numBits; i++) + if(adc->adcBits[i] == 0) + zeroes++; + else if(adc->adcBits[i] == 1) + ones++; + else + fprintf(stderr, "what the fuck man\n"); + printf("%X %X %X\n", adc->numBits, zeroes, ones); + MeshHeader *meshHeader = geometry->meshHeader; + printf("%X\n", meshHeader->totalIndices); } static void -writeADC(Stream *stream, int32, void *, int32, int32) +writeADC(Stream *stream, int32 len, void *object, int32 offset, int32) { - writeChunkHeader(stream, ID_ADC, 4); - stream->writeI32(0); + ADCData *adc = PLUGINOFFSET(ADCData, object, offset); + Geometry *geometry = (Geometry*)object; + writeChunkHeader(stream, ID_ADC, len-12); + if(geometry->geoflags & Geometry::NATIVE){ + stream->writeI32(0); + return; + } + stream->writeI32(adc->numBits); + int32 size = adc->numBits+3 & ~3; + stream->write(adc->adcBits, size); } static int32 getSizeADC(void *object, int32 offset, int32) { + Geometry *geometry = (Geometry*)object; ADCData *adc = PLUGINOFFSET(ADCData, object, offset); - return adc->adcFormatted ? 16 : -1; + if(!adc->adcFormatted) + return -1; + if(geometry->geoflags & Geometry::NATIVE) + return 16; + return 16 + (adc->numBits+3 & ~3); } void registerADCPlugin(void) { Geometry::registerPlugin(sizeof(ADCData), ID_ADC, - createADC, NULL, copyADC); + createADC, destroyADC, copyADC); Geometry::registerPluginStream(ID_ADC, readADC, writeADC, diff --git a/src/rwplugin.h b/src/rwplugin.h index 57053a1..c005107 100644 --- a/src/rwplugin.h +++ b/src/rwplugin.h @@ -97,6 +97,7 @@ PluginBase::streamReadPlugins(Stream *stream) (void*)this, p->offset, p->size); goto cont; } +// printf("skipping plugin %X\n", header.type); stream->seek(header.length); cont: length -= header.length; diff --git a/src/rwps2.h b/src/rwps2.h index 3823e72..c10af7a 100644 --- a/src/rwps2.h +++ b/src/rwps2.h @@ -84,12 +84,15 @@ int32 getSizeNativeSkin(void *object, int32 offset); // ADC plugin -// The plugin is a little crippled due to lack of documentation +// Each element in adcBits corresponds to an index in Mesh->indices, +// this assumes the Mesh indices are ADC formatted. +// For some reason ADCData->numBits != Mesh->numIndices struct ADCData { - // only information we can get from GTA DFFs :/ - uint32 adcFormatted; + bool32 adcFormatted; + int8 *adcBits; + int32 numBits; }; void registerADCPlugin(void); diff --git a/src/xbox.cpp b/src/xbox.cpp index aeaae39..4fcee0d 100644 --- a/src/xbox.cpp +++ b/src/xbox.cpp @@ -239,6 +239,7 @@ static void readVertexFmt(Stream *stream, int32, void *object, int32 offset, int32) { uint32 fmt = stream->readU32(); + printf("vertexfmt: %X\n", fmt); *PLUGINOFFSET(uint32, object, offset) = fmt; // TODO: create and attach "vertex shader" }