more error handling

This commit is contained in:
aap 2016-06-17 16:20:02 +02:00
parent 1bb17b3094
commit 634a96be07
21 changed files with 599 additions and 328 deletions

View File

@ -4,12 +4,13 @@
#include <cassert>
#include "rwbase.h"
#include "rwerror.h"
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwplugins.h"
using namespace std;
#define PLUGIN_ID 2 // ?
namespace rw {
@ -21,7 +22,7 @@ void
registerAnimInterpolatorInfo(AnimInterpolatorInfo *interpInfo)
{
for(int32 i = 0; i < MAXINTERPINFO; i++)
if(interpInfoList[i] == NULL){
if(interpInfoList[i] == nil){
interpInfoList[i] = interpInfo;
return;
}
@ -35,7 +36,7 @@ findAnimInterpolatorInfo(int32 id)
if(interpInfoList[i] && interpInfoList[i]->id == id)
return interpInfoList[i];
}
return NULL;
return nil;
}
Animation*
@ -65,7 +66,8 @@ Animation*
Animation::streamRead(Stream *stream)
{
Animation *anim;
assert(stream->readI32() == 0x100);
if(stream->readI32() != 0x100)
return nil;
int32 typeID = stream->readI32();
AnimInterpolatorInfo *interpInfo = findAnimInterpolatorInfo(typeID);
int32 numFrames = stream->readI32();
@ -156,7 +158,11 @@ UVAnimDictionary *currentUVAnimDictionary;
UVAnimDictionary*
UVAnimDictionary::create(void)
{
UVAnimDictionary *dict = (UVAnimDictionary*)malloc(sizeof(*dict));
UVAnimDictionary *dict = (UVAnimDictionary*)malloc(sizeof(UVAnimDictionary));
if(dict == nil){
RWERROR((ERR_ALLOC, sizeof(UVAnimDictionary)));
return nil;
}
dict->animations.init();
return dict;
}
@ -177,7 +183,6 @@ void
UVAnimDictionary::add(Animation *anim)
{
UVAnimDictEntry *de = new UVAnimDictEntry;
UVAnimCustomData *custom = (UVAnimCustomData*)anim->customData;
de->anim = anim;
this->animations.append(&de->inDict);
}
@ -185,14 +190,29 @@ UVAnimDictionary::add(Animation *anim)
UVAnimDictionary*
UVAnimDictionary::streamRead(Stream *stream)
{
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
UVAnimDictionary *dict = UVAnimDictionary::create();
if(dict == nil)
return nil;
int32 numAnims = stream->readI32();
Animation *anim;
for(int32 i = 0; i < numAnims; i++){
assert(findChunk(stream, ID_ANIMANIMATION, NULL, NULL));
dict->add(Animation::streamRead(stream));
if(!findChunk(stream, ID_ANIMANIMATION, nil, nil)){
RWERROR((ERR_CHUNK, "ANIMANIMATION"));
goto fail;
}
anim = Animation::streamRead(stream);
if(anim == nil)
goto fail;
dict->add(anim);
}
return dict;
fail:
dict->destroy();
return nil;
}
bool
@ -214,7 +234,6 @@ uint32
UVAnimDictionary::streamGetSize(void)
{
uint32 size = 12 + 4;
int32 numAnims = this->count();
FORLIST(lnk, this->animations){
UVAnimDictEntry *de = UVAnimDictEntry::fromDict(lnk);
size += 12 + de->anim->streamGetSize();
@ -231,7 +250,7 @@ UVAnimDictionary::find(const char *name)
if(strncmp_ci(custom->name, name, 32) == 0)
return anim;
}
return NULL;
return nil;
}
static void
@ -358,21 +377,24 @@ makeDummyAnimation(const char *name)
return anim;
}
static void
static Stream*
readUVAnim(Stream *stream, int32, void *object, int32 offset, int32)
{
UVAnim *uvanim = PLUGINOFFSET(UVAnim, object, offset);
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
char name[32];
uint32 mask = stream->readI32();
uint32 bit = 1;
for(int32 i = 0; i < 8; i++){
if(mask & bit){
stream->read(name, 32);
Animation *anim = NULL;
Animation *anim = nil;
if(currentUVAnimDictionary)
anim = currentUVAnimDictionary->find(name);
if(anim == NULL){
if(anim == nil){
anim = makeDummyAnimation(name);
if(currentUVAnimDictionary)
currentUVAnimDictionary->add(anim);
@ -384,9 +406,10 @@ readUVAnim(Stream *stream, int32, void *object, int32 offset, int32)
}
bit <<= 1;
}
return stream;
}
static void
static Stream*
writeUVAnim(Stream *stream, int32 size, void *object, int32 offset, int32)
{
UVAnim *uvanim = PLUGINOFFSET(UVAnim, object, offset);
@ -406,6 +429,7 @@ writeUVAnim(Stream *stream, int32 size, void *object, int32 offset, int32)
stream->write(custom->name, 32);
}
}
return stream;
}
static int32

View File

@ -6,3 +6,7 @@ ECODE(ERR_FILE,
"Couldn't open file %s")
ECODE(ERR_CHUNK,
"Couldn't find chunk %s")
ECODE(ERR_VERSION,
"Unsupported version %X")
ECODE(ERR_PLATFORM,
"Unsupported platform %d")

View File

@ -9,8 +9,6 @@
#include "rwobjects.h"
#include "rwengine.h"
using namespace std;
#define PLUGIN_ID 2
namespace rw {
@ -74,6 +72,8 @@ Clump::streamRead(Stream *stream)
uint32 length, version;
int32 buf[3];
Clump *clump;
int32 numGeometries;
Geometry **geometryList;
if(!findChunk(stream, ID_STRUCT, &length, &version)){
RWERROR((ERR_CHUNK, "STRUCT"));
@ -103,8 +103,8 @@ Clump::streamRead(Stream *stream)
clump->setFrame(frmlst.frames[0]);
// Geometry list
int32 numGeometries = 0;
Geometry **geometryList = nil;
numGeometries = 0;
geometryList = nil;
if(version >= 0x30400){
if(!findChunk(stream, ID_GEOMETRYLIST, nil, nil)){
RWERROR((ERR_CHUNK, "GEOMETRYLIST"));
@ -502,13 +502,14 @@ Atomic::defaultRenderCB(Atomic *atomic)
// Atomic Rights plugin
static void
static Stream*
readAtomicRights(Stream *stream, int32, void *, int32, int32)
{
stream->read(atomicRights, 8);
return stream;
}
static void
static Stream*
writeAtomicRights(Stream *stream, int32, void *object, int32, int32)
{
Atomic *atomic = (Atomic*)object;
@ -516,6 +517,7 @@ writeAtomicRights(Stream *stream, int32, void *object, int32, int32)
buffer[0] = atomic->pipeline->pluginID;
buffer[1] = atomic->pipeline->pluginData;
stream->write(buffer, 8);
return stream;
}
static int32

View File

@ -3,8 +3,6 @@
#include <cstring>
#include <cassert>
#include <new>
#include "rwbase.h"
#include "rwplg.h"
#include "rwpipeline.h"
@ -562,7 +560,6 @@ static void*
createNativeRaster(void *object, int32 offset, int32)
{
D3dRaster *raster = PLUGINOFFSET(D3dRaster, object, offset);
new (raster) D3dRaster;
raster->texture = NULL;
raster->palette = NULL;
raster->format = 0;

View File

@ -4,6 +4,7 @@
#include <cassert>
#include "rwbase.h"
#include "rwerror.h"
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
@ -11,7 +12,7 @@
#include "rwd3d.h"
#include "rwd3d8.h"
using namespace std;
#define PLUGIN_ID 2
namespace rw {
namespace d3d8 {
@ -51,11 +52,12 @@ void*
destroyNativeData(void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
assert(geometry->instData != NULL);
assert(geometry->instData->platform == PLATFORM_D3D8);
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_D3D8)
return object;
InstanceDataHeader *header =
(InstanceDataHeader*)geometry->instData;
geometry->instData = NULL;
geometry->instData = nil;
InstanceData *inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
deleteObject(inst->indexBuffer);
@ -67,13 +69,20 @@ destroyNativeData(void *object, int32, int32)
return object;
}
void
Stream*
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_D3D8);
uint32 platform;
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"))
return nil;
}
platform = stream->readU32();
if(platform != PLATFORM_D3D8){
RWERROR((ERR_PLATFORM, platform));
return nil;
}
InstanceDataHeader *header = new InstanceDataHeader;
geometry->instData = header;
header->platform = PLATFORM_D3D8;
@ -96,8 +105,8 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
inst->material = geometry->materialList[matid];
inst->vertexShader = *(uint32*)p; p += 4;
inst->primType = *(uint32*)p; p += 4;
inst->indexBuffer = NULL; p += 4;
inst->vertexBuffer = NULL; p += 4;
inst->indexBuffer = nil; p += 4;
inst->vertexBuffer = nil; p += 4;
inst->baseIndex = 0; p += 4;
inst->vertexAlpha = *p++;
inst->managed = 0; p++;
@ -121,15 +130,17 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
inst++;
}
return stream;
}
void
Stream*
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_D3D8);
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_D3D8)
return stream;
stream->writeU32(PLATFORM_D3D8);
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
@ -172,14 +183,16 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
unlockVertices(inst->vertexBuffer);
inst++;
}
return stream;
}
int32
getSizeNativeData(void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
assert(geometry->instData != NULL);
assert(geometry->instData->platform == PLATFORM_D3D8);
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_D3D8)
return 0;
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
InstanceData *inst = header->inst;
@ -195,7 +208,7 @@ void
registerNativeDataPlugin(void)
{
Geometry::registerPlugin(0, ID_NATIVEDATA,
NULL, destroyNativeData, NULL);
nil, destroyNativeData, nil);
Geometry::registerPluginStream(ID_NATIVEDATA,
readNativeData,
writeNativeData,
@ -229,7 +242,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
inst->material = mesh->material;
inst->vertexShader = 0;
inst->primType = meshh->flags == 1 ? D3DPT_TRIANGLESTRIP : D3DPT_TRIANGLELIST;
inst->vertexBuffer = NULL;
inst->vertexBuffer = nil;
inst->baseIndex = 0; // (maybe) not used by us
inst->vertexAlpha = 0;
inst->managed = 0;
@ -257,7 +270,7 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
Geometry *geo = atomic->geometry;
if((geo->geoflags & Geometry::NATIVE) == 0)
return;
assert(geo->instData != NULL);
assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_D3D8);
geo->geoflags &= ~Geometry::NATIVE;
geo->allocateData();
@ -290,7 +303,7 @@ render(rw::ObjPipeline *rwpipe, Atomic *atomic)
Geometry *geo = atomic->geometry;
if((geo->geoflags & Geometry::NATIVE) == 0)
pipe->instance(atomic);
assert(geo->instData != NULL);
assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_D3D8);
if(pipe->renderCB)
pipe->renderCB(atomic, (InstanceDataHeader*)geo->instData);
@ -302,9 +315,9 @@ ObjPipeline::ObjPipeline(uint32 platform)
this->impl.instance = d3d8::instance;
this->impl.uninstance = d3d8::uninstance;
this->impl.render = d3d8::render;
this->instanceCB = NULL;
this->uninstanceCB = NULL;
this->renderCB = NULL;
this->instanceCB = nil;
this->uninstanceCB = nil;
this->renderCB = nil;
}
void
@ -463,9 +476,19 @@ readAsImage(Stream *stream, int32 width, int32 height, int32 depth, int32 format
Texture*
readNativeTexture(Stream *stream)
{
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
assert(stream->readU32() == PLATFORM_D3D8);
Texture *tex = Texture::create(NULL);
uint32 platform;
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"))
return nil;
}
platform = stream->readU32();
if(platform != PLATFORM_D3D8){
RWERROR((ERR_PLATFORM, platform));
return nil;
}
Texture *tex = Texture::create(nil);
if(tex == nil)
return nil;
// Texture
tex->filterAddressing = stream->readU32();

View File

@ -4,6 +4,7 @@
#include <cassert>
#include "rwbase.h"
#include "rwerror.h"
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
@ -11,6 +12,8 @@
#include "rwd3d.h"
#include "rwd3d9.h"
#define PLUGIN_ID 2
namespace rw {
namespace d3d9 {
using namespace d3d;
@ -70,11 +73,12 @@ void*
destroyNativeData(void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
assert(geometry->instData != NULL);
assert(geometry->instData->platform == PLATFORM_D3D9);
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_D3D9)
return object;
InstanceDataHeader *header =
(InstanceDataHeader*)geometry->instData;
geometry->instData = NULL;
geometry->instData = nil;
deleteObject(header->vertexDeclaration);
deleteObject(header->indexBuffer);
deleteObject(header->vertexStream[0].vertexBuffer);
@ -84,13 +88,20 @@ destroyNativeData(void *object, int32, int32)
return object;
}
void
Stream*
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_D3D9);
uint32 platform;
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"))
return nil;
}
platform = stream->readU32();
if(platform != PLATFORM_D3D9){
RWERROR((ERR_PLATFORM, platform));
return nil;
}
InstanceDataHeader *header = new InstanceDataHeader;
geometry->instData = header;
header->platform = PLATFORM_D3D9;
@ -101,11 +112,11 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
uint8 *p = data;
header->serialNumber = *(uint32*)p; p += 4;
header->numMeshes = *(uint32*)p; p += 4;
header->indexBuffer = NULL; p += 4;
header->indexBuffer = nil; p += 4;
header->primType = *(uint32*)p; p += 4;
p += 16*2; // skip vertex streams, they're repeated with the vertex buffers
header->useOffsets = *(bool32*)p; p += 4;
header->vertexDeclaration = NULL; p += 4;
header->vertexDeclaration = nil; p += 4;
header->totalNumIndex = *(uint32*)p; p += 4;
header->totalNumVertex = *(uint32*)p; p += 4;
header->inst = new InstanceData[header->numMeshes];
@ -117,7 +128,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
uint32 matid = *(uint32*)p; p += 4;
inst->material = geometry->materialList[matid];
inst->vertexAlpha = *(bool32*)p; p += 4;
inst->vertexShader = NULL; p += 4;
inst->vertexShader = nil; p += 4;
inst->baseIndex = 0; p += 4;
inst->numVertices = *(uint32*)p; p += 4;
inst->startIndex = *(uint32*)p; p += 4;
@ -147,7 +158,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
s->managed = *p++;
s->dynamicLock = *p++;
if(s->vertexBuffer == NULL)
if(s->vertexBuffer == nil)
continue;
// TODO: unset managed flag when using morph targets.
// also uses different buffer type and locks differently
@ -165,15 +176,17 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
}
delete[] data;
return stream;
}
void
Stream*
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_D3D9);
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_D3D9)
return stream;
stream->writeU32(PLATFORM_D3D9);
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
int32 size = 64 + geometry->meshHeader->numMeshes*36;
@ -228,7 +241,7 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
*p++ = s->dynamicLock;
stream->write(data, 16);
if(s->vertexBuffer == NULL)
if(s->vertexBuffer == nil)
continue;
uint8 *verts = lockVertices(s->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
stream->write(verts, s->stride*header->totalNumVertex);
@ -236,17 +249,19 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
}
delete[] data;
return stream;
}
int32
getSizeNativeData(void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
assert(geometry->instData != NULL);
assert(geometry->instData->platform == PLATFORM_D3D9);
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_D3D9)
return 0;
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
int32 size = 12 + 4 + 4 + 64 + header->numMeshes*36;
uint32 numElt = getDeclaration(header->vertexDeclaration, NULL);
uint32 numElt = getDeclaration(header->vertexDeclaration, nil);
size += 4 + numElt*8;
size += 2*header->totalNumIndex;
size += 0x10 + header->vertexStream[0].stride*header->totalNumVertex;
@ -258,7 +273,7 @@ void
registerNativeDataPlugin(void)
{
Geometry::registerPlugin(0, ID_NATIVEDATA,
NULL, destroyNativeData, NULL);
nil, destroyNativeData, nil);
Geometry::registerPluginStream(ID_NATIVEDATA,
readNativeData,
writeNativeData,
@ -298,7 +313,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
inst->numIndex = mesh->numIndices;
inst->material = mesh->material;
inst->vertexAlpha = 0;
inst->vertexShader = NULL;
inst->vertexShader = nil;
inst->baseIndex = inst->minVert;
inst->startIndex = startindex;
inst->numPrimitives = header->primType == D3DPT_TRIANGLESTRIP ? inst->numIndex-2 : inst->numIndex/3;
@ -325,7 +340,7 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
Geometry *geo = atomic->geometry;
if((geo->geoflags & Geometry::NATIVE) == 0)
return;
assert(geo->instData != NULL);
assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_D3D9);
geo->geoflags &= ~Geometry::NATIVE;
geo->allocateData();
@ -358,7 +373,7 @@ render(rw::ObjPipeline *rwpipe, Atomic *atomic)
Geometry *geo = atomic->geometry;
if((geo->geoflags & Geometry::NATIVE) == 0)
pipe->instance(atomic);
assert(geo->instData != NULL);
assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_D3D9);
if(pipe->renderCB)
pipe->renderCB(atomic, (InstanceDataHeader*)geo->instData);
@ -370,9 +385,9 @@ ObjPipeline::ObjPipeline(uint32 platform)
this->impl.instance = d3d9::instance;
this->impl.uninstance = d3d9::uninstance;
this->impl.render = d3d9::render;
this->instanceCB = NULL;
this->uninstanceCB = NULL;
this->renderCB = NULL;
this->instanceCB = nil;
this->uninstanceCB = nil;
this->renderCB = nil;
}
void
@ -571,9 +586,19 @@ makeMatFXPipeline(void)
Texture*
readNativeTexture(Stream *stream)
{
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
assert(stream->readU32() == PLATFORM_D3D9);
Texture *tex = Texture::create(NULL);
uint32 platform;
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"))
return nil;
}
platform = stream->readU32();
if(platform != PLATFORM_D3D9){
RWERROR((ERR_PLATFORM, platform));
return nil;
}
Texture *tex = Texture::create(nil);
if(tex == nil)
return nil;
// Texture
tex->filterAddressing = stream->readU32();

