summaryrefslogtreecommitdiff
path: root/src/light.cpp
diff options
context:
space:
mode:
authorclaude-bot <[email protected]>2026-07-13 12:40:03 +0000
committerclaude-bot <[email protected]>2026-07-13 12:40:03 +0000
commit847962910f0bff071f3bf07c9abb87764fb6cac3 (patch)
treeddcd429e134c7fd5f72ddc97ced175de8d66fcd0 /src/light.cpp
downloadlibrw-master.tar.gz
librw-master.zip
Import aap/librw @ masterHEADmaster
Snapshot for re3/reVC vendoring, per @lzcnt. Source: https://github.com/aap/librw (master).
Diffstat (limited to 'src/light.cpp')
-rw-r--r--src/light.cpp163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/light.cpp b/src/light.cpp
new file mode 100644
index 0000000..ca68cda
--- /dev/null
+++ b/src/light.cpp
@@ -0,0 +1,163 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "rwbase.h"
+#include "rwerror.h"
+#include "rwplg.h"
+#include "rwpipeline.h"
+#include "rwobjects.h"
+#include "rwengine.h"
+
+#define PLUGIN_ID ID_LIGHT
+
+namespace rw {
+
+int32 Light::numAllocated;
+
+PluginList Light::s_plglist(sizeof(Light));
+
+static void
+lightSync(ObjectWithFrame*)
+{
+}
+
+static void
+worldLightSync(ObjectWithFrame *obj)
+{
+ Light *light = (Light*)obj;
+ light->originalSync(obj);
+}
+
+Light*
+Light::create(int32 type)
+{
+ Light *light = (Light*)rwMalloc(s_plglist.size, MEMDUR_EVENT | ID_LIGHT);
+ if(light == nil){
+ RWERROR((ERR_ALLOC, s_plglist.size));
+ return nil;
+ }
+ numAllocated++;
+ light->object.object.init(Light::ID, type);
+ light->object.syncCB = lightSync;
+ light->radius = 0.0f;
+ light->color.red = 1.0f;
+ light->color.green = 1.0f;
+ light->color.blue = 1.0f;
+ light->color.alpha = 1.0f;
+ light->minusCosAngle = 1.0f;
+ light->object.object.privateFlags = 1;
+ light->object.object.flags = LIGHTATOMICS | LIGHTWORLD;
+ light->inWorld.init();
+
+ // clump extension
+ light->clump = nil;
+ light->inClump.init();
+
+ // world extension
+ light->world = nil;
+ light->originalSync = light->object.syncCB;
+ light->object.syncCB = worldLightSync;
+
+ s_plglist.construct(light);
+ return light;
+}
+
+void
+Light::destroy(void)
+{
+ s_plglist.destruct(this);
+ assert(this->clump == nil);
+ assert(this->world == nil);
+ this->setFrame(nil);
+ rwFree(this);
+ numAllocated--;
+}
+
+void
+Light::setAngle(float32 angle)
+{
+ this->minusCosAngle = -cosf(angle);
+}
+
+float32
+Light::getAngle(void)
+{
+ return acosf(-this->minusCosAngle);
+}
+
+void
+Light::setColor(float32 r, float32 g, float32 b)
+{
+ this->color.red = r;
+ this->color.green = g;
+ this->color.blue = b;
+ this->object.object.privateFlags = r == g && r == b;
+}
+
+struct LightChunkData
+{
+ float32 radius;
+ float32 red, green, blue;
+ float32 minusCosAngle;
+ uint32 type_flags;
+};
+
+Light*
+Light::streamRead(Stream *stream)
+{
+ uint32 version;
+ LightChunkData buf;
+
+ if(!findChunk(stream, ID_STRUCT, nil, &version)){
+ RWERROR((ERR_CHUNK, "STRUCT"));
+ return nil;
+ }
+ stream->read32(&buf, sizeof(LightChunkData));
+ Light *light = Light::create(buf.type_flags>>16);
+ if(light == nil)
+ return nil;
+ light->radius = buf.radius;
+ light->setColor(buf.red, buf.green, buf.blue);
+ float32 a = buf.minusCosAngle;
+ if(version >= 0x30300)
+ light->minusCosAngle = a;
+ else
+ // tan -> -cos
+ light->minusCosAngle = -1.0f/sqrtf(a*a+1.0f);
+ light->object.object.flags = (uint8)buf.type_flags;
+ if(s_plglist.streamRead(stream, light))
+ return light;
+ light->destroy();
+ return nil;
+}
+
+bool
+Light::streamWrite(Stream *stream)
+{
+ LightChunkData buf;
+ writeChunkHeader(stream, ID_LIGHT, this->streamGetSize());
+ writeChunkHeader(stream, ID_STRUCT, sizeof(LightChunkData));
+ buf.radius = this->radius;
+ buf.red = this->color.red;
+ buf.green = this->color.green;
+ buf.blue = this->color.blue;
+ if(version >= 0x30300)
+ buf.minusCosAngle = this->minusCosAngle;
+ else
+ buf.minusCosAngle = tanf(acosf(-this->minusCosAngle));
+ buf.type_flags = (uint32)this->object.object.flags |
+ (uint32)this->object.object.subType << 16;
+ stream->write32(&buf, sizeof(LightChunkData));
+
+ s_plglist.streamWrite(stream, this);
+ return true;
+}
+
+uint32
+Light::streamGetSize(void)
+{
+ return 12 + sizeof(LightChunkData) + 12 + s_plglist.streamGetSize(this);
+}
+
+}