1#include <Wire.h>
2#include <Adafruit_GFX.h>
3#include <Adafruit_SSD1306.h>
4#include <Fonts/FreeSans9pt7b.h>
5
6#define SCREEN_WIDTH 128
7#define SCREEN_HEIGHT 64
8#define OLED_RESET -1
9Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
10
11void setup() {
12 Serial.begin(115200);
13 if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
14 for(;;);
15 }
16 display.setFont(&FreeSans9pt7b);
17 display.setTextColor(WHITE);
18 display.clearDisplay();
19}
20
21void loop() {
22 // ========================================================
23 // THE FULL SONG TIMELINE
24 // Every single word is here. Tweak the delays to match the audio!
25 // ========================================================
26
27 drawScene(0, "I MISS YOU"); delay(1200);
28 drawScene(1, "COME HERE"); delay(1200);
29 drawScene(2, "AND OH..."); delay(800);
30 drawScene(2, "IT'S HARD"); delay(1000);
31 drawScene(3, "TO SEE YOU"); delay(1200);
32 drawScene(4, "BUT I WISH YOU"); delay(1500);
33 drawScene(5, "WERE RIGHT HERE"); delay(1500);
34 drawScene(0, "OHH IT'S HARD"); delay(1200);
35 drawScene(1, "TO LEAVE YOU"); delay(1500);
36 drawScene(3, "WHEN I GET"); delay(1000);
37 drawScene(6, "EVERYWHERE"); delay(1500);
38 drawScene(7, "ALL THIS TIME"); delay(1500);
39 drawScene(8, "I'M THINKING"); delay(1500);
40 drawScene(9, "I'M STRONG"); delay(1000);
41 drawScene(9, "ENOUGH"); delay(800);
42 drawScene(10, "TO SINK IN"); delay(1500);
43 drawScene(11, "OH I DON'T"); delay(1000);
44 drawScene(11, "NEED YOU"); delay(1000);
45 drawScene(12, "BUT I MISS YOU"); delay(1800);
46 drawScene(1, "COME HERE!"); delay(2000);
47
48 // Quick 2-second reset for fast-paced video looping
49 display.clearDisplay();
50 display.display();
51 delay(2000);
52}
53
54// ========================================================
55// THE MASTER SCENE ENGINE (Two-Color Strict Layout)
56// ========================================================
57
58void drawScene(int type, const char* text) {
59 display.clearDisplay();
60
61 // 1. DYNAMIC TEXT CENTERING (Top Yellow Band: Y=0 to 15)
62 int16_t x1, y1;
63 uint16_t w, h;
64 display.getTextBounds(text, 0, 14, &x1, &y1, &w, &h);
65 display.setCursor((128 - w) / 2, 14); // Perfect center math
66 display.print(text);
67
68 // 2. SOLID STICKER EMOJIS (Bottom Blue Band: Y=20 to 63)
69 int x = 64; int y = 44;
70
71 switch(type) {
72 case 0: // Sad
73 display.fillRoundRect(x-16, y-12, 32, 24, 10, WHITE);
74 display.drawLine(x-8, y-2, x-3, y-2, BLACK); display.drawLine(x+8, y-2, x+3, y-2, BLACK);
75 display.drawLine(x-3, y+4, x+3, y+4, BLACK);
76 display.fillCircle(x-18, y+8, 4, WHITE); display.fillCircle(x+18, y+8, 4, WHITE);
77 break;
78
79 case 1: // Big Eyes Reaching
80 display.fillRoundRect(x-18, y-14, 36, 26, 12, WHITE);
81 display.fillCircle(x-7, y-1, 5, BLACK); display.fillCircle(x+7, y-1, 5, BLACK);
82 display.fillCircle(x-8, y-2, 1, WHITE); display.fillCircle(x+6, y-2, 1, WHITE);
83 display.fillRoundRect(x-28, y, 12, 6, 3, WHITE); display.fillRoundRect(x+16, y, 12, 6, 3, WHITE);
84 break;
85
86 case 2: // Hands on Cheeks / Squint
87 display.fillRoundRect(x-16, y-12, 32, 24, 10, WHITE);
88 display.drawLine(x-10, y-3, x-4, y+1, BLACK); display.drawLine(x-10, y+5, x-4, y+1, BLACK);
89 display.drawLine(x+10, y-3, x+4, y+1, BLACK); display.drawLine(x+10, y+5, x+4, y+1, BLACK);
90 display.fillCircle(x-12, y+6, 5, BLACK); display.fillCircle(x-12, y+6, 3, WHITE);
91 display.fillCircle(x+12, y+6, 5, BLACK); display.fillCircle(x+12, y+6, 3, WHITE);
92 break;
93
94 case 3: // Looking Down
95 display.fillRoundRect(x-16, y-12, 32, 24, 10, WHITE);
96 display.fillCircle(x-6, y+4, 3, BLACK); display.fillCircle(x+6, y+4, 3, BLACK);
97 display.drawLine(x-10, y-6, x-6, y-10, WHITE); display.drawLine(x+10, y-6, x+6, y-10, WHITE);
98 break;
99
100 case 4: // Two Characters Together
101 display.fillRoundRect(x-24, y-10, 24, 20, 8, WHITE);
102 display.fillCircle(x-16, y-2, 2, BLACK); display.fillCircle(x-8, y-2, 2, BLACK);
103 display.fillRoundRect(x+4, y-10, 24, 20, 8, WHITE);
104 display.fillCircle(x+12, y-2, 2, BLACK); display.fillCircle(x+20, y-2, 2, BLACK);
105 break;
106
107 case 5: // Two Characters Cuddling
108 display.fillRoundRect(x-18, y-12, 28, 22, 8, WHITE);
109 display.fillCircle(x-8, y-2, 2, BLACK); display.fillCircle(x, y-2, 2, BLACK);
110 display.fillRoundRect(x+6, y-6, 20, 16, 6, WHITE);
111 display.fillCircle(x+12, y, 2, BLACK); display.fillCircle(x+18, y, 2, BLACK);
112 break;
113
114 case 6: // Happy Everywhere
115 display.fillRoundRect(x-16, y-12, 32, 24, 10, WHITE);
116 display.drawLine(x-8, y-2, x-4, y-2, BLACK); display.drawLine(x+8, y-2, x+4, y-2, BLACK);
117 display.fillTriangle(x-5, y+2, x+5, y+2, x, y+8, BLACK);
118 display.fillRoundRect(x-24, y-10, 8, 8, 4, WHITE); display.fillRoundRect(x+16, y-10, 8, 8, 4, WHITE);
119 break;
120
121 case 7: // Waiting / Looking Up
122 display.fillRoundRect(x-16, y-12, 32, 24, 10, WHITE);
123 display.fillCircle(x-8, y-4, 3, BLACK); display.fillCircle(x+2, y-4, 3, BLACK);
124 display.drawLine(x-4, y+6, x+4, y+6, BLACK);
125 break;
126
127 case 8: // Thinking Bubble
128 display.fillRoundRect(x-24, y-8, 24, 20, 8, WHITE);
129 display.fillCircle(x+6, y-10, 3, WHITE); display.fillCircle(x+14, y-16, 4, WHITE);
130 display.fillRoundRect(x+22, y-24, 34, 16, 5, WHITE);
131 display.setTextColor(BLACK);
132 display.setCursor(x+26, y-12); display.print("???");
133 display.setTextColor(WHITE);
134 break;
135
136 case 9: // Strong Flexing
137 display.fillRoundRect(x-16, y-12, 32, 24, 10, WHITE);
138 display.drawLine(x-6, y-2, x-2, y, BLACK); display.drawLine(x+6, y-2, x+2, y, BLACK);
139 display.fillRoundRect(x-26, y-6, 12, 12, 4, WHITE); display.fillRoundRect(x+14, y-6, 12, 12, 4, WHITE);
140 break;
141
142 case 10: // Sinking in Water
143 display.fillRoundRect(x-16, y-12, 32, 24, 10, WHITE);
144 display.fillRoundRect(x-24, y-2, 8, 14, 4, WHITE); display.fillRoundRect(x+16, y-2, 8, 14, 4, WHITE);
145 display.fillRect(0, y+8, 128, 20, BLACK);
146 display.drawLine(0, y+8, 128, y+8, WHITE);
147 for(int i=0; i<128; i+=10) display.drawLine(i, y+12, i+5, y+12, WHITE);
148 break;
149
150 case 11: // Flash lines
151 display.drawCircle(x, y, 15, WHITE);
152 display.drawLine(x, y-20, x, y-30, WHITE); display.drawLine(x, y+20, x, y+30, WHITE);
153 display.drawLine(x-20, y, x-30, y, WHITE); display.drawLine(x+20, y, x+30, y, WHITE);
154 display.drawLine(x-15, y-15, x-22, y-22, WHITE); display.drawLine(x+15, y+15, x+22, y+22, WHITE);
155 break;
156
157 case 12: // Massive Climax
158 display.fillRoundRect(x-22, y-16, 44, 32, 12, WHITE);
159 display.fillCircle(x-10, y-2, 7, BLACK); display.fillCircle(x+10, y-2, 7, BLACK);
160 display.fillCircle(x-11, y-4, 2, WHITE); display.fillCircle(x+9, y-4, 2, WHITE);
161 display.drawLine(x-3, y+8, x+3, y+8, BLACK);
162 break;
163 }
164
165 display.display();
166}