diff --git a/src/camera.cpp b/src/camera.cpp index a8bdbb4..8875433 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -195,6 +195,9 @@ calczShiftScale(Camera *cam) float32 f = cam->farPlane; float32 N = engine->zNear; float32 F = engine->zFar; + // RW does this + N += (F - N)/10000.0f; + F -= (F - N)/10000.0f; if(cam->projection == Camera::PERSPECTIVE){ cam->zScale = (N - F)*n*f/(f - n); cam->zShift = (F*f - N*n)/(f - n); diff --git a/src/d3d/xboxplugins.cpp b/src/d3d/xboxplugins.cpp index afd903a..0c9d675 100644 --- a/src/d3d/xboxplugins.cpp +++ b/src/d3d/xboxplugins.cpp @@ -65,8 +65,7 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset) stream->read(natskin->vertexBuffer, size); stream->read(skin->inverseMatrices, skin->numBones*64); - // no split skins in GTA - stream->seek(12); + readSkinSplitData(stream, skin); return stream; } @@ -91,8 +90,8 @@ writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset) stream->write(natskin->vertexBuffer, geometry->numVertices*natskin->stride); stream->write(skin->inverseMatrices, skin->numBones*64); - int32 buffer[3] = { 0, 0, 0}; - stream->write(buffer, 12); + + writeSkinSplitData(stream, skin); return stream; } @@ -107,7 +106,8 @@ getSizeNativeSkin(void *object, int32 offset) return -1; NativeSkin *natskin = (NativeSkin*)skin->platformData; return 12 + 8 + 2*256*4 + 4*4 + - natskin->stride*geometry->numVertices + skin->numBones*64 + 12; + natskin->stride*geometry->numVertices + skin->numBones*64 + + skinSplitDataSize(skin); } void diff --git a/src/ps2/ps2skin.cpp b/src/ps2/ps2skin.cpp index 47b7455..1750c39 100644 --- a/src/ps2/ps2skin.cpp +++ b/src/ps2/ps2skin.cpp @@ -108,10 +108,12 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset) skin->usedBones[i] = i; } - if(!oldFormat) - // last 3 ints are split data as in the other formats - // TODO: what are the other 4? - stream->seek(7*4); + if(!oldFormat){ + // TODO: what is this? + stream->seek(4*4); + + readSkinSplitData(stream, skin); + } return stream; } @@ -140,8 +142,10 @@ writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset) stream->write(skin->usedBones, skin->numUsedBones); stream->write(skin->inverseMatrices, skin->numBones*64); if(!oldFormat){ - uint32 buffer[7] = { 0, 0, 0, 0, 0, 0, 0 }; - stream->write(buffer, 7*4); + uint32 buffer[4] = { 0, 0, 0, 0, }; + stream->write(buffer, 4*4); + + writeSkinSplitData(stream, skin); } return stream; } @@ -155,7 +159,7 @@ getSizeNativeSkin(void *object, int32 offset) int32 size = 12 + 4 + 4 + skin->numBones*64; // not sure which version introduced the new format if(version >= 0x34000) - size += skin->numUsedBones + 16 + 12; + size += skin->numUsedBones + 16 + skinSplitDataSize(skin); return size; } diff --git a/src/rwplugins.h b/src/rwplugins.h index b970782..adf2dd2 100644 --- a/src/rwplugins.h +++ b/src/rwplugins.h @@ -147,6 +147,15 @@ struct Skin float *inverseMatrices; uint8 *indices; float *weights; + + // split data; not sure what RLE is exactly + int32 boneLimit; + int32 numMeshes; + int32 numRLE; + int8 *remapIndices; + int16 *RLEcount; + int16 *RLE; + uint8 *data; // only used by delete void *platformData; // a place to store platform specific stuff @@ -162,6 +171,9 @@ struct SkinGlobals ObjPipeline *pipelines[NUM_PLATFORMS]; }; extern SkinGlobals skinGlobals; +Stream *readSkinSplitData(Stream *stream, Skin *skin); +Stream *writeSkinSplitData(Stream *stream, Skin *skin); +int32 skinSplitDataSize(Skin *skin); void registerSkinPlugin(void); } diff --git a/src/skin.cpp b/src/skin.cpp index ab7d1d0..1ca5d93 100644 --- a/src/skin.cpp +++ b/src/skin.cpp @@ -38,6 +38,7 @@ destroySkin(void *object, int32 offset, int32) Skin *skin = *PLUGINOFFSET(Skin*, object, offset); if(skin){ delete[] skin->data; + free(skin->remapIndices); // delete[] skin->platformData; } delete skin; @@ -69,6 +70,41 @@ copySkin(void *dst, void *src, int32 offset, int32) return dst; } +Stream* +readSkinSplitData(Stream *stream, Skin *skin) +{ + uint32 sz; + int8 *data; + + skin->boneLimit = stream->readI32(); + skin->numMeshes = stream->readI32(); + skin->numRLE = stream->readI32(); + sz = skin->numBones + 2*(skin->numMeshes+skin->numRLE); + if(sz != 0){ + data = (int8*)malloc(sz); + stream->read(data, sz); + skin->remapIndices = data; + skin->RLEcount = (int16*)(data + skin->numBones); + skin->RLE = (int16*)(data + skin->numBones + 2*skin->numMeshes); + } +} + +Stream* +writeSkinSplitData(Stream *stream, Skin *skin) +{ + stream->writeI32(skin->boneLimit); + stream->writeI32(skin->numMeshes); + stream->writeI32(skin->numRLE); + stream->write(skin->remapIndices, + skin->numBones + 2*(skin->numMeshes+skin->numRLE)); +} + +int32 +skinSplitDataSize(Skin *skin) +{ + return 12 + skin->numBones + 2*(skin->numMeshes+skin->numRLE); +} + static Stream* readSkin(Stream *stream, int32 len, void *object, int32 offset, int32) { @@ -114,18 +150,6 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32) if(oldFormat) stream->seek(4); // skip 0xdeaddead stream->read(&skin->inverseMatrices[i*16], 64); - - //{ - //float *mat = &skin->inverseMatrices[i*16]; - //printf("[ [ %8.4f, %8.4f, %8.4f, %8.4f ]\n" - // " [ %8.4f, %8.4f, %8.4f, %8.4f ]\n" - // " [ %8.4f, %8.4f, %8.4f, %8.4f ]\n" - // " [ %8.4f, %8.4f, %8.4f, %8.4f ] ]\n", - // mat[0], mat[4], mat[8], mat[12], - // mat[1], mat[5], mat[9], mat[13], - // mat[2], mat[6], mat[10], mat[14], - // mat[3], mat[7], mat[11], mat[15]); - //} } if(oldFormat){ @@ -133,9 +157,9 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32) skin->findUsedBones(geometry->numVertices); } - // no split skins in GTA if(!oldFormat) - stream->seek(12); + readSkinSplitData(stream, skin); + return stream; } @@ -181,11 +205,8 @@ writeSkin(Stream *stream, int32 len, void *object, int32 offset, int32) stream->write(&skin->inverseMatrices[i*16], 64); } - // no split skins in GTA - if(!oldFormat){ - uint32 buffer[3] = { 0, 0, 0}; - stream->write(buffer, 12); - } + if(!oldFormat) + writeSkinSplitData(stream, skin); return stream; } @@ -218,7 +239,7 @@ getSizeSkin(void *object, int32 offset, int32) if(version < 0x34000) size += skin->numBones*4; else - size += skin->numUsedBones + 12; + size += skin->numUsedBones + skinSplitDataSize(skin); return size; } @@ -289,6 +310,13 @@ Skin::init(int32 numBones, int32 numUsedBones, int32 numVertices) if(numVertices) this->weights = (float*)p; + this->boneLimit = 0; + this->numMeshes = 0; + this->numRLE = 0; + this->remapIndices = nil; + this->RLEcount = nil; + this->RLE = nil; + this->platformData = nil; } diff --git a/tools/dumprwtree/dumprwtree.cpp b/tools/dumprwtree/dumprwtree.cpp index e604534..1f9d3bf 100644 --- a/tools/dumprwtree/dumprwtree.cpp +++ b/tools/dumprwtree/dumprwtree.cpp @@ -129,9 +129,10 @@ main(int argc, char *argv[]) s.open(argv[1], "rb"); ChunkHeaderInfo header; - readChunkHeaderInfo(&s, &header); - if(argc == 2) - readchunk(&s, &header, 0); + while(readChunkHeaderInfo(&s, &header)){ + if(argc == 2) + readchunk(&s, &header, 0); + } printf("%x %x %x\n", header.version, header.build, libraryIDPack(header.version, header.build));