//Sprite_scroll
//241 LED ring cilindrical map 
//Fastled rgb led demo
//Yaroslaw Turbin, 02-05-2021 
//https://vk.com/ldirko 
//https://www.reddit.com/user/ldirko/ 
//https://twitter.com/ldir_ko


#include <FastLED.h>

#define DATA_PIN     3
#define NUM_COLS_CILINDR 60           // resolution for cilindrical lookup table
#define NUM_ROWS_CILINDR 9           // resolution for cinindrical lookup table
#define NUM_LEDS    241

#define LED_TYPE    WS2812B          //leds type
#define COLOR_ORDER GRB              //color order of leds
#define MAX_POWER_MILLIAMPS 800  //write here your power in milliamps. default i set 800 mA for safety
#define BRIGHTNESS 255

CRGB leds[NUM_LEDS+1];  //one safe pixel in bottom. its index 241 

const uint8_t exp_gamma[256] PROGMEM = {
0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   1,   1,
1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
1,   2,   2,   2,   2,   2,   2,   2,   2,   2,   3,   3,   3,   3,   3,
4,   4,   4,   4,   4,   5,   5,   5,   5,   5,   6,   6,   6,   7,   7,
7,   7,   8,   8,   8,   9,   9,   9,   10,  10,  10,  11,  11,  12,  12,
12,  13,  13,  14,  14,  14,  15,  15,  16,  16,  17,  17,  18,  18,  19,
19,  20,  20,  21,  21,  22,  23,  23,  24,  24,  25,  26,  26,  27,  28,
28,  29,  30,  30,  31,  32,  32,  33,  34,  35,  35,  36,  37,  38,  39,
39,  40,  41,  42,  43,  44,  44,  45,  46,  47,  48,  49,  50,  51,  52,
53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,
68,  70,  71,  72,  73,  74,  75,  77,  78,  79,  80,  82,  83,  84,  85,
87,  89,  91,  92,  93,  95,  96,  98,  99,  100, 101, 102, 105, 106, 108,
109, 111, 112, 114, 115, 117, 118, 120, 121, 123, 125, 126, 128, 130, 131,
133, 135, 136, 138, 140, 142, 143, 145, 147, 149, 151, 152, 154, 156, 158,
160, 162, 164, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187,
190, 192, 194, 196, 198, 200, 202, 204, 207, 209, 211, 213, 216, 218, 220,
222, 225, 227, 229, 232, 234, 236, 239, 241, 244, 246, 249, 251, 253, 254, 255};

