diff --git a/librw.vcxproj b/librw.vcxproj index 6444b73..4376ed2 100644 --- a/librw.vcxproj +++ b/librw.vcxproj @@ -202,7 +202,6 @@ - diff --git a/src/clump.cpp b/src/clump.cpp index 2af4982..7ec69ca 100644 --- a/src/clump.cpp +++ b/src/clump.cpp @@ -19,33 +19,32 @@ using namespace std; namespace rw { -Frame::Frame(void) +Frame* +Frame::create(void) { - this->object.init(0, 0); - this->objectList.init(); - this->child = NULL; - this->next = NULL; - this->root = NULL; + Frame *f = (Frame*)malloc(PluginBase::s_size); + f->object.init(0, 0); + f->objectList.init(); + f->child = NULL; + f->next = NULL; + f->root = NULL; for(int i = 0; i < 16; i++) - this->matrix[i] = 0.0f; - this->matrix[0] = 1.0f; - this->matrix[5] = 1.0f; - this->matrix[10] = 1.0f; - this->matrix[15] = 1.0f; - this->matflag = 0; - this->dirty = true; - constructPlugins(); + f->matrix[i] = 0.0f; + f->matrix[0] = 1.0f; + f->matrix[5] = 1.0f; + f->matrix[10] = 1.0f; + f->matrix[15] = 1.0f; + f->matflag = 0; + f->dirty = true; + f->constructPlugins(); + return f; } -Frame::Frame(Frame *f) +void +Frame::destroy(void) { - // TODO - copyPlugins(f); -} - -Frame::~Frame(void) -{ - destructPlugins(); + this->destructPlugins(); + free(this); } Frame* @@ -162,29 +161,49 @@ makeFrameList(Frame *frame, Frame **flist) // Clump // -Clump::Clump(void) +Clump* +Clump::create(void) { - this->object.init(2, 0); - this->numAtomics = 0; - this->numLights = 0; - this->numCameras = 0; - this->atomicList = NULL; - this->lightList = NULL; - this->constructPlugins(); + Clump *clump = (Clump*)malloc(PluginBase::s_size); + clump->object.init(2, 0); + clump->atomics.init(); + clump->lights.init(); + clump->constructPlugins(); + return clump; } -Clump::Clump(Clump *c) +Clump* +Clump::clone(void) { - this->numAtomics = c->numAtomics; - this->numLights = c->numLights; - this->numCameras = c->numCameras; - // TODO: atomics and lights - this->copyPlugins(c); + Clump *clump = Clump::create(); + // TODO actually clone + clump->copyPlugins(this); + return clump; } -Clump::~Clump(void) +void +Clump::destroy(void) { this->destructPlugins(); + free(this); +} + +int32 +Clump::countAtomics(void) +{ + int32 n = 0; + FORLIST(l, this->atomics) + n++; + return n; +} + +int32 +Clump::countLights(void) +{ + int32 n = 0; + FORLIST(l, this->lights) + n++; + return n; } Clump* @@ -194,15 +213,13 @@ Clump::streamRead(Stream *stream) int32 buf[3]; Clump *clump; assert(findChunk(stream, ID_STRUCT, &length, &version)); - clump = new Clump; + clump = Clump::create(); stream->read(buf, length); - clump->numAtomics = buf[0]; - clump->numLights = 0; - clump->numCameras = 0; - if(version > 0x33000){ - clump->numLights = buf[1]; - clump->numCameras = buf[2]; - } + int32 numAtomics = buf[0]; + int32 numLights = 0; + if(version > 0x33000) + numLights = buf[1]; + // ignore cameras // Frame list Frame **frameList; @@ -226,26 +243,21 @@ Clump::streamRead(Stream *stream) } // Atomics - if(clump->numAtomics) - clump->atomicList = new Atomic*[clump->numAtomics]; - for(int32 i = 0; i < clump->numAtomics; i++){ + for(int32 i = 0; i < numAtomics; i++){ assert(findChunk(stream, ID_ATOMIC, NULL, NULL)); - clump->atomicList[i] = Atomic::streamReadClump(stream, - frameList, geometryList); - clump->atomicList[i]->clump = clump; + Atomic *a = Atomic::streamReadClump(stream, frameList, geometryList); + clump->addAtomic(a); } // Lights - if(clump->numLights) - clump->lightList = new Light*[clump->numLights]; - for(int32 i = 0; i < clump->numLights; i++){ + for(int32 i = 0; i < numLights; i++){ int32 frm; assert(findChunk(stream, ID_STRUCT, NULL, NULL)); frm = stream->readI32(); assert(findChunk(stream, ID_LIGHT, NULL, NULL)); - clump->lightList[i] = Light::streamRead(stream); - clump->lightList[i]->setFrame(frameList[frm]); - clump->lightList[i]->clump = clump; + Light *l = Light::streamRead(stream); + l->setFrame(frameList[frm]); + clump->addLight(l); } delete[] frameList; @@ -259,7 +271,9 @@ Clump::streamWrite(Stream *stream) { int size = this->streamGetSize(); writeChunkHeader(stream, ID_CLUMP, size); - int buf[3] = { this->numAtomics, this->numLights, this->numCameras }; + int32 numAtomics = this->countAtomics(); + int32 numLights = this->countLights(); + int buf[3] = { numAtomics, numLights, 0 }; size = version > 0x33000 ? 12 : 4; writeChunkHeader(stream, ID_STRUCT, size); stream->write(buf, size); @@ -272,22 +286,21 @@ Clump::streamWrite(Stream *stream) if(rw::version >= 0x30400){ size = 12+4; - for(int32 i = 0; i < this->numAtomics; i++) - size += 12 + - this->atomicList[i]->geometry->streamGetSize(); + FORLIST(lnk, this->atomics) + size += 12 + Atomic::fromClump(lnk)->geometry->streamGetSize(); writeChunkHeader(stream, ID_GEOMETRYLIST, size); writeChunkHeader(stream, ID_STRUCT, 4); - stream->writeI32(this->numAtomics); // same as numGeometries - for(int32 i = 0; i < this->numAtomics; i++) - this->atomicList[i]->geometry->streamWrite(stream); + stream->writeI32(numAtomics); // same as numGeometries + FORLIST(lnk, this->atomics) + Atomic::fromClump(lnk)->geometry->streamWrite(stream); } - for(int32 i = 0; i < this->numAtomics; i++) - this->atomicList[i]->streamWriteClump(stream, flist, numFrames); + FORLIST(lnk, this->atomics) + Atomic::fromClump(lnk)->streamWriteClump(stream, flist, numFrames); - for(int32 i = 0; i < this->numLights; i++){ - Light *l = this->lightList[i]; - int frm = findPointer((void*)l->object.parent, (void**)flist,numFrames); + FORLIST(lnk, this->lights){ + Light *l = Light::fromClump(lnk); + int frm = findPointer((void*)l->object.parent, (void**)flist, numFrames); if(frm < 0) return false; writeChunkHeader(stream, ID_STRUCT, 4); @@ -326,18 +339,17 @@ Clump::streamGetSize(void) if(rw::version >= 0x30400){ // geometry list size += 12 + 12 + 4; - for(int32 i = 0; i < this->numAtomics; i++) - size += 12 + - this->atomicList[i]->geometry->streamGetSize(); + FORLIST(lnk, this->atomics) + size += 12 + Atomic::fromClump(lnk)->geometry->streamGetSize(); } // atomics - for(int32 i = 0; i < this->numAtomics; i++) - size += 12 + this->atomicList[i]->streamGetSize(); + FORLIST(lnk, this->atomics) + size += 12 + Atomic::fromClump(lnk)->streamGetSize(); // light - for(int32 i = 0; i < this->numLights; i++) - size += 16 + 12 + this->lightList[i]->streamGetSize(); + FORLIST(lnk, this->lights) + size += 16 + 12 + Light::fromClump(lnk)->streamGetSize(); size += 12 + this->streamGetPluginSize(); return size; @@ -355,7 +367,7 @@ Clump::frameListStreamRead(Stream *stream, Frame ***flp, int32 *nf) Frame **frameList = new Frame*[numFrames]; for(int32 i = 0; i < numFrames; i++){ Frame *f; - frameList[i] = f = new Frame; + frameList[i] = f = Frame::create(); stream->read(&buf, sizeof(buf)); f->matrix[0] = buf.mat[0]; f->matrix[1] = buf.mat[1]; @@ -424,24 +436,32 @@ Clump::frameListStreamWrite(Stream *stream, Frame **frameList, int32 numFrames) // Atomic // -Atomic::Atomic(void) +Atomic* +Atomic::create(void) { - this->object.init(1, 0); - this->geometry = NULL; - this->pipeline = NULL; - constructPlugins(); + Atomic *atomic = (Atomic*)malloc(PluginBase::s_size); + atomic->object.init(1, 0); + atomic->geometry = NULL; + atomic->pipeline = NULL; + atomic->constructPlugins(); + return atomic; } -Atomic::Atomic(Atomic *a) +Atomic* +Atomic::clone() { + Atomic *atomic = Atomic::create(); //TODO - copyPlugins(a); + atomic->copyPlugins(this); + return atomic; } -Atomic::~Atomic(void) +void +Atomic::destroy(void) { //TODO - destructPlugins(); + this->destructPlugins(); + free(this); } static uint32 atomicRights[2]; @@ -454,7 +474,7 @@ Atomic::streamReadClump(Stream *stream, uint32 version; assert(findChunk(stream, ID_STRUCT, NULL, &version)); stream->read(buf, version < 0x30400 ? 12 : 16); - Atomic *atomic = new Atomic; + Atomic *atomic = Atomic::create(); atomic->setFrame(frameList[buf[0]]); if(version < 0x30400){ assert(findChunk(stream, ID_GEOMETRY, NULL, NULL)); @@ -484,10 +504,12 @@ Atomic::streamWriteClump(Stream *stream, Frame **frameList, int32 numFrames) stream->write(buf, sizeof(int[3])); this->geometry->streamWrite(stream); }else{ - // TODO - for(buf[1] = 0; buf[1] < c->numAtomics; buf[1]++) - if(c->atomicList[buf[1]]->geometry == this->geometry) + buf[1] = 0; + FORLIST(lnk, c->atomics){ + if(Atomic::fromClump(lnk)->geometry == this->geometry) goto foundgeo; + buf[1]++; + } return false; foundgeo: stream->write(buf, sizeof(buf)); @@ -578,30 +600,29 @@ registerAtomicRightsPlugin(void) // Light // -Light::Light(int32 type) +Light* +Light::create(int32 type) { - this->object.init(3, type); - this->radius = 0.0f; - this->color[0] = 1.0f; - this->color[1] = 1.0f; - this->color[2] = 1.0f; - this->color[3] = 1.0f; - this->minusCosAngle = 1.0f; - this->object.privateFlags = 1; - this->object.flags = 1 | 2; - Clump *clump; - constructPlugins(); + Light *light = (Light*)malloc(PluginBase::s_size); + light->object.init(3, type); + light->radius = 0.0f; + light->color[0] = 1.0f; + light->color[1] = 1.0f; + light->color[2] = 1.0f; + light->color[3] = 1.0f; + light->minusCosAngle = 1.0f; + light->object.privateFlags = 1; + light->object.flags = 1 | 2; + light->inClump.init(); + light->constructPlugins(); + return light; } -Light::Light(Light *l) +void +Light::destroy(void) { - // TODO - copyPlugins(l); -} - -Light::~Light(void) -{ - destructPlugins(); + this->destructPlugins(); + free(this); } struct LightChunkData @@ -619,7 +640,7 @@ Light::streamRead(Stream *stream) LightChunkData buf; assert(findChunk(stream, ID_STRUCT, NULL, NULL)); stream->read(&buf, sizeof(LightChunkData)); - Light *light = new Light(buf.type); + Light *light = Light::create(buf.type); light->radius = buf.radius; light->color[0] = buf.red; light->color[1] = buf.green; diff --git a/src/d3d8.cpp b/src/d3d8.cpp index 5e6b696..d14aab8 100644 --- a/src/d3d8.cpp +++ b/src/d3d8.cpp @@ -387,7 +387,7 @@ readNativeTexture(Stream *stream) { assert(findChunk(stream, ID_STRUCT, NULL, NULL)); assert(stream->readU32() == PLATFORM_D3D8); - Texture *tex = new Texture; + Texture *tex = Texture::create(NULL); // Texture tex->filterAddressing = stream->readU32(); @@ -407,10 +407,10 @@ readNativeTexture(Stream *stream) Raster *raster; D3dRaster *ras; if(compression){ - raster = new Raster(width, height, depth, format | type | 0x80, PLATFORM_D3D8); + raster = Raster::create(width, height, depth, format | type | 0x80, PLATFORM_D3D8); allocateDXT(raster, compression, numLevels, hasAlpha); }else - raster = new Raster(width, height, depth, format | type, PLATFORM_D3D8); + raster = Raster::create(width, height, depth, format | type, PLATFORM_D3D8); ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); tex->raster = raster; diff --git a/src/geometry.cpp b/src/geometry.cpp index 1542f85..d928d73 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -15,79 +15,80 @@ using namespace std; namespace rw { -Geometry::Geometry(int32 numVerts, int32 numTris, uint32 flags) +Geometry* +Geometry::create(int32 numVerts, int32 numTris, uint32 flags) { - this->object.init(8, 0); - this->geoflags = flags & 0xFF00FFFF; - this->numTexCoordSets = (flags & 0xFF0000) >> 16; - if(this->numTexCoordSets == 0) - this->numTexCoordSets = (this->geoflags & TEXTURED) ? 1 : - (this->geoflags & TEXTURED2) ? 2 : 0; - this->numTriangles = numTris; - this->numVertices = numVerts; - this->numMorphTargets = 1; + Geometry *geo = (Geometry*)malloc(PluginBase::s_size); + geo->object.init(8, 0); + geo->geoflags = flags & 0xFF00FFFF; + geo->numTexCoordSets = (flags & 0xFF0000) >> 16; + if(geo->numTexCoordSets == 0) + geo->numTexCoordSets = (geo->geoflags & TEXTURED) ? 1 : + (geo->geoflags & TEXTURED2) ? 2 : 0; + geo->numTriangles = numTris; + geo->numVertices = numVerts; + geo->numMorphTargets = 1; - this->colors = NULL; - for(int32 i = 0; i < this->numTexCoordSets; i++) - this->texCoords[i] = NULL; - this->triangles = NULL; - if(!(this->geoflags & NATIVE) && this->numVertices){ - if(this->geoflags & PRELIT) - this->colors = new uint8[4*this->numVertices]; - if((this->geoflags & TEXTURED) || (this->geoflags & TEXTURED2)) - for(int32 i = 0; i < this->numTexCoordSets; i++) - this->texCoords[i] = - new float32[2*this->numVertices]; - this->triangles = new uint16[4*this->numTriangles]; + geo->colors = NULL; + for(int32 i = 0; i < geo->numTexCoordSets; i++) + geo->texCoords[i] = NULL; + geo->triangles = NULL; + if(!(geo->geoflags & NATIVE) && geo->numVertices){ + if(geo->geoflags & PRELIT) + geo->colors = new uint8[4*geo->numVertices]; + if((geo->geoflags & TEXTURED) || (geo->geoflags & TEXTURED2)) + for(int32 i = 0; i < geo->numTexCoordSets; i++) + geo->texCoords[i] = + new float32[2*geo->numVertices]; + geo->triangles = new uint16[4*geo->numTriangles]; } - this->morphTargets = new MorphTarget[1]; - MorphTarget *m = this->morphTargets; + geo->morphTargets = new MorphTarget[1]; + MorphTarget *m = geo->morphTargets; m->boundingSphere[0] = 0.0f; m->boundingSphere[1] = 0.0f; m->boundingSphere[2] = 0.0f; m->boundingSphere[3] = 0.0f; m->vertices = NULL; m->normals = NULL; - if(!(this->geoflags & NATIVE) && this->numVertices){ - m->vertices = new float32[3*this->numVertices]; - if(this->geoflags & NORMALS) - m->normals = new float32[3*this->numVertices]; + if(!(geo->geoflags & NATIVE) && geo->numVertices){ + m->vertices = new float32[3*geo->numVertices]; + if(geo->geoflags & NORMALS) + m->normals = new float32[3*geo->numVertices]; } - this->numMaterials = 0; - this->materialList = NULL; - this->meshHeader = NULL; - this->instData = NULL; - this->refCount = 1; + geo->numMaterials = 0; + geo->materialList = NULL; + geo->meshHeader = NULL; + geo->instData = NULL; + geo->refCount = 1; - this->constructPlugins(); + geo->constructPlugins(); + return geo; } -Geometry::~Geometry(void) -{ - this->destructPlugins(); - delete[] this->colors; - for(int32 i = 0; i < this->numTexCoordSets; i++) - delete[] this->texCoords[i]; - delete[] this->triangles; - - for(int32 i = 0; i < this->numMorphTargets; i++){ - MorphTarget *m = &this->morphTargets[i]; - delete[] m->vertices; - delete[] m->normals; - } - delete[] this->morphTargets; - delete this->meshHeader; - for(int32 i = 0; i < this->numMaterials; i++) - this->materialList[i]->decRef(); - delete[] this->materialList; -} void -Geometry::decRef(void) +Geometry::destroy(void) { this->refCount--; - if(this->refCount == 0) - delete this; + if(this->refCount == 0){ + this->destructPlugins(); + delete[] this->colors; + for(int32 i = 0; i < this->numTexCoordSets; i++) + delete[] this->texCoords[i]; + delete[] this->triangles; + + for(int32 i = 0; i < this->numMorphTargets; i++){ + MorphTarget *m = &this->morphTargets[i]; + delete[] m->vertices; + delete[] m->normals; + } + delete[] this->morphTargets; + delete this->meshHeader; + for(int32 i = 0; i < this->numMaterials; i++) + this->materialList[i]->destroy(); + delete[] this->materialList; + free(this); + } } struct GeoStreamData @@ -105,8 +106,8 @@ Geometry::streamRead(Stream *stream) GeoStreamData buf; assert(findChunk(stream, ID_STRUCT, NULL, &version)); stream->read(&buf, sizeof(buf)); - Geometry *geo = new Geometry(buf.numVertices, - buf.numTriangles, buf.flags); + Geometry *geo = Geometry::create(buf.numVertices, + buf.numTriangles, buf.flags); geo->addMorphTargets(buf.numMorphTargets-1); // skip surface properties if(version < 0x34000) @@ -401,49 +402,48 @@ Geometry::generateTriangles(int8 *adc) // Material // -Material::Material(void) +Material* +Material::create(void) { - this->texture = NULL; - memset(this->color, 0xFF, 4); - surfaceProps.ambient = 1.0f; - surfaceProps.specular = 1.0f; - surfaceProps.diffuse = 1.0f; - this->pipeline = NULL; - this->refCount = 1; - this->constructPlugins(); + Material *mat = (Material*)malloc(PluginBase::s_size); + mat->texture = NULL; + memset(mat->color, 0xFF, 4); + mat->surfaceProps.ambient = 1.0f; + mat->surfaceProps.specular = 1.0f; + mat->surfaceProps.diffuse = 1.0f; + mat->pipeline = NULL; + mat->refCount = 1; + mat->constructPlugins(); + return mat; } -Material::Material(Material *m) +Material* +Material::clone(void) { - this->color[0] = m->color[0]; - this->color[1] = m->color[1]; - this->color[2] = m->color[2]; - this->color[3] = m->color[3]; - this->surfaceProps.ambient = m->surfaceProps.ambient; - this->surfaceProps.specular = m->surfaceProps.specular; - this->surfaceProps.diffuse = m->surfaceProps.diffuse; - this->texture = m->texture; - if(this->texture) - this->texture->refCount++; - this->pipeline = m->pipeline; - this->refCount = 1; - this->constructPlugins(); - this->copyPlugins(m); -} - -Material::~Material(void) -{ - this->destructPlugins(); - if(this->texture) - this->texture->decRef(); + Material *mat = Material::create(); + mat->color[0] = this->color[0]; + mat->color[1] = this->color[1]; + mat->color[2] = this->color[2]; + mat->color[3] = this->color[3]; + mat->surfaceProps = this->surfaceProps; + mat->texture = this->texture; + if(mat->texture) + mat->texture->refCount++; + mat->pipeline = this->pipeline; + mat->copyPlugins(this); + return mat; } void -Material::decRef(void) +Material::destroy(void) { this->refCount--; - if(this->refCount == 0) - delete this; + if(this->refCount == 0){ + this->destructPlugins(); + if(this->texture) + this->texture->destroy(); + free(this); + } } struct MatStreamData @@ -464,7 +464,7 @@ Material::streamRead(Stream *stream) assert(findChunk(stream, ID_STRUCT, NULL, &version)); stream->read(&buf, sizeof(buf)); - Material *mat = new Material; + Material *mat = Material::create(); mat->color[0] = buf.color[0]; mat->color[1] = buf.color[1]; mat->color[2] = buf.color[2]; diff --git a/src/gtaplg.cpp b/src/gtaplg.cpp index 23fdb3e..3a0ef20 100644 --- a/src/gtaplg.cpp +++ b/src/gtaplg.cpp @@ -21,8 +21,8 @@ namespace rw { int32 findPlatform(Clump *c) { - for(int32 i = 0; i < c->numAtomics; i++){ - Geometry *g = c->atomicList[i]->geometry; + FORLIST(lnk, c->atomics){ + Geometry *g = Atomic::fromClump(lnk)->geometry; if(g->instData) return g->instData->platform; } @@ -32,8 +32,8 @@ findPlatform(Clump *c) void switchPipes(Clump *c, int32 platform) { - for(int32 i = 0; i < c->numAtomics; i++){ - Atomic *a = c->atomicList[i]; + FORLIST(lnk, c->atomics){ + Atomic *a = Atomic::fromClump(lnk); if(a->pipeline && a->pipeline->platform != platform){ uint32 plgid = a->pipeline->pluginID; switch(plgid){ @@ -527,7 +527,7 @@ destroySpecMat(void *object, int32 offset, int32) if(*specmat == NULL) return object; if((*specmat)->texture) - (*specmat)->texture->decRef(); + (*specmat)->texture->destroy(); delete *specmat; *specmat = NULL; return object; @@ -560,7 +560,7 @@ readSpecMat(Stream *stream, int32, void *object, int32 offset, int32) *PLUGINOFFSET(SpecMat*, object, offset) = spec; stream->read(&buf, sizeof(buf)); spec->specularity = buf.specularity; - spec->texture = new Texture; + spec->texture = Texture::create(NULL); strncpy(spec->texture->name, buf.texname, 24); } diff --git a/src/image.cpp b/src/image.cpp index 1c034b8..d21c4b1 100755 --- a/src/image.cpp +++ b/src/image.cpp @@ -29,27 +29,40 @@ namespace rw { TexDictionary *currentTexDictionary; -TexDictionary::TexDictionary(void) +TexDictionary* +TexDictionary::create(void) { - this->object.init(6, 0); - this->first = NULL; + TexDictionary *dict = (TexDictionary*)malloc(PluginBase::s_size); + dict->object.init(6, 0); + dict->textures.init(); + dict->constructPlugins(); + return dict; } void -TexDictionary::add(Texture *tex) +TexDictionary::destroy(void) { - Texture **tp; - for(tp = &this->first; *tp; tp = &(*tp)->next) - ; - *tp = tex; + this->destructPlugins(); + free(this); +} + +int32 +TexDictionary::count(void) +{ + int32 n = 0; + FORLIST(l, this->textures) + n++; + return n; } Texture* TexDictionary::find(const char *name) { - for(Texture *tex = this->first; tex; tex = tex->next) + FORLIST(lnk, this->textures){ + Texture *tex = Texture::fromDict(lnk); if(strncmp(tex->name, name, 32) == 0) return tex; + } return NULL; } @@ -60,7 +73,7 @@ TexDictionary::streamRead(Stream *stream) int32 numTex = stream->readI16(); stream->readI16(); // some platform id (1 = d3d8, 2 = d3d9, 5 = opengl, // 6 = ps2, 8 = xbox) - TexDictionary *txd = new TexDictionary; + TexDictionary *txd = TexDictionary::create(); for(int32 i = 0; i < numTex; i++){ assert(findChunk(stream, ID_TEXTURENATIVE, NULL, NULL)); Texture *tex = Texture::streamReadNative(stream); @@ -75,13 +88,11 @@ TexDictionary::streamWrite(Stream *stream) { writeChunkHeader(stream, ID_TEXDICTIONARY, this->streamGetSize()); writeChunkHeader(stream, ID_STRUCT, 4); - int32 numTex = 0; - for(Texture *tex = this->first; tex; tex = tex->next) - numTex++; + int32 numTex = this->count(); stream->writeI16(numTex); stream->writeI16(0); - for(Texture *tex = this->first; tex; tex = tex->next) - tex->streamWriteNative(stream); + FORLIST(lnk, this->textures) + Texture::fromDict(lnk)->streamWriteNative(stream); this->streamWritePlugins(stream); } @@ -89,8 +100,8 @@ uint32 TexDictionary::streamGetSize(void) { uint32 size = 12 + 4; - for(Texture *tex = this->first; tex; tex = tex->next) - size += 12 + tex->streamGetSizeNative(); + FORLIST(lnk, this->textures) + size += 12 + Texture::fromDict(lnk)->streamGetSizeNative(); size += 12 + this->streamGetPluginSize(); return size; } @@ -99,28 +110,29 @@ TexDictionary::streamGetSize(void) // Texture // -Texture::Texture(void) +Texture* +Texture::create(Raster *raster) { - memset(this->name, 0, 32); - memset(this->mask, 0, 32); - this->filterAddressing = (WRAP << 12) | (WRAP << 8) | NEAREST; - this->raster = NULL; - this->refCount = 1; - this->next = NULL; - this->constructPlugins(); -} - -Texture::~Texture(void) -{ - this->destructPlugins(); + Texture *tex = (Texture*)malloc(PluginBase::s_size); + tex->dict = NULL; + tex->inDict.init(); + memset(tex->name, 0, 32); + memset(tex->mask, 0, 32); + tex->filterAddressing = (WRAP << 12) | (WRAP << 8) | NEAREST; + tex->raster = raster; + tex->refCount = 1; + tex->constructPlugins(); + return tex; } void -Texture::decRef(void) +Texture::destroy(void) { this->refCount--; - if(this->refCount == 0) - delete this; + if(this->refCount == 0){ + this->destructPlugins(); + free(this); + } } // TODO: do this properly, pretty ugly right now @@ -133,7 +145,7 @@ Texture::read(const char *name, const char *mask) if(currentTexDictionary && (tex = currentTexDictionary->find(name))) return tex; - tex = new Texture; + tex = Texture::create(NULL); strncpy(tex->name, name, 32); strncpy(tex->mask, mask, 32); // char *n = (char*)malloc(strlen(name) + 5); @@ -144,9 +156,9 @@ Texture::read(const char *name, const char *mask) // if(img){ // //raster = Raster::createFromImage(img); // raster = new Raster(0, 0, 0, 0x80); -// delete img; +// img->destroy(); // }else - raster = new Raster(0, 0, 0, 0x80); + raster = Raster::create(0, 0, 0, 0x80); tex->raster = raster; if(currentTexDictionary /*&& img*/) currentTexDictionary->add(tex); @@ -265,20 +277,25 @@ Texture::streamGetSizeNative(void) // Image // -Image::Image(int32 width, int32 height, int32 depth) +Image* +Image::create(int32 width, int32 height, int32 depth) { - this->flags = 0; - this->width = width; - this->height = height; - this->depth = depth; - this->stride = 0; - this->pixels = NULL; - this->palette = NULL; + Image *img = (Image*)malloc(sizeof(*img)); + img->flags = 0; + img->width = width; + img->height = height; + img->depth = depth; + img->stride = 0; + img->pixels = NULL; + img->palette = NULL; + return img; } -Image::~Image(void) +void +Image::destroy(void) { this->free(); + ::free(this); } void @@ -443,7 +460,7 @@ readTGA(const char *afilename) assert(depth == 24 || depth == 32); } - image = new Image(header.width, header.height, depth); + image = Image::create(header.width, header.height, depth); image->allocate(); uint8 *palette = header.colorMapType ? image->palette : NULL; uint8 (*color)[4] = NULL; @@ -548,29 +565,34 @@ writeTGA(Image *image, const char *filename) int32 Raster::nativeOffsets[NUM_PLATFORMS]; -Raster::Raster(int32 width, int32 height, int32 depth, int32 format, int32 platform) +Raster* +Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platform) { - this->platform = platform ? platform : rw::platform; - this->type = format & 0x7; - this->flags = format & 0xF8; - this->format = format & 0xFF00; - this->width = width; - this->height = height; - this->depth = depth; - this->texels = this->palette = NULL; - this->constructPlugins(); + Raster *raster = (Raster*)malloc(PluginBase::s_size); + raster->platform = platform ? platform : rw::platform; + raster->type = format & 0x7; + raster->flags = format & 0xF8; + raster->format = format & 0xFF00; + raster->width = width; + raster->height = height; + raster->depth = depth; + raster->texels = raster->palette = NULL; + raster->constructPlugins(); - int32 offset = nativeOffsets[this->platform]; + int32 offset = nativeOffsets[raster->platform]; assert(offset != 0 && "unimplemented raster platform"); - NativeRaster *nr = PLUGINOFFSET(NativeRaster, this, offset); - nr->create(this); + NativeRaster *nr = PLUGINOFFSET(NativeRaster, raster, offset); + nr->create(raster); + return raster; } -Raster::~Raster(void) +void +Raster::destroy(void) { this->destructPlugins(); delete[] this->texels; delete[] this->palette; + free(this); } uint8* @@ -629,8 +651,8 @@ Raster::createFromImage(Image *image) format = Raster::PAL4 | Raster::C8888; else return NULL; - Raster *raster = new Raster(image->width, image->height, - image->depth, format | 4 | 0x80); + Raster *raster = Raster::create(image->width, image->height, + image->depth, format | 4 | 0x80); raster->stride = image->stride; raster->texels = new uint8[raster->stride*raster->height]; diff --git a/src/plugins.cpp b/src/plugins.cpp index 4f9eeea..af905f2 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -772,19 +772,19 @@ clearMatFX(MatFX *matfx) switch(matfx->fx[i].type){ case MatFX::BUMPMAP: if(matfx->fx[i].bump.bumpedTex) - matfx->fx[i].bump.bumpedTex->decRef(); + matfx->fx[i].bump.bumpedTex->destroy(); if(matfx->fx[i].bump.tex) - matfx->fx[i].bump.tex->decRef(); + matfx->fx[i].bump.tex->destroy(); break; case MatFX::ENVMAP: if(matfx->fx[i].env.tex) - matfx->fx[i].env.tex->decRef(); + matfx->fx[i].env.tex->destroy(); break; case MatFX::DUAL: if(matfx->fx[i].dual.tex) - matfx->fx[i].dual.tex->decRef(); + matfx->fx[i].dual.tex->destroy(); break; } memset(matfx, 0, sizeof(MatFX)); diff --git a/src/ps2.cpp b/src/ps2.cpp index bb224a2..d9ab612 100644 --- a/src/ps2.cpp +++ b/src/ps2.cpp @@ -1828,7 +1828,7 @@ readNativeTexture(Stream *stream) uint32 length, oldversion, version; assert(findChunk(stream, ID_STRUCT, NULL, NULL)); assert(stream->readU32() == 0x00325350); // 'PS2\0' - Texture *tex = new Texture; + Texture *tex = Texture::create(NULL); // Texture tex->filterAddressing = stream->readU32(); @@ -1846,9 +1846,9 @@ readNativeTexture(Stream *stream) Raster *raster; noNewStyleRasters = streamExt.type < 2; rw::version = version; - raster = new Raster(streamExt.width, streamExt.height, - streamExt.depth, streamExt.rasterFormat, - PLATFORM_PS2); + raster = Raster::create(streamExt.width, streamExt.height, + streamExt.depth, streamExt.rasterFormat, + PLATFORM_PS2); noNewStyleRasters = 0; rw::version = oldversion; tex->raster = raster; diff --git a/src/rwobjects.h b/src/rwobjects.h index 4b3c137..b6a7d69 100644 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -33,11 +33,22 @@ struct LinkList this->link.next->prev = link; this->link.next = link; } + void append(LLLink *link){ + link->next = &this->link; + link->prev = this->link.prev; + this->link.prev->next = link; + this->link.prev = link; + } LLLink *end(void){ return &this->link; } }; +#define FORLIST(_link, _list) \ + for(LLLink *_link = (_list).link.next; \ + (_link) != (_list).end(); \ + (_link) = (_link)->next) + struct Object { uint8 type; @@ -72,9 +83,10 @@ struct Frame : PluginBase int32 matflag; bool dirty; - Frame(void); - Frame(Frame *f); - ~Frame(void); + // MEM create, clonehiearchy, destroy, destroy hierarchy + static Frame *create(void); + void destroy(void); + Frame *addChild(Frame *f); Frame *removeChild(void); Frame *forAllChildren(Callback cb, void *data); @@ -145,8 +157,9 @@ struct Image uint8 *pixels; uint8 *palette; - Image(int32 width, int32 height, int32 depth); - ~Image(void); + // MEM create, destroy + static Image *create(int32 width, int32 height, int32 depth); + void destroy(void); void allocate(void); void free(void); void setPixels(uint8 *pixels); @@ -184,8 +197,9 @@ struct Raster : PluginBase static int32 nativeOffsets[NUM_PLATFORMS]; - Raster(int32 width, int32 height, int32 depth, int32 format, int32 platform = 0); - ~Raster(void); + // MEM create, destroy + static Raster *create(int32 width, int32 height, int32 depth, int32 format, int32 platform = 0); + void destroy(void); static Raster *createFromImage(Image *image); uint8 *lock(int32 level); @@ -226,22 +240,24 @@ struct NativeRaster { assert(IGNORERASTERIMP && "unimplemented"); return 0; }; }; -// TODO: link into texdict +struct TexDictionary; + struct Texture : PluginBase { Raster *raster; - // TODO: pointer to txd and link + TexDictionary *dict; + LLLink inDict; char name[32]; char mask[32]; uint32 filterAddressing; // VVVVUUUU FFFFFFFF int32 refCount; - // temporary - pointer to next tex in dictionary - Texture *next; - - Texture(void); - ~Texture(void); - void decRef(void); + // MEM create, addref, destroy + static Texture *create(Raster *raster); + void destroy(void); + static Texture *fromDict(LLLink *lnk){ + return LLLinkGetData(lnk, Texture, inDict); + } static Texture *streamRead(Stream *stream); bool streamWrite(Stream *stream); uint32 streamGetSize(void); @@ -281,10 +297,10 @@ struct Material : PluginBase Pipeline *pipeline; int32 refCount; - Material(void); - Material(Material *m); - void decRef(void); - ~Material(void); + // MEM create, clone, addref, destroy + static Material *create(void); + Material *clone(void); + void destroy(void); static Material *streamRead(Stream *stream); bool streamWrite(Stream *stream); uint32 streamGetSize(void); @@ -406,9 +422,9 @@ struct Geometry : PluginBase int32 refCount; - Geometry(int32 numVerts, int32 numTris, uint32 flags); - void decRef(void); - ~Geometry(void); + // MEM create, addref, destroy + static Geometry *create(int32 numVerts, int32 numTris, uint32 flags); + void destroy(void); static Geometry *streamRead(Stream *stream); bool streamWrite(Stream *stream); uint32 streamGetSize(void); @@ -472,11 +488,15 @@ struct Light : PluginBase // clump link handled by plugin in RW Clump *clump; + LLLink inClump; - Light(int32 type); - Light(Light *l); - ~Light(void); + // MEM create, destroy + static Light *create(int32 type); + void destroy(void); void setFrame(Frame *f) { this->object.setFrame(f); } + static Light *fromClump(LLLink *lnk){ + return LLLinkGetData(lnk, Light, inClump); + } static Light *streamRead(Stream *stream); bool streamWrite(Stream *stream); uint32 streamGetSize(void); @@ -487,12 +507,17 @@ struct Atomic : PluginBase ObjectWithFrame object; Geometry *geometry; Clump *clump; + LLLink inClump; ObjPipeline *pipeline; - Atomic(void); - Atomic(Atomic *a); - ~Atomic(void); + // MEM create, clone, destroy + static Atomic *create(void); + Atomic *clone(void); + void destroy(void); void setFrame(Frame *f) { this->object.setFrame(f); } + static Atomic *fromClump(LLLink *lnk){ + return LLLinkGetData(lnk, Atomic, inClump); + } static Atomic *streamReadClump(Stream *stream, Frame **frameList, Geometry **geometryList); bool streamWriteClump(Stream *stream, @@ -510,31 +535,46 @@ void registerAtomicRightsPlugin(void); struct Clump : PluginBase { Object object; - int32 numAtomics; - Atomic **atomicList; - int32 numLights; - Light **lightList; - int32 numCameras; + LinkList atomics; + LinkList lights; // cameras not implemented - Clump(void); - Clump(Clump *c); - ~Clump(void); + // MEM create, clone, destroy + static Clump *create(void); + Clump *clone(void); + void destroy(void); + int32 countAtomics(void); + void addAtomic(Atomic *a){ + a->clump = this; + this->atomics.append(&a->inClump); + } + int32 countLights(void); + void addLight(Light *l){ + l->clump = this; + this->lights.append(&l->inClump); + } static Clump *streamRead(Stream *stream); bool streamWrite(Stream *stream); uint32 streamGetSize(void); void frameListStreamRead(Stream *stream, Frame ***flp, int32 *nf); void frameListStreamWrite(Stream *stream, Frame **flp, int32 nf); + }; struct TexDictionary : PluginBase { Object object; - Texture *first; + LinkList textures; - TexDictionary(void); - void add(Texture *tex); + // MEM create, destroy + static TexDictionary *create(void); + void destroy(void); + int32 count(void); + void add(Texture *t){ + t->dict = this; + this->textures.append(&t->inDict); + } Texture *find(const char *name); static TexDictionary *streamRead(Stream *stream); void streamWrite(Stream *stream); @@ -599,6 +639,7 @@ struct UVAnimCustomData struct UVAnimDictionary { + // TODO: linked list probably int32 numAnims; Animation **anims; diff --git a/src/rwplugin.h b/src/rwplugin.h index 9453384..c9bf186 100644 --- a/src/rwplugin.h +++ b/src/rwplugin.h @@ -205,15 +205,13 @@ PluginBase::getPluginOffset(uint32 id) template void* PluginBase::operator new(size_t) { - void *m = malloc(T::s_size); - if(!m) - throw std::bad_alloc(); - return m; + assert(0); + return NULL; } template void PluginBase::operator delete(void *p) { - free(p); + assert(0); } } diff --git a/src/xbox.cpp b/src/xbox.cpp index ec4dbe6..8d6e448 100644 --- a/src/xbox.cpp +++ b/src/xbox.cpp @@ -869,7 +869,7 @@ readNativeTexture(Stream *stream) assert(findChunk(stream, ID_STRUCT, NULL, &version)); assert(version >= 0x34001); assert(stream->readU32() == PLATFORM_XBOX); - Texture *tex = new Texture; + Texture *tex = Texture::create(NULL); // Texture tex->filterAddressing = stream->readU32(); @@ -891,7 +891,7 @@ readNativeTexture(Stream *stream) assert(unknownFlag == 0); Raster *raster; if(compression){ - raster = new Raster(width, height, depth, format | type | 0x80, PLATFORM_XBOX); + raster = Raster::create(width, height, depth, format | type | 0x80, PLATFORM_XBOX); XboxRaster *ras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset); ras->format = compression; ras->hasAlpha = hasAlpha; @@ -900,7 +900,7 @@ readNativeTexture(Stream *stream) ras->format); raster->flags &= ~0x80; }else - raster = new Raster(width, height, depth, format | type, PLATFORM_XBOX); + raster = Raster::create(width, height, depth, format | type, PLATFORM_XBOX); XboxRaster *ras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset); tex->raster = raster; diff --git a/tools/insttest/insttest.cpp b/tools/insttest/insttest.cpp index 6009db6..88071c4 100644 --- a/tools/insttest/insttest.cpp +++ b/tools/insttest/insttest.cpp @@ -132,8 +132,8 @@ main(int argc, char *argv[]) } if(uninstance) - for(int32 i = 0; i < c->numAtomics; i++){ - Atomic *a = c->atomicList[i]; + FORLIST(lnk, c->atomics){ + Atomic *a = Atomic::fromClump(lnk); ObjPipeline *p = a->getPipeline(); p->uninstance(a); if(outplatform != PLATFORM_PS2) @@ -144,8 +144,8 @@ main(int argc, char *argv[]) switchPipes(c, rw::platform); if(instance) - for(int32 i = 0; i < c->numAtomics; i++){ - Atomic *a = c->atomicList[i]; + FORLIST(lnk, c->atomics){ + Atomic *a = Atomic::fromClump(lnk); ObjPipeline *p = a->getPipeline(); p->instance(a); if(outplatform != PLATFORM_PS2) @@ -185,7 +185,7 @@ main(int argc, char *argv[]) // out.close(); // delete[] data; - delete c; + c->destroy(); return 0; } diff --git a/tools/rsltest/rsltest.cpp b/tools/rsltest/rsltest.cpp index 582e5b4..11b7297 100644 --- a/tools/rsltest/rsltest.cpp +++ b/tools/rsltest/rsltest.cpp @@ -71,7 +71,7 @@ mapID(int32 id) Frame* convertFrame(RslFrame *f) { - Frame *rwf = new Frame; + Frame *rwf = Frame::create(); rwf->matrix[0] = f->modelling.right.x; rwf->matrix[1] = f->modelling.right.y; rwf->matrix[2] = f->modelling.right.z; @@ -123,7 +123,7 @@ Material* convertMaterial(RslMaterial *m) { Material *rwm; - rwm = new Material; + rwm = Material::create(); rwm->color[0] = m->color.red; rwm->color[1] = m->color.green; @@ -300,9 +300,9 @@ convertMesh(Geometry *rwg, RslGeometry *g, int32 ii) Atomic* convertAtomic(RslAtomic *atomic) { - Atomic *rwa = new Atomic; + Atomic *rwa = Atomic::create(); RslGeometry *g = atomic->geometry; - Geometry *rwg = new Geometry(0, 0, 0); + Geometry *rwg = Geometry::create(0, 0, 0); rwa->geometry = rwg; rwg->numMaterials = g->matList.numMaterials; @@ -396,7 +396,7 @@ convertClump(RslClump *c) Atomic *rwa; rslFrameList frameList; - rwc = new Clump; + rwc = Clump::create(); rslFrameListInitialize(&frameList, (RslFrame*)c->object.parent); Frame **rwframes = new Frame*[frameList.numFrames]; for(int32 i = 0; i < frameList.numFrames; i++){ @@ -409,17 +409,15 @@ convertClump(RslClump *c) } rwc->object.parent = rwframes[0]; - rwc->numAtomics = RslClumpGetNumAtomics(c); - rwc->atomicList = new Atomic*[rwc->numAtomics]; - RslAtomic **alist = new RslAtomic*[rwc->numAtomics]; + int32 numAtomics = RslClumpGetNumAtomics(c); + RslAtomic **alist = new RslAtomic*[numAtomics]; RslAtomic **ap = &alist[0]; RslClumpForAllAtomics(c, collectAtomics, &ap); - for(int32 i = 0; i < rwc->numAtomics; i++){ + for(int32 i = 0; i < numAtomics; i++){ rwa = convertAtomic(alist[i]); - rwc->atomicList[i] = rwa; int32 fi = findPointer(alist[i]->object.object.parent, (void**)frameList.frames, frameList.numFrames); - rwa->object.parent = rwframes[fi]; - rwa->clump = rwc; + rwa->setFrame(rwframes[fi]); + rwc->addAtomic(rwa); } delete[] alist; @@ -614,14 +612,14 @@ RslTexture *dumpTextureCB(RslTexture *texture, void*) uint8 *palette = getPalettePS2(texture->raster); uint8 *texels = getTexelPS2(texture->raster, 0); printf(" %x %x %x %x %x %s\n", w, h, d, mip, swizmask, texture->name); - Image *img = new Image(w, h, 32); + Image *img = Image::create(w, h, 32); img->allocate(); convertTo32(img->pixels, palette, texels, w, h, d, swizmask&1); char *name = new char[strlen(texture->name)+5]; strcpy(name, texture->name); strcat(name, ".tga"); writeTGA(img, name); - delete img; + img->destroy(); delete[] name; return texture; } @@ -630,7 +628,7 @@ RslTexture* convertTexturePS2(RslTexture *texture, void *pData) { TexDictionary *rwtxd = (TexDictionary*)pData; - Texture *rwtex = new Texture; + Texture *rwtex = Texture::create(NULL); RslRasterPS2 *ras = &texture->raster->ps2; strncpy(rwtex->name, texture->name, 32); @@ -703,7 +701,7 @@ convertTexturePS2(RslTexture *texture, void *pData) fprintf(stderr, "unsupported depth %d\n", d); return NULL; } - Raster *rwras = new Raster(w, h, d == 4 ? 8 : d, format | 4, PLATFORM_D3D8); + Raster *rwras = Raster::create(w, h, d == 4 ? 8 : d, format | 4, PLATFORM_D3D8); d3d::D3dRaster *d3dras = PLUGINOFFSET(d3d::D3dRaster, rwras, d3d::nativeRasterOffset); int32 pallen = d == 4 ? 16 : @@ -744,7 +742,7 @@ convertTexturePS2(RslTexture *texture, void *pData) TexDictionary* convertTXD(RslTexDictionary *txd) { - TexDictionary *rwtxd = new TexDictionary; + TexDictionary *rwtxd = TexDictionary::create(); RslTexDictionaryForAllTextures(txd, convertTexturePS2, rwtxd); return rwtxd; } diff --git a/tools/txdwrite/txdwrite.cpp b/tools/txdwrite/txdwrite.cpp index 918fcc0..362de42 100644 --- a/tools/txdwrite/txdwrite.cpp +++ b/tools/txdwrite/txdwrite.cpp @@ -40,8 +40,8 @@ xboxToD3d8(Raster *raster) int32 format = raster->format; // format &= ~Raster::MIPMAP; if(ras->format){ - newras = new Raster(raster->width, raster->height, raster->depth, - format | raster->type | 0x80, PLATFORM_D3D8); + newras = Raster::create(raster->width, raster->height, raster->depth, + format | raster->type | 0x80, PLATFORM_D3D8); int32 dxt = 0; switch(ras->format){ case D3DFMT_DXT1: @@ -57,8 +57,8 @@ xboxToD3d8(Raster *raster) d3d::allocateDXT(newras, dxt, numLevels, ras->hasAlpha); }else{ printf("swizzled!\n"); - newras = new Raster(raster->width, raster->height, raster->depth, - format | raster->type, PLATFORM_D3D8); + newras = Raster::create(raster->width, raster->height, raster->depth, + format | raster->type, PLATFORM_D3D8); } if(raster->format & Raster::PAL4) @@ -145,8 +145,10 @@ main(int argc, char *argv[]) } if(outplatform == PLATFORM_D3D8) - for(Texture *tex = txd->first; tex; tex = tex->next) + FORLIST(lnk, txd->textures){ + Texture *tex = Texture::fromDict(lnk); tex->raster = xboxToD3d8(tex->raster); + } // for(Texture *tex = txd->first; tex; tex = tex->next) // tex->filterAddressing = (tex->filterAddressing&~0xF) | 0x2;