moved iOS dff converter to rsltest
This commit is contained in:
@ -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;
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
Reference in New Issue
Block a user