diff --git a/dffwrite.cpp b/dffwrite.cpp index 773382d..e86f2a9 100644 --- a/dffwrite.cpp +++ b/dffwrite.cpp @@ -26,6 +26,7 @@ main(int argc, char *argv[]) gta::registerBreakableModelPlugin(); gta::registerExtraVertColorPlugin(); rw::ps2::registerADCPlugin(); + rw::ps2::registerPDSPlugin(); rw::registerSkinPlugin(); rw::registerNativeDataPlugin(); // rw::ps2::registerNativeDataPlugin(); diff --git a/dumprwtree.cpp b/dumprwtree.cpp index 6b6cc87..7a02261 100644 --- a/dumprwtree.cpp +++ b/dumprwtree.cpp @@ -64,8 +64,8 @@ const char *toolkitchunks1[] = { const char *RSchunks[] = { "Unused 1", "Unused 2", "Unused 3", "Pipeline Set", "Unused 5", "Unused 6", "Specular Material", - "Unused 8", "2dfx", "Night Vertex Colors", "Collision Model", - "Unused 12", "Reflection Material", "Mesh Extension", "Frame", + "Unused 8", "2dfx", "Extra Colors", "Collision Model", + "Unused 12", "Environment Material", "Breakable", "Node Name", "Unused 16" }; diff --git a/insttest.cpp b/insttest.cpp index 1e74f0a..4400017 100644 --- a/insttest.cpp +++ b/insttest.cpp @@ -23,16 +23,19 @@ main(int argc, char *argv[]) gta::registerBreakableModelPlugin(); gta::registerExtraVertColorPlugin(); rw::ps2::registerADCPlugin(); + rw::ps2::registerPDSPlugin(); rw::registerSkinPlugin(); rw::registerNativeDataPlugin(); rw::registerMeshPlugin(); rw::platform = rw::PLATFORM_PS2; - rw::Pipeline *defpipe = rw::ps2::makeDefaultPipeline(); -// rw::Pipeline *skinpipe = rw::ps2::makeSkinPipeline(); -// rw::ps2::dumpPipeline(defpipe); -// rw::ps2::dumpPipeline(skinpipe); + rw::ps2::ObjPipeline *defpipe = rw::ps2::makeDefaultPipeline(); + rw::ps2::ObjPipeline *skinpipe = rw::ps2::makeSkinPipeline(); + rw::ps2::ObjPipeline *matfxpipe = rw::ps2::makeMatFXPipeline(); +// rw::ps2::defaultMatPipe->dump(); +// skinpipe->groupPipeline->dump(); +// matfxpipe->groupPipeline->dump(); int uninstance = 0; int arg = 1; @@ -62,7 +65,19 @@ main(int argc, char *argv[]) c = Clump::streamRead(&in); assert(c != NULL); - printf("%s\n", argv[arg]); +// printf("%s\n", argv[arg]); + + for(int32 i = 0; i < c->numAtomics; i++){ + Atomic *a = c->atomicList[i]; + Pipeline *ap = a->pipeline; + Geometry *g = a->geometry; + for(int32 j = 0; j < g->numMaterials; j++){ + Pipeline *mp = g->materialList[j]->pipeline; + if(ap && mp) + printf("%s %x %x\n", argv[arg], ap->pluginData, mp->pluginData); + } + } + for(int32 i = 0; i < c->numAtomics; i++){ Atomic *a = c->atomicList[i]; if(a->pipeline){ @@ -83,7 +98,6 @@ main(int argc, char *argv[]) } } -/* data = new rw::uint8[256*1024]; rw::StreamMemory out; out.open(data, 0, 256*1024); @@ -95,7 +109,6 @@ main(int argc, char *argv[]) fclose(cf); out.close(); delete[] data; -*/ delete c; diff --git a/src/geometry.cpp b/src/geometry.cpp index cbeab77..f012d04 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -398,7 +398,7 @@ static void readMaterialRights(Stream *stream, int32, void *, int32, int32) { stream->read(materialRights, 8); -// printf("materialrights: %X %X\n", buffer[0], buffer[1]); +// printf("materialrights: %X %X\n", materialRights[0], materialRights[1]); } static void diff --git a/src/pipeline.cpp b/src/pipeline.cpp index 5e61987..02aa35d 100644 --- a/src/pipeline.cpp +++ b/src/pipeline.cpp @@ -20,8 +20,6 @@ Pipeline::Pipeline(uint32 platform) this->pluginID = 0; this->pluginData = 0; this->platform = platform; - for(int i = 0; i < 10; i++) - this->attribs[i] = NULL; } Pipeline::Pipeline(Pipeline *) @@ -33,6 +31,11 @@ Pipeline::~Pipeline(void) { } +void +Pipeline::dump(void) +{ +} + void Pipeline::instance(Atomic *atomic) { diff --git a/src/plugins.cpp b/src/plugins.cpp index 44c2b2f..2883faf 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -592,6 +592,7 @@ readAtomicMatFX(Stream *stream, int32, void *object, int32 offset, int32) { int32 flag; stream->read(&flag, 4); +// printf("matfx: %d\n", flag); *PLUGINOFFSET(int32, object, offset) = flag; if(flag) ((Atomic*)object)->pipeline = @@ -609,9 +610,10 @@ writeAtomicMatFX(Stream *stream, int32, void *object, int32 offset, int32) static int32 getSizeAtomicMatFX(void *object, int32 offset, int32) { - int32 flag; +/* int32 flag; flag = *PLUGINOFFSET(int32, object, offset); - return flag ? 4 : -1; + return flag ? 4 : -1; */ + return 4; } // Material diff --git a/src/ps2.cpp b/src/ps2.cpp index 9120686..ddac10c 100644 --- a/src/ps2.cpp +++ b/src/ps2.cpp @@ -16,6 +16,9 @@ using namespace std; namespace rw { namespace ps2 { +ObjPipeline *defaultObjPipe; +MatPipeline *defaultMatPipe; + void* destroyNativeData(void *object, int32, int32) { @@ -237,8 +240,46 @@ PipeAttribute attribWeights = { AT_V4_32 | AT_RW }; -Pipeline::Pipeline(uint32 platform) - : rw::Pipeline(platform) { } +MatPipeline::MatPipeline(uint32 platform) + : rw::Pipeline(platform) +{ + for(int i = 0; i < 10; i++) + this->attribs[i] = NULL; +} + +void +MatPipeline::dump(void) +{ + if(this->platform != PLATFORM_PS2) + return; + PipeAttribute *a; + for(uint i = 0; i < nelem(this->attribs); i++){ + a = this->attribs[i]; + if(a) + printf("%d %s: %x\n", i, a->name, a->attrib); + } + printf("stride: %x\n", this->inputStride); + printf("triSCount: %x\n", this->triStripCount); + printf("triLCount: %x\n", this->triListCount); + printf("vifOffset: %x\n", this->vifOffset); +} + +void +MatPipeline::setTriBufferSizes(uint32 inputStride, uint32 stripCount) +{ + this->inputStride = inputStride; + this->triListCount = stripCount/12*12; + PipeAttribute *a; + for(uint i = 0; i < nelem(this->attribs); i++){ + a = this->attribs[i]; + if(a && a->attrib & AT_RW) + goto brokenout; + } + this->triStripCount = stripCount/4*4; + return; +brokenout: + this->triStripCount = (stripCount-2)/4*4+2; +} static uint32 attribSize(uint32 unpack) @@ -250,7 +291,7 @@ attribSize(uint32 unpack) #define QWC(x) (((x)+0xF)>>4) static uint32 -getBatchSize(Pipeline *pipe, uint32 vertCount) +getBatchSize(MatPipeline *pipe, uint32 vertCount) { PipeAttribute *a; uint32 size = 1; @@ -345,7 +386,7 @@ instanceNormal(uint32 *wp, Geometry *g, Mesh *m, uint32 idx, uint32 n) uint32 markcnt = 0xf790; static void -instanceMat(Pipeline *pipe, Geometry *g, InstanceData *inst, Mesh *m) +instanceMat(MatPipeline *pipe, Geometry *g, InstanceData *inst, Mesh *m) { PipeAttribute *a; uint32 numAttribs = 0; @@ -367,7 +408,7 @@ instanceMat(Pipeline *pipe, Geometry *g, InstanceData *inst, Mesh *m) } batchVertCount = pipe->triStripCount; lastBatchVertCount = totalVerts%pipe->triStripCount; - }else{ // trilist + }else{ // trilist numBatches = (m->numIndices+pipe->triListCount-1) / pipe->triListCount; totalVerts = m->numIndices; @@ -488,18 +529,17 @@ instanceMat(Pipeline *pipe, Geometry *g, InstanceData *inst, Mesh *m) *p++ = 0x06000000; // MSKPATH3; SA: FLUSH } } - -/* - FILE *f = fopen("out.bin", "w"); - fwrite(inst->data, inst->dataSize, 1, f); - fclose(f); -*/ } +ObjPipeline::ObjPipeline(uint32 platform) + : rw::Pipeline(platform), groupPipeline(NULL) { } + void -Pipeline::instance(Atomic *atomic) +ObjPipeline::instance(Atomic *atomic) { Geometry *geometry = atomic->geometry; + if(geometry->geoflags & Geometry::NATIVE) + return; InstanceDataHeader *header = new InstanceDataHeader; geometry->instData = header; header->platform = PLATFORM_PS2; @@ -509,8 +549,14 @@ Pipeline::instance(Atomic *atomic) for(uint32 i = 0; i < header->numMeshes; i++){ Mesh *mesh = &geometry->meshHeader->mesh[i]; InstanceData *instance = &header->instanceMeshes[i]; - // TODO: should depend on material pipeline - instanceMat(this, geometry, instance, mesh); + + MatPipeline *m; + m = this->groupPipeline ? + m = this->groupPipeline : + (MatPipeline*)mesh->material->pipeline; + if(m == NULL) + m = defaultMatPipe; + instanceMat(m, geometry, instance, mesh); //printf("\n"); } geometry->geoflags |= Geometry::NATIVE; @@ -543,7 +589,7 @@ printVertCounts(InstanceData *inst, int flag) // Only a dummy right now void -Pipeline::uninstance(Atomic *atomic) +ObjPipeline::uninstance(Atomic *atomic) { Geometry *geometry = atomic->geometry; assert(geometry->instData->platform == PLATFORM_PS2); @@ -560,41 +606,32 @@ Pipeline::uninstance(Atomic *atomic) #undef QWC -void -Pipeline::setTriBufferSizes(uint32 inputStride, uint32 stripCount) -{ - this->inputStride = inputStride; - this->triListCount = stripCount/12*12; - PipeAttribute *a; - for(uint i = 0; i < nelem(this->attribs); i++){ - a = this->attribs[i]; - if(a && a->attrib & AT_RW) - goto brokenout; - } - this->triStripCount = stripCount/4*4; - return; -brokenout: - this->triStripCount = (stripCount-2)/4*4+2; -} - -Pipeline* +ObjPipeline* makeDefaultPipeline(void) { - Pipeline *pipe = new Pipeline(PLATFORM_PS2); - pipe->attribs[AT_XYZ] = &attribXYZ; - pipe->attribs[AT_UV] = &attribUV; - pipe->attribs[AT_RGBA] = &attribRGBA; - pipe->attribs[AT_NORMAL] = &attribNormal; - uint32 vertCount = Pipeline::getVertCount(VU_Lights, 4, 3, 2); - pipe->setTriBufferSizes(4, vertCount); - pipe->vifOffset = pipe->inputStride*vertCount; - return pipe; + if(defaultMatPipe == NULL){ + MatPipeline *pipe = new MatPipeline(PLATFORM_PS2); + pipe->attribs[AT_XYZ] = &attribXYZ; + pipe->attribs[AT_UV] = &attribUV; + pipe->attribs[AT_RGBA] = &attribRGBA; + pipe->attribs[AT_NORMAL] = &attribNormal; + uint32 vertCount = MatPipeline::getVertCount(VU_Lights,4,3,2); + pipe->setTriBufferSizes(4, vertCount); + pipe->vifOffset = pipe->inputStride*vertCount; + defaultMatPipe = pipe; + } + + if(defaultObjPipe == NULL){ + ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2); + defaultObjPipe = opipe; + } + return defaultObjPipe; } -Pipeline* +ObjPipeline* makeSkinPipeline(void) { - Pipeline *pipe = new Pipeline(PLATFORM_PS2); + MatPipeline *pipe = new MatPipeline(PLATFORM_PS2); pipe->pluginID = ID_SKIN; pipe->pluginData = 1; pipe->attribs[AT_XYZ] = &attribXYZ; @@ -602,44 +639,36 @@ makeSkinPipeline(void) pipe->attribs[AT_RGBA] = &attribRGBA; pipe->attribs[AT_NORMAL] = &attribNormal; pipe->attribs[AT_NORMAL+1] = &attribWeights; - uint32 vertCount = Pipeline::getVertCount(VU_Lights-0x100, 5, 3, 2); + uint32 vertCount = MatPipeline::getVertCount(VU_Lights-0x100, 5, 3, 2); pipe->setTriBufferSizes(5, vertCount); pipe->vifOffset = pipe->inputStride*vertCount; - return pipe; + + ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2); + opipe->pluginID = ID_SKIN; + opipe->pluginData = 1; + opipe->groupPipeline = pipe; + return opipe; } -Pipeline* +ObjPipeline* makeMatFXPipeline(void) { - Pipeline *pipe = new Pipeline(PLATFORM_PS2); + MatPipeline *pipe = new MatPipeline(PLATFORM_PS2); pipe->pluginID = ID_MATFX; pipe->pluginData = 0; pipe->attribs[AT_XYZ] = &attribXYZ; pipe->attribs[AT_UV] = &attribUV; pipe->attribs[AT_RGBA] = &attribRGBA; pipe->attribs[AT_NORMAL] = &attribNormal; - uint32 vertCount = Pipeline::getVertCount(0x3C5, 4, 3, 3); + uint32 vertCount = MatPipeline::getVertCount(0x3C5, 4, 3, 3); pipe->setTriBufferSizes(4, vertCount); pipe->vifOffset = pipe->inputStride*vertCount; - return pipe; -} -void -dumpPipeline(rw::Pipeline *rwpipe) -{ - if(rwpipe->platform != PLATFORM_PS2) - return; - Pipeline *pipe = (Pipeline*)rwpipe; - PipeAttribute *a; - for(uint i = 0; i < nelem(pipe->attribs); i++){ - a = pipe->attribs[i]; - if(a) - printf("%d %s: %x\n", i, a->name, a->attrib); - } - printf("stride: %x\n", pipe->inputStride); - printf("triSCount: %x\n", pipe->triStripCount); - printf("triLCount: %x\n", pipe->triListCount); - printf("vifOffset: %x\n", pipe->vifOffset); + ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2); + opipe->pluginID = ID_MATFX; + opipe->pluginData = 0; + opipe->groupPipeline = pipe; + return opipe; } // Skin @@ -731,6 +760,7 @@ getSizeNativeSkin(void *object, int32 offset) return size; } + // ADC static void* @@ -788,6 +818,39 @@ registerADCPlugin(void) } +// PDS plugin + +static void +atomicPDSRights(void *object, int32, int32, uint32 data) +{ + Atomic *a = (Atomic*)object; + // TODO: lookup pipeline by data + a->pipeline = new Pipeline(PLATFORM_PS2); + a->pipeline->pluginID = ID_PDS; + a->pipeline->pluginData = data; +} + +static void +materialPDSRights(void *object, int32, int32, uint32 data) +{ + Material *m = (Material*)object; + // TODO: lookup pipeline by data + m->pipeline = new Pipeline(PLATFORM_PS2); + m->pipeline->pluginID = ID_PDS; + m->pipeline->pluginData = data; +} + +void +registerPDSPlugin(void) +{ + Atomic::registerPlugin(0, ID_PDS, NULL, NULL, NULL); + Atomic::setStreamRightsCallback(ID_PDS, atomicPDSRights); + + Material::registerPlugin(0, ID_PDS, NULL, NULL, NULL); + Material::setStreamRightsCallback(ID_PDS, materialPDSRights); +} + + // misc stuff void diff --git a/src/rwpipeline.h b/src/rwpipeline.h index 96bb4b3..c5cc223 100644 --- a/src/rwpipeline.h +++ b/src/rwpipeline.h @@ -8,17 +8,18 @@ struct PipeAttribute struct Atomic; -struct Pipeline +class Pipeline { +public: uint32 pluginID; uint32 pluginData; - uint32 platform; - PipeAttribute *attribs[10]; Pipeline(uint32 platform); Pipeline(Pipeline *p); ~Pipeline(void); + virtual void dump(void); + // TODO: this is bad, maybe split obj and mat pipelines? virtual void instance(Atomic *atomic); virtual void uninstance(Atomic *atomic); virtual void render(Atomic *atomic); diff --git a/src/rwps2.h b/src/rwps2.h index 8e887e4..8b1fde7 100644 --- a/src/rwps2.h +++ b/src/rwps2.h @@ -38,27 +38,43 @@ void fixDmaOffsets(InstanceData *inst); void unfixDmaOffsets(InstanceData *inst); // -struct Pipeline : rw::Pipeline +class MatPipeline : public rw::Pipeline { +public: uint32 vifOffset; uint32 inputStride; uint32 triStripCount, triListCount; + PipeAttribute *attribs[10]; static uint32 getVertCount(uint32 top, uint32 inAttribs, uint32 outAttribs, uint32 outBufs) { return (top-outBufs)/(inAttribs*2+outAttribs*outBufs); } - Pipeline(uint32 platform); - virtual void instance(Atomic *atomic); - virtual void uninstance(Atomic *atomic); -// virtual void render(Atomic *atomic); + MatPipeline(uint32 platform); + virtual void dump(void); +// virtual void instance(Atomic *atomic); +// virtual void uninstance(Atomic *atomic); +/// virtual void render(Atomic *atomic); void setTriBufferSizes(uint32 inputStride, uint32 stripCount); }; -Pipeline *makeDefaultPipeline(void); -Pipeline *makeSkinPipeline(void); -Pipeline *makeMatFXPipeline(void); +class ObjPipeline : public rw::Pipeline +{ +public: + MatPipeline *groupPipeline; + + ObjPipeline(uint32 platform); + virtual void instance(Atomic *atomic); + virtual void uninstance(Atomic *atomic); +}; + +extern ObjPipeline *defaultObjPipe; +extern MatPipeline *defaultMatPipe; + +ObjPipeline *makeDefaultPipeline(void); +ObjPipeline *makeSkinPipeline(void); +ObjPipeline *makeMatFXPipeline(void); void dumpPipeline(rw::Pipeline *pipe); // Skin plugin @@ -79,5 +95,21 @@ struct ADCData void registerADCPlugin(void); +// PDS plugin + +// IDs used by SA +// n atomic material +// 1892 53f20080 53f20081 // ? +// 1 53f20080 53f2008d // triad_buddha01.dff +// 56430 53f20082 53f20083 // world +// 39 53f20082 53f2008f // reflective world +// 6941 53f20084 53f20085 // vehicles +// 3423 53f20084 53f20087 // vehicles +// 4640 53f20084 53f2008b // vehicles +// 418 53f20088 53f20089 // peds + + +void registerPDSPlugin(void); + } }