Make AuroraDemo great again.

And test out ChatGPT's attempt to create some effects as well.
This commit is contained in:
mrcodetastic 2024-07-29 17:23:53 +01:00
parent e2f856d713
commit f77a5cac9c
44 changed files with 790 additions and 1219 deletions

View file

@ -24,7 +24,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include "Vector.h" #include "Vector2.hpp"
class Attractor { class Attractor {
public: public:
@ -33,7 +33,7 @@ public:
PVector location; // Location PVector location; // Location
Attractor() { Attractor() {
location = PVector(VPANEL_W/2, VPANEL_H/2); location = PVector(effects.getCenterX(), effects.getCenterY());
mass = 10; mass = 10;
G = .5; G = .5;
} }

View file

@ -21,6 +21,10 @@
- "GFX_Lite" to provide a simple graphics library for drawing on the virtual display. - "GFX_Lite" to provide a simple graphics library for drawing on the virtual display.
GFX_Lite is a fork of AdaFruitGFX and FastLED library combined together, with a focus on simplicity and ease of use. GFX_Lite is a fork of AdaFruitGFX and FastLED library combined together, with a focus on simplicity and ease of use.
Instructions:
* Use the serial input to advance through the patterns, or to toggle auto advance. Sending 'n' will advance to the next
pattern, 'p' will go to the previous pattern. Sending 'a' will toggle auto advance on and off.
*/ */
#define USE_GFX_LITE 1 #define USE_GFX_LITE 1
@ -59,21 +63,21 @@ MatrixPanel_I2S_DMA *matrix = nullptr;
// placeholder for the virtual display object // placeholder for the virtual display object
VirtualMatrixPanel *virtualDisp = nullptr; VirtualMatrixPanel *virtualDisp = nullptr;
// Aurora related
#include "Effects.h"
Effects effects(VPANEL_W, VPANEL_H);
#include "Drawable.h" #include "EffectsLayer.hpp" // FastLED CRGB Pixel Buffer for which the patterns are drawn
#include "Playlist.h" EffectsLayer effects(VPANEL_W, VPANEL_H);
#include "Geometry.h"
#include "Patterns.h" #include "Drawable.hpp"
#include "Geometry.hpp"
#include "Patterns.hpp"
Patterns patterns; Patterns patterns;
/* -------------------------- Some variables -------------------------- */ /* -------------------------- Some variables -------------------------- */
unsigned long ms_current = 0; unsigned long ms_current = 0;
unsigned long ms_previous = 0; unsigned long ms_previous = 0;
unsigned long ms_animation_max_duration = 10000; // 10 seconds unsigned long ms_previous_palette = 0;
unsigned long ms_animation_max_duration = 30000; // 10 seconds
unsigned long next_frame = 0; unsigned long next_frame = 0;
void listPatterns(); void listPatterns();
@ -121,50 +125,71 @@ void setup()
Serial.println("VIRTUAL PANEL HEIGHT " + String(VPANEL_H)); Serial.println("VIRTUAL PANEL HEIGHT " + String(VPANEL_H));
#endif #endif
// setup the effects generator
effects.Setup();
delay(500);
Serial.println("Effects being loaded: ");
listPatterns(); listPatterns();
Serial.println("LastPattern index: " + String(lastPattern)); patterns.setPattern(0);
patterns.setPattern(lastPattern); // // simple noise
patterns.start(); patterns.start();
ms_previous = millis();
Serial.print("Starting with pattern: "); Serial.print("Starting with pattern: ");
Serial.println(patterns.getCurrentPatternName()); Serial.println(patterns.getCurrentPatternName());
} }
void patternAdvance(){ bool autoAdvance = true;
// Go to next pattern in the list (se Patterns.h) char incomingByte = 0;
patterns.stop(); void handleSerialRead()
{
if (Serial.available() > 0) {
patterns.moveRandom(1); // read the incoming byte:
//patterns.move(1); incomingByte = Serial.read();
patterns.start();
if (incomingByte == 'n') {
Serial.println("Going to next pattern");
patterns.move(1);
}
if (incomingByte == 'p') {
Serial.println("Going to previous pattern");
patterns.move(-1);
}
if (incomingByte == 'a') {
autoAdvance = !autoAdvance;
if (autoAdvance)
Serial.println("Auto pattern advance is ON");
else
Serial.println("Auto pattern advance is OFF");
}
ms_previous = millis();
}
} // end handleSerialRead
// Select a random palette as well
effects.RandomPalette();
Serial.print("Changing pattern to: ");
Serial.println(patterns.getCurrentPatternName());
}
void loop() void loop()
{ {
ms_current = millis();
if ( (ms_current - ms_previous) > ms_animation_max_duration )
{
patternAdvance();
// just auto-change the palette handleSerialRead();
effects.RandomPalette();
ms_current = millis();
if (ms_current - ms_previous_palette > 10000) // change colour palette evert 10 seconds
{
effects.RandomPalette();
ms_previous_palette = ms_current;
}
if ( ((ms_current - ms_previous) > ms_animation_max_duration) && autoAdvance)
{
patterns.move(1);
ms_previous = ms_current; ms_previous = ms_current;
} }

View file

@ -322,5 +322,5 @@ class Boid {
} }
}; };
static const uint8_t AVAILABLE_BOID_COUNT = 40; static const uint8_t AVAILABLE_BOID_COUNT = VPANEL_W;
Boid boids[AVAILABLE_BOID_COUNT]; Boid boids[AVAILABLE_BOID_COUNT];

View file

@ -61,7 +61,7 @@
class Effects { class EffectsLayer : public GFX {
public: public:
@ -80,7 +80,7 @@ public:
int height; int height;
int num_leds = 0; int num_leds = 0;
Effects(int w, int h) : width(w), height(h) { EffectsLayer(int w, int h) : GFX(w, h), width(w), height(h) {
// we do dynamic allocation for leds buffer, otherwise esp32 toolchain can't link static arrays of such a big size for 256+ matrices // we do dynamic allocation for leds buffer, otherwise esp32 toolchain can't link static arrays of such a big size for 256+ matrices
leds = (CRGB *)malloc((width * height + 1) * sizeof(CRGB)); leds = (CRGB *)malloc((width * height + 1) * sizeof(CRGB));
@ -93,10 +93,15 @@ public:
noise[i] = (uint8_t *)malloc(height * sizeof(uint8_t)); noise[i] = (uint8_t *)malloc(height * sizeof(uint8_t));
} }
// Set starting palette
currentPalette = RainbowColors_p;
loadPalette(0);
NoiseVariablesSetup();
ClearFrame(); ClearFrame();
} }
~Effects(){ ~EffectsLayer(){
free(leds); free(leds);
for (int i = 0; i < width; ++i) { for (int i = 0; i < width; ++i) {
free(noise[i]); free(noise[i]);
@ -134,6 +139,15 @@ public:
} }
} }
uint16_t getCenterX() {
return width / 2;
}
uint16_t getCenterY() {
return height / 2;
}
// scale the brightness of the screenbuffer down // scale the brightness of the screenbuffer down
void DimAll(byte value) { void DimAll(byte value) {
for (int i = 0; i < num_leds; i++) for (int i = 0; i < num_leds; i++)
@ -186,11 +200,6 @@ public:
static const int HeatColorsPaletteIndex = 6; static const int HeatColorsPaletteIndex = 6;
static const int RandomPaletteIndex = 9; static const int RandomPaletteIndex = 9;
void Setup() {
currentPalette = RainbowColors_p;
loadPalette(0);
NoiseVariablesSetup();
}
void CyclePalette(int offset = 1) { void CyclePalette(int offset = 1) {
loadPalette(paletteIndex + offset); loadPalette(paletteIndex + offset);
@ -679,13 +688,6 @@ public:
} }
} }
// write one pixel with the specified color from the current palette to coordinates
/*
void Pixel(int x, int y, uint8_t colorIndex) {
leds[XY16(x, y)] = ColorFromCurrentPalette(colorIndex);
matrix.drawBackgroundPixelRGB888(x,y, leds[XY16(x, y)]); // now draw it?
}
*/
CRGB ColorFromCurrentPalette(uint8_t index = 0, uint8_t brightness = 255, TBlendType blendType = LINEARBLEND) { CRGB ColorFromCurrentPalette(uint8_t index = 0, uint8_t brightness = 255, TBlendType blendType = LINEARBLEND) {
return ColorFromPalette(currentPalette, index, brightness, currentBlendType); return ColorFromPalette(currentPalette, index, brightness, currentBlendType);
@ -794,7 +796,22 @@ public:
} // end column loop } // end column loop
} /// MoveY } /// MoveY
// Override GFX methods
void drawPixel(int16_t x, int16_t y, uint16_t color) override {
setPixel(x, y, CRGB(color));
}
// Override GFX methods
void drawPixel(int16_t x, int16_t y, CRGB color) override {
setPixel(x, y, color);
}
void fillScreen(uint16_t color) override {
ClearFrame();
}
// Add any other GFX methods you want to override
}; };
#endif #endif

View file

