summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Animation.c118
-rw-r--r--Animation.h44
-rw-r--r--AnimationInterpolate.c78
-rw-r--r--AnimationInterpolate.h22
-rw-r--r--AnimationMove.c34
-rw-r--r--AnimationMove.h31
-rw-r--r--AnimationObject.c78
-rw-r--r--AnimationObject.h56
-rw-r--r--FrameRender/FrameRender.c25
-rw-r--r--FrameRender/FrameRender.h10
-rw-r--r--FrameRender/P_Square.c22
-rw-r--r--FrameRender/P_Square.h14
-rw-r--r--FrameRender/P_TransformCenter.c19
-rw-r--r--FrameRender/P_TransformCenter.h14
-rw-r--r--FrameRender/PixelCallback.h20
-rw-r--r--global.h2
-rw-r--r--graphics.c190
17 files changed, 155 insertions, 622 deletions
diff --git a/Animation.c b/Animation.c
deleted file mode 100644
index 2dc6380..0000000
--- a/Animation.c
+++ /dev/null
@@ -1,118 +0,0 @@
-#include "Animation.h"
-#include <stdlib.h>
-
-struct AnimationEventNode {
- AnimationEventNode* next;
-
- u32 startFrame;
- u32 endFrame;
- PixelRenderer renderCallback;
- void* privateData;
-};
-
-AnimationEventNode*
-AnimationEventNode_new(u32 startFrame, u32 endFrame, PixelRenderer renderCallback, void* privateData) {
- AnimationEventNode* aen = (AnimationEventNode*)malloc(sizeof(AnimationEventNode));
- aen->next = NULL;
- aen->startFrame = startFrame;
- aen->endFrame = endFrame;
- aen->renderCallback = renderCallback;
- aen->privateData = privateData;
-
- return aen;
-}
-
-Animation
-Animation_new(u32 width, u32 height, u32 frameCount) {
- return (Animation){
- .width = width,
- .height = height,
- .frameCount = frameCount,
- .duplicateFrames = 0,
- .frameBuffer = RGBImage_new(width, height),
- .events = NULL,
- };
-}
-
-void
-Animation_free(Animation anim) {
- RGBImage_free(anim.frameBuffer);
- while (anim.events != NULL) {
- AnimationEventNode* toFree = anim.events;
- anim.events = anim.events->next;
- free(toFree);
- }
-}
-
-void
-Animation_delete(Animation* anim) {
- Animation_free(*anim);
- anim->width = anim->height = anim->frameCount = 0;
- RGBImage_delete(&anim->frameBuffer);
-}
-
-void
-Animation_pushEvent(Animation* anim, u32 startFrame, u32 endFrame, PixelRenderer renderer, void* privateData) {
- if (anim->events == NULL) {
- anim->events = AnimationEventNode_new(startFrame, endFrame, renderer, privateData);
- return;
- }
-
- AnimationEventNode* prevNode = NULL, *currNode = anim->events;
- while (currNode != NULL) {
- if (startFrame < currNode->startFrame) {
- prevNode->next = AnimationEventNode_new(startFrame, endFrame, renderer, privateData);
- prevNode->next->next = currNode;
- return;
- }
-
- prevNode = currNode;
- currNode = currNode->next;
- }
-
- prevNode->next = AnimationEventNode_new(startFrame, endFrame, renderer, privateData);
-}
-
-void
-Animation_render(Animation* anim) {
- for (u32 currFrame = 0; currFrame < anim->frameCount; ++currFrame) {
- if (anim->events != NULL)
- for (i32 r = 0; r < anim->frameBuffer.width; ++r)
- for (i32 c = 0; c < anim->frameBuffer.height; ++c) {
- for (AnimationEventNode* aen = anim->events; aen != NULL && aen->startFrame <= currFrame; aen = aen->next) {
- ARGB* pixel = RGBImage_at(anim->frameBuffer, r, c);
- ARGB newPixel = aen->renderCallback(anim, (PixelRendererParams){
- .frame = {
- .current = currFrame,
- .start = aen->startFrame,
- .end = aen->endFrame,
- },
- .pixel = *pixel,
- .row = r, .col = c,
- .priv = aen->privateData,
- });
- ARGB_merge(pixel, newPixel);
- }
-
- AnimationEventNode* prevNode = NULL, *currNode = anim->events;
- while (currNode != NULL && currNode->startFrame <= currFrame) {
- if (currNode->endFrame <= currFrame) {
- if (prevNode != NULL)
- prevNode->next = currNode->next;
- else
- anim->events = NULL;
- free(currNode);
- }
- else {
- prevNode = currNode;
- currNode = currNode->next;
- }
- }
- }
-
- ppm6_write(stdout, anim->frameBuffer);
-
- for (u32 duplicates = 0; duplicates < anim->duplicateFrames; ++duplicates)
- ppm6_write(stdout, anim->frameBuffer);
- }
-}
diff --git a/Animation.h b/Animation.h
deleted file mode 100644
index 6cebdb0..0000000
--- a/Animation.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef _ANIMATION
-#define _ANIMATION
-
-#include "RGBImage.h"
-
-struct AnimationEventNode;
-typedef struct AnimationEventNode AnimationEventNode;
-
-typedef struct Animation {
- u32 width;
- u32 height;
- u32 frameCount;
- u32 duplicateFrames;
-
- RGBImage frameBuffer;
- AnimationEventNode* events;
-} Animation;
-
-typedef struct PixelRendererParams {
- struct Frames {
- u32 current;
- u32 start;
- u32 end;
- } frame;
-
- ARGB pixel;
-
- i32 row;
- i32 col;
-
- void* priv;
-} PixelRendererParams;
-
-typedef ARGB (*PixelRenderer)(const Animation* anim, PixelRendererParams params);
-
-AnimationEventNode* AnimationEventNode_new(u32 startFrame, u32 endFrame, PixelRenderer renderCallback, void* privateData);
-Animation Animation_new(u32 width, u32 height, u32 frameCount);
-void Animation_free(Animation anim);
-void Animation_delete(Animation* anim);
-
-void Animation_pushEvent(Animation* anim, u32 startFrame, u32 endFrame, PixelRenderer renderer, void* privateData);
-void Animation_render(Animation* anim);
-
-#endif /* _ANIMATION */
diff --git a/AnimationInterpolate.c b/AnimationInterpolate.c
deleted file mode 100644
index a84b5a2..0000000
--- a/AnimationInterpolate.c
+++ /dev/null
@@ -1,78 +0,0 @@
-#include "AnimationInterpolate.h"
-#include "AnimationObject.h"
-#include "AnimationMove.h"
-#include <string.h>
-
-#define NUM_INTERPOLATE(a, b, perc) (a * (1.0 - (perc)) + b * (perc))
-
-color
-colorInterpolate(color ina, color inb, double percentage) {
- ARGB a, b;
- ARGB_set(&a, ina);
- ARGB_set(&b, inb);
-
- a.a = NUM_INTERPOLATE(a.a, b.a, percentage);
- a.r = NUM_INTERPOLATE(a.r, b.r, percentage);
- a.g = NUM_INTERPOLATE(a.g, b.g, percentage);
- a.b = NUM_INTERPOLATE(a.b, b.b, percentage);
-
- return a.a << 24 | a.r << 16 | a.g << 8 | a.b;
-}
-
-ARGB
-A_Interpolate(const Animation* anim, PixelRendererParams a) {
- struct A_Interpolate in = *(struct A_Interpolate*)a.priv;
-
- if (in.interpolate == NULL) {
- fprintf(stderr, "Interpolation function cannot be NULL!\n");
- ARGB_set(&a.pixel, 0xFFFF00FF);
- return a.pixel;
- }
-
- if (a.frame.current == a.frame.start) {
- memcpy(in.initialValueTemp, in.value, in.initialValueTempSize);
- }
-
- double perc = (double)(a.frame.current - a.frame.start) / (a.frame.end - a.frame.start);
- if (perc < 0.0) perc = 0.0;
- if (perc > 1.0) perc = 1.0;
-
- in.interpolate(in.value, in.initialValueTemp, in.goalValue, perc);
-
- return a.pixel;
-}
-
-void
-AO_LineInterpolate(void* valueLine, const void* initialLine, const void* finalLine, double percentage) {
- struct AO_Line* value = valueLine;
- const struct AO_Line* initial = initialLine, *final = finalLine;
-
- value->a = NUM_INTERPOLATE(initial->a, final->a, percentage);
- value->b = NUM_INTERPOLATE(initial->b, final->b, percentage);
- value->c = NUM_INTERPOLATE(initial->c, final->c, percentage);
- value->width = NUM_INTERPOLATE(initial->width, final->width, percentage);
- value->color = colorInterpolate(initial->color, final->color, percentage);
-}
-
-void
-AM_LinearInterpolate(void* valueIn, const void* initialIn, const void* finalIn, double percentage) {
- struct AM_Linear* value = valueIn;
- const struct AM_Linear* initial = initialIn, *final = finalIn;
-
- value->startRow = NUM_INTERPOLATE(initial->startRow, final->startRow, percentage);
- value->startCol = NUM_INTERPOLATE(initial->startCol, final->startCol, percentage);
- value->dRow = NUM_INTERPOLATE(initial->dRow, final->dRow, percentage);
- value->dCol = NUM_INTERPOLATE(initial->dCol, final->dCol, percentage);
- value->wrapCoordinates = NUM_INTERPOLATE(initial->wrapCoordinates, final->wrapCoordinates, percentage);
-}
-
-void
-AM_SpinInterpolate(void* valueIn, const void* initialIn, const void* finalIn, double percentage) {
- struct AM_Spin* value = valueIn;
- const struct AM_Spin* initial = initialIn, *final = finalIn;
-
- value->theta = NUM_INTERPOLATE(initial->theta, final->theta, percentage);
- value->dTheta = NUM_INTERPOLATE(initial->dTheta, final->dTheta, percentage);
- value->centerRow = NUM_INTERPOLATE(initial->centerRow, final->centerRow, percentage);
- value->centerCol = NUM_INTERPOLATE(initial->centerCol, final->centerCol, percentage);
-}
diff --git a/AnimationInterpolate.h b/AnimationInterpolate.h
deleted file mode 100644
index 18ae841..0000000
--- a/AnimationInterpolate.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _ANIMATION_INTERPOLATE
-#define _ANIMATION_INTERPOLATE
-
-#include "Animation.h"
-
-struct A_Interpolate {
- void* initialValueTemp;
- size_t initialValueTempSize;
-
- void* value;
- void* goalValue;
- void (*interpolate)(void* value, const void* initialState, const void* finalState, double percentage);
-};
-
-ARGB A_Interpolate(const Animation* anim, PixelRendererParams params);
-
-void AO_LineInterpolate(void* valueLine, const void* initialLine, const void* finalLine, double percentage);
-
-void AM_LinearInterpolate(void* valueLinear, const void* initialLinear, const void* finalLinear, double percentage);
-void AM_SpinInterpolate(void* valueSpin, const void* initialSpin, const void* finalSpin, double percentage);
-
-#endif /* _ANIMATION_INTERPOLATE */
diff --git a/AnimationMove.c b/AnimationMove.c
deleted file mode 100644
index 7ac52f9..0000000
--- a/AnimationMove.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "AnimationMove.h"
-#include <math.h>
-
-ARGB
-AM_Linear(const Animation* anim, PixelRendererParams a) {
- struct AM_Linear ml = *(struct AM_Linear*)a.priv;
-
- a.row = (a.row - ml.startRow - (i32)(a.frame.current * ml.dRow));
- a.col = (a.col - ml.startCol - (i32)(a.frame.current * ml.dCol));
-
- if (ml.wrapCoordinates == true) {
- a.row %= anim->width;
- a.col %= anim->height;
- }
-
- a.priv = ml.priv;
- return ml.callback(anim, a);
-}
-
-ARGB
-AM_Spin(const Animation* anim, PixelRendererParams a) {
- struct AM_Spin ms = *(struct AM_Spin*)a.priv;
-
- double radius = sqrt(a.row * a.row + a.col * a.col);
- double phi = atan2(a.col, a.row);
-
- phi += ms.theta + ms.dTheta * a.frame.current;
-
- a.row = (ms.centerRow + (i32)(radius * cos(phi)));
- a.col = (ms.centerCol + (i32)(radius * sin(phi)));
-
- a.priv = ms.priv;
- return ms.callback(anim, a);
-}
diff --git a/AnimationMove.h b/AnimationMove.h
deleted file mode 100644
index 48a3b92..0000000
--- a/AnimationMove.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef _ANIMATION_MOVE
-#define _ANIMATION_MOVE
-
-#include "Animation.h"
-
-struct AM_Linear {
- PixelRenderer callback;
- void* priv;
-
- i32 startRow;
- i32 startCol;
- float dRow;
- float dCol;
- bool wrapCoordinates;
-};
-
-ARGB AM_Linear(const Animation* anim, PixelRendererParams params);
-
-struct AM_Spin {
- PixelRenderer callback;
- void* priv;
-
- float theta;
- float dTheta;
- i32 centerRow;
- i32 centerCol;
-};
-
-ARGB AM_Spin(const Animation* anim, PixelRendererParams params);
-
-#endif /* _ANIMATION_MOVE */
diff --git a/AnimationObject.c b/AnimationObject.c
deleted file mode 100644
index 63594ce..0000000
--- a/AnimationObject.c
+++ /dev/null
@@ -1,78 +0,0 @@
-#include "AnimationObject.h"
-#include <math.h>
-#include <stdlib.h>
-
-ARGB
-AO_CheckerPattern(const Animation* anim, PixelRendererParams a) {
- struct AO_CheckerPattern chp = *(struct AO_CheckerPattern*)a.priv;
-
- a.row /= chp.squareSize;
- a.col /= chp.squareSize;
-
- if ((a.row + a.col) % 2 == 0) {
- ARGB_set(&a.pixel, 0xFF000000);
- }
- else {
- ARGB_set(&a.pixel, 0xFFFF00FF);
- }
-
- return a.pixel;
-}
-
-ARGB
-AO_Square(const Animation* anim, PixelRendererParams a) {
- struct AO_Square* set = (struct AO_Square*)a.priv;
-
- if (0 <= a.row && a.row <= set->width && 0 <= a.col && a.col <= set->height) {
- ARGB_set(&a.pixel, set->color);
- }
-
- return a.pixel;
-}
-
-ARGB
-AO_Circle(const Animation* anim, PixelRendererParams a) {
- struct AO_Circle* cir = (struct AO_Circle*)a.priv;
-
- if (a.row * a.row + a.col * a.col < cir->radius * cir->radius) {
- ARGB_set(&a.pixel, cir->color);
- }
-
- return a.pixel;
-}
-
-ARGB
-AO_Image(const Animation* anim, PixelRendererParams a) {
- struct AO_Image img = *(struct AO_Image*)a.priv;
-
- if (img.noRepeat == true &&
- (a.col < 0 || img.img.width * img.zoom <= a.col ||
- a.row < 0 || img.img.height * img.zoom <= a.row))
- {
- return a.pixel;
- }
-
- return *RGBImage_at(*(RGBImage*)a.priv, a.row / img.zoom, a.col / img.zoom);
-}
-
-ARGB
-AO_Line(const Animation* anim, PixelRendererParams a) {
- struct AO_Line l = *(struct AO_Line*)a.priv;
-
- if (fabs(l.a * a.col + l.b * a.row + l.c) / sqrt(l.a * l.a + l.b * l.b) < l.width) {
- ARGB_set(&a.pixel, l.color);
- }
-
- return a.pixel;
-}
-
-ARGB
-AO_HorSegment(const Animation* anim, PixelRendererParams a) {
- struct AO_HorSegment hs = *(struct AO_HorSegment*)a.priv;
-
- if (abs(a.row) <= hs.width && hs.left <= a.col && a.col <= hs.right) {
- ARGB_set(&a.pixel, hs.color);
- }
-
- return a.pixel;
-}
diff --git a/AnimationObject.h b/AnimationObject.h
deleted file mode 100644
index ef8c3a3..0000000
--- a/AnimationObject.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef _ANIMATION_OBJECT
-#define _ANIMATION_OBJECT
-
-#include "Animation.h"
-
-struct AO_CheckerPattern {
- u32 squareSize;
- color colorA;
- color colorB;
-};
-
-ARGB AO_CheckerPattern(const Animation* anim, PixelRendererParams params);
-
-struct AO_Square {
- u32 width;
- u32 height;
- color color;
-};
-
-ARGB AO_Square(const Animation* anim, PixelRendererParams params);
-
-struct AO_Circle {
- double radius;
- color color;
-};
-
-ARGB AO_Circle(const Animation* anim, PixelRendererParams params);
-
-struct AO_Image {
- RGBImage img;
- double zoom;
- bool noRepeat;
-};
-
-ARGB AO_Image(const Animation* anim, PixelRendererParams params);
-
-struct AO_Line {
- double a;
- double b;
- double c;
- double width;
- color color;
-};
-
-ARGB AO_Line(const Animation* anim, PixelRendererParams params);
-
-struct AO_HorSegment {
- i32 left;
- i32 right;
- double width;
- color color;
-};
-
-ARGB AO_HorSegment(const Animation* anim, PixelRendererParams params);
-
-#endif /* _ANIMATION_OBJECT */
diff --git a/FrameRender/FrameRender.c b/FrameRender/FrameRender.c
new file mode 100644
index 0000000..bf148bd
--- /dev/null
+++ b/FrameRender/FrameRender.c
@@ -0,0 +1,25 @@
+#include "FrameRender.h"
+#include <string.h>
+
+void RenderFrame(RGBImage buffer, const PixelCallback** callbacks, usize sizeCallbacks) {
+ struct PixelContext pc;
+ for (u32 x = 0; x < buffer.width; ++x) {
+ for (u32 y = 0; y < buffer.height; ++y) {
+ pc.x = x;
+ pc.y = y;
+ pc.pixel.a = pc.pixel.r = pc.pixel.g = pc.pixel.b = 0;
+
+ for (usize i = 0; i < sizeCallbacks; ++i) {
+ // Soft context reset
+ if (callbacks[i] == NULL) {
+ pc.x = x;
+ pc.y = y;
+ }
+ else
+ callbacks[i]->callback(callbacks[i]->callback_self, &pc);
+ }
+
+ memcpy(RGBImage_at(buffer, y, x), &pc.pixel, sizeof(pc.pixel));
+ }
+ }
+}
diff --git a/FrameRender/FrameRender.h b/FrameRender/FrameRender.h
new file mode 100644
index 0000000..09037cb
--- /dev/null
+++ b/FrameRender/FrameRender.h
@@ -0,0 +1,10 @@
+#ifndef _FRAME_RENDER
+#define _FRAME_RENDER
+
+#include "../global.h"
+#include "../RGBImage.h"
+#include "PixelCallback.h"
+
+void RenderFrame(RGBImage buffer, const PixelCallback** callbacks, usize sizeCallbacks);
+
+#endif /* _FRAME_RENDER */
diff --git a/FrameRender/P_Square.c b/FrameRender/P_Square.c
new file mode 100644
index 0000000..7865370
--- /dev/null
+++ b/FrameRender/P_Square.c
@@ -0,0 +1,22 @@
+#include "P_Square.h"
+#include "PixelCallback.h"
+#include <stdlib.h>
+#include <string.h>
+
+void Square_callback(Square* self, struct PixelContext* fc) {
+ if (0 <= fc->x && fc->x <= self->width &&
+ 0 <= fc->y && fc->y <= self->height)
+ {
+ ARGB_set(&fc->pixel, self->color);
+ }
+}
+
+PixelCallback* Square_setup(Square obj) {
+ PixelCallback* pca = malloc(sizeof(struct PixelCallback));
+
+ pca->callback = (PixelCallback_callback)Square_callback;
+ pca->callback_self = malloc(sizeof(obj));
+ memcpy(pca->callback_self, &obj, sizeof(obj));
+
+ return pca;
+}
diff --git a/FrameRender/P_Square.h b/FrameRender/P_Square.h
new file mode 100644
index 0000000..1cfbc45
--- /dev/null
+++ b/FrameRender/P_Square.h
@@ -0,0 +1,14 @@
+#ifndef P_SQUARE
+#define P_SQUARE
+
+#include "PixelCallback.h"
+
+typedef struct Square {
+ u32 width;
+ u32 height;
+ color color;
+} Square;
+
+PixelCallback* Square_setup(Square obj);
+
+#endif /* P_SQUARE */
diff --git a/FrameRender/P_TransformCenter.c b/FrameRender/P_TransformCenter.c
new file mode 100644
index 0000000..5388437
--- /dev/null
+++ b/FrameRender/P_TransformCenter.c
@@ -0,0 +1,19 @@
+#include "P_TransformCenter.h"
+#include "PixelCallback.h"
+#include <stdlib.h>
+#include <string.h>
+
+void TransformCenter_callback(TransformCenter* self, struct PixelContext* pc) {
+ pc->x -= self->centerX;
+ pc->y -= self->centerY;
+}
+
+PixelCallback* TransformCenter_setup(TransformCenter obj) {
+ PixelCallback* pca = malloc(sizeof(struct PixelCallback));
+
+ pca->callback = (PixelCallback_callback)TransformCenter_callback;
+ pca->callback_self = malloc(sizeof(obj));
+ memcpy(pca->callback_self, &obj, sizeof(obj));
+
+ return pca;
+}
diff --git a/FrameRender/P_TransformCenter.h b/FrameRender/P_TransformCenter.h
new file mode 100644
index 0000000..ab75c32
--- /dev/null
+++ b/FrameRender/P_TransformCenter.h
@@ -0,0 +1,14 @@
+#ifndef P_TRANSFORMCENTER
+#define P_TRANSFORMCENTER
+
+#include "PixelCallback.h"
+#include "../global.h"
+
+typedef struct TransformCenter {
+ i32 centerX;
+ i32 centerY;
+} TransformCenter;
+
+PixelCallback* TransformCenter_setup(TransformCenter obj);
+
+#endif /* P_TRANSFORMCENTER */
diff --git a/FrameRender/PixelCallback.h b/FrameRender/PixelCallback.h
new file mode 100644
index 0000000..b0aee1f
--- /dev/null
+++ b/FrameRender/PixelCallback.h
@@ -0,0 +1,20 @@
+#ifndef _PIXEL_CALLBACK
+#define _PIXEL_CALLBACK
+
+#include "../global.h"
+#include "../RGBImage.h"
+
+struct PixelContext {
+ i32 x;
+ i32 y;
+ ARGB pixel;
+};
+
+typedef void (*PixelCallback_callback)(void* self, struct PixelContext* pc);
+
+typedef struct PixelCallback {
+ PixelCallback_callback callback;
+ void* callback_self;
+} PixelCallback;
+
+#endif /* _PIXEL_CALLBACK */
diff --git a/global.h b/global.h
index 9b322a9..fc31f28 100644
--- a/global.h
+++ b/global.h
@@ -9,6 +9,6 @@ typedef uint8_t bool;
typedef int32_t i32;
typedef uint32_t u32;
-
+typedef uint32_t usize;
#endif /* _GLOBAL */
diff --git a/graphics.c b/graphics.c
index 4ac5055..6281f6f 100644
--- a/graphics.c
+++ b/graphics.c
@@ -2,169 +2,39 @@
* gcc -std=c99 *.c -lm && ./a.out | ffmpeg -r 30 -i - output.mp4
*/
-#include "Animation.h"
-#include "AnimationObject.h"
-#include "AnimationMove.h"
-#include "AnimationInterpolate.h"
-#include <math.h>
-
-double
-pointDistance(i32 rowA, i32 colA, i32 rowB, i32 colB) {
- return sqrt(pow(rowA - rowB, 2) + pow(colA - colB, 2));
-}
-
-void
-HorSegmentByPoints(
- i32 rowA, i32 colA, i32 rowB, i32 colB,
- struct AO_HorSegment* segment,
- struct AM_Spin* rotate,
- struct AM_Linear* translate)
-{
- segment->left = 0;
- segment->right = pointDistance(rowA, colA, rowB, colB);
-
- rotate->theta = atan2(rowB - rowA, colB - colA);
-
- translate->startRow = rowA;
- translate->startCol = colA;
-
- rotate->callback = AO_HorSegment;
- rotate->priv = segment;
- translate->callback = AM_Spin;
- translate->priv = rotate;
-}
+#include "FrameRender/FrameRender.h"
+#include "FrameRender/P_Square.h"
+#include "FrameRender/P_TransformCenter.h"
+#include "RGBImage.h"
+#include <stdlib.h>
int
main() {
- const u32 FPS = 60;
- Animation anim = Animation_new(512, 512, FPS * 5);
-
- struct AO_Square background = {
- .width = anim.width, .height = anim.height,
- .color = 0xFFF0F0F0,
- };
- Animation_pushEvent(&anim, 0, anim.frameCount, AO_Square, &background);
-
- /* Root node */
- struct AO_Circle rootNode_ = {
- .radius = 60, .color = 0xFFFF0000,
- };
- struct AM_Linear rootNode_linear = {
- .callback = AO_Circle, .priv = &rootNode_,
-
- .startRow = anim.height / 4, .startCol = anim.width / 2,
- };
-
- struct AM_Linear rootNode = rootNode_linear;
-
- /* Child node */
- struct AO_Circle childNode_ = {
- .radius = 60, .color = 0xFF00FF00,
- };
-
- struct AM_Linear childNode_left = {
- .callback = AO_Circle, .priv = &childNode_,
-
- .startRow = anim.height * 3 / 4, .startCol = anim.width / 4,
- };
- struct AM_Linear childNode_right = {
- .callback = AO_Circle, .priv = &childNode_,
-
- .startRow = anim.height * 3 / 4, .startCol = anim.width * 3 / 4,
- };
-
- struct AM_Linear childNode = childNode_right;
-
- /* Root Node --- Child Node */
- struct AO_HorSegment link_ = {
- .color = 0xFFFF00FF, .width = 10,
- };
-
- struct AM_Spin link_spin_left = {};
- struct AM_Linear link_translate_left = {};
- HorSegmentByPoints(
- rootNode_linear.startRow, rootNode_linear.startCol,
- childNode_left.startRow, childNode_left.startCol,
- &link_, &link_spin_left, &link_translate_left);
-
- struct AM_Spin link_spin_right = {};
- struct AM_Linear link_translate_right = {};
- HorSegmentByPoints(
- rootNode_linear.startRow, rootNode_linear.startCol,
- childNode_right.startRow, childNode_right.startCol,
- &link_, &link_spin_right, &link_translate_right);
-
- struct AM_Spin link_spin = link_spin_right;
- struct AM_Linear link_translate = link_translate_right;
- link_translate.priv = &link_spin;
-
- Animation_pushEvent(&anim, 0, anim.frameCount, AM_Linear, &link_translate);
- Animation_pushEvent(&anim, 0, anim.frameCount, AM_Linear, &rootNode);
- Animation_pushEvent(&anim, 0, anim.frameCount, AM_Linear, &childNode);
-
- /* Movement */
-
- struct AM_Linear temp1;
- struct A_Interpolate childNode_moveToLeft = {
- .initialValueTemp = &temp1, .initialValueTempSize = sizeof(temp1),
-
- .interpolate = AM_LinearInterpolate,
- .value = &childNode, .goalValue = &childNode_left,
- };
- struct AM_Spin temp11;
- struct A_Interpolate segment_spin_moveToLeft = {
- .initialValueTemp = &temp11, .initialValueTempSize = sizeof(temp11),
-
- .interpolate = AM_SpinInterpolate,
- .value = &link_spin, .goalValue = &link_spin_left,
- };
- struct AM_Linear temp12;
- struct A_Interpolate segment_translate_moveToLeft = {
- .initialValueTemp = &temp12, .initialValueTempSize = sizeof(temp12),
-
- .interpolate = AM_LinearInterpolate,
- .value = &link_translate, .goalValue = &link_translate_left,
- };
-
- struct AM_Linear temp2;
- struct A_Interpolate childNode_moveToRight = {
- .initialValueTemp = &temp2, .initialValueTempSize = sizeof(temp2),
-
- .interpolate = AM_LinearInterpolate,
- .value = &childNode, .goalValue = &childNode_right,
- };
- struct AM_Spin temp21;
- struct A_Interpolate segment_spin_moveToRight = {
- .initialValueTemp = &temp21, .initialValueTempSize = sizeof(temp21),
-
- .interpolate = AM_SpinInterpolate,
- .value = &link_spin, .goalValue = &link_spin_right,
- };
- struct AM_Linear temp22;
- struct A_Interpolate segment_translate_moveToRight = {
- .initialValueTemp = &temp22, .initialValueTempSize = sizeof(temp22),
-
- .interpolate = AM_LinearInterpolate,
- .value = &link_translate, .goalValue = &link_translate_right,
- };
-
- /* Move child node from right to left */
-
- u32 start = anim.frameCount / 3 - FPS, end = anim.frameCount / 3;
- Animation_pushEvent(&anim, start, end, A_Interpolate, &childNode_moveToLeft);
- Animation_pushEvent(&anim, start, end, A_Interpolate, &segment_spin_moveToLeft);
- Animation_pushEvent(&anim, start, end, A_Interpolate, &segment_translate_moveToLeft);
-
- /* Move child node from left to right */
-
- start = anim.frameCount * 2 / 3 - FPS, end = anim.frameCount * 2 / 3;
- Animation_pushEvent(&anim, start, end, A_Interpolate, &childNode_moveToRight);
- Animation_pushEvent(&anim, start, end, A_Interpolate, &segment_spin_moveToRight);
- Animation_pushEvent(&anim, start, end, A_Interpolate, &segment_translate_moveToRight);
-
- Animation_render(&anim);
-
- Animation_delete(&anim);
+ RGBImage frame = RGBImage_new(512, 512);
+
+ PixelCallback* callbacks[] = {
+ TransformCenter_setup((TransformCenter){
+ .centerX = frame.width / 2, .centerY = frame.width / 2,
+ }),
+ Square_setup((Square){
+ .width = 100, .height = 100, .color = 0xFFFF0000,
+ }),
+ NULL,
+ Square_setup((Square){
+ .width = 200, .height = 200, .color = 0xFF00FFFF,
+ }),
+ };
+ u32 sizeCallbacks = sizeof(callbacks) / sizeof(*callbacks);
+
+ RenderFrame(frame, (const PixelCallback**)callbacks, sizeCallbacks);
+ ppm6_write(stdout, frame);
+
+ RGBImage_delete(&frame);
+ for (u32 i = 0; i < sizeCallbacks; ++i) {
+ if (callbacks[i] == NULL) continue;
+ free(callbacks[i]->callback_self);
+ free(callbacks[i]);
+ }
return 0;
}