pbnj

snippet #2

#include <MD_MAX72xx.h>
#include <MD_Parola.h>


#include "main.h"



int scrollPosition = 32;  // Start COMPLETELY off-screen right
int currentChar = 0;
unsigned long lastScrollTime = 0;
unsigned long lastCharTime = 0;
int textIndex = 0;
bool textChanged = false;
int lastXOffset = 32;  // Track last position for clearing
int Left =44;

unsigned long currentMillis;






// 8x8 pixel retro game characters - OPTIMIZED FOR VISIBILITY
uint8_t retro[][8] = {
  // Pac-Man (open mouth) - MORE DETAILED
  {0x3C, 0x7E, 0xE7, 0xC3, 0xC3, 0xE7, 0x7E, 0x3C},
  // Pac-Man (closed mouth)
  {0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C},
  // Blinky Ghost (red)
  {0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x5A, 0x7E},
  // Pinky Ghost
  {0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C},
  // Space Invader 1
  {0x18, 0x3C, 0x7E, 0xDB, 0xFF, 0x24, 0x5A, 0x42},
  // Space Invader 2
  {0x18, 0x3C, 0x7E, 0xDB, 0xBD, 0x24, 0x5A, 0x42},
  // Mario - BETTER DETAIL
  {0x18, 0x3C, 0x7E, 0xDB, 0x7E, 0x3C, 0x5A, 0x7E},
  // Luigi
  {0x18, 0x3C, 0x7E, 0xDB, 0x7E, 0x3C, 0x7E, 0x5A},
  // Donkey Kong
  {0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x3C, 0x18},
  // Barrel
  {0x3C, 0x42, 0x81, 0x81, 0x81, 0x81, 0x42, 0x3C},
  // Tetris L-block
  {0x40, 0x40, 0x40, 0x40, 0x7C, 0x7C, 0x7C, 0x7C},
  // Tetris Square
  {0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C},
  // Galaga Ship
  {0x18, 0x3C, 0x7E, 0xFF, 0x7E, 0x3C, 0x18, 0x00},
  // Galaga Enemy
  {0x24, 0x5A, 0xBD, 0xDB, 0xDB, 0xBD, 0x5A, 0x24},
  // Frogger
  {0x18, 0x3C, 0x5A, 0xFF, 0xFF, 0x7E, 0x3C, 0x18},
  // Dig Dug
  {0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x3C, 0x18},
  // Q*bert
  {0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81},
  // Centipede
  {0x66, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00},
  // Missile Command Base
  {0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x3C, 0x18},
  // Asteroids Ship
  {0x18, 0x3C, 0x66, 0xFF, 0xFF, 0x66, 0x3C, 0x18},
  // Defender Ship
  {0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x3C, 0x18},
  // Robotron 2084
  {0x3C, 0x42, 0x99, 0xA5, 0xA5, 0x99, 0x42, 0x3C},
  // Burger Time Chef
  {0x3C, 0x42, 0x81, 0x99, 0x99, 0x81, 0x42, 0x3C},
  // Bubble Bobble Dragon
  {0x3C, 0x42, 0x81, 0x81, 0x81, 0x81, 0x42, 0x3C},
  // Bomberman
  {0x3C, 0x42, 0x99, 0xBD, 0xBD, 0x99, 0x42, 0x3C},
  // Arkanoid Paddle
  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
  // Pong Paddle
  {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
  // Tetris T-block
  {0x00, 0x10, 0x38, 0x7C, 0x10, 0x10, 0x10, 0x00},
  // Zelda Triforce
  {0x18, 0x3C, 0x7E, 0xFF, 0x18, 0x3C, 0x18, 0x00},
  // Metroid Samus
  {0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x3C, 0x18},
  // Castlevania
  {0x00, 0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x00, 0x00},
  // Contra Soldier
  {0x3C, 0x42, 0x81, 0x81, 0x81, 0x81, 0x42, 0x3C},
  // Double Dragon
  {0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x3C, 0x18},
  // Street Fighter Hadouken
  {0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00},
  // Sonic
  {0x3C, 0x42, 0x81, 0x99, 0x81, 0x42, 0x3C, 0x00},
  // Megaman
  {0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x3C, 0x18},
  // Extra Monsters (red/black only)

  // Dracula (Castlevania style)
  {0x3C, 0x42, 0xA5, 0x81, 0xA5, 0x99, 0x42, 0x3C},

  // Frankenstein Monster
  {0x7E, 0xDB, 0xFF, 0xFF, 0xE7, 0xE7, 0xDB, 0x7E},

  // Demon Face
  {0x3C, 0x7E, 0xDB, 0xFF, 0xFF, 0xDB, 0x7E, 0x3C},

  // Skull
  {0x3C, 0x7E, 0xDB, 0xFF, 0xFF, 0xDB, 0x7E, 0x3C},

  // Bat
  {0x18, 0x3C, 0x7E, 0xFF, 0x7E, 0x3C, 0x18, 0x00},

  // Spider
  {0x24, 0x5A, 0xBD, 0xFF, 0xFF, 0xBD, 0x5A, 0x24},

  // Dragon Head
  {0x3C, 0x7E, 0xFF, 0xE7, 0xE7, 0xFF, 0x7E, 0x3C},

  // Ogre
  {0x7E, 0xFF, 0xDB, 0xFF, 0xFF, 0xDB, 0xFF, 0x7E},

  // Zombie
  {0x3C, 0x7E, 0xDB, 0xFF, 0xFF, 0xDB, 0x7E, 0x3C},

  // Alien (Space Invader boss style)
  {0x18, 0x3C, 0x7E, 0xDB, 0xFF, 0xDB, 0x7E, 0x3C},

  // Classic UFO (flying saucer)
  {0x00, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x3C, 0x00},

  // Alien Invader (wide arms)
  {0x18, 0x3C, 0x7E, 0xDB, 0xFF, 0xDB, 0x7E, 0x3C},

  // Alien Crab (Space Invaders style)
  {0x3C, 0x7E, 0xFF, 0x5A, 0x5A, 0xFF, 0x7E, 0x3C},

  // Saucer with beam
  {0x00, 0x3C, 0x7E, 0xFF, 0x7E, 0x3C, 0x18, 0x18},

  // Rocket Ship
  {0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18},

  // Alien Face (big eyes)
  {0x3C, 0x42, 0xA5, 0x81, 0xA5, 0x99, 0x42, 0x3C},

  // UFO with antenna
  {0x00, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x5A, 0x24},

  // Space Fighter (Galaga style)
  {0x18, 0x3C, 0x7E, 0xFF, 0x7E, 0x3C, 0x18, 0x00},

  // Alien Octopus
  {0x3C, 0x7E, 0xFF, 0x5A, 0x5A, 0xFF, 0x7E, 0x3C},

  // Mothership
  {0x7E, 0xFF, 0xDB, 0xFF, 0xFF, 0xDB, 0xFF, 0x7E}

};



const int TOTAL_CHARS = sizeof(retro) / sizeof(retro[0]);

 

// COMPREHENSIVE RETRO GAME NAMES FOR SCROLLING TEXT
const char* gameTexts[] =  {
  "PAC-MAN  *  MS. PAC-MAN  *  GALAGA  *  DONKEY KONG  *  SPACE INVADERS  *  ASTEROIDS  *  DEFENDER  */"
  "CENTIPEDE  *  FROGGER  *  DIG DUG  *  BURGERTIME  *  QBERT  *  JOUST  *  ROBOTRON  *  TETRIS  * /"
  "ARKANOID  *  PONG  *  BREAKOUT  *  TEMPEST  *  STAR WARS  *  TRON  *  ZAXXON  *  BUBBLE BOBBLE  *  /"
  "GHOSTS N GOBLINS  *  DOUBLE DRAGON  *  STREET FIGHTER  *  FINAL FIGHTER  *  CONTRA  *  CASTLEVANIA  *  /"
  "METROID  *  MEGA MAN  *  SONIC  *  MARIO BROS  *  SUPER MARIO  *  ZELDA  *  PUNCH OUT  *  OUTRUN  *  /"
  "AFTER BURNER  *  GYRUSS  *  TIME PILOT  *  1942  *  SPY HUNTER  *  POLE POSITION  *  OUTLAWS  *  /"
  "GAUNTLET  *  RAMPAGE  *  ALTERED BEAST  *  GOLDEN AXE  *  SHINOBI  *  STRIDER  *  /"
  "TEENAGE MUTANT NINJA TURTLES  *  SIMPSONS  *  X-MEN  *  CAPTAIN COMMANDO  *  /"
  "CADILLACS AND DINOSAURS  *  KING OF FIGHTERS  *  METAL SLUG  *  DARKSTALKERS  *  /"
  "MARVEL VS CAPCOM  *  HOUSE OF THE DEAD  *  TIME CRISIS  *  VIRTUA FIGHTER  *  /"
  "TEKKEN  *  SOUL CALIBUR  *  DANCE DANCE REVOLUTION  *  BEATMANIA  /"
  "POKEMON  *  KIRBY'S ADVENTURE  * EARTHBOUND  *  CHRONO TRIGGER * FINAL FANTASY /"
  "QUAKE *  DUKE NUKEM * WOLFENSTEIN 3D * " 
  
};






void drawCharAtPosition(uint8_t charData[8], int xOffset) {
  // SIMPLIFIED - Only clear the column that's being left behind
  int columnToClear = xOffset + 8;  // The column RIGHT of the character
  
  if (columnToClear >= 0 && columnToClear < Left) {
    for (int y = 0; y < 8; y++) {
      mx2.setPoint(y, columnToClear, false);
    }
  }
  
  // Draw the 8x8 character at current position
  for (int x = 0; x < 8; x++) {
    int displayX = x + xOffset;
    if (displayX >= 0 && displayX < Left) {
      for (int y = 0; y < 8; y++) {
        bool pixelOn = (charData[y] >> (7 - x)) & 0x01;
        mx2.setPoint(y, displayX, pixelOn);
      }
    }
  }
}

void anime1()
{

  
  // ===== PANEL 1: GAME NAMES SCROLLING =====
  if (parola.displayAnimate()) {
    parola.displayReset();
    textChanged = true;
  }
  
  // Change text occasionally for variety
  if (textChanged && (currentMillis % (TEXT_CHANGE_MIN * 60000) == 0)) {
    textIndex = (textIndex + 1) % (sizeof(gameTexts) / sizeof(gameTexts[0]));
    parola.displayText(gameTexts[textIndex], PA_CENTER, 0, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
    textChanged = false;
    
    // LED effect for text change
    for (int i = 0; i < 3; i++) {
      digitalWrite(LED_BUILTIN, HIGH);
      delay(100);
      digitalWrite(LED_BUILTIN, LOW);
      delay(100);
    }
  }
  
  // ===== PANEL 2: CHARACTER SCROLLING =====
  // Update scroll position
  if (currentMillis - lastScrollTime >= SCROLL_SPEED_MS) {
    scrollPosition--;
    lastScrollTime = currentMillis;
    
    // Draw character at current position
    drawCharAtPosition(retro[currentChar], scrollPosition);
    
    // Check if character has completely scrolled off screen LEFT side
     if (scrollPosition <= -OFFSCREEN_BUFFER) {
 
      scrollPosition = 32;  // Reset to off-screen right
      currentChar = (currentChar + 1) % TOTAL_CHARS;
      
      // Clear the entire display before starting new character
      mx2.clear();
      
      // LED feedback for character change
      digitalWrite(LED_BUILTIN, HIGH);
      delay(10);
      digitalWrite(LED_BUILTIN, LOW);
      
      Serial.print("Character changed to: ");
      Serial.println(currentChar);
    }
  }
  
  // Change character automatically every few seconds
  if (currentMillis - lastCharTime >= CHAR_CHANGE_MS) {
    currentChar = (currentChar + 1) % TOTAL_CHARS;
    lastCharTime = currentMillis;
    scrollPosition = 32;  // Restart from off-screen right
    mx2.clear();  // Clear display for fresh start
    
    // Double blink for character change
    digitalWrite(LED_BUILTIN, HIGH);
    delay(30);
    digitalWrite(LED_BUILTIN, LOW);
    delay(30);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(30);
    digitalWrite(LED_BUILTIN, LOW);
    
    Serial.print("Auto character change to: ");
    Serial.println(currentChar);
  }

}