View File

@ -1,14 +1,11 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include "rwbase.h"
#include "rwerror.h"
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwengine.h"
#define PLUGIN_ID 0
@ -260,15 +257,15 @@ FrameList_::streamRead(Stream *stream)
return nil;
}
this->numFrames = stream->readI32();
Frame **frameList = (Frame**)malloc(this->numFrames*sizeof(Frame*));
if(frameList == nil){
this->frames = (Frame**)malloc(this->numFrames*sizeof(Frame*));
if(this->frames == nil){
RWERROR((ERR_ALLOC, this->numFrames*sizeof(Frame*)));
return nil;
}
for(int32 i = 0; i < this->numFrames; i++){
Frame *f;
stream->read(&buf, sizeof(buf));
frameList[i] = f = Frame::create();
this->frames[i] = f = Frame::create();
if(f == nil){
// TODO: clean up frames?
free(this->frames);
@ -284,10 +281,10 @@ FrameList_::streamRead(Stream *stream)
f->matrix.posw = 1.0f;
//f->matflag = buf.matflag;
if(buf.parent >= 0)
frameList[buf.parent]->addChild(f);
this->frames[buf.parent]->addChild(f);
}
for(int32 i = 0; i < this->numFrames; i++)
frameList[i]->streamReadPlugins(stream);
this->frames[i]->streamReadPlugins(stream);
return this;
}
@ -334,6 +331,7 @@ FrameList_::streamGetSize(Frame *f)
int32 numFrames = f->count();
uint32 size = 12 + 12 + 4 + numFrames*(sizeof(FrameStreamData)+12);
sizeCB(f, (void*)&size);
return size;
}
Frame**