@ -24,7 +24,7 @@
class PatternAttract : public Drawable { class PatternAttract : public Drawable {
private: private:
const int count = 8; const int count = AVAILABLE_BOID_COUNT-1;
Attractor attractor; Attractor attractor;
public: public:
@ -38,7 +38,7 @@ public:
direction = -1; direction = -1;
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
Boid boid = Boid(15, 31 - i); Boid boid = Boid(VPANEL_W/2, VPANEL_H - i);
boid.mass = 1; // random(0.1, 2); boid.mass = 1; // random(0.1, 2);
boid.velocity.x = ((float) random(40, 50)) / 100.0; boid.velocity.x = ((float) random(40, 50)) / 100.0;
boid.velocity.x *= direction; boid.velocity.x *= direction;

View file

@ -24,7 +24,7 @@
class PatternBounce : public Drawable { class PatternBounce : public Drawable {
private: private:
static const int count = 32; static const int count = VPANEL_W-1;
PVector gravity = PVector(0, 0.0125); PVector gravity = PVector(0, 0.0125);
public: public:
@ -56,7 +56,7 @@ public:
boid.update(); boid.update();
effects.drawBackgroundFastLEDPixelCRGB(boid.location.x, boid.location.y, effects.ColorFromCurrentPalette(boid.colorIndex)); effects.setPixel(boid.location.x, boid.location.y, effects.ColorFromCurrentPalette(boid.colorIndex));
if (boid.location.y >= VPANEL_H - 1) { if (boid.location.y >= VPANEL_H - 1) {
boid.location.y = VPANEL_H - 1; boid.location.y = VPANEL_H - 1;

View file

@ -35,7 +35,7 @@ class PatternCube : public Drawable {
int cubeWidth = 28; // Cube size int cubeWidth = 28; // Cube size
float Angx = 20.0, AngxSpeed = 0.05; // rotation (angle+speed) around X-axis float Angx = 20.0, AngxSpeed = 0.05; // rotation (angle+speed) around X-axis
float Angy = 10.0, AngySpeed = 0.05; // rotation (angle+speed) around Y-axis float Angy = 10.0, AngySpeed = 0.05; // rotation (angle+speed) around Y-axis
float Ox = 15.5, Oy = 15.5; // position (x,y) of the frame center float Ox = VPANEL_W/2, Oy = VPANEL_H/2; // position (x,y) of the frame center
int zCamera = 110; // distance from cube to the eye of the camera int zCamera = 110; // distance from cube to the eye of the camera
// Local vertices // Local vertices
@ -151,11 +151,11 @@ class PatternCube : public Drawable {
public: public:
PatternCube() { PatternCube() {
name = (char *)"Cube"; name = (char *)"Cube";
make(cubeWidth); make(VPANEL_W);
} }
unsigned int drawFrame() { unsigned int drawFrame() {
uint8_t blurAmount = beatsin8(2, 10, 255); uint8_t blurAmount = beatsin8(2, 10, 128);
#if FASTLED_VERSION >= 3001000 #if FASTLED_VERSION >= 3001000
blur2d(effects.leds, VPANEL_W, VPANEL_H, blurAmount); blur2d(effects.leds, VPANEL_W, VPANEL_H, blurAmount);
@ -164,8 +164,8 @@ class PatternCube : public Drawable {
#endif #endif
zCamera = beatsin8(2, 100, 140); zCamera = beatsin8(2, 100, 140);
AngxSpeed = beatsin8(3, 1, 10) / 100.0f; AngxSpeed = beatsin8(3, 1, 6) / 100.0f;
AngySpeed = beatcos8(5, 1, 10) / 100.0f; AngySpeed = effects.beatcos8(5, 1, 6) / 100.0f;
// Update values // Update values
Angx += AngxSpeed; Angx += AngxSpeed;
@ -188,7 +188,7 @@ class PatternCube : public Drawable {
{ {
e = edge + i; e = edge + i;
if (!e->visible) { if (!e->visible) {
matrix.drawLine(screen[e->x].x, screen[e->x].y, screen[e->y].x, screen[e->y].y, color); effects.drawLine(screen[e->x].x, screen[e->x].y, screen[e->y].x, screen[e->y].y, color);
} }
} }
@ -200,7 +200,7 @@ class PatternCube : public Drawable {
e = edge + i; e = edge + i;
if (e->visible) if (e->visible)
{ {
matrix.drawLine(screen[e->x].x, screen[e->x].y, screen[e->y].x, screen[e->y].y, color); effects.drawLine(screen[e->x].x, screen[e->x].y, screen[e->y].x, screen[e->y].y, color);
} }
} }

View file

@ -1,118 +0,0 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from FastLED Fire2012 example by Mark Kriegsman: https://github.com/FastLED/FastLED/tree/master/examples/Fire2012WithPalette
* Copyright (c) 2013 FastLED
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternFire_H
#define PatternFire_H
#ifndef Effects_H
#include "Effects.h"
#endif
class PatternFire : public Drawable {
private:
public:
PatternFire() {
name = (char *)"Fire";
}
// There are two main parameters you can play with to control the look and
// feel of your fire: COOLING (used in step 1 above), and SPARKING (used
// in step 3 above).
//
// cooling: How much does the air cool as it rises?
// Less cooling = taller flames. More cooling = shorter flames.
// Default 55, suggested range 20-100
int cooling = 100;
// sparking: What chance (out of 255) is there that a new spark will be lit?
// Higher chance = more roaring fire. Lower chance = more flickery fire.
// Default 120, suggested range 50-200.
unsigned int sparking = 100;
unsigned int drawFrame() {
// Add entropy to random number generator; we use a lot of it.
random16_add_entropy( random16());
effects.DimAll(235);
for (int x = 0; x < VPANEL_W; x++) {
// Step 1. Cool down every cell a little
for (int y = 0; y < VPANEL_H; y++) {
int xy = XY16(x, y);
heat[xy] = qsub8(heat[xy], random8(0, ((cooling * 10) / VPANEL_H) + 2));
}
// Step 2. Heat from each cell drifts 'up' and diffuses a little
for (int y = 0; y < VPANEL_H; y++) {
heat[XY16(x, y)] = (heat[XY16(x, y + 1)] + heat[XY16(x, y + 2)] + heat[XY16(x, y + 2)]) / 3;
}
// Step 2. Randomly ignite new 'sparks' of heat
if (random8() < sparking) {
// int x = (p[0] + p[1] + p[2]) / 3;
int xy = XY16(x, VPANEL_H - 1);
heat[xy] = qadd8(heat[xy], random8(160, 255));
}
// Step 4. Map from heat cells to LED colors
for (int y = 0; y < VPANEL_H; y++) {
int xy = XY16(x, y);
byte colorIndex = heat[xy];
// Recommend that you use values 0-240 rather than
// the usual 0-255, as the last 15 colors will be
// 'wrapping around' from the hot end to the cold end,
// which looks wrong.
colorIndex = scale8(colorIndex, 200);
// override color 0 to ensure a black background?
if (colorIndex != 0)
// effects.leds[xy] = CRGB::Black;
// else
effects.leds[xy] = effects.ColorFromCurrentPalette(colorIndex);
}
}
// Noise
noise_x += 1000;
noise_y += 1000;
noise_z += 1000;
noise_scale_x = 4000;
noise_scale_y = 4000;
effects.FillNoise();
effects.MoveX(2);
effects.MoveFractionalNoiseX(2);
effects.ShowFrame();
return 15;
}
};
#endif

View file

@ -1,109 +0,0 @@
/*
Aurora: https://github.com/pixelmatix/aurora
Copyright (c) 2014 Jason Coon
Added by @Kosso. Cobbled together from various places which I can't remember. I'll update this when I track it down.
Requires PaletteFireKoz.h
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternFireKoz_H
#define PatternFireKoz_H
class PatternFireKoz : public Drawable {
private:
const int FIRE_HEIGHT = 800;
int Bit = 0, NBit = 1;
float fire_c;
// might not need this buffer here... there some led buffers set up in Effects.h
uint8_t fireBuffer[VPANEL_W][VPANEL_H][2];
public:
PatternFireKoz() {
name = (char *)"FireKoz";
}
unsigned int drawFrame() {
for (int x = 1; x < VPANEL_W - 1; x++)
{
fireBuffer[x][VPANEL_H - 2][Bit] = random(0, FIRE_HEIGHT);
if (random(0, 100) > 80)
{
fireBuffer[x][VPANEL_H - 2][Bit] = 0;
fireBuffer[x][VPANEL_H - 3][Bit] = 0;
}
}
for (int y = 1; y < VPANEL_H - 1; y++)
{
for (int x = 1; x < VPANEL_W - 1; x++)
{
fire_c = (fireBuffer[x - 1][y][Bit] +
fireBuffer[x + 1][y][Bit] +
fireBuffer[x][y - 1][Bit] +
fireBuffer[x][y + 1][Bit] +
fireBuffer[x][y][Bit]) /
5.0;
fire_c = (fireBuffer[x - 1][y][Bit] +
fireBuffer[x + 1][y][Bit] +
fireBuffer[x][y - 1][Bit] +
fireBuffer[x][y + 1][Bit] +
fireBuffer[x][y][Bit]) /
5.0;
if (fire_c > (FIRE_HEIGHT / 2) && fire_c < FIRE_HEIGHT) {
fire_c -= 0.2;
} else if (fire_c > (FIRE_HEIGHT / 4) && fire_c < (FIRE_HEIGHT / 2)) {
fire_c -= 0.4;
} else if (fire_c <= (FIRE_HEIGHT / 8)) {
fire_c -= 0.7;
} else {
fire_c -= 1;
}
if (fire_c < 0)
fire_c = 0;
if (fire_c >= FIRE_HEIGHT + 1)
fire_c = FIRE_HEIGHT - 1;
fireBuffer[x][y - 1][NBit] = fire_c;
int index = (int)fire_c * 3;
if (fire_c == 0)
{
effects.drawBackgroundFastLEDPixelCRGB(x, y, CRGB(0, 0, 0));
}
else
{
effects.drawBackgroundFastLEDPixelCRGB(x, y, CRGB(palette_fire[index], palette_fire[index + 1], palette_fire[index + 2]));
}
}
}
//display.drawRect(0, 0, VPANEL_W, VPANEL_H, display.color565(25, 25, 25));
NBit = Bit;
Bit = 1 - Bit;
effects.ShowFrame();
return 30; // no idea what this is for...
}
};
#endif

View file

@ -1,3 +1,117 @@
/*
Aurora: https://github.com/pixelmatix/aurora
Copyright (c) 2014 Jason Coon
Added by @Kosso. Cobbled together from various places which I can't remember. I'll update this when I track it down.
Requires PaletteFireKoz.h
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternFireKoz_H
#define PatternFireKoz_H
const uint8_t PROGMEM palette_fire[] = {/* RGB888 R,G,B,R,G,B,R,G,B,... */ const uint8_t PROGMEM palette_fire[] = {/* RGB888 R,G,B,R,G,B,R,G,B,... */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x05,0x00,0x00,0x0a,0x00,0x00,0x10,0x00,0x00,0x15,0x00,0x00,0x1b,0x00,0x00,0x20,0x00,0x00,0x25,0x00,0x00,0x2b,0x00,0x00,0x31,0x00,0x00,0x36,0x00,0x00,0x3c,0x00,0x00,0x41,0x00,0x00,0x46,0x00,0x00,0x4c,0x00,0x00,0x52,0x00,0x00,0x57,0x00,0x00,0x5d,0x00,0x00,0x62,0x00,0x00,0x68,0x00,0x00,0x6d,0x00,0x00,0x73,0x00,0x00,0x79,0x00,0x00,0x7e,0x00,0x00,0x83,0x00,0x00,0x89,0x00,0x00,0x8e,0x00,0x00,0x94,0x00,0x00,0x9a,0x00,0x00,0x9f,0x00,0x00,0xa5,0x00,0x00,0xaa,0x00,0x00,0xb0,0x00,0x00,0xb5,0x00,0x00,0xbb,0x00,0x00,0xc0,0x00,0x00,0xc6,0x00,0x00,0xcb,0x00,0x00,0xd1,0x00,0x00,0xd7,0x00,0x00,0xdc,0x00,0x00,0xe1,0x00,0x00,0xe6,0x00,0x00,0xe8,0x02,0x00,0xe9,0x08,0x00,0xe9,0x0f,0x00,0xe9,0x13,0x00,0xe9,0x16,0x00,0xe9,0x1b,0x00,0xe9,0x21,0x00,0xe9,0x26,0x00,0xe9,0x2a,0x00,0xe9,0x2e,0x00,0xe9,0x32,0x00,0xe9,0x37,0x00,0xe9,0x3b,0x00,0xe9,0x3f,0x00,0xe9,0x44,0x00,0xe9,0x4a,0x00,0xe9,0x4e,0x00,0xe9,0x52,0x00,0xe9,0x56,0x00,0xe9,0x5a,0x00,0xe9,0x5d,0x00,0xe9,0x63,0x00,0xe9,0x67,0x00,0xe9,0x6b,0x00,0xe9,0x71,0x00,0xe9,0x77,0x00,0xe9,0x78,0x00,0xe9,0x7c,0x00,0xe9,0x81,0x00,0xe9,0x86,0x00,0xe9,0x8b,0x00,0xe9,0x8f,0x00,0xe9,0x93,0x00,0xe9,0x99,0x00,0xe9,0x9d,0x00,0xe9,0xa0,0x00,0xe9,0xa4,0x00,0xe9,0xaa,0x00,0xe9,0xb0,0x00,0xe9,0xb4,0x00,0xe9,0xb5,0x00,0xe9,0xb9,0x00,0xe9,0xbe,0x00,0xe9,0xc3,0x00,0xe9,0xc9,0x00,0xe9,0xce,0x00,0xe9,0xd2,0x00,0xe9,0xd6,0x00,0xe9,0xd9,0x00,0xe9,0xdd,0x00,0xe9,0xe2,0x00,0xe9,0xe7,0x02,0xe9,0xe9,0x0e,0xe9,0xe9,0x1c,0xe9,0xe9,0x28,0xe9,0xe9,0x38,0xe9,0xe9,0x48,0xe9,0xe9,0x57,0xe9,0xe9,0x67,0xe9,0xe9,0x73,0xe9,0xe9,0x81,0xe9,0xe9,0x90,0xe9,0xe9,0xa1,0xe9,0xe9,0xb1,0xe9,0xe9,0xbf,0xe9,0xe9,0xcb,0xe9,0xe9,0xcb,0xe9,0xe9,0xcd,0xe9,0xe9,0xd9,0xe9,0xe9,0xe5,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe7,0xe7,0xe7,0xe7,0xe7,0xe7,0xe6,0xe6,0xe6,0xe4,0xe4,0xe4,0xe3,0xe3,0xe3,0xe0,0xe0,0xe0,0xdc,0xdc,0xdc,0xd8,0xd8,0xd8,0xd2,0xd2,0xd2,0xca,0xca,0xca,0xc1,0xc1,0xc1,0xb7,0xb7,0xb7,0xab,0xab,0xab,0x9d,0x9d,0x9d,0x8f,0x8f,0x8f,0x81,0x81,0x81,0x72,0x72,0x72,0x64,0x64,0x64,0x56,0x56,0x56,0x4a,0x4a,0x4a,0x3e,0x3e,0x3e,0x33,0x33,0x33,0x2a,0x2a,0x2a,0x22,0x22,0x22,0x1b,0x1b,0x1b,0x16,0x16,0x16,0x11,0x11,0x11,0x0d,0x0d,0x0d,0x0b,0x0b,0x0b,0x08,0x08,0x08,0x07,0x07,0x07,0x06,0x06,0x06,0x05,0x05,0x05,0x04,0x04,0x04,0x03,0x03,0x03,0x03,0x03,0x03,0x02,0x02,0x02,0x02,0x02,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x05,0x00,0x00,0x0a,0x00,0x00,0x10,0x00,0x00,0x15,0x00,0x00,0x1b,0x00,0x00,0x20,0x00,0x00,0x25,0x00,0x00,0x2b,0x00,0x00,0x31,0x00,0x00,0x36,0x00,0x00,0x3c,0x00,0x00,0x41,0x00,0x00,0x46,0x00,0x00,0x4c,0x00,0x00,0x52,0x00,0x00,0x57,0x00,0x00,0x5d,0x00,0x00,0x62,0x00,0x00,0x68,0x00,0x00,0x6d,0x00,0x00,0x73,0x00,0x00,0x79,0x00,0x00,0x7e,0x00,0x00,0x83,0x00,0x00,0x89,0x00,0x00,0x8e,0x00,0x00,0x94,0x00,0x00,0x9a,0x00,0x00,0x9f,0x00,0x00,0xa5,0x00,0x00,0xaa,0x00,0x00,0xb0,0x00,0x00,0xb5,0x00,0x00,0xbb,0x00,0x00,0xc0,0x00,0x00,0xc6,0x00,0x00,0xcb,0x00,0x00,0xd1,0x00,0x00,0xd7,0x00,0x00,0xdc,0x00,0x00,0xe1,0x00,0x00,0xe6,0x00,0x00,0xe8,0x02,0x00,0xe9,0x08,0x00,0xe9,0x0f,0x00,0xe9,0x13,0x00,0xe9,0x16,0x00,0xe9,0x1b,0x00,0xe9,0x21,0x00,0xe9,0x26,0x00,0xe9,0x2a,0x00,0xe9,0x2e,0x00,0xe9,0x32,0x00,0xe9,0x37,0x00,0xe9,0x3b,0x00,0xe9,0x3f,0x00,0xe9,0x44,0x00,0xe9,0x4a,0x00,0xe9,0x4e,0x00,0xe9,0x52,0x00,0xe9,0x56,0x00,0xe9,0x5a,0x00,0xe9,0x5d,0x00,0xe9,0x63,0x00,0xe9,0x67,0x00,0xe9,0x6b,0x00,0xe9,0x71,0x00,0xe9,0x77,0x00,0xe9,0x78,0x00,0xe9,0x7c,0x00,0xe9,0x81,0x00,0xe9,0x86,0x00,0xe9,0x8b,0x00,0xe9,0x8f,0x00,0xe9,0x93,0x00,0xe9,0x99,0x00,0xe9,0x9d,0x00,0xe9,0xa0,0x00,0xe9,0xa4,0x00,0xe9,0xaa,0x00,0xe9,0xb0,0x00,0xe9,0xb4,0x00,0xe9,0xb5,0x00,0xe9,0xb9,0x00,0xe9,0xbe,0x00,0xe9,0xc3,0x00,0xe9,0xc9,0x00,0xe9,0xce,0x00,0xe9,0xd2,0x00,0xe9,0xd6,0x00,0xe9,0xd9,0x00,0xe9,0xdd,0x00,0xe9,0xe2,0x00,0xe9,0xe7,0x02,0xe9,0xe9,0x0e,0xe9,0xe9,0x1c,0xe9,0xe9,0x28,0xe9,0xe9,0x38,0xe9,0xe9,0x48,0xe9,0xe9,0x57,0xe9,0xe9,0x67,0xe9,0xe9,0x73,0xe9,0xe9,0x81,0xe9,0xe9,0x90,0xe9,0xe9,0xa1,0xe9,0xe9,0xb1,0xe9,0xe9,0xbf,0xe9,0xe9,0xcb,0xe9,0xe9,0xcb,0xe9,0xe9,0xcd,0xe9,0xe9,0xd9,0xe9,0xe9,0xe5,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe7,0xe7,0xe7,0xe7,0xe7,0xe7,0xe6,0xe6,0xe6,0xe4,0xe4,0xe4,0xe3,0xe3,0xe3,0xe0,0xe0,0xe0,0xdc,0xdc,0xdc,0xd8,0xd8,0xd8,0xd2,0xd2,0xd2,0xca,0xca,0xca,0xc1,0xc1,0xc1,0xb7,0xb7,0xb7,0xab,0xab,0xab,0x9d,0x9d,0x9d,0x8f,0x8f,0x8f,0x81,0x81,0x81,0x72,0x72,0x72,0x64,0x64,0x64,0x56,0x56,0x56,0x4a,0x4a,0x4a,0x3e,0x3e,0x3e,0x33,0x33,0x33,0x2a,0x2a,0x2a,0x22,0x22,0x22,0x1b,0x1b,0x1b,0x16,0x16,0x16,0x11,0x11,0x11,0x0d,0x0d,0x0d,0x0b,0x0b,0x0b,0x08,0x08,0x08,0x07,0x07,0x07,0x06,0x06,0x06,0x05,0x05,0x05,0x04,0x04,0x04,0x03,0x03,0x03,0x03,0x03,0x03,0x02,0x02,0x02,0x02,0x02,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
}; };
class PatternFireKoz : public Drawable {
private:
const int FIRE_HEIGHT = 800;
int Bit = 0, NBit = 1;
float fire_c;
// might not need this buffer here... there some led buffers set up in EffectsLayer.h
uint8_t fireBuffer[VPANEL_W][VPANEL_H][2];
public:
PatternFireKoz() {
name = (char *)"FireKoz";
}
void start(){
effects.ClearFrame();
}
unsigned int drawFrame() {
for (int x = 1; x < VPANEL_W - 1; x++)
{
fireBuffer[x][VPANEL_H - 2][Bit] = random(0, FIRE_HEIGHT);
if (random(0, 100) > 80)
{
fireBuffer[x][VPANEL_H - 2][Bit] = 0;
fireBuffer[x][VPANEL_H - 3][Bit] = 0;
}
}
for (int y = 1; y < VPANEL_H - 1; y++)
{
for (int x = 1; x < VPANEL_W - 1; x++)
{
fire_c = (fireBuffer[x - 1][y][Bit] +
fireBuffer[x + 1][y][Bit] +
fireBuffer[x][y - 1][Bit] +
fireBuffer[x][y + 1][Bit] +
fireBuffer[x][y][Bit]) /
5.0;
fire_c = (fireBuffer[x - 1][y][Bit] +
fireBuffer[x + 1][y][Bit] +
fireBuffer[x][y - 1][Bit] +
fireBuffer[x][y + 1][Bit] +
fireBuffer[x][y][Bit]) /
5.0;
if (fire_c > (FIRE_HEIGHT / 2) && fire_c < FIRE_HEIGHT) {
fire_c -= 0.2;
} else if (fire_c > (FIRE_HEIGHT / 4) && fire_c < (FIRE_HEIGHT / 2)) {
fire_c -= 0.4;
} else if (fire_c <= (FIRE_HEIGHT / 8)) {
fire_c -= 0.7;
} else {
fire_c -= 1;
}
if (fire_c < 0)
fire_c = 0;
if (fire_c >= FIRE_HEIGHT + 1)
fire_c = FIRE_HEIGHT - 1;
fireBuffer[x][y - 1][NBit] = fire_c;
int index = (int)fire_c * 3;
if (fire_c == 0)
{
effects.setPixel(x, y, CRGB(0, 0, 0));
}
else
{
effects.setPixel(x, y, CRGB(palette_fire[index], palette_fire[index + 1], palette_fire[index + 2]));
}
}
}
//display.drawRect(0, 0, VPANEL_W, VPANEL_H, display.color565(25, 25, 25));
NBit = Bit;
Bit = 1 - Bit;
effects.ShowFrame();
return 30; // no idea what this is for...
}
};
#endif

View file

@ -46,7 +46,7 @@ class PatternFlock : public Drawable {
name = (char *)"Flock"; name = (char *)"Flock";
} }
static const int boidCount = 10; static const int boidCount = VPANEL_W-1;
Boid predator; Boid predator;
PVector wind; PVector wind;

View file

@ -31,19 +31,21 @@ class PatternIncrementalDrift : public Drawable {
} }
unsigned int drawFrame() { unsigned int drawFrame() {
uint8_t dim = beatsin8(2, 230, 250); //uint8_t dim = beatsin8(2, 230, 250);
effects.DimAll(dim); effects.ShowFrame(); effects.DimAll(250);
for (int i = 2; i <= VPANEL_W / 2; i++) for (int i = 2; i <= VPANEL_W / 2; i++)
{ {
CRGB color = effects.ColorFromCurrentPalette((i - 2) * (240 / (VPANEL_W / 2))); CRGB color = effects.ColorFromCurrentPalette((i - 2) * (240 / (VPANEL_W / 2)));
uint8_t x = effects.beatcos8((17 - i) * 2, VPANEL_W/2 - i, VPANEL_W/2 + i); uint8_t x = effects.beatcos8((17 - i) * 2, effects.getCenterX() - i, effects.getCenterX() + i);
uint8_t y = beatsin8((17 - i) * 2, VPANEL_H/2 - i, VPANEL_H/2 + i); uint8_t y = beatsin8((17 - i) * 2, effects.getCenterY() - i, effects.getCenterY() + i);
effects.setPixel(x, y, color); effects.setPixel(x, y, color);
} }
effects.ShowFrame();
return 0; return 0;
} }
}; };

View file

@ -28,30 +28,35 @@ public:
name = (char *)"Infinity"; name = (char *)"Infinity";
} }
void start() {
effects.ClearFrame();
}
unsigned int drawFrame() { unsigned int drawFrame() {
// dim all pixels on the display slightly // dim all pixels on the display slightly
// to 250/255 (98%) of their current brightness // to 250/255 (98%) of their current brightness
blur2d(effects.leds, VPANEL_W > 255 ? 255 : VPANEL_W, VPANEL_H > 255 ? 255 : VPANEL_H, 250); //blur2d(effects.leds, VPANEL_W > 255 ? 255 : VPANEL_W, VPANEL_H > 255 ? 255 : VPANEL_H, 250);
// effects.DimAll(250); effects.ShowFrame(); // effects.DimAll(250); effects.ShowFrame();
// the Effects class has some sample oscillators // the EffectsLayer class has some sample oscillators
// that move from 0 to 255 at different speeds // that move from 0 to 255 at different speeds
effects.MoveOscillators(); effects.MoveOscillators();
// the horizontal position of the head of the infinity sign // the horizontal position of the head of the infinity sign
// oscillates from 0 to the maximum horizontal and back // oscillates from 0 to the maximum horizontal and back
int x = (VPANEL_W - 1) - effects.p[1]; int x = (VPANEL_W - 4) - effects.p[1];
// the vertical position of the head oscillates // the vertical position of the head oscillates
// from 8 to 23 and back (hard-coded for a 32x32 matrix) // from 8 to 23 and back (hard-coded for a 32x32 matrix)
int y = map8(sin8(effects.osci[3]), 8, 23); int y = map8(sin8(effects.osci[3]), 8, VPANEL_H - 8);
// the hue oscillates from 0 to 255, overflowing back to 0 // the hue oscillates from 0 to 255, overflowing back to 0
byte hue = sin8(effects.osci[5]); byte hue = sin8(effects.osci[5]);
// draw a pixel at x,y using a color from the current palette // draw a pixel at x,y using a color from the current palette
effects.setPixelFromPaletteIndex(x, y, hue); effects.drawTriangle(x,y,x+1,y+1,x+2,y+2,effects.ColorFromCurrentPalette(hue));
////effects.setPixelFromPaletteIndex(x, y, hue);
effects.ShowFrame(); effects.ShowFrame();
return 30; return 30;

View file

@ -1,154 +0,0 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Inspired by 'Space Invader Generator': https://the8bitpimp.wordpress.com/2013/05/07/space-invader-generator
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternInvaders_H
#define PatternInvaders_H
class PatternInvadersSmall : public Drawable {
private:
uint8_t x = 1;
uint8_t y = 1;
public:
PatternInvadersSmall() {
name = (char *)"Invaders Small";
}
void start() {
matrix->fillScreen(0);
}
unsigned int drawFrame() {
CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255));
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 5; j++) {
CRGB color = CRGB::Black;
if (random(0, 2) == 1) color = color1;
effects.setPixel(x + i, y + j, color);
if (i < 2)
effects.setPixel(x + (4 - i), y + j, color);
}
}
x += 6;
if (x > 25) {
x = 1;
y += 6;
}
if (y > 25) y = x = 1;
effects.ShowFrame();
return 125;
}
};
class PatternInvadersMedium : public Drawable {
private:
uint8_t x = 0;
uint8_t y = 0;
public:
PatternInvadersMedium() {
name = (char *)"Invaders Medium";
}
void start() {
matrix->fillScreen(0);
}
unsigned int drawFrame() {
CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255));
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 5; j++) {
CRGB color = CRGB::Black;
if (random(0, 2) == 1) color = color1;
effects.setPixel(x + (i * 2), y + (j * 2), color);
if (i < 2)
effects.setPixel(x + (8 - i * 2), y + (j * 2), color);
}
}
x += 11;
if (x > 22) {
x = 0;
y += 11;
}
if (y > 22) y = x = 0;
effects.ShowFrame();
return 500;
}
};
class PatternInvadersLarge : public Drawable {
private:
public:
PatternInvadersLarge() {
name = (char *)"Invaders Large";
}
void start() {
matrix->fillScreen(0);
}
unsigned int drawFrame() {
matrix->fillScreen(0);
CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255));
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 5; y++) {
CRGB color = CRGB::Black;
if (random(0, 2) == 1) {
color = color1;
}
effects.setPixel(1 + x * 6, 1 + y * 6, color);
if (x < 2)
effects.setPixel(1 + (4 - x) * 6, 1 + y * 6, color);
}
}
effects.ShowFrame();
return 2000;
}
};
#endif

