redid the plugin system; some engine init stuff

This commit is contained in:
aap 2016-06-25 17:58:52 +02:00
parent e3fa1fcc7f
commit a906d58bcb
21 changed files with 399 additions and 333 deletions

View File

@ -11,7 +11,7 @@ SRC := $(wildcard $(SRCDIR)/*.cpp $(SRCDIR)/d3d/*.cpp $(SRCDIR)/ps2/*.cpp \
OBJ := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$(SRC)) OBJ := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$(SRC))
DEP := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.d,$(SRC)) DEP := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.d,$(SRC))
INC := -I/usr/local/include INC := -I/usr/local/include
CFLAGS=-Wall -Wextra -g $(BUILDDEF) -Wno-parentheses -Wno-invalid-offsetof -fno-diagnostics-show-caret CFLAGS=-Wall -Wextra -g $(BUILDDEF) -Wno-parentheses -Wno-invalid-offsetof -fno-diagnostics-show-caret -Wno-unused-parameter
#-Wconversion #-Wconversion
LIB=librw-$(BUILD).a LIB=librw-$(BUILD).a

3
rw.h
View File

@ -14,6 +14,9 @@
#include "src/d3d/rwd3d.h" #include "src/d3d/rwd3d.h"
#include "src/d3d/rwd3d8.h" #include "src/d3d/rwd3d8.h"
#include "src/d3d/rwd3d9.h" #include "src/d3d/rwd3d9.h"
#ifdef RW_OPENGL
#include <GL/glew.h>
#endif
#include "src/gl/rwwdgl.h" #include "src/gl/rwwdgl.h"
#include "src/gl/rwgl3.h" #include "src/gl/rwgl3.h"
#include "src/gl/rwgl3shader.h" #include "src/gl/rwgl3shader.h"

View File

@ -12,11 +12,6 @@
#include "rwobjects.h" #include "rwobjects.h"
#include "rwplugins.h" #include "rwplugins.h"
#include "rwengine.h" #include "rwengine.h"
#include "ps2/rwps2.h"
#include "d3d/rwxbox.h"
#include "d3d/rwd3d8.h"
#include "d3d/rwd3d9.h"
#include "gl/rwwdgl.h"
namespace rw { namespace rw {
@ -52,34 +47,6 @@ static Matrix3 identMat3 = {
{ 0.0f, 0.0f, 1.0f} { 0.0f, 0.0f, 1.0f}
}; };
void
initialize(void)
{
ObjPipeline *defpipe = new ObjPipeline(PLATFORM_nil);
for(uint i = 0; i < NUM_PLATFORMS; i++){
driver[i].defaultPipeline = defpipe;
driver[i].beginUpdate = null::beginUpdate;
driver[i].endUpdate = null::endUpdate;
driver[i].rasterCreate = null::rasterCreate;
driver[i].rasterLock = null::rasterLock;
driver[i].rasterUnlock = null::rasterUnlock;
driver[i].rasterNumLevels = null::rasterNumLevels;
driver[i].rasterFromImage = null::rasterFromImage;
}
ps2::initializePlatform();
xbox::initializePlatform();
d3d8::initializePlatform();
d3d9::initializePlatform();
wdgl::initializePlatform();
Frame::dirtyList.init();
}
// lazy implementation // lazy implementation
int int
strncmp_ci(const char *s1, const char *s2, int n) strncmp_ci(const char *s1, const char *s2, int n)

View File

@ -15,7 +15,7 @@ namespace rw {
void void
defaultBeginUpdateCB(Camera *cam) defaultBeginUpdateCB(Camera *cam)
{ {
engine.currentCamera = cam; engine->currentCamera = cam;
Frame::syncDirty(); Frame::syncDirty();
DRIVER.beginUpdate(cam); DRIVER.beginUpdate(cam);
} }
@ -34,7 +34,7 @@ cameraSync(ObjectWithFrame*)
void void
worldBeginUpdateCB(Camera *cam) worldBeginUpdateCB(Camera *cam)
{ {
engine.currentWorld = cam->world; engine->currentWorld = cam->world;
cam->originalBeginUpdate(cam); cam->originalBeginUpdate(cam);
} }
@ -54,9 +54,9 @@ worldCameraSync(ObjectWithFrame *obj)
Camera* Camera*
Camera::create(void) Camera::create(void)
{ {
Camera *cam = (Camera*)malloc(PluginBase::s_size); Camera *cam = (Camera*)malloc(s_plglist.size);
if(cam == nil){ if(cam == nil){
RWERROR((ERR_ALLOC, PluginBase::s_size)); RWERROR((ERR_ALLOC, s_plglist.size));
return nil; return nil;
} }
cam->object.object.init(Camera::ID, 0); cam->object.object.init(Camera::ID, 0);
@ -83,7 +83,7 @@ Camera::create(void)
cam->beginUpdateCB = worldBeginUpdateCB; cam->beginUpdateCB = worldBeginUpdateCB;
cam->endUpdateCB = worldEndUpdateCB; cam->endUpdateCB = worldEndUpdateCB;
cam->constructPlugins(); s_plglist.construct(cam);
return cam; return cam;
} }
@ -101,14 +101,14 @@ Camera::clone(void)
cam->farPlane = this->farPlane; cam->farPlane = this->farPlane;
cam->fogPlane = this->fogPlane; cam->fogPlane = this->fogPlane;
cam->projection = this->projection; cam->projection = this->projection;
cam->copyPlugins(this); s_plglist.copy(cam, this);
return cam; return cam;
} }
void void
Camera::destroy(void) Camera::destroy(void)
{ {
this->destructPlugins(); s_plglist.destruct(this);
if(this->clump) if(this->clump)
this->inClump.remove(); this->inClump.remove();
free(this); free(this);
@ -139,7 +139,7 @@ Camera::streamRead(Stream *stream)
cam->farPlane = buf.farPlane; cam->farPlane = buf.farPlane;
cam->fogPlane = buf.fogPlane; cam->fogPlane = buf.fogPlane;
cam->projection = buf.projection; cam->projection = buf.projection;
if(cam->streamReadPlugins(stream)) if(s_plglist.streamRead(stream, cam))
return cam; return cam;
cam->destroy(); cam->destroy();
return nil; return nil;
@ -158,14 +158,15 @@ Camera::streamWrite(Stream *stream)
buf.fogPlane = this->fogPlane; buf.fogPlane = this->fogPlane;
buf.projection = this->projection; buf.projection = this->projection;
stream->write(&buf, sizeof(CameraChunkData)); stream->write(&buf, sizeof(CameraChunkData));
this->streamWritePlugins(stream); s_plglist.streamWrite(stream, this);
return true; return true;
} }
uint32 uint32
Camera::streamGetSize(void) Camera::streamGetSize(void)
{ {
return 12 + sizeof(CameraChunkData) + 12 + this->streamGetPluginSize(); return 12 + sizeof(CameraChunkData) + 12 +
s_plglist.streamGetSize(this);
} }
// TODO: remove // TODO: remove

View File

@ -20,16 +20,16 @@ namespace rw {
Clump* Clump*
Clump::create(void) Clump::create(void)
{ {
Clump *clump = (Clump*)malloc(PluginBase::s_size); Clump *clump = (Clump*)malloc(s_plglist.size);
if(clump == nil){ if(clump == nil){
RWERROR((ERR_ALLOC, PluginBase::s_size)); RWERROR((ERR_ALLOC, s_plglist.size));
return nil; return nil;
} }
clump->object.init(Clump::ID, 0); clump->object.init(Clump::ID, 0);
clump->atomics.init(); clump->atomics.init();
clump->lights.init(); clump->lights.init();
clump->cameras.init(); clump->cameras.init();
clump->constructPlugins(); s_plglist.construct(clump);
return clump; return clump;
} }
@ -46,7 +46,7 @@ Clump::clone(void)
clump->addAtomic(atomic); clump->addAtomic(atomic);
} }
root->purgeClone(); root->purgeClone();
clump->copyPlugins(this); s_plglist.copy(clump, this);
return clump; return clump;
} }
@ -54,7 +54,7 @@ void
Clump::destroy(void) Clump::destroy(void)
{ {
Frame *f; Frame *f;
this->destructPlugins(); s_plglist.destruct(this);
FORLIST(lnk, this->atomics) FORLIST(lnk, this->atomics)
Atomic::fromClump(lnk)->destroy(); Atomic::fromClump(lnk)->destroy();
FORLIST(lnk, this->lights) FORLIST(lnk, this->lights)
@ -192,7 +192,7 @@ Clump::streamRead(Stream *stream)
geometryList[i]->destroy(); geometryList[i]->destroy();
free(geometryList); free(geometryList);
free(frmlst.frames); free(frmlst.frames);
if(clump->streamReadPlugins(stream)) if(s_plglist.streamRead(stream, clump))
return clump; return clump;
failgeo: failgeo:
@ -261,7 +261,7 @@ Clump::streamWrite(Stream *stream)
free(frmlst.frames); free(frmlst.frames);
this->streamWritePlugins(stream); s_plglist.streamWrite(stream, this);
return true; return true;
} }
@ -296,7 +296,7 @@ Clump::streamGetSize(void)
FORLIST(lnk, this->cameras) FORLIST(lnk, this->cameras)
size += 16 + 12 + Camera::fromClump(lnk)->streamGetSize(); size += 16 + 12 + Camera::fromClump(lnk)->streamGetSize();
size += 12 + this->streamGetPluginSize(); size += 12 + s_plglist.streamGetSize(this);
return size; return size;
} }
@ -331,9 +331,9 @@ worldAtomicSync(ObjectWithFrame *obj)
Atomic* Atomic*
Atomic::create(void) Atomic::create(void)
{ {
Atomic *atomic = (Atomic*)malloc(PluginBase::s_size); Atomic *atomic = (Atomic*)malloc(s_plglist.size);
if(atomic == nil){ if(atomic == nil){
RWERROR((ERR_ALLOC, PluginBase::s_size)); RWERROR((ERR_ALLOC, s_plglist.size));
return nil; return nil;
} }
atomic->object.object.init(Atomic::ID, 0); atomic->object.object.init(Atomic::ID, 0);
@ -352,7 +352,7 @@ Atomic::create(void)
atomic->originalSync = atomic->object.syncCB; atomic->originalSync = atomic->object.syncCB;
atomic->object.syncCB = worldAtomicSync; atomic->object.syncCB = worldAtomicSync;
atomic->constructPlugins(); s_plglist.construct(atomic);
return atomic; return atomic;
} }
@ -367,14 +367,14 @@ Atomic::clone()
if(this->geometry) if(this->geometry)
atomic->setGeometry(this->geometry); atomic->setGeometry(this->geometry);
atomic->pipeline = this->pipeline; atomic->pipeline = this->pipeline;
atomic->copyPlugins(this); s_plglist.copy(atomic, this);
return atomic; return atomic;
} }
void void
Atomic::destroy(void) Atomic::destroy(void)
{ {
this->destructPlugins(); s_plglist.destruct(this);
if(this->geometry) if(this->geometry)
this->geometry->destroy(); this->geometry->destroy();
if(this->clump) if(this->clump)
@ -452,10 +452,10 @@ Atomic::streamReadClump(Stream *stream,
atomic->object.object.flags = buf[2]; atomic->object.object.flags = buf[2];
atomicRights[0] = 0; atomicRights[0] = 0;
if(!atomic->streamReadPlugins(stream)) if(!s_plglist.streamRead(stream, atomic))
goto fail; goto fail;
if(atomicRights[0]) if(atomicRights[0])
atomic->assertRights(atomicRights[0], atomicRights[1]); s_plglist.assertRights(atomic, atomicRights[0], atomicRights[1]);
return atomic; return atomic;
fail: fail:
@ -491,14 +491,14 @@ Atomic::streamWriteClump(Stream *stream, FrameList_ *frmlst)
stream->write(buf, sizeof(buf)); stream->write(buf, sizeof(buf));
} }
this->streamWritePlugins(stream); s_plglist.streamWrite(stream, this);
return true; return true;
} }
uint32 uint32
Atomic::streamGetSize(void) Atomic::streamGetSize(void)
{ {
uint32 size = 12 + 12 + 12 + this->streamGetPluginSize(); uint32 size = 12 + 12 + 12 + s_plglist.streamGetSize(this);
if(rw::version < 0x30400) if(rw::version < 0x30400)
size += 12 + this->geometry->streamGetSize(); size += 12 + this->geometry->streamGetSize();
else else

View File

@ -510,7 +510,7 @@ readNativeTexture(Stream *stream)
pallength = format & Raster::PAL4 ? 32 : 256; pallength = format & Raster::PAL4 ? 32 : 256;
if(!d3d::isP8supported){ if(!d3d::isP8supported){
tex->raster = readAsImage(stream, width, height, depth, format|type, numLevels); tex->raster = readAsImage(stream, width, height, depth, format|type, numLevels);
tex->streamReadPlugins(stream); Texture::s_plglist.streamRead(stream, tex);
return tex; return tex;
} }
} }
@ -544,7 +544,7 @@ readNativeTexture(Stream *stream)
}else }else
stream->seek(size); stream->seek(size);
} }
tex->streamReadPlugins(stream); Texture::s_plglist.streamRead(stream, tex);
return tex; return tex;
} }
@ -552,7 +552,7 @@ void
writeNativeTexture(Texture *tex, Stream *stream) writeNativeTexture(Texture *tex, Stream *stream)
{ {
int32 chunksize = getSizeNativeTexture(tex); int32 chunksize = getSizeNativeTexture(tex);
int32 plgsize = tex->streamGetPluginSize(); int32 plgsize = Texture::s_plglist.streamGetSize(tex);
writeChunkHeader(stream, ID_TEXTURENATIVE, chunksize); writeChunkHeader(stream, ID_TEXTURENATIVE, chunksize);
writeChunkHeader(stream, ID_STRUCT, chunksize-24-plgsize); writeChunkHeader(stream, ID_STRUCT, chunksize-24-plgsize);
stream->writeU32(PLATFORM_D3D8); stream->writeU32(PLATFORM_D3D8);
@ -608,7 +608,7 @@ writeNativeTexture(Texture *tex, Stream *stream)
stream->write(data, size); stream->write(data, size);
raster->unlock(i); raster->unlock(i);
} }
tex->streamWritePlugins(stream); Texture::s_plglist.streamWrite(stream, tex);
} }
uint32 uint32
@ -622,7 +622,7 @@ getSizeNativeTexture(Texture *tex)
size += 4*256; size += 4*256;
for(int32 i = 0; i < levels; i++) for(int32 i = 0; i < levels; i++)
size += 4 + getLevelSize(tex->raster, i); size += 4 + getLevelSize(tex->raster, i);
size += 12 + tex->streamGetPluginSize(); size += 12 + Texture::s_plglist.streamGetSize(tex);
return size; return size;
} }

View File

@ -653,7 +653,7 @@ readNativeTexture(Stream *stream)
}else }else
stream->seek(size); stream->seek(size);
} }
tex->streamReadPlugins(stream); Texture::s_plglist.streamRead(stream, tex);
return tex; return tex;
} }
@ -661,7 +661,7 @@ void
writeNativeTexture(Texture *tex, Stream *stream) writeNativeTexture(Texture *tex, Stream *stream)
{ {
int32 chunksize = getSizeNativeTexture(tex); int32 chunksize = getSizeNativeTexture(tex);
int32 plgsize = tex->streamGetPluginSize(); int32 plgsize = Texture::s_plglist.streamGetSize(tex);
writeChunkHeader(stream, ID_TEXTURENATIVE, chunksize); writeChunkHeader(stream, ID_TEXTURENATIVE, chunksize);
writeChunkHeader(stream, ID_STRUCT, chunksize-24-plgsize); writeChunkHeader(stream, ID_STRUCT, chunksize-24-plgsize);
stream->writeU32(PLATFORM_D3D9); stream->writeU32(PLATFORM_D3D9);
@ -705,7 +705,7 @@ writeNativeTexture(Texture *tex, Stream *stream)
stream->write(data, size); stream->write(data, size);
raster->unlock(i); raster->unlock(i);
} }
tex->streamWritePlugins(stream); Texture::s_plglist.streamWrite(stream, tex);
} }
uint32 uint32
@ -719,7 +719,7 @@ getSizeNativeTexture(Texture *tex)
size += 4*256; size += 4*256;
for(int32 i = 0; i < levels; i++) for(int32 i = 0; i < levels; i++)
size += 4 + getLevelSize(tex->raster, i); size += 4 + getLevelSize(tex->raster, i);
size += 12 + tex->streamGetPluginSize(); size += 12 + Texture::s_plglist.streamGetSize(tex);
return size; return size;
} }

View File

@ -979,7 +979,7 @@ readNativeTexture(Stream *stream)
stream->read(data, totalSize); stream->read(data, totalSize);
raster->unlock(0); raster->unlock(0);
tex->streamReadPlugins(stream); Texture::s_plglist.streamRead(stream, tex);
return tex; return tex;
} }
@ -987,7 +987,7 @@ void
writeNativeTexture(Texture *tex, Stream *stream) writeNativeTexture(Texture *tex, Stream *stream)
{ {
int32 chunksize = getSizeNativeTexture(tex); int32 chunksize = getSizeNativeTexture(tex);
int32 plgsize = tex->streamGetPluginSize(); int32 plgsize = Texture::s_plglist.streamGetSize(tex);
writeChunkHeader(stream, ID_TEXTURENATIVE, chunksize); writeChunkHeader(stream, ID_TEXTURENATIVE, chunksize);
writeChunkHeader(stream, ID_STRUCT, chunksize-24-plgsize); writeChunkHeader(stream, ID_STRUCT, chunksize-24-plgsize);
stream->writeU32(PLATFORM_XBOX); stream->writeU32(PLATFORM_XBOX);
@ -1027,7 +1027,7 @@ writeNativeTexture(Texture *tex, Stream *stream)
stream->write(data, totalSize); stream->write(data, totalSize);
raster->unlock(0); raster->unlock(0);
tex->streamWritePlugins(stream); Texture::s_plglist.streamWrite(stream, tex);
} }
uint32 uint32
@ -1042,7 +1042,7 @@ getSizeNativeTexture(Texture *tex)
size += 4*32; size += 4*32;
else if(tex->raster->format & Raster::PAL8) else if(tex->raster->format & Raster::PAL8)
size += 4*256; size += 4*256;
size += 12 + tex->streamGetPluginSize(); size += 12 + Texture::s_plglist.streamGetSize(tex);
return size; return size;
} }

View File

@ -7,13 +7,59 @@
#include "rwpipeline.h" #include "rwpipeline.h"
#include "rwobjects.h" #include "rwobjects.h"
#include "rwengine.h" #include "rwengine.h"
#include "ps2/rwps2.h"
#include "d3d/rwxbox.h"
#include "d3d/rwd3d.h"
#include "d3d/rwd3d8.h"
#include "d3d/rwd3d9.h"
#include "gl/rwgl3.h"
#include "gl/rwwdgl.h"
namespace rw { namespace rw {
Engine engine; Engine *engine;
Driver driver[NUM_PLATFORMS]; Driver driver[NUM_PLATFORMS];
PluginList Engine::s_plglist = {sizeof(Engine), sizeof(Engine), nil, nil};
void
Engine::init(void)
{
ObjPipeline *defpipe = new ObjPipeline(PLATFORM_nil);
for(uint i = 0; i < NUM_PLATFORMS; i++){
driver[i].defaultPipeline = defpipe;
driver[i].beginUpdate = null::beginUpdate;
driver[i].endUpdate = null::endUpdate;
driver[i].rasterCreate = null::rasterCreate;
driver[i].rasterLock = null::rasterLock;
driver[i].rasterUnlock = null::rasterUnlock;
driver[i].rasterNumLevels = null::rasterNumLevels;
driver[i].rasterFromImage = null::rasterFromImage;
}
Frame::dirtyList.init();
rw::gl3::registerNativeRaster();
rw::ps2::registerNativeRaster();
rw::xbox::registerNativeRaster();
rw::d3d::registerNativeRaster();
}
void
Engine::open(void)
{
rw::engine = (Engine*)malloc(s_plglist.size);
s_plglist.construct(rw::engine);
ps2::initializePlatform();
xbox::initializePlatform();
d3d8::initializePlatform();
d3d9::initializePlatform();
gl3::initializePlatform();
wdgl::initializePlatform();
}
namespace null { namespace null {
void beginUpdate(Camera*) { } void beginUpdate(Camera*) { }

View File

@ -16,9 +16,9 @@ LinkList Frame::dirtyList;
Frame* Frame*
Frame::create(void) Frame::create(void)
{ {
Frame *f = (Frame*)malloc(PluginBase::s_size); Frame *f = (Frame*)malloc(s_plglist.size);
if(f == nil){ if(f == nil){
RWERROR((ERR_ALLOC, PluginBase::s_size)); RWERROR((ERR_ALLOC, s_plglist.size));
return nil; return nil;
} }
f->object.init(Frame::ID, 0); f->object.init(Frame::ID, 0);
@ -28,7 +28,7 @@ Frame::create(void)
f->root = f; f->root = f;
f->matrix.setIdentity(); f->matrix.setIdentity();
f->ltm.setIdentity(); f->ltm.setIdentity();
f->constructPlugins(); s_plglist.construct(f);
return f; return f;
} }
@ -43,7 +43,7 @@ Frame::cloneHierarchy(void)
void void
Frame::destroy(void) Frame::destroy(void)
{ {
this->destructPlugins(); s_plglist.destruct(this);
Frame *parent = this->getParent(); Frame *parent = this->getParent();
Frame *child; Frame *child;
if(parent){ if(parent){
@ -73,7 +73,7 @@ Frame::destroyHierarchy(void)
next = child->next; next = child->next;
child->destroyHierarchy(); child->destroyHierarchy();
} }
this->destructPlugins(); s_plglist.destruct(this);
free(this); free(this);
} }
@ -295,7 +295,7 @@ Frame::cloneAndLink(Frame *clonedroot)
frame->child = clonedchild; frame->child = clonedchild;
clonedchild->object.parent = frame; clonedchild->object.parent = frame;
} }
frame->copyPlugins(this); s_plglist.copy(frame, this);
return frame; return frame;
} }
@ -352,7 +352,7 @@ FrameList_::streamRead(Stream *stream)
this->frames[buf.parent]->addChild(f); this->frames[buf.parent]->addChild(f);
} }
for(int32 i = 0; i < this->numFrames; i++) for(int32 i = 0; i < this->numFrames; i++)
this->frames[i]->streamReadPlugins(stream); Frame::s_plglist.streamRead(stream, this->frames[i]);
return this; return this;
} }
@ -365,7 +365,7 @@ FrameList_::streamWrite(Stream *stream)
structsize = 4 + this->numFrames*sizeof(FrameStreamData); structsize = 4 + this->numFrames*sizeof(FrameStreamData);
size += 12 + structsize; size += 12 + structsize;
for(int32 i = 0; i < this->numFrames; i++) for(int32 i = 0; i < this->numFrames; i++)
size += 12 + this->frames[i]->streamGetPluginSize(); size += 12 + Frame::s_plglist.streamGetSize(this->frames[i]);
writeChunkHeader(stream, ID_FRAMELIST, size); writeChunkHeader(stream, ID_FRAMELIST, size);
writeChunkHeader(stream, ID_STRUCT, structsize); writeChunkHeader(stream, ID_STRUCT, structsize);
@ -382,13 +382,13 @@ FrameList_::streamWrite(Stream *stream)
stream->write(&buf, sizeof(buf)); stream->write(&buf, sizeof(buf));
} }
for(int32 i = 0; i < this->numFrames; i++) for(int32 i = 0; i < this->numFrames; i++)
this->frames[i]->streamWritePlugins(stream); Frame::s_plglist.streamWrite(stream, this->frames[i]);
} }
static Frame* static Frame*
sizeCB(Frame *f, void *size) sizeCB(Frame *f, void *size)
{ {
*(int32*)size += f->streamGetPluginSize(); *(int32*)size += Frame::s_plglist.streamGetSize(f);
f->forAllChildren(sizeCB, size); f->forAllChildren(sizeCB, size);
return f; return f;
} }

View File

@ -17,9 +17,9 @@ namespace rw {
Geometry* Geometry*
Geometry::create(int32 numVerts, int32 numTris, uint32 flags) Geometry::create(int32 numVerts, int32 numTris, uint32 flags)
{ {
Geometry *geo = (Geometry*)malloc(PluginBase::s_size); Geometry *geo = (Geometry*)malloc(s_plglist.size);
if(geo == nil){ if(geo == nil){
RWERROR((ERR_ALLOC, PluginBase::s_size)); RWERROR((ERR_ALLOC, s_plglist.size));
return nil; return nil;
} }
geo->object.init(Geometry::ID, 0); geo->object.init(Geometry::ID, 0);
@ -62,7 +62,7 @@ Geometry::create(int32 numVerts, int32 numTris, uint32 flags)
geo->instData = nil; geo->instData = nil;
geo->refCount = 1; geo->refCount = 1;
geo->constructPlugins(); s_plglist.construct(geo);
return geo; return geo;
} }
@ -71,7 +71,7 @@ Geometry::destroy(void)
{ {
this->refCount--; this->refCount--;
if(this->refCount <= 0){ if(this->refCount <= 0){
this->destructPlugins(); s_plglist.destruct(this);
delete[] this->colors; delete[] this->colors;
for(int32 i = 0; i < this->numTexCoordSets; i++) for(int32 i = 0; i < this->numTexCoordSets; i++)
delete[] this->texCoords[i]; delete[] this->texCoords[i];
@ -168,7 +168,7 @@ Geometry::streamRead(Stream *stream)
goto fail; goto fail;
geo->materialList[i] = m; geo->materialList[i] = m;
} }
if(geo->streamReadPlugins(stream)) if(s_plglist.streamRead(stream, geo))
return geo; return geo;
fail: fail:
@ -266,7 +266,7 @@ Geometry::streamWrite(Stream *stream)
for(int32 i = 0; i < this->numMaterials; i++) for(int32 i = 0; i < this->numMaterials; i++)
this->materialList[i]->streamWrite(stream); this->materialList[i]->streamWrite(stream);
this->streamWritePlugins(stream); s_plglist.streamWrite(stream, this);
return true; return true;
} }
@ -278,7 +278,7 @@ Geometry::streamGetSize(void)
size += 12 + 12 + 4; size += 12 + 12 + 4;
for(int32 i = 0; i < this->numMaterials; i++) for(int32 i = 0; i < this->numMaterials; i++)
size += 4 + 12 + this->materialList[i]->streamGetSize(); size += 4 + 12 + this->materialList[i]->streamGetSize();
size += 12 + this->streamGetPluginSize(); size += 12 + s_plglist.streamGetSize(this);
return size; return size;
} }
@ -538,9 +538,9 @@ Geometry::removeUnusedMaterials(void)
Material* Material*
Material::create(void) Material::create(void)
{ {
Material *mat = (Material*)malloc(PluginBase::s_size); Material *mat = (Material*)malloc(s_plglist.size);
if(mat == nil){ if(mat == nil){
RWERROR((ERR_ALLOC, PluginBase::s_size)); RWERROR((ERR_ALLOC, s_plglist.size));
return nil; return nil;
} }
mat->texture = nil; mat->texture = nil;
@ -550,7 +550,7 @@ Material::create(void)
mat->surfaceProps.diffuse = 1.0f; mat->surfaceProps.diffuse = 1.0f;
mat->pipeline = nil; mat->pipeline = nil;
mat->refCount = 1; mat->refCount = 1;
mat->constructPlugins(); s_plglist.construct(mat);
return mat; return mat;
} }
@ -559,7 +559,7 @@ Material::clone(void)
{ {
Material *mat = Material::create(); Material *mat = Material::create();
if(mat == nil){ if(mat == nil){
RWERROR((ERR_ALLOC, PluginBase::s_size)); RWERROR((ERR_ALLOC, s_plglist.size));
return nil; return nil;
} }
mat->color = this->color; mat->color = this->color;
@ -567,7 +567,7 @@ Material::clone(void)
if(this->texture) if(this->texture)
mat->setTexture(this->texture); mat->setTexture(this->texture);
mat->pipeline = this->pipeline; mat->pipeline = this->pipeline;
mat->copyPlugins(this); s_plglist.copy(mat, this);
return mat; return mat;
} }
@ -576,7 +576,7 @@ Material::destroy(void)
{ {
this->refCount--; this->refCount--;
if(this->refCount <= 0){ if(this->refCount <= 0){
this->destructPlugins(); s_plglist.destruct(this);
if(this->texture) if(this->texture)
this->texture->destroy(); this->texture->destroy();
free(this); free(this);
@ -641,10 +641,10 @@ Material::streamRead(Stream *stream)
} }
materialRights[0] = 0; materialRights[0] = 0;
if(!mat->streamReadPlugins(stream)) if(!s_plglist.streamRead(stream, mat))
goto fail; goto fail;
if(materialRights[0]) if(materialRights[0])
mat->assertRights(materialRights[0], materialRights[1]); s_plglist.assertRights(mat, materialRights[0], materialRights[1]);
return mat; return mat;
fail: fail:
@ -678,7 +678,7 @@ Material::streamWrite(Stream *stream)
if(this->texture) if(this->texture)
this->texture->streamWrite(stream); this->texture->streamWrite(stream);
this->streamWritePlugins(stream); s_plglist.streamWrite(stream, this);
return true; return true;
} }
@ -691,7 +691,7 @@ Material::streamGetSize(void)
size += 12; size += 12;
if(this->texture) if(this->texture)
size += 12 + this->texture->streamGetSize(); size += 12 + this->texture->streamGetSize();
size += 12 + this->streamGetPluginSize(); size += 12 + s_plglist.streamGetSize(this);
return size; return size;
} }

View File

@ -112,14 +112,9 @@ copyNativeRaster(void *dst, void *, int32 offset, int32)
return dst; return dst;
} }
void static void*
registerNativeRaster(void) nativeOpen(void*, int32 offset, int32)
{ {
nativeRasterOffset = Raster::registerPlugin(sizeof(Gl3Raster),
0x12340000 | PLATFORM_GL3,
createNativeRaster,
destroyNativeRaster,
copyNativeRaster);
driver[PLATFORM_GL3].rasterNativeOffset = nativeRasterOffset; driver[PLATFORM_GL3].rasterNativeOffset = nativeRasterOffset;
driver[PLATFORM_GL3].rasterCreate = rasterCreate; driver[PLATFORM_GL3].rasterCreate = rasterCreate;
driver[PLATFORM_GL3].rasterLock = rasterLock; driver[PLATFORM_GL3].rasterLock = rasterLock;
@ -128,5 +123,21 @@ registerNativeRaster(void)
driver[PLATFORM_GL3].rasterFromImage = rasterFromImage; driver[PLATFORM_GL3].rasterFromImage = rasterFromImage;
} }
static void*
nativeClose(void*, int32 offset, int32)
{
printf("native close\n");
}
void registerNativeRaster(void)
{
Engine::registerPlugin(0, 0x1234, nativeOpen, nativeClose);
nativeRasterOffset = Raster::registerPlugin(sizeof(Gl3Raster),
0x12340000 | PLATFORM_GL3,
createNativeRaster,
destroyNativeRaster,
copyNativeRaster);
}
} }
} }

View File

@ -292,7 +292,7 @@ lightingCB(void)
RGBAf ambLight = (RGBAf){0.0, 0.0, 0.0, 1.0}; RGBAf ambLight = (RGBAf){0.0, 0.0, 0.0, 1.0};
int n = 0; int n = 0;
world = (World*)engine.currentWorld; world = (World*)engine->currentWorld;
// only unpositioned lights right now // only unpositioned lights right now
FORLIST(lnk, world->directionalLights){ FORLIST(lnk, world->directionalLights){
Light *l = Light::fromWorld(lnk); Light *l = Light::fromWorld(lnk);

View File

@ -33,14 +33,14 @@ TexDictionary *currentTexDictionary;
TexDictionary* TexDictionary*
TexDictionary::create(void) TexDictionary::create(void)
{ {
TexDictionary *dict = (TexDictionary*)malloc(PluginBase::s_size); TexDictionary *dict = (TexDictionary*)malloc(s_plglist.size);
if(dict == nil){ if(dict == nil){
RWERROR((ERR_ALLOC, PluginBase::s_size)); RWERROR((ERR_ALLOC, s_plglist.size));
return nil; return nil;
} }
dict->object.init(TexDictionary::ID, 0); dict->object.init(TexDictionary::ID, 0);
dict->textures.init(); dict->textures.init();
dict->constructPlugins(); s_plglist.construct(dict);
return dict; return dict;
} }
@ -49,7 +49,7 @@ TexDictionary::destroy(void)
{ {
FORLIST(lnk, this->textures) FORLIST(lnk, this->textures)
Texture::fromDict(lnk)->destroy(); Texture::fromDict(lnk)->destroy();
this->destructPlugins(); s_plglist.destruct(this);
free(this); free(this);
} }
@ -88,7 +88,7 @@ TexDictionary::streamRead(Stream *stream)
goto fail; goto fail;
txd->add(tex); txd->add(tex);
} }
if(txd->streamReadPlugins(stream)) if(s_plglist.streamRead(stream, txd))
return txd; return txd;
fail: fail:
txd->destroy(); txd->destroy();
@ -105,7 +105,7 @@ TexDictionary::streamWrite(Stream *stream)
stream->writeI16(0); stream->writeI16(0);
FORLIST(lnk, this->textures) FORLIST(lnk, this->textures)
Texture::fromDict(lnk)->streamWriteNative(stream); Texture::fromDict(lnk)->streamWriteNative(stream);
this->streamWritePlugins(stream); s_plglist.streamWrite(stream, this);
} }
uint32 uint32
@ -114,7 +114,7 @@ TexDictionary::streamGetSize(void)
uint32 size = 12 + 4; uint32 size = 12 + 4;
FORLIST(lnk, this->textures) FORLIST(lnk, this->textures)
size += 12 + Texture::fromDict(lnk)->streamGetSizeNative(); size += 12 + Texture::fromDict(lnk)->streamGetSizeNative();
size += 12 + this->streamGetPluginSize(); size += 12 + s_plglist.streamGetSize(this);
return size; return size;
} }
@ -133,9 +133,9 @@ Texture *(*Texture::readCB)(const char *name, const char *mask) = defaultReadCB;
Texture* Texture*
Texture::create(Raster *raster) Texture::create(Raster *raster)
{ {
Texture *tex = (Texture*)malloc(PluginBase::s_size); Texture *tex = (Texture*)malloc(s_plglist.size);
if(tex == nil){ if(tex == nil){
RWERROR((ERR_ALLOC, PluginBase::s_size)); RWERROR((ERR_ALLOC, s_plglist.size));
return nil; return nil;
} }
tex->dict = nil; tex->dict = nil;
@ -145,7 +145,7 @@ Texture::create(Raster *raster)
tex->filterAddressing = (WRAP << 12) | (WRAP << 8) | NEAREST; tex->filterAddressing = (WRAP << 12) | (WRAP << 8) | NEAREST;
tex->raster = raster; tex->raster = raster;
tex->refCount = 1; tex->refCount = 1;
tex->constructPlugins(); s_plglist.construct(tex);
return tex; return tex;
} }
@ -154,7 +154,7 @@ Texture::destroy(void)
{ {
this->refCount--; this->refCount--;
if(this->refCount <= 0){ if(this->refCount <= 0){
this->destructPlugins(); s_plglist.destruct(this);
if(this->dict) if(this->dict)
this->inDict.remove(); this->inDict.remove();
if(this->raster) if(this->raster)
@ -260,7 +260,7 @@ Texture::streamRead(Stream *stream)
tex->filterAddressing = filterAddressing; tex->filterAddressing = filterAddressing;
tex->refCount++; // TODO: RW doesn't do this, why? tex->refCount++; // TODO: RW doesn't do this, why?
if(tex->streamReadPlugins(stream)) if(s_plglist.streamRead(stream, tex))
return tex; return tex;
tex->destroy(); tex->destroy();
return nil; return nil;
@ -287,7 +287,7 @@ Texture::streamWrite(Stream *stream)
writeChunkHeader(stream, ID_STRING, size); writeChunkHeader(stream, ID_STRING, size);
stream->write(buf, size); stream->write(buf, size);
this->streamWritePlugins(stream); s_plglist.streamWrite(stream, this);
return true; return true;
} }
@ -299,7 +299,7 @@ Texture::streamGetSize(void)
size += 12 + 12; size += 12 + 12;
size += strlen(this->name)+4 & ~3; size += strlen(this->name)+4 & ~3;
size += strlen(this->mask)+4 & ~3; size += strlen(this->mask)+4 & ~3;
size += 12 + this->streamGetPluginSize(); size += 12 + s_plglist.streamGetSize(this);
return size; return size;
} }
@ -679,7 +679,7 @@ writeTGA(Image *image, const char *filename)
Raster* Raster*
Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platform) Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platform)
{ {
Raster *raster = (Raster*)malloc(PluginBase::s_size); Raster *raster = (Raster*)malloc(s_plglist.size);
assert(raster != nil); assert(raster != nil);
raster->platform = platform ? platform : rw::platform; raster->platform = platform ? platform : rw::platform;
raster->type = format & 0x7; raster->type = format & 0x7;
@ -689,7 +689,7 @@ Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platf
raster->height = height; raster->height = height;
raster->depth = depth; raster->depth = depth;
raster->texels = raster->palette = nil; raster->texels = raster->palette = nil;
raster->constructPlugins(); s_plglist.construct(raster);
driver[raster->platform].rasterCreate(raster); driver[raster->platform].rasterCreate(raster);
return raster; return raster;
@ -698,7 +698,7 @@ Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platf
void void
Raster::destroy(void) Raster::destroy(void)
{ {
this->destructPlugins(); s_plglist.destruct(this);
delete[] this->texels; delete[] this->texels;
delete[] this->palette; delete[] this->palette;
free(this); free(this);

View File

@ -26,9 +26,9 @@ worldLightSync(ObjectWithFrame *obj)
Light* Light*
Light::create(int32 type) Light::create(int32 type)
{ {
Light *light = (Light*)malloc(PluginBase::s_size); Light *light = (Light*)malloc(s_plglist.size);
if(light == nil){ if(light == nil){
RWERROR((ERR_ALLOC, PluginBase::s_size)); RWERROR((ERR_ALLOC, s_plglist.size));
return nil; return nil;
} }
light->object.object.init(Light::ID, type); light->object.object.init(Light::ID, type);
@ -52,14 +52,14 @@ Light::create(int32 type)
light->originalSync = light->object.syncCB; light->originalSync = light->object.syncCB;
light->object.syncCB = worldLightSync; light->object.syncCB = worldLightSync;
light->constructPlugins(); s_plglist.construct(light);
return light; return light;
} }
void void
Light::destroy(void) Light::destroy(void)
{ {
this->destructPlugins(); s_plglist.destruct(this);
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
@ -119,7 +119,7 @@ Light::streamRead(Stream *stream)
// tan -> -cos // tan -> -cos
light->minusCosAngle = -1.0f/sqrt(a*a+1.0f); light->minusCosAngle = -1.0f/sqrt(a*a+1.0f);
light->object.object.flags = (uint8)buf.flags; light->object.object.flags = (uint8)buf.flags;
if(light->streamReadPlugins(stream)) if(s_plglist.streamRead(stream, light))
return light; return light;
light->destroy(); light->destroy();
return nil; return nil;
@ -143,14 +143,14 @@ Light::streamWrite(Stream *stream)
buf.type = this->object.object.subType; buf.type = this->object.object.subType;
stream->write(&buf, sizeof(LightChunkData)); stream->write(&buf, sizeof(LightChunkData));
this->streamWritePlugins(stream); s_plglist.streamWrite(stream, this);
return true; return true;
} }
uint32 uint32
Light::streamGetSize(void) Light::streamGetSize(void)
{ {
return 12 + sizeof(LightChunkData) + 12 + this->streamGetPluginSize(); return 12 + sizeof(LightChunkData) + 12 + s_plglist.streamGetSize(this);
} }
} }

167
src/plg.cpp Normal file
View File

@ -0,0 +1,167 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <cmath>
#include <cctype>
#include "rwbase.h"
#include "rwerror.h"
#include "rwplg.h"
namespace rw {
static void *defCtor(void *object, int32, int32) { return object; }
static void *defDtor(void *object, int32, int32) { return object; }
static void *defCopy(void *dst, void*, int32, int32) { return dst; }
void
PluginList::construct(void *object)
{
for(Plugin *p = this->first; p; p = p->next)
p->constructor(object, p->offset, p->size);
}
void
PluginList::destruct(void *object)
{
for(Plugin *p = this->first; p; p = p->next)
p->destructor(object, p->offset, p->size);
}
void
PluginList::copy(void *dst, void *src)
{
for(Plugin *p = this->first; p; p = p->next)
p->copy(dst, src, p->offset, p->size);
}
bool
PluginList::streamRead(Stream *stream, void *object)
{
int32 length;
ChunkHeaderInfo header;
if(!findChunk(stream, ID_EXTENSION, (uint32*)&length, nil))
return false;
while(length > 0){
if(!readChunkHeaderInfo(stream, &header))
return false;
length -= 12;
for(Plugin *p = this->first; p; p = p->next)
if(p->id == header.type && p->read){
p->read(stream, header.length,
object, p->offset, p->size);
goto cont;
}
stream->seek(header.length);
cont:
length -= header.length;
}
return true;
}
void
PluginList::streamWrite(Stream *stream, void *object)
{
int size = this->streamGetSize(object);
writeChunkHeader(stream, ID_EXTENSION, size);
for(Plugin *p = this->first; p; p = p->next){
if(p->getSize == nil ||
(size = p->getSize(object, p->offset, p->size)) <= 0)
continue;
writeChunkHeader(stream, p->id, size);
p->write(stream, size, object, p->offset, p->size);
}
}
int
PluginList::streamGetSize(void *object)
{
int32 size = 0;
int32 plgsize;
for(Plugin *p = this->first; p; p = p->next)
if(p->getSize &&
(plgsize = p->getSize(object, p->offset, p->size)) > 0)
size += 12 + plgsize;
return size;
}
void
PluginList::assertRights(void *object, uint32 pluginID, uint32 data)
{
for(Plugin *p = this->first; p; p = p->next)
if(p->id == pluginID){
if(p->rightsCallback)
p->rightsCallback(object,
p->offset, p->size, data);
return;
}
}
int32
PluginList::registerPlugin(int32 size, uint32 id,
Constructor ctor, Destructor dtor, CopyConstructor copy)
{
Plugin *p = (Plugin*)malloc(sizeof(Plugin));
p->offset = this->size;
this->size += size;
p->size = size;
p->id = id;
p->constructor = ctor ? ctor : defCtor;
p->destructor = dtor ? dtor : defDtor;
p->copy = copy ? copy : defCopy;
p->read = nil;
p->write = nil;
p->getSize = nil;
p->rightsCallback = nil;
p->next = nil;
p->prev = nil;
if(this->first == nil){
this->first = p;
this->last = p;
}else{
this->last->next = p;
p->prev = this->last;
this->last = p;
}
return p->offset;
}
int32
PluginList::registerStream(uint32 id,
StreamRead read, StreamWrite write, StreamGetSize getSize)
{
for(Plugin *p = this->first; p; p = p->next)
if(p->id == id){
p->read = read;
p->write = write;
p->getSize = getSize;
return p->offset;
}
return -1;
}
int32
PluginList::setStreamRightsCallback(uint32 id, RightsCallback cb)
{
for(Plugin *p = this->first; p; p = p->next)
if(p->id == id){
p->rightsCallback = cb;
return p->offset;
}
return -1;
}
int32
PluginList::getPluginOffset(uint32 id)
{
for(Plugin *p = this->first; p; p = p->next)
if(p->id == id)
return p->offset;
return -1;
}
}

View File

@ -476,6 +476,21 @@ getSizeMipmap(void*, int32, int32)
return rw::platform == PLATFORM_PS2 ? 4 : 0; return rw::platform == PLATFORM_PS2 ? 4 : 0;
} }
static void*
nativeOpen(void*, int32 offset, int32)
{
driver[PLATFORM_PS2].rasterNativeOffset = nativeRasterOffset;
driver[PLATFORM_PS2].rasterCreate = rasterCreate;
driver[PLATFORM_PS2].rasterLock = rasterLock;
driver[PLATFORM_PS2].rasterUnlock = rasterUnlock;
driver[PLATFORM_PS2].rasterNumLevels = rasterNumLevels;
}
static void*
nativeClose(void*, int32 offset, int32)
{
}
void void
registerNativeRaster(void) registerNativeRaster(void)
{ {
@ -484,11 +499,7 @@ registerNativeRaster(void)
createNativeRaster, createNativeRaster,
destroyNativeRaster, destroyNativeRaster,
copyNativeRaster); copyNativeRaster);
driver[PLATFORM_PS2].rasterNativeOffset = nativeRasterOffset; Engine::registerPlugin(0, 0x1234, nativeOpen, nativeClose);
driver[PLATFORM_PS2].rasterCreate = rasterCreate;
driver[PLATFORM_PS2].rasterLock = rasterLock;
driver[PLATFORM_PS2].rasterUnlock = rasterUnlock;
driver[PLATFORM_PS2].rasterNumLevels = rasterNumLevels;
Texture::registerPlugin(0, ID_SKYMIPMAP, nil, nil, nil); Texture::registerPlugin(0, ID_SKYMIPMAP, nil, nil, nil);
Texture::registerPluginStream(ID_SKYMIPMAP, readMipmap, writeMipmap, getSizeMipmap); Texture::registerPluginStream(ID_SKYMIPMAP, readMipmap, writeMipmap, getSizeMipmap);
@ -595,7 +606,7 @@ readNativeTexture(Stream *stream)
stream->read(raster->texels-0x50, natras->texelSize); stream->read(raster->texels-0x50, natras->texelSize);
stream->read(raster->palette-0x50, natras->paletteSize); stream->read(raster->palette-0x50, natras->paletteSize);
} }
if(tex->streamReadPlugins(stream)) if(Texture::s_plglist.streamRead(stream, tex))
return tex; return tex;
fail: fail:
@ -654,7 +665,7 @@ writeNativeTexture(Texture *tex, Stream *stream)
stream->write(raster->texels-0x50, ras->texelSize); stream->write(raster->texels-0x50, ras->texelSize);
stream->write(raster->palette-0x50, ras->paletteSize); stream->write(raster->palette-0x50, ras->paletteSize);
} }
tex->streamWritePlugins(stream); Texture::s_plglist.streamWrite(stream, tex);
} }
uint32 uint32
@ -666,7 +677,7 @@ getSizeNativeTexture(Texture *tex)
size += 12 + 12 + 64 + 12; size += 12 + 12 + 64 + 12;
Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, tex->raster, nativeRasterOffset); Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, tex->raster, nativeRasterOffset);
size += ras->texelSize + ras->paletteSize; size += ras->texelSize + ras->paletteSize;
size += 12 + tex->streamGetPluginSize(); size += 12 + Texture::s_plglist.streamGetSize(tex);
return size; return size;
} }

View File

@ -329,8 +329,6 @@ extern int build;
extern int platform; extern int platform;
extern char *debugFile; extern char *debugFile;
void initialize(void);
int strncmp_ci(const char *s1, const char *s2, int n); int strncmp_ci(const char *s1, const char *s2, int n);
// 0x04000000 3.1 // 0x04000000 3.1

View File

@ -1,15 +1,21 @@
namespace rw { namespace rw {
// TODO: move more stuff into this // TODO: move more stuff into this
struct Engine struct Engine
{ {
void *currentCamera; void *currentCamera;
void *currentWorld; void *currentWorld;
static PluginList s_plglist;
static void init(void);
static void open(void);
static int32 registerPlugin(int32 size, uint32 id, Constructor ctor,
Destructor dtor){
return s_plglist.registerPlugin(size, id, ctor, dtor, nil);
}
}; };
extern Engine engine; extern Engine *engine;
struct Driver struct Driver
{ {

View File

@ -24,196 +24,52 @@ struct Plugin
StreamGetSize getSize; StreamGetSize getSize;
RightsCallback rightsCallback; RightsCallback rightsCallback;
Plugin *next; Plugin *next;
Plugin *prev;
};
struct PluginList
{
int32 size;
int32 defaultSize;
Plugin *first;
Plugin *last;
void construct(void *);
void destruct(void *);
void copy(void *dst, void *src);
bool streamRead(Stream *stream, void *);
void streamWrite(Stream *stream, void *);
int streamGetSize(void *);
void assertRights(void *, uint32 pluginID, uint32 data);
int32 registerPlugin(int32 size, uint32 id,
Constructor, Destructor, CopyConstructor);
int32 registerStream(uint32 id, StreamRead, StreamWrite, StreamGetSize);
int32 setStreamRightsCallback(uint32 id, RightsCallback cb);
int32 getPluginOffset(uint32 id);
}; };
template <typename T> template <typename T>
struct PluginBase struct PluginBase
{ {
static int32 s_defaultSize; static PluginList s_plglist;
static int32 s_size;
static Plugin *s_plugins;
void constructPlugins(void); static int32 registerPlugin(int32 size, uint32 id, Constructor ctor,
void destructPlugins(void); Destructor dtor, CopyConstructor copy){
void copyPlugins(T *t); return s_plglist.registerPlugin(size, id, ctor, dtor, copy);
bool streamReadPlugins(Stream *stream); }
void streamWritePlugins(Stream *stream); static int32 registerPluginStream(uint32 id, StreamRead read,
int streamGetPluginSize(void); StreamWrite write, StreamGetSize getSize){
void assertRights(uint32 pluginID, uint32 data); return s_plglist.registerStream(id, read, write, getSize);
}
static int registerPlugin(int32 size, uint32 id, static int32 setStreamRightsCallback(uint32 id, RightsCallback cb){
Constructor, Destructor, CopyConstructor); return s_plglist.setStreamRightsCallback(id, cb);
static int registerPluginStream(uint32 id, }
StreamRead, StreamWrite, StreamGetSize); static int32 getPluginOffset(uint32 id){
static int setStreamRightsCallback(uint32 id, RightsCallback cb); return s_plglist.getPluginOffset(id);
static int getPluginOffset(uint32 id); }
static void *operator new(size_t size);
static void operator delete(void *p);
}; };
template <typename T> template <typename T>
int PluginBase<T>::s_defaultSize = sizeof(T); PluginList PluginBase<T>::s_plglist = { sizeof(T), sizeof(T), nil, nil };
template <typename T>
int PluginBase<T>::s_size = sizeof(T);
template <typename T>
Plugin *PluginBase<T>::s_plugins = 0;
template <typename T> void
PluginBase<T>::constructPlugins(void)
{
for(Plugin *p = this->s_plugins; p; p = p->next)
if(p->constructor)
p->constructor((void*)this, p->offset, p->size);
}
template <typename T> void
PluginBase<T>::destructPlugins(void)
{
for(Plugin *p = this->s_plugins; p; p = p->next)
if(p->destructor)
p->destructor((void*)this, p->offset, p->size);
}
template <typename T> void
PluginBase<T>::copyPlugins(T *t)
{
for(Plugin *p = this->s_plugins; p; p = p->next)
if(p->copy)
p->copy((void*)this, (void*)t, p->offset, p->size);
}
template <typename T> bool
PluginBase<T>::streamReadPlugins(Stream *stream)
{
int32 length;
ChunkHeaderInfo header;
if(!findChunk(stream, ID_EXTENSION, (uint32*)&length, nil))
return false;
while(length > 0){
if(!readChunkHeaderInfo(stream, &header))
return false;
length -= 12;
for(Plugin *p = this->s_plugins; p; p = p->next)
if(p->id == header.type && p->read){
p->read(stream, header.length,
(void*)this, p->offset, p->size);
goto cont;
}
//printf("skipping plugin %X\n", header.type);
stream->seek(header.length);
cont:
length -= header.length;
}
return true;
}
template <typename T> void
PluginBase<T>::streamWritePlugins(Stream *stream)
{
int size = this->streamGetPluginSize();
writeChunkHeader(stream, ID_EXTENSION, size);
for(Plugin *p = this->s_plugins; p; p = p->next){
if(p->getSize == nil ||
(size = p->getSize(this, p->offset, p->size)) <= 0)
continue;
writeChunkHeader(stream, p->id, size);
p->write(stream, size, this, p->offset, p->size);
}
}
template <typename T> int32
PluginBase<T>::streamGetPluginSize(void)
{
int32 size = 0;
int32 plgsize;
for(Plugin *p = this->s_plugins; p; p = p->next)
if(p->getSize &&
(plgsize = p->getSize(this, p->offset, p->size)) > 0)
size += 12 + plgsize;
return size;
}
template <typename T> void
PluginBase<T>::assertRights(uint32 pluginID, uint32 data)
{
for(Plugin *p = this->s_plugins; p; p = p->next)
if(p->id == pluginID){
if(p->rightsCallback)
p->rightsCallback(this,
p->offset, p->size, data);
return;
}
}
template <typename T> int32
PluginBase<T>::registerPlugin(int32 size, uint32 id,
Constructor ctor, Destructor dtor, CopyConstructor cctor)
{
Plugin *p = new Plugin;
p->offset = s_size;
s_size += size;
p->size = size;
p->id = id;
p->constructor = ctor;
p->copy = cctor;
p->destructor = dtor;
p->read = nil;
p->write = nil;
p->getSize = nil;
p->rightsCallback = nil;
Plugin **next;
for(next = &s_plugins; *next; next = &(*next)->next)
;
*next = p;
p->next = nil;
return p->offset;
}
template <typename T> int32
PluginBase<T>::registerPluginStream(uint32 id,
StreamRead read, StreamWrite write, StreamGetSize getSize)
{
for(Plugin *p = PluginBase<T>::s_plugins; p; p = p->next)
if(p->id == id){
p->read = read;
p->write = write;
p->getSize = getSize;
return p->offset;
}
return -1;
}
template <typename T> int32
PluginBase<T>::setStreamRightsCallback(uint32 id, RightsCallback cb)
{
for(Plugin *p = PluginBase<T>::s_plugins; p; p = p->next)
if(p->id == id){
p->rightsCallback = cb;
return p->offset;
}
return -1;
}
template <typename T> int32
PluginBase<T>::getPluginOffset(uint32 id)
{
for(Plugin *p = PluginBase<T>::s_plugins; p; p = p->next)
if(p->id == id)
return p->offset;
return -1;
}
template <typename T> void*
PluginBase<T>::operator new(size_t)
{
abort();
return nil;
}
template <typename T> void
PluginBase<T>::operator delete(void *p)
{
abort();
}
} }

View File

@ -16,9 +16,9 @@ namespace rw {
World* World*
World::create(void) World::create(void)
{ {
World *world = (World*)malloc(PluginBase::s_size); World *world = (World*)malloc(PluginBase::s_plglist.size);
if(world == nil){ if(world == nil){
RWERROR((ERR_ALLOC, PluginBase::s_size)); RWERROR((ERR_ALLOC, PluginBase::s_plglist.size));
return nil; return nil;
} }
world->object.init(World::ID, 0); world->object.init(World::ID, 0);