mirror of
https://github.com/aap/librw.git
synced 2025-01-21 08:11:09 +00:00
implemented xbox native geometry and skin
This commit is contained in:
parent
6f8dccd095
commit
d04e97fb47
4
Makefile
4
Makefile
@ -7,11 +7,11 @@ BUILDDIR=build-$(BUILD)
|
|||||||
SRCDIR=src
|
SRCDIR=src
|
||||||
SRC := $(patsubst %.cpp,$(SRCDIR)/%.cpp, rwbase.cpp clump.cpp\
|
SRC := $(patsubst %.cpp,$(SRCDIR)/%.cpp, rwbase.cpp clump.cpp\
|
||||||
geometry.cpp plugins.cpp pipeline.cpp\
|
geometry.cpp plugins.cpp pipeline.cpp\
|
||||||
ps2.cpp ogl.cpp\
|
ps2.cpp ogl.cpp xbox.cpp\
|
||||||
image.cpp gtaplg.cpp)
|
image.cpp gtaplg.cpp)
|
||||||
OBJ := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$(SRC))
|
OBJ := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$(SRC))
|
||||||
DEP := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.d,$(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=librw-$(BUILD).a
|
||||||
|
|
||||||
$(LIB): $(OBJ)
|
$(LIB): $(OBJ)
|
||||||
|
@ -7,11 +7,11 @@ BUILDDIR=build-$(BUILD)
|
|||||||
SRCDIR=src
|
SRCDIR=src
|
||||||
SRC := $(patsubst %.cpp,$(SRCDIR)/%.cpp, rwbase.cpp clump.cpp\
|
SRC := $(patsubst %.cpp,$(SRCDIR)/%.cpp, rwbase.cpp clump.cpp\
|
||||||
geometry.cpp plugins.cpp pipeline.cpp\
|
geometry.cpp plugins.cpp pipeline.cpp\
|
||||||
ps2.cpp ogl.cpp\
|
ps2.cpp ogl.cpp xbox.cpp\
|
||||||
image.cpp gtaplg.cpp)
|
image.cpp gtaplg.cpp)
|
||||||
OBJ := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$(SRC))
|
OBJ := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$(SRC))
|
||||||
DEP := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.d,$(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=librw-$(BUILD).a
|
||||||
|
|
||||||
$(LIB): $(OBJ)
|
$(LIB): $(OBJ)
|
||||||
|
@ -8,11 +8,11 @@ BUILDDIR=build-$(BUILD)
|
|||||||
SRCDIR=src
|
SRCDIR=src
|
||||||
SRC := $(patsubst %.cpp,$(SRCDIR)/%.cpp, rwbase.cpp clump.cpp\
|
SRC := $(patsubst %.cpp,$(SRCDIR)/%.cpp, rwbase.cpp clump.cpp\
|
||||||
geometry.cpp plugins.cpp pipeline.cpp\
|
geometry.cpp plugins.cpp pipeline.cpp\
|
||||||
ps2.cpp ogl.cpp\
|
ps2.cpp ogl.cpp xbox.cpp\
|
||||||
image.cpp gtaplg.cpp)
|
image.cpp gtaplg.cpp)
|
||||||
OBJ := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$(SRC))
|
OBJ := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$(SRC))
|
||||||
DEP := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.d,$(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
|
INCPATH=-I$(PS2SDK)/ee/include -I$(PS2SDK)/common/include
|
||||||
LIB=librw-$(BUILD).a
|
LIB=librw-$(BUILD).a
|
||||||
|
|
||||||
|
@ -23,11 +23,12 @@ main(int argc, char *argv[])
|
|||||||
rw::registerAtomicRightsPlugin();
|
rw::registerAtomicRightsPlugin();
|
||||||
rw::registerHAnimPlugin();
|
rw::registerHAnimPlugin();
|
||||||
gta::registerNodeNamePlugin();
|
gta::registerNodeNamePlugin();
|
||||||
gta::registerBreakableModelPlugin();
|
// gta::registerBreakableModelPlugin();
|
||||||
gta::registerExtraVertColorPlugin();
|
gta::registerExtraVertColorPlugin();
|
||||||
rw::ps2::registerADCPlugin();
|
rw::ps2::registerADCPlugin();
|
||||||
rw::ps2::registerPDSPlugin();
|
rw::ps2::registerPDSPlugin();
|
||||||
rw::registerSkinPlugin();
|
rw::registerSkinPlugin();
|
||||||
|
rw::xbox::registerVertexFormatPlugin();
|
||||||
rw::registerNativeDataPlugin();
|
rw::registerNativeDataPlugin();
|
||||||
// rw::ps2::registerNativeDataPlugin();
|
// rw::ps2::registerNativeDataPlugin();
|
||||||
rw::registerMeshPlugin();
|
rw::registerMeshPlugin();
|
||||||
|
@ -77,6 +77,8 @@ getChunkName(uint32 id)
|
|||||||
return "Bin Mesh PLG";
|
return "Bin Mesh PLG";
|
||||||
case 0x510:
|
case 0x510:
|
||||||
return "Native Data PLG";
|
return "Native Data PLG";
|
||||||
|
case 0x511:
|
||||||
|
return "Vertex Format PLG";
|
||||||
case 0xF21E:
|
case 0xF21E:
|
||||||
return "ZModeler Lock";
|
return "ZModeler Lock";
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ main(int argc, char *argv[])
|
|||||||
rw::ps2::registerADCPlugin();
|
rw::ps2::registerADCPlugin();
|
||||||
rw::ps2::registerPDSPlugin();
|
rw::ps2::registerPDSPlugin();
|
||||||
rw::registerSkinPlugin();
|
rw::registerSkinPlugin();
|
||||||
|
rw::xbox::registerVertexFormatPlugin();
|
||||||
rw::registerNativeDataPlugin();
|
rw::registerNativeDataPlugin();
|
||||||
rw::registerMeshPlugin();
|
rw::registerMeshPlugin();
|
||||||
rw::Atomic::init();
|
rw::Atomic::init();
|
||||||
|
1
rw.h
1
rw.h
@ -4,3 +4,4 @@
|
|||||||
#include "src/rwobjects.h"
|
#include "src/rwobjects.h"
|
||||||
#include "src/rwps2.h"
|
#include "src/rwps2.h"
|
||||||
#include "src/rwogl.h"
|
#include "src/rwogl.h"
|
||||||
|
#include "src/rwxbox.h"
|
||||||
|
@ -205,7 +205,7 @@ Clump::streamRead(Stream *stream)
|
|||||||
clump->numAtomics = buf[0];
|
clump->numAtomics = buf[0];
|
||||||
clump->numLights = 0;
|
clump->numLights = 0;
|
||||||
clump->numCameras = 0;
|
clump->numCameras = 0;
|
||||||
if(version >= 0x33000){
|
if(version > 0x33000){
|
||||||
clump->numLights = buf[1];
|
clump->numLights = buf[1];
|
||||||
clump->numCameras = buf[2];
|
clump->numCameras = buf[2];
|
||||||
}
|
}
|
||||||
@ -264,7 +264,7 @@ Clump::streamWrite(Stream *stream)
|
|||||||
int size = this->streamGetSize();
|
int size = this->streamGetSize();
|
||||||
writeChunkHeader(stream, ID_CLUMP, size);
|
writeChunkHeader(stream, ID_CLUMP, size);
|
||||||
int buf[3] = { this->numAtomics, this->numLights, this->numCameras };
|
int buf[3] = { this->numAtomics, this->numLights, this->numCameras };
|
||||||
size = version >= 0x33000 ? 12 : 4;
|
size = version > 0x33000 ? 12 : 4;
|
||||||
writeChunkHeader(stream, ID_STRUCT, size);
|
writeChunkHeader(stream, ID_STRUCT, size);
|
||||||
stream->write(buf, size);
|
stream->write(buf, size);
|
||||||
|
|
||||||
@ -316,7 +316,7 @@ Clump::streamGetSize(void)
|
|||||||
uint32 size = 0;
|
uint32 size = 0;
|
||||||
size += 12; // Struct
|
size += 12; // Struct
|
||||||
size += 4; // numAtomics
|
size += 4; // numAtomics
|
||||||
if(version >= 0x33000)
|
if(version > 0x33000)
|
||||||
size += 8; // numLights, numCameras
|
size += 8; // numLights, numCameras
|
||||||
|
|
||||||
// frame list
|
// frame list
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "rwpipeline.h"
|
#include "rwpipeline.h"
|
||||||
#include "rwobjects.h"
|
#include "rwobjects.h"
|
||||||
#include "rwps2.h"
|
#include "rwps2.h"
|
||||||
|
#include "rwxbox.h"
|
||||||
#include "rwogl.h"
|
#include "rwogl.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -283,7 +284,11 @@ readNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
|
|||||||
if(platform == PLATFORM_PS2)
|
if(platform == PLATFORM_PS2)
|
||||||
ps2::readNativeData(stream, len, object, o, s);
|
ps2::readNativeData(stream, len, object, o, s);
|
||||||
else if(platform == PLATFORM_XBOX)
|
else if(platform == PLATFORM_XBOX)
|
||||||
|
xbox::readNativeData(stream, len, object, o, s);
|
||||||
|
else{
|
||||||
|
fprintf(stderr, "unknown platform %d\n", platform);
|
||||||
stream->seek(len);
|
stream->seek(len);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
stream->seek(-12);
|
stream->seek(-12);
|
||||||
gl::readNativeData(stream, len, object, o, s);
|
gl::readNativeData(stream, len, object, o, s);
|
||||||
@ -298,6 +303,8 @@ writeNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
|
|||||||
return;
|
return;
|
||||||
if(geometry->instData->platform == PLATFORM_PS2)
|
if(geometry->instData->platform == PLATFORM_PS2)
|
||||||
ps2::writeNativeData(stream, len, object, o, s);
|
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)
|
else if(geometry->instData->platform == PLATFORM_OGL)
|
||||||
gl::writeNativeData(stream, len, object, o, s);
|
gl::writeNativeData(stream, len, object, o, s);
|
||||||
}
|
}
|
||||||
@ -311,7 +318,7 @@ getSizeNativeData(void *object, int32 offset, int32 size)
|
|||||||
if(geometry->instData->platform == PLATFORM_PS2)
|
if(geometry->instData->platform == PLATFORM_PS2)
|
||||||
return ps2::getSizeNativeData(object, offset, size);
|
return ps2::getSizeNativeData(object, offset, size);
|
||||||
else if(geometry->instData->platform == PLATFORM_XBOX)
|
else if(geometry->instData->platform == PLATFORM_XBOX)
|
||||||
return -1;
|
return xbox::getSizeNativeData(object, offset, size);
|
||||||
else if(geometry->instData->platform == PLATFORM_OGL)
|
else if(geometry->instData->platform == PLATFORM_OGL)
|
||||||
return gl::getSizeNativeData(object, offset, size);
|
return gl::getSizeNativeData(object, offset, size);
|
||||||
return -1;
|
return -1;
|
||||||
@ -366,6 +373,7 @@ copySkin(void *dst, void *src, int32 offset, int32)
|
|||||||
dstskin->numUsedBones = srcskin->numUsedBones;
|
dstskin->numUsedBones = srcskin->numUsedBones;
|
||||||
dstskin->maxIndex = srcskin->maxIndex;
|
dstskin->maxIndex = srcskin->maxIndex;
|
||||||
|
|
||||||
|
assert(0 && "can't copy skin yet");
|
||||||
dstskin->allocateData(geometry->numVertices);
|
dstskin->allocateData(geometry->numVertices);
|
||||||
memcpy(dstskin->usedBones, srcskin->usedBones, srcskin->numUsedBones);
|
memcpy(dstskin->usedBones, srcskin->usedBones, srcskin->numUsedBones);
|
||||||
memcpy(dstskin->inverseMatrices, srcskin->inverseMatrices,
|
memcpy(dstskin->inverseMatrices, srcskin->inverseMatrices,
|
||||||
@ -382,8 +390,11 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
|
|||||||
Geometry *geometry = (Geometry*)object;
|
Geometry *geometry = (Geometry*)object;
|
||||||
|
|
||||||
if(geometry->instData){
|
if(geometry->instData){
|
||||||
|
// TODO: function pointers
|
||||||
if(geometry->instData->platform == PLATFORM_PS2)
|
if(geometry->instData->platform == PLATFORM_PS2)
|
||||||
ps2::readNativeSkin(stream, len, object, offset);
|
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)
|
else if(geometry->instData->platform == PLATFORM_OGL)
|
||||||
gl::readNativeSkin(stream, len, object, offset);
|
gl::readNativeSkin(stream, len, object, offset);
|
||||||
else
|
else
|
||||||
@ -415,8 +426,8 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
|
|||||||
stream->seek(4); // skip 0xdeaddead
|
stream->seek(4); // skip 0xdeaddead
|
||||||
stream->read(&skin->inverseMatrices[i*16], 64);
|
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)
|
if(!oldFormat)
|
||||||
stream->seek(12);
|
stream->seek(12);
|
||||||
}
|
}
|
||||||
@ -430,6 +441,8 @@ writeSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
|
|||||||
if(geometry->instData){
|
if(geometry->instData){
|
||||||
if(geometry->instData->platform == PLATFORM_PS2)
|
if(geometry->instData->platform == PLATFORM_PS2)
|
||||||
ps2::writeNativeSkin(stream, len, object, offset);
|
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)
|
else if(geometry->instData->platform == PLATFORM_OGL)
|
||||||
gl::writeNativeSkin(stream, len, object, offset);
|
gl::writeNativeSkin(stream, len, object, offset);
|
||||||
else
|
else
|
||||||
@ -457,6 +470,8 @@ writeSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
|
|||||||
stream->writeU32(0xdeaddead);
|
stream->writeU32(0xdeaddead);
|
||||||
stream->write(&skin->inverseMatrices[i*16], 64);
|
stream->write(&skin->inverseMatrices[i*16], 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// no split skins in GTA
|
||||||
if(!oldFormat){
|
if(!oldFormat){
|
||||||
uint32 buffer[3] = { 0, 0, 0};
|
uint32 buffer[3] = { 0, 0, 0};
|
||||||
stream->write(buffer, 12);
|
stream->write(buffer, 12);
|
||||||
@ -471,6 +486,8 @@ getSizeSkin(void *object, int32 offset, int32)
|
|||||||
if(geometry->instData){
|
if(geometry->instData){
|
||||||
if(geometry->instData->platform == PLATFORM_PS2)
|
if(geometry->instData->platform == PLATFORM_PS2)
|
||||||
return ps2::getSizeNativeSkin(object, offset);
|
return ps2::getSizeNativeSkin(object, offset);
|
||||||
|
if(geometry->instData->platform == PLATFORM_XBOX)
|
||||||
|
return xbox::getSizeNativeSkin(object, offset);
|
||||||
if(geometry->instData->platform == PLATFORM_OGL)
|
if(geometry->instData->platform == PLATFORM_OGL)
|
||||||
return gl::getSizeNativeSkin(object, offset);
|
return gl::getSizeNativeSkin(object, offset);
|
||||||
assert(0 && "unsupported native skin platform");
|
assert(0 && "unsupported native skin platform");
|
||||||
@ -553,6 +570,7 @@ Skin::allocateData(int32 numVerts)
|
|||||||
if(numVerts)
|
if(numVerts)
|
||||||
this->weights = (float*)data;
|
this->weights = (float*)data;
|
||||||
|
|
||||||
|
this->platformData = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -611,10 +629,9 @@ writeAtomicMatFX(Stream *stream, int32, void *object, int32 offset, int32)
|
|||||||
static int32
|
static int32
|
||||||
getSizeAtomicMatFX(void *object, int32 offset, int32)
|
getSizeAtomicMatFX(void *object, int32 offset, int32)
|
||||||
{
|
{
|
||||||
// TODO: version dependent
|
int32 flag = *PLUGINOFFSET(int32, object, offset);
|
||||||
/* int32 flag;
|
// TODO: not sure which version
|
||||||
flag = *PLUGINOFFSET(int32, object, offset);
|
return flag && rw::version < 0x35000 ? 4 : -1;
|
||||||
return flag ? 4 : -1; */
|
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ void*
|
|||||||
destroyNativeData(void *object, int32, int32)
|
destroyNativeData(void *object, int32, int32)
|
||||||
{
|
{
|
||||||
Geometry *geometry = (Geometry*)object;
|
Geometry *geometry = (Geometry*)object;
|
||||||
|
assert(geometry->instData != NULL);
|
||||||
assert(geometry->instData->platform == PLATFORM_PS2);
|
assert(geometry->instData->platform == PLATFORM_PS2);
|
||||||
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++)
|
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;
|
Geometry *geometry = (Geometry*)object;
|
||||||
writeChunkHeader(stream, ID_STRUCT, len-12);
|
writeChunkHeader(stream, ID_STRUCT, len-12);
|
||||||
|
assert(geometry->instData != NULL);
|
||||||
assert(geometry->instData->platform == PLATFORM_PS2);
|
assert(geometry->instData->platform == PLATFORM_PS2);
|
||||||
stream->writeU32(PLATFORM_PS2);
|
stream->writeU32(PLATFORM_PS2);
|
||||||
assert(geometry->instData != NULL);
|
|
||||||
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
InstanceData *instance = &header->instanceMeshes[i];
|
InstanceData *instance = &header->instanceMeshes[i];
|
||||||
@ -87,8 +88,8 @@ getSizeNativeData(void *object, int32, int32)
|
|||||||
{
|
{
|
||||||
Geometry *geometry = (Geometry*)object;
|
Geometry *geometry = (Geometry*)object;
|
||||||
int32 size = 16;
|
int32 size = 16;
|
||||||
assert(geometry->instData->platform == PLATFORM_PS2);
|
|
||||||
assert(geometry->instData != NULL);
|
assert(geometry->instData != NULL);
|
||||||
|
assert(geometry->instData->platform == PLATFORM_PS2);
|
||||||
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
InstanceData *instance = &header->instanceMeshes[i];
|
InstanceData *instance = &header->instanceMeshes[i];
|
||||||
@ -593,8 +594,8 @@ void
|
|||||||
ObjPipeline::uninstance(Atomic *atomic)
|
ObjPipeline::uninstance(Atomic *atomic)
|
||||||
{
|
{
|
||||||
Geometry *geometry = atomic->geometry;
|
Geometry *geometry = atomic->geometry;
|
||||||
assert(geometry->instData->platform == PLATFORM_PS2);
|
|
||||||
assert(geometry->instData != NULL);
|
assert(geometry->instData != NULL);
|
||||||
|
assert(geometry->instData->platform == PLATFORM_PS2);
|
||||||
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
Mesh *mesh = &geometry->meshHeader->mesh[i];
|
Mesh *mesh = &geometry->meshHeader->mesh[i];
|
||||||
|
@ -140,6 +140,7 @@ enum PluginID
|
|||||||
ID_ADC = 0x134,
|
ID_ADC = 0x134,
|
||||||
ID_MESH = 0x50E,
|
ID_MESH = 0x50E,
|
||||||
ID_NATIVEDATA = 0x510,
|
ID_NATIVEDATA = 0x510,
|
||||||
|
ID_VERTEXFMT = 0x511,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int version;
|
extern int version;
|
||||||
|
@ -320,6 +320,7 @@ struct Skin
|
|||||||
uint8 *indices;
|
uint8 *indices;
|
||||||
float *weights;
|
float *weights;
|
||||||
uint8 *data; // only used by delete
|
uint8 *data; // only used by delete
|
||||||
|
void *platformData; // a place to store platform specific stuff
|
||||||
|
|
||||||
void allocateData(int32 numVerts);
|
void allocateData(int32 numVerts);
|
||||||
void allocateVertexData(int32 numVerts);
|
void allocateVertexData(int32 numVerts);
|
||||||
|
47
src/rwxbox.h
Normal file
47
src/rwxbox.h
Normal file
@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
271
src/xbox.cpp
Normal file
271
src/xbox.cpp
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -200,6 +200,7 @@ init(void)
|
|||||||
rw::ps2::registerADCPlugin();
|
rw::ps2::registerADCPlugin();
|
||||||
rw::ps2::registerPDSPlugin();
|
rw::ps2::registerPDSPlugin();
|
||||||
rw::registerSkinPlugin();
|
rw::registerSkinPlugin();
|
||||||
|
rw::xbox::registerVertexFormatPlugin();
|
||||||
rw::registerNativeDataPlugin();
|
rw::registerNativeDataPlugin();
|
||||||
// rw::ps2::registerNativeDataPlugin();
|
// rw::ps2::registerNativeDataPlugin();
|
||||||
rw::registerMeshPlugin();
|
rw::registerMeshPlugin();
|
||||||
|
@ -238,6 +238,7 @@ main()
|
|||||||
rw::ps2::registerADCPlugin();
|
rw::ps2::registerADCPlugin();
|
||||||
rw::ps2::registerPDSPlugin();
|
rw::ps2::registerPDSPlugin();
|
||||||
rw::registerSkinPlugin();
|
rw::registerSkinPlugin();
|
||||||
|
rw::xbox::registerVertexFormatPlugin();
|
||||||
rw::registerNativeDataPlugin();
|
rw::registerNativeDataPlugin();
|
||||||
// rw::ps2::registerNativeDataPlugin();
|
// rw::ps2::registerNativeDataPlugin();
|
||||||
rw::registerMeshPlugin();
|
rw::registerMeshPlugin();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user