Advertisement
atuline

fireworksxy

Jul 31st, 2015
877
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.38 KB | None | 0 0
  1. #include "FastLED.h"
  2.  
  3. // FireworksXY
  4. // Quick and dirty 2-D fireworks simulation using FastLED.
  5. //
  6. // Originaly designed an Adafruit 5x8 WS2811 shield, but works fine
  7. // on other XY matricies.
  8. //
  9. // by Mark Kriegsman, July 2013
  10. // (and not updated too much since then, so it's a little stale,
  11. //  but it's a good starting point, if rather uncommented.)
  12.  
  13. #define PIXEL_WIDTH  8
  14. #define PIXEL_HEIGHT 8
  15.  
  16. #define LED_TYPE     WS2811
  17. #define COLOR_ORDER  GRB
  18. #define DATA_PIN     12
  19. //#define CLK_PIN    4
  20.  
  21. #define BRIGHTNESS   255
  22.  
  23.  
  24. #define NUM_LEDS (PIXEL_WIDTH * PIXEL_HEIGHT)
  25. CRGB leds[NUM_LEDS];
  26.  
  27. #define MODEL_BORDER 0
  28. #define MODEL_WIDTH  (MODEL_BORDER + PIXEL_WIDTH  + MODEL_BORDER)
  29. #define MODEL_HEIGHT (MODEL_BORDER + PIXEL_HEIGHT + MODEL_BORDER)
  30.  
  31. #define PIXEL_X_OFFSET ((MODEL_WIDTH  - PIXEL_WIDTH ) / 2)
  32. #define PIXEL_Y_OFFSET ((MODEL_HEIGHT - PIXEL_HEIGHT) / 2)
  33.  
  34. #define WINDOW_X_MIN (PIXEL_X_OFFSET)
  35. #define WINDOW_X_MAX (WINDOW_X_MIN + PIXEL_WIDTH -1 )
  36. #define WINDOW_Y_MIN (PIXEL_Y_OFFSET)
  37. #define WINDOW_Y_MAX (WINDOW_Y_MIN + PIXEL_HEIGHT -1)
  38.  
  39. #define kMatrixSerpentineLayout true
  40.  
  41.  
  42. CRGB overrun;
  43.  
  44.  
  45.  
  46. CRGB& XY( byte x, byte y) {
  47.   uint16_t i;
  48.  
  49.   x -= PIXEL_X_OFFSET;
  50.   y -= PIXEL_Y_OFFSET;
  51.  
  52.   if( x >= PIXEL_WIDTH || y >= PIXEL_HEIGHT) {
  53.     return overrun;
  54.   }
  55.  
  56.   if( kMatrixSerpentineLayout == false) {
  57.     i = (y * PIXEL_WIDTH) + x;
  58.   }
  59.  
  60.   if( kMatrixSerpentineLayout == true) {
  61.     if( y & 0x01) {
  62.       // Odd rows run backwards
  63.       uint8_t reverseX = (PIXEL_WIDTH - 1) - x;
  64.       i = (y * PIXEL_WIDTH) + reverseX;
  65.     } else {
  66.       // Even rows run forwards
  67.       i = (y * PIXEL_WIDTH) + x;
  68.     }
  69.   }
  70.  
  71.   return leds[i];
  72. }
  73.  
  74.  
  75.  
  76. /*
  77. CRGB& XY( byte x, byte y)
  78. {
  79.   x -= PIXEL_X_OFFSET;
  80.   y -= PIXEL_Y_OFFSET;
  81.   if( x < PIXEL_WIDTH && y < PIXEL_HEIGHT) {
  82.     return leds[ (x * PIXEL_HEIGHT) + y ] ;
  83.   } else
  84.     return overrun;
  85. }
  86. */
  87.  
  88.  
  89. void screenscale( accum88 a, byte N, byte& screen, byte& screenerr)
  90. {
  91.   byte ia = a >> 8;
  92.   screen = scale8( ia, N);
  93.   byte m = screen * (256 / N);
  94.   screenerr = (ia - m) * scale8(255,N);
  95.   return;
  96. }
  97.  
  98.  
  99. void plot88( byte x, byte y, CRGB& color)
  100. {
  101.   byte ix = scale8( x, MODEL_WIDTH);
  102.   byte iy = scale8( y, MODEL_HEIGHT);
  103.   CRGB& px = XY( ix, iy);
  104.   px = color;
  105. }
  106.  
  107.  
  108. static int16_t scale15by8_local( int16_t i, fract8 scale )
  109. {
  110.     int16_t result;
  111.     result = (int32_t)((int32_t)i * scale) / 256;
  112.     return result;
  113. }
  114.  
  115. saccum78 gGravity = 10;
  116. fract8  gBounce = 200;
  117. fract8  gDrag = 255;
  118. bool gSkyburst = 0;
  119.  
  120. accum88 gBurstx;
  121. accum88 gBursty;
  122. saccum78 gBurstxv;
  123. saccum78 gBurstyv;
  124. CRGB gBurstcolor;
  125.  
  126. #define NONE 0
  127. #define SHELL 1
  128. #define SPARK 2
  129.  
  130. class Dot {
  131. public:
  132.   byte    show;
  133.   byte    theType;
  134.   accum88 x;
  135.   accum88 y;
  136.   saccum78 xv;
  137.   saccum78 yv;
  138.   accum88 r;
  139.   CRGB    color;
  140.  
  141.   Dot()
  142.   {
  143.     show = 0;
  144.     theType = 0;
  145.     x =  0;
  146.     y =  0;
  147.     xv = 0;
  148.     yv = 0;
  149.     r  = 0;
  150.     color.setRGB( 0, 0, 0);
  151.   }
  152.  
  153.   void Draw()
  154.   {
  155.     if( !show) return;
  156.     byte ix, xe, xc;
  157.     byte iy, ye, yc;
  158.     screenscale( x, MODEL_WIDTH, ix, xe);
  159.     screenscale( y, MODEL_HEIGHT, iy, ye);
  160.     yc = 255 - ye;
  161.     xc = 255 - xe;
  162.    
  163.     CRGB c00 = CRGB( dim8_video( scale8( scale8( color.r, yc), xc)),
  164.                      dim8_video( scale8( scale8( color.g, yc), xc)),
  165.                      dim8_video( scale8( scale8( color.b, yc), xc))
  166.                      );
  167.     CRGB c01 = CRGB( dim8_video( scale8( scale8( color.r, ye), xc)),
  168.                      dim8_video( scale8( scale8( color.g, ye), xc)),
  169.                      dim8_video( scale8( scale8( color.b, ye), xc))
  170.                      );
  171.  
  172.     CRGB c10 = CRGB( dim8_video( scale8( scale8( color.r, yc), xe)),
  173.                      dim8_video( scale8( scale8( color.g, yc), xe)),
  174.                      dim8_video( scale8( scale8( color.b, yc), xe))
  175.                      );
  176.     CRGB c11 = CRGB( dim8_video( scale8( scale8( color.r, ye), xe)),
  177.                      dim8_video( scale8( scale8( color.g, ye), xe)),
  178.                      dim8_video( scale8( scale8( color.b, ye), xe))
  179.                      );
  180.  
  181.     XY(ix, iy) += c00;
  182.     XY(ix, iy + 1) += c01;
  183.     XY(ix + 1, iy) += c10;
  184.     XY(ix + 1, iy + 1) += c11;
  185.   }
  186.  
  187.   void Move()
  188.   {
  189.     saccum78 oyv = yv;
  190.    
  191.     if( !show) return;
  192.     yv -= gGravity;
  193.     xv = scale15by8_local( xv, gDrag);    
  194.     yv = scale15by8_local( yv, gDrag);
  195.  
  196.     if( theType == SPARK) {
  197.       xv = scale15by8_local( xv, gDrag);    
  198.       yv = scale15by8_local( yv, gDrag);
  199.       color.nscale8( 255);
  200.       if( !color) {
  201.         show = 0;
  202.       }
  203.     }
  204.  
  205.     // if we'd hit the ground, bounce
  206.     if( yv < 0 && (y < (-yv)) ) {
  207.       if( theType == SPARK ) {
  208.         show = 0;
  209.       } else {
  210.         yv = -yv;
  211.         yv = scale15by8_local( yv, gBounce);
  212.         if( yv < 500 ) {
  213.           show = 0;
  214.         }
  215.       }
  216.     }
  217.    
  218.     if( (yv < -300) /* && (!(oyv < 0))*/ ) {
  219.       // pinnacle
  220.       if( theType == SHELL ) {
  221.  
  222.         if( (y > (uint16_t)(0x8000)) /*&& (random8() < 64)*/) {
  223.           // boom
  224.           LEDS.showColor( CRGB::White);
  225.           //delay( 1);
  226.           LEDS.showColor( CRGB::Black);
  227.         }
  228.  
  229.         show = 0;
  230.  
  231.         gSkyburst = 1;
  232.         gBurstx = x;
  233.         gBursty = y;
  234.         gBurstxv = xv;
  235.         gBurstyv = yv;
  236.         gBurstcolor = color;        
  237.       }
  238.     }
  239.     if( theType == SPARK) {
  240.       if( ((xv >  0) && (x > xv)) ||
  241.           ((xv < 0 ) && (x < (0xFFFF + xv))) )  {
  242.         x += xv;
  243.       } else {
  244.         show = 0;
  245.       }
  246.     } else {
  247.       x += xv;
  248.     }
  249.     y += yv;
  250.    
  251.   }
  252.  
  253.   void GroundLaunch()
  254.   {
  255.     yv = 600 + random16(300 + (25 * PIXEL_HEIGHT));
  256.     xv = (int16_t)random16(600) - (int16_t)300;
  257.     y = 0;
  258.     x = 0x8000;
  259.     hsv2rgb_rainbow( CHSV( random8(), 240, 200), color);
  260.     show = 1;
  261.   }
  262.  
  263.   void Skyburst( accum88 basex, accum88 basey, saccum78 basedv, CRGB& basecolor)
  264.   {
  265.     yv = (int16_t)0 + (int16_t)random16(1500) - (int16_t)500;
  266.     xv = basedv + (int16_t)random16(2000) - (int16_t)1000;
  267.     y = basey;
  268.     x = basex;
  269.     color = basecolor;
  270.     color *= 4;
  271.     theType = SPARK;
  272.     show = 1;
  273.   }
  274.  
  275. };
  276.  
  277. #define NUM_SPARKS 12
  278.  
  279. Dot gDot;
  280. Dot gSparks[NUM_SPARKS];
  281.  
  282. void setup() {
  283.   delay(2000);
  284.   LEDS.setBrightness(BRIGHTNESS);
  285.   LEDS.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS)
  286.     .setCorrection(TypicalLEDStrip)
  287.     .setDither(BRIGHTNESS<255);
  288. }
  289.  
  290. void loop()
  291. {
  292.   random16_add_entropy( random() );
  293.   CRGB sky1(0,0,2);
  294.   CRGB sky2(2,0,2);
  295.  
  296.   memset8( leds, 0, NUM_LEDS * 3);
  297.  
  298. #if 1
  299.    for( byte v = 0; v < NUM_LEDS; v++) {
  300.      leds[v] = sky1;
  301.    }
  302.    for( byte u = 0; u < 1; u++) {
  303.     leds[random8(NUM_LEDS)] = sky2;
  304.   }
  305. #endif
  306.  
  307.   gDot.Move();
  308.   gDot.Draw();
  309.   for( byte b = 0; b < NUM_SPARKS; b++) {
  310.     gSparks[b].Move();
  311.     gSparks[b].Draw();
  312.   }
  313.  
  314.   LEDS.show();
  315.   static uint16_t launchcountdown = 0;
  316.   if( gDot.show == 0 ) {
  317.     if( launchcountdown == 0) {
  318.       gDot.GroundLaunch();
  319.       gDot.theType = SHELL;
  320.       launchcountdown = random16( 350) + 1;
  321.     } else {
  322.       launchcountdown --;
  323.     }
  324.   }
  325.  
  326.   if( gSkyburst) {
  327.     byte nsparks = random8( NUM_SPARKS / 2, NUM_SPARKS + 1);
  328.     for( byte b = 0; b < nsparks; b++) {
  329.       gSparks[b].Skyburst( gBurstx, gBursty, gBurstyv, gBurstcolor);
  330.       gSkyburst = 0;
  331.     }
  332.   }
  333.  
  334.   delay(10);
  335. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement