From d04e97fb47024ea50266f5af5e22a8a1e13c8398 Mon Sep 17 00:00:00 2001 From: aap Date: Sat, 15 Aug 2015 23:22:51 +0200 Subject: [PATCH] implemented xbox native geometry and skin --- Makefile | 4 +- Makefile.mingw | 4 +- Makefile.ps2 | 4 +- dffwrite.cpp | 3 +- dumprwtree.cpp | 2 + insttest.cpp | 1 + rw.h | 1 + src/clump.cpp | 6 +- src/plugins.cpp | 31 ++++-- src/ps2.cpp | 7 +- src/rwbase.h | 1 + src/rwobjects.h | 1 + src/rwxbox.h | 47 ++++++++ src/xbox.cpp | 271 +++++++++++++++++++++++++++++++++++++++++++++ tests/gl/main.cpp | 1 + tests/ps2/main.cpp | 1 + 16 files changed, 365 insertions(+), 20 deletions(-) create mode 100644 src/rwxbox.h create mode 100644 src/xbox.cpp diff --git a/Makefile b/Makefile index c163b5d..557535b 100644 --- a/Makefile +++ b/Makefile @@ -7,11 +7,11 @@ BUILDDIR=build-$(BUILD) SRCDIR=src SRC := $(patsubst %.cpp,$(SRCDIR)/%.cpp, rwbase.cpp clump.cpp\ geometry.cpp plugins.cpp pipeline.cpp\ - ps2.cpp ogl.cpp\ + ps2.cpp ogl.cpp xbox.cpp\ image.cpp gtaplg.cpp) OBJ := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$(SRC)) DEP := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.d,$(SRC)) -CFLAGS=-Wall -Wextra -g $(BUILDDEF) #-Wno-parentheses #-Wconversion +CFLAGS=-Wall -Wextra -g $(BUILDDEF) -Wno-parentheses #-Wconversion LIB=librw-$(BUILD).a $(LIB): $(OBJ) diff --git a/Makefile.mingw b/Makefile.mingw index e6bd3ff..38e9904 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -7,11 +7,11 @@ BUILDDIR=build-$(BUILD) SRCDIR=src SRC := $(patsubst %.cpp,$(SRCDIR)/%.cpp, rwbase.cpp clump.cpp\ geometry.cpp plugins.cpp pipeline.cpp\ - ps2.cpp ogl.cpp\ + ps2.cpp ogl.cpp xbox.cpp\ image.cpp gtaplg.cpp) OBJ := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$(SRC)) DEP := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.d,$(SRC)) -CFLAGS=-Wall -Wextra -g -DGLEW_STATIC $(BUILDDEF) #-Wno-parentheses #-Wconversion +CFLAGS=-Wall -Wextra -g -DGLEW_STATIC $(BUILDDEF) -Wno-parentheses #-Wconversion LIB=librw-$(BUILD).a $(LIB): $(OBJ) diff --git a/Makefile.ps2 b/Makefile.ps2 index 4684c71..c67f116 100644 --- a/Makefile.ps2 +++ b/Makefile.ps2 @@ -8,11 +8,11 @@ BUILDDIR=build-$(BUILD) SRCDIR=src SRC := $(patsubst %.cpp,$(SRCDIR)/%.cpp, rwbase.cpp clump.cpp\ geometry.cpp plugins.cpp pipeline.cpp\ - ps2.cpp ogl.cpp\ + ps2.cpp ogl.cpp xbox.cpp\ image.cpp gtaplg.cpp) OBJ := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$(SRC)) DEP := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.d,$(SRC)) -CFLAGS=-Wall -g $(BUILDDEF) #-Wno-parentheses #-Wconversion +CFLAGS=-Wall -g $(BUILDDEF) -Wno-parentheses #-Wconversion INCPATH=-I$(PS2SDK)/ee/include -I$(PS2SDK)/common/include LIB=librw-$(BUILD).a diff --git a/dffwrite.cpp b/dffwrite.cpp index c11ed0e..330eff8 100644 --- a/dffwrite.cpp +++ b/dffwrite.cpp @@ -23,11 +23,12 @@ main(int argc, char *argv[]) rw::registerAtomicRightsPlugin(); rw::registerHAnimPlugin(); gta::registerNodeNamePlugin(); - gta::registerBreakableModelPlugin(); +// gta::registerBreakableModelPlugin(); gta::registerExtraVertColorPlugin(); rw::ps2::registerADCPlugin(); rw::ps2::registerPDSPlugin(); rw::registerSkinPlugin(); + rw::xbox::registerVertexFormatPlugin(); rw::registerNativeDataPlugin(); // rw::ps2::registerNativeDataPlugin(); rw::registerMeshPlugin(); diff --git a/dumprwtree.cpp b/dumprwtree.cpp index 7a02261..8e73137 100644 --- a/dumprwtree.cpp +++ b/dumprwtree.cpp @@ -77,6 +77,8 @@ getChunkName(uint32 id) return "Bin Mesh PLG"; case 0x510: return "Native Data PLG"; + case 0x511: + return "Vertex Format PLG"; case 0xF21E: return "ZModeler Lock"; } diff --git a/insttest.cpp b/insttest.cpp index e9c1592..14630a7 100644 --- a/insttest.cpp +++ b/insttest.cpp @@ -25,6 +25,7 @@ main(int argc, char *argv[]) rw::ps2::registerADCPlugin(); rw::ps2::registerPDSPlugin(); rw::registerSkinPlugin(); + rw::xbox::registerVertexFormatPlugin(); rw::registerNativeDataPlugin(); rw::registerMeshPlugin(); rw::Atomic::init(); diff --git a/rw.h b/rw.h index 8d5382c..d6e861e 100644 --- a/rw.h +++ b/rw.h @@ -4,3 +4,4 @@ #include "src/rwobjects.h" #include "src/rwps2.h" #include "src/rwogl.h" +#include "src/rwxbox.h" diff --git a/src/clump.cpp b/src/clump.cpp index b3f3d72..84ac9bb 100644 --- a/src/clump.cpp +++ b/src/clump.cpp @@ -205,7 +205,7 @@ Clump::streamRead(Stream *stream) clump->numAtomics = buf[0]; clump->numLights = 0; clump->numCameras = 0; - if(version >= 0x33000){ + if(version > 0x33000){ clump->numLights = buf[1]; clump->numCameras = buf[2]; } @@ -264,7 +264,7 @@ Clump::streamWrite(Stream *stream) int size = this->streamGetSize(); writeChunkHeader(stream, ID_CLUMP, size); int buf[3] = { this->numAtomics, this->numLights, this->numCameras }; - size = version >= 0x33000 ? 12 : 4; + size = version > 0x33000 ? 12 : 4; writeChunkHeader(stream, ID_STRUCT, size); stream->write(buf, size); @@ -316,7 +316,7 @@ Clump::streamGetSize(void) uint32 size = 0; size += 12; // Struct size += 4; // numAtomics - if(version >= 0x33000) + if(version > 0x33000) size += 8; // numLights, numCameras // frame list diff --git a/src/plugins.cpp b/src/plugins.cpp index 6546d4b..5c2652b 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -10,6 +10,7 @@ #include "rwpipeline.h" #include "rwobjects.h" #include "rwps2.h" +#include "rwxbox.h" #include "rwogl.h" using namespace std; @@ -283,7 +284,11 @@ readNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s) if(platform == PLATFORM_PS2) ps2::readNativeData(stream, len, object, o, s); else if(platform == PLATFORM_XBOX) + xbox::readNativeData(stream, len, object, o, s); + else{ + fprintf(stderr, "unknown platform %d\n", platform); stream->seek(len); + } }else{ stream->seek(-12); gl::readNativeData(stream, len, object, o, s); @@ -298,6 +303,8 @@ writeNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s) return; if(geometry->instData->platform == PLATFORM_PS2) ps2::writeNativeData(stream, len, object, o, s); + else if(geometry->instData->platform == PLATFORM_XBOX) + xbox::writeNativeData(stream, len, object, o, s); else if(geometry->instData->platform == PLATFORM_OGL) gl::writeNativeData(stream, len, object, o, s); } @@ -311,7 +318,7 @@ getSizeNativeData(void *object, int32 offset, int32 size) if(geometry->instData->platform == PLATFORM_PS2) return ps2::getSizeNativeData(object, offset, size); else if(geometry->instData->platform == PLATFORM_XBOX) - return -1; + return xbox::getSizeNativeData(object, offset, size); else if(geometry->instData->platform == PLATFORM_OGL) return gl::getSizeNativeData(object, offset, size); return -1; @@ -366,6 +373,7 @@ copySkin(void *dst, void *src, int32 offset, int32) dstskin->numUsedBones = srcskin->numUsedBones; dstskin->maxIndex = srcskin->maxIndex; + assert(0 && "can't copy skin yet"); dstskin->allocateData(geometry->numVertices); memcpy(dstskin->usedBones, srcskin->usedBones, srcskin->numUsedBones); memcpy(dstskin->inverseMatrices, srcskin->inverseMatrices, @@ -382,8 +390,11 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32) Geometry *geometry = (Geometry*)object; if(geometry->instData){ + // TODO: function pointers if(geometry->instData->platform == PLATFORM_PS2) ps2::readNativeSkin(stream, len, object, offset); + else if(geometry->instData->platform == PLATFORM_XBOX) + xbox::readNativeSkin(stream, len, object, offset); else if(geometry->instData->platform == PLATFORM_OGL) gl::readNativeSkin(stream, len, object, offset); else @@ -415,8 +426,8 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32) stream->seek(4); // skip 0xdeaddead stream->read(&skin->inverseMatrices[i*16], 64); } - // TODO: find out what this is (related to skin splitting) - // always 0 in GTA files + + // no split skins in GTA if(!oldFormat) stream->seek(12); } @@ -430,6 +441,8 @@ writeSkin(Stream *stream, int32 len, void *object, int32 offset, int32) if(geometry->instData){ if(geometry->instData->platform == PLATFORM_PS2) ps2::writeNativeSkin(stream, len, object, offset); + else if(geometry->instData->platform == PLATFORM_XBOX) + xbox::writeNativeSkin(stream, len, object, offset); else if(geometry->instData->platform == PLATFORM_OGL) gl::writeNativeSkin(stream, len, object, offset); else @@ -457,6 +470,8 @@ writeSkin(Stream *stream, int32 len, void *object, int32 offset, int32) stream->writeU32(0xdeaddead); stream->write(&skin->inverseMatrices[i*16], 64); } + + // no split skins in GTA if(!oldFormat){ uint32 buffer[3] = { 0, 0, 0}; stream->write(buffer, 12); @@ -471,6 +486,8 @@ getSizeSkin(void *object, int32 offset, int32) if(geometry->instData){ if(geometry->instData->platform == PLATFORM_PS2) return ps2::getSizeNativeSkin(object, offset); + if(geometry->instData->platform == PLATFORM_XBOX) + return xbox::getSizeNativeSkin(object, offset); if(geometry->instData->platform == PLATFORM_OGL) return gl::getSizeNativeSkin(object, offset); assert(0 && "unsupported native skin platform"); @@ -553,6 +570,7 @@ Skin::allocateData(int32 numVerts) if(numVerts) this->weights = (float*)data; + this->platformData = NULL; } void @@ -611,10 +629,9 @@ writeAtomicMatFX(Stream *stream, int32, void *object, int32 offset, int32) static int32 getSizeAtomicMatFX(void *object, int32 offset, int32) { - // TODO: version dependent -/* int32 flag; - flag = *PLUGINOFFSET(int32, object, offset); - return flag ? 4 : -1; */ + int32 flag = *PLUGINOFFSET(int32, object, offset); + // TODO: not sure which version + return flag && rw::version < 0x35000 ? 4 : -1; return 4; } diff --git a/src/ps2.cpp b/src/ps2.cpp index f1488b8..5c6e4bd 100644 --- a/src/ps2.cpp +++ b/src/ps2.cpp @@ -23,6 +23,7 @@ void* destroyNativeData(void *object, int32, int32) { Geometry *geometry = (Geometry*)object; + assert(geometry->instData != NULL); assert(geometry->instData->platform == PLATFORM_PS2); InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; for(uint32 i = 0; i < header->numMeshes; i++) @@ -66,9 +67,9 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32) { Geometry *geometry = (Geometry*)object; writeChunkHeader(stream, ID_STRUCT, len-12); + assert(geometry->instData != NULL); assert(geometry->instData->platform == PLATFORM_PS2); stream->writeU32(PLATFORM_PS2); - assert(geometry->instData != NULL); InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; for(uint32 i = 0; i < header->numMeshes; i++){ InstanceData *instance = &header->instanceMeshes[i]; @@ -87,8 +88,8 @@ getSizeNativeData(void *object, int32, int32) { Geometry *geometry = (Geometry*)object; int32 size = 16; - assert(geometry->instData->platform == PLATFORM_PS2); assert(geometry->instData != NULL); + assert(geometry->instData->platform == PLATFORM_PS2); InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; for(uint32 i = 0; i < header->numMeshes; i++){ InstanceData *instance = &header->instanceMeshes[i]; @@ -593,8 +594,8 @@ void ObjPipeline::uninstance(Atomic *atomic) { Geometry *geometry = atomic->geometry; - assert(geometry->instData->platform == PLATFORM_PS2); assert(geometry->instData != NULL); + assert(geometry->instData->platform == PLATFORM_PS2); InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; for(uint32 i = 0; i < header->numMeshes; i++){ Mesh *mesh = &geometry->meshHeader->mesh[i]; diff --git a/src/rwbase.h b/src/rwbase.h index 5d13354..64695a8 100644 --- a/src/rwbase.h +++ b/src/rwbase.h @@ -140,6 +140,7 @@ enum PluginID ID_ADC = 0x134, ID_MESH = 0x50E, ID_NATIVEDATA = 0x510, + ID_VERTEXFMT = 0x511, }; extern int version; diff --git a/src/rwobjects.h b/src/rwobjects.h index b1555a7..eebf616 100644 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -320,6 +320,7 @@ struct Skin uint8 *indices; float *weights; uint8 *data; // only used by delete + void *platformData; // a place to store platform specific stuff void allocateData(int32 numVerts); void allocateVertexData(int32 numVerts); diff --git a/src/rwxbox.h b/src/rwxbox.h new file mode 100644 index 0000000..7162ab9 --- /dev/null +++ b/src/rwxbox.h @@ -0,0 +1,47 @@ +namespace rw { +namespace xbox { + +struct InstanceData +{ + uint32 minVert; + int32 numVertices; + int32 numIndices; + void *indexBuffer; + Material *material; + uint32 vertexShader; +}; + +struct InstanceDataHeader : rw::InstanceDataHeader +{ + int32 size; + uint16 serialNumber; + uint16 numMeshes; + uint32 primType; + int32 numVertices; + int32 stride; + void *vertexBuffer; + bool32 vertexAlpha; + InstanceData *begin; + InstanceData *end; + + uint8 *data; +}; + +void *destroyNativeData(void *object, int32, int32); +void readNativeData(Stream *stream, int32 len, void *object, int32, int32); +void writeNativeData(Stream *stream, int32 len, void *object, int32, int32); +int32 getSizeNativeData(void *object, int32, int32); +void registerNativeDataPlugin(void); + +// Skin plugin + +void readNativeSkin(Stream *stream, int32, void *object, int32 offset); +void writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset); +int32 getSizeNativeSkin(void *object, int32 offset); + +// Vertex Format plugin + +void registerVertexFormatPlugin(void); + +} +} diff --git a/src/xbox.cpp b/src/xbox.cpp new file mode 100644 index 0000000..aeaae39 --- /dev/null +++ b/src/xbox.cpp @@ -0,0 +1,271 @@ +#include +#include +#include +#include + +#include + +#include "rwbase.h" +#include "rwplugin.h" +#include "rwpipeline.h" +#include "rwobjects.h" +#include "rwxbox.h" + +using namespace std; + +namespace rw { +namespace xbox { + +void* +destroyNativeData(void *object, int32, int32) +{ + Geometry *geometry = (Geometry*)object; + assert(geometry->instData != NULL); + assert(geometry->instData->platform == PLATFORM_XBOX); + InstanceDataHeader *header = + (InstanceDataHeader*)geometry->instData; + delete header; + return object; +} + +void +readNativeData(Stream *stream, int32, void *object, int32, int32) +{ + Geometry *geometry = (Geometry*)object; + uint32 vers; + assert(findChunk(stream, ID_STRUCT, NULL, &vers)); + assert(stream->readU32() == PLATFORM_XBOX); + assert(vers >= 0x35000 && "can't handle native Xbox data < 0x35000"); + InstanceDataHeader *header = new InstanceDataHeader; + geometry->instData = header; + header->platform = PLATFORM_XBOX; + + int32 size = stream->readI32(); + // The 0x18 byte are the resentryheader. + // We don't have it but it's used for alignment. + header->data = new uint8[size + 0x18]; + uint8 *p = header->data+0x18+4; + stream->read(p, size-4); + + header->size = size; + header->serialNumber = *(uint16*)p; p += 2; + header->numMeshes = *(uint16*)p; p += 2; + header->primType = *(uint32*)p; p += 4; + header->numVertices = *(uint32*)p; p += 4; + header->stride = *(uint32*)p; p += 4; + // RxXboxVertexFormat in 3.3 here + p += 4; // skip vertexBuffer pointer + header->vertexAlpha = *(bool32*)p; p += 4; + p += 8; // skip begin, end pointers + + InstanceData *inst = new InstanceData[header->numMeshes]; + header->begin = inst; + for(int i = 0; i < header->numMeshes; i++){ + inst->minVert = *(uint32*)p; p += 4; + inst->numVertices = *(int32*)p; p += 4; + inst->numIndices = *(int32*)p; p += 4; + inst->indexBuffer = header->data + *(uint32*)p; p += 4; + p += 8; // skip material and vertexShader + inst->vertexShader = 0; + // pixelShader in 3.3 here + inst++; + } + header->end = inst; + + header->vertexBuffer = new uint8[header->stride*header->numVertices]; + stream->read(header->vertexBuffer, header->stride*header->numVertices); +} + +void +writeNativeData(Stream *stream, int32 len, void *object, int32, int32) +{ + Geometry *geometry = (Geometry*)object; + writeChunkHeader(stream, ID_STRUCT, len-12); + assert(geometry->instData != NULL); + assert(geometry->instData->platform == PLATFORM_XBOX); + stream->writeU32(PLATFORM_XBOX); + InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; + + // we just fill header->data and write that + uint8 *p = header->data+0x18; + //uint8 *end = (uint8*)header->begin->indexBuffer; + //memset(p, 0xAB, end-p); + *(int32*)p = header->size; p += 4; + *(uint16*)p = header->serialNumber; p += 2; + *(uint16*)p = header->numMeshes; p += 2; + *(uint32*)p = header->primType; p += 4; + *(uint32*)p = header->numVertices; p += 4; + *(uint32*)p = header->stride; p += 4; + // RxXboxVertexFormat in 3.3 here + p += 4; // skip vertexBuffer pointer + *(bool32*)p = header->vertexAlpha; p += 4; + p += 8; // skip begin, end pointers + + InstanceData *inst = header->begin; + for(int i = 0; i < header->numMeshes; i++){ + *(uint32*)p = inst->minVert; p += 4; + *(int32*)p = inst->numVertices; p += 4; + *(int32*)p = inst->numIndices; p += 4; + *(uint32*)p = (uint8*)inst->indexBuffer - header->data; p += 4; + p += 8; // skip material and vertexShader + // pixelShader in 3.3 here + inst++; + } + + stream->write(header->data+0x18, header->size); + stream->write(header->vertexBuffer, header->stride*header->numVertices); +} + +int32 +getSizeNativeData(void *object, int32, int32) +{ + Geometry *geometry = (Geometry*)object; + assert(geometry->instData != NULL); + assert(geometry->instData->platform == PLATFORM_XBOX); + InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; + return 12 + 4 + header->size + header->stride*header->numVertices; +} + +void +registerNativeDataPlugin(void) +{ + Geometry::registerPlugin(0, ID_NATIVEDATA, + NULL, destroyNativeData, NULL); + Geometry::registerPluginStream(ID_NATIVEDATA, + readNativeData, + writeNativeData, + getSizeNativeData); +} + +// Skin plugin + +struct NativeSkin +{ + int32 table1[256]; // maps indices to bones + int32 table2[256]; // maps bones to indices + int32 numUsedBones; + void *vertexBuffer; + int32 stride; +}; + +void +readNativeSkin(Stream *stream, int32, void *object, int32 offset) +{ + Geometry *geometry = (Geometry*)object; + uint32 vers; + assert(findChunk(stream, ID_STRUCT, NULL, &vers)); + assert(vers >= 0x35000 && "can't handle native xbox skin < 0x35000"); + assert(stream->readU32() == PLATFORM_XBOX); + Skin *skin = new Skin; + *PLUGINOFFSET(Skin*, geometry, offset) = skin; + skin->numBones = stream->readI32(); + + // only allocate matrices + skin->numUsedBones = 0; + skin->allocateData(0); + NativeSkin *natskin = new NativeSkin; + skin->platformData = natskin; + stream->read(natskin->table1, 256*sizeof(int32)); + stream->read(natskin->table2, 256*sizeof(int32)); + // we use our own variable for this due to allocation + natskin->numUsedBones = stream->readI32(); + skin->maxIndex = stream->readI32(); + stream->seek(4); // skip pointer to vertexBuffer + natskin->stride = stream->readI32(); + int32 size = geometry->numVertices*natskin->stride; + natskin->vertexBuffer = new uint8[size]; + stream->read(natskin->vertexBuffer, size); + stream->read(skin->inverseMatrices, skin->numBones*64); + + // no split skins in GTA + stream->seek(12); +} + +void +writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset) +{ + Geometry *geometry = (Geometry*)object; + Skin *skin = *PLUGINOFFSET(Skin*, object, offset); + assert(skin->platformData); + assert(rw::version >= 0x35000 && "can't handle native xbox skin < 0x35000"); + NativeSkin *natskin = (NativeSkin*)skin->platformData; + + writeChunkHeader(stream, ID_STRUCT, len-12); + stream->writeU32(PLATFORM_XBOX); + stream->writeI32(skin->numBones); + stream->write(natskin->table1, 256*sizeof(int32)); + stream->write(natskin->table2, 256*sizeof(int32)); + stream->writeI32(natskin->numUsedBones); + stream->writeI32(skin->maxIndex); + stream->writeU32(0xBADEAFFE); // pointer to vertexBuffer + stream->writeI32(natskin->stride); + stream->write(natskin->vertexBuffer, + geometry->numVertices*natskin->stride); + stream->write(skin->inverseMatrices, skin->numBones*64); + int32 buffer[3] = { 0, 0, 0}; + stream->write(buffer, 12); +} + +int32 +getSizeNativeSkin(void *object, int32 offset) +{ + Geometry *geometry = (Geometry*)object; + Skin *skin = *PLUGINOFFSET(Skin*, object, offset); + if(skin == NULL) + return -1; + assert(skin->platformData); + NativeSkin *natskin = (NativeSkin*)skin->platformData; + return 12 + 8 + 2*256*4 + 4*4 + + natskin->stride*geometry->numVertices + skin->numBones*64 + 12; +} + +// Vertex Format Plugin + +static void* +createVertexFmt(void *object, int32 offset, int32) +{ + *PLUGINOFFSET(uint32, object, offset) = 0; + return object; +} + +static void* +copyVertexFmt(void *dst, void *src, int32 offset, int32) +{ + *PLUGINOFFSET(uint32, dst, offset) = *PLUGINOFFSET(uint32, src, offset); + return dst; +} + +static void +readVertexFmt(Stream *stream, int32, void *object, int32 offset, int32) +{ + uint32 fmt = stream->readU32(); + *PLUGINOFFSET(uint32, object, offset) = fmt; + // TODO: create and attach "vertex shader" +} + +static void +writeVertexFmt(Stream *stream, int32, void *object, int32 offset, int32) +{ + stream->writeI32(*PLUGINOFFSET(uint32, object, offset)); +} + +static int32 +getSizeVertexFmt(void*, int32, int32) +{ + // TODO: make dependent on platform + return 4; +} + +void +registerVertexFormatPlugin(void) +{ + Geometry::registerPlugin(sizeof(uint32), ID_VERTEXFMT, + createVertexFmt, NULL, copyVertexFmt); + Geometry::registerPluginStream(ID_VERTEXFMT, + readVertexFmt, + writeVertexFmt, + getSizeVertexFmt); +} + +} +} diff --git a/tests/gl/main.cpp b/tests/gl/main.cpp index 5754989..10615ef 100755 --- a/tests/gl/main.cpp +++ b/tests/gl/main.cpp @@ -200,6 +200,7 @@ init(void) rw::ps2::registerADCPlugin(); rw::ps2::registerPDSPlugin(); rw::registerSkinPlugin(); + rw::xbox::registerVertexFormatPlugin(); rw::registerNativeDataPlugin(); // rw::ps2::registerNativeDataPlugin(); rw::registerMeshPlugin(); diff --git a/tests/ps2/main.cpp b/tests/ps2/main.cpp index b97304d..e4028d0 100755 --- a/tests/ps2/main.cpp +++ b/tests/ps2/main.cpp @@ -238,6 +238,7 @@ main() rw::ps2::registerADCPlugin(); rw::ps2::registerPDSPlugin(); rw::registerSkinPlugin(); + rw::xbox::registerVertexFormatPlugin(); rw::registerNativeDataPlugin(); // rw::ps2::registerNativeDataPlugin(); rw::registerMeshPlugin();