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))
DEP := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.d,$(SRC))
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
LIB=librw-$(BUILD).a

3
rw.h
View File

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

View File

@ -12,11 +12,6 @@
#include "rwobjects.h"
#include "rwplugins.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 {
@ -52,34 +47,6 @@ static Matrix3 identMat3 = {
{ 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
int
strncmp_ci(const char *s1, const char *s2, int n)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,13 +7,59 @@
#include "rwpipeline.h"
#include "rwobjects.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 {
Engine engine;
Engine *engine;
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 {
void beginUpdate(Camera*) { }

View File

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

View File

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

View File

@ -112,14 +112,9 @@ copyNativeRaster(void *dst, void *, int32 offset, int32)
return dst;
}
void
registerNativeRaster(void)
static 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].rasterCreate = rasterCreate;
driver[PLATFORM_GL3].rasterLock = rasterLock;
@ -128,5 +123,21 @@ registerNativeRaster(void)
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};
int n = 0;
world = (World*)engine.currentWorld;
world = (World*)engine->currentWorld;
// only unpositioned lights right now
FORLIST(lnk, world->directionalLights){
Light *l = Light::fromWorld(lnk);

View File

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

View File

@ -26,9 +26,9 @@ worldLightSync(ObjectWithFrame *obj)
Light*
Light::create(int32 type)
{
Light *light = (Light*)malloc(PluginBase::s_size);
Light *light = (Light*)malloc(s_plglist.size);
if(light == nil){
RWERROR((ERR_ALLOC, PluginBase::s_size));
RWERROR((ERR_ALLOC, s_plglist.size));
return nil;
}
light->object.object.init(Light::ID, type);
@ -52,14 +52,14 @@ Light::create(int32 type)
light->originalSync = light->object.syncCB;
light->object.syncCB = worldLightSync;
light->constructPlugins();
s_plglist.construct(light);
return light;
}
void
Light::destroy(void)
{
this->destructPlugins();
s_plglist.destruct(this);
if(this->clump)
this->inClump.remove();
// we do not remove from world, be careful
@ -119,7 +119,7 @@ Light::streamRead(Stream *stream)
// tan -> -cos
light->minusCosAngle = -1.0f/sqrt(a*a+1.0f);
light->object.object.flags = (uint8)buf.flags;
if(light->streamReadPlugins(stream))
if(s_plglist.streamRead(stream, light))
return light;
light->destroy();
return nil;
@ -143,14 +143,14 @@ Light::streamWrite(Stream *stream)
buf.type = this->object.object.subType;
stream->write(&buf, sizeof(LightChunkData));
this->streamWritePlugins(stream);
s_plglist.streamWrite(stream, this);
return true;
}
uint32
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;
}
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
registerNativeRaster(void)
{
@ -484,11 +499,7 @@ registerNativeRaster(void)
createNativeRaster,
destroyNativeRaster,
copyNativeRaster);
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;
Engine::registerPlugin(0, 0x1234, nativeOpen, nativeClose);
Texture::registerPlugin(0, ID_SKYMIPMAP, nil, nil, nil);
Texture::registerPluginStream(ID_SKYMIPMAP, readMipmap, writeMipmap, getSizeMipmap);
@ -595,7 +606,7 @@ readNativeTexture(Stream *stream)
stream->read(raster->texels-0x50, natras->texelSize);
stream->read(raster->palette-0x50, natras->paletteSize);
}
if(tex->streamReadPlugins(stream))
if(Texture::s_plglist.streamRead(stream, tex))
return tex;
fail:
@ -654,7 +665,7 @@ writeNativeTexture(Texture *tex, Stream *stream)
stream->write(raster->texels-0x50, ras->texelSize);
stream->write(raster->palette-0x50, ras->paletteSize);
}
tex->streamWritePlugins(stream);
Texture::s_plglist.streamWrite(stream, tex);
}
uint32
@ -666,7 +677,7 @@ getSizeNativeTexture(Texture *tex)
size += 12 + 12 + 64 + 12;
Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, tex->raster, nativeRasterOffset);
size += ras->texelSize + ras->paletteSize;
size += 12 + tex->streamGetPluginSize();
size += 12 + Texture::s_plglist.streamGetSize(tex);
return size;
}

View File

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

View File

@ -1,15 +1,21 @@
namespace rw {
// TODO: move more stuff into this
struct Engine
{
void *currentCamera;
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
{

View File

@ -24,196 +24,52 @@ struct Plugin
StreamGetSize getSize;
RightsCallback rightsCallback;
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>
struct PluginBase
{
static int32 s_defaultSize;
static int32 s_size;
static Plugin *s_plugins;
static PluginList s_plglist;
void constructPlugins(void);
void destructPlugins(void);
void copyPlugins(T *t);
bool streamReadPlugins(Stream *stream);
void streamWritePlugins(Stream *stream);
int streamGetPluginSize(void);
void assertRights(uint32 pluginID, uint32 data);
static int registerPlugin(int32 size, uint32 id,
Constructor, Destructor, CopyConstructor);
static int registerPluginStream(uint32 id,
StreamRead, StreamWrite, StreamGetSize);
static int setStreamRightsCallback(uint32 id, RightsCallback cb);
static int getPluginOffset(uint32 id);
static void *operator new(size_t size);
static void operator delete(void *p);
static int32 registerPlugin(int32 size, uint32 id, Constructor ctor,
Destructor dtor, CopyConstructor copy){
return s_plglist.registerPlugin(size, id, ctor, dtor, copy);
}
static int32 registerPluginStream(uint32 id, StreamRead read,
StreamWrite write, StreamGetSize getSize){
return s_plglist.registerStream(id, read, write, getSize);
}
static int32 setStreamRightsCallback(uint32 id, RightsCallback cb){
return s_plglist.setStreamRightsCallback(id, cb);
}
static int32 getPluginOffset(uint32 id){
return s_plglist.getPluginOffset(id);
}
};
template <typename T>
int PluginBase<T>::s_defaultSize = sizeof(T);
template <typename T>
int PluginBase<T>::s_size = sizeof(T);
template <typename T>
Plugin *PluginBase<T>::s_plugins = 0;
PluginList PluginBase<T>::s_plglist = { sizeof(T), sizeof(T), nil, nil };
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::create(void)
{
World *world = (World*)malloc(PluginBase::s_size);
World *world = (World*)malloc(PluginBase::s_plglist.size);
if(world == nil){
RWERROR((ERR_ALLOC, PluginBase::s_size));
RWERROR((ERR_ALLOC, PluginBase::s_plglist.size));
return nil;
}
world->object.init(World::ID, 0);