View File

@ -12,8 +12,6 @@
#define PLUGIN_ID 2
using namespace std;
namespace rw {
Geometry*
@ -699,14 +697,15 @@ Material::streamGetSize(void)
// Material Rights plugin
static void
static Stream*
readMaterialRights(Stream *stream, int32, void *, int32, int32)
{
stream->read(materialRights, 8);
// printf("materialrights: %X %X\n", materialRights[0], materialRights[1]);
return stream;
}
static void
static Stream*
writeMaterialRights(Stream *stream, int32, void *object, int32, int32)
{
Material *material = (Material*)object;
@ -714,6 +713,7 @@ writeMaterialRights(Stream *stream, int32, void *object, int32, int32)
buffer[0] = material->pipeline->pluginID;
buffer[1] = material->pipeline->pluginData;
stream->write(buffer, 8);
return stream;
}
static int32
@ -721,7 +721,7 @@ getSizeMaterialRights(void *object, int32, int32)
{
Material *material = (Material*)object;
if(material->pipeline == nil || material->pipeline->pluginID == 0)
return -1;
return 0;
return 8;
}

View File

@ -4,6 +4,7 @@
#include <cassert>
#include "rwbase.h"
#include "rwerror.h"
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
@ -19,7 +20,7 @@
#define strdup _strdup
#endif
using namespace std;
#define PLUGIN_ID 0
namespace rw {
@ -33,7 +34,10 @@ TexDictionary*
TexDictionary::create(void)
{
TexDictionary *dict = (TexDictionary*)malloc(PluginBase::s_size);
assert(dict != NULL);
if(dict == nil){
RWERROR((ERR_ALLOC, PluginBase::s_size));
return nil;
}
dict->object.init(TexDictionary::ID, 0);
dict->textures.init();
dict->constructPlugins();
@ -57,24 +61,38 @@ TexDictionary::find(const char *name)
if(strncmp_ci(tex->name, name, 32) == 0)
return tex;
}
return NULL;
return nil;
}
TexDictionary*
TexDictionary::streamRead(Stream *stream)
{
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
int32 numTex = stream->readI16();
stream->readI16(); // some platform id (1 = d3d8, 2 = d3d9, 5 = opengl,
// 6 = ps2, 8 = xbox)
TexDictionary *txd = TexDictionary::create();
if(txd == nil)
return nil;
Texture *tex;
for(int32 i = 0; i < numTex; i++){
assert(findChunk(stream, ID_TEXTURENATIVE, NULL, NULL));
Texture *tex = Texture::streamReadNative(stream);
if(!findChunk(stream, ID_TEXTURENATIVE, nil, nil)){
RWERROR((ERR_CHUNK, "TEXTURENATIVE"));
goto fail;
}
tex = Texture::streamReadNative(stream);
if(tex == nil)
goto fail;
txd->add(tex);
}
txd->streamReadPlugins(stream);
if(txd->streamReadPlugins(stream))
return txd;
fail:
txd->destroy();
return nil;
}
void
@ -116,8 +134,11 @@ Texture*
Texture::create(Raster *raster)
{
Texture *tex = (Texture*)malloc(PluginBase::s_size);
assert(tex != NULL);
tex->dict = NULL;
if(tex == nil){
RWERROR((ERR_ALLOC, PluginBase::s_size));
return nil;
}
tex->dict = nil;
tex->inDict.init();
memset(tex->name, 0, 32);
memset(tex->mask, 0, 32);
@ -148,7 +169,7 @@ defaultFindCB(const char *name)
if(currentTexDictionary)
return currentTexDictionary->find(name);
// TODO: RW searches *all* TXDs otherwise
return NULL;
return nil;
}
static Texture*
@ -169,14 +190,14 @@ defaultReadCB(const char *name, const char *mask)
img->destroy();
return tex;
}else
return NULL;
return nil;
}
Texture*
Texture::read(const char *name, const char *mask)
{
(void)mask;
Raster *raster = NULL;
Raster *raster = nil;
Texture *tex;
if(tex = Texture::findCB(name)){
@ -185,11 +206,13 @@ Texture::read(const char *name, const char *mask)
}
if(loadTextures){
tex = Texture::readCB(name, mask);
if(tex == NULL)
if(tex == nil)
goto dummytex;
}else{
dummytex:
tex = Texture::create(NULL);
tex = Texture::create(nil);
if(tex == nil)
return nil;
strncpy(tex->name, name, 32);
if(mask)
strncpy(tex->mask, mask, 32);
@ -209,26 +232,38 @@ Texture::streamRead(Stream *stream)
{
uint32 length;
char name[128], mask[128];
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
uint32 filterAddressing = stream->readU32();
// TODO: if V addressing is 0, copy U
// if using mipmap filter mode, set automipmapping,
// if 0x10000 is set, set mipmapping
assert(findChunk(stream, ID_STRING, &length, NULL));
if(!findChunk(stream, ID_STRING, &length, nil)){
RWERROR((ERR_CHUNK, "STRING"));
return nil;
}
stream->read(name, length);
assert(findChunk(stream, ID_STRING, &length, NULL));
if(!findChunk(stream, ID_STRING, &length, nil)){
RWERROR((ERR_CHUNK, "STRING"));
return nil;
}
stream->read(mask, length);
Texture *tex = Texture::read(name, mask);
if(tex == nil)
return nil;
if(tex->refCount == 1)
tex->filterAddressing = filterAddressing;
tex->refCount++; // TODO: RW doesn't do this, why?
tex->streamReadPlugins(stream);
if(tex->streamReadPlugins(stream))
return tex;
tex->destroy();
return nil;
}
bool
@ -271,7 +306,10 @@ Texture::streamGetSize(void)
Texture*
Texture::streamReadNative(Stream *stream)
{
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
uint32 platform = stream->readU32();
stream->seek(-16);
if(platform == FOURCC_PS2)
@ -283,7 +321,7 @@ Texture::streamReadNative(Stream *stream)
if(platform == PLATFORM_XBOX)
return xbox::readNativeTexture(stream);
assert(0 && "unsupported platform");
return NULL;
return nil;
}
void
@ -323,15 +361,18 @@ Texture::streamGetSizeNative(void)
Image*
Image::create(int32 width, int32 height, int32 depth)
{
Image *img = (Image*)malloc(sizeof(*img));
assert(img != NULL);
Image *img = (Image*)malloc(sizeof(Image));
if(img == nil){
RWERROR((ERR_ALLOC, sizeof(Image)));
return nil;
}
img->flags = 0;
img->width = width;
img->height = height;
img->depth = depth;
img->stride = 0;
img->pixels = NULL;
img->palette = NULL;
img->pixels = nil;
img->palette = nil;
return img;
}
@ -345,12 +386,12 @@ Image::destroy(void)
void
Image::allocate(void)
{
if(this->pixels == NULL){
if(this->pixels == nil){
this->stride = this->width*(this->depth==4 ? 1 : this->depth/8);
this->pixels = new uint8[this->stride*this->height];
this->flags |= 1;
}
if(this->palette == NULL){
if(this->palette == nil){
if(this->depth == 4 || this->depth == 8)
this->palette = new uint8[(this->depth==4? 16 : 256)*4];
this->flags |= 2;
@ -401,7 +442,7 @@ Image::hasAlpha(void)
return ret != 0xFF;
}
static char *searchPaths = NULL;
static char *searchPaths = nil;
int numSearchPaths = 0;
void
@ -413,7 +454,7 @@ Image::setSearchPath(const char *path)
if(path)
searchPaths = p = strdup(path);
else{
searchPaths = NULL;
searchPaths = nil;
return;
}
while(p && *p){
@ -448,11 +489,14 @@ Image::getFilename(const char *name)
printf("found %s\n", name);
return strdup(name);
}
return NULL;
return nil;
}else
for(int i = 0; i < numSearchPaths; i++){
s = (char*)malloc(strlen(p)+len);
assert(s != NULL);
if(s == nil){
RWERROR((ERR_ALLOC, strlen(p)+len));
return nil;
}
strcpy(s, p);
strcat(s, name);
f = fopen(s, "r");
@ -464,7 +508,7 @@ Image::getFilename(const char *name)
::free(s);
p += strlen(p) + 1;
}
return NULL;
return nil;
}
//
@ -504,11 +548,11 @@ readTGA(const char *afilename)
char *filename;
int depth = 0, palDepth = 0;
filename = Image::getFilename(afilename);
if(filename == NULL)
return NULL;
if(filename == nil)
return nil;
uint32 length;
uint8 *data = getFileContents(filename, &length);
assert(data != NULL);
assert(data != nil);
free(filename);
StreamMemory file;
file.open(data, length);
@ -528,8 +572,8 @@ readTGA(const char *afilename)
image = Image::create(header.width, header.height, depth);
image->allocate();
uint8 *palette = header.colorMapType ? image->palette : NULL;
uint8 (*color)[4] = NULL;
uint8 *palette = header.colorMapType ? image->palette : nil;
uint8 (*color)[4] = nil;
if(palette){
int maxlen = depth == 4 ? 16 : 256;
color = (uint8(*)[4])palette;
@ -579,10 +623,13 @@ writeTGA(Image *image, const char *filename)
{
TGAHeader header;
StreamFile file;
assert(file.open(filename, "wb"));
if(!file.open(filename, "wb")){
RWERROR((ERR_FILE, filename));
return;
}
header.IDlen = 0;
header.imageType = image->palette != NULL ? 1 : 2;
header.colorMapType = image->palette != NULL;
header.imageType = image->palette != nil ? 1 : 2;
header.colorMapType = image->palette != nil;
header.colorMapOrigin = 0;
header.colorMapLength = image->depth == 4 ? 16 :
image->depth == 8 ? 256 : 0;
@ -596,7 +643,7 @@ writeTGA(Image *image, const char *filename)
file.write(&header, sizeof(header));
uint8 *pixels = image->pixels;
uint8 *palette = header.colorMapType ? image->palette : NULL;
uint8 *palette = header.colorMapType ? image->palette : nil;
uint8 (*color)[4] = (uint8(*)[4])palette;;
if(palette)
for(int i = 0; i < header.colorMapLength; i++){
@ -633,7 +680,7 @@ Raster*
Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platform)
{
Raster *raster = (Raster*)malloc(PluginBase::s_size);
assert(raster != NULL);
assert(raster != nil);
raster->platform = platform ? platform : rw::platform;
raster->type = format & 0x7;
raster->flags = format & 0xF8;
@ -641,7 +688,7 @@ Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platf
raster->width = width;
raster->height = height;
raster->depth = depth;
raster->texels = raster->palette = NULL;
raster->texels = raster->palette = nil;
raster->constructPlugins();
engine[raster->platform].rasterCreate(raster);

View File

@ -4,6 +4,7 @@
#include <cassert>
#include "rwbase.h"
#include "rwerror.h"
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
@ -15,7 +16,7 @@
#include "rwd3d9.h"
#include "rwwdgl.h"
using namespace std;
#define PLUGIN_ID 2
namespace rw {
@ -151,7 +152,7 @@ copyHAnim(void *dst, void *src, int32 offset, int32)
return dst;
}
static void
static Stream*
readHAnim(Stream *stream, int32, void *object, int32 offset, int32)
{
int32 ver, numNodes;
@ -176,9 +177,10 @@ readHAnim(Stream *stream, int32, void *object, int32 offset, int32)
delete[] nodeFlags;
delete[] nodeIDs;
}
return stream;
}
static void
static Stream*
writeHAnim(Stream *stream, int32, void *object, int32 offset, int32)
{
HAnimData *hanim = PLUGINOFFSET(HAnimData, object, offset);
@ -186,7 +188,7 @@ writeHAnim(Stream *stream, int32, void *object, int32 offset, int32)
stream->writeI32(hanim->id);
if(hanim->hierarchy == NULL){
stream->writeI32(0);
return;
return stream;
}
HAnimHierarchy *hier = hanim->hierarchy;
stream->writeI32(hier->numNodes);
@ -197,6 +199,7 @@ writeHAnim(Stream *stream, int32, void *object, int32 offset, int32)
stream->writeI32(hier->nodeInfo[i].index);
stream->writeI32(hier->nodeInfo[i].flags);
}
return stream;
}
static int32
@ -270,7 +273,7 @@ registerHAnimPlugin(void)
// Mesh
static void
static Stream*
readMesh(Stream *stream, int32 len, void *object, int32, int32)
{
Geometry *geo = (Geometry*)object;
@ -315,9 +318,10 @@ readMesh(Stream *stream, int32 len, void *object, int32, int32)
}
mesh++;
}
return stream;
}
static void
static Stream*
writeMesh(Stream *stream, int32, void *object, int32, int32)
{
Geometry *geo = (Geometry*)object;
@ -352,6 +356,7 @@ writeMesh(Stream *stream, int32, void *object, int32, int32)
}
mesh++;
}
return stream;
}
static int32
@ -418,7 +423,7 @@ destroyNativeData(void *object, int32 offset, int32 size)
return object;
}
static void
static Stream*
readNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
{
ChunkHeaderInfo header;
@ -433,13 +438,13 @@ readNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
platform = stream->readU32();
stream->seek(-16);
if(platform == PLATFORM_PS2)
ps2::readNativeData(stream, len, object, o, s);
return ps2::readNativeData(stream, len, object, o, s);
else if(platform == PLATFORM_XBOX)
xbox::readNativeData(stream, len, object, o, s);
return xbox::readNativeData(stream, len, object, o, s);
else if(platform == PLATFORM_D3D8)
d3d8::readNativeData(stream, len, object, o, s);
return d3d8::readNativeData(stream, len, object, o, s);
else if(platform == PLATFORM_D3D9)
d3d9::readNativeData(stream, len, object, o, s);
return d3d9::readNativeData(stream, len, object, o, s);
else{
fprintf(stderr, "unknown platform %d\n", platform);
stream->seek(len);
@ -448,24 +453,26 @@ readNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
stream->seek(-12);
wdgl::readNativeData(stream, len, object, o, s);
}
return stream;
}
static void
static Stream*
writeNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
{
Geometry *geometry = (Geometry*)object;
if(geometry->instData == NULL)
return;
return stream;
if(geometry->instData->platform == PLATFORM_PS2)
ps2::writeNativeData(stream, len, object, o, s);
return ps2::writeNativeData(stream, len, object, o, s);
else if(geometry->instData->platform == PLATFORM_WDGL)
wdgl::writeNativeData(stream, len, object, o, s);
return wdgl::writeNativeData(stream, len, object, o, s);
else if(geometry->instData->platform == PLATFORM_XBOX)
xbox::writeNativeData(stream, len, object, o, s);
return xbox::writeNativeData(stream, len, object, o, s);
else if(geometry->instData->platform == PLATFORM_D3D8)
d3d8::writeNativeData(stream, len, object, o, s);
return d3d8::writeNativeData(stream, len, object, o, s);
else if(geometry->instData->platform == PLATFORM_D3D9)
d3d9::writeNativeData(stream, len, object, o, s);
return d3d9::writeNativeData(stream, len, object, o, s);
return stream;
}
static int32
@ -473,7 +480,7 @@ getSizeNativeData(void *object, int32 offset, int32 size)
{
Geometry *geometry = (Geometry*)object;
if(geometry->instData == NULL)
return -1;
return 0;
if(geometry->instData->platform == PLATFORM_PS2)
return ps2::getSizeNativeData(object, offset, size);
else if(geometry->instData->platform == PLATFORM_WDGL)
@ -484,7 +491,7 @@ getSizeNativeData(void *object, int32 offset, int32 size)
return d3d8::getSizeNativeData(object, offset, size);
else if(geometry->instData->platform == PLATFORM_D3D9)
return d3d9::getSizeNativeData(object, offset, size);
return -1;
return 0;
}
void
@ -548,7 +555,7 @@ copySkin(void *dst, void *src, int32 offset, int32)
return dst;
}
static void
static Stream*
readSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
{
uint8 header[4];
@ -557,14 +564,15 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
if(geometry->instData){
// TODO: function pointers
if(geometry->instData->platform == PLATFORM_PS2)
ps2::readNativeSkin(stream, len, object, offset);
return ps2::readNativeSkin(stream, len, object, offset);
else if(geometry->instData->platform == PLATFORM_WDGL)
wdgl::readNativeSkin(stream, len, object, offset);
return wdgl::readNativeSkin(stream, len, object, offset);
else if(geometry->instData->platform == PLATFORM_XBOX)
xbox::readNativeSkin(stream, len, object, offset);
else
return xbox::readNativeSkin(stream, len, object, offset);
else{
assert(0 && "unsupported native skin platform");
return;
return nil;
}
}
stream->read(header, 4); // numBones, numUsedBones, numWeights, unused
@ -614,9 +622,10 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
// no split skins in GTA
if(!oldFormat)
stream->seek(12);
return stream;
}
static void
static Stream*
writeSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
{
uint8 header[4];
@ -629,9 +638,10 @@ writeSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
wdgl::writeNativeSkin(stream, len, object, offset);
else if(geometry->instData->platform == PLATFORM_XBOX)
xbox::writeNativeSkin(stream, len, object, offset);
else
else{
assert(0 && "unsupported native skin platform");
return;
return nil;
}
}
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
@ -662,6 +672,7 @@ writeSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
uint32 buffer[3] = { 0, 0, 0};
stream->write(buffer, 12);
}
return stream;
}
static int32
@ -835,17 +846,19 @@ copyAtomicMatFX(void *dst, void *src, int32 offset, int32)
return dst;
}
static void
readAtomicMatFX(Stream *stream, int32, void *object, int32 offset, int32)
static Stream*
readAtomicMatFX(Stream *stream, int32, void *object, int32, int32)
{
if(stream->readI32())
MatFX::enableEffects((Atomic*)object);
return stream;
}
static void
static Stream*
writeAtomicMatFX(Stream *stream, int32, void *object, int32 offset, int32)
{
stream->writeI32(*PLUGINOFFSET(int32, object, offset));
return stream;
}
static int32
@ -1036,7 +1049,7 @@ copyMaterialMatFX(void *dst, void *src, int32 offset, int32)
return dst;
}
static void
static Stream*
readMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
{
Texture *tex, *bumpedTex;
@ -1057,13 +1070,19 @@ readMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
coefficient = stream->readF32();
bumpedTex = tex = NULL;
if(stream->readI32()){
assert(findChunk(stream, ID_TEXTURE,
NULL, NULL));
if(!findChunk(stream, ID_TEXTURE,
NULL, NULL)){
RWERROR((ERR_CHUNK, "TEXTURE"));
return nil;
}
bumpedTex = Texture::streamRead(stream);
}
if(stream->readI32()){
assert(findChunk(stream, ID_TEXTURE,
NULL, NULL));
if(!findChunk(stream, ID_TEXTURE,
NULL, NULL)){
RWERROR((ERR_CHUNK, "TEXTURE"));
return nil;
}
tex = Texture::streamRead(stream);
}
idx = matfx->getEffectIndex(type);
@ -1078,8 +1097,11 @@ readMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
fbAlpha = stream->readI32();
tex = NULL;
if(stream->readI32()){
assert(findChunk(stream, ID_TEXTURE,
NULL, NULL));
if(!findChunk(stream, ID_TEXTURE,
NULL, NULL)){
RWERROR((ERR_CHUNK, "TEXTURE"));
return nil;
}
tex = Texture::streamRead(stream);
}
idx = matfx->getEffectIndex(type);
@ -1094,8 +1116,11 @@ readMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
dstBlend = stream->readI32();
tex = NULL;
if(stream->readI32()){
assert(findChunk(stream, ID_TEXTURE,
NULL, NULL));
if(!findChunk(stream, ID_TEXTURE,
NULL, NULL)){
RWERROR((ERR_CHUNK, "TEXTURE"));
return nil;
}
tex = Texture::streamRead(stream);
}
idx = matfx->getEffectIndex(type);
@ -1106,9 +1131,10 @@ readMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
break;
}
}
return stream;
}
static void
static Stream*
writeMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
{
MatFX *matfx = *PLUGINOFFSET(MatFX*, object, offset);
@ -1144,6 +1170,7 @@ writeMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
break;
}
}
return stream;
}
static int32

