/*
  
  binary hero
  
  
  
  
  Hardware part
  
  +5V--------------------------------------------------
     |      |      |      |      |      |      |      |  
     |      |      |      |      |      |      |      |     
     +-/    + /    + /    + /    + /    + /    + /    + /   
      /      /      /      /      /      /      /      /      
     /      /      /      /      /      /      /      /      
     |      |      |      |      |      |      |      |      
     +-D2   +-D3   +-D4   +-D5   +-D6   +-D7   +-D10  +-D11   
     |      |      |      |      |      |      |      |      
     -      -      -      -      -      -      -      -      
    |R|    |R|    |R|    |R|    |R|    |R|    |R|    |R|   
    |1|    |1|    |1|    |1|    |1|    |1|    |1|    |1|   
     -      -      -      -      -      -      -      -     
     |      |      |      |      |      |      |      |      
     |      |      |      |      |      |      |      |      
  GND--------------------------------------------------
  
  
  
  
  
  +5V------------------------------------
     |      |      |      |      |      |  
     |      |      |      |      |      |     
     +-/    +-/    + /    + /    + /    + /   
   [--/      /      /      /      /      /       
     /      /      /      /      /      /        
     |      |      |      |      |      |        
     +-D12  +-D13  +-A0   +-A1   +-A2   +-A3   
     |      |      |      |      |      |         
     -      -      -      -      -      -         
    |R|    |R|    |R|    |R|    |R|    |R|     
    |1|    |1|    |1|    |1|    |1|    |1|    
     -      -      -      -      -      -        
     |      |      |      |      |      |         
     |      |      |      |      |      |         
  GND------------------------------------
  
  
      
  D8-|    D8-|
     |       |
     _       _
    \ /     \ /
     -       -
     |       | 
     -       -  
    |R|     |R|      
    |2|     |3|     
     -       - 
     |       |
     |       |
     ---------
         |
         |----
         |   |
         |   -
         |  |R|
         |  |4|
         |   -
         |   |
         |   |----->To Gnd
        To   To
        RCA  RCA
        Pin  GND   
  
  ________________________________
  Pin|    Role      |Information |
  ________________________________
  D2 |Bit 2^0       |NC switch   |
  D3 |Bit 2^1       |NO switch   |        
  D4 |Bit 2^2       |NO switch   |     
  D5 |Bit 2^3       |NO switch   |   
  D6 |Bit 2^4       |NO switch   |   
  D7 |Bit 2^5       |NO switch   |    
  D8 |Tvout Video   |            |
  D9 |Tvout Sync    |            |
  D10|Bit 2^6       |NO switch   |
  D11|Bit 2^7       |NO switch   |
  D12|Help button   |NC switch   |
  D13|Pap button    |NC button   |
  A0 |nb bits select|NO switch   |
  A1 |nb bits select|NO switch   |
  A2 |speed select  |NO switch   |
  A3 |speed select  |NO switch   |
  ________________________________
  
  
  NO = Normaly open
  NC = Normaly close
  
  
  R1 = 10 Kohms
  R2 = 330 ohms
  R3 = 1 Kohms
  R4 = 75 ohms
  For leds I use basic red leds (I suppose you can use basic signal diode, but I haven't make the test...)
  */
  
  
  #include <TVout.h>
  // You can found this lib on http://code.google.com/p/arduino-tvout/downloads/list
  // I use this one : TVout_w_audio.zip 	R5.91 with added sound output on port B pin 3 (digital pin 11 m168/328 only for now) by adam wolf 
  
  #include <stdlib.h> //for itoa function
  
  //button setup
  #define b1 2
  #define b2 3
  #define b4 4
  #define b8 5
  #define b16 6
  #define b32 7
  #define b64 10
  #define b128 11
  
  #define bhelp 12
  
  #define bbutton 13
  
  #define bbit1 14
  #define bbit2 15
  
  #define bspeed1 16
  #define bspeed2 17
  
  
  
  TVout TV;
  //bonus variables
  int x = 0;
  char xx[10]; 
  //help string
  char charhelp[10]; 
  //score string
  char charscore[10];
  //number string
  char charnum[10];
  int number = 0; 
  
  
  long previousMillis = 0;
  //low limit
  int limitebasse = 64;
  int pas = 1;
  
  //decimal value for binary swtich
  int valeur = 300;
  int previousvaleur = 300;
  int score = 0;
  int previousscore = 0;
  
  char* _speed [4] = {"slow","normal","fast","hardcore"};
  int Ispeed = 0;
  char* bits[4] = {"4","5","6","8",};
  int Ibits = 0;
  char* help [2] = {"yes","no"};
  int Ihelp = 0;  
  
  int highscore;
  
  
  void setup()  {
    pinMode(b1, INPUT);      
    pinMode(b2, INPUT);      
    pinMode(b4, INPUT);      
    pinMode(b8, INPUT);      
    pinMode(b16, INPUT);      
    pinMode(b32, INPUT);      
    pinMode(b64, INPUT);      
    pinMode(b128, INPUT);      
    pinMode(bhelp, INPUT);      
    pinMode(bbutton, INPUT);      
    pinMode(bbit1, INPUT);      
    pinMode(bbit2, INPUT);      
    pinMode(bspeed1, INPUT);      
    pinMode(bspeed2, INPUT);      
  
    TV.start_render(_PAL);	//for devices with only 1k sram(m168) use TV.begin(_PAL,128,56)
    TV.clear_screen();
    //Serial.begin(9600);
  }
  
  void loop() 
  {
    int _Ispeed = 100; 
    boolean gameover = false;
    int i = 0;
    int maxbit = 4;
    int help = 0;
      
    TV.clear_screen();
     TV.print_str(0,8,"      TETALAB ");
    TV.print_str(0,16,"    WE MAKE PORN");
    TV.print_str(0,32,"  Binary Hero v0.91");
    TV.print_str(0,48,"  Complex Solutions");
    TV.print_str(0,56,"         to ");
    TV.print_str(0,64," Inexistant problems");
    delay(2000);
  
    TV.clear_screen();
    menu(); 
    TV.clear_screen();
  
    if (Ispeed == 0) _Ispeed = 200;
    if (Ispeed == 1) _Ispeed = 100;
    if (Ispeed == 2) _Ispeed = 50;
    if (Ispeed == 3) _Ispeed = 25;
  
    if (Ibits == 0) maxbit = 15;
    if (Ibits == 1) maxbit = 31;
    if (Ibits == 2) maxbit = 63;
    if (Ibits == 3) maxbit = 255;
  
    help = Ihelp;
      
    randomSeed(analogRead(5));
    number = random(0,maxbit);
   
    TV.clear_screen();
  
  
    //game init 
    TV.draw_line(0,0,0,68,1);
    TV.draw_line(0,0,35,0,1);
    TV.draw_line(35,68,0,68,1);
    TV.draw_line(35,68,35,0,1);
    if (Ihelp == 0)
    {    
      TV.print_str(45,8,"Help:");
    }
    TV.print_str(45,32,"Bonus X");
    TV.print_str(90,32,xx);
    TV.print_str(45,56,"Score");
    TV.print_str(82,56,"0");
  
  
  
    
    while (!gameover)
    {
      if (millis() - previousMillis > _Ispeed) 
      {
        previousMillis = millis(); 
        if (pas > limitebasse-2) 
        {
          TV.clear_screen();
          TV.print_str(0,8,"      Game over");
          TV.print_str(0,32,"       Score :");
          //char charscore[4];
          itoa(score,charscore,10);
          TV.print_str(60,60,charscore);
          int truc = 1;
          delay(3000);
          score = 0;
          pas = 1;
          number = random(0,maxbit);
          TV.clear_screen();
          gameover = true;
        }
        else
        {
          TV.draw_line(1,pas,34,pas,0);
          pas++;
       }
      }
  
      itoa(number,charnum,10);
      TV.print_str(10,pas,charnum);
    
      valeur = 0;
      if (digitalRead(b1)==LOW) valeur = valeur+1;
      if (digitalRead(b2)==HIGH) valeur = valeur+2;
      if (digitalRead(b4)==HIGH) valeur = valeur+4;
      if (digitalRead(b8)==HIGH) valeur = valeur+8;
      if (digitalRead(b16)==HIGH) valeur = valeur+16;
      if (digitalRead(b32)==HIGH) valeur = valeur+32;
      if (digitalRead(b64)==HIGH) valeur = valeur+64;
      if (digitalRead(b128)==HIGH) valeur = valeur+128;
      
      
      
      if (Ihelp == 0 && previousvaleur != valeur)
      {    
      
        itoa(valeur,charhelp,10);
        if (valeur<10) 
        {
          charhelp[2] = charhelp[0];
          charhelp[1] = '0';
          charhelp[0] = '0';
        } 
        if (valeur>9 && valeur<100) 
        {
          charhelp[2] = charhelp[1];
          charhelp[1] = charhelp[0];
          charhelp[0] = '0';
        }
        TV.print_str(75,8,charhelp);
        previousvaleur = valeur;
      }
  
  
  
  
      if (score != previousscore)
      {
        itoa(score,charscore,10);
        TV.print_str(82,56,charscore);
        previousscore = score;
      }
  
      if (valeur == number)
      {
        score = score + x;
        number = random(0,maxbit);
        
        i = 0;
        while (i < 8)
        {
          TV.draw_line(1,pas+i,34,pas+i,0);
          i++;
        }
        TV.draw_line(35,68,0,68,1);
        pas = 1;
       }
    }  
  }
  
  
  void displaymenu(int a,int b,int c)
  {
  //a = _speed
  //b = bits
  //c = help
    TV.clear_screen();
    TV.print_str(16,8, "Speed  :");
    TV.print_str(16,16,"Nb bits:");
    TV.print_str(16,24,"Help   :");
    TV.print_str(12,40,"Press PAP to start");
  
    TV.print_str(65,8,_speed[a]);
    TV.print_str(65,16,bits[b]);
    TV.print_str(65,24,help[c]);
  
    x=0;
    x = Ispeed + Ibits + Ihelp;
    x = pow(2,x);
  
    itoa(x,xx,10);
    TV.print_str(20,80,"Bonus : X");
    TV.print_str(80,80,xx);
  
  }
  
  void  menu()
  {
    int i = 0;
    boolean paplast = true;
    displaymenu(Ispeed,Ibits,Ihelp);
    
    int lasthelp = 5;
    int lastspeed = 5;
    int lastbits = 5;
         
    while(i==0)
    {
      if (digitalRead(bhelp) == LOW) Ihelp = 0;
      else Ihelp = 1;
      
      if ((Ihelp != lasthelp) || (Ibits != lastbits) || (Ispeed !=lastspeed))
      {
        displaymenu(Ispeed,Ibits,Ihelp);
        lasthelp = Ihelp;
        lastspeed = Ispeed;
        lastbits = Ibits;
      }
      
      if (digitalRead(bbit1) == HIGH && digitalRead(bbit2) == HIGH) Ibits = 0;
      if (digitalRead(bbit1) == HIGH && digitalRead(bbit2) == LOW) Ibits = 1;
      if (digitalRead(bbit1) == LOW && digitalRead(bbit2) == HIGH) Ibits = 2;
      if (digitalRead(bbit1) == LOW && digitalRead(bbit2) == LOW) Ibits = 3;
  
      if (digitalRead(bspeed1) == HIGH && digitalRead(bspeed2) == HIGH) Ispeed = 0;
      if (digitalRead(bspeed1) == HIGH && digitalRead(bspeed2) == LOW) Ispeed = 1;
      if (digitalRead(bspeed1) == LOW && digitalRead(bspeed2) == HIGH) Ispeed = 2;
      if (digitalRead(bspeed1) == LOW && digitalRead(bspeed2) == LOW) Ispeed = 3;
      
      if (digitalRead(bhelp) == HIGH) Ihelp = 1;
      else Ihelp = 0;
        
      if (digitalRead(bbutton) == LOW) i = 1;
    }
  }