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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,8 +6,8 @@ namespace rw {
typedef void *(*Constructor)(void *object, int32 offset, int32 size); typedef void *(*Constructor)(void *object, int32 offset, int32 size);
typedef void *(*Destructor)(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 *(*CopyConstructor)(void *dst, void *src, int32 offset, int32 size);
typedef void (*StreamRead)(Stream *stream, int32 length, void *object, int32 offset, int32 size); typedef Stream *(*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 *(*StreamWrite)(Stream *stream, int32 length, void *object, int32 offset, int32 size);
typedef int32 (*StreamGetSize)(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); 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 *destroyNativeData(void *object, int32, int32);
void readNativeData(Stream *stream, int32 len, void *object, int32, int32); Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32);
void writeNativeData(Stream *stream, int32 len, void *object, int32, int32); Stream *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);

View File

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

View File

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

View File

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

View File

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

View File

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