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 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 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 work. Rendering some things on the PS2 is working as a test only.
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
# Building # Building

17
TODO
View File

@ -1,7 +1,11 @@
TODO: TODO:
- maintain the TODO list properly - 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 - examples
- morph targets and morphing
- geometry lock/unlock - geometry lock/unlock
-> reinstance -> reinstance
-> revisit pipelines -> revisit pipelines
@ -13,16 +17,13 @@ TODO:
- PS2 rendering! - PS2 rendering!
- Im2d and Im3d - Im2d and Im3d
- change naming convention? make globals stand out more - change naming convention? make globals stand out more
- Pipelines (PDS, Xbox, PC)
- ADC conversion
BUGS: BUGS:
- fseek with negative offset on ps2 over ps2link messes up the current position - fseek with negative offset on ps2 over ps2link messes up the current position
Clump & related: Clump & related:
- !!! work on ref counts, destruction, copying etc.
- define and use types:
color
triangle
texcoord
- implement plugins: - implement plugins:
Clump Clump
Animation (old III dffs) Animation (old III dffs)
@ -37,7 +38,3 @@ Clump & related:
- only stubs: - only stubs:
R* 2dfx 0x253F2F8 R* 2dfx 0x253F2F8
R* Collision 0x253F2FA 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); fseek(cf, 0, SEEK_END);
*len = ftell(cf); *len = ftell(cf);
fseek(cf, 0, SEEK_SET); fseek(cf, 0, SEEK_SET);
uint8 *data = new uint8[*len]; uint8 *data = rwNewT(uint8, *len, MEMDUR_EVENT);
fread(data, *len, 1, cf); fread(data, *len, 1, cf);
fclose(cf); fclose(cf);
return data; return data;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -18,6 +18,14 @@
#define PLUGIN_ID 0 #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 { namespace rw {
Engine *engine; Engine *engine;
@ -25,8 +33,29 @@ PluginList Driver::s_plglist[NUM_PLATFORMS];
Engine::State Engine::state = Dead; Engine::State Engine::state = Dead;
MemoryFunctions Engine::memfuncs; 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); } 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 // This function mainly registers engine plugins
// RW initializes memory related things here too and // RW initializes memory related things here too and
@ -40,9 +69,11 @@ Engine::init(void)
return 0; return 0;
} }
memfuncs.malloc = malloc_h; memfuncs.rwmalloc = malloc_h;
memfuncs.realloc = realloc_h; memfuncs.rwrealloc = realloc_h;
memfuncs.free = free; memfuncs.rwfree = free;
memfuncs.rwmustmalloc = mustmalloc_h;
memfuncs.rwmustrealloc = mustrealloc_h;
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++)
@ -72,7 +103,7 @@ Engine::open(void)
} }
// Allocate engine // Allocate engine
engine = (Engine*)rwMalloc(sizeof(Engine), MEMDUR_GLOBAL); engine = rwNewT(Engine, 1, MEMDUR_GLOBAL);
engine->currentCamera = nil; engine->currentCamera = nil;
engine->currentWorld = nil; engine->currentWorld = nil;
engine->currentTexDictionary = nil; engine->currentTexDictionary = nil;
@ -97,7 +128,8 @@ Engine::open(void)
// TODO: init driver functions // TODO: init driver functions
ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL); ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL);
for(uint i = 0; i < NUM_PLATFORMS; i++){ 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; engine->driver[i]->defaultPipeline = defpipe;

View File

@ -18,9 +18,9 @@ namespace rw {
PluginList Geometry::s_plglist = { sizeof(Geometry), sizeof(Geometry), nil, nil }; PluginList Geometry::s_plglist = { sizeof(Geometry), sizeof(Geometry), nil, nil };
PluginList Material::s_plglist = { sizeof(Material), sizeof(Material), 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*
Geometry::create(int32 numVerts, int32 numTris, uint32 flags) 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->flags & TEXTURED2) ? 2 : 0;
geo->numTriangles = numTris; geo->numTriangles = numTris;
geo->numVertices = numVerts; geo->numVertices = numVerts;
geo->numMorphTargets = 1;
geo->colors = nil; geo->colors = nil;
for(int32 i = 0; i < geo->numTexCoordSets; i++) for(int32 i = 0; i < 8; i++)
geo->texCoords[i] = nil; geo->texCoords[i] = nil;
geo->triangles = 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) if(geo->flags & PRELIT)
geo->colors = new RGBA[geo->numVertices]; sz += geo->numVertices*sizeof(RGBA);
if((geo->flags & TEXTURED) || (geo->flags & TEXTURED2)) sz += geo->numTexCoordSets*geo->numVertices*sizeof(TexCoords);
for(int32 i = 0; i < geo->numTexCoordSets; i++)
geo->texCoords[i] = uint8 *data = (uint8*)rwNew(sz, MEMDUR_EVENT | ID_GEOMETRY);
new TexCoords[geo->numVertices]; geo->triangles = (Triangle*)data;
geo->triangles = new Triangle[geo->numTriangles]; data += geo->numTriangles*sizeof(Triangle);
} if(geo->flags & PRELIT && geo->numVertices){
geo->morphTargets = new MorphTarget[1]; geo->colors = (RGBA*)data;
MorphTarget *m = geo->morphTargets; data += geo->numVertices*sizeof(RGBA);
m->boundingSphere.center.set(0.0f, 0.0f, 0.0f); }
m->boundingSphere.radius = 0.0f; if(geo->numVertices)
m->vertices = nil; for(int32 i = 0; i < geo->numTexCoordSets; i++){
m->normals = nil; geo->texCoords[i] = (TexCoords*)data;
if(!(geo->flags & NATIVE) && geo->numVertices){ data += geo->numVertices*sizeof(TexCoords);
m->vertices = new V3d[geo->numVertices]; }
if(geo->flags & NORMALS)
m->normals = new V3d[geo->numVertices]; // 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->matList.init();
geo->meshHeader = nil; geo->meshHeader = nil;
geo->instData = nil; geo->instData = nil;
@ -78,18 +87,12 @@ Geometry::destroy(void)
this->refCount--; this->refCount--;
if(this->refCount <= 0){ if(this->refCount <= 0){
s_plglist.destruct(this); s_plglist.destruct(this);
delete[] this->colors; // Also frees colors and tex coords
for(int32 i = 0; i < this->numTexCoordSets; i++) rwFree(this->triangles);
delete[] this->texCoords[i]; // Also frees their data
delete[] this->triangles; rwFree(this->morphTargets);
// Also frees indices
for(int32 i = 0; i < this->numMorphTargets; i++){ rwFree(this->meshHeader);
MorphTarget *m = &this->morphTargets[i];
delete[] m->vertices;
delete[] m->normals;
}
delete[] this->morphTargets;
delete this->meshHeader;
this->matList.deinit(); this->matList.deinit();
rwFree(this); rwFree(this);
} }
@ -158,6 +161,7 @@ Geometry::streamRead(Stream *stream)
} }
if(version < 0x34000) if(version < 0x34000)
defaultSurfaceProps = surfProps; defaultSurfaceProps = surfProps;
ret = MaterialList::streamRead(stream, &geo->matList); ret = MaterialList::streamRead(stream, &geo->matList);
if(version < 0x34000) if(version < 0x34000)
defaultSurfaceProps = reset; defaultSurfaceProps = reset;
@ -271,20 +275,52 @@ Geometry::addMorphTargets(int32 n)
if(n == 0) if(n == 0)
return; return;
n += this->numMorphTargets; n += this->numMorphTargets;
MorphTarget *morphTargets = new MorphTarget[n];
memcpy(morphTargets, this->morphTargets, int32 sz;
this->numMorphTargets*sizeof(MorphTarget)); sz = sizeof(MorphTarget);
delete[] this->morphTargets; if(!(this->flags & NATIVE)){
this->morphTargets = morphTargets; sz += this->numVertices*sizeof(V3d);
for(int32 i = this->numMorphTargets; i < n; i++){ if(this->flags & NORMALS)
MorphTarget *m = &morphTargets[i]; sz += this->numVertices*sizeof(V3d);
m->vertices = nil; }
m->normals = nil;
if(!(this->flags & NATIVE)){ // Memory layout: MorphTarget[n]; (vertices and normals)[n]
m->vertices = new V3d[this->numVertices]; MorphTarget *mts;
if(this->flags & NORMALS) if(this->numMorphTargets){
m->normals = new V3d[this->numVertices]; 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; this->numMorphTargets = n;
} }
@ -324,21 +360,54 @@ Geometry::hasColoredMaterial(void)
return 0; return 0;
} }
// TODO: allocate as one chunk // Force allocate data, even when native flag is set
void void
Geometry::allocateData(void) Geometry::allocateData(void)
{ {
// Geometry data
// Pretty much copy pasted from ::create above
int32 sz = this->numTriangles*sizeof(Triangle);
if(this->flags & PRELIT) if(this->flags & PRELIT)
this->colors = new RGBA[this->numVertices]; sz += this->numVertices*sizeof(RGBA);
if((this->flags & TEXTURED) || (this->flags & TEXTURED2)) sz += this->numTexCoordSets*this->numVertices*sizeof(TexCoords);
for(int32 i = 0; i < this->numTexCoordSets; i++)
this->texCoords[i] = uint8 *data = (uint8*)rwNew(sz, MEMDUR_EVENT | ID_GEOMETRY);
new TexCoords[this->numVertices]; 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)
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++){ for(int32 i = 0; i < this->numMorphTargets; i++){
MorphTarget *m = &morphTargets[i]; mt->parent = this;
m->vertices = new V3d[this->numVertices]; mt->vertices = nil;
if(this->flags & NORMALS) mt->normals = nil;
m->normals = new V3d[this->numVertices]; 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]; idx[1] == idx[2];
} }
// This functions assumes there is enough space allocated
// for triangles. Use MeshHeader::guessNumTriangles() and
// Geometry::allocateData()
void void
Geometry::generateTriangles(int8 *adc) Geometry::generateTriangles(int8 *adc)
{ {
@ -357,7 +429,7 @@ Geometry::generateTriangles(int8 *adc)
assert(header != nil); assert(header != nil);
this->numTriangles = 0; this->numTriangles = 0;
Mesh *m = header->mesh; Mesh *m = header->getMeshes();
int8 *adcbits = adc; int8 *adcbits = adc;
for(uint32 i = 0; i < header->numMeshes; i++){ for(uint32 i = 0; i < header->numMeshes; i++){
if(m->numIndices < 3){ if(m->numIndices < 3){
@ -378,11 +450,8 @@ Geometry::generateTriangles(int8 *adc)
m++; m++;
} }
delete[] this->triangles;
this->triangles = new Triangle[this->numTriangles];
Triangle *tri = this->triangles; Triangle *tri = this->triangles;
m = header->mesh; m = header->getMeshes();
adcbits = adc; adcbits = adc;
for(uint32 i = 0; i < header->numMeshes; i++){ for(uint32 i = 0; i < header->numMeshes; i++){
if(m->numIndices < 3){ if(m->numIndices < 3){
@ -434,38 +503,44 @@ dumpMesh(Mesh *m)
void void
Geometry::buildMeshes(void) Geometry::buildMeshes(void)
{ {
//dumpMesh(this->meshHeader->mesh);
delete this->meshHeader;
Triangle *tri; Triangle *tri;
MeshHeader *h = new MeshHeader; Mesh *mesh;
this->meshHeader = h;
rwFree(this->meshHeader);
this->meshHeader = nil;
int32 numMeshes = this->matList.numMaterials;
if((this->flags & Geometry::TRISTRIP) == 0){ if((this->flags & Geometry::TRISTRIP) == 0){
h->flags = 0; int32 *numIndices = rwNewT(int32, numMeshes,
h->totalIndices = this->numTriangles*3; MEMDUR_FUNCTION | ID_GEOMETRY);
h->numMeshes = this->matList.numMaterials; memset(numIndices, 0, numMeshes*sizeof(int32));
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;
}
// count indices per mesh // count indices per mesh
tri = this->triangles; tri = this->triangles;
for(int32 i = 0; i < this->numTriangles; i++){ 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++; tri++;
} }
h->allocateIndices(); // setup meshes
for(uint32 i = 0; i < h->numMeshes; i++) this->allocateMeshes(numMeshes, this->numTriangles*3, 0);
h->mesh[i].numIndices = 0; mesh = this->meshHeader->getMeshes();
// same as above but fill with indices 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; tri = this->triangles;
for(int32 i = 0; i < this->numTriangles; i++){ for(int32 i = 0; i < this->numTriangles; i++){
uint32 idx = h->mesh[tri->matId].numIndices; uint32 idx = mesh[tri->matId].numIndices;
h->mesh[tri->matId].indices[idx++] = tri->v[0]; mesh[tri->matId].indices[idx++] = tri->v[0];
h->mesh[tri->matId].indices[idx++] = tri->v[1]; mesh[tri->matId].indices[idx++] = tri->v[1];
h->mesh[tri->matId].indices[idx++] = tri->v[2]; mesh[tri->matId].indices[idx++] = tri->v[2];
h->mesh[tri->matId].numIndices = idx; mesh[tri->matId].numIndices = idx;
tri++; tri++;
} }
}else }else
@ -479,19 +554,19 @@ void
Geometry::correctTristripWinding(void) Geometry::correctTristripWinding(void)
{ {
MeshHeader *header = this->meshHeader; MeshHeader *header = this->meshHeader;
if(header == nil || header->flags != MeshHeader::TRISTRIP || if(this->flags & NATIVE || header == nil ||
this->instData) header->flags != MeshHeader::TRISTRIP)
return; 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->flags = header->flags;
newhead->numMeshes = header->numMeshes;
newhead->totalIndices = 0;
newhead->mesh = new Mesh[newhead->numMeshes];
/* get a temporary working buffer */ /* 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 *mesh = header->getMeshes();
Mesh *newmesh = newhead->mesh; Mesh *newmesh = newhead->getMeshes();
for(uint16 i = 0; i < header->numMeshes; i++){ for(uint16 i = 0; i < header->numMeshes; i++){
newmesh->numIndices = 0; newmesh->numIndices = 0;
newmesh->indices = &indices[newhead->totalIndices]; newmesh->indices = &indices[newhead->totalIndices];
@ -523,11 +598,11 @@ Geometry::correctTristripWinding(void)
mesh++; mesh++;
newmesh++; newmesh++;
} }
newhead->allocateIndices(); rwFree(header);
memcpy(newhead->mesh[0].indices, indices, newhead->totalIndices*2); // Now allocate indices and copy them
delete[] indices; this->allocateMeshes(newhead->numMeshes, newhead->totalIndices, 0);
this->meshHeader = newhead; memcpy(this->meshHeader->getMeshes()->indices, indices, newhead->totalIndices*2);
delete header; rwFree(indices);
} }
void void
@ -536,16 +611,18 @@ Geometry::removeUnusedMaterials(void)
if(this->meshHeader == nil) if(this->meshHeader == nil)
return; return;
MeshHeader *mh = this->meshHeader; MeshHeader *mh = this->meshHeader;
Mesh *m = mh->getMeshes();
for(uint32 i = 0; i < mh->numMeshes; i++) for(uint32 i = 0; i < mh->numMeshes; i++)
if(mh->mesh[i].indices == nil) if(m[i].indices == nil)
return; return;
int32 *map = new int32[this->matList.numMaterials]; int32 *map = rwNewT(int32, this->matList.numMaterials,
Material **materials = new Material*[this->matList.numMaterials]; MEMDUR_FUNCTION | ID_GEOMETRY);
Material **materials = rwNewT(Material*,this->matList.numMaterials,
MEMDUR_EVENT | ID_MATERIAL);
int32 numMaterials = 0; int32 numMaterials = 0;
/* Build new material list and map */ /* Build new material list and map */
for(uint32 i = 0; i < mh->numMeshes; i++){ for(uint32 i = 0; i < mh->numMeshes; i++){
Mesh *m = &mh->mesh[i];
if(m->numIndices <= 0) if(m->numIndices <= 0)
continue; continue;
materials[numMaterials] = m->material; materials[numMaterials] = m->material;
@ -553,6 +630,7 @@ Geometry::removeUnusedMaterials(void)
int32 oldid = this->matList.findIndex(m->material); int32 oldid = this->matList.findIndex(m->material);
map[oldid] = numMaterials; map[oldid] = numMaterials;
numMaterials++; numMaterials++;
m++;
} }
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();
@ -562,38 +640,35 @@ Geometry::removeUnusedMaterials(void)
this->matList.numMaterials = numMaterials; this->matList.numMaterials = numMaterials;
/* Build new meshes */ /* Build new meshes */
MeshHeader *newmh = new MeshHeader; this->meshHeader = nil;
MeshHeader *newmh = this->allocateMeshes(numMaterials, mh->totalIndices, 0);
newmh->flags = mh->flags; newmh->flags = mh->flags;
newmh->numMeshes = numMaterials; Mesh *newm = newmh->getMeshes();
newmh->mesh = new Mesh[newmh->numMeshes]; m = mh->getMeshes();
newmh->totalIndices = mh->totalIndices;
Mesh *newm = newmh->mesh;
for(uint32 i = 0; i < mh->numMeshes; i++){ for(uint32 i = 0; i < mh->numMeshes; i++){
Mesh *oldm = &mh->mesh[i]; if(m[i].numIndices <= 0)
if(oldm->numIndices <= 0)
continue; continue;
newm->numIndices = oldm->numIndices; newm->numIndices = m[i].numIndices;
newm->material = oldm->material; newm->material = m[i].material;
newm++; newm++;
} }
newmh->allocateIndices(); newmh->setupIndices();
/* Copy indices */ /* Copy indices */
newm = newmh->mesh; newm = newmh->getMeshes();;
m = mh->getMeshes();
for(uint32 i = 0; i < mh->numMeshes; i++){ for(uint32 i = 0; i < mh->numMeshes; i++){
Mesh *oldm = &mh->mesh[i]; if(m[i].numIndices <= 0)
if(oldm->numIndices <= 0)
continue; continue;
memcpy(newm->indices, oldm->indices, memcpy(newm->indices, m[i].indices,
oldm->numIndices*sizeof(*oldm->indices)); m[i].numIndices*sizeof(*m[i].indices));
newm++; newm++;
} }
delete this->meshHeader; rwFree(mh);
this->meshHeader = newmh;
/* Remap triangle material IDs */ /* Remap triangle material IDs */
for(int32 i = 0; i < this->numTriangles; i++) for(int32 i = 0; i < this->numTriangles; i++)
this->triangles[i].matId = map[this->triangles[i].matId]; 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){ if(this->numMaterials >= this->space){
space = this->space + 20; space = this->space + 20;
if(this->materials) if(this->materials)
ml = (Material**)rwRealloc(this->materials, ml = rwReallocT(Material*, this->materials, space,
space*sizeof(Material*),
MEMDUR_EVENT | ID_MATERIAL); MEMDUR_EVENT | ID_MATERIAL);
else else
ml = (Material**)rwMalloc(space*sizeof(Material*), ml = rwMallocT(Material*, space, MEMDUR_EVENT | ID_MATERIAL);
MEMDUR_EVENT | ID_MATERIAL);
if(ml == nil) if(ml == nil)
return -1; return -1;
this->space = space; this->space = space;
@ -666,7 +739,7 @@ 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**)rwMalloc(numMat*sizeof(Material*), MEMDUR_EVENT | ID_MATERIAL); matlist->materials = rwMallocT(Material*,numMat, MEMDUR_EVENT | ID_MATERIAL);
if(matlist->materials == nil) if(matlist->materials == nil)
goto fail; goto fail;
matlist->space = numMat; matlist->space = numMat;

View File

@ -25,39 +25,119 @@ namespace rw {
// Mesh // 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* static Stream*
readMesh(Stream *stream, int32 len, void *object, int32, int32) readMesh(Stream *stream, int32 len, void *object, int32, int32)
{ {
Geometry *geo = (Geometry*)object; MeshHeaderStream mhs;
MeshStream ms;
MeshHeader *mh;
Mesh *mesh;
int32 indbuf[256]; int32 indbuf[256];
uint32 buf[3]; uint16 *indices;
stream->read(buf, 12); Geometry *geo = (Geometry*)object;
geo->meshHeader = new MeshHeader;
geo->meshHeader->flags = buf[0]; stream->read(&mhs, sizeof(MeshHeaderStream));
geo->meshHeader->numMeshes = buf[1]; // Have to do this dance for War Drum's meshes
geo->meshHeader->totalIndices = buf[2]; bool32 hasData = len > sizeof(MeshHeaderStream)+mhs.numMeshes*sizeof(MeshStream);
geo->meshHeader->mesh = new Mesh[geo->meshHeader->numMeshes]; assert(geo->meshHeader == nil);
Mesh *mesh = geo->meshHeader->mesh; geo->meshHeader = nil;
bool hasData = len > 12+geo->meshHeader->numMeshes*8; mh = geo->allocateMeshes(mhs.numMeshes, mhs.totalIndices,
uint16 *p = nil; geo->flags & Geometry::NATIVE && !hasData);
if(!(geo->flags & Geometry::NATIVE) || hasData)
p = new uint16[geo->meshHeader->totalIndices]; mesh = mh->getMeshes();
for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){ indices = mesh->indices;
stream->read(buf, 8); for(uint32 i = 0; i < mh->numMeshes; i++){
mesh->numIndices = buf[0]; stream->read(&ms, sizeof(MeshStream));
mesh->material = geo->matList.materials[buf[1]]; mesh->numIndices = ms.numIndices;
mesh->indices = nil; mesh->material = geo->matList.materials[ms.matIndex];
if(geo->flags & Geometry::NATIVE){ if(geo->flags & Geometry::NATIVE){
// OpenGL stores uint16 indices here // War Drum OpenGL stores uint16 indices here
if(hasData){ if(hasData){
mesh->indices = p; mesh->indices = indices;
p += mesh->numIndices; indices += mesh->numIndices;
stream->read(mesh->indices, stream->read(mesh->indices,
mesh->numIndices*2); mesh->numIndices*2);
} }
}else{ }else{
mesh->indices = p; mesh->indices = indices;
p += mesh->numIndices; indices += mesh->numIndices;
uint16 *ind = mesh->indices; uint16 *ind = mesh->indices;
int32 numIndices = mesh->numIndices; int32 numIndices = mesh->numIndices;
for(; numIndices > 0; numIndices -= 256){ for(; numIndices > 0; numIndices -= 256){
@ -76,18 +156,19 @@ readMesh(Stream *stream, int32 len, void *object, int32, int32)
static Stream* static Stream*
writeMesh(Stream *stream, int32, void *object, int32, int32) writeMesh(Stream *stream, int32, void *object, int32, int32)
{ {
Geometry *geo = (Geometry*)object; MeshHeaderStream mhs;
MeshStream ms;
int32 indbuf[256]; int32 indbuf[256];
uint32 buf[3]; Geometry *geo = (Geometry*)object;
buf[0] = geo->meshHeader->flags; mhs.flags = geo->meshHeader->flags;
buf[1] = geo->meshHeader->numMeshes; mhs.numMeshes = geo->meshHeader->numMeshes;
buf[2] = geo->meshHeader->totalIndices; mhs.totalIndices = geo->meshHeader->totalIndices;
stream->write(buf, 12); stream->write(&mhs, sizeof(MeshHeaderStream));
Mesh *mesh = geo->meshHeader->mesh; Mesh *mesh = geo->meshHeader->getMeshes();
for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){ for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){
buf[0] = mesh->numIndices; ms.numIndices = mesh->numIndices;
buf[1] = geo->matList.findIndex(mesh->material); ms.matIndex = geo->matList.findIndex(mesh->material);
stream->write(buf, 8); stream->write(&ms, sizeof(MeshStream));
if(geo->flags & Geometry::NATIVE){ if(geo->flags & Geometry::NATIVE){
assert(geo->instData != nil); assert(geo->instData != nil);
if(geo->instData->platform == PLATFORM_WDGL) if(geo->instData->platform == PLATFORM_WDGL)
@ -133,23 +214,17 @@ registerMeshPlugin(void)
Geometry::registerPluginStream(0x50E, readMesh, writeMesh, getSizeMesh); 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 if(this->flags == MeshHeader::TRISTRIP)
delete[] this->mesh[0].indices; return this->totalIndices - 2*this->numMeshes;
delete[] this->mesh; else
} return this->totalIndices/3;
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++;
}
} }
// Native Data // Native Data

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -61,7 +61,7 @@ registerPDSPlugin(int32 n)
{ {
pdsGlobals.maxPipes = n; pdsGlobals.maxPipes = n;
pdsGlobals.numPipes = 0; 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::registerPlugin(0, ID_PDS, nil, nil, nil);
Atomic::setStreamRightsCallback(ID_PDS, atomicPDSRights); Atomic::setStreamRightsCallback(ID_PDS, atomicPDSRights);

View File

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

View File

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

View File

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

View File

@ -109,9 +109,13 @@ enum MemHint
struct MemoryFunctions struct MemoryFunctions
{ {
void *(*malloc)(size_t sz, uint32 hint); void *(*rwmalloc)(size_t sz, uint32 hint);
void *(*realloc)(void *p, size_t sz, uint32 hint); void *(*rwrealloc)(void *p, size_t sz, uint32 hint);
void (*free)(void *p); 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 // This is for platform independent things
@ -158,9 +162,16 @@ 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) // These must be macros because we might want to pass __FILE__ and __LINE__ later
#define rwRealloc(p, s, h) rw::Engine::memfuncs.realloc(p,s,h) #define rwMalloc(s, h) rw::Engine::memfuncs.rwmalloc(s,h)
#define rwFree(p) rw::Engine::memfuncs.free(p) #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 { namespace null {
void beginUpdate(Camera*); void beginUpdate(Camera*);

View File

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

View File

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

View File

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

View File

@ -9,6 +9,7 @@
#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 2
@ -427,7 +428,7 @@ Geometry::buildTristrips(void)
printf("%ld\n", sizeof(StripNode)); 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++){ for(int32 i = 0; i < this->matList.numMaterials; i++){
smesh.loneNodes.init(); smesh.loneNodes.init();
smesh.endNodes.init(); smesh.endNodes.init();
@ -444,7 +445,7 @@ printf("-------\n");
//printf("-------\n"); //printf("-------\n");
//printEnds(&smesh); //printEnds(&smesh);
} }
delete[] smesh.nodes; rwFree(smesh.nodes);
exit(1); exit(1);
} }

View File

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

View File

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