diff --git a/librw.sln b/librw.sln index f1cc1e2..146ebde 100644 --- a/librw.sln +++ b/librw.sln @@ -30,6 +30,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txdwrite", "tools\txdwrite\ {30552BB0-3B19-49A4-ABF4-87CF68AF9E38} = {30552BB0-3B19-49A4-ABF4-87CF68AF9E38} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rsltest", "tools\rsltest\rsltest.vcxproj", "{27ECE916-900F-49B2-8E9F-95E6B347E161}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug - null|Win32 = Debug - null|Win32 @@ -100,6 +102,15 @@ Global {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|Win32 + {27ECE916-900F-49B2-8E9F-95E6B347E161}.Debug - null|Win32.Build.0 = Debug|Win32 + {27ECE916-900F-49B2-8E9F-95E6B347E161}.Debug - null|x64.ActiveCfg = Debug|Win32 + {27ECE916-900F-49B2-8E9F-95E6B347E161}.Debug|Win32.ActiveCfg = Debug|Win32 + {27ECE916-900F-49B2-8E9F-95E6B347E161}.Debug|Win32.Build.0 = Debug|Win32 + {27ECE916-900F-49B2-8E9F-95E6B347E161}.Debug|x64.ActiveCfg = Debug|Win32 + {27ECE916-900F-49B2-8E9F-95E6B347E161}.Release|Win32.ActiveCfg = Release|Win32 + {27ECE916-900F-49B2-8E9F-95E6B347E161}.Release|Win32.Build.0 = Release|Win32 + {27ECE916-900F-49B2-8E9F-95E6B347E161}.Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/mdl.cpp b/src/mdl.cpp index 9bfc4a4..672040e 100644 --- a/src/mdl.cpp +++ b/src/mdl.cpp @@ -315,11 +315,12 @@ convertRslGeometry(Geometry *g) // Be careful with face winding. if(lastId == rm->matID) m->numIndices += (rm-1)->numTriangles % 2 ? 3 : 2; - m->material = g->materialList[rm->matID]; lastId = rm->matID; } - for(uint32 i = 0; i < g->meshHeader->numMeshes; i++) + 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 ? */ diff --git a/src/rwplugin.h b/src/rwplugin.h index 5b0902f..9453384 100644 --- a/src/rwplugin.h +++ b/src/rwplugin.h @@ -97,7 +97,7 @@ PluginBase::streamReadPlugins(Stream *stream) (void*)this, p->offset, p->size); goto cont; } -// printf("skipping plugin %X\n", header.type); + //printf("skipping plugin %X\n", header.type); stream->seek(header.length); cont: length -= header.length; diff --git a/tools/rsltest/rsl.h b/tools/rsltest/rsl.h new file mode 100644 index 0000000..c8ebce9 --- /dev/null +++ b/tools/rsltest/rsl.h @@ -0,0 +1,252 @@ +struct RslStream { + uint32 ident; + bool32 isMulti; + uint32 fileSize; + uint32 dataSize; + uint8 ***reloc; + uint32 relocSize; + uint8 **hashTab; // ?? + uint16 hashTabSize; + uint16 numAtomics; + + uint8 *data; + void relocate(void); +}; + +struct RslObject; +struct RslObjectHasFrame; +struct RslClump; +struct RslAtomic; +struct RslFrame; +struct RslNativeGeometry; +struct RslNativeMesh; +struct RslGeometry; +struct RslSkin; +struct RslMaterial; +struct RslHAnimHierarchy; +struct RslHAnimNode; +struct RslPS2ResEntryHeader; +struct RslPS2InstanceData; + +typedef RslClump *(*RslClumpCallBack)(RslClump *clump, void *data); +typedef RslAtomic *(*RslAtomicCallBack)(RslAtomic *atomic, void *data); +typedef RslMaterial *(*RslMaterialCallBack)(RslMaterial *material, void *data); + +struct RslLLLink { + RslLLLink *next; + RslLLLink *prev; +}; + +struct RslLinkList { + RslLLLink link; +}; + +#define rslLLLinkGetData(linkvar,type,entry) \ + ((type *)(((uint8 *)(linkvar))-offsetof(type,entry))) + +#define rslLLLinkGetNext(linkvar) \ + ((linkvar)->next) + +#define rslLLLinkGetPrevious(linkvar) \ + ((linkvar)->prev) + +#define rslLLLinkInitialize(linkvar) \ + ( (linkvar)->prev = (RslLLLink *)NULL, \ + (linkvar)->next = (RslLLLink *)NULL ) + +#define rslLLLinkAttached(linkvar) \ + ((linkvar)->next) + +struct RslObject { + uint8 type; + uint8 subType; + uint8 flags; + uint8 privateFlags; + void *parent; +}; + +struct RslObjectHasFrame { + RslObject object; + RslLLLink lFrame; + void (*sync)(); +}; + +// from Serge +//void TEX::getInfo(TEXInfo a) +//{ +// bpp = (a.flags & 0xF000) >> 12; +// swizzle = (a.flags & 0xF000000) >> 24; +// Width = (int)pow(2.0, (int)(a.flags & 0xF)); +// Height = (int)pow(16.0, (int)((a.flags & 0xF00) >> 8))*(int)pow(2.0, (int)(((a.flags & 0xF0) >> 4) / 4)); +// mipmaps = (a.flags & 0xFF0000) >> 20; +//} + +struct RslRaster { + uint8 *data; + // XXXXSSSSMMMMMMMMBBBBHHHHHHHHWWWW + uint32 flags; +}; + +struct RslTexDictionary { + RslObject object; + RslLinkList texturesInDict; + RslLLLink lInInstance; +}; + +struct RslTexture { + RslRaster *raster; + RslTexDictionary *dict; + RslLLLink lInDictionary; + char name[32]; + char mask[32]; +}; + +struct RslClump { + RslObject object; + RslLinkList atomicList; +}; + +struct RslAtomic { + RslObjectHasFrame object; + RslGeometry *geometry; + RslClump *clump; + RslLLLink inClumpLink; + + // what's this? + uint32 unk1; + uint16 unk2; + uint16 unk3; + RslHAnimHierarchy *hier; + int32 pad; // 0xAAAAAAAA +}; + +struct RslFrame { + RslObject object; + RslLLLink inDirtyListLink; // ? + + float32 modelling[16]; + float32 ltm[16]; + RslFrame *child; + RslFrame *next; + RslFrame *root; + + // RwHAnimFrameExtension + int32 nodeId; + RslHAnimHierarchy *hier; + + // R* Node name + char *name; + uint32 unk3; // ?pad? +}; + + +struct RslMaterialList { + RslMaterial **materials; + int32 numMaterials; + int32 space; +}; + +struct RslGeometry { + RslObject object; + uint16 locked; // ? + int16 refCount; // ? + + RslMaterialList matList; + + RslSkin *skin; + uint32 pad; // 0xAAAAAAAA +}; + +struct RslMatFXEnv { + RslFrame *frame; + char *texname; + float32 intensity; +}; + +struct RslMatFX { + union { + RslMatFXEnv env; + }; + int32 effectType; +}; + +struct RslMaterial { + char *texname; + uint32 color; + uint16 refCount; + uint16 pad; + RslMatFX *matfx; +}; + +struct RslHAnimNodeInfo { + int8 id; + int8 index; + int8 flags; + RslFrame *frame; +}; + +struct RslHAnimHierarchy { + int32 flags; + int32 numNodes; + void *pCurrentAnim; + float32 currentTime; + void *pNextFrame; + void (*pAnimCallBack)(); + void *pAnimCallBackData; + float32 animCallBackTime; + void (*pAnimLoopCallBack)(); + void *pAnimLoopCallBackData; + float32 *pMatrixArray; + void *pMatrixArrayUnaligned; + RslHAnimNodeInfo *pNodeInfo; + RslFrame *parentFrame; + int32 maxKeyFrameSize; + int32 currentKeyFrameSize; + void (*keyFrameToMatrixCB)(); + void (*keyFrameBlendCB)(); + void (*keyFrameInterpolateCB)(); + void (*keyFrameAddCB)(); + RslHAnimHierarchy *parentHierarchy; + int32 offsetInParent; + int32 rootParentOffset; +}; + +struct RslSkin { + uint32 numBones; + uint32 numUsedBones; // == numBones + uint8 *usedBones; // NULL + float32 *invMatrices; + int32 numWeights; // 0 + uint8 *indices; // NULL + float32 *weights; // NULL + uint32 unk1; // 0 + uint32 unk2; // 0 + uint32 unk3; // 0 + uint32 unk4; // 0 + uint32 unk5; // 0 + void *data; // NULL +}; + +struct RslPS2ResEntryHeader { + float32 bound[4]; + uint32 size; // and numMeshes + int32 flags; + uint32 unk1; + uint32 unk2; + uint32 unk3; + uint32 unk4; + float32 scale[3]; + float32 pos[3]; +}; + +struct RslPS2InstanceData { + float32 bound[4]; // ? + float32 uvScale[2]; + int32 unk1; + uint8 *dmaPacket; + uint16 numTriangles; + int16 matID; + void *unk2; + void *unk3; + void *unk4; +}; diff --git a/tools/rsltest/rsltest.cpp b/tools/rsltest/rsltest.cpp new file mode 100644 index 0000000..4828856 --- /dev/null +++ b/tools/rsltest/rsltest.cpp @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include + +#include +#include + +using namespace std; +using namespace rw; +#include "rsl.h" + +void +RslStream::relocate(void) +{ + uint32 off = (uint32)this->data; + off -= 0x20; + *(uint32*)&this->reloc += off; + *(uint32*)&this->hashTab += off; + + uint8 **rel = (uint8**)this->reloc; + for(uint32 i = 0; i < this->relocSize; i++){ + rel[i] += off; + *this->reloc[i] += off; + } +} + +RslClump* +RslClumpForAllAtomics(RslClump *clump, RslAtomicCallBack callback, void *pData) +{ + RslAtomic *a; + RslLLLink *link; + for(link = rslLLLinkGetNext(&clump->atomicList.link); + link != &clump->atomicList.link; + link = link->next){ + a = rslLLLinkGetData(link, RslAtomic, inClumpLink); + if(callback(a, pData) == NULL) + break; + } + return clump; +} + +RslGeometry* +RslGeometryForAllMaterials(RslGeometry *geometry, RslMaterialCallBack fpCallBack, void *pData) +{ + for(int32 i = 0; i < geometry->matList.numMaterials; i++) + if(fpCallBack(geometry->matList.materials[i], pData) == NULL) + break; + return geometry; +} + + + +RslMaterial *dumpMaterialCB(RslMaterial *material, void*) +{ + printf(" mat: %s %x %x\n", material->texname, material->pad, material->refCount); + if(material->matfx){ + RslMatFX *fx = material->matfx; + printf(" matfx: ", fx->effectType); + if(fx->effectType == 2) + printf("env[%s %f] ", fx->env.texname, fx->env.intensity); + printf("\n"); + } + return material; +} + +RslAtomic *dumpAtomicCB(RslAtomic *atomic, void*) +{ + printf(" atm: %x %x %x %p\n", atomic->unk1, atomic->unk2, atomic->unk3, atomic->hier); + RslGeometry *g = atomic->geometry; + RslGeometryForAllMaterials(g, dumpMaterialCB, NULL); + return atomic; +} + +int +main(int argc, char *argv[]) +{ + gta::attachPlugins(); + rw::version = 0; + + assert(sizeof(void*) == 4); + + if(argc < 2){ + printf("usage: %s [-u] in.dff\n", argv[0]); + return 0; + } + + StreamFile stream; + assert(stream.open(argv[1], "rb")); + RslStream *rslstr = new RslStream; + stream.read(rslstr, 0x20); + rslstr->data = new uint8[rslstr->fileSize-0x20]; + stream.read(rslstr->data, rslstr->fileSize-0x20); + stream.close(); + rslstr->relocate(); + + RslClump *clump; + if(rslstr->numAtomics){ + uint8 *p = *rslstr->hashTab; + p -= 0x24; + RslAtomic *a = (RslAtomic*)p; + clump = a->clump; + if(clump) + RslClumpForAllAtomics(clump, dumpAtomicCB, NULL); + else + dumpAtomicCB(a, NULL); + } + + return 0; +} diff --git a/tools/rsltest/rsltest.vcxproj b/tools/rsltest/rsltest.vcxproj new file mode 100644 index 0000000..491654c --- /dev/null +++ b/tools/rsltest/rsltest.vcxproj @@ -0,0 +1,87 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {27ECE916-900F-49B2-8E9F-95E6B347E161} + rsltest + + + + Application + true + v120 + MultiByte + + + Application + false + v120 + true + MultiByte + + + + + + + + + + + + + $(SolutionDir);$(IncludePath) + $(SolutionDir)$(Configuration);$(LibraryPath) + + + $(SolutionDir)$(Configuration);$(LibraryPath) + $(SolutionDir);$(IncludePath) + + + + Level3 + Disabled + true + + + true + librw.lib;%(AdditionalDependencies) + + + copy /y "$(TargetPath)" "C:\Users\aap\bin\" + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + librw.lib;%(AdditionalDependencies) + + + + + + + + + + + + \ No newline at end of file