Components and supplies
Stereo audio female plug
HC-05 Bluetooth Module
WS2812b 5m - 150 LEDs strip
Black foam board (A2 - 5mm thick)
Arduino Nano R3
TL072 based audio amplifier
Illuminated blue rocker switch
19mm illuminated blue push button
L profiled aluminium bar
Too many cables...
Prototype PCB
45mm illuminated round arcade push button
405x405mm white acrylic glass
5V - 50W power supply
LACK table - Ikea
Tools and machines
Soldering iron (generic)
Box cutter
3D Printer (generic)
Wood rasp
Drill
Hot glue gun (generic)
Saw
Project description
Code
Audio spectrum visualizer
arduino
FischiMc's code adapted to my LED matrix
1/* 2 Written by FischiMc and SupaStefe, modified by Antoine Rochebois (scaling to 12*12) 3 4 This sketch uses a 10x10 RGB LED-Matrix as a spectrum analyzer 5 It uses a FTT Library to analyze an audio signal connected to the 6 pin A7 of an Arduino nano. Everytime a column gets higher than 7 10 pixels the color of each column changes. 8*/ 9 10#define LOG_OUT 0 //set output of FFT library to linear not logarithmical 11#define LIN_OUT 1 12#define FFT_N 256 //set to 256 point fft 13 14#include <FFT.h> //include the FFT library 15#include <FastLED.h> //include the FastLED Library 16#include <math.h> //include library for mathematic funcions 17#define DATA_PIN 5 //DATA PIN WHERE YOUR LEDS ARE CONNECTED 18#define NUM_LEDS 144 //amount of LEDs in your matrix 19CRGB leds[NUM_LEDS]; 20float faktoren[12] = {1, 1.1, 1.15, 1.25, 1.35, 1.45, 1.55, 1.65 , 1.75, 1.8, 2, 3}; //factors to increase the height of each column 21unsigned char hs[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0}; //height of each column 22float hue = 0; //hue value of the colors 23 24void setBalken(unsigned char column, unsigned char height) { //calculation of the height of each column 25 unsigned char h = (unsigned char)map(height, 0, 255, 0, 12); 26 h = (unsigned char)(h * faktoren[column]); 27 if (h < hs[column]) { 28 hs[column]--; 29 } 30 else if (h > hs[column]) { 31 hs[column] = h; 32 } 33 if (height > 250) { 34 hue += 2; //CHANGE THIS VALUE IF YOU WANT THE DIFFERENCE BETWEEN THE COLORS TO BE BIGGER 35 if (hue > 25) hue = 0; 36 } 37 38 for (unsigned char y = 0; y < 12; y++) { //set colors of pixels according to column and hue 39 if (hs[column] > y) { 40 if (column % 2 == 0) { 41 leds[y + (column * 12)] = CHSV((hue * 12) + (column * 12), 255, 200); 42 } else { 43 leds[12 - y + (column * 12)] = CHSV((hue * 12) + (column * 12), 255, 200); 44 } 45 46 } else { 47 if (column % 2 == 0) { 48 leds[y + (column * 12)] = CRGB::Black; 49 } else { 50 leds[12 - y + (column * 12)] = CRGB::Black; 51 } 52 } 53 } 54} 55 56unsigned char grenzen[13] = {0, 3, 5, 7, 9, 11, 13, 15, 17, 20, 24, 32, 69}; //borders of the frequency areas 57 58void setup() { 59 FastLED.addLeds<WS2812B, DATA_PIN, GRB> (leds, NUM_LEDS); 60 TIMSK0 = 0; //turn off timer0 for lower jitter 61 ADCSRA = 0xe5; //set the adc to free running mode 62 ADMUX = 0x40; //use pin A0 63 DIDR0 = 0x01; //turn off the digital input for 64 analogReference(EXTERNAL); //set aref to external 65} 66 67void loop() { 68 while (1) { //reduces jitter 69 cli(); //UDRE interrupt slows this way down on arduino1.0 70 for (int i = 0 ; i < 512 ; i += 2) { //save 256 samples 71 while (!(ADCSRA & 0x10)); //wait for adc to be ready 72 ADCSRA = 0xf5; //restart adc 73 byte m = ADCL; //fetch adc data 74 byte j = ADCH; 75 int k = (j << 8) | m; //form into an int 76 k -= 0x0200; //form into a signed int 77 k <<= 6; //form into a 16b signed int 78 fft_input[i] = k; //put real data into even bins 79 } 80 81 fft_window(); // window the data for better frequency response 82 fft_reorder(); // reorder the data before doing the fft 83 fft_run(); // process the data in the fft 84 fft_mag_lin(); // take the output of the fft 85 sei(); 86 87 fft_lin_out[0] = 0; 88 fft_lin_out[1] = 0; 89 90 for (unsigned char i = 0; i < 13; i++) { 91 unsigned char maxW = 0; 92 for (unsigned char x = grenzen[i]; x < grenzen[i + 1]; x++) { 93 94 if ((unsigned char)fft_lin_out[x] > maxW) { 95 maxW = (unsigned char)fft_lin_out[x]; 96 } 97 } 98 99 setBalken(i, maxW); 100 101 } 102 TIMSK0 = 1; 103 FastLED.show(); 104 TIMSK0 = 0; 105 } 106}
decoration.h
c_cpp
1/*void fillingScreen() { 2 int iterations = 0; 3 while (!menuValidation && iterations < 400) { 4 byte c[3]; 5 for (byte i = 0; i < 3; i++) { 6 c[i] = random(0, 256); 7 } 8 for (byte i = 0; i < 12; i++) { 9 for (byte j = 0; j < 12; j++) { 10 leds[pgm_read_byte(&ledsAdress[i][j])] = (( (c[0])) << 16) + ( (c[1]) << 8) + ( (c[2])); 11 FastLED.show(); 12 delay(25); 13 iterations++; 14 } 15 } 16 } 17} 18 19void fadingScreen() { 20 int iterations = 0; 21 while (!menuValidation && iterations < 400) { 22 byte c[3]; 23 for (byte i = 0; i < 3; i++) { 24 c[i] = random(0, 256); 25 } 26 for (byte k = 0; k < 128; k = k + 2) { 27 for (byte i = 0; i < 12; i++) { 28 for (byte j = 0; j < 12; j++) { 29 leds[pgm_read_byte(&ledsAdress[i][j])] = (( (c[0])) << 16) + ( (c[1]) << 8) + ( (c[2])); 30 } 31 32 } 33 iterations++; 34 FastLED.setBrightness(k); 35 FastLED.show(); 36 delay(50); 37 } 38 for (uint8_t k = 128; k > 0; k = k - 2) { 39 for (byte i = 0; i < 12; i++) { 40 for (byte j = 0; j < 12; j++) { 41 leds[pgm_read_byte(&ledsAdress[i][j])] = (( (c[0])) << 16) + ( (c[1]) << 8) + ( (c[2])); 42 } 43 44 } 45 iterations++; 46 FastLED.setBrightness(k); 47 FastLED.show(); 48 delay(50); 49 } 50 51 } 52 clearImg(); 53 FastLED.setBrightness(128); 54}*/ 55void crossingSnakes() { 56 for (byte i = 0; i < 144; i++) { 57 for (byte j = 0; j < 5; j++) { 58 leds[(i + j + 0) % 144] = 0xff0000; 59 leds[(i + j + 12) % 144] = 0xffff00; 60 leds[(i + j + 23) % 144] = 0x00ff00; 61 leds[(i + j + 36) % 144] = 0x00ffff; 62 leds[(i + j + 48) % 144] = 0x0000ff; 63 leds[(i + j + 59) % 144] = 0xff00ff; 64 leds[(i + j + 72) % 144] = 0xff0000; 65 leds[(i + j + 84) % 144] = 0xffff00; 66 leds[(i + j + 95) % 144] = 0x00ff00; 67 leds[(i + j + 107) % 144] = 0x00ffff; 68 leds[(i + j + 120) % 144] = 0x0000ff; 69 leds[(i + j + 134) % 144] = 0xff00ff; 70 } 71 FastLED.show(); 72 delay(85); 73 clearImg(); 74 if (menuValidation) break; 75 } 76} 77 78 79/*public void rainingStars(Panel p) { 80 int iterations = 0; 81 while (!TableLED.menuValidation && iterations < 400) { 82 83 int img[][] = new int[12][12]; 84 int color[][] = new int[12][12]; 85 boolean stars[][] = new boolean[12][12]; 86 for (int i = 0; i < stars.length; i++) { 87 for (int j = 0; j < stars[i].length; j++) { 88 if (Math.random() < 0.035) { 89 stars[i][j] = true; 90 color[i][j] = (int) (Math.random() * 4); 91 } 92 } 93 } 94 for (int k = 0; k < 256; k = k + 4) { 95 try { 96 Thread.sleep(50); 97 } catch (InterruptedException e) { 98 e.printStackTrace(); 99 } 100 iterations++; 101 for (int i = 0; i < stars.length; i++) { 102 for (int j = 0; j < stars[i].length; j++) { 103 if (stars[i][j]) { 104 105 switch (color[i][j]) { 106 case 0: 107 img[i][j] = (((int) (0.2 * k)) << 16) + ((int) (0.32 * k) << 8) + ((int) (0.7 * k)); 108 break; 109 case 1: 110 img[i][j] = (((int) (0.28 * k)) << 16) + ((int) (0.463 * k) << 8) + k; 111 break; 112 case 2: 113 img[i][j] = (k << 16) + ((int) (0.757 * k) << 8) + ((int) (0.146 * k)); 114 break; 115 default: 116 img[i][j] = (((int) (0.27 * k)) << 16) + ((int) (0.118 * k) << 8) + ((int) (0.44 * k)); 117 break; 118 } 119 120 } 121 } 122 } 123 p.setFrame(img); 124 } 125 } 126 }*/ 127 128 129 130/*void decoration() { 131 132 byte r = random(0, 6); 133 readPointer(); 134 switch (r) { 135 case 0: 136 crossingSnakes(); 137 break; 138 case 1: 139 glitchRainingStars(); 140 break; 141 case 2: 142 rainingStars(); 143 break; 144 case 3: 145 fadingScreen(); 146 break; 147 case 4: 148 bottleAnimation(60, 334); 149 default: 150 fillingScreen(); 151 break; 152 } 153 154}*/ 155
Arduino main code
arduino
This file is the main code that run on the Arduino, it uses several home-made methods & functions to run games and other features. I'll upload them once the code is finished and bugless.
1/* 2 * 3 * Code by Antoine ROCHEBOIS : CC-BY-NC 4 * 5 * 6 * This file is the main code that run on the Arduino, it uses several 7 * home-made methods & functions to run games and other features, I'll * upload them once the code is finished and bugless. 8 * 9 * 10 * 11 * */ 12#include "FastLED.h" 13#include <avr/pgmspace.h> 14#include <SoftwareSerial.h> 15 16#include "imgMario.h" //Import 2D array of 32bits int provinding the RGB 17#include "imgMenu.h" //code for each image of the Menu and Images function 18 19#define M_PIN 2 //Pin for the menuInterrupt 20#define R1_PIN 8 // 21#define L1_PIN 9 // Digital inputs used by arcade buttons (side) 22#define R2_PIN 6 // 23#define L2_PIN 7 // 24#define DATA_PIN 5 //Data PIN for the led matrix 25 26#define COLOR_ORDER GRB // if colors are mismatched; change this 27#define NUM_LEDS 144 // 12*12=144 leds in the strip 28#define LED_TYPE WS2812B 29// this creates an LED array to hold the values for each led in your strip 30CRGB leds[NUM_LEDS]; 31 32const PROGMEM byte ledsAdress[12][12] = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 33 {23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12}, 34 {24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35}, 35 {47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36}, 36 {48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, 37 {71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60}, 38 {72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83}, 39 {95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84}, 40 {96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107}, 41 {119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108}, 42 {120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131}, 43 {143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132} 44}; //Adress of each led in the matrix (Progmem means stored in FLASH instead //of SRAM) 45 46SoftwareSerial BT(10, 11); //Emulates an Serial BT terminal 47 48boolean grid[12][12]; //(used in a game, ignore) 49char message; //char read on the BT terminal 50char curControl; //current control ID 51int menuPointer = 0; //Position in the menu 52volatile bool menuValidation = 0; //Variable set to true when the menu switch 53//is pushed 54 55unsigned long curTime; 56unsigned long prevUpdateTime = 0; //Variables for timed events 57unsigned long prevButtonTime = 0; 58 59//Function executed when the user push the menuButton (set menuValidation to 60//true + debounce input) 61void menuInterrupt() { 62 static unsigned long last_interrupt_time = 0; 63 unsigned long interrupt_time = millis(); 64 if (interrupt_time - last_interrupt_time > 200) { 65 menuValidation = true; 66 } 67 last_interrupt_time = interrupt_time; 68} 69 70//Displays static images stocked in FLASH, if roll == 1, draws it whith a fancy red line 71void setImg(const unsigned long frame[12][12], bool roll) { 72 if (!roll) { 73 for (byte i = 0; i < 12; i++) { 74 for (byte j = 0; j < 12; j++) { 75 leds[pgm_read_byte(&ledsAdress[i][j])] = pgm_read_dword(&frame[i][j]); 76 } 77 } 78 FastLED.show(); 79 80 } else { 81 for (uint8_t i = 11; i > 0; i--) { 82 for (byte j = 0; j < 12; j++) { 83 if (i > 0) { 84 leds[pgm_read_byte(&ledsAdress[i][j])] = 0xe22c79; 85 } else { 86 leds[pgm_read_byte(&ledsAdress[i][j])] = pgm_read_dword(&frame[i][j]); 87 } 88 89 leds[pgm_read_byte(&ledsAdress[(i + 13) % 12][j])] = pgm_read_dword(&frame[(i + 13) % 12][j]); 90 } 91 FastLED.show(); 92 delay(70); 93 } 94 } 95 96 97} 98 99//Erase the screen with a red sweeping line 100void resetImg() { 101 for (byte i = 0; i < 12; i++) { 102 for (byte j = 0; j < 12; j++) { 103 leds[pgm_read_byte(&ledsAdress[i][j])] = 0xe22c79; 104 if (i > 0) { 105 leds[pgm_read_byte(&ledsAdress[(i + 11) % 12][j])] = 0x000000; 106 } 107 108 } 109 FastLED.show(); 110 delay(70); 111 } 112} 113//Erase the screen by fading it 114void fadeImg() { 115 for (uint8_t i = 128; i > 0; i = i - 4) { 116 FastLED.setBrightness(i); 117 FastLED.show(); 118 delay(24); 119 } 120 delay(250); 121 FastLED.setBrightness(128); 122} 123//Instant erase of the screen 124void clearImg() { 125 for (byte dim1 = 0; dim1 < 12; dim1++) { 126 for (byte dim2 = 0; dim2 < 12; dim2++) { 127 leds[pgm_read_byte(&ledsAdress[dim1][dim2])] = 0x000000; 128 } 129 } 130} 131 132 133//Read inputs (BT + digital IO) 134void readPointer() { 135 136 //Read BT (hc-05 module) 137 while (BT.available() > 0) { 138 message = BT.read(); 139 } 140 //Changes control variables 141 if (message == 'q' ) { 142 --menuPointer; 143 curControl = 'q'; 144 } else if (message == 'd') { 145 ++menuPointer; 146 curControl = 'd'; 147 } else if (message == 'z') { 148 curControl = 'z'; 149 } else if (message == 's') { 150 curControl = 's'; 151 } else if (message == 'a') { 152 curControl = 'a'; 153 } else if (message == 'y') { 154 menuValidation = true; 155 } 156 message = 'n'; //Reset message 157 158 //Read digital IO pins 159 if (!digitalRead(L1_PIN)) { 160 if ( (millis() - prevButtonTime) > 150) { 161 curControl = 'q'; 162 --menuPointer; 163 prevButtonTime = millis(); 164 } 165 } else if (!digitalRead(R1_PIN)) { 166 if ( (millis() - prevButtonTime) > 150) { 167 curControl = 'd'; 168 ++menuPointer; 169 prevButtonTime = millis(); 170 } 171 } else if (!digitalRead(L2_PIN)) { 172 if ( (millis() - prevButtonTime) > 150) { 173 curControl = 'z'; 174 --menuPointer; 175 prevButtonTime = millis(); 176 } 177 } else if (!digitalRead(l2_PIN)) { 178 if ( (millis() - prevButtonTime) > 150) { 179 curControl = 's'; 180 ++menuPointer; 181 prevButtonTime = millis(); 182 } 183 } 184 185} 186 187#include "gameOfLife.h" //Include features and games methods and functions 188#include "snake.h" 189#include "pong.h" 190#include "tetris.h" 191#include "bottle.h" 192#include "decoration.h" 193#include "font.h" 194 195 196 197 198 199 200 201/* 202* 203* RUN AT STARTUP 204* 205*/ 206 207void setup() { 208 //Setup the BT connection 209 BT.begin(9600); 210 211 //Setup the IO pin (Inputs with a built-in pull-up resistor or interupt) 212 pinMode(R1_PIN, INPUT_PULLUP); 213 pinMode(L1_PIN, INPUT_PULLUP); 214 pinMode(R2_PIN, INPUT_PULLUP); 215 pinMode(L2_PIN, INPUT_PULLUP); 216 attachInterrupt(digitalPinToInterrupt(M_PIN), menuInterrupt, FALLING); 217 218 //Setup the Led strip 219 FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); 220 221 //Intro animation (display a beer and load the menu) 222 FastLED.setBrightness(0); 223 setImg(beer, 0); 224 delay(250); 225 for (uint8_t i = 0; i <= 128; i = i + 4) { 226 FastLED.setBrightness(i); 227 FastLED.show(); 228 delay(42); 229 } 230 delay(2400); 231 fadeImg(); 232 clearImg(); 233 FastLED.show(); 234 delay(250); 235 setImg(menuTetris, 1); 236 237} 238 239 240 241 242 243 244 245 246/* 247* 248* RUN PERPETUALY 249* 250*/ 251void loop() { 252 253//Menu Interface and games/features launcher 254 switch ((menuPointer + 12000) % 12) { 255 case 0: 256 setImg(menuTetris, 0); 257 while ((menuPointer + 12000) % 12 == 0 && !menuValidation) { 258 readPointer(); 259 } 260 if (menuValidation) { 261 menuValidation = false; 262 while (!menuValidation) { 263 launchTetris(); //Tetris game 264 } 265 menuValidation = false; 266 menuPointer = 0; 267 resetImg(); 268 setImg(menuTetris, 1); 269 } 270 break; 271 case 1: 272 setImg(menuSimon, 0); 273 while ((menuPointer + 12000) % 12 == 1 && !menuValidation) { 274 readPointer(); 275 } 276 if (menuValidation) { 277 menuValidation = false; //Displays a cross : feature not implemented yet 278 setImg(menuError, 0); 279 delay(1250); 280 menuPointer = 1; 281 resetImg(); 282 setImg(menuSimon, 1); 283 } 284 break; 285 case 2: 286 setImg(menuPong, 0); 287 while ((menuPointer + 12000) % 12 == 2 && !menuValidation) { 288 readPointer(); 289 } 290 if (menuValidation) { 291 menuValidation = false; 292 while (!menuValidation) { 293 launchPong(); //Pong game for 2 players 294 } 295 menuValidation = false; 296 menuPointer = 2; 297 resetImg(); 298 setImg(menuPong, 1); 299 } 300 break; 301 case 3: 302 setImg(menuSnake, 0); 303 while ((menuPointer + 12000) % 12 == 3 && !menuValidation) { 304 readPointer(); 305 } 306 if (menuValidation) { 307 menuValidation = false; 308 while (!menuValidation) { 309 launchSnake(); //Snake game 310 } 311 menuValidation = false; 312 menuPointer = 3; 313 resetImg(); 314 setImg(menuSnake, 1); 315 } 316 break; 317 case 4: 318 setImg(menuBottle, 0); 319 while ((menuPointer + 12000) % 12 == 4 && !menuValidation) { 320 readPointer(); 321 } 322 if (menuValidation) { 323 menuValidation = false; 324 while (!menuValidation) { 325 bottle(); //A wheel that stops on a random location on the screen 326 } 327 menuValidation = false; 328 menuPointer = 4; 329 resetImg(); 330 setImg(menuBottle, 1); 331 } 332 break; 333 case 5: 334 setImg(menuGameOfLife, 0); 335 while ((menuPointer + 12000) % 12 == 5 && !menuValidation) { 336 readPointer(); 337 } 338 if (menuValidation) { 339 menuValidation = false; 340 while (!menuValidation) { 341 gameOfLife(); //Run conway's game of life 342 } 343 menuValidation = false; 344 menuPointer = 5; 345 resetImg(); 346 setImg(menuGameOfLife, 1); 347 } 348 break; 349 case 6: 350 setImg(menuParty, 0); 351 while ((menuPointer + 12000) % 12 == 6 && !menuValidation) { 352 readPointer(); 353 } 354 if (menuValidation) { 355 menuValidation = false; 356 while (!menuValidation) { 357 launchManualAnimations(); //Visual animation (choice) 358 } 359 menuValidation = false; 360 menuPointer = 6; 361 resetImg(); 362 setImg(menuParty, 1); 363 } 364 break; 365 case 7: 366 setImg(menuParty, 0); 367 while ((menuPointer + 12000) % 12 == 7 && !menuValidation) { 368 readPointer(); 369 } 370 if (menuValidation) { 371 menuValidation = false; 372 while (!menuValidation) { 373 launchRandomAnimations(); //Launch random visual animation 374 } 375 menuValidation = false; 376 menuPointer = 7; 377 resetImg(); 378 setImg(menuParty, 1); 379 } 380 break; 381 case 8: 382 setImg(menuImage, 0); 383 while ((menuPointer + 12000) % 12 == 8 && !menuValidation) { 384 readPointer(); 385 } 386 if (menuValidation) { 387 menuValidation = false; 388 while (!menuValidation) { 389 launchManualImage(); //Images manual selection 390 } 391 menuValidation = false; 392 menuPointer = 8; 393 resetImg(); 394 setImg(menuImage, 1); 395 } 396 break; 397 case 9: 398 setImg(menuImage, 0); 399 while ((menuPointer + 12000) % 12 == 9 && !menuValidation) { 400 readPointer(); 401 } 402 if (menuValidation) { 403 menuValidation = false; 404 while (!menuValidation) { 405 launchRandomImage(); //Images random selection 406 } 407 menuValidation = false; 408 menuPointer = 9; 409 resetImg(); 410 setImg(menuImage, 1); 411 } 412 break; 413 case 10: 414 setImg(menuText, 0); 415 while ((menuPointer + 12000) % 12 == 10 && !menuValidation) { 416 readPointer(); 417 } 418 if (menuValidation) { 419 menuValidation = false; 420 while (!menuValidation) { 421 scrollText("Hi!",3, 0xff0000); //Scrolls a defined text on the screen TODO: BT defined text & color 422 } 423 menuValidation = false; 424 menuPointer = 10; 425 resetImg(); 426 setImg(menuText, 1); 427 } 428 break; 429 case 11: 430 setImg(menuSpectrum, 0); 431 while ((menuPointer + 12000) % 12 == 11 && !menuValidation) { 432 readPointer(); 433 } 434 if (menuValidation) { //Spectrum Analyzer code is too heavy for the FLASH/SRAM, needs a specific upload to run. Displays an error message 435 menuValidation = false; 436 setImg(menuError, 0); 437 delay(1250); 438 scrollText("Connect USB",11, 0xff0000); 439 menuPointer = 11; 440 resetImg(); 441 setImg(menuSpectrum, 1); 442 } 443 break; 444 } 445 446} 447 448
tetris.h
arduino
1 2// Playing field 3byte selectedColor = 0; 4const unsigned long PROGMEM colorLib[5] = {0x000000, 0xff0000, 0xffff00, 0x00ff00, 0x03cdff}; 5struct Field { 6 boolean pix[12][12 + 1]; //Make field one larger so that collision detection with bottom of field can be done in a uniform way 7 byte color[12][12]; 8}; 9Field field; 10 11//Structure to represent active brick on screen 12struct Brick { 13 boolean enabled;//Brick is disabled when it has landed 14 byte xpos, ypos; 15 byte yOffset;//Y-offset to use when placing brick at top of field 16 byte siz; 17 boolean pix[4][4]; 18 19 byte color; 20}; 21Brick activeBrick; 22 23//Struct to contain the different choices of blocks 24struct AbstractBrick { 25 byte yOffset;//Y-offset to use when placing brick at top of field 26 byte siz; 27 byte pix[4][4]; 28}; 29 30//Brick "library" 31AbstractBrick brickLib[7] = { 32 { 33 1,//yoffset when adding brick to field 34 4, 35 { {0, 0, 0, 0}, 36 {0, 1, 1, 0}, 37 {0, 1, 1, 0}, 38 {0, 0, 0, 0} 39 } 40 }, 41 { 42 0, 43 4, 44 { {0, 1, 0, 0}, 45 {0, 1, 0, 0}, 46 {0, 1, 0, 0}, 47 {0, 1, 0, 0} 48 } 49 }, 50 { 51 1, 52 3, 53 { {0, 0, 0, 0}, 54 {1, 1, 1, 0}, 55 {0, 0, 1, 0}, 56 {0, 0, 0, 0} 57 } 58 }, 59 { 60 1, 61 3, 62 { {0, 0, 1, 0}, 63 {1, 1, 1, 0}, 64 {0, 0, 0, 0}, 65 {0, 0, 0, 0} 66 } 67 }, 68 { 69 1, 70 3, 71 { {0, 0, 0, 0}, 72 {1, 1, 1, 0}, 73 {0, 1, 0, 0}, 74 {0, 0, 0, 0} 75 } 76 }, 77 { 78 1, 79 3, 80 { {0, 1, 1, 0}, 81 {1, 1, 0, 0}, 82 {0, 0, 0, 0}, 83 {0, 0, 0, 0} 84 } 85 }, 86 { 87 1, 88 3, 89 { {1, 1, 0, 0}, 90 {0, 1, 1, 0}, 91 {0, 0, 0, 0}, 92 {0, 0, 0, 0} 93 } 94 } 95}; 96 97 98uint16_t brickSpeed; 99byte nbRowsThisLevel; 100uint16_t nbRowsTotal; 101Brick tmpBrick; 102boolean tetrisRunning = false; 103boolean tetrisGameOver; 104 105/* *** Game functions *** */ 106//Check collision between bricks in the field and the specified brick 107boolean checkFieldCollision(struct Brick* brick) { 108 byte bx, by; 109 byte fx, fy; 110 for (by = 0; by < 4; by++) { 111 for (bx = 0; bx < 4; bx++) { 112 fx = (*brick).xpos + bx; 113 fy = (*brick).ypos + by; 114 if (( (*brick).pix[bx][by] == 1) 115 && ( field.pix[fx][fy] == 1)) { 116 return true; 117 } 118 } 119 } 120 return false; 121} 122 123void newActiveBrick() { 124 // byte selectedBrick = 3; 125 byte selectedBrick = random(7); 126 ++selectedColor; 127 if (selectedColor > 3) { 128 selectedColor = 0; 129 } 130 //Set properties of brick 131 activeBrick.siz = brickLib[selectedBrick].siz; 132 activeBrick.yOffset = brickLib[selectedBrick].yOffset; 133 activeBrick.xpos = 12 / 2 - activeBrick.siz / 2; 134 activeBrick.ypos = -1 - activeBrick.yOffset; 135 activeBrick.enabled = true; 136 137 //Set color of brick 138 switch (selectedColor) { 139 case 0 : 140 activeBrick.color = 1; 141 break; 142 case 1 : 143 activeBrick.color = 2; 144 break; 145 case 2 : 146 activeBrick.color = 3; 147 break; 148 case 3 : 149 activeBrick.color = 4; 150 break; 151 } 152 //activeBrick.color = colorLib[1]; 153 154 //Copy pix array of selected Brick 155 for (byte y = 0; y < 4; y++) { 156 for (byte x = 0; x < 4; x++) { 157 activeBrick.pix[x][y] = (brickLib[selectedBrick]).pix[x][y]; 158 } 159 } 160 161 //Check collision, if already, then game is over 162 if (checkFieldCollision(&activeBrick)) { 163 tetrisGameOver = true; 164 } 165} 166 167//Check collision between specified brick and all sides of the playing field 168boolean checkSidesCollision(struct Brick* brick) { 169 //Check vertical collision with sides of field 170 byte fx, fy; 171 for (byte by = 0; by < 4; by++) { 172 for (byte bx = 0; bx < 4; bx++) { 173 if ( (*brick).pix[bx][by] == 1) { 174 fx = (*brick).xpos + bx;//Determine actual position in the field of the current pix of the brick 175 fy = (*brick).ypos + by; 176 if (fx < 0 || fx >= 12) { 177 return true; 178 } 179 } 180 } 181 } 182 return false; 183} 184 185 186void printField() { 187 for (byte x = 0; x < 12; x++) { 188 for (byte y = 0; y < 12; y++) { 189 boolean activeBrickPix = 0; 190 if (activeBrick.enabled) { //Only draw brick if it is enabled 191 //Now check if brick is "in view" 192 if ((x >= activeBrick.xpos) && (x < (activeBrick.xpos + (activeBrick.siz))) 193 && (y >= activeBrick.ypos) && (y < (activeBrick.ypos + (activeBrick.siz)))) { 194 activeBrickPix = (activeBrick.pix)[x - activeBrick.xpos][y - activeBrick.ypos]; 195 } 196 } 197 if (field.pix[x][y] == 1) { 198 leds[pgm_read_byte(&ledsAdress[y][x])] = pgm_read_dword(&colorLib[field.color[x][y]]); 199 } else if (activeBrickPix == 1) { 200 leds[pgm_read_byte(&ledsAdress[y][x])] = pgm_read_dword(&colorLib[activeBrick.color]); 201 } else { 202 leds[pgm_read_byte(&ledsAdress[y][x])] = 0x000000; 203 } 204 } 205 } 206 FastLED.show(); 207} 208 209void rotateActiveBrick() { 210 //Copy active brick pix array to temporary pix array 211 for (byte y = 0; y < 4; y++) { 212 for (byte x = 0; x < 4; x++) { 213 tmpBrick.pix[x][y] = activeBrick.pix[x][y]; 214 } 215 } 216 tmpBrick.xpos = activeBrick.xpos; 217 tmpBrick.ypos = activeBrick.ypos; 218 tmpBrick.siz = activeBrick.siz; 219 220 //Depending on size of the active brick, we will rotate differently 221 if (activeBrick.siz == 3) { 222 //Perform rotation around center pix 223 tmpBrick.pix[0][0] = activeBrick.pix[0][2]; 224 tmpBrick.pix[0][1] = activeBrick.pix[1][2]; 225 tmpBrick.pix[0][2] = activeBrick.pix[2][2]; 226 tmpBrick.pix[1][0] = activeBrick.pix[0][1]; 227 tmpBrick.pix[1][1] = activeBrick.pix[1][1]; 228 tmpBrick.pix[1][2] = activeBrick.pix[2][1]; 229 tmpBrick.pix[2][0] = activeBrick.pix[0][0]; 230 tmpBrick.pix[2][1] = activeBrick.pix[1][0]; 231 tmpBrick.pix[2][2] = activeBrick.pix[2][0]; 232 //Keep other parts of temporary block clear 233 tmpBrick.pix[0][3] = 0; 234 tmpBrick.pix[1][3] = 0; 235 tmpBrick.pix[2][3] = 0; 236 tmpBrick.pix[3][3] = 0; 237 tmpBrick.pix[3][2] = 0; 238 tmpBrick.pix[3][1] = 0; 239 tmpBrick.pix[3][0] = 0; 240 241 } else if (activeBrick.siz == 4) { 242 //Perform rotation around center "cross" 243 tmpBrick.pix[0][0] = activeBrick.pix[0][3]; 244 tmpBrick.pix[0][1] = activeBrick.pix[1][3]; 245 tmpBrick.pix[0][2] = activeBrick.pix[2][3]; 246 tmpBrick.pix[0][3] = activeBrick.pix[3][3]; 247 tmpBrick.pix[1][0] = activeBrick.pix[0][2]; 248 tmpBrick.pix[1][1] = activeBrick.pix[1][2]; 249 tmpBrick.pix[1][2] = activeBrick.pix[2][2]; 250 tmpBrick.pix[1][3] = activeBrick.pix[3][2]; 251 tmpBrick.pix[2][0] = activeBrick.pix[0][1]; 252 tmpBrick.pix[2][1] = activeBrick.pix[1][1]; 253 tmpBrick.pix[2][2] = activeBrick.pix[2][1]; 254 tmpBrick.pix[2][3] = activeBrick.pix[3][1]; 255 tmpBrick.pix[3][0] = activeBrick.pix[0][0]; 256 tmpBrick.pix[3][1] = activeBrick.pix[1][0]; 257 tmpBrick.pix[3][2] = activeBrick.pix[2][0]; 258 tmpBrick.pix[3][3] = activeBrick.pix[3][0]; 259 } 260 261 //Now validate by checking collision. 262 //Collision possibilities: 263 // -Brick now sticks outside field 264 // -Brick now sticks inside fixed bricks of field 265 //In case of collision, we just discard the rotated temporary brick 266 if ((!checkSidesCollision(&tmpBrick)) && (!checkFieldCollision(&tmpBrick))) { 267 //Copy temporary brick pix array to active pix array 268 for (byte y = 0; y < 4; y++) { 269 for (byte x = 0; x < 4; x++) { 270 activeBrick.pix[x][y] = tmpBrick.pix[x][y]; 271 } 272 } 273 } 274} 275 276//Copy active pixels to field, including color 277void addActiveBrickToField() { 278 byte fx, fy; 279 for (byte by = 0; by < 4; by++) { 280 for (byte bx = 0; bx < 4; bx++) { 281 fx = activeBrick.xpos + bx; 282 fy = activeBrick.ypos + by; 283 284 if (fx >= 0 && fy >= 0 && fx < 12 && fy < 12 && activeBrick.pix[bx][by]) { //Check if inside playing field 285 //field.pix[fx][fy] = field.pix[fx][fy] || activeBrick.pix[bx][by]; 286 field.pix[fx][fy] = activeBrick.pix[bx][by]; 287 field.color[fx][fy] = activeBrick.color; 288 } 289 } 290 } 291} 292//Shift brick left/right/down by one if possible 293void shiftActiveBrick(char dir) { 294 //Change position of active brick (no copy to temporary needed) 295 if (dir == 'q') { 296 activeBrick.xpos--; 297 } else if (dir == 'd') { 298 activeBrick.xpos++; 299 } else if (dir == 's') { 300 activeBrick.ypos++; 301 } 302 303 //Check position of active brick 304 //Two possibilities when collision is detected: 305 // -Direction was LEFT/RIGHT, just revert position back 306 // -Direction was DOWN, revert position and fix block to field on collision 307 //When no collision, keep activeBrick coordinates 308 if ((checkSidesCollision(&activeBrick)) || (checkFieldCollision(&activeBrick))) { 309 //Serial.println("coll"); 310 if (dir == 'q') { 311 activeBrick.xpos++; 312 } else if (dir == 'd') { 313 activeBrick.xpos--; 314 } else if (dir == 's') { 315 activeBrick.ypos--;//Go back up one 316 addActiveBrickToField(); 317 activeBrick.enabled = false;//Disable brick, it is no longer moving 318 } 319 } 320} 321 322 323 324//Move all pix from te field above startRow down by one. startRow is overwritten 325void moveFieldDownOne(byte startRow) { 326 if (startRow == 0) { //Topmost row has nothing on top to move... 327 return; 328 } 329 byte x, y; 330 for (y = startRow - 1; y > 0; y--) { 331 for (x = 0; x < 12; x++) { 332 field.pix[x][y + 1] = field.pix[x][y]; 333 field.color[x][y + 1] = field.color[x][y]; 334 } 335 } 336} 337 338void checkFullLines() { 339 int x, y; 340 int minY = 0; 341 for (y = (12 - 1); y >= minY; y--) { 342 byte rowSum = 0; 343 for (x = 0; x < 12; x++) { 344 rowSum = rowSum + (field.pix[x][y]); 345 } 346 if (rowSum >= 12) { 347 //Found full row, animate its removal 348 for (x = 0; x < 12; x++) { 349 field.pix[x][y] = 0; 350 printField(); 351 delay(100); 352 } 353 //Move all upper rows down by one 354 moveFieldDownOne(y); 355 y++; minY++; 356 printField(); 357 delay(100); 358 359 nbRowsThisLevel++; nbRowsTotal++; 360 if (nbRowsThisLevel >= 2) { 361 nbRowsThisLevel = 0; 362 brickSpeed = brickSpeed - 100; 363 if (brickSpeed < 200) { 364 brickSpeed = 200; 365 } 366 } 367 } 368 } 369} 370 371void clearField() { 372 for (byte y = 0; y < 12; y++) { 373 for (byte x = 0; x < 12; x++) { 374 field.pix[x][y] = 0; 375 field.color[x][y] = 0; 376 } 377 } 378 for (byte x = 0; x < 12; x++) { //This last row is invisible to the player and only used for the collision detection routine 379 field.pix[x][12] = 1; 380 } 381} 382 383void playerControlActiveBrick() { 384 switch (curControl) { 385 case 'd': 386 shiftActiveBrick('d'); 387 break; 388 case 'q': 389 shiftActiveBrick('q'); 390 break; 391 case 's': 392 shiftActiveBrick('s'); 393 break; 394 case 'a': 395 rotateActiveBrick(); 396 break; 397 case 'y': 398 tetrisRunning = false; 399 break; 400 } 401} 402 403 404void tetrisInit() { 405 clearField(); 406 brickSpeed = 1000; 407 nbRowsThisLevel = 0; 408 nbRowsTotal = 0; 409 tetrisGameOver = false; 410 411 newActiveBrick(); 412} 413 414 415void runTetris(void) { 416 tetrisInit(); 417 418 prevUpdateTime = 0; 419 420 tetrisRunning = true; 421 while (tetrisRunning) { 422 curTime = 0; 423 424 do { 425 readPointer(); //ATTENTION SOURCE BUG ?! 426 if (menuValidation) { 427 tetrisRunning = false; 428 break; 429 } 430 if (curControl != 'n') { 431 playerControlActiveBrick(); 432 printField(); 433 curControl = 'n'; 434 } 435 if (tetrisGameOver) break; 436 437 curTime = millis(); 438 } while ((curTime - prevUpdateTime) < brickSpeed);//Once enough time has passed, proceed. The lower this number, the faster the game is 439 prevUpdateTime = curTime; 440 441 if (tetrisGameOver) { 442 fadeImg(); 443 444 //Disable loop and exit to main menu of led table 445 tetrisRunning = false; 446 break; 447 } 448 449 //If brick is still "on the loose", then move it down by one 450 if (activeBrick.enabled) { 451 shiftActiveBrick('s'); 452 } else { 453 //Active brick has "crashed", check for full lines 454 //and create new brick at top of field 455 checkFullLines(); 456 newActiveBrick(); 457 prevUpdateTime = millis();//Reset update time to avoid brick dropping two spaces 458 } 459 printField(); 460 } 461 462 463} 464 465 466 467 468 469 470
imgMario.h
arduino
1const unsigned long mushroom[12][12] PROGMEM = {{0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 2 {0x000000, 0x000000, 0x000000, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0x000000, 0x000000, 0x000000}, 3 {0x000000, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0x000000}, 4 {0x000000, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0x000000}, 5 {0xDF0202, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xDF0202}, 6 {0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202}, 7 {0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202}, 8 {0xDF0202, 0xDF0202, 0xFFFFFF, 0x000000, 0x000000, 0xFFFFFF, 0xFFFFFF, 0x000000, 0x000000, 0xFFFFFF, 0xDF0202, 0xDF0202}, 9 {0xDF0202, 0xFFFFFF, 0xFFFFFF, 0x000000, 0x000000, 0xFFFFFF, 0xFFFFFF, 0x000000, 0x000000, 0xFFFFFF, 0xFFFFFF, 0xDF0202}, 10 {0x000000, 0xFFFFFF, 0xFFFFFF, 0x000000, 0x000000, 0xFFFFFF, 0xFFFFFF, 0x000000, 0x000000, 0xFFFFFF, 0xFFFFFF, 0x000000}, 11 {0x000000, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0x000000}, 12 {0x000000, 0x000000, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0x000000, 0x000000} 13}; 14 15const unsigned long flower[12][12] PROGMEM = {{0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 16 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 17 {0x000000, 0x000000, 0x000000, 0xFC3205, 0xFC3205, 0xFC3205, 0xFC3205, 0xFC3205, 0xFC3205, 0x000000, 0x000000, 0x000000}, 18 {0x000000, 0x000000, 0xFC3205, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFC3205, 0x000000, 0x000000}, 19 {0x000000, 0xFC3205, 0xFAFE13, 0xFFFFFF, 0x000000, 0xFFFFFF, 0xFFFFFF, 0x000000, 0xFFFFFF, 0xFAFE13, 0xFC3205, 0x000000}, 20 {0x000000, 0xFC3205, 0xFAFE13, 0xFFFFFF, 0x000000, 0xFFFFFF, 0xFFFFFF, 0x000000, 0xFFFFFF, 0xFAFE13, 0xFC3205, 0x000000}, 21 {0x000000, 0x000000, 0xFC3205, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFC3205, 0x000000, 0x000000}, 22 {0x000000, 0x000000, 0x000000, 0xFC3205, 0xFC3205, 0xFC3205, 0xFC3205, 0xFC3205, 0xFC3205, 0x000000, 0x000000, 0x000000}, 23 {0x000000, 0x0DFC03, 0x0DFC03, 0x000000, 0x000000, 0x0DFC03, 0x0DFC03, 0x000000, 0x000000, 0x0DFC03, 0x0DFC03, 0x000000}, 24 {0x000000, 0x0DFC03, 0x0DFC03, 0x0DFC03, 0x000000, 0x0DFC03, 0x0DFC03, 0x000000, 0x0DFC03, 0x0DFC03, 0x0DFC03, 0x000000}, 25 {0x000000, 0x000000, 0x0DFC03, 0x0DFC03, 0x0DFC03, 0x0DFC03, 0x0DFC03, 0x0DFC03, 0x0DFC03, 0x0DFC03, 0x000000, 0x000000}, 26 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0DFC03, 0x0DFC03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000} 27}; 28 29const unsigned long star[12][12] PROGMEM = {{0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 30 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 31 {0x000000, 0x000000, 0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000, 0x000000, 0x000000}, 32 {0x000000, 0x000000, 0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000, 0x000000, 0x000000}, 33 {0x000000, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0x000000}, 34 {0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0x000000, 0xFAFE13, 0xFAFE13, 0x000000, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000}, 35 {0x000000, 0x000000, 0x000000, 0xFAFE13, 0x000000, 0xFAFE13, 0xFAFE13, 0x000000, 0xFAFE13, 0x000000, 0x000000, 0x000000}, 36 {0x000000, 0x000000, 0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000, 0x000000, 0x000000}, 37 {0x000000, 0x000000, 0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000, 0x000000, 0x000000}, 38 {0x000000, 0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000, 0x000000}, 39 {0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000}, 40 {0x000000, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0x000000} 41}; 42 43 44const unsigned long beer[12][12] PROGMEM = {{0x020202, 0x020202, 0x020202, 0x020202, 0x020202, 0x020202, 0x020202, 0x020202, 0x020202, 0x020202, 0x020202, 0x020202}, 45 {0x000000, 0x000000, 0x000000, 0xBEBEBD, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xBEBEBD, 0x000000, 0x000000, 0x000000, 0x000000}, 46 {0x000000, 0x000000, 0x000000, 0xBEBEBD, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xBEBEBD, 0x000000, 0x000000, 0x000000, 0x000000}, 47 {0x000000, 0x000000, 0x000000, 0xB49C04, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xB49C04, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0x000000}, 48 {0x000000, 0x000000, 0x000000, 0xB49C04, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xB49C04, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0x000000}, 49 {0x000000, 0x000000, 0x000000, 0xB49C04, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xB49C04, 0x000000, 0x000000, 0xFFFFFF, 0x000000}, 50 {0x000000, 0x000000, 0x000000, 0xB49C04, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xB49C04, 0x000000, 0x000000, 0xFFFFFF, 0x000000}, 51 {0x000000, 0x000000, 0x000000, 0xB49C04, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xB49C04, 0x000000, 0x000000, 0xFFFFFF, 0x000000}, 52 {0x000000, 0x000000, 0x000000, 0xB49C04, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xB49C04, 0x000000, 0x000000, 0xFFFFFF, 0x000000}, 53 {0x000000, 0x000000, 0x000000, 0xB49C04, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xB49C04, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0x000000}, 54 {0x000000, 0x000000, 0x000000, 0xB49C04, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xA48E01, 0x000000, 0x000000, 0x000000, 0x000000}, 55 {0x000000, 0x000000, 0x000000, 0xB49C04, 0xB49C04, 0xB49C04, 0xB49C04, 0xB49C04, 0x000000, 0x000000, 0x000000, 0x000000} 56}; 57
imgMenu.h
arduino
1const unsigned long PROGMEM menuError[12][12] = {{0xEF3101, 0xED2D01, 0x040100, 0x040100, 0x000000, 0x000000, 0x000000, 0x000000, 0x040100, 0x040100, 0xEB2801, 0xED2C01}, 2 {0xED2C01, 0xEB2701, 0xE92202, 0x040100, 0x040100, 0x000000, 0x000000, 0x040100, 0x040100, 0xE81F02, 0xEA2301, 0xEB2701}, 3 {0x040100, 0xE92202, 0xE81E01, 0xE61A01, 0x040000, 0x040000, 0x040000, 0x040000, 0xE61601, 0xE61A02, 0xE71D02, 0x040100}, 4 {0x040100, 0x040100, 0xE61901, 0xE51501, 0xE31101, 0x040000, 0x040000, 0xE20F01, 0xE41202, 0xE51501, 0x040100, 0x040100}, 5 {0x000000, 0x040000, 0x040000, 0xE31102, 0xE20D02, 0xE10A02, 0xE00902, 0xE10B02, 0xE20D02, 0x040000, 0x040000, 0x000000}, 6 {0x000000, 0x000000, 0x040000, 0x040000, 0xE10B01, 0xDF0701, 0xDF0602, 0xE00702, 0x040000, 0x040000, 0x000000, 0x000000}, 7 {0x000000, 0x000000, 0x040000, 0x040000, 0xE10902, 0xDF0502, 0xDE0202, 0xDF0501, 0x040000, 0x040000, 0x000000, 0x000000}, 8 {0x000000, 0x040000, 0x040000, 0xE30F02, 0xE10A02, 0xE00702, 0xE00502, 0xE00701, 0xE10A02, 0x040000, 0x040000, 0x000000}, 9 {0x040100, 0x040000, 0xE61601, 0xE41102, 0xE20D02, 0x040000, 0x040000, 0xE10B02, 0xE20D02, 0xE41101, 0x040000, 0x040100}, 10 {0x040100, 0xE81F01, 0xE71A01, 0xE51501, 0x040000, 0x040000, 0x040000, 0x040000, 0xE31202, 0xE51502, 0xE61A01, 0x040100}, 11 {0xEB2801, 0xEA2301, 0xE81E01, 0x040000, 0x040000, 0x000000, 0x000000, 0x040000, 0x040000, 0xE71A01, 0xE81D01, 0xEA2301}, 12 {0xED2C01, 0xEB2801, 0x040100, 0x040000, 0x000000, 0x000000, 0x000000, 0x000000, 0x040000, 0x040000, 0xE92202, 0xEB2701} 13}; 14 15const unsigned long PROGMEM menuGameOfLife[12][12] = {{0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x00FF00, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 16 17 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 18 {0xb2a24, 0x2cb194, 0xe281f, 0xc2720, 0xb261f, 0xb241e, 0x8231e, 0xa231f, 0x258d76, 0x8211d, 0x91e19, 0x91e19}, 19 {0xb2823, 0xb2823, 0xa2723, 0x92621, 0x27a285, 0x7251d, 0x25977e, 0x7221d, 0x9201a, 0x9201a, 0x1e7f6b, 0x81b17}, 20 {0x2bb292, 0x2aac90, 0x7281f, 0x27a486, 0xa231f, 0xc231b, 0xa2117, 0x238a75, 0x91f1c, 0x81d18, 0x91c1a, 0x1d775e}, 21 {0x2aad8d, 0xc261d, 0xc251f, 0x9241d, 0x92320, 0xb211e, 0x228c76, 0x23876f, 0x91e19, 0x1e7b68, 0x81b17, 0x71a18}, 22 {0x29aa8e, 0x27a387, 0x8261c, 0xc221f, 0x21967b, 0x248e77, 0x228a73, 0x1f826e, 0x1e7d67, 0x71c15, 0x71a16, 0x1d6c59}, 23 {0xc2521, 0x26a286, 0x269b81, 0x28967d, 0x8211b, 0xa211b, 0x218470, 0xa1d19, 0x91c1a, 0x71c17, 0x81815, 0x61915}, 24 {0xa2520, 0xa231f, 0x25977d, 0x9221c, 0x248a75, 0x1f8770, 0xa1f1a, 0x71c17, 0x81b17, 0x1d6e5b, 0x1a6956, 0x196251}, 25 {0xa2520, 0x25977d, 0x8231c, 0x7221b, 0x92018, 0x22816d, 0x1f7c69, 0x1c7563, 0x91916, 0x61915, 0x196352, 0x71613}, 26 {0x259a7f, 0x8231e, 0x8211b, 0x91f1c, 0x20836e, 0x91e17, 0x71c17, 0x91916, 0x1a6b5a, 0x1a6455, 0x81712, 0x61512}, 27 {0xb211e, 0x82219, 0x228974, 0x22836f, 0x1e7f6b, 0x1d7962, 0x71b19, 0x1b6c59, 0x1a6755, 0x186150, 0x175b4c, 0x514f} 28}; 29 30const unsigned long PROGMEM menuPong[12][12] = {{0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 31 32 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 33 {0x000000, 0x000000, 0xFF0000, 0xFF0000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 34 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 35 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 36 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 37 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 38 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 39 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 40 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 41 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 42 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0xFF0000, 0xFF0000, 0x000000, 0x000000} 43}; 44 45 46const unsigned long PROGMEM menuTetris[12][12] = {{0x00a651, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 47 48 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 49 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 50 {0x000000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 51 {0x000000, 0x000000, 0x000000, 0xFF0000, 0xFF0000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 52 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 53 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0xFF0000, 0x000000, 0x000000}, 54 {0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0xFF0000, 0x4DBB2E, 0x000000}, 55 {0xFF0000, 0xFF0000, 0x4DBB2E, 0x4DBB2E, 0x000000, 0x000000, 0xD4BD0D, 0xD4BD0D, 0xD4BD0D, 0x4DBB2E, 0x4DBB2E, 0xFF0000}, 56 {0xFF0000, 0x0DA5D4, 0x4DBB2E, 0x4DBB2E, 0xFF0000, 0x000000, 0x4DBB2E, 0xD4BD0D, 0x0DA5D4, 0x0DA5D4, 0x4DBB2E, 0xFF0000}, 57 {0x0DA5D4, 0x0DA5D4, 0x0DA5D4, 0x000000, 0xFF0000, 0x4DBB2E, 0x4DBB2E, 0x000000, 0x0DA5D4, 0xD4BD0D, 0xD4BD0D, 0xFF0000}, 58 {0xD4BD0D, 0xD4BD0D, 0xD4BD0D, 0xD4BD0D, 0xFF0000, 0xFF0000, 0x4DBB2E, 0x000000, 0x0DA5D4, 0xD4BD0D, 0xD4BD0D, 0xFF0000} 59}; 60 61 62const unsigned long PROGMEM menuSnake[12][12] = {{0x000000, 0x000000, 0x000000, 0xF26522, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 63 64 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 65 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 66 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 67 {0x388FEC, 0x388FEC, 0x000000, 0xFF0000, 0x000000, 0x388FEC, 0x388FEC, 0x388FEC, 0x000000, 0x000000, 0x388FEC, 0x388FEC}, 68 {0x000000, 0x388FEC, 0x000000, 0x000000, 0x000000, 0x388FEC, 0x000000, 0x388FEC, 0x000000, 0x000000, 0x388FEC, 0x000000}, 69 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x388FEC, 0x000000, 0x388FEC, 0x388FEC, 0x388FEC, 0x388FEC, 0x000000}, 70 {0x000000, 0x000000, 0x388FEC, 0x000000, 0x000000, 0x388FEC, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 71 {0x000000, 0x000000, 0x388FEC, 0x000000, 0x000000, 0x388FEC, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 72 {0x000000, 0x000000, 0x388FEC, 0x388FEC, 0x388FEC, 0x388FEC, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 73 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 74 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000} 75}; 76 77const unsigned long PROGMEM menuSimon[12][12] = 78{{0x000000, 0x388FEC, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 79 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 80 {0xFFF202, 0xFFF202, 0xFFF20C, 0xFFF202, 0xFFF202, 0x000000, 0x000000, 0xFF0202, 0xFF191A, 0xFF2727, 0xFF1A1A, 0xFF0202}, 81 {0xFFF202, 0xFFF234, 0xFFF257, 0xFFF235, 0xFFF202, 0x000000, 0x000000, 0xFF191A, 0xFF4C4C, 0xFF6767, 0xFF4C4C, 0xFF1A19}, 82 {0xFFF20C, 0xFFF257, 0xFFF898, 0xFFF257, 0xFFF20C, 0x000000, 0x000000, 0xFF2727, 0xFF6767, 0xFF9797, 0xFF6767, 0xFF2726}, 83 {0xFFF202, 0xFFF235, 0xFFF257, 0xFFF234, 0xFFF202, 0x000000, 0x000000, 0xFF1919, 0xFF4C4C, 0xFF6767, 0xFF4C4C, 0xFF1A19}, 84 {0xFFF202, 0xFFF202, 0xFFF20C, 0xFFF202, 0xFFF202, 0x000000, 0x000000, 0xFF0202, 0xFF1A19, 0xFF2626, 0xFF1A1A, 0xFF0202}, 85 {0x34BA20, 0x34BA20, 0x34BA20, 0x34BA20, 0x34BA20, 0x000000, 0x000000, 0x2760B9, 0x4360B9, 0x4F68B9, 0x4360B9, 0x2760B9}, 86 {0x34BA20, 0x48BA40, 0x6BBA63, 0x48BA41, 0x34BA20, 0x000000, 0x000000, 0x4360B9, 0x6D87B9, 0x819ABE, 0x6D86B9, 0x4360B9}, 87 {0x34BA20, 0x6BBA63, 0xACE2A4, 0x6BBA63, 0x34BA20, 0x000000, 0x000000, 0x4F68B9, 0x819ABE, 0xA4BEE1, 0x819BBE, 0x4F68B9}, 88 {0x34BA20, 0x49BA40, 0x6BBA63, 0x48BA41, 0x34BA20, 0x000000, 0x000000, 0x4360B9, 0x6D86B9, 0x819BBE, 0x6D86B9, 0x4360B9}, 89 {0x34BA20, 0x34BA20, 0x34BA20, 0x34BA20, 0x34BA20, 0x000000, 0x000000, 0x2760B9, 0x4360B9, 0x4F68B9, 0x4360B9, 0x2760B9} 90}; 91 92 93const unsigned long PROGMEM menuBottle[12][12] = 94{{0x000000, 0x000000, 0x000000, 0x000000, 0xFFF200, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 95 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 96 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 97 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x02F900, 0x0EFA00, 0x1FFB01}, 98 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x33FC01, 0x41FE00, 0x4BFE00}, 99 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x7BFF02, 0x7AFE02, 0x79FF01}, 100 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 101 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 102 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 103 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 104 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 105 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000} 106}; 107 108 109 110const unsigned long PROGMEM menuParty[12][12] = {{0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x960055, 0x960055, 0x000000, 0x000000, 0x000000, 0x000000}, 111 112 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 113 {0x00A651, 0x00A651, 0x00A651, 0x00A651, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x00A651, 0x00A651}, 114 {0xEC008C, 0xEC008C, 0xEC008C, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xEC008C, 0xEC008C, 0xEC008C}, 115 {0xF7941D, 0xF7941D, 0xF7941D, 0xF7941D, 0xF7941D, 0xF7941D, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 116 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x00AEEF, 0x00AEEF, 0x00AEEF, 0x00AEEF, 0x00AEEF, 0x00AEEF, 0x000000}, 117 {0xFFF200, 0xFFF200, 0xFFF200, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFFF200, 0xFFF200, 0xFFF200}, 118 {0x000000, 0x000000, 0xED1C24, 0xED1C24, 0xED1C24, 0xED1C24, 0xED1C24, 0xED1C24, 0x000000, 0x000000, 0x000000, 0x000000}, 119 {0x2E3192, 0x2E3192, 0x2E3192, 0x2E3192, 0x2E3192, 0x2E3192, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 120 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x00A651, 0x00A651, 0x00A651, 0x00A651, 0x00A651, 0x00A651}, 121 {0x000000, 0x000000, 0x000000, 0xF7941D, 0xF7941D, 0xF7941D, 0xF7941D, 0xF7941D, 0xF7941D, 0x000000, 0x000000, 0x000000}, 122 {0xEC008C, 0xEC008C, 0xEC008C, 0xEC008C, 0xEC008C, 0xEC008C, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000} 123}; 124 125const unsigned long PROGMEM menuImage[12][12] = {{0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0xFF0000, 0x000000, 0x000000}, 126 127 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 128 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 129 {0x000000, 0xAC8255, 0xFBBD7B, 0xE8AF72, 0xE8AF72, 0xE8AF72, 0xE8AF72, 0xE8AF72, 0xEAB276, 0xE7A45D, 0x9E6C36, 0x000000}, 130 {0x000000, 0xAD7F4F, 0xF1ECCE, 0xD6FFFF, 0xD4FFFF, 0xDCFFFF, 0xFAFFF9, 0xFFFF3E, 0xFFD529, 0xF4A05C, 0x9D6B36, 0x000000}, 131 {0x000000, 0xAD7F4F, 0xF1ECCE, 0xD6FFFF, 0xD4FFFF, 0xDCFFFF, 0xFAFFFA, 0xFFFF42, 0xFFFF00, 0xF4D31A, 0x9D683A, 0x000000}, 132 {0x000000, 0xAB8959, 0xFF5638, 0xFF0000, 0xFF0000, 0xFF2020, 0xFFDFDF, 0xFFFFFF, 0xFFFFFF, 0xF4D3B0, 0x9D6830, 0x000000}, 133 {0x000000, 0xBD8B4E, 0xFF5731, 0xFF0000, 0xFF0000, 0xFF0000, 0xFE0505, 0xE1BDBE, 0xD5FFFF, 0xDDD3B0, 0x9E6830, 0x000000}, 134 {0x000000, 0xB68959, 0x734338, 0x007100, 0x00BF00, 0x001920, 0x0066DF, 0x0088FF, 0x0080FF, 0x5F89B0, 0xA76E30, 0x000000}, 135 {0x000000, 0xB67F59, 0x73EC38, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FD05, 0x00A1BE, 0x0076FF, 0x5F89B0, 0xA76E30, 0x000000}, 136 {0x000000, 0x9F6D38, 0xD38B3D, 0xC7843C, 0xC7843C, 0xC7843C, 0xC7843C, 0xC7843C, 0xC7843C, 0xD38B3D, 0x9F6D38, 0x000000}, 137 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000} 138}; 139 140const unsigned long PROGMEM menuSpectrum[12][12] = {{0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xffff00}, 141 142 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 143 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 144 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x531A8D, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 145 {0x000000, 0x000000, 0x000000, 0x000000, 0x5E2598, 0x000000, 0x2585A9, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 146 {0x000000, 0x000000, 0x000000, 0x000000, 0x3696B9, 0x591F93, 0x2585A9, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 147 {0x000000, 0x000000, 0x000000, 0x642B9E, 0x3696B9, 0x3389AA, 0x2585A9, 0x000000, 0x490F83, 0x000000, 0x000000, 0x000000}, 148 {0x000000, 0x6F36A9, 0x000000, 0x3E9EC1, 0x3C92B3, 0x3389AA, 0x2585A9, 0x4E1488, 0x16769A, 0x000000, 0x000000, 0x000000}, 149 {0x743BAE, 0x4EAED2, 0x000000, 0x3E9DC1, 0x3C92B3, 0x3289AA, 0x2A80A1, 0x217898, 0x167699, 0x000000, 0x000000, 0x000000}, 150 {0x60B7D7, 0x4EAED2, 0x000000, 0x3E9DC1, 0x3C92B3, 0x3289AA, 0x2A80A0, 0x217798, 0x16769A, 0x000000, 0x40077A, 0x000000}, 151 {0x60B7D7, 0x4EAED2, 0x6A30A4, 0x3E9EC1, 0x3C92B3, 0x3289AA, 0x2A80A1, 0x217898, 0x167699, 0x000000, 0x0A698D, 0x3D0376}, 152 {0x60B7D7, 0x57AECE, 0x4FA5C5, 0x459CBC, 0x3C92B3, 0x3389A9, 0x2A80A1, 0x217898, 0x167699, 0x440B7E, 0x09698D, 0x065C7C} 153}; 154 155 156const unsigned long PROGMEM menuText[12][12] = {{0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFFF200, 0x000000}, 157 158 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 159 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 160 {0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 161 {0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 162 {0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0xFF0000, 0xFF0000, 0x000000, 0x000000}, 163 {0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0x000000}, 164 {0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0x000000}, 165 {0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 166 {0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0x000000}, 167 {0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0xFF0000, 0xFF0000, 0x000000, 0x000000}, 168 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000} 169}; 170 171
font.h
c_cpp
1/* uTFT Font library 2 * http://www.henningkarlsen.com/electronics/r_fonts.php 3 * 4 */ 5 6 7const unsigned char PROGMEM font[760] = 8{ 90x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // <Space> 100x18,0x3C,0x3C,0x18,0x18,0x00,0x18,0x00, // ! 110x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00, // " 120x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00, // # 130x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00, // $ 140x00,0xC6,0xCC,0x18,0x30,0x66,0xC6,0x00, // % 150x38,0x6C,0x38,0x76,0xDC,0xCC,0x76,0x00, // & 160x18,0x18,0x30,0x00,0x00,0x00,0x00,0x00, // ' 170x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00, // ( 180x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00, // ) 190x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00, // * 200x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00, // + 210x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30, // , 220x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00, // - 230x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00, // . 240x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00, // / 250x7C,0xC6,0xCE,0xD6,0xE6,0xC6,0x7C,0x00, // 0 260x18,0x38,0x18,0x18,0x18,0x18,0x7E,0x00, // 1 270x7C,0xC6,0x06,0x1C,0x30,0x66,0xFE,0x00, // 2 280x7C,0xC6,0x06,0x3C,0x06,0xC6,0x7C,0x00, // 3 290x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x1E,0x00, // 4 300xFE,0xC0,0xC0,0xFC,0x06,0xC6,0x7C,0x00, // 5 310x38,0x60,0xC0,0xFC,0xC6,0xC6,0x7C,0x00, // 6 320xFE,0xC6,0x0C,0x18,0x30,0x30,0x30,0x00, // 7 330x7C,0xC6,0xC6,0x7C,0xC6,0xC6,0x7C,0x00, // 8 340x7C,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00, // 9 350x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00, // : 360x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30, // ; 370x06,0x0C,0x18,0x30,0x18,0x0C,0x06,0x00, // < 380x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00, // = 390x60,0x30,0x18,0x0C,0x18,0x30,0x60,0x00, // > 400x7C,0xC6,0x0C,0x18,0x18,0x00,0x18,0x00, // ? 410x7C,0xC6,0xDE,0xDE,0xDE,0xC0,0x78,0x00, // @ 420x38,0x6C,0xC6,0xFE,0xC6,0xC6,0xC6,0x00, // A 430xFC,0x66,0x66,0x7C,0x66,0x66,0xFC,0x00, // B 440x3C,0x66,0xC0,0xC0,0xC0,0x66,0x3C,0x00, // C 450xF8,0x6C,0x66,0x66,0x66,0x6C,0xF8,0x00, // D 460xFE,0x62,0x68,0x78,0x68,0x62,0xFE,0x00, // E 470xFE,0x62,0x68,0x78,0x68,0x60,0xF0,0x00, // F 480x3C,0x66,0xC0,0xC0,0xCE,0x66,0x3A,0x00, // G 490xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00, // H 500x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // I 510x1E,0x0C,0x0C,0x0C,0xCC,0xCC,0x78,0x00, // J 520xE6,0x66,0x6C,0x78,0x6C,0x66,0xE6,0x00, // K 530xF0,0x60,0x60,0x60,0x62,0x66,0xFE,0x00, // L 540xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0x00, // M 550xC6,0xE6,0xF6,0xDE,0xCE,0xC6,0xC6,0x00, // N 560x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00, // O 570xFC,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00, // P 580x7C,0xC6,0xC6,0xC6,0xC6,0xCE,0x7C,0x0E, // Q 590xFC,0x66,0x66,0x7C,0x6C,0x66,0xE6,0x00, // R 600x7C,0xC6,0x60,0x38,0x0C,0xC6,0x7C,0x00, // S 610x7E,0x7E,0x5A,0x18,0x18,0x18,0x3C,0x00, // T 620xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00, // U 630xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x00, // V 640xC6,0xC6,0xC6,0xD6,0xD6,0xFE,0x6C,0x00, // W 650xC6,0xC6,0x6C,0x38,0x6C,0xC6,0xC6,0x00, // X 660x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00, // Y 670xFE,0xC6,0x8C,0x18,0x32,0x66,0xFE,0x00, // Z 680x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00, // [ 690xC0,0x60,0x30,0x18,0x0C,0x06,0x02,0x00, // <Backslash> 700x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00, // ] 710x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00, // ^ 720x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF, // _ 730x30,0x18,0x0C,0x00,0x00,0x00,0x00,0x00, // ' 740x00,0x00,0x78,0x0C,0x7C,0xCC,0x76,0x00, // a 750xE0,0x60,0x7C,0x66,0x66,0x66,0xDC,0x00, // b 760x00,0x00,0x7C,0xC6,0xC0,0xC6,0x7C,0x00, // c 770x1C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00, // d 780x00,0x00,0x7C,0xC6,0xFE,0xC0,0x7C,0x00, // e 790x3C,0x66,0x60,0xF8,0x60,0x60,0xF0,0x00, // f 800x00,0x00,0x76,0xCC,0xCC,0x7C,0x0C,0xF8, // g 810xE0,0x60,0x6C,0x76,0x66,0x66,0xE6,0x00, // h 820x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00, // i 830x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C, // j 840xE0,0x60,0x66,0x6C,0x78,0x6C,0xE6,0x00, // k 850x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // l 860x00,0x00,0xEC,0xFE,0xD6,0xD6,0xD6,0x00, // m 870x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x00, // n 880x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0x00, // o 890x00,0x00,0xDC,0x66,0x66,0x7C,0x60,0xF0, // p 900x00,0x00,0x76,0xCC,0xCC,0x7C,0x0C,0x1E, // q 910x00,0x00,0xDC,0x76,0x60,0x60,0xF0,0x00, // r 920x00,0x00,0x7E,0xC0,0x7C,0x06,0xFC,0x00, // s 930x30,0x30,0xFC,0x30,0x30,0x36,0x1C,0x00, // t 940x00,0x00,0xCC,0xCC,0xCC,0xCC,0x76,0x00, // u 950x00,0x00,0xC6,0xC6,0xC6,0x6C,0x38,0x00, // v 960x00,0x00,0xC6,0xD6,0xD6,0xFE,0x6C,0x00, // w 970x00,0x00,0xC6,0x6C,0x38,0x6C,0xC6,0x00, // x 980x00,0x00,0xC6,0xC6,0xC6,0x7E,0x06,0xFC, // y 990x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00, // z 1000x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00, // { 1010x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00, // | 1020x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00, // } 1030x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00, // ~ 104}; 105 106 107uint8_t charBuffer[8][8]; 108 109//Load char in buffer and return width in pixels 110uint8_t loadCharInBuffer(char letter) { 111 uint8_t* tmpCharPix; 112 uint8_t tmpCharWidth; 113 114 int letterIdx = (letter - 32) * 8; 115 116 int x = 0; int y = 0; 117 for (int idx = letterIdx; idx < letterIdx + 8; idx++) { 118 for (int x = 0; x < 8; x++) { 119 charBuffer[x][y] = ((pgm_read_byte(&font[idx])) & (1 << (7 - x))) > 0; 120 } 121 y++; 122 } 123 124 tmpCharWidth = 8; 125 return tmpCharWidth; 126} 127 128void printText(char* text, unsigned int textLength, int xoffset, int yoffset, unsigned long color) { 129 uint8_t curLetterWidth = 0; 130 int curX = xoffset; 131 clearImg(); 132 133 //Loop over all the letters in the string 134 for (int i = 0; i < textLength; i++) { 135 //Determine width of current letter and load its pixels in a buffer 136 curLetterWidth = loadCharInBuffer(text[i]); 137 //Loop until width of letter is reached 138 for (int lx = 0; lx < curLetterWidth; lx++) { 139 //Now copy column per column to field (as long as within the field 140 if (curX >= 12) { //If we are to far to the right, stop loop entirely 141 break; 142 } else if (curX >= 0) { //Draw pixels as soon as we are "inside" the drawing area 143 for (int ly = 0; ly < 8; ly++) { //Finally copy column 144 leds[pgm_read_byte(&ledsAdress[yoffset + ly][curX])] = charBuffer[lx][ly] * color; 145 146 } 147 } 148 curX++; 149 } 150 } 151 FastLED.show(); 152} 153//Scroll current selection text from right to left; 154void scrollText(char* curSelectionText, int curSelectionTextLength, unsigned long color ) { 155 for (int x = 12; x > -(curSelectionTextLength * 8); x--) { 156 printText(curSelectionText, curSelectionTextLength, x, 2, color); 157 delay(80); 158 } 159} 160 161
tetris.h
arduino
1 2// Playing field 3byte selectedColor = 0; 4const unsigned long PROGMEM colorLib[5] = {0x000000, 0xff0000, 0xffff00, 0x00ff00, 0x03cdff}; 5struct Field { 6 boolean pix[12][12 + 1]; //Make field one larger so that collision detection with bottom of field can be done in a uniform way 7 byte color[12][12]; 8}; 9Field field; 10 11//Structure to represent active brick on screen 12struct Brick { 13 boolean enabled;//Brick is disabled when it has landed 14 byte xpos, ypos; 15 byte yOffset;//Y-offset to use when placing brick at top of field 16 byte siz; 17 boolean pix[4][4]; 18 19 byte color; 20}; 21Brick activeBrick; 22 23//Struct to contain the different choices of blocks 24struct AbstractBrick { 25 byte yOffset;//Y-offset to use when placing brick at top of field 26 byte siz; 27 byte pix[4][4]; 28}; 29 30//Brick "library" 31AbstractBrick brickLib[7] = { 32 { 33 1,//yoffset when adding brick to field 34 4, 35 { {0, 0, 0, 0}, 36 {0, 1, 1, 0}, 37 {0, 1, 1, 0}, 38 {0, 0, 0, 0} 39 } 40 }, 41 { 42 0, 43 4, 44 { {0, 1, 0, 0}, 45 {0, 1, 0, 0}, 46 {0, 1, 0, 0}, 47 {0, 1, 0, 0} 48 } 49 }, 50 { 51 1, 52 3, 53 { {0, 0, 0, 0}, 54 {1, 1, 1, 0}, 55 {0, 0, 1, 0}, 56 {0, 0, 0, 0} 57 } 58 }, 59 { 60 1, 61 3, 62 { {0, 0, 1, 0}, 63 {1, 1, 1, 0}, 64 {0, 0, 0, 0}, 65 {0, 0, 0, 0} 66 } 67 }, 68 { 69 1, 70 3, 71 { {0, 0, 0, 0}, 72 {1, 1, 1, 0}, 73 {0, 1, 0, 0}, 74 {0, 0, 0, 0} 75 } 76 }, 77 { 78 1, 79 3, 80 { {0, 1, 1, 0}, 81 {1, 1, 0, 0}, 82 {0, 0, 0, 0}, 83 {0, 0, 0, 0} 84 } 85 }, 86 { 87 1, 88 3, 89 { {1, 1, 0, 0}, 90 {0, 1, 1, 0}, 91 {0, 0, 0, 0}, 92 {0, 0, 0, 0} 93 } 94 } 95}; 96 97 98uint16_t brickSpeed; 99byte nbRowsThisLevel; 100uint16_t nbRowsTotal; 101Brick tmpBrick; 102boolean tetrisRunning = false; 103boolean tetrisGameOver; 104 105/* *** Game functions *** */ 106//Check collision between bricks in the field and the specified brick 107boolean checkFieldCollision(struct Brick* brick) { 108 byte bx, by; 109 byte fx, fy; 110 for (by = 0; by < 4; by++) { 111 for (bx = 0; bx < 4; bx++) { 112 fx = (*brick).xpos + bx; 113 fy = (*brick).ypos + by; 114 if (( (*brick).pix[bx][by] == 1) 115 && ( field.pix[fx][fy] == 1)) { 116 return true; 117 } 118 } 119 } 120 return false; 121} 122 123void newActiveBrick() { 124 // byte selectedBrick = 3; 125 byte selectedBrick = random(7); 126 ++selectedColor; 127 if (selectedColor > 3) { 128 selectedColor = 0; 129 } 130 //Set properties of brick 131 activeBrick.siz = brickLib[selectedBrick].siz; 132 activeBrick.yOffset = brickLib[selectedBrick].yOffset; 133 activeBrick.xpos = 12 / 2 - activeBrick.siz / 2; 134 activeBrick.ypos = -1 - activeBrick.yOffset; 135 activeBrick.enabled = true; 136 137 //Set color of brick 138 switch (selectedColor) { 139 case 0 : 140 activeBrick.color = 1; 141 break; 142 case 1 : 143 activeBrick.color = 2; 144 break; 145 case 2 : 146 activeBrick.color = 3; 147 break; 148 case 3 : 149 activeBrick.color = 4; 150 break; 151 } 152 //activeBrick.color = colorLib[1]; 153 154 //Copy pix array of selected Brick 155 for (byte y = 0; y < 4; y++) { 156 for (byte x = 0; x < 4; x++) { 157 activeBrick.pix[x][y] = (brickLib[selectedBrick]).pix[x][y]; 158 } 159 } 160 161 //Check collision, if already, then game is over 162 if (checkFieldCollision(&activeBrick)) { 163 tetrisGameOver = true; 164 } 165} 166 167//Check collision between specified brick and all sides of the playing field 168boolean checkSidesCollision(struct Brick* brick) { 169 //Check vertical collision with sides of field 170 byte fx, fy; 171 for (byte by = 0; by < 4; by++) { 172 for (byte bx = 0; bx < 4; bx++) { 173 if ( (*brick).pix[bx][by] == 1) { 174 fx = (*brick).xpos + bx;//Determine actual position in the field of the current pix of the brick 175 fy = (*brick).ypos + by; 176 if (fx < 0 || fx >= 12) { 177 return true; 178 } 179 } 180 } 181 } 182 return false; 183} 184 185 186void printField() { 187 for (byte x = 0; x < 12; x++) { 188 for (byte y = 0; y < 12; y++) { 189 boolean activeBrickPix = 0; 190 if (activeBrick.enabled) { //Only draw brick if it is enabled 191 //Now check if brick is "in view" 192 if ((x >= activeBrick.xpos) && (x < (activeBrick.xpos + (activeBrick.siz))) 193 && (y >= activeBrick.ypos) && (y < (activeBrick.ypos + (activeBrick.siz)))) { 194 activeBrickPix = (activeBrick.pix)[x - activeBrick.xpos][y - activeBrick.ypos]; 195 } 196 } 197 if (field.pix[x][y] == 1) { 198 leds[pgm_read_byte(&ledsAdress[y][x])] = pgm_read_dword(&colorLib[field.color[x][y]]); 199 } else if (activeBrickPix == 1) { 200 leds[pgm_read_byte(&ledsAdress[y][x])] = pgm_read_dword(&colorLib[activeBrick.color]); 201 } else { 202 leds[pgm_read_byte(&ledsAdress[y][x])] = 0x000000; 203 } 204 } 205 } 206 FastLED.show(); 207} 208 209void rotateActiveBrick() { 210 //Copy active brick pix array to temporary pix array 211 for (byte y = 0; y < 4; y++) { 212 for (byte x = 0; x < 4; x++) { 213 tmpBrick.pix[x][y] = activeBrick.pix[x][y]; 214 } 215 } 216 tmpBrick.xpos = activeBrick.xpos; 217 tmpBrick.ypos = activeBrick.ypos; 218 tmpBrick.siz = activeBrick.siz; 219 220 //Depending on size of the active brick, we will rotate differently 221 if (activeBrick.siz == 3) { 222 //Perform rotation around center pix 223 tmpBrick.pix[0][0] = activeBrick.pix[0][2]; 224 tmpBrick.pix[0][1] = activeBrick.pix[1][2]; 225 tmpBrick.pix[0][2] = activeBrick.pix[2][2]; 226 tmpBrick.pix[1][0] = activeBrick.pix[0][1]; 227 tmpBrick.pix[1][1] = activeBrick.pix[1][1]; 228 tmpBrick.pix[1][2] = activeBrick.pix[2][1]; 229 tmpBrick.pix[2][0] = activeBrick.pix[0][0]; 230 tmpBrick.pix[2][1] = activeBrick.pix[1][0]; 231 tmpBrick.pix[2][2] = activeBrick.pix[2][0]; 232 //Keep other parts of temporary block clear 233 tmpBrick.pix[0][3] = 0; 234 tmpBrick.pix[1][3] = 0; 235 tmpBrick.pix[2][3] = 0; 236 tmpBrick.pix[3][3] = 0; 237 tmpBrick.pix[3][2] = 0; 238 tmpBrick.pix[3][1] = 0; 239 tmpBrick.pix[3][0] = 0; 240 241 } else if (activeBrick.siz == 4) { 242 //Perform rotation around center "cross" 243 tmpBrick.pix[0][0] = activeBrick.pix[0][3]; 244 tmpBrick.pix[0][1] = activeBrick.pix[1][3]; 245 tmpBrick.pix[0][2] = activeBrick.pix[2][3]; 246 tmpBrick.pix[0][3] = activeBrick.pix[3][3]; 247 tmpBrick.pix[1][0] = activeBrick.pix[0][2]; 248 tmpBrick.pix[1][1] = activeBrick.pix[1][2]; 249 tmpBrick.pix[1][2] = activeBrick.pix[2][2]; 250 tmpBrick.pix[1][3] = activeBrick.pix[3][2]; 251 tmpBrick.pix[2][0] = activeBrick.pix[0][1]; 252 tmpBrick.pix[2][1] = activeBrick.pix[1][1]; 253 tmpBrick.pix[2][2] = activeBrick.pix[2][1]; 254 tmpBrick.pix[2][3] = activeBrick.pix[3][1]; 255 tmpBrick.pix[3][0] = activeBrick.pix[0][0]; 256 tmpBrick.pix[3][1] = activeBrick.pix[1][0]; 257 tmpBrick.pix[3][2] = activeBrick.pix[2][0]; 258 tmpBrick.pix[3][3] = activeBrick.pix[3][0]; 259 } 260 261 //Now validate by checking collision. 262 //Collision possibilities: 263 // -Brick now sticks outside field 264 // -Brick now sticks inside fixed bricks of field 265 //In case of collision, we just discard the rotated temporary brick 266 if ((!checkSidesCollision(&tmpBrick)) && (!checkFieldCollision(&tmpBrick))) { 267 //Copy temporary brick pix array to active pix array 268 for (byte y = 0; y < 4; y++) { 269 for (byte x = 0; x < 4; x++) { 270 activeBrick.pix[x][y] = tmpBrick.pix[x][y]; 271 } 272 } 273 } 274} 275 276//Copy active pixels to field, including color 277void addActiveBrickToField() { 278 byte fx, fy; 279 for (byte by = 0; by < 4; by++) { 280 for (byte bx = 0; bx < 4; bx++) { 281 fx = activeBrick.xpos + bx; 282 fy = activeBrick.ypos + by; 283 284 if (fx >= 0 && fy >= 0 && fx < 12 && fy < 12 && activeBrick.pix[bx][by]) { //Check if inside playing field 285 //field.pix[fx][fy] = field.pix[fx][fy] || activeBrick.pix[bx][by]; 286 field.pix[fx][fy] = activeBrick.pix[bx][by]; 287 field.color[fx][fy] = activeBrick.color; 288 } 289 } 290 } 291} 292//Shift brick left/right/down by one if possible 293void shiftActiveBrick(char dir) { 294 //Change position of active brick (no copy to temporary needed) 295 if (dir == 'q') { 296 activeBrick.xpos--; 297 } else if (dir == 'd') { 298 activeBrick.xpos++; 299 } else if (dir == 's') { 300 activeBrick.ypos++; 301 } 302 303 //Check position of active brick 304 //Two possibilities when collision is detected: 305 // -Direction was LEFT/RIGHT, just revert position back 306 // -Direction was DOWN, revert position and fix block to field on collision 307 //When no collision, keep activeBrick coordinates 308 if ((checkSidesCollision(&activeBrick)) || (checkFieldCollision(&activeBrick))) { 309 //Serial.println("coll"); 310 if (dir == 'q') { 311 activeBrick.xpos++; 312 } else if (dir == 'd') { 313 activeBrick.xpos--; 314 } else if (dir == 's') { 315 activeBrick.ypos--;//Go back up one 316 addActiveBrickToField(); 317 activeBrick.enabled = false;//Disable brick, it is no longer moving 318 } 319 } 320} 321 322 323 324//Move all pix from te field above startRow down by one. startRow is overwritten 325void moveFieldDownOne(byte startRow) { 326 if (startRow == 0) { //Topmost row has nothing on top to move... 327 return; 328 } 329 byte x, y; 330 for (y = startRow - 1; y > 0; y--) { 331 for (x = 0; x < 12; x++) { 332 field.pix[x][y + 1] = field.pix[x][y]; 333 field.color[x][y + 1] = field.color[x][y]; 334 } 335 } 336} 337 338void checkFullLines() { 339 int x, y; 340 int minY = 0; 341 for (y = (12 - 1); y >= minY; y--) { 342 byte rowSum = 0; 343 for (x = 0; x < 12; x++) { 344 rowSum = rowSum + (field.pix[x][y]); 345 } 346 if (rowSum >= 12) { 347 //Found full row, animate its removal 348 for (x = 0; x < 12; x++) { 349 field.pix[x][y] = 0; 350 printField(); 351 delay(100); 352 } 353 //Move all upper rows down by one 354 moveFieldDownOne(y); 355 y++; minY++; 356 printField(); 357 delay(100); 358 359 nbRowsThisLevel++; nbRowsTotal++; 360 if (nbRowsThisLevel >= 2) { 361 nbRowsThisLevel = 0; 362 brickSpeed = brickSpeed - 100; 363 if (brickSpeed < 200) { 364 brickSpeed = 200; 365 } 366 } 367 } 368 } 369} 370 371void clearField() { 372 for (byte y = 0; y < 12; y++) { 373 for (byte x = 0; x < 12; x++) { 374 field.pix[x][y] = 0; 375 field.color[x][y] = 0; 376 } 377 } 378 for (byte x = 0; x < 12; x++) { //This last row is invisible to the player and only used for the collision detection routine 379 field.pix[x][12] = 1; 380 } 381} 382 383void playerControlActiveBrick() { 384 switch (curControl) { 385 case 'd': 386 shiftActiveBrick('d'); 387 break; 388 case 'q': 389 shiftActiveBrick('q'); 390 break; 391 case 's': 392 shiftActiveBrick('s'); 393 break; 394 case 'a': 395 rotateActiveBrick(); 396 break; 397 case 'y': 398 tetrisRunning = false; 399 break; 400 } 401} 402 403 404void tetrisInit() { 405 clearField(); 406 brickSpeed = 1000; 407 nbRowsThisLevel = 0; 408 nbRowsTotal = 0; 409 tetrisGameOver = false; 410 411 newActiveBrick(); 412} 413 414 415void runTetris(void) { 416 tetrisInit(); 417 418 prevUpdateTime = 0; 419 420 tetrisRunning = true; 421 while (tetrisRunning) { 422 curTime = 0; 423 424 do { 425 readPointer(); //ATTENTION SOURCE BUG ?! 426 if (menuValidation) { 427 tetrisRunning = false; 428 break; 429 } 430 if (curControl != 'n') { 431 playerControlActiveBrick(); 432 printField(); 433 curControl = 'n'; 434 } 435 if (tetrisGameOver) break; 436 437 curTime = millis(); 438 } while ((curTime - prevUpdateTime) < brickSpeed);//Once enough time has passed, proceed. The lower this number, the faster the game is 439 prevUpdateTime = curTime; 440 441 if (tetrisGameOver) { 442 fadeImg(); 443 444 //Disable loop and exit to main menu of led table 445 tetrisRunning = false; 446 break; 447 } 448 449 //If brick is still "on the loose", then move it down by one 450 if (activeBrick.enabled) { 451 shiftActiveBrick('s'); 452 } else { 453 //Active brick has "crashed", check for full lines 454 //and create new brick at top of field 455 checkFullLines(); 456 newActiveBrick(); 457 prevUpdateTime = millis();//Reset update time to avoid brick dropping two spaces 458 } 459 printField(); 460 } 461 462 463} 464 465 466 467 468 469 470
pong.h
arduino
1 2byte scorePlayerLeft = 0; 3byte scorePlayerRight = 0; 4 5byte 6 positionPlayerLeft; 7byte positionPlayerRight; 8 9uint8_t ballx; 10uint8_t 11 previousBallx; 12uint8_t bally; 13uint8_t previousBally; 14uint8_t velocityx; 15uint8_t 16 velocityy; 17byte ballBounces; 18 19byte gameSpeed; 20 21//Arduino : Unsigned 22 long !!!!! 23unsigned long lastAutoPlayerMoveTime; 24unsigned long rumbleUntil; 25unsigned 26 long waitUntil; 27 28void setPosition() { 29 if (!digitalRead(R1_PIN)) { 30 31 if (positionPlayerLeft + (3 - 1) / 2 < 12 - 1) { 32 ++positionPlayerLeft; 33 34 } 35 } 36 else if (!digitalRead(L1_PIN)) { 37 if (positionPlayerLeft 38 - 3 / 2 > 0) { 39 --positionPlayerLeft; 40 } 41 } 42 if (!digitalRead(L2_PIN)) 43 { 44 if (positionPlayerRight - 3 / 2 > 0) { 45 --positionPlayerRight; 46 47 } 48 } 49 else if (!digitalRead(R2_PIN)) { 50 if (positionPlayerRight 51 + (3 - 1) / 2 < 12 - 1) { 52 ++positionPlayerRight; 53 } 54 55 } 56 57 curControl = 'n'; 58} 59 60void checkBallHitByPlayer() { 61 if (ballx == 62 1) 63 { 64 if (bally == positionPlayerLeft) 65 { 66 velocityx = 67 1; 68 ballx = 1; 69 ++ballBounces; 70 rumbleUntil = curTime + 71 200; 72 } 73 else if (bally < positionPlayerLeft && bally >= positionPlayerLeft 74 - 3 / 2) 75 { 76 velocityx = 1; 77 velocityy = max(-1, velocityy 78 - 1); 79 ballx = 1; 80 bally = positionPlayerLeft - 3 / 2 - 1; 81 ++ballBounces; 82 83 rumbleUntil = curTime + 200; 84 } 85 else if (bally > positionPlayerLeft 86 && bally <= positionPlayerLeft + (3 - 1) / 2) 87 { 88 velocityx = 1; 89 90 velocityy = min(1, velocityy + 1); 91 ballx = 1; 92 bally = positionPlayerLeft 93 + (3 - 1) / 2 + 1; 94 ++ballBounces; 95 rumbleUntil = curTime + 200; 96 97 } 98 } 99 else if (ballx == 12 - 2) 100 { 101 if (bally == positionPlayerRight) 102 103 { 104 velocityx = -1; 105 ballx = 12 - 2; 106 ++ballBounces; 107 108 } 109 else if (bally < positionPlayerRight && bally >= positionPlayerRight 110 - 3 / 2) 111 { 112 velocityx = -1; 113 velocityy = max(-1, velocityy 114 - 1); 115 ballx = 12 - 2; 116 bally = positionPlayerRight - 3 / 2 - 1; 117 118 ++ballBounces; 119 } 120 else if (bally > positionPlayerRight && bally 121 <= positionPlayerRight + (3 - 1) / 2) 122 { 123 velocityx = -1; 124 velocityy 125 = min(1, velocityy + 1); 126 ballx = 12 - 2; 127 bally = positionPlayerRight 128 + (3 - 1) / 2 + 1; 129 ++ballBounces; 130 } 131 } 132} 133 134void checkBallOutOfBounds() 135 { 136 if (bally < 1) 137 { 138 velocityy = - velocityy; 139 bally = 0; 140 141 //bally = 1; 142 } else if (bally > 12 -1) 143 { 144 velocityy = - velocityy; 145 146 bally = 12 - 2; 147 //bally = 12-1; 148 } 149 if (ballx < 0) 150 { 151 152 velocityx = - velocityx; 153 velocityy = 0; 154 ballx = 12 / 2; 155 bally 156 = 12 / 2; 157 ++scorePlayerRight; 158 ballBounces = 0; 159 waitUntil = 160 curTime + 2000; 161 fadeImg(); 162 } 163 else if (ballx > 12 - 1) 164 { 165 166 velocityx = - velocityx; 167 velocityy = 0; 168 ballx = 12 / 2; 169 bally 170 = 12 / 2; 171 ++scorePlayerLeft; 172 ballBounces = 0; 173 waitUntil = curTime 174 + 2000; 175 fadeImg(); 176 } 177} 178 179/*boolean moveAutoPlayer() 180 { 181 182 if (bally < positionPlayerRight) 183 { 184 if (positionPlayerRight - 3 / 2 185 > 0) 186 { 187 --positionPlayerRight; 188 return true; 189 } 190 191 } 192 else if (bally > positionPlayerRight) 193 { 194 if (positionPlayerRight 195 + (3 - 1) / 2 < 12 - 1) 196 { 197 ++positionPlayerRight; 198 return 199 true; 200 } 201 } 202 return false; 203 }*/ 204 205void pongInit() { 206 scorePlayerLeft 207 = 0; 208 scorePlayerRight = 0; 209 positionPlayerLeft = 12 / 2; 210 positionPlayerRight 211 = 12 / 2; 212 ballx = 12 / 2; 213 bally = 12 / 2; 214 velocityx = 1; 215 velocityy 216 = 0; 217 ballBounces = 0; 218 gameSpeed = 180; 219 lastAutoPlayerMoveTime = 0; 220 221 rumbleUntil = 0; 222 waitUntil = 0; 223} 224 225void runPong() { 226 pongInit(); 227 228 229 boolean pongRunning = true; 230 while (pongRunning) { 231 232 if (scorePlayerLeft 233 == 5) { 234 pongRunning = false; 235 scrollText("Game over", 9, 0xff0000); 236 237 scorePlayerLeft = 0; 238 scorePlayerRight = 0; 239 break; 240 } 241 if (scorePlayerRight == 5) { 242 pongRunning = false; 243 scrollText("Game 244 over", 9, 0xff0000); 245 scorePlayerLeft = 0; 246 scorePlayerRight = 247 0; 248 break; 249 } 250 251 checkBallHitByPlayer(); 252 253 /* if 254 ((curTime - lastAutoPlayerMoveTime) > 200) { 255 if (moveAutoPlayer()) { 256 257 lastAutoPlayerMoveTime = curTime; 258 } 259 }*/ 260 261 ballx 262 += velocityx; 263 bally += velocityy; 264 265 checkBallOutOfBounds(); 266 267 for (byte i = 0; i < 12; i++) { 268 for (byte j = 0; j < 12; j++) { 269 270 leds[pgm_read_byte(&ledsAdress[i][j])] = 0x000000; 271 } 272 } 273 274 275 276 // Draw ball 277 leds[pgm_read_byte(&ledsAdress[ballx][bally])] = 0xffffff; 278 279 // Draw player left 280 for (int y = positionPlayerLeft - 3 / 2; y <= positionPlayerLeft 281 + 3 / 2; ++y) { 282 leds[pgm_read_byte(&ledsAdress[0][y])] = 0x0000ff; 283 284 } 285 // Draw player right 286 for (int y = positionPlayerRight - 3 / 287 2; y <= positionPlayerRight + 3 / 2; ++y) { 288 leds[pgm_read_byte(&ledsAdress[12 289 - 1][y])] = 0xffff00; 290 } 291 292 FastLED.show(); 293 boolean dirChanged 294 = false; 295 do { 296 if (menuValidation) { 297 pongRunning = false; 298 299 break; 300 } 301 readPointer(); 302 if (curControl != 'n' 303 && !dirChanged) { //Can only change direction once per loop 304 dirChanged 305 = true; 306 setPosition(); 307 } 308 curTime = millis(); 309 } 310 311 while ((curTime - prevUpdateTime) < 140); //Once enough time has passed, proceed. 312 The lower this number, the faster the game is 313 prevUpdateTime = curTime; 314 315 } 316} 317 318 319
snake.h
arduino
1byte curLength;//Curren length of snake 2int xs[127];//Array containing 3 all snake segments, 4int ys[127];// max snake length is array length 5char dir;//Current 6 Direction of snake 7 8boolean snakeGameOver; 9 10byte ax = 0;//Apple x position 11byte 12 ay = 0;//Apple y position 13 14void snakeInit() { 15 //Snake start position 16 and direction & initialise variables 17 curLength = 3; 18 xs[0] = 3; 19 xs[1] 20 = 2; 21 xs[2] = 1; 22 ys[0] = 12 / 2; 23 ys[1] = 12 / 2; 24 ys[2] = 12 / 25 2; 26 dir = 'd'; 27 //Generate random apple position 28 ax = random(0, 11); 29 30 ay = random(0, 11); 31 32 snakeGameOver = false; 33} 34/* Set direction from 35 current button state */ 36void setDirection() { 37 readPointer(); 38 switch 39 (curControl) { 40 case 'q': 41 dir = 'z'; 42 break; 43 case 44 'd': 45 dir = 's'; 46 break; 47 case 's': 48 dir = 'd'; 49 50 break; 51 case 'z': 52 dir = 'q'; 53 break; 54 } 55} 56 57/* 58 Ending, show score */ 59void die() { 60 snakeGameOver = true; 61 fadeImg(); 62} 63 64/* 65 Collision detection function */ 66boolean collide(int x1, int x2, int y1, int y2, 67 int w1, int w2, int h1, int h2) { 68 if ((x1 + w1 > x2) && (x1 < x2 + w2) && (y1 69 + h1 > y2) && (y1 < y2 + h2)) { 70 return true; 71 } else { 72 return 73 false; 74 } 75} 76 77void runSnake() { 78 snakeInit(); 79 prevUpdateTime 80 = 0; 81 boolean snakeRunning = true; 82 while (snakeRunning) { 83 //Check 84 self-collision with snake 85 int i = curLength - 1; 86 while (i >= 2) { 87 88 if (collide(xs[0], xs[i], ys[0], ys[i], 1, 1, 1, 1)) { 89 die(); 90 91 } 92 i = i - 1; 93 } 94 95 if (snakeGameOver) { 96 snakeRunning 97 = false; 98 break; 99 } 100 101 //Check collision of snake head with 102 apple 103 if (collide(xs[0], ax, ys[0], ay, 1, 1, 1, 1)) { 104 //Increase 105 score and snake length; 106 curLength = curLength + 1; 107 //Add snake 108 segment with temporary position of new segments 109 xs[curLength - 1] = 255; 110 111 ys[curLength - 1] = 255; 112 113 //Generate new apple position 114 ax 115 = random(0, 11); 116 ay = random(0, 11); 117 118 for (int j = 0; j < curLength; 119 j++) { 120 if (collide(ax, xs[j], ay, ys[j], 1, 1, 1, 1)) { 121 ax 122 = random(0, 11); 123 ay = random(0, 11); 124 j = 0; //ICI 125 126 } 127 } 128 } 129 130 //Shift snake position array by one 131 132 i = curLength - 1; 133 while (i >= 1) { 134 xs[i] = xs[i - 1]; 135 ys[i] 136 = ys[i - 1]; 137 i = i - 1; 138 } 139 //Determine new position of head 140 of snake 141 if (dir == 'd') { 142 xs[0] = xs[0] + 1; 143 } else if (dir 144 == 'q') { 145 xs[0] = xs[0] - 1; 146 } else if (dir == 'z') { 147 ys[0] 148 = ys[0] - 1; 149 } else {//DOWN 150 ys[0] = ys[0] + 1; 151 } 152 153 154 //Check if outside playing field 155 if ((xs[0] < 0) || (xs[0] >= 12) || 156 (ys[0] < 0) || (ys[0] >= 12)) { 157 if (xs[0] < 0) { 158 xs[0] = 12 159 - 1; 160 } else if (xs[0] >= 12) { 161 xs[0] = 0; 162 } else if 163 (ys[0] < 0) { 164 ys[0] = 12 - 1; 165 } else if (ys[0] >= 12) { 166 167 ys[0] = 0; 168 } 169 } 170 171 for (int j = 0; j < 144; j++) 172 { 173 leds[j] = 0x000000; 174 175 } 176 177 //Draw apple 178 leds[pgm_read_byte(&ledsAdress[ax][ay])] 179 = 0xFF0000; 180 181 //Draw snake 182 for (int j = 0; j < curLength; j++) { 183 184 leds[pgm_read_byte(&ledsAdress[xs[j]] [ys[j]])] = 0x388FEC; 185 } 186 187 188 FastLED.show(); 189 190 //Check buttons and set snake movement direction 191 while we are waiting to draw the next move 192 curTime = 0; 193 boolean dirChanged 194 = false; 195 do { 196 if (menuValidation) { 197 snakeRunning = false; 198 199 break; 200 } 201 if (curControl != 'n' && !dirChanged) {//Can 202 only change direction once per loop 203 dirChanged = true; 204 setDirection(); 205 206 } 207 curTime = millis(); 208 } while ((curTime - prevUpdateTime) 209 < 200);//Once enough time has passed, proceed. The lower this number, the faster 210 the game is 211 prevUpdateTime = curTime; 212 } 213 214 215} 216 217 218
Random roulette mode (idk how to call it ^^' )
arduino
1const unsigned long PROGMEM img[12][12] = {{0x020EF4, 0x022FF4, 0x0159F3, 2 0x018AF5, 0x01BFF9, 0x01F5FB, 0x01FFD6, 0x01FDA5, 0x01FC7A, 0x01FB54, 0x01FA38, 3 0x02F91F}, 4 {0x0100F3, 0x010EF4, 0x0237F3, 0x0170F4, 0x01B1F9, 0x01F2FA, 0x01FFCB, 5 0x01FC8E, 0x01FB5D, 0x01FA37, 0x01F918, 0x00F905}, 6 {0x0001F2, 0x0000F2, 0x010FF3, 7 0x0247F4, 0x019BF7, 0x01EFF8, 0x01FFBA, 0x01FB6E, 0x01FA35, 0x00F812, 0x00F802, 8 0x01F900}, 9 {0x0201F2, 0x0001F2, 0x0000F3, 0x0010F3, 0x016CF6, 0x01E9F5, 0x00FF97, 10 0x00FA35, 0x00F908, 0x02F900, 0x0EFA00, 0x1FFB01}, 11 {0x2C00F3, 0x1D01F3, 0x0F01F2, 12 0x0100F2, 0x001BF9, 0x00CEE4, 0x00FF42, 0x08F901, 0x1DFB00, 0x33FC01, 0x41FE00, 13 0x4BFE00}, 14 {0x6701F3, 0x6501F3, 0x6501F4, 0x6402F5, 0x6700FE, 0x756F82, 0x7CFF00, 15 0x7BFF02, 0x7AFF02, 0x7BFF02, 0x7AFE02, 0x79FF01}, 16 {0x9F00F3, 0xAC01F3, 0xC301F7, 17 0xE001F1, 0xF900AE, 0xFF0C15, 0xFFAF00, 0xF3FD04, 0xD8FF03, 0xC0FF03, 0xB2FF04, 18 0xA9FE04}, 19 {0xD301F5, 0xE600F2, 0xF401DF, 0xF600AF, 0xF4004F, 0xF30001, 0xF95000, 20 0xFFC002, 0xFFF303, 0xF7FF03, 0xE6FF02, 0xD3FF03}, 21 {0xF301E9, 0xF501D0, 0xF301A9, 22 0xF30074, 0xF20026, 0xF10000, 0xF52A01, 0xFA8202, 0xFFC003, 0xFFEA04, 0xFFFD03, 23 0xF7FF03}, 24 {0xF400C5, 0xF301A8, 0xF20182, 0xF2014F, 0xF20113, 0xF20000, 0xF41801, 25 0xF75C02, 0xFD9502, 0xFEBF02, 0xFFE103, 0xFFF803}, 26 {0xF301A8, 0xF30089, 0xF20065, 27 0xF10137, 0xF20009, 0xF20000, 0xF30D01, 0xF64301, 0xF97601, 0xFDA001, 0xFEC002, 28 0xFFDB03}, 29 {0xF30090, 0xF20172, 0xF2014E, 0xF30126, 0xF20003, 0xF20000, 0xF30801, 30 0xF43201, 0xF75F02, 0xFC8602, 0xFEA601, 0xFEC102} 31}; 32 33void bottleAnimation(byte 34 t, byte stopb) { 35 byte iterations = 0; 36 37 while (!menuValidation) { 38 39 for (byte k = 0; k < 4; k++) { 40 switch (k) { 41 case 0: 42 43 for (byte i = 2; i < 12; i++) { 44 iterations++; 45 if 46 (iterations == stopb) { 47 goto mainLoopBottle; 48 } 49 50 clearImg(); 51 leds[pgm_read_byte(&ledsAdress[2][i - 2])] 52 = pgm_read_dword(&img[1][i - 2]); 53 leds[pgm_read_byte(&ledsAdress[2][i 54 - 1])] = pgm_read_dword(&img[2][i - 1]); 55 leds[pgm_read_byte(&ledsAdress[2][i])] 56 = pgm_read_dword(&img[2][i]); 57 leds[pgm_read_byte(&ledsAdress[1][i 58 - 2])] = pgm_read_dword(&img[1][i - 2]); 59 leds[pgm_read_byte(&ledsAdress[1][i 60 - 1])] = pgm_read_dword(&img[1][i - 1]); 61 leds[pgm_read_byte(&ledsAdress[1][i])] 62 = pgm_read_dword(&img[1][i]); 63 leds[pgm_read_byte(&ledsAdress[0][i 64 - 2])] = pgm_read_dword(&img[1][i - 2]); 65 leds[pgm_read_byte(&ledsAdress[0][i])] 66 = pgm_read_dword(&img[0][i]); 67 leds[pgm_read_byte(&ledsAdress[0][i 68 - 1])] = pgm_read_dword(&img[1][i - 1]); 69 FastLED.show(); 70 delay(t); 71 72 } 73 break; 74 case 1: 75 for (byte i = 2; 76 i < 12; i++) { 77 iterations++; 78 if (iterations == stopb) 79 { 80 goto mainLoopBottle; 81 } 82 clearImg(); 83 84 leds[pgm_read_byte(&ledsAdress[i - 2][11])] = pgm_read_dword(&img[i 85 - 2][11]); 86 leds[pgm_read_byte(&ledsAdress[i - 1][11])] = pgm_read_dword(&img[i 87 - 1][11]); 88 leds[pgm_read_byte(&ledsAdress[i][11])] = pgm_read_dword(&img[i][11]); 89 90 leds[pgm_read_byte(&ledsAdress[i - 2][10])] = pgm_read_dword(&img[i 91 - 2][10]); 92 leds[pgm_read_byte(&ledsAdress[i - 1][10])] = pgm_read_dword(&img[i 93 - 1][10]); 94 leds[pgm_read_byte(&ledsAdress[i][10])] = pgm_read_dword(&img[i][10]); 95 96 leds[pgm_read_byte(&ledsAdress[i - 2][9])] = pgm_read_dword(&img[i - 97 2][9]); 98 leds[pgm_read_byte(&ledsAdress[i - 1][9])] = pgm_read_dword(&img[i 99 - 1][9]); 100 leds[pgm_read_byte(&ledsAdress[i][9])] = pgm_read_dword(&img[i][9]); 101 102 FastLED.show(); 103 delay(t); 104 } 105 break; 106 107 case 2: 108 for (byte i = 12 - 1; i > 1; i--) { 109 iterations++; 110 111 if (iterations == stopb) { 112 goto mainLoopBottle; 113 114 } 115 clearImg(); 116 leds[pgm_read_byte(&ledsAdress[11][i 117 - 2])] = pgm_read_dword(&img[11][i - 2]); 118 leds[pgm_read_byte(&ledsAdress[11][i 119 - 1])] = pgm_read_dword(&img[11][i - 1]); 120 leds[pgm_read_byte(&ledsAdress[11][i])] 121 = pgm_read_dword(&img[11][i]); 122 leds[pgm_read_byte(&ledsAdress[10][i 123 - 2])] = pgm_read_dword(&img[10][i - 2]); 124 leds[pgm_read_byte(&ledsAdress[10][i 125 - 1])] = pgm_read_dword(&img[10][i - 1]); 126 leds[pgm_read_byte(&ledsAdress[10][i])] 127 = pgm_read_dword(&img[10][i]); 128 leds[pgm_read_byte(&ledsAdress[9][i 129 - 2])] = pgm_read_dword(&img[9][i - 2]); 130 leds[pgm_read_byte(&ledsAdress[9][i])] 131 = pgm_read_dword(&img[9][i]); 132 leds[pgm_read_byte(&ledsAdress[9][i 133 - 1])] = pgm_read_dword(&img[9][i - 1]); 134 FastLED.show(); 135 delay(t); 136 137 } 138 break; 139 case 3: 140 for (byte i = 12 141 - 1; i > 1; i--) { 142 iterations++; 143 if (iterations == 144 stopb) { 145 goto mainLoopBottle; 146 } 147 clearImg(); 148 149 leds[pgm_read_byte(&ledsAdress[i - 2][2])] = pgm_read_dword(&img[i - 150 2][2]); 151 leds[pgm_read_byte(&ledsAdress[i - 1][2])] = pgm_read_dword(&img[i 152 - 1][2]); 153 leds[pgm_read_byte(&ledsAdress[i][2])] = pgm_read_dword(&img[i][2]); 154 155 leds[pgm_read_byte(&ledsAdress[i - 2][1])] = pgm_read_dword(&img[i - 156 2][1]); 157 leds[pgm_read_byte(&ledsAdress[i - 1][1])] = pgm_read_dword(&img[i 158 - 1][1]); 159 leds[pgm_read_byte(&ledsAdress[i][1])] = pgm_read_dword(&img[i][1]); 160 161 leds[pgm_read_byte(&ledsAdress[i - 2][0])] = pgm_read_dword(&img[i - 162 2][0]); 163 leds[pgm_read_byte(&ledsAdress[i - 1][0])] = pgm_read_dword(&img[i 164 - 1][0]); 165 leds[pgm_read_byte(&ledsAdress[i][0])] = pgm_read_dword(&img[i][0]); 166 167 FastLED.show(); 168 delay(t); 169 } 170 break; 171 172 173 } 174 } 175} mainLoopBottle: 176delay(4); 177} 178 179void bottle() { 180 181 bottleAnimation(60, random(100, 139)); 182 183 int prevPointer = menuPointer; 184 185 while (!menuValidation && menuPointer == prevPointer) { 186 readPointer(); 187 188 delay(4); 189 } 190}
Audio spectrum visualizer
arduino
FischiMc's code adapted to my LED matrix
1/* 2 Written by FischiMc and SupaStefe, modified by Antoine Rochebois 3 (scaling to 12*12) 4 5 This sketch uses a 10x10 RGB LED-Matrix as a spectrum 6 analyzer 7 It uses a FTT Library to analyze an audio signal connected to the 8 9 pin A7 of an Arduino nano. Everytime a column gets higher than 10 10 pixels 11 the color of each column changes. 12*/ 13 14#define LOG_OUT 0 //set output 15 of FFT library to linear not logarithmical 16#define LIN_OUT 1 17#define FFT_N 18 256 //set to 256 point fft 19 20#include <FFT.h> //include the 21 FFT library 22#include <FastLED.h> //include the FastLED Library 23#include 24 <math.h> //include library for mathematic funcions 25#define DATA_PIN 5 26 //DATA PIN WHERE YOUR LEDS ARE CONNECTED 27#define NUM_LEDS 144 //amount 28 of LEDs in your matrix 29CRGB leds[NUM_LEDS]; 30float faktoren[12] = {1, 1.1, 31 1.15, 1.25, 1.35, 1.45, 1.55, 1.65 , 1.75, 1.8, 2, 3}; //factors to increase 32 the height of each column 33unsigned char hs[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 34 0, 0 , 0}; //height of each column 35float hue = 0; //hue 36 value of the colors 37 38void setBalken(unsigned char column, unsigned char height) 39 { //calculation of the height of each column 40 unsigned char 41 h = (unsigned char)map(height, 0, 255, 0, 12); 42 h = (unsigned char)(h * faktoren[column]); 43 44 if (h < hs[column]) { 45 hs[column]--; 46 } 47 else if (h > hs[column]) 48 { 49 hs[column] = h; 50 } 51 if (height > 250) { 52 hue += 2; //CHANGE 53 THIS VALUE IF YOU WANT THE DIFFERENCE BETWEEN THE COLORS TO BE BIGGER 54 if 55 (hue > 25) hue = 0; 56 } 57 58 for (unsigned char y = 0; y < 12; y++) { //set 59 colors of pixels according to column and hue 60 if (hs[column] > y) { 61 if 62 (column % 2 == 0) { 63 leds[y + (column * 12)] = CHSV((hue * 12) + (column 64 * 12), 255, 200); 65 } else { 66 leds[12 - y + (column * 12)] = CHSV((hue 67 * 12) + (column * 12), 255, 200); 68 } 69 70 } else { 71 if (column 72 % 2 == 0) { 73 leds[y + (column * 12)] = CRGB::Black; 74 } else { 75 76 leds[12 - y + (column * 12)] = CRGB::Black; 77 } 78 } 79 } 80} 81 82unsigned 83 char grenzen[13] = {0, 3, 5, 7, 9, 11, 13, 15, 17, 20, 24, 32, 69}; //borders of 84 the frequency areas 85 86void setup() { 87 FastLED.addLeds<WS2812B, DATA_PIN, 88 GRB> (leds, NUM_LEDS); 89 TIMSK0 = 0; //turn 90 off timer0 for lower jitter 91 ADCSRA = 0xe5; //set 92 the adc to free running mode 93 ADMUX = 0x40; //use 94 pin A0 95 DIDR0 = 0x01; //turn 96 off the digital input for 97 analogReference(EXTERNAL); //set 98 aref to external 99} 100 101void loop() { 102 while (1) { //reduces 103 jitter 104 cli(); //UDRE 105 interrupt slows this way down on arduino1.0 106 for (int i = 0 ; i < 512 ; i 107 += 2) { //save 256 samples 108 while (!(ADCSRA & 109 0x10)); //wait for adc to be ready 110 ADCSRA 111 = 0xf5; //restart adc 112 byte 113 m = ADCL; //fetch adc data 114 byte 115 j = ADCH; 116 int k = (j << 8) | m; //form 117 into an int 118 k -= 0x0200; //form 119 into a signed int 120 k <<= 6; //form 121 into a 16b signed int 122 fft_input[i] = k; //put 123 real data into even bins 124 } 125 126 fft_window(); // 127 window the data for better frequency response 128 fft_reorder(); // 129 reorder the data before doing the fft 130 fft_run(); // 131 process the data in the fft 132 fft_mag_lin(); // 133 take the output of the fft 134 sei(); 135 136 fft_lin_out[0] = 0; 137 fft_lin_out[1] 138 = 0; 139 140 for (unsigned char i = 0; i < 13; i++) { 141 unsigned char 142 maxW = 0; 143 for (unsigned char x = grenzen[i]; x < grenzen[i + 1]; x++) { 144 145 146 if ((unsigned char)fft_lin_out[x] > maxW) { 147 maxW = (unsigned 148 char)fft_lin_out[x]; 149 } 150 } 151 152 setBalken(i, maxW); 153 154 155 } 156 TIMSK0 = 1; 157 FastLED.show(); 158 TIMSK0 = 0; 159 } 160}
Game of Life
arduino
The algorithm for the Conway's Game of life function
1void gameOfLife(void) { 2 //Génération d'une grille de départ aléatoire 3 for (byte i = 0; i < 12; i++) { 4 for (byte j = 0; j < 12; j++) { 5 byte r = random(0, 100); 6 if (r < 35) { 7 grid[i][j] = true; 8 leds[pgm_read_byte(&ledsAdress[i][j])] = 0x2CB697; 9 } else { 10 grid[i][j] = false; 11 leds[pgm_read_byte(&ledsAdress[i][j])] = 0x11463A; 12 } 13 } 14 } 15 FastLED.show(); 16 17 //Tant que la grille n'est pas vide 18 byte nbCases; 19 byte iterations = 0; 20 21 do { 22 readPointer(); 23 if (menuValidation) { 24 break; 25 } 26 ++iterations; 27 if (iterations > 250) { 28 break; 29 } 30 //Délai de 150ms 31 delay(120); 32 33 //Initialisation et comptage du nombre de voisins de chaque case 34 nbCases = 0; 35 byte voisins[12][12]; 36 for (byte i = 0; i < 12; i++) { 37 for (byte j = 0; j < 12; j++) { 38 voisins[i][j] = 0; 39 } 40 } 41 42 for (byte i = 0; i < 12; i++) { 43 for (byte j = 0; j < 12; j++) { 44 for (int k = -1; k < 2; k++) { 45 for (int m = -1; m < 2; m++) { 46 if ((grid[(i + k + 12) % 12][(j + m + 12) % 12] == true) && !(k == 0 && m == 0)) { 47 voisins[i][j]++; 48 } 49 } 50 } 51 } 52 } 53 54 //Détermination des cellules vivantes et mortes et mise à jour de l'affichage 55 for (byte i = 0; i < 12; i++) { 56 for (byte j = 0; j < 12; j++) { 57 if (grid[i][j]) { 58 nbCases++; 59 //Cellule vivante reste vivante avec 2 ou 3 voisins 60 if (voisins[i][j] == 2 || voisins[i][j] == 3) { 61 grid[i][j] = true; 62 leds[pgm_read_byte(&ledsAdress[i][j])] = 0x2CB697; 63 } else { 64 grid[i][j] = false; 65 leds[pgm_read_byte(&ledsAdress[i][j])] = 0x11463A; 66 } 67 68 } else { 69 if (voisins[i][j] == 3) { 70 //Cellule morte devient vivante si elle a 3 voisins 71 grid[i][j] = true; 72 leds[pgm_read_byte(&ledsAdress[i][j])] = 0x2CB697; 73 } 74 } 75 } 76 } 77 FastLED.show(); 78 if (nbCases <= 4) { 79 for (byte i = 0; i < 12; i++) { 80 for (byte j = 0; j < 12; j++) { 81 if (i < 12 - 1) { 82 leds[pgm_read_byte(&ledsAdress[i][j])] = 0xe22c79; 83 } else { 84 leds[pgm_read_byte(&ledsAdress[i][j])] = 0x11463A; 85 } 86 87 leds[pgm_read_byte(&ledsAdress[(i + 11) % 12][j])] = 0x11463A; 88 } 89 FastLED.show(); 90 delay(100); 91 } 92 } 93 } while (nbCases > 4); 94}
pong.h
arduino
1 2byte scorePlayerLeft = 0; 3byte scorePlayerRight = 0; 4 5byte positionPlayerLeft; 6byte positionPlayerRight; 7 8uint8_t ballx; 9uint8_t previousBallx; 10uint8_t bally; 11uint8_t previousBally; 12uint8_t velocityx; 13uint8_t velocityy; 14byte ballBounces; 15 16byte gameSpeed; 17 18//Arduino : Unsigned long !!!!! 19unsigned long lastAutoPlayerMoveTime; 20unsigned long rumbleUntil; 21unsigned long waitUntil; 22 23void setPosition() { 24 if (!digitalRead(R1_PIN)) { 25 if (positionPlayerLeft + (3 - 1) / 2 < 12 - 1) { 26 ++positionPlayerLeft; 27 } 28 } 29 else if (!digitalRead(L1_PIN)) { 30 if (positionPlayerLeft - 3 / 2 > 0) { 31 --positionPlayerLeft; 32 } 33 } 34 if (!digitalRead(L2_PIN)) { 35 if (positionPlayerRight - 3 / 2 > 0) { 36 --positionPlayerRight; 37 } 38 } 39 else if (!digitalRead(R2_PIN)) { 40 if (positionPlayerRight + (3 - 1) / 2 < 12 - 1) { 41 ++positionPlayerRight; 42 } 43 44 } 45 curControl = 'n'; 46} 47 48void checkBallHitByPlayer() { 49 if (ballx == 1) 50 { 51 if (bally == positionPlayerLeft) 52 { 53 velocityx = 1; 54 ballx = 1; 55 ++ballBounces; 56 rumbleUntil = curTime + 200; 57 } 58 else if (bally < positionPlayerLeft && bally >= positionPlayerLeft - 3 / 2) 59 { 60 velocityx = 1; 61 velocityy = max(-1, velocityy - 1); 62 ballx = 1; 63 bally = positionPlayerLeft - 3 / 2 - 1; 64 ++ballBounces; 65 rumbleUntil = curTime + 200; 66 } 67 else if (bally > positionPlayerLeft && bally <= positionPlayerLeft + (3 - 1) / 2) 68 { 69 velocityx = 1; 70 velocityy = min(1, velocityy + 1); 71 ballx = 1; 72 bally = positionPlayerLeft + (3 - 1) / 2 + 1; 73 ++ballBounces; 74 rumbleUntil = curTime + 200; 75 } 76 } 77 else if (ballx == 12 - 2) 78 { 79 if (bally == positionPlayerRight) 80 { 81 velocityx = -1; 82 ballx = 12 - 2; 83 ++ballBounces; 84 } 85 else if (bally < positionPlayerRight && bally >= positionPlayerRight - 3 / 2) 86 { 87 velocityx = -1; 88 velocityy = max(-1, velocityy - 1); 89 ballx = 12 - 2; 90 bally = positionPlayerRight - 3 / 2 - 1; 91 ++ballBounces; 92 } 93 else if (bally > positionPlayerRight && bally <= positionPlayerRight + (3 - 1) / 2) 94 { 95 velocityx = -1; 96 velocityy = min(1, velocityy + 1); 97 ballx = 12 - 2; 98 bally = positionPlayerRight + (3 - 1) / 2 + 1; 99 ++ballBounces; 100 } 101 } 102} 103 104void checkBallOutOfBounds() { 105 if (bally < 1) 106 { 107 velocityy = - velocityy; 108 bally = 0; 109 //bally = 1; 110 } else if (bally > 12 -1) 111 { 112 velocityy = - velocityy; 113 bally = 12 - 2; 114 //bally = 12-1; 115 } 116 if (ballx < 0) 117 { 118 velocityx = - velocityx; 119 velocityy = 0; 120 ballx = 12 / 2; 121 bally = 12 / 2; 122 ++scorePlayerRight; 123 ballBounces = 0; 124 waitUntil = curTime + 2000; 125 fadeImg(); 126 } 127 else if (ballx > 12 - 1) 128 { 129 velocityx = - velocityx; 130 velocityy = 0; 131 ballx = 12 / 2; 132 bally = 12 / 2; 133 ++scorePlayerLeft; 134 ballBounces = 0; 135 waitUntil = curTime + 2000; 136 fadeImg(); 137 } 138} 139 140/*boolean moveAutoPlayer() 141 { 142 if (bally < positionPlayerRight) 143 { 144 if (positionPlayerRight - 3 / 2 > 0) 145 { 146 --positionPlayerRight; 147 return true; 148 } 149 } 150 else if (bally > positionPlayerRight) 151 { 152 if (positionPlayerRight + (3 - 1) / 2 < 12 - 1) 153 { 154 ++positionPlayerRight; 155 return true; 156 } 157 } 158 return false; 159 }*/ 160 161void pongInit() { 162 scorePlayerLeft = 0; 163 scorePlayerRight = 0; 164 positionPlayerLeft = 12 / 2; 165 positionPlayerRight = 12 / 2; 166 ballx = 12 / 2; 167 bally = 12 / 2; 168 velocityx = 1; 169 velocityy = 0; 170 ballBounces = 0; 171 gameSpeed = 180; 172 lastAutoPlayerMoveTime = 0; 173 rumbleUntil = 0; 174 waitUntil = 0; 175} 176 177void runPong() { 178 pongInit(); 179 180 boolean pongRunning = true; 181 while (pongRunning) { 182 183 if (scorePlayerLeft == 5) { 184 pongRunning = false; 185 scrollText("Game over", 9, 0xff0000); 186 scorePlayerLeft = 0; 187 scorePlayerRight = 0; 188 break; 189 } if (scorePlayerRight == 5) { 190 pongRunning = false; 191 scrollText("Game over", 9, 0xff0000); 192 scorePlayerLeft = 0; 193 scorePlayerRight = 0; 194 break; 195 } 196 197 checkBallHitByPlayer(); 198 199 /* if ((curTime - lastAutoPlayerMoveTime) > 200) { 200 if (moveAutoPlayer()) { 201 lastAutoPlayerMoveTime = curTime; 202 } 203 }*/ 204 205 ballx += velocityx; 206 bally += velocityy; 207 208 checkBallOutOfBounds(); 209 for (byte i = 0; i < 12; i++) { 210 for (byte j = 0; j < 12; j++) { 211 leds[pgm_read_byte(&ledsAdress[i][j])] = 0x000000; 212 } 213 } 214 215 216 // Draw ball 217 leds[pgm_read_byte(&ledsAdress[ballx][bally])] = 0xffffff; 218 // Draw player left 219 for (int y = positionPlayerLeft - 3 / 2; y <= positionPlayerLeft + 3 / 2; ++y) { 220 leds[pgm_read_byte(&ledsAdress[0][y])] = 0x0000ff; 221 } 222 // Draw player right 223 for (int y = positionPlayerRight - 3 / 2; y <= positionPlayerRight + 3 / 2; ++y) { 224 leds[pgm_read_byte(&ledsAdress[12 - 1][y])] = 0xffff00; 225 } 226 227 FastLED.show(); 228 boolean dirChanged = false; 229 do { 230 if (menuValidation) { 231 pongRunning = false; 232 break; 233 } 234 readPointer(); 235 if (curControl != 'n' && !dirChanged) { //Can only change direction once per loop 236 dirChanged = true; 237 setPosition(); 238 } 239 curTime = millis(); 240 } 241 while ((curTime - prevUpdateTime) < 140); //Once enough time has passed, proceed. The lower this number, the faster the game is 242 prevUpdateTime = curTime; 243 } 244} 245 246 247
font.h
c_cpp
1/* uTFT Font library 2 * http://www.henningkarlsen.com/electronics/r_fonts.php 3 * 4 */ 5 6 7const unsigned char PROGMEM font[760] = 8{ 90x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // <Space> 100x18,0x3C,0x3C,0x18,0x18,0x00,0x18,0x00, // ! 110x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00, // " 120x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00, // # 130x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00, // $ 140x00,0xC6,0xCC,0x18,0x30,0x66,0xC6,0x00, // % 150x38,0x6C,0x38,0x76,0xDC,0xCC,0x76,0x00, // & 160x18,0x18,0x30,0x00,0x00,0x00,0x00,0x00, // ' 170x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00, // ( 180x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00, // ) 190x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00, // * 200x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00, // + 210x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30, // , 220x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00, // - 230x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00, // . 240x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00, // / 250x7C,0xC6,0xCE,0xD6,0xE6,0xC6,0x7C,0x00, // 0 260x18,0x38,0x18,0x18,0x18,0x18,0x7E,0x00, // 1 270x7C,0xC6,0x06,0x1C,0x30,0x66,0xFE,0x00, // 2 280x7C,0xC6,0x06,0x3C,0x06,0xC6,0x7C,0x00, // 3 290x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x1E,0x00, // 4 300xFE,0xC0,0xC0,0xFC,0x06,0xC6,0x7C,0x00, // 5 310x38,0x60,0xC0,0xFC,0xC6,0xC6,0x7C,0x00, // 6 320xFE,0xC6,0x0C,0x18,0x30,0x30,0x30,0x00, // 7 330x7C,0xC6,0xC6,0x7C,0xC6,0xC6,0x7C,0x00, // 8 340x7C,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00, // 9 350x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00, // : 360x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30, // ; 370x06,0x0C,0x18,0x30,0x18,0x0C,0x06,0x00, // < 380x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00, // = 390x60,0x30,0x18,0x0C,0x18,0x30,0x60,0x00, // > 400x7C,0xC6,0x0C,0x18,0x18,0x00,0x18,0x00, // ? 410x7C,0xC6,0xDE,0xDE,0xDE,0xC0,0x78,0x00, // @ 420x38,0x6C,0xC6,0xFE,0xC6,0xC6,0xC6,0x00, // A 430xFC,0x66,0x66,0x7C,0x66,0x66,0xFC,0x00, // B 440x3C,0x66,0xC0,0xC0,0xC0,0x66,0x3C,0x00, // C 450xF8,0x6C,0x66,0x66,0x66,0x6C,0xF8,0x00, // D 460xFE,0x62,0x68,0x78,0x68,0x62,0xFE,0x00, // E 470xFE,0x62,0x68,0x78,0x68,0x60,0xF0,0x00, // F 480x3C,0x66,0xC0,0xC0,0xCE,0x66,0x3A,0x00, // G 490xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00, // H 500x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // I 510x1E,0x0C,0x0C,0x0C,0xCC,0xCC,0x78,0x00, // J 520xE6,0x66,0x6C,0x78,0x6C,0x66,0xE6,0x00, // K 530xF0,0x60,0x60,0x60,0x62,0x66,0xFE,0x00, // L 540xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0x00, // M 550xC6,0xE6,0xF6,0xDE,0xCE,0xC6,0xC6,0x00, // N 560x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00, // O 570xFC,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00, // P 580x7C,0xC6,0xC6,0xC6,0xC6,0xCE,0x7C,0x0E, // Q 590xFC,0x66,0x66,0x7C,0x6C,0x66,0xE6,0x00, // R 600x7C,0xC6,0x60,0x38,0x0C,0xC6,0x7C,0x00, // S 610x7E,0x7E,0x5A,0x18,0x18,0x18,0x3C,0x00, // T 620xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00, // U 630xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x00, // V 640xC6,0xC6,0xC6,0xD6,0xD6,0xFE,0x6C,0x00, // W 650xC6,0xC6,0x6C,0x38,0x6C,0xC6,0xC6,0x00, // X 660x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00, // Y 670xFE,0xC6,0x8C,0x18,0x32,0x66,0xFE,0x00, // Z 680x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00, // [ 690xC0,0x60,0x30,0x18,0x0C,0x06,0x02,0x00, // <Backslash> 700x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00, // ] 710x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00, // ^ 720x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF, // _ 730x30,0x18,0x0C,0x00,0x00,0x00,0x00,0x00, // ' 740x00,0x00,0x78,0x0C,0x7C,0xCC,0x76,0x00, // a 750xE0,0x60,0x7C,0x66,0x66,0x66,0xDC,0x00, // b 760x00,0x00,0x7C,0xC6,0xC0,0xC6,0x7C,0x00, // c 770x1C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00, // d 780x00,0x00,0x7C,0xC6,0xFE,0xC0,0x7C,0x00, // e 790x3C,0x66,0x60,0xF8,0x60,0x60,0xF0,0x00, // f 800x00,0x00,0x76,0xCC,0xCC,0x7C,0x0C,0xF8, // g 810xE0,0x60,0x6C,0x76,0x66,0x66,0xE6,0x00, // h 820x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00, // i 830x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C, // j 840xE0,0x60,0x66,0x6C,0x78,0x6C,0xE6,0x00, // k 850x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // l 860x00,0x00,0xEC,0xFE,0xD6,0xD6,0xD6,0x00, // m 870x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x00, // n 880x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0x00, // o 890x00,0x00,0xDC,0x66,0x66,0x7C,0x60,0xF0, // p 900x00,0x00,0x76,0xCC,0xCC,0x7C,0x0C,0x1E, // q 910x00,0x00,0xDC,0x76,0x60,0x60,0xF0,0x00, // r 920x00,0x00,0x7E,0xC0,0x7C,0x06,0xFC,0x00, // s 930x30,0x30,0xFC,0x30,0x30,0x36,0x1C,0x00, // t 940x00,0x00,0xCC,0xCC,0xCC,0xCC,0x76,0x00, // u 950x00,0x00,0xC6,0xC6,0xC6,0x6C,0x38,0x00, // v 960x00,0x00,0xC6,0xD6,0xD6,0xFE,0x6C,0x00, // w 970x00,0x00,0xC6,0x6C,0x38,0x6C,0xC6,0x00, // x 980x00,0x00,0xC6,0xC6,0xC6,0x7E,0x06,0xFC, // y 990x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00, // z 1000x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00, // { 1010x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00, // | 1020x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00, // } 1030x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00, // ~ 104}; 105 106 107uint8_t charBuffer[8][8]; 108 109//Load char in buffer and return width in pixels 110uint8_t loadCharInBuffer(char letter) { 111 uint8_t* tmpCharPix; 112 uint8_t tmpCharWidth; 113 114 int letterIdx = (letter - 32) * 8; 115 116 int x = 0; int y = 0; 117 for (int idx = letterIdx; idx < letterIdx + 8; idx++) { 118 for (int x = 0; x < 8; x++) { 119 charBuffer[x][y] = ((pgm_read_byte(&font[idx])) & (1 << (7 - x))) > 0; 120 } 121 y++; 122 } 123 124 tmpCharWidth = 8; 125 return tmpCharWidth; 126} 127 128void printText(char* text, unsigned int textLength, int xoffset, int yoffset, unsigned long color) { 129 uint8_t curLetterWidth = 0; 130 int curX = xoffset; 131 clearImg(); 132 133 //Loop over all the letters in the string 134 for (int i = 0; i < textLength; i++) { 135 //Determine width of current letter and load its pixels in a buffer 136 curLetterWidth = loadCharInBuffer(text[i]); 137 //Loop until width of letter is reached 138 for (int lx = 0; lx < curLetterWidth; lx++) { 139 //Now copy column per column to field (as long as within the field 140 if (curX >= 12) { //If we are to far to the right, stop loop entirely 141 break; 142 } else if (curX >= 0) { //Draw pixels as soon as we are "inside" the drawing area 143 for (int ly = 0; ly < 8; ly++) { //Finally copy column 144 leds[pgm_read_byte(&ledsAdress[yoffset + ly][curX])] = charBuffer[lx][ly] * color; 145 146 } 147 } 148 curX++; 149 } 150 } 151 FastLED.show(); 152} 153//Scroll current selection text from right to left; 154void scrollText(char* curSelectionText, int curSelectionTextLength, unsigned long color ) { 155 for (int x = 12; x > -(curSelectionTextLength * 8); x--) { 156 printText(curSelectionText, curSelectionTextLength, x, 2, color); 157 delay(80); 158 } 159} 160 161
imgMario.h
arduino
1const unsigned long mushroom[12][12] PROGMEM = {{0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 2 {0x000000, 0x000000, 0x000000, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0x000000, 0x000000, 0x000000}, 3 {0x000000, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0x000000}, 4 {0x000000, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0x000000}, 5 {0xDF0202, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xDF0202}, 6 {0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202}, 7 {0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202, 0xDF0202}, 8 {0xDF0202, 0xDF0202, 0xFFFFFF, 0x000000, 0x000000, 0xFFFFFF, 0xFFFFFF, 0x000000, 0x000000, 0xFFFFFF, 0xDF0202, 0xDF0202}, 9 {0xDF0202, 0xFFFFFF, 0xFFFFFF, 0x000000, 0x000000, 0xFFFFFF, 0xFFFFFF, 0x000000, 0x000000, 0xFFFFFF, 0xFFFFFF, 0xDF0202}, 10 {0x000000, 0xFFFFFF, 0xFFFFFF, 0x000000, 0x000000, 0xFFFFFF, 0xFFFFFF, 0x000000, 0x000000, 0xFFFFFF, 0xFFFFFF, 0x000000}, 11 {0x000000, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0x000000}, 12 {0x000000, 0x000000, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0x000000, 0x000000} 13}; 14 15const unsigned long flower[12][12] PROGMEM = {{0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 16 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 17 {0x000000, 0x000000, 0x000000, 0xFC3205, 0xFC3205, 0xFC3205, 0xFC3205, 0xFC3205, 0xFC3205, 0x000000, 0x000000, 0x000000}, 18 {0x000000, 0x000000, 0xFC3205, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFC3205, 0x000000, 0x000000}, 19 {0x000000, 0xFC3205, 0xFAFE13, 0xFFFFFF, 0x000000, 0xFFFFFF, 0xFFFFFF, 0x000000, 0xFFFFFF, 0xFAFE13, 0xFC3205, 0x000000}, 20 {0x000000, 0xFC3205, 0xFAFE13, 0xFFFFFF, 0x000000, 0xFFFFFF, 0xFFFFFF, 0x000000, 0xFFFFFF, 0xFAFE13, 0xFC3205, 0x000000}, 21 {0x000000, 0x000000, 0xFC3205, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFC3205, 0x000000, 0x000000}, 22 {0x000000, 0x000000, 0x000000, 0xFC3205, 0xFC3205, 0xFC3205, 0xFC3205, 0xFC3205, 0xFC3205, 0x000000, 0x000000, 0x000000}, 23 {0x000000, 0x0DFC03, 0x0DFC03, 0x000000, 0x000000, 0x0DFC03, 0x0DFC03, 0x000000, 0x000000, 0x0DFC03, 0x0DFC03, 0x000000}, 24 {0x000000, 0x0DFC03, 0x0DFC03, 0x0DFC03, 0x000000, 0x0DFC03, 0x0DFC03, 0x000000, 0x0DFC03, 0x0DFC03, 0x0DFC03, 0x000000}, 25 {0x000000, 0x000000, 0x0DFC03, 0x0DFC03, 0x0DFC03, 0x0DFC03, 0x0DFC03, 0x0DFC03, 0x0DFC03, 0x0DFC03, 0x000000, 0x000000}, 26 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0DFC03, 0x0DFC03, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000} 27}; 28 29const unsigned long star[12][12] PROGMEM = {{0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 30 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 31 {0x000000, 0x000000, 0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000, 0x000000, 0x000000}, 32 {0x000000, 0x000000, 0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000, 0x000000, 0x000000}, 33 {0x000000, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0x000000}, 34 {0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0x000000, 0xFAFE13, 0xFAFE13, 0x000000, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000}, 35 {0x000000, 0x000000, 0x000000, 0xFAFE13, 0x000000, 0xFAFE13, 0xFAFE13, 0x000000, 0xFAFE13, 0x000000, 0x000000, 0x000000}, 36 {0x000000, 0x000000, 0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000, 0x000000, 0x000000}, 37 {0x000000, 0x000000, 0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000, 0x000000, 0x000000}, 38 {0x000000, 0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000, 0x000000}, 39 {0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000}, 40 {0x000000, 0xFAFE13, 0xFAFE13, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFAFE13, 0xFAFE13, 0x000000} 41}; 42 43 44const unsigned long beer[12][12] PROGMEM = {{0x020202, 0x020202, 0x020202, 0x020202, 0x020202, 0x020202, 0x020202, 0x020202, 0x020202, 0x020202, 0x020202, 0x020202}, 45 {0x000000, 0x000000, 0x000000, 0xBEBEBD, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xBEBEBD, 0x000000, 0x000000, 0x000000, 0x000000}, 46 {0x000000, 0x000000, 0x000000, 0xBEBEBD, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xBEBEBD, 0x000000, 0x000000, 0x000000, 0x000000}, 47 {0x000000, 0x000000, 0x000000, 0xB49C04, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xB49C04, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0x000000}, 48 {0x000000, 0x000000, 0x000000, 0xB49C04, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xB49C04, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0x000000}, 49 {0x000000, 0x000000, 0x000000, 0xB49C04, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xB49C04, 0x000000, 0x000000, 0xFFFFFF, 0x000000}, 50 {0x000000, 0x000000, 0x000000, 0xB49C04, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xB49C04, 0x000000, 0x000000, 0xFFFFFF, 0x000000}, 51 {0x000000, 0x000000, 0x000000, 0xB49C04, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xB49C04, 0x000000, 0x000000, 0xFFFFFF, 0x000000}, 52 {0x000000, 0x000000, 0x000000, 0xB49C04, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xB49C04, 0x000000, 0x000000, 0xFFFFFF, 0x000000}, 53 {0x000000, 0x000000, 0x000000, 0xB49C04, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xB49C04, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0x000000}, 54 {0x000000, 0x000000, 0x000000, 0xB49C04, 0xFAFE13, 0xFAFE13, 0xFAFE13, 0xA48E01, 0x000000, 0x000000, 0x000000, 0x000000}, 55 {0x000000, 0x000000, 0x000000, 0xB49C04, 0xB49C04, 0xB49C04, 0xB49C04, 0xB49C04, 0x000000, 0x000000, 0x000000, 0x000000} 56}; 57
Arduino main code
arduino
This file is the main code that run on the Arduino, it uses several home-made methods & functions to run games and other features. I'll upload them once the code is finished and bugless.
1/* 2 * 3 * Code by Antoine ROCHEBOIS : CC-BY-NC 4 * 5 * 6 * This file is the main code that run on the Arduino, it uses several 7 * home-made methods & functions to run games and other features, I'll * upload them once the code is finished and bugless. 8 * 9 * 10 * 11 * */ 12#include "FastLED.h" 13#include <avr/pgmspace.h> 14#include <SoftwareSerial.h> 15 16#include "imgMario.h" //Import 2D array of 32bits int provinding the RGB 17#include "imgMenu.h" //code for each image of the Menu and Images function 18 19#define M_PIN 2 //Pin for the menuInterrupt 20#define R1_PIN 8 // 21#define L1_PIN 9 // Digital inputs used by arcade buttons (side) 22#define R2_PIN 6 // 23#define L2_PIN 7 // 24#define DATA_PIN 5 //Data PIN for the led matrix 25 26#define COLOR_ORDER GRB // if colors are mismatched; change this 27#define NUM_LEDS 144 // 12*12=144 leds in the strip 28#define LED_TYPE WS2812B 29// this creates an LED array to hold the values for each led in your strip 30CRGB leds[NUM_LEDS]; 31 32const PROGMEM byte ledsAdress[12][12] = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 33 {23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12}, 34 {24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35}, 35 {47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36}, 36 {48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, 37 {71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60}, 38 {72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83}, 39 {95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84}, 40 {96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107}, 41 {119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108}, 42 {120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131}, 43 {143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132} 44}; //Adress of each led in the matrix (Progmem means stored in FLASH instead //of SRAM) 45 46SoftwareSerial BT(10, 11); //Emulates an Serial BT terminal 47 48boolean grid[12][12]; //(used in a game, ignore) 49char message; //char read on the BT terminal 50char curControl; //current control ID 51int menuPointer = 0; //Position in the menu 52volatile bool menuValidation = 0; //Variable set to true when the menu switch 53//is pushed 54 55unsigned long curTime; 56unsigned long prevUpdateTime = 0; //Variables for timed events 57unsigned long prevButtonTime = 0; 58 59//Function executed when the user push the menuButton (set menuValidation to 60//true + debounce input) 61void menuInterrupt() { 62 static unsigned long last_interrupt_time = 0; 63 unsigned long interrupt_time = millis(); 64 if (interrupt_time - last_interrupt_time > 200) { 65 menuValidation = true; 66 } 67 last_interrupt_time = interrupt_time; 68} 69 70//Displays static images stocked in FLASH, if roll == 1, draws it whith a fancy red line 71void setImg(const unsigned long frame[12][12], bool roll) { 72 if (!roll) { 73 for (byte i = 0; i < 12; i++) { 74 for (byte j = 0; j < 12; j++) { 75 leds[pgm_read_byte(&ledsAdress[i][j])] = pgm_read_dword(&frame[i][j]); 76 } 77 } 78 FastLED.show(); 79 80 } else { 81 for (uint8_t i = 11; i > 0; i--) { 82 for (byte j = 0; j < 12; j++) { 83 if (i > 0) { 84 leds[pgm_read_byte(&ledsAdress[i][j])] = 0xe22c79; 85 } else { 86 leds[pgm_read_byte(&ledsAdress[i][j])] = pgm_read_dword(&frame[i][j]); 87 } 88 89 leds[pgm_read_byte(&ledsAdress[(i + 13) % 12][j])] = pgm_read_dword(&frame[(i + 13) % 12][j]); 90 } 91 FastLED.show(); 92 delay(70); 93 } 94 } 95 96 97} 98 99//Erase the screen with a red sweeping line 100void resetImg() { 101 for (byte i = 0; i < 12; i++) { 102 for (byte j = 0; j < 12; j++) { 103 leds[pgm_read_byte(&ledsAdress[i][j])] = 0xe22c79; 104 if (i > 0) { 105 leds[pgm_read_byte(&ledsAdress[(i + 11) % 12][j])] = 0x000000; 106 } 107 108 } 109 FastLED.show(); 110 delay(70); 111 } 112} 113//Erase the screen by fading it 114void fadeImg() { 115 for (uint8_t i = 128; i > 0; i = i - 4) { 116 FastLED.setBrightness(i); 117 FastLED.show(); 118 delay(24); 119 } 120 delay(250); 121 FastLED.setBrightness(128); 122} 123//Instant erase of the screen 124void clearImg() { 125 for (byte dim1 = 0; dim1 < 12; dim1++) { 126 for (byte dim2 = 0; dim2 < 12; dim2++) { 127 leds[pgm_read_byte(&ledsAdress[dim1][dim2])] = 0x000000; 128 } 129 } 130} 131 132 133//Read inputs (BT + digital IO) 134void readPointer() { 135 136 //Read BT (hc-05 module) 137 while (BT.available() > 0) { 138 message = BT.read(); 139 } 140 //Changes control variables 141 if (message == 'q' ) { 142 --menuPointer; 143 curControl = 'q'; 144 } else if (message == 'd') { 145 ++menuPointer; 146 curControl = 'd'; 147 } else if (message == 'z') { 148 curControl = 'z'; 149 } else if (message == 's') { 150 curControl = 's'; 151 } else if (message == 'a') { 152 curControl = 'a'; 153 } else if (message == 'y') { 154 menuValidation = true; 155 } 156 message = 'n'; //Reset message 157 158 //Read digital IO pins 159 if (!digitalRead(L1_PIN)) { 160 if ( (millis() - prevButtonTime) > 150) { 161 curControl = 'q'; 162 --menuPointer; 163 prevButtonTime = millis(); 164 } 165 } else if (!digitalRead(R1_PIN)) { 166 if ( (millis() - prevButtonTime) > 150) { 167 curControl = 'd'; 168 ++menuPointer; 169 prevButtonTime = millis(); 170 } 171 } else if (!digitalRead(L2_PIN)) { 172 if ( (millis() - prevButtonTime) > 150) { 173 curControl = 'z'; 174 --menuPointer; 175 prevButtonTime = millis(); 176 } 177 } else if (!digitalRead(l2_PIN)) { 178 if ( (millis() - prevButtonTime) > 150) { 179 curControl = 's'; 180 ++menuPointer; 181 prevButtonTime = millis(); 182 } 183 } 184 185} 186 187#include "gameOfLife.h" //Include features and games methods and functions 188#include "snake.h" 189#include "pong.h" 190#include "tetris.h" 191#include "bottle.h" 192#include "decoration.h" 193#include "font.h" 194 195 196 197 198 199 200 201/* 202* 203* RUN AT STARTUP 204* 205*/ 206 207void setup() { 208 //Setup the BT connection 209 BT.begin(9600); 210 211 //Setup the IO pin (Inputs with a built-in pull-up resistor or interupt) 212 pinMode(R1_PIN, INPUT_PULLUP); 213 pinMode(L1_PIN, INPUT_PULLUP); 214 pinMode(R2_PIN, INPUT_PULLUP); 215 pinMode(L2_PIN, INPUT_PULLUP); 216 attachInterrupt(digitalPinToInterrupt(M_PIN), menuInterrupt, FALLING); 217 218 //Setup the Led strip 219 FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); 220 221 //Intro animation (display a beer and load the menu) 222 FastLED.setBrightness(0); 223 setImg(beer, 0); 224 delay(250); 225 for (uint8_t i = 0; i <= 128; i = i + 4) { 226 FastLED.setBrightness(i); 227 FastLED.show(); 228 delay(42); 229 } 230 delay(2400); 231 fadeImg(); 232 clearImg(); 233 FastLED.show(); 234 delay(250); 235 setImg(menuTetris, 1); 236 237} 238 239 240 241 242 243 244 245 246/* 247* 248* RUN PERPETUALY 249* 250*/ 251void loop() { 252 253//Menu Interface and games/features launcher 254 switch ((menuPointer + 12000) % 12) { 255 case 0: 256 setImg(menuTetris, 0); 257 while ((menuPointer + 12000) % 12 == 0 && !menuValidation) { 258 readPointer(); 259 } 260 if (menuValidation) { 261 menuValidation = false; 262 while (!menuValidation) { 263 launchTetris(); //Tetris game 264 } 265 menuValidation = false; 266 menuPointer = 0; 267 resetImg(); 268 setImg(menuTetris, 1); 269 } 270 break; 271 case 1: 272 setImg(menuSimon, 0); 273 while ((menuPointer + 12000) % 12 == 1 && !menuValidation) { 274 readPointer(); 275 } 276 if (menuValidation) { 277 menuValidation = false; //Displays a cross : feature not implemented yet 278 setImg(menuError, 0); 279 delay(1250); 280 menuPointer = 1; 281 resetImg(); 282 setImg(menuSimon, 1); 283 } 284 break; 285 case 2: 286 setImg(menuPong, 0); 287 while ((menuPointer + 12000) % 12 == 2 && !menuValidation) { 288 readPointer(); 289 } 290 if (menuValidation) { 291 menuValidation = false; 292 while (!menuValidation) { 293 launchPong(); //Pong game for 2 players 294 } 295 menuValidation = false; 296 menuPointer = 2; 297 resetImg(); 298 setImg(menuPong, 1); 299 } 300 break; 301 case 3: 302 setImg(menuSnake, 0); 303 while ((menuPointer + 12000) % 12 == 3 && !menuValidation) { 304 readPointer(); 305 } 306 if (menuValidation) { 307 menuValidation = false; 308 while (!menuValidation) { 309 launchSnake(); //Snake game 310 } 311 menuValidation = false; 312 menuPointer = 3; 313 resetImg(); 314 setImg(menuSnake, 1); 315 } 316 break; 317 case 4: 318 setImg(menuBottle, 0); 319 while ((menuPointer + 12000) % 12 == 4 && !menuValidation) { 320 readPointer(); 321 } 322 if (menuValidation) { 323 menuValidation = false; 324 while (!menuValidation) { 325 bottle(); //A wheel that stops on a random location on the screen 326 } 327 menuValidation = false; 328 menuPointer = 4; 329 resetImg(); 330 setImg(menuBottle, 1); 331 } 332 break; 333 case 5: 334 setImg(menuGameOfLife, 0); 335 while ((menuPointer + 12000) % 12 == 5 && !menuValidation) { 336 readPointer(); 337 } 338 if (menuValidation) { 339 menuValidation = false; 340 while (!menuValidation) { 341 gameOfLife(); //Run conway's game of life 342 } 343 menuValidation = false; 344 menuPointer = 5; 345 resetImg(); 346 setImg(menuGameOfLife, 1); 347 } 348 break; 349 case 6: 350 setImg(menuParty, 0); 351 while ((menuPointer + 12000) % 12 == 6 && !menuValidation) { 352 readPointer(); 353 } 354 if (menuValidation) { 355 menuValidation = false; 356 while (!menuValidation) { 357 launchManualAnimations(); //Visual animation (choice) 358 } 359 menuValidation = false; 360 menuPointer = 6; 361 resetImg(); 362 setImg(menuParty, 1); 363 } 364 break; 365 case 7: 366 setImg(menuParty, 0); 367 while ((menuPointer + 12000) % 12 == 7 && !menuValidation) { 368 readPointer(); 369 } 370 if (menuValidation) { 371 menuValidation = false; 372 while (!menuValidation) { 373 launchRandomAnimations(); //Launch random visual animation 374 } 375 menuValidation = false; 376 menuPointer = 7; 377 resetImg(); 378 setImg(menuParty, 1); 379 } 380 break; 381 case 8: 382 setImg(menuImage, 0); 383 while ((menuPointer + 12000) % 12 == 8 && !menuValidation) { 384 readPointer(); 385 } 386 if (menuValidation) { 387 menuValidation = false; 388 while (!menuValidation) { 389 launchManualImage(); //Images manual selection 390 } 391 menuValidation = false; 392 menuPointer = 8; 393 resetImg(); 394 setImg(menuImage, 1); 395 } 396 break; 397 case 9: 398 setImg(menuImage, 0); 399 while ((menuPointer + 12000) % 12 == 9 && !menuValidation) { 400 readPointer(); 401 } 402 if (menuValidation) { 403 menuValidation = false; 404 while (!menuValidation) { 405 launchRandomImage(); //Images random selection 406 } 407 menuValidation = false; 408 menuPointer = 9; 409 resetImg(); 410 setImg(menuImage, 1); 411 } 412 break; 413 case 10: 414 setImg(menuText, 0); 415 while ((menuPointer + 12000) % 12 == 10 && !menuValidation) { 416 readPointer(); 417 } 418 if (menuValidation) { 419 menuValidation = false; 420 while (!menuValidation) { 421 scrollText("Hi!",3, 0xff0000); //Scrolls a defined text on the screen TODO: BT defined text & color 422 } 423 menuValidation = false; 424 menuPointer = 10; 425 resetImg(); 426 setImg(menuText, 1); 427 } 428 break; 429 case 11: 430 setImg(menuSpectrum, 0); 431 while ((menuPointer + 12000) % 12 == 11 && !menuValidation) { 432 readPointer(); 433 } 434 if (menuValidation) { //Spectrum Analyzer code is too heavy for the FLASH/SRAM, needs a specific upload to run. Displays an error message 435 menuValidation = false; 436 setImg(menuError, 0); 437 delay(1250); 438 scrollText("Connect USB",11, 0xff0000); 439 menuPointer = 11; 440 resetImg(); 441 setImg(menuSpectrum, 1); 442 } 443 break; 444 } 445 446} 447 448
snake.h
arduino
1byte curLength;//Curren length of snake 2int xs[127];//Array containing all snake segments, 3int ys[127];// max snake length is array length 4char dir;//Current Direction of snake 5 6boolean snakeGameOver; 7 8byte ax = 0;//Apple x position 9byte ay = 0;//Apple y position 10 11void snakeInit() { 12 //Snake start position and direction & initialise variables 13 curLength = 3; 14 xs[0] = 3; 15 xs[1] = 2; 16 xs[2] = 1; 17 ys[0] = 12 / 2; 18 ys[1] = 12 / 2; 19 ys[2] = 12 / 2; 20 dir = 'd'; 21 //Generate random apple position 22 ax = random(0, 11); 23 ay = random(0, 11); 24 25 snakeGameOver = false; 26} 27/* Set direction from current button state */ 28void setDirection() { 29 readPointer(); 30 switch (curControl) { 31 case 'q': 32 dir = 'z'; 33 break; 34 case 'd': 35 dir = 's'; 36 break; 37 case 's': 38 dir = 'd'; 39 break; 40 case 'z': 41 dir = 'q'; 42 break; 43 } 44} 45 46/* Ending, show score */ 47void die() { 48 snakeGameOver = true; 49 fadeImg(); 50} 51 52/* Collision detection function */ 53boolean collide(int x1, int x2, int y1, int y2, int w1, int w2, int h1, int h2) { 54 if ((x1 + w1 > x2) && (x1 < x2 + w2) && (y1 + h1 > y2) && (y1 < y2 + h2)) { 55 return true; 56 } else { 57 return false; 58 } 59} 60 61void runSnake() { 62 snakeInit(); 63 prevUpdateTime = 0; 64 boolean snakeRunning = true; 65 while (snakeRunning) { 66 //Check self-collision with snake 67 int i = curLength - 1; 68 while (i >= 2) { 69 if (collide(xs[0], xs[i], ys[0], ys[i], 1, 1, 1, 1)) { 70 die(); 71 } 72 i = i - 1; 73 } 74 75 if (snakeGameOver) { 76 snakeRunning = false; 77 break; 78 } 79 80 //Check collision of snake head with apple 81 if (collide(xs[0], ax, ys[0], ay, 1, 1, 1, 1)) { 82 //Increase score and snake length; 83 curLength = curLength + 1; 84 //Add snake segment with temporary position of new segments 85 xs[curLength - 1] = 255; 86 ys[curLength - 1] = 255; 87 88 //Generate new apple position 89 ax = random(0, 11); 90 ay = random(0, 11); 91 92 for (int j = 0; j < curLength; j++) { 93 if (collide(ax, xs[j], ay, ys[j], 1, 1, 1, 1)) { 94 ax = random(0, 11); 95 ay = random(0, 11); 96 j = 0; //ICI 97 } 98 } 99 } 100 101 //Shift snake position array by one 102 i = curLength - 1; 103 while (i >= 1) { 104 xs[i] = xs[i - 1]; 105 ys[i] = ys[i - 1]; 106 i = i - 1; 107 } 108 //Determine new position of head of snake 109 if (dir == 'd') { 110 xs[0] = xs[0] + 1; 111 } else if (dir == 'q') { 112 xs[0] = xs[0] - 1; 113 } else if (dir == 'z') { 114 ys[0] = ys[0] - 1; 115 } else {//DOWN 116 ys[0] = ys[0] + 1; 117 } 118 119 //Check if outside playing field 120 if ((xs[0] < 0) || (xs[0] >= 12) || (ys[0] < 0) || (ys[0] >= 12)) { 121 if (xs[0] < 0) { 122 xs[0] = 12 - 1; 123 } else if (xs[0] >= 12) { 124 xs[0] = 0; 125 } else if (ys[0] < 0) { 126 ys[0] = 12 - 1; 127 } else if (ys[0] >= 12) { 128 ys[0] = 0; 129 } 130 } 131 132 for (int j = 0; j < 144; j++) { 133 leds[j] = 0x000000; 134 135 } 136 137 //Draw apple 138 leds[pgm_read_byte(&ledsAdress[ax][ay])] = 0xFF0000; 139 140 //Draw snake 141 for (int j = 0; j < curLength; j++) { 142 leds[pgm_read_byte(&ledsAdress[xs[j]] [ys[j]])] = 0x388FEC; 143 } 144 145 FastLED.show(); 146 147 //Check buttons and set snake movement direction while we are waiting to draw the next move 148 curTime = 0; 149 boolean dirChanged = false; 150 do { 151 if (menuValidation) { 152 snakeRunning = false; 153 break; 154 } 155 if (curControl != 'n' && !dirChanged) {//Can only change direction once per loop 156 dirChanged = true; 157 setDirection(); 158 } 159 curTime = millis(); 160 } while ((curTime - prevUpdateTime) < 200);//Once enough time has passed, proceed. The lower this number, the faster the game is 161 prevUpdateTime = curTime; 162 } 163 164 165} 166 167 168
decoration.h
c_cpp
1/*void fillingScreen() { 2 int iterations = 0; 3 while (!menuValidation && iterations < 400) { 4 byte c[3]; 5 for (byte i = 0; i < 3; i++) { 6 c[i] = random(0, 256); 7 } 8 for (byte i = 0; i < 12; i++) { 9 for (byte j = 0; j < 12; j++) { 10 leds[pgm_read_byte(&ledsAdress[i][j])] = (( (c[0])) << 16) + ( (c[1]) << 8) + ( (c[2])); 11 FastLED.show(); 12 delay(25); 13 iterations++; 14 } 15 } 16 } 17} 18 19void fadingScreen() { 20 int iterations = 0; 21 while (!menuValidation && iterations < 400) { 22 byte c[3]; 23 for (byte i = 0; i < 3; i++) { 24 c[i] = random(0, 256); 25 } 26 for (byte k = 0; k < 128; k = k + 2) { 27 for (byte i = 0; i < 12; i++) { 28 for (byte j = 0; j < 12; j++) { 29 leds[pgm_read_byte(&ledsAdress[i][j])] = (( (c[0])) << 16) + ( (c[1]) << 8) + ( (c[2])); 30 } 31 32 } 33 iterations++; 34 FastLED.setBrightness(k); 35 FastLED.show(); 36 delay(50); 37 } 38 for (uint8_t k = 128; k > 0; k = k - 2) { 39 for (byte i = 0; i < 12; i++) { 40 for (byte j = 0; j < 12; j++) { 41 leds[pgm_read_byte(&ledsAdress[i][j])] = (( (c[0])) << 16) + ( (c[1]) << 8) + ( (c[2])); 42 } 43 44 } 45 iterations++; 46 FastLED.setBrightness(k); 47 FastLED.show(); 48 delay(50); 49 } 50 51 } 52 clearImg(); 53 FastLED.setBrightness(128); 54}*/ 55void crossingSnakes() { 56 for (byte i = 0; i < 144; i++) { 57 for (byte j = 0; j < 5; j++) { 58 leds[(i + j + 0) % 144] = 0xff0000; 59 leds[(i + j + 12) % 144] = 0xffff00; 60 leds[(i + j + 23) % 144] = 0x00ff00; 61 leds[(i + j + 36) % 144] = 0x00ffff; 62 leds[(i + j + 48) % 144] = 0x0000ff; 63 leds[(i + j + 59) % 144] = 0xff00ff; 64 leds[(i + j + 72) % 144] = 0xff0000; 65 leds[(i + j + 84) % 144] = 0xffff00; 66 leds[(i + j + 95) % 144] = 0x00ff00; 67 leds[(i + j + 107) % 144] = 0x00ffff; 68 leds[(i + j + 120) % 144] = 0x0000ff; 69 leds[(i + j + 134) % 144] = 0xff00ff; 70 } 71 FastLED.show(); 72 delay(85); 73 clearImg(); 74 if (menuValidation) break; 75 } 76} 77 78 79/*public void rainingStars(Panel p) { 80 int iterations = 0; 81 while (!TableLED.menuValidation && iterations < 400) { 82 83 int img[][] = new int[12][12]; 84 int color[][] = new int[12][12]; 85 boolean stars[][] = new boolean[12][12]; 86 for (int i = 0; i < stars.length; i++) { 87 for (int j = 0; j < stars[i].length; j++) { 88 if (Math.random() < 0.035) { 89 stars[i][j] = true; 90 color[i][j] = (int) (Math.random() * 4); 91 } 92 } 93 } 94 for (int k = 0; k < 256; k = k + 4) { 95 try { 96 Thread.sleep(50); 97 } catch (InterruptedException e) { 98 e.printStackTrace(); 99 } 100 iterations++; 101 for (int i = 0; i < stars.length; i++) { 102 for (int j = 0; j < stars[i].length; j++) { 103 if (stars[i][j]) { 104 105 switch (color[i][j]) { 106 case 0: 107 img[i][j] = (((int) (0.2 * k)) << 16) + ((int) (0.32 * k) << 8) + ((int) (0.7 * k)); 108 break; 109 case 1: 110 img[i][j] = (((int) (0.28 * k)) << 16) + ((int) (0.463 * k) << 8) + k; 111 break; 112 case 2: 113 img[i][j] = (k << 16) + ((int) (0.757 * k) << 8) + ((int) (0.146 * k)); 114 break; 115 default: 116 img[i][j] = (((int) (0.27 * k)) << 16) + ((int) (0.118 * k) << 8) + ((int) (0.44 * k)); 117 break; 118 } 119 120 } 121 } 122 } 123 p.setFrame(img); 124 } 125 } 126 }*/ 127 128 129 130/*void decoration() { 131 132 byte r = random(0, 6); 133 readPointer(); 134 switch (r) { 135 case 0: 136 crossingSnakes(); 137 break; 138 case 1: 139 glitchRainingStars(); 140 break; 141 case 2: 142 rainingStars(); 143 break; 144 case 3: 145 fadingScreen(); 146 break; 147 case 4: 148 bottleAnimation(60, 334); 149 default: 150 fillingScreen(); 151 break; 152 } 153 154}*/ 155
imgMenu.h
arduino
1const unsigned long PROGMEM menuError[12][12] = {{0xEF3101, 0xED2D01, 0x040100, 0x040100, 0x000000, 0x000000, 0x000000, 0x000000, 0x040100, 0x040100, 0xEB2801, 0xED2C01}, 2 {0xED2C01, 0xEB2701, 0xE92202, 0x040100, 0x040100, 0x000000, 0x000000, 0x040100, 0x040100, 0xE81F02, 0xEA2301, 0xEB2701}, 3 {0x040100, 0xE92202, 0xE81E01, 0xE61A01, 0x040000, 0x040000, 0x040000, 0x040000, 0xE61601, 0xE61A02, 0xE71D02, 0x040100}, 4 {0x040100, 0x040100, 0xE61901, 0xE51501, 0xE31101, 0x040000, 0x040000, 0xE20F01, 0xE41202, 0xE51501, 0x040100, 0x040100}, 5 {0x000000, 0x040000, 0x040000, 0xE31102, 0xE20D02, 0xE10A02, 0xE00902, 0xE10B02, 0xE20D02, 0x040000, 0x040000, 0x000000}, 6 {0x000000, 0x000000, 0x040000, 0x040000, 0xE10B01, 0xDF0701, 0xDF0602, 0xE00702, 0x040000, 0x040000, 0x000000, 0x000000}, 7 {0x000000, 0x000000, 0x040000, 0x040000, 0xE10902, 0xDF0502, 0xDE0202, 0xDF0501, 0x040000, 0x040000, 0x000000, 0x000000}, 8 {0x000000, 0x040000, 0x040000, 0xE30F02, 0xE10A02, 0xE00702, 0xE00502, 0xE00701, 0xE10A02, 0x040000, 0x040000, 0x000000}, 9 {0x040100, 0x040000, 0xE61601, 0xE41102, 0xE20D02, 0x040000, 0x040000, 0xE10B02, 0xE20D02, 0xE41101, 0x040000, 0x040100}, 10 {0x040100, 0xE81F01, 0xE71A01, 0xE51501, 0x040000, 0x040000, 0x040000, 0x040000, 0xE31202, 0xE51502, 0xE61A01, 0x040100}, 11 {0xEB2801, 0xEA2301, 0xE81E01, 0x040000, 0x040000, 0x000000, 0x000000, 0x040000, 0x040000, 0xE71A01, 0xE81D01, 0xEA2301}, 12 {0xED2C01, 0xEB2801, 0x040100, 0x040000, 0x000000, 0x000000, 0x000000, 0x000000, 0x040000, 0x040000, 0xE92202, 0xEB2701} 13}; 14 15const unsigned long PROGMEM menuGameOfLife[12][12] = {{0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x00FF00, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 16 17 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 18 {0xb2a24, 0x2cb194, 0xe281f, 0xc2720, 0xb261f, 0xb241e, 0x8231e, 0xa231f, 0x258d76, 0x8211d, 0x91e19, 0x91e19}, 19 {0xb2823, 0xb2823, 0xa2723, 0x92621, 0x27a285, 0x7251d, 0x25977e, 0x7221d, 0x9201a, 0x9201a, 0x1e7f6b, 0x81b17}, 20 {0x2bb292, 0x2aac90, 0x7281f, 0x27a486, 0xa231f, 0xc231b, 0xa2117, 0x238a75, 0x91f1c, 0x81d18, 0x91c1a, 0x1d775e}, 21 {0x2aad8d, 0xc261d, 0xc251f, 0x9241d, 0x92320, 0xb211e, 0x228c76, 0x23876f, 0x91e19, 0x1e7b68, 0x81b17, 0x71a18}, 22 {0x29aa8e, 0x27a387, 0x8261c, 0xc221f, 0x21967b, 0x248e77, 0x228a73, 0x1f826e, 0x1e7d67, 0x71c15, 0x71a16, 0x1d6c59}, 23 {0xc2521, 0x26a286, 0x269b81, 0x28967d, 0x8211b, 0xa211b, 0x218470, 0xa1d19, 0x91c1a, 0x71c17, 0x81815, 0x61915}, 24 {0xa2520, 0xa231f, 0x25977d, 0x9221c, 0x248a75, 0x1f8770, 0xa1f1a, 0x71c17, 0x81b17, 0x1d6e5b, 0x1a6956, 0x196251}, 25 {0xa2520, 0x25977d, 0x8231c, 0x7221b, 0x92018, 0x22816d, 0x1f7c69, 0x1c7563, 0x91916, 0x61915, 0x196352, 0x71613}, 26 {0x259a7f, 0x8231e, 0x8211b, 0x91f1c, 0x20836e, 0x91e17, 0x71c17, 0x91916, 0x1a6b5a, 0x1a6455, 0x81712, 0x61512}, 27 {0xb211e, 0x82219, 0x228974, 0x22836f, 0x1e7f6b, 0x1d7962, 0x71b19, 0x1b6c59, 0x1a6755, 0x186150, 0x175b4c, 0x514f} 28}; 29 30const unsigned long PROGMEM menuPong[12][12] = {{0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 31 32 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 33 {0x000000, 0x000000, 0xFF0000, 0xFF0000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 34 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 35 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 36 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 37 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 38 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 39 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 40 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 41 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 42 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0xFF0000, 0xFF0000, 0x000000, 0x000000} 43}; 44 45 46const unsigned long PROGMEM menuTetris[12][12] = {{0x00a651, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 47 48 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 49 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 50 {0x000000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 51 {0x000000, 0x000000, 0x000000, 0xFF0000, 0xFF0000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 52 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 53 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0xFF0000, 0x000000, 0x000000}, 54 {0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0xFF0000, 0x4DBB2E, 0x000000}, 55 {0xFF0000, 0xFF0000, 0x4DBB2E, 0x4DBB2E, 0x000000, 0x000000, 0xD4BD0D, 0xD4BD0D, 0xD4BD0D, 0x4DBB2E, 0x4DBB2E, 0xFF0000}, 56 {0xFF0000, 0x0DA5D4, 0x4DBB2E, 0x4DBB2E, 0xFF0000, 0x000000, 0x4DBB2E, 0xD4BD0D, 0x0DA5D4, 0x0DA5D4, 0x4DBB2E, 0xFF0000}, 57 {0x0DA5D4, 0x0DA5D4, 0x0DA5D4, 0x000000, 0xFF0000, 0x4DBB2E, 0x4DBB2E, 0x000000, 0x0DA5D4, 0xD4BD0D, 0xD4BD0D, 0xFF0000}, 58 {0xD4BD0D, 0xD4BD0D, 0xD4BD0D, 0xD4BD0D, 0xFF0000, 0xFF0000, 0x4DBB2E, 0x000000, 0x0DA5D4, 0xD4BD0D, 0xD4BD0D, 0xFF0000} 59}; 60 61 62const unsigned long PROGMEM menuSnake[12][12] = {{0x000000, 0x000000, 0x000000, 0xF26522, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 63 64 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 65 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 66 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 67 {0x388FEC, 0x388FEC, 0x000000, 0xFF0000, 0x000000, 0x388FEC, 0x388FEC, 0x388FEC, 0x000000, 0x000000, 0x388FEC, 0x388FEC}, 68 {0x000000, 0x388FEC, 0x000000, 0x000000, 0x000000, 0x388FEC, 0x000000, 0x388FEC, 0x000000, 0x000000, 0x388FEC, 0x000000}, 69 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x388FEC, 0x000000, 0x388FEC, 0x388FEC, 0x388FEC, 0x388FEC, 0x000000}, 70 {0x000000, 0x000000, 0x388FEC, 0x000000, 0x000000, 0x388FEC, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 71 {0x000000, 0x000000, 0x388FEC, 0x000000, 0x000000, 0x388FEC, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 72 {0x000000, 0x000000, 0x388FEC, 0x388FEC, 0x388FEC, 0x388FEC, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 73 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 74 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000} 75}; 76 77const unsigned long PROGMEM menuSimon[12][12] = 78{{0x000000, 0x388FEC, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 79 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 80 {0xFFF202, 0xFFF202, 0xFFF20C, 0xFFF202, 0xFFF202, 0x000000, 0x000000, 0xFF0202, 0xFF191A, 0xFF2727, 0xFF1A1A, 0xFF0202}, 81 {0xFFF202, 0xFFF234, 0xFFF257, 0xFFF235, 0xFFF202, 0x000000, 0x000000, 0xFF191A, 0xFF4C4C, 0xFF6767, 0xFF4C4C, 0xFF1A19}, 82 {0xFFF20C, 0xFFF257, 0xFFF898, 0xFFF257, 0xFFF20C, 0x000000, 0x000000, 0xFF2727, 0xFF6767, 0xFF9797, 0xFF6767, 0xFF2726}, 83 {0xFFF202, 0xFFF235, 0xFFF257, 0xFFF234, 0xFFF202, 0x000000, 0x000000, 0xFF1919, 0xFF4C4C, 0xFF6767, 0xFF4C4C, 0xFF1A19}, 84 {0xFFF202, 0xFFF202, 0xFFF20C, 0xFFF202, 0xFFF202, 0x000000, 0x000000, 0xFF0202, 0xFF1A19, 0xFF2626, 0xFF1A1A, 0xFF0202}, 85 {0x34BA20, 0x34BA20, 0x34BA20, 0x34BA20, 0x34BA20, 0x000000, 0x000000, 0x2760B9, 0x4360B9, 0x4F68B9, 0x4360B9, 0x2760B9}, 86 {0x34BA20, 0x48BA40, 0x6BBA63, 0x48BA41, 0x34BA20, 0x000000, 0x000000, 0x4360B9, 0x6D87B9, 0x819ABE, 0x6D86B9, 0x4360B9}, 87 {0x34BA20, 0x6BBA63, 0xACE2A4, 0x6BBA63, 0x34BA20, 0x000000, 0x000000, 0x4F68B9, 0x819ABE, 0xA4BEE1, 0x819BBE, 0x4F68B9}, 88 {0x34BA20, 0x49BA40, 0x6BBA63, 0x48BA41, 0x34BA20, 0x000000, 0x000000, 0x4360B9, 0x6D86B9, 0x819BBE, 0x6D86B9, 0x4360B9}, 89 {0x34BA20, 0x34BA20, 0x34BA20, 0x34BA20, 0x34BA20, 0x000000, 0x000000, 0x2760B9, 0x4360B9, 0x4F68B9, 0x4360B9, 0x2760B9} 90}; 91 92 93const unsigned long PROGMEM menuBottle[12][12] = 94{{0x000000, 0x000000, 0x000000, 0x000000, 0xFFF200, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 95 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 96 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 97 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x02F900, 0x0EFA00, 0x1FFB01}, 98 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x33FC01, 0x41FE00, 0x4BFE00}, 99 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x7BFF02, 0x7AFE02, 0x79FF01}, 100 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 101 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 102 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 103 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 104 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 105 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000} 106}; 107 108 109 110const unsigned long PROGMEM menuParty[12][12] = {{0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x960055, 0x960055, 0x000000, 0x000000, 0x000000, 0x000000}, 111 112 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 113 {0x00A651, 0x00A651, 0x00A651, 0x00A651, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x00A651, 0x00A651}, 114 {0xEC008C, 0xEC008C, 0xEC008C, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xEC008C, 0xEC008C, 0xEC008C}, 115 {0xF7941D, 0xF7941D, 0xF7941D, 0xF7941D, 0xF7941D, 0xF7941D, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 116 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x00AEEF, 0x00AEEF, 0x00AEEF, 0x00AEEF, 0x00AEEF, 0x00AEEF, 0x000000}, 117 {0xFFF200, 0xFFF200, 0xFFF200, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFFF200, 0xFFF200, 0xFFF200}, 118 {0x000000, 0x000000, 0xED1C24, 0xED1C24, 0xED1C24, 0xED1C24, 0xED1C24, 0xED1C24, 0x000000, 0x000000, 0x000000, 0x000000}, 119 {0x2E3192, 0x2E3192, 0x2E3192, 0x2E3192, 0x2E3192, 0x2E3192, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 120 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x00A651, 0x00A651, 0x00A651, 0x00A651, 0x00A651, 0x00A651}, 121 {0x000000, 0x000000, 0x000000, 0xF7941D, 0xF7941D, 0xF7941D, 0xF7941D, 0xF7941D, 0xF7941D, 0x000000, 0x000000, 0x000000}, 122 {0xEC008C, 0xEC008C, 0xEC008C, 0xEC008C, 0xEC008C, 0xEC008C, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000} 123}; 124 125const unsigned long PROGMEM menuImage[12][12] = {{0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0xFF0000, 0x000000, 0x000000}, 126 127 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 128 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 129 {0x000000, 0xAC8255, 0xFBBD7B, 0xE8AF72, 0xE8AF72, 0xE8AF72, 0xE8AF72, 0xE8AF72, 0xEAB276, 0xE7A45D, 0x9E6C36, 0x000000}, 130 {0x000000, 0xAD7F4F, 0xF1ECCE, 0xD6FFFF, 0xD4FFFF, 0xDCFFFF, 0xFAFFF9, 0xFFFF3E, 0xFFD529, 0xF4A05C, 0x9D6B36, 0x000000}, 131 {0x000000, 0xAD7F4F, 0xF1ECCE, 0xD6FFFF, 0xD4FFFF, 0xDCFFFF, 0xFAFFFA, 0xFFFF42, 0xFFFF00, 0xF4D31A, 0x9D683A, 0x000000}, 132 {0x000000, 0xAB8959, 0xFF5638, 0xFF0000, 0xFF0000, 0xFF2020, 0xFFDFDF, 0xFFFFFF, 0xFFFFFF, 0xF4D3B0, 0x9D6830, 0x000000}, 133 {0x000000, 0xBD8B4E, 0xFF5731, 0xFF0000, 0xFF0000, 0xFF0000, 0xFE0505, 0xE1BDBE, 0xD5FFFF, 0xDDD3B0, 0x9E6830, 0x000000}, 134 {0x000000, 0xB68959, 0x734338, 0x007100, 0x00BF00, 0x001920, 0x0066DF, 0x0088FF, 0x0080FF, 0x5F89B0, 0xA76E30, 0x000000}, 135 {0x000000, 0xB67F59, 0x73EC38, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FD05, 0x00A1BE, 0x0076FF, 0x5F89B0, 0xA76E30, 0x000000}, 136 {0x000000, 0x9F6D38, 0xD38B3D, 0xC7843C, 0xC7843C, 0xC7843C, 0xC7843C, 0xC7843C, 0xC7843C, 0xD38B3D, 0x9F6D38, 0x000000}, 137 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000} 138}; 139 140const unsigned long PROGMEM menuSpectrum[12][12] = {{0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xffff00}, 141 142 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 143 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 144 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x531A8D, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 145 {0x000000, 0x000000, 0x000000, 0x000000, 0x5E2598, 0x000000, 0x2585A9, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 146 {0x000000, 0x000000, 0x000000, 0x000000, 0x3696B9, 0x591F93, 0x2585A9, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 147 {0x000000, 0x000000, 0x000000, 0x642B9E, 0x3696B9, 0x3389AA, 0x2585A9, 0x000000, 0x490F83, 0x000000, 0x000000, 0x000000}, 148 {0x000000, 0x6F36A9, 0x000000, 0x3E9EC1, 0x3C92B3, 0x3389AA, 0x2585A9, 0x4E1488, 0x16769A, 0x000000, 0x000000, 0x000000}, 149 {0x743BAE, 0x4EAED2, 0x000000, 0x3E9DC1, 0x3C92B3, 0x3289AA, 0x2A80A1, 0x217898, 0x167699, 0x000000, 0x000000, 0x000000}, 150 {0x60B7D7, 0x4EAED2, 0x000000, 0x3E9DC1, 0x3C92B3, 0x3289AA, 0x2A80A0, 0x217798, 0x16769A, 0x000000, 0x40077A, 0x000000}, 151 {0x60B7D7, 0x4EAED2, 0x6A30A4, 0x3E9EC1, 0x3C92B3, 0x3289AA, 0x2A80A1, 0x217898, 0x167699, 0x000000, 0x0A698D, 0x3D0376}, 152 {0x60B7D7, 0x57AECE, 0x4FA5C5, 0x459CBC, 0x3C92B3, 0x3389A9, 0x2A80A1, 0x217898, 0x167699, 0x440B7E, 0x09698D, 0x065C7C} 153}; 154 155 156const unsigned long PROGMEM menuText[12][12] = {{0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFFF200, 0x000000}, 157 158 {0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3, 0xFDCAD3}, 159 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 160 {0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 161 {0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 162 {0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0xFF0000, 0xFF0000, 0x000000, 0x000000}, 163 {0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0x000000}, 164 {0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0x000000}, 165 {0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000}, 166 {0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0x000000}, 167 {0x000000, 0x000000, 0xFF0000, 0x000000, 0x000000, 0x000000, 0x000000, 0xFF0000, 0xFF0000, 0xFF0000, 0x000000, 0x000000}, 168 {0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000} 169}; 170 171
Random roulette mode (idk how to call it ^^' )
arduino
1const unsigned long PROGMEM img[12][12] = {{0x020EF4, 0x022FF4, 0x0159F3, 0x018AF5, 0x01BFF9, 0x01F5FB, 0x01FFD6, 0x01FDA5, 0x01FC7A, 0x01FB54, 0x01FA38, 0x02F91F}, 2 {0x0100F3, 0x010EF4, 0x0237F3, 0x0170F4, 0x01B1F9, 0x01F2FA, 0x01FFCB, 0x01FC8E, 0x01FB5D, 0x01FA37, 0x01F918, 0x00F905}, 3 {0x0001F2, 0x0000F2, 0x010FF3, 0x0247F4, 0x019BF7, 0x01EFF8, 0x01FFBA, 0x01FB6E, 0x01FA35, 0x00F812, 0x00F802, 0x01F900}, 4 {0x0201F2, 0x0001F2, 0x0000F3, 0x0010F3, 0x016CF6, 0x01E9F5, 0x00FF97, 0x00FA35, 0x00F908, 0x02F900, 0x0EFA00, 0x1FFB01}, 5 {0x2C00F3, 0x1D01F3, 0x0F01F2, 0x0100F2, 0x001BF9, 0x00CEE4, 0x00FF42, 0x08F901, 0x1DFB00, 0x33FC01, 0x41FE00, 0x4BFE00}, 6 {0x6701F3, 0x6501F3, 0x6501F4, 0x6402F5, 0x6700FE, 0x756F82, 0x7CFF00, 0x7BFF02, 0x7AFF02, 0x7BFF02, 0x7AFE02, 0x79FF01}, 7 {0x9F00F3, 0xAC01F3, 0xC301F7, 0xE001F1, 0xF900AE, 0xFF0C15, 0xFFAF00, 0xF3FD04, 0xD8FF03, 0xC0FF03, 0xB2FF04, 0xA9FE04}, 8 {0xD301F5, 0xE600F2, 0xF401DF, 0xF600AF, 0xF4004F, 0xF30001, 0xF95000, 0xFFC002, 0xFFF303, 0xF7FF03, 0xE6FF02, 0xD3FF03}, 9 {0xF301E9, 0xF501D0, 0xF301A9, 0xF30074, 0xF20026, 0xF10000, 0xF52A01, 0xFA8202, 0xFFC003, 0xFFEA04, 0xFFFD03, 0xF7FF03}, 10 {0xF400C5, 0xF301A8, 0xF20182, 0xF2014F, 0xF20113, 0xF20000, 0xF41801, 0xF75C02, 0xFD9502, 0xFEBF02, 0xFFE103, 0xFFF803}, 11 {0xF301A8, 0xF30089, 0xF20065, 0xF10137, 0xF20009, 0xF20000, 0xF30D01, 0xF64301, 0xF97601, 0xFDA001, 0xFEC002, 0xFFDB03}, 12 {0xF30090, 0xF20172, 0xF2014E, 0xF30126, 0xF20003, 0xF20000, 0xF30801, 0xF43201, 0xF75F02, 0xFC8602, 0xFEA601, 0xFEC102} 13}; 14 15void bottleAnimation(byte t, byte stopb) { 16 byte iterations = 0; 17 18 while (!menuValidation) { 19 for (byte k = 0; k < 4; k++) { 20 switch (k) { 21 case 0: 22 for (byte i = 2; i < 12; i++) { 23 iterations++; 24 if (iterations == stopb) { 25 goto mainLoopBottle; 26 } 27 clearImg(); 28 leds[pgm_read_byte(&ledsAdress[2][i - 2])] = pgm_read_dword(&img[1][i - 2]); 29 leds[pgm_read_byte(&ledsAdress[2][i - 1])] = pgm_read_dword(&img[2][i - 1]); 30 leds[pgm_read_byte(&ledsAdress[2][i])] = pgm_read_dword(&img[2][i]); 31 leds[pgm_read_byte(&ledsAdress[1][i - 2])] = pgm_read_dword(&img[1][i - 2]); 32 leds[pgm_read_byte(&ledsAdress[1][i - 1])] = pgm_read_dword(&img[1][i - 1]); 33 leds[pgm_read_byte(&ledsAdress[1][i])] = pgm_read_dword(&img[1][i]); 34 leds[pgm_read_byte(&ledsAdress[0][i - 2])] = pgm_read_dword(&img[1][i - 2]); 35 leds[pgm_read_byte(&ledsAdress[0][i])] = pgm_read_dword(&img[0][i]); 36 leds[pgm_read_byte(&ledsAdress[0][i - 1])] = pgm_read_dword(&img[1][i - 1]); 37 FastLED.show(); 38 delay(t); 39 } 40 break; 41 case 1: 42 for (byte i = 2; i < 12; i++) { 43 iterations++; 44 if (iterations == stopb) { 45 goto mainLoopBottle; 46 } 47 clearImg(); 48 leds[pgm_read_byte(&ledsAdress[i - 2][11])] = pgm_read_dword(&img[i - 2][11]); 49 leds[pgm_read_byte(&ledsAdress[i - 1][11])] = pgm_read_dword(&img[i - 1][11]); 50 leds[pgm_read_byte(&ledsAdress[i][11])] = pgm_read_dword(&img[i][11]); 51 leds[pgm_read_byte(&ledsAdress[i - 2][10])] = pgm_read_dword(&img[i - 2][10]); 52 leds[pgm_read_byte(&ledsAdress[i - 1][10])] = pgm_read_dword(&img[i - 1][10]); 53 leds[pgm_read_byte(&ledsAdress[i][10])] = pgm_read_dword(&img[i][10]); 54 leds[pgm_read_byte(&ledsAdress[i - 2][9])] = pgm_read_dword(&img[i - 2][9]); 55 leds[pgm_read_byte(&ledsAdress[i - 1][9])] = pgm_read_dword(&img[i - 1][9]); 56 leds[pgm_read_byte(&ledsAdress[i][9])] = pgm_read_dword(&img[i][9]); 57 FastLED.show(); 58 delay(t); 59 } 60 break; 61 case 2: 62 for (byte i = 12 - 1; i > 1; i--) { 63 iterations++; 64 if (iterations == stopb) { 65 goto mainLoopBottle; 66 } 67 clearImg(); 68 leds[pgm_read_byte(&ledsAdress[11][i - 2])] = pgm_read_dword(&img[11][i - 2]); 69 leds[pgm_read_byte(&ledsAdress[11][i - 1])] = pgm_read_dword(&img[11][i - 1]); 70 leds[pgm_read_byte(&ledsAdress[11][i])] = pgm_read_dword(&img[11][i]); 71 leds[pgm_read_byte(&ledsAdress[10][i - 2])] = pgm_read_dword(&img[10][i - 2]); 72 leds[pgm_read_byte(&ledsAdress[10][i - 1])] = pgm_read_dword(&img[10][i - 1]); 73 leds[pgm_read_byte(&ledsAdress[10][i])] = pgm_read_dword(&img[10][i]); 74 leds[pgm_read_byte(&ledsAdress[9][i - 2])] = pgm_read_dword(&img[9][i - 2]); 75 leds[pgm_read_byte(&ledsAdress[9][i])] = pgm_read_dword(&img[9][i]); 76 leds[pgm_read_byte(&ledsAdress[9][i - 1])] = pgm_read_dword(&img[9][i - 1]); 77 FastLED.show(); 78 delay(t); 79 } 80 break; 81 case 3: 82 for (byte i = 12 - 1; i > 1; i--) { 83 iterations++; 84 if (iterations == stopb) { 85 goto mainLoopBottle; 86 } 87 clearImg(); 88 leds[pgm_read_byte(&ledsAdress[i - 2][2])] = pgm_read_dword(&img[i - 2][2]); 89 leds[pgm_read_byte(&ledsAdress[i - 1][2])] = pgm_read_dword(&img[i - 1][2]); 90 leds[pgm_read_byte(&ledsAdress[i][2])] = pgm_read_dword(&img[i][2]); 91 leds[pgm_read_byte(&ledsAdress[i - 2][1])] = pgm_read_dword(&img[i - 2][1]); 92 leds[pgm_read_byte(&ledsAdress[i - 1][1])] = pgm_read_dword(&img[i - 1][1]); 93 leds[pgm_read_byte(&ledsAdress[i][1])] = pgm_read_dword(&img[i][1]); 94 leds[pgm_read_byte(&ledsAdress[i - 2][0])] = pgm_read_dword(&img[i - 2][0]); 95 leds[pgm_read_byte(&ledsAdress[i - 1][0])] = pgm_read_dword(&img[i - 1][0]); 96 leds[pgm_read_byte(&ledsAdress[i][0])] = pgm_read_dword(&img[i][0]); 97 FastLED.show(); 98 delay(t); 99 } 100 break; 101 102 } 103 } 104} mainLoopBottle: 105delay(4); 106} 107 108void bottle() { 109 bottleAnimation(60, random(100, 139)); 110 111 int prevPointer = menuPointer; 112 while (!menuValidation && menuPointer == prevPointer) { 113 readPointer(); 114 delay(4); 115 } 116}
Documentation
Main interface panel
On this panel you'll find the main control buttons, audio IO and the USB port used to upload the code on the Arduino Nano. Made on Fusion360
Main interface panel
Main interface panel
On this panel you'll find the main control buttons, audio IO and the USB port used to upload the code on the Arduino Nano. Made on Fusion360
Main interface panel
Comments
Only logged in users can leave comments