started moving to custom malloc/free

This commit is contained in:
aap 2017-08-24 15:10:34 +02:00
parent 6d38dea0d9
commit 040bb6cb51
22 changed files with 675 additions and 580 deletions

View File

@ -71,6 +71,7 @@ project "librw"
project "dumprwtree" project "dumprwtree"
kind "ConsoleApp" kind "ConsoleApp"
targetdir (Bindir) targetdir (Bindir)
removeplatforms { "*gl3", "*d3d9", "ps2" }
files { "tools/dumprwtree/*" } files { "tools/dumprwtree/*" }
includedirs { "." } includedirs { "." }
libdirs { Libdir } libdirs { Libdir }

View File

@ -8,10 +8,11 @@
#include "rwplg.h" #include "rwplg.h"
#include "rwpipeline.h" #include "rwpipeline.h"
#include "rwobjects.h" #include "rwobjects.h"
#include "rwengine.h"
#include "rwanim.h" #include "rwanim.h"
#include "rwplugins.h" #include "rwplugins.h"
#define PLUGIN_ID 0 #define PLUGIN_ID ID_ANIMANIMATION
namespace rw { namespace rw {
@ -55,7 +56,7 @@ Animation::create(AnimInterpolatorInfo *interpInfo, int32 numFrames,
int32 sz = sizeof(Animation) + int32 sz = sizeof(Animation) +
numFrames*interpInfo->animKeyFrameSize + numFrames*interpInfo->animKeyFrameSize +
interpInfo->customDataSize; interpInfo->customDataSize;
uint8 *data = (uint8*)malloc(sz); uint8 *data = (uint8*)rwMalloc(sz, MEMDUR_EVENT | ID_ANIMANIMATION);
if(data == nil){ if(data == nil){
RWERROR((ERR_ALLOC, sz)); RWERROR((ERR_ALLOC, sz));
return nil; return nil;
@ -75,7 +76,7 @@ Animation::create(AnimInterpolatorInfo *interpInfo, int32 numFrames,
void void
Animation::destroy(void) Animation::destroy(void)
{ {
free(this); rwFree(this);
} }
int32 int32
@ -179,7 +180,7 @@ AnimInterpolator::create(int32 numNodes, int32 maxFrameSize)
if(sizeof(void*) > 4) if(sizeof(void*) > 4)
realsz += 16; realsz += 16;
sz = sizeof(AnimInterpolator) + numNodes*realsz; sz = sizeof(AnimInterpolator) + numNodes*realsz;
interp = (AnimInterpolator*)malloc(sz); interp = (AnimInterpolator*)rwMalloc(sz, MEMDUR_EVENT | ID_ANIMANIMATION);
if(interp == nil){ if(interp == nil){
RWERROR((ERR_ALLOC, sz)); RWERROR((ERR_ALLOC, sz));
return nil; return nil;
@ -198,7 +199,7 @@ AnimInterpolator::create(int32 numNodes, int32 maxFrameSize)
void void
AnimInterpolator::destroy(void) AnimInterpolator::destroy(void)
{ {
free(this); rwFree(this);
} }
bool32 bool32

View File

@ -143,12 +143,12 @@ V3d::transformVectors(V3d *out, V3d *in, int32 n, Matrix *m)
// Matrix // Matrix
// //
static Matrix::Tolerance matrixDefaultTolerance = { 0.01, 0.01, 0.01 }; static Matrix::Tolerance matrixDefaultTolerance = { 0.01f, 0.01f, 0.01f };
Matrix* Matrix*
Matrix::create(void) Matrix::create(void)
{ {
Matrix *m = (Matrix*)malloc(sizeof(Matrix)); Matrix *m = (Matrix*)rwMalloc(sizeof(Matrix), MEMDUR_EVENT | ID_MATRIX);
m->setIdentity(); m->setIdentity();
return m; return m;
} }
@ -156,7 +156,7 @@ Matrix::create(void)
void void
Matrix::destroy(void) Matrix::destroy(void)
{ {
free(this); rwFree(this);
} }
void void
@ -770,13 +770,13 @@ StreamFile::close(void)
uint32 uint32
StreamFile::write(const void *data, uint32 length) StreamFile::write(const void *data, uint32 length)
{ {
return fwrite(data, length, 1, this->file); return (uint32)fwrite(data, length, 1, this->file);
} }
uint32 uint32
StreamFile::read(void *data, uint32 length) StreamFile::read(void *data, uint32 length)
{ {
return fread(data, length, 1, this->file); return (uint32)fread(data, length, 1, this->file);
} }
void void

View File

@ -8,7 +8,7 @@
#include "rwobjects.h" #include "rwobjects.h"
#include "rwengine.h" #include "rwengine.h"
#define PLUGIN_ID 0 #define PLUGIN_ID ID_CAMERA
namespace rw { namespace rw {
@ -268,7 +268,7 @@ worldCameraSync(ObjectWithFrame *obj)
Camera* Camera*
Camera::create(void) Camera::create(void)
{ {
Camera *cam = (Camera*)malloc(s_plglist.size); Camera *cam = (Camera*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_CAMERA);
if(cam == nil){ if(cam == nil){
RWERROR((ERR_ALLOC, s_plglist.size)); RWERROR((ERR_ALLOC, s_plglist.size));
return nil; return nil;
@ -325,7 +325,7 @@ Camera::destroy(void)
s_plglist.destruct(this); s_plglist.destruct(this);
if(this->clump) if(this->clump)
this->inClump.remove(); this->inClump.remove();
free(this); rwFree(this);
} }
void void

View File

@ -23,7 +23,7 @@ PluginList Atomic::s_plglist = { sizeof(Atomic), sizeof(Atomic), nil, nil };
Clump* Clump*
Clump::create(void) Clump::create(void)
{ {
Clump *clump = (Clump*)malloc(s_plglist.size); Clump *clump = (Clump*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_CLUMP);
if(clump == nil){ if(clump == nil){
RWERROR((ERR_ALLOC, s_plglist.size)); RWERROR((ERR_ALLOC, s_plglist.size));
return nil; return nil;
@ -66,7 +66,7 @@ Clump::destroy(void)
Camera::fromClump(lnk)->destroy(); Camera::fromClump(lnk)->destroy();
if(f = this->getFrame(), f) if(f = this->getFrame(), f)
f->destroyHierarchy(); f->destroyHierarchy();
free(this); rwFree(this);
} }
Clump* Clump*
@ -120,7 +120,7 @@ Clump::streamRead(Stream *stream)
numGeometries = stream->readI32(); numGeometries = stream->readI32();
if(numGeometries){ if(numGeometries){
size_t sz = numGeometries*sizeof(Geometry*); size_t sz = numGeometries*sizeof(Geometry*);
geometryList = (Geometry**)malloc(sz); geometryList = (Geometry**)rwMalloc(sz, MEMDUR_FUNCTION | ID_CLUMP);
if(geometryList == nil){ if(geometryList == nil){
RWERROR((ERR_ALLOC, sz)); RWERROR((ERR_ALLOC, sz));
goto fail; goto fail;
@ -193,8 +193,8 @@ Clump::streamRead(Stream *stream)
for(int32 i = 0; i < numGeometries; i++) for(int32 i = 0; i < numGeometries; i++)
if(geometryList[i]) if(geometryList[i])
geometryList[i]->destroy(); geometryList[i]->destroy();
free(geometryList); rwFree(geometryList);
free(frmlst.frames); rwFree(frmlst.frames);
if(s_plglist.streamRead(stream, clump)) if(s_plglist.streamRead(stream, clump))
return clump; return clump;
@ -202,9 +202,9 @@ failgeo:
for(int32 i = 0; i < numGeometries; i++) for(int32 i = 0; i < numGeometries; i++)
if(geometryList[i]) if(geometryList[i])
geometryList[i]->destroy(); geometryList[i]->destroy();
free(geometryList); rwFree(geometryList);
fail: fail:
free(frmlst.frames); rwFree(frmlst.frames);
clump->destroy(); clump->destroy();
return nil; return nil;
} }
@ -224,7 +224,7 @@ Clump::streamWrite(Stream *stream)
FrameList_ frmlst; FrameList_ frmlst;
frmlst.numFrames = this->getFrame()->count(); frmlst.numFrames = this->getFrame()->count();
frmlst.frames = (Frame**)malloc(frmlst.numFrames*sizeof(Frame*)); frmlst.frames = (Frame**)rwMalloc(frmlst.numFrames*sizeof(Frame*), MEMDUR_FUNCTION | ID_CLUMP);
makeFrameList(this->getFrame(), frmlst.frames); makeFrameList(this->getFrame(), frmlst.frames);
frmlst.streamWrite(stream); frmlst.streamWrite(stream);
@ -262,7 +262,7 @@ Clump::streamWrite(Stream *stream)
c->streamWrite(stream); c->streamWrite(stream);
} }
free(frmlst.frames); rwFree(frmlst.frames);
s_plglist.streamWrite(stream, this); s_plglist.streamWrite(stream, this);
return true; return true;
@ -336,7 +336,7 @@ worldAtomicSync(ObjectWithFrame *obj)
Atomic* Atomic*
Atomic::create(void) Atomic::create(void)
{ {
Atomic *atomic = (Atomic*)malloc(s_plglist.size); Atomic *atomic = (Atomic*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_ATOMIC);
if(atomic == nil){ if(atomic == nil){
RWERROR((ERR_ALLOC, s_plglist.size)); RWERROR((ERR_ALLOC, s_plglist.size));
return nil; return nil;
@ -389,7 +389,7 @@ Atomic::destroy(void)
if(this->clump) if(this->clump)
this->inClump.remove(); this->inClump.remove();
this->setFrame(nil); this->setFrame(nil);
free(this); rwFree(this);
} }
void void

View File

@ -23,6 +23,10 @@ namespace rw {
Engine *engine; Engine *engine;
PluginList Driver::s_plglist[NUM_PLATFORMS]; PluginList Driver::s_plglist[NUM_PLATFORMS];
Engine::State Engine::state = Dead; Engine::State Engine::state = Dead;
MemoryFunctions Engine::memfuncs;
void *malloc_h(size_t sz, uint32 hint) { return malloc(sz); }
void *realloc_h(void *p, size_t sz, uint32 hint) { return realloc(p, sz); }
// This function mainly registers engine plugins // This function mainly registers engine plugins
// RW initializes memory related things here too and // RW initializes memory related things here too and
@ -36,6 +40,10 @@ Engine::init(void)
return 0; return 0;
} }
memfuncs.malloc = malloc_h;
memfuncs.realloc = realloc_h;
memfuncs.free = free;
PluginList init = { sizeof(Driver), sizeof(Driver), nil, nil }; PluginList init = { sizeof(Driver), sizeof(Driver), nil, nil };
for(uint i = 0; i < NUM_PLATFORMS; i++) for(uint i = 0; i < NUM_PLATFORMS; i++)
Driver::s_plglist[i] = init; Driver::s_plglist[i] = init;
@ -64,7 +72,7 @@ Engine::open(void)
} }
// Allocate engine // Allocate engine
engine = (Engine*)malloc(sizeof(Engine)); engine = (Engine*)rwMalloc(sizeof(Engine), MEMDUR_GLOBAL);
engine->currentCamera = nil; engine->currentCamera = nil;
engine->currentWorld = nil; engine->currentWorld = nil;
engine->currentTexDictionary = nil; engine->currentTexDictionary = nil;
@ -133,11 +141,14 @@ Engine::start(EngineStartParams *p)
void void
Engine::term(void) Engine::term(void)
{ {
// TODO
} }
void void
Engine::close(void) Engine::close(void)
{ {
// TODO
rwFree(engine);
} }
void void

View File

@ -6,8 +6,9 @@
#include "rwplg.h" #include "rwplg.h"
#include "rwpipeline.h" #include "rwpipeline.h"
#include "rwobjects.h" #include "rwobjects.h"
#include "rwengine.h"
#define PLUGIN_ID 0 #define PLUGIN_ID ID_FRAMELIST
namespace rw { namespace rw {
@ -17,7 +18,7 @@ PluginList Frame::s_plglist = { sizeof(Frame), sizeof(Frame), nil, nil };
Frame* Frame*
Frame::create(void) Frame::create(void)
{ {
Frame *f = (Frame*)malloc(s_plglist.size); Frame *f = (Frame*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_FRAMELIST);
if(f == nil){ if(f == nil){
RWERROR((ERR_ALLOC, s_plglist.size)); RWERROR((ERR_ALLOC, s_plglist.size));
return nil; return nil;
@ -51,7 +52,7 @@ Frame::destroy(void)
this->inDirtyList.remove(); this->inDirtyList.remove();
for(Frame *f = this->child; f; f = f->next) for(Frame *f = this->child; f; f = f->next)
f->object.parent = nil; f->object.parent = nil;
free(this); rwFree(this);
} }
void void
@ -65,7 +66,7 @@ Frame::destroyHierarchy(void)
s_plglist.destruct(this); s_plglist.destruct(this);
if(this->object.privateFlags & Frame::HIERARCHYSYNC) if(this->object.privateFlags & Frame::HIERARCHYSYNC)
this->inDirtyList.remove(); this->inDirtyList.remove();
free(this); rwFree(this);
} }
Frame* Frame*
@ -343,7 +344,7 @@ FrameList_::streamRead(Stream *stream)
return nil; return nil;
} }
this->numFrames = stream->readI32(); this->numFrames = stream->readI32();
this->frames = (Frame**)malloc(this->numFrames*sizeof(Frame*)); this->frames = (Frame**)rwMalloc(this->numFrames*sizeof(Frame*), MEMDUR_EVENT | ID_FRAMELIST);
if(this->frames == nil){ if(this->frames == nil){
RWERROR((ERR_ALLOC, this->numFrames*sizeof(Frame*))); RWERROR((ERR_ALLOC, this->numFrames*sizeof(Frame*)));
return nil; return nil;
@ -354,7 +355,7 @@ FrameList_::streamRead(Stream *stream)
this->frames[i] = f = Frame::create(); this->frames[i] = f = Frame::create();
if(f == nil){ if(f == nil){
// TODO: clean up frames? // TODO: clean up frames?
free(this->frames); rwFree(this->frames);
return nil; return nil;
} }
f->matrix.right = buf.right; f->matrix.right = buf.right;

View File

@ -9,8 +9,9 @@
#include "rwplg.h" #include "rwplg.h"
#include "rwpipeline.h" #include "rwpipeline.h"
#include "rwobjects.h" #include "rwobjects.h"
#include "rwengine.h"
#define PLUGIN_ID 2 #define PLUGIN_ID ID_GEOMETRY
namespace rw { namespace rw {
@ -23,7 +24,7 @@ SurfaceProperties defaultSurfaceProps = { 1.0f, 1.0f, 1.0f };
Geometry* Geometry*
Geometry::create(int32 numVerts, int32 numTris, uint32 flags) Geometry::create(int32 numVerts, int32 numTris, uint32 flags)
{ {
Geometry *geo = (Geometry*)malloc(s_plglist.size); Geometry *geo = (Geometry*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_GEOMETRY);
if(geo == nil){ if(geo == nil){
RWERROR((ERR_ALLOC, s_plglist.size)); RWERROR((ERR_ALLOC, s_plglist.size));
return nil; return nil;
@ -90,7 +91,7 @@ Geometry::destroy(void)
delete[] this->morphTargets; delete[] this->morphTargets;
delete this->meshHeader; delete this->meshHeader;
this->matList.deinit(); this->matList.deinit();
free(this); rwFree(this);
} }
} }
@ -269,7 +270,8 @@ Geometry::addMorphTargets(int32 n)
{ {
if(n == 0) if(n == 0)
return; return;
MorphTarget *morphTargets = new MorphTarget[this->numMorphTargets+n]; n += this->numMorphTargets;
MorphTarget *morphTargets = new MorphTarget[n];
memcpy(morphTargets, this->morphTargets, memcpy(morphTargets, this->morphTargets,
this->numMorphTargets*sizeof(MorphTarget)); this->numMorphTargets*sizeof(MorphTarget));
delete[] this->morphTargets; delete[] this->morphTargets;
@ -284,7 +286,7 @@ Geometry::addMorphTargets(int32 n)
m->normals = new V3d[this->numVertices]; m->normals = new V3d[this->numVertices];
} }
} }
this->numMorphTargets += n; this->numMorphTargets = n;
} }
void void
@ -332,11 +334,12 @@ Geometry::allocateData(void)
for(int32 i = 0; i < this->numTexCoordSets; i++) for(int32 i = 0; i < this->numTexCoordSets; i++)
this->texCoords[i] = this->texCoords[i] =
new TexCoords[this->numVertices]; new TexCoords[this->numVertices];
MorphTarget *m = this->morphTargets; for(int32 i = 0; i < this->numMorphTargets; i++){
MorphTarget *m = &morphTargets[i];
m->vertices = new V3d[this->numVertices]; m->vertices = new V3d[this->numVertices];
if(this->flags & NORMALS) if(this->flags & NORMALS)
m->normals = new V3d[this->numVertices]; m->normals = new V3d[this->numVertices];
// TODO: morph targets (who cares anyway?) }
} }
static int static int
@ -553,7 +556,7 @@ Geometry::removeUnusedMaterials(void)
} }
for(int32 i = 0; i < this->matList.numMaterials; i++) for(int32 i = 0; i < this->matList.numMaterials; i++)
this->matList.materials[i]->destroy(); this->matList.materials[i]->destroy();
free(this->matList.materials); rwFree(this->matList.materials);
this->matList.materials = materials; this->matList.materials = materials;
this->matList.space = this->matList.numMaterials; this->matList.space = this->matList.numMaterials;
this->matList.numMaterials = numMaterials; this->matList.numMaterials = numMaterials;
@ -596,6 +599,8 @@ Geometry::removeUnusedMaterials(void)
// //
// MaterialList // MaterialList
// //
#undef PLUGIN_ID
#define PLUGIN_ID ID_MATERIAL
void void
MaterialList::init(void) MaterialList::init(void)
@ -611,7 +616,7 @@ MaterialList::deinit(void)
if(this->materials){ if(this->materials){
for(int32 i = 0; i < this->numMaterials; i++) for(int32 i = 0; i < this->numMaterials; i++)
this->materials[i]->destroy(); this->materials[i]->destroy();
free(this->materials); rwFree(this->materials);
} }
} }
@ -623,10 +628,12 @@ MaterialList::appendMaterial(Material *mat)
if(this->numMaterials >= this->space){ if(this->numMaterials >= this->space){
space = this->space + 20; space = this->space + 20;
if(this->materials) if(this->materials)
ml = (Material**)realloc(this->materials, ml = (Material**)rwRealloc(this->materials,
space*sizeof(Material*)); space*sizeof(Material*),
MEMDUR_EVENT | ID_MATERIAL);
else else
ml = (Material**)malloc(space*sizeof(Material*)); ml = (Material**)rwMalloc(space*sizeof(Material*),
MEMDUR_EVENT | ID_MATERIAL);
if(ml == nil) if(ml == nil)
return -1; return -1;
this->space = space; this->space = space;
@ -659,12 +666,12 @@ MaterialList::streamRead(Stream *stream, MaterialList *matlist)
numMat = stream->readI32(); numMat = stream->readI32();
if(numMat == 0) if(numMat == 0)
return matlist; return matlist;
matlist->materials = (Material**)malloc(numMat*sizeof(Material*)); matlist->materials = (Material**)rwMalloc(numMat*sizeof(Material*), MEMDUR_EVENT | ID_MATERIAL);
if(matlist->materials == nil) if(matlist->materials == nil)
goto fail; goto fail;
matlist->space = numMat; matlist->space = numMat;
indices = (int32*)malloc(numMat*4); indices = (int32*)rwMalloc(numMat*4, MEMDUR_FUNCTION | ID_MATERIAL);
stream->read(indices, numMat*4); stream->read(indices, numMat*4);
Material *m; Material *m;
@ -684,10 +691,10 @@ MaterialList::streamRead(Stream *stream, MaterialList *matlist)
matlist->appendMaterial(m); matlist->appendMaterial(m);
m->destroy(); m->destroy();
} }
free(indices); rwFree(indices);
return matlist; return matlist;
fail: fail:
free(indices); rwFree(indices);
matlist->deinit(); matlist->deinit();
return nil; return nil;
} }
@ -741,7 +748,7 @@ MaterialList::streamGetSize(void)
Material* Material*
Material::create(void) Material::create(void)
{ {
Material *mat = (Material*)malloc(s_plglist.size); Material *mat = (Material*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_MATERIAL);
if(mat == nil){ if(mat == nil){
RWERROR((ERR_ALLOC, s_plglist.size)); RWERROR((ERR_ALLOC, s_plglist.size));
return nil; return nil;
@ -780,7 +787,7 @@ Material::destroy(void)
s_plglist.destruct(this); s_plglist.destruct(this);
if(this->texture) if(this->texture)
this->texture->destroy(); this->texture->destroy();
free(this); rwFree(this);
} }
} }

View File

@ -74,7 +74,7 @@ loadfile(const char *path)
} }
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
len = ftell(f); len = ftell(f);
buf = (char*)malloc(len+1); buf = (char*)rwMalloc(len+1, MEMDUR_EVENT);
rewind(f); rewind(f);
fread(buf, 1, len, f); fread(buf, 1, len, f);
buf[len] = '\0'; buf[len] = '\0';
@ -97,10 +97,10 @@ compileshader(GLenum type, const char *src, GLuint *shader)
fprintf(stderr, "Error in %s shader\n", fprintf(stderr, "Error in %s shader\n",
type == GL_VERTEX_SHADER ? "vertex" : "fragment"); type == GL_VERTEX_SHADER ? "vertex" : "fragment");
glGetShaderiv(shdr, GL_INFO_LOG_LENGTH, &len); glGetShaderiv(shdr, GL_INFO_LOG_LENGTH, &len);
log = (char*)malloc(len); log = (char*)rwMalloc(len, MEMDUR_FUNCTION);
glGetShaderInfoLog(shdr, len, nil, log); glGetShaderInfoLog(shdr, len, nil, log);
fprintf(stderr, "%s\n", log); fprintf(stderr, "%s\n", log);
free(log); rwFree(log);
return 1; return 1;
} }
*shader = shdr; *shader = shdr;
@ -123,10 +123,10 @@ linkprogram(GLint vs, GLint fs, GLuint *program)
if(!success){ if(!success){
fprintf(stderr, "Error in program\n"); fprintf(stderr, "Error in program\n");
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len); glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);
log = (char*)malloc(len); log = (char*)rwMalloc(len, MEMDUR_FUNCTION);
glGetProgramInfoLog(prog, len, nil, log); glGetProgramInfoLog(prog, len, nil, log);
fprintf(stderr, "%s\n", log); fprintf(stderr, "%s\n", log);
free(log); rwFree(log);
return 1; return 1;
} }
*program = prog; *program = prog;
@ -181,8 +181,8 @@ Shader::fromFiles(const char *vspath, const char *fspath)
vsrc = loadfile(vspath); vsrc = loadfile(vspath);
fsrc = loadfile(fspath); fsrc = loadfile(fspath);
Shader *s = fromStrings(vsrc, fsrc); Shader *s = fromStrings(vsrc, fsrc);
free(vsrc); rwFree(vsrc);
free(fsrc); rwFree(fsrc);
return s; return s;
} }