const uint32_t sprite4 [] PROGMEM = {   //20x31

0x549a44, 0xc7ffba, 0x80df77, 0x147c03, 0x33950a, 0x3f8900, 0x92ad00, 0xe2e54e, 0xbec16a, 0x111900, 0x000706, 0x000e2b, 0x045283, 0x1f71a3, 0x376889, 0x001928, 0x000406, 0x030400, 0x6e6f5d, 0x999b85, 
0x368c2b, 0x39942d, 0x2a8b1a, 0x379314, 0x297900, 0x9ed539, 0xe3f65e, 0x9d9e26, 0x191e00, 0x000a00, 0x000f1a, 0x215376, 0x2f76a4, 0x185b86, 0x001a33, 0x00050f, 0x020804, 0x808074, 0xdbdccc, 0x939482, 
0x11890e, 0x1e8e12, 0x177a00, 0x3c8600, 0xacd730, 0xa3b61c, 0xb5bb51, 0x1c1e00, 0x000800, 0x000f1a, 0x1c5c82, 0x17608d, 0x2b6388, 0x001a34, 0x000610, 0x000602, 0x919481, 0xbabca6, 0xb3b4a6, 0x333528, 
0x068300, 0x2b9a0d, 0x368800, 0x7daf1c, 0xe1f45d, 0xc0c247, 0x181900, 0x000900, 0x00101b, 0x1a4b6c, 0x2a719f, 0x276a95, 0x001731, 0x00050f, 0x010602, 0x807e6f, 0xdeddc8, 0xe3e5cf, 0x31342b, 0x030802, 
0x2f9606, 0x267b00, 0xafda33, 0xe4f45e, 0x939834, 0x151800, 0x000800, 0x000f1c, 0x1b5980, 0x3175a4, 0x1f557b, 0x001a34, 0x00050f, 0x010801, 0x929381, 0xfcfae3, 0xb6b7a5, 0x383c2e, 0x000403, 0x00090b, 
0x388e00, 0x9bdc44, 0xa3b720, 0xbabb43, 0x161900, 0x000700, 0x001120, 0x23587a, 0x155b8c, 0x266692, 0x001933, 0x00050f, 0x060b05, 0x989989, 0xbdbba4, 0xd3d2bd, 0x383b30, 0x000506, 0x000815, 0x122f41, 
0x589e00, 0xc8fd71, 0xa9ba54, 0x171b00, 0x000700, 0x001120, 0x0f4d74, 0x2d74a2, 0x2e668b, 0x001630, 0x000610, 0x030804, 0x7d7e6c, 0xeaead2, 0xeae9d5, 0x303227, 0x000403, 0x000816, 0x043351, 0x19557a, 
0x4e8505, 0x5d881f, 0x0d1e00, 0x000900, 0x00101f, 0x26587b, 0x2e75a3, 0x155680, 0x001933, 0x000610, 0x030804, 0x99978a, 0xf9f9e1, 0xb1b199, 0x38382c, 0x000605, 0x000918, 0x113a56, 0x2d6890, 0x0d507d, 
0x3f6927, 0x001b00, 0x000a00, 0x000f1d, 0x1e5c83, 0x165d8b, 0x2e648a, 0x001a31, 0x00050f, 0x030905, 0x9e9f8f, 0xafae99, 0xdad9c5, 0x343525, 0x010300, 0x000813, 0x0d4367, 0x195d8a, 0x255f85, 0x002e52, 
0x001500, 0x000f05, 0x001222, 0x1a4c6f, 0x3175a4, 0x256690, 0x00152d, 0x00060e, 0x050b07, 0x797c6b, 0xebf2d3, 0xdee5c4, 0x71735b, 0x050600, 0x010300, 0x001421, 0x326c92, 0x28719e, 0x03416a, 0x00173c, 
0x000a0e, 0x001525, 0x1c6087, 0x2c73a1, 0x1f5378, 0x00172d, 0x00060e, 0x050a04, 0x9b9e8d, 0xeef7d8, 0xa0b58a, 0xa8be90, 0xf4fbd9, 0x787a64, 0x060600, 0x00050b, 0x00223a, 0x1f5579, 0x266994, 0x004877, 
0x001431, 0x255a7c, 0x165f8c, 0x246791, 0x00172d, 0x00050d, 0x040903, 0x9fa490, 0xa2b28d, 0xcceab4, 0x4e833d, 0x598e48, 0xcfedb7, 0xacba96, 0x7d806d, 0x000500, 0x000610, 0x001f35, 0x266085, 0x064d79, 
0x09568a, 0x2f76a4, 0x295f85, 0x00162e, 0x00040d, 0x070c06, 0x828371, 0xeafad5, 0xc0eeae, 0x29731c, 0x2f9226, 0x2b8c23, 0x397e2b, 0xd7ffc3, 0xe7f3cf, 0x666755, 0x000501, 0x00060e, 0x00192d, 0x27536e, 
0x2272a7, 0x165682, 0x001630, 0x00050d, 0x080d07, 0xa2a791, 0xe9f7d3, 0x96bc81, 0x408930, 0x349220, 0x177f00, 0x1b8100, 0x368f21, 0x519542, 0xa2c38c, 0xeffad8, 0x7f826f, 0x020701, 0x00060e, 0x031927, 
0x2f6081, 0x001731, 0x000612, 0x050b07, 0xa1a491, 0xaaba93, 0xc3efb0, 0x448a34, 0x19790d, 0x30900a, 0x75b719, 0x60a204, 0x30900b, 0x1b7b10, 0x549344, 0xd0f3bb, 0xaab692, 0x808372, 0x000503, 0x00090e, 
0x00294a, 0x000a22, 0x00050d, 0x5f6058, 0xf8fae4, 0xcddeb2, 0x548241, 0x3e8a2f, 0x238e1a, 0x258a00, 0xc3ff61, 0xb8f456, 0x137900, 0x299422, 0x40842f, 0x61874c, 0xdeedc6, 0xeaecd7, 0x31332e, 0x04080b, 
0x276e9c, 0x002347, 0x000615, 0x010300, 0x7e8170, 0xb6bfa0, 0xe0faca, 0x548c41, 0x177d0f, 0x279815, 0x4da31a, 0x3f950c, 0x289715, 0x17780d, 0x6d9f58, 0xeafcd2, 0xa9b297, 0x5c5f54, 0x000505, 0x030a10, 
0x1f6d9e, 0x1e5f89, 0x00203a, 0x000610, 0x000702, 0x7e836f, 0xdde8c6, 0xa4c78f, 0x49983f, 0x2d8f22, 0x1b7d06, 0x1c7b05, 0x2f8c21, 0x63ab55, 0xa3c18d, 0xe5ebcf, 0x5b5f51, 0x000403, 0x000713, 0x092334, 
0x054976, 0x3277a1, 0x266590, 0x00213f, 0x000710, 0x020700, 0x666b57, 0xedfbd8, 0xc9eab5, 0x3f792d, 0x378f27, 0x348b23, 0x4e8439, 0xe0fccb, 0xe7f2d4, 0x464a3b, 0x000400, 0x000612, 0x002441, 0x1f577c, 
0x001131, 0x144c6f, 0x1a618f, 0x2f6e99, 0x00223b, 0x000811, 0x000700, 0x7c7f6c, 0xabb497, 0xdcf8c7, 0x539243, 0x67a456, 0xe2f9cb, 0xafb39a, 0x5c5e50, 0x000603, 0x000714, 0x062b45, 0x2c668c, 0x0b4e7b, 
0x000610, 0x000b1d, 0x194f75, 0x2a6d98, 0x1c5d87, 0x002444, 0x000610, 0x010300, 0x7b7e6d, 0xe8f1d2, 0xa4ba8c, 0xa2b588, 0xedf3d7, 0x5a5b4b, 0x010200, 0x000610, 0x003353, 0x175a84, 0x27658c, 0x033d63, 
0x031c00, 0x000d00, 0x000f20, 0x0e4468, 0x2f76a2, 0x296a94, 0x001e38, 0x000612, 0x000501, 0x616252, 0xf5f5dd, 0xeaead0, 0x686752, 0x030400, 0x020200, 0x011422, 0x356f94, 0x2a73a0, 0x00406a, 0x00183f, 
0x3a7c25, 0x002a00, 0x000d00, 0x000c1d, 0x174c6e, 0x1d5e88, 0x2e6f99, 0x002646, 0x000612, 0x030500, 0x7b7c6c, 0xb3b29d, 0xeeeed4, 0x575642, 0x030200, 0x00050d, 0x083049, 0x1e587d, 0x236892, 0x003f6e, 
0x3c8909, 0x6fa83d, 0x1c2e00, 0x000800, 0x000d18, 0x174c6c, 0x2b729e, 0x1a5b85, 0x00233e, 0x000612, 0x000601, 0x787b6a, 0xf3f5df, 0xb3b29d, 0x565749, 0x000301, 0x000814, 0x062e47, 0x2b678c, 0x0a4e7b, 
0x689f05, 0xd3fd6d, 0xbac84f, 0x282b00, 0x000800, 0x000c1a, 0x0b4163, 0x31749f, 0x2d6c97, 0x002141, 0x000611, 0x000500, 0x5c5e50, 0xf2f4de, 0xf2f1dc, 0x434635, 0x000300, 0x000710, 0x00253c, 0x275674, 
0x438700, 0x8ac022, 0xa6bf26, 0xcdd55b, 0x2c2f00, 0x000900, 0x000c18, 0x154b6d, 0x185c89, 0x306f9a, 0x00253f, 0x000712, 0x000601, 0x727564, 0xb3b59d, 0xe9ebd3, 0x595a4a, 0x000400, 0x000611, 0x0a2739, 
0x259505, 0x217d00, 0x95c82f, 0xd4ea57, 0xa7ad2f, 0x2c3000, 0x000800, 0x000a1b, 0x154a6c, 0x3474a0, 0x185b86, 0x002849, 0x000712, 0x030500, 0x727564, 0xf5f7e1, 0xb3b39b, 0x585b4a, 0x000504, 0x000b11, 
0x008100, 0x2b9b13, 0x358500, 0x73a40a, 0xe0f75f, 0xc7cd51, 0x242500, 0x000800, 0x000f19, 0x093e60, 0x2e75a1, 0x30719b, 0x00203a, 0x000813, 0x000601, 0x585a4c, 0xe8e7d2, 0xe9ebd6, 0x41423a, 0x050a04, 
0x158c14, 0x138708, 0x128200, 0x338c00, 0x8fbf2b, 0x9eb326, 0xd1d75b, 0x2e3200, 0x000800, 0x000b17, 0x17496a, 0x1c5b86, 0x2d6e98, 0x00294a, 0x000712, 0x000400, 0x6c6e61, 0xadae9e, 0xc7c9bb, 0x4e5243, 
0x308c29, 0x4eb147, 0x25921f, 0x2e9414, 0x297600, 0x91c22a, 0xe1f055, 0xa6a727, 0x2f2f00, 0x000700, 0x000917, 0x15496e, 0x2b77a8, 0x165d89, 0x032843, 0x000610, 0x000403, 0x656559, 0xd7dac9, 0x8a8d7a, 
0x669755, 0xd7ffc8, 0x9de291, 0x1a700b, 0x2c9a13, 0x328d00, 0x85a400, 0xeded57, 0xd1d368, 0x141800, 0x000600, 0x000b22, 0x014572, 0x2876a7, 0x357098, 0x001b35, 0x00040a, 0x020300, 0x585a4d, 0xa2a594

};

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