View file

@ -1,129 +0,0 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from Andrew: http://pastebin.com/f22bfe94d
* which, in turn, was "Adapted from the Life example on the Processing.org site"
*
* Made much more colorful by J.B. Langston: https://github.com/jblang/aurora/commit/6db5a884e3df5d686445c4f6b669f1668841929b
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternLife_H
#define PatternLife_H
class Cell {
public:
byte alive : 1;
byte prev : 1;
byte hue: 6;
byte brightness;
};
class PatternLife : public Drawable {
private:
Cell world[VPANEL_W][VPANEL_H];
unsigned int density = 50;
int generation = 0;
void randomFillWorld() {
for (int i = 0; i < VPANEL_W; i++) {
for (int j = 0; j < VPANEL_H; j++) {
if (random(100) < density) {
world[i][j].alive = 1;
world[i][j].brightness = 255;
}
else {
world[i][j].alive = 0;
world[i][j].brightness = 0;
}
world[i][j].prev = world[i][j].alive;
world[i][j].hue = 0;
}
}
}
int neighbours(int x, int y) {
return (world[(x + 1) % VPANEL_W][y].prev) +
(world[x][(y + 1) % VPANEL_H].prev) +
(world[(x + VPANEL_W - 1) % VPANEL_W][y].prev) +
(world[x][(y + VPANEL_H - 1) % VPANEL_H].prev) +
(world[(x + 1) % VPANEL_W][(y + 1) % VPANEL_H].prev) +
(world[(x + VPANEL_W - 1) % VPANEL_W][(y + 1) % VPANEL_H].prev) +
(world[(x + VPANEL_W - 1) % VPANEL_W][(y + VPANEL_H - 1) % VPANEL_H].prev) +
(world[(x + 1) % VPANEL_W][(y + VPANEL_H - 1) % VPANEL_H].prev);
}
public:
PatternLife() {
name = (char *)"Life";
}
unsigned int drawFrame() {
if (generation == 0) {
effects.ClearFrame();
randomFillWorld();
}
// Display current generation
for (int i = 0; i < VPANEL_W; i++) {
for (int j = 0; j < VPANEL_H; j++) {
effects.leds[XY16(i, j)] = effects.ColorFromCurrentPalette(world[i][j].hue * 4, world[i][j].brightness);
}
}
// Birth and death cycle
for (int x = 0; x < VPANEL_W; x++) {
for (int y = 0; y < VPANEL_H; y++) {
// Default is for cell to stay the same
if (world[x][y].brightness > 0 && world[x][y].prev == 0)
world[x][y].brightness *= 0.9;
int count = neighbours(x, y);
if (count == 3 && world[x][y].prev == 0) {
// A new cell is born
world[x][y].alive = 1;
world[x][y].hue += 2;
world[x][y].brightness = 255;
} else if ((count < 2 || count > 3) && world[x][y].prev == 1) {
// Cell dies
world[x][y].alive = 0;
}
}
}
// Copy next generation into place
for (int x = 0; x < VPANEL_W; x++) {
for (int y = 0; y < VPANEL_H; y++) {
world[x][y].prev = world[x][y].alive;
}
}
generation++;
if (generation >= 256)
generation = 0;
effects.ShowFrame();
return 60;
}
};
#endif

