mirror of
https://github.com/aap/librw.git
synced 2024-11-25 05:05:42 +00:00
started moving to custom malloc/free
This commit is contained in:
parent
6d38dea0d9
commit
040bb6cb51
@ -71,6 +71,7 @@ project "librw"
|
||||
project "dumprwtree"
|
||||
kind "ConsoleApp"
|
||||
targetdir (Bindir)
|
||||
removeplatforms { "*gl3", "*d3d9", "ps2" }
|
||||
files { "tools/dumprwtree/*" }
|
||||
includedirs { "." }
|
||||
libdirs { Libdir }
|
||||
|
11
src/anim.cpp
11
src/anim.cpp
@ -8,10 +8,11 @@
|
||||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
#include "rwengine.h"
|
||||
#include "rwanim.h"
|
||||
#include "rwplugins.h"
|
||||
|
||||
#define PLUGIN_ID 0
|
||||
#define PLUGIN_ID ID_ANIMANIMATION
|
||||
|
||||
namespace rw {
|
||||
|
||||
@ -55,7 +56,7 @@ Animation::create(AnimInterpolatorInfo *interpInfo, int32 numFrames,
|
||||
int32 sz = sizeof(Animation) +
|
||||
numFrames*interpInfo->animKeyFrameSize +
|
||||
interpInfo->customDataSize;
|
||||
uint8 *data = (uint8*)malloc(sz);
|
||||
uint8 *data = (uint8*)rwMalloc(sz, MEMDUR_EVENT | ID_ANIMANIMATION);
|
||||
if(data == nil){
|
||||
RWERROR((ERR_ALLOC, sz));
|
||||
return nil;
|
||||
@ -75,7 +76,7 @@ Animation::create(AnimInterpolatorInfo *interpInfo, int32 numFrames,
|
||||
void
|
||||
Animation::destroy(void)
|
||||
{
|
||||
free(this);
|
||||
rwFree(this);
|
||||
}
|
||||
|
||||
int32
|
||||
@ -179,7 +180,7 @@ AnimInterpolator::create(int32 numNodes, int32 maxFrameSize)
|
||||
if(sizeof(void*) > 4)
|
||||
realsz += 16;
|
||||
sz = sizeof(AnimInterpolator) + numNodes*realsz;
|
||||
interp = (AnimInterpolator*)malloc(sz);
|
||||
interp = (AnimInterpolator*)rwMalloc(sz, MEMDUR_EVENT | ID_ANIMANIMATION);
|
||||
if(interp == nil){
|
||||
RWERROR((ERR_ALLOC, sz));
|
||||
return nil;
|
||||
@ -198,7 +199,7 @@ AnimInterpolator::create(int32 numNodes, int32 maxFrameSize)
|
||||
void
|
||||
AnimInterpolator::destroy(void)
|
||||
{
|
||||
free(this);
|
||||
rwFree(this);
|
||||
}
|
||||
|
||||
bool32
|
||||
|
10
src/base.cpp
10
src/base.cpp
@ -143,12 +143,12 @@ V3d::transformVectors(V3d *out, V3d *in, int32 n, Matrix *m)
|
||||
// Matrix
|
||||
//
|
||||
|
||||
static Matrix::Tolerance matrixDefaultTolerance = { 0.01, 0.01, 0.01 };
|
||||
static Matrix::Tolerance matrixDefaultTolerance = { 0.01f, 0.01f, 0.01f };
|
||||
|
||||
Matrix*
|
||||
Matrix::create(void)
|
||||
{
|
||||
Matrix *m = (Matrix*)malloc(sizeof(Matrix));
|
||||
Matrix *m = (Matrix*)rwMalloc(sizeof(Matrix), MEMDUR_EVENT | ID_MATRIX);
|
||||
m->setIdentity();
|
||||
return m;
|
||||
}
|
||||
@ -156,7 +156,7 @@ Matrix::create(void)
|
||||
void
|
||||
Matrix::destroy(void)
|
||||
{
|
||||
free(this);
|
||||
rwFree(this);
|
||||
}
|
||||
|
||||
void
|
||||
@ -770,13 +770,13 @@ StreamFile::close(void)
|
||||
uint32
|
||||
StreamFile::write(const void *data, uint32 length)
|
||||
{
|
||||
return fwrite(data, length, 1, this->file);
|
||||
return (uint32)fwrite(data, length, 1, this->file);
|
||||
}
|
||||
|
||||
uint32
|
||||
StreamFile::read(void *data, uint32 length)
|
||||
{
|
||||
return fread(data, length, 1, this->file);
|
||||
return (uint32)fread(data, length, 1, this->file);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "rwobjects.h"
|
||||
#include "rwengine.h"
|
||||
|
||||
#define PLUGIN_ID 0
|
||||
#define PLUGIN_ID ID_CAMERA
|
||||
|
||||
namespace rw {
|
||||
|
||||
@ -268,7 +268,7 @@ worldCameraSync(ObjectWithFrame *obj)
|
||||
Camera*
|
||||
Camera::create(void)
|
||||
{
|
||||
Camera *cam = (Camera*)malloc(s_plglist.size);
|
||||
Camera *cam = (Camera*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_CAMERA);
|
||||
if(cam == nil){
|
||||
RWERROR((ERR_ALLOC, s_plglist.size));
|
||||
return nil;
|
||||
@ -325,7 +325,7 @@ Camera::destroy(void)
|
||||
s_plglist.destruct(this);
|
||||
if(this->clump)
|
||||
this->inClump.remove();
|
||||
free(this);
|
||||
rwFree(this);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -23,7 +23,7 @@ PluginList Atomic::s_plglist = { sizeof(Atomic), sizeof(Atomic), nil, nil };
|
||||
Clump*
|
||||
Clump::create(void)
|
||||
{
|
||||
Clump *clump = (Clump*)malloc(s_plglist.size);
|
||||
Clump *clump = (Clump*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_CLUMP);
|
||||
if(clump == nil){
|
||||
RWERROR((ERR_ALLOC, s_plglist.size));
|
||||
return nil;
|
||||
@ -66,7 +66,7 @@ Clump::destroy(void)
|
||||
Camera::fromClump(lnk)->destroy();
|
||||
if(f = this->getFrame(), f)
|
||||
f->destroyHierarchy();
|
||||
free(this);
|
||||
rwFree(this);
|
||||
}
|
||||
|
||||
Clump*
|
||||
@ -120,7 +120,7 @@ Clump::streamRead(Stream *stream)
|
||||
numGeometries = stream->readI32();
|
||||
if(numGeometries){
|
||||
size_t sz = numGeometries*sizeof(Geometry*);
|
||||
geometryList = (Geometry**)malloc(sz);
|
||||
geometryList = (Geometry**)rwMalloc(sz, MEMDUR_FUNCTION | ID_CLUMP);
|
||||
if(geometryList == nil){
|
||||
RWERROR((ERR_ALLOC, sz));
|
||||
goto fail;
|
||||
@ -193,8 +193,8 @@ Clump::streamRead(Stream *stream)
|
||||
for(int32 i = 0; i < numGeometries; i++)
|
||||
if(geometryList[i])
|
||||
geometryList[i]->destroy();
|
||||
free(geometryList);
|
||||
free(frmlst.frames);
|
||||
rwFree(geometryList);
|
||||
rwFree(frmlst.frames);
|
||||
if(s_plglist.streamRead(stream, clump))
|
||||
return clump;
|
||||
|
||||
@ -202,9 +202,9 @@ failgeo:
|
||||
for(int32 i = 0; i < numGeometries; i++)
|
||||
if(geometryList[i])
|
||||
geometryList[i]->destroy();
|
||||
free(geometryList);
|
||||
rwFree(geometryList);
|
||||
fail:
|
||||
free(frmlst.frames);
|
||||
rwFree(frmlst.frames);
|
||||
clump->destroy();
|
||||
return nil;
|
||||
}
|
||||
@ -224,7 +224,7 @@ Clump::streamWrite(Stream *stream)
|
||||
|
||||
FrameList_ frmlst;
|
||||
frmlst.numFrames = this->getFrame()->count();
|
||||
frmlst.frames = (Frame**)malloc(frmlst.numFrames*sizeof(Frame*));
|
||||
frmlst.frames = (Frame**)rwMalloc(frmlst.numFrames*sizeof(Frame*), MEMDUR_FUNCTION | ID_CLUMP);
|
||||
makeFrameList(this->getFrame(), frmlst.frames);
|
||||
frmlst.streamWrite(stream);
|
||||
|
||||
@ -262,7 +262,7 @@ Clump::streamWrite(Stream *stream)
|
||||
c->streamWrite(stream);
|
||||
}
|
||||
|
||||
free(frmlst.frames);
|
||||
rwFree(frmlst.frames);
|
||||
|
||||
s_plglist.streamWrite(stream, this);
|
||||
return true;
|
||||
@ -336,7 +336,7 @@ worldAtomicSync(ObjectWithFrame *obj)
|
||||
Atomic*
|
||||
Atomic::create(void)
|
||||
{
|
||||
Atomic *atomic = (Atomic*)malloc(s_plglist.size);
|
||||
Atomic *atomic = (Atomic*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_ATOMIC);
|
||||
if(atomic == nil){
|
||||
RWERROR((ERR_ALLOC, s_plglist.size));
|
||||
return nil;
|
||||
@ -389,7 +389,7 @@ Atomic::destroy(void)
|
||||
if(this->clump)
|
||||
this->inClump.remove();
|
||||
this->setFrame(nil);
|
||||
free(this);
|
||||
rwFree(this);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -23,6 +23,10 @@ namespace rw {
|
||||
Engine *engine;
|
||||
PluginList Driver::s_plglist[NUM_PLATFORMS];
|
||||
Engine::State Engine::state = Dead;
|
||||
MemoryFunctions Engine::memfuncs;
|
||||
|
||||
void *malloc_h(size_t sz, uint32 hint) { return malloc(sz); }
|
||||
void *realloc_h(void *p, size_t sz, uint32 hint) { return realloc(p, sz); }
|
||||
|
||||
// This function mainly registers engine plugins
|
||||
// RW initializes memory related things here too and
|
||||
@ -36,6 +40,10 @@ Engine::init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
memfuncs.malloc = malloc_h;
|
||||
memfuncs.realloc = realloc_h;
|
||||
memfuncs.free = free;
|
||||
|
||||
PluginList init = { sizeof(Driver), sizeof(Driver), nil, nil };
|
||||
for(uint i = 0; i < NUM_PLATFORMS; i++)
|
||||
Driver::s_plglist[i] = init;
|
||||
@ -64,7 +72,7 @@ Engine::open(void)
|
||||
}
|
||||
|
||||
// Allocate engine
|
||||
engine = (Engine*)malloc(sizeof(Engine));
|
||||
engine = (Engine*)rwMalloc(sizeof(Engine), MEMDUR_GLOBAL);
|
||||
engine->currentCamera = nil;
|
||||
engine->currentWorld = nil;
|
||||
engine->currentTexDictionary = nil;
|
||||
@ -133,11 +141,14 @@ Engine::start(EngineStartParams *p)
|
||||
void
|
||||
Engine::term(void)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void
|
||||
Engine::close(void)
|
||||
{
|
||||
// TODO
|
||||
rwFree(engine);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -6,8 +6,9 @@
|
||||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
#include "rwengine.h"
|
||||
|
||||
#define PLUGIN_ID 0
|
||||
#define PLUGIN_ID ID_FRAMELIST
|
||||
|
||||
namespace rw {
|
||||
|
||||
@ -17,7 +18,7 @@ PluginList Frame::s_plglist = { sizeof(Frame), sizeof(Frame), nil, nil };
|
||||
Frame*
|
||||
Frame::create(void)
|
||||
{
|
||||
Frame *f = (Frame*)malloc(s_plglist.size);
|
||||
Frame *f = (Frame*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_FRAMELIST);
|
||||
if(f == nil){
|
||||
RWERROR((ERR_ALLOC, s_plglist.size));
|
||||
return nil;
|
||||
@ -51,7 +52,7 @@ Frame::destroy(void)
|
||||
this->inDirtyList.remove();
|
||||
for(Frame *f = this->child; f; f = f->next)
|
||||
f->object.parent = nil;
|
||||
free(this);
|
||||
rwFree(this);
|
||||
}
|
||||
|
||||
void
|
||||
@ -65,7 +66,7 @@ Frame::destroyHierarchy(void)
|
||||
s_plglist.destruct(this);
|
||||
if(this->object.privateFlags & Frame::HIERARCHYSYNC)
|
||||
this->inDirtyList.remove();
|
||||
free(this);
|
||||
rwFree(this);
|
||||
}
|
||||
|
||||
Frame*
|
||||
@ -343,7 +344,7 @@ FrameList_::streamRead(Stream *stream)
|
||||
return nil;
|
||||
}
|
||||
this->numFrames = stream->readI32();
|
||||
this->frames = (Frame**)malloc(this->numFrames*sizeof(Frame*));
|
||||
this->frames = (Frame**)rwMalloc(this->numFrames*sizeof(Frame*), MEMDUR_EVENT | ID_FRAMELIST);
|
||||
if(this->frames == nil){
|
||||
RWERROR((ERR_ALLOC, this->numFrames*sizeof(Frame*)));
|
||||
return nil;
|
||||
@ -354,7 +355,7 @@ FrameList_::streamRead(Stream *stream)
|
||||
this->frames[i] = f = Frame::create();
|
||||
if(f == nil){
|
||||
// TODO: clean up frames?
|
||||
free(this->frames);
|
||||
rwFree(this->frames);
|
||||
return nil;
|
||||
}
|
||||
f->matrix.right = buf.right;
|
||||
|
@ -9,8 +9,9 @@
|
||||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
#include "rwengine.h"
|
||||
|
||||
#define PLUGIN_ID 2
|
||||
#define PLUGIN_ID ID_GEOMETRY
|
||||
|
||||
namespace rw {
|
||||
|
||||
@ -23,7 +24,7 @@ SurfaceProperties defaultSurfaceProps = { 1.0f, 1.0f, 1.0f };
|
||||
Geometry*
|
||||
Geometry::create(int32 numVerts, int32 numTris, uint32 flags)
|
||||
{
|
||||
Geometry *geo = (Geometry*)malloc(s_plglist.size);
|
||||
Geometry *geo = (Geometry*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_GEOMETRY);
|
||||
if(geo == nil){
|
||||
RWERROR((ERR_ALLOC, s_plglist.size));
|
||||
return nil;
|
||||
@ -90,7 +91,7 @@ Geometry::destroy(void)
|
||||
delete[] this->morphTargets;
|
||||
delete this->meshHeader;
|
||||
this->matList.deinit();
|
||||
free(this);
|
||||
rwFree(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,7 +270,8 @@ Geometry::addMorphTargets(int32 n)
|
||||
{
|
||||
if(n == 0)
|
||||
return;
|
||||
MorphTarget *morphTargets = new MorphTarget[this->numMorphTargets+n];
|
||||
n += this->numMorphTargets;
|
||||
MorphTarget *morphTargets = new MorphTarget[n];
|
||||
memcpy(morphTargets, this->morphTargets,
|
||||
this->numMorphTargets*sizeof(MorphTarget));
|
||||
delete[] this->morphTargets;
|
||||
@ -284,7 +286,7 @@ Geometry::addMorphTargets(int32 n)
|
||||
m->normals = new V3d[this->numVertices];
|
||||
}
|
||||
}
|
||||
this->numMorphTargets += n;
|
||||
this->numMorphTargets = n;
|
||||
}
|
||||
|
||||
void
|
||||
@ -332,11 +334,12 @@ Geometry::allocateData(void)
|
||||
for(int32 i = 0; i < this->numTexCoordSets; i++)
|
||||
this->texCoords[i] =
|
||||
new TexCoords[this->numVertices];
|
||||
MorphTarget *m = this->morphTargets;
|
||||
m->vertices = new V3d[this->numVertices];
|
||||
if(this->flags & NORMALS)
|
||||
m->normals = new V3d[this->numVertices];
|
||||
// TODO: morph targets (who cares anyway?)
|
||||
for(int32 i = 0; i < this->numMorphTargets; i++){
|
||||
MorphTarget *m = &morphTargets[i];
|
||||
m->vertices = new V3d[this->numVertices];
|
||||
if(this->flags & NORMALS)
|
||||
m->normals = new V3d[this->numVertices];
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@ -553,7 +556,7 @@ Geometry::removeUnusedMaterials(void)
|
||||
}
|
||||
for(int32 i = 0; i < this->matList.numMaterials; i++)
|
||||
this->matList.materials[i]->destroy();
|
||||
free(this->matList.materials);
|
||||
rwFree(this->matList.materials);
|
||||
this->matList.materials = materials;
|
||||
this->matList.space = this->matList.numMaterials;
|
||||
this->matList.numMaterials = numMaterials;
|
||||
@ -596,6 +599,8 @@ Geometry::removeUnusedMaterials(void)
|
||||
//
|
||||
// MaterialList
|
||||
//
|
||||
#undef PLUGIN_ID
|
||||
#define PLUGIN_ID ID_MATERIAL
|
||||
|
||||
void
|
||||
MaterialList::init(void)
|
||||
@ -611,7 +616,7 @@ MaterialList::deinit(void)
|
||||
if(this->materials){
|
||||
for(int32 i = 0; i < this->numMaterials; i++)
|
||||
this->materials[i]->destroy();
|
||||
free(this->materials);
|
||||
rwFree(this->materials);
|
||||
}
|
||||
}
|
||||
|
||||
@ -623,10 +628,12 @@ MaterialList::appendMaterial(Material *mat)
|
||||
if(this->numMaterials >= this->space){
|
||||
space = this->space + 20;
|
||||
if(this->materials)
|
||||
ml = (Material**)realloc(this->materials,
|
||||
space*sizeof(Material*));
|
||||
ml = (Material**)rwRealloc(this->materials,
|
||||
space*sizeof(Material*),
|
||||
MEMDUR_EVENT | ID_MATERIAL);
|
||||
else
|
||||
ml = (Material**)malloc(space*sizeof(Material*));
|
||||
ml = (Material**)rwMalloc(space*sizeof(Material*),
|
||||
MEMDUR_EVENT | ID_MATERIAL);
|
||||
if(ml == nil)
|
||||
return -1;
|
||||
this->space = space;
|
||||
@ -659,12 +666,12 @@ MaterialList::streamRead(Stream *stream, MaterialList *matlist)
|
||||
numMat = stream->readI32();
|
||||
if(numMat == 0)
|
||||
return matlist;
|
||||
matlist->materials = (Material**)malloc(numMat*sizeof(Material*));
|
||||
matlist->materials = (Material**)rwMalloc(numMat*sizeof(Material*), MEMDUR_EVENT | ID_MATERIAL);
|
||||
if(matlist->materials == nil)
|
||||
goto fail;
|
||||
matlist->space = numMat;
|
||||
|
||||
indices = (int32*)malloc(numMat*4);
|
||||
indices = (int32*)rwMalloc(numMat*4, MEMDUR_FUNCTION | ID_MATERIAL);
|
||||
stream->read(indices, numMat*4);
|
||||
|
||||
Material *m;
|
||||
@ -684,10 +691,10 @@ MaterialList::streamRead(Stream *stream, MaterialList *matlist)
|
||||
matlist->appendMaterial(m);
|
||||
m->destroy();
|
||||
}
|
||||
free(indices);
|
||||
rwFree(indices);
|
||||
return matlist;
|
||||
fail:
|
||||
free(indices);
|
||||
rwFree(indices);
|
||||
matlist->deinit();
|
||||
return nil;
|
||||
}
|
||||
@ -741,7 +748,7 @@ MaterialList::streamGetSize(void)
|
||||
Material*
|
||||
Material::create(void)
|
||||
{
|
||||
Material *mat = (Material*)malloc(s_plglist.size);
|
||||
Material *mat = (Material*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_MATERIAL);
|
||||
if(mat == nil){
|
||||
RWERROR((ERR_ALLOC, s_plglist.size));
|
||||
return nil;
|
||||
@ -780,7 +787,7 @@ Material::destroy(void)
|
||||
s_plglist.destruct(this);
|
||||
if(this->texture)
|
||||
this->texture->destroy();
|
||||
free(this);
|
||||
rwFree(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ loadfile(const char *path)
|
||||
}
|
||||
fseek(f, 0, SEEK_END);
|
||||
len = ftell(f);
|
||||
buf = (char*)malloc(len+1);
|
||||
buf = (char*)rwMalloc(len+1, MEMDUR_EVENT);
|
||||
rewind(f);
|
||||
fread(buf, 1, len, f);
|
||||
buf[len] = '\0';
|
||||
@ -97,10 +97,10 @@ compileshader(GLenum type, const char *src, GLuint *shader)
|
||||
fprintf(stderr, "Error in %s shader\n",
|
||||
type == GL_VERTEX_SHADER ? "vertex" : "fragment");
|
||||
glGetShaderiv(shdr, GL_INFO_LOG_LENGTH, &len);
|
||||
log = (char*)malloc(len);
|
||||
log = (char*)rwMalloc(len, MEMDUR_FUNCTION);
|
||||
glGetShaderInfoLog(shdr, len, nil, log);
|
||||
fprintf(stderr, "%s\n", log);
|
||||
free(log);
|
||||
rwFree(log);
|
||||
return 1;
|
||||
}
|
||||
*shader = shdr;
|
||||
@ -123,10 +123,10 @@ linkprogram(GLint vs, GLint fs, GLuint *program)
|
||||
if(!success){
|
||||
fprintf(stderr, "Error in program\n");
|
||||
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);
|
||||
log = (char*)malloc(len);
|
||||
log = (char*)rwMalloc(len, MEMDUR_FUNCTION);
|
||||
glGetProgramInfoLog(prog, len, nil, log);
|
||||
fprintf(stderr, "%s\n", log);
|
||||
free(log);
|
||||
rwFree(log);
|
||||
return 1;
|
||||
}
|
||||
*program = prog;
|
||||
@ -181,8 +181,8 @@ Shader::fromFiles(const char *vspath, const char *fspath)
|
||||
vsrc = loadfile(vspath);
|
||||
fsrc = loadfile(fspath);
|
||||
Shader *s = fromStrings(vsrc, fsrc);
|
||||
free(vsrc);
|
||||
free(fsrc);
|
||||
rwFree(vsrc);
|
||||
rwFree(fsrc);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,11 @@ HAnimHierarchy*
|
||||
HAnimHierarchy::create(int32 numNodes, int32 *nodeFlags, int32 *nodeIDs,
|
||||
int32 flags, int32 maxKeySize)
|
||||
{
|
||||
HAnimHierarchy *hier = (HAnimHierarchy*)malloc(sizeof(*hier));
|
||||
HAnimHierarchy *hier = (HAnimHierarchy*)rwMalloc(sizeof(*hier), MEMDUR_EVENT | ID_HANIM);
|
||||
if(hier == nil){
|
||||
RWERROR((ERR_ALLOC, sizeof(*hier)));
|
||||
return nil;
|
||||
}
|
||||
hier->currentAnim = AnimInterpolator::create(numNodes, maxKeySize);
|
||||
|
||||
hier->numNodes = numNodes;
|
||||
@ -61,7 +65,7 @@ HAnimHierarchy::destroy(void)
|
||||
{
|
||||
delete[] (uint8*)this->matricesUnaligned;
|
||||
delete[] this->nodeInfo;
|
||||
free(this);
|
||||
rwFree(this);
|
||||
}
|
||||
|
||||
static Frame*
|
||||
@ -313,10 +317,10 @@ assert(t >= in1->time && t <= in2->time);
|
||||
void
|
||||
registerHAnimPlugin(void)
|
||||
{
|
||||
hAnimOffset = Frame::registerPlugin(sizeof(HAnimData), ID_HANIMPLUGIN,
|
||||
hAnimOffset = Frame::registerPlugin(sizeof(HAnimData), ID_HANIM,
|
||||
createHAnim,
|
||||
destroyHAnim, copyHAnim);
|
||||
Frame::registerPluginStream(ID_HANIMPLUGIN,
|
||||
Frame::registerPluginStream(ID_HANIM,
|
||||
readHAnim,
|
||||
writeHAnim,
|
||||
getSizeHAnim);
|
||||
|
476
src/image.cpp
476
src/image.cpp
@ -15,387 +15,16 @@
|
||||
#include "d3d/rwd3d8.h"
|
||||
#include "d3d/rwd3d9.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
/* srsly? */
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
|
||||
#define PLUGIN_ID 0
|
||||
#define PLUGIN_ID ID_IMAGE
|
||||
|
||||
namespace rw {
|
||||
|
||||
PluginList TexDictionary::s_plglist = { sizeof(TexDictionary), sizeof(TexDictionary), nil, nil };
|
||||
PluginList Texture::s_plglist = { sizeof(Texture), sizeof(Texture), nil, nil };
|
||||
PluginList Raster::s_plglist = { sizeof(Raster), sizeof(Raster), nil, nil };
|
||||
|
||||
//
|
||||
// TexDictionary
|
||||
//
|
||||
|
||||
TexDictionary*
|
||||
TexDictionary::create(void)
|
||||
{
|
||||
TexDictionary *dict = (TexDictionary*)malloc(s_plglist.size);
|
||||
if(dict == nil){
|
||||
RWERROR((ERR_ALLOC, s_plglist.size));
|
||||
return nil;
|
||||
}
|
||||
dict->object.init(TexDictionary::ID, 0);
|
||||
dict->textures.init();
|
||||
s_plglist.construct(dict);
|
||||
return dict;
|
||||
}
|
||||
|
||||
void
|
||||
TexDictionary::destroy(void)
|
||||
{
|
||||
if(engine->currentTexDictionary == this)
|
||||
engine->currentTexDictionary = nil;
|
||||
FORLIST(lnk, this->textures)
|
||||
Texture::fromDict(lnk)->destroy();
|
||||
s_plglist.destruct(this);
|
||||
free(this);
|
||||
}
|
||||
|
||||
void
|
||||
TexDictionary::add(Texture *t)
|
||||
{
|
||||
if(t->dict)
|
||||
t->inDict.remove();
|
||||
t->dict = this;
|
||||
this->textures.append(&t->inDict);
|
||||
}
|
||||
|
||||
Texture*
|
||||
TexDictionary::find(const char *name)
|
||||
{
|
||||
FORLIST(lnk, this->textures){
|
||||
Texture *tex = Texture::fromDict(lnk);
|
||||
if(strncmp_ci(tex->name, name, 32) == 0)
|
||||
return tex;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
TexDictionary*
|
||||
TexDictionary::streamRead(Stream *stream)
|
||||
{
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
int32 numTex = stream->readI16();
|
||||
stream->readI16(); // device id (0 = unknown, 1 = d3d8, 2 = d3d9,
|
||||
// 3 = gcn, 4 = null, 5 = opengl,
|
||||
// 6 = ps2, 7 = softras, 8 = xbox, 9 = psp)
|
||||
TexDictionary *txd = TexDictionary::create();
|
||||
if(txd == nil)
|
||||
return nil;
|
||||
Texture *tex;
|
||||
for(int32 i = 0; i < numTex; i++){
|
||||
if(!findChunk(stream, ID_TEXTURENATIVE, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "TEXTURENATIVE"));
|
||||
goto fail;
|
||||
}
|
||||
tex = Texture::streamReadNative(stream);
|
||||
if(tex == nil)
|
||||
goto fail;
|
||||
Texture::s_plglist.streamRead(stream, tex);
|
||||
txd->add(tex);
|
||||
}
|
||||
if(s_plglist.streamRead(stream, txd))
|
||||
return txd;
|
||||
fail:
|
||||
txd->destroy();
|
||||
return nil;
|
||||
}
|
||||
|
||||
void
|
||||
TexDictionary::streamWrite(Stream *stream)
|
||||
{
|
||||
writeChunkHeader(stream, ID_TEXDICTIONARY, this->streamGetSize());
|
||||
writeChunkHeader(stream, ID_STRUCT, 4);
|
||||
int32 numTex = this->count();
|
||||
stream->writeI16(numTex);
|
||||
stream->writeI16(0);
|
||||
FORLIST(lnk, this->textures){
|
||||
Texture *tex = Texture::fromDict(lnk);
|
||||
uint32 sz = tex->streamGetSizeNative();
|
||||
sz += 12 + Texture::s_plglist.streamGetSize(tex);
|
||||
writeChunkHeader(stream, ID_TEXTURENATIVE, sz);
|
||||
tex->streamWriteNative(stream);
|
||||
Texture::s_plglist.streamWrite(stream, tex);
|
||||
}
|
||||
s_plglist.streamWrite(stream, this);
|
||||
}
|
||||
|
||||
uint32
|
||||
TexDictionary::streamGetSize(void)
|
||||
{
|
||||
uint32 size = 12 + 4;
|
||||
FORLIST(lnk, this->textures){
|
||||
Texture *tex = Texture::fromDict(lnk);
|
||||
size += 12 + tex->streamGetSizeNative();
|
||||
size += 12 + Texture::s_plglist.streamGetSize(tex);
|
||||
}
|
||||
size += 12 + s_plglist.streamGetSize(this);
|
||||
return size;
|
||||
}
|
||||
|
||||
void
|
||||
TexDictionary::setCurrent(TexDictionary *txd)
|
||||
{
|
||||
engine->currentTexDictionary = txd;
|
||||
}
|
||||
|
||||
TexDictionary*
|
||||
TexDictionary::getCurrent(void)
|
||||
{
|
||||
return engine->currentTexDictionary;
|
||||
}
|
||||
|
||||
//
|
||||
// Texture
|
||||
//
|
||||
|
||||
static Texture *defaultFindCB(const char *name);
|
||||
static Texture *defaultReadCB(const char *name, const char *mask);
|
||||
|
||||
Texture *(*Texture::findCB)(const char *name) = defaultFindCB;
|
||||
Texture *(*Texture::readCB)(const char *name, const char *mask) = defaultReadCB;
|
||||
|
||||
Texture*
|
||||
Texture::create(Raster *raster)
|
||||
{
|
||||
Texture *tex = (Texture*)malloc(s_plglist.size);
|
||||
if(tex == nil){
|
||||
RWERROR((ERR_ALLOC, s_plglist.size));
|
||||
return nil;
|
||||
}
|
||||
tex->dict = nil;
|
||||
tex->inDict.init();
|
||||
memset(tex->name, 0, 32);
|
||||
memset(tex->mask, 0, 32);
|
||||
tex->filterAddressing = (WRAP << 12) | (WRAP << 8) | NEAREST;
|
||||
tex->raster = raster;
|
||||
tex->refCount = 1;
|
||||
s_plglist.construct(tex);
|
||||
return tex;
|
||||
}
|
||||
|
||||
void
|
||||
Texture::destroy(void)
|
||||
{
|
||||
this->refCount--;
|
||||
if(this->refCount <= 0){
|
||||
s_plglist.destruct(this);
|
||||
if(this->dict)
|
||||
this->inDict.remove();
|
||||
if(this->raster)
|
||||
this->raster->destroy();
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
static Texture*
|
||||
defaultFindCB(const char *name)
|
||||
{
|
||||
if(engine->currentTexDictionary)
|
||||
return engine->currentTexDictionary->find(name);
|
||||
// TODO: RW searches *all* TXDs otherwise
|
||||
return nil;
|
||||
}
|
||||
|
||||
static Texture*
|
||||
defaultReadCB(const char *name, const char *mask)
|
||||
{
|
||||
Texture *tex;
|
||||
Image *img;
|
||||
char *n = (char*)malloc(strlen(name) + 5);
|
||||
strcpy(n, name);
|
||||
strcat(n, ".tga");
|
||||
img = readTGA(n);
|
||||
free(n);
|
||||
if(img){
|
||||
tex = Texture::create(Raster::createFromImage(img));
|
||||
strncpy(tex->name, name, 32);
|
||||
if(mask)
|
||||
strncpy(tex->mask, mask, 32);
|
||||
img->destroy();
|
||||
return tex;
|
||||
}else
|
||||
return nil;
|
||||
}
|
||||
|
||||
Texture*
|
||||
Texture::read(const char *name, const char *mask)
|
||||
{
|
||||
(void)mask;
|
||||
Raster *raster = nil;
|
||||
Texture *tex;
|
||||
|
||||
if(tex = Texture::findCB(name), tex){
|
||||
tex->refCount++;
|
||||
return tex;
|
||||
}
|
||||
if(engine->loadTextures){
|
||||
tex = Texture::readCB(name, mask);
|
||||
if(tex == nil)
|
||||
goto dummytex;
|
||||
}else dummytex: if(engine->makeDummies){
|
||||
tex = Texture::create(nil);
|
||||
if(tex == nil)
|
||||
return nil;
|
||||
strncpy(tex->name, name, 32);
|
||||
if(mask)
|
||||
strncpy(tex->mask, mask, 32);
|
||||
raster = Raster::create(0, 0, 0, Raster::DONTALLOCATE);
|
||||
tex->raster = raster;
|
||||
}
|
||||
if(tex && engine->currentTexDictionary){
|
||||
if(tex->dict)
|
||||
tex->inDict.remove();
|
||||
engine->currentTexDictionary->add(tex);
|
||||
}
|
||||
return tex;
|
||||
}
|
||||
|
||||
Texture*
|
||||
Texture::streamRead(Stream *stream)
|
||||
{
|
||||
uint32 length;
|
||||
char name[128], mask[128];
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
uint32 filterAddressing = stream->readU32();
|
||||
// TODO: if V addressing is 0, copy U
|
||||
// if using mipmap filter mode, set automipmapping,
|
||||
// if 0x10000 is set, set mipmapping
|
||||
|
||||
if(!findChunk(stream, ID_STRING, &length, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRING"));
|
||||
return nil;
|
||||
}
|
||||
stream->read(name, length);
|
||||
|
||||
if(!findChunk(stream, ID_STRING, &length, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRING"));
|
||||
return nil;
|
||||
}
|
||||
stream->read(mask, length);
|
||||
|
||||
Texture *tex = Texture::read(name, mask);
|
||||
if(tex == nil)
|
||||
return nil;
|
||||
if(tex->refCount == 1)
|
||||
tex->filterAddressing = filterAddressing;
|
||||
|
||||
if(s_plglist.streamRead(stream, tex))
|
||||
return tex;
|
||||
|
||||
tex->destroy();
|
||||
return nil;
|
||||
}
|
||||
|
||||
bool
|
||||
Texture::streamWrite(Stream *stream)
|
||||
{
|
||||
int size;
|
||||
char buf[36];
|
||||
writeChunkHeader(stream, ID_TEXTURE, this->streamGetSize());
|
||||
writeChunkHeader(stream, ID_STRUCT, 4);
|
||||
stream->writeU32(this->filterAddressing);
|
||||
|
||||
memset(buf, 0, 36);
|
||||
strncpy(buf, this->name, 32);
|
||||
size = strlen(buf)+4 & ~3;
|
||||
writeChunkHeader(stream, ID_STRING, size);
|
||||
stream->write(buf, size);
|
||||
|
||||
memset(buf, 0, 36);
|
||||
strncpy(buf, this->mask, 32);
|
||||
size = strlen(buf)+4 & ~3;
|
||||
writeChunkHeader(stream, ID_STRING, size);
|
||||
stream->write(buf, size);
|
||||
|
||||
s_plglist.streamWrite(stream, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32
|
||||
Texture::streamGetSize(void)
|
||||
{
|
||||
uint32 size = 0;
|
||||
size += 12 + 4;
|
||||
size += 12 + 12;
|
||||
size += strlen(this->name)+4 & ~3;
|
||||
size += strlen(this->mask)+4 & ~3;
|
||||
size += 12 + s_plglist.streamGetSize(this);
|
||||
return size;
|
||||
}
|
||||
|
||||
Texture*
|
||||
Texture::streamReadNative(Stream *stream)
|
||||
{
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
uint32 platform = stream->readU32();
|
||||
stream->seek(-16);
|
||||
if(platform == FOURCC_PS2)
|
||||
return ps2::readNativeTexture(stream);
|
||||
if(platform == PLATFORM_D3D8)
|
||||
return d3d8::readNativeTexture(stream);
|
||||
if(platform == PLATFORM_D3D9)
|
||||
return d3d9::readNativeTexture(stream);
|
||||
if(platform == PLATFORM_XBOX)
|
||||
return xbox::readNativeTexture(stream);
|
||||
assert(0 && "unsupported platform");
|
||||
return nil;
|
||||
}
|
||||
|
||||
void
|
||||
Texture::streamWriteNative(Stream *stream)
|
||||
{
|
||||
if(this->raster->platform == PLATFORM_PS2)
|
||||
ps2::writeNativeTexture(this, stream);
|
||||
else if(this->raster->platform == PLATFORM_D3D8)
|
||||
d3d8::writeNativeTexture(this, stream);
|
||||
else if(this->raster->platform == PLATFORM_D3D9)
|
||||
d3d9::writeNativeTexture(this, stream);
|
||||
else if(this->raster->platform == PLATFORM_XBOX)
|
||||
xbox::writeNativeTexture(this, stream);
|
||||
else
|
||||
assert(0 && "unsupported platform");
|
||||
}
|
||||
|
||||
uint32
|
||||
Texture::streamGetSizeNative(void)
|
||||
{
|
||||
if(this->raster->platform == PLATFORM_PS2)
|
||||
return ps2::getSizeNativeTexture(this);
|
||||
if(this->raster->platform == PLATFORM_D3D8)
|
||||
return d3d8::getSizeNativeTexture(this);
|
||||
if(this->raster->platform == PLATFORM_D3D9)
|
||||
return d3d9::getSizeNativeTexture(this);
|
||||
if(this->raster->platform == PLATFORM_XBOX)
|
||||
return xbox::getSizeNativeTexture(this);
|
||||
assert(0 && "unsupported platform");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Image
|
||||
//
|
||||
// TODO: full 16 bit support
|
||||
|
||||
Image*
|
||||
Image::create(int32 width, int32 height, int32 depth)
|
||||
{
|
||||
Image *img = (Image*)malloc(sizeof(Image));
|
||||
Image *img = (Image*)rwMalloc(sizeof(Image), MEMDUR_EVENT | ID_IMAGE);
|
||||
if(img == nil){
|
||||
RWERROR((ERR_ALLOC, sizeof(Image)));
|
||||
return nil;
|
||||
@ -414,7 +43,7 @@ void
|
||||
Image::destroy(void)
|
||||
{
|
||||
this->free();
|
||||
::free(this);
|
||||
rwFree(this);
|
||||
}
|
||||
|
||||
void
|
||||
@ -836,14 +465,25 @@ Image::extractMask(void)
|
||||
static char *searchPaths = nil;
|
||||
int numSearchPaths = 0;
|
||||
|
||||
static char*
|
||||
rwstrdup(const char *s)
|
||||
{
|
||||
char *t;
|
||||
int32 len = strlen(s)+1;
|
||||
t = (char*)rwMalloc(len, MEMDUR_EVENT);
|
||||
if(t)
|
||||
memcpy(t, s, len);
|
||||
return t;
|
||||
}
|
||||
|
||||
void
|
||||
Image::setSearchPath(const char *path)
|
||||
{
|
||||
char *p, *end;
|
||||
::free(searchPaths);
|
||||
rwFree(searchPaths);
|
||||
numSearchPaths = 0;
|
||||
if(path)
|
||||
searchPaths = p = strdup(path);
|
||||
searchPaths = p = rwstrdup(path);
|
||||
else{
|
||||
searchPaths = nil;
|
||||
return;
|
||||
@ -878,12 +518,12 @@ Image::getFilename(const char *name)
|
||||
if(f){
|
||||
fclose(f);
|
||||
printf("found %s\n", name);
|
||||
return strdup(name);
|
||||
return rwstrdup(name);
|
||||
}
|
||||
return nil;
|
||||
}else
|
||||
for(int i = 0; i < numSearchPaths; i++){
|
||||
s = (char*)malloc(strlen(p)+len);
|
||||
s = (char*)rwMalloc(strlen(p)+len, MEMDUR_EVENT | ID_IMAGE);
|
||||
if(s == nil){
|
||||
RWERROR((ERR_ALLOC, strlen(p)+len));
|
||||
return nil;
|
||||
@ -896,88 +536,10 @@ Image::getFilename(const char *name)
|
||||
printf("found %s\n", name);
|
||||
return s;
|
||||
}
|
||||
::free(s);
|
||||
rwFree(s);
|
||||
p += strlen(p) + 1;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
//
|
||||
// Raster
|
||||
//
|
||||
|
||||
Raster*
|
||||
Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platform)
|
||||
{
|
||||
// TODO: pass arguments through to the driver and create the raster there
|
||||
Raster *raster = (Raster*)malloc(s_plglist.size);
|
||||
assert(raster != nil);
|
||||
raster->platform = platform ? platform : rw::platform;
|
||||
raster->type = format & 0x7;
|
||||
raster->flags = format & 0xF8;
|
||||
raster->format = format & 0xFF00;
|
||||
raster->width = width;
|
||||
raster->height = height;
|
||||
raster->depth = depth;
|
||||
raster->pixels = raster->palette = nil;
|
||||
s_plglist.construct(raster);
|
||||
|
||||
// printf("%d %d %d %d\n", raster->type, raster->width, raster->height, raster->depth);
|
||||
engine->driver[raster->platform]->rasterCreate(raster);
|
||||
return raster;
|
||||
}
|
||||
|
||||
void
|
||||
Raster::destroy(void)
|
||||
{
|
||||
s_plglist.destruct(this);
|
||||
// delete[] this->texels;
|
||||
// delete[] this->palette;
|
||||
free(this);
|
||||
}
|
||||
|
||||
uint8*
|
||||
Raster::lock(int32 level)
|
||||
{
|
||||
return engine->driver[this->platform]->rasterLock(this, level);
|
||||
}
|
||||
|
||||
void
|
||||
Raster::unlock(int32 level)
|
||||
{
|
||||
engine->driver[this->platform]->rasterUnlock(this, level);
|
||||
}
|
||||
|
||||
int32
|
||||
Raster::getNumLevels(void)
|
||||
{
|
||||
return engine->driver[this->platform]->rasterNumLevels(this);
|
||||
}
|
||||
|
||||
int32
|
||||
Raster::calculateNumLevels(int32 width, int32 height)
|
||||
{
|
||||
int32 size = width >= height ? width : height;
|
||||
int32 n;
|
||||
for(n = 0; size != 0; n++)
|
||||
size /= 2;
|
||||
return n;
|
||||
}
|
||||
|
||||
Raster*
|
||||
Raster::createFromImage(Image *image, int32 platform)
|
||||
{
|
||||
Raster *raster = Raster::create(image->width, image->height,
|
||||
image->depth, TEXTURE | DONTALLOCATE,
|
||||
platform);
|
||||
engine->driver[raster->platform]->rasterFromImage(raster, image);
|
||||
return raster;
|
||||
}
|
||||
|
||||
Image*
|
||||
Raster::toImage(void)
|
||||
{
|
||||
return engine->driver[this->platform]->rasterToImage(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,8 +6,9 @@
|
||||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
#include "rwengine.h"
|
||||
|
||||
#define PLUGIN_ID 2
|
||||
#define PLUGIN_ID ID_LIGHT
|
||||
|
||||
namespace rw {
|
||||
|
||||
@ -28,7 +29,7 @@ worldLightSync(ObjectWithFrame *obj)
|
||||
Light*
|
||||
Light::create(int32 type)
|
||||
{
|
||||
Light *light = (Light*)malloc(s_plglist.size);
|
||||
Light *light = (Light*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_LIGHT);
|
||||
if(light == nil){
|
||||
RWERROR((ERR_ALLOC, s_plglist.size));
|
||||
return nil;
|
||||
@ -65,7 +66,7 @@ Light::destroy(void)
|
||||
if(this->clump)
|
||||
this->inClump.remove();
|
||||
// we do not remove from world, be careful
|
||||
free(this);
|
||||
rwFree(this);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -8,6 +8,9 @@
|
||||
#include "rwbase.h"
|
||||
#include "rwerror.h"
|
||||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
#include "rwengine.h"
|
||||
|
||||
namespace rw {
|
||||
|
||||
@ -103,7 +106,7 @@ int32
|
||||
PluginList::registerPlugin(int32 size, uint32 id,
|
||||
Constructor ctor, Destructor dtor, CopyConstructor copy)
|
||||
{
|
||||
Plugin *p = (Plugin*)malloc(sizeof(Plugin));
|
||||
Plugin *p = (Plugin*)rwMalloc(sizeof(Plugin), MEMDUR_GLOBAL);
|
||||
p->offset = this->size;
|
||||
this->size += size;
|
||||
int32 round = sizeof(void*)-1;
|
||||
|
@ -86,7 +86,7 @@ mallocalign(size_t size, int32 alignment)
|
||||
{
|
||||
void *p;
|
||||
void **pp;
|
||||
p = malloc(size + alignment + sizeof(void*));
|
||||
p = rwMalloc(size + alignment + sizeof(void*), MEMDUR_EVENT | ID_RASTERPS2);
|
||||
if(p == nil) return nil;
|
||||
pp = (void**)(((uintptr)p + sizeof(void*) + alignment)&~(alignment-1));
|
||||
pp[-1] = p;
|
||||
@ -99,7 +99,7 @@ freealign(void *p)
|
||||
void *pp;
|
||||
if(p == nil) return;
|
||||
pp = ((void**)p)[-1];
|
||||
free(pp);
|
||||
rwFree(pp);
|
||||
}
|
||||
|
||||
// TODO: these depend on video mode, set in deviceSystem!
|
||||
@ -391,13 +391,13 @@ static uint8 blockmaprev_PSMCT16[32] = {
|
||||
static void
|
||||
calcOffsets(int32 width_Px, int32 height_Px, int32 psm, uint64 *bufferBase_B, uint64 *bufferWidth_W, uint32 *trxpos, uint32 *totalSize, uint32 *paletteBase)
|
||||
{
|
||||
int32 pageWidth_Px, pageHeight_Px;
|
||||
int32 blockWidth_Px, blockHeight_Px;
|
||||
int32 mindim_Px;
|
||||
uint32 pageWidth_Px, pageHeight_Px;
|
||||
uint32 blockWidth_Px, blockHeight_Px;
|
||||
uint32 mindim_Px;
|
||||
int32 nlevels;
|
||||
int32 n;
|
||||
int32 mipw_Px, miph_Px;
|
||||
int32 lastmipw_Px, lastmiph_Px;
|
||||
uint32 mipw_Px, miph_Px;
|
||||
uint32 lastmipw_Px, lastmiph_Px;
|
||||
uint32 bufferHeight_P[8];
|
||||
uint32 bufferPage_B[8]; // address of page in which the level is allocated
|
||||
uint32 xoff_Px, yoff_Px; // x/y offset the last level starts at
|
||||
@ -408,7 +408,7 @@ calcOffsets(int32 width_Px, int32 height_Px, int32 psm, uint64 *bufferBase_B, ui
|
||||
uint32 widthstack_Px[8];
|
||||
uint32 heightstack_Px[8];
|
||||
uint32 basestack_B[8];
|
||||
int32 flag;
|
||||
uint32 flag;
|
||||
|
||||
switch(psm){
|
||||
case PSMCT32:
|
||||
@ -652,7 +652,7 @@ calcOffsets(int32 width_Px, int32 height_Px, int32 psm, uint64 *bufferBase_B, ui
|
||||
// the R bits are the block's row in a row of pages
|
||||
// We want to swap P and R: PPRRRCC
|
||||
bufferBase_B[n] =
|
||||
(bufferBase_B[n] & ~(bufpagestride_B - PAGEWIDTH_B)) // mask out R and P
|
||||
(bufferBase_B[n] & ~((uint64)bufpagestride_B - PAGEWIDTH_B)) // mask out R and P
|
||||
| ((bufferBase_B[n] & (bufwidth_B - PAGEWIDTH_B)) * (bufpagestride_B/bufwidth_B)) // extract P and shift left
|
||||
| ((bufferBase_B[n] & (bufpagestride_B - bufwidth_B)) / (bufwidth_B/PAGEWIDTH_B)); // extract R and shift right
|
||||
}
|
||||
@ -968,8 +968,8 @@ createTexRaster(Raster *raster)
|
||||
|
||||
ras->pixelSize = ALIGN16(raster->stride*raster->height);
|
||||
ras->paletteSize = paletteWidth*paletteHeight*paletteDepth;
|
||||
ras->miptbp1 = 1<<54 | 1<<34 | 1<<14;
|
||||
ras->miptbp2 = 1<<54 | 1<<34 | 1<<14;
|
||||
ras->miptbp1 = 1ULL<<54 | 1ULL<<34 | 1ULL<<14;
|
||||
ras->miptbp2 = 1ULL<<54 | 1ULL<<34 | 1ULL<<14;
|
||||
ras->tex1low = 0; // one mipmap level
|
||||
|
||||
// find out number of pages needed
|
||||
@ -1010,8 +1010,8 @@ createTexRaster(Raster *raster)
|
||||
th << 30 |
|
||||
tcc << 34 |
|
||||
cpsm << 51 |
|
||||
0 << 55 | // csm0
|
||||
0 << 56 | // entry offset
|
||||
0ULL << 55 | // csm0
|
||||
0ULL << 56 | // entry offset
|
||||
cld << 61;
|
||||
|
||||
|
||||
|
12
src/rwbase.h
12
src/rwbase.h
@ -381,11 +381,12 @@ enum Platform
|
||||
// SOFTRAS
|
||||
PLATFORM_D3D8 = 8,
|
||||
PLATFORM_D3D9 = 9,
|
||||
// PSP
|
||||
|
||||
// non-stock-RW platforms
|
||||
|
||||
PLATFORM_WDGL = 10, // WarDrum OpenGL
|
||||
PLATFORM_GL3 = 11, // my GL3 implementation
|
||||
PLATFORM_WDGL = 11, // WarDrum OpenGL
|
||||
PLATFORM_GL3 = 12, // my GL3 implementation
|
||||
|
||||
NUM_PLATFORMS,
|
||||
|
||||
@ -404,6 +405,8 @@ enum VendorID
|
||||
VEND_PLATFORM = 10,
|
||||
};
|
||||
|
||||
// TODO: modules (VEND_CRITERIONINT)
|
||||
|
||||
enum PluginID
|
||||
{
|
||||
// Core
|
||||
@ -415,6 +418,8 @@ enum PluginID
|
||||
ID_TEXTURE = MAKEPLUGINID(VEND_CORE, 0x06),
|
||||
ID_MATERIAL = MAKEPLUGINID(VEND_CORE, 0x07),
|
||||
ID_MATLIST = MAKEPLUGINID(VEND_CORE, 0x08),
|
||||
ID_WORLD = MAKEPLUGINID(VEND_CORE, 0x0B),
|
||||
ID_MATRIX = MAKEPLUGINID(VEND_CORE, 0x0D),
|
||||
ID_FRAMELIST = MAKEPLUGINID(VEND_CORE, 0x0E),
|
||||
ID_GEOMETRY = MAKEPLUGINID(VEND_CORE, 0x0F),
|
||||
ID_CLUMP = MAKEPLUGINID(VEND_CORE, 0x10),
|
||||
@ -422,6 +427,7 @@ enum PluginID
|
||||
ID_ATOMIC = MAKEPLUGINID(VEND_CORE, 0x14),
|
||||
ID_TEXTURENATIVE = MAKEPLUGINID(VEND_CORE, 0x15),
|
||||
ID_TEXDICTIONARY = MAKEPLUGINID(VEND_CORE, 0x16),
|
||||
ID_IMAGE = MAKEPLUGINID(VEND_CORE, 0x18),
|
||||
ID_GEOMETRYLIST = MAKEPLUGINID(VEND_CORE, 0x1A),
|
||||
ID_ANIMANIMATION = MAKEPLUGINID(VEND_CORE, 0x1B),
|
||||
ID_RIGHTTORENDER = MAKEPLUGINID(VEND_CORE, 0x1F),
|
||||
@ -430,7 +436,7 @@ enum PluginID
|
||||
// Toolkit
|
||||
ID_SKYMIPMAP = MAKEPLUGINID(VEND_CRITERIONTK, 0x10),
|
||||
ID_SKIN = MAKEPLUGINID(VEND_CRITERIONTK, 0x16),
|
||||
ID_HANIMPLUGIN = MAKEPLUGINID(VEND_CRITERIONTK, 0x1E),
|
||||
ID_HANIM = MAKEPLUGINID(VEND_CRITERIONTK, 0x1E),
|
||||
ID_USERDATA = MAKEPLUGINID(VEND_CRITERIONTK, 0x1F),
|
||||
ID_MATFX = MAKEPLUGINID(VEND_CRITERIONTK, 0x20),
|
||||
ID_PDS = MAKEPLUGINID(VEND_CRITERIONTK, 0x31),
|
||||
|
@ -94,6 +94,26 @@ struct Driver
|
||||
|
||||
struct EngineStartParams;
|
||||
|
||||
enum MemHint
|
||||
{
|
||||
MEMDUR_NA = 0,
|
||||
// used inside function
|
||||
MEMDUR_FUNCTION = 0x10000,
|
||||
// used for one frame
|
||||
MEMDUR_FRAME = 0x20000,
|
||||
// used for longer time
|
||||
MEMDUR_EVENT = 0x30000,
|
||||
// used while the engine is running
|
||||
MEMDUR_GLOBAL = 0x40000
|
||||
};
|
||||
|
||||
struct MemoryFunctions
|
||||
{
|
||||
void *(*malloc)(size_t sz, uint32 hint);
|
||||
void *(*realloc)(void *p, size_t sz, uint32 hint);
|
||||
void (*free)(void *p);
|
||||
};
|
||||
|
||||
// This is for platform independent things
|
||||
// TODO: move more stuff into this
|
||||
// TODO: make this have plugins and allocate in Engine::open
|
||||
@ -118,6 +138,8 @@ struct Engine
|
||||
Driver *driver[NUM_PLATFORMS];
|
||||
Device device;
|
||||
|
||||
// These must always be available
|
||||
static MemoryFunctions memfuncs;
|
||||
static State state;
|
||||
|
||||
static bool32 init(void);
|
||||
@ -136,6 +158,10 @@ inline void SetRenderState(int32 state, uint32 value){
|
||||
inline uint32 GetRenderState(int32 state){
|
||||
return engine->device.getRenderState(state); }
|
||||
|
||||
#define rwMalloc(s, h) rw::Engine::memfuncs.malloc(s,h)
|
||||
#define rwRealloc(p, s, h) rw::Engine::memfuncs.realloc(p,s,h)
|
||||
#define rwFree(p) rw::Engine::memfuncs.free(p)
|
||||
|
||||
namespace null {
|
||||
void beginUpdate(Camera*);
|
||||
void endUpdate(Camera*);
|
||||
|
@ -39,7 +39,7 @@ destroySkin(void *object, int32 offset, int32)
|
||||
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
|
||||
if(skin){
|
||||
delete[] skin->data;
|
||||
free(skin->remapIndices);
|
||||
rwFree(skin->remapIndices);
|
||||
// delete[] skin->platformData;
|
||||
}
|
||||
delete skin;
|
||||
@ -83,7 +83,7 @@ readSkinSplitData(Stream *stream, Skin *skin)
|
||||
skin->rleSize = stream->readI32();
|
||||
if(skin->numMeshes){
|
||||
sz = skin->numBones + 2*(skin->numMeshes+skin->rleSize);
|
||||
data = (int8*)malloc(sz);
|
||||
data = (int8*)rwMalloc(sz, MEMDUR_EVENT | ID_SKIN);
|
||||
stream->read(data, sz);
|
||||
skin->remapIndices = data;
|
||||
skin->rleCount = (Skin::RLEcount*)(data + skin->numBones);
|
||||
|
468
src/texture.cpp
Normal file
468
src/texture.cpp
Normal file
@ -0,0 +1,468 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#include "rwbase.h"
|
||||
#include "rwerror.h"
|
||||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
#include "rwengine.h"
|
||||
#include "ps2/rwps2.h"
|
||||
#include "d3d/rwd3d.h"
|
||||
#include "d3d/rwxbox.h"
|
||||
#include "d3d/rwd3d8.h"
|
||||
#include "d3d/rwd3d9.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
/* srsly? */
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
|
||||
#define PLUGIN_ID 0
|
||||
|
||||
namespace rw {
|
||||
|
||||
PluginList TexDictionary::s_plglist = { sizeof(TexDictionary), sizeof(TexDictionary), nil, nil };
|
||||
PluginList Texture::s_plglist = { sizeof(Texture), sizeof(Texture), nil, nil };
|
||||
PluginList Raster::s_plglist = { sizeof(Raster), sizeof(Raster), nil, nil };
|
||||
|
||||
//
|
||||
// TexDictionary
|
||||
//
|
||||
|
||||
TexDictionary*
|
||||
TexDictionary::create(void)
|
||||
{
|
||||
TexDictionary *dict = (TexDictionary*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_TEXDICTIONARY);
|
||||
if(dict == nil){
|
||||
RWERROR((ERR_ALLOC, s_plglist.size));
|
||||
return nil;
|
||||
}
|
||||
dict->object.init(TexDictionary::ID, 0);
|
||||
dict->textures.init();
|
||||
s_plglist.construct(dict);
|
||||
return dict;
|
||||
}
|
||||
|
||||
void
|
||||
TexDictionary::destroy(void)
|
||||
{
|
||||
if(engine->currentTexDictionary == this)
|
||||
engine->currentTexDictionary = nil;
|
||||
FORLIST(lnk, this->textures)
|
||||
Texture::fromDict(lnk)->destroy();
|
||||
s_plglist.destruct(this);
|
||||
rwFree(this);
|
||||
}
|
||||
|
||||
void
|
||||
TexDictionary::add(Texture *t)
|
||||
{
|
||||
if(t->dict)
|
||||
t->inDict.remove();
|
||||
t->dict = this;
|
||||
this->textures.append(&t->inDict);
|
||||
}
|
||||
|
||||
Texture*
|
||||
TexDictionary::find(const char *name)
|
||||
{
|
||||
FORLIST(lnk, this->textures){
|
||||
Texture *tex = Texture::fromDict(lnk);
|
||||
if(strncmp_ci(tex->name, name, 32) == 0)
|
||||
return tex;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
TexDictionary*
|
||||
TexDictionary::streamRead(Stream *stream)
|
||||
{
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
int32 numTex = stream->readI16();
|
||||
stream->readI16(); // device id (0 = unknown, 1 = d3d8, 2 = d3d9,
|
||||
// 3 = gcn, 4 = null, 5 = opengl,
|
||||
// 6 = ps2, 7 = softras, 8 = xbox, 9 = psp)
|
||||
TexDictionary *txd = TexDictionary::create();
|
||||
if(txd == nil)
|
||||
return nil;
|
||||
Texture *tex;
|
||||
for(int32 i = 0; i < numTex; i++){
|
||||
if(!findChunk(stream, ID_TEXTURENATIVE, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "TEXTURENATIVE"));
|
||||
goto fail;
|
||||
}
|
||||
tex = Texture::streamReadNative(stream);
|
||||
if(tex == nil)
|
||||
goto fail;
|
||||
Texture::s_plglist.streamRead(stream, tex);
|
||||
txd->add(tex);
|
||||
}
|
||||
if(s_plglist.streamRead(stream, txd))
|
||||
return txd;
|
||||
fail:
|
||||
txd->destroy();
|
||||
return nil;
|
||||
}
|
||||
|
||||
void
|
||||
TexDictionary::streamWrite(Stream *stream)
|
||||
{
|
||||
writeChunkHeader(stream, ID_TEXDICTIONARY, this->streamGetSize());
|
||||
writeChunkHeader(stream, ID_STRUCT, 4);
|
||||
int32 numTex = this->count();
|
||||
stream->writeI16(numTex);
|
||||
stream->writeI16(0);
|
||||
FORLIST(lnk, this->textures){
|
||||
Texture *tex = Texture::fromDict(lnk);
|
||||
uint32 sz = tex->streamGetSizeNative();
|
||||
sz += 12 + Texture::s_plglist.streamGetSize(tex);
|
||||
writeChunkHeader(stream, ID_TEXTURENATIVE, sz);
|
||||
tex->streamWriteNative(stream);
|
||||
Texture::s_plglist.streamWrite(stream, tex);
|
||||
}
|
||||
s_plglist.streamWrite(stream, this);
|
||||
}
|
||||
|
||||
uint32
|
||||
TexDictionary::streamGetSize(void)
|
||||
{
|
||||
uint32 size = 12 + 4;
|
||||
FORLIST(lnk, this->textures){
|
||||
Texture *tex = Texture::fromDict(lnk);
|
||||
size += 12 + tex->streamGetSizeNative();
|
||||
size += 12 + Texture::s_plglist.streamGetSize(tex);
|
||||
}
|
||||
size += 12 + s_plglist.streamGetSize(this);
|
||||
return size;
|
||||
}
|
||||
|
||||
void
|
||||
TexDictionary::setCurrent(TexDictionary *txd)
|
||||
{
|
||||
engine->currentTexDictionary = txd;
|
||||
}
|
||||
|
||||
TexDictionary*
|
||||
TexDictionary::getCurrent(void)
|
||||
{
|
||||
return engine->currentTexDictionary;
|
||||
}
|
||||
|
||||
//
|
||||
// Texture
|
||||
//
|
||||
|
||||
static Texture *defaultFindCB(const char *name);
|
||||
static Texture *defaultReadCB(const char *name, const char *mask);
|
||||
|
||||
Texture *(*Texture::findCB)(const char *name) = defaultFindCB;
|
||||
Texture *(*Texture::readCB)(const char *name, const char *mask) = defaultReadCB;
|
||||
|
||||
Texture*
|
||||
Texture::create(Raster *raster)
|
||||
{
|
||||
Texture *tex = (Texture*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_TEXTURE);
|
||||
if(tex == nil){
|
||||
RWERROR((ERR_ALLOC, s_plglist.size));
|
||||
return nil;
|
||||
}
|
||||
tex->dict = nil;
|
||||
tex->inDict.init();
|
||||
memset(tex->name, 0, 32);
|
||||
memset(tex->mask, 0, 32);
|
||||
tex->filterAddressing = (WRAP << 12) | (WRAP << 8) | NEAREST;
|
||||
tex->raster = raster;
|
||||
tex->refCount = 1;
|
||||
s_plglist.construct(tex);
|
||||
return tex;
|
||||
}
|
||||
|
||||
void
|
||||
Texture::destroy(void)
|
||||
{
|
||||
this->refCount--;
|
||||
if(this->refCount <= 0){
|
||||
s_plglist.destruct(this);
|
||||
if(this->dict)
|
||||
this->inDict.remove();
|
||||
if(this->raster)
|
||||
this->raster->destroy();
|
||||
rwFree(this);
|
||||
}
|
||||
}
|
||||
|
||||
static Texture*
|
||||
defaultFindCB(const char *name)
|
||||
{
|
||||
if(engine->currentTexDictionary)
|
||||
return engine->currentTexDictionary->find(name);
|
||||
// TODO: RW searches *all* TXDs otherwise
|
||||
return nil;
|
||||
}
|
||||
|
||||
static Texture*
|
||||
defaultReadCB(const char *name, const char *mask)
|
||||
{
|
||||
Texture *tex;
|
||||
Image *img;
|
||||
char *n = (char*)rwMalloc(strlen(name) + 5, MEMDUR_FUNCTION | ID_TEXTURE);
|
||||
strcpy(n, name);
|
||||
strcat(n, ".tga");
|
||||
img = readTGA(n);
|
||||
rwFree(n);
|
||||
if(img){
|
||||
tex = Texture::create(Raster::createFromImage(img));
|
||||
strncpy(tex->name, name, 32);
|
||||
if(mask)
|
||||
strncpy(tex->mask, mask, 32);
|
||||
img->destroy();
|
||||
return tex;
|
||||
}else
|
||||
return nil;
|
||||
}
|
||||
|
||||
Texture*
|
||||
Texture::read(const char *name, const char *mask)
|
||||
{
|
||||
(void)mask;
|
||||
Raster *raster = nil;
|
||||
Texture *tex;
|
||||
|
||||
if(tex = Texture::findCB(name), tex){
|
||||
tex->refCount++;
|
||||
return tex;
|
||||
}
|
||||
if(engine->loadTextures){
|
||||
tex = Texture::readCB(name, mask);
|
||||
if(tex == nil)
|
||||
goto dummytex;
|
||||
}else dummytex: if(engine->makeDummies){
|
||||
tex = Texture::create(nil);
|
||||
if(tex == nil)
|
||||
return nil;
|
||||
strncpy(tex->name, name, 32);
|
||||
if(mask)
|
||||
strncpy(tex->mask, mask, 32);
|
||||
raster = Raster::create(0, 0, 0, Raster::DONTALLOCATE);
|
||||
tex->raster = raster;
|
||||
}
|
||||
if(tex && engine->currentTexDictionary){
|
||||
if(tex->dict)
|
||||
tex->inDict.remove();
|
||||
engine->currentTexDictionary->add(tex);
|
||||
}
|
||||
return tex;
|
||||
}
|
||||
|
||||
Texture*
|
||||
Texture::streamRead(Stream *stream)
|
||||
{
|
||||
uint32 length;
|
||||
char name[128], mask[128];
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
uint32 filterAddressing = stream->readU32();
|
||||
// TODO: if V addressing is 0, copy U
|
||||
// if using mipmap filter mode, set automipmapping,
|
||||
// if 0x10000 is set, set mipmapping
|
||||
|
||||
if(!findChunk(stream, ID_STRING, &length, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRING"));
|
||||
return nil;
|
||||
}
|
||||
stream->read(name, length);
|
||||
|
||||
if(!findChunk(stream, ID_STRING, &length, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRING"));
|
||||
return nil;
|
||||
}
|
||||
stream->read(mask, length);
|
||||
|
||||
Texture *tex = Texture::read(name, mask);
|
||||
if(tex == nil)
|
||||
return nil;
|
||||
if(tex->refCount == 1)
|
||||
tex->filterAddressing = filterAddressing;
|
||||
|
||||
if(s_plglist.streamRead(stream, tex))
|
||||
return tex;
|
||||
|
||||
tex->destroy();
|
||||
return nil;
|
||||
}
|
||||
|
||||
bool
|
||||
Texture::streamWrite(Stream *stream)
|
||||
{
|
||||
int size;
|
||||
char buf[36];
|
||||
writeChunkHeader(stream, ID_TEXTURE, this->streamGetSize());
|
||||
writeChunkHeader(stream, ID_STRUCT, 4);
|
||||
stream->writeU32(this->filterAddressing);
|
||||
|
||||
memset(buf, 0, 36);
|
||||
strncpy(buf, this->name, 32);
|
||||
size = strlen(buf)+4 & ~3;
|
||||
writeChunkHeader(stream, ID_STRING, size);
|
||||
stream->write(buf, size);
|
||||
|
||||
memset(buf, 0, 36);
|
||||
strncpy(buf, this->mask, 32);
|
||||
size = strlen(buf)+4 & ~3;
|
||||
writeChunkHeader(stream, ID_STRING, size);
|
||||
stream->write(buf, size);
|
||||
|
||||
s_plglist.streamWrite(stream, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32
|
||||
Texture::streamGetSize(void)
|
||||
{
|
||||
uint32 size = 0;
|
||||
size += 12 + 4;
|
||||
size += 12 + 12;
|
||||
size += strlen(this->name)+4 & ~3;
|
||||
size += strlen(this->mask)+4 & ~3;
|
||||
size += 12 + s_plglist.streamGetSize(this);
|
||||
return size;
|
||||
}
|
||||
|
||||
Texture*
|
||||
Texture::streamReadNative(Stream *stream)
|
||||
{
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
uint32 platform = stream->readU32();
|
||||
stream->seek(-16);
|
||||
if(platform == FOURCC_PS2)
|
||||
return ps2::readNativeTexture(stream);
|
||||
if(platform == PLATFORM_D3D8)
|
||||
return d3d8::readNativeTexture(stream);
|
||||
if(platform == PLATFORM_D3D9)
|
||||
return d3d9::readNativeTexture(stream);
|
||||
if(platform == PLATFORM_XBOX)
|
||||
return xbox::readNativeTexture(stream);
|
||||
assert(0 && "unsupported platform");
|
||||
return nil;
|
||||
}
|
||||
|
||||
void
|
||||
Texture::streamWriteNative(Stream *stream)
|
||||
{
|
||||
if(this->raster->platform == PLATFORM_PS2)
|
||||
ps2::writeNativeTexture(this, stream);
|
||||
else if(this->raster->platform == PLATFORM_D3D8)
|
||||
d3d8::writeNativeTexture(this, stream);
|
||||
else if(this->raster->platform == PLATFORM_D3D9)
|
||||
d3d9::writeNativeTexture(this, stream);
|
||||
else if(this->raster->platform == PLATFORM_XBOX)
|
||||
xbox::writeNativeTexture(this, stream);
|
||||
else
|
||||
assert(0 && "unsupported platform");
|
||||
}
|
||||
|
||||
uint32
|
||||
Texture::streamGetSizeNative(void)
|
||||
{
|
||||
if(this->raster->platform == PLATFORM_PS2)
|
||||
return ps2::getSizeNativeTexture(this);
|
||||
if(this->raster->platform == PLATFORM_D3D8)
|
||||
return d3d8::getSizeNativeTexture(this);
|
||||
if(this->raster->platform == PLATFORM_D3D9)
|
||||
return d3d9::getSizeNativeTexture(this);
|
||||
if(this->raster->platform == PLATFORM_XBOX)
|
||||
return xbox::getSizeNativeTexture(this);
|
||||
assert(0 && "unsupported platform");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Raster
|
||||
//
|
||||
|
||||
Raster*
|
||||
Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platform)
|
||||
{
|
||||
// TODO: pass arguments through to the driver and create the raster there
|
||||
Raster *raster = (Raster*)rwMalloc(s_plglist.size, MEMDUR_EVENT); // TODO
|
||||
assert(raster != nil);
|
||||
raster->platform = platform ? platform : rw::platform;
|
||||
raster->type = format & 0x7;
|
||||
raster->flags = format & 0xF8;
|
||||
raster->format = format & 0xFF00;
|
||||
raster->width = width;
|
||||
raster->height = height;
|
||||
raster->depth = depth;
|
||||
raster->pixels = raster->palette = nil;
|
||||
s_plglist.construct(raster);
|
||||
|
||||
// printf("%d %d %d %d\n", raster->type, raster->width, raster->height, raster->depth);
|
||||
engine->driver[raster->platform]->rasterCreate(raster);
|
||||
return raster;
|
||||
}
|
||||
|
||||
void
|
||||
Raster::destroy(void)
|
||||
{
|
||||
s_plglist.destruct(this);
|
||||
// delete[] this->texels;
|
||||
// delete[] this->palette;
|
||||
rwFree(this);
|
||||
}
|
||||
|
||||
uint8*
|
||||
Raster::lock(int32 level)
|
||||
{
|
||||
return engine->driver[this->platform]->rasterLock(this, level);
|
||||
}
|
||||
|
||||
void
|
||||
Raster::unlock(int32 level)
|
||||
{
|
||||
engine->driver[this->platform]->rasterUnlock(this, level);
|
||||
}
|
||||
|
||||
int32
|
||||
Raster::getNumLevels(void)
|
||||
{
|
||||
return engine->driver[this->platform]->rasterNumLevels(this);
|
||||
}
|
||||
|
||||
int32
|
||||
Raster::calculateNumLevels(int32 width, int32 height)
|
||||
{
|
||||
int32 size = width >= height ? width : height;
|
||||
int32 n;
|
||||
for(n = 0; size != 0; n++)
|
||||
size /= 2;
|
||||
return n;
|
||||
}
|
||||
|
||||
Raster*
|
||||
Raster::createFromImage(Image *image, int32 platform)
|
||||
{
|
||||
Raster *raster = Raster::create(image->width, image->height,
|
||||
image->depth, TEXTURE | DONTALLOCATE,
|
||||
platform);
|
||||
engine->driver[raster->platform]->rasterFromImage(raster, image);
|
||||
return raster;
|
||||
}
|
||||
|
||||
Image*
|
||||
Raster::toImage(void)
|
||||
{
|
||||
return engine->driver[this->platform]->rasterToImage(this);
|
||||
}
|
||||
|
||||
}
|
@ -57,7 +57,7 @@ readTGA(const char *afilename)
|
||||
uint32 length;
|
||||
uint8 *data = getFileContents(filename, &length);
|
||||
assert(data != nil);
|
||||
free(filename);
|
||||
rwFree(filename);
|
||||
StreamMemory file;
|
||||
file.open(data, length);
|
||||
file.read(&header, sizeof(header));
|
||||
|
@ -17,14 +17,16 @@ namespace rw {
|
||||
|
||||
UserDataGlobals userDataGlobals;
|
||||
|
||||
#define udMalloc(sz) rwMalloc(sz, MEMDUR_EVENT | ID_USERDATA)
|
||||
|
||||
void
|
||||
UserDataArray::setString(int32 n, const char *s)
|
||||
{
|
||||
int32 len;
|
||||
char **sp = &((char**)this->data)[n];
|
||||
free(*sp);
|
||||
len = strlen(s)+1;
|
||||
*sp = (char*)malloc(len);
|
||||
rwFree(*sp);
|
||||
len = (int32)strlen(s)+1;
|
||||
*sp = (char*)udMalloc(len);
|
||||
if(*sp)
|
||||
strncpy(*sp, s, len);
|
||||
}
|
||||
@ -47,21 +49,21 @@ destroyUserData(void *object, int32 offset, int32)
|
||||
UserDataExtension *ext = PLUGINOFFSET(UserDataExtension, object, offset);
|
||||
a = ext->arrays;
|
||||
for(i = 0; i < ext->numArrays; i++){
|
||||
free(a->name);
|
||||
rwFree(a->name);
|
||||
switch(a->datatype){
|
||||
case USERDATASTRING:
|
||||
strar = (char**)a->data;
|
||||
for(j = 0; j < a->numElements; j++)
|
||||
free(strar[j]);
|
||||
rwFree(strar[j]);
|
||||
/* fallthrough */
|
||||
case USERDATAINT:
|
||||
case USERDATAFLOAT:
|
||||
free(a->data);
|
||||
rwFree(a->data);
|
||||
break;
|
||||
}
|
||||
a++;
|
||||
}
|
||||
free(ext->arrays);
|
||||
rwFree(ext->arrays);
|
||||
ext->numArrays = 0;
|
||||
ext->arrays = nil;
|
||||
return object;
|
||||
@ -76,30 +78,31 @@ copyUserData(void *dst, void *src, int32 offset, int32)
|
||||
UserDataExtension *srcext = PLUGINOFFSET(UserDataExtension, src, offset);
|
||||
UserDataExtension *dstext = PLUGINOFFSET(UserDataExtension, dst, offset);
|
||||
dstext->numArrays = srcext->numArrays;
|
||||
dstext->arrays = (UserDataArray*)malloc(dstext->numArrays*sizeof(UserDataArray));
|
||||
dstext->arrays = (UserDataArray*)udMalloc(dstext->numArrays*sizeof(UserDataArray));
|
||||
srca = srcext->arrays;
|
||||
dsta = srcext->arrays;
|
||||
for(i = 0; i < srcext->numArrays; i++){
|
||||
int32 len = strlen(srca->name)+1;
|
||||
dsta->name = (char*)malloc(len);
|
||||
int32 len = (int32)strlen(srca->name)+1;
|
||||
dsta->name = (char*)udMalloc(len);
|
||||
strncpy(dsta->name, srca->name, len);
|
||||
dsta->datatype = srca->datatype;
|
||||
dsta->numElements = srca->numElements;
|
||||
switch(srca->datatype){
|
||||
case USERDATAINT:
|
||||
dsta->data = (int32*)malloc(sizeof(int32)*dsta->numElements);
|
||||
dsta->data = (int32*)udMalloc(sizeof(int32)*dsta->numElements);
|
||||
memcpy(dsta->data, srca->data, sizeof(int32)*dsta->numElements);
|
||||
break;
|
||||
case USERDATAFLOAT:
|
||||
dsta->data = (float32*)malloc(sizeof(float32)*dsta->numElements);
|
||||
dsta->data = (float32*)udMalloc(sizeof(float32)*dsta->numElements);
|
||||
memcpy(dsta->data, srca->data, sizeof(float32)*dsta->numElements);
|
||||
break;
|
||||
case USERDATASTRING:
|
||||
dststrar = (char**)malloc(sizeof(char*)*dsta->numElements);
|
||||
dststrar = (char**)udMalloc(sizeof(char*)*dsta->numElements);
|
||||
dsta->data = dststrar;
|
||||
srcstrar = (char**)srca->data;
|
||||
for(j = 0; j < dsta->numElements; j++){
|
||||
len = strlen(srcstrar[j])+1;
|
||||
dststrar[j] = (char*)malloc(len);
|
||||
len = (int32)strlen(srcstrar[j])+1;
|
||||
dststrar[j] = (char*)udMalloc(len);
|
||||
strncpy(dststrar[j], srcstrar[j], len);
|
||||
}
|
||||
break;
|
||||
@ -118,29 +121,29 @@ readUserData(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
UserDataArray *a;
|
||||
UserDataExtension *ext = PLUGINOFFSET(UserDataExtension, object, offset);
|
||||
ext->numArrays = stream->readI32();
|
||||
ext->arrays = (UserDataArray*)malloc(ext->numArrays*sizeof(UserDataArray));
|
||||
ext->arrays = (UserDataArray*)udMalloc(ext->numArrays*sizeof(UserDataArray));
|
||||
a = ext->arrays;
|
||||
for(i = 0; i < ext->numArrays; i++){
|
||||
int32 len = stream->readI32();
|
||||
a->name = (char*)malloc(len);
|
||||
a->name = (char*)udMalloc(len);
|
||||
stream->read(a->name, len);
|
||||
a->datatype = stream->readU32();
|
||||
a->numElements = stream->readI32();
|
||||
switch(a->datatype){
|
||||
case USERDATAINT:
|
||||
a->data = (int32*)malloc(sizeof(int32)*a->numElements);
|
||||
a->data = (int32*)udMalloc(sizeof(int32)*a->numElements);
|
||||
stream->read(a->data, sizeof(int32)*a->numElements);
|
||||
break;
|
||||
case USERDATAFLOAT:
|
||||
a->data = (float32*)malloc(sizeof(float32)*a->numElements);
|
||||
a->data = (float32*)udMalloc(sizeof(float32)*a->numElements);
|
||||
stream->read(a->data, sizeof(float32)*a->numElements);
|
||||
break;
|
||||
case USERDATASTRING:
|
||||
strar = (char**)malloc(sizeof(char*)*a->numElements);
|
||||
strar = (char**)udMalloc(sizeof(char*)*a->numElements);
|
||||
a->data = strar;
|
||||
for(j = 0; j < a->numElements; j++){
|
||||
len = stream->readI32();
|
||||
strar[j] = (char*)malloc(len);
|
||||
strar[j] = (char*)udMalloc(len);
|
||||
stream->read(strar[j], len);
|
||||
}
|
||||
break;
|
||||
@ -161,7 +164,7 @@ writeUserData(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
stream->writeI32(ext->numArrays);
|
||||
a = ext->arrays;
|
||||
for(i = 0; i < ext->numArrays; i++){
|
||||
len = strlen(a->name)+1;
|
||||
len = (int32)strlen(a->name)+1;
|
||||
stream->writeI32(len);
|
||||
stream->write(a->name, len);
|
||||
stream->writeU32(a->datatype);
|
||||
@ -176,7 +179,7 @@ writeUserData(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
case USERDATASTRING:
|
||||
strar = (char**)a->data;
|
||||
for(j = 0; j < a->numElements; j++){
|
||||
len = strlen(strar[j])+1;
|
||||
len = (int32)strlen(strar[j])+1;
|
||||
stream->writeI32(len);
|
||||
stream->write(strar[j], len);
|
||||
}
|
||||
@ -201,7 +204,7 @@ getSizeUserData(void *object, int32 offset, int32)
|
||||
size = 4; // numArrays
|
||||
a = ext->arrays;
|
||||
for(i = 0; i < ext->numArrays; i++){
|
||||
len = strlen(a->name)+1;
|
||||
len = (int32)strlen(a->name)+1;
|
||||
size += 4 + len + 4 + 4; // name len, name, type, numElements
|
||||
switch(a->datatype){
|
||||
case USERDATAINT:
|
||||
@ -213,7 +216,7 @@ getSizeUserData(void *object, int32 offset, int32)
|
||||
case USERDATASTRING:
|
||||
strar = (char**)a->data;
|
||||
for(j = 0; j < a->numElements; j++){
|
||||
len = strlen(strar[j])+1;
|
||||
len = (int32)strlen(strar[j])+1;
|
||||
size += 4 + len; // len and string
|
||||
}
|
||||
break;
|
||||
@ -235,17 +238,17 @@ add(UserDataExtension *ext, const char *name, int32 datatype, int32 numElements)
|
||||
if(ext->arrays[i].datatype == USERDATANA)
|
||||
goto alloc;
|
||||
// have to realloc
|
||||
a = (UserDataArray*)malloc((ext->numArrays+1)*sizeof(UserDataArray));
|
||||
a = (UserDataArray*)udMalloc((ext->numArrays+1)*sizeof(UserDataArray));
|
||||
if(a == nil)
|
||||
return -1;
|
||||
memcpy(a, ext->arrays, ext->numArrays*sizeof(UserDataArray));
|
||||
free(ext->arrays);
|
||||
rwFree(ext->arrays);
|
||||
ext->arrays = a;
|
||||
i = ext->numArrays++;
|
||||
alloc:
|
||||
a = &ext->arrays[i];
|
||||
len = strlen(name)+1;
|
||||
a->name = (char*)malloc(len+1);
|
||||
len = (int32)strlen(name)+1;
|
||||
a->name = (char*)udMalloc(len+1);
|
||||
assert(a->name);
|
||||
strncpy(a->name, name, len);
|
||||
a->datatype = datatype;
|
||||
@ -253,7 +256,7 @@ alloc:
|
||||
typesz = datatype == USERDATAINT ? sizeof(int32) :
|
||||
datatype == USERDATAFLOAT ? sizeof(float32) :
|
||||
datatype == USERDATASTRING ? sizeof(char*) : 0;
|
||||
a->data = malloc(typesz*numElements);
|
||||
a->data = udMalloc(typesz*numElements);
|
||||
assert(a->data);
|
||||
memset(a->data, 0, typesz*numElements);
|
||||
return i;
|
||||
@ -265,14 +268,14 @@ remove(UserDataExtension *ext, int32 n)
|
||||
int32 i;
|
||||
UserDataArray *a = &ext->arrays[n];
|
||||
if(a->name){
|
||||
free(a->name);
|
||||
rwFree(a->name);
|
||||
a->name = nil;
|
||||
}
|
||||
if(a->datatype == USERDATASTRING)
|
||||
for(i = 0; i < a->numElements; i++)
|
||||
free(((char**)a->data)[i]);
|
||||
rwFree(((char**)a->data)[i]);
|
||||
if(a->data){
|
||||
free(a->data);
|
||||
rwFree(a->data);
|
||||
a->data = nil;
|
||||
}
|
||||
a->datatype = USERDATANA;
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
#include "rwengine.h"
|
||||
#include "rwanim.h"
|
||||
#include "rwplugins.h"
|
||||
|
||||
@ -32,7 +33,7 @@ UVAnimDictionary *currentUVAnimDictionary;
|
||||
UVAnimDictionary*
|
||||
UVAnimDictionary::create(void)
|
||||
{
|
||||
UVAnimDictionary *dict = (UVAnimDictionary*)malloc(sizeof(UVAnimDictionary));
|
||||
UVAnimDictionary *dict = (UVAnimDictionary*)rwMalloc(sizeof(UVAnimDictionary), MEMDUR_EVENT | ID_UVANIMATION);
|
||||
if(dict == nil){
|
||||
RWERROR((ERR_ALLOC, sizeof(UVAnimDictionary)));
|
||||
return nil;
|
||||
@ -50,7 +51,7 @@ UVAnimDictionary::destroy(void)
|
||||
cust->destroy(de->anim);
|
||||
delete de;
|
||||
}
|
||||
free(this);
|
||||
rwFree(this);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "rwobjects.h"
|
||||
#include "rwengine.h"
|
||||
|
||||
#define PLUGIN_ID 2
|
||||
#define PLUGIN_ID ID_WORLD
|
||||
|
||||
namespace rw {
|
||||
|
||||
@ -18,7 +18,7 @@ PluginList World::s_plglist = { sizeof(World), sizeof(World), nil, nil };
|
||||
World*
|
||||
World::create(void)
|
||||
{
|
||||
World *world = (World*)malloc(s_plglist.size);
|
||||
World *world = (World*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_WORLD);
|
||||
if(world == nil){
|
||||
RWERROR((ERR_ALLOC, s_plglist.size));
|
||||
return nil;
|
||||
|
Loading…
Reference in New Issue
Block a user