View File

@ -30,7 +30,11 @@ HAnimHierarchy*
HAnimHierarchy::create(int32 numNodes, int32 *nodeFlags, int32 *nodeIDs, HAnimHierarchy::create(int32 numNodes, int32 *nodeFlags, int32 *nodeIDs,
int32 flags, int32 maxKeySize) int32 flags, int32 maxKeySize)
{ {
HAnimHierarchy *hier = (HAnimHierarchy*)malloc(sizeof(*hier)); HAnimHierarchy *hier = (HAnimHierarchy*)rwMalloc(sizeof(*hier), MEMDUR_EVENT | ID_HANIM);
if(hier == nil){
RWERROR((ERR_ALLOC, sizeof(*hier)));
return nil;
}
hier->currentAnim = AnimInterpolator::create(numNodes, maxKeySize); hier->currentAnim = AnimInterpolator::create(numNodes, maxKeySize);
hier->numNodes = numNodes; hier->numNodes = numNodes;
@ -61,7 +65,7 @@ HAnimHierarchy::destroy(void)
{ {
delete[] (uint8*)this->matricesUnaligned; delete[] (uint8*)this->matricesUnaligned;
delete[] this->nodeInfo; delete[] this->nodeInfo;
free(this); rwFree(this);
} }
static Frame* static Frame*
@ -313,10 +317,10 @@ assert(t >= in1->time && t <= in2->time);
void void
registerHAnimPlugin(void) registerHAnimPlugin(void)
{ {
hAnimOffset = Frame::registerPlugin(sizeof(HAnimData), ID_HANIMPLUGIN, hAnimOffset = Frame::registerPlugin(sizeof(HAnimData), ID_HANIM,
createHAnim, createHAnim,
destroyHAnim, copyHAnim); destroyHAnim, copyHAnim);
Frame::registerPluginStream(ID_HANIMPLUGIN, Frame::registerPluginStream(ID_HANIM,
readHAnim, readHAnim,
writeHAnim, writeHAnim,
getSizeHAnim); getSizeHAnim);

View File

@ -15,387 +15,16 @@
#include "d3d/rwd3d8.h" #include "d3d/rwd3d8.h"
#include "d3d/rwd3d9.h" #include "d3d/rwd3d9.h"
#ifdef _WIN32 #define PLUGIN_ID ID_IMAGE
/* srsly? */
#define strdup _strdup
#endif
#define PLUGIN_ID 0
namespace rw { namespace rw {
PluginList TexDictionary::s_plglist = { sizeof(TexDictionary), sizeof(TexDictionary), nil, nil };
PluginList Texture::s_plglist = { sizeof(Texture), sizeof(Texture), nil, nil };
PluginList Raster::s_plglist = { sizeof(Raster), sizeof(Raster), nil, nil };
//
// TexDictionary
//
TexDictionary*
TexDictionary::create(void)
{
TexDictionary *dict = (TexDictionary*)malloc(s_plglist.size);
if(dict == nil){
RWERROR((ERR_ALLOC, s_plglist.size));
return nil;
}
dict->object.init(TexDictionary::ID, 0);
dict->textures.init();
s_plglist.construct(dict);
return dict;
}
void
TexDictionary::destroy(void)
{
if(engine->currentTexDictionary == this)
engine->currentTexDictionary = nil;
FORLIST(lnk, this->textures)
Texture::fromDict(lnk)->destroy();
s_plglist.destruct(this);
free(this);
}
void
TexDictionary::add(Texture *t)
{
if(t->dict)
t->inDict.remove();
t->dict = this;
this->textures.append(&t->inDict);
}
Texture*
TexDictionary::find(const char *name)
{
FORLIST(lnk, this->textures){
Texture *tex = Texture::fromDict(lnk);
if(strncmp_ci(tex->name, name, 32) == 0)
return tex;
}
return nil;
}
TexDictionary*
TexDictionary::streamRead(Stream *stream)
{
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
int32 numTex = stream->readI16();
stream->readI16(); // device id (0 = unknown, 1 = d3d8, 2 = d3d9,
// 3 = gcn, 4 = null, 5 = opengl,
// 6 = ps2, 7 = softras, 8 = xbox, 9 = psp)
TexDictionary *txd = TexDictionary::create();
if(txd == nil)
return nil;
Texture *tex;
for(int32 i = 0; i < numTex; i++){
if(!findChunk(stream, ID_TEXTURENATIVE, nil, nil)){
RWERROR((ERR_CHUNK, "TEXTURENATIVE"));
goto fail;
}
tex = Texture::streamReadNative(stream);
if(tex == nil)
goto fail;
Texture::s_plglist.streamRead(stream, tex);
txd->add(tex);
}
if(s_plglist.streamRead(stream, txd))
return txd;
fail:
txd->destroy();
return nil;
}
void
TexDictionary::streamWrite(Stream *stream)
{
writeChunkHeader(stream, ID_TEXDICTIONARY, this->streamGetSize());
writeChunkHeader(stream, ID_STRUCT, 4);
int32 numTex = this->count();
stream->writeI16(numTex);
stream->writeI16(0);
FORLIST(lnk, this->textures){
Texture *tex = Texture::fromDict(lnk);
uint32 sz = tex->streamGetSizeNative();
sz += 12 + Texture::s_plglist.streamGetSize(tex);
writeChunkHeader(stream, ID_TEXTURENATIVE, sz);
tex->streamWriteNative(stream);
Texture::s_plglist.streamWrite(stream, tex);
}
s_plglist.streamWrite(stream, this);
}
uint32
TexDictionary::streamGetSize(void)
{
uint32 size = 12 + 4;
FORLIST(lnk, this->textures){
Texture *tex = Texture::fromDict(lnk);
size += 12 + tex->streamGetSizeNative();
size += 12 + Texture::s_plglist.streamGetSize(tex);
}
size += 12 + s_plglist.streamGetSize(this);
return size;
}
void
TexDictionary::setCurrent(TexDictionary *txd)
{
engine->currentTexDictionary = txd;
}
TexDictionary*
TexDictionary::getCurrent(void)
{
return engine->currentTexDictionary;
}
//
// Texture
//
static Texture *defaultFindCB(const char *name);
static Texture *defaultReadCB(const char *name, const char *mask);
Texture *(*Texture::findCB)(const char *name) = defaultFindCB;
Texture *(*Texture::readCB)(const char *name, const char *mask) = defaultReadCB;
Texture*
Texture::create(Raster *raster)
{
Texture *tex = (Texture*)malloc(s_plglist.size);
if(tex == nil){
RWERROR((ERR_ALLOC, s_plglist.size));
return nil;
}
tex->dict = nil;
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;
s_plglist.construct(tex);
return tex;
}
void
Texture::destroy(void)
{
this->refCount--;
if(this->refCount <= 0){
s_plglist.destruct(this);
if(this->dict)
this->inDict.remove();
if(this->raster)
this->raster->destroy();
free(this);
}
}
static Texture*
defaultFindCB(const char *name)
{
if(engine->currentTexDictionary)
return engine->currentTexDictionary->find(name);
// TODO: RW searches *all* TXDs otherwise
return nil;
}
static Texture*
defaultReadCB(const char *name, const char *mask)
{
Texture *tex;
Image *img;
char *n = (char*)malloc(strlen(name) + 5);
strcpy(n, name);
strcat(n, ".tga");
img = readTGA(n);
free(n);
if(img){
tex = Texture::create(Raster::createFromImage(img));
strncpy(tex->name, name, 32);
if(mask)
strncpy(tex->mask, mask, 32);
img->destroy();
return tex;
}else
return nil;
}
Texture*
Texture::read(const char *name, const char *mask)
{
(void)mask;
Raster *raster = nil;
Texture *tex;
if(tex = Texture::findCB(name), tex){
tex->refCount++;
return tex;
}
if(engine->loadTextures){
tex = Texture::readCB(name, mask);
if(tex == nil)
goto dummytex;
}else dummytex: if(engine->makeDummies){
tex = Texture::create(nil);
if(tex == nil)
return nil;
strncpy(tex->name, name, 32);
if(mask)
strncpy(tex->mask, mask, 32);
raster = Raster::create(0, 0, 0, Raster::DONTALLOCATE);
tex->raster = raster;
}
if(tex && engine->currentTexDictionary){
if(tex->dict)
tex->inDict.remove();
engine->currentTexDictionary->add(tex);
}
return tex;
}
Texture*
Texture::streamRead(Stream *stream)
{
uint32 length;
char name[128], mask[128];
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
uint32 filterAddressing = stream->readU32();
// TODO: if V addressing is 0, copy U
// if using mipmap filter mode, set automipmapping,
// if 0x10000 is set, set mipmapping
if(!findChunk(stream, ID_STRING, &length, nil)){
RWERROR((ERR_CHUNK, "STRING"));
return nil;
}
stream->read(name, length);
if(!findChunk(stream, ID_STRING, &length, nil)){
RWERROR((ERR_CHUNK, "STRING"));
return nil;
}
stream->read(mask, length);
Texture *tex = Texture::read(name, mask);
if(tex == nil)
return nil;
if(tex->refCount == 1)
tex->filterAddressing = filterAddressing;
if(s_plglist.streamRead(stream, tex))
return tex;
tex->destroy();
return nil;
}
bool
Texture::streamWrite(Stream *stream)
{
int size;
char buf[36];
writeChunkHeader(stream, ID_TEXTURE, this->streamGetSize());
writeChunkHeader(stream, ID_STRUCT, 4);
stream->writeU32(this->filterAddressing);
memset(buf, 0, 36);
strncpy(buf, this->name, 32);
size = strlen(buf)+4 & ~3;
writeChunkHeader(stream, ID_STRING, size);
stream->write(buf, size);
memset(buf, 0, 36);
strncpy(buf, this->mask, 32);
size = strlen(buf)+4 & ~3;
writeChunkHeader(stream, ID_STRING, size);
stream->write(buf, size);
s_plglist.streamWrite(stream, this);
return true;
}
uint32
Texture::streamGetSize(void)
{
uint32 size = 0;
size += 12 + 4;
size += 12 + 12;
size += strlen(this->name)+4 & ~3;
size += strlen(this->mask)+4 & ~3;
size += 12 + s_plglist.streamGetSize(this);
return size;
}
Texture*
Texture::streamReadNative(Stream *stream)
{
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
uint32 platform = stream->readU32();
stream->seek(-16);
if(platform == FOURCC_PS2)
return ps2::readNativeTexture(stream);
if(platform == PLATFORM_D3D8)
return d3d8::readNativeTexture(stream);
if(platform == PLATFORM_D3D9)
return d3d9::readNativeTexture(stream);
if(platform == PLATFORM_XBOX)
return xbox::readNativeTexture(stream);
assert(0 && "unsupported platform");
return nil;
}
void
Texture::streamWriteNative(Stream *stream)
{
if(this->raster->platform == PLATFORM_PS2)
ps2::writeNativeTexture(this, stream);
else if(this->raster->platform == PLATFORM_D3D8)
d3d8::writeNativeTexture(this, stream);
else if(this->raster->platform == PLATFORM_D3D9)
d3d9::writeNativeTexture(this, stream);
else if(this->raster->platform == PLATFORM_XBOX)
xbox::writeNativeTexture(this, stream);
else
assert(0 && "unsupported platform");
}
uint32
Texture::streamGetSizeNative(void)
{
if(this->raster->platform == PLATFORM_PS2)
return ps2::getSizeNativeTexture(this);
if(this->raster->platform == PLATFORM_D3D8)
return d3d8::getSizeNativeTexture(this);
if(this->raster->platform == PLATFORM_D3D9)
return d3d9::getSizeNativeTexture(this);
if(this->raster->platform == PLATFORM_XBOX)
return xbox::getSizeNativeTexture(this);
assert(0 && "unsupported platform");
return 0;
}
//
// Image
//
// TODO: full 16 bit support // TODO: full 16 bit support
Image* Image*
Image::create(int32 width, int32 height, int32 depth) Image::create(int32 width, int32 height, int32 depth)
{ {
Image *img = (Image*)malloc(sizeof(Image)); Image *img = (Image*)rwMalloc(sizeof(Image), MEMDUR_EVENT | ID_IMAGE);
if(img == nil){ if(img == nil){
RWERROR((ERR_ALLOC, sizeof(Image))); RWERROR((ERR_ALLOC, sizeof(Image)));
return nil; return nil;
@ -414,7 +43,7 @@ void
Image::destroy(void) Image::destroy(void)
{ {
this->free(); this->free();
::free(this); rwFree(this);
} }
void void
@ -836,14 +465,25 @@ Image::extractMask(void)
static char *searchPaths = nil; static char *searchPaths = nil;
int numSearchPaths = 0; int numSearchPaths = 0;
static char*
rwstrdup(const char *s)
{
char *t;
int32 len = strlen(s)+1;
t = (char*)rwMalloc(len, MEMDUR_EVENT);
if(t)
memcpy(t, s, len);
return t;
}
void void
Image::setSearchPath(const char *path) Image::setSearchPath(const char *path)
{ {
char *p, *end; char *p, *end;
::free(searchPaths); rwFree(searchPaths);
numSearchPaths = 0; numSearchPaths = 0;
if(path) if(path)
searchPaths = p = strdup(path); searchPaths = p = rwstrdup(path);
else{ else{
searchPaths = nil; searchPaths = nil;
return; return;
@ -878,12 +518,12 @@ Image::getFilename(const char *name)
if(f){ if(f){
fclose(f); fclose(f);
printf("found %s\n", name); printf("found %s\n", name);
return strdup(name); return rwstrdup(name);
} }
return nil; return nil;
}else }else
for(int i = 0; i < numSearchPaths; i++){ for(int i = 0; i < numSearchPaths; i++){
s = (char*)malloc(strlen(p)+len); s = (char*)rwMalloc(strlen(p)+len, MEMDUR_EVENT | ID_IMAGE);
if(s == nil){ if(s == nil){
RWERROR((ERR_ALLOC, strlen(p)+len)); RWERROR((ERR_ALLOC, strlen(p)+len));
return nil; return nil;
@ -896,88 +536,10 @@ Image::getFilename(const char *name)
printf("found %s\n", name); printf("found %s\n", name);
return s; return s;
} }
::free(s); rwFree(s);
p += strlen(p) + 1; p += strlen(p) + 1;
} }
return nil; return nil;
} }
//
// Raster
//
Raster*
Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platform)
{
// TODO: pass arguments through to the driver and create the raster there
Raster *raster = (Raster*)malloc(s_plglist.size);
assert(raster != nil);
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->pixels = raster->palette = nil;
s_plglist.construct(raster);
// printf("%d %d %d %d\n", raster->type, raster->width, raster->height, raster->depth);
engine->driver[raster->platform]->rasterCreate(raster);
return raster;
}
void
Raster::destroy(void)
{
s_plglist.destruct(this);
// delete[] this->texels;
// delete[] this->palette;
free(this);
}
uint8*
Raster::lock(int32 level)
{
return engine->driver[this->platform]->rasterLock(this, level);
}
void
Raster::unlock(int32 level)
{
engine->driver[this->platform]->rasterUnlock(this, level);
}
int32
Raster::getNumLevels(void)
{
return engine->driver[this->platform]->rasterNumLevels(this);
}
int32
Raster::calculateNumLevels(int32 width, int32 height)
{
int32 size = width >= height ? width : height;
int32 n;
for(n = 0; size != 0; n++)
size /= 2;
return n;
}
Raster*
Raster::createFromImage(Image *image, int32 platform)
{
Raster *raster = Raster::create(image->width, image->height,
image->depth, TEXTURE | DONTALLOCATE,
platform);
engine->driver[raster->platform]->rasterFromImage(raster, image);
return raster;
}
Image*
Raster::toImage(void)
{
return engine->driver[this->platform]->rasterToImage(this);
}
} }

View File

@ -6,8 +6,9 @@
#include "rwplg.h" #include "rwplg.h"
#include "rwpipeline.h" #include "rwpipeline.h"
#include "rwobjects.h" #include "rwobjects.h"
#include "rwengine.h"
#define PLUGIN_ID 2 #define PLUGIN_ID ID_LIGHT
namespace rw { namespace rw {
@ -28,7 +29,7 @@ worldLightSync(ObjectWithFrame *obj)
Light* Light*
Light::create(int32 type) Light::create(int32 type)
{ {
Light *light = (Light*)malloc(s_plglist.size); Light *light = (Light*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_LIGHT);
if(light == nil){ if(light == nil){
RWERROR((ERR_ALLOC, s_plglist.size)); RWERROR((ERR_ALLOC, s_plglist.size));
return nil; return nil;
@ -65,7 +66,7 @@ Light::destroy(void)
if(this->clump) if(this->clump)
this->inClump.remove(); this->inClump.remove();
// we do not remove from world, be careful // we do not remove from world, be careful
free(this); rwFree(this);
} }
void void

View File

@ -8,6 +8,9 @@
#include "rwbase.h" #include "rwbase.h"
#include "rwerror.h" #include "rwerror.h"
#include "rwplg.h" #include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwengine.h"
namespace rw { namespace rw {
@ -103,7 +106,7 @@ int32
PluginList::registerPlugin(int32 size, uint32 id, PluginList::registerPlugin(int32 size, uint32 id,
Constructor ctor, Destructor dtor, CopyConstructor copy) Constructor ctor, Destructor dtor, CopyConstructor copy)
{ {
Plugin *p = (Plugin*)malloc(sizeof(Plugin)); Plugin *p = (Plugin*)rwMalloc(sizeof(Plugin), MEMDUR_GLOBAL);
p->offset = this->size; p->offset = this->size;
this->size += size; this->size += size;
int32 round = sizeof(void*)-1; int32 round = sizeof(void*)-1;

View File

@ -86,7 +86,7 @@ mallocalign(size_t size, int32 alignment)
{ {
void *p; void *p;
void **pp; void **pp;
p = malloc(size + alignment + sizeof(void*)); p = rwMalloc(size + alignment + sizeof(void*), MEMDUR_EVENT | ID_RASTERPS2);
if(p == nil) return nil; if(p == nil) return nil;
pp = (void**)(((uintptr)p + sizeof(void*) + alignment)&~(alignment-1)); pp = (void**)(((uintptr)p + sizeof(void*) + alignment)&~(alignment-1));
pp[-1] = p; pp[-1] = p;
@ -99,7 +99,7 @@ freealign(void *p)
void *pp; void *pp;
if(p == nil) return; if(p == nil) return;
pp = ((void**)p)[-1]; pp = ((void**)p)[-1];
free(pp); rwFree(pp);
} }
// TODO: these depend on video mode, set in deviceSystem! // TODO: these depend on video mode, set in deviceSystem!
@ -391,13 +391,13 @@ static uint8 blockmaprev_PSMCT16[32] = {
static void static void
calcOffsets(int32 width_Px, int32 height_Px, int32 psm, uint64 *bufferBase_B, uint64 *bufferWidth_W, uint32 *trxpos, uint32 *totalSize, uint32 *paletteBase) calcOffsets(int32 width_Px, int32 height_Px, int32 psm, uint64 *bufferBase_B, uint64 *bufferWidth_W, uint32 *trxpos, uint32 *totalSize, uint32 *paletteBase)
{ {
int32 pageWidth_Px, pageHeight_Px; uint32 pageWidth_Px, pageHeight_Px;
int32 blockWidth_Px, blockHeight_Px; uint32 blockWidth_Px, blockHeight_Px;
int32 mindim_Px; uint32 mindim_Px;
int32 nlevels; int32 nlevels;
int32 n; int32 n;
int32 mipw_Px, miph_Px; uint32 mipw_Px, miph_Px;
int32 lastmipw_Px, lastmiph_Px; uint32 lastmipw_Px, lastmiph_Px;
uint32 bufferHeight_P[8]; uint32 bufferHeight_P[8];
uint32 bufferPage_B[8]; // address of page in which the level is allocated uint32 bufferPage_B[8]; // address of page in which the level is allocated
uint32 xoff_Px, yoff_Px; // x/y offset the last level starts at uint32 xoff_Px, yoff_Px; // x/y offset the last level starts at
@ -408,7 +408,7 @@ calcOffsets(int32 width_Px, int32 height_Px, int32 psm, uint64 *bufferBase_B, ui
uint32 widthstack_Px[8]; uint32 widthstack_Px[8];
uint32 heightstack_Px[8]; uint32 heightstack_Px[8];
uint32 basestack_B[8]; uint32 basestack_B[8];
int32 flag; uint32 flag;
switch(psm){ switch(psm){
case PSMCT32: case PSMCT32:
@ -652,7 +652,7 @@ calcOffsets(int32 width_Px, int32 height_Px, int32 psm, uint64 *bufferBase_B, ui
// the R bits are the block's row in a row of pages // the R bits are the block's row in a row of pages
// We want to swap P and R: PPRRRCC // We want to swap P and R: PPRRRCC
bufferBase_B[n] = bufferBase_B[n] =
(bufferBase_B[n] & ~(bufpagestride_B - PAGEWIDTH_B)) // mask out R and P (bufferBase_B[n] & ~((uint64)bufpagestride_B - PAGEWIDTH_B)) // mask out R and P
| ((bufferBase_B[n] & (bufwidth_B - PAGEWIDTH_B)) * (bufpagestride_B/bufwidth_B)) // extract P and shift left | ((bufferBase_B[n] & (bufwidth_B - PAGEWIDTH_B)) * (bufpagestride_B/bufwidth_B)) // extract P and shift left
| ((bufferBase_B[n] & (bufpagestride_B - bufwidth_B)) / (bufwidth_B/PAGEWIDTH_B)); // extract R and shift right | ((bufferBase_B[n] & (bufpagestride_B - bufwidth_B)) / (bufwidth_B/PAGEWIDTH_B)); // extract R and shift right
} }
@ -968,8 +968,8 @@ createTexRaster(Raster *raster)
ras->pixelSize = ALIGN16(raster->stride*raster->height); ras->pixelSize = ALIGN16(raster->stride*raster->height);
ras->paletteSize = paletteWidth*paletteHeight*paletteDepth; ras->paletteSize = paletteWidth*paletteHeight*paletteDepth;
ras->miptbp1 = 1<<54 | 1<<34 | 1<<14; ras->miptbp1 = 1ULL<<54 | 1ULL<<34 | 1ULL<<14;
ras->miptbp2 = 1<<54 | 1<<34 | 1<<14; ras->miptbp2 = 1ULL<<54 | 1ULL<<34 | 1ULL<<14;
ras->tex1low = 0; // one mipmap level ras->tex1low = 0; // one mipmap level
// find out number of pages needed // find out number of pages needed
@ -1010,8 +1010,8 @@ createTexRaster(Raster *raster)
th << 30 | th << 30 |
tcc << 34 | tcc << 34 |
cpsm << 51 | cpsm << 51 |
0 << 55 | // csm0 0ULL << 55 | // csm0
0 << 56 | // entry offset 0ULL << 56 | // entry offset
cld << 61; cld << 61;

View File

@ -381,11 +381,12 @@ enum Platform
// SOFTRAS // SOFTRAS
PLATFORM_D3D8 = 8, PLATFORM_D3D8 = 8,
PLATFORM_D3D9 = 9, PLATFORM_D3D9 = 9,
// PSP
// non-stock-RW platforms // non-stock-RW platforms
PLATFORM_WDGL = 10, // WarDrum OpenGL PLATFORM_WDGL = 11, // WarDrum OpenGL
PLATFORM_GL3 = 11, // my GL3 implementation PLATFORM_GL3 = 12, // my GL3 implementation
NUM_PLATFORMS, NUM_PLATFORMS,
@ -404,6 +405,8 @@ enum VendorID
VEND_PLATFORM = 10, VEND_PLATFORM = 10,
}; };
// TODO: modules (VEND_CRITERIONINT)
enum PluginID enum PluginID
{ {
// Core // Core
@ -415,6 +418,8 @@ enum PluginID
ID_TEXTURE = MAKEPLUGINID(VEND_CORE, 0x06), ID_TEXTURE = MAKEPLUGINID(VEND_CORE, 0x06),
ID_MATERIAL = MAKEPLUGINID(VEND_CORE, 0x07), ID_MATERIAL = MAKEPLUGINID(VEND_CORE, 0x07),
ID_MATLIST = MAKEPLUGINID(VEND_CORE, 0x08), ID_MATLIST = MAKEPLUGINID(VEND_CORE, 0x08),
ID_WORLD = MAKEPLUGINID(VEND_CORE, 0x0B),
ID_MATRIX = MAKEPLUGINID(VEND_CORE, 0x0D),
ID_FRAMELIST = MAKEPLUGINID(VEND_CORE, 0x0E), ID_FRAMELIST = MAKEPLUGINID(VEND_CORE, 0x0E),
ID_GEOMETRY = MAKEPLUGINID(VEND_CORE, 0x0F), ID_GEOMETRY = MAKEPLUGINID(VEND_CORE, 0x0F),
ID_CLUMP = MAKEPLUGINID(VEND_CORE, 0x10), ID_CLUMP = MAKEPLUGINID(VEND_CORE, 0x10),
@ -422,6 +427,7 @@ enum PluginID
ID_ATOMIC = MAKEPLUGINID(VEND_CORE, 0x14), ID_ATOMIC = MAKEPLUGINID(VEND_CORE, 0x14),
ID_TEXTURENATIVE = MAKEPLUGINID(VEND_CORE, 0x15), ID_TEXTURENATIVE = MAKEPLUGINID(VEND_CORE, 0x15),
ID_TEXDICTIONARY = MAKEPLUGINID(VEND_CORE, 0x16), ID_TEXDICTIONARY = MAKEPLUGINID(VEND_CORE, 0x16),
ID_IMAGE = MAKEPLUGINID(VEND_CORE, 0x18),
ID_GEOMETRYLIST = MAKEPLUGINID(VEND_CORE, 0x1A), ID_GEOMETRYLIST = MAKEPLUGINID(VEND_CORE, 0x1A),
ID_ANIMANIMATION = MAKEPLUGINID(VEND_CORE, 0x1B), ID_ANIMANIMATION = MAKEPLUGINID(VEND_CORE, 0x1B),
ID_RIGHTTORENDER = MAKEPLUGINID(VEND_CORE, 0x1F), ID_RIGHTTORENDER = MAKEPLUGINID(VEND_CORE, 0x1F),
@ -430,7 +436,7 @@ enum PluginID
// Toolkit // Toolkit
ID_SKYMIPMAP = MAKEPLUGINID(VEND_CRITERIONTK, 0x10), ID_SKYMIPMAP = MAKEPLUGINID(VEND_CRITERIONTK, 0x10),
ID_SKIN = MAKEPLUGINID(VEND_CRITERIONTK, 0x16), ID_SKIN = MAKEPLUGINID(VEND_CRITERIONTK, 0x16),
ID_HANIMPLUGIN = MAKEPLUGINID(VEND_CRITERIONTK, 0x1E), ID_HANIM = MAKEPLUGINID(VEND_CRITERIONTK, 0x1E),
ID_USERDATA = MAKEPLUGINID(VEND_CRITERIONTK, 0x1F), ID_USERDATA = MAKEPLUGINID(VEND_CRITERIONTK, 0x1F),
ID_MATFX = MAKEPLUGINID(VEND_CRITERIONTK, 0x20), ID_MATFX = MAKEPLUGINID(VEND_CRITERIONTK, 0x20),
ID_PDS = MAKEPLUGINID(VEND_CRITERIONTK, 0x31), ID_PDS = MAKEPLUGINID(VEND_CRITERIONTK, 0x31),

View File

@ -94,6 +94,26 @@ struct Driver
struct EngineStartParams; struct EngineStartParams;
enum MemHint
{
MEMDUR_NA = 0,
// used inside function
MEMDUR_FUNCTION = 0x10000,
// used for one frame
MEMDUR_FRAME = 0x20000,
// used for longer time
MEMDUR_EVENT = 0x30000,
// used while the engine is running
MEMDUR_GLOBAL = 0x40000
};
struct MemoryFunctions
{
void *(*malloc)(size_t sz, uint32 hint);
void *(*realloc)(void *p, size_t sz, uint32 hint);
void (*free)(void *p);
};
// This is for platform independent things // This is for platform independent things
// TODO: move more stuff into this // TODO: move more stuff into this
// TODO: make this have plugins and allocate in Engine::open // TODO: make this have plugins and allocate in Engine::open
@ -118,6 +138,8 @@ struct Engine
Driver *driver[NUM_PLATFORMS]; Driver *driver[NUM_PLATFORMS];
Device device; Device device;
// These must always be available
static MemoryFunctions memfuncs;
static State state; static State state;
static bool32 init(void); static bool32 init(void);
@ -136,6 +158,10 @@ inline void SetRenderState(int32 state, uint32 value){
inline uint32 GetRenderState(int32 state){ inline uint32 GetRenderState(int32 state){
return engine->device.getRenderState(state); } return engine->device.getRenderState(state); }
#define rwMalloc(s, h) rw::Engine::memfuncs.malloc(s,h)
#define rwRealloc(p, s, h) rw::Engine::memfuncs.realloc(p,s,h)
#define rwFree(p) rw::Engine::memfuncs.free(p)
namespace null { namespace null {
void beginUpdate(Camera*); void beginUpdate(Camera*);
void endUpdate(Camera*); void endUpdate(Camera*);

View File

@ -39,7 +39,7 @@ destroySkin(void *object, int32 offset, int32)
Skin *skin = *PLUGINOFFSET(Skin*, object, offset); Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
if(skin){ if(skin){
delete[] skin->data; delete[] skin->data;
free(skin->remapIndices); rwFree(skin->remapIndices);
// delete[] skin->platformData; // delete[] skin->platformData;
} }
delete skin; delete skin;
@ -83,7 +83,7 @@ readSkinSplitData(Stream *stream, Skin *skin)
skin->rleSize = stream->readI32(); skin->rleSize = stream->readI32();
if(skin->numMeshes){ if(skin->numMeshes){
sz = skin->numBones + 2*(skin->numMeshes+skin->rleSize); sz = skin->numBones + 2*(skin->numMeshes+skin->rleSize);
data = (int8*)malloc(sz); data = (int8*)rwMalloc(sz, MEMDUR_EVENT | ID_SKIN);
stream->read(data, sz); stream->read(data, sz);
skin->remapIndices = data; skin->remapIndices = data;
skin->rleCount = (Skin::RLEcount*)(data + skin->numBones); skin->rleCount = (Skin::RLEcount*)(data + skin->numBones);

468
src/texture.cpp Normal file
View File

@ -0,0 +1,468 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include "rwbase.h"
#include "rwerror.h"
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwengine.h"
#include "ps2/rwps2.h"
#include "d3d/rwd3d.h"
#include "d3d/rwxbox.h"
#include "d3d/rwd3d8.h"
#include "d3d/rwd3d9.h"
#ifdef _WIN32
/* srsly? */
#define strdup _strdup
#endif
#define PLUGIN_ID 0
namespace rw {
PluginList TexDictionary::s_plglist = { sizeof(TexDictionary), sizeof(TexDictionary), nil, nil };
PluginList Texture::s_plglist = { sizeof(Texture), sizeof(Texture), nil, nil };
PluginList Raster::s_plglist = { sizeof(Raster), sizeof(Raster), nil, nil };
//
// TexDictionary
//
TexDictionary*
TexDictionary::create(void)
{
TexDictionary *dict = (TexDictionary*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_TEXDICTIONARY);
if(dict == nil){
RWERROR((ERR_ALLOC, s_plglist.size));
return nil;
}
dict->object.init(TexDictionary::ID, 0);
dict->textures.init();
s_plglist.construct(dict);
return dict;
}
void
TexDictionary::destroy(void)
{
if(engine->currentTexDictionary == this)
engine->currentTexDictionary = nil;
FORLIST(lnk, this->textures)
Texture::fromDict(lnk)->destroy();
s_plglist.destruct(this);
rwFree(this);
}
void
TexDictionary::add(Texture *t)
{
if(t->dict)
t->inDict.remove();
t->dict = this;
this->textures.append(&t->inDict);
}
Texture*
TexDictionary::find(const char *name)
{
FORLIST(lnk, this->textures){
Texture *tex = Texture::fromDict(lnk);
if(strncmp_ci(tex->name, name, 32) == 0)
return tex;
}
return nil;
}
TexDictionary*
TexDictionary::streamRead(Stream *stream)
{
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
int32 numTex = stream->readI16();
stream->readI16(); // device id (0 = unknown, 1 = d3d8, 2 = d3d9,
// 3 = gcn, 4 = null, 5 = opengl,
// 6 = ps2, 7 = softras, 8 = xbox, 9 = psp)
TexDictionary *txd = TexDictionary::create();
if(txd == nil)
return nil;
Texture *tex;
for(int32 i = 0; i < numTex; i++){
if(!findChunk(stream, ID_TEXTURENATIVE, nil, nil)){
RWERROR((ERR_CHUNK, "TEXTURENATIVE"));
goto fail;
}
tex = Texture::streamReadNative(stream);
if(tex == nil)
goto fail;
Texture::s_plglist.streamRead(stream, tex);
txd->add(tex);
}
if(s_plglist.streamRead(stream, txd))
return txd;
fail:
txd->destroy();
return nil;
}
void
TexDictionary::streamWrite(Stream *stream)
{
writeChunkHeader(stream, ID_TEXDICTIONARY, this->streamGetSize());
writeChunkHeader(stream, ID_STRUCT, 4);
int32 numTex = this->count();
stream->writeI16(numTex);
stream->writeI16(0);
FORLIST(lnk, this->textures){
Texture *tex = Texture::fromDict(lnk);
uint32 sz = tex->streamGetSizeNative();
sz += 12 + Texture::s_plglist.streamGetSize(tex);
writeChunkHeader(stream, ID_TEXTURENATIVE, sz);
tex->streamWriteNative(stream);
Texture::s_plglist.streamWrite(stream, tex);
}
s_plglist.streamWrite(stream, this);
}
uint32
TexDictionary::streamGetSize(void)
{
uint32 size = 12 + 4;
FORLIST(lnk, this->textures){
Texture *tex = Texture::fromDict(lnk);
size += 12 + tex->streamGetSizeNative();
size += 12 + Texture::s_plglist.streamGetSize(tex);
}
size += 12 + s_plglist.streamGetSize(this);
return size;
}
void
TexDictionary::setCurrent(TexDictionary *txd)
{
engine->currentTexDictionary = txd;
}
TexDictionary*
TexDictionary::getCurrent(void)
{
return engine->currentTexDictionary;
}
//
// Texture
//
static Texture *defaultFindCB(const char *name);
static Texture *defaultReadCB(const char *name, const char *mask);
Texture *(*Texture::findCB)(const char *name) = defaultFindCB;
Texture *(*Texture::readCB)(const char *name, const char *mask) = defaultReadCB;
Texture*
Texture::create(Raster *raster)
{
Texture *tex = (Texture*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_TEXTURE);
if(tex == nil){
RWERROR((ERR_ALLOC, s_plglist.size));
return nil;
}
tex->dict = nil;
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;
s_plglist.construct(tex);
return tex;
}
void
Texture::destroy(void)
{
this->refCount--;
if(this->refCount <= 0){
s_plglist.destruct(this);
if(this->dict)
this->inDict.remove();
if(this->raster)
this->raster->destroy();
rwFree(this);
}
}
static Texture*
defaultFindCB(const char *name)
{
if(engine->currentTexDictionary)
return engine->currentTexDictionary->find(name);
// TODO: RW searches *all* TXDs otherwise
return nil;
}
static Texture*
defaultReadCB(const char *name, const char *mask)
{
Texture *tex;
Image *img;
char *n = (char*)rwMalloc(strlen(name) + 5, MEMDUR_FUNCTION | ID_TEXTURE);
strcpy(n, name);
strcat(n, ".tga");
img = readTGA(n);
rwFree(n);
if(img){
tex = Texture::create(Raster::createFromImage(img));
strncpy(tex->name, name, 32);
if(mask)
strncpy(tex->mask, mask, 32);
img->destroy();
return tex;
}else
return nil;
}
Texture*
Texture::read(const char *name, const char *mask)
{
(void)mask;
Raster *raster = nil;
Texture *tex;
if(tex = Texture::findCB(name), tex){
tex->refCount++;
return tex;
}
if(engine->loadTextures){
tex = Texture::readCB(name, mask);
if(tex == nil)
goto dummytex;
}else dummytex: if(engine->makeDummies){
tex = Texture::create(nil);
if(tex == nil)
return nil;
strncpy(tex->name, name, 32);
if(mask)
strncpy(tex->mask, mask, 32);
raster = Raster::create(0, 0, 0, Raster::DONTALLOCATE);
tex->raster = raster;
}
if(tex && engine->currentTexDictionary){
if(tex->dict)
tex->inDict.remove();
engine->currentTexDictionary->add(tex);
}
return tex;
}
Texture*
Texture::streamRead(Stream *stream)
{
uint32 length;
char name[128], mask[128];
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
uint32 filterAddressing = stream->readU32();
// TODO: if V addressing is 0, copy U
// if using mipmap filter mode, set automipmapping,
// if 0x10000 is set, set mipmapping
if(!findChunk(stream, ID_STRING, &length, nil)){
RWERROR((ERR_CHUNK, "STRING"));
return nil;
}
stream->read(name, length);
if(!findChunk(stream, ID_STRING, &length, nil)){
RWERROR((ERR_CHUNK, "STRING"));
return nil;
}
stream->read(mask, length);
Texture *tex = Texture::read(name, mask);
if(tex == nil)
return nil;
if(tex->refCount == 1)
tex->filterAddressing = filterAddressing;
if(s_plglist.streamRead(stream, tex))
return tex;
tex->destroy();
return nil;
}
bool
Texture::streamWrite(Stream *stream)
{
int size;
char buf[36];
writeChunkHeader(stream, ID_TEXTURE, this->streamGetSize());
writeChunkHeader(stream, ID_STRUCT, 4);
stream->writeU32(this->filterAddressing);
memset(buf, 0, 36);
strncpy(buf, this->name, 32);
size = strlen(buf)+4 & ~3;
writeChunkHeader(stream, ID_STRING, size);
stream->write(buf, size);
memset(buf, 0, 36);
strncpy(buf, this->mask, 32);
size = strlen(buf)+4 & ~3;
writeChunkHeader(stream, ID_STRING, size);
stream->write(buf, size);
s_plglist.streamWrite(stream, this);
return true;
}
uint32
Texture::streamGetSize(void)
{
uint32 size = 0;
size += 12 + 4;
size += 12 + 12;
size += strlen(this->name)+4 & ~3;
size += strlen(this->mask)+4 & ~3;
size += 12 + s_plglist.streamGetSize(this);
return size;
}
Texture*
Texture::streamReadNative(Stream *stream)
{
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
uint32 platform = stream->readU32();
stream->seek(-16);
if(platform == FOURCC_PS2)
return ps2::readNativeTexture(stream);
if(platform == PLATFORM_D3D8)
return d3d8::readNativeTexture(stream);
if(platform == PLATFORM_D3D9)
return d3d9::readNativeTexture(stream);
if(platform == PLATFORM_XBOX)
return xbox::readNativeTexture(stream);
assert(0 && "unsupported platform");
return nil;
}
void
Texture::streamWriteNative(Stream *stream)
{
if(this->raster->platform == PLATFORM_PS2)
ps2::writeNativeTexture(this, stream);
else if(this->raster->platform == PLATFORM_D3D8)
d3d8::writeNativeTexture(this, stream);
else if(this->raster->platform == PLATFORM_D3D9)
d3d9::writeNativeTexture(this, stream);
else if(this->raster->platform == PLATFORM_XBOX)
xbox::writeNativeTexture(this, stream);
else
assert(0 && "unsupported platform");
}
uint32
Texture::streamGetSizeNative(void)
{
if(this->raster->platform == PLATFORM_PS2)
return ps2::getSizeNativeTexture(this);
if(this->raster->platform == PLATFORM_D3D8)
return d3d8::getSizeNativeTexture(this);
if(this->raster->platform == PLATFORM_D3D9)
return d3d9::getSizeNativeTexture(this);
if(this->raster->platform == PLATFORM_XBOX)
return xbox::getSizeNativeTexture(this);
assert(0 && "unsupported platform");
return 0;
}
//
// Raster
//
Raster*
Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platform)
{
// TODO: pass arguments through to the driver and create the raster there
Raster *raster = (Raster*)rwMalloc(s_plglist.size, MEMDUR_EVENT); // TODO
assert(raster != nil);
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->pixels = raster->palette = nil;
s_plglist.construct(raster);
// printf("%d %d %d %d\n", raster->type, raster->width, raster->height, raster->depth);
engine->driver[raster->platform]->rasterCreate(raster);
return raster;
}
void
Raster::destroy(void)
{
s_plglist.destruct(this);
// delete[] this->texels;
// delete[] this->palette;
rwFree(this);
}
uint8*
Raster::lock(int32 level)
{
return engine->driver[this->platform]->rasterLock(this, level);
}
void
Raster::unlock(int32 level)
{
engine->driver[this->platform]->rasterUnlock(this, level);
}
int32
Raster::getNumLevels(void)
{
return engine->driver[this->platform]->rasterNumLevels(this);
}
int32
Raster::calculateNumLevels(int32 width, int32 height)
{
int32 size = width >= height ? width : height;
int32 n;
for(n = 0; size != 0; n++)
size /= 2;
return n;
}
Raster*
Raster::createFromImage(Image *image, int32 platform)
{
Raster *raster = Raster::create(image->width, image->height,
image->depth, TEXTURE | DONTALLOCATE,
platform);
engine->driver[raster->platform]->rasterFromImage(raster, image);
return raster;
}
Image*
Raster::toImage(void)
{
return engine->driver[this->platform]->rasterToImage(this);
}
}

View File

@ -57,7 +57,7 @@ readTGA(const char *afilename)
uint32 length; uint32 length;
uint8 *data = getFileContents(filename, &length); uint8 *data = getFileContents(filename, &length);
assert(data != nil); assert(data != nil);
free(filename); rwFree(filename);
StreamMemory file; StreamMemory file;
file.open(data, length); file.open(data, length);
file.read(&header, sizeof(header)); file.read(&header, sizeof(header));

View File

@ -17,14 +17,16 @@ namespace rw {
UserDataGlobals userDataGlobals; UserDataGlobals userDataGlobals;
#define udMalloc(sz) rwMalloc(sz, MEMDUR_EVENT | ID_USERDATA)
void void
UserDataArray::setString(int32 n, const char *s) UserDataArray::setString(int32 n, const char *s)
{ {
int32 len; int32 len;
char **sp = &((char**)this->data)[n]; char **sp = &((char**)this->data)[n];
free(*sp); rwFree(*sp);
len = strlen(s)+1; len = (int32)strlen(s)+1;
*sp = (char*)malloc(len); *sp = (char*)udMalloc(len);
if(*sp) if(*sp)
strncpy(*sp, s, len); strncpy(*sp, s, len);
} }
@ -47,21 +49,21 @@ destroyUserData(void *object, int32 offset, int32)
UserDataExtension *ext = PLUGINOFFSET(UserDataExtension, object, offset); UserDataExtension *ext = PLUGINOFFSET(UserDataExtension, object, offset);
a = ext->arrays; a = ext->arrays;
for(i = 0; i < ext->numArrays; i++){ for(i = 0; i < ext->numArrays; i++){
free(a->name); rwFree(a->name);
switch(a->datatype){ switch(a->datatype){
case USERDATASTRING: case USERDATASTRING:
strar = (char**)a->data; strar = (char**)a->data;
for(j = 0; j < a->numElements; j++) for(j = 0; j < a->numElements; j++)
free(strar[j]); rwFree(strar[j]);
/* fallthrough */ /* fallthrough */
case USERDATAINT: case USERDATAINT:
case USERDATAFLOAT: case USERDATAFLOAT:
free(a->data); rwFree(a->data);
break; break;
} }
a++; a++;
} }
free(ext->arrays); rwFree(ext->arrays);
ext->numArrays = 0; ext->numArrays = 0;
ext->arrays = nil; ext->arrays = nil;
return object; return object;
@ -76,30 +78,31 @@ copyUserData(void *dst, void *src, int32 offset, int32)
UserDataExtension *srcext = PLUGINOFFSET(UserDataExtension, src, offset); UserDataExtension *srcext = PLUGINOFFSET(UserDataExtension, src, offset);
UserDataExtension *dstext = PLUGINOFFSET(UserDataExtension, dst, offset); UserDataExtension *dstext = PLUGINOFFSET(UserDataExtension, dst, offset);
dstext->numArrays = srcext->numArrays; dstext->numArrays = srcext->numArrays;
dstext->arrays = (UserDataArray*)malloc(dstext->numArrays*sizeof(UserDataArray)); dstext->arrays = (UserDataArray*)udMalloc(dstext->numArrays*sizeof(UserDataArray));
srca = srcext->arrays; srca = srcext->arrays;
dsta = srcext->arrays; dsta = srcext->arrays;
for(i = 0; i < srcext->numArrays; i++){ for(i = 0; i < srcext->numArrays; i++){
int32 len = strlen(srca->name)+1; int32 len = (int32)strlen(srca->name)+1;
dsta->name = (char*)malloc(len); dsta->name = (char*)udMalloc(len);
strncpy(dsta->name, srca->name, len); strncpy(dsta->name, srca->name, len);
dsta->datatype = srca->datatype; dsta->datatype = srca->datatype;
dsta->numElements = srca->numElements; dsta->numElements = srca->numElements;
switch(srca->datatype){ switch(srca->datatype){
case USERDATAINT: case USERDATAINT:
dsta->data = (int32*)malloc(sizeof(int32)*dsta->numElements); dsta->data = (int32*)udMalloc(sizeof(int32)*dsta->numElements);
memcpy(dsta->data, srca->data, sizeof(int32)*dsta->numElements); memcpy(dsta->data, srca->data, sizeof(int32)*dsta->numElements);
break; break;
case USERDATAFLOAT: case USERDATAFLOAT:
dsta->data = (float32*)malloc(sizeof(float32)*dsta->numElements); dsta->data = (float32*)udMalloc(sizeof(float32)*dsta->numElements);
memcpy(dsta->data, srca->data, sizeof(float32)*dsta->numElements); memcpy(dsta->data, srca->data, sizeof(float32)*dsta->numElements);
break; break;
case USERDATASTRING: case USERDATASTRING:
dststrar = (char**)malloc(sizeof(char*)*dsta->numElements); dststrar = (char**)udMalloc(sizeof(char*)*dsta->numElements);
dsta->data = dststrar; dsta->data = dststrar;
srcstrar = (char**)srca->data;
for(j = 0; j < dsta->numElements; j++){ for(j = 0; j < dsta->numElements; j++){
len = strlen(srcstrar[j])+1; len = (int32)strlen(srcstrar[j])+1;
dststrar[j] = (char*)malloc(len); dststrar[j] = (char*)udMalloc(len);
strncpy(dststrar[j], srcstrar[j], len); strncpy(dststrar[j], srcstrar[j], len);
} }
break; break;
@ -118,29 +121,29 @@ readUserData(Stream *stream, int32, void *object, int32 offset, int32)
UserDataArray *a; UserDataArray *a;
UserDataExtension *ext = PLUGINOFFSET(UserDataExtension, object, offset); UserDataExtension *ext = PLUGINOFFSET(UserDataExtension, object, offset);
ext->numArrays = stream->readI32(); ext->numArrays = stream->readI32();
ext->arrays = (UserDataArray*)malloc(ext->numArrays*sizeof(UserDataArray)); ext->arrays = (UserDataArray*)udMalloc(ext->numArrays*sizeof(UserDataArray));
a = ext->arrays; a = ext->arrays;
for(i = 0; i < ext->numArrays; i++){ for(i = 0; i < ext->numArrays; i++){
int32 len = stream->readI32(); int32 len = stream->readI32();
a->name = (char*)malloc(len); a->name = (char*)udMalloc(len);
stream->read(a->name, len); stream->read(a->name, len);
a->datatype = stream->readU32(); a->datatype = stream->readU32();
a->numElements = stream->readI32(); a->numElements = stream->readI32();
switch(a->datatype){ switch(a->datatype){
case USERDATAINT: case USERDATAINT:
a->data = (int32*)malloc(sizeof(int32)*a->numElements); a->data = (int32*)udMalloc(sizeof(int32)*a->numElements);
stream->read(a->data, sizeof(int32)*a->numElements); stream->read(a->data, sizeof(int32)*a->numElements);
break; break;
case USERDATAFLOAT: case USERDATAFLOAT:
a->data = (float32*)malloc(sizeof(float32)*a->numElements); a->data = (float32*)udMalloc(sizeof(float32)*a->numElements);
stream->read(a->data, sizeof(float32)*a->numElements); stream->read(a->data, sizeof(float32)*a->numElements);
break; break;
case USERDATASTRING: case USERDATASTRING:
strar = (char**)malloc(sizeof(char*)*a->numElements); strar = (char**)udMalloc(sizeof(char*)*a->numElements);
a->data = strar; a->data = strar;
for(j = 0; j < a->numElements; j++){ for(j = 0; j < a->numElements; j++){
len = stream->readI32(); len = stream->readI32();
strar[j] = (char*)malloc(len); strar[j] = (char*)udMalloc(len);
stream->read(strar[j], len); stream->read(strar[j], len);
} }
break; break;
@ -161,7 +164,7 @@ writeUserData(Stream *stream, int32, void *object, int32 offset, int32)
stream->writeI32(ext->numArrays); stream->writeI32(ext->numArrays);
a = ext->arrays; a = ext->arrays;
for(i = 0; i < ext->numArrays; i++){ for(i = 0; i < ext->numArrays; i++){
len = strlen(a->name)+1; len = (int32)strlen(a->name)+1;
stream->writeI32(len); stream->writeI32(len);
stream->write(a->name, len); stream->write(a->name, len);
stream->writeU32(a->datatype); stream->writeU32(a->datatype);
@ -176,7 +179,7 @@ writeUserData(Stream *stream, int32, void *object, int32 offset, int32)
case USERDATASTRING: case USERDATASTRING:
strar = (char**)a->data; strar = (char**)a->data;
for(j = 0; j < a->numElements; j++){ for(j = 0; j < a->numElements; j++){
len = strlen(strar[j])+1; len = (int32)strlen(strar[j])+1;
stream->writeI32(len); stream->writeI32(len);
stream->write(strar[j], len); stream->write(strar[j], len);
} }
@ -201,7 +204,7 @@ getSizeUserData(void *object, int32 offset, int32)
size = 4; // numArrays size = 4; // numArrays
a = ext->arrays; a = ext->arrays;
for(i = 0; i < ext->numArrays; i++){ for(i = 0; i < ext->numArrays; i++){
len = strlen(a->name)+1; len = (int32)strlen(a->name)+1;
size += 4 + len + 4 + 4; // name len, name, type, numElements size += 4 + len + 4 + 4; // name len, name, type, numElements
switch(a->datatype){ switch(a->datatype){
case USERDATAINT: case USERDATAINT:
@ -213,7 +216,7 @@ getSizeUserData(void *object, int32 offset, int32)
case USERDATASTRING: case USERDATASTRING:
strar = (char**)a->data; strar = (char**)a->data;
for(j = 0; j < a->numElements; j++){ for(j = 0; j < a->numElements; j++){
len = strlen(strar[j])+1; len = (int32)strlen(strar[j])+1;
size += 4 + len; // len and string size += 4 + len; // len and string
} }
break; break;
@ -235,17 +238,17 @@ add(UserDataExtension *ext, const char *name, int32 datatype, int32 numElements)
if(ext->arrays[i].datatype == USERDATANA) if(ext->arrays[i].datatype == USERDATANA)
goto alloc; goto alloc;
// have to realloc // have to realloc
a = (UserDataArray*)malloc((ext->numArrays+1)*sizeof(UserDataArray)); a = (UserDataArray*)udMalloc((ext->numArrays+1)*sizeof(UserDataArray));
if(a == nil) if(a == nil)
return -1; return -1;
memcpy(a, ext->arrays, ext->numArrays*sizeof(UserDataArray)); memcpy(a, ext->arrays, ext->numArrays*sizeof(UserDataArray));
free(ext->arrays); rwFree(ext->arrays);
ext->arrays = a; ext->arrays = a;
i = ext->numArrays++; i = ext->numArrays++;
alloc: alloc:
a = &ext->arrays[i]; a = &ext->arrays[i];
len = strlen(name)+1; len = (int32)strlen(name)+1;
a->name = (char*)malloc(len+1); a->name = (char*)udMalloc(len+1);
assert(a->name); assert(a->name);
strncpy(a->name, name, len); strncpy(a->name, name, len);
a->datatype = datatype; a->datatype = datatype;
@ -253,7 +256,7 @@ alloc:
typesz = datatype == USERDATAINT ? sizeof(int32) : typesz = datatype == USERDATAINT ? sizeof(int32) :
datatype == USERDATAFLOAT ? sizeof(float32) : datatype == USERDATAFLOAT ? sizeof(float32) :
datatype == USERDATASTRING ? sizeof(char*) : 0; datatype == USERDATASTRING ? sizeof(char*) : 0;
a->data = malloc(typesz*numElements); a->data = udMalloc(typesz*numElements);
assert(a->data); assert(a->data);
memset(a->data, 0, typesz*numElements); memset(a->data, 0, typesz*numElements);
return i; return i;
@ -265,14 +268,14 @@ remove(UserDataExtension *ext, int32 n)
int32 i; int32 i;
UserDataArray *a = &ext->arrays[n]; UserDataArray *a = &ext->arrays[n];
if(a->name){ if(a->name){
free(a->name); rwFree(a->name);
a->name = nil; a->name = nil;
} }
if(a->datatype == USERDATASTRING) if(a->datatype == USERDATASTRING)
for(i = 0; i < a->numElements; i++) for(i = 0; i < a->numElements; i++)
free(((char**)a->data)[i]); rwFree(((char**)a->data)[i]);
if(a->data){ if(a->data){
free(a->data); rwFree(a->data);
a->data = nil; a->data = nil;
} }
a->datatype = USERDATANA; a->datatype = USERDATANA;

View File

@ -8,6 +8,7 @@
#include "rwplg.h" #include "rwplg.h"
#include "rwpipeline.h" #include "rwpipeline.h"
#include "rwobjects.h" #include "rwobjects.h"
#include "rwengine.h"
#include "rwanim.h" #include "rwanim.h"
#include "rwplugins.h" #include "rwplugins.h"
@ -32,7 +33,7 @@ UVAnimDictionary *currentUVAnimDictionary;
UVAnimDictionary* UVAnimDictionary*
UVAnimDictionary::create(void) UVAnimDictionary::create(void)
{ {
UVAnimDictionary *dict = (UVAnimDictionary*)malloc(sizeof(UVAnimDictionary)); UVAnimDictionary *dict = (UVAnimDictionary*)rwMalloc(sizeof(UVAnimDictionary), MEMDUR_EVENT | ID_UVANIMATION);
if(dict == nil){ if(dict == nil){
RWERROR((ERR_ALLOC, sizeof(UVAnimDictionary))); RWERROR((ERR_ALLOC, sizeof(UVAnimDictionary)));
return nil; return nil;
@ -50,7 +51,7 @@ UVAnimDictionary::destroy(void)
cust->destroy(de->anim); cust->destroy(de->anim);
delete de; delete de;
} }
free(this); rwFree(this);
} }
void void

View File

@ -9,7 +9,7 @@
#include "rwobjects.h" #include "rwobjects.h"
#include "rwengine.h" #include "rwengine.h"
#define PLUGIN_ID 2 #define PLUGIN_ID ID_WORLD
namespace rw { namespace rw {
@ -18,7 +18,7 @@ PluginList World::s_plglist = { sizeof(World), sizeof(World), nil, nil };
World* World*
World::create(void) World::create(void)
{ {
World *world = (World*)malloc(s_plglist.size); World *world = (World*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_WORLD);
if(world == nil){ if(world == nil){
RWERROR((ERR_ALLOC, s_plglist.size)); RWERROR((ERR_ALLOC, s_plglist.size));
return nil; return nil;