diff options
| author | Syndamia <kamen@syndamia.com> | 2026-03-14 22:39:06 +0200 |
|---|---|---|
| committer | Syndamia <kamen@syndamia.com> | 2026-03-14 22:39:06 +0200 |
| commit | 508bc660f5bdd05ef35662b3acc19d47f1ebb6d9 (patch) | |
| tree | b1d2cce0efe7a4f0c7ec4186b3a6a8d8c6dfbc06 | |
| parent | 4bdd9ba823da792beae6dd4340b4d320437908cb (diff) | |
| download | ppm_graphics-508bc660f5bdd05ef35662b3acc19d47f1ebb6d9.tar ppm_graphics-508bc660f5bdd05ef35662b3acc19d47f1ebb6d9.tar.gz ppm_graphics-508bc660f5bdd05ef35662b3acc19d47f1ebb6d9.zip | |
feat: Separate movement into other callbacks
| -rw-r--r-- | graphics.c | 103 |
1 files changed, 86 insertions, 17 deletions
@@ -2,6 +2,7 @@ #include <stdlib.h> #include <stdint.h> #include <string.h> +#include <math.h> inline int OK(int x) { @@ -12,6 +13,7 @@ typedef uint8_t bool; #define false 0 #define true 1 +typedef int32_t i32; typedef uint32_t u32; ////RGBImage//// @@ -103,7 +105,7 @@ typedef struct Animation { AnimationEventNode* events; } Animation; -typedef ARGB (*PixelRenderer)(const Animation* anim, u32 currentFrame, const ARGB* pixel, u32 row, u32 col, void* priv); +typedef ARGB (*PixelRenderer)(const Animation* anim, u32 currentFrame, ARGB pixel, u32 row, u32 col, void* priv); struct AnimationEventNode { AnimationEventNode* next; @@ -185,7 +187,7 @@ Animation_render(Animation* anim) { for (int 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, currFrame, pixel, r, c, aen->privateData); + ARGB newPixel = aen->renderCallback(anim, currFrame, *pixel, r, c, aen->privateData); ARGB_merge(pixel, newPixel); } @@ -211,12 +213,18 @@ Animation_render(Animation* anim) { ////main//// +struct CheckerPattern { + u32 squareSize; + byte4 colorA; + byte4 colorB; +}; + ARGB -MovingBackground(const Animation* anim, u32 frameIndex, const ARGB* currentPixel, u32 r, u32 c, void* priv) { - ARGB pixel; +CheckerPattern(const Animation* anim, u32 frameIndex, ARGB pixel, u32 r, u32 c, void* priv) { + struct CheckerPattern chp = *(struct CheckerPattern*)priv; - r = (r + frameIndex) / 32; - c = (c + frameIndex) / 32; + r /= chp.squareSize; + c /= chp.squareSize; if ((r + c) % 2 == 0) { ARGB_set(&pixel, 0xFF000000); @@ -235,15 +243,9 @@ struct SquareSettings { }; ARGB -Square(const Animation* anim, u32 frameIndex, const ARGB* currentPixel, u32 r, u32 c, void* priv) { - ARGB pixel; - memcpy(&pixel, currentPixel, sizeof(ARGB)); - +Square(const Animation* anim, u32 frameIndex, ARGB pixel, u32 r, u32 c, void* priv) { struct SquareSettings* set = (struct SquareSettings*)priv; - r = (r - frameIndex * 8) % anim->width; - c = (c - frameIndex * 8) % anim->height; - if (0 <= r && r <= set->width && 0 <= c && c <= set->height) { ARGB_set(&pixel, set->color); } @@ -251,21 +253,88 @@ Square(const Animation* anim, u32 frameIndex, const ARGB* currentPixel, u32 r, u return pixel; } +struct MoveLinear { + u32 startRow; + u32 startCol; + float dRow; + float dCol; + PixelRenderer callback; + void* priv; +}; + +ARGB +MoveLinear(const Animation* anim, u32 frameIndex, ARGB pixel, u32 r, u32 c, void* priv) { + struct MoveLinear ml = *(struct MoveLinear*)priv; + + r = (r + ml.startRow - (u32)(frameIndex * ml.dRow)) % anim->width; + c = (c + ml.startCol - (u32)(frameIndex * ml.dCol)) % anim->height; + + return ml.callback(anim, frameIndex, pixel, r, c, ml.priv); +} + +struct MoveRotate { + float radius; + float theta; + PixelRenderer callback; + void* priv; +}; + +ARGB +MoveRotate(const Animation* anim, u32 frameIndex, ARGB pixel, u32 r, u32 c, void* priv) { + struct MoveRotate mr = *(struct MoveRotate*)priv; + + r = (r + (u32)(mr.radius * cos(mr.theta * frameIndex))) % anim->width; + c = (c + (u32)(mr.radius * sin(mr.theta * frameIndex))) % anim->height; + + return mr.callback(anim, frameIndex, pixel, r, c, mr.priv); +} + int main() { Animation anim = Animation_new(512, 512, 120); - Animation_pushEvent(&anim, 0, 120, MovingBackground, NULL); + // Background + struct CheckerPattern chp1 = { + .squareSize = 32, + .colorA = 0xFF000000, .colorB = 0xFFFF00FF, + }; + struct MoveLinear ml1 = { + .startRow = 0, .startCol = 0, + .dRow = 1, .dCol = 1, + + .callback = CheckerPattern, .priv = &chp1, + }; + Animation_pushEvent(&anim, 0, 120, MoveLinear, &ml1); + // Yellow square struct SquareSettings s1 = { .width = 20, .height = 20, .color = 0xFFFFFF00, }; - Animation_pushEvent(&anim, 0, 30, Square, &s1); + struct MoveRotate mr1 = { + .radius = 20, .theta = 3.14159 / 20, + .callback = Square, .priv = &s1, + }; + struct MoveLinear ml3 = { + .startRow = 0, .startCol = 0, + .dRow = -3, .dCol = 3, + + .callback = MoveRotate, .priv = &mr1, + }; + Animation_pushEvent(&anim, 0, 80, MoveLinear, &ml3); + + // Green square struct SquareSettings s2 = { - .width = 10, .height = 25, .color = 0x5009FAA5, + .width = 25, .height = 40, .color = 0xA009FAA5, }; - Animation_pushEvent(&anim, 60, 100, Square, &s2); + struct MoveLinear ml2 = { + .startRow = 20, .startCol = 5, + .dRow = -4, .dCol = -10, + + .callback = Square, .priv = &s2, + }; + Animation_pushEvent(&anim, 60, 100, MoveLinear, &ml2); + Animation_render(&anim); |
