19 Replies Latest reply on Oct 14, 2020 4:45 PM by Christopher Stanton

    Deciphering Arduino Code

    dlnxdaman

      Hey everyone,

       

      I am new to this community and was hoping I could work with someone (or a few people) in helping me to understand a program that was written. I am new to Arduino, and have done around 30 lesson from Paul Mcwhorter on Youtube, but there is a lot of differences in the terms used and the commands used that weren't brought up in the tutorials I watched. So I was wondering if anyone would be willing to meet via Zoom and talk the code through with me so I can understand what controls what? Or, if more preferable, we could discuss the code here in a thread!

       

      The code is actually a program written by one of the main contributors to this website, DJ Harrigan, and the program is for his Tomodachi (Tamagotchi spin-off) project. I came across his YouTube video while searching how to start creating the very same type of code in Arduino that he already had developed, but I need to understand all of the components so I can rework the entire thing into a project I am trying to combine with my ceramic artwork. I am a graduate student working toward my MFA in ceramics in the US and am trying to implement some new ways of incorporating technology with clay/ceramics.

       

      If anyone is interested in helping me on this endeavor let me know! I would really appreciate it! Of course, we won't need to go over the entire code in one sitting, but just knowing someone could help guide me in this process would be an immense relief!

       

      The code is attached at the bottom!

       

      Thanks for your time!

      -Dylan F.

       

      #include <Arduino.h>
      #include <U8g2lib.h>
      #include <SPI.h>
      #include <Bounce2.h>
      #include <armus.h>
      
      
      #define PIN_PIEZO 5
      #define PIN_BTN_LEFT 6
      #define PIN_BTN_RIGHT 9
      #define PIN_BTN_OK 10
      
      
      #define X_WIDTH 128
      #define Y_HEIGHT 64
      #define TEMPO 400
      #define MAX_LEVEL 3
      #define MAX_POWER 8
      
      
      U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 11, /* dc=*/ 13, /* reset=*/ 12);
      Bounce btnLeft = Bounce();
      Bounce btnRight = Bounce(); 
      Bounce btnOk = Bounce();
      ArMus piezo(PIN_PIEZO, TEMPO);
        
      enum gamestate {
        home,
        viewTomo,
        minigame,
        stats
      };
      
      
      gamestate curState = home;
      gamestate lastState = viewTomo;
      boolean displayInverted = false;
      
      
      int curSelection = 0;
      int lastSelection = -1;
      char mIntro[] = "-3C -2C -1C C";
      char mBeep[] = "C*";
      char mOk[] = "2C 3C*";
      char mBack[] = "3C 2C*";
      char mSuccess[] = "2C 2C 2C 3C*";
      char mLevelUp[] = "C C C 1C* 2C 2C 2C 3C*";
      char mFailure[] = "F F -2F2";
      
      
      char *tomoText[] = {"charging up...", "leveling up!", "missing!", "tired.", "strong."};
      int tomoAction = 0; // placeholder for future
      boolean tomoIsLevelingUp = false;
      int tomoLevel = 0;
      int tomoPower = 6; // experience
      int tomoFrame = 0; // frame of animation
      unsigned long curTime = 0;
      unsigned long lastTime = -1;
      int animationInterval = 800;
      
      
      // Minigame vars
      boolean minigameAvailable = true;
      int minigameLives = 3;
      int minigameScore = 0;
      int curMinigame = 0;
      int minigameCountdown = 9;
      boolean minigameCountdownActive = false;
      //u8g2 u8g2_font_open_iconic_all_2x_t
      int symbolList[] = {104, 152, 223, 175, 168, 259, 96, 193}; // bug, drop, moon, earth, fire, suns, bolt, key 
      
      
      
      
      // ******************************** PowerGo ******************************** 
      int powerGoPresses = 0;
      int powerGoCountdownInterval = 70;
      boolean powerGoLocation = 0;
      
      
      // ******************************** MemoSym ********************************
       enum memoSymState {
        msRevealed, msHidden, msIncorrect, msCorrect
      };
      const char memoSymSelMax = 8;
      int memoSymIcons[] = {104, 152, 223, 175, 168, 259, 96, 193}; // bug, drop, moon, earth, fire, suns, bolt, key 
      int memoSymIconsOrder[] = {0, 1, 2, 3, 4, 5, 6, 7};
      memoSymState memoSymStates[] = {msRevealed, msRevealed, msRevealed, msRevealed, msRevealed, msRevealed, msRevealed, msRevealed}; 
      //99 = box, 120=correct button, 121=incorrect button
      int memoSymGuessCount = 0;
      int memoSymIconToGuess = 0;
      
      
      // ******************************** StackIt ********************************
      int stackItBallRad = 4;
      int stackItBallDir = -1;
      int stackItBallXPos = 64;
      int stackItLastBallXPos = -1;
      int stackItBallYPos = 59;
      int stackItBallYOffset = 0;
      int stackItUpdateInterval = 65;
      int stackItHeight = 0;
      
      
      // ******************************** StackIt ********************************
      int lucky64ReelIcons[] = {224, 228, 232, 236};
      int lucky64ReelOffset = 0;
      int lucky64ReelsStopped = 0;
      int lucky64UpdateInterval = 333;
      
      
      void setup(void){ // **************************************************************** BEGIN SETUP ****************************************************************
      
      
        Serial.begin(115200);
        u8g2.begin();
        u8g2_prepare();
        u8g2.setFont(u8g2_font_nokiafc22_tf); 
        drawStrCentered(0, "Element14 Presents");
        u8g2.setFont(u8g2_font_sticker_mel_tr);
        drawStrCentered(20, "TOMODACHI");
        u8g2.setFont(u8g2_font_nokiafc22_tf);
        drawStrCentered(48, "Digital friend!");
        u8g2.sendBuffer();
        piezo.playMelody(mIntro);
        pinMode(PIN_BTN_LEFT, INPUT_PULLUP);
        pinMode(PIN_BTN_RIGHT, INPUT_PULLUP);
        pinMode(PIN_BTN_OK, INPUT_PULLUP);
        btnLeft.attach(PIN_BTN_LEFT);
        btnLeft.interval(8);
        btnRight.attach(PIN_BTN_RIGHT);
        btnRight.interval(8);
        btnOk.attach(PIN_BTN_OK);
        btnOk.interval(8);
        while(true){ // hang in the splash screen
          btnOk.update();
          if (btnOk.fell()){
            piezo.playMelody(mOk);
            flashDisplay(8);
            break; 
          }
        }
        
        
      }
      
      
      void flashDisplay(int flashes){
        for (int ii = 0; ii < flashes; ii++){
          invertDisplay();
          delay(100);
        }
      }
      
      
      void getInput(){
        btnLeft.update();
        btnRight.update();
        btnOk.update();
        if (btnOk.fell() || btnLeft.fell() || btnRight.fell()) piezo.playMelody(mBeep); //enable sound
      }
      
      
      void u8g2_prepare(void) {
        u8g2.setFontRefHeightExtendedText();
        u8g2.setDrawColor(1);
        u8g2.setFontPosTop();
        u8g2.setFontDirection(0);
      }
      
      
      void drawStrCentered(int yVal, const char *text){
        u8g2.drawStr((X_WIDTH - u8g2.getStrWidth(text)) >> 1, yVal, text);
      }
      
      
      void drawTomo(int xPos, int yPos, int curLevel, int frame){
        
        // Body
        u8g2.drawBox(xPos-2, yPos, 4, 8+(6*curLevel)); // vertical line
        u8g2.drawBox(xPos-12, yPos-6, 24, 6); // horizontal line
        
        // Upgrades
        if (curLevel >= 1){ // +antennae
          u8g2.drawVLine(xPos-11, yPos-11, 5); // L
          u8g2.drawVLine(xPos+10, yPos-11, 5); // R
        }
        if (curLevel >= 2){ // +fancy antennae
          u8g2.drawCircle(xPos-11, yPos-13, 2); // L
          u8g2.drawCircle(xPos+10, yPos-13, 2); // R
        }
        if (curLevel >= 3){ // +arms
          u8g2.drawLine(xPos-3, yPos+10, xPos-8, yPos+7); // L
          u8g2.drawLine(xPos+2, yPos+10, xPos+7, yPos+7); // R
        }
        
        // Eyes
        u8g2.setDrawColor(0);
        if (frame){
          u8g2.drawVLine(xPos-9, yPos-4, 2); // left eye
          u8g2.drawVLine(xPos+10, yPos-4, 2); // right eye
        } else {
          u8g2.drawVLine(xPos-10, yPos-4, 2); // left eye
          u8g2.drawVLine(xPos+9, yPos-4, 2); // right eye
        }
        u8g2.setDrawColor(1);
      }
      
      
      void invertDisplay(){ // default to flash
        displayInverted = !displayInverted;
        if (displayInverted){
          u8g2.sendF("c", 0x0a7); // inverse
        } else {
          u8g2.sendF("c", 0x0a6); // normal
        }
      }
      
      
      void drawLives(int tempLives){
        u8g2.setDrawColor(0);
        u8g2.drawBox(0, 13, 25, 10);
        u8g2.setDrawColor(1);
        u8g2.setFont(u8g2_font_nokiafc22_tf);
        u8g2.setCursor(0, 13);
        for (int ii = 0; ii < tempLives; ii++){
          u8g2.print("T"); // full battery
        }
        u8g2.sendBuffer();
      }
      
      
      void drawScore(int tempScore){
        u8g2.setDrawColor(0);
        u8g2.drawBox(128-10, 13, 16, 16);
        u8g2.setDrawColor(1);
        u8g2.setFont(u8g2_font_nokiafc22_tf);
        u8g2.setCursor(128-7, 13);
        u8g2.print(tempScore);
        u8g2.sendBuffer();
      }
      
      
      void drawPowerGo(){
        u8g2.setFont(u8g2_font_freedoomr25_mn);
        u8g2.setDrawColor(0);
        u8g2.drawBox(18, 25, 30, 39);
        u8g2.setDrawColor(1);
        u8g2.setCursor(64-9, 32-6);
        u8g2.print(powerGoPresses);
        u8g2.sendBuffer();
        u8g2.setFont(u8g2_font_open_iconic_all_2x_t);
      }
      
      
      void memoSymNewPattern(){
        randomSeed(analogRead(A1));
        int tempIcon = 0;
        for (int ii = 0; ii < 8; ii++){ // shuffled the symbols in place
          tempIcon = memoSymIcons[ii];
          long randIndex = random(8);
          memoSymIcons[ii] = memoSymIcons[randIndex];
          memoSymIcons[randIndex] = tempIcon;
        }
        for (int ii = 0; ii < 8; ii++){ // create a random list of indexes for the current symbol to find
          tempIcon = memoSymIconsOrder[ii];
          long randIndex = random(8);
          memoSymIconsOrder[ii] = memoSymIconsOrder[randIndex];
          memoSymIconsOrder[randIndex] = tempIcon;
        }
      
      
      }
      
      
      void memoSymDrawPattern(){
      
      
        int iconToDraw = 0;
        u8g2.setFont(u8g2_font_open_iconic_all_2x_t);
        //clear area
        u8g2.setDrawColor(0);
        if (!minigameCountdownActive)u8g2.drawBox(56, 13, 16, 16); // clear prompt symbol
        u8g2.drawBox(0, 32, 128, 16); // clear prompt symbol
        u8g2.setDrawColor(1);
        if (!minigameCountdownActive)u8g2.drawGlyph(56, 13, memoSymIcons[memoSymIconsOrder[memoSymGuessCount]]); // show a random index of the symbol array
        for (int ii = 0; ii < 8; ii++){
          switch (memoSymStates[ii]){
            case msRevealed:
              iconToDraw = memoSymIcons[ii];
            break;
            case msHidden:
              iconToDraw = 99; // box
            break;
            case msIncorrect:
              iconToDraw = 121; // x button
            break;
            case msCorrect:
              iconToDraw = 120; // check button
            break;
          }
          u8g2.drawGlyph(ii*16, 32, iconToDraw);
        }
        u8g2.sendBuffer();
      }
      
      
      void memoSymClearCursor(){
        u8g2.setDrawColor(0);
        u8g2.drawBox(16*curSelection, 50, 16, 16);
        u8g2.setDrawColor(1);
      }
      
      
      void memoSymDrawCursor(){
        u8g2.setFont(u8g2_font_open_iconic_all_2x_t);
        u8g2.drawGlyph(16*curSelection, 50, 82); // up arrow symbol
        u8g2.sendBuffer();
      }
      
      
      void memoSymSetPattern(memoSymState tempState){
        for (int ii = 0; ii < 8; ii++){
          memoSymStates[ii] = tempState;
        }
      }
      
      
      void memoSymUpdateCounter(){
        u8g2.setFont(u8g2_font_freedoomr10_tu);
        u8g2.setDrawColor(0);
        u8g2.drawBox(56, 13, 17, 17);
        u8g2.setDrawColor(1);
        u8g2.setCursor(61, 15);
        u8g2.print(minigameCountdown);
        u8g2.sendBuffer();
        u8g2.setFont(u8g2_font_open_iconic_all_2x_t);
      }
      
      
      void minigameScoreIncrease(int pts, int maxLevel){
        minigameScore+=pts;
        if (minigameScore > maxLevel){
          piezo.playMelody(mSuccess);
          tomoPower++; 
          checkTomoLevel();// test for level up!
          curState = stats;
          getInput(); // avoid triggering menu 
        } else {
          drawScore(minigameScore);
          piezo.playMelody(mOk); 
        }
      }
      
      
      void minigameLoseLife(){
        minigameLives--;
        if (minigameLives < 1){
          piezo.playMelody(mFailure);
          curState = home;
          getInput();
          delay(600);
        } else {
          piezo.playMelody(mBack);
          drawLives(minigameLives);                      
        }
      }
      
      
      void stackItClearBall(){
        u8g2.setDrawColor(0);
        u8g2.drawBox(stackItBallXPos-stackItBallRad, stackItBallYPos-stackItBallRad-stackItBallYOffset, 9, 9);
        u8g2.setDrawColor(1);
      }
      
      
      void stackItDrawBall(){
        u8g2.drawCircle(stackItBallXPos, stackItBallYPos - stackItBallYOffset, stackItBallRad);
      }
      
      
      void stackItReset(){
        stackItBallXPos = 64;
        stackItLastBallXPos = -1;
        stackItBallYPos = 59;
        stackItBallYOffset = 0;
        stackItUpdateInterval = 80;
        stackItHeight = 0;
      }
      
      
      void lucky64ClearReels(){
        u8g2.setDrawColor(0);
        u8g2.drawBox(20+(24*lucky64ReelsStopped), 24, 128, 17);
        u8g2.setDrawColor(1);
      }
      
      
      void lucky64DrawReels(){
        u8g2.setFont(u8g2_font_open_iconic_all_2x_t);
        for (int ii = 0; ii < 4; ii++){
          u8g2.drawGlyph(20+(24*ii), 24, lucky64ReelIcons[ii]);
        }
        u8g2.sendBuffer();
      }
      
      
      void lucky64Reset(){
        for (int ii = 0; ii < 4; ii++){
          lucky64ReelIcons[ii] = 224 + (4 * ii);
        }
        lucky64ReelOffset = 0;
        lucky64ReelsStopped = 0;
      }
      
      
      void checkTomoLevel(){
        if (tomoPower >= MAX_POWER && tomoLevel < MAX_LEVEL){
          tomoIsLevelingUp = true;
          curState = viewTomo;
        } else {
          tomoPower = MAX_POWER;
        }
      }
      
      
      void loop() { // **************************************************************** BEGIN MAIN LOOP ****************************************************************
        
        getInput();
        curTime = millis();
        // u8g2.clear();
        // First switchcase handles one-time drawing
        if (curState != lastState){
          u8g2.clear();
          u8g2.setFont(u8g2_font_nokiafc22_tf);      
          switch (curState){
            case home:
              //print menu        
              minigameScore = 0;
              curSelection = 0;
              curMinigame = 0;
              minigameCountdown = 9; 
              minigameLives = 3;
              u8g2.setFont(u8g2_font_sticker_mel_tr);
              u8g2.drawStr(18, 1, "PowerGo");
              u8g2.drawStr(18, 33, "MemoSym");
              u8g2.drawStr(18, 17, "StackIt");
              u8g2.drawStr(18, 49, "Lucky64");
              u8g2.setFont(u8g2_font_open_iconic_all_2x_t);
              u8g2.drawGlyph(0, 16*curSelection, 75); // right arrow button
              //select menu
              if (lastState == minigame){
                minigameAvailable = false;
              }
            break;
            case viewTomo:
              minigameAvailable = true;
              drawStrCentered(0, "Tomo is:");
              drawStrCentered(12, tomoText[tomoAction]);
              drawTomo(X_WIDTH>>1, 8+(Y_HEIGHT>>1), tomoLevel, tomoFrame);
              while (tomoIsLevelingUp){
                u8g2.clear();
                u8g2.setFont(u8g2_font_nokiafc22_tf); 
                drawStrCentered(0, "Tomo is:");
                delay(700);
                u8g2.sendBuffer();
                u8g2.setFont(u8g2_font_sticker_mel_tr);
                drawStrCentered(14, "MAXED OUT!");
                piezo.playMelody(mLevelUp); 
                delay(200);
                u8g2.sendBuffer();
                flashDisplay(18);
                for (int ii = 0; ii < 10; ii++){
                  u8g2.clear();
                  drawTomo(X_WIDTH>>1, 8+(Y_HEIGHT>>1), tomoLevel, tomoFrame);
                  u8g2.sendBuffer();            
                  flashDisplay(1);
                  delay(100);            
                  u8g2.clear();
                  drawTomo(X_WIDTH>>1, 8+(Y_HEIGHT>>1), tomoLevel+1, tomoFrame);
                  flashDisplay(1);
                  delay(100);            
                  u8g2.sendBuffer();
                }
                tomoLevel+=1;
                delay(1000);
                u8g2.clear();
                drawTomo(X_WIDTH>>1, 8+(Y_HEIGHT>>1), tomoLevel, tomoFrame);
                u8g2.sendBuffer();
                tomoIsLevelingUp = false;
                curState = stats;
                tomoPower = 0;
              }
            break;
            case minigame:
              u8g2.drawHLine(0, 11, X_WIDTH);
              drawLives(minigameLives);
              drawScore(minigameScore);
              switch (curMinigame){
                case 0: // PowerGo
                  drawStrCentered(0, "PowerGo: win 1 battery");
                  drawPowerGo(); 
                break;
                case 1: // StackIt
                  drawStrCentered(0, "StackIt: win 2 batteries");
                  u8g2.drawVLine(32, 12, 52); // Borders
                  u8g2.drawVLine(91, 12, 52);
                  stackItReset();
                  stackItDrawBall();
                break;
                case 2: // MemoSym
                  drawStrCentered(0, "MemoSym: win 3 batteries");
                  memoSymNewPattern();
                  memoSymSetPattern(msRevealed);
                  memoSymUpdateCounter();
                  memoSymDrawPattern();
                  curSelection = 0;
                  memoSymGuessCount = 0;
                  minigameCountdownActive = true;
                  memoSymDrawCursor();
                break;
                case 3: // Lucky64
                  drawStrCentered(0, "Lucky64: win X batteries");
                  lucky64Reset();
                  lucky64DrawReels();
                break;
              }
              // on game end, gain power and level up
            break;
            case stats:
              drawStrCentered(0, "Statistics");
              u8g2.setFont(u8g2_font_sticker_mel_tr);
              // Level
              u8g2.drawStr(0, 20, "LVL;"); // semicolon is swapped with colon in this font
              u8g2.setCursor(42, 20);
              u8g2.print(tomoLevel);
              u8g2.drawStr(0, 46, "PWR;");
              u8g2.setFont(u8g2_font_battery19_tn);
              u8g2.setCursor(46, 42);
              for (int ii = 0; ii < MAX_POWER; ii++){
                if (tomoPower >= ii){
                  u8g2.print("5"); // full battery
                } else {
                  u8g2.print("0"); // empty battery
                }  
              }
            break;
            default:
            break;
          }
          lastState = curState;
          u8g2.sendBuffer();
        }
      
      
        // Second switchcase processes input events
        switch (curState){ // **************************************************************** HANDLE INPUT ****************************************************************
          case home:
            if (btnOk.rose()){
              u8g2.setDrawColor(0);
              u8g2.drawBox(0, 16*curSelection, 16, 16+(16*curSelection));
              curSelection++;
              if (curSelection>3)curSelection = 0;
              u8g2.setDrawColor(1);
              u8g2.drawGlyph(0, 16*curSelection, 75);
              u8g2.sendBuffer();
            }
            if (btnOk.read() == 0 && btnOk.duration() > 1200 && minigameAvailable){
              curState = minigame;
              curMinigame = curSelection;
              piezo.playMelody(mOk);
            }
            if (btnLeft.fell()){
              curState = viewTomo;
            }
            if (btnRight.fell()){
              curState = stats;
            }
          break;
          case viewTomo:
            if (btnOk.fell()){
              // play with Tomo?
              minigameAvailable = true;
              piezo.playMelody(mOk);
            }
            if (btnLeft.fell()){
              curState = stats;
            }
            if (btnRight.fell()){
              curState = home;
            }
            if (curTime - lastTime > animationInterval){
              tomoFrame = !tomoFrame;
              drawTomo(X_WIDTH>>1, 8+(Y_HEIGHT>>1), tomoLevel, tomoFrame);
              u8g2.sendBuffer();
              lastTime = curTime;
            }
          break;
          case minigame:
            
            switch (curMinigame){
                case 0: // PowerGo
                  if (btnOk.fell()){
                    if (minigameCountdownActive == false){
                      powerGoPresses++;
                      drawPowerGo();
                    }
                    if (powerGoPresses >= 9 && minigameCountdownActive == false){
                      minigameCountdownActive = true;
                      drawPowerGo();
                      //choose random symbol
                      randomSeed(analogRead(0));
                      long randomSide = random(100);
                      Serial.print("randomSide ");
                      Serial.println(randomSide);
                      if (randomSide<50){ // draw left side
                        powerGoLocation = 0;
                        u8g2.drawGlyph(0, 28, 104); // bug
                        u8g2.drawGlyph(X_WIDTH-16, 28, 96); // bolt
                      } else {
                        powerGoLocation = 1;
                        u8g2.drawGlyph(X_WIDTH-16, 28, 104); // bug
                        u8g2.drawGlyph(0, 28, 96); // bolt
                      }
                      u8g2.sendBuffer();
                    }
                  }
                  if (minigameCountdownActive){
                    if (btnLeft.fell() && powerGoLocation){ // Did you press on a lightning bolt on the correct side?
                      if (powerGoLocation){
                        powerGoPresses = 0;
                        minigameCountdownActive = false;
                        u8g2.setDrawColor(0);
                        u8g2.drawBox(0, 25, X_WIDTH, 39);
                        u8g2.setDrawColor(1);
                        minigameScore++;
                        if (minigameScore > 9){
                          piezo.playMelody(mSuccess);
                          tomoPower++;
                          checkTomoLevel();
                          flashDisplay(6);
                          curState = home; 
                        } else {
                          drawScore(minigameScore);
                          piezo.playMelody(mOk); 
                          drawPowerGo();  
                        }              
                      } else { 
                        minigameLoseLife();
                      }
                      minigameCountdownActive = false;
                    }
                    if (btnRight.fell()){ // Did you press on a lightning bolt on the correct side?
                      if (!powerGoLocation){
                        powerGoPresses = 0;
                        minigameCountdownActive = false;
                        u8g2.setDrawColor(0);
                        u8g2.drawBox(0, 25, X_WIDTH, 39);
                        u8g2.setDrawColor(1);
                        minigameScore++;
                        if (minigameScore > 9){
                          piezo.playMelody(mSuccess);
                          tomoPower++;
                          checkTomoLevel();
                          curState = home; 
                        } else {
                          drawScore(minigameScore);
                          piezo.playMelody(mOk); 
                          drawPowerGo();  
                        }
                      } else { 
                        minigameLoseLife();
                      }
                      minigameCountdownActive = false;
                    }
      
      
                    if (curTime - lastTime > powerGoCountdownInterval && minigameCountdownActive){ // seems redundant, but can lose two lives quickly otherwise
                      powerGoPresses--;
                      if (powerGoPresses < 0){
                        powerGoPresses = 0;
                        minigameCountdownActive = false;
                        u8g2.setDrawColor(0);
                        u8g2.drawBox(0, 25, X_WIDTH, 39);
                        u8g2.setDrawColor(1);
                        minigameLoseLife();
                      }
                      drawPowerGo();
                      lastTime = curTime;
                    }
                  }
                break;
                case 2: // MemoSym
                  if (btnOk.fell() && !minigameCountdownActive){
                    if (memoSymIcons[curSelection] == memoSymIcons[memoSymIconsOrder[memoSymGuessCount]]){
                      memoSymStates[curSelection] = msCorrect;
                      minigameScoreIncrease(1, 8); 
                    } else {
                      memoSymStates[curSelection] = msIncorrect;
                      minigameLoseLife();
                    }
                    // guesses increase
                    memoSymGuessCount++;
                    if (memoSymGuessCount > 7){
                      piezo.playMelody(mSuccess);
                      tomoPower+=3;
                      curState = home; 
                      checkTomoLevel();
                      flashDisplay(6);
                      
                    }
                    memoSymDrawPattern();
                  }
                  if (btnLeft.fell()){
                    memoSymClearCursor();
                    curSelection--;
                    if (curSelection < 0) curSelection = 7;
                    memoSymDrawCursor();
                  }
                  if (btnRight.fell()){
                    memoSymClearCursor();
                    curSelection++;
                    if (curSelection > 7) curSelection = 0;
                    memoSymDrawCursor();
                  }
                  if (curTime - lastTime > 1000 && minigameCountdownActive){
                    minigameCountdown--;
                    if (minigameCountdown < 0){
                      // hide boxes
                      memoSymSetPattern(msHidden);                
                      minigameCountdownActive = false;
                    } else {
                      memoSymUpdateCounter();
                    }
                    memoSymDrawPattern();
                    lastTime = curTime;
                  }
                  
                break;
                case 1: // StackIt
                  if (curTime - lastTime > stackItUpdateInterval){
                    stackItClearBall();
                    stackItBallXPos += stackItBallDir;
                    if (stackItBallXPos < 38 || stackItBallXPos > 85){ 
                     stackItBallDir *= -1;
                    }
                    stackItDrawBall();
                    u8g2.sendBuffer();
                    lastTime = curTime;
                  }
                  if (btnOk.fell()){
                    //test stackable
                    if (stackItHeight == 0){
                      stackItLastBallXPos = stackItBallXPos;
                      stackItBallYOffset += 9;
                      stackItUpdateInterval -= 16;
                      stackItHeight++;
                    } else if (stackItBallXPos > (stackItLastBallXPos-3) && stackItBallXPos < (stackItLastBallXPos+3)){
                      stackItLastBallXPos = stackItBallXPos;
                      stackItBallYOffset += 9;
                      stackItUpdateInterval -= 16;
                      stackItHeight++;
                      if (stackItHeight > 4){
                        piezo.playMelody(mSuccess); // turn into generic minigame success threshold function
                        tomoPower+=2;
                        flashDisplay(4);
                        curState = home;
                        checkTomoLevel();// test level up
                      }
                    } else {
                      minigameLoseLife();
                      delay(400);
                    }
                  }
                  if (btnLeft.fell()){ // placeholder
                  }
                  if (btnRight.fell()){ // placeholder
                  }
                  
                break;
                case 3: // Lucky64
                  if (curTime - lastTime > lucky64UpdateInterval){
                    lucky64ClearReels();
                    for (int ii = lucky64ReelsStopped; ii < 4; ii++){ // update the active reels
                      lucky64ReelIcons[ii]++;
                      
                      if (lucky64ReelIcons[ii] > 239) lucky64ReelIcons[ii] = 224;
                    }
                    lucky64DrawReels();
                    lastTime = curTime;
                  }
                  if (btnOk.fell()){
                    lucky64ReelsStopped++;
                    if (lucky64ReelsStopped > 3){ // test matches
                      if (lucky64ReelIcons[0] == lucky64ReelIcons[1]){                  
                        minigameScoreIncrease(1, 4);
                        if (lucky64ReelIcons[0] == lucky64ReelIcons[2]){
                          minigameScoreIncrease(1, 4);
                          if (lucky64ReelIcons[0] == lucky64ReelIcons[3]){
                            minigameScoreIncrease(2, 4);
                          }
                        }
                      } else {
                        minigameLoseLife();
                        lucky64Reset();
                      }
                    }              
                  }
                  if (btnLeft.fell()){ // placeholder
                  }
                  if (btnRight.fell()){ // placeholder
                  }
                break;
              }
              // on game end, check for level up
          break;
          case stats:
            if (btnOk.fell()){
              // interact with stats? different view?
              //piezo.playMelody(mBack);
            }
            if (btnLeft.fell()){
              curState = home;
            }
            if (btnRight.fell()){
              curState = viewTomo;
            }
          break;
        }
        //
      
        
      }