Tetrix vStrip 2D modification.

AA version of Bouncing balls
Better AA
This commit is contained in:
Blaz Kristan 2022-08-30 17:20:58 +02:00
parent d28d2c57e4
commit 8719adef1e
3 changed files with 75 additions and 53 deletions

View File

@ -2806,6 +2806,8 @@ uint16_t mode_bouncing_balls(void) {
SEGMENT.fill(SEGCOLOR(2) ? BLACK : SEGCOLOR(1)); SEGMENT.fill(SEGCOLOR(2) ? BLACK : SEGCOLOR(1));
// virtualStrip idea by @ewowi (Ewoud Wijma) // virtualStrip idea by @ewowi (Ewoud Wijma)
// requires virtual strip # to be embedded into upper 16 bits of index in setPixelColor()
// the following functions will not work on virtual strips: fill(), fade_out(), fadeToBlack(), blur()
struct virtualStrip { struct virtualStrip {
static void runStrip(size_t stripNr, Ball* balls) { static void runStrip(size_t stripNr, Ball* balls) {
// number of balls based on intensity setting to max of 7 (cycles colors) // number of balls based on intensity setting to max of 7 (cycles colors)
@ -2847,8 +2849,8 @@ uint16_t mode_bouncing_balls(void) {
} }
int pos = roundf(balls[i].height * (SEGLEN - 1)); int pos = roundf(balls[i].height * (SEGLEN - 1));
SEGMENT.setPixelColor(pos | int((stripNr+1)<<16), color); // encode virtual strip into index if (SEGLEN<32) SEGMENT.setPixelColor(pos | int((stripNr+1)<<16), color); // encode virtual strip into index
//SEGMENT.setPixelColor(balls[i].height + (stripNr+1)*10.0f, color); else SEGMENT.setPixelColor(balls[i].height + (stripNr+1)*10.0f, color);
} }
} }
}; };
@ -3464,66 +3466,86 @@ static const char _data_FX_MODE_DRIP[] PROGMEM = "Drip@Gravity,# of drips;!,!;!;
* Tetris or Stacking (falling bricks) Effect * Tetris or Stacking (falling bricks) Effect
* by Blaz Kristan (AKA blazoncek) (https://github.com/blazoncek, https://blaz.at/home) * by Blaz Kristan (AKA blazoncek) (https://github.com/blazoncek, https://blaz.at/home)
*/ */
//12 bytes //20 bytes
typedef struct Tetris { typedef struct Tetris {
float pos; float pos;
float speed; float speed;
uint32_t col; uint32_t col;
uint16_t aux0; // 2D-fication of SEGENV.aux0 (brick size)
uint16_t aux1; // 2D-fication of SEGENV.aux1 (stack size)
uint32_t step; // 2D-fication of SEGENV.step (state)
} tetris; } tetris;
uint16_t mode_tetrix(void) { uint16_t mode_tetrix(void) {
uint16_t strips = SEGMENT.nrOfVStrips(); // allow running on virtual strips (columns in 2D segment)
uint16_t dataSize = sizeof(tetris); uint16_t dataSize = sizeof(tetris);
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize * strips)) return mode_static(); //allocation failed
Tetris* drop = reinterpret_cast<Tetris*>(SEGENV.data); Tetris* drops = reinterpret_cast<Tetris*>(SEGENV.data);
if (SEGENV.call == 0) SEGMENT.fill(SEGCOLOR(1)); // will fill entire segment (1D or 2D)
// virtualStrip idea by @ewowi (Ewoud Wijma)
// requires virtual strip # to be embedded into upper 16 bits of index in setPixelcolor()
// the following functions will not work on virtual strips: fill(), fade_out(), fadeToBlack(), blur()
struct virtualStrip {
static void runStrip(size_t stripNr, Tetris *drop) {
// initialize dropping on first call or segment full // initialize dropping on first call or segment full
if (SEGENV.call == 0 /*|| SEGENV.aux1 >= SEGLEN*/) { if (SEGENV.call == 0) {
SEGENV.aux1 = 0; // reset brick stack size drop->aux1 = 0; // reset brick stack size
SEGENV.step = 0; drop->step = 0;
SEGMENT.fill(SEGCOLOR(1)); //for (int i=0; i<SEGLEN; i++) SEGMENT.setPixelColor(i | int((stripNr+1)<<16), SEGCOLOR(1)); // will fill virtual strip only
//return 250; // short wait
} }
if (SEGENV.step == 0) { // init brick if (drop->step == 0) { // init brick
drop->speed = 0.0238 * (SEGMENT.speed ? (SEGMENT.speed>>2)+1 : random8(6,64)); // set speed // speed calcualtion: a single brick should reach bottom of strip in X seconds
// if the speed is set to 1 this should take 5s and at 255 it should take 0.25s
// as this is dependant on SEGLEN it should be taken into account and the fact that effect runs every FRAMETIME s
int speed = SEGMENT.speed ? SEGMENT.speed : random8(1,255);
speed = map(speed, 1, 255, 5000, 250); // time taken for full (SEGLEN) drop
drop->speed = float(SEGLEN * FRAMETIME) / float(speed); // set speed
drop->pos = SEGLEN; // start at end of segment (no need to subtract 1) drop->pos = SEGLEN; // start at end of segment (no need to subtract 1)
drop->col = SEGMENT.color_from_palette(random8(0,15)<<4,false,false,0); // limit color choices so there is enough HUE gap drop->col = SEGMENT.color_from_palette(random8(0,15)<<4,false,false,0); // limit color choices so there is enough HUE gap
SEGENV.step = 1; // drop state (0 init, 1 forming, 2 falling) drop->step = 1; // drop state (0 init, 1 forming, 2 falling)
SEGENV.aux0 = (SEGMENT.intensity ? (SEGMENT.intensity>>5)+1 : random8(1,5)) * (1+(SEGLEN>>6)); // size of brick drop->aux0 = (SEGMENT.intensity ? (SEGMENT.intensity>>5)+1 : random8(1,5)) * (1+(SEGLEN>>6)); // size of brick
} }
if (SEGENV.step == 1) { // forming if (drop->step == 1) { // forming
if (random8()>>6) { // random drop if (random8()>>6) { // random drop
SEGENV.step = 2; // fall drop->step = 2; // fall
} }
} }
if (SEGENV.step == 2) { // falling if (drop->step == 2) { // falling
if (drop->pos > SEGENV.aux1) { // fall until top of stack if (drop->pos > drop->aux1) { // fall until top of stack
drop->pos -= drop->speed; // may add gravity as: speed += gravity drop->pos -= drop->speed; // may add gravity as: speed += gravity
if (uint16_t(drop->pos) < SEGENV.aux1) drop->pos = SEGENV.aux1; if (uint16_t(drop->pos) < drop->aux1) drop->pos = drop->aux1;
for (int i=int(drop->pos); i<SEGLEN; i++) SEGMENT.setPixelColor(i,i<int(drop->pos)+SEGENV.aux0 ? drop->col : SEGCOLOR(1)); for (int i=int(drop->pos); i<SEGLEN; i++) SEGMENT.setPixelColor(i | int((stripNr+1)<<16), i<int(drop->pos)+drop->aux0 ? drop->col : SEGCOLOR(1));
} else { // we hit bottom } else { // we hit bottom
SEGENV.step = 0; // proceed with next brick, go back to init drop->step = 0; // proceed with next brick, go back to init
SEGENV.aux1 += SEGENV.aux0; // increase the stack size drop->aux1 += drop->aux0; // increase the stack size
if (SEGENV.aux1 >= SEGLEN) SEGENV.step = millis() + 2500; // fade out stack if (drop->aux1 >= SEGLEN) drop->step = millis() + 2000; // fade out stack
} }
} }
if (SEGENV.step > 2) { if (drop->step > 2) {
SEGENV.aux0 = 0; // reset brick size (no more growing) drop->aux0 = 0; // reset brick size (no more growing)
if (SEGENV.step > millis()) { if (drop->step > millis()) {
SEGMENT.fade_out(24); // fade out stack // allow fading of virtual strip
for (int i=0; i<SEGLEN; i++) SEGMENT.blendPixelColor(i | int((stripNr+1)<<16), SEGCOLOR(1), 25); // 10% blend
} else { } else {
SEGENV.aux1 = 0; // reset brick stack size drop->aux1 = 0; // reset brick stack size
SEGENV.step = 0; // proceed with next brick drop->step = 0; // proceed with next brick
} }
} }
}
};
for (int stripNr=0; stripNr<strips; stripNr++)
virtualStrip::runStrip(stripNr, &drops[stripNr]);
return FRAMETIME; return FRAMETIME;
} }
static const char _data_FX_MODE_TETRIX[] PROGMEM = "Tetrix@!,Width;!,!,;!;sx=224,ix=0,pal=11,mp12=1,1d"; //vertical static const char _data_FX_MODE_TETRIX[] PROGMEM = "Tetrix@!,Width;!,!,;!;sx=0,ix=0,pal=11,mp12=1,1d";
/* /*

View File

@ -209,10 +209,10 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa)
uint16_t xR = roundf(fX+0.49f); uint16_t xR = roundf(fX+0.49f);
uint16_t yT = roundf(fY-0.49f); uint16_t yT = roundf(fY-0.49f);
uint16_t yB = roundf(fY+0.49f); uint16_t yB = roundf(fY+0.49f);
float dL = fX - xL; float dL = (fX - xL)*(fX - xL);
float dR = xR - fX; float dR = (xR - fX)*(xR - fX);
float dT = fY - yT; float dT = (fY - yT)*(fY - yT);
float dB = yB - fY; float dB = (yB - fY)*(yB - fY);
uint32_t cXLYT = getPixelColorXY(xL, yT); uint32_t cXLYT = getPixelColorXY(xL, yT);
uint32_t cXRYT = getPixelColorXY(xR, yT); uint32_t cXRYT = getPixelColorXY(xR, yT);
uint32_t cXLYB = getPixelColorXY(xL, yB); uint32_t cXLYB = getPixelColorXY(xL, yB);

View File

@ -548,8 +548,8 @@ void Segment::setPixelColor(float i, uint32_t col, bool aa)
if (aa) { if (aa) {
uint16_t iL = roundf(fC-0.49f); uint16_t iL = roundf(fC-0.49f);
uint16_t iR = roundf(fC+0.49f); uint16_t iR = roundf(fC+0.49f);
float dL = fC - iL; float dL = (fC - iL)*(fC - iL);
float dR = iR - fC; float dR = (iR - fC)*(iR - fC);
uint32_t cIL = getPixelColor(iL | (vStrip<<16)); uint32_t cIL = getPixelColor(iL | (vStrip<<16));
uint32_t cIR = getPixelColor(iR | (vStrip<<16)); uint32_t cIR = getPixelColor(iR | (vStrip<<16));
if (iR!=iL) { if (iR!=iL) {