worked on error handling

This commit is contained in:
aap 2016-06-17 13:29:49 +02:00
parent 6e71e34933
commit 1bb17b3094
8 changed files with 298 additions and 226 deletions

View File

@ -188,6 +188,7 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\anim.cpp" /> <ClCompile Include="src\anim.cpp" />
<ClCompile Include="src\camera.cpp" />
<ClCompile Include="src\clump.cpp" /> <ClCompile Include="src\clump.cpp" />
<ClCompile Include="src\d3d.cpp" /> <ClCompile Include="src\d3d.cpp" />
<ClCompile Include="src\d3d8.cpp" /> <ClCompile Include="src\d3d8.cpp" />
@ -195,15 +196,19 @@
<ClCompile Include="src\d3d9.cpp" /> <ClCompile Include="src\d3d9.cpp" />
<ClCompile Include="src\d3d9render.cpp" /> <ClCompile Include="src\d3d9render.cpp" />
<ClCompile Include="src\d3ddriver.cpp" /> <ClCompile Include="src\d3ddriver.cpp" />
<ClCompile Include="src\engine.cpp" />
<ClCompile Include="src\error.cpp" />
<ClCompile Include="src\frame.cpp" />
<ClCompile Include="src\geometry.cpp" /> <ClCompile Include="src\geometry.cpp" />
<ClCompile Include="src\image.cpp" /> <ClCompile Include="src\image.cpp" />
<ClCompile Include="src\ogl.cpp" /> <ClCompile Include="src\light.cpp" />
<ClCompile Include="src\pds.cpp" /> <ClCompile Include="src\pds.cpp" />
<ClCompile Include="src\pipeline.cpp" /> <ClCompile Include="src\pipeline.cpp" />
<ClCompile Include="src\plugins.cpp" /> <ClCompile Include="src\plugins.cpp" />
<ClCompile Include="src\ps2.cpp" /> <ClCompile Include="src\ps2.cpp" />
<ClCompile Include="src\ps2raster.cpp" /> <ClCompile Include="src\ps2raster.cpp" />
<ClCompile Include="src\rwbase.cpp" /> <ClCompile Include="src\rwbase.cpp" />
<ClCompile Include="src\wdgl.cpp" />
<ClCompile Include="src\xbox.cpp" /> <ClCompile Include="src\xbox.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -211,13 +216,21 @@
<ClInclude Include="src\rwd3d.h" /> <ClInclude Include="src\rwd3d.h" />
<ClInclude Include="src\rwd3d8.h" /> <ClInclude Include="src\rwd3d8.h" />
<ClInclude Include="src\rwd3d9.h" /> <ClInclude Include="src\rwd3d9.h" />
<ClInclude Include="src\rwengine.h" />
<ClInclude Include="src\rwerror.h" />
<ClInclude Include="src\rwobjects.h" /> <ClInclude Include="src\rwobjects.h" />
<ClInclude Include="src\rwogl.h" />
<ClInclude Include="src\rwpipeline.h" /> <ClInclude Include="src\rwpipeline.h" />
<ClInclude Include="src\rwplg.h" />
<ClInclude Include="src\rwplugin.h" /> <ClInclude Include="src\rwplugin.h" />
<ClInclude Include="src\rwplugins.h" />
<ClInclude Include="src\rwps2.h" /> <ClInclude Include="src\rwps2.h" />
<ClInclude Include="src\rwps2plg.h" />
<ClInclude Include="src\rwwdgl.h" />
<ClInclude Include="src\rwxbox.h" /> <ClInclude Include="src\rwxbox.h" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="src\base.err" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>

View File

