From fed5ea7c9a3d49bb67dd773f3905bb7e73f415ee Mon Sep 17 00:00:00 2001 From: aap Date: Tue, 8 Sep 2015 10:29:24 +0200 Subject: [PATCH] implemented xbox uninstance --- src/d3d8.cpp | 70 +++++++++++----------- src/plugins.cpp | 12 ++-- src/xbox.cpp | 113 +++++++++++++++++++++++++++++++++++- tools/d3d9/d3dInit.cpp | 3 +- tools/insttest/insttest.cpp | 4 +- 5 files changed, 157 insertions(+), 45 deletions(-) diff --git a/src/d3d8.cpp b/src/d3d8.cpp index ef3c9d7..b8842d3 100644 --- a/src/d3d8.cpp +++ b/src/d3d8.cpp @@ -280,37 +280,6 @@ ObjPipeline::uninstance(Atomic *atomic) destroyNativeData(geo, 0, 0); } -void -defaultUninstanceCB(Geometry *geo, InstanceData *inst) -{ - uint8 *src = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); - uninstV3d(VERT_FLOAT3, - &geo->morphTargets[0].vertices[3*inst->minVert], - src, inst->numVertices, inst->stride); - src += 12; - - if(geo->geoflags & Geometry::NORMALS){ - uninstV3d(VERT_FLOAT3, - &geo->morphTargets[0].normals[3*inst->minVert], - src, inst->numVertices, inst->stride); - src += 12; - } - - inst->vertexAlpha = 0; - if(geo->geoflags & Geometry::PRELIT){ - uninstColor(VERT_ARGB, &geo->colors[4*inst->minVert], src, - inst->numVertices, inst->stride); - src += 4; - } - - for(int32 i = 0; i < geo->numTexCoordSets; i++){ - uninstV2d(VERT_FLOAT2, &geo->texCoords[i][2*inst->minVert], src, - inst->numVertices, inst->stride); - src += 8; - } - unlockVertices(inst->vertexBuffer); -} - void defaultInstanceCB(Geometry *geo, InstanceData *inst) { @@ -329,26 +298,57 @@ defaultInstanceCB(Geometry *geo, InstanceData *inst) if(geo->geoflags & Geometry::NORMALS){ instV3d(VERT_FLOAT3, dst, - &geo->morphTargets[0].normals[3*inst->minVert], - inst->numVertices, inst->stride); + &geo->morphTargets[0].normals[3*inst->minVert], + inst->numVertices, inst->stride); dst += 12; } inst->vertexAlpha = 0; if(geo->geoflags & Geometry::PRELIT){ inst->vertexAlpha = instColor(VERT_ARGB, dst, &geo->colors[4*inst->minVert], - inst->numVertices, inst->stride); + inst->numVertices, inst->stride); dst += 4; } for(int32 i = 0; i < geo->numTexCoordSets; i++){ instV2d(VERT_FLOAT2, dst, &geo->texCoords[i][2*inst->minVert], - inst->numVertices, inst->stride); + inst->numVertices, inst->stride); dst += 8; } unlockVertices(inst->vertexBuffer); } +void +defaultUninstanceCB(Geometry *geo, InstanceData *inst) +{ + uint8 *src = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); + uninstV3d(VERT_FLOAT3, + &geo->morphTargets[0].vertices[3*inst->minVert], + src, inst->numVertices, inst->stride); + src += 12; + + if(geo->geoflags & Geometry::NORMALS){ + uninstV3d(VERT_FLOAT3, + &geo->morphTargets[0].normals[3*inst->minVert], + src, inst->numVertices, inst->stride); + src += 12; + } + + inst->vertexAlpha = 0; + if(geo->geoflags & Geometry::PRELIT){ + uninstColor(VERT_ARGB, &geo->colors[4*inst->minVert], src, + inst->numVertices, inst->stride); + src += 4; + } + + for(int32 i = 0; i < geo->numTexCoordSets; i++){ + uninstV2d(VERT_FLOAT2, &geo->texCoords[i][2*inst->minVert], src, + inst->numVertices, inst->stride); + src += 8; + } + unlockVertices(inst->vertexBuffer); +} + ObjPipeline* makeDefaultPipeline(void) { diff --git a/src/plugins.cpp b/src/plugins.cpp index 0b3a656..ccafd5e 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -430,10 +430,10 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32) // TODO: function pointers if(geometry->instData->platform == PLATFORM_PS2) ps2::readNativeSkin(stream, len, object, offset); - else if(geometry->instData->platform == PLATFORM_XBOX) - xbox::readNativeSkin(stream, len, object, offset); else if(geometry->instData->platform == PLATFORM_OGL) gl::readNativeSkin(stream, len, object, offset); + else if(geometry->instData->platform == PLATFORM_XBOX) + xbox::readNativeSkin(stream, len, object, offset); else assert(0 && "unsupported native skin platform"); return; @@ -485,10 +485,10 @@ writeSkin(Stream *stream, int32 len, void *object, int32 offset, int32) if(geometry->instData){ if(geometry->instData->platform == PLATFORM_PS2) ps2::writeNativeSkin(stream, len, object, offset); - else if(geometry->instData->platform == PLATFORM_XBOX) - xbox::writeNativeSkin(stream, len, object, offset); else if(geometry->instData->platform == PLATFORM_OGL) gl::writeNativeSkin(stream, len, object, offset); + else if(geometry->instData->platform == PLATFORM_XBOX) + xbox::writeNativeSkin(stream, len, object, offset); else assert(0 && "unsupported native skin platform"); return; @@ -532,10 +532,10 @@ getSizeSkin(void *object, int32 offset, int32) if(geometry->instData){ if(geometry->instData->platform == PLATFORM_PS2) return ps2::getSizeNativeSkin(object, offset); - if(geometry->instData->platform == PLATFORM_XBOX) - return xbox::getSizeNativeSkin(object, offset); if(geometry->instData->platform == PLATFORM_OGL) return gl::getSizeNativeSkin(object, offset); + if(geometry->instData->platform == PLATFORM_XBOX) + return xbox::getSizeNativeSkin(object, offset); if(geometry->instData->platform == PLATFORM_D3D8) return -1; if(geometry->instData->platform == PLATFORM_D3D9) diff --git a/src/xbox.cpp b/src/xbox.cpp index 2f68944..d6cb4b5 100644 --- a/src/xbox.cpp +++ b/src/xbox.cpp @@ -201,7 +201,28 @@ ObjPipeline::instance(Atomic *atomic) void ObjPipeline::uninstance(Atomic *atomic) { - assert(0 && "can't uninstance"); + Geometry *geo = atomic->geometry; + if((geo->geoflags & Geometry::NATIVE) == 0) + return; + assert(geo->instData != NULL); + assert(geo->instData->platform == PLATFORM_XBOX); + geo->geoflags &= ~Geometry::NATIVE; + geo->allocateData(); + geo->meshHeader->allocateIndices(); + + InstanceDataHeader *header = (InstanceDataHeader*)geo->instData; + InstanceData *inst = header->begin; + Mesh *mesh = geo->meshHeader->mesh; + for(uint32 i = 0; i < header->numMeshes; i++){ + uint16 *indices = (uint16*)inst->indexBuffer; + memcpy(mesh->indices, indices, inst->numIndices*2); + mesh++; + inst++; + } + + this->uninstanceCB(geo, header); + geo->generateTriangles(); + destroyNativeData(geo, 0, 0); } int v3dFormatMap[] = { @@ -255,11 +276,49 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header) assert(0 && "can't instance tangents or whatever it is"); } +void +defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header) +{ + uint32 *vertexFmt = getVertexFmt(geo); + uint32 fmt = *vertexFmt; + assert(fmt != 0); + uint32 offset = 0; + uint8 *src = (uint8*)header->vertexBuffer; + + uint32 sel = fmt & 0xF; + uninstV3d(v3dFormatMap[sel], geo->morphTargets[0].vertices, src, + header->numVertices, header->stride); + src += sel == 4 ? 4 : 3*vertexFormatSizes[sel]; + + sel = (fmt >> 4) & 0xF; + if(sel){ + uninstV3d(v3dFormatMap[sel], geo->morphTargets[0].normals, src, + header->numVertices, header->stride); + src += sel == 4 ? 4 : 3*vertexFormatSizes[sel]; + } + + if(fmt & 0x1000000){ + uninstColor(VERT_ARGB, geo->colors, src, + header->numVertices, header->stride); + src += 4; + } + + for(int i = 0; i < 4; i++){ + sel = (fmt >> (i*4 + 8)) & 0xF; + if(sel == 0) + break; + uninstV2d(v2dFormatMap[sel], geo->texCoords[i], src, + header->numVertices, header->stride); + src += sel == 4 ? 4 : 2*vertexFormatSizes[sel]; + } +} + ObjPipeline* makeDefaultPipeline(void) { ObjPipeline *pipe = new ObjPipeline(PLATFORM_XBOX); pipe->instanceCB = defaultInstanceCB; + pipe->uninstanceCB = defaultUninstanceCB; return pipe; } @@ -397,11 +456,62 @@ skinInstanceCB(Geometry *geo, InstanceDataHeader *header) } } +void +skinUninstanceCB(Geometry *geo, InstanceDataHeader *header) +{ + defaultUninstanceCB(geo, header); + + Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset); + if(skin == NULL) + return; + NativeSkin *natskin = (NativeSkin*)skin->platformData; + + uint8 *data = skin->data; + float *invMats = skin->inverseMatrices; + skin->init(skin->numBones, natskin->numUsedBones, geo->numVertices); + memcpy(skin->inverseMatrices, invMats, skin->numBones*64); + delete[] data; + + for(int32 i = 0; i < skin->numUsedBones; i++) + skin->usedBones[i] = natskin->table1[i]; + + float *weights = skin->weights; + uint8 *indices = skin->indices; + uint8 *p = (uint8*)natskin->vertexBuffer; + int32 numVertices = header->numVertices; + float w[4]; + uint8 i[4]; + uint16 *ip; + while(numVertices--){ + w[0] = w[1] = w[2] = w[3] = 0.0f; + i[0] = i[1] = i[2] = i[3] = 0; + + for(int32 j = 0; j < skin->numWeights; j++) + w[j] = *p++/255.0f; + + ip = (uint16*)p; + for(int32 j = 0; j < skin->numWeights; j++){ + i[j] = natskin->table1[*ip++/3]; + if(w[j] == 0.0f) i[j] = 0; // clean up a bit + } + p = (uint8*)ip; + + for(int32 j = 0; j < 4; j++){ + *weights++ = w[j]; + *indices++ = i[j]; + } + } + + delete[] (uint8*)natskin->vertexBuffer; + delete natskin; +} + ObjPipeline* makeSkinPipeline(void) { ObjPipeline *pipe = new ObjPipeline(PLATFORM_XBOX); pipe->instanceCB = skinInstanceCB; + pipe->uninstanceCB = skinUninstanceCB; pipe->pluginID = ID_SKIN; pipe->pluginData = 1; return pipe; @@ -412,6 +522,7 @@ makeMatFXPipeline(void) { ObjPipeline *pipe = new ObjPipeline(PLATFORM_XBOX); pipe->instanceCB = defaultInstanceCB; + pipe->uninstanceCB = defaultUninstanceCB; pipe->pluginID = ID_MATFX; pipe->pluginData = 0; return pipe; diff --git a/tools/d3d9/d3dInit.cpp b/tools/d3d9/d3dInit.cpp index 16408eb..b001473 100644 --- a/tools/d3d9/d3dInit.cpp +++ b/tools/d3d9/d3dInit.cpp @@ -242,7 +242,7 @@ initrw(void) rw::platform = rw::PLATFORM_D3D9; rw::d3d::device = Device; - char *filename = "D:\\rockstargames\\pc\\gtavc\\models\\gta3_archive\\admiral.dff"; +// char *filename = "D:\\rockstargames\\pc\\gtavc\\models\\gta3_archive\\admiral.dff"; // char *filename = "D:\\rockstargames\\pc\\gtavc\\models\\gta3_archive\\player.dff"; // char *filename = "D:\\rockstargames\\pc\\gtavc\\models\\gta3_archive\\od_newscafe_dy.dff"; // char *filename = "D:\\rockstargames\\pc\\gtasa\\models\\gta3_archive\\admiral.dff"; @@ -250,6 +250,7 @@ initrw(void) // char *filename = "C:\\gtasa\\test\\hanger.dff"; // char *filename = "C:\\Users\\aap\\Desktop\\tmp\\out.dff"; // char *filename = "out2.dff"; + char *filename = "C:\\Users\\aap\\src\\librw\\tools\\insttest\\out.dff"; rw::StreamFile in; if(in.open(filename, "rb") == NULL){ MessageBox(0, "couldn't open file\n", 0, 0); diff --git a/tools/insttest/insttest.cpp b/tools/insttest/insttest.cpp index cb1a0c1..811d3ca 100644 --- a/tools/insttest/insttest.cpp +++ b/tools/insttest/insttest.cpp @@ -32,9 +32,9 @@ main(int argc, char *argv[]) // rw::version = 0x33002; // rw::platform = rw::PLATFORM_PS2; // rw::platform = rw::PLATFORM_OGL; -// rw::platform = rw::PLATFORM_XBOX; + rw::platform = rw::PLATFORM_XBOX; // rw::platform = rw::PLATFORM_D3D8; - rw::platform = rw::PLATFORM_D3D9; +// rw::platform = rw::PLATFORM_D3D9; int uninstance = 0; int arg = 1;