mirror of https://github.com/aap/librw.git
support for < 0x30400 dffs
This commit is contained in:
parent
3639ada1c3
commit
3698d97c50
|
@ -16,6 +16,7 @@ main(int argc, char *argv[])
|
|||
// rw::build = 0;
|
||||
|
||||
// rw::version = 0x33002;
|
||||
// rw::version = 0x30200;
|
||||
|
||||
gta::registerEnvSpecPlugin();
|
||||
rw::registerMatFXPlugin();
|
||||
|
|
|
@ -216,17 +216,19 @@ Clump::streamRead(Stream *stream)
|
|||
clump->frameListStreamRead(stream, &frameList, &numFrames);
|
||||
clump->parent = (void*)frameList[0];
|
||||
|
||||
// Geometry list
|
||||
int32 numGeometries = 0;
|
||||
assert(findChunk(stream, ID_GEOMETRYLIST, NULL, NULL));
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
|
||||
numGeometries = stream->readI32();
|
||||
Geometry **geometryList = 0;
|
||||
if(numGeometries)
|
||||
geometryList = new Geometry*[numGeometries];
|
||||
for(int32 i = 0; i < numGeometries; i++){
|
||||
assert(findChunk(stream, ID_GEOMETRY, NULL, NULL));
|
||||
geometryList[i] = Geometry::streamRead(stream);
|
||||
if(version >= 0x30400){
|
||||
// Geometry list
|
||||
int32 numGeometries = 0;
|
||||
assert(findChunk(stream, ID_GEOMETRYLIST, NULL, NULL));
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
|
||||
numGeometries = stream->readI32();
|
||||
if(numGeometries)
|
||||
geometryList = new Geometry*[numGeometries];
|
||||
for(int32 i = 0; i < numGeometries; i++){
|
||||
assert(findChunk(stream, ID_GEOMETRY, NULL, NULL));
|
||||
geometryList[i] = Geometry::streamRead(stream);
|
||||
}
|
||||
}
|
||||
|
||||
// Atomics
|
||||
|
@ -274,14 +276,17 @@ Clump::streamWrite(Stream *stream)
|
|||
|
||||
this->frameListStreamWrite(stream, flist, numFrames);
|
||||
|
||||
size = 12+4;
|
||||
for(int32 i = 0; i < this->numAtomics; i++)
|
||||
size += 12 + this->atomicList[i]->geometry->streamGetSize();
|
||||
writeChunkHeader(stream, ID_GEOMETRYLIST, size);
|
||||
writeChunkHeader(stream, ID_STRUCT, 4);
|
||||
stream->writeI32(this->numAtomics); // same as numGeometries
|
||||
for(int32 i = 0; i < this->numAtomics; i++)
|
||||
this->atomicList[i]->geometry->streamWrite(stream);
|
||||
if(rw::version >= 0x30400){
|
||||
size = 12+4;
|
||||
for(int32 i = 0; i < this->numAtomics; i++)
|
||||
size += 12 +
|
||||
this->atomicList[i]->geometry->streamGetSize();
|
||||
writeChunkHeader(stream, ID_GEOMETRYLIST, size);
|
||||
writeChunkHeader(stream, ID_STRUCT, 4);
|
||||
stream->writeI32(this->numAtomics); // same as numGeometries
|
||||
for(int32 i = 0; i < this->numAtomics; i++)
|
||||
this->atomicList[i]->geometry->streamWrite(stream);
|
||||
}
|
||||
|
||||
for(int32 i = 0; i < this->numAtomics; i++)
|
||||
this->atomicList[i]->streamWriteClump(stream, flist, numFrames);
|
||||
|
@ -324,10 +329,13 @@ Clump::streamGetSize(void)
|
|||
size += 12 + 12 + 4 + numFrames*(sizeof(FrameStreamData)+12);
|
||||
sizeCB((Frame*)this->parent, (void*)&size);
|
||||
|
||||
// geometry list
|
||||
size += 12 + 12 + 4;
|
||||
for(int32 i = 0; i < this->numAtomics; i++)
|
||||
size += 12 + this->atomicList[i]->geometry->streamGetSize();
|
||||
if(rw::version >= 0x30400){
|
||||
// geometry list
|
||||
size += 12 + 12 + 4;
|
||||
for(int32 i = 0; i < this->numAtomics; i++)
|
||||
size += 12 +
|
||||
this->atomicList[i]->geometry->streamGetSize();
|
||||
}
|
||||
|
||||
// atomics
|
||||
for(int32 i = 0; i < this->numAtomics; i++)
|
||||
|
@ -449,11 +457,16 @@ Atomic::streamReadClump(Stream *stream,
|
|||
Frame **frameList, Geometry **geometryList)
|
||||
{
|
||||
int32 buf[4];
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
|
||||
stream->read(buf, 16);
|
||||
uint32 version;
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, &version));
|
||||
stream->read(buf, version < 0x30400 ? 12 : 16);
|
||||
Atomic *atomic = new Atomic;
|
||||
atomic->frame = frameList[buf[0]];
|
||||
atomic->geometry = geometryList[buf[1]];
|
||||
if(version < 0x30400){
|
||||
assert(findChunk(stream, ID_GEOMETRY, NULL, NULL));
|
||||
atomic->geometry = Geometry::streamRead(stream);
|
||||
}else
|
||||
atomic->geometry = geometryList[buf[1]];
|
||||
|
||||
atomicRights[0] = 0;
|
||||
atomic->streamReadPlugins(stream);
|
||||
|
@ -470,17 +483,22 @@ Atomic::streamWriteClump(Stream *stream, Frame **frameList, int32 numFrames)
|
|||
if(c == NULL)
|
||||
return false;
|
||||
writeChunkHeader(stream, ID_ATOMIC, this->streamGetSize());
|
||||
writeChunkHeader(stream, ID_STRUCT, 16);
|
||||
writeChunkHeader(stream, ID_STRUCT, rw::version < 0x30400 ? 12 : 16);
|
||||
buf[0] = findPointer((void*)this->frame, (void**)frameList, numFrames);
|
||||
|
||||
// TODO
|
||||
for(buf[1] = 0; buf[1] < c->numAtomics; buf[1]++)
|
||||
if(c->atomicList[buf[1]]->geometry == this->geometry)
|
||||
goto foundgeo;
|
||||
return false;
|
||||
foundgeo:
|
||||
if(version < 0x30400){
|
||||
stream->write(buf, sizeof(int[3]));
|
||||
this->geometry->streamWrite(stream);
|
||||
}else{
|
||||
// TODO
|
||||
for(buf[1] = 0; buf[1] < c->numAtomics; buf[1]++)
|
||||
if(c->atomicList[buf[1]]->geometry == this->geometry)
|
||||
goto foundgeo;
|
||||
return false;
|
||||
foundgeo:
|
||||
stream->write(buf, sizeof(buf));
|
||||
}
|
||||
|
||||
stream->write(buf, sizeof(buf));
|
||||
this->streamWritePlugins(stream);
|
||||
return true;
|
||||
}
|
||||
|
@ -488,7 +506,12 @@ foundgeo:
|
|||
uint32
|
||||
Atomic::streamGetSize(void)
|
||||
{
|
||||
return 12 + 16 + 12 + this->streamGetPluginSize();
|
||||
uint32 size = 12 + 12 + 12 + this->streamGetPluginSize();
|
||||
if(rw::version < 0x30400)
|
||||
size += 12 + this->geometry->streamGetSize();
|
||||
else
|
||||
size += 4;
|
||||
return size;
|
||||
}
|
||||
|
||||
ObjPipeline *defaultPipelines[NUM_PLATFORMS];
|
||||
|
|
|
@ -24,7 +24,6 @@ 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++)
|
||||
|
@ -317,7 +316,6 @@ Geometry::generateTriangles(void)
|
|||
|
||||
delete[] this->triangles;
|
||||
this->triangles = new uint16[4*this->numTriangles];
|
||||
printf("%d %p\n", this->numTriangles, this->triangles);
|
||||
|
||||
uint16 *f = this->triangles;
|
||||
m = header->mesh;
|
||||
|
@ -395,7 +393,6 @@ struct MatStreamData
|
|||
uint8 color[4];
|
||||
int32 unused;
|
||||
int32 textured;
|
||||
float32 surfaceProps[3];
|
||||
};
|
||||
|
||||
static uint32 materialRights[2];
|
||||
|
@ -403,18 +400,26 @@ static uint32 materialRights[2];
|
|||
Material*
|
||||
Material::streamRead(Stream *stream)
|
||||
{
|
||||
uint32 length;
|
||||
uint32 length, version;
|
||||
MatStreamData buf;
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, &version));
|
||||
stream->read(&buf, sizeof(buf));
|
||||
Material *mat = new Material;
|
||||
mat->color[0] = buf.color[0];
|
||||
mat->color[1] = buf.color[1];
|
||||
mat->color[2] = buf.color[2];
|
||||
mat->color[3] = buf.color[3];
|
||||
mat->surfaceProps[0] = buf.surfaceProps[0];
|
||||
mat->surfaceProps[1] = buf.surfaceProps[1];
|
||||
mat->surfaceProps[2] = buf.surfaceProps[2];
|
||||
if(version < 0x30400){
|
||||
mat->surfaceProps[0] = 1.0f;
|
||||
mat->surfaceProps[1] = 1.0f;
|
||||
mat->surfaceProps[2] = 1.0f;
|
||||
}else{
|
||||
float32 surfaceProps[3];
|
||||
stream->read(surfaceProps, sizeof(surfaceProps));
|
||||
mat->surfaceProps[0] = surfaceProps[0];
|
||||
mat->surfaceProps[1] = surfaceProps[1];
|
||||
mat->surfaceProps[2] = surfaceProps[2];
|
||||
}
|
||||
|
||||
if(buf.textured){
|
||||
assert(findChunk(stream, ID_TEXTURE, &length, NULL));
|
||||
|
@ -434,20 +439,26 @@ Material::streamWrite(Stream *stream)
|
|||
MatStreamData buf;
|
||||
|
||||
writeChunkHeader(stream, ID_MATERIAL, this->streamGetSize());
|
||||
writeChunkHeader(stream, ID_STRUCT, sizeof(MatStreamData));
|
||||
writeChunkHeader(stream, ID_STRUCT, sizeof(MatStreamData)
|
||||
+ (rw::version >= 0x30400 ? 12 : 0));
|
||||
|
||||
buf.color[0] = this->color[0];
|
||||
buf.color[1] = this->color[1];
|
||||
buf.color[2] = this->color[2];
|
||||
buf.color[3] = this->color[3];
|
||||
buf.surfaceProps[0] = this->surfaceProps[0];
|
||||
buf.surfaceProps[1] = this->surfaceProps[1];
|
||||
buf.surfaceProps[2] = this->surfaceProps[2];
|
||||
buf.flags = 0;
|
||||
buf.unused = 0;
|
||||
buf.textured = this->texture != NULL;
|
||||
stream->write(&buf, sizeof(buf));
|
||||
|
||||
if(rw::version >= 0x30400){
|
||||
float32 surfaceProps[3];
|
||||
surfaceProps[0] = this->surfaceProps[0];
|
||||
surfaceProps[1] = this->surfaceProps[1];
|
||||
surfaceProps[2] = this->surfaceProps[2];
|
||||
stream->write(surfaceProps, sizeof(surfaceProps));
|
||||
}
|
||||
|
||||
if(this->texture)
|
||||
this->texture->streamWrite(stream);
|
||||
|
||||
|
@ -460,6 +471,8 @@ Material::streamGetSize(void)
|
|||
{
|
||||
uint32 size = 0;
|
||||
size += 12 + sizeof(MatStreamData);
|
||||
if(rw::version >= 0x30400)
|
||||
size += 12;
|
||||
if(this->texture)
|
||||
size += 12 + this->texture->streamGetSize();
|
||||
size += 12 + this->streamGetPluginSize();
|
||||
|
|
|
@ -159,7 +159,6 @@ 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;
|
||||
|
|
95
src/ps2.cpp
95
src/ps2.cpp
|
@ -800,6 +800,86 @@ skinInstanceCB(MatPipeline *, Geometry *g, Mesh *m, uint8 **data, int32 n)
|
|||
|
||||
// TODO: look at PC SA rccam.dff bloodrb.dff, Xbox csbigbear.dff
|
||||
|
||||
static void
|
||||
rotateface(int f[])
|
||||
{
|
||||
int tmp;
|
||||
while(f[0] > f[1] || f[0] > f[2]){
|
||||
tmp = f[0];
|
||||
f[0] = f[1];
|
||||
f[1] = f[2];
|
||||
f[2] = tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
if(f[0] > f[1]){
|
||||
tmp = f[0];
|
||||
f[0] = f[1];
|
||||
f[1] = tmp;
|
||||
}
|
||||
if(f[0] > f[2]){
|
||||
tmp = f[0];
|
||||
f[0] = f[2];
|
||||
f[2] = tmp;
|
||||
}
|
||||
if(f[1] > f[2]){
|
||||
tmp = f[1];
|
||||
f[1] = f[2];
|
||||
f[2] = tmp;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
static int
|
||||
validFace(Geometry *g, uint16 *f, int j, int m)
|
||||
{
|
||||
int f1[3], f2[3];
|
||||
f1[0] = f[j+0 + (j%2)];
|
||||
f1[1] = f[j+1 - (j%2)];
|
||||
f1[2] = f[j+2];
|
||||
//printf("-> %d %d %d\n", f1[0], f1[1], f1[2]);
|
||||
rotateface(f1);
|
||||
uint16 *fs = g->triangles;
|
||||
for(int i = 0; i < g->numTriangles; i++, fs += 4){
|
||||
if(fs[2] != m)
|
||||
continue;
|
||||
f2[0] = fs[1];
|
||||
f2[1] = fs[0];
|
||||
f2[2] = fs[3];
|
||||
//printf("<- %d %d %d\n", f2[0], f2[1], f2[2]);
|
||||
rotateface(f2);
|
||||
if(f1[0] == f2[0] &&
|
||||
f1[1] == f2[1] &&
|
||||
f1[2] == f2[2])
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
isdegenerate(uint16 *f)
|
||||
{
|
||||
return f[0] == f[1] ||
|
||||
f[0] == f[2] ||
|
||||
f[1] == f[2];
|
||||
}
|
||||
|
||||
static int
|
||||
debugadc(Geometry *g, MeshHeader *mh, ADCData *adc)
|
||||
{
|
||||
int n = 0;
|
||||
for(int i = 0; i < mh->numMeshes; i++){
|
||||
uint16 *idx = mh->mesh[i].indices;
|
||||
for(int j = 0; j < mh->mesh[i].numIndices-2; j++){
|
||||
if(!validFace(g, idx, j, i) && !isdegenerate(idx+j)){
|
||||
n++;
|
||||
// printf("> %d %d %d %d\n", i, idx[j+0], idx[j+1], idx[j+2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static void*
|
||||
createADC(void *object, int32 offset, int32)
|
||||
{
|
||||
|
@ -847,18 +927,21 @@ readADC(Stream *stream, int32, void *object, int32 offset, int32)
|
|||
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)
|
||||
if(adc->adcBits[i])
|
||||
ones++;
|
||||
else
|
||||
fprintf(stderr, "what the fuck man\n");
|
||||
printf("%X %X %X\n", adc->numBits, zeroes, ones);
|
||||
zeroes++;
|
||||
MeshHeader *meshHeader = geometry->meshHeader;
|
||||
printf("%X\n", meshHeader->totalIndices);
|
||||
int n = debugadc(geometry, meshHeader, adc);
|
||||
printf("%X %X | %X %X %X\n",
|
||||
meshHeader->totalIndices,
|
||||
meshHeader->totalIndices + n,
|
||||
adc->numBits, zeroes, ones);
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -86,7 +86,10 @@ int32 getSizeNativeSkin(void *object, int32 offset);
|
|||
|
||||
// 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
|
||||
// ADCData->numBits != Mesh->numIndices. ADCData->numBits is probably
|
||||
// equal to Mesh->numIndices before the Mesh gets ADC formatted.
|
||||
//
|
||||
// Can't convert between ADC-formatted and non-ADC-formatted yet :(
|
||||
|
||||
struct ADCData
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue