worked on allocation

This commit is contained in:
aap 2017-08-25 14:06:53 +02:00
parent 040bb6cb51
commit 45b48b8f4e
29 changed files with 591 additions and 386 deletions

View File

@ -13,14 +13,7 @@ File formats are already supported rather well, although rasters
as used by TXD files still need some work, especially for PS2.
As for rendering, D3D9 and OpenGL 3 work somewhat well but both still need
work. Rendering some things on the PS2 worked in the past but the code
is not maintained, it was only a test.
# Roadmap
* Work on platform independent rendering functions (setting render states etc.)
* Get a solid GL3 driver working
work. Rendering some things on the PS2 is working as a test only.
# Building

17
TODO
View File

@ -1,7 +1,11 @@
TODO:
- maintain the TODO list properly
- skeleton
- get the error system in better shape
- move everything to custom malloc
- proper cleanup! and check for memory leaks
- skeleton (partially done)
- examples
- morph targets and morphing
- geometry lock/unlock
-> reinstance
-> revisit pipelines
@ -13,16 +17,13 @@ TODO:
- PS2 rendering!
- Im2d and Im3d
- change naming convention? make globals stand out more
- Pipelines (PDS, Xbox, PC)
- ADC conversion
BUGS:
- fseek with negative offset on ps2 over ps2link messes up the current position
Clump & related:
- !!! work on ref counts, destruction, copying etc.
- define and use types:
color
triangle
texcoord
- implement plugins:
Clump
Animation (old III dffs)
@ -37,7 +38,3 @@ Clump & related:
- only stubs:
R* 2dfx 0x253F2F8
R* Collision 0x253F2FA
- Pipelines (PDS, Xbox, PC)
- ADC conversion

View File

@ -863,7 +863,7 @@ getFileContents(char *name, uint32 *len)
fseek(cf, 0, SEEK_END);
*len = ftell(cf);
fseek(cf, 0, SEEK_SET);
uint8 *data = new uint8[*len];
uint8 *data = rwNewT(uint8, *len, MEMDUR_EVENT);
fread(data, *len, 1, cf);
fclose(cf);
return data;

View File

@ -187,7 +187,7 @@ createIndexBuffer(uint32 length)
d3ddevice->CreateIndexBuffer(length, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &ibuf, 0);
return ibuf;
#else
return new uint8[length];
return rwNewT(uint8, length, MEMDUR_EVENT | ID_DRIVER);
#endif
}
@ -230,7 +230,7 @@ createVertexBuffer(uint32 length, uint32 fvf, int32 pool)
#else
(void)fvf;
(void)pool;
return new uint8[length];
return rwNewT(uint8, length, MEMDUR_EVENT | ID_DRIVER);
#endif
}
@ -282,7 +282,8 @@ createTexture(int32 width, int32 height, int32 numlevels, uint32 format)
h /= 2;
if(h == 0) h = 1;
}
uint8 *data = new uint8[sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1)+size];
uint8 *data = (uint8*)rwNew(sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1)+size,
MEMDUR_EVENT | ID_DRIVER);
RasterLevels *levels = (RasterLevels*)data;
data += sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1);
levels->numlevels = numlevels;
@ -338,7 +339,7 @@ deleteObject(void *object)
IUnknown *unk = (IUnknown*)object;
unk->Release();
#else
delete[] (uint*)object;
rwFree(object);
#endif
}
@ -379,7 +380,7 @@ rasterCreate(Raster *raster)
uint32 format;
if(raster->format & (Raster::PAL4 | Raster::PAL8)){
format = D3DFMT_P8;
natras->palette = new uint8[4*256];
natras->palette = (uint8*)rwNew(4*256, MEMDUR_EVENT | ID_DRIVER);
}else
format = formatMap[(raster->format >> 8) & 0xF];
natras->format = 0;

View File

@ -91,8 +91,8 @@ destroyNativeData(void *object, int32, int32)
deleteObject(inst->vertexBuffer);
inst++;
}
delete[] header->inst;
delete header;
rwFree(header->inst);
rwFree(header);
return object;
}
@ -110,17 +110,17 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
RWERROR((ERR_PLATFORM, platform));
return nil;
}
InstanceDataHeader *header = new InstanceDataHeader;
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
geometry->instData = header;
header->platform = PLATFORM_D3D8;
int32 size = stream->readI32();
uint8 *data = new uint8[size];
uint8 *data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_GEOMETRY);
stream->read(data, size);
uint8 *p = data;
header->serialNumber = *(uint16*)p; p += 2;
header->numMeshes = *(uint16*)p; p += 2;
header->inst = new InstanceData[header->numMeshes];
header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
InstanceData *inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
@ -140,7 +140,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
inst->remapped = 0; p++; // TODO: really unused? and what's that anyway?
inst++;
}
delete[] data;
rwFree(data);
inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
@ -172,7 +172,7 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
int32 size = 4 + geometry->meshHeader->numMeshes*0x2C;
uint8 *data = new uint8[size];
uint8 *data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_GEOMETRY);
stream->writeI32(size);
uint8 *p = data;
*(uint16*)p = header->serialNumber; p += 2;
@ -197,7 +197,7 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
inst++;
}
stream->write(data, size);
delete[] data;
rwFree(data);
inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
@ -251,17 +251,17 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
// TODO: allow for REINSTANCE
if(geo->instData)
return;
InstanceDataHeader *header = new InstanceDataHeader;
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
MeshHeader *meshh = geo->meshHeader;
geo->instData = header;
header->platform = PLATFORM_D3D8;
header->serialNumber = 0;
header->numMeshes = meshh->numMeshes;
header->inst = new InstanceData[header->numMeshes];
header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
InstanceData *inst = header->inst;
Mesh *mesh = meshh->mesh;
Mesh *mesh = meshh->getMeshes();
for(uint32 i = 0; i < header->numMeshes; i++){
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
&inst->minVert, &inst->numVertices);
@ -299,13 +299,13 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
return;
assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_D3D8);
geo->flags &= ~Geometry::NATIVE;
geo->numTriangles = geo->meshHeader->guessNumTriangles();
geo->allocateData();
geo->meshHeader->allocateIndices();
geo->allocateMeshes(geo->meshHeader->numMeshes, geo->meshHeader->totalIndices, 0);
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
InstanceData *inst = header->inst;
Mesh *mesh = geo->meshHeader->mesh;
Mesh *mesh = geo->meshHeader->getMeshes();
for(uint32 i = 0; i < header->numMeshes; i++){
uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0);
if(inst->minVert == 0)
@ -320,6 +320,7 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
inst++;
}
geo->generateTriangles();
geo->flags &= ~Geometry::NATIVE;
destroyNativeData(geo, 0, 0);
}
@ -448,7 +449,7 @@ readAsImage(Stream *stream, int32 width, int32 height, int32 depth, int32 format
for(int32 i = 0; i < numLevels; i++){
uint32 size = stream->readU32();
if(i == 0){
data = new uint8[size];
data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_IMAGE);
stream->read(data, size);
}else
stream->seek(size);
@ -471,7 +472,7 @@ readAsImage(Stream *stream, int32 width, int32 height, int32 depth, int32 format
}
}
delete[] data;
rwFree(data);
Raster *ras = Raster::createFromImage(img, PLATFORM_D3D8);
img->destroy();
return ras;

View File

@ -71,7 +71,7 @@ createVertexDeclaration(VertexElement *elements)
VertexElement *e = (VertexElement*)elements;
while(e[n++].stream != 0xFF)
;
e = (VertexElement*)new uint8[n*sizeof(VertexElement)];
e = rwNewT(VertexElement, n, MEMDUR_EVENT | ID_DRIVER);
memcpy(e, elements, n*sizeof(VertexElement));
return e;
#endif
@ -111,8 +111,8 @@ destroyNativeData(void *object, int32, int32)
deleteObject(header->indexBuffer);
deleteObject(header->vertexStream[0].vertexBuffer);
deleteObject(header->vertexStream[1].vertexBuffer);
delete[] header->inst;
delete header;
rwFree(header->inst);
rwFree(header);
return object;
}
@ -130,12 +130,12 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
RWERROR((ERR_PLATFORM, platform));
return nil;
}
InstanceDataHeader *header = new InstanceDataHeader;
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
geometry->instData = header;
header->platform = PLATFORM_D3D9;
int32 size = stream->readI32();
uint8 *data = new uint8[size];
uint8 *data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_GEOMETRY);
stream->read(data, size);
uint8 *p = data;
header->serialNumber = *(uint32*)p; p += 4;
@ -147,7 +147,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
header->vertexDeclaration = nil; p += 4;
header->totalNumIndex = *(uint32*)p; p += 4;
header->totalNumVertex = *(uint32*)p; p += 4;
header->inst = new InstanceData[header->numMeshes];
header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
InstanceData *inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
@ -203,7 +203,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
inst++;
}
delete[] data;
rwFree(data);
return stream;
}
@ -218,7 +218,7 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
stream->writeU32(PLATFORM_D3D9);
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
int32 size = 64 + geometry->meshHeader->numMeshes*36;
uint8 *data = new uint8[size];
uint8 *data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_GEOMETRY);
stream->writeI32(size);
uint8 *p = data;
@ -276,7 +276,7 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
unlockVertices(s->vertexBuffer);
}
delete[] data;
rwFree(data);
return stream;
}
@ -316,7 +316,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
// TODO: allow for REINSTANCE
if(geo->instData)
return;
InstanceDataHeader *header = new InstanceDataHeader;
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
MeshHeader *meshh = geo->meshHeader;
geo->instData = header;
header->platform = PLATFORM_D3D9;
@ -327,13 +327,13 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
header->useOffsets = 0;
header->totalNumVertex = geo->numVertices;
header->totalNumIndex = meshh->totalIndices;
header->inst = new InstanceData[header->numMeshes];
header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
header->indexBuffer = createIndexBuffer(header->totalNumIndex*2);
uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0);
InstanceData *inst = header->inst;
Mesh *mesh = meshh->mesh;
Mesh *mesh = meshh->getMeshes();
uint32 startindex = 0;
for(uint32 i = 0; i < header->numMeshes; i++){
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
@ -370,14 +370,14 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
return;
assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_D3D9);
geo->flags &= ~Geometry::NATIVE;
geo->numTriangles = geo->meshHeader->guessNumTriangles();
geo->allocateData();
geo->meshHeader->allocateIndices();
geo->allocateMeshes(geo->meshHeader->numMeshes, geo->meshHeader->totalIndices, 0);
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0);
InstanceData *inst = header->inst;
Mesh *mesh = geo->meshHeader->mesh;
Mesh *mesh = geo->meshHeader->getMeshes();
for(uint32 i = 0; i < header->numMeshes; i++){
if(inst->minVert == 0)
memcpy(mesh->indices, &indices[inst->startIndex], inst->numIndex*2);
@ -391,6 +391,7 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
pipe->uninstanceCB(geo, header);
geo->generateTriangles();
geo->flags &= ~Geometry::NATIVE;
destroyNativeData(geo, 0, 0);
}

