#include <FastLED.h>
#define pWIDTH 128
#define pHEIGHT 8
#define NUM_LEDS ((pWIDTH) * (pHEIGHT))
extern CRGBPalette16 gCurrentGradientPalette;
extern CRGBPalette16 gTargetGradientPalette;
CRGB leds[NUM_LEDS];
bool loadingFlag = true;
void drawPixelXY(int8_t x, int8_t y, CRGB color) {
if (leds == nullptr) return;
if (x < 0 || x >= pWIDTH || y < 0 || y >= pHEIGHT) return;
int16_t thisPixel = getPixelNumber(x, y);
if (thisPixel >= 0 && thisPixel < NUM_LEDS) leds[thisPixel] = color;
}
uint16_t getPixelNumber(uint8_t x, uint8_t y) {
if (x >= pWIDTH || y >= pHEIGHT)
return NUM_LEDS;
if (y & 1)
x = pWIDTH - 1 - x;
return x + (y * pWIDTH);
}
uint32_t getPixColor(int16_t thisPixel) {
if (leds == nullptr) return 0;
if (thisPixel < 0 || thisPixel >= NUM_LEDS) return 0;
return (((uint32_t)leds[thisPixel].r << 16) | ((uint32_t)leds[thisPixel].g << 8 ) | (uint32_t)leds[thisPixel].b);
}
uint32_t getPixColorXY(int8_t x, int8_t y) {
return getPixColor(getPixelNumber(x, y));
}
uint16_t XY(uint8_t x, uint8_t y) {
return getPixelNumber(x, y);
}
#define NSTARS (pWIDTH + pHEIGHT)
void drawPixelXYF(float x, float y,
const CRGB & color) {
// extract the fractional parts and derive their inverses
uint8_t xx = (x - (int) x) * 255, yy = (y - (int) y) * 255, ix = 255 - xx, iy = 255 - yy;
// calculate the intensities for each affected pixel
#define WU_WEIGHT(a, b)((uint8_t)(((a) * (b) + (a) + (b)) >> 8))
uint8_t wu[4] = {
WU_WEIGHT(ix, iy),
WU_WEIGHT(xx, iy),
WU_WEIGHT(ix, yy),
WU_WEIGHT(xx, yy)
};
// multiply the intensities by the colour, and saturating-add them to the pixels
for (uint8_t i = 0; i < 4; i++) {
int16_t xn = x + (i & 1), yn = y + ((i >> 1) & 1);
int16_t idx = getPixelNumber(xn, yn);
if (idx >=0 && idx < NUM_LEDS) {
CRGB clr = leds[idx];
clr.r = qadd8(clr.r, (color.r * wu[i]) >> 8);
clr.g = qadd8(clr.g, (color.g * wu[i]) >> 8);
clr.b = qadd8(clr.b, (color.b * wu[i]) >> 8);
nblend(leds[idx],clr,128);
//nblend(leds[idx],color,128);
}
}
#undef WU_WEIGHT
}
static float fmap(const float x,
const float in_min,
const float in_max,
const float out_min,
const float out_max) {
return (out_max - out_min) * (x - in_min) / (in_max - in_min) + out_min;
}
uint8_t divider = 6;
struct {
int16_t PosX;
int16_t PosY;
int16_t PosW;
void reg() {
randomSeed(millis());
PosX = random(pHEIGHT * -divider, pHEIGHT * divider);
PosY = random(pHEIGHT * -divider, pHEIGHT * divider);
PosW = pWIDTH * divider;
};
void run() {
PosW -=(8-divider);
//PosW -=(divider);
if (PosW < 0) {
reg();
}
float SX = pWIDTH * 0.5 + fmap(float(PosX) / float(PosW), 0, 1, 0, (float) pWIDTH/2);
float SY = pHEIGHT * 0.5 + fmap(float(PosY) / float(PosW), 0, 1, 0, (float) pHEIGHT/2);
if(SX>=0 && SX < pWIDTH && SY>=0 && SY<pHEIGHT)
drawPixelXYF(SX, SY, CHSV(64, 64, map(PosW, 0, pWIDTH * divider, 255, 128)));
}
}
star[NSTARS];
void setup() {
FastLED.addLeds<WS2812B, 3, GRB>(leds, NUM_LEDS);
}
void loop() {
if (loadingFlag) {
loadingFlag = false;
randomSeed(millis());
for (byte i = 0; i < NSTARS; i++) {
star[i].run();
star[i].PosW = random(pWIDTH * divider);
}
FastLED.clear();
}
fadeToBlackBy(leds, NUM_LEDS, 32);
for (byte i = 0; i < NSTARS; i++) {
star[i].run();
}
FastLED.delay(10);
}