// for u/patrickrjbrown 
// original tread here https://www.reddit.com/r/FastLED/comments/wl7or3/4_matrixs_connected_together_in_a_string/

//Yaroslaw Turbin 11-08-2022
//https://vk.com/ldirko
//https://www.reddit.com/user/ldirko/
//https://twitter.com/ldir_ko 
//https://github.com/ldirko/

#include "FastLED.h"
 
// Matrix size
#define NUM_ROWS 32
#define NUM_COLS 32
#define NUM_LEDS NUM_ROWS * NUM_COLS
 
// LEDs pin
#define DATA_PIN 3   
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB
 
// LED brightness
#define BRIGHTNESS 255
#define MAX_POWER_MILLIAMPS 700 
 
// Define the array of leds
CRGB leds[NUM_LEDS];


void setup() {
  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  // FastLED.setMaxPowerInVoltsAndMilliamps(5, MAX_POWER_MILLIAMPS);
  FastLED.setBrightness(BRIGHTNESS);
}
 
void loop() {

// Sin_plasma();
fire2021();

FastLED.show();

}

void Sin_plasma() {
  int t=millis()/100;
  int t1=t*7;
  int t2=t*6;
  for (int i = 0; i < NUM_COLS; i++) { 
    for (int j = 0; j < NUM_ROWS; j++) {
      byte ind = sin8((i<<3)+sin8((i<<1)+t2))/2+sin8((j<<3)+sin8((j<<1)+t1)/2);
      CRGB color = CHSV(ind,255,255);
      nblend (leds [XY(i,j)], color, 64);
    }
  }
}

void fire2021 (){
  int  a = millis();
  int  a1 = a/3;

  uint16_t yScale = a;
  for (byte j = 0; j < NUM_ROWS; j++) { 
    uint16_t xScale =  0;
    byte yHeight =  abs8(j - (NUM_ROWS-1)) * 255 / (NUM_ROWS+4);
    for (byte i = 0; i < NUM_COLS; i++) {
      int ledsindex = XY( i, j);
      byte val = qsub8 (inoise8 (xScale, yScale, a1), yHeight);
      CRGB color = HeatColor(val);
      nblend(leds[ledsindex], color, 64);
      xScale +=40;
    }
  yScale += 40;
  }
}


uint16_t XY (byte x, byte y) {

// interesting thing about XYTable inside this function
// if you use https://macetech.github.io/FastLED-XY-Map-Generator/ 
// for generation layout, declaration of table is as const XY[]
// and this gives very slow FPS!
// if you place XYTable outside this function (as global array) 
// or add static in declaration FPS get то 14!
// for future projects just remember add static to declaration
// or not place tables inside function 

//for memory reduce i make table for first sector
//another sectors calculate by add number of sector*256 

  static const  byte  XYTable[] = {    //add static to declaration and FPS get то 14
// const  byte  XYTable[] = {    //this declaration gives slow 4 FPS!

    0,   1,   2,   3,   4,   5,   6,   7,
    15,  14,  13,  12,  11,  10,   9,   8,
    16,  17,  18,  19,  20,  21,  22,  23,
    31,  30,  29,  28,  27,  26,  25,  24,
    32,  33,  34,  35,  36,  37,  38,  39,
    47,  46,  45,  44,  43,  42,  41,  40,
    48,  49,  50,  51,  52,  53,  54,  55,
    63,  62,  61,  60,  59,  58,  57,  56,
    64,  65,  66,  67,  68,  69,  70,  71,
    79,  78,  77,  76,  75,  74,  73,  72,
    80,  81,  82,  83,  84,  85,  86,  87,
    95,  94,  93,  92,  91,  90,  89,  88,
    96,  97,  98,  99, 100, 101, 102, 103,
   111, 110, 109, 108, 107, 106, 105, 104,
   112, 113, 114, 115, 116, 117, 118, 119,
   127, 126, 125, 124, 123, 122, 121, 120,
   128, 129, 130, 131, 132, 133, 134, 135,
   143, 142, 141, 140, 139, 138, 137, 136,
   144, 145, 146, 147, 148, 149, 150, 151,
   159, 158, 157, 156, 155, 154, 153, 152,
   160, 161, 162, 163, 164, 165, 166, 167,
   175, 174, 173, 172, 171, 170, 169, 168,
   176, 177, 178, 179, 180, 181, 182, 183,
   191, 190, 189, 188, 187, 186, 185, 184,
   192, 193, 194, 195, 196, 197, 198, 199,
   207, 206, 205, 204, 203, 202, 201, 200,
   208, 209, 210, 211, 212, 213, 214, 215,
   223, 222, 221, 220, 219, 218, 217, 216,
   224, 225, 226, 227, 228, 229, 230, 231,
   239, 238, 237, 236, 235, 234, 233, 232,
   240, 241, 242, 243, 244, 245, 246, 247,
   255, 254, 253, 252, 251, 250, 249, 248
  };

  byte whatSectorWeIn = x>>3;         // x/8   0, 1, 2 or 3 calculate number of sector
  byte whatColumnInSectorWeIn = x&7;  // x%8   0..7 calculate row in sector
  uint16_t index = XYTable [(y<<3)+whatColumnInSectorWeIn] + (whatSectorWeIn<<8);
  return index;
}




// // // this XY() taken from satubarosu sketch https://wokwi.com/projects/339693454666760786 
// // // if you dont have free space try it!


//  uint16_t XY(const int8_t x, const int8_t y) {   
//   // when out-of-bounds return the pixel after the visible LEDs
//   if (x >= NUM_COLS || x < 0)  return NUM_LEDS;
//   if (y >= NUM_ROWS || y < 0) return NUM_LEDS;

//   const uint8_t qwidth = NUM_COLS / 4;
//   uint8_t matrix = x / qwidth;  // which submatrix
//   uint8_t localx = x % qwidth;  // coordinate on the submatrix
//   uint8_t localy = y;
//   // if (matrix & 1) { // odd numbered matrices are rotated 180°
//   //   localx = qwidth - 1 - localx;
//   //   localy = NUM_ROWS - 1 - localy;
//   // }

//   // offset to start of the submatrix
//   uint16_t xy = matrix * qwidth * NUM_ROWS;
//   if (localy & 1)  // odd rows are reversed
//     xy += (localy + 1) * qwidth - 1 - localx;
//   else
//     xy += localy * qwidth + localx;
//   return xy;
// }
FPS: 0
Power: 0.00W