static uint16_t yspeed = 255; 
static uint16_t xspeed = 255;

byte sprOffs = beatsin8 (5,0,8);
for (byte j = 0; j < NUM_ROWS_CILINDR; j++) {
  byte yoffs = (j+yspeed)%31;

   for (byte i = 0; i < NUM_COLS_CILINDR; i++) {
    byte xoffs = (i+xspeed)%12;
    uint16_t index = XY_cilindrical(i,j);
    if (index!=241) leds[index] = pgm_read_dword (sprite4+yoffs*20+xoffs+sprOffs);
}}    
yspeed++;
// xspeed++;

// GammaCorrection();
LEDS.show();
delay(60); 

}

byte XY_cilindrical (byte x, byte y) {
static const byte CilindricalLookTable [] = {   //1/4 of full table for reduce memory size. little bit tricky to calculate index )) 
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
60, 61, 241, 62, 63, 64, 65, 241, 66, 67, 68, 69, 241, 70, 71,
108, 241, 109, 110, 241, 111, 112, 241, 113, 114, 241, 115, 116, 241, 117,
148, 241, 149, 241, 150, 241, 151, 241, 152, 153, 241, 154, 241, 155, 241,
180, 241, 241, 181, 241, 182, 241, 241, 183, 241, 184, 241, 241, 185, 241,
204, 241, 241, 241, 205, 241, 241, 241, 206, 241, 241, 207, 241, 241, 241,
220, 241, 241, 241, 241, 221, 241, 241, 241, 241, 222, 241, 241, 241, 241,
232, 241, 241, 241, 241, 241, 241, 241, 233, 241, 241, 241, 241, 241, 241,
240, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241};

static const byte offs [] = {15, 12, 10, 8, 6, 4, 3, 2, 0};

byte index = CilindricalLookTable [y*15+x%15];
if (index!=241) {index+= (x/15)*offs[y];}

return (index);
}

void GammaCorrection(){   //gamma correction function 
byte r,g,b;
for (uint16_t i=0; i<256; i++){
r=leds[i].r;
g=leds[i].g;
b=leds[i].b;
leds[i].r = pgm_read_byte(exp_gamma + r);
leds[i].g = pgm_read_byte(exp_gamma + g);
leds[i].b = pgm_read_byte(exp_gamma + b);
}
}