diff --git a/librw.sln b/librw.sln
index d2e140e..521ed17 100644
--- a/librw.sln
+++ b/librw.sln
@@ -65,7 +65,6 @@ Global
{B487F101-0C2B-4F99-A1E0-B0B0C0F3FE7E}.Release|Win32.ActiveCfg = Release|Win32
{B487F101-0C2B-4F99-A1E0-B0B0C0F3FE7E}.Release|Win32.Build.0 = Release|Win32
{B487F101-0C2B-4F99-A1E0-B0B0C0F3FE7E}.Release|x64.ActiveCfg = Release|x64
- {B487F101-0C2B-4F99-A1E0-B0B0C0F3FE7E}.Release|x64.Build.0 = Release|x64
{85F56A7D-6EA2-4B9B-806A-87AF6C577FDF}.Debug - null|Win32.ActiveCfg = Debug - null|Win32
{85F56A7D-6EA2-4B9B-806A-87AF6C577FDF}.Debug - null|x64.ActiveCfg = Debug - null|x64
{85F56A7D-6EA2-4B9B-806A-87AF6C577FDF}.Debug|Win32.ActiveCfg = Debug|Win32
@@ -74,8 +73,8 @@ Global
{85F56A7D-6EA2-4B9B-806A-87AF6C577FDF}.Release|Win32.ActiveCfg = Release|Win32
{85F56A7D-6EA2-4B9B-806A-87AF6C577FDF}.Release|Win32.Build.0 = Release|Win32
{85F56A7D-6EA2-4B9B-806A-87AF6C577FDF}.Release|x64.ActiveCfg = Release|x64
- {85F56A7D-6EA2-4B9B-806A-87AF6C577FDF}.Release|x64.Build.0 = Release|x64
{2592ED29-F258-4949-AB45-7B873BF697F7}.Debug - null|Win32.ActiveCfg = Debug - null|Win32
+ {2592ED29-F258-4949-AB45-7B873BF697F7}.Debug - null|Win32.Build.0 = Debug - null|Win32
{2592ED29-F258-4949-AB45-7B873BF697F7}.Debug - null|x64.ActiveCfg = Debug - null|x64
{2592ED29-F258-4949-AB45-7B873BF697F7}.Debug|Win32.ActiveCfg = Debug|Win32
{2592ED29-F258-4949-AB45-7B873BF697F7}.Debug|x64.ActiveCfg = Debug|x64
@@ -83,7 +82,6 @@ Global
{2592ED29-F258-4949-AB45-7B873BF697F7}.Release|Win32.ActiveCfg = Release|Win32
{2592ED29-F258-4949-AB45-7B873BF697F7}.Release|Win32.Build.0 = Release|Win32
{2592ED29-F258-4949-AB45-7B873BF697F7}.Release|x64.ActiveCfg = Release|x64
- {2592ED29-F258-4949-AB45-7B873BF697F7}.Release|x64.Build.0 = Release|x64
{E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Debug - null|Win32.ActiveCfg = Debug - null|Win32
{E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Debug - null|x64.ActiveCfg = Debug - null|x64
{E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Debug|Win32.ActiveCfg = Debug|Win32
@@ -93,7 +91,6 @@ Global
{E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Release|Win32.ActiveCfg = Release|Win32
{E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Release|Win32.Build.0 = Release|Win32
{E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Release|x64.ActiveCfg = Release|x64
- {E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Release|x64.Build.0 = Release|x64
{403C35A9-6D06-4261-B305-9ED000F00136}.Debug - null|Win32.ActiveCfg = Debug - null|Win32
{403C35A9-6D06-4261-B305-9ED000F00136}.Debug - null|x64.ActiveCfg = Debug - null|x64
{403C35A9-6D06-4261-B305-9ED000F00136}.Debug|Win32.ActiveCfg = Debug|Win32
@@ -102,7 +99,6 @@ Global
{403C35A9-6D06-4261-B305-9ED000F00136}.Release|Win32.ActiveCfg = Release|Win32
{403C35A9-6D06-4261-B305-9ED000F00136}.Release|Win32.Build.0 = Release|Win32
{403C35A9-6D06-4261-B305-9ED000F00136}.Release|x64.ActiveCfg = Release|x64
- {403C35A9-6D06-4261-B305-9ED000F00136}.Release|x64.Build.0 = Release|x64
{27ECE916-900F-49B2-8E9F-95E6B347E161}.Debug - null|Win32.ActiveCfg = Debug - null|Win32
{27ECE916-900F-49B2-8E9F-95E6B347E161}.Debug - null|Win32.Build.0 = Debug - null|Win32
{27ECE916-900F-49B2-8E9F-95E6B347E161}.Debug - null|x64.ActiveCfg = Debug - null|Win32
diff --git a/librw.vcxproj b/librw.vcxproj
index baf04fc..6444b73 100644
--- a/librw.vcxproj
+++ b/librw.vcxproj
@@ -193,7 +193,6 @@
-
diff --git a/rw.h b/rw.h
index 8f1c24e..e633a40 100644
--- a/rw.h
+++ b/rw.h
@@ -8,4 +8,3 @@
#include "src/rwd3d8.h"
#include "src/rwd3d9.h"
#include "src/rwogl.h"
-#include "src/mdl.h"
diff --git a/src/clump.cpp b/src/clump.cpp
index d1a5c91..8697963 100644
--- a/src/clump.cpp
+++ b/src/clump.cpp
@@ -31,6 +31,7 @@ Frame::Frame(void)
this->matrix[5] = 1.0f;
this->matrix[10] = 1.0f;
this->matrix[15] = 1.0f;
+ this->matflag = 0;
this->dirty = true;
constructPlugins();
}
diff --git a/src/geometry.cpp b/src/geometry.cpp
index 9ba6b3d..4348069 100644
--- a/src/geometry.cpp
+++ b/src/geometry.cpp
@@ -41,6 +41,10 @@ Geometry::Geometry(int32 numVerts, int32 numTris, uint32 flags)
}
this->morphTargets = new MorphTarget[1];
MorphTarget *m = this->morphTargets;
+ m->boundingSphere[0] = 0.0f;
+ m->boundingSphere[1] = 0.0f;
+ m->boundingSphere[2] = 0.0f;
+ m->boundingSphere[3] = 0.0f;
m->vertices = NULL;
m->normals = NULL;
if(!(this->geoflags & NATIVE) && this->numVertices){
diff --git a/src/gtaplg.cpp b/src/gtaplg.cpp
index 1e98f1b..c9a8612 100644
--- a/src/gtaplg.cpp
+++ b/src/gtaplg.cpp
@@ -12,7 +12,6 @@
#include "rwps2.h"
#include "rwd3d.h"
#include "rwxbox.h"
-#include "mdl.h"
#include "gtaplg.h"
using namespace std;
@@ -82,8 +81,6 @@ attachPlugins(void)
gta::register2dEffectPlugin();
gta::registerPipelinePlugin();
- registerRslPlugin();
-
rw::Atomic::init();
}
@@ -156,6 +153,12 @@ registerNodeNamePlugin(void)
getSizeNodeName);
}
+char*
+getNodeName(Frame *f)
+{
+ return PLUGINOFFSET(char, f, nodeNameOffset);
+}
+
//
// Geometry
//
diff --git a/src/gtaplg.h b/src/gtaplg.h
index b31a51d..3a81ad8 100644
--- a/src/gtaplg.h
+++ b/src/gtaplg.h
@@ -25,6 +25,7 @@ void attachPlugins(void);
extern int32 nodeNameOffset;
void registerNodeNamePlugin(void);
+char *getNodeName(Frame *f);
// Breakable model
diff --git a/src/image.cpp b/src/image.cpp
index fb4f2d0..2ee80a7 100755
--- a/src/image.cpp
+++ b/src/image.cpp
@@ -130,18 +130,19 @@ Texture::read(const char *name, const char *mask)
tex = new Texture;
strncpy(tex->name, name, 32);
strncpy(tex->mask, mask, 32);
- char *n = (char*)malloc(strlen(name) + 5);
- strcpy(n, name);
- strcat(n, ".tga");
- Image *img = readTGA(n);
- free(n);
- if(img){
- raster = Raster::createFromImage(img);
- delete img;
- }else
+// char *n = (char*)malloc(strlen(name) + 5);
+// strcpy(n, name);
+// strcat(n, ".tga");
+// Image *img = readTGA(n);
+// free(n);
+// if(img){
+// //raster = Raster::createFromImage(img);
+// raster = new Raster(0, 0, 0, 0x80);
+// delete img;
+// }else
raster = new Raster(0, 0, 0, 0x80);
tex->raster = raster;
- if(currentTexDictionary && img)
+ if(currentTexDictionary /*&& img*/)
currentTexDictionary->add(tex);
return tex;
}
diff --git a/src/mdl.cpp b/src/mdl.cpp
deleted file mode 100644
index e2f4886..0000000
--- a/src/mdl.cpp
+++ /dev/null
@@ -1,602 +0,0 @@
-#include
-#include
-#include
-#include
-
-#include
-
-#include "rwbase.h"
-#include "rwplugin.h"
-#include "rwpipeline.h"
-#include "rwobjects.h"
-#include "rwps2.h"
-#include "rwogl.h"
-#include "rwxbox.h"
-#include "rwd3d8.h"
-#include "rwd3d9.h"
-#include "mdl.h"
-
-using namespace std;
-using namespace rw;
-
-enum {
- ID_RSL = 0xf00d0000
-};
-int32 rslPluginOffset;
-
-struct RslMesh
-{
- float32 bound[4]; // ?
- float32 uvScale[2];
- uint32 unknown;
- uint32 dmaOffset;
- uint16 numTriangles;
- int16 matID;
- float32 pos[3]; // ?
-};
-
-struct RslGeometry
-{
- float32 bound[4];
- uint32 size;
- int32 flags;
- int32 unknown[4];
- float32 scale[3];
- float32 pos[3];
-
- uint32 numMeshes;
- RslMesh *meshes;
- uint32 dataSize;
- uint8 *data;
-};
-
-float32
-halfFloat(uint16 half)
-{
- uint32 f = (uint32)(half & 0x7fff) << 13;
- uint32 sgn = (uint32)(half & 0x8000) << 16;
- f += 0x38000000;
- if((half & 0x7c00) == 0) f = 0;
- f |= sgn;
- return *(float32*)&f;
-}
-
-static uint32
-unpackSize(uint32 unpack)
-{
- if((unpack&0x6F000000) == 0x6F000000)
- return 2;
- static uint32 size[] = { 32, 16, 8, 16 };
- return ((unpack>>26 & 3)+1)*size[unpack>>24 & 3]/8;
-}
-
-int
-analyzeDMA(uint8 *p)
-{
- uint32 *w = (uint32*)p;
- uint32 *end;
- end = (uint32*)(p + ((w[0] & 0xFFFF) + 1)*0x10);
- w += 4;
- int flags = 0;
- while(w < end){
- if((w[0] & 0x60000000) == 0x60000000){
-// printf("UNPACK %x %x\n", w[0], unpackSize(w[0]));
- printf("UNPACK %x %x %x\n", w[0] & 0x7F004000, w[0], unpackSize(w[0]));
- uint32 type = w[0] & 0x7F004000;
- if(w[0] != 0x6c018000){
- if(type == 0x79000000)
- flags |= 0x1;
- if(type == 0x76004000)
- flags |= 0x10;
- if(type == 0x6a000000)
- flags |= 0x100;
- if(type == 0x6f000000)
- flags |= 0x1000;
- if(type == 0x6c000000)
- flags |= 0x10000;
- }
- int32 n = (w[0] >> 16) & 0xFF;
- p = (uint8*)(w+1);
- p += (n*unpackSize(w[0])+3)&~3;
- w = (uint32*)p;
- continue;
- }
- switch(w[0] & 0x7F000000){
- case 0x20000000: // STMASK
- printf("STMASK %x\n", w[1]);
- w++;
- break;
- case 0x30000000:
- printf("STROW %x %x %x %x\n", w[1], w[2], w[3], w[4]);
- w+=4;
- break;
- case 0x31000000:
- printf("STCOL %x %x %x %x\n", w[1], w[2], w[3], w[4]);
- w+=4;
- break;
- case 0x14000000:
- printf("MSCAL %x\n", w[0]&0xFFFF);
- return flags;
- break;
- case 0:
- break;
- default:
- printf("vif: %x\n", w[0]);
- break;
- }
- w++;
- }
- return flags;
-}
-
-uint32*
-skipUnpack(uint32 *p)
-{
- int32 n = (p[0] >> 16) & 0xFF;
- return p + (n*unpackSize(p[0])+3 >> 2) + 1;
-}
-
-void
-convertRslMesh(Geometry *g, RslGeometry *rg, Mesh *m, RslMesh *rm)
-{
- ps2::SkinVertex v;
- uint32 mask = 0x1001; // tex coords, vertices
- if(g->geoflags & Geometry::NORMALS)
- mask |= 0x10;
- if(g->geoflags & Geometry::PRELIT)
- mask |= 0x100;
- float32 *verts = &g->morphTargets[0].vertices[g->numVertices*3];
- float32 *norms = &g->morphTargets[0].normals[g->numVertices*3];
- uint8 *cols = &g->colors[g->numVertices*4];
- float32 *texCoords = &g->texCoords[0][g->numVertices*2];
- uint8 *indices = NULL;
- float32 *weights = NULL;
- Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
- if(skin){
- indices = &skin->indices[g->numVertices*4];
- weights = &skin->weights[g->numVertices*4];
- mask |= 0x10000;
- }
-
- int16 *vuVerts = NULL;
- int8 *vuNorms = NULL;
- uint8 *vuTex = NULL;
- uint16 *vuCols = NULL;
- uint32 *vuSkin = NULL;
-
- uint8 *p = rg->data + rm->dmaOffset;
- uint32 *w = (uint32*)p;
- uint32 *end = (uint32*)(p + ((w[0] & 0xFFFF) + 1)*0x10);
- w += 4;
- int flags = 0;
- int32 nvert;
- bool first = 1;
- while(w < end){
- /* Get data pointers */
-
- // GIFtag probably
- assert(w[0] == 0x6C018000); // UNPACK
- nvert = w[4] & 0x7FFF;
- if(!first) nvert -=2;
- w += 5;
-
- // positions
- assert(w[0] == 0x20000000); // STMASK
- w += 2;
- assert(w[0] == 0x30000000); // STROW
- w += 5;
- assert((w[0] & 0xFF004000) == 0x79000000);
- vuVerts = (int16*)(w+1);
- if(!first) vuVerts += 2*3;
- w = skipUnpack(w);
-
- // tex coords
- assert(w[0] == 0x20000000); // STMASK
- w += 2;
- assert(w[0] == 0x30000000); // STROW
- w += 5;
- assert((w[0] & 0xFF004000) == 0x76004000);
- vuTex = (uint8*)(w+1);
- if(!first) vuTex += 2*2;
- w = skipUnpack(w);
-
- if(g->geoflags & Geometry::NORMALS){
- assert((w[0] & 0xFF004000) == 0x6A000000);
- vuNorms = (int8*)(w+1);
- if(!first) vuNorms += 2*3;
- w = skipUnpack(w);
- }
-
- if(g->geoflags & Geometry::PRELIT){
- assert((w[0] & 0xFF004000) == 0x6F000000);
- vuCols = (uint16*)(w+1);
- if(!first) vuCols += 2;
- w = skipUnpack(w);
- }
-
- if(skin){
- assert((w[0] & 0xFF004000) == 0x6C000000);
- vuSkin = w+1;
- if(!first) vuSkin += 2*4;
- w = skipUnpack(w);
- }
-
- assert(w[0] == 0x14000006); // MSCAL
- w++;
- while(w[0] == 0) w++;
-
- /* Insert Data */
- for(int32 i = 0; i < nvert; i++){
- v.p[0] = vuVerts[0]/32768.0f*rg->scale[0] + rg->pos[0];
- v.p[1] = vuVerts[1]/32768.0f*rg->scale[1] + rg->pos[1];
- v.p[2] = vuVerts[2]/32768.0f*rg->scale[2] + rg->pos[2];
- v.t[0] = vuTex[0]/128.0f*rm->uvScale[0];
- v.t[1] = vuTex[1]/128.0f*rm->uvScale[1];
- if(mask & 0x10){
- v.n[0] = vuNorms[0]/127.0f;
- v.n[1] = vuNorms[1]/127.0f;
- v.n[2] = vuNorms[2]/127.0f;
- }
- if(mask & 0x100){
- v.c[0] = (vuCols[0] & 0x1f) * 255 / 0x1F;
- v.c[1] = (vuCols[0]>>5 & 0x1f) * 255 / 0x1F;
- v.c[2] = (vuCols[0]>>10 & 0x1f) * 255 / 0x1F;
- v.c[3] = vuCols[0]&0x8000 ? 0xFF : 0;
- }
- if(mask & 0x10000){
- for(int j = 0; j < 4; j++){
- ((uint32*)v.w)[j] = vuSkin[j] & ~0x3FF;
- v.i[j] = vuSkin[j] >> 2;
- //if(v.i[j]) v.i[j]--;
- if(v.w[j] == 0.0f) v.i[j] = 0;
- }
- }
-
- int32 idx = ps2::findVertexSkin(g, NULL, mask, &v);
- if(idx < 0)
- idx = g->numVertices++;
- /* Insert mesh joining indices when we get the index of the first vertex
- * in the first VU chunk of a non-first RslMesh. */
- if(i == 0 && first && rm != &rg->meshes[0] && (rm-1)->matID == rm->matID){
- m->indices[m->numIndices] = m->indices[m->numIndices-1];
- m->numIndices++;
- m->indices[m->numIndices++] = idx;
- if((rm-1)->numTriangles % 2)
- m->indices[m->numIndices++] = idx;
- }
- m->indices[m->numIndices++] = idx;
- ps2::insertVertexSkin(g, idx, mask, &v);
-
- vuVerts += 3;
- vuTex += 2;
- vuNorms += 3;
- vuCols++;
- vuSkin += 4;
- }
- first = 0;
- }
-}
-
-void
-convertRslGeometry(Geometry *g)
-{
- RslGeometry *rg = *PLUGINOFFSET(RslGeometry*, g, rslPluginOffset);
- assert(rg != NULL);
-
- g->meshHeader = new MeshHeader;
- g->meshHeader->flags = 1;
- g->meshHeader->numMeshes = g->numMaterials;
- g->meshHeader->mesh = new Mesh[g->meshHeader->numMeshes];
- g->meshHeader->totalIndices = 0;
- Mesh *meshes = g->meshHeader->mesh;
- for(uint32 i = 0; i < g->meshHeader->numMeshes; i++)
- meshes[i].numIndices = 0;
- RslMesh *rm = rg->meshes;
- int32 lastId = -1;
- for(uint32 i = 0; i < rg->numMeshes; i++, rm++){
- Mesh *m = &meshes[rm->matID];
- g->numVertices += rm->numTriangles+2;
- m->numIndices += rm->numTriangles+2;
- // Extra indices since we're merging tristrip
- // meshes with the same material.
- // Be careful with face winding.
- if(lastId == rm->matID)
- m->numIndices += (rm-1)->numTriangles % 2 ? 3 : 2;
- lastId = rm->matID;
- }
- for(uint32 i = 0; i < g->meshHeader->numMeshes; i++){
- g->meshHeader->mesh[i].material = g->materialList[i];
- g->meshHeader->totalIndices += meshes[i].numIndices;
- }
- g->geoflags = Geometry::TRISTRIP |
- Geometry::POSITIONS | /* 0x01 ? */
- Geometry::TEXTURED | /* 0x04 ? */
- Geometry::LIGHT;
- if(g->hasColoredMaterial())
- g->geoflags |= Geometry::MODULATE;
- if(rg->flags & 0x2)
- g->geoflags |= Geometry::NORMALS;
- if(rg->flags & 0x8)
- g->geoflags |= Geometry::PRELIT;
- g->numTexCoordSets = 1;
-
- g->allocateData();
- g->meshHeader->allocateIndices();
-
- Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
- if(rg->flags & 0x10)
- assert(skin);
- if(skin){
- uint8 *data = skin->data;
- float *invMats = skin->inverseMatrices;
- skin->init(skin->numBones, skin->numBones, g->numVertices);
- memcpy(skin->inverseMatrices, invMats, skin->numBones*64);
- delete[] data;
- }
-
- for(uint32 i = 0; i < g->meshHeader->numMeshes; i++)
- meshes[i].numIndices = 0;
- g->numVertices = 0;
- rm = rg->meshes;
- for(uint32 i = 0; i < rg->numMeshes; i++, rm++)
- convertRslMesh(g, rg, &meshes[rm->matID], rm);
-
- if(skin){
- skin->findNumWeights(g->numVertices);
- skin->findUsedBones(g->numVertices);
- }
- g->calculateBoundingSphere();
- g->generateTriangles();
-}
-
-Geometry*
-geometryStreamReadRsl(Stream *stream)
-{
- RslGeometry *rg = new RslGeometry;
- stream->read(rg, 0x40);
- rg->numMeshes = rg->size >> 20;
- rg->size &= 0xFFFFF;
- rg->meshes = new RslMesh[rg->numMeshes];
- rg->dataSize = rg->size - 0x40;
- stream->read(rg->meshes, rg->numMeshes*sizeof(RslMesh));
- rg->dataSize -= rg->numMeshes*sizeof(RslMesh);
- rg->data = new uint8[rg->dataSize];
- stream->read(rg->data, rg->dataSize);
-
- Geometry *g = new Geometry(0, 0, 0);
- *PLUGINOFFSET(RslGeometry*, g, rslPluginOffset) = rg;
-
- assert(findChunk(stream, ID_MATLIST, NULL, NULL));
- assert(findChunk(stream, ID_STRUCT, NULL, NULL));
- g->numMaterials = stream->readI32();
- g->materialList = new Material*[g->numMaterials];
- stream->seek(g->numMaterials*4); // unused (-1)
- for(int32 i = 0; i < g->numMaterials; i++){
- assert(findChunk(stream, ID_MATERIAL, NULL, NULL));
- g->materialList[i] = Material::streamRead(stream);
- // unimplemented by Rsl
- g->materialList[i]->surfaceProps.ambient = 1.0f;
- g->materialList[i]->surfaceProps.specular = 1.0f;
- g->materialList[i]->surfaceProps.diffuse = 1.0f;
- }
-
- g->streamReadPlugins(stream);
-
- return g;
-}
-
-bool
-geometryStreamWriteRsl(Stream *stream, Geometry *g)
-{
- uint32 buf[3] = { ID_GEOMETRY, geometryStreamGetSizeRsl(g), 0xf00d };
- stream->write(&buf, 12);
-
- RslGeometry *rg = *PLUGINOFFSET(RslGeometry*, g, rslPluginOffset);
- assert(rg != NULL);
- rg->size |= rg->numMeshes << 20;
- stream->write(rg, 0x40);
- rg->numMeshes = rg->size >> 20;
- rg->size &= 0xFFFFF;
- stream->write(rg->meshes, rg->numMeshes*sizeof(RslMesh));
- stream->write(rg->data, rg->dataSize);
-
- uint32 size = 12 + 4;
- for(int32 i = 0; i < g->numMaterials; i++)
- size += 4 + 12 + g->materialList[i]->streamGetSize();
- writeChunkHeader(stream, ID_MATLIST, size);
- writeChunkHeader(stream, ID_STRUCT, 4 + g->numMaterials*4);
- stream->writeI32(g->numMaterials);
- for(int32 i = 0; i < g->numMaterials; i++)
- stream->writeI32(-1);
- for(int32 i = 0; i < g->numMaterials; i++)
- g->materialList[i]->streamWrite(stream);
-
- g->streamWritePlugins(stream);
- return true;
-}
-
-uint32
-geometryStreamGetSizeRsl(Geometry *g)
-{
- RslGeometry *rg = *PLUGINOFFSET(RslGeometry*, g, rslPluginOffset);
- assert(rg != NULL);
-
- uint32 size = rg->size;
- size += 12 + 12 + 4;
- for(int32 i = 0; i < g->numMaterials; i++)
- size += 4 + 12 + g->materialList[i]->streamGetSize();
- size += 12 + g->streamGetPluginSize();
- return size;
-}
-
-static uint32 atomicRights[2];
-
-Atomic*
-atomicStreamReadRsl(Stream *stream, Frame **frameList)
-{
- int32 buf[4];
- uint32 version;
- assert(findChunk(stream, ID_STRUCT, NULL, &version));
- stream->read(buf, 16);
- Atomic *atomic = new Atomic;
- atomic->frame = frameList[buf[0]];
- assert(findChunk(stream, ID_GEOMETRY, NULL, &version));
- assert(version == 0x00f00d00);
- atomic->geometry = geometryStreamReadRsl(stream);
-
- atomicRights[0] = 0;
- atomic->streamReadPlugins(stream);
- if(atomicRights[0])
- atomic->assertRights(atomicRights[0], atomicRights[1]);
- return atomic;
-}
-
-bool
-atomicStreamWriteRsl(Stream *stream, Atomic *a, Frame **frameList, int32 numFrames)
-{
- int32 buf[4] = { 0, 0, 5, 0 };
- Clump *c = a->clump;
- if(c == NULL)
- return false;
- writeChunkHeader(stream, ID_ATOMIC, atomicStreamGetSizeRsl(a));
- buf[0] = findPointer((void*)a->frame, (void**)frameList, numFrames);
- writeChunkHeader(stream, ID_STRUCT, 16);
- stream->write(buf, sizeof(buf));
-
- geometryStreamWriteRsl(stream, a->geometry);
-
- a->streamWritePlugins(stream);
- return true;
-}
-
-uint32
-atomicStreamGetSizeRsl(Atomic *a)
-{
- uint32 size = 12 + 12 + 12 + a->streamGetPluginSize();
- size += 16 + geometryStreamGetSizeRsl(a->geometry);
- return size;
-}
-
-Clump*
-clumpStreamReadRsl(Stream *stream)
-{
- uint32 length, version;
- int32 buf[3];
- Clump *clump;
- assert(findChunk(stream, ID_STRUCT, &length, &version));
- clump = new Clump;
- stream->read(buf, length);
- clump->numAtomics = buf[0];
- clump->numLights = 0;
- clump->numCameras = 0;
-
- // Frame list
- Frame **frameList;
- int32 numFrames;
- clump->frameListStreamRead(stream, &frameList, &numFrames);
- clump->parent = (void*)frameList[0];
-
- Geometry **geometryList = 0;
-
- // Atomics
- if(clump->numAtomics)
- clump->atomicList = new Atomic*[clump->numAtomics];
- for(int32 i = 0; i < clump->numAtomics; i++){
- assert(findChunk(stream, ID_ATOMIC, NULL, NULL));
- clump->atomicList[i] = atomicStreamReadRsl(stream, frameList);
- clump->atomicList[i]->clump = clump;
- }
-
- delete[] frameList;
-
- clump->streamReadPlugins(stream);
- return clump;
-}
-
-bool
-clumpStreamWriteRsl(Stream *stream, Clump *c)
-{
- int size = clumpStreamGetSizeRsl(c);
- writeChunkHeader(stream, ID_CLUMP, size);
- int buf[3] = { c->numAtomics, 0, 0 };
- writeChunkHeader(stream, ID_STRUCT, 4);
- stream->write(buf, 4);
-
- int32 numFrames = ((Frame*)c->parent)->count();
- Frame **flist = new Frame*[numFrames];
- makeFrameList((Frame*)c->parent, flist);
-
- c->frameListStreamWrite(stream, flist, numFrames);
-
- for(int32 i = 0; i < c->numAtomics; i++)
- atomicStreamWriteRsl(stream, c->atomicList[i], flist, numFrames);
-
- delete[] flist;
-
- c->streamWritePlugins(stream);
- return true;
-}
-
-static Frame*
-sizeCB(Frame *f, void *size)
-{
- *(int32*)size += f->streamGetPluginSize();
- f->forAllChildren(sizeCB, size);
- return f;
-}
-
-uint32
-clumpStreamGetSizeRsl(Clump *c)
-{
- uint32 size = 0;
- size += 12; // Struct
- size += 4; // numAtomics
-
- // frame list
- // TODO: make this into a function
- int32 numFrames = ((Frame*)c->parent)->count();
- size += 12 + 12 + 4 + numFrames*(56+12);
- sizeCB((Frame*)c->parent, (void*)&size);
-
- // atomics
- for(int32 i = 0; i < c->numAtomics; i++)
- size += 12 + atomicStreamGetSizeRsl(c->atomicList[i]);
-
- size += 12 + c->streamGetPluginSize();
- return size;
-}
-
-
-static void*
-createRslGeo(void *object, int32 offset, int32)
-{
- *PLUGINOFFSET(RslGeometry*, object, offset) = NULL;
- return object;
-}
-
-static void*
-destroyRslGeo(void *object, int32 offset, int32)
-{
- RslGeometry *rg = *PLUGINOFFSET(RslGeometry*, object, offset);
- delete rg->data;
- delete rg->meshes;
- delete rg;
- *PLUGINOFFSET(RslGeometry*, object, offset) = NULL;
- return object;
-}
-
-static void*
-copyRslGeo(void *dst, void *src, int32 offset, int32)
-{
- // TODO
- return dst;
-}
-
-void
-registerRslPlugin(void)
-{
- rslPluginOffset = Geometry::registerPlugin(sizeof(RslGeometry*), ID_RSL,
- createRslGeo,
- destroyRslGeo,
- copyRslGeo);
-}
diff --git a/src/mdl.h b/src/mdl.h
deleted file mode 100644
index 7125685..0000000
--- a/src/mdl.h
+++ /dev/null
@@ -1,13 +0,0 @@
-rw::Clump *clumpStreamReadRsl(rw::Stream *stream);
-bool clumpStreamWriteRsl(rw::Stream *stream, rw::Clump *c);
-rw::uint32 clumpStreamGetSizeRsl(rw::Clump *c);
-
-rw::Atomic *atomicStreamReadRsl(rw::Stream *stream, rw::Frame **frameList);
-rw::uint32 atomicStreamGetSizeRsl(rw::Atomic *a);
-
-rw::Geometry *geometryStreamReadRsl(rw::Stream *stream);
-rw::uint32 geometryStreamGetSizeRsl(rw::Geometry *g);
-
-void convertRslGeometry(rw::Geometry *g);
-
-void registerRslPlugin(void);
\ No newline at end of file
diff --git a/src/plugins.cpp b/src/plugins.cpp
index 4e88962..4f9eeea 100644
--- a/src/plugins.cpp
+++ b/src/plugins.cpp
@@ -499,7 +499,7 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
skin->init(header[0], header[1], geometry->numVertices);
skin->numWeights = header[2];
- if(!oldFormat && !skinGlobals.forceSkipUsedBones)
+ if(!oldFormat)
stream->read(skin->usedBones, skin->numUsedBones);
if(skin->indices)
stream->read(skin->indices, geometry->numVertices*4);
@@ -826,6 +826,22 @@ MatFX::getEffectIndex(uint32 type)
return -1;
}
+void
+MatFX::setEnvTexture(Texture *t)
+{
+ int32 i = this->getEffectIndex(ENVMAP);
+ if(i >= 0)
+ this->fx[i].env.tex = t;
+}
+
+void
+MatFX::setEnvCoefficient(float32 coef)
+{
+ int32 i = this->getEffectIndex(ENVMAP);
+ if(i >= 0)
+ this->fx[i].env.coefficient = coef;
+}
+
static void*
createMaterialMatFX(void *object, int32 offset, int32)
{
@@ -889,13 +905,7 @@ readMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
*PLUGINOFFSET(MatFX*, object, offset) = matfx;
matfx->setEffects(stream->readU32());
- if(matfx->type == MatFX::BUMPMAP && matFXGlobals.hack){
- stream->seek(12);
- return;
- }
-
- int32 n = matFXGlobals.hack ? 1 : 2;
- for(int i = 0; i < n; i++){
+ for(int i = 0; i < 2; i++){
uint32 type = stream->readU32();
switch(type){
case MatFX::BUMPMAP:
@@ -920,10 +930,7 @@ readMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
case MatFX::ENVMAP:
coefficient = stream->readF32();
- if(matFXGlobals.hack)
- fbAlpha = 0;
- else
- fbAlpha = stream->readI32();
+ fbAlpha = stream->readI32();
tex = NULL;
if(stream->readI32()){
assert(findChunk(stream, ID_TEXTURE,
diff --git a/src/rwobjects.h b/src/rwobjects.h
index 4de0506..9f119df 100644
--- a/src/rwobjects.h
+++ b/src/rwobjects.h
@@ -8,6 +8,7 @@ struct Object
void *parent;
};
+// TODO: missing: list of attached objects
struct Frame : PluginBase, Object
{
typedef Frame *(*Callback)(Frame *f, void *data);
@@ -270,6 +271,8 @@ struct MatFX
void setEffects(uint32 flags);
int32 getEffectIndex(uint32 type);
+ void setEnvTexture(Texture *t);
+ void setEnvCoefficient(float32 coef);
};
struct MatFXGlobals
@@ -277,7 +280,6 @@ struct MatFXGlobals
int32 atomicOffset;
int32 materialOffset;
ObjPipeline *pipelines[NUM_PLATFORMS];
- bool32 hack;
};
extern MatFXGlobals matFXGlobals;
void registerMatFXPlugin(void);
@@ -387,7 +389,6 @@ struct SkinGlobals
{
int32 offset;
ObjPipeline *pipelines[NUM_PLATFORMS];
- bool32 forceSkipUsedBones;
};
extern SkinGlobals skinGlobals;
void registerSkinPlugin(void);
diff --git a/tools/d3d9/d3dInit.cpp b/tools/d3d9/d3dInit.cpp
index 7376296..93620ab 100644
--- a/tools/d3d9/d3dInit.cpp
+++ b/tools/d3d9/d3dInit.cpp
@@ -74,8 +74,8 @@ setMaterial(Material *mat)
{
D3DMATERIAL9 mat9;
D3DCOLORVALUE black = { 0, 0, 0, 0 };
- float ambmult = mat->surfaceProps[0]/255.0f;
- float diffmult = mat->surfaceProps[2]/255.0f;
+ float ambmult = mat->surfaceProps.ambient/255.0f;
+ float diffmult = mat->surfaceProps.diffuse/255.0f;
mat9.Ambient.r = mat->color[0]*ambmult;
mat9.Ambient.g = mat->color[1]*ambmult;
mat9.Ambient.b = mat->color[2]*ambmult;
diff --git a/tools/insttest/insttest.cpp b/tools/insttest/insttest.cpp
index 08c6dcc..469bb54 100644
--- a/tools/insttest/insttest.cpp
+++ b/tools/insttest/insttest.cpp
@@ -25,37 +25,6 @@ struct {
char *argv0;
-Frame*
-findHierCB(Frame *f, void *p)
-{
- HAnimData *hanim = PLUGINOFFSET(HAnimData, f, hAnimOffset);
- if(hanim->hierarchy){
- *(HAnimHierarchy**)p = hanim->hierarchy;
- return NULL;
- }
- f->forAllChildren(findHierCB, p);
- return f;
-}
-
-HAnimHierarchy*
-getHierarchy(Clump *c)
-{
- HAnimHierarchy *hier = NULL;
- findHierCB((Frame*)c->parent, &hier);
- return hier;
-}
-
-void
-fixLcsHier(HAnimHierarchy *hier)
-{
- hier->maxInterpKeyFrameSize = findAnimInterpolatorInfo(1)->keyFrameSize;
- for(int32 i = 0; i < hier->numNodes; i++){
- int32 id = hier->nodeInfo[i].id;
- if(id == 255) hier->nodeInfo[i].id = -1;
- else if(id > 0x80) hier->nodeInfo[i].id |= 0x1300;
- }
-}
-
void
usage(void)
{
@@ -64,7 +33,6 @@ usage(void)
fprintf(stderr, "\t-i instance\n");
fprintf(stderr, "\t-v RW version, e.g. 33004 for 3.3.0.4\n");
fprintf(stderr, "\t-o output platform. ps2, xbox, mobile, d3d8, d3d9\n");
- fprintf(stderr, "\t-s expect iOS LCS dff as input\n");
exit(1);
}
@@ -84,7 +52,6 @@ main(int argc, char *argv[])
int uninstance = 0;
int instance = 0;
- int lcs = 0;
int outplatform = rw::PLATFORM_D3D8;
char *s;
@@ -110,9 +77,6 @@ main(int argc, char *argv[])
outplatform = PLATFORM_D3D8;
found:
break;
- case 's':
- lcs++;
- break;
default:
usage();
}ARGEND;
@@ -122,9 +86,6 @@ main(int argc, char *argv[])
return 1;
}
- matFXGlobals.hack = lcs;
- skinGlobals.forceSkipUsedBones = lcs;
-
if(argc < 1)
usage();
@@ -145,10 +106,7 @@ main(int argc, char *argv[])
}
assert(header.type == ID_CLUMP);
debugFile = argv[0];
- if(lcs)
- c = clumpStreamReadRsl(&in);
- else
- c = Clump::streamRead(&in);
+ c = Clump::streamRead(&in);
assert(c != NULL);
in.close();
@@ -173,18 +131,6 @@ main(int argc, char *argv[])
switchPipes(c, rw::platform);
}
- if(lcs){
- HAnimHierarchy *hier = getHierarchy(c);
- if(hier)
- fixLcsHier(hier);
- for(int32 i = 0; i < c->numAtomics; i++){
- Skin *skin = *PLUGINOFFSET(Skin*, c->atomicList[i]->geometry, skinGlobals.offset);
- convertRslGeometry(c->atomicList[i]->geometry);
- if(skin)
- c->atomicList[i]->pipeline = skinGlobals.pipelines[rw::platform];
- }
- }
-
if(uninstance)
for(int32 i = 0; i < c->numAtomics; i++){
Atomic *a = c->atomicList[i];
diff --git a/tools/rsltest/rsl.cpp b/tools/rsltest/rsl.cpp
index 42f60b2..91027d0 100644
--- a/tools/rsltest/rsl.cpp
+++ b/tools/rsltest/rsl.cpp
@@ -28,15 +28,15 @@ RslMatrixSetIdentity(RslMatrix *matrix)
void
rslObjectHasFrameSetFrame(RslObjectHasFrame *object, RslFrame *f)
{
- if(object->object.parent){
- object->lFrame.prev->next = object->lFrame.next;
- object->lFrame.next->prev = object->lFrame.prev;
- }
+ if(object->object.parent){
+ object->lFrame.prev->next = object->lFrame.next;
+ object->lFrame.next->prev = object->lFrame.prev;
+ }
object->object.parent = f;
- if(f){
- object->lFrame.prev = &f->objectList.link;
- object->lFrame.next = f->objectList.link.next;
- f->objectList.link.next->prev = &object->lFrame;
+ if(f){
+ object->lFrame.prev = &f->objectList.link;
+ object->lFrame.next = f->objectList.link.next;
+ f->objectList.link.next->prev = &object->lFrame;
f->objectList.link.next = &object->lFrame;
f->root->object.privateFlags |= 1;
@@ -49,8 +49,8 @@ RslFrameCreate(void)
{
RslFrame *f = new RslFrame;
rslObjectInitialize(&f->object, 0, 0);
- f->objectList.link.prev = &f->objectList.link;
- f->objectList.link.next = &f->objectList.link;
+ f->objectList.link.prev = &f->objectList.link;
+ f->objectList.link.next = &f->objectList.link;
RslMatrixSetIdentity(&f->modelling);
RslMatrixSetIdentity(&f->ltm);
f->child = NULL;
@@ -71,15 +71,24 @@ RslFrameAddChild(RslFrame *parent, RslFrame *child)
{
RslFrame *p = (RslFrame*)child->object.parent;
assert(p == NULL);
- child->next = parent->child;
- parent->child = child;
- child->object.parent = parent;
- child->root = parent->root;
- child->root->object.privateFlags |= 1;
+ child->next = parent->child;
+ parent->child = child;
+ child->object.parent = parent;
+ child->root = parent->root;
+ child->root->object.privateFlags |= 1;
child->object.privateFlags |= 2;
return parent;
}
+int32
+RslFrameCount(RslFrame *f)
+{
+ int32 n = 1;
+ for(RslFrame *c = f->child; c; c = c->next)
+ n += RslFrameCount(c);
+ return n;
+}
+
RslFrame*
RslFrameForAllChildren(RslFrame *frame, RslFrameCallBack callBack, void *data)
{
@@ -99,7 +108,7 @@ struct StreamFrame
};
void
-rwFrameListStreamRead(Stream *stream, rslFrameList *framelist)
+rslFrameListStreamRead(Stream *stream, rslFrameList *framelist)
{
uint32 length;
StreamFrame strfrm;
@@ -140,6 +149,25 @@ rwFrameListStreamRead(Stream *stream, rslFrameList *framelist)
}
}
+static RslFrame**
+rslFrameListFill(RslFrame *f, RslFrame **flist)
+{
+ *flist++ = f;
+ if(f->next)
+ flist = rslFrameListFill(f->next, flist);
+ if(f->child)
+ flist = rslFrameListFill(f->child, flist);
+ return flist;
+}
+
+void
+rslFrameListInitialize(rslFrameList *frameList, RslFrame *root)
+{
+ frameList->numFrames = RslFrameCount(root);
+ frameList->frames = new RslFrame*[frameList->numFrames];
+ rslFrameListFill(root, frameList->frames);
+}
+
RslHAnimHierarchy*
RslHAnimHierarchyCreate(int32 numNodes, uint32 *nodeFlags, int32 *nodeIDs, int32 flags, int32 maxKeySize)
{
@@ -147,10 +175,10 @@ RslHAnimHierarchyCreate(int32 numNodes, uint32 *nodeFlags, int32 *nodeIDs, int32
memset(hier, 0, sizeof(RslHAnimHierarchy));
if(maxKeySize < 0x24)
maxKeySize = 0x24;
- hier->flags = flags;
- hier->numNodes = numNodes;
- hier->parentFrame = 0;
- hier->maxKeyFrameSize = maxKeySize;
+ hier->flags = flags;
+ hier->numNodes = numNodes;
+ hier->parentFrame = 0;
+ hier->maxKeyFrameSize = maxKeySize;
hier->currentKeyFrameSize = 0x24;
int32 msz = numNodes*0x40 + 0x3f;
@@ -320,7 +348,7 @@ RslClumpStreamRead(Stream *stream)
clump = RslClumpCreate();
assert(findChunk(stream, ID_FRAMELIST, NULL, NULL));
- rwFrameListStreamRead(stream, &framelist);
+ rslFrameListStreamRead(stream, &framelist);
clump->object.parent = framelist.frames[0];
for(int32 i = 0; i < numAtomics; i++){
@@ -336,16 +364,17 @@ RslClumpStreamRead(Stream *stream)
stream->seek(header.length);
length -= 12 + header.length;
}
+ delete[] framelist.frames;
return clump;
}
RslClump*
RslClumpAddAtomic(RslClump *clump, RslAtomic *a)
-{
- a->inClumpLink.prev = &clump->atomicList.link;
- a->inClumpLink.next = clump->atomicList.link.next;
- clump->atomicList.link.next->prev = &a->inClumpLink;
- clump->atomicList.link.next = &a->inClumpLink;
+{
+ a->inClumpLink.prev = &clump->atomicList.link;
+ a->inClumpLink.next = clump->atomicList.link.next;
+ clump->atomicList.link.next->prev = &a->inClumpLink;
+ clump->atomicList.link.next = &a->inClumpLink;
a->clump = clump;
return clump;
}
@@ -365,6 +394,18 @@ RslClumpForAllAtomics(RslClump *clump, RslAtomicCallBack callback, void *pData)
return clump;
}
+int32
+RslClumpGetNumAtomics(RslClump *clump)
+{
+ int32 n = 0;
+ RslLLLink *link;
+ for(link = rslLLLinkGetNext(&clump->atomicList.link);
+ link != &clump->atomicList.link;
+ link = link->next)
+ n++;
+ return n;
+}
+
RslGeometry*
RslGeometryCreatePS2(uint32 sz)
{
@@ -385,13 +426,13 @@ RslGeometryForAllMaterials(RslGeometry *geometry, RslMaterialCallBack fpCallBack
return geometry;
}
-struct RslMaterialChunkInfo
-{
- int32 flags;
- RslRGBA color; // used
- int32 unused;
- bool32 textured; // used
- SurfaceProperties surfaceProps;
+struct RslMaterialChunkInfo
+{
+ int32 flags;
+ RslRGBA color; // used
+ int32 unused;
+ bool32 textured; // used
+ SurfaceProperties surfaceProps;
};
RslMaterial*
@@ -479,11 +520,11 @@ void
rpMaterialListAppendMaterial(RslMaterialList *matlist, RslMaterial *mat)
{
if(matlist->space <= matlist->numMaterials){
- matlist->space += 16;
RslMaterial **mats = matlist->materials;
- matlist->materials = new RslMaterial*[matlist->space];
- if(matlist->space-16)
- memcpy(matlist->materials, mats, (matlist->space+16)*sizeof(RslMaterial*));
+ matlist->materials = new RslMaterial*[matlist->space+16];
+ if(matlist->space)
+ memcpy(matlist->materials, mats, matlist->space*sizeof(RslMaterial*));
+ matlist->space += 16;
delete[] mats;
}
matlist->materials[matlist->numMaterials++] = mat;
diff --git a/tools/rsltest/rsl.h b/tools/rsltest/rsl.h
index 10a8292..d821c9d 100644
--- a/tools/rsltest/rsl.h
+++ b/tools/rsltest/rsl.h
@@ -42,12 +42,12 @@ typedef RslAtomic *(*RslAtomicCallBack)(RslAtomic *atomic, void *data);
typedef RslMaterial *(*RslMaterialCallBack)(RslMaterial *material, void *data);
typedef RslTexture *(*RslTextureCallBack)(RslTexture *texture, void *pData);
-struct RslRGBA
-{
- uint8 red;
- uint8 green;
- uint8 blue;
- uint8 alpha;
+struct RslRGBA
+{
+ uint8 red;
+ uint8 green;
+ uint8 blue;
+ uint8 alpha;
};
struct RslV3d
@@ -57,13 +57,13 @@ struct RslV3d
struct RslMatrix
{
- RslV3d right;
- uint32 flags;
- RslV3d up;
- uint32 pad1;
- RslV3d at;
- uint32 pad2;
- RslV3d pos;
+ RslV3d right;
+ uint32 flags;
+ RslV3d up;
+ uint32 pad1;
+ RslV3d at;
+ uint32 pad2;
+ RslV3d pos;
uint32 pad3;
};
@@ -104,16 +104,17 @@ struct RslObject {
void *parent;
};
-#define rslObjectInitialize(o, t, s) \
-{ \
- ((RslObject*)(o))->type = (uint8)(t); \
- ((RslObject*)(o))->subType = (uint8)(s); \
- ((RslObject*)(o))->flags = 0; \
- ((RslObject*)(o))->privateFlags = 0; \
- ((RslObject*)(o))->parent = NULL; \
+#define rslObjectInitialize(o, t, s) \
+{ \
+ ((RslObject*)(o))->type = (uint8)(t); \
+ ((RslObject*)(o))->subType = (uint8)(s); \
+ ((RslObject*)(o))->flags = 0; \
+ ((RslObject*)(o))->privateFlags = 0; \
+ ((RslObject*)(o))->parent = NULL; \
}
-#define rslObjectGetParent(object) (((const RslObject *)(object))->parent)
+#define rslObjectGetParent(object) (((RslObject*)(object))->parent)
+#define rslObjectSetParent(c,p) (((RslObject*)(c))->parent) = (void*)(p)
struct RslObjectHasFrame {
RslObject object;
@@ -197,6 +198,7 @@ struct RslFrame {
RslFrame *RslFrameCreate(void);
RslFrame *RslFrameAddChild(RslFrame *parent, RslFrame *child);
+int32 RslFrameCount(RslFrame *f);
RslFrame *RslFrameForAllChildren(RslFrame *frame, RslFrameCallBack callBack, void *data);
struct rslFrameList
@@ -205,16 +207,25 @@ struct rslFrameList
int32 numFrames;
};
+void rslFrameListStreamRead(Stream *stream, rslFrameList *framelist);
+void rslFrameListInitialize(rslFrameList *frameList, RslFrame *root);
+
struct RslClump {
RslObject object;
RslLinkList atomicList;
};
#define RslClumpGetFrame(_clump) \
- ((RslFrame *) rslObjectGetParent(_clump))
+ ((RslFrame*)rslObjectGetParent(_clump))
+#define RslClumpSetFrame(_clump, _frame) \
+ (rslObjectSetParent(_clump, _frame), \
+ (_clump))
+
+RslClump *RslClumpCreate(void);
RslClump *RslClumpStreamRead(Stream *stream);
RslClump *RslClumpAddAtomic(RslClump *clump, RslAtomic *a);
+int32 RslClumpGetNumAtomics(RslClump *clump);
RslClump *RslClumpForAllAtomics(RslClump *clump, RslAtomicCallBack callback, void *pData);
struct RslAtomic {
@@ -234,7 +245,7 @@ struct RslAtomic {
};
#define RslAtomicGetFrame(_atomic) \
- ((RslFrame *) rslObjectGetParent(_atomic))
+ ((RslFrame*)rslObjectGetParent(_atomic))
RslAtomic *RslAtomicCreate(void);
RslAtomic *RslAtomicSetFrame(RslAtomic *atomic, RslFrame *frame);
diff --git a/tools/rsltest/rsltest.cpp b/tools/rsltest/rsltest.cpp
index 31d4b73..8098891 100644
--- a/tools/rsltest/rsltest.cpp
+++ b/tools/rsltest/rsltest.cpp
@@ -40,7 +40,8 @@ RslFrame *dumpFrameCB(RslFrame *frame, void *data)
RslMaterial *dumpMaterialCB(RslMaterial *material, void*)
{
- printf(" mat: %s %x\n", material->texname, material->refCount);
+ printf(" mat: %d %d %d %d %s %x\n", material->color.red, material->color.green, material->color.blue, material->color.alpha,
+ material->texname, material->refCount);
if(material->matfx){
RslMatFX *fx = material->matfx;
printf(" matfx: ", fx->effectType);
@@ -59,6 +60,411 @@ RslAtomic *dumpAtomicCB(RslAtomic *atomic, void*)
return atomic;
}
+int32
+mapID(int32 id)
+{
+ if(id == 255) return -1;
+ if(id > 0x80) id |= 0x1300;
+ return id;
+}
+
+Frame*
+convertFrame(RslFrame *f)
+{
+ Frame *rwf = new Frame;
+ rwf->matrix[0] = f->modelling.right.x;
+ rwf->matrix[1] = f->modelling.right.y;
+ rwf->matrix[2] = f->modelling.right.z;
+ rwf->matrix[4] = f->modelling.up.x;
+ rwf->matrix[5] = f->modelling.up.y;
+ rwf->matrix[6] = f->modelling.up.z;
+ rwf->matrix[8] = f->modelling.at.x;
+ rwf->matrix[9] = f->modelling.at.y;
+ rwf->matrix[10] = f->modelling.at.z;
+ rwf->matrix[12] = f->modelling.pos.x;
+ rwf->matrix[13] = f->modelling.pos.y;
+ rwf->matrix[14] = f->modelling.pos.z;
+
+ if(f->name)
+ strncpy(gta::getNodeName(rwf), f->name, 24);
+
+ HAnimData *hanim = PLUGINOFFSET(HAnimData, rwf, hAnimOffset);
+ hanim->id = f->nodeId;
+ if(f->hier){
+ HAnimHierarchy *hier;
+ hanim->hierarchy = hier = new HAnimHierarchy;
+ hier->numNodes = f->hier->numNodes;
+ hier->flags = f->hier->flags;
+ hier->maxInterpKeyFrameSize = f->hier->maxKeyFrameSize;
+ hier->parentFrame = rwf;
+ hier->parentHierarchy = hier;
+ hier->nodeInfo = new HAnimNodeInfo[hier->numNodes];
+ for(int32 i = 0; i < hier->numNodes; i++){
+ hier->nodeInfo[i].id = mapID((uint8)f->hier->pNodeInfo[i].id);
+ hier->nodeInfo[i].index = f->hier->pNodeInfo[i].index;
+ hier->nodeInfo[i].flags = f->hier->pNodeInfo[i].flags;
+ hier->nodeInfo[i].frame = NULL;
+ }
+ }
+ return rwf;
+}
+
+Texture*
+convertTexture(RslTexture *t)
+{
+ Texture *tex = Texture::read(t->name, t->mask);
+ //tex->refCount++; // ??
+ if(tex->refCount == 1)
+ tex->filterAddressing = (Texture::WRAP << 12) | (Texture::WRAP << 8) | Texture::LINEAR;
+ return tex;
+}
+
+Material*
+convertMaterial(RslMaterial *m)
+{
+ Material *rwm;
+ rwm = new Material;
+
+ rwm->color[0] = m->color.red;
+ rwm->color[1] = m->color.green;
+ rwm->color[2] = m->color.blue;
+ rwm->color[3] = m->color.alpha;
+ if(m->texture)
+ rwm->texture = convertTexture(m->texture);
+
+ if(m->matfx){
+ MatFX *matfx = new MatFX;
+ matfx->setEffects(m->matfx->effectType);
+ matfx->setEnvCoefficient(m->matfx->env.intensity);
+ if(m->matfx->env.texture)
+ matfx->setEnvTexture(convertTexture(m->matfx->env.texture));
+ *PLUGINOFFSET(MatFX*, rwm, matFXGlobals.materialOffset) = matfx;
+ }
+ return rwm;
+}
+
+static uint32
+unpackSize(uint32 unpack)
+{
+ if((unpack&0x6F000000) == 0x6F000000)
+ return 2;
+ static uint32 size[] = { 32, 16, 8, 16 };
+ return ((unpack>>26 & 3)+1)*size[unpack>>24 & 3]/8;
+}
+
+static uint32*
+skipUnpack(uint32 *p)
+{
+ int32 n = (p[0] >> 16) & 0xFF;
+ return p + (n*unpackSize(p[0])+3 >> 2) + 1;
+}
+
+void
+convertMesh(Geometry *rwg, RslGeometry *g, int32 ii)
+{
+ RslPS2ResEntryHeader *resHeader = (RslPS2ResEntryHeader*)(g+1);
+ RslPS2InstanceData *inst = (RslPS2InstanceData*)(resHeader+1);
+ int32 numInst = resHeader->size >> 20;
+ uint8 *p = (uint8*)(inst+numInst);
+ inst += ii;
+ p += inst->dmaPacket;
+ Mesh *m = &rwg->meshHeader->mesh[inst->matID];
+
+ ps2::SkinVertex v;
+ uint32 mask = 0x1001; // tex coords, vertices
+ if(rwg->geoflags & Geometry::NORMALS)
+ mask |= 0x10;
+ if(rwg->geoflags & Geometry::PRELIT)
+ mask |= 0x100;
+ float32 *verts = &rwg->morphTargets[0].vertices[rwg->numVertices*3];
+ float32 *norms = &rwg->morphTargets[0].normals[rwg->numVertices*3];
+ uint8 *cols = &rwg->colors[rwg->numVertices*4];
+ float32 *texCoords = &rwg->texCoords[0][rwg->numVertices*2];
+ uint8 *indices = NULL;
+ float32 *weights = NULL;
+ Skin *skin = *PLUGINOFFSET(Skin*, rwg, skinGlobals.offset);
+ if(skin){
+ indices = &skin->indices[rwg->numVertices*4];
+ weights = &skin->weights[rwg->numVertices*4];
+ mask |= 0x10000;
+ }
+
+ int16 *vuVerts = NULL;
+ int8 *vuNorms = NULL;
+ uint8 *vuTex = NULL;
+ uint16 *vuCols = NULL;
+ uint32 *vuSkin = NULL;
+
+ uint32 *w = (uint32*)p;
+ uint32 *end = (uint32*)(p + ((w[0] & 0xFFFF) + 1)*0x10);
+ w += 4;
+ int flags = 0;
+ int32 nvert;
+ bool first = 1;
+ while(w < end){
+ /* Get data pointers */
+
+ // GIFtag probably
+ assert(w[0] == 0x6C018000); // UNPACK
+ nvert = w[4] & 0x7FFF;
+ if(!first) nvert -=2;
+ w += 5;
+
+ // positions
+ assert(w[0] == 0x20000000); // STMASK
+ w += 2;
+ assert(w[0] == 0x30000000); // STROW
+ w += 5;
+ assert((w[0] & 0xFF004000) == 0x79000000);
+ vuVerts = (int16*)(w+1);
+ if(!first) vuVerts += 2*3;
+ w = skipUnpack(w);
+
+ // tex coords
+ assert(w[0] == 0x20000000); // STMASK
+ w += 2;
+ assert(w[0] == 0x30000000); // STROW
+ w += 5;
+ assert((w[0] & 0xFF004000) == 0x76004000);
+ vuTex = (uint8*)(w+1);
+ if(!first) vuTex += 2*2;
+ w = skipUnpack(w);
+
+ if(rwg->geoflags & Geometry::NORMALS){
+ assert((w[0] & 0xFF004000) == 0x6A000000);
+ vuNorms = (int8*)(w+1);
+ if(!first) vuNorms += 2*3;
+ w = skipUnpack(w);
+ }
+
+ if(rwg->geoflags & Geometry::PRELIT){
+ assert((w[0] & 0xFF004000) == 0x6F000000);
+ vuCols = (uint16*)(w+1);
+ if(!first) vuCols += 2;
+ w = skipUnpack(w);
+ }
+
+ if(skin){
+ assert((w[0] & 0xFF004000) == 0x6C000000);
+ vuSkin = w+1;
+ if(!first) vuSkin += 2*4;
+ w = skipUnpack(w);
+ }
+
+ assert(w[0] == 0x14000006); // MSCAL
+ w++;
+ while(w[0] == 0) w++;
+
+ /* Insert Data */
+ for(int32 i = 0; i < nvert; i++){
+ v.p[0] = vuVerts[0]/32768.0f*resHeader->scale[0] + resHeader->pos[0];
+ v.p[1] = vuVerts[1]/32768.0f*resHeader->scale[1] + resHeader->pos[1];
+ v.p[2] = vuVerts[2]/32768.0f*resHeader->scale[2] + resHeader->pos[2];
+ v.t[0] = vuTex[0]/128.0f*inst->uvScale[0];
+ v.t[1] = vuTex[1]/128.0f*inst->uvScale[1];
+ if(mask & 0x10){
+ v.n[0] = vuNorms[0]/127.0f;
+ v.n[1] = vuNorms[1]/127.0f;
+ v.n[2] = vuNorms[2]/127.0f;
+ }
+ if(mask & 0x100){
+ v.c[0] = (vuCols[0] & 0x1f) * 255 / 0x1F;
+ v.c[1] = (vuCols[0]>>5 & 0x1f) * 255 / 0x1F;
+ v.c[2] = (vuCols[0]>>10 & 0x1f) * 255 / 0x1F;
+ v.c[3] = vuCols[0]&0x8000 ? 0xFF : 0;
+ }
+ if(mask & 0x10000){
+ for(int j = 0; j < 4; j++){
+ ((uint32*)v.w)[j] = vuSkin[j] & ~0x3FF;
+ v.i[j] = vuSkin[j] >> 2;
+ //if(v.i[j]) v.i[j]--;
+ if(v.w[j] == 0.0f) v.i[j] = 0;
+ }
+ }
+
+ int32 idx = ps2::findVertexSkin(rwg, NULL, mask, &v);
+ if(idx < 0)
+ idx = rwg->numVertices++;
+ /* Insert mesh joining indices when we get the index of the first vertex
+ * in the first VU chunk of a non-first RslMesh. */
+ if(i == 0 && first && ii != 0 && inst[-1].matID == inst->matID){
+ m->indices[m->numIndices] = m->indices[m->numIndices-1];
+ m->numIndices++;
+ m->indices[m->numIndices++] = idx;
+ if(inst[-1].numTriangles % 2)
+ m->indices[m->numIndices++] = idx;
+ }
+ m->indices[m->numIndices++] = idx;
+ ps2::insertVertexSkin(rwg, idx, mask, &v);
+
+ vuVerts += 3;
+ vuTex += 2;
+ vuNorms += 3;
+ vuCols++;
+ vuSkin += 4;
+ }
+ first = 0;
+ }
+}
+
+Atomic*
+convertAtomic(RslAtomic *atomic)
+{
+ Atomic *rwa = new Atomic;
+ RslGeometry *g = atomic->geometry;
+ Geometry *rwg = new Geometry(0, 0, 0);
+ rwa->geometry = rwg;
+
+ rwg->numMaterials = g->matList.numMaterials;
+ rwg->materialList = new Material*[rwg->numMaterials];
+ for(int32 i = 0; i < rwg->numMaterials; i++)
+ rwg->materialList[i] = convertMaterial(g->matList.materials[i]);
+
+ rwg->meshHeader = new MeshHeader;
+ rwg->meshHeader->flags = 1;
+ rwg->meshHeader->numMeshes = rwg->numMaterials;
+ rwg->meshHeader->mesh = new Mesh[rwg->meshHeader->numMeshes];
+ rwg->meshHeader->totalIndices = 0;
+ Mesh *meshes = rwg->meshHeader->mesh;
+ for(uint32 i = 0; i < rwg->meshHeader->numMeshes; i++)
+ meshes[i].numIndices = 0;
+
+ RslPS2ResEntryHeader *resHeader = (RslPS2ResEntryHeader*)(g+1);
+ RslPS2InstanceData *inst = (RslPS2InstanceData*)(resHeader+1);
+ int32 numInst = resHeader->size >> 20;
+
+ int32 lastId = -1;
+ for(int32 i = 0; i < numInst; i++){
+ Mesh *m = &meshes[inst[i].matID];
+ rwg->numVertices += inst[i].numTriangles+2;
+ m->numIndices += inst[i].numTriangles+2;
+ // Extra indices since we're merging tristrip
+ // meshes with the same material.
+ // Be careful with face winding.
+ if(lastId == inst[i].matID)
+ m->numIndices += inst[i-1].numTriangles % 2 ? 3 : 2;
+ lastId = inst[i].matID;
+ }
+ for(uint32 i = 0; i < rwg->meshHeader->numMeshes; i++){
+ rwg->meshHeader->mesh[i].material = rwg->materialList[i];
+ rwg->meshHeader->totalIndices += meshes[i].numIndices;
+ }
+ rwg->geoflags = Geometry::TRISTRIP |
+ Geometry::POSITIONS | /* 0x01 ? */
+ Geometry::TEXTURED | /* 0x04 ? */
+ Geometry::LIGHT;
+ if(rwg->hasColoredMaterial())
+ rwg->geoflags |= Geometry::MODULATE;
+ if(resHeader->flags & 0x2)
+ rwg->geoflags |= Geometry::NORMALS;
+ if(resHeader->flags & 0x8)
+ rwg->geoflags |= Geometry::PRELIT;
+ rwg->numTexCoordSets = 1;
+
+ rwg->allocateData();
+ rwg->meshHeader->allocateIndices();
+
+ Skin *skin = NULL;
+ if(resHeader->flags & 0x10)
+ assert(g->skin);
+ if(g->skin){
+ skin = new Skin;
+ *PLUGINOFFSET(Skin*, rwg, skinGlobals.offset) = skin;
+ skin->init(g->skin->numBones, g->skin->numBones, rwg->numVertices);
+ memcpy(skin->inverseMatrices, g->skin->invMatrices, skin->numBones*64);
+ }
+
+ for(uint32 i = 0; i < rwg->meshHeader->numMeshes; i++)
+ meshes[i].numIndices = 0;
+ rwg->meshHeader->totalIndices = rwg->numVertices = 0;
+ for(int32 i = 0; i < numInst; i++)
+ convertMesh(rwg, g, i);
+ for(uint32 i = 0; i < rwg->meshHeader->numMeshes; i++)
+ rwg->meshHeader->totalIndices += meshes[i].numIndices;
+ if(skin){
+ skin->findNumWeights(rwg->numVertices);
+ skin->findUsedBones(rwg->numVertices);
+ }
+ rwg->calculateBoundingSphere();
+ rwg->generateTriangles();
+ return rwa;
+}
+
+RslAtomic*
+collectAtomics(RslAtomic *atomic, void *data)
+{
+ RslAtomic ***alist = (RslAtomic***)data;
+ *(*alist)++ = atomic;
+ return atomic;
+}
+
+Clump*
+convertClump(RslClump *c)
+{
+ Clump *rwc;
+ Frame *rwf;
+ Atomic *rwa;
+ rslFrameList frameList;
+
+ rwc = new Clump;
+ rslFrameListInitialize(&frameList, (RslFrame*)c->object.parent);
+ Frame **rwframes = new Frame*[frameList.numFrames];
+ for(int32 i = 0; i < frameList.numFrames; i++){
+ rwf = convertFrame(frameList.frames[i]);
+ rwframes[i] = rwf;
+ void *par = frameList.frames[i]->object.parent;
+ int32 parent = findPointer(par, (void**)frameList.frames, frameList.numFrames);
+ if(parent >= 0)
+ rwframes[parent]->addChild(rwf);
+ }
+ rwc->parent = rwframes[0];
+
+ rwc->numAtomics = RslClumpGetNumAtomics(c);
+ rwc->atomicList = new Atomic*[rwc->numAtomics];
+ RslAtomic **alist = new RslAtomic*[rwc->numAtomics];
+ RslAtomic **ap = &alist[0];
+ RslClumpForAllAtomics(c, collectAtomics, &ap);
+ for(int32 i = 0; i < rwc->numAtomics; i++){
+ rwa = convertAtomic(alist[i]);
+ rwc->atomicList[i] = rwa;
+ int32 fi = findPointer(alist[i]->object.object.parent, (void**)frameList.frames, frameList.numFrames);
+ rwa->frame = rwframes[fi];
+ rwa->clump = rwc;
+ }
+
+ delete[] alist;
+ delete[] rwframes;
+ delete[] frameList.frames;
+ return rwc;
+}
+
+RslAtomic*
+makeTextures(RslAtomic *atomic, void*)
+{
+ RslGeometry *g = atomic->geometry;
+ RslMaterial *m;
+ for(int32 i = 0; i < g->matList.numMaterials; i++){
+ m = g->matList.materials[i];
+ if(m->texname){
+ RslTexture *tex = RslTextureCreate(NULL);
+ strncpy(tex->name, m->texname, 32);
+ strncpy(tex->mask, m->texname, 32);
+ m->texture = tex;
+ }
+ if(m->matfx && m->matfx->effectType == MatFX::ENVMAP &&
+ m->matfx->env.texname){
+ RslTexture *tex = RslTextureCreate(NULL);
+ strncpy(tex->name, m->matfx->env.texname, 32);
+ strncpy(tex->mask, m->matfx->env.texname, 32);
+ m->matfx->env.texture = tex;
+ }
+ }
+ return atomic;
+}
+
+
+
+
uint8*
getPalettePS2(RslRaster *raster)
{
@@ -356,10 +762,10 @@ convertTXD(RslTexDictionary *txd)
void
usage(void)
{
- fprintf(stderr, "%s [-v version] [-x] [-s] input [output.txd]\n", argv0);
+ fprintf(stderr, "%s [-v version] [-x] [-s] input [output.{txd|dff}]\n", argv0);
fprintf(stderr, "\t-v RW version, e.g. 33004 for 3.3.0.4\n");
- fprintf(stderr, "\t-x extract to tga\n");
- fprintf(stderr, "\t-s don't unswizzle\n");
+ fprintf(stderr, "\t-x extract textures to tga\n");
+ fprintf(stderr, "\t-s don't unswizzle textures\n");
exit(1);
}
@@ -368,6 +774,7 @@ main(int argc, char *argv[])
{
gta::attachPlugins();
rw::version = 0x34003;
+ rw::platform = PLATFORM_D3D8;
assert(sizeof(void*) == 4);
int extract = 0;
@@ -389,10 +796,11 @@ main(int argc, char *argv[])
if(argc < 1)
usage();
- World *world;
- Sector *sector;
- RslClump *clump;
- RslTexDictionary *txd;
+ World *world = NULL;
+ Sector *sector = NULL;
+ RslClump *clump = NULL;
+ RslAtomic *atomic = NULL;
+ RslTexDictionary *txd = NULL;
StreamFile stream;
@@ -408,11 +816,12 @@ main(int argc, char *argv[])
assert(txd);
goto writeTxd;
}
- if(ident == 0x10){
+ if(ident == ID_CLUMP){
findChunk(&stream, ID_CLUMP, NULL, NULL);
clump = RslClumpStreamRead(&stream);
stream.close();
- return 0;
+ assert(clump);
+ goto writeDff;
}
RslStream *rslstr = new RslStream;
@@ -486,14 +895,30 @@ main(int argc, char *argv[])
}else if(rslstr->ident == MDL_IDENT){
uint8 *p = *rslstr->hashTab;
p -= 0x24;
- RslAtomic *a = (RslAtomic*)p;
- clump = a->clump;
- if(clump)
+ atomic = (RslAtomic*)p;
+ clump = atomic->clump;
+ Clump *rwc;
+ if(clump){
+ RslClumpForAllAtomics(clump, makeTextures, NULL);
//RslClumpForAllAtomics(clump, dumpAtomicCB, NULL);
- RslFrameForAllChildren(RslClumpGetFrame(clump), dumpFrameCB, NULL);
- else
+ //RslFrameForAllChildren(RslClumpGetFrame(clump), dumpFrameCB, NULL);
+ }else{
+ makeTextures(atomic, NULL);
+ clump = RslClumpCreate();
+ RslAtomicSetFrame(atomic, RslFrameCreate());
+ RslClumpSetFrame(clump, RslAtomicGetFrame(atomic));
+ RslClumpAddAtomic(clump, atomic);
//dumpAtomicCB(a, NULL);
- RslFrameForAllChildren(RslAtomicGetFrame(a), dumpFrameCB, NULL);
+ //RslFrameForAllChildren(RslAtomicGetFrame(atomic), dumpFrameCB, NULL);
+ }
+ writeDff:
+ rwc = convertClump(clump);
+ if(argc > 1)
+ assert(stream.open(argv[1], "wb"));
+ else
+ assert(stream.open("out.dff", "wb"));
+ rwc->streamWrite(&stream);
+ stream.close();
}else if(rslstr->ident == TEX_IDENT){
txd = (RslTexDictionary*)rslstr->data;
writeTxd: