// LEDmePlay Development Template // for the LEDmePlay // // www.mithotronic.de // // Version: 1.1.0 // Author: Thomas Laubach and Michael Rosskopf (2018) // // Release Notes: // V1.1.0: Support for real analog joystick inquiry // V1.0.0: First release // Include libraries for adafruit matrix #include // Core graphics library #include // Hardware-specific library #include // Necessary to maintain data in program memory // Setup adafruit matrix #define CLK 50 #define OE 51 #define LAT 10 #define A A0 #define B A1 #define C A2 #define D A3 RGBmatrixPanel matrix(A, B, C, D, CLK, LAT, OE, false); // Audio out int audio = 2; // Define notes #define NOTE_B0 31 #define NOTE_C1 33 #define NOTE_CS1 35 #define NOTE_D1 37 #define NOTE_DS1 39 #define NOTE_E1 41 #define NOTE_F1 44 #define NOTE_FS1 46 #define NOTE_G1 49 #define NOTE_GS1 52 #define NOTE_A1 55 #define NOTE_AS1 58 #define NOTE_B1 62 #define NOTE_C2 65 #define NOTE_CS2 69 #define NOTE_D2 73 #define NOTE_DS2 78 #define NOTE_E2 82 #define NOTE_F2 87 #define NOTE_FS2 93 #define NOTE_G2 98 #define NOTE_GS2 104 #define NOTE_A2 110 #define NOTE_AS2 117 #define NOTE_B2 123 #define NOTE_C3 131 #define NOTE_CS3 139 #define NOTE_D3 147 #define NOTE_DS3 156 #define NOTE_E3 165 #define NOTE_F3 175 #define NOTE_FS3 185 #define NOTE_G3 196 #define NOTE_GS3 208 #define NOTE_A3 220 #define NOTE_AS3 233 #define NOTE_B3 247 #define NOTE_C4 262 #define NOTE_CS4 277 #define NOTE_D4 294 #define NOTE_DS4 311 #define NOTE_E4 330 #define NOTE_F4 349 #define NOTE_FS4 370 #define NOTE_G4 392 #define NOTE_GS4 415 #define NOTE_A4 440 #define NOTE_AS4 466 #define NOTE_B4 494 #define NOTE_C5 523 #define NOTE_CS5 554 #define NOTE_D5 587 #define NOTE_DS5 622 #define NOTE_E5 659 #define NOTE_F5 698 #define NOTE_FS5 740 #define NOTE_G5 784 #define NOTE_GS5 831 #define NOTE_A5 880 #define NOTE_AS5 932 #define NOTE_B5 988 #define NOTE_C6 1047 #define NOTE_CS6 1109 #define NOTE_D6 1175 #define NOTE_DS6 1245 #define NOTE_E6 1319 #define NOTE_F6 1397 #define NOTE_FS6 1480 #define NOTE_G6 1568 #define NOTE_GS6 1661 #define NOTE_A6 1760 #define NOTE_AS6 1865 #define NOTE_B6 1976 #define NOTE_C7 2093 #define NOTE_CS7 2217 #define NOTE_D7 2349 #define NOTE_DS7 2489 #define NOTE_E7 2637 #define NOTE_F7 2794 #define NOTE_FS7 2960 #define NOTE_G7 3136 #define NOTE_GS7 3322 #define NOTE_A7 3520 #define NOTE_AS7 3729 #define NOTE_B7 3951 #define NOTE_C8 4186 #define NOTE_CS8 4435 #define NOTE_D8 4699 #define NOTE_DS8 4978 // Joystick 1 int buttonU1 = 30; int buttonD1 = 32; int buttonL1 = 34; int buttonR1 = 36; int buttonFire1 = 38; int analogX1 = 8; int analogY1 = 9; // Joystick 2 int buttonU2 = 31; int buttonD2 = 33; int buttonL2 = 35; int buttonR2 = 37; int buttonFire2 = 39; int analogX2 = 10; int analogY2 = 11; // Sensitivity of analog thumb joysticks (of the LEDmePlay Joypad) in case of "digital usage" (detects movement if deviates from center position value of 512 by sensitivity value) const int sensitivity = 192; // Sensitivity of analog thumb joysticks (minimal difference from center position) const int sensitivityAnalog = 64; // Returns the value of maximal excursion already at 0 + maxValueDistance or 1024 - maxValueDistance const int maxValueDistanceAnalog = 64; // Helper int denominatorAnalog = 512 - sensitivityAnalog - maxValueDistanceAnalog; // Buffer for analog joystick values double joy1X; double joy1Y; double joy2X; double joy2Y; // Other buttons int buttonReset = 42; int buttonPause = 43; void setup() { // Initialize serial connection Serial.begin(9600); // Initialize random number generator randomSeed(analogRead(40)); // Initialize joysticks and buttons pinMode(buttonL1, INPUT); pinMode(buttonR1, INPUT); pinMode(buttonU1, INPUT); pinMode(buttonD1, INPUT); pinMode(buttonFire1, INPUT); pinMode(buttonL2, INPUT); pinMode(buttonR2, INPUT); pinMode(buttonU2, INPUT); pinMode(buttonD2, INPUT); pinMode(buttonFire2, INPUT); pinMode(buttonReset, INPUT); pinMode(buttonPause, INPUT); // Activate internal pull-up resistors digitalWrite(buttonL1, HIGH); digitalWrite(buttonR1, HIGH); digitalWrite(buttonU1, HIGH); digitalWrite(buttonD1, HIGH); digitalWrite(buttonFire1, HIGH); digitalWrite(buttonL2, HIGH); digitalWrite(buttonR2, HIGH); digitalWrite(buttonU2, HIGH); digitalWrite(buttonD2, HIGH); digitalWrite(buttonFire2, HIGH); digitalWrite(buttonReset, HIGH); digitalWrite(buttonPause, HIGH); // Initialize matrix and define text mode matrix.begin(); matrix.setTextSize(1); matrix.setTextWrap(false); // Logos mithotronic(); ledMePlay(); // Enter the game loop loop(); } // Joystick inquiry (allows to use a classic joystick or a LEDmePlay Joypad without any configuration) boolean joy1Up() { if((digitalRead(buttonU1) == LOW && digitalRead(buttonD1) != LOW) || (digitalRead(buttonL1) == LOW && digitalRead(buttonR1) == LOW && analogRead(analogY1) > (512 + sensitivity))){ return true; } return false; } boolean joy1Down() { if((digitalRead(buttonD1) == LOW && digitalRead(buttonU1) != LOW) || (digitalRead(buttonL1) == LOW && digitalRead(buttonR1) == LOW && analogRead(analogY1) < (512 - sensitivity))){ return true; } return false; } boolean joy1Left() { if((digitalRead(buttonL1) == LOW && digitalRead(buttonR1) != LOW) || (digitalRead(buttonL1) == LOW && digitalRead(buttonR1) == LOW && analogRead(analogX1) > (512 + sensitivity))){ return true; } return false; } boolean joy1Right() { if((digitalRead(buttonR1) == LOW && digitalRead(buttonL1) != LOW) || (digitalRead(buttonL1) == LOW && digitalRead(buttonR1) == LOW && analogRead(analogX1) < (512 - sensitivity))){ return true; } return false; } float joy1XValue() { joy1X = analogRead(analogX1); if((joy1X > (512 - sensitivityAnalog)) && (joy1X < (512 + sensitivityAnalog))){ return 0.0; } else if(joy1X > (1024 - maxValueDistanceAnalog)){ return 1.0; } else if(joy1X < maxValueDistanceAnalog){ return -1.0; } else if(joy1X > 512){ return (1.0 * (joy1X - sensitivityAnalog - 512) / denominatorAnalog); } else{ return (-1.0 * (512 - joy1X - sensitivityAnalog) / denominatorAnalog); } } float joy1YValue() { joy1Y = analogRead(analogY1); if((joy1Y > (512 - sensitivityAnalog)) && (joy1Y < (512 + sensitivityAnalog))){ return 0.0; } else if(joy1Y > (1024 - maxValueDistanceAnalog)){ return 1.0; } else if(joy1Y < maxValueDistanceAnalog){ return -1.0; } else if(joy1Y > 512){ return (1.0 * (joy1Y - sensitivityAnalog - 512) / denominatorAnalog); } else{ return (-1.0 * (512 - joy1Y - sensitivityAnalog) / denominatorAnalog); } } boolean joy1Fire() { if(digitalRead(buttonFire1) == LOW || (digitalRead(buttonU1) == LOW && digitalRead(buttonD1) == LOW)){ return true; } return false; } boolean joy1FireA() { if(digitalRead(buttonFire1) == LOW){ return true; } return false; } boolean joy1FireB() { if(digitalRead(buttonU1) == LOW && digitalRead(buttonD1) == LOW){ return true; } return false; } boolean joy1IsLEDmePlayJoypad() { if(digitalRead(buttonL1) == LOW && digitalRead(buttonR1) == LOW){ return true; } return false; } boolean joy2Up() { if((digitalRead(buttonU2) == LOW && digitalRead(buttonD2) != LOW) || (digitalRead(buttonL2) == LOW && digitalRead(buttonR2) == LOW && analogRead(analogY2) > (512 + sensitivity))){ return true; } return false; } boolean joy2Down() { if((digitalRead(buttonD2) == LOW && digitalRead(buttonU2) != LOW) || (digitalRead(buttonL2) == LOW && digitalRead(buttonR2) == LOW && analogRead(analogY2) < (512 - sensitivity))){ return true; } return false; } boolean joy2Left() { if((digitalRead(buttonL2) == LOW && digitalRead(buttonR2) != LOW) || (digitalRead(buttonL2) == LOW && digitalRead(buttonR2) == LOW && analogRead(analogX2) > (512 + sensitivity))){ return true; } return false; } boolean joy2Right() { if((digitalRead(buttonR2) == LOW && digitalRead(buttonL2) != LOW) || (digitalRead(buttonL2) == LOW && digitalRead(buttonR2) == LOW && analogRead(analogX2) < (512 - sensitivity))){ return true; } return false; } float joy2XValue() { joy2X = analogRead(analogX2); if((joy2X > (512 - sensitivityAnalog)) && (joy2X < (512 + sensitivityAnalog))){ return 0.0; } else if(joy2X > (1024 - maxValueDistanceAnalog)){ return 1.0; } else if(joy2X < maxValueDistanceAnalog){ return -1.0; } else if(joy2X > 512){ return (1.0 * (joy2X - sensitivityAnalog - 512) / denominatorAnalog); } else{ return (-1.0 * (512 - joy2X - sensitivityAnalog) / denominatorAnalog); } } float joy2YValue() { joy2Y = analogRead(analogY2); if((joy2Y > (512 - sensitivityAnalog)) && (joy2Y < (512 + sensitivityAnalog))){ return 0.0; } else if(joy2Y > (1024 - maxValueDistanceAnalog)){ return 1.0; } else if(joy2Y < maxValueDistanceAnalog){ return -1.0; } else if(joy2Y > 512){ return (1.0 * (joy2Y - sensitivityAnalog - 512) / denominatorAnalog); } else{ return (-1.0 * (512 - joy2Y - sensitivityAnalog) / denominatorAnalog); } } boolean joy2Fire() { if(digitalRead(buttonFire2) == LOW || (digitalRead(buttonU2) == LOW && digitalRead(buttonD2) == LOW)){ return true; } return false; } boolean joy2FireA() { if(digitalRead(buttonFire2)){ return true; } return false; } boolean joy2FireB() { if(digitalRead(buttonU2) == LOW && digitalRead(buttonD2) == LOW){ return true; } return false; } boolean joy2IsLEDmePlayJoypad() { if(digitalRead(buttonL2) == LOW && digitalRead(buttonR2) == LOW){ return true; } return false; } // Draw the M of the Mithotronic logo void drawM(int x, int y) { matrix.fillRect(x + 2, y + 2, 6, 1, matrix.Color333(0, 0, 0)); matrix.fillRect(x, y + 3, 10, 1, matrix.Color333(0, 0, 0)); matrix.fillRect(x, y + 4, 2, 6, matrix.Color333(3, 3, 3)); matrix.fillRect(x + 2, y + 3, 2, 2, matrix.Color333(3, 3, 3)); matrix.fillRect(x + 4, y + 4, 2, 6, matrix.Color333(3, 3, 3)); matrix.fillRect(x + 6, y + 3, 2, 2, matrix.Color333(3, 3, 3)); matrix.fillRect(x + 8, y + 4, 2, 6, matrix.Color333(3, 3, 3)); } // Draw the T of the Mithotronic logo void drawT(int x, int y) { matrix.fillRect(x, y + 5, 6, 1, matrix.Color333(0, 0, 0)); matrix.fillRect(x + 2, y + 10, 3, 1, matrix.Color333(0, 0, 0)); matrix.fillRect(x, y + 3, 6, 2, matrix.Color333(0, 0, 7)); matrix.fillRect(x + 2, y, 2, 10, matrix.Color333(0, 0, 7)); matrix.fillRect(x + 4, y + 8, 1, 2, matrix.Color333(0, 0, 7)); } // Draw the animated Mithotronic logo and play jingle void mithotronic() { int i = -10; do { drawM(7, i); drawT(19, 22 - i); i++; delay(50); } while(i <= 11); // Jingle on start screen tone(audio,NOTE_C4,200); delay(400+20); tone(audio,NOTE_C4,90); delay(200-20); tone(audio,NOTE_G4,140); delay(400+20); tone(audio,NOTE_G4,140); delay(200-20); tone(audio,NOTE_C5,450); delay(600); tone(audio,NOTE_AS4,140); delay(200-20); tone(audio,NOTE_A4,130); delay(200-10); tone(audio,NOTE_F4,120); delay(200); tone(audio,NOTE_G4,1000); delay(3000); } // Sets color for the next character to show the LEDmePLay logo void setLEDMePlayColor(int i) { switch(i % 9) { case 0: matrix.setTextColor(matrix.Color333(5,0,0)); break; case 1: matrix.setTextColor(matrix.Color333(5,2,0)); break; case 2: matrix.setTextColor(matrix.Color333(2,5,0)); break; case 3: matrix.setTextColor(matrix.Color333(0,5,0)); break; case 4: matrix.setTextColor(matrix.Color333(0,5,2)); break; case 5: matrix.setTextColor(matrix.Color333(0,2,5)); break; case 6: matrix.setTextColor(matrix.Color333(0,0,5)); break; case 7: matrix.setTextColor(matrix.Color333(2,0,5)); break; case 8: matrix.setTextColor(matrix.Color333(5,0,2)); break; } } // Draw the LEDmePlay logo void ledMePlay() { // Clear screen matrix.fillScreen(matrix.Color333(0, 0, 0)); int i = 0; do { // Write 'LEDmePlay' setLEDMePlayColor(i++); matrix.setCursor(7, 5); matrix.println("L"); setLEDMePlayColor(i++); matrix.setCursor(13, 5); matrix.println("E"); setLEDMePlayColor(i++); matrix.setCursor(19, 5); matrix.println("D"); setLEDMePlayColor(i++); matrix.setCursor(10, 11); matrix.println("m"); setLEDMePlayColor(i++); matrix.setCursor(16, 11); matrix.println("e"); setLEDMePlayColor(i++); matrix.setCursor(4, 19); matrix.println("P"); setLEDMePlayColor(i++); matrix.setCursor(10, 19); matrix.println("l"); setLEDMePlayColor(i++); matrix.setCursor(16, 19); matrix.println("a"); setLEDMePlayColor(i++); matrix.setCursor(22, 19); matrix.println("y"); i++; if(i > 81) { i = 0; } int j = 0; do { j++; delay(1); } while(j < 250 && digitalRead(buttonFire1) != LOW && digitalRead(buttonFire2) != LOW); } while(digitalRead(buttonFire1) != LOW && digitalRead(buttonFire2) != LOW); tone(audio,1024,20); delay(200); matrix.fillRect(0, 0, 32, 32, matrix.Color333(0,0,0)); } void loop() { // Develop your game here }