View File

@ -57,10 +57,10 @@ destroyNativeData(void *object, int32, int32)
InstanceDataHeader *header =
(InstanceDataHeader*)geometry->instData;
geometry->instData = nil;
delete[] (uint8*)header->vertexBuffer;
delete[] header->begin;
delete[] header->data;
delete header;
rwFree(header->vertexBuffer);
rwFree(header->begin);
rwFree(header->data);
rwFree(header);
return object;
}
@ -83,14 +83,14 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
RWERROR((ERR_VERSION, vers));
return nil;
}
InstanceDataHeader *header = new InstanceDataHeader;
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
geometry->instData = header;
header->platform = PLATFORM_XBOX;
int32 size = stream->readI32();
// The 0x18 byte are the resentryheader.
// We don't have it but it's used for alignment.
header->data = new uint8[size + 0x18];
header->data = rwNewT(uint8, size + 0x18, MEMDUR_EVENT | ID_GEOMETRY);
uint8 *p = header->data+0x18+4;
stream->read(p, size-4);
@ -105,7 +105,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
header->vertexAlpha = *(bool32*)p; p += 4;
p += 8; // skip begin, end pointers
InstanceData *inst = new InstanceData[header->numMeshes];
InstanceData *inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
header->begin = inst;
for(int i = 0; i < header->numMeshes; i++){
inst->minVert = *(uint32*)p; p += 4;
@ -119,7 +119,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
}
header->end = inst;
header->vertexBuffer = new uint8[header->stride*header->numVertices];
header->vertexBuffer = rwNewT(uint8, header->stride*header->numVertices, MEMDUR_EVENT | ID_GEOMETRY);
stream->read(header->vertexBuffer, header->stride*header->numVertices);
return stream;
}
@ -200,18 +200,18 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
// TODO: allow for REINSTANCE (or not, xbox can't render)
if(geo->instData)
return;
InstanceDataHeader *header = new InstanceDataHeader;
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
MeshHeader *meshh = geo->meshHeader;
geo->instData = header;
header->platform = PLATFORM_XBOX;
header->size = 0x24 + meshh->numMeshes*0x18 + 0x10;
Mesh *mesh = meshh->mesh;
Mesh *mesh = meshh->getMeshes();
for(uint32 i = 0; i < meshh->numMeshes; i++)
header->size += (mesh++->numIndices*2 + 0xF) & ~0xF;
// The 0x18 byte are the resentryheader.
// We don't have it but it's used for alignment.
header->data = new uint8[header->size + 0x18];
header->data = rwNewT(uint8, header->size + 0x18, MEMDUR_EVENT | ID_GEOMETRY);
header->serialNumber = 0;
header->numMeshes = meshh->numMeshes;
header->primType = meshh->flags == 1 ? D3DPT_TRIANGLESTRIP : D3DPT_TRIANGLELIST;
@ -221,9 +221,9 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
header->stride = 0;
header->vertexBuffer = nil;
InstanceData *inst = new InstanceData[header->numMeshes];
InstanceData *inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
header->begin = inst;
mesh = meshh->mesh;
mesh = meshh->getMeshes();
uint8 *indexbuf = (uint8*)header->data + ((0x18 + 0x24 + header->numMeshes*0x18 + 0xF)&~0xF);
for(uint32 i = 0; i < header->numMeshes; i++){
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
@ -251,13 +251,13 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
return;
assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_XBOX);
geo->flags &= ~Geometry::NATIVE;
geo->numTriangles = geo->meshHeader->guessNumTriangles();
geo->allocateData();
geo->meshHeader->allocateIndices();
geo->allocateMeshes(geo->meshHeader->numMeshes, geo->meshHeader->totalIndices, 0);
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
InstanceData *inst = header->begin;
Mesh *mesh = geo->meshHeader->mesh;
Mesh *mesh = geo->meshHeader->getMeshes();
for(uint32 i = 0; i < header->numMeshes; i++){
uint16 *indices = (uint16*)inst->indexBuffer;
memcpy(mesh->indices, indices, inst->numIndices*2);
@ -267,6 +267,7 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
pipe->uninstanceCB(geo, header);
geo->generateTriangles();
geo->flags &= ~Geometry::NATIVE;
destroyNativeData(geo, 0, 0);
}
@ -295,7 +296,7 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
if(*vertexFmt == 0)
*vertexFmt = makeVertexFmt(geo->flags, geo->numTexCoordSets);
header->stride = getVertexFmtStride(*vertexFmt);
header->vertexBuffer = new uint8[header->stride*header->numVertices];
header->vertexBuffer = rwNewT(uint8, header->stride*header->numVertices, MEMDUR_EVENT | ID_GEOMETRY);
uint8 *dst = (uint8*)header->vertexBuffer;
uint32 fmt = *vertexFmt;
@ -476,7 +477,8 @@ createTexture(int32 width, int32 height, int32 numlevels, uint32 format)
if(h == 0) h = 1;
}
size = (size+3)&~3;
uint8 *data = new uint8[sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1)+size];
uint8 *data = (uint8*)rwNew(sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1)+size,
MEMDUR_EVENT | ID_DRIVER);
RasterLevels *levels = (RasterLevels*)data;
data += sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1);
levels->numlevels = numlevels;
@ -536,7 +538,7 @@ rasterCreate(Raster *raster)
uint32 format;
if(raster->format & (Raster::PAL4 | Raster::PAL8)){
format = D3DFMT_P8;
natras->palette = new uint8[4*256];
natras->palette = (uint8*)rwNew(4*256, MEMDUR_EVENT | ID_DRIVER);
}else
format = formatMap[(raster->format >> 8) & 0xF];
natras->format = 0;

View File

@ -48,12 +48,12 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
return nil;
}
Skin *skin = new Skin;
Skin *skin = rwNewT(Skin, 1, MEMDUR_EVENT | ID_SKIN);
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
int32 numBones = stream->readI32();
skin->init(numBones, 0, 0);
NativeSkin *natskin = new NativeSkin;
NativeSkin *natskin = rwNewT(NativeSkin, 1, MEMDUR_EVENT | ID_SKIN);
skin->platformData = natskin;
stream->read(natskin->table1, 256*sizeof(int32));
stream->read(natskin->table2, 256*sizeof(int32));
@ -62,7 +62,7 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
stream->seek(4); // skip pointer to vertexBuffer
natskin->stride = stream->readI32();
int32 size = geometry->numVertices*natskin->stride;
natskin->vertexBuffer = new uint8[size];
natskin->vertexBuffer = rwNewT(uint8, size, MEMDUR_EVENT | ID_SKIN);
stream->read(natskin->vertexBuffer, size);
stream->read(skin->inverseMatrices, skin->numBones*64);
@ -119,7 +119,7 @@ skinInstanceCB(Geometry *geo, InstanceDataHeader *header)
Skin *skin = Skin::get(geo);
if(skin == nil)
return;
NativeSkin *natskin = new NativeSkin;
NativeSkin *natskin = rwNewT(NativeSkin, 1, MEMDUR_EVENT | ID_SKIN);
skin->platformData = natskin;
natskin->numUsedBones = skin->numUsedBones;
@ -131,7 +131,7 @@ skinInstanceCB(Geometry *geo, InstanceDataHeader *header)
}
natskin->stride = 3*skin->numWeights;
uint8 *vbuf = new uint8[header->numVertices*natskin->stride];
uint8 *vbuf = rwNewT(uint8, header->numVertices*natskin->stride, MEMDUR_EVENT | ID_SKIN);
natskin->vertexBuffer = vbuf;
int32 w[4];
@ -179,7 +179,7 @@ skinUninstanceCB(Geometry *geo, InstanceDataHeader *header)
float *invMats = skin->inverseMatrices;
skin->init(skin->numBones, natskin->numUsedBones, geo->numVertices);
memcpy(skin->inverseMatrices, invMats, skin->numBones*64);
delete[] data;
rwFree(data);
for(int32 j = 0; j < skin->numUsedBones; j++)
skin->usedBones[j] = natskin->table1[j];
@ -211,8 +211,8 @@ skinUninstanceCB(Geometry *geo, InstanceDataHeader *header)
}
}
delete[] (uint8*)natskin->vertexBuffer;
delete natskin;
rwFree(natskin->vertexBuffer);
rwFree(natskin);
}
static void*

View File

