|
- #ifndef MAGENTA_SQUARES_H__
- #define MAGENTA_SQUARES_H__
-
- #include <Arduino.h>
- #include "ILI9488_t3.h"
- #include "MathUtil.h"
- #include "BaseAnimation.h"
-
-
- const uint_fast8_t SQ_SPEED = 0x06;
- const uint_fast8_t SQ_SIZE = 16;
- const uint_fast8_t RIPPLE_SPEED_MIN = 0x05;
- const uint_fast8_t RIPPLE_SPEED_MAX = 0x0b;
- const uint_fast8_t RIPPLE_STROKE = 0x20;
- const float RIPPLE_AMP_LATCH = 1.5f;
- const float RIPPLE_AMP_DECAY = 0.01f;
-
-
- class MagentaSquares : public BaseAnimation {
- public:
- MagentaSquares() : BaseAnimation() {};
-
- void init( ILI9488_t3 tft );
- uint_fast16_t bgColor( void );
- String title();
- void perFrame( ILI9488_t3 tft, FrameParams frameParams );
-
- private:
- inline float distance2D( float w, float h );
-
- uint_fast8_t _step = 0;
- float _audioPeak = 0;
- uint_fast8_t _ripplePos = 0;
- uint_fast8_t _rippleSpeed = 0;
- uint_fast16_t _bgColor;
-
- uint_fast8_t sqAcross;
- uint_fast8_t sqDown;
- uint_fast8_t * radii;
- };
-
- inline float MagentaSquares::distance2D( float w, float h ) {
- return sqrt( w*w + h*h );
- }
-
- void MagentaSquares::init( ILI9488_t3 tft ) {
- uint_fast16_t w = tft.width();
- uint_fast16_t h = tft.height();
-
- sqAcross = w / SQ_SIZE;
- sqDown = h / SQ_SIZE;
-
- radii = (uint_fast8_t*)malloc( sqAcross * sqDown * sizeof(uint_fast8_t) );
-
- float w_2 = w / 2;
- float h_2 = h / 2;
- float distanceMult = (255.0-RIPPLE_STROKE) / distance2D( w_2, h_2 );
-
- for( uint_fast8_t i=0; i<sqAcross; i++ ) {
- for( uint_fast8_t j=0; j<sqDown; j++ ) {
- uint_fast8_t idx = j*sqAcross + i;
-
- radii[idx] = distanceMult * distance2D( ((float)i-sqAcross/2)*SQ_SIZE, ((float)j-sqDown/2)*SQ_SIZE );
- }
- }
-
- _bgColor = tft.color565( 0x88, 0, 0x88 );
- }
-
- uint_fast16_t MagentaSquares::bgColor( void ) {
- return _bgColor;
- }
-
- String MagentaSquares::title() {
- return "MagentaSquares";
- }
-
- void MagentaSquares::perFrame( ILI9488_t3 tft, FrameParams frameParams ) {
- //uint_fast16_t w = tft.width();
- //uint_fast16_t h = tft.height();
-
- // Trigger a new audio ripple?
- float amp_f = frameParams.audioMean; // range [0..1]
- if( amp_f > _audioPeak ) {
- _ripplePos = 0.0; // reset the ripple
-
- _rippleSpeed = lerp( RIPPLE_SPEED_MIN, RIPPLE_SPEED_MAX, min( 1.0, amp_f/_audioPeak - 1.0 ) );
-
- // The next peak must be ~1.5x louder than this one to trigger a ripple
- _audioPeak = amp_f * RIPPLE_AMP_LATCH;
- }
-
- for( uint_fast8_t i=0; i<sqAcross; i++ ) {
- for( uint_fast8_t j=0; j<sqDown; j++ ) {
-
- uint_fast16_t x = i * SQ_SIZE;
- uint_fast16_t y = j * SQ_SIZE;
-
- // Redraw black borders at the edge of each square.
- //tft.drawRect( x, y, SQ_SIZE, SQ_SIZE, 0x0 );
-
- uint_fast16_t clr;
-
- // If this square is within the ripple area, draw using white
- uint_fast8_t idx = j*sqAcross + i;
- uint_fast8_t radius = radii[idx];
- if( (radius < _ripplePos) && (_ripplePos < radius+RIPPLE_STROKE) ) {
- clr = tft.color565( 0xff, random(0x99,0xff), 0xff );
-
- } else {
- uint_fast8_t bright = (x+y+_step) & 0xff;
- clr = tft.color565( bright, 0, bright );
- }
-
- uint_fast8_t rando = random(SQ_SIZE>>1);
- tft.drawRect( x+rando, y+rando, SQ_SIZE-2*rando, SQ_SIZE-2*rando, clr );
- }
- }
-
- //delay(10);
-
- _step += SQ_SPEED * frameParams.timeMult;
- _audioPeak *= (1.0 - RIPPLE_AMP_DECAY * frameParams.timeMult);
- _ripplePos = min( 0xff, (uint_fast16_t)_ripplePos + _rippleSpeed * frameParams.timeMult );
- }
-
- #endif
|