@ -15,9 +15,9 @@ Camera*
Camera::create(void) Camera::create(void)
{ {
Camera *cam = (Camera*)malloc(PluginBase::s_size); Camera *cam = (Camera*)malloc(PluginBase::s_size);
if(cam == NULL){ if(cam == nil){
RWERROR((ERR_ALLOC, PluginBase::s_size)); RWERROR((ERR_ALLOC, PluginBase::s_size));
return NULL; return nil;
} }
cam->object.object.init(Camera::ID, 0); cam->object.object.init(Camera::ID, 0);
cam->viewWindow.set(1.0f, 1.0f); cam->viewWindow.set(1.0f, 1.0f);
@ -26,7 +26,7 @@ Camera::create(void)
cam->farPlane = 10.0f; cam->farPlane = 10.0f;
cam->fogPlane = 5.0f; cam->fogPlane = 5.0f;
cam->projection = Camera::PERSPECTIVE; cam->projection = Camera::PERSPECTIVE;
cam->clump = NULL; cam->clump = nil;
cam->inClump.init(); cam->inClump.init();
cam->constructPlugins(); cam->constructPlugins();
return cam; return cam;
@ -36,8 +36,8 @@ Camera*
Camera::clone(void) Camera::clone(void)
{ {
Camera *cam = Camera::create(); Camera *cam = Camera::create();
if(cam == NULL) if(cam == nil)
return NULL; return nil;
cam->object.object.copy(&this->object.object); cam->object.object.copy(&this->object.object);
cam->setFrame(this->getFrame()); cam->setFrame(this->getFrame());
cam->viewWindow = this->viewWindow; cam->viewWindow = this->viewWindow;
@ -72,9 +72,9 @@ Camera*
Camera::streamRead(Stream *stream) Camera::streamRead(Stream *stream)
{ {
CameraChunkData buf; CameraChunkData buf;
if(!findChunk(stream, ID_STRUCT, NULL, NULL)){ if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT")); RWERROR((ERR_CHUNK, "STRUCT"));
return NULL; return nil;
} }
stream->read(&buf, sizeof(CameraChunkData)); stream->read(&buf, sizeof(CameraChunkData));
Camera *cam = Camera::create(); Camera *cam = Camera::create();
@ -84,9 +84,10 @@ Camera::streamRead(Stream *stream)
cam->farPlane = buf.farPlane; cam->farPlane = buf.farPlane;
cam->fogPlane = buf.fogPlane; cam->fogPlane = buf.fogPlane;
cam->projection = buf.projection; cam->projection = buf.projection;
cam->streamReadPlugins(stream); if(cam->streamReadPlugins(stream))
return cam; return cam;
cam->destroy();
return nil;
} }
bool bool

View File

@ -1,5 +1,6 @@
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <cstring>
#include "rwbase.h" #include "rwbase.h"
#include "rwerror.h" #include "rwerror.h"
@ -78,9 +79,6 @@ Clump::streamRead(Stream *stream)
RWERROR((ERR_CHUNK, "STRUCT")); RWERROR((ERR_CHUNK, "STRUCT"));
return nil; return nil;
} }
clump = Clump::create();
if(clump == nil)
return nil;
stream->read(buf, length); stream->read(buf, length);
int32 numAtomics = buf[0]; int32 numAtomics = buf[0];
int32 numLights = 0; int32 numLights = 0;
@ -89,41 +87,51 @@ Clump::streamRead(Stream *stream)
numLights = buf[1]; numLights = buf[1];
numCameras = buf[2]; numCameras = buf[2];
} }
clump = Clump::create();
if(clump == nil)
return nil;
// Frame list // Frame list
Frame **frameList; FrameList_ frmlst;
int32 numFrames; frmlst.frames = nil;
clump->frameListStreamRead(stream, &frameList, &numFrames); if(!findChunk(stream, ID_FRAMELIST, nil, nil)){
clump->setFrame(frameList[0]); 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){ if(version >= 0x30400){
// Geometry list
int32 numGeometries = 0;
if(!findChunk(stream, ID_GEOMETRYLIST, nil, nil)){ if(!findChunk(stream, ID_GEOMETRYLIST, nil, nil)){
RWERROR((ERR_CHUNK, "GEOMETRYLIST")); RWERROR((ERR_CHUNK, "GEOMETRYLIST"));
// TODO: free goto fail;
return nil;
} }
if(!findChunk(stream, ID_STRUCT, nil, nil)){ if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT")); RWERROR((ERR_CHUNK, "STRUCT"));
// TODO: free goto fail;
return nil;
} }
numGeometries = stream->readI32(); numGeometries = stream->readI32();
if(numGeometries) if(numGeometries){
geometryList = new Geometry*[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++){ for(int32 i = 0; i < numGeometries; i++){
if(!findChunk(stream, ID_GEOMETRY, nil, nil)){ if(!findChunk(stream, ID_GEOMETRY, nil, nil)){
RWERROR((ERR_CHUNK, "GEOMETRY")); RWERROR((ERR_CHUNK, "GEOMETRY"));
// TODO: free goto failgeo;
return nil;
} }
geometryList[i] = Geometry::streamRead(stream); geometryList[i] = Geometry::streamRead(stream);
if(geometryList[i] == nil){ if(geometryList[i] == nil)
// TODO: free goto failgeo;
return nil;
}
} }
} }
@ -132,67 +140,70 @@ Clump::streamRead(Stream *stream)
for(int32 i = 0; i < numAtomics; i++){ for(int32 i = 0; i < numAtomics; i++){
if(!findChunk(stream, ID_ATOMIC, nil, nil)){ if(!findChunk(stream, ID_ATOMIC, nil, nil)){
RWERROR((ERR_CHUNK, "ATOMIC")); RWERROR((ERR_CHUNK, "ATOMIC"));
// TODO: free goto failgeo;
return nil;
}
a = Atomic::streamReadClump(stream, frameList, geometryList);
if(a == nil){
// TODO: free
return nil;
} }
a = Atomic::streamReadClump(stream, &frmlst, geometryList);
if(a == nil)
goto failgeo;
clump->addAtomic(a); clump->addAtomic(a);
} }
// Lights // Lights
int32 frm;
Light *l;
for(int32 i = 0; i < numLights; i++){ for(int32 i = 0; i < numLights; i++){
int32 frm;
if(!findChunk(stream, ID_STRUCT, nil, nil)){ if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT")); RWERROR((ERR_CHUNK, "STRUCT"));
// TODO: free goto failgeo;
return nil;
} }
frm = stream->readI32(); frm = stream->readI32();
if(!findChunk(stream, ID_LIGHT, nil, nil)){ if(!findChunk(stream, ID_LIGHT, nil, nil)){
RWERROR((ERR_CHUNK, "LIGHT")); RWERROR((ERR_CHUNK, "LIGHT"));
// TODO: free goto failgeo;
return nil;
} }
Light *l = Light::streamRead(stream); l = Light::streamRead(stream);
if(l == nil){ if(l == nil)
// TODO: free goto failgeo;
return nil; l->setFrame(frmlst.frames[frm]);
}
l->setFrame(frameList[frm]);
clump->addLight(l); clump->addLight(l);
} }
// Cameras // Cameras
Camera *cam;
for(int32 i = 0; i < numCameras; i++){ for(int32 i = 0; i < numCameras; i++){
int32 frm;
if(!findChunk(stream, ID_STRUCT, nil, nil)){ if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT")); RWERROR((ERR_CHUNK, "STRUCT"));
// TODO: free goto failgeo;
return nil;
} }
frm = stream->readI32(); frm = stream->readI32();
if(!findChunk(stream, ID_CAMERA, nil, nil)){ if(!findChunk(stream, ID_CAMERA, nil, nil)){
RWERROR((ERR_CHUNK, "CAMERA")); RWERROR((ERR_CHUNK, "CAMERA"));
// TODO: free goto failgeo;
return nil;
} }
Camera *cam = Camera::streamRead(stream); cam = Camera::streamRead(stream);
if(cam == nil){ if(cam == nil)
// TODO: free goto failgeo;
return nil; cam->setFrame(frmlst.frames[frm]);
}
cam->setFrame(frameList[frm]);
clump->addCamera(cam); 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); failgeo:
return clump; for(int32 i = 0; i < numGeometries; i++)
if(geometryList[i])
geometryList[i]->destroy();
free(geometryList);
fail:
free(frmlst.frames);
clump->destroy();
return nil;
} }
bool bool
@ -208,10 +219,11 @@ Clump::streamWrite(Stream *stream)
writeChunkHeader(stream, ID_STRUCT, size); writeChunkHeader(stream, ID_STRUCT, size);
stream->write(buf, size); stream->write(buf, size);
int32 numFrames = this->getFrame()->count(); FrameList_ frmlst;
Frame **flist = new Frame*[numFrames]; frmlst.numFrames = this->getFrame()->count();
makeFrameList(this->getFrame(), flist); frmlst.frames = (Frame**)malloc(frmlst.numFrames*sizeof(Frame*));
this->frameListStreamWrite(stream, flist, numFrames); makeFrameList(this->getFrame(), frmlst.frames);
frmlst.streamWrite(stream);
if(rw::version >= 0x30400){ if(rw::version >= 0x30400){
size = 12+4; size = 12+4;
@ -225,11 +237,11 @@ Clump::streamWrite(Stream *stream)
} }
FORLIST(lnk, this->atomics) FORLIST(lnk, this->atomics)
Atomic::fromClump(lnk)->streamWriteClump(stream, flist, numFrames); Atomic::fromClump(lnk)->streamWriteClump(stream, &frmlst);
FORLIST(lnk, this->lights){ FORLIST(lnk, this->lights){
Light *l = Light::fromClump(lnk); 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) if(frm < 0)
return false; return false;
writeChunkHeader(stream, ID_STRUCT, 4); writeChunkHeader(stream, ID_STRUCT, 4);
@ -239,7 +251,7 @@ Clump::streamWrite(Stream *stream)
FORLIST(lnk, this->cameras){ FORLIST(lnk, this->cameras){
Camera *c = Camera::fromClump(lnk); 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) if(frm < 0)
return false; return false;
writeChunkHeader(stream, ID_STRUCT, 4); writeChunkHeader(stream, ID_STRUCT, 4);
@ -247,27 +259,12 @@ Clump::streamWrite(Stream *stream)
c->streamWrite(stream); c->streamWrite(stream);
} }
delete[] flist; free(frmlst.frames);
this->streamWritePlugins(stream); this->streamWritePlugins(stream);
return true; 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 uint32
Clump::streamGetSize(void) Clump::streamGetSize(void)
{ {
@ -278,9 +275,7 @@ Clump::streamGetSize(void)
size += 8; // numLights, numCameras size += 8; // numLights, numCameras
// Frame list // Frame list
int32 numFrames = this->getFrame()->count(); size += FrameList_::streamGetSize(this->getFrame());
size += 12 + 12 + 4 + numFrames*(sizeof(FrameStreamData)+12);
sizeCB(this->getFrame(), (void*)&size);
if(rw::version >= 0x30400){ if(rw::version >= 0x30400){
// Geometry list // 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 // Atomic
// //
@ -412,12 +340,12 @@ Atomic*
Atomic::clone() Atomic::clone()
{ {
Atomic *atomic = Atomic::create(); Atomic *atomic = Atomic::create();
if(atomic == nil)
return nil;
atomic->object.object.copy(&this->object.object); atomic->object.object.copy(&this->object.object);
atomic->object.object.privateFlags |= 1; atomic->object.object.privateFlags |= 1;
if(this->geometry){ if(this->geometry)
atomic->geometry = this->geometry; atomic->setGeometry(this->geometry);
atomic->geometry->refCount++;
}
atomic->pipeline = this->pipeline; atomic->pipeline = this->pipeline;
atomic->copyPlugins(this); atomic->copyPlugins(this);
return atomic; 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* Sphere*
Atomic::getWorldBoundingSphere(void) Atomic::getWorldBoundingSphere(void)
{ {
@ -464,7 +403,7 @@ static uint32 atomicRights[2];
Atomic* Atomic*
Atomic::streamReadClump(Stream *stream, Atomic::streamReadClump(Stream *stream,
Frame **frameList, Geometry **geometryList) FrameList_ *frameList, Geometry **geometryList)
{ {
int32 buf[4]; int32 buf[4];
uint32 version; uint32 version;
@ -476,31 +415,36 @@ Atomic::streamReadClump(Stream *stream,
Atomic *atomic = Atomic::create(); Atomic *atomic = Atomic::create();
if(atomic == nil) if(atomic == nil)
return nil; return nil;
atomic->setFrame(frameList[buf[0]]); atomic->setFrame(frameList->frames[buf[0]]);
Geometry *g;
if(version < 0x30400){ if(version < 0x30400){
if(!findChunk(stream, ID_GEOMETRY, nil, nil)){ if(!findChunk(stream, ID_GEOMETRY, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT")); RWERROR((ERR_CHUNK, "STRUCT"));
// TODO: free goto fail;
return nil;
}
atomic->geometry = Geometry::streamRead(stream);
if(atomic->geometry == nil){
// TODO: free
return nil;
} }
g = Geometry::streamRead(stream);
if(g == nil)
goto fail;
atomic->setGeometry(g);
g->destroy();
}else }else
atomic->geometry = geometryList[buf[1]]; atomic->setGeometry(geometryList[buf[1]]);
atomic->object.object.flags = buf[2]; atomic->object.object.flags = buf[2];
atomicRights[0] = 0; atomicRights[0] = 0;
atomic->streamReadPlugins(stream); if(!atomic->streamReadPlugins(stream))
goto fail;
if(atomicRights[0]) if(atomicRights[0])
atomic->assertRights(atomicRights[0], atomicRights[1]); atomic->assertRights(atomicRights[0], atomicRights[1]);
return atomic; return atomic;
fail:
atomic->destroy();
return nil;
} }
bool bool
Atomic::streamWriteClump(Stream *stream, Frame **frameList, int32 numFrames) Atomic::streamWriteClump(Stream *stream, FrameList_ *frmlst)
{ {
int32 buf[4] = { 0, 0, 0, 0 }; int32 buf[4] = { 0, 0, 0, 0 };
Clump *c = this->clump; Clump *c = this->clump;
@ -508,7 +452,7 @@ Atomic::streamWriteClump(Stream *stream, Frame **frameList, int32 numFrames)
return false; return false;
writeChunkHeader(stream, ID_ATOMIC, this->streamGetSize()); writeChunkHeader(stream, ID_ATOMIC, this->streamGetSize());
writeChunkHeader(stream, ID_STRUCT, rw::version < 0x30400 ? 12 : 16); 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){ if(version < 0x30400){
buf[1] = this->object.object.flags; buf[1] = this->object.object.flags;
@ -579,7 +523,7 @@ getSizeAtomicRights(void *object, int32, int32)
{ {
Atomic *atomic = (Atomic*)object; Atomic *atomic = (Atomic*)object;
if(atomic->pipeline == nil || atomic->pipeline->pluginID == 0) if(atomic->pipeline == nil || atomic->pipeline->pluginID == 0)
return -1; return 0;
return 8; return 8;
} }

View File

@ -1,7 +1,6 @@
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <cassert>
#include <cmath> #include <cmath>
#include "rwbase.h" #include "rwbase.h"
@ -10,11 +9,6 @@
#include "rwpipeline.h" #include "rwpipeline.h"
#include "rwobjects.h" #include "rwobjects.h"
#include "rwengine.h" #include "rwengine.h"
#include "rwps2.h"
#include "rwxbox.h"
#include "rwd3d8.h"
#include "rwd3d9.h"
#include "rwwdgl.h"
#define PLUGIN_ID 0 #define PLUGIN_ID 0
@ -248,6 +242,100 @@ Frame::purgeClone(void)
this->setHierarchyRoot(parent ? parent->root : this); 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** Frame**
makeFrameList(Frame *frame, Frame **flist) makeFrameList(Frame *frame, Frame **flist)
{ {

View File

@ -87,7 +87,8 @@ Geometry::destroy(void)
delete[] this->morphTargets; delete[] this->morphTargets;
delete this->meshHeader; delete this->meshHeader;
for(int32 i = 0; i < this->numMaterials; i++) for(int32 i = 0; i < this->numMaterials; i++)
this->materialList[i]->destroy(); if(this->materialList[i])
this->materialList[i]->destroy();
delete[] this->materialList; delete[] this->materialList;
free(this); free(this);
} }
@ -149,29 +150,32 @@ Geometry::streamRead(Stream *stream)
if(!findChunk(stream, ID_MATLIST, nil, nil)){ if(!findChunk(stream, ID_MATLIST, nil, nil)){
RWERROR((ERR_CHUNK, "MATLIST")); RWERROR((ERR_CHUNK, "MATLIST"));
// TODO: free goto fail;
return nil;
} }
if(!findChunk(stream, ID_STRUCT, nil, nil)){ if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT")); RWERROR((ERR_CHUNK, "STRUCT"));
// TODO: free goto fail;
return nil;
} }
geo->numMaterials = stream->readI32(); geo->numMaterials = stream->readI32();
geo->materialList = new Material*[geo->numMaterials]; 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++){ for(int32 i = 0; i < geo->numMaterials; i++){
if(!findChunk(stream, ID_MATERIAL, nil, nil)){ if(!findChunk(stream, ID_MATERIAL, nil, nil)){
RWERROR((ERR_CHUNK, "MATERIAL")); RWERROR((ERR_CHUNK, "MATERIAL"));
// TODO: free goto fail;
return nil;
} }
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); fail:
geo->destroy();
return geo; return nil;
} }
static uint32 static uint32
@ -562,10 +566,8 @@ Material::clone(void)
} }
mat->color = this->color; mat->color = this->color;
mat->surfaceProps = this->surfaceProps; mat->surfaceProps = this->surfaceProps;
if(this->texture){ if(this->texture)
mat->texture = this->texture; mat->setTexture(this->texture);
mat->texture->refCount++;
}
mat->pipeline = this->pipeline; mat->pipeline = this->pipeline;
mat->copyPlugins(this); mat->copyPlugins(this);
return mat; 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 struct MatStreamData
{ {
int32 flags; // unused according to RW int32 flags; // unused according to RW
@ -622,21 +634,24 @@ Material::streamRead(Stream *stream)
if(buf.textured){ if(buf.textured){
if(!findChunk(stream, ID_TEXTURE, &length, nil)){ if(!findChunk(stream, ID_TEXTURE, &length, nil)){
RWERROR((ERR_CHUNK, "TEXTURE")); RWERROR((ERR_CHUNK, "TEXTURE"));
// TODO: free goto fail;
return nil;
}
mat->texture = Texture::streamRead(stream);
if(mat->texture == nil){
// TODO: fre
return nil;
} }
Texture *t = Texture::streamRead(stream);
if(t == nil)
goto fail;
mat->setTexture(t);
} }
materialRights[0] = 0; materialRights[0] = 0;
mat->streamReadPlugins(stream); if(!mat->streamReadPlugins(stream))
goto fail;
if(materialRights[0]) if(materialRights[0])
mat->assertRights(materialRights[0], materialRights[1]); mat->assertRights(materialRights[0], materialRights[1]);
return mat; return mat;
fail:
mat->destroy();
return nil;
} }
bool bool

View File

@ -15,9 +15,9 @@ Light*
Light::create(int32 type) Light::create(int32 type)
{ {
Light *light = (Light*)malloc(PluginBase::s_size); Light *light = (Light*)malloc(PluginBase::s_size);
if(light == NULL){ if(light == nil){
RWERROR((ERR_ALLOC, PluginBase::s_size)); RWERROR((ERR_ALLOC, PluginBase::s_size));
return NULL; return nil;
} }
light->object.object.init(Light::ID, type); light->object.object.init(Light::ID, type);
light->radius = 0.0f; light->radius = 0.0f;
@ -28,7 +28,7 @@ Light::create(int32 type)
light->minusCosAngle = 1.0f; light->minusCosAngle = 1.0f;
light->object.object.privateFlags = 1; light->object.object.privateFlags = 1;
light->object.object.flags = LIGHTATOMICS | LIGHTWORLD; light->object.object.flags = LIGHTATOMICS | LIGHTWORLD;
light->clump = NULL; light->clump = nil;
light->inClump.init(); light->inClump.init();
light->constructPlugins(); light->constructPlugins();
return light; return light;
@ -79,14 +79,14 @@ Light::streamRead(Stream *stream)
uint32 version; uint32 version;
LightChunkData buf; LightChunkData buf;
if(!findChunk(stream, ID_STRUCT, NULL, &version)){ if(!findChunk(stream, ID_STRUCT, nil, &version)){
RWERROR((ERR_CHUNK, "STRUCT")); RWERROR((ERR_CHUNK, "STRUCT"));
return NULL; return nil;
} }
stream->read(&buf, sizeof(LightChunkData)); stream->read(&buf, sizeof(LightChunkData));
Light *light = Light::create(buf.type); Light *light = Light::create(buf.type);
if(light == NULL) if(light == nil)
return NULL; return nil;
light->radius = buf.radius; light->radius = buf.radius;
light->setColor(buf.red, buf.green, buf.blue); light->setColor(buf.red, buf.green, buf.blue);
float32 a = buf.minusCosAngle; float32 a = buf.minusCosAngle;
@ -96,8 +96,10 @@ Light::streamRead(Stream *stream)
// tan -> -cos // tan -> -cos
light->minusCosAngle = -1.0f/sqrt(a*a+1.0f); light->minusCosAngle = -1.0f/sqrt(a*a+1.0f);
light->object.object.flags = (uint8)buf.flags; light->object.object.flags = (uint8)buf.flags;
light->streamReadPlugins(stream); if(light->streamReadPlugins(stream))
return light; return light;
light->destroy();
return nil;
} }
bool bool

View File

@ -130,6 +130,15 @@ struct Frame : PluginBase<Frame>
void purgeClone(void); 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); Frame **makeFrameList(Frame *frame, Frame **flist);
struct ObjectWithFrame struct ObjectWithFrame
@ -288,6 +297,7 @@ struct Material : PluginBase<Material>
static Material *create(void); static Material *create(void);
Material *clone(void); Material *clone(void);
void destroy(void); void destroy(void);
void setTexture(Texture *tex);
static Material *streamRead(Stream *stream); static Material *streamRead(Stream *stream);
bool streamWrite(Stream *stream); bool streamWrite(Stream *stream);
uint32 streamGetSize(void); uint32 streamGetSize(void);
@ -424,13 +434,13 @@ struct Atomic : PluginBase<Atomic>
static Atomic *fromClump(LLLink *lnk){ static Atomic *fromClump(LLLink *lnk){
return LLLinkGetData(lnk, Atomic, inClump); } return LLLinkGetData(lnk, Atomic, inClump); }
void removeFromClump(void); void removeFromClump(void);
void setGeometry(Geometry *geo);
Sphere *getWorldBoundingSphere(void); Sphere *getWorldBoundingSphere(void);
ObjPipeline *getPipeline(void); ObjPipeline *getPipeline(void);
void render(void) { this->renderCB(this); } void render(void) { this->renderCB(this); }
static Atomic *streamReadClump(Stream *stream, static Atomic *streamReadClump(Stream *stream,
Frame **frameList, Geometry **geometryList); FrameList_ *frameList, Geometry **geometryList);
bool streamWriteClump(Stream *stream, bool streamWriteClump(Stream *stream, FrameList_ *frmlst);
Frame **frameList, int32 numframes);
uint32 streamGetSize(void); uint32 streamGetSize(void);
static void defaultRenderCB(Atomic *atomic); static void defaultRenderCB(Atomic *atomic);
@ -543,9 +553,6 @@ struct Clump : PluginBase<Clump>
bool streamWrite(Stream *stream); bool streamWrite(Stream *stream);
uint32 streamGetSize(void); uint32 streamGetSize(void);
void render(void); void render(void);
bool frameListStreamRead(Stream *stream, Frame ***flp, int32 *nf);
void frameListStreamWrite(Stream *stream, Frame **flp, int32 nf);
}; };
struct TexDictionary : PluginBase<TexDictionary> struct TexDictionary : PluginBase<TexDictionary>

View File

@ -36,7 +36,7 @@ struct PluginBase
void constructPlugins(void); void constructPlugins(void);
void destructPlugins(void); void destructPlugins(void);
void copyPlugins(T *t); void copyPlugins(T *t);
void streamReadPlugins(Stream *stream); bool streamReadPlugins(Stream *stream);
void streamWritePlugins(Stream *stream); void streamWritePlugins(Stream *stream);
int streamGetPluginSize(void); int streamGetPluginSize(void);
void assertRights(uint32 pluginID, uint32 data); void assertRights(uint32 pluginID, uint32 data);
@ -81,15 +81,16 @@ PluginBase<T>::copyPlugins(T *t)
p->copy((void*)this, (void*)t, p->offset, p->size); p->copy((void*)this, (void*)t, p->offset, p->size);
} }
template <typename T> void template <typename T> bool
PluginBase<T>::streamReadPlugins(Stream *stream) PluginBase<T>::streamReadPlugins(Stream *stream)
{ {
int32 length; int32 length;
ChunkHeaderInfo header; ChunkHeaderInfo header;
if(!findChunk(stream, ID_EXTENSION, (uint32*)&length, NULL)) if(!findChunk(stream, ID_EXTENSION, (uint32*)&length, NULL))
return; return false;
while(length > 0){ while(length > 0){
readChunkHeaderInfo(stream, &header); if(!readChunkHeaderInfo(stream, &header))
return false;
length -= 12; length -= 12;
for(Plugin *p = this->s_plugins; p; p = p->next) for(Plugin *p = this->s_plugins; p; p = p->next)
if(p->id == header.type && p->read){ if(p->id == header.type && p->read){
@ -102,6 +103,7 @@ PluginBase<T>::streamReadPlugins(Stream *stream)
cont: cont:
length -= header.length; length -= header.length;
} }
return true;
} }
template <typename T> void template <typename T> void