View File

@ -4,6 +4,7 @@
#include <cassert>
#include "rwbase.h"
#include "rwerror.h"
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
@ -12,6 +13,8 @@
#include "rwps2.h"
#include "rwps2plg.h"
#define PLUGIN_ID 2
namespace rw {
namespace ps2 {
@ -28,8 +31,9 @@ void*
destroyNativeData(void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
assert(geometry->instData != NULL);
assert(geometry->instData->platform == PLATFORM_PS2);
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_PS2)
return object;
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
for(uint32 i = 0; i < header->numMeshes; i++)
delete[] header->instanceMeshes[i].data;
@ -38,16 +42,24 @@ destroyNativeData(void *object, int32, int32)
return object;
}
void
Stream*
readNativeData(Stream *stream, int32, void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
assert(stream->readU32() == PLATFORM_PS2);
uint32 platform;
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"))
return nil;
}
platform = stream->readU32();
if(platform != PLATFORM_PS2){
RWERROR((ERR_PLATFORM, platform));
return nil;
}
InstanceDataHeader *header = new InstanceDataHeader;
geometry->instData = header;
header->platform = PLATFORM_PS2;
assert(geometry->meshHeader != NULL);
assert(geometry->meshHeader != nil);
header->numMeshes = geometry->meshHeader->numMeshes;
header->instanceMeshes = new InstanceData[header->numMeshes];
for(uint32 i = 0; i < header->numMeshes; i++){
@ -66,15 +78,17 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
instance->material = geometry->meshHeader->mesh[i].material;
// sizedebug(instance);
}
return stream;
}
void
Stream*
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);
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_PS2)
return stream;
stream->writeU32(PLATFORM_PS2);
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
for(uint32 i = 0; i < header->numMeshes; i++){
@ -87,6 +101,7 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
stream->write(buf, 8);
stream->write(instance->data, instance->dataSize);
}
return stream;
}
int32
@ -94,8 +109,9 @@ getSizeNativeData(void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
int32 size = 16;
assert(geometry->instData != NULL);
assert(geometry->instData->platform == PLATFORM_PS2);
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_PS2)
return 0;
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
for(uint32 i = 0; i < header->numMeshes; i++){
InstanceData *instance = &header->instanceMeshes[i];
@ -109,7 +125,7 @@ void
registerNativeDataPlugin(void)
{
Geometry::registerPlugin(0, ID_NATIVEDATA,
NULL, destroyNativeData, NULL);
nil, destroyNativeData, nil);
Geometry::registerPluginStream(ID_NATIVEDATA,
readNativeData,
writeNativeData,
@ -380,11 +396,11 @@ instanceNormal(uint32 *wp, Geometry *g, Mesh *m, uint32 idx, uint32 n)
}
MatPipeline::MatPipeline(uint32 platform)
: rw::Pipeline(platform), instanceCB(NULL), uninstanceCB(NULL),
preUninstCB(NULL), postUninstCB(NULL)
: rw::Pipeline(platform), instanceCB(nil), uninstanceCB(nil),
preUninstCB(nil), postUninstCB(nil)
{
for(int i = 0; i < 10; i++)
this->attribs[i] = NULL;
this->attribs[i] = nil;
}
void
@ -653,7 +669,7 @@ MatPipeline::collectData(Geometry *g, InstanceData *inst, Mesh *m, uint8 *data[]
InstMeshInfo im = getInstMeshInfo(this, g, m);
uint8 *raw = im.vertexSize*m->numIndices ?
new uint8[im.vertexSize*m->numIndices] : NULL;
new uint8[im.vertexSize*m->numIndices] : nil;
uint8 *dp = raw;
for(uint i = 0; i < nelem(this->attribs); i++)
if(a = this->attribs[i])
@ -706,7 +722,7 @@ objInstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
InstanceDataHeader *header = new InstanceDataHeader;
geo->instData = header;
header->platform = PLATFORM_PS2;
assert(geo->meshHeader != NULL);
assert(geo->meshHeader != nil);
header->numMeshes = geo->meshHeader->numMeshes;
header->instanceMeshes = new InstanceData[header->numMeshes];
for(uint32 i = 0; i < header->numMeshes; i++){
@ -717,7 +733,7 @@ objInstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
m = pipe->groupPipeline ?
pipe->groupPipeline :
(MatPipeline*)mesh->material->pipeline;
if(m == NULL)
if(m == nil)
m = defaultMatPipe;
m->instance(geo, instance, mesh);
instance->material = mesh->material;
@ -761,7 +777,7 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
Geometry *geo = atomic->geometry;
if((geo->geoflags & Geometry::NATIVE) == 0)
return;
assert(geo->instData != NULL);
assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_PS2);
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
// highest possible number of vertices
@ -778,7 +794,7 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
m = pipe->groupPipeline ?
pipe->groupPipeline :
(MatPipeline*)mesh->material->pipeline;
if(m == NULL) m = defaultMatPipe;
if(m == nil) m = defaultMatPipe;
if(m->preUninstCB) m->preUninstCB(m, geo);
}
geo->numVertices = 0;
@ -789,9 +805,9 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
m = pipe->groupPipeline ?
pipe->groupPipeline :
(MatPipeline*)mesh->material->pipeline;
if(m == NULL) m = defaultMatPipe;
if(m == nil) m = defaultMatPipe;
uint8 *data[nelem(m->attribs)] = { NULL };
uint8 *data[nelem(m->attribs)] = { nil };
uint8 *raw = m->collectData(geo, instance, mesh, data);
assert(m->uninstanceCB);
m->uninstanceCB(m, geo, flags, mesh, data);
@ -803,7 +819,7 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
m = pipe->groupPipeline ?
pipe->groupPipeline :
(MatPipeline*)mesh->material->pipeline;
if(m == NULL) m = defaultMatPipe;
if(m == nil) m = defaultMatPipe;
if(m->postUninstCB) m->postUninstCB(m, geo);
}
@ -811,7 +827,7 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
geo->generateTriangles(bits);
delete[] flags;
destroyNativeData(geo, 0, 0);
geo->instData = NULL;
geo->instData = nil;
/*
for(uint32 i = 0; i < header->numMeshes; i++){
Mesh *mesh = &geo->meshHeader->mesh[i];
@ -826,7 +842,7 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
ObjPipeline::ObjPipeline(uint32 platform)
: rw::ObjPipeline(platform)
{
this->groupPipeline = NULL;
this->groupPipeline = nil;
this->impl.instance = objInstance;
this->impl.uninstance = objUninstance;
}
@ -900,13 +916,13 @@ genericPreCB(MatPipeline *pipe, Geometry *geo)
void
genericUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[])
{
float32 *xyz = NULL, *xyzw = NULL;
float32 *uv = NULL, *uv2 = NULL;
uint8 *rgba = NULL;
int8 *normals = NULL;
uint32 *weights = NULL;
int8 *adc = NULL;
Skin *skin = NULL;
float32 *xyz = nil, *xyzw = nil;
float32 *uv = nil, *uv2 = nil;
uint8 *rgba = nil;
int8 *normals = nil;
uint32 *weights = nil;
int8 *adc = nil;
Skin *skin = nil;
if(skinGlobals.offset)
skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
@ -1031,7 +1047,7 @@ defaultUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh
ObjPipeline*
makeDefaultPipeline(void)
{
if(defaultMatPipe == NULL){
if(defaultMatPipe == nil){
MatPipeline *pipe = new MatPipeline(PLATFORM_PS2);
pipe->attribs[AT_XYZ] = &attribXYZ;
pipe->attribs[AT_UV] = &attribUV;
@ -1044,7 +1060,7 @@ makeDefaultPipeline(void)
defaultMatPipe = pipe;
}
if(defaultObjPipe == NULL){
if(defaultObjPipe == nil){
ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2);
defaultObjPipe = opipe;
}
@ -1101,14 +1117,21 @@ makeMatFXPipeline(void)
// Skin
void
Stream*
readNativeSkin(Stream *stream, int32, void *object, int32 offset)
{
uint8 header[4];
uint32 vers;
Geometry *geometry = (Geometry*)object;
assert(findChunk(stream, ID_STRUCT, NULL, &vers));
assert(stream->readU32() == PLATFORM_PS2);
uint32 platform;
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"))
return nil;
}
platform = stream->readU32();
if(platform != PLATFORM_PS2){
RWERROR((ERR_PLATFORM, platform));
return nil;
}
stream->read(header, 4);
Skin *skin = new Skin;
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
@ -1140,9 +1163,10 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
// last 3 ints are split data as in the other formats
// TODO: what are the other 4?
stream->seek(7*4);
return stream;
}
void
Stream*
writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
{
uint8 header[4];
@ -1170,13 +1194,14 @@ writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
uint32 buffer[7] = { 0, 0, 0, 0, 0, 0, 0 };
stream->write(buffer, 7*4);
}
return stream;
}
int32
getSizeNativeSkin(void *object, int32 offset)
{
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
if(skin == NULL)
if(skin == nil)
return -1;
int32 size = 12 + 4 + 4 + skin->numBones*64;
// not sure which version introduced the new format
@ -1206,7 +1231,7 @@ void
skinInstanceCB(MatPipeline *, Geometry *g, Mesh *m, uint8 **data)
{
Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
if(skin == NULL)
if(skin == nil)
return;
instanceSkinData(g, m, skin, (uint32*)data[4]);
}
@ -1216,8 +1241,8 @@ int32
findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, Vertex *v)
{
Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
float32 *wghts = NULL;
uint8 *inds = NULL;
float32 *wghts = nil;
uint8 *inds = nil;
if(skin){
wghts = skin->weights;
inds = skin->indices;
@ -1331,7 +1356,7 @@ void
skinPreCB(MatPipeline*, Geometry *geo)
{
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
if(skin == NULL)
if(skin == nil)
return;
uint8 *data = skin->data;
float *invMats = skin->inverseMatrices;
@ -1358,7 +1383,7 @@ int32 adcOffset;
int8*
getADCbits(Geometry *geo)
{
int8 *bits = NULL;
int8 *bits = nil;
if(adcOffset){
ADCData *adc = PLUGINOFFSET(ADCData, geo, adcOffset);
if(adc->adcFormatted)
@ -1371,8 +1396,8 @@ int8*
getADCbitsForMesh(Geometry *geo, Mesh *mesh)
{
int8 *bits = getADCbits(geo);
if(bits == NULL)
return NULL;
if(bits == nil)
return nil;
int32 n = mesh - geo->meshHeader->mesh;
for(int32 i = 0; i < n; i++)
bits += geo->meshHeader->mesh[i].numIndices;
@ -1430,7 +1455,7 @@ unconvertADC(Geometry *g)
g->meshHeader = h;
adc->adcFormatted = 0;
delete[] adc->adcBits;
adc->adcBits = NULL;
adc->adcBits = nil;
adc->numBits = 0;
}
@ -1477,24 +1502,28 @@ destroyADC(void *object, int32 offset, int32)
return object;
}
static void
static Stream*
readADC(Stream *stream, int32, void *object, int32 offset, int32)
{
ADCData *adc = PLUGINOFFSET(ADCData, object, offset);
assert(findChunk(stream, ID_ADC, NULL, NULL));
if(!findChunk(stream, ID_ADC, nil, nil)){
RWERROR((ERR_CHUNK, "ADC"));
return nil;
}
adc->numBits = stream->readI32();
adc->adcFormatted = 1;
if(adc->numBits == 0){
adc->adcBits = NULL;
adc->adcBits = nil;
adc->numBits = 0;
return;
return stream;
}
int32 size = adc->numBits+3 & ~3;
adc->adcBits = new int8[size];
stream->read(adc->adcBits, size);
return stream;
}
static void
static Stream*
writeADC(Stream *stream, int32 len, void *object, int32 offset, int32)
{
ADCData *adc = PLUGINOFFSET(ADCData, object, offset);
@ -1502,11 +1531,12 @@ writeADC(Stream *stream, int32 len, void *object, int32 offset, int32)
writeChunkHeader(stream, ID_ADC, len-12);
if(geometry->geoflags & Geometry::NATIVE){
stream->writeI32(0);
return;
return stream;
}
stream->writeI32(adc->numBits);
int32 size = adc->numBits+3 & ~3;
stream->write(adc->adcBits, size);
return stream;
}
static int32
@ -1564,7 +1594,7 @@ sizedebug(InstanceData *inst)
return;
uint32 *base = (uint32*)inst->data;
uint32 *tag = (uint32*)inst->data;
uint32 *last = NULL;
uint32 *last = nil;
for(;;){
switch(tag[0]&0x70000000){
case DMAcnt:

View File

@ -3,15 +3,16 @@
#include <cstring>
#include <cassert>
#include <new>
#include "rwbase.h"
#include "rwerror.h"
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwengine.h"
#include "rwps2.h"
#define PLUGIN_ID 0
#define max(a, b) ((a) > (b) ? (a) : (b))
namespace rw {
@ -385,7 +386,7 @@ rasterLock(Raster *raster, int32 level)
// TODO
(void)raster;
(void)level;
return NULL;
return nil;
}
static void
@ -400,7 +401,7 @@ static int32
rasterNumLevels(Raster *raster)
{
Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset);
if(raster->texels == NULL) return 0;
if(raster->texels == nil) return 0;
if(raster->format & Raster::MIPMAP)
return MAXLEVEL(ras)+1;
return 1;
@ -410,7 +411,6 @@ static void*
createNativeRaster(void *object, int32 offset, int32)
{
Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, object, offset);
new (raster) Ps2Raster;
raster->tex0[0] = 0;
raster->tex0[1] = 0;
raster->tex1[0] = 0;
@ -426,7 +426,7 @@ createNativeRaster(void *object, int32 offset, int32)
SETKL(raster, 0xFC0);
raster->dataSize = 0;
raster->data = NULL;
raster->data = nil;
return object;
}
@ -447,24 +447,27 @@ copyNativeRaster(void *dst, void *src, int32 offset, int32)
return dst;
}
static void
static Stream*
readMipmap(Stream *stream, int32, void *object, int32 offset, int32)
{
uint16 val = stream->readI32();
Texture *tex = (Texture*)object;
if(tex->raster == NULL)
return;
if(tex->raster == nil)
return stream;
Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, tex->raster, offset);
SETKL(raster, val);
return stream;
}
static void
static Stream*
writeMipmap(Stream *stream, int32, void *object, int32 offset, int32)
{
Texture *tex = (Texture*)object;
assert(tex->raster);
if(tex->raster)
return nil;
Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, tex->raster, offset);
stream->writeI32(raster->tex1[1]&0xFFFF);
return stream;
}
static int32
@ -487,7 +490,7 @@ registerNativeRaster(void)
engine[PLATFORM_PS2].rasterUnlock = rasterUnlock;
engine[PLATFORM_PS2].rasterNumLevels = rasterNumLevels;
Texture::registerPlugin(0, ID_SKYMIPMAP, NULL, NULL, NULL);
Texture::registerPlugin(0, ID_SKYMIPMAP, nil, nil, nil);
Texture::registerPluginStream(ID_SKYMIPMAP, readMipmap, writeMipmap, getSizeMipmap);
}
@ -512,24 +515,47 @@ Texture*
readNativeTexture(Stream *stream)
{
uint32 length, oldversion, version;
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
assert(stream->readU32() == 0x00325350); // 'PS2\0'
Texture *tex = Texture::create(NULL);
uint32 fourcc;
Raster *raster;
Ps2Raster *natras;
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
fourcc = stream->readU32();
if(fourcc != FOURCC_PS2){
RWERROR((ERR_PLATFORM, fourcc));
return nil;
}
Texture *tex = Texture::create(nil);
if(tex == nil)
return nil;
// Texture
tex->filterAddressing = stream->readU32();
assert(findChunk(stream, ID_STRING, &length, NULL));
if(!findChunk(stream, ID_STRING, &length, nil)){
RWERROR((ERR_CHUNK, "STRING"));
goto fail;
}
stream->read(tex->name, length);
assert(findChunk(stream, ID_STRING, &length, NULL));
if(!findChunk(stream, ID_STRING, &length, nil)){
RWERROR((ERR_CHUNK, "STRING"));
goto fail;
}
stream->read(tex->mask, length);
// Raster
StreamRasterExt streamExt;
oldversion = rw::version;
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
assert(findChunk(stream, ID_STRUCT, NULL, &version));
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
goto fail;
}
if(!findChunk(stream, ID_STRUCT, nil, &version)){
RWERROR((ERR_CHUNK, "STRUCT"));
goto fail;
}
stream->read(&streamExt, 0x40);
Raster *raster;
noNewStyleRasters = streamExt.type < 2;
rw::version = version;
raster = Raster::create(streamExt.width, streamExt.height,
@ -538,36 +564,43 @@ readNativeTexture(Stream *stream)
noNewStyleRasters = 0;
rw::version = oldversion;
tex->raster = raster;
Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset);
natras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset);
//printf("%08X%08X %08X%08X %08X%08X %08X%08X\n",
// ras->tex0[1], ras->tex0[0], ras->tex1[1], ras->tex1[0],
// ras->miptbp1[0], ras->miptbp1[1], ras->miptbp2[0], ras->miptbp2[1]);
ras->tex0[0] = streamExt.tex0[0];
ras->tex0[1] = streamExt.tex0[1];
ras->tex1[0] = streamExt.tex1[0];
ras->tex1[1] = ras->tex1[1]&~0xFF0000 | streamExt.tex1[1]<<16 & 0xFF0000;
ras->miptbp1[0] = streamExt.miptbp1[0];
ras->miptbp1[1] = streamExt.miptbp1[1];
ras->miptbp2[0] = streamExt.miptbp2[0];
ras->miptbp2[1] = streamExt.miptbp2[1];
ras->texelSize = streamExt.texelSize;
ras->paletteSize = streamExt.paletteSize;
ras->gsSize = streamExt.gsSize;
SETKL(ras, streamExt.mipmapVal);
natras->tex0[0] = streamExt.tex0[0];
natras->tex0[1] = streamExt.tex0[1];
natras->tex1[0] = streamExt.tex1[0];
natras->tex1[1] = natras->tex1[1]&~0xFF0000 |
streamExt.tex1[1]<<16 & 0xFF0000;
natras->miptbp1[0] = streamExt.miptbp1[0];
natras->miptbp1[1] = streamExt.miptbp1[1];
natras->miptbp2[0] = streamExt.miptbp2[0];
natras->miptbp2[1] = streamExt.miptbp2[1];
natras->texelSize = streamExt.texelSize;
natras->paletteSize = streamExt.paletteSize;
natras->gsSize = streamExt.gsSize;
SETKL(natras, streamExt.mipmapVal);
//printf("%08X%08X %08X%08X %08X%08X %08X%08X\n",
// ras->tex0[1], ras->tex0[0], ras->tex1[1], ras->tex1[0],
// ras->miptbp1[0], ras->miptbp1[1], ras->miptbp2[0], ras->miptbp2[1]);
assert(findChunk(stream, ID_STRUCT, &length, NULL));
if(!findChunk(stream, ID_STRING, &length, nil)){
RWERROR((ERR_CHUNK, "STRING"));
goto fail;
}
if(streamExt.type < 2){
stream->read(raster->texels, length);
}else{
stream->read(raster->texels-0x50, ras->texelSize);
stream->read(raster->palette-0x50, ras->paletteSize);
stream->read(raster->texels-0x50, natras->texelSize);
stream->read(raster->palette-0x50, natras->paletteSize);
}
tex->streamReadPlugins(stream);
if(tex->streamReadPlugins(stream))
return tex;
fail:
tex->destroy();
return nil;
}
void

View File

@ -32,8 +32,8 @@ uint32 makeFVFDeclaration(uint32 flags, int32 numTex);
int32 getStride(uint32 flags, int32 numTex);
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);
Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32);
Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
int32 getSizeNativeData(void *object, int32, int32);
void registerNativeDataPlugin(void);

View File

@ -55,8 +55,8 @@ void *createVertexDeclaration(VertexElement *elements);
uint32 getDeclaration(void *declaration, VertexElement *elements);
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);
Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32);
Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
int32 getSizeNativeData(void *object, int32, int32);
void registerNativeDataPlugin(void);

View File

@ -6,8 +6,8 @@ namespace rw {
typedef void *(*Constructor)(void *object, int32 offset, int32 size);
typedef void *(*Destructor)(void *object, int32 offset, int32 size);
typedef void *(*CopyConstructor)(void *dst, void *src, int32 offset, int32 size);
typedef void (*StreamRead)(Stream *stream, int32 length, void *object, int32 offset, int32 size);
typedef void (*StreamWrite)(Stream *stream, int32 length, void *object, int32 offset, int32 size);
typedef Stream *(*StreamRead)(Stream *stream, int32 length, void *object, int32 offset, int32 size);
typedef Stream *(*StreamWrite)(Stream *stream, int32 length, void *object, int32 offset, int32 size);
typedef int32 (*StreamGetSize)(void *object, int32 offset, int32 size);
typedef void (*RightsCallback)(void *object, int32 offset, int32 size, uint32 data);

View File

@ -49,8 +49,8 @@ enum PS2AttibTypes {
};
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);
Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32);
Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
int32 getSizeNativeData(void *object, int32, int32);
void registerNativeDataPlugin(void);

View File

@ -9,8 +9,8 @@ ObjPipeline *makeMatFXPipeline(void);
void insertVertexSkin(Geometry *geo, int32 i, uint32 mask, Vertex *v);
int32 findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, Vertex *v);
void readNativeSkin(Stream *stream, int32, void *object, int32 offset);
void writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
Stream *readNativeSkin(Stream *stream, int32, void *object, int32 offset);
Stream *writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
int32 getSizeNativeSkin(void *object, int32 offset);
void instanceSkinData(Geometry *g, Mesh *m, Skin *skin, uint32 *data);

View File

@ -1,3 +1,4 @@
namespace rw {
namespace wdgl {
@ -38,8 +39,8 @@ void packattrib(uint8 *dst, float32 *src, AttribDesc *a, float32 scale);
void unpackattrib(float *dst, uint8 *src, AttribDesc *a, float32 scale);
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);
Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32);
Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
int32 getSizeNativeData(void *object, int32, int32);
void registerNativeDataPlugin(void);
@ -59,8 +60,8 @@ ObjPipeline *makeDefaultPipeline(void);
// Skin plugin
void readNativeSkin(Stream *stream, int32, void *object, int32 offset);
void writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
Stream *readNativeSkin(Stream *stream, int32, void *object, int32 offset);
Stream *writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
int32 getSizeNativeSkin(void *object, int32 offset);
ObjPipeline *makeSkinPipeline(void);

View File

@ -30,8 +30,8 @@ struct InstanceDataHeader : rw::InstanceDataHeader
};
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);
Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32);
Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
int32 getSizeNativeData(void *object, int32, int32);
void registerNativeDataPlugin(void);
@ -48,8 +48,8 @@ ObjPipeline *makeDefaultPipeline(void);
// Skin plugin
void readNativeSkin(Stream *stream, int32, void *object, int32 offset);
void writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
Stream *readNativeSkin(Stream *stream, int32, void *object, int32 offset);
Stream *writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
int32 getSizeNativeSkin(void *object, int32 offset);
ObjPipeline *makeSkinPipeline(void);

View File

@ -4,6 +4,7 @@
#include <cassert>
#include "rwbase.h"
#include "rwerror.h"
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
@ -15,7 +16,7 @@
#include <GL/glew.h>
#endif
using namespace std;
#define PLUGIN_ID 2
namespace rw {
namespace wdgl {
@ -217,7 +218,9 @@ void*
destroyNativeData(void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
assert(geometry->instData->platform == PLATFORM_WDGL);
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_WDGL)
return object;
InstanceDataHeader *header =
(InstanceDataHeader*)geometry->instData;
geometry->instData = NULL;
@ -228,7 +231,7 @@ destroyNativeData(void *object, int32, int32)
return object;
}
void
Stream*
readNativeData(Stream *stream, int32, void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
@ -244,24 +247,30 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
header->dataSize = header->attribs[0].stride*geometry->numVertices;
header->data = new uint8[header->dataSize];
stream->read(header->data, header->dataSize);
return stream;
}
void
Stream*
writeNativeData(Stream *stream, int32, void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
assert(geometry->instData->platform == PLATFORM_WDGL);
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_WDGL)
return stream;
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
stream->writeU32(header->numAttribs);
stream->write(header->attribs, header->numAttribs*sizeof(AttribDesc));
stream->write(header->data, header->dataSize);
return stream;
}
int32
getSizeNativeData(void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
assert(geometry->instData->platform == PLATFORM_WDGL);
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_WDGL)
return 0;
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
return 4 + header->numAttribs*sizeof(AttribDesc) + header->dataSize;
}
@ -511,22 +520,30 @@ makeDefaultPipeline(void)
// Skin
void
Stream*
readNativeSkin(Stream *stream, int32, void *object, int32 offset)
{
uint32 vers;
Geometry *geometry = (Geometry*)object;
assert(findChunk(stream, ID_STRUCT, NULL, &vers));
assert(stream->readU32() == PLATFORM_WDGL);
uint32 platform;
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
platform = stream->readU32();
if(platform != PLATFORM_GL){
RWERROR((ERR_PLATFORM, platform));
return nil;
}
Skin *skin = new Skin;
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
int32 numBones = stream->readI32();
skin->init(numBones, 0, 0);
stream->read(skin->inverseMatrices, skin->numBones*64);
return stream;
}
void
Stream*
writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
{
writeChunkHeader(stream, ID_STRUCT, len-12);
@ -534,6 +551,7 @@ writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
stream->writeI32(skin->numBones);
stream->write(skin->inverseMatrices, skin->numBones*64);
return stream;
}
int32

View File

@ -3,9 +3,8 @@
#include <cstring>
#include <cassert>
#include <new>
#include "rwbase.h"
#include "rwerror.h"
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
@ -13,7 +12,7 @@
#include "rwplugins.h"
#include "rwxbox.h"
using namespace std;
#define PLUGIN_ID 2
namespace rw {
namespace xbox {
@ -28,8 +27,9 @@ void*
destroyNativeData(void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
assert(geometry->instData != NULL);
assert(geometry->instData->platform == PLATFORM_XBOX);
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_XBOX)
return object;
InstanceDataHeader *header =
(InstanceDataHeader*)geometry->instData;
geometry->instData = NULL;
@ -40,14 +40,25 @@ destroyNativeData(void *object, int32, int32)
return object;
}
void
Stream*
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");
uint32 platform;
if(!findChunk(stream, ID_STRUCT, nil, &vers)){
RWERROR((ERR_CHUNK, "STRUCT"))
return nil;
}
platform = stream->readU32();
if(platform != PLATFORM_XBOX){
RWERROR((ERR_PLATFORM, platform));
return nil;
}
if(vers < 0x35000){
RWERROR((ERR_VERSION, vers));
return nil;
}
InstanceDataHeader *header = new InstanceDataHeader;
geometry->instData = header;
header->platform = PLATFORM_XBOX;
@ -86,15 +97,17 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
header->vertexBuffer = new uint8[header->stride*header->numVertices];
stream->read(header->vertexBuffer, header->stride*header->numVertices);
return stream;
}
void
Stream*
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);
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_XBOX)
return stream;
stream->writeU32(PLATFORM_XBOX);
assert(rw::version >= 0x35000 && "can't write native Xbox data < 0x35000");
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
@ -125,14 +138,16 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
stream->write(header->data+0x18, header->size);
stream->write(header->vertexBuffer, header->stride*header->numVertices);
return stream;
}
int32
getSizeNativeData(void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
assert(geometry->instData != NULL);
assert(geometry->instData->platform == PLATFORM_XBOX);
if(geometry->instData == nil ||
geometry->instData->platform != PLATFORM_XBOX)
return 0;
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
return 12 + 4 + header->size + header->stride*header->numVertices;
}
@ -347,14 +362,25 @@ struct NativeSkin
int32 stride;
};
void
Stream*
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);
uint32 vers, platform;
if(!findChunk(stream, ID_STRUCT, nil, &vers)){
RWERROR((ERR_CHUNK, "STRUCT"))
return nil;
}
platform = stream->readU32();
if(platform != PLATFORM_XBOX){
RWERROR((ERR_PLATFORM, platform));
return nil;
}
if(vers < 0x35000){
RWERROR((ERR_VERSION, vers));
return nil;
}
Skin *skin = new Skin;
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
@ -375,9 +401,10 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
// no split skins in GTA
stream->seek(12);
return stream;
}
void
Stream*
writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
{
Geometry *geometry = (Geometry*)object;
@ -400,6 +427,7 @@ writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
stream->write(skin->inverseMatrices, skin->numBones*64);
int32 buffer[3] = { 0, 0, 0};
stream->write(buffer, 12);
return stream;
}
int32
@ -604,18 +632,20 @@ copyVertexFmt(void *dst, void *src, int32 offset, int32)
return dst;
}
static void
static Stream*
readVertexFmt(Stream *stream, int32, void *object, int32 offset, int32)
{
uint32 fmt = stream->readU32();
*PLUGINOFFSET(uint32, object, offset) = fmt;
// TODO: ? create and attach "vertex shader"
return stream;
}
static void
static Stream*
writeVertexFmt(Stream *stream, int32, void *object, int32 offset, int32)
{
stream->writeI32(*PLUGINOFFSET(uint32, object, offset));
return stream;
}
static int32
@ -842,7 +872,6 @@ static void*
createNativeRaster(void *object, int32 offset, int32)
{
XboxRaster *raster = PLUGINOFFSET(XboxRaster, object, offset);
new (raster) XboxRaster;
raster->texture = NULL;
raster->palette = NULL;
raster->format = 0;
@ -888,11 +917,24 @@ registerNativeRaster(void)
Texture*
readNativeTexture(Stream *stream)
{
uint32 version;
assert(findChunk(stream, ID_STRUCT, NULL, &version));
assert(version >= 0x34001);
assert(stream->readU32() == PLATFORM_XBOX);
Texture *tex = Texture::create(NULL);
uint32 vers, platform;
if(!findChunk(stream, ID_STRUCT, nil, &vers)){
RWERROR((ERR_CHUNK, "STRUCT"))
return nil;
}
platform = stream->readU32();
if(platform != PLATFORM_XBOX){
RWERROR((ERR_PLATFORM, platform));
return nil;
}
if(version < 0x34001){
RWERROR((ERR_VERSION, version));
return nil;
}
Texture *tex = Texture::create(nil);
if(tex == nil)
return nil;
// Texture
tex->filterAddressing = stream->readU32();