summaryrefslogtreecommitdiff
path: root/AnimationRender
diff options
context:
space:
mode:
authorSyndamia <kamen@syndamia.com>2026-03-28 22:14:32 +0200
committerSyndamia <kamen@syndamia.com>2026-03-28 22:14:32 +0200
commit1cc8f72fb1c44e203a324e274038c2883c351fbb (patch)
treebb3f63143fc643fa9d35bcba6566a0d6ef445cab /AnimationRender
parent6a63e2c0e1f37c502501e1b611e8dc289476c1f2 (diff)
downloadppm_graphics-1cc8f72fb1c44e203a324e274038c2883c351fbb.tar
ppm_graphics-1cc8f72fb1c44e203a324e274038c2883c351fbb.tar.gz
ppm_graphics-1cc8f72fb1c44e203a324e274038c2883c351fbb.zip
feat: Add animation capabilities with linear interpolation
Diffstat (limited to 'AnimationRender')
-rw-r--r--AnimationRender/AnimationRender.c26
-rw-r--r--AnimationRender/AnimationRender.h9
-rw-r--r--AnimationRender/F_Draw.c21
-rw-r--r--AnimationRender/F_Draw.h17
-rw-r--r--AnimationRender/F_Interpolate.c33
-rw-r--r--AnimationRender/F_Interpolate.h20
-rw-r--r--AnimationRender/FrameCallback.h22
7 files changed, 148 insertions, 0 deletions
diff --git a/AnimationRender/AnimationRender.c b/AnimationRender/AnimationRender.c
new file mode 100644
index 0000000..8974ba3
--- /dev/null
+++ b/AnimationRender/AnimationRender.c
@@ -0,0 +1,26 @@
+#include "AnimationRender.h"
+#include "FrameCallback.h"
+
+void RenderAnimation(u32 width, u32 height, u32 totalFrames, const FrameCallback** callbacks, usize sizeCallbacks) {
+ RGBImage frameBuffer = RGBImage_new(width, height);
+
+ struct FrameContext fc;
+ fc.startFrame = 0;
+ fc.endFrame = totalFrames;
+ fc.frameBuffer = frameBuffer;
+
+ for (u32 f = 0; f < totalFrames; ++f) {
+ fc.frame = f;
+ for (usize i = 0; i < sizeCallbacks; ++i) {
+ // Soft context reset
+ if (callbacks[i] == NULL) {
+ fc.startFrame = 0;
+ fc.endFrame = totalFrames;
+ }
+ else
+ callbacks[i]->callback(callbacks[i]->callback_self, &fc);
+ }
+ }
+
+ RGBImage_delete(&frameBuffer);
+}
diff --git a/AnimationRender/AnimationRender.h b/AnimationRender/AnimationRender.h
new file mode 100644
index 0000000..19545ee
--- /dev/null
+++ b/AnimationRender/AnimationRender.h
@@ -0,0 +1,9 @@
+#ifndef _ANIMATION_RENDER
+#define _ANIMATION_RENDER
+
+#include "../global.h"
+#include "FrameCallback.h"
+
+void RenderAnimation(u32 width, u32 height, u32 totalFrames, const FrameCallback** callbacks, usize sizeCallbacks);
+
+#endif /* _ANIMATION_RENDER */
diff --git a/AnimationRender/F_Draw.c b/AnimationRender/F_Draw.c
new file mode 100644
index 0000000..fb90883
--- /dev/null
+++ b/AnimationRender/F_Draw.c
@@ -0,0 +1,21 @@
+#include "F_Draw.h"
+#include "../FrameRender/FrameRender.h"
+#include <stdlib.h>
+#include <string.h>
+
+void Draw_callback(Draw* self, struct FrameContext* fc) {
+ if (self->startFrame <= fc->frame && fc->frame <= self->endFrame) {
+ RenderFrame(fc->frameBuffer, self->callbacks, self->sizeCallbacks);
+ ppm6_write(stdout, fc->frameBuffer);
+ }
+}
+
+FrameCallback* Draw_setup(Draw obj) {
+ FrameCallback* fca = malloc(sizeof(struct FrameCallback));
+
+ fca->callback = (FrameCallback_callback)Draw_callback;
+ fca->callback_self = malloc(sizeof(obj));
+ memcpy(fca->callback_self, &obj, sizeof(obj));
+
+ return fca;
+}
diff --git a/AnimationRender/F_Draw.h b/AnimationRender/F_Draw.h
new file mode 100644
index 0000000..729cec9
--- /dev/null
+++ b/AnimationRender/F_Draw.h
@@ -0,0 +1,17 @@
+#ifndef F_DRAW
+#define F_DRAW
+
+#include "../global.h"
+#include "../FrameRender/PixelCallback.h"
+#include "FrameCallback.h"
+
+typedef struct Draw {
+ u32 startFrame;
+ u32 endFrame;
+ const PixelCallback** callbacks;
+ usize sizeCallbacks;
+} Draw;
+
+FrameCallback* Draw_setup(Draw obj);
+
+#endif /* F_DRAW */
diff --git a/AnimationRender/F_Interpolate.c b/AnimationRender/F_Interpolate.c
new file mode 100644
index 0000000..cc72163
--- /dev/null
+++ b/AnimationRender/F_Interpolate.c
@@ -0,0 +1,33 @@
+#include "F_Interpolate.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void Interpolate_callback(Interpolate* self, struct FrameContext* fc) {
+ if (self->interpolate == NULL) {
+ fprintf(stderr, "Interpolation function cannot be NULL!\n");
+ return;
+ }
+
+ double p = (double)(fc->frame - fc->startFrame) / (fc->endFrame - fc->startFrame);
+
+ if (0.0 <= p && p <= 1.0)
+ self->interpolate(self->value, self->startValue, self->endValue, p);
+}
+
+FrameCallback* Interpolate_setup(Interpolate obj) {
+ FrameCallback* fca = malloc(sizeof(struct FrameCallback));
+
+ fca->callback = (FrameCallback_callback)Interpolate_callback;
+ fca->callback_self = malloc(sizeof(obj));
+ memcpy(fca->callback_self, &obj, sizeof(obj));
+
+ return fca;
+}
+
+#define NUM_INTERPOLATE(a, b, perc) ((a) * (1.0 - (perc)) + (b) * (perc))
+
+void Interpolate_TransformCenter(TransformCenter* value, const TransformCenter* start, const TransformCenter* end, double progress) {
+ value->centerX = NUM_INTERPOLATE(start->centerX, end->centerX, progress);
+ value->centerY = NUM_INTERPOLATE(start->centerY, end->centerY, progress);
+}
diff --git a/AnimationRender/F_Interpolate.h b/AnimationRender/F_Interpolate.h
new file mode 100644
index 0000000..502fbb4
--- /dev/null
+++ b/AnimationRender/F_Interpolate.h
@@ -0,0 +1,20 @@
+#ifndef F_INTERPOLATE
+#define F_INTERPOLATE
+
+#include "FrameCallback.h"
+#include "../FrameRender/P_TransformCenter.h"
+
+typedef void (*f_interpolate)(void* value, const void* start, const void* end, double progress);
+
+typedef struct Interpolate {
+ f_interpolate interpolate;
+ void* value;
+ const void* startValue;
+ const void* endValue;
+} Interpolate;
+
+FrameCallback* Interpolate_setup(Interpolate obj);
+
+void Interpolate_TransformCenter(TransformCenter* value, const TransformCenter* start, const TransformCenter* end, double progress);
+
+#endif /* F_INTERPOLATE */
diff --git a/AnimationRender/FrameCallback.h b/AnimationRender/FrameCallback.h
new file mode 100644
index 0000000..b3292bb
--- /dev/null
+++ b/AnimationRender/FrameCallback.h
@@ -0,0 +1,22 @@
+#ifndef _FRAME_CALLBACK
+#define _FRAME_CALLBACK
+
+#include "../global.h"
+#include "../RGBImage.h"
+
+struct FrameContext {
+ u32 frame;
+ u32 startFrame;
+ u32 endFrame;
+
+ RGBImage frameBuffer;
+};
+
+typedef void (*FrameCallback_callback)(void* self, struct FrameContext* fc);
+
+typedef struct FrameCallback {
+ FrameCallback_callback callback;
+ void* callback_self;
+} FrameCallback;
+
+#endif /* _FRAME_CALLBACK */