Controls: Use the direction pad + A or B button for 8 different sound samples.
The memes can’t stop, won’t stop.
#include <Arduboy2.h>
#include <ArduboyPlaytune.h>
#include "particle.h"
#define dParticleMax 12
Particle dotsLanded[dParticleMax];
Arduboy2 arduboy;
ArduboyPlaytune tunes(arduboy.audio.enabled);
const unsigned char PROGMEM b1 [] = {
//
0x90, 62, 0, 62, 0x80, 0, 63, 0x90, 60, 0, 62, 0x80, 0, 63, 0x90, 62, 0, 62, 0x80, 0, 63, 0x90, 60, 0, 62, 0x80,
0, 63, 0x90, 62, 0, 62, 0x80, 0, 63, 0x90, 60, 0, 62, 0x80, 0, 63, 0x90, 62, 0, 62, 0x80, 0, 63, 0x90, 57, 0, 125,
0x90, 60, 0, 250, 0x90, 62, 0, 125, 0x80, 0, 125, 0x90, 65, 0, 250, 0x90, 67, 0, 250, 0x80, 0xF0
};
const unsigned char PROGMEM b2 [] = {
//
0x90, 53, 0, 125, 0x90, 54, 0, 125, 0x90, 55, 0, 125, 0x90, 57, 0, 125, 0x80, 0, 125, 0x90, 60, 0, 125, 0x80, 0, 125,
0x90, 60, 0, 125, 0x80, 0, 125, 0x90, 60, 0, 125, 0x80, 0, 125, 0x90, 60, 0, 125, 0x90, 61, 0, 125, 0x80, 0, 125, 0x90, 62,
0, 187, 0x80, 0xF0
};
const unsigned char PROGMEM b3 [] = {
//
0x90, 62, 0, 125, 0x90, 60, 0, 62, 0x80, 0, 188, 0x90, 60, 0, 62, 0x80, 0, 188, 0x90, 57, 0, 125, 0x90, 60, 0, 125,
0x90, 62, 0, 125, 0x80, 0, 125, 0x90, 65, 0, 62, 0x80, 0, 188, 0x90, 67, 0, 125, 0x90, 67, 0, 125, 0x80, 0, 125, 0x90, 69,
0, 125, 0x80, 0xF0
};
const unsigned char PROGMEM b4 [] = {
//
0x90, 56, 0, 125, 0x90, 55, 0, 125, 0x90, 56, 0, 125, 0x90, 55, 0, 125, 0x80, 0, 125, 0x90, 55, 0, 62, 0x80, 0, 63,
0x90, 55, 0, 125, 0x90, 53, 0, 125, 0x90, 55, 0, 125, 0x90, 53, 0, 125, 0x80, 0, 125, 0x90, 53, 0, 62, 0x80, 0, 63,
0x90, 53, 0, 125, 0x90, 52, 0, 125, 0x90, 53, 0, 125, 0x80, 0xF0
};
const unsigned char PROGMEM b5 [] = {
//
0x90, 62, 2, 175, 0x90, 61, 0, 63, 0x90, 61, 0, 62, 0x90, 60, 0, 63, 0x90, 61, 0, 62, 0x90, 61, 0, 63, 0x90, 62,
0, 125, 0x80, 0, 125, 0x90, 60, 0, 125, 0x80, 0, 125, 0x90, 57, 0, 125, 0x90, 60, 0, 125, 0x80, 0, 125, 0x90, 62, 0, 125,
0x80, 0xF0
};
const unsigned char PROGMEM b6 [] = {
//
0x90, 50, 0, 250, 0x90, 62, 0, 125, 0x90, 50, 0, 125, 0x80, 0, 62, 0x90, 62, 0, 125, 0x80, 0, 188, 0x90, 50, 0, 125,
0x80, 0, 125, 0x90, 50, 0, 125, 0x90, 60, 0, 250, 0x90, 53, 0, 125, 0x90, 50, 0, 125, 0x80, 0, 125, 0x90, 50, 0, 125,
0x80, 0xF0
};
const unsigned char PROGMEM b7 [] = {
//
0x90, 38, 0, 250, 0x80, 0, 250, 0x90, 50, 0, 250, 0x80, 0, 125, 0x90, 41, 0, 125, 0x80, 0, 125, 0x90, 41, 0, 125, 0x90, 48,
0, 187, 0x80, 0, 63, 0x90, 45, 0, 125, 0x90, 43, 0, 125, 0x90, 44, 0, 125, 0x90, 45, 0, 125, 0x80, 0xF0
};
const unsigned char PROGMEM b8 [] = {
//
0, 250, 0x90, 74, 0x91, 38, 0, 125, 0x80, 0, 125, 0x90, 74, 0x81, 0, 125, 0x90, 74, 0, 125, 0x90, 45, 0, 125, 0x91, 74,
0x90, 43, 0, 125, 0x90, 38, 0x81, 0, 125, 0x91, 74, 0, 125, 0x80, 0x81, 0, 125, 0x90, 74, 0x91, 38, 0, 125, 0x90, 74, 0x91, 38,
0, 125, 0x80, 0, 125, 0x81, 1, 244, 0x90, 74, 0x91, 38, 0, 125, 0x80, 0, 125, 0x90, 74, 0x81, 0, 125, 0x90, 74, 0, 125,
0x90, 43, 0, 125, 0x91, 74, 0x90, 45, 0, 125, 0x90, 38, 0x81, 0, 125, 0x91, 74, 0, 125, 0x80, 0x81, 0, 125, 0x90, 74, 0x91, 38,
0, 125, 0x90, 74, 0x91, 38, 0, 125, 0x80, 0x81, 0, 125, 0x90, 41, 0, 250, 0x80, 0xF0
};
constexpr uint8_t Sax[] PROGMEM
{
//Frame 0
0x18, 0x1C, 0x12, 0x22, 0x23, 0x31, 0x29, 0x31, 0xF9, 0xC9, 0x47, 0x41, 0x81, 0x85, 0x8A, 0xB4, 0xC8, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0xF8, 0x24, 0xAE, 0x43, 0x54, 0x48, 0x49, 0x48, 0x49, 0x49, 0x49, 0x6D, 0xFF, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xE1, 0x33, 0x3F, 0xFE, 0xFE, 0xFE, 0x3E, 0xDE, 0xDE, 0x3E, 0xFE, 0xFE, 0xFF, 0x0F, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xB6, 0xB5, 0xCD, 0xFE, 0xFF, 0xFF, 0xC1, 0x20, 0xF0, 0x08, 0xE4, 0xF4, 0xF4, 0xE8, 0xD0, 0xA0, 0x40, 0x80, 0x00, 0x00,
0x00, 0x00, 0xFE, 0xF3, 0x6D, 0xAD, 0xB3, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x4F, 0xA3, 0xA7, 0x40, 0x81, 0x80, 0x8F, 0xF8, 0xC1, 0x0F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x78, 0x87, 0x78,
0xF0, 0x8F, 0x77, 0x77, 0x76, 0x8D, 0xFD, 0xFE, 0xFF, 0xDF, 0xBF, 0xB8, 0x77, 0x6F, 0xEF, 0xF7, 0xF8, 0xFF, 0xFF, 0xFF, 0x0F, 0x07, 0x03, 0x06, 0x06, 0x06, 0x02, 0x03, 0x01, 0x00,
0x07, 0x0F, 0x3F, 0x3F, 0x7D, 0xFB, 0xF7, 0xF7, 0xFB, 0xFF, 0xC7, 0xBB, 0xBB, 0xBB, 0xC6, 0xFE, 0xFE, 0xFE, 0x3E, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x06, 0x06, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x06, 0x06, 0x06, 0x04, 0x04, 0x00, 0x00, 0x00
};
void updateDots() {
for ( int i = 0; i < dParticleMax; i++) {
dotsLanded[i].update();
if ( dotsLanded[i].render() ) { // the dot should be rendered
int pSize = dotsLanded[i].getSize();
if ( dotsLanded[i].getType() == 2) {
arduboy.setCursor( dotsLanded[i].getX(), dotsLanded[i].getY() );
//strcpy_P(buffer, (char *)pgm_read_word(&(goodWords[ dotsLanded[i].getWord() ])));
//arduboy.print(buffer);
arduboy.print("!");
}
else if ( dotsLanded[i].getType() == 3) {
arduboy.setCursor( dotsLanded[i].getX(), dotsLanded[i].getY() );
//arduboy.print( dotsLanded[i].getWord() );
} else {
if ( pSize == 1 ) {
arduboy.drawPixel( dotsLanded[i].getX(), dotsLanded[i].getY(), 1);
} else {
arduboy.drawLine(dotsLanded[i].getX() + (pSize * .6), dotsLanded[i].getY(), dotsLanded[i].getX() + pSize, dotsLanded[i].getY() - (pSize * 1.8), 1);
arduboy.drawCircle( dotsLanded[i].getX(), dotsLanded[i].getY(), pSize / 2, 1);
}
}
}
}
}
void setup()
{
arduboy.beginDoFirst();
arduboy.setFrameRate(60);
tunes.initChannel(PIN_SPEAKER_1);
tunes.initChannel(PIN_SPEAKER_2);
for(int i=-60;i<1;i++){
arduboy.clear();
arduboy.drawBitmap(30, i, Sax, 30, 60, 1);
delay(10);
arduboy.display();
}
}
bool song1 = 0;
bool song2 = 0;
bool song3 = 0;
bool song4 = 0;
bool song5 = 0;
bool song6 = 0;
bool song7 = 0;
bool song8 = 0;
int noteCounter;
void loop()
{
// pause render until it's time for the next frame
if (!(arduboy.nextFrame()))
return;
if (arduboy.pressed(A_BUTTON)) {
if (arduboy.pressed(UP_BUTTON)) {
if (!tunes.playing()) {
clearSongs();
song1 = 1;
tunes.playScore(b1);
}
} else if (arduboy.pressed(DOWN_BUTTON)) {
if (!tunes.playing()) {
clearSongs();
song2 = 1;
tunes.playScore(b2);
}
} else if (arduboy.pressed(LEFT_BUTTON)) {
if (!tunes.playing()) {
clearSongs();
song3 = 1;
tunes.playScore(b3);
}
} else if (arduboy.pressed(RIGHT_BUTTON)) {
if (!tunes.playing()) {
clearSongs();
song4 = 1;
tunes.playScore(b4);
}
}
} else if (arduboy.pressed(B_BUTTON)) {
if (arduboy.pressed(UP_BUTTON)) {
if (!tunes.playing()) {
clearSongs();
song5 = 1;
tunes.playScore(b5);
}
} else if (arduboy.pressed(DOWN_BUTTON)) {
if (!tunes.playing()) {
clearSongs();
song6 = 1;
tunes.playScore(b6);
}
} else if (arduboy.pressed(LEFT_BUTTON)) {
if (!tunes.playing()) {
clearSongs();
song7 = 1;
tunes.playScore(b7);
}
} else if (arduboy.pressed(RIGHT_BUTTON)) {
if (!tunes.playing()) {
clearSongs();
song8 = 1;
tunes.playScore(b8);
}
}
}
arduboy.clear();
arduboy.drawBitmap(30, 0, Sax, 30, 60, 1);
if (song1) {
if (tunes.playing()) {
arduboy.fillRect(41, 22, 2, 3, 0);
noteCounter++;
if (noteCounter > 10) {
drawMusic();
noteCounter = 0;
}
}
}
if (song2) {
if (tunes.playing()) {
arduboy.fillRect(40, 28, 2, 2, 0);
noteCounter++;
if (noteCounter > 10) {
drawMusic();
noteCounter = 0;
}
}
}
if (song3) {
if (tunes.playing()) {
arduboy.fillRect(34, 34, 2, 2, 0);
noteCounter++;
if (noteCounter > 10) {
drawMusic();
noteCounter = 0;
}
}
}
if (song4) {
if (tunes.playing()) {
arduboy.fillRect(35, 39, 2, 2, 0);
noteCounter++;
if (noteCounter > 10) {
drawMusic();
noteCounter = 0;
}
}
}
if (song5) {
if (tunes.playing()) {
arduboy.fillRect(32, 44, 3, 3, 0);
noteCounter++;
if (noteCounter > 10) {
drawMusic();
noteCounter = 0;
}
}
}
if (song6) {
if (tunes.playing()) {
arduboy.fillRect(41, 51, 3, 3, 0);
noteCounter++;
if (noteCounter > 10) {
drawMusic();
noteCounter = 0;
}
}
}
if (song7) {
if (tunes.playing()) {
arduboy.fillRect(43, 39, 2, 5, 0);
arduboy.fillRect(42, 40, 4, 3, 0);
noteCounter++;
if (noteCounter > 10) {
drawMusic();
noteCounter = 0;
}
}
}
if (song8) {
if (tunes.playing()) {
updateRainbow();
noteCounter++;
if (noteCounter == 1) arduboy.fillRect(41, 22, 2, 3, 0);
if (noteCounter == 2 ) arduboy.fillRect(40, 28, 2, 2, 0);
if (noteCounter == 3 ) arduboy.fillRect(34, 34, 2, 2, 0);
if (noteCounter == 4 ) arduboy.fillRect(35, 39, 2, 2, 0);
if (noteCounter == 5 ) arduboy.fillRect(32, 44, 3, 3, 0);
if (noteCounter == 6 ) arduboy.fillRect(41, 51, 3, 3, 0);
if (noteCounter == 6 ) {
arduboy.fillRect(43, 39, 2, 5, 0);
arduboy.fillRect(42, 40, 4, 3, 0);
}
if (noteCounter > 10) {
drawMusic();
noteCounter = 0;
}
}
}
if (!tunes.playing()) {
clearSongs();
}
updateDots();
arduboy.display();
}
void clearSongs(){
song1 = 0;
song2 = 0;
song3 = 0;
song4 = 0;
song5 = 0;
song6 = 0;
song7 = 0;
song8 = 0;
}
int songPlaying() {
return song1 +
song2 +
song3 +
song4 +
song5 +
song6 +
song7 +
song8 ;
}
void drawMusic() {
for ( int i = 0; i < 2; i++) {
dotsLanded[i].setX( 50 );
dotsLanded[i].setY( 36 );
dotsLanded[i].setVelX( random(4, 6) );
dotsLanded[i].setVelY( random(2, 5) );
dotsLanded[i].setCounter( random(15, 100) );
dotsLanded[i].setSize( random(2, 7) );
dotsLanded[i].setType( 0 );
}
}
void updateRainbow() {
static uint8_t hue = 0;
// Convert hue to RGB values.
uint8_t r, g, b;
hueToRGB(hue, r, g, b);
// Set the RGB LED.
simulateAnalogWriteRGB(r, g, b);
// Move to the next hue.
hue += 5;
}
void hueToRGB(uint8_t hue, uint8_t &r, uint8_t &g, uint8_t &b) {
uint8_t region = hue / 43;
uint8_t remainder = (hue - (region * 43)) * 6;
uint8_t p = 0;
uint8_t q = (255 - remainder);
uint8_t t = remainder;
switch (region) {
case 0:
r = 255; g = t; b = p;
break;
case 1:
r = q; g = 255; b = p;
break;
case 2:
r = p; g = 255; b = t;
break;
case 3:
r = p; g = q; b = 255;
break;
case 4:
r = t; g = p; b = 255;
break;
default:
r = 255; g = p; b = q;
break;
}
}
void simulateAnalogWriteRGB(uint8_t r, uint8_t g, uint8_t b) {
// Simulate varying brightness by toggling the LED on and off rapidly.
// The values of r, g, b determine how long the LED stays on/off.
for (int i = 0; i < 255; i += 5) {
arduboy.digitalWriteRGB(i < r, i < g, i < b);
delayMicroseconds(5); // Adjust this for smoother or faster changes.
arduboy.digitalWriteRGB(1, 1, 1);
delayMicroseconds(300); // Adjust this for smoother or faster changes.
}
}
Note: Seems like the simulator is dropping some notes that the hardware plays alright? Seems like the pauses aren’t being handled quite right, there are a few places where there are supposed to be short pauses and it’s almost twice as long. I guess some kind of minor timer mismatch that propagates out?