View file

@ -38,7 +38,7 @@
#define AMP_BPM 2 #define AMP_BPM 2
#define SKEW_BPM 4 #define SKEW_BPM 4
#define WAVE_TIMEMINSKEW VPANEL_W/8 #define WAVE_TIMEMINSKEW VPANEL_W/8
#define WAVE_TIMEMAXSKEW VPANEL_W/2 #define WAVE_TIMEMAXSKEW effects.getCenterX()
class PatternPendulumWave : public Drawable { class PatternPendulumWave : public Drawable {
public: public:
@ -46,8 +46,9 @@ class PatternPendulumWave : public Drawable {
name = (char *)"Pendulum Wave"; name = (char *)"Pendulum Wave";
} }
unsigned int drawFrame() { unsigned int drawFrame()
effects.ClearFrame(); {
effects.DimAll(192);
for (int x = 0; x < VPANEL_W; ++x) for (int x = 0; x < VPANEL_W; ++x)
{ {

View file

@ -1,82 +0,0 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Based at least in part on someone else's work that I can no longer find.
* Please let me know if you recognize any of this code!
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternPulse_H
#define PatternPulse_H
class PatternPulse : public Drawable {
private:
int hue;
int centerX = 0;
int centerY = 0;
int step = -1;
int maxSteps = 16;
float fadeRate = 0.8;
int diff;
public:
PatternPulse() {
name = (char *)"Pulse";
}
unsigned int drawFrame() {
effects.DimAll(235);
if (step == -1) {
centerX = random(32);
centerY = random(32);
hue = random(256); // 170;
step = 0;
}
if (step == 0) {
matrix.drawCircle(centerX, centerY, step, effects.ColorFromCurrentPalette(hue));
step++;
}
else {
if (step < maxSteps) {
// initial pulse
matrix.drawCircle(centerX, centerY, step, effects.ColorFromCurrentPalette(hue, pow(fadeRate, step - 2) * 255));
// secondary pulse
if (step > 3) {
matrix.drawCircle(centerX, centerY, step - 3, effects.ColorFromCurrentPalette(hue, pow(fadeRate, step - 2) * 255));
}
step++;
}
else {
step = -1;
}
}
effects.standardNoiseSmearing();
effects.ShowFrame();
return 30;
}
};
#endif

View file

@ -36,7 +36,7 @@ class PatternRadar : public Drawable {
unsigned int drawFrame() { unsigned int drawFrame() {
effects.DimAll(254); effects.ShowFrame(); effects.DimAll(254); effects.ShowFrame();
for (int offset = 0; offset < VPANEL_W/2; offset++) { for (int offset = 0; offset < effects.getCenterX(); offset++) {
byte hue = 255 - (offset * 16 + hueoffset); byte hue = 255 - (offset * 16 + hueoffset);
CRGB color = effects.ColorFromCurrentPalette(hue); CRGB color = effects.ColorFromCurrentPalette(hue);
uint8_t x = effects.mapcos8(theta, offset, (VPANEL_W - 1) - offset); uint8_t x = effects.mapcos8(theta, offset, (VPANEL_W - 1) - offset);

View file

@ -28,7 +28,7 @@
class PatternSnake : public Drawable { class PatternSnake : public Drawable {
private: private:
static const byte SNAKE_LENGTH = 16; static const byte SNAKE_LENGTH = 8;
CRGB colors[SNAKE_LENGTH]; CRGB colors[SNAKE_LENGTH];
uint8_t initialHue; uint8_t initialHue;

View file

@ -1,113 +0,0 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from FastLED Fire2012 example by Mark Kriegsman: https://github.com/FastLED/FastLED/tree/master/examples/Fire2012WithPalette
* Copyright (c) 2013 FastLED
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternSpark_H
#define PatternSpark_H
class PatternSpark : public Drawable {
private:
public:
PatternSpark() {
name = (char *)"Spark";
}
// There are two main parameters you can play with to control the look and
// feel of your fire: COOLING (used in step 1 above), and SPARKING (used
// in step 3 above).
//
// COOLING: How much does the air cool as it rises?
// Less cooling = taller flames. More cooling = shorter flames.
// Default 55, suggested range 20-100
uint8_t cooling = 100;
// SPARKING: What chance (out of 255) is there that a new spark will be lit?
// Higher chance = more roaring fire. Lower chance = more flickery fire.
// Default 120, suggested range 50-200.
uint8_t sparking = 50;
unsigned int drawFrame() {
// Add entropy to random number generator; we use a lot of it.
random16_add_entropy( random16());
effects.DimAll(235); effects.ShowFrame();
for (uint8_t x = 0; x < VPANEL_W; x++) {
// Step 1. Cool down every cell a little
for (int y = 0; y < VPANEL_H; y++) {
int xy = XY16(x, y);
heat[xy] = qsub8(heat[xy], random8(0, ((cooling * 10) / VPANEL_H) + 2));
}
// Step 2. Heat from each cell drifts 'up' and diffuses a little
for (int y = 0; y < VPANEL_H; y++) {
heat[XY16(x, y)] = (heat[XY16(x, y + 1)] + heat[XY16(x, y + 2)] + heat[XY16(x, y + 2)]) / 3;
}
// Step 2. Randomly ignite new 'sparks' of heat
if (random8() < sparking) {
uint8_t xt = random8(MATRIX_CENTRE_X - 2, MATRIX_CENTER_X + 3);
int xy = XY16(xt, VPANEL_H - 1);
heat[xy] = qadd8(heat[xy], random8(160, 255));
}
// Step 4. Map from heat cells to LED colors
for (int y = 0; y < VPANEL_H; y++) {
int xy = XY16(x, y);
byte colorIndex = heat[xy];
// Recommend that you use values 0-240 rather than
// the usual 0-255, as the last 15 colors will be
// 'wrapping around' from the hot end to the cold end,
// which looks wrong.
colorIndex = scale8(colorIndex, 240);
// override color 0 to ensure a black background?
if (colorIndex != 0)
// effects.leds[xy] = CRGB::Black;
// else
effects.leds[xy] = effects.ColorFromCurrentPalette(colorIndex);
}
}
// Noise
noise_x += 1000;
noise_y += 1000;
noise_z += 1000;
noise_scale_x = 4000;
noise_scale_y = 4000;
effects.FillNoise();
effects.MoveX(3);
effects.MoveFractionalNoiseX(4);
effects.ShowFrame();
return 15;
}
};
#endif

View file

@ -0,0 +1,103 @@
// Codetastic 2024
// ChatGPT was used to create this.
#ifndef PatternSphereSpin_H
#define PatternSphereSpin_H
#include <vector>
#include <cmath>
struct Point3D {
float x, y, z;
};
struct Point2D {
int x, y;
};
class PatternSphereSpin : public Drawable {
private:
std::vector<Point3D> points;
float angleX = 0.0f;
float angleY = 0.0f;
float distance = 3.0f;
Point2D project(Point3D point, float distance) {
Point2D projected;
projected.x = static_cast<int>((point.x / (distance - point.z)) * VPANEL_W / 2 + VPANEL_W / 2);
projected.y = static_cast<int>((point.y / (distance - point.z)) * VPANEL_H / 2 + VPANEL_H / 2);
return projected;
}
std::vector<Point3D> generateSpherePoints(int numPoints) {
std::vector<Point3D> points;
for (int i = 0; i < numPoints; ++i) {
float theta = 2 * PI * (i / static_cast<float>(numPoints));
for (int j = 0; j < numPoints / 2; ++j) {
float phi = PI * (j / static_cast<float>(numPoints / 2));
points.push_back({ cos(theta) * sin(phi), sin(theta) * sin(phi), cos(phi) });
}
}
return points;
}
void rotatePoints(std::vector<Point3D>& points, float angleX, float angleY) {
for (auto& point : points) {
// Rotate around the X axis
float y = point.y * cos(angleX) - point.z * sin(angleX);
float z = point.y * sin(angleX) + point.z * cos(angleX);
point.y = y;
point.z = z;
// Rotate around the Y axis
float x = point.x * cos(angleY) + point.z * sin(angleY);
z = -point.x * sin(angleY) + point.z * cos(angleY);
point.x = x;
point.z = z;
}
}
public:
PatternSphereSpin() {
name = (char *)"Sphere Spin";
}
void start()
{
points = generateSpherePoints(30);
angleX = 0.0f;
angleY = 0.0f;
distance = 3.0f;
};
unsigned int drawFrame() {
effects.ClearFrame();
// Rotate points
rotatePoints(points, angleX, angleY);
// Project and draw lines between points
for (size_t i = 0; i < points.size(); ++i) {
Point2D p1 = project(points[i], distance);
for (size_t j = i + 1; j < points.size(); ++j) {
Point2D p2 = project(points[j], distance);
effects.drawLine(p1.x, p1.y, p2.x, p2.y, CRGB(255,255,255));
}
}
// Update angles for rotation
angleX += 0.05f;
angleY += 0.05f;
effects.ShowFrame();
return 0;
}
};
#endif

View file

@ -48,7 +48,7 @@ public:
} }
unsigned int drawFrame() { unsigned int drawFrame() {
effects.DimAll(190); effects.ShowFrame();
CRGB color = effects.ColorFromCurrentPalette(speed * 8); CRGB color = effects.ColorFromCurrentPalette(speed * 8);
@ -59,23 +59,26 @@ public:
// target position // target position
float targetDegrees = degrees + speed; float targetDegrees = degrees + speed;
float targetRadians = radians(targetDegrees); float targetRadians = radians(targetDegrees);
int targetX = (int) (MATRIX_CENTER_X + radius * cos(targetRadians)); int targetX = (int) (effects.getCenterX() + radius * cos(targetRadians));
int targetY = (int) (MATRIX_CENTER_Y - radius * sin(targetRadians)); int targetY = (int) (effects.getCenterY() - radius * sin(targetRadians));
float tempDegrees = degrees; float tempDegrees = degrees;
do{ for (int i =0; i < 16; i++)
{
float radians = radians(tempDegrees); float radians = radians(tempDegrees);
x = (int) (MATRIX_CENTER_X + radius * cos(radians)); x = (int) (effects.getCenterX() + radius * cos(radians));
y = (int) (MATRIX_CENTER_Y - radius * sin(radians)); y = (int) (effects.getCenterY() - radius * sin(radians));
effects.drawBackgroundFastLEDPixelCRGB(x, y, color); effects.setPixel(x, y, color);
effects.drawBackgroundFastLEDPixelCRGB(y, x, color); effects.setPixel(y, x, color);
tempDegrees += 1; tempDegrees += 1;
if (tempDegrees >= 360) if (tempDegrees >= 360)
tempDegrees = 0; tempDegrees = 0;
} while (x != targetX || y != targetY);
}
degrees += speed; degrees += speed;
@ -93,6 +96,8 @@ public:
} }
} }
effects.ShowFrame();
return 0; return 0;
} }
}; };

View file

@ -30,12 +30,12 @@ class PatternSpiro : public Drawable {
uint8_t radiusx = VPANEL_W / 4; uint8_t radiusx = VPANEL_W / 4;
uint8_t radiusy = VPANEL_H / 4; uint8_t radiusy = VPANEL_H / 4;
uint8_t minx = VPANEL_W/2 - radiusx; uint8_t minx = effects.getCenterX() - radiusx;
uint8_t maxx = VPANEL_W/2 + radiusx + 1; uint8_t maxx = effects.getCenterX() + radiusx + 1;
uint8_t miny = VPANEL_H/2 - radiusy; uint8_t miny = effects.getCenterY() - radiusy;
uint8_t maxy = VPANEL_H/2 + radiusy + 1; uint8_t maxy = effects.getCenterY() + radiusy + 1;
uint8_t spirocount = 16; uint8_t spirocount = 64;
uint8_t spirooffset = 256 / spirocount; uint8_t spirooffset = 256 / spirocount;
boolean spiroincrement = true; boolean spiroincrement = true;
@ -55,7 +55,7 @@ class PatternSpiro : public Drawable {
}; };
unsigned int drawFrame() { unsigned int drawFrame() {
blur2d(effects.leds, VPANEL_W > 255 ? 255 : VPANEL_W, VPANEL_H > 255 ? 255 : VPANEL_H, 192); blur2d(effects.leds, VPANEL_W > 255 ? 255 : VPANEL_W, VPANEL_H > 255 ? 255 : VPANEL_H, 64);
boolean change = false; boolean change = false;
@ -69,8 +69,8 @@ class PatternSpiro : public Drawable {
CRGB color = effects.ColorFromCurrentPalette(hueoffset + i * spirooffset, 128); CRGB color = effects.ColorFromCurrentPalette(hueoffset + i * spirooffset, 128);
effects.leds[XY16(x2, y2)] += color; effects.leds[XY16(x2, y2)] += color;
if((x2 == VPANEL_W/2 && y2 == VPANEL_H/2) || if((x2 == effects.getCenterX() && y2 == effects.getCenterY()) ||
(x2 == VPANEL_W/2 && y2 == VPANEL_H/2)) change = true; (x2 == effects.getCenterX() && y2 == effects.getCenterY())) change = true;
} }
theta2 += 1; theta2 += 1;

View file

@ -0,0 +1,77 @@
// Codetastic 2024
// ChatGPT was used to create this.
#ifndef PatternStarfield_H
#define PatternStarfield_H
#include <vector>
#define STAR_COUNT 128
// Star structure
struct Star {
float x, y, z;
CRGB colour;
};
class PatternStarfield : public Drawable {
private:
std::vector<Star> stars;
float speed = 0.5f;
public:
PatternStarfield() {
name = (char *)"Starfield";
}
void start()
{
stars.resize(STAR_COUNT);
for (int i = 0; i < STAR_COUNT; ++i) {
stars[i] = { static_cast<float>(rand() % VPANEL_W - VPANEL_W / 2),
static_cast<float>(rand() % VPANEL_H - VPANEL_H / 2),
static_cast<float>(rand() % VPANEL_W),
effects.ColorFromCurrentPalette(rand()*255)
};
} // random positions
};
unsigned int drawFrame() {
effects.DimAll(250);
// Update star positions
for (auto& star : stars) {
star.z -= speed;
if (star.z <= 0) {
star.z = VPANEL_W;
star.x = static_cast<float>(rand() % VPANEL_W - VPANEL_W / 2);
star.y = static_cast<float>(rand() % VPANEL_H - VPANEL_H / 2);
}
}
// draw position
for (const auto& star : stars) {
float k = 128.0f / star.z;
int x = static_cast<int>(star.x * k + VPANEL_W / 2);
int y = static_cast<int>(star.y * k + VPANEL_H / 2);
if (x >= 0 && x < VPANEL_W && y >= 0 && y < VPANEL_H) {
// TODO: Get brighter as we get closer to edges?
effects.setPixel(x, y, star.colour);
}
}
effects.ShowFrame();
return 0;
}
};
#endif

View file

@ -1,79 +0,0 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from SmartMatrixSwirl by Mark Kriegsman: https://gist.github.com/kriegsman/5adca44e14ad025e6d3b
* https://www.youtube.com/watch?v=bsGBT-50cts
* Copyright (c) 2014 Mark Kriegsman
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternSwirl_H
class PatternSwirl : public Drawable {
private:
const uint8_t borderWidth = 2;
public:
PatternSwirl() {
name = (char *)"Swirl";
}
void start() {
effects.ClearFrame();
}
unsigned int drawFrame() {
// Apply some blurring to whatever's already on the matrix
// Note that we never actually clear the matrix, we just constantly
// blur it repeatedly. Since the blurring is 'lossy', there's
// an automatic trend toward black -- by design.
uint8_t blurAmount = beatsin8(2, 10, 255);
#if FASTLED_VERSION >= 3001000
blur2d(effects.leds, VPANEL_W > 255 ? 255 : VPANEL_W, VPANEL_H > 255 ? 255 : VPANEL_H, blurAmount);
#else
effects.DimAll(blurAmount);
#endif
// Use two out-of-sync sine waves
uint8_t i = beatsin8(256/VPANEL_H, borderWidth, VPANEL_W - borderWidth);
uint8_t j = beatsin8(2048/VPANEL_W, borderWidth, VPANEL_H - borderWidth);
// Also calculate some reflections
uint8_t ni = (VPANEL_W - 1) - i;
uint8_t nj = (VPANEL_H - 1) - j;
// The color of each point shifts over time, each at a different speed.
uint16_t ms = millis();
effects.leds[XY16(i, j)] += effects.ColorFromCurrentPalette(ms / 11);
//effects.leds[XY16(j, i)] += effects.ColorFromCurrentPalette(ms / 13); // this doesn't work for non-square matrices
effects.leds[XY16(ni, nj)] += effects.ColorFromCurrentPalette(ms / 17);
//effects.leds[XY16(nj, ni)] += effects.ColorFromCurrentPalette(ms / 29); // this doesn't work for non-square matrices
effects.leds[XY16(i, nj)] += effects.ColorFromCurrentPalette(ms / 37);
effects.leds[XY16(ni, j)] += effects.ColorFromCurrentPalette(ms / 41);
effects.ShowFrame();
return 0;
}
};
#endif

View file

@ -0,0 +1,54 @@
// Codetastic 2024
// ChatGPT was used to create this.
#ifndef PatternTheMatrix_H
#define PatternTheMatrix_H
// Function to generate a random greenish color for the digital rain
CRGB generateRainColor() {
return CHSV(96 + random(64), 255, 255); // Greenish colors
}
class PatternTheMatrix : public Drawable {
public:
PatternTheMatrix() {
name = (char *)"The Matrix";
}
// Function to draw the digital rain effect
void drawDigitalRain() {
// Shift all the LEDs down by one row
for (int x = 0; x < VPANEL_W ; x++) {
for (int y = VPANEL_H - 1; y > 0; y--) {
effects.leds[XY(x, y)] = effects.leds[XY(x, y - 1)];
}
// Add a new drop at the top of the column randomly
if (random(10) > 7) { // Adjust the probability to control density of rain
effects.leds[XY(x, 0)] = generateRainColor();
} else {
effects.leds[XY(x, 0)] = CRGB::Black;
}
}
}
void start()
{
};
unsigned int drawFrame() {
effects.DimAll(250);
drawDigitalRain();
effects.ShowFrame();
return 0;
}
};
#endif

View file

@ -0,0 +1,66 @@
// Codetastic 2024
// ChatGPT was used to create this.
#ifndef PatternTunnel_H
#define PatternTunnel_H
class PatternTunnel : public Drawable {
private:
uint8_t circlePositions[5] = {0, 6, 12, 18, 24}; // Initial positions of circles
public:
PatternTunnel() {
name = (char *)"Tunnel";
}
// Function to draw a circle on the matrix
void drawCircle(int centerX, int centerY, int radius, CRGB color) {
for (int y = -radius; y <= radius; y++) {
for (int x = -radius; x <= radius; x++) {
if (x*x + y*y <= radius*radius) {
int drawX = centerX + x;
int drawY = centerY + y;
if (drawX >= 0 && drawX < VPANEL_W && drawY >= 0 && drawY < VPANEL_H) {
effects.leds[XY(drawX, drawY)] = color;
}
}
}
}
}
void start()
{
};
unsigned int drawFrame() {
effects.DimAll(250);
// Draw circles
for (int i = 0; i < 5; i++) {
int radius = circlePositions[i] % 32;
CRGB color = CHSV(map(radius, 0, 31, 0, 255), 255, 255);
drawCircle(VPANEL_W / 2, VPANEL_H / 2, radius, color);
// Move circles forward
circlePositions[i]++;
// Reset the position if the circle is out of bounds
if (circlePositions[i] >= 32) {
circlePositions[i] = 0;
}
}
effects.ShowFrame();
return 0;
}
};
#endif

View file

@ -94,8 +94,8 @@ public:
break; break;
} }
effects.DimAll(254); effects.DimAll(220);
effects.ShowFrame();
if (thetaUpdate >= thetaUpdateFrequency) { if (thetaUpdate >= thetaUpdateFrequency) {
thetaUpdate = 0; thetaUpdate = 0;
@ -113,6 +113,8 @@ public:
hueUpdate++; hueUpdate++;
} }
effects.ShowFrame();
return 0; return 0;
} }
}; };

