mirror of
https://github.com/aap/librw.git
synced 2024-11-25 13:15:43 +00:00
Implemented Extra vertex colors and (crippled) ADC plugin.
This commit is contained in:
parent
cec7963a9d
commit
811c045326
5
Makefile
5
Makefile
@ -6,8 +6,9 @@ BUILDDEF:=$(shell echo $(BUILD) | tr a-z A-Z | sed 's/^/-DRW_/')
|
|||||||
BUILDDIR=build-$(BUILD)
|
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 ps2.cpp\
|
geometry.cpp geometryplg.cpp\
|
||||||
ogl.cpp image.cpp)
|
ps2.cpp ogl.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
|
||||||
|
@ -6,8 +6,9 @@ BUILDDEF:=$(shell echo $(BUILD) | tr a-z A-Z | sed 's/^/-DRW_/')
|
|||||||
BUILDDIR=build-$(BUILD)
|
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 ps2.cpp\
|
geometry.cpp geometryplg.cpp\
|
||||||
ogl.cpp)
|
ps2.cpp ogl.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
|
||||||
|
@ -7,8 +7,9 @@ BUILDDEF:=$(shell echo $(BUILD) | tr a-z A-Z | sed 's/^/-DRW_/')
|
|||||||
BUILDDIR=build-$(BUILD)
|
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 ps2.cpp\
|
geometry.cpp geometryplg.cpp\
|
||||||
ogl.cpp image.cpp)
|
ps2.cpp ogl.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
|
||||||
|
13
dffwrite.cpp
13
dffwrite.cpp
@ -6,6 +6,7 @@
|
|||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
#include "rw.h"
|
#include "rw.h"
|
||||||
|
#include "src/gtaplg.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -15,11 +16,13 @@ main(int argc, char *argv[])
|
|||||||
// Rw::Version = 0x31000;
|
// Rw::Version = 0x31000;
|
||||||
// Rw::Build = 0;
|
// Rw::Build = 0;
|
||||||
|
|
||||||
registerNodeNamePlugin();
|
Rw::RegisterNodeNamePlugin();
|
||||||
registerBreakableModelPlugin();
|
Rw::RegisterBreakableModelPlugin();
|
||||||
registerNativeDataPlugin();
|
Rw::RegisterExtraVertColorPlugin();
|
||||||
// Ps2::registerNativeDataPlugin();
|
Rw::Ps2::RegisterADCPlugin();
|
||||||
registerMeshPlugin();
|
Rw::RegisterNativeDataPlugin();
|
||||||
|
// Rw::Ps2::RegisterNativeDataPlugin();
|
||||||
|
Rw::RegisterMeshPlugin();
|
||||||
Rw::Clump *c;
|
Rw::Clump *c;
|
||||||
|
|
||||||
// ifstream in(argv[1], ios::binary);
|
// ifstream in(argv[1], ios::binary);
|
||||||
|
@ -435,6 +435,7 @@ Texture::streamWrite(Stream *stream)
|
|||||||
WriteChunkHeader(stream, ID_STRUCT, 4);
|
WriteChunkHeader(stream, ID_STRUCT, 4);
|
||||||
stream->writeU32(this->filterAddressing);
|
stream->writeU32(this->filterAddressing);
|
||||||
|
|
||||||
|
// TODO: 4 char string -> 8 bytes
|
||||||
// TODO: length can't be > 32
|
// TODO: length can't be > 32
|
||||||
size = strlen(this->name)+3 & ~3;
|
size = strlen(this->name)+3 & ~3;
|
||||||
if(size < 4)
|
if(size < 4)
|
||||||
|
388
src/plugins.cpp
388
src/plugins.cpp
@ -1,388 +0,0 @@
|
|||||||
#include <cstdio>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
//#include <iostream>
|
|
||||||
//#include <fstream>
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include "rwbase.h"
|
|
||||||
#include "rwplugin.h"
|
|
||||||
#include "rwobjects.h"
|
|
||||||
#include "rwps2.h"
|
|
||||||
#include "rwogl.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace Rw;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Frame
|
|
||||||
//
|
|
||||||
|
|
||||||
// Node Name
|
|
||||||
|
|
||||||
static void*
|
|
||||||
createNodeName(void *object, int32 offset, int32)
|
|
||||||
{
|
|
||||||
char *name = PLUGINOFFSET(char, object, offset);
|
|
||||||
name[0] = '\0';
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void*
|
|
||||||
copyNodeName(void *dst, void *src, int32 offset, int32)
|
|
||||||
{
|
|
||||||
char *dstname = PLUGINOFFSET(char, dst, offset);
|
|
||||||
char *srcname = PLUGINOFFSET(char, src, offset);
|
|
||||||
strncpy(dstname, srcname, 17);
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void*
|
|
||||||
destroyNodeName(void *object, int32, int32)
|
|
||||||
{
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
readNodeName(Stream *stream, int32 len, void *object, int32 offset, int32)
|
|
||||||
{
|
|
||||||
char *name = PLUGINOFFSET(char, object, offset);
|
|
||||||
stream->read(name, len);
|
|
||||||
name[len] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
writeNodeName(Stream *stream, int32 len, void *object, int32 offset, int32)
|
|
||||||
{
|
|
||||||
char *name = PLUGINOFFSET(char, object, offset);
|
|
||||||
stream->write(name, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32
|
|
||||||
getSizeNodeName(void *object, int32 offset)
|
|
||||||
{
|
|
||||||
char *name = PLUGINOFFSET(char, object, offset);
|
|
||||||
int32 len = strlen(name);
|
|
||||||
return len > 0 ? len : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
registerNodeNamePlugin(void)
|
|
||||||
{
|
|
||||||
Frame::registerPlugin(18, 0x253f2fe, (Constructor)createNodeName,
|
|
||||||
(Destructor)destroyNodeName,
|
|
||||||
(CopyConstructor)copyNodeName);
|
|
||||||
Frame::registerPluginStream(0x253f2fe, (StreamRead)readNodeName,
|
|
||||||
(StreamWrite)writeNodeName,
|
|
||||||
(StreamGetSize)getSizeNodeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Geometry
|
|
||||||
//
|
|
||||||
|
|
||||||
// Mesh
|
|
||||||
|
|
||||||
static void
|
|
||||||
readMesh(Stream *stream, int32 len, void *object, int32, int32)
|
|
||||||
{
|
|
||||||
Geometry *geo = (Geometry*)object;
|
|
||||||
int32 indbuf[256];
|
|
||||||
uint32 buf[3];
|
|
||||||
stream->read(buf, 12);
|
|
||||||
geo->meshHeader = new MeshHeader;
|
|
||||||
geo->meshHeader->flags = buf[0];
|
|
||||||
geo->meshHeader->numMeshes = buf[1];
|
|
||||||
geo->meshHeader->totalIndices = buf[2];
|
|
||||||
geo->meshHeader->mesh = new Mesh[geo->meshHeader->numMeshes];
|
|
||||||
Mesh *mesh = geo->meshHeader->mesh;
|
|
||||||
bool hasData = len > 12+geo->meshHeader->numMeshes*8;
|
|
||||||
for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){
|
|
||||||
stream->read(buf, 8);
|
|
||||||
mesh->numIndices = buf[0];
|
|
||||||
mesh->material = geo->materialList[buf[1]];
|
|
||||||
mesh->indices = NULL;
|
|
||||||
if(geo->geoflags & Geometry::NATIVE){
|
|
||||||
// OpenGL stores uint16 indices here
|
|
||||||
if(hasData){
|
|
||||||
mesh->indices = new uint16[mesh->numIndices];
|
|
||||||
stream->read(mesh->indices,
|
|
||||||
mesh->numIndices*2);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
mesh->indices = new uint16[mesh->numIndices];
|
|
||||||
uint16 *ind = mesh->indices;
|
|
||||||
int32 numIndices = mesh->numIndices;
|
|
||||||
for(; numIndices > 0; numIndices -= 256){
|
|
||||||
int32 n = numIndices < 256 ? numIndices : 256;
|
|
||||||
stream->read(indbuf, n*4);
|
|
||||||
for(int32 j = 0; j < n; j++)
|
|
||||||
ind[j] = indbuf[j];
|
|
||||||
ind += n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mesh++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
writeMesh(Stream *stream, int32, void *object, int32, int32)
|
|
||||||
{
|
|
||||||
Geometry *geo = (Geometry*)object;
|
|
||||||
int32 indbuf[256];
|
|
||||||
uint32 buf[3];
|
|
||||||
buf[0] = geo->meshHeader->flags;
|
|
||||||
buf[1] = geo->meshHeader->numMeshes;
|
|
||||||
buf[2] = geo->meshHeader->totalIndices;
|
|
||||||
stream->write(buf, 12);
|
|
||||||
Mesh *mesh = geo->meshHeader->mesh;
|
|
||||||
for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){
|
|
||||||
buf[0] = mesh->numIndices;
|
|
||||||
buf[1] = findPointer((void*)mesh->material,
|
|
||||||
(void**)geo->materialList,
|
|
||||||
geo->numMaterials);
|
|
||||||
stream->write(buf, 8);
|
|
||||||
if(geo->geoflags & Geometry::NATIVE){
|
|
||||||
assert(geo->instData != NULL);
|
|
||||||
if(geo->instData->platform == PLATFORM_OGL)
|
|
||||||
stream->write(mesh->indices,
|
|
||||||
mesh->numIndices*2);
|
|
||||||
}else{
|
|
||||||
uint16 *ind = mesh->indices;
|
|
||||||
int32 numIndices = mesh->numIndices;
|
|
||||||
for(; numIndices > 0; numIndices -= 256){
|
|
||||||
int32 n = numIndices < 256 ? numIndices : 256;
|
|
||||||
for(int32 j = 0; j < n; j++)
|
|
||||||
indbuf[j] = ind[j];
|
|
||||||
stream->write(indbuf, n*4);
|
|
||||||
ind += n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mesh++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32
|
|
||||||
getSizeMesh(void *object, int32)
|
|
||||||
{
|
|
||||||
Geometry *geo = (Geometry*)object;
|
|
||||||
if(geo->meshHeader == NULL)
|
|
||||||
return -1;
|
|
||||||
int32 size = 12 + geo->meshHeader->numMeshes*8;
|
|
||||||
if(geo->geoflags & Geometry::NATIVE){
|
|
||||||
assert(geo->instData != NULL);
|
|
||||||
if(geo->instData->platform == PLATFORM_OGL)
|
|
||||||
size += geo->meshHeader->totalIndices*2;
|
|
||||||
}else{
|
|
||||||
size += geo->meshHeader->totalIndices*4;
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
registerMeshPlugin(void)
|
|
||||||
{
|
|
||||||
Geometry::registerPlugin(0, 0x50E, NULL, NULL, NULL);
|
|
||||||
Geometry::registerPluginStream(0x50E, (StreamRead)readMesh,
|
|
||||||
(StreamWrite)writeMesh,
|
|
||||||
(StreamGetSize)getSizeMesh);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Native Data
|
|
||||||
|
|
||||||
static void*
|
|
||||||
destroyNativeData(void *object, int32 offset, int32 size)
|
|
||||||
{
|
|
||||||
Geometry *geometry = (Geometry*)object;
|
|
||||||
if(geometry->instData == NULL)
|
|
||||||
return object;
|
|
||||||
if(geometry->instData->platform == PLATFORM_PS2)
|
|
||||||
return Ps2::DestroyNativeData(object, offset, size);
|
|
||||||
if(geometry->instData->platform == PLATFORM_OGL)
|
|
||||||
return Gl::DestroyNativeData(object, offset, size);
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
readNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
|
|
||||||
{
|
|
||||||
ChunkHeaderInfo header;
|
|
||||||
uint32 libid;
|
|
||||||
uint32 platform;
|
|
||||||
// ugly hack to find out platform
|
|
||||||
stream->seek(-4);
|
|
||||||
libid = stream->readU32();
|
|
||||||
ReadChunkHeaderInfo(stream, &header);
|
|
||||||
if(header.type == ID_STRUCT &&
|
|
||||||
LibraryIDPack(header.version, header.build) == libid){
|
|
||||||
// must be PS2 or Xbox
|
|
||||||
platform = stream->readU32();
|
|
||||||
stream->seek(-16);
|
|
||||||
if(platform == PLATFORM_PS2)
|
|
||||||
Ps2::ReadNativeData(stream, len, object, o, s);
|
|
||||||
else if(platform == PLATFORM_XBOX)
|
|
||||||
stream->seek(len);
|
|
||||||
}else{
|
|
||||||
stream->seek(-12);
|
|
||||||
Gl::ReadNativeData(stream, len, object, o, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
writeNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
|
|
||||||
{
|
|
||||||
Geometry *geometry = (Geometry*)object;
|
|
||||||
if(geometry->instData == NULL)
|
|
||||||
return;
|
|
||||||
if(geometry->instData->platform == PLATFORM_PS2)
|
|
||||||
Ps2::WriteNativeData(stream, len, object, o, s);
|
|
||||||
else if(geometry->instData->platform == PLATFORM_OGL)
|
|
||||||
Gl::WriteNativeData(stream, len, object, o, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32
|
|
||||||
getSizeNativeData(void *object, int32 offset, int32 size)
|
|
||||||
{
|
|
||||||
Geometry *geometry = (Geometry*)object;
|
|
||||||
if(geometry->instData == NULL)
|
|
||||||
return -1;
|
|
||||||
if(geometry->instData->platform == PLATFORM_PS2)
|
|
||||||
return Ps2::GetSizeNativeData(object, offset, size);
|
|
||||||
else if(geometry->instData->platform == PLATFORM_XBOX)
|
|
||||||
return -1;
|
|
||||||
else if(geometry->instData->platform == PLATFORM_OGL)
|
|
||||||
return Gl::GetSizeNativeData(object, offset, size);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
registerNativeDataPlugin(void)
|
|
||||||
{
|
|
||||||
Geometry::registerPlugin(0, ID_NATIVEDATA,
|
|
||||||
NULL, destroyNativeData, NULL);
|
|
||||||
Geometry::registerPluginStream(ID_NATIVEDATA,
|
|
||||||
(StreamRead)readNativeData,
|
|
||||||
(StreamWrite)writeNativeData,
|
|
||||||
(StreamGetSize)getSizeNativeData);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Breakable Model
|
|
||||||
|
|
||||||
// TODO: put this in a header
|
|
||||||
struct Breakable
|
|
||||||
{
|
|
||||||
uint32 position;
|
|
||||||
uint32 numVertices;
|
|
||||||
uint32 numFaces;
|
|
||||||
uint32 numMaterials;
|
|
||||||
|
|
||||||
float32 *vertices;
|
|
||||||
float32 *texCoords;
|
|
||||||
uint8 *colors;
|
|
||||||
uint16 *faces;
|
|
||||||
uint16 *matIDs;
|
|
||||||
char (*texNames)[32];
|
|
||||||
char (*maskNames)[32];
|
|
||||||
float32 (*surfaceProps)[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
static void*
|
|
||||||
createBreakableModel(void *object, int32 offset, int32)
|
|
||||||
{
|
|
||||||
*PLUGINOFFSET(uint8*, object, offset) = 0;
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void*
|
|
||||||
destroyBreakableModel(void *object, int32 offset, int32)
|
|
||||||
{
|
|
||||||
uint8 *p = *PLUGINOFFSET(uint8*, object, offset);
|
|
||||||
delete[] p;
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
readBreakableModel(Stream *stream, int32, void *object, int32 o, int32)
|
|
||||||
{
|
|
||||||
uint32 header[13];
|
|
||||||
uint32 hasBreakable = stream->readU32();
|
|
||||||
if(hasBreakable == 0)
|
|
||||||
return;
|
|
||||||
stream->read(header, 13*4);
|
|
||||||
uint32 size = header[1]*(12+8+4) + header[5]*(6+2) +
|
|
||||||
header[8]*(32+32+12);
|
|
||||||
uint8 *p = new uint8[sizeof(Breakable)+size];
|
|
||||||
Breakable *breakable = (Breakable*)p;
|
|
||||||
*PLUGINOFFSET(Breakable*, object, o) = breakable;
|
|
||||||
breakable->position = header[0];
|
|
||||||
breakable->numVertices = header[1];
|
|
||||||
breakable->numFaces = header[5];
|
|
||||||
breakable->numMaterials = header[8];
|
|
||||||
p += sizeof(Breakable);
|
|
||||||
stream->read(p, size);
|
|
||||||
breakable->vertices = (float*)p;
|
|
||||||
p += breakable->numVertices*12;
|
|
||||||
breakable->texCoords = (float*)p;
|
|
||||||
p += breakable->numVertices*8;
|
|
||||||
breakable->colors = (uint8*)p;
|
|
||||||
p += breakable->numVertices*4;
|
|
||||||
breakable->faces = (uint16*)p;
|
|
||||||
p += breakable->numFaces*6;
|
|
||||||
breakable->matIDs = (uint16*)p;
|
|
||||||
p += breakable->numFaces*2;
|
|
||||||
breakable->texNames = (char(*)[32])p;
|
|
||||||
p += breakable->numMaterials*32;
|
|
||||||
breakable->maskNames = (char(*)[32])p;
|
|
||||||
p += breakable->numMaterials*32;
|
|
||||||
breakable->surfaceProps = (float32(*)[3])p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
writeBreakableModel(Stream *stream, int32, void *object, int32 o, int32)
|
|
||||||
{
|
|
||||||
uint32 header[13];
|
|
||||||
Breakable *breakable = *PLUGINOFFSET(Breakable*, object, o);
|
|
||||||
uint8 *p = (uint8*)breakable;
|
|
||||||
if(breakable == NULL){
|
|
||||||
stream->writeU32(0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
stream->writeU32(1);
|
|
||||||
memset((char*)header, 0, 13*4);
|
|
||||||
header[0] = breakable->position;
|
|
||||||
header[1] = breakable->numVertices;
|
|
||||||
header[5] = breakable->numFaces;
|
|
||||||
header[8] = breakable->numMaterials;
|
|
||||||
stream->write(header, 13*4);
|
|
||||||
p += sizeof(Breakable);
|
|
||||||
stream->write(p, breakable->numVertices*(12+8+4) +
|
|
||||||
breakable->numFaces*(6+2) +
|
|
||||||
breakable->numMaterials*(32+32+12));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32
|
|
||||||
getSizeBreakableModel(void *object, int32 offset, int32)
|
|
||||||
{
|
|
||||||
Breakable *breakable = *PLUGINOFFSET(Breakable*, object, offset);
|
|
||||||
if(breakable == NULL)
|
|
||||||
return 4;
|
|
||||||
return 56 + breakable->numVertices*(12+8+4) +
|
|
||||||
breakable->numFaces*(6+2) +
|
|
||||||
breakable->numMaterials*(32+32+12);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
registerBreakableModelPlugin(void)
|
|
||||||
{
|
|
||||||
Geometry::registerPlugin(sizeof(Breakable*), ID_BREAKABLE,
|
|
||||||
createBreakableModel,
|
|
||||||
destroyBreakableModel, NULL);
|
|
||||||
Geometry::registerPluginStream(ID_BREAKABLE,
|
|
||||||
(StreamRead)readBreakableModel,
|
|
||||||
(StreamWrite)writeBreakableModel,
|
|
||||||
(StreamGetSize)getSizeBreakableModel);
|
|
||||||
}
|
|
129
src/ps2.cpp
129
src/ps2.cpp
@ -53,6 +53,7 @@ ReadNativeData(Stream *stream, int32, void *object, int32, int32)
|
|||||||
assert(a % 0x10 == 0);
|
assert(a % 0x10 == 0);
|
||||||
#endif
|
#endif
|
||||||
stream->read(instance->data, instance->dataSize);
|
stream->read(instance->data, instance->dataSize);
|
||||||
|
// sizedebug(instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +95,7 @@ GetSizeNativeData(void *object, int32, int32)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
registerNativeDataPlugin(void)
|
RegisterNativeDataPlugin(void)
|
||||||
{
|
{
|
||||||
Geometry::registerPlugin(0, ID_NATIVEDATA,
|
Geometry::registerPlugin(0, ID_NATIVEDATA,
|
||||||
NULL, DestroyNativeData, NULL);
|
NULL, DestroyNativeData, NULL);
|
||||||
@ -180,5 +181,131 @@ unfixDmaOffsets(InstanceData *inst)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ADC
|
||||||
|
|
||||||
|
static void*
|
||||||
|
createADC(void *object, int32 offset, int32)
|
||||||
|
{
|
||||||
|
ADCData *adc = PLUGINOFFSET(ADCData, object, offset);
|
||||||
|
adc->adcFormatted = 0;
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
copyADC(void *dst, void *src, int32 offset, int32)
|
||||||
|
{
|
||||||
|
ADCData *dstadc = PLUGINOFFSET(ADCData, dst, offset);
|
||||||
|
ADCData *srcadc = PLUGINOFFSET(ADCData, src, offset);
|
||||||
|
dstadc->adcFormatted = srcadc->adcFormatted;
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
readADC(Stream *stream, int32, void *object, int32 offset, int32)
|
||||||
|
{
|
||||||
|
ADCData *adc = PLUGINOFFSET(ADCData, object, offset);
|
||||||
|
stream->seek(12);
|
||||||
|
uint32 x = stream->readU32();
|
||||||
|
assert(x == 0);
|
||||||
|
adc->adcFormatted = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
writeADC(Stream *stream, int32, void *, int32, int32)
|
||||||
|
{
|
||||||
|
WriteChunkHeader(stream, ID_ADC, 4);
|
||||||
|
stream->writeI32(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32
|
||||||
|
getSizeADC(void *object, int32 offset, int32)
|
||||||
|
{
|
||||||
|
ADCData *adc = PLUGINOFFSET(ADCData, object, offset);
|
||||||
|
return adc->adcFormatted ? 16 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RegisterADCPlugin(void)
|
||||||
|
{
|
||||||
|
Geometry::registerPlugin(sizeof(ADCData), ID_ADC,
|
||||||
|
createADC, NULL, copyADC);
|
||||||
|
Geometry::registerPluginStream(ID_ADC,
|
||||||
|
(StreamRead)readADC,
|
||||||
|
(StreamWrite)writeADC,
|
||||||
|
(StreamGetSize)getSizeADC);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// misc stuff
|
||||||
|
|
||||||
|
/* Function to specifically walk geometry chains */
|
||||||
|
void
|
||||||
|
walkDMA(InstanceData *inst, void (*f)(uint32 *data, int32 size))
|
||||||
|
{
|
||||||
|
if(inst->arePointersFixed == 2)
|
||||||
|
return;
|
||||||
|
uint32 *base = (uint32*)inst->data;
|
||||||
|
uint32 *tag = (uint32*)inst->data;
|
||||||
|
for(;;){
|
||||||
|
switch(tag[0]&0x70000000){
|
||||||
|
// DMAcnt
|
||||||
|
case 0x10000000:
|
||||||
|
f(tag+2, 2+(tag[0]&0xFFFF)*4);
|
||||||
|
tag += (1+(tag[0]&0xFFFF))*4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// DMAref
|
||||||
|
case 0x3000000:
|
||||||
|
f(base + tag[1]*4, (tag[0]&0xFFFF)*4);
|
||||||
|
tag += 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// DMAret
|
||||||
|
case 0x60000000:
|
||||||
|
f(tag+2, 2+(tag[0]&0xFFFF)*4);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sizedebug(InstanceData *inst)
|
||||||
|
{
|
||||||
|
if(inst->arePointersFixed == 2)
|
||||||
|
return;
|
||||||
|
uint32 *base = (uint32*)inst->data;
|
||||||
|
uint32 *tag = (uint32*)inst->data;
|
||||||
|
uint32 *last = NULL;
|
||||||
|
for(;;){
|
||||||
|
switch(tag[0]&0x70000000){
|
||||||
|
// DMAcnt
|
||||||
|
case 0x10000000:
|
||||||
|
tag += (1+(tag[0]&0xFFFF))*4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// DMAref
|
||||||
|
case 0x30000000:
|
||||||
|
last = base + tag[1]*4 + (tag[0]&0xFFFF)*4;
|
||||||
|
tag += 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// DMAret
|
||||||
|
case 0x60000000:
|
||||||
|
tag += (1+(tag[0]&0xFFFF))*4;
|
||||||
|
uint32 diff;
|
||||||
|
if(!last)
|
||||||
|
diff = (uint8*)tag - (uint8*)base;
|
||||||
|
else
|
||||||
|
diff = (uint8*)last - (uint8*)base;
|
||||||
|
printf("%x %x %x\n", inst->dataSize-diff, diff, inst->dataSize);
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("unkown DMAtag: %X %X\n", tag[0], tag[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,10 +104,8 @@ enum PluginID
|
|||||||
ID_RIGHTTORENDER = 0x1F,
|
ID_RIGHTTORENDER = 0x1F,
|
||||||
ID_UVANIMDICT = 0x2B,
|
ID_UVANIMDICT = 0x2B,
|
||||||
|
|
||||||
|
ID_ADC = 0x134,
|
||||||
ID_NATIVEDATA = 0x510,
|
ID_NATIVEDATA = 0x510,
|
||||||
|
|
||||||
ID_EXTRACOLORS = 0x253f2f9,
|
|
||||||
ID_BREAKABLE = 0x253f2fd
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int Version;
|
extern int Version;
|
||||||
|
@ -225,9 +225,7 @@ private:
|
|||||||
void frameListStreamWrite(Stream *stream, Frame **flp, int32 nf);
|
void frameListStreamWrite(Stream *stream, Frame **flp, int32 nf);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
void RegisterMeshPlugin(void);
|
||||||
|
void RegisterNativeDataPlugin(void);
|
||||||
|
|
||||||
void registerNodeNamePlugin(void);
|
}
|
||||||
void registerMeshPlugin(void);
|
|
||||||
void registerNativeDataPlugin(void);
|
|
||||||
void registerBreakableModelPlugin(void);
|
|
||||||
|
17
src/rwps2.h
17
src/rwps2.h
@ -23,11 +23,26 @@ void *DestroyNativeData(void *object, int32, int32);
|
|||||||
void ReadNativeData(Stream *stream, int32 len, void *object, int32, int32);
|
void ReadNativeData(Stream *stream, int32 len, void *object, int32, int32);
|
||||||
void WriteNativeData(Stream *stream, int32 len, void *object, int32, int32);
|
void WriteNativeData(Stream *stream, int32 len, void *object, int32, int32);
|
||||||
int32 GetSizeNativeData(void *object, int32, int32);
|
int32 GetSizeNativeData(void *object, int32, int32);
|
||||||
void registerNativeDataPlugin(void);
|
void RegisterNativeDataPlugin(void);
|
||||||
|
|
||||||
|
void walkDMA(InstanceData *inst, void (*f)(uint32 *data, int32 size));
|
||||||
|
void sizedebug(InstanceData *inst);
|
||||||
|
|
||||||
// only RW_PS2
|
// only RW_PS2
|
||||||
void fixDmaOffsets(InstanceData *inst);
|
void fixDmaOffsets(InstanceData *inst);
|
||||||
void unfixDmaOffsets(InstanceData *inst);
|
void unfixDmaOffsets(InstanceData *inst);
|
||||||
|
|
||||||
|
// ADC plugin
|
||||||
|
|
||||||
|
// The plugin is a little crippled due to lack of documentation
|
||||||
|
|
||||||
|
struct ADCData
|
||||||
|
{
|
||||||
|
// only information we can get from GTA DFFs :/
|
||||||
|
uint32 adcFormatted;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RegisterADCPlugin(void);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user