diff --git a/Makefile b/Makefile index 75355c1..bf0ffde 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/rw.h b/rw.h index ffc88a6..2773223 100644 --- a/rw.h +++ b/rw.h @@ -14,6 +14,9 @@ #include "src/d3d/rwd3d.h" #include "src/d3d/rwd3d8.h" #include "src/d3d/rwd3d9.h" +#ifdef RW_OPENGL +#include +#endif #include "src/gl/rwwdgl.h" #include "src/gl/rwgl3.h" #include "src/gl/rwgl3shader.h" diff --git a/src/rwbase.cpp b/src/base.cpp similarity index 95% rename from src/rwbase.cpp rename to src/base.cpp index 142c76b..47a3cdc 100644 --- a/src/rwbase.cpp +++ b/src/base.cpp @@ -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) diff --git a/src/camera.cpp b/src/camera.cpp index d55fc95..b1e78b8 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -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 diff --git a/src/clump.cpp b/src/clump.cpp index 6f9b867..57a4a6a 100644 --- a/src/clump.cpp +++ b/src/clump.cpp @@ -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 diff --git a/src/d3d/d3d8.cpp b/src/d3d/d3d8.cpp index d3ab9bc..1284862 100644 --- a/src/d3d/d3d8.cpp +++ b/src/d3d/d3d8.cpp @@ -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; } diff --git a/src/d3d/d3d9.cpp b/src/d3d/d3d9.cpp index dc14002..561dcd4 100644 --- a/src/d3d/d3d9.cpp +++ b/src/d3d/d3d9.cpp @@ -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; } diff --git a/src/d3d/xbox.cpp b/src/d3d/xbox.cpp index e0efaba..3a35b44 100644 --- a/src/d3d/xbox.cpp +++ b/src/d3d/xbox.cpp @@ -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; } diff --git a/src/engine.cpp b/src/engine.cpp index 866dde3..7b28a5f 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -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*) { } diff --git a/src/frame.cpp b/src/frame.cpp index 1f9bc12..5e2e05f 100644 --- a/src/frame.cpp +++ b/src/frame.cpp @@ -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; } diff --git a/src/geometry.cpp b/src/geometry.cpp index 974033f..13363b2 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -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; } diff --git a/src/gl/gl3raster.cpp b/src/gl/gl3raster.cpp index e698026..aee49e4 100644 --- a/src/gl/gl3raster.cpp +++ b/src/gl/gl3raster.cpp @@ -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); +} + } } diff --git a/src/gl/gl3render.cpp b/src/gl/gl3render.cpp index af5ff66..1a6f9c1 100644 --- a/src/gl/gl3render.cpp +++ b/src/gl/gl3render.cpp @@ -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); diff --git a/src/image.cpp b/src/image.cpp index c1eaa3e..7a37db4 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -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); diff --git a/src/light.cpp b/src/light.cpp index dd28824..55eeba0 100644 --- a/src/light.cpp +++ b/src/light.cpp @@ -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); } } diff --git a/src/plg.cpp b/src/plg.cpp new file mode 100644 index 0000000..0cf8afb --- /dev/null +++ b/src/plg.cpp @@ -0,0 +1,167 @@ +#include +#include +#include +#include +#include +#include + +#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; +} + +} diff --git a/src/ps2/ps2raster.cpp b/src/ps2/ps2raster.cpp index c30f4f7..e958094 100644 --- a/src/ps2/ps2raster.cpp +++ b/src/ps2/ps2raster.cpp @@ -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; } diff --git a/src/rwbase.h b/src/rwbase.h index 0b91be8..2ac9a4a 100644 --- a/src/rwbase.h +++ b/src/rwbase.h @@ -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 diff --git a/src/rwengine.h b/src/rwengine.h index fb7e7dd..8118899 100644 --- a/src/rwengine.h +++ b/src/rwengine.h @@ -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 { diff --git a/src/rwplg.h b/src/rwplg.h index 00b4a58..9dc082b 100644 --- a/src/rwplg.h +++ b/src/rwplg.h @@ -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 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 -int PluginBase::s_defaultSize = sizeof(T); -template -int PluginBase::s_size = sizeof(T); -template -Plugin *PluginBase::s_plugins = 0; +PluginList PluginBase::s_plglist = { sizeof(T), sizeof(T), nil, nil }; -template void -PluginBase::constructPlugins(void) -{ - for(Plugin *p = this->s_plugins; p; p = p->next) - if(p->constructor) - p->constructor((void*)this, p->offset, p->size); -} - -template void -PluginBase::destructPlugins(void) -{ - for(Plugin *p = this->s_plugins; p; p = p->next) - if(p->destructor) - p->destructor((void*)this, p->offset, p->size); -} - -template void -PluginBase::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 bool -PluginBase::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 void -PluginBase::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 int32 -PluginBase::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 void -PluginBase::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 int32 -PluginBase::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 int32 -PluginBase::registerPluginStream(uint32 id, - StreamRead read, StreamWrite write, StreamGetSize getSize) -{ - for(Plugin *p = PluginBase::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 int32 -PluginBase::setStreamRightsCallback(uint32 id, RightsCallback cb) -{ - for(Plugin *p = PluginBase::s_plugins; p; p = p->next) - if(p->id == id){ - p->rightsCallback = cb; - return p->offset; - } - return -1; -} - -template int32 -PluginBase::getPluginOffset(uint32 id) -{ - for(Plugin *p = PluginBase::s_plugins; p; p = p->next) - if(p->id == id) - return p->offset; - return -1; -} - -template void* -PluginBase::operator new(size_t) -{ - abort(); - return nil; -} - -template void -PluginBase::operator delete(void *p) -{ - abort(); -} } diff --git a/src/world.cpp b/src/world.cpp index 4d612b1..b3c6baa 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -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);