diff --git a/animations/Makefile b/animations/Makefile index 1435566..72c8f55 100644 --- a/animations/Makefile +++ b/animations/Makefile @@ -53,8 +53,8 @@ ifeq ($(ANIMATION_LOGO_27C3),y) SRC += 27c3.c endif -ifeq ($(ANIMATION_PLASMA),y) - SRC += plasma.c +ifneq (,$(filter y,$(ANIMATION_PLASMA) $(ANIMATION_PSYCHEDELIC))) + SRC += fpmath_patterns.c endif include $(TOPDIR)/rules.mk diff --git a/animations/config.in b/animations/config.in index 332e142..51089ed 100644 --- a/animations/config.in +++ b/animations/config.in @@ -22,6 +22,7 @@ comment "Animations" endmenu bool "Plasma" ANIMATION_PLASMA + bool "Psychedelic" ANIMATION_PSYCHEDELIC comment "Special Animations" bool "Test Animations" ANIMATION_TESTS diff --git a/animations/fpmath_patterns.c b/animations/fpmath_patterns.c new file mode 100644 index 0000000..54f10a7 --- /dev/null +++ b/animations/fpmath_patterns.c @@ -0,0 +1,131 @@ +#include // Floating point math is dog slow on AVR, but I don't care. +#include +#include +#include "../config.h" +#include "../pixel.h" +#include "../util.h" +#include "fpmath_patterns.h" + +#undef DOUBLE_BUFFERING +#ifdef DOUBLE_BUFFERING +#define BUFFER pixmap_buffer +#else +#define BUFFER pixmap +#endif + + +/** + * Pointer to a function which return a value depending on two-dimensional + * coordinates and a "step" value. + * @param x x-coordinate + * @param y y-coordinate + * @param t a step value which changes for each frame, allowing for animations + * @return + */ +typedef unsigned char (*fpmath_pattern_func_t)(unsigned char const x, + unsigned char const y, + double t); + + +/** + * Calculates the distance between two points. + * @param x1 x coordinate of the first point + * @param y1 y coordinate of the first point + * @param x2 x coordinate of the second point + * @param y2 y coordinate of the second point + * @return distance between the points + */ +static double dist(double x1, double y1, double x2, double y2) +{ + return sqrt(((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2))); +} + + +/** + * Draws an animated two dimensional graph for a given function f(x,y,t). + * @param t_start start value for the function's time variable + * @param t_stop stop value for the function's time variable + * @param t_delta value by which the functions timing variable gets incremented + * @param frame_delay frame delay in ms + * @param fpPattern function which generates a pattern depending x, y, t + */ +static void fpmath_pattern(double const t_start, + double const t_stop, + double const t_delta, + unsigned int const frame_delay, + fpmath_pattern_func_t fpPattern) +{ +#ifdef DOUBLE_BUFFERING + // double buffering to reduce half painted pictures + unsigned char pixmap_buffer[NUMPLANE][NUM_ROWS][LINEBYTES]; +#endif + for (double t = t_start; t < t_stop; t += t_delta) + { + for (unsigned char y = 0; y < NUM_ROWS; ++y) + { + for (unsigned char x = 0; x < NUM_COLS; ++x) + { + unsigned char color = fpPattern(x, y, t); + for (uint8_t p = NUMPLANE; p--;) + { + if (p == (color - 1)) + { + BUFFER[p][y][x / 8] |= shl_table[x % 8U]; + } + else + { + BUFFER[p][y][x / 8] &= ~shl_table[x % 8U]; + } + } + } + } +#ifdef DOUBLE_BUFFERING + memcpy(pixmap, pixmap_buffer, sizeof(pixmap)); +#endif + wait(frame_delay); + } +} + + +#ifdef ANIMATION_PLASMA +#define PLASMA_X (1.0 / (NUM_COLS / (2.0 * M_PI))) + +/** + * Draws a simple plasma like pattern. + */ +static unsigned char fpmath_plasma(unsigned char x, unsigned char y, double t) +{ + return (sin(x * PLASMA_X + t) + sin(dist(x, y, NUM_COLS * sin(t) + NUM_COLS, + NUM_ROWS * cos(t) + NUM_ROWS) * PLASMA_X) + 2) * (NUMPLANE - 1) / 2; +} + +void plasma(void) +{ +#ifndef __AVR__ + fpmath_pattern(0.0, 75, 0.1, 80, fpmath_plasma); +#else + fpmath_pattern(0.0, 60.0, 0.1, 1, fpmath_plasma); +#endif +} +#endif + + +#ifdef ANIMATION_PSYCHEDELIC +/** + * Draws flowing circular waves with a rotating center. + */ +static unsigned char fpmath_psycho(unsigned char x, unsigned char y, double t) +{ + return (sin(dist(x, y, NUM_COLS * cos(t), NUM_ROWS * sin(t)) - t * 10) + 1) + * (NUMPLANE - 1); +} + +void psychedelic(void) +{ +#ifndef __AVR__ + fpmath_pattern(0.0, 75, 0.1, 80, fpmath_psycho); +#else + fpmath_pattern(0.0, 60.0, 0.1, 1, fpmath_psycho); +#endif +} +#endif diff --git a/animations/fpmath_patterns.h b/animations/fpmath_patterns.h new file mode 100644 index 0000000..0eb2939 --- /dev/null +++ b/animations/fpmath_patterns.h @@ -0,0 +1,8 @@ +#ifndef FPMATH_PATTERNS_H_ +#define FPMATH_PATTERNS_H_ + +void plasma(void); + +void psychedelic(void); + +#endif /* FPMATH_PATTERNS_H_ */ diff --git a/animations/plasma.c b/animations/plasma.c deleted file mode 100644 index 8254b9a..0000000 --- a/animations/plasma.c +++ /dev/null @@ -1,54 +0,0 @@ -#include // Floating point math is dog slow on AVR, but I don't care. -#include -#include "../config.h" -#include "../pixel.h" -#include "../util.h" -#include "plasma.h" - - -#ifndef __AVR__ - #define FRAME_TICK 80 - #define FRAME_COUNT 750 -#else - #define FRAME_TICK 1 - #define FRAME_COUNT 600 -#endif - -#define PLASMA_X (1.0 / (NUM_COLS / (2.0 * M_PI))) - - -/** - * calculates the distance between two points - * @param x1 x coordinate of the first point - * @param y1 y coordinate of the first point - * @param x2 x coordinate of the second point - * @param y2 y coordinate of the second point - * @return distance between the points - */ -static double dist(double x1, double y1, double x2, double y2) -{ - return sqrt(((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2))); -} - - -/** - * draws a simple plasma effect - */ -void plasma(void) -{ - for (double t = 0; t < (FRAME_COUNT / 10.0); t = t + 0.1) { - for (unsigned char x = 0; x < NUM_COLS; ++x) - { - for (unsigned char y = 0; y < NUM_ROWS; ++y) - { - double nColor1 = sin(x * PLASMA_X + t) + 1; - double nColor2 = sin(dist(x, y, NUM_COLS * sin(t) + NUM_COLS, - NUM_ROWS * cos(t) + NUM_ROWS) * PLASMA_X) + 1; - unsigned char nColor = - ((nColor1 + nColor2) * (NUMPLANE - 1)) / 2; - setpixel((pixel){x, y}, nColor); - } - } - wait(FRAME_TICK); - } -} diff --git a/animations/plasma.h b/animations/plasma.h deleted file mode 100644 index 40beb28..0000000 --- a/animations/plasma.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef PLASMA_H_ -#define PLASMA_H_ - -void plasma(void); - -#endif /* PLASMA_H_ */ diff --git a/display_loop.c b/display_loop.c index d65eedf..ad6e498 100644 --- a/display_loop.c +++ b/display_loop.c @@ -16,6 +16,7 @@ #include "animations/laborlogo.h" #include "animations/27c3.h" #include "animations/plasma.h" +#include "animations/fpmath_patterns.h" #include "animations/mherweg.h" #include "borg_hw/borg_hw.h" #include "can/borg_can.h" @@ -178,6 +179,12 @@ void display_loop(){ break; #endif +#ifdef ANIMATION_PSYCHEDELIC + case 19: + psychedelic(); + break; +#endif + #ifdef ANIMATION_TESTS case 31: