mirror of
https://github.com/aap/librw.git
synced 2025-04-21 17:17:46 +01:00
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::build = 0;
|
||||||
|
|
||||||
// rw::version = 0x33002;
|
// rw::version = 0x33002;
|
||||||
|
// rw::version = 0x30200;
|
||||||
|
|
||||||
gta::registerEnvSpecPlugin();
|
gta::registerEnvSpecPlugin();
|
||||||
rw::registerMatFXPlugin();
|
rw::registerMatFXPlugin();
|
||||||
|
@ -216,18 +216,20 @@ Clump::streamRead(Stream *stream)
|
|||||||
clump->frameListStreamRead(stream, &frameList, &numFrames);
|
clump->frameListStreamRead(stream, &frameList, &numFrames);
|
||||||
clump->parent = (void*)frameList[0];
|
clump->parent = (void*)frameList[0];
|
||||||
|
|
||||||
|
Geometry **geometryList = 0;
|
||||||
|
if(version >= 0x30400){
|
||||||
// Geometry list
|
// Geometry list
|
||||||
int32 numGeometries = 0;
|
int32 numGeometries = 0;
|
||||||
assert(findChunk(stream, ID_GEOMETRYLIST, NULL, NULL));
|
assert(findChunk(stream, ID_GEOMETRYLIST, NULL, NULL));
|
||||||
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
|
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
|
||||||
numGeometries = stream->readI32();
|
numGeometries = stream->readI32();
|
||||||
Geometry **geometryList = 0;
|
|
||||||
if(numGeometries)
|
if(numGeometries)
|
||||||
geometryList = new Geometry*[numGeometries];
|
geometryList = new Geometry*[numGeometries];
|
||||||
for(int32 i = 0; i < numGeometries; i++){
|
for(int32 i = 0; i < numGeometries; i++){
|
||||||
assert(findChunk(stream, ID_GEOMETRY, NULL, NULL));
|
assert(findChunk(stream, ID_GEOMETRY, NULL, NULL));
|
||||||
geometryList[i] = Geometry::streamRead(stream);
|
geometryList[i] = Geometry::streamRead(stream);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Atomics
|
// Atomics
|
||||||
if(clump->numAtomics)
|
if(clump->numAtomics)
|
||||||
@ -274,14 +276,17 @@ Clump::streamWrite(Stream *stream)
|
|||||||
|
|
||||||
this->frameListStreamWrite(stream, flist, numFrames);
|
this->frameListStreamWrite(stream, flist, numFrames);
|
||||||
|
|
||||||
|
if(rw::version >= 0x30400){
|
||||||
size = 12+4;
|
size = 12+4;
|
||||||
for(int32 i = 0; i < this->numAtomics; i++)
|
for(int32 i = 0; i < this->numAtomics; i++)
|
||||||
size += 12 + this->atomicList[i]->geometry->streamGetSize();
|
size += 12 +
|
||||||
|
this->atomicList[i]->geometry->streamGetSize();
|
||||||
writeChunkHeader(stream, ID_GEOMETRYLIST, size);
|
writeChunkHeader(stream, ID_GEOMETRYLIST, size);
|
||||||
writeChunkHeader(stream, ID_STRUCT, 4);
|
writeChunkHeader(stream, ID_STRUCT, 4);
|
||||||
stream->writeI32(this->numAtomics); // same as numGeometries
|
stream->writeI32(this->numAtomics); // same as numGeometries
|
||||||
for(int32 i = 0; i < this->numAtomics; i++)
|
for(int32 i = 0; i < this->numAtomics; i++)
|
||||||
this->atomicList[i]->geometry->streamWrite(stream);
|
this->atomicList[i]->geometry->streamWrite(stream);
|
||||||
|
}
|
||||||
|
|
||||||
for(int32 i = 0; i < this->numAtomics; i++)
|
for(int32 i = 0; i < this->numAtomics; i++)
|
||||||
this->atomicList[i]->streamWriteClump(stream, flist, numFrames);
|
this->atomicList[i]->streamWriteClump(stream, flist, numFrames);
|
||||||
@ -324,10 +329,13 @@ Clump::streamGetSize(void)
|
|||||||
size += 12 + 12 + 4 + numFrames*(sizeof(FrameStreamData)+12);
|
size += 12 + 12 + 4 + numFrames*(sizeof(FrameStreamData)+12);
|
||||||
sizeCB((Frame*)this->parent, (void*)&size);
|
sizeCB((Frame*)this->parent, (void*)&size);
|
||||||
|
|
||||||
|
if(rw::version >= 0x30400){
|
||||||
// geometry list
|
// geometry list
|
||||||
size += 12 + 12 + 4;
|
size += 12 + 12 + 4;
|
||||||
for(int32 i = 0; i < this->numAtomics; i++)
|
for(int32 i = 0; i < this->numAtomics; i++)
|
||||||
size += 12 + this->atomicList[i]->geometry->streamGetSize();
|
size += 12 +
|
||||||
|
this->atomicList[i]->geometry->streamGetSize();
|
||||||
|
}
|
||||||
|
|
||||||
// atomics
|
// atomics
|
||||||
for(int32 i = 0; i < this->numAtomics; i++)
|
for(int32 i = 0; i < this->numAtomics; i++)
|
||||||
@ -449,10 +457,15 @@ Atomic::streamReadClump(Stream *stream,
|
|||||||
Frame **frameList, Geometry **geometryList)
|
Frame **frameList, Geometry **geometryList)
|
||||||
{
|
{
|
||||||
int32 buf[4];
|
int32 buf[4];
|
||||||
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
|
uint32 version;
|
||||||
stream->read(buf, 16);
|
assert(findChunk(stream, ID_STRUCT, NULL, &version));
|
||||||
|
stream->read(buf, version < 0x30400 ? 12 : 16);
|
||||||
Atomic *atomic = new Atomic;
|
Atomic *atomic = new Atomic;
|
||||||
atomic->frame = frameList[buf[0]];
|
atomic->frame = frameList[buf[0]];
|
||||||
|
if(version < 0x30400){
|
||||||
|
assert(findChunk(stream, ID_GEOMETRY, NULL, NULL));
|
||||||
|
atomic->geometry = Geometry::streamRead(stream);
|
||||||
|
}else
|
||||||
atomic->geometry = geometryList[buf[1]];
|
atomic->geometry = geometryList[buf[1]];
|
||||||
|
|
||||||
atomicRights[0] = 0;
|
atomicRights[0] = 0;
|
||||||
@ -470,17 +483,22 @@ Atomic::streamWriteClump(Stream *stream, Frame **frameList, int32 numFrames)
|
|||||||
if(c == NULL)
|
if(c == NULL)
|
||||||
return false;
|
return false;
|
||||||
writeChunkHeader(stream, ID_ATOMIC, this->streamGetSize());
|
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);
|
buf[0] = findPointer((void*)this->frame, (void**)frameList, numFrames);
|
||||||
|
|
||||||
// TODO
|
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]++)
|
for(buf[1] = 0; buf[1] < c->numAtomics; buf[1]++)
|
||||||
if(c->atomicList[buf[1]]->geometry == this->geometry)
|
if(c->atomicList[buf[1]]->geometry == this->geometry)
|
||||||
goto foundgeo;
|
goto foundgeo;
|
||||||
return false;
|
return false;
|
||||||
foundgeo:
|
foundgeo:
|
||||||
|
|
||||||
stream->write(buf, sizeof(buf));
|
stream->write(buf, sizeof(buf));
|
||||||
|
}
|
||||||
|
|
||||||
this->streamWritePlugins(stream);
|
this->streamWritePlugins(stream);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -488,7 +506,12 @@ foundgeo:
|
|||||||
uint32
|
uint32
|
||||||
Atomic::streamGetSize(void)
|
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];
|
ObjPipeline *defaultPipelines[NUM_PLATFORMS];
|
||||||
|
@ -24,7 +24,6 @@ Geometry::Geometry(int32 numVerts, int32 numTris, uint32 flags)
|
|||||||
this->numTriangles = numTris;
|
this->numTriangles = numTris;
|
||||||
this->numVertices = numVerts;
|
this->numVertices = numVerts;
|
||||||
this->numMorphTargets = 1;
|
this->numMorphTargets = 1;
|
||||||
printf("geometry: %X %X\n", this->numTriangles, this->numVertices);
|
|
||||||
|
|
||||||
this->colors = NULL;
|
this->colors = NULL;
|
||||||
for(int32 i = 0; i < this->numTexCoordSets; i++)
|
for(int32 i = 0; i < this->numTexCoordSets; i++)
|
||||||
@ -317,7 +316,6 @@ Geometry::generateTriangles(void)
|
|||||||
|
|
||||||
delete[] this->triangles;
|
delete[] this->triangles;
|
||||||
this->triangles = new uint16[4*this->numTriangles];
|
this->triangles = new uint16[4*this->numTriangles];
|
||||||
printf("%d %p\n", this->numTriangles, this->triangles);
|
|
||||||
|
|
||||||
uint16 *f = this->triangles;
|
uint16 *f = this->triangles;
|
||||||
m = header->mesh;
|
m = header->mesh;
|
||||||
@ -395,7 +393,6 @@ struct MatStreamData
|
|||||||
uint8 color[4];
|
uint8 color[4];
|
||||||
int32 unused;
|
int32 unused;
|
||||||
int32 textured;
|
int32 textured;
|
||||||
float32 surfaceProps[3];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint32 materialRights[2];
|
static uint32 materialRights[2];
|
||||||
@ -403,18 +400,26 @@ static uint32 materialRights[2];
|
|||||||
Material*
|
Material*
|
||||||
Material::streamRead(Stream *stream)
|
Material::streamRead(Stream *stream)
|
||||||
{
|
{
|
||||||
uint32 length;
|
uint32 length, version;
|
||||||
MatStreamData buf;
|
MatStreamData buf;
|
||||||
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
|
assert(findChunk(stream, ID_STRUCT, NULL, &version));
|
||||||
stream->read(&buf, sizeof(buf));
|
stream->read(&buf, sizeof(buf));
|
||||||
Material *mat = new Material;
|
Material *mat = new Material;
|
||||||
mat->color[0] = buf.color[0];
|
mat->color[0] = buf.color[0];
|
||||||
mat->color[1] = buf.color[1];
|
mat->color[1] = buf.color[1];
|
||||||
mat->color[2] = buf.color[2];
|
mat->color[2] = buf.color[2];
|
||||||
mat->color[3] = buf.color[3];
|
mat->color[3] = buf.color[3];
|
||||||
mat->surfaceProps[0] = buf.surfaceProps[0];
|
if(version < 0x30400){
|
||||||
mat->surfaceProps[1] = buf.surfaceProps[1];
|
mat->surfaceProps[0] = 1.0f;
|
||||||
mat->surfaceProps[2] = buf.surfaceProps[2];
|
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){
|
if(buf.textured){
|
||||||
assert(findChunk(stream, ID_TEXTURE, &length, NULL));
|
assert(findChunk(stream, ID_TEXTURE, &length, NULL));
|
||||||
@ -434,20 +439,26 @@ Material::streamWrite(Stream *stream)
|
|||||||
MatStreamData buf;
|
MatStreamData buf;
|
||||||
|
|
||||||
writeChunkHeader(stream, ID_MATERIAL, this->streamGetSize());
|
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[0] = this->color[0];
|
||||||
buf.color[1] = this->color[1];
|
buf.color[1] = this->color[1];
|
||||||
buf.color[2] = this->color[2];
|
buf.color[2] = this->color[2];
|
||||||
buf.color[3] = this->color[3];
|
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.flags = 0;
|
||||||
buf.unused = 0;
|
buf.unused = 0;
|
||||||
buf.textured = this->texture != NULL;
|
buf.textured = this->texture != NULL;
|
||||||
stream->write(&buf, sizeof(buf));
|
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)
|
if(this->texture)
|
||||||
this->texture->streamWrite(stream);
|
this->texture->streamWrite(stream);
|
||||||
|
|
||||||
@ -460,6 +471,8 @@ Material::streamGetSize(void)
|
|||||||
{
|
{
|
||||||
uint32 size = 0;
|
uint32 size = 0;
|
||||||
size += 12 + sizeof(MatStreamData);
|
size += 12 + sizeof(MatStreamData);
|
||||||
|
if(rw::version >= 0x30400)
|
||||||
|
size += 12;
|
||||||
if(this->texture)
|
if(this->texture)
|
||||||
size += 12 + this->texture->streamGetSize();
|
size += 12 + this->texture->streamGetSize();
|
||||||
size += 12 + this->streamGetPluginSize();
|
size += 12 + this->streamGetPluginSize();
|
||||||
|
@ -159,7 +159,6 @@ readMesh(Stream *stream, int32 len, void *object, int32, int32)
|
|||||||
geo->meshHeader->flags = buf[0];
|
geo->meshHeader->flags = buf[0];
|
||||||
geo->meshHeader->numMeshes = buf[1];
|
geo->meshHeader->numMeshes = buf[1];
|
||||||
geo->meshHeader->totalIndices = buf[2];
|
geo->meshHeader->totalIndices = buf[2];
|
||||||
printf("total: %X\n", geo->meshHeader->totalIndices);
|
|
||||||
geo->meshHeader->mesh = new Mesh[geo->meshHeader->numMeshes];
|
geo->meshHeader->mesh = new Mesh[geo->meshHeader->numMeshes];
|
||||||
Mesh *mesh = geo->meshHeader->mesh;
|
Mesh *mesh = geo->meshHeader->mesh;
|
||||||
bool hasData = len > 12+geo->meshHeader->numMeshes*8;
|
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
|
// 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*
|
static void*
|
||||||
createADC(void *object, int32 offset, int32)
|
createADC(void *object, int32 offset, int32)
|
||||||
{
|
{
|
||||||
@ -847,18 +927,21 @@ readADC(Stream *stream, int32, void *object, int32 offset, int32)
|
|||||||
adc->adcBits = new int8[size];
|
adc->adcBits = new int8[size];
|
||||||
stream->read(adc->adcBits, size);
|
stream->read(adc->adcBits, size);
|
||||||
|
|
||||||
|
/*
|
||||||
Geometry *geometry = (Geometry*)object;
|
Geometry *geometry = (Geometry*)object;
|
||||||
int ones = 0, zeroes = 0;
|
int ones = 0, zeroes = 0;
|
||||||
for(int i = 0; i < adc->numBits; i++)
|
for(int i = 0; i < adc->numBits; i++)
|
||||||
if(adc->adcBits[i] == 0)
|
if(adc->adcBits[i])
|
||||||
zeroes++;
|
|
||||||
else if(adc->adcBits[i] == 1)
|
|
||||||
ones++;
|
ones++;
|
||||||
else
|
else
|
||||||
fprintf(stderr, "what the fuck man\n");
|
zeroes++;
|
||||||
printf("%X %X %X\n", adc->numBits, zeroes, ones);
|
|
||||||
MeshHeader *meshHeader = geometry->meshHeader;
|
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
|
static void
|
||||||
|
@ -86,7 +86,10 @@ int32 getSizeNativeSkin(void *object, int32 offset);
|
|||||||
|
|
||||||
// Each element in adcBits corresponds to an index in Mesh->indices,
|
// Each element in adcBits corresponds to an index in Mesh->indices,
|
||||||
// this assumes the Mesh indices are ADC formatted.
|
// 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
|
struct ADCData
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user