@ -18,6 +18,14 @@
#define PLUGIN_ID 0
// on windows
//#ifdef DEBUG
//#include <crtdbg.h>
//#define free(p) _free_dbg(p, _NORMAL_BLOCK);
//#define malloc(sz) _malloc_dbg(sz, _NORMAL_BLOCK, __FILE__, __LINE__)
//#define realloc(p, sz) _realloc_dbg(p, sz, _NORMAL_BLOCK, __FILE__, __LINE__)
//#endif
namespace rw {
Engine *engine;
@ -25,8 +33,29 @@ PluginList Driver::s_plglist[NUM_PLATFORMS];
Engine::State Engine::state = Dead;
MemoryFunctions Engine::memfuncs;
void *malloc_h(size_t sz, uint32 hint) { return malloc(sz); }
void *malloc_h(size_t sz, uint32 hint) { if(sz == 0) return nil; return malloc(sz); }
void *realloc_h(void *p, size_t sz, uint32 hint) { return realloc(p, sz); }
// TODO: make the debug out configurable
void *mustmalloc_h(size_t sz, uint32 hint)
{
void *ret;
ret = rwMalloc(sz, hint);
if(ret)
return ret;
fprintf(stderr, "Error: out of memory\n");
exit(1);
return nil;
}
void *mustrealloc_h(void *p, size_t sz, uint32 hint)
{
void *ret;
ret = rwRealloc(p, sz, hint);
if(ret)
return ret;
fprintf(stderr, "Error: out of memory\n");
exit(1);
return nil;
}
// This function mainly registers engine plugins
// RW initializes memory related things here too and
@ -40,9 +69,11 @@ Engine::init(void)
return 0;
}
memfuncs.malloc = malloc_h;
memfuncs.realloc = realloc_h;
memfuncs.free = free;
memfuncs.rwmalloc = malloc_h;
memfuncs.rwrealloc = realloc_h;
memfuncs.rwfree = free;
memfuncs.rwmustmalloc = mustmalloc_h;
memfuncs.rwmustrealloc = mustrealloc_h;
PluginList init = { sizeof(Driver), sizeof(Driver), nil, nil };
for(uint i = 0; i < NUM_PLATFORMS; i++)
@ -72,7 +103,7 @@ Engine::open(void)
}
// Allocate engine
engine = (Engine*)rwMalloc(sizeof(Engine), MEMDUR_GLOBAL);
engine = rwNewT(Engine, 1, MEMDUR_GLOBAL);
engine->currentCamera = nil;
engine->currentWorld = nil;
engine->currentTexDictionary = nil;
@ -97,7 +128,8 @@ Engine::open(void)
// TODO: init driver functions
ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL);
for(uint i = 0; i < NUM_PLATFORMS; i++){
rw::engine->driver[i] = (Driver*)malloc(Driver::s_plglist[i].size);
rw::engine->driver[i] = (Driver*)rwNew(Driver::s_plglist[i].size,
MEMDUR_GLOBAL);
engine->driver[i]->defaultPipeline = defpipe;

View File

@ -18,9 +18,9 @@ namespace rw {
PluginList Geometry::s_plglist = { sizeof(Geometry), sizeof(Geometry), nil, nil };
PluginList Material::s_plglist = { sizeof(Material), sizeof(Material), nil, nil };
SurfaceProperties defaultSurfaceProps = { 1.0f, 1.0f, 1.0f };
static SurfaceProperties defaultSurfaceProps = { 1.0f, 1.0f, 1.0f };
// TODO: allocate everything in one chunk
// We allocate twice because we have to allocate the data separately for uninstancing
Geometry*
Geometry::create(int32 numVerts, int32 numTris, uint32 flags)
{
@ -37,32 +37,41 @@ Geometry::create(int32 numVerts, int32 numTris, uint32 flags)
(geo->flags & TEXTURED2) ? 2 : 0;
geo->numTriangles = numTris;
geo->numVertices = numVerts;
geo->numMorphTargets = 1;
geo->colors = nil;
for(int32 i = 0; i < geo->numTexCoordSets; i++)
for(int32 i = 0; i < 8; i++)
geo->texCoords[i] = nil;
geo->triangles = nil;
if(!(geo->flags & NATIVE) && geo->numVertices){
// Allocate all attributes at once. The triangle pointer
// will hold the first address (even when there are no triangles)
// so we can free easily.
if(!(geo->flags & NATIVE)){
int32 sz = geo->numTriangles*sizeof(Triangle);
if(geo->flags & PRELIT)
geo->colors = new RGBA[geo->numVertices];
if((geo->flags & TEXTURED) || (geo->flags & TEXTURED2))
for(int32 i = 0; i < geo->numTexCoordSets; i++)
geo->texCoords[i] =
new TexCoords[geo->numVertices];
geo->triangles = new Triangle[geo->numTriangles];
sz += geo->numVertices*sizeof(RGBA);
sz += geo->numTexCoordSets*geo->numVertices*sizeof(TexCoords);
uint8 *data = (uint8*)rwNew(sz, MEMDUR_EVENT | ID_GEOMETRY);
geo->triangles = (Triangle*)data;
data += geo->numTriangles*sizeof(Triangle);
if(geo->flags & PRELIT && geo->numVertices){
geo->colors = (RGBA*)data;
data += geo->numVertices*sizeof(RGBA);
}
geo->morphTargets = new MorphTarget[1];
MorphTarget *m = geo->morphTargets;
m->boundingSphere.center.set(0.0f, 0.0f, 0.0f);
m->boundingSphere.radius = 0.0f;
m->vertices = nil;
m->normals = nil;
if(!(geo->flags & NATIVE) && geo->numVertices){
m->vertices = new V3d[geo->numVertices];
if(geo->flags & NORMALS)
m->normals = new V3d[geo->numVertices];
if(geo->numVertices)
for(int32 i = 0; i < geo->numTexCoordSets; i++){
geo->texCoords[i] = (TexCoords*)data;
data += geo->numVertices*sizeof(TexCoords);
}
// init triangles
for(int32 i = 0; i < geo->numTriangles; i++)
geo->triangles[i].matId = 0xFFFF;
}
geo->numMorphTargets = 0;
geo->morphTargets = nil;
geo->addMorphTargets(1);
geo->matList.init();
geo->meshHeader = nil;
geo->instData = nil;
@ -78,18 +87,12 @@ Geometry::destroy(void)
this->refCount--;
if(this->refCount <= 0){
s_plglist.destruct(this);
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;
// Also frees colors and tex coords
rwFree(this->triangles);
// Also frees their data
rwFree(this->morphTargets);
// Also frees indices
rwFree(this->meshHeader);
this->matList.deinit();
rwFree(this);
}
@ -158,6 +161,7 @@ Geometry::streamRead(Stream *stream)
}
if(version < 0x34000)
defaultSurfaceProps = surfProps;
ret = MaterialList::streamRead(stream, &geo->matList);
if(version < 0x34000)
defaultSurfaceProps = reset;
@ -271,20 +275,52 @@ Geometry::addMorphTargets(int32 n)
if(n == 0)
return;
n += this->numMorphTargets;
MorphTarget *morphTargets = new MorphTarget[n];
memcpy(morphTargets, this->morphTargets,
this->numMorphTargets*sizeof(MorphTarget));
delete[] this->morphTargets;
this->morphTargets = morphTargets;
for(int32 i = this->numMorphTargets; i < n; i++){
MorphTarget *m = &morphTargets[i];
m->vertices = nil;
m->normals = nil;
int32 sz;
sz = sizeof(MorphTarget);
if(!(this->flags & NATIVE)){
m->vertices = new V3d[this->numVertices];
sz += this->numVertices*sizeof(V3d);
if(this->flags & NORMALS)
m->normals = new V3d[this->numVertices];
sz += this->numVertices*sizeof(V3d);
}
// Memory layout: MorphTarget[n]; (vertices and normals)[n]
MorphTarget *mts;
if(this->numMorphTargets){
mts = (MorphTarget*)rwResize(this->morphTargets, n*sz, MEMDUR_EVENT | ID_GEOMETRY);
this->morphTargets = mts;
// Since we now have more morph targets than before, move the vertex data up
uint8 *src = (uint8*)mts + sz*this->numMorphTargets;
uint8 *dst = (uint8*)mts + sz*n;
uint32 len = (sz-sizeof(MorphTarget))*this->numMorphTargets;
while(len--)
*--dst = *--src;
}else{
mts = (MorphTarget*)rwNew(n*sz, MEMDUR_EVENT | ID_GEOMETRY);
this->morphTargets = mts;
}
// Set up everything and initialize the bounding sphere for new morph targets
V3d *data = (V3d*)&mts[n];
for(int32 i = 0; i < n; i++){
mts->parent = this;
mts->vertices = nil;
mts->normals = nil;
if(i >= this->numMorphTargets){
mts->boundingSphere.center.x = 0.0f;
mts->boundingSphere.center.y = 0.0f;
mts->boundingSphere.center.z = 0.0f;
mts->boundingSphere.radius = 0.0f;
}
if(!(this->flags & NATIVE) && this->numVertices){
mts->vertices = data;
data += this->numVertices;
if(this->flags & NORMALS){
mts->normals = data;
data += this->numVertices;
}
}
mts++;
}
this->numMorphTargets = n;
}
@ -324,21 +360,54 @@ Geometry::hasColoredMaterial(void)
return 0;
}
// TODO: allocate as one chunk
// Force allocate data, even when native flag is set
void
Geometry::allocateData(void)
{
// Geometry data
// Pretty much copy pasted from ::create above
int32 sz = this->numTriangles*sizeof(Triangle);
if(this->flags & PRELIT)
this->colors = new RGBA[this->numVertices];
if((this->flags & TEXTURED) || (this->flags & TEXTURED2))
for(int32 i = 0; i < this->numTexCoordSets; i++)
this->texCoords[i] =
new TexCoords[this->numVertices];
for(int32 i = 0; i < this->numMorphTargets; i++){
MorphTarget *m = &morphTargets[i];
m->vertices = new V3d[this->numVertices];
sz += this->numVertices*sizeof(RGBA);
sz += this->numTexCoordSets*this->numVertices*sizeof(TexCoords);
uint8 *data = (uint8*)rwNew(sz, MEMDUR_EVENT | ID_GEOMETRY);
this->triangles = (Triangle*)data;
data += this->numTriangles*sizeof(Triangle);
for(int32 i = 0; i < this->numTriangles; i++)
this->triangles[i].matId = 0xFFFF;
if(this->flags & PRELIT){
this->colors = (RGBA*)data;
data += this->numVertices*sizeof(RGBA);
}
for(int32 i = 0; i < this->numTexCoordSets; i++){
this->texCoords[i] = (TexCoords*)data;
data += this->numVertices*sizeof(TexCoords);
}
// MorphTarget data
// Bounding sphere is copied by realloc.
sz = sizeof(MorphTarget) + this->numVertices*sizeof(V3d);
if(this->flags & NORMALS)
m->normals = new V3d[this->numVertices];
sz += this->numVertices*sizeof(V3d);
MorphTarget *mt = (MorphTarget*)rwResize(this->morphTargets,
sz*this->numMorphTargets, MEMDUR_EVENT | ID_GEOMETRY);
this->morphTargets = mt;
V3d *vdata = (V3d*)&mt[this->numMorphTargets];
for(int32 i = 0; i < this->numMorphTargets; i++){
mt->parent = this;
mt->vertices = nil;
mt->normals = nil;
if(this->numVertices){
mt->vertices = vdata;
vdata += this->numVertices;
if(this->flags & NORMALS){
mt->normals = vdata;
vdata += this->numVertices;
}
}
mt++;
}
}
@ -350,6 +419,9 @@ isDegenerate(uint16 *idx)
idx[1] == idx[2];
}
// This functions assumes there is enough space allocated
// for triangles. Use MeshHeader::guessNumTriangles() and
// Geometry::allocateData()
void
Geometry::generateTriangles(int8 *adc)
{
@ -357,7 +429,7 @@ Geometry::generateTriangles(int8 *adc)
assert(header != nil);
this->numTriangles = 0;
Mesh *m = header->mesh;
Mesh *m = header->getMeshes();
int8 *adcbits = adc;
for(uint32 i = 0; i < header->numMeshes; i++){
if(m->numIndices < 3){
@ -378,11 +450,8 @@ Geometry::generateTriangles(int8 *adc)
m++;
}
delete[] this->triangles;
this->triangles = new Triangle[this->numTriangles];
Triangle *tri = this->triangles;
m = header->mesh;
m = header->getMeshes();
adcbits = adc;
for(uint32 i = 0; i < header->numMeshes; i++){
if(m->numIndices < 3){
@ -434,38 +503,44 @@ dumpMesh(Mesh *m)
void
Geometry::buildMeshes(void)
{
//dumpMesh(this->meshHeader->mesh);
delete this->meshHeader;
Triangle *tri;
MeshHeader *h = new MeshHeader;
this->meshHeader = h;
Mesh *mesh;
rwFree(this->meshHeader);
this->meshHeader = nil;
int32 numMeshes = this->matList.numMaterials;
if((this->flags & Geometry::TRISTRIP) == 0){
h->flags = 0;
h->totalIndices = this->numTriangles*3;
h->numMeshes = this->matList.numMaterials;
h->mesh = new Mesh[h->numMeshes];
for(uint32 i = 0; i < h->numMeshes; i++){
h->mesh[i].material = this->matList.materials[i];
h->mesh[i].numIndices = 0;
}
int32 *numIndices = rwNewT(int32, numMeshes,
MEMDUR_FUNCTION | ID_GEOMETRY);
memset(numIndices, 0, numMeshes*sizeof(int32));
// count indices per mesh
tri = this->triangles;
for(int32 i = 0; i < this->numTriangles; i++){
h->mesh[tri->matId].numIndices += 3;
assert(tri->matId >= 0 && tri->matId < numMeshes);
numIndices[tri->matId] += 3;
tri++;
}
h->allocateIndices();
for(uint32 i = 0; i < h->numMeshes; i++)
h->mesh[i].numIndices = 0;
// same as above but fill with indices
// setup meshes
this->allocateMeshes(numMeshes, this->numTriangles*3, 0);
mesh = this->meshHeader->getMeshes();
for(int32 i = 0; i < numMeshes; i++){
mesh[i].material = this->matList.materials[i];
mesh[i].numIndices = numIndices[i];
}
this->meshHeader->setupIndices();
rwFree(numIndices);
// now fill in the indices
for(int32 i = 0; i < numMeshes; i++)
mesh[i].numIndices = 0;
tri = this->triangles;
for(int32 i = 0; i < this->numTriangles; i++){
uint32 idx = h->mesh[tri->matId].numIndices;
h->mesh[tri->matId].indices[idx++] = tri->v[0];
h->mesh[tri->matId].indices[idx++] = tri->v[1];
h->mesh[tri->matId].indices[idx++] = tri->v[2];
h->mesh[tri->matId].numIndices = idx;
uint32 idx = mesh[tri->matId].numIndices;
mesh[tri->matId].indices[idx++] = tri->v[0];
mesh[tri->matId].indices[idx++] = tri->v[1];
mesh[tri->matId].indices[idx++] = tri->v[2];
mesh[tri->matId].numIndices = idx;
tri++;
}
}else
@ -479,19 +554,19 @@ void
Geometry::correctTristripWinding(void)
{
MeshHeader *header = this->meshHeader;
if(header == nil || header->flags != MeshHeader::TRISTRIP ||
this->instData)
if(this->flags & NATIVE || header == nil ||
header->flags != MeshHeader::TRISTRIP)
return;
MeshHeader *newhead = new MeshHeader;
this->meshHeader = nil;
// Allocate no indices, we realloc later
MeshHeader *newhead = this->allocateMeshes(header->numMeshes, 0, 1);
newhead->flags = header->flags;
newhead->numMeshes = header->numMeshes;
newhead->totalIndices = 0;
newhead->mesh = new Mesh[newhead->numMeshes];
/* get a temporary working buffer */
uint16 *indices = new uint16[header->totalIndices*2];
uint16 *indices = rwNewT(uint16, header->totalIndices*2,
MEMDUR_FUNCTION | ID_GEOMETRY);
Mesh *mesh = header->mesh;
Mesh *newmesh = newhead->mesh;
Mesh *mesh = header->getMeshes();
Mesh *newmesh = newhead->getMeshes();
for(uint16 i = 0; i < header->numMeshes; i++){
newmesh->numIndices = 0;
newmesh->indices = &indices[newhead->totalIndices];
@ -523,11 +598,11 @@ Geometry::correctTristripWinding(void)
mesh++;
newmesh++;
}
newhead->allocateIndices();
memcpy(newhead->mesh[0].indices, indices, newhead->totalIndices*2);
delete[] indices;
this->meshHeader = newhead;
delete header;
rwFree(header);
// Now allocate indices and copy them
this->allocateMeshes(newhead->numMeshes, newhead->totalIndices, 0);
memcpy(this->meshHeader->getMeshes()->indices, indices, newhead->totalIndices*2);
rwFree(indices);
}
void
@ -536,16 +611,18 @@ Geometry::removeUnusedMaterials(void)
if(this->meshHeader == nil)
return;
MeshHeader *mh = this->meshHeader;
Mesh *m = mh->getMeshes();
for(uint32 i = 0; i < mh->numMeshes; i++)
if(mh->mesh[i].indices == nil)
if(m[i].indices == nil)
return;
int32 *map = new int32[this->matList.numMaterials];
Material **materials = new Material*[this->matList.numMaterials];
int32 *map = rwNewT(int32, this->matList.numMaterials,
MEMDUR_FUNCTION | ID_GEOMETRY);
Material **materials = rwNewT(Material*,this->matList.numMaterials,
MEMDUR_EVENT | ID_MATERIAL);
int32 numMaterials = 0;
/* Build new material list and map */
for(uint32 i = 0; i < mh->numMeshes; i++){
Mesh *m = &mh->mesh[i];
if(m->numIndices <= 0)
continue;
materials[numMaterials] = m->material;
@ -553,6 +630,7 @@ Geometry::removeUnusedMaterials(void)
int32 oldid = this->matList.findIndex(m->material);
map[oldid] = numMaterials;
numMaterials++;
m++;
}
for(int32 i = 0; i < this->matList.numMaterials; i++)
this->matList.materials[i]->destroy();
@ -562,38 +640,35 @@ Geometry::removeUnusedMaterials(void)
this->matList.numMaterials = numMaterials;
/* Build new meshes */
MeshHeader *newmh = new MeshHeader;
this->meshHeader = nil;
MeshHeader *newmh = this->allocateMeshes(numMaterials, mh->totalIndices, 0);
newmh->flags = mh->flags;
newmh->numMeshes = numMaterials;
newmh->mesh = new Mesh[newmh->numMeshes];
newmh->totalIndices = mh->totalIndices;
Mesh *newm = newmh->mesh;
Mesh *newm = newmh->getMeshes();
m = mh->getMeshes();
for(uint32 i = 0; i < mh->numMeshes; i++){
Mesh *oldm = &mh->mesh[i];
if(oldm->numIndices <= 0)
if(m[i].numIndices <= 0)
continue;
newm->numIndices = oldm->numIndices;
newm->material = oldm->material;
newm->numIndices = m[i].numIndices;
newm->material = m[i].material;
newm++;
}
newmh->allocateIndices();
newmh->setupIndices();
/* Copy indices */
newm = newmh->mesh;
newm = newmh->getMeshes();;
m = mh->getMeshes();
for(uint32 i = 0; i < mh->numMeshes; i++){
Mesh *oldm = &mh->mesh[i];
if(oldm->numIndices <= 0)
if(m[i].numIndices <= 0)
continue;
memcpy(newm->indices, oldm->indices,
oldm->numIndices*sizeof(*oldm->indices));
memcpy(newm->indices, m[i].indices,
m[i].numIndices*sizeof(*m[i].indices));
newm++;
}
delete this->meshHeader;
this->meshHeader = newmh;
rwFree(mh);
/* Remap triangle material IDs */
for(int32 i = 0; i < this->numTriangles; i++)
this->triangles[i].matId = map[this->triangles[i].matId];
delete[] map;
rwFree(map);
}
//
@ -628,12 +703,10 @@ MaterialList::appendMaterial(Material *mat)
if(this->numMaterials >= this->space){
space = this->space + 20;
if(this->materials)
ml = (Material**)rwRealloc(this->materials,
space*sizeof(Material*),
ml = rwReallocT(Material*, this->materials, space,
MEMDUR_EVENT | ID_MATERIAL);
else
ml = (Material**)rwMalloc(space*sizeof(Material*),
MEMDUR_EVENT | ID_MATERIAL);
ml = rwMallocT(Material*, space, MEMDUR_EVENT | ID_MATERIAL);
if(ml == nil)
return -1;
this->space = space;
@ -666,7 +739,7 @@ MaterialList::streamRead(Stream *stream, MaterialList *matlist)
numMat = stream->readI32();
if(numMat == 0)
return matlist;
matlist->materials = (Material**)rwMalloc(numMat*sizeof(Material*), MEMDUR_EVENT | ID_MATERIAL);
matlist->materials = rwMallocT(Material*,numMat, MEMDUR_EVENT | ID_MATERIAL);
if(matlist->materials == nil)
goto fail;
matlist->space = numMat;

View File

@ -25,39 +25,119 @@ namespace rw {
// Mesh
// Allocate a mesh header, meshes and optionally indices.
// If existing meshes already exist, retain their information.
MeshHeader*
Geometry::allocateMeshes(int32 numMeshes, uint32 numIndices, bool32 noIndices)
{
uint32 sz;
MeshHeader *mh;
Mesh *m;
uint16 *indices;
int32 oldNumMeshes;
int32 i;
sz = sizeof(MeshHeader) + numMeshes*sizeof(Mesh);
if(!noIndices)
sz += numIndices*sizeof(uint16);
if(this->meshHeader){
oldNumMeshes = this->meshHeader->numMeshes;
mh = (MeshHeader*)rwResize(this->meshHeader, sz, MEMDUR_EVENT | ID_GEOMETRY);
}else{
oldNumMeshes = 0;
mh = (MeshHeader*)rwNew(sz, MEMDUR_EVENT | ID_GEOMETRY);
mh->flags = 0;
this->meshHeader = mh;
}
mh->numMeshes = numMeshes;
mh->serialNum = 0; // TODO
mh->totalIndices = numIndices;
m = mh->getMeshes();
indices = (uint16*)&m[numMeshes];
for(i = 0; i < mh->numMeshes; i++){
// keep these
if(i >= oldNumMeshes){
m->material = nil;
m->numIndices = 0;
}
// always init indices
if(noIndices)
m->indices = nil;
else{
m->indices = indices;
indices += m->numIndices;
}
m++;
}
return mh;
}
void
MeshHeader::setupIndices(void)
{
int32 i;
uint16 *indices;
Mesh *m;
m = this->getMeshes();
indices = m->indices;
// return if native
if(indices == nil)
return;
for(i = 0; i < this->numMeshes; i++){
m->indices = indices;
indices += m->numIndices;
m++;
}
}
struct MeshHeaderStream
{
uint32 flags;
uint32 numMeshes;
uint32 totalIndices;
};
struct MeshStream
{
uint32 numIndices;
int32 matIndex;
};
static Stream*
readMesh(Stream *stream, int32 len, void *object, int32, int32)
{
Geometry *geo = (Geometry*)object;
MeshHeaderStream mhs;
MeshStream ms;
MeshHeader *mh;
Mesh *mesh;
int32 indbuf[256];
uint32 buf[3];
stream->read(buf, 12);
geo->meshHeader = new MeshHeader;
geo->meshHeader->flags = buf[0];
geo->meshHeader->numMeshes = buf[1];
geo->meshHeader->totalIndices = buf[2];
geo->meshHeader->mesh = new Mesh[geo->meshHeader->numMeshes];
Mesh *mesh = geo->meshHeader->mesh;
bool hasData = len > 12+geo->meshHeader->numMeshes*8;
uint16 *p = nil;
if(!(geo->flags & Geometry::NATIVE) || hasData)
p = new uint16[geo->meshHeader->totalIndices];
for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){
stream->read(buf, 8);
mesh->numIndices = buf[0];
mesh->material = geo->matList.materials[buf[1]];
mesh->indices = nil;
uint16 *indices;
Geometry *geo = (Geometry*)object;
stream->read(&mhs, sizeof(MeshHeaderStream));
// Have to do this dance for War Drum's meshes
bool32 hasData = len > sizeof(MeshHeaderStream)+mhs.numMeshes*sizeof(MeshStream);
assert(geo->meshHeader == nil);
geo->meshHeader = nil;
mh = geo->allocateMeshes(mhs.numMeshes, mhs.totalIndices,
geo->flags & Geometry::NATIVE && !hasData);
mesh = mh->getMeshes();
indices = mesh->indices;
for(uint32 i = 0; i < mh->numMeshes; i++){
stream->read(&ms, sizeof(MeshStream));
mesh->numIndices = ms.numIndices;
mesh->material = geo->matList.materials[ms.matIndex];
if(geo->flags & Geometry::NATIVE){
// OpenGL stores uint16 indices here
// War Drum OpenGL stores uint16 indices here
if(hasData){
mesh->indices = p;
p += mesh->numIndices;
mesh->indices = indices;
indices += mesh->numIndices;
stream->read(mesh->indices,
mesh->numIndices*2);
}
}else{
mesh->indices = p;
p += mesh->numIndices;
mesh->indices = indices;
indices += mesh->numIndices;
uint16 *ind = mesh->indices;
int32 numIndices = mesh->numIndices;
for(; numIndices > 0; numIndices -= 256){
@ -76,18 +156,19 @@ readMesh(Stream *stream, int32 len, void *object, int32, int32)
static Stream*
writeMesh(Stream *stream, int32, void *object, int32, int32)
{
Geometry *geo = (Geometry*)object;
MeshHeaderStream mhs;
MeshStream ms;
int32 indbuf[256];
uint32 buf[3];
buf[0] = geo->meshHeader->flags;
buf[1] = geo->meshHeader->numMeshes;
buf[2] = geo->meshHeader->totalIndices;
stream->write(buf, 12);
Mesh *mesh = geo->meshHeader->mesh;
Geometry *geo = (Geometry*)object;
mhs.flags = geo->meshHeader->flags;
mhs.numMeshes = geo->meshHeader->numMeshes;
mhs.totalIndices = geo->meshHeader->totalIndices;
stream->write(&mhs, sizeof(MeshHeaderStream));
Mesh *mesh = geo->meshHeader->getMeshes();
for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){
buf[0] = mesh->numIndices;
buf[1] = geo->matList.findIndex(mesh->material);
stream->write(buf, 8);
ms.numIndices = mesh->numIndices;
ms.matIndex = geo->matList.findIndex(mesh->material);
stream->write(&ms, sizeof(MeshStream));
if(geo->flags & Geometry::NATIVE){
assert(geo->instData != nil);
if(geo->instData->platform == PLATFORM_WDGL)
@ -133,23 +214,17 @@ registerMeshPlugin(void)
Geometry::registerPluginStream(0x50E, readMesh, writeMesh, getSizeMesh);
}
MeshHeader::~MeshHeader(void)
// Returns the maximum number of triangles. Just so
// we can allocate enough before instancing. This does not
// take into account degerate triangles or ADC bits as
// we don't look at the data.
uint32
MeshHeader::guessNumTriangles(void)
{
// first mesh holds pointer to all indices
delete[] this->mesh[0].indices;
delete[] this->mesh;
}
void
MeshHeader::allocateIndices(void)
{
uint16 *p = new uint16[this->totalIndices];
Mesh *mesh = this->mesh;
for(uint32 i = 0; i < this->numMeshes; i++){
mesh->indices = p;
p += mesh->numIndices;
mesh++;
}
if(this->flags == MeshHeader::TRISTRIP)
return this->totalIndices - 2*this->numMeshes;
else
return this->totalIndices/3;
}
// Native Data

View File

@ -30,7 +30,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
// TODO: allow for REINSTANCE
if(geo->instData)
return;
InstanceDataHeader *header = new InstanceDataHeader;
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
MeshHeader *meshh = geo->meshHeader;
geo->instData = header;
header->platform = PLATFORM_GL3;
@ -40,11 +40,11 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
header->primType = meshh->flags == 1 ? GL_TRIANGLE_STRIP : GL_TRIANGLES;
header->totalNumVertex = geo->numVertices;
header->totalNumIndex = meshh->totalIndices;
header->inst = new InstanceData[header->numMeshes];
header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
header->indexBuffer = new uint16[header->totalNumIndex];
header->indexBuffer = rwNewT(uint16, header->totalNumIndex, MEMDUR_EVENT | ID_GEOMETRY);
InstanceData *inst = header->inst;
Mesh *mesh = meshh->mesh;
Mesh *mesh = meshh->getMeshes();
uint32 offset = 0;
for(uint32 i = 0; i < header->numMeshes; i++){
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
@ -167,14 +167,14 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
header->numAttribs = a - attribs;
for(a = attribs; a != &attribs[header->numAttribs]; a++)
a->stride = stride;
header->attribDesc = new AttribDesc[header->numAttribs];
header->attribDesc = rwNewT(AttribDesc, header->numAttribs, MEMDUR_EVENT | ID_GEOMETRY);
memcpy(header->attribDesc, attribs,
header->numAttribs*sizeof(AttribDesc));
//
// Allocate and fill vertex buffer
//
uint8 *verts = new uint8[header->totalNumVertex*stride];
uint8 *verts = rwNewT(uint8, header->totalNumVertex*stride, MEMDUR_EVENT | ID_GEOMETRY);
header->vertexBuffer = verts;
// Positions

View File

@ -342,7 +342,7 @@ skinInstanceCB(Geometry *geo, InstanceDataHeader *header)
header->numAttribs = a - attribs;
for(a = attribs; a != &attribs[header->numAttribs]; a++)
a->stride = stride;
header->attribDesc = new AttribDesc[header->numAttribs];
header->attribDesc = rwNewT(AttribDesc, header->numAttribs, MEMDUR_EVENT | ID_GEOMETRY);
memcpy(header->attribDesc, attribs,
header->numAttribs*sizeof(AttribDesc));
@ -350,7 +350,7 @@ skinInstanceCB(Geometry *geo, InstanceDataHeader *header)
// Allocate and fill vertex buffer
//
Skin *skin = Skin::get(geo);
uint8 *verts = new uint8[header->totalNumVertex*stride];
uint8 *verts = rwNewT(uint8, header->totalNumVertex*stride, MEMDUR_EVENT | ID_GEOMETRY);
header->vertexBuffer = verts;
// Positions

View File

@ -154,7 +154,7 @@ Shader::fromStrings(const char *vsrc, const char *fsrc)
glDeleteProgram(vs);
glDeleteProgram(fs);
Shader *sh = new Shader;
Shader *sh = rwNewT(Shader, 1, MEMDUR_EVENT | ID_DRIVER); // or global?
// set uniform block binding
for(i = 0; i < uniformRegistry.numBlocks; i++){
@ -166,7 +166,7 @@ Shader::fromStrings(const char *vsrc, const char *fsrc)
// query uniform locations
sh->program = program;
sh->uniformLocations = new GLint[uniformRegistry.numUniforms];
sh->uniformLocations = rwNewT(GLint, uniformRegistry.numUniforms, MEMDUR_EVENT | ID_DRIVER);
for(i = 0; i < uniformRegistry.numUniforms; i++)
sh->uniformLocations[i] = glGetUniformLocation(program,
uniformRegistry.uniformNames[i]);

View File

@ -95,7 +95,7 @@ uploadGeo(Geometry *geo)
0, GL_STATIC_DRAW);
GLintptr offset = 0;
for(uint32 i = 0; i < meshHeader->numMeshes; i++){
Mesh *mesh = &meshHeader->mesh[i];
Mesh *mesh = &meshHeader->getMeshes()[i];
glBufferSubData(GL_ARRAY_BUFFER, offset, mesh->numIndices*2,
mesh->indices);
offset += mesh->numIndices*2;
@ -240,9 +240,9 @@ destroyNativeData(void *object, int32, int32)
(InstanceDataHeader*)geometry->instData;
geometry->instData = nil;
// TODO: delete ibo and vbo
delete[] header->attribs;
delete[] header->data;
delete header;
rwFree(header->attribs);
rwFree(header->data);
rwFree(header);
return object;
}
@ -250,17 +250,17 @@ Stream*
readNativeData(Stream *stream, int32, void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
InstanceDataHeader *header = new InstanceDataHeader;
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
geometry->instData = header;
header->platform = PLATFORM_WDGL;
header->vbo = 0;
header->ibo = 0;
header->numAttribs = stream->readU32();
header->attribs = new AttribDesc[header->numAttribs];
header->attribs = rwNewT(AttribDesc, header->numAttribs, MEMDUR_EVENT | ID_GEOMETRY);
stream->read(header->attribs,
header->numAttribs*sizeof(AttribDesc));
header->dataSize = header->attribs[0].stride*geometry->numVertices;
header->data = new uint8[header->dataSize];
header->data = rwNewT(uint8, header->dataSize, MEMDUR_EVENT | ID_GEOMETRY);
stream->read(header->data, header->dataSize);
return stream;
}
@ -325,7 +325,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
// TODO: allow for REINSTANCE (or not, wdgl can't render)
if(geo->instData)
return;
InstanceDataHeader *header = new InstanceDataHeader;
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
geo->instData = header;
header->platform = PLATFORM_WDGL;
header->vbo = 0;
@ -337,7 +337,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
if(geo->flags & Geometry::NORMALS)
header->numAttribs++;
int32 offset = 0;
header->attribs = new AttribDesc[header->numAttribs];
header->attribs = rwNewT(AttribDesc, header->numAttribs, MEMDUR_EVENT | ID_GEOMETRY);
AttribDesc *a = header->attribs;
// Vertices
@ -388,7 +388,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
offset += pipe->instanceCB(geo, firstCustom, offset);
else{
header->dataSize = offset*geo->numVertices;
header->data = new uint8[header->dataSize];
header->data = rwNewT(uint8, header->dataSize, MEMDUR_EVENT | ID_GEOMETRY);
}
a = header->attribs;
@ -453,7 +453,7 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
return;
assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_WDGL);
geo->flags &= ~Geometry::NATIVE;
geo->numTriangles = geo->meshHeader->guessNumTriangles();
geo->allocateData();
uint8 *p;
@ -513,6 +513,7 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
geo->generateTriangles();
geo->flags &= ~Geometry::NATIVE;
destroyNativeData(geo, 0, 0);
}
@ -549,7 +550,7 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
RWERROR((ERR_PLATFORM, platform));
return nil;
}
Skin *skin = new Skin;
Skin *skin = rwNewT(Skin, 1, MEMDUR_EVENT | ID_SKIN);
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
int32 numBones = stream->readI32();
@ -602,7 +603,7 @@ skinInstanceCB(Geometry *g, int32 i, uint32 offset)
offset += 4;
header->dataSize = offset*g->numVertices;
header->data = new uint8[header->dataSize];
header->data = rwNewT(uint8, header->dataSize, MEMDUR_EVENT | ID_GEOMETRY);
Skin *skin = Skin::get(g);
if(skin == nil)
@ -640,7 +641,7 @@ skinUninstanceCB(Geometry *geo)
float *invMats = skin->inverseMatrices;
skin->init(skin->numBones, skin->numBones, geo->numVertices);
memcpy(skin->inverseMatrices, invMats, skin->numBones*64);
delete[] data;
rwFree(data);
uint8 *p;
float *weights = skin->weights;

View File

@ -45,12 +45,11 @@ HAnimHierarchy::create(int32 numNodes, int32 *nodeFlags, int32 *nodeIDs,
hier->matrices = nil;
hier->matricesUnaligned = nil;
}else{
hier->matricesUnaligned =
(void*) new uint8[hier->numNodes*64 + 15];
hier->matricesUnaligned = rwNew(hier->numNodes*64 + 0xF, MEMDUR_EVENT | ID_HANIM);
hier->matrices =
(Matrix*)((uintptr)hier->matricesUnaligned & ~0xF);
}
hier->nodeInfo = new HAnimNodeInfo[hier->numNodes];
hier->nodeInfo = rwNewT(HAnimNodeInfo, hier->numNodes, MEMDUR_EVENT | ID_HANIM);
for(int32 i = 0; i < hier->numNodes; i++){
hier->nodeInfo[i].id = nodeIDs[i];
hier->nodeInfo[i].index = i;
@ -63,8 +62,8 @@ HAnimHierarchy::create(int32 numNodes, int32 *nodeFlags, int32 *nodeIDs,
void
HAnimHierarchy::destroy(void)
{
delete[] (uint8*)this->matricesUnaligned;
delete[] this->nodeInfo;
rwFree(this->matricesUnaligned);
rwFree(this->nodeInfo);
rwFree(this);
}
@ -208,8 +207,10 @@ readHAnim(Stream *stream, int32, void *object, int32 offset, int32)
int32 maxKeySize = stream->readI32();
// Sizes are fucked for 64 bit pointers but
// AnimInterpolator::create() will take care of that
int32 *nodeFlags = new int32[numNodes];
int32 *nodeIDs = new int32[numNodes];
int32 *nodeFlags = rwNewT(int32, numNodes,
MEMDUR_FUNCTION | ID_HANIM);
int32 *nodeIDs = rwNewT(int32, numNodes,
MEMDUR_FUNCTION | ID_HANIM);
for(int32 i = 0; i < numNodes; i++){
nodeIDs[i] = stream->readI32();
stream->readI32(); // index...unused
@ -218,8 +219,8 @@ readHAnim(Stream *stream, int32, void *object, int32 offset, int32)
hanim->hierarchy = HAnimHierarchy::create(numNodes,
nodeFlags, nodeIDs, flags, maxKeySize);
hanim->hierarchy->parentFrame = (Frame*)object;
delete[] nodeFlags;
delete[] nodeIDs;
rwFree(nodeFlags);
rwFree(nodeIDs);
}
return stream;
}
@ -325,7 +326,7 @@ registerHAnimPlugin(void)
writeHAnim,
getSizeHAnim);
AnimInterpolatorInfo *info = new AnimInterpolatorInfo;
AnimInterpolatorInfo *info = rwNewT(AnimInterpolatorInfo, 1, MEMDUR_GLOBAL | ID_HANIM);
info->id = 1;
info->interpKeyFrameSize = sizeof(HAnimInterpFrame);
info->animKeyFrameSize = sizeof(HAnimKeyFrame);

View File

@ -51,12 +51,12 @@ Image::allocate(void)
{
if(this->pixels == nil){
this->stride = this->width*(this->depth==4 ? 1 : this->depth/8);
this->pixels = new uint8[this->stride*this->height];
this->pixels = rwNewT(uint8, this->stride*this->height, MEMDUR_EVENT | ID_IMAGE);
this->flags |= 1;
}
if(this->palette == nil){
if(this->depth == 4 || this->depth == 8)
this->palette = new uint8[(this->depth==4? 16 : 256)*4];
this->palette = rwNewT(uint8, (this->depth==4? 16 : 256)*4, MEMDUR_EVENT | ID_IMAGE);
this->flags |= 2;
}
}
@ -65,11 +65,11 @@ void
Image::free(void)
{
if(this->flags&1){
delete[] this->pixels;
rwFree(this->pixels);
this->pixels = nil;
}
if(this->flags&2){
delete[] this->palette;
rwFree(this->palette);
this->palette = nil;
}
}
@ -355,7 +355,7 @@ Image::unindex(void)
int32 ndepth = this->hasAlpha() ? 32 : 24;
int32 nstride = this->width*ndepth/8;
uint8 *npixels = new uint8[nstride*this->height];
uint8 *npixels = rwNewT(uint8, nstride*this->height, MEMDUR_EVENT | ID_IMAGE);
uint8 *line = this->pixels;
uint8 *nline = npixels;

View File

@ -101,7 +101,7 @@ MatFX::setEffects(Material *mat, uint32 type)
matfx = MatFX::get(mat);
if(matfx == nil){
matfx = new MatFX;
matfx = rwNewT(MatFX, 1, MEMDUR_EVENT | ID_MATFX);
memset(matfx, 0, sizeof(MatFX));
*PLUGINOFFSET(MatFX*, mat, matFXGlobals.materialOffset) = matfx;
}
@ -231,7 +231,7 @@ destroyMaterialMatFX(void *object, int32 offset, int32)
MatFX *matfx = *PLUGINOFFSET(MatFX*, object, offset);
if(matfx){
clearMatFX(matfx);
delete matfx;
rwFree(matfx);
}
return object;
}
@ -242,7 +242,7 @@ copyMaterialMatFX(void *dst, void *src, int32 offset, int32)
MatFX *srcfx = *PLUGINOFFSET(MatFX*, src, offset);
if(srcfx == nil)
return dst;
MatFX *dstfx = new MatFX;
MatFX *dstfx = rwNewT(MatFX, 1, MEMDUR_EVENT | ID_MATFX);
*PLUGINOFFSET(MatFX*, dst, offset) = dstfx;
memcpy(dstfx, srcfx, sizeof(MatFX));
for(int i = 0; i < 2; i++)

View File

@ -61,7 +61,7 @@ registerPDSPlugin(int32 n)
{
pdsGlobals.maxPipes = n;
pdsGlobals.numPipes = 0;
pdsGlobals.pipes = new Pipeline*[n];
pdsGlobals.pipes = rwNewT(Pipeline*, n, MEMDUR_GLOBAL | ID_PDS);
Atomic::registerPlugin(0, ID_PDS, nil, nil, nil);
Atomic::setStreamRightsCallback(ID_PDS, atomicPDSRights);

View File

@ -61,9 +61,10 @@ destroyNativeData(void *object, int32, int32)
return object;
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
for(uint32 i = 0; i < header->numMeshes; i++)
delete[] header->instanceMeshes[i].data;
delete[] header->instanceMeshes;
delete header;
rwFree(header->instanceMeshes[i].data);
rwFree(header->instanceMeshes);
rwFree(header);
geometry->instData = nil;
return object;
}
@ -81,19 +82,20 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
RWERROR((ERR_PLATFORM, platform));
return nil;
}
InstanceDataHeader *header = new InstanceDataHeader;
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
geometry->instData = header;
header->platform = PLATFORM_PS2;
assert(geometry->meshHeader != nil);
header->numMeshes = geometry->meshHeader->numMeshes;
header->instanceMeshes = new InstanceData[header->numMeshes];
header->instanceMeshes = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
Mesh *m = geometry->meshHeader->getMeshes();
for(uint32 i = 0; i < header->numMeshes; i++){
InstanceData *instance = &header->instanceMeshes[i];
uint32 buf[2];
stream->read(buf, 8);
instance->dataSize = buf[0];
// TODO: force alignment
instance->data = new uint8[instance->dataSize];
instance->data = rwNewT(uint8, instance->dataSize, MEMDUR_EVENT | ID_GEOMETRY);
#ifdef RW_PS2
uint32 a = (uint32)instance->data;
assert(a % 0x10 == 0);
@ -103,8 +105,9 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
if(!buf[1])
fixDmaOffsets(instance);
#endif
instance->material = geometry->meshHeader->mesh[i].material;
instance->material = m->material;
// sizedebug(instance);
m++;
}
return stream;
}
@ -591,7 +594,7 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
inst->dataSize = (im.size+im.size2)<<4;
// TODO: force alignment
inst->data = new uint8[inst->dataSize];
inst->data = rwNewT(uint8, inst->dataSize, MEMDUR_EVENT | ID_GEOMETRY);
/* make array of addresses of broken out sections */
uint8 *datap[nelem(this->attribs)];
@ -700,8 +703,7 @@ MatPipeline::collectData(Geometry *g, InstanceData *inst, Mesh *m, uint8 *data[]
PipeAttribute *a;
InstMeshInfo im = getInstMeshInfo(this, g, m);
uint8 *raw = im.vertexSize*m->numIndices ?
new uint8[im.vertexSize*m->numIndices] : nil;
uint8 *raw = rwNewT(uint8, im.vertexSize*m->numIndices, MEMDUR_EVENT | ID_GEOMETRY);
uint8 *dp = raw;
for(uint i = 0; i < nelem(this->attribs); i++)
if(a = this->attribs[i])
@ -752,14 +754,14 @@ objInstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
// TODO: allow for REINSTANCE
if(geo->instData)
return;
InstanceDataHeader *header = new InstanceDataHeader;
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
geo->instData = header;
header->platform = PLATFORM_PS2;
assert(geo->meshHeader != nil);
header->numMeshes = geo->meshHeader->numMeshes;
header->instanceMeshes = new InstanceData[header->numMeshes];
header->instanceMeshes = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
for(uint32 i = 0; i < header->numMeshes; i++){
Mesh *mesh = &geo->meshHeader->mesh[i];
Mesh *mesh = &geo->meshHeader->getMeshes()[i];
InstanceData *instance = &header->instanceMeshes[i];
MatPipeline *m;
@ -816,14 +818,15 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
// highest possible number of vertices
geo->numVertices = geo->meshHeader->totalIndices;
geo->flags &= ~Geometry::NATIVE;
geo->numTriangles = geo->meshHeader->guessNumTriangles();
geo->allocateData();
geo->meshHeader->allocateIndices();
uint32 *flags = new uint32[geo->numVertices];
geo->allocateMeshes(geo->meshHeader->numMeshes, geo->meshHeader->totalIndices, 0);
uint32 *flags = rwNewT(uint32, geo->numVertices,
MEMDUR_FUNCTION | ID_GEOMETRY);
memset(flags, 0, 4*geo->numVertices);
memset(geo->meshHeader->mesh[0].indices, 0, 2*geo->meshHeader->totalIndices);
memset(geo->meshHeader->getMeshes()->indices, 0, 2*geo->meshHeader->totalIndices);
for(uint32 i = 0; i < header->numMeshes; i++){
Mesh *mesh = &geo->meshHeader->mesh[i];
Mesh *mesh = &geo->meshHeader->getMeshes()[i];
MatPipeline *m;
m = pipe->groupPipeline ?
pipe->groupPipeline :
@ -833,7 +836,7 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
}
geo->numVertices = 0;
for(uint32 i = 0; i < header->numMeshes; i++){
Mesh *mesh = &geo->meshHeader->mesh[i];
Mesh *mesh = &geo->meshHeader->getMeshes()[i];
InstanceData *instance = &header->instanceMeshes[i];
MatPipeline *m;
m = pipe->groupPipeline ?
@ -845,10 +848,10 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
uint8 *raw = m->collectData(geo, instance, mesh, data);
assert(m->uninstanceCB);
m->uninstanceCB(m, geo, flags, mesh, data);
if(raw) delete[] raw;
rwFree(raw);
}
for(uint32 i = 0; i < header->numMeshes; i++){
Mesh *mesh = &geo->meshHeader->mesh[i];
Mesh *mesh = &geo->meshHeader->getMeshes()[i];
MatPipeline *m;
m = pipe->groupPipeline ?
pipe->groupPipeline :
@ -859,9 +862,9 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
int8 *bits = getADCbits(geo);
geo->generateTriangles(bits);
delete[] flags;
rwFree(flags);
geo->flags &= ~Geometry::NATIVE;
destroyNativeData(geo, 0, 0);
geo->instData = nil;
/*
for(uint32 i = 0; i < header->numMeshes; i++){
Mesh *mesh = &geo->meshHeader->mesh[i];
@ -1085,9 +1088,9 @@ getADCbitsForMesh(Geometry *geo, Mesh *mesh)
int8 *bits = getADCbits(geo);
if(bits == nil)
return nil;
int32 n = mesh - geo->meshHeader->mesh;
int32 n = mesh - geo->meshHeader->getMeshes();
for(int32 i = 0; i < n; i++)
bits += geo->meshHeader->mesh[i].numIndices;
bits += geo->meshHeader->getMeshes()[i].numIndices;
return bits;
}
@ -1105,28 +1108,30 @@ unconvertADC(Geometry *g)
if(!adc->adcFormatted)
return;
int8 *b = adc->adcBits;
MeshHeader *h = new MeshHeader;
h->flags = g->meshHeader->flags; // should be tristrip
h->numMeshes = g->meshHeader->numMeshes;
h->mesh = new Mesh[h->numMeshes];
Mesh *oldm = g->meshHeader->mesh;
Mesh *newm = h->mesh;
h->totalIndices = 0;
for(int32 i = 0; i < h->numMeshes; i++){
MeshHeader *oldmh = g->meshHeader;
g->meshHeader = nil;
// Don't allocate indices for now
MeshHeader *newmh = g->allocateMeshes(oldmh->numMeshes, 0, 1);
newmh->flags = oldmh->flags; // should be tristrip
Mesh *oldm = oldmh->getMeshes();
Mesh *newm = newmh->getMeshes();
for(int32 i = 0; i < newmh->numMeshes; i++){
newm->material = oldm->material;
newm->numIndices = oldm->numIndices;
for(uint32 j = 0; j < oldm->numIndices; j++)
if(*b++)
newm->numIndices += 2;
h->totalIndices += newm->numIndices;
newmh->totalIndices += newm->numIndices;
newm++;
oldm++;
}
h->allocateIndices();
// Now re-allocate with indices
newmh = g->allocateMeshes(newmh->numMeshes, newmh->totalIndices, 0);
b = adc->adcBits;
oldm = g->meshHeader->mesh;
newm = h->mesh;
for(int32 i = 0; i < h->numMeshes; i++){
oldm = oldmh->getMeshes();
newm = newmh->getMeshes();
for(int32 i = 0; i < newmh->numMeshes; i++){
int32 n = 0;
for(uint32 j = 0; j < oldm->numIndices; j++){
if(*b++){
@ -1138,10 +1143,9 @@ unconvertADC(Geometry *g)
newm++;
oldm++;
}
delete g->meshHeader;
g->meshHeader = h;
rwFree(oldmh);
adc->adcFormatted = 0;
delete[] adc->adcBits;
rwFree(adc->adcBits);
adc->adcBits = nil;
adc->numBits = 0;
}
@ -1153,7 +1157,7 @@ allocateADC(Geometry *geo)
adc->adcFormatted = 1;
adc->numBits = geo->meshHeader->totalIndices;
int32 size = adc->numBits+3 & ~3;
adc->adcBits = new int8[size];
adc->adcBits = rwNewT(int8, size, MEMDUR_EVENT | ID_ADC);
memset(adc->adcBits, 0, size);
}
@ -1175,7 +1179,7 @@ copyADC(void *dst, void *src, int32 offset, int32)
return dst;
dstadc->numBits = srcadc->numBits;
int32 size = dstadc->numBits+3 & ~3;
dstadc->adcBits = new int8[size];
dstadc->adcBits = rwNewT(int8, size, MEMDUR_EVENT | ID_ADC);
memcpy(dstadc->adcBits, srcadc->adcBits, size);
return dst;
}
@ -1185,7 +1189,7 @@ destroyADC(void *object, int32 offset, int32)
{
ADCData *adc = PLUGINOFFSET(ADCData, object, offset);
if(adc->adcFormatted)
delete[] adc->adcBits;
rwFree(adc->adcBits);
return object;
}
@ -1205,7 +1209,7 @@ readADC(Stream *stream, int32, void *object, int32 offset, int32)
return stream;
}
int32 size = adc->numBits+3 & ~3;
adc->adcBits = new int8[size];
adc->adcBits = rwNewT(int8, size, MEMDUR_EVENT | ID_ADC);
stream->read(adc->adcBits, size);
return stream;
}

View File

@ -83,7 +83,7 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
return nil;
}
stream->read(header, 4);
Skin *skin = new Skin;
Skin *skin = rwNewT(Skin, 1, MEMDUR_EVENT | ID_SKIN);
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
// numUsedBones and numWeights appear in/after 34003
@ -313,7 +313,7 @@ skinPreCB(MatPipeline*, Geometry *geo)
// meshHeader->totalIndices is highest possible number of vertices again
skin->init(skin->numBones, skin->numBones, geo->meshHeader->totalIndices);
memcpy(skin->inverseMatrices, invMats, skin->numBones*64);
delete[] data;
rwFree(data);
}
void

View File

@ -401,8 +401,10 @@ enum VendorID
VEND_CRITERIONTK = 1,
VEND_CRITERIONINT = 4,
VEND_CRITERIONWORLD = 5,
// Used for platform-specific stuff like rasters
VEND_PLATFORM = 10,
// Used for rasters (platform-specific)
VEND_RASTER = 10,
// Used for driver/device allocation tags
VEND_DRIVER = 11,
};
// TODO: modules (VEND_CRITERIONINT)
@ -449,13 +451,16 @@ enum PluginID
ID_VERTEXFMT = MAKEPLUGINID(VEND_CRITERIONWORLD, 0x11),
// custom native raster
ID_RASTERGL = MAKEPLUGINID(VEND_PLATFORM, PLATFORM_GL),
ID_RASTERPS2 = MAKEPLUGINID(VEND_PLATFORM, PLATFORM_PS2),
ID_RASTERXBOX = MAKEPLUGINID(VEND_PLATFORM, PLATFORM_XBOX),
ID_RASTERD3D8 = MAKEPLUGINID(VEND_PLATFORM, PLATFORM_D3D8),
ID_RASTERD3D9 = MAKEPLUGINID(VEND_PLATFORM, PLATFORM_D3D9),
ID_RASTERWDGL = MAKEPLUGINID(VEND_PLATFORM, PLATFORM_WDGL),
ID_RASTERGL3 = MAKEPLUGINID(VEND_PLATFORM, PLATFORM_GL3),
ID_RASTERGL = MAKEPLUGINID(VEND_RASTER, PLATFORM_GL),
ID_RASTERPS2 = MAKEPLUGINID(VEND_RASTER, PLATFORM_PS2),
ID_RASTERXBOX = MAKEPLUGINID(VEND_RASTER, PLATFORM_XBOX),
ID_RASTERD3D8 = MAKEPLUGINID(VEND_RASTER, PLATFORM_D3D8),
ID_RASTERD3D9 = MAKEPLUGINID(VEND_RASTER, PLATFORM_D3D9),
ID_RASTERWDGL = MAKEPLUGINID(VEND_RASTER, PLATFORM_WDGL),
ID_RASTERGL3 = MAKEPLUGINID(VEND_RASTER, PLATFORM_GL3),
// anything driver/device related (only as allocation tag)
ID_DRIVER = MAKEPLUGINID(VEND_DRIVER, 0),
};
#define ECODE(c, s) c,

View File

@ -109,9 +109,13 @@ enum MemHint
struct MemoryFunctions
{
void *(*malloc)(size_t sz, uint32 hint);
void *(*realloc)(void *p, size_t sz, uint32 hint);
void (*free)(void *p);
void *(*rwmalloc)(size_t sz, uint32 hint);
void *(*rwrealloc)(void *p, size_t sz, uint32 hint);
void (*rwfree)(void *p);
// These are temporary until we have better error handling
// TODO: Maybe don't put them here since they shouldn't really be switched out
void *(*rwmustmalloc)(size_t sz, uint32 hint);
void *(*rwmustrealloc)(void *p, size_t sz, uint32 hint);
};
// This is for platform independent things
@ -158,9 +162,16 @@ inline void SetRenderState(int32 state, uint32 value){
inline uint32 GetRenderState(int32 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)
// These must be macros because we might want to pass __FILE__ and __LINE__ later
#define rwMalloc(s, h) rw::Engine::memfuncs.rwmalloc(s,h)
#define rwMallocT(t, s, h) (t*)rw::Engine::memfuncs.rwmalloc((s)*sizeof(t),h)
#define rwRealloc(p, s, h) rw::Engine::memfuncs.rwrealloc(p,s,h)
#define rwReallocT(t, p, s, h) (t*)rw::Engine::memfuncs.rwrealloc(p,(s)*sizeof(t),h)
#define rwFree(p) rw::Engine::memfuncs.rwfree(p)
#define rwNew(s, h) rw::Engine::memfuncs.rwmustmalloc(s,h)
#define rwNewT(t, s, h) (t*)rw::Engine::memfuncs.rwmustmalloc((s)*sizeof(t),h)
#define rwResize(p, s, h) rw::Engine::memfuncs.rwmustrealloc(p,s,h)
#define rwResizeT(t, p, s, h) (t*)rw::Engine::memfuncs.rwmustrealloc(p,(s)*sizeof(t),h)
namespace null {
void beginUpdate(Camera*);

View File

@ -362,16 +362,21 @@ struct MeshHeader
};
uint32 flags;
uint16 numMeshes;
// RW has uint16 serialNum here
uint16 serialNum; // not used yet
uint32 totalIndices;
Mesh *mesh; // RW has a byte offset here
uint32 pad; // needed for alignment of Meshes
// after this the meshes
void allocateIndices(void);
~MeshHeader(void);
Mesh *getMeshes(void) { return (Mesh*)(this+1); }
void setupIndices(void);
uint32 guessNumTriangles(void);
};
struct Geometry;
struct MorphTarget
{
Geometry *parent;
Sphere boundingSphere;
V3d *vertices;
V3d *normals;
@ -433,6 +438,7 @@ struct Geometry
void calculateBoundingSphere(void);
bool32 hasColoredMaterial(void);
void allocateData(void);
MeshHeader *allocateMeshes(int32 numMeshes, uint32 numIndices, bool32 noIndices);
void generateTriangles(int8 *adc = nil);
void buildMeshes(void);
void buildTristrips(void);
@ -463,6 +469,7 @@ struct Geometry
// librw's pipelines are different so it's unused here.
NATIVEINSTANCE = 0x02000000
};
};
void registerMeshPlugin(void);

View File

@ -38,11 +38,11 @@ destroySkin(void *object, int32 offset, int32)
{
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
if(skin){
delete[] skin->data;
rwFree(skin->data);
rwFree(skin->remapIndices);
// delete[] skin->platformData;
}
delete skin;
rwFree(skin);
return object;
}
@ -55,7 +55,7 @@ copySkin(void *dst, void *src, int32 offset, int32)
Geometry *geometry = (Geometry*)src;
assert(geometry->instData == nil);
assert(((Geometry*)src)->numVertices == ((Geometry*)dst)->numVertices);
Skin *dstskin = new Skin;
Skin *dstskin = rwNewT(Skin, 1, MEMDUR_EVENT | ID_SKIN);
*PLUGINOFFSET(Skin*, dst, offset) = dstskin;
dstskin->numBones = srcskin->numBones;
dstskin->numUsedBones = srcskin->numUsedBones;
@ -134,7 +134,7 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
stream->read(header, 4); // numBones, numUsedBones,
// numWeights, unused
Skin *skin = new Skin;
Skin *skin = rwNewT(Skin, 1, MEMDUR_EVENT | ID_SKIN);
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
// numUsedBones and numWeights appear in/after 34003
@ -315,7 +315,7 @@ Skin::init(int32 numBones, int32 numUsedBones, int32 numVertices)
uint32 size = this->numUsedBones +
this->numBones*64 +
numVertices*(16+4) + 0xF;
this->data = new uint8[size];
this->data = rwNewT(uint8, size, MEMDUR_EVENT | ID_SKIN);
uint8 *p = this->data;
this->usedBones = nil;

View File

@ -118,7 +118,7 @@ readTGA(const char *afilename)
}
file.close();
delete[] data;
rwFree(data);
return image;
}

View File

@ -9,6 +9,7 @@
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwengine.h"
#define PLUGIN_ID 2
@ -427,7 +428,7 @@ Geometry::buildTristrips(void)
printf("%ld\n", sizeof(StripNode));
smesh.nodes = new StripNode[this->numTriangles];
smesh.nodes = rwNewT(StripNode, this->numTriangles, MEMDUR_FUNCTION | ID_GEOMETRY);
for(int32 i = 0; i < this->matList.numMaterials; i++){
smesh.loneNodes.init();
smesh.endNodes.init();
@ -444,7 +445,7 @@ printf("-------\n");
//printf("-------\n");
//printEnds(&smesh);
}
delete[] smesh.nodes;
rwFree(smesh.nodes);
exit(1);
}

View File

@ -49,7 +49,7 @@ UVAnimDictionary::destroy(void)
UVAnimDictEntry *de = UVAnimDictEntry::fromDict(lnk);
UVAnimCustomData *cust = UVAnimCustomData::get(de->anim);
cust->destroy(de->anim);
delete de;
rwFree(de);
}
rwFree(this);
}
@ -57,7 +57,7 @@ UVAnimDictionary::destroy(void)
void
UVAnimDictionary::add(Animation *anim)
{
UVAnimDictEntry *de = new UVAnimDictEntry;
UVAnimDictEntry *de = rwNewT(UVAnimDictEntry, 1, MEMDUR_EVENT | ID_UVANIMDICT);
de->anim = anim;
this->animations.append(&de->inDict);
}
@ -172,7 +172,7 @@ static void
registerUVAnimInterpolator(void)
{
// Linear
AnimInterpolatorInfo *info = new AnimInterpolatorInfo;
AnimInterpolatorInfo *info = rwNewT(AnimInterpolatorInfo, 1, MEMDUR_GLOBAL | ID_UVANIMATION);
info->id = 0x1C0;
info->interpKeyFrameSize = sizeof(UVAnimInterpFrame);
info->animKeyFrameSize = sizeof(UVAnimKeyFrame);
@ -188,7 +188,7 @@ registerUVAnimInterpolator(void)
AnimInterpolatorInfo::registerInterp(info);
// Param
info = new AnimInterpolatorInfo;
info = rwNewT(AnimInterpolatorInfo, 1, MEMDUR_GLOBAL | ID_UVANIMATION);
info->id = 0x1C1;
info->interpKeyFrameSize = sizeof(UVAnimInterpFrame);
info->animKeyFrameSize = sizeof(UVAnimKeyFrame);
@ -226,7 +226,7 @@ destroyUVAnim(void *object, int32 offset, int32)
UVAnimCustomData *custom =
UVAnimCustomData::get(ip->currentAnim);
custom->destroy(ip->currentAnim);
delete ip;
rwFree(ip);
}
}
return object;

View File

@ -703,7 +703,7 @@ main()
rw::findChunk(&in, rw::ID_CLUMP, NULL, NULL);
rw::Clump *clump = rw::Clump::streamRead(&in);
in.close();
delete[] data;
rwFree(data);
GsCtx gsCtx;