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