#include "display.h" #include "config.h" #include "game_logic.h" #include #include #include static Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); static unsigned long lastUpdateMs = 0; // ── Screens ───────────────────────────────────────────────────────── static void screenSplash() { oled.clearDisplay(); oled.setTextColor(SSD1306_WHITE); oled.setTextSize(2); oled.setCursor(8, 10); oled.print("HEISSER"); oled.setCursor(20, 30); oled.print("DRAHT"); oled.setTextSize(1); oled.setCursor(48, 52); oled.print(VERSION_STR); oled.display(); } static void screenIdle() { oled.clearDisplay(); oled.setTextColor(SSD1306_WHITE); oled.setTextSize(2); oled.setCursor(8, 5); oled.print("HEISSER"); oled.setCursor(20, 23); oled.print("DRAHT"); // Blinking "Druecke START" if ((millis() / 500) % 2 == 0) { oled.setTextSize(1); oled.setCursor(12, 50); oled.print("Druecke START"); } oled.display(); } static void screenCountdown() { GameData& gd = gameGetData(); oled.clearDisplay(); oled.setTextColor(SSD1306_WHITE); if (gd.countdownValue > 0) { oled.setTextSize(4); oled.setCursor(52, 16); oled.print(gd.countdownValue); } else { oled.setTextSize(3); oled.setCursor(36, 20); oled.print("GO!"); } oled.display(); } static void screenPlaying() { GameData& gd = gameGetData(); oled.clearDisplay(); oled.setTextColor(SSD1306_WHITE); // Timer MM:SS unsigned long remainMs = 0; unsigned long totalMs = (unsigned long)GAME_DURATION_S * 1000UL; if (gd.elapsedMs < totalMs) remainMs = totalMs - gd.elapsedMs; uint8_t mins = (remainMs / 1000) / 60; uint8_t secs = (remainMs / 1000) % 60; oled.setTextSize(1); oled.setCursor(0, 0); oled.print("Zeit: "); if (mins < 10) oled.print('0'); oled.print(mins); oled.print(':'); if (secs < 10) oled.print('0'); oled.print(secs); // Strikes oled.setCursor(0, 14); oled.print("Fehler: "); oled.print(gd.strikes); oled.print('/'); oled.print(MAX_STRIKES); // Score (large) oled.setTextSize(3); oled.setCursor(10, 34); oled.print(gd.score); oled.display(); } static void screenGameOver() { GameData& gd = gameGetData(); oled.clearDisplay(); oled.setTextColor(SSD1306_WHITE); oled.setTextSize(1); oled.setCursor(20, 0); oled.print(gd.won ? "GESCHAFFT!" : "GAME OVER!"); // Final score oled.setTextSize(2); oled.setCursor(10, 14); oled.print("Score:"); oled.print(gd.score); // Stats oled.setTextSize(1); unsigned long totalSec = gd.elapsedMs / 1000; oled.setCursor(0, 36); oled.print("Zeit: "); oled.print(totalSec); oled.print("s Fehler: "); oled.print(gd.strikes); // Restart hint (blinking) if ((millis() / 600) % 2 == 0) { oled.setCursor(8, 54); oled.print("START = Nochmal"); } oled.display(); } // ── Public API ────────────────────────────────────────────────────── void displayInit() { Wire.begin(PIN_SDA, PIN_SCL); if (!oled.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) { Serial.println("[OLED] Init FAILED"); return; } Serial.println("[OLED] Init OK"); screenSplash(); delay(1500); } void displayUpdate() { unsigned long now = millis(); if (now - lastUpdateMs < DISPLAY_UPDATE_MS) return; lastUpdateMs = now; GameData& gd = gameGetData(); switch (gd.state) { case STATE_IDLE: screenIdle(); break; case STATE_COUNTDOWN: screenCountdown(); break; case STATE_PLAYING: screenPlaying(); break; case STATE_GAME_OVER: screenGameOver(); break; } }