From 1bb17b309492e9f9113475a613e55f98a7acacb7 Mon Sep 17 00:00:00 2001 From: aap Date: Fri, 17 Jun 2016 13:29:49 +0200 Subject: [PATCH] worked on error handling --- librw.vcxproj | 17 ++- src/camera.cpp | 21 ++-- src/clump.cpp | 274 +++++++++++++++++++---------------------------- src/frame.cpp | 100 +++++++++++++++-- src/geometry.cpp | 63 ++++++----- src/light.cpp | 20 ++-- src/rwobjects.h | 19 ++-- src/rwplg.h | 10 +- 8 files changed, 298 insertions(+), 226 deletions(-) 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