librw/src/clump.cpp

598 lines
13 KiB
C++
Raw Normal View History

2014-12-18 17:26:57 +01:00
#include <cstdio>
#include <cstdlib>
2016-06-17 13:29:49 +02:00
#include <cstring>
2014-12-18 17:26:57 +01:00
#include "rwbase.h"
#include "rwerror.h"
2016-06-16 14:08:09 +02:00
#include "rwplg.h"
2015-07-11 23:48:11 +02:00
#include "rwpipeline.h"
2014-12-23 15:59:14 +01:00
#include "rwobjects.h"
2016-06-16 14:08:09 +02:00
#include "rwengine.h"
2014-12-18 17:26:57 +01:00
#define PLUGIN_ID 2
namespace rw {
2014-12-18 17:26:57 +01:00
PluginList Clump::s_plglist = { sizeof(Clump), sizeof(Clump), nil, nil };
PluginList Atomic::s_plglist = { sizeof(Atomic), sizeof(Atomic), nil, nil };
2015-01-09 20:17:32 +01:00
//
// Clump
//
2014-12-18 17:26:57 +01:00
Clump*
Clump::create(void)
2014-12-18 17:26:57 +01:00
{
2017-08-24 15:10:34 +02:00
Clump *clump = (Clump*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_CLUMP);
if(clump == nil){
RWERROR((ERR_ALLOC, s_plglist.size));
return nil;
}
2016-01-13 08:58:15 +01:00
clump->object.init(Clump::ID, 0);
clump->atomics.init();
clump->lights.init();
2016-01-13 08:58:15 +01:00
clump->cameras.init();
s_plglist.construct(clump);
return clump;
2014-12-18 17:26:57 +01:00
}
Clump*
Clump::clone(void)
2014-12-18 17:26:57 +01:00
{
Clump *clump = Clump::create();
2020-04-16 09:10:11 +02:00
Frame *root = this->getFrame()->cloneAndLink();
clump->setFrame(root);
FORLIST(lnk, this->atomics){
Atomic *a = Atomic::fromClump(lnk);
Atomic *atomic = a->clone();
atomic->setFrame(a->getFrame()->root);
clump->addAtomic(atomic);
}
root->purgeClone();
s_plglist.copy(clump, this);
return clump;
2014-12-18 17:26:57 +01:00
}
void
Clump::destroy(void)
2014-12-18 17:26:57 +01:00
{
Frame *f;
s_plglist.destruct(this);
FORLIST(lnk, this->atomics)
Atomic::fromClump(lnk)->destroy();
FORLIST(lnk, this->lights)
Light::fromClump(lnk)->destroy();
2016-01-13 08:58:15 +01:00
FORLIST(lnk, this->cameras)
Camera::fromClump(lnk)->destroy();
2017-07-12 10:10:57 +02:00
if(f = this->getFrame(), f)
f->destroyHierarchy();
2017-08-24 15:10:34 +02:00
rwFree(this);
}
2014-12-18 17:26:57 +01:00
Clump*
Clump::streamRead(Stream *stream)
2014-12-18 17:26:57 +01:00
{
uint32 length, version;
int32 buf[3];
Clump *clump;
2016-06-17 16:20:02 +02:00
int32 numGeometries;
Geometry **geometryList;
if(!findChunk(stream, ID_STRUCT, &length, &version)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
stream->read(buf, length);
int32 numAtomics = buf[0];
int32 numLights = 0;
2016-01-13 08:58:15 +01:00
int32 numCameras = 0;
if(version > 0x33000){
numLights = buf[1];
2016-01-13 08:58:15 +01:00
numCameras = buf[2];
}
2016-06-17 13:29:49 +02:00
clump = Clump::create();
if(clump == nil)
return nil;
2014-12-18 17:26:57 +01:00
// Frame list
2016-06-17 13:29:49 +02:00
FrameList_ frmlst;
frmlst.frames = nil;
if(!findChunk(stream, ID_FRAMELIST, nil, nil)){
RWERROR((ERR_CHUNK, "FRAMELIST"));
goto fail;
}
if(frmlst.streamRead(stream) == nil)
goto fail;
clump->setFrame(frmlst.frames[0]);
2014-12-18 17:26:57 +01:00
2016-06-17 13:29:49 +02:00
// Geometry list
2016-06-17 16:20:02 +02:00
numGeometries = 0;
geometryList = nil;
2015-08-16 23:23:41 +02:00
if(version >= 0x30400){
if(!findChunk(stream, ID_GEOMETRYLIST, nil, nil)){
RWERROR((ERR_CHUNK, "GEOMETRYLIST"));
2016-06-17 13:29:49 +02:00
goto fail;
}
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
2016-06-17 13:29:49 +02:00
goto fail;
}
2015-08-16 23:23:41 +02:00
numGeometries = stream->readI32();
2016-06-17 13:29:49 +02:00
if(numGeometries){
size_t sz = numGeometries*sizeof(Geometry*);
2017-08-24 15:10:34 +02:00
geometryList = (Geometry**)rwMalloc(sz, MEMDUR_FUNCTION | ID_CLUMP);
2016-06-17 13:29:49 +02:00
if(geometryList == nil){
RWERROR((ERR_ALLOC, sz));
goto fail;
}
memset(geometryList, 0, sz);
}
2015-08-16 23:23:41 +02:00
for(int32 i = 0; i < numGeometries; i++){
if(!findChunk(stream, ID_GEOMETRY, nil, nil)){
RWERROR((ERR_CHUNK, "GEOMETRY"));
2016-06-17 13:29:49 +02:00
goto failgeo;
}
2015-08-16 23:23:41 +02:00
geometryList[i] = Geometry::streamRead(stream);
2016-06-17 13:29:49 +02:00
if(geometryList[i] == nil)
goto failgeo;
2015-08-16 23:23:41 +02:00
}
2014-12-18 17:26:57 +01:00
}
// Atomics
Atomic *a;
for(int32 i = 0; i < numAtomics; i++){
if(!findChunk(stream, ID_ATOMIC, nil, nil)){
RWERROR((ERR_CHUNK, "ATOMIC"));
2016-06-17 13:29:49 +02:00
goto failgeo;
}
2016-06-17 13:29:49 +02:00
a = Atomic::streamReadClump(stream, &frmlst, geometryList);
if(a == nil)
goto failgeo;
clump->addAtomic(a);
2014-12-18 17:26:57 +01:00
}
// Lights
2016-06-17 13:29:49 +02:00
int32 frm;
Light *l;
for(int32 i = 0; i < numLights; i++){
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
2016-06-17 13:29:49 +02:00
goto failgeo;
}
frm = stream->readI32();
if(!findChunk(stream, ID_LIGHT, nil, nil)){
RWERROR((ERR_CHUNK, "LIGHT"));
2016-06-17 13:29:49 +02:00
goto failgeo;
}
2016-06-17 13:29:49 +02:00
l = Light::streamRead(stream);
if(l == nil)
goto failgeo;
l->setFrame(frmlst.frames[frm]);
clump->addLight(l);
2014-12-18 17:26:57 +01:00
}
2016-01-13 08:58:15 +01:00
// Cameras
2016-06-17 13:29:49 +02:00
Camera *cam;
2016-01-13 08:58:15 +01:00
for(int32 i = 0; i < numCameras; i++){
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
2016-06-17 13:29:49 +02:00
goto failgeo;
}
2016-01-13 08:58:15 +01:00
frm = stream->readI32();
if(!findChunk(stream, ID_CAMERA, nil, nil)){
RWERROR((ERR_CHUNK, "CAMERA"));
2016-06-17 13:29:49 +02:00
goto failgeo;
}
2016-06-17 13:29:49 +02:00
cam = Camera::streamRead(stream);
if(cam == nil)
goto failgeo;
cam->setFrame(frmlst.frames[frm]);
2016-01-13 08:58:15 +01:00
clump->addCamera(cam);
}
2016-06-17 13:29:49 +02:00
for(int32 i = 0; i < numGeometries; i++)
if(geometryList[i])
geometryList[i]->destroy();
2017-08-24 15:10:34 +02:00
rwFree(geometryList);
rwFree(frmlst.frames);
if(s_plglist.streamRead(stream, clump))
2016-06-17 13:29:49 +02:00
return clump;
failgeo:
for(int32 i = 0; i < numGeometries; i++)
if(geometryList[i])
geometryList[i]->destroy();
2017-08-24 15:10:34 +02:00
rwFree(geometryList);
2016-06-17 13:29:49 +02:00
fail:
2017-08-24 15:10:34 +02:00
rwFree(frmlst.frames);
2016-06-17 13:29:49 +02:00
clump->destroy();
return nil;
2014-12-18 17:26:57 +01:00
}
bool
Clump::streamWrite(Stream *stream)
2014-12-18 17:26:57 +01:00
{
int size = this->streamGetSize();
writeChunkHeader(stream, ID_CLUMP, size);
int32 numAtomics = this->countAtomics();
int32 numLights = this->countLights();
2016-01-24 01:42:51 +01:00
int32 numCameras = this->countCameras();
int buf[3] = { numAtomics, numLights, numCameras };
size = version > 0x33000 ? 12 : 4;
writeChunkHeader(stream, ID_STRUCT, size);
stream->write(buf, size);
2014-12-18 17:26:57 +01:00
2016-06-17 13:29:49 +02:00
FrameList_ frmlst;
frmlst.numFrames = this->getFrame()->count();
2017-08-24 15:10:34 +02:00
frmlst.frames = (Frame**)rwMalloc(frmlst.numFrames*sizeof(Frame*), MEMDUR_FUNCTION | ID_CLUMP);
2016-06-17 13:29:49 +02:00
makeFrameList(this->getFrame(), frmlst.frames);
frmlst.streamWrite(stream);
2014-12-18 17:26:57 +01:00
2015-08-16 23:23:41 +02:00
if(rw::version >= 0x30400){
size = 12+4;
FORLIST(lnk, this->atomics)
size += 12 + Atomic::fromClump(lnk)->geometry->streamGetSize();
2015-08-16 23:23:41 +02:00
writeChunkHeader(stream, ID_GEOMETRYLIST, size);
writeChunkHeader(stream, ID_STRUCT, 4);
stream->writeI32(numAtomics); // same as numGeometries
FORLIST(lnk, this->atomics)
Atomic::fromClump(lnk)->geometry->streamWrite(stream);
2015-08-16 23:23:41 +02:00
}
2014-12-18 17:26:57 +01:00
FORLIST(lnk, this->atomics)
2016-06-17 13:29:49 +02:00
Atomic::fromClump(lnk)->streamWriteClump(stream, &frmlst);
2014-12-18 17:26:57 +01:00
FORLIST(lnk, this->lights){
Light *l = Light::fromClump(lnk);
2016-06-17 13:29:49 +02:00
int frm = findPointer(l->getFrame(), (void**)frmlst.frames, frmlst.numFrames);
2014-12-18 17:26:57 +01:00
if(frm < 0)
return false;
writeChunkHeader(stream, ID_STRUCT, 4);
stream->writeI32(frm);
2014-12-18 17:26:57 +01:00
l->streamWrite(stream);
}
2016-01-13 08:58:15 +01:00
FORLIST(lnk, this->cameras){
Camera *c = Camera::fromClump(lnk);
2016-06-17 13:29:49 +02:00
int frm = findPointer(c->getFrame(), (void**)frmlst.frames, frmlst.numFrames);
2016-01-13 08:58:15 +01:00
if(frm < 0)
return false;
writeChunkHeader(stream, ID_STRUCT, 4);
stream->writeI32(frm);
c->streamWrite(stream);
}
2017-08-24 15:10:34 +02:00
rwFree(frmlst.frames);
2014-12-18 17:26:57 +01:00
s_plglist.streamWrite(stream, this);
2014-12-18 17:26:57 +01:00
return true;
}
uint32
Clump::streamGetSize(void)
{
uint32 size = 0;
size += 12; // Struct
size += 4; // numAtomics
if(version > 0x33000)
2014-12-18 17:26:57 +01:00
size += 8; // numLights, numCameras
2016-01-13 08:58:15 +01:00
// Frame list
2016-06-17 13:29:49 +02:00
size += FrameList_::streamGetSize(this->getFrame());
2014-12-18 17:26:57 +01:00
2015-08-16 23:23:41 +02:00
if(rw::version >= 0x30400){
2016-01-13 08:58:15 +01:00
// Geometry list
2015-08-16 23:23:41 +02:00
size += 12 + 12 + 4;
FORLIST(lnk, this->atomics)
size += 12 + Atomic::fromClump(lnk)->geometry->streamGetSize();
2015-08-16 23:23:41 +02:00
}
2014-12-18 17:26:57 +01:00
2016-01-13 08:58:15 +01:00
// Atomics
FORLIST(lnk, this->atomics)
size += 12 + Atomic::fromClump(lnk)->streamGetSize();
2014-12-18 17:26:57 +01:00
2016-01-13 08:58:15 +01:00
// Lights
FORLIST(lnk, this->lights)
size += 16 + 12 + Light::fromClump(lnk)->streamGetSize();
2014-12-18 17:26:57 +01:00
2016-01-13 08:58:15 +01:00
// Cameras
FORLIST(lnk, this->cameras)
size += 16 + 12 + Camera::fromClump(lnk)->streamGetSize();
size += 12 + s_plglist.streamGetSize(this);
2014-12-18 17:26:57 +01:00
return size;
}
2016-02-14 20:56:05 +01:00
void
Clump::render(void)
{
Atomic *a;
FORLIST(lnk, this->atomics){
a = Atomic::fromClump(lnk);
2016-06-16 14:08:09 +02:00
if(a->object.object.flags & Atomic::RENDER)
2016-02-14 20:56:05 +01:00
a->render();
}
}
2014-12-18 17:26:57 +01:00
2015-01-09 20:17:32 +01:00
//
// Atomic
//
2014-12-18 17:26:57 +01:00
static void
atomicSync(ObjectWithFrame *obj)
{
// TODO: interpolate
obj->object.privateFlags |= Atomic::WORLDBOUNDDIRTY;
}
2016-06-23 16:39:34 +02:00
static void
worldAtomicSync(ObjectWithFrame *obj)
{
Atomic *atomic = (Atomic*)obj;
atomic->originalSync(obj);
}
Atomic*
Atomic::create(void)
2014-12-18 17:26:57 +01:00
{
2017-08-24 15:10:34 +02:00
Atomic *atomic = (Atomic*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_ATOMIC);
if(atomic == nil){
RWERROR((ERR_ALLOC, s_plglist.size));
return nil;
}
2016-06-16 14:08:09 +02:00
atomic->object.object.init(Atomic::ID, 0);
atomic->object.syncCB = atomicSync;
atomic->geometry = nil;
atomic->boundingSphere.center.set(0.0f, 0.0f, 0.0f);
atomic->boundingSphere.radius = 0.0f;
2016-02-18 14:56:10 +01:00
atomic->worldBoundingSphere.center.set(0.0f, 0.0f, 0.0f);
atomic->worldBoundingSphere.radius = 0.0f;
atomic->setFrame(nil);
atomic->object.object.privateFlags |= WORLDBOUNDDIRTY;
atomic->clump = nil;
atomic->pipeline = nil;
atomic->renderCB = Atomic::defaultRenderCB;
2016-06-16 14:08:09 +02:00
atomic->object.object.flags = Atomic::COLLISIONTEST | Atomic::RENDER;
// TODO: interpolator
2016-06-23 16:39:34 +02:00
// World extension
atomic->world = nil;
atomic->originalSync = atomic->object.syncCB;
atomic->object.syncCB = worldAtomicSync;
s_plglist.construct(atomic);
return atomic;
2016-01-13 08:58:15 +01:00
}
2014-12-18 17:26:57 +01:00
Atomic*
Atomic::clone()
2014-12-18 17:26:57 +01:00
{
Atomic *atomic = Atomic::create();
2016-06-17 13:29:49 +02:00
if(atomic == nil)
return nil;
2016-06-16 14:08:09 +02:00
atomic->object.object.copy(&this->object.object);
atomic->object.object.privateFlags |= WORLDBOUNDDIRTY;
2016-06-17 13:29:49 +02:00
if(this->geometry)
atomic->setGeometry(this->geometry, 0);
2017-12-31 10:50:49 +01:00
atomic->renderCB = this->renderCB;
atomic->pipeline = this->pipeline;
s_plglist.copy(atomic, this);
return atomic;
2014-12-18 17:26:57 +01:00
}
void
Atomic::destroy(void)
2014-12-18 17:26:57 +01:00
{
s_plglist.destruct(this);
if(this->geometry)
this->geometry->destroy();
2016-02-17 23:59:05 +01:00
if(this->clump)
this->inClump.remove();
this->setFrame(nil);
2017-08-24 15:10:34 +02:00
rwFree(this);
2014-12-18 17:26:57 +01:00
}
2016-06-14 23:07:16 +02:00
void
Atomic::removeFromClump(void)
{
if(this->clump){
this->inClump.remove();
this->clump = nil;
2016-06-14 23:07:16 +02:00
}
}
2016-06-17 13:29:49 +02:00
void
Atomic::setGeometry(Geometry *geo, uint32 flags)
2016-06-17 13:29:49 +02:00
{
if(this->geometry)
this->geometry->destroy();
if(geo)
geo->refCount++;
this->geometry = geo;
if(flags & SAMEBOUNDINGSPHERE)
return;
if(geo){
this->boundingSphere = geo->morphTargets[0].boundingSphere;
if(this->getFrame()) // TODO: && getWorld???
this->getFrame()->updateObjects();
}
2016-06-17 13:29:49 +02:00
}
2016-02-18 14:56:10 +01:00
Sphere*
Atomic::getWorldBoundingSphere(void)
{
Sphere *s = &this->worldBoundingSphere;
// TODO: if we ever support morphing, check interpolation
2016-02-18 14:56:10 +01:00
if(!this->getFrame()->dirty() &&
2016-06-16 14:08:09 +02:00
(this->object.object.privateFlags & WORLDBOUNDDIRTY) == 0)
2016-02-18 14:56:10 +01:00
return s;
Matrix *ltm = this->getFrame()->getLTM();
// TODO: support scaling
2017-08-04 19:54:03 +02:00
V3d::transformPoints(&s->center, &this->boundingSphere.center, 1, ltm);
s->radius = this->boundingSphere.radius;
2016-06-16 14:08:09 +02:00
this->object.object.privateFlags &= ~WORLDBOUNDDIRTY;
2016-02-18 14:56:10 +01:00
return s;
}
2015-01-10 22:13:27 +01:00
static uint32 atomicRights[2];
2014-12-18 17:26:57 +01:00
Atomic*
Atomic::streamReadClump(Stream *stream,
2016-06-17 13:29:49 +02:00
FrameList_ *frameList, Geometry **geometryList)
2014-12-18 17:26:57 +01:00
{
int32 buf[4];
2015-08-16 23:23:41 +02:00
uint32 version;
if(!findChunk(stream, ID_STRUCT, nil, &version)){
RWERROR((ERR_CHUNK, "STRUCT"));
return nil;
}
2015-08-16 23:23:41 +02:00
stream->read(buf, version < 0x30400 ? 12 : 16);
Atomic *atomic = Atomic::create();
if(atomic == nil)
return nil;
2016-06-17 13:29:49 +02:00
atomic->setFrame(frameList->frames[buf[0]]);
Geometry *g;
2015-08-16 23:23:41 +02:00
if(version < 0x30400){
if(!findChunk(stream, ID_GEOMETRY, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
2016-06-17 13:29:49 +02:00
goto fail;
}
2016-06-17 13:29:49 +02:00
g = Geometry::streamRead(stream);
if(g == nil)
goto fail;
atomic->setGeometry(g, 0);
2016-06-17 13:29:49 +02:00
g->destroy();
2015-08-16 23:23:41 +02:00
}else
atomic->setGeometry(geometryList[buf[1]], 0);
2016-06-16 14:08:09 +02:00
atomic->object.object.flags = buf[2];
2015-01-10 22:13:27 +01:00
atomicRights[0] = 0;
if(!s_plglist.streamRead(stream, atomic))
2016-06-17 13:29:49 +02:00
goto fail;
2015-01-10 22:13:27 +01:00
if(atomicRights[0])
s_plglist.assertRights(atomic, atomicRights[0], atomicRights[1]);
2014-12-18 17:26:57 +01:00
return atomic;
2016-06-17 13:29:49 +02:00
fail:
atomic->destroy();
return nil;
2014-12-18 17:26:57 +01:00
}
bool
2016-06-17 13:29:49 +02:00
Atomic::streamWriteClump(Stream *stream, FrameList_ *frmlst)
2014-12-18 17:26:57 +01:00
{
2016-02-14 20:56:05 +01:00
int32 buf[4] = { 0, 0, 0, 0 };
2014-12-18 17:26:57 +01:00
Clump *c = this->clump;
if(c == nil)
2014-12-18 17:26:57 +01:00
return false;
writeChunkHeader(stream, ID_ATOMIC, this->streamGetSize());
2015-08-16 23:23:41 +02:00
writeChunkHeader(stream, ID_STRUCT, rw::version < 0x30400 ? 12 : 16);
2016-06-17 13:29:49 +02:00
buf[0] = findPointer(this->getFrame(), (void**)frmlst->frames, frmlst->numFrames);
2014-12-18 17:26:57 +01:00
2015-08-16 23:23:41 +02:00
if(version < 0x30400){
2016-06-16 14:08:09 +02:00
buf[1] = this->object.object.flags;
2015-08-16 23:23:41 +02:00
stream->write(buf, sizeof(int[3]));
this->geometry->streamWrite(stream);
}else{
buf[1] = 0;
FORLIST(lnk, c->atomics){
if(Atomic::fromClump(lnk)->geometry == this->geometry)
2015-08-16 23:23:41 +02:00
goto foundgeo;
buf[1]++;
}
2015-08-16 23:23:41 +02:00
return false;
foundgeo:
2016-06-16 14:08:09 +02:00
buf[2] = this->object.object.flags;
2015-08-16 23:23:41 +02:00
stream->write(buf, sizeof(buf));
}
2014-12-18 17:26:57 +01:00
s_plglist.streamWrite(stream, this);
2014-12-18 17:26:57 +01:00
return true;
}
uint32
Atomic::streamGetSize(void)
{
uint32 size = 12 + 12 + 12 + s_plglist.streamGetSize(this);
2015-08-16 23:23:41 +02:00
if(rw::version < 0x30400)
size += 12 + this->geometry->streamGetSize();
else
size += 4;
return size;
2014-12-18 17:26:57 +01:00
}
2015-08-03 18:30:10 +02:00
ObjPipeline*
Atomic::getPipeline(void)
{
return this->pipeline ?
this->pipeline :
2017-08-09 10:57:32 +02:00
engine->driver[platform]->defaultPipeline;
2015-08-03 18:30:10 +02:00
}
2017-08-21 23:15:31 +02:00
void
Atomic::instance(void)
{
if(this->geometry->flags & Geometry::NATIVE)
return;
this->getPipeline()->instance(this);
this->geometry->flags |= Geometry::NATIVE;
}
void
Atomic::uninstance(void)
{
if(!(this->geometry->flags & Geometry::NATIVE))
return;
this->getPipeline()->uninstance(this);
// this should be done by the CB already, just make sure
this->geometry->flags &= ~Geometry::NATIVE;
}
2015-08-03 18:30:10 +02:00
void
Atomic::defaultRenderCB(Atomic *atomic)
{
atomic->getPipeline()->render(atomic);
2015-08-03 18:30:10 +02:00
}
2015-01-09 20:17:32 +01:00
// Atomic Rights plugin
2016-06-17 16:20:02 +02:00
static Stream*
2015-01-09 20:17:32 +01:00
readAtomicRights(Stream *stream, int32, void *, int32, int32)
{
2015-01-10 22:13:27 +01:00
stream->read(atomicRights, 8);
2016-06-17 16:20:02 +02:00
return stream;
2015-01-10 22:13:27 +01:00
}
2016-06-17 16:20:02 +02:00
static Stream*
2015-01-10 22:13:27 +01:00
writeAtomicRights(Stream *stream, int32, void *object, int32, int32)
{
Atomic *atomic = (Atomic*)object;
uint32 buffer[2];
buffer[0] = atomic->pipeline->pluginID;
buffer[1] = atomic->pipeline->pluginData;
stream->write(buffer, 8);
2016-06-17 16:20:02 +02:00
return stream;
2015-01-10 22:13:27 +01:00
}
static int32
getSizeAtomicRights(void *object, int32, int32)
{
Atomic *atomic = (Atomic*)object;
if(atomic->pipeline == nil || atomic->pipeline->pluginID == 0)
2016-06-17 13:29:49 +02:00
return 0;
2015-01-10 22:13:27 +01:00
return 8;
2015-01-09 20:17:32 +01:00
}
void
registerAtomicRightsPlugin(void)
2015-01-09 20:17:32 +01:00
{
Atomic::registerPlugin(0, ID_RIGHTTORENDER, nil, nil, nil);
2015-01-09 20:17:32 +01:00
Atomic::registerPluginStream(ID_RIGHTTORENDER,
2015-01-10 22:13:27 +01:00
readAtomicRights,
writeAtomicRights,
getSizeAtomicRights);
2015-01-09 20:17:32 +01:00
}
2014-12-18 17:26:57 +01:00
}