View file

@ -1,297 +0,0 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef Patterns_H
#define Patterns_H
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
#include "Vector.h"
#include "Boid.h"
#include "Attractor.h"
/*
* Note from mrfaptastic:
*
* Commented out patterns are due to the fact they either didn't work properly with a non-square display,
* or from my personal opinion, are crap.
*/
#include "PatternTest.h"
//#include "PatternNoiseSmearing.h" // Doesn't seem to work, omitting.
#include "PatternSpiro.h"
#include "PatternRadar.h"
#include "PatternSwirl.h"
#include "PatternPendulumWave.h"
#include "PatternFlowField.h"
#include "PatternIncrementalDrift.h"
#include "PatternIncrementalDrift2.h" // Doesn't seem to work, omitting.
#include "PatternMunch.h"
#include "PatternElectricMandala.h"
//#include "PatternSpin.h" // Doesn't seem to work, omitting.
#include "PatternSimplexNoise.h"
#include "PatternWave.h"
#include "PatternAttract.h"
//#include "PatternBounce.h" // Doesn't seem to work, omitting.
#include "PatternFlock.h"
#include "PatternInfinity.h"
#include "PatternPlasma.h"
#include "PatternSnake.h"
#include "PatternInvaders.h"
//#include "PatternCube.h" // Doesn't seem to work, omitting.
//#include "PatternFire.h" // Doesn't seem to work, omitting.
#include "PatternLife.h"
#include "PatternMaze.h"
//#include "PatternPulse.h" // Doesn't seem to work, omitting.
//#include "PatternSpark.h" // Doesn't seem to work, omitting.
#include "PatternSpiral.h"
class Patterns : public Playlist {
private:
PatternTest patternTest;
// PatternRainbowFlag rainbowFlag; // doesn't work
// PatternPaletteSmear paletteSmear;
// PatternMultipleStream multipleStream; // doesn't work
// PatternMultipleStream2 multipleStream2; // doesn't work
// PatternMultipleStream3 multipleStream3; // doesn't work
// PatternMultipleStream4 multipleStream4; // doesn't work
// PatternMultipleStream5 multipleStream5; // doesn't work
// PatternMultipleStream8 multipleStream8; // doesn't work
PatternSpiro spiro;
// PatternRadar radar;
PatternSwirl swirl;
PatternPendulumWave pendulumWave;
PatternFlowField flowField;
PatternIncrementalDrift incrementalDrift;
PatternIncrementalDrift2 incrementalDrift2;
PatternMunch munch;
PatternElectricMandala electricMandala;
// PatternSpin spin;
PatternSimplexNoise simplexNoise;
PatternWave wave;
PatternAttract attract;
// PatternBounce bounce;
PatternFlock flock;
PatternInfinity infinity;
PatternPlasma plasma;
PatternInvadersSmall invadersSmall;
// PatternInvadersMedium invadersMedium;
// PatternInvadersLarge invadersLarge;
PatternSnake snake;
// PatternCube cube;
// PatternFire fire;
PatternLife life;
PatternMaze maze;
// PatternPulse pulse;
// PatternSpark spark;
PatternSpiral spiral;
int currentIndex = 0;
Drawable* currentItem;
int getCurrentIndex() {
return currentIndex;
}
const static int PATTERN_COUNT = 14;
Drawable* shuffledItems[PATTERN_COUNT];
Drawable* items[PATTERN_COUNT] = {
// &patternTest, // ok
&spiro, // cool
// &paletteSmear, // fail
// &multipleStream, // fail
// &multipleStream8,// fail
// &multipleStream5,// fail
// &multipleStream3,// fail
// &radar, // fail
// &multipleStream4, // fail
// &multipleStream2, // fail
&life, // ok
&flowField,
&pendulumWave, //11 ok
&incrementalDrift, //12 ok
&incrementalDrift2, // 13 fail
&munch, // 14 ok
// &electricMandala, // 15 ok, but ugly (vortigont)
// &spin, // 16 ok but repetitive
// &simplexNoise, // 17 - cool!
// &wave, // 18 ok (can't work with 256+ matrix due to uint8_t vars)
// &rainbowFlag, //20 // fail
&attract, // 21 ok
// &swirl, // 22 ok, but ugly (vortigont)
// &bounce, // bouncing line crap
&flock, // works
&infinity, // works
&plasma, // works
// &invadersSmall, // works ish, but ugly (vortigont)
// &invadersMedium, // fail
// &invadersLarge, // fail
&snake, // ok
// &cube, // works ish
// &fire, // ok ish
&maze, // ok
// &pulse,// fail
// &spark, // same as fire
&spiral, // ok
};
public:
Patterns() {
// add the items to the shuffledItems array
for (int a = 0; a < PATTERN_COUNT; a++) {
shuffledItems[a] = items[a];
}
shuffleItems();
this->currentItem = items[0];
this->currentItem->start();
}
char* Drawable::name = (char *)"Patterns";
void stop() {
if (currentItem)
currentItem->stop();
}
void start() {
if (currentItem)
currentItem->start();
}
void move(int step) {
currentIndex += step;
if (currentIndex >= PATTERN_COUNT) currentIndex = 0;
else if (currentIndex < 0) currentIndex = PATTERN_COUNT - 1;
if (effects.paletteIndex == effects.RandomPaletteIndex)
effects.RandomPalette();
moveTo(currentIndex);
//if (!isTimeAvailable && currentItem == &analogClock)
// move(step);
}
void moveRandom(int step) {
currentIndex += step;
if (currentIndex >= PATTERN_COUNT) currentIndex = 0;
else if (currentIndex < 0) currentIndex = PATTERN_COUNT - 1;
if (effects.paletteIndex == effects.RandomPaletteIndex)
effects.RandomPalette();
if (currentItem)
currentItem->stop();
currentItem = shuffledItems[currentIndex];
if (currentItem)
currentItem->start();
// if (!isTimeAvailable && currentItem == &analogClock)
// moveRandom(step);
}
void shuffleItems() {
for (int a = 0; a < PATTERN_COUNT; a++)
{
int r = random(a, PATTERN_COUNT);
Drawable* temp = shuffledItems[a];
shuffledItems[a] = shuffledItems[r];
shuffledItems[r] = temp;
}
}
unsigned int drawFrame() {
return currentItem->drawFrame();
}
void listPatterns() {
Serial.println(F("{"));
Serial.print(F(" \"count\": "));
Serial.print(PATTERN_COUNT);
Serial.println(",");
Serial.println(F(" \"results\": ["));
for (int i = 0; i < PATTERN_COUNT; i++) {
Serial.print(F(" \""));
Serial.print(i, DEC);
Serial.print(F(": "));
Serial.print(items[i]->name);
if (i == PATTERN_COUNT - 1)
Serial.println(F("\""));
else
Serial.println(F("\","));
}
Serial.println(" ]");
Serial.println("}");
}
char * getCurrentPatternName()
{
return currentItem->name;
}
void moveTo(int index) {
if (currentItem)
currentItem->stop();
currentIndex = index;
currentItem = items[currentIndex];
if (currentItem)
currentItem->start();
}
bool setPattern(String name) {
for (int i = 0; i < PATTERN_COUNT; i++) {
if (name.compareTo(items[i]->name) == 0) {
moveTo(i);
return true;
}
}
return false;
}
bool setPattern(int index) {
if (index >= PATTERN_COUNT || index < 0)
return false;
moveTo(index);
return true;
}
};
#endif

View file

@ -0,0 +1,220 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Original Copyright (c) 2014 Jason Coon
*
* Modified by Codetastic 2024
*
*/
#ifndef Patterns_H
#define Patterns_H
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
#include "Vector2.hpp"
#include "Boid.hpp"
#include "Attractor.hpp"
/*
* Note from mrfaptastic:
*
* Commented out patterns are due to the fact they either didn't work properly with a non-square display,
* or from my personal opinion, are crap.
*/
#include "PatternStarfield.hpp" // new 2024
#include "PatternAttract.hpp"
#include "PatternBounce.hpp" // Doesn't seem to work, omitting.
#include "PatternCube.hpp" // Doesn't seem to work, omitting.
#include "PatternElectricMandala.hpp"
#include "PatternFireKoz.hpp" // Doesn't seem to work, omitting.
#include "PatternFlock.hpp"
#include "PatternFlowField.hpp"
#include "PatternIncrementalDrift.hpp"
#include "PatternIncrementalDrift2.hpp" // Doesn't seem to work, omitting.
#include "PatternInfinity.hpp"
#include "PatternMaze.hpp" // ??
#include "PatternMunch.hpp"
//#include "PatternNoiseSmearing.hpp"
#include "PatternPendulumWave.hpp"
#include "PatternPlasma.hpp"
#include "PatternRadar.hpp"
#include "PatternSimplexNoise.hpp"
#include "PatternSnake.hpp"
#include "PatternSpiral.hpp"
#include "PatternSpiro.hpp"
#include "PatternWave.hpp"
#include "PatternTheMatrix.hpp"
//#include "PatternTunnel.hpp" // fail
//#include "PatternSphereSpin.hpp" // fail
class Patterns {
private:
PatternStarfield starfield;
// PatternSphereSpin sspin;
PatternAttract attract;
PatternBounce bounce;
PatternCube cube;
PatternElectricMandala electricMandala;
PatternFireKoz fire;
PatternFlock flock;
PatternFlowField flowField;
PatternIncrementalDrift incrementalDrift;
PatternIncrementalDrift2 incrementalDrift2;
PatternInfinity infinity;
PatternMaze maze;
PatternMunch munch;
PatternPendulumWave pendwave;
PatternPlasma plasma;
PatternRadar radar;
PatternSimplexNoise simpnoise;
PatternSnake snake;
PatternSpiral spiral;
PatternSpiro spiro;
PatternWave wave;
PatternTheMatrix matrix;
// PatternTunnel tunnel;
std::vector<Drawable*> availablePatterns = {
// &tunnel,
&matrix,
&starfield,
// &sspin,
&attract,
&bounce,
&cube,
&electricMandala,
&fire,
&flock,
&spiro,
&radar,
&flowField,
&incrementalDrift,
&incrementalDrift2,
&infinity,
&maze,
&munch,
&pendwave,
&plasma,
&radar,
&simpnoise,
//&snake, // a bit crap
//&spiral, // a bit crap
&spiro,
&wave,
};
int currentIndex = 0;
Drawable* currentItem;
int getCurrentIndex() {
return currentIndex;
}
public:
Patterns() {
this->currentItem = availablePatterns[0];
this->currentItem->start();
}
void stop() {
if (currentItem)
currentItem->stop();
}
void start() {
if (currentItem)
currentItem->start();
}
void moveTo(int index)
{
index = ((index >= availablePatterns.size()) || (index < 0)) ? 0 : index;
if (currentItem)
currentItem->stop();
currentIndex = index;
currentItem = availablePatterns[currentIndex];
Serial.print("Changing pattern to: ");
Serial.println(getCurrentPatternName());
if (currentItem)
currentItem->start();
} // index
void move(int step) {
currentIndex += step;
if (currentIndex >= availablePatterns.size()) currentIndex = 0;
else if (currentIndex < 0) currentIndex = 0;
moveTo(currentIndex);
}
void moveRandom(int step) {
int rand_index = random(0, availablePatterns.size()-1);
moveTo(rand_index);
}
unsigned int drawFrame() {
return currentItem->drawFrame();
}
void listPatterns() {
Serial.println(F("{"));
Serial.print(F(" \"count\": "));
Serial.print(availablePatterns.size());
Serial.println(",");
Serial.println(F(" \"results\": ["));
for (size_t i = 0; i < availablePatterns.size(); i++) {
Serial.print(F(" \""));
Serial.print(i, DEC);
Serial.print(F(": "));
Serial.print(availablePatterns[i]->name);
if (i == availablePatterns.size() - 1)
Serial.println(F("\""));
else
Serial.println(F("\","));
}
Serial.println(" ]");
Serial.println("}");
}
char * getCurrentPatternName()
{
return currentItem->name;
}
/*
bool setPattern(String name) {
for (size_t i = 0; i < availablePatterns.size(); i++) {
if (name.compareTo(availablePatterns[i]->name) == 0) {
moveTo(i);
return true;
}
}
return false;
}
*/
bool setPattern(int index) {
if (index >= availablePatterns.size() || index < 0)
return false;
moveTo(index);
return true;
}
};
#endif

View file

@ -1,39 +0,0 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef Playlist_H
#define Playlist_H
class Playlist : public Drawable {
public:
virtual bool isPlaylist() {
return true;
}
boolean isCurrentItemFinished = true;
virtual void move(int step) = 0;
virtual void moveRandom(int step) = 0;
virtual int getCurrentIndex();
};
#endif