diff --git a/librw.vcxproj b/librw.vcxproj
index 8ddd113..191a9e4 100644
--- a/librw.vcxproj
+++ b/librw.vcxproj
@@ -188,6 +188,7 @@
+
@@ -195,15 +196,19 @@
+
+
+
-
+
+
@@ -211,13 +216,21 @@
+
+
-
+
+
+
+
+
+
+
diff --git a/src/camera.cpp b/src/camera.cpp
index e6e334e..2e8e7cc 100644
--- a/src/camera.cpp
+++ b/src/camera.cpp
@@ -15,9 +15,9 @@ Camera*
Camera::create(void)
{
Camera *cam = (Camera*)malloc(PluginBase::s_size);
- if(cam == NULL){
+ if(cam == nil){
RWERROR((ERR_ALLOC, PluginBase::s_size));
- return NULL;
+ return nil;
}
cam->object.object.init(Camera::ID, 0);
cam->viewWindow.set(1.0f, 1.0f);
@@ -26,7 +26,7 @@ Camera::create(void)
cam->farPlane = 10.0f;
cam->fogPlane = 5.0f;
cam->projection = Camera::PERSPECTIVE;
- cam->clump = NULL;
+ cam->clump = nil;
cam->inClump.init();
cam->constructPlugins();
return cam;
@@ -36,8 +36,8 @@ Camera*
Camera::clone(void)
{
Camera *cam = Camera::create();
- if(cam == NULL)
- return NULL;
+ if(cam == nil)
+ return nil;
cam->object.object.copy(&this->object.object);
cam->setFrame(this->getFrame());
cam->viewWindow = this->viewWindow;
@@ -72,9 +72,9 @@ Camera*
Camera::streamRead(Stream *stream)
{
CameraChunkData buf;
- if(!findChunk(stream, ID_STRUCT, NULL, NULL)){
+ if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
- return NULL;
+ return nil;
}
stream->read(&buf, sizeof(CameraChunkData));
Camera *cam = Camera::create();
@@ -84,9 +84,10 @@ Camera::streamRead(Stream *stream)
cam->farPlane = buf.farPlane;
cam->fogPlane = buf.fogPlane;
cam->projection = buf.projection;
- cam->streamReadPlugins(stream);
- return cam;
-
+ if(cam->streamReadPlugins(stream))
+ return cam;
+ cam->destroy();
+ return nil;
}
bool
diff --git a/src/clump.cpp b/src/clump.cpp
index 69eb51c..7ea41f9 100644
--- a/src/clump.cpp
+++ b/src/clump.cpp
@@ -1,5 +1,6 @@
#include
#include
+#include
#include "rwbase.h"
#include "rwerror.h"
@@ -78,9 +79,6 @@ Clump::streamRead(Stream *stream)
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
- clump = Clump::create();
- if(clump == nil)
- return nil;
stream->read(buf, length);
int32 numAtomics = buf[0];
int32 numLights = 0;
@@ -89,41 +87,51 @@ Clump::streamRead(Stream *stream)
numLights = buf[1];
numCameras = buf[2];
}
+ clump = Clump::create();
+ if(clump == nil)
+ return nil;
// Frame list
- Frame **frameList;
- int32 numFrames;
- clump->frameListStreamRead(stream, &frameList, &numFrames);
- clump->setFrame(frameList[0]);
+ FrameList_ frmlst;
+ frmlst.frames = nil;
+ if(!findChunk(stream, ID_FRAMELIST, nil, nil)){
+ RWERROR((ERR_CHUNK, "FRAMELIST"));
+ goto fail;
+ }
+ if(frmlst.streamRead(stream) == nil)
+ goto fail;
+ clump->setFrame(frmlst.frames[0]);
- Geometry **geometryList = 0;
+ // Geometry list
+ int32 numGeometries = 0;
+ Geometry **geometryList = nil;
if(version >= 0x30400){
- // Geometry list
- int32 numGeometries = 0;
if(!findChunk(stream, ID_GEOMETRYLIST, nil, nil)){
RWERROR((ERR_CHUNK, "GEOMETRYLIST"));
- // TODO: free
- return nil;
+ goto fail;
}
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
- // TODO: free
- return nil;
+ goto fail;
}
numGeometries = stream->readI32();
- if(numGeometries)
- geometryList = new Geometry*[numGeometries];
+ if(numGeometries){
+ size_t sz = numGeometries*sizeof(Geometry*);
+ geometryList = (Geometry**)malloc(sz);
+ if(geometryList == nil){
+ RWERROR((ERR_ALLOC, sz));
+ goto fail;
+ }
+ memset(geometryList, 0, sz);
+ }
for(int32 i = 0; i < numGeometries; i++){
if(!findChunk(stream, ID_GEOMETRY, nil, nil)){
RWERROR((ERR_CHUNK, "GEOMETRY"));
- // TODO: free
- return nil;
+ goto failgeo;
}
geometryList[i] = Geometry::streamRead(stream);
- if(geometryList[i] == nil){
- // TODO: free
- return nil;
- }
+ if(geometryList[i] == nil)
+ goto failgeo;
}
}
@@ -132,67 +140,70 @@ Clump::streamRead(Stream *stream)
for(int32 i = 0; i < numAtomics; i++){
if(!findChunk(stream, ID_ATOMIC, nil, nil)){
RWERROR((ERR_CHUNK, "ATOMIC"));
- // TODO: free
- return nil;
- }
- a = Atomic::streamReadClump(stream, frameList, geometryList);
- if(a == nil){
- // TODO: free
- return nil;
+ goto failgeo;
}
+ a = Atomic::streamReadClump(stream, &frmlst, geometryList);
+ if(a == nil)
+ goto failgeo;
clump->addAtomic(a);
}
// Lights
+ int32 frm;
+ Light *l;
for(int32 i = 0; i < numLights; i++){
- int32 frm;
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
- // TODO: free
- return nil;
+ goto failgeo;
}
frm = stream->readI32();
if(!findChunk(stream, ID_LIGHT, nil, nil)){
RWERROR((ERR_CHUNK, "LIGHT"));
- // TODO: free
- return nil;
+ goto failgeo;
}
- Light *l = Light::streamRead(stream);
- if(l == nil){
- // TODO: free
- return nil;
- }
- l->setFrame(frameList[frm]);
+ l = Light::streamRead(stream);
+ if(l == nil)
+ goto failgeo;
+ l->setFrame(frmlst.frames[frm]);
clump->addLight(l);
}
// Cameras
+ Camera *cam;
for(int32 i = 0; i < numCameras; i++){
- int32 frm;
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
- // TODO: free
- return nil;
+ goto failgeo;
}
frm = stream->readI32();
if(!findChunk(stream, ID_CAMERA, nil, nil)){
RWERROR((ERR_CHUNK, "CAMERA"));
- // TODO: free
- return nil;
+ goto failgeo;
}
- Camera *cam = Camera::streamRead(stream);
- if(cam == nil){
- // TODO: free
- return nil;
- }
- cam->setFrame(frameList[frm]);
+ cam = Camera::streamRead(stream);
+ if(cam == nil)
+ goto failgeo;
+ cam->setFrame(frmlst.frames[frm]);
clump->addCamera(cam);
}
- delete[] frameList;
+ for(int32 i = 0; i < numGeometries; i++)
+ if(geometryList[i])
+ geometryList[i]->destroy();
+ free(geometryList);
+ free(frmlst.frames);
+ if(clump->streamReadPlugins(stream))
+ return clump;
- clump->streamReadPlugins(stream);
- return clump;
+failgeo:
+ for(int32 i = 0; i < numGeometries; i++)
+ if(geometryList[i])
+ geometryList[i]->destroy();
+ free(geometryList);
+fail:
+ free(frmlst.frames);
+ clump->destroy();
+ return nil;
}
bool
@@ -208,10 +219,11 @@ Clump::streamWrite(Stream *stream)
writeChunkHeader(stream, ID_STRUCT, size);
stream->write(buf, size);
- int32 numFrames = this->getFrame()->count();
- Frame **flist = new Frame*[numFrames];
- makeFrameList(this->getFrame(), flist);
- this->frameListStreamWrite(stream, flist, numFrames);
+ FrameList_ frmlst;
+ frmlst.numFrames = this->getFrame()->count();
+ frmlst.frames = (Frame**)malloc(frmlst.numFrames*sizeof(Frame*));
+ makeFrameList(this->getFrame(), frmlst.frames);
+ frmlst.streamWrite(stream);
if(rw::version >= 0x30400){
size = 12+4;
@@ -225,11 +237,11 @@ Clump::streamWrite(Stream *stream)
}
FORLIST(lnk, this->atomics)
- Atomic::fromClump(lnk)->streamWriteClump(stream, flist, numFrames);
+ Atomic::fromClump(lnk)->streamWriteClump(stream, &frmlst);
FORLIST(lnk, this->lights){
Light *l = Light::fromClump(lnk);
- int frm = findPointer(l->getFrame(), (void**)flist, numFrames);
+ int frm = findPointer(l->getFrame(), (void**)frmlst.frames, frmlst.numFrames);
if(frm < 0)
return false;
writeChunkHeader(stream, ID_STRUCT, 4);
@@ -239,7 +251,7 @@ Clump::streamWrite(Stream *stream)
FORLIST(lnk, this->cameras){
Camera *c = Camera::fromClump(lnk);
- int frm = findPointer(c->getFrame(), (void**)flist, numFrames);
+ int frm = findPointer(c->getFrame(), (void**)frmlst.frames, frmlst.numFrames);
if(frm < 0)
return false;
writeChunkHeader(stream, ID_STRUCT, 4);
@@ -247,27 +259,12 @@ Clump::streamWrite(Stream *stream)
c->streamWrite(stream);
}
- delete[] flist;
+ free(frmlst.frames);
this->streamWritePlugins(stream);
return true;
}
-struct FrameStreamData
-{
- V3d right, up, at, pos;
- int32 parent;
- int32 matflag;
-};
-
-static Frame*
-sizeCB(Frame *f, void *size)
-{
- *(int32*)size += f->streamGetPluginSize();
- f->forAllChildren(sizeCB, size);
- return f;
-}
-
uint32
Clump::streamGetSize(void)
{
@@ -278,9 +275,7 @@ Clump::streamGetSize(void)
size += 8; // numLights, numCameras
// Frame list
- int32 numFrames = this->getFrame()->count();
- size += 12 + 12 + 4 + numFrames*(sizeof(FrameStreamData)+12);
- sizeCB(this->getFrame(), (void*)&size);
+ size += FrameList_::streamGetSize(this->getFrame());
if(rw::version >= 0x30400){
// Geometry list
@@ -316,73 +311,6 @@ Clump::render(void)
}
}
-bool
-Clump::frameListStreamRead(Stream *stream, Frame ***flp, int32 *nf)
-{
- FrameStreamData buf;
- int32 numFrames = 0;
- if(!findChunk(stream, ID_FRAMELIST, nil, nil)){
- RWERROR((ERR_CHUNK, "FRAMELIST"));
- return 0;
- }
- if(!findChunk(stream, ID_STRUCT, nil, nil)){
- RWERROR((ERR_CHUNK, "STRUCT"));
- return 0;
- }
- numFrames = stream->readI32();
- Frame **frameList = new Frame*[numFrames];
- for(int32 i = 0; i < numFrames; i++){
- Frame *f;
- frameList[i] = f = Frame::create();
- stream->read(&buf, sizeof(buf));
- f->matrix.right = buf.right;
- f->matrix.rightw = 0.0f;
- f->matrix.up = buf.up;
- f->matrix.upw = 0.0f;
- f->matrix.at = buf.at;
- f->matrix.atw = 0.0f;
- f->matrix.pos = buf.pos;
- f->matrix.posw = 1.0f;
- //f->matflag = buf.matflag;
- if(buf.parent >= 0)
- frameList[buf.parent]->addChild(f);
- }
- for(int32 i = 0; i < numFrames; i++)
- frameList[i]->streamReadPlugins(stream);
- *nf = numFrames;
- *flp = frameList;
- return 1;
-}
-
-void
-Clump::frameListStreamWrite(Stream *stream, Frame **frameList, int32 numFrames)
-{
- FrameStreamData buf;
-
- int size = 0, structsize = 0;
- structsize = 4 + numFrames*sizeof(FrameStreamData);
- size += 12 + structsize;
- for(int32 i = 0; i < numFrames; i++)
- size += 12 + frameList[i]->streamGetPluginSize();
-
- writeChunkHeader(stream, ID_FRAMELIST, size);
- writeChunkHeader(stream, ID_STRUCT, structsize);
- stream->writeU32(numFrames);
- for(int32 i = 0; i < numFrames; i++){
- Frame *f = frameList[i];
- buf.right = f->matrix.right;
- buf.up = f->matrix.up;
- buf.at = f->matrix.at;
- buf.pos = f->matrix.pos;
- buf.parent = findPointer(f->getParent(), (void**)frameList,
- numFrames);
- buf.matflag = 0; //f->matflag;
- stream->write(&buf, sizeof(buf));
- }
- for(int32 i = 0; i < numFrames; i++)
- frameList[i]->streamWritePlugins(stream);
-}
-
//
// Atomic
//
@@ -412,12 +340,12 @@ Atomic*
Atomic::clone()
{
Atomic *atomic = Atomic::create();
+ if(atomic == nil)
+ return nil;
atomic->object.object.copy(&this->object.object);
atomic->object.object.privateFlags |= 1;
- if(this->geometry){
- atomic->geometry = this->geometry;
- atomic->geometry->refCount++;
- }
+ if(this->geometry)
+ atomic->setGeometry(this->geometry);
atomic->pipeline = this->pipeline;
atomic->copyPlugins(this);
return atomic;
@@ -444,6 +372,17 @@ Atomic::removeFromClump(void)
}
}
+void
+Atomic::setGeometry(Geometry *geo)
+{
+ if(this->geometry)
+ this->geometry->destroy();
+ if(geo)
+ geo->refCount++;
+ this->geometry = geo;
+ // TODO: bounding stuff
+}
+
Sphere*
Atomic::getWorldBoundingSphere(void)
{
@@ -464,7 +403,7 @@ static uint32 atomicRights[2];
Atomic*
Atomic::streamReadClump(Stream *stream,
- Frame **frameList, Geometry **geometryList)
+ FrameList_ *frameList, Geometry **geometryList)
{
int32 buf[4];
uint32 version;
@@ -476,31 +415,36 @@ Atomic::streamReadClump(Stream *stream,
Atomic *atomic = Atomic::create();
if(atomic == nil)
return nil;
- atomic->setFrame(frameList[buf[0]]);
+ atomic->setFrame(frameList->frames[buf[0]]);
+ Geometry *g;
if(version < 0x30400){
if(!findChunk(stream, ID_GEOMETRY, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
- // TODO: free
- return nil;
- }
- atomic->geometry = Geometry::streamRead(stream);
- if(atomic->geometry == nil){
- // TODO: free
- return nil;
+ goto fail;
}
+ g = Geometry::streamRead(stream);
+ if(g == nil)
+ goto fail;
+ atomic->setGeometry(g);
+ g->destroy();
}else
- atomic->geometry = geometryList[buf[1]];
+ atomic->setGeometry(geometryList[buf[1]]);
atomic->object.object.flags = buf[2];
atomicRights[0] = 0;
- atomic->streamReadPlugins(stream);
+ if(!atomic->streamReadPlugins(stream))
+ goto fail;
if(atomicRights[0])
atomic->assertRights(atomicRights[0], atomicRights[1]);
return atomic;
+
+fail:
+ atomic->destroy();
+ return nil;
}
bool
-Atomic::streamWriteClump(Stream *stream, Frame **frameList, int32 numFrames)
+Atomic::streamWriteClump(Stream *stream, FrameList_ *frmlst)
{
int32 buf[4] = { 0, 0, 0, 0 };
Clump *c = this->clump;
@@ -508,7 +452,7 @@ Atomic::streamWriteClump(Stream *stream, Frame **frameList, int32 numFrames)
return false;
writeChunkHeader(stream, ID_ATOMIC, this->streamGetSize());
writeChunkHeader(stream, ID_STRUCT, rw::version < 0x30400 ? 12 : 16);
- buf[0] = findPointer(this->getFrame(), (void**)frameList, numFrames);
+ buf[0] = findPointer(this->getFrame(), (void**)frmlst->frames, frmlst->numFrames);
if(version < 0x30400){
buf[1] = this->object.object.flags;
@@ -579,7 +523,7 @@ getSizeAtomicRights(void *object, int32, int32)
{
Atomic *atomic = (Atomic*)object;
if(atomic->pipeline == nil || atomic->pipeline->pluginID == 0)
- return -1;
+ return 0;
return 8;
}
diff --git a/src/frame.cpp b/src/frame.cpp
index 5bfd50b..20c4005 100644
--- a/src/frame.cpp
+++ b/src/frame.cpp
@@ -1,7 +1,6 @@
#include
#include
#include
-#include
#include
#include "rwbase.h"
@@ -10,11 +9,6 @@
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwengine.h"
-#include "rwps2.h"
-#include "rwxbox.h"
-#include "rwd3d8.h"
-#include "rwd3d9.h"
-#include "rwwdgl.h"
#define PLUGIN_ID 0
@@ -248,6 +242,100 @@ Frame::purgeClone(void)
this->setHierarchyRoot(parent ? parent->root : this);
}
+struct FrameStreamData
+{
+ V3d right, up, at, pos;
+ int32 parent;
+ int32 matflag;
+};
+
+FrameList_*
+FrameList_::streamRead(Stream *stream)
+{
+ FrameStreamData buf;
+ this->numFrames = 0;
+ this->frames = nil;
+ if(!findChunk(stream, ID_STRUCT, nil, nil)){
+ RWERROR((ERR_CHUNK, "STRUCT"));
+ return nil;
+ }
+ this->numFrames = stream->readI32();
+ Frame **frameList = (Frame**)malloc(this->numFrames*sizeof(Frame*));
+ if(frameList == nil){
+ RWERROR((ERR_ALLOC, this->numFrames*sizeof(Frame*)));
+ return nil;
+ }
+ for(int32 i = 0; i < this->numFrames; i++){
+ Frame *f;
+ stream->read(&buf, sizeof(buf));
+ frameList[i] = f = Frame::create();
+ if(f == nil){
+ // TODO: clean up frames?
+ free(this->frames);
+ return nil;
+ }
+ f->matrix.right = buf.right;
+ f->matrix.rightw = 0.0f;
+ f->matrix.up = buf.up;
+ f->matrix.upw = 0.0f;
+ f->matrix.at = buf.at;
+ f->matrix.atw = 0.0f;
+ f->matrix.pos = buf.pos;
+ f->matrix.posw = 1.0f;
+ //f->matflag = buf.matflag;
+ if(buf.parent >= 0)
+ frameList[buf.parent]->addChild(f);
+ }
+ for(int32 i = 0; i < this->numFrames; i++)
+ frameList[i]->streamReadPlugins(stream);
+ return this;
+}
+
+void
+FrameList_::streamWrite(Stream *stream)
+{
+ FrameStreamData buf;
+
+ int size = 0, structsize = 0;
+ structsize = 4 + this->numFrames*sizeof(FrameStreamData);
+ size += 12 + structsize;
+ for(int32 i = 0; i < this->numFrames; i++)
+ size += 12 + this->frames[i]->streamGetPluginSize();
+
+ writeChunkHeader(stream, ID_FRAMELIST, size);
+ writeChunkHeader(stream, ID_STRUCT, structsize);
+ stream->writeU32(this->numFrames);
+ for(int32 i = 0; i < this->numFrames; i++){
+ Frame *f = this->frames[i];
+ buf.right = f->matrix.right;
+ buf.up = f->matrix.up;
+ buf.at = f->matrix.at;
+ buf.pos = f->matrix.pos;
+ buf.parent = findPointer(f->getParent(), (void**)this->frames,
+ this->numFrames);
+ buf.matflag = 0; //f->matflag;
+ stream->write(&buf, sizeof(buf));
+ }
+ for(int32 i = 0; i < this->numFrames; i++)
+ this->frames[i]->streamWritePlugins(stream);
+}
+
+static Frame*
+sizeCB(Frame *f, void *size)
+{
+ *(int32*)size += f->streamGetPluginSize();
+ f->forAllChildren(sizeCB, size);
+ return f;
+}
+
+uint32
+FrameList_::streamGetSize(Frame *f)
+{
+ int32 numFrames = f->count();
+ uint32 size = 12 + 12 + 4 + numFrames*(sizeof(FrameStreamData)+12);
+ sizeCB(f, (void*)&size);
+}
+
Frame**
makeFrameList(Frame *frame, Frame **flist)
{
diff --git a/src/geometry.cpp b/src/geometry.cpp
index e34237c..3482b88 100644
--- a/src/geometry.cpp
+++ b/src/geometry.cpp
@@ -87,7 +87,8 @@ Geometry::destroy(void)
delete[] this->morphTargets;
delete this->meshHeader;
for(int32 i = 0; i < this->numMaterials; i++)
- this->materialList[i]->destroy();
+ if(this->materialList[i])
+ this->materialList[i]->destroy();
delete[] this->materialList;
free(this);
}
@@ -149,29 +150,32 @@ Geometry::streamRead(Stream *stream)
if(!findChunk(stream, ID_MATLIST, nil, nil)){
RWERROR((ERR_CHUNK, "MATLIST"));
- // TODO: free
- return nil;
+ goto fail;
}
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
- // TODO: free
- return nil;
+ goto fail;
}
geo->numMaterials = stream->readI32();
geo->materialList = new Material*[geo->numMaterials];
- stream->seek(geo->numMaterials*4); // unused (-1)
+ stream->seek(geo->numMaterials*4); // material indices...but always -1
+ Material *m;
for(int32 i = 0; i < geo->numMaterials; i++){
if(!findChunk(stream, ID_MATERIAL, nil, nil)){
RWERROR((ERR_CHUNK, "MATERIAL"));
- // TODO: free
- return nil;
+ goto fail;
}
- geo->materialList[i] = Material::streamRead(stream);
+ m = Material::streamRead(stream);
+ if(m == nil)
+ goto fail;
+ geo->materialList[i] = m;
}
+ if(geo->streamReadPlugins(stream))
+ return geo;
- geo->streamReadPlugins(stream);
-
- return geo;
+fail:
+ geo->destroy();
+ return nil;
}
static uint32
@@ -562,10 +566,8 @@ Material::clone(void)
}
mat->color = this->color;
mat->surfaceProps = this->surfaceProps;
- if(this->texture){
- mat->texture = this->texture;
- mat->texture->refCount++;
- }
+ if(this->texture)
+ mat->setTexture(this->texture);
mat->pipeline = this->pipeline;
mat->copyPlugins(this);
return mat;
@@ -583,6 +585,16 @@ Material::destroy(void)
}
}
+void
+Material::setTexture(Texture *tex)
+{
+ if(this->texture)
+ this->texture->destroy();
+ if(tex)
+ tex->refCount++;
+ this->texture = tex;
+}
+
struct MatStreamData
{
int32 flags; // unused according to RW
@@ -622,21 +634,24 @@ Material::streamRead(Stream *stream)
if(buf.textured){
if(!findChunk(stream, ID_TEXTURE, &length, nil)){
RWERROR((ERR_CHUNK, "TEXTURE"));
- // TODO: free
- return nil;
- }
- mat->texture = Texture::streamRead(stream);
- if(mat->texture == nil){
- // TODO: fre
- return nil;
+ goto fail;
}
+ Texture *t = Texture::streamRead(stream);
+ if(t == nil)
+ goto fail;
+ mat->setTexture(t);
}
materialRights[0] = 0;
- mat->streamReadPlugins(stream);
+ if(!mat->streamReadPlugins(stream))
+ goto fail;
if(materialRights[0])
mat->assertRights(materialRights[0], materialRights[1]);
return mat;
+
+fail:
+ mat->destroy();
+ return nil;
}
bool
diff --git a/src/light.cpp b/src/light.cpp
index 10967bb..5013e7e 100644
--- a/src/light.cpp
+++ b/src/light.cpp
@@ -15,9 +15,9 @@ Light*
Light::create(int32 type)
{
Light *light = (Light*)malloc(PluginBase::s_size);
- if(light == NULL){
+ if(light == nil){
RWERROR((ERR_ALLOC, PluginBase::s_size));
- return NULL;
+ return nil;
}
light->object.object.init(Light::ID, type);
light->radius = 0.0f;
@@ -28,7 +28,7 @@ Light::create(int32 type)
light->minusCosAngle = 1.0f;
light->object.object.privateFlags = 1;
light->object.object.flags = LIGHTATOMICS | LIGHTWORLD;
- light->clump = NULL;
+ light->clump = nil;
light->inClump.init();
light->constructPlugins();
return light;
@@ -79,14 +79,14 @@ Light::streamRead(Stream *stream)
uint32 version;
LightChunkData buf;
- if(!findChunk(stream, ID_STRUCT, NULL, &version)){
+ if(!findChunk(stream, ID_STRUCT, nil, &version)){
RWERROR((ERR_CHUNK, "STRUCT"));
- return NULL;
+ return nil;
}
stream->read(&buf, sizeof(LightChunkData));
Light *light = Light::create(buf.type);
- if(light == NULL)
- return NULL;
+ if(light == nil)
+ return nil;
light->radius = buf.radius;
light->setColor(buf.red, buf.green, buf.blue);
float32 a = buf.minusCosAngle;
@@ -96,8 +96,10 @@ Light::streamRead(Stream *stream)
// tan -> -cos
light->minusCosAngle = -1.0f/sqrt(a*a+1.0f);
light->object.object.flags = (uint8)buf.flags;
- light->streamReadPlugins(stream);
- return light;
+ if(light->streamReadPlugins(stream))
+ return light;
+ light->destroy();
+ return nil;
}
bool
diff --git a/src/rwobjects.h b/src/rwobjects.h
index 78b8231..60d32b6 100644
--- a/src/rwobjects.h
+++ b/src/rwobjects.h
@@ -130,6 +130,15 @@ struct Frame : PluginBase
void purgeClone(void);
};
+struct FrameList_
+{
+ int32 numFrames;
+ Frame **frames;
+
+ FrameList_ *streamRead(Stream *stream);
+ void streamWrite(Stream *stream);
+ static uint32 streamGetSize(Frame *f);
+};
Frame **makeFrameList(Frame *frame, Frame **flist);
struct ObjectWithFrame
@@ -288,6 +297,7 @@ struct Material : PluginBase
static Material *create(void);
Material *clone(void);
void destroy(void);
+ void setTexture(Texture *tex);
static Material *streamRead(Stream *stream);
bool streamWrite(Stream *stream);
uint32 streamGetSize(void);
@@ -424,13 +434,13 @@ struct Atomic : PluginBase
static Atomic *fromClump(LLLink *lnk){
return LLLinkGetData(lnk, Atomic, inClump); }
void removeFromClump(void);
+ void setGeometry(Geometry *geo);
Sphere *getWorldBoundingSphere(void);
ObjPipeline *getPipeline(void);
void render(void) { this->renderCB(this); }
static Atomic *streamReadClump(Stream *stream,
- Frame **frameList, Geometry **geometryList);
- bool streamWriteClump(Stream *stream,
- Frame **frameList, int32 numframes);
+ FrameList_ *frameList, Geometry **geometryList);
+ bool streamWriteClump(Stream *stream, FrameList_ *frmlst);
uint32 streamGetSize(void);
static void defaultRenderCB(Atomic *atomic);
@@ -543,9 +553,6 @@ struct Clump : PluginBase
bool streamWrite(Stream *stream);
uint32 streamGetSize(void);
void render(void);
-
- bool frameListStreamRead(Stream *stream, Frame ***flp, int32 *nf);
- void frameListStreamWrite(Stream *stream, Frame **flp, int32 nf);
};
struct TexDictionary : PluginBase
diff --git a/src/rwplg.h b/src/rwplg.h
index fd7893e..caf4dd7 100644
--- a/src/rwplg.h
+++ b/src/rwplg.h
@@ -36,7 +36,7 @@ struct PluginBase
void constructPlugins(void);
void destructPlugins(void);
void copyPlugins(T *t);
- void streamReadPlugins(Stream *stream);
+ bool streamReadPlugins(Stream *stream);
void streamWritePlugins(Stream *stream);
int streamGetPluginSize(void);
void assertRights(uint32 pluginID, uint32 data);
@@ -81,15 +81,16 @@ PluginBase::copyPlugins(T *t)
p->copy((void*)this, (void*)t, p->offset, p->size);
}
-template void
+template bool
PluginBase::streamReadPlugins(Stream *stream)
{
int32 length;
ChunkHeaderInfo header;
if(!findChunk(stream, ID_EXTENSION, (uint32*)&length, NULL))
- return;
+ return false;
while(length > 0){
- readChunkHeaderInfo(stream, &header);
+ if(!readChunkHeaderInfo(stream, &header))
+ return false;
length -= 12;
for(Plugin *p = this->s_plugins; p; p = p->next)
if(p->id == header.type && p->read){
@@ -102,6 +103,7 @@ PluginBase::streamReadPlugins(Stream *stream)
cont:
length -= header.length;
}
+ return true;
}
template void