// Black and white NTSC video generation with fixed point animation

// D.0 is sync

// D.1 is video

// Mega644 version by Shane Pryor

// mod by brl4@cornell.edu:

//    for mega1284

//    for resolution 160 horizontal x 200 vertical

//    plays a musical scale from port B.3

//    UART SPI-mode video output from Morgan D. Jones

 

#include <avr/io.h>

#include <avr/pgmspace.h>

#include <avr/interrupt.h>

#include <stdlib.h>

#include <math.h>

#include <util/delay.h> 

#include <avr/sleep.h>

 

#include "app_fontset.h"

#include "functions.h"

//#include "app_video_ball.h"

//#include "app_fix_math.h"

 

//#include "bsp_adc.h"

 

// optional, if preferred///

#define begin {

#define end   }

////////////////////////////

//timeout values for each task

#define t1 200 

#define t2 50

#define t3 50

#define t4 200 

#define t5 50

#define t6 50      

 

//State machine state names

#define NoPush 1

#define MaybePush 2

#define Pushed 3

#define MaybeNoPush 4           

 

//cycles = 63.625 * 16 Note NTSC is 63.55

//but this line duration makes each frame exactly 1/60 sec

//which is nice for keeping a realtime clock

// video timing

#define LINE_TIME 1018 // 20 MHz 1271

#define SLEEP_TIME 999 // 20 MHz 1250

#define bytes_per_line 20

#define screen_width (bytes_per_line*8)

#define screen_height 200

#define screen_array_size screen_width*screen_height/8

#define right_wall 150

#define left_wall 49

#define right_wall_A 60

#define left_wall_A 0

#define right_wall_B 95

#define left_wall_B 156

#define ground 190

#define ground_tp 156

 

#define ScreenTop 30

#define ScreenBot (ScreenTop+screen_height)

 

 

#define maxkeys 16

#define PORTDIR DDRA

#define PORTDATA PORTA

#define PORTIN PINA

#define PORTDIRB DDRB

#define PORTDATAB PORTB

#define PORTINB PINB

#define right 20

#define down 30

#define left 40

#define cw 50

#define ccw 60

#define swap 70

char  str;

 

 

//uint8_t screen[screen_array_size];

//One bit masks

//uint8_t pos[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};

int cri; //change to floats

int no_syl; 

int syl_dur;

int sri;

int bf;

int dc;

 

int calc_val[8];

int index;

int cnt;

int fp;

 

//timeout value for LCD task

#define t2 100

 

// The raw keyscan

volatile unsigned char key, debounce_key, key1, keyB, debounce_keyB, key1B ;  

// The decoded button number

unsigned char butnum = 2;

unsigned char butnumB = 2;

 

 

int enter;

int butval, butvalB;

 

unsigned char keytbl[16]={0xee, 0xed, 0xeb, 0xe7,

                                          0xde, 0xdd, 0xdb, 0xd7,

                                          0xbe, 0xbd, 0xbb, 0xb7,

                                          0x7e, 0x7d, 0x7b, 0x77};

 

//sync

char syncON, syncOFF;

volatile unsigned char time1, time2, time3, time4, time5, time6;       //timeout counters

unsigned char PushFlag = 0;             //message indicating a button push

unsigned char PushFlagB = 0;

unsigned char led;               //LED count

unsigned char PushState = NoPush;       //state machine

unsigned char PushStateB = NoPush; 

//current line number in the current frame

volatile int LineCount;

volatile int update_piece = 0;

volatile int timer1 = 0;

volatile int timer2 = 0;

volatile int timer3 = 0;

//volatile space s;

 

//160h x 160v - screen buffer and pointer

//char screen[screen_array_size];

int* screenindex;

 

//One bit masks

//char pos[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};

 

// Musical note values

// middle-C to C-above-middle-C

// zeros are rests

 

char notes[] = {150,132,117,112,100,89,79,75,0,0,0,0}; 

char note, musicT;

 

/*ISR (TIMER0_COMPA_vect)

begin     

  //Decrement the three times if they are not already zero

  if (time1>0)      --time1;

  if (time2>0)      --time2;

  if (time3>0)      --time3;

end 

*/

// put the MCU to sleep JUST before the CompA ISR goes off

ISR(TIMER1_COMPB_vect, ISR_NAKED)

{

       sei();

       sleep_cpu();

       reti();

      

      

}

 

 

//==================================

//This is the sync generator and raster generator. It MUST be entered from

//sleep mode to get accurate timing of the sync pulses

 

ISR (TIMER1_COMPA_vect) {

       int s, screenStart ;

       //start the Horizontal sync pulse   

       PORTD = syncON;

 

       //update the current scanline number

       LineCount++;  

      

      

   

       /*     if (time1>0) --time1;

             if (time2>0) --time2;

             if (time3>0) --time3;

       */

       //begin inverted (Vertical) synch after line 247

       if (LineCount==248) {

       syncON = 0b00000001;

       syncOFF = 0;

            

       }

 

       //back to regular sync after line 250

       if (LineCount==251) {

             syncON = 0;

             syncOFF = 0b00000001;

       } 

 

       //start new frame after line 262

       if (LineCount==263)

       {

             LineCount = 1;

            

            

 

             /*if (timer1 == 12 && time1 > 0)

             {

                    time1--;

                    timer1 = 0;

             }

             if (timer2 == 3 && time2 > 0)

             {

                    time2--;

                    timer2 = 0;

             }

             if (timer2 == 3 && time3 > 0)

             {

                    time3--;

                    timer3 = 0;

             }*/

       }

 

     

       //adjust to make 5 us pulses

       _delay_us(3);

 

       //end sync pulse

       PORTD = syncOFF;  

 

       if (LineCount < ScreenBot && LineCount >= ScreenTop) {

             //compute offset into screen array

             //screenindex = screen + ((LineCount - ScreenTop) << 4) + ((LineCount - ScreenTop) << 3);

            

             //compute offset into screen array

             //screenStart = ((LineCount - ScreenTop) << 4) + ((LineCount - ScreenTop) << 3) ;

             screenStart = (LineCount - ScreenTop) * bytes_per_line;

             //center image on screen

             _delay_us(7);

             //blast the data to the screen

             // We can load UDR twice because it is double-bufffered

             UDR0 = screen[screenStart] ;

             UCSR0B = _BV(TXEN0);

             UDR0 = screen[screenStart+1] ;

             for (s = 2; s < bytes_per_line; s++)

             begin

                    while (!(UCSR0A & _BV(UDRE0))) ;

                    UDR0 = screen[screenStart+s] ;

             end

             UCSR0B = 0 ;

       }        

}

 

 

 

//=== fixed conversion macros =========================================

#define int2fix(a)   (((int)(a))<<8)            //Convert char to fix. a is a char

#define fix2int(a)   ((signed char)((a)>>8))    //Convert fix to int. a is an int

#define float2fix(a) ((int)((a)*256.0))         //Convert float to fix. a is a float

#define fix2float(a) (((float)(a))/256.0)       //Convert fix to float. a is an int  

 

//=== animation stuff ==================================================

 

char r;

int vx, vy, g, drag;

char cu1[]="Cornell  ECE 4760";

char cu2[]="COPYRIGHT:2012";

char cu5[]="HOW MANY PLAYERS?";

 

 

///////////////

 

//==================================        

// set up the ports and timers

int main() {

 

  //set up the ports

  PORTDIR = 0x00;   // PORT D is an input

  DDRC = 0xff;    // PORT C is an ouput

  PORTC = 0xff ;  // turn off leds

/*

 //set up timer 0 for 1 mSec timebase

  OCR0A = 249;             //set the compare re to 250 time ticks

  TIMSK0= (1<<OCIE0A);     //turn on timer 0 cmp match ISR

  //set prescalar to divide by 64

  TCCR0B= 3; //0b00000011;

  // turn on clear-on-match

  TCCR0A= (1<<WGM01) ;

*/

  //init the LED status (all off)

  led=0x00;

  PORTC = ~led;

 

  //init the task timers

  time1=t1;

  time2=t2;

  time3=t3;   

 

  //init the  message

  //for no button push

  PushFlag = 0;

  //init the state machine

  PushState = NoPush;

 

  //init timer 1 to generate sync

  //OCR1A = lineTime;      //One NTSC line

  // TIMER 1: OC1* disconnected, CTC mode, fosc/1 (20MHz), OC1A and OC1B

  //         interrupts enabled

  TCCR1B = _BV(WGM12) | _BV(CS10);

  OCR1A = LINE_TIME;       // time for one NTSC line

  OCR1B = SLEEP_TIME;      // time to go to sleep

  TIMSK1 = _BV(OCIE1B) | _BV(OCIE1A);

 

  //init ports

  DDRD = 0x03;             //video out

 

  // USART in MSPIM mode, transmitter enabled, frequency fosc/4

  UCSR0B = _BV(TXEN0);

  UCSR0C = _BV(UMSEL01) | _BV(UMSEL00);

  UBRR0 = 1 ;

 

  //initialize synch constants

  LineCount = 1;

 

  syncON = 0b00000000;

  syncOFF = 0b00000001;

 

 

  //Print "CORNELL" message

  //video_puts(30,2,cu1);

 

  //Print "Copyright" message

  //video_putsmalls(screen_width-70,screen_height-10,cu2);

 

  //side lines

  #define width screen_width-1

  #define height screen_height-1

 

 

  /*Different variables used throughout code*/

  space s, sB;

  row r, rB;

  int x = 10;

  int y = 1;

  int xA = 5;

  int yA = 1;

  int xB = 22;

  int yB = 1;

 

  int turn, turnB, x1A, x1B, y1A, y1B;

  int random_save = 10;

  int random_saveB = 10;

  int spin_save;

  int spin_saveB;

  int temp;

  int tempB;

  int speed = 80;

  int speed_counter = 0;

  int two_player = 1;

  int pit;

  int left_A;

  int right_A;

  int left_B;

  int right_B;

 

 

  /* Initialize coordinates depending on amount of players*/

  if (two_player)

  {

       x1A = xA;

       x1B = xB;

       y1A = yA;

       y1B = yB;

       pit = 25;

       left_A = 0;

       right_A = 9;

       left_B = 16;

       right_B = 25;

 

  }

  else

  {

       x1A = x;

       x1B = x;

       y1A = y;

       y1B = y;

       pit = 18;

       left_A = 5;

       right_A = 14;

       xA = x;

       yA = y;

  }

 

  //init musical scale

  note = 0;

  musicT = 0;

  //use OC0A (pin B.3) for music 

  DDRB = (1<<PORTB3) ;

 

  ///////////////////////

 

  // Set up single video line timing

  sei();

  set_sleep_mode(SLEEP_MODE_IDLE);

  sleep_enable();

 

  int random = rand() % 7;

  int randomB = rand() % 7;

  int bottom = 0;

  int bottomB = 0;

  int game_over = 0;

  matrix board, new_board, boardB, new_boardB;

 

  //initialize matrix

  for (int i = 0; i < 26; i++){

         for (int j = 0; j < 10; j++){

               board.b[i][j] = 0;

         }

  }

  for (int i = 0; i < 26; i++){

         for (int j = 0; j < 10; j++){

               boardB.b[i][j] = 0;

         }

  }

int spin = 0;

int spinB = 0;

int button = 0;

int buttonB = 0;

char winner = 0;

char cu3[] = "WINNER IS:";

char cu4;

if (two_player)

  {

       video_line(left_wall_A,ground_tp,right_wall_A,ground_tp,1);

       video_line(right_wall_A,ground_tp,right_wall_A,0,1);

 

       video_line(left_wall_B,0,left_wall_B,ground_tp,1);

       video_line(left_wall_B,ground_tp,right_wall_B,ground_tp,1);

       video_line(right_wall_B,ground_tp,right_wall_B,0,1);

  }

else

  {

         video_line(left_wall,0,left_wall,ground,1);

       video_line(left_wall,ground,right_wall,ground,1);

       video_line(right_wall,ground,right_wall,0,1);

  }

 

 

  // The following loop executes the if-block

  // when the screen refresh is done

  // then does all of the frame-end processing

  while(game_over == 0) {

       button = 0;

       buttonB = 0;

       timer1++;

       if (timer1 == 65)

       {

             if (time1>0) --time1;

             if (time2>0) --time2;

             if (time3>0) --time3;

             if (time4>0) --time4;

             if (time5>0) --time5;

             if (time6>0) --time6;      

             timer1 = 0;

       }

 

      

 

       if (LineCount == ScreenBot) {

             update_piece++;

             speed_counter++;

             if (speed_counter == 120 && speed > 10)

             {

                    speed_counter = 0;

                    speed--;

             }

        //Play a note

       //prescaler=256 so 1 tick is 12.8 microsec

          TCCR0B = 4;

          // toggle OC0A on compare match and turn on comp-match

          TCCR0A = (1<<COM0A0) | (1<<WGM01) ;

       if((musicT++) > 15) {       //each note 1/4 second

                    musicT = 0;

                    OCR0A = notes[note++] ;

                    if (note>18) note = 0;        //test for end of scale

       }

 

            

            

 

       

 

          //Draw shape

             s = draw_shape(x1A, y1A, random, spin, two_player);

             if(two_player) //Draw Shape for 2nd player

             {

                    sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

             }

             if (update_piece >= speed-1) { //move the piece down one space

                    bottom = check_matrix(board, s);

                    bottomB = check_matrix_tp(boardB, sB);

                   

                   

                   

 

                    if (y1A + s.floor < pit && bottom == 0) { //If we have not hit the floor or another piece, keep going

                           delete_shape(x1A, y1A, random, spin, two_player);

                           y1A = y1A + 1;

                          

                           //s = draw_shape(x, y, random);

                    }

                    else {

                           board = update_matrix(board, s, 1);  //Add piece to the matrix

                           r = check_matrix_row(board, s, two_player); //Check whether we need to clear a row

                          

                           if(r.clear == 1)

                           {

                                  new_board = row_deleter(r, s, board, two_player, 1); //Clear row in matrix

                                  if(new_board.k != 0)

                                 {

                                        for(int g = 0; g < 26-new_board.k; g++)

                                        {

                                              for(int d = 0; d < 10; d++)

                                              {

                                                     new_boardB.b[g][d] = boardB.b[g+new_board.k][d];   

                                              }

                                        }

                                        for(int g = 26-new_board.k; g < 26; g++)

                                        {

                                              for(int d = 0; d < 10; d++)

                                              {

                                                     new_boardB.b[g][d] = 1;  

                                              }

                                        }

                                        delete_shape(x1B, y1B, randomB, spinB, two_player);

                                        sB = draw_shape(x1B, y1B - new_board.k, randomB, spinB, two_player);

                                        y1B = y1B-new_board.k;

                                        draw_board_tp(boardB, new_boardB); //Draw's opponent's board with added rows

                                        boardB = new_boardB;

                                 }

                                  draw_board(board, new_board,two_player);

                                 board = new_board;

                           }

                           //y = 1;

                           random = rand() % 7;  //Start a new piece

                           x1A = xA;

                           y1A = yA;

                           spin = 0;

                          

                           s = draw_shape(x1A, y1A, random, spin, two_player);

                           game_over = check_matrix(board, s);  //Check if we have hit the top

                           if (game_over == 1)

                           {

                                 winner = 2;

                                 cu4 = 2;

                           }

                          

                          

                    }

                    if (y1B + sB.floor < pit && bottomB == 0 && two_player) {

                           delete_shape(x1B, y1B, randomB, spinB, two_player);

                           y1B = y1B + 1;

                          

                          

                    }

                    else if (two_player){

                           boardB = update_matrix(boardB, sB, 2);

                           rB = check_matrix_row(boardB, sB, two_player);

                          

                           if(rB.clear == 1)

                           {

                                  new_boardB = row_deleter(rB, sB, boardB, two_player, 2);

                                  if(new_boardB.k != 0)

                                 {

                                        for(int g = 0; g < 26-new_boardB.k; g++)

                                        {

                                              for(int d = 0; d < 10; d++)

                                              {

                                                     new_board.b[g][d] = board.b[g+new_boardB.k][d];     

                                              }

                                        }

                                        for(int g = 26-new_boardB.k; g < 26; g++)

                                        {

                                              for(int d = 0; d < 10; d++)

                                              {

                                                     new_board.b[g][d] = 1;    

                                              }

                                        }

                                        delete_shape(x1A, y1A, random, spin, two_player);

                                        s = draw_shape(x1A, y1A - new_boardB.k, random, spin, two_player);

                                        y1A = y1A-new_boardB.k;

                                        draw_board(board, new_board,two_player);

                                        board = new_board;

                                 }

                                  draw_board_tp(boardB, new_boardB);

                                 boardB = new_boardB;

                           }

                          

                           randomB = rand() % 7;

                           x1B = xB;

                           y1B = yB;

                           spinB = 0;

                          

                           sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                           game_over = check_matrix_tp(boardB, sB);

                           if (game_over == 1)

                           {

                                 winner = 1;

                                 cu4 = 1;

                           }

                          

                          

                    }

                   

                    update_piece = 0;

                   

                   

             }

            

 

             if (time1==0) task1();

          

             if (time2==0)      

             {

                    task2();

           }

            

             if (time3==0)

             {     

                    button = task3();

                   

             }

 

             if (time4==0) task4();

          

             if (time5==0)      

             {

                    task5();

           }

            

             if (time6==0)

             {     

                    buttonB = task6();

                   

             }

 

      

            

             if (button == right)  //Move right

             {

                    bottom = check_matrix_wall(board, s, 1);

                    if(s.r_wall + x1A < right_A && bottom == 0)

                    {

                           delete_shape(x1A, y1A, random, spin, two_player);

                           x1A = x1A + 1;

                           s = draw_shape(x1A, y1A, random, spin, two_player);

                           button = 0;

                    }

                    bottom = 0;

                   

             }

 

             if (button == left) //Move left

             {

                    bottom = check_matrix_wall(board, s, -1);

                    if(x1A - s.l_wall > left_A && bottom == 0)

                    {

                           delete_shape(x1A, y1A, random, spin, two_player);

                           x1A = x1A - 1;

                           s = draw_shape(x1A, y1A, random, spin, two_player);

                           button = 0;

                    }

                    bottom = 0;

                   

             }

 

             if (button == down) //Move down

             {

                    bottom = check_matrix(board, s);

                    if (y1A + s.floor < pit && bottom == 0) {

                           delete_shape(x1A, y1A, random, spin, two_player);

                           y1A = y1A + 1;

                           s = draw_shape(x1A, y1A, random, spin, two_player);

                    }

                    bottom = 0;

                   

             }

 

             if (button == swap) //Store current piece

             {

                    if(random_save == 10)

                    {

                           random_save = random;

                           delete_shape(x1A, y1A, random, spin, two_player);

                           if(!two_player)

                           {

                                 s = draw_shape(2, 5, random, spin, two_player);

                           }

                           else

                           {

                                 s = draw_shape(13, 5, random, spin, two_player);

                           }

                           spin_save = spin;

                           random = rand() % 7;

                           x1A = xA;

                           y1A = yA;

                           spin = 0;

                           s = draw_shape(xA, yA, random, spin, two_player);

                           game_over = check_matrix(board, s);

                    }

                    else

                    {

                           delete_shape(x1A, y1A, random, spin, two_player);

                           if(!two_player)

                           {

                                  delete_shape(2, 5, random_save, spin_save, two_player);

                                 s = draw_shape(2, 5, random, spin, two_player);

                                 s = draw_shape(xA, yA, random_save, spin_save, two_player);

                           }

                           else

                           {

                                  delete_shape(13, 5, random_save, spin_save, two_player);

                                 s = draw_shape(13, 5, random, spin, two_player);

                                 s = draw_shape(xA, yA, random_save, spin_save, two_player);

                           }

                           s = draw_shape(xA, yA, random_save, spin_save, two_player);

                           x1A = xA;

                           y1A = yA;

                           temp = random;

                           random = random_save;

                           random_save = temp;

                           temp = spin;

                           spin = spin_save;

                           spin_save = temp;

                    }

             }

 

 

 

             if (button == cw) //Rotate clockwise

             {

                   

                    if( spin == 3)

                    {

                           spin = 0;

                           s = spin_shape(x1A, y1A, random, spin);

                           turn = check_matrix_spin(board, s, two_player);

                           if(turn == 0)

                           {

                                 spin = 3;

                                  delete_shape(x1A, y1A, random, spin, two_player);

                                 spin = 0;

                                 s = draw_shape(x1A, y1A, random, spin, two_player);

                           }

                           else if(turn == 2)

                           {

                                 spin = 3;

                                  delete_shape(x1A, y1A, random, spin, two_player);

                                 spin = 0;

                                 x1A = left_A + s.l_wall;

                                 s = draw_shape(x1A, y1A, random, spin, two_player);

                           }

                           else if(turn == 3)

                           {

                                 spin = 3;

                                  delete_shape(x1A, y1A, random, spin, two_player);

                                 spin = 0;

                                 x1A = right_A - s.r_wall;

                                 s = draw_shape(x1A, y1A, random, spin, two_player);

                           }

                           else if(turn == 4)

                           {

                                 spin = 3;

                                  delete_shape(x1A, y1A, random, spin, two_player);

                                 spin = 0;

                                 y1A = y1A - s.floor;

                                 s = draw_shape(x1A, y1A, random, spin, two_player);

                           }

                           else

                           {

                                 spin = 3;

                           }

                    }

                    else

                    {

                           spin++;

                           s = spin_shape(x1A, y1A, random, spin);

                           turn = check_matrix_spin(board, s, two_player);

                           if(turn == 0)

                           {

                                 spin--;

                                  delete_shape(x1A, y1A, random, spin, two_player);

                                  spin++;

                                 s = draw_shape(x1A, y1A, random, spin, two_player);

                           }

                           else if(turn == 2)

                           {

                                 spin--;

                                  delete_shape(x1A, y1A, random, spin, two_player);

                                  spin++;

                                 x1A = left_A + s.l_wall;

                                 s = draw_shape(x1A, y1A, random, spin, two_player);

                           }

                           else if(turn == 3)

                           {

                                 spin--;

                                  delete_shape(x1A, y1A, random, spin, two_player);

                                  spin++;

                                 x1A = right_A - s.r_wall;

                                 s = draw_shape(x1A, y1A, random, spin, two_player);

                           }

                           else if(turn == 4)

                           {

                                 spin--;

                                  delete_shape(x1A, y1A, random, spin, two_player);

                                  spin++;

                                 y1A = y1A - s.floor;

                                 s = draw_shape(x1A, y1A, random, spin, two_player);

                           }

                           else

                           {

                                 spin--;

                           }

                    }

             }     

            

             if (button == ccw) //Rotate counter clocwise

             {

                   

                    if( spin == 0)

                    {

                           spin = 3;

                           s = spin_shape(x1A, y1A, random, spin);

                           turn = check_matrix_spin(board, s, two_player);

                           if(turn == 0)

                           {

                                 spin = 0;

                                  delete_shape(x1A, y1A, random, spin, two_player);

                                 spin = 3;

                                 s = draw_shape(x1A, y1A, random, spin, two_player);

                           }

                           else if(turn == 2)

                           {

                                 spin = 0;

                                  delete_shape(x1A, y1A, random, spin, two_player);

                                 spin = 3;

                                 x1A = left_A + s.l_wall;

                                 s = draw_shape(x1A, y1A, random, spin, two_player);

                           }

                           else if(turn == 3)

                           {

                                 spin = 0;

                                  delete_shape(x1A, y1A, random, spin, two_player);

                                 spin = 3;

                                 x1A = right_A - s.r_wall;

                                 s = draw_shape(x1A, y1A, random, spin, two_player);

                           }

                           else if(turn == 4)

                           {

                                 spin = 0;

                                  delete_shape(x1A, y1A, random, spin, two_player);

                                 spin = 3;

                                 y1A = y1A - s.floor;

                                 s = draw_shape(x1A, y1A, random, spin, two_player);

                           }

                           else

                           {

                                 spin = 0;

                           }

                    }

                    else

                    {

                           spin--;

                           s = spin_shape(x1A, y1A, random, spin);

                           turn = check_matrix_spin(board, s, two_player);

                           if(turn == 0)

                           {

                                  spin++;

                                  delete_shape(x1A, y1A, random, spin, two_player);

                                 spin--;

                                 s = draw_shape(x1A, y1A, random, spin, two_player);

                           }

                           else if(turn == 2)

                           {

                                  spin++;

                                  delete_shape(x1A, y1A, random, spin, two_player);

                                 spin--;

                                 x1A = left_A + s.l_wall;

                                 s = draw_shape(x1A, y1A, random, spin, two_player);

                           }

                           else if(turn == 3)

                           {

                                  spin++;

                                  delete_shape(x1A, y1A, random, spin, two_player);

                                 spin--;

                                 x1A = right_A - s.r_wall;

                                 s = draw_shape(x1A, y1A, random, spin, two_player);

                           }

                           else if(turn == 4)

                           {

                                  spin++;

                                  delete_shape(x1A, y1A, random, spin, two_player);

                                 spin--;

                                 y1A = y1A - s.floor;

                                 s = draw_shape(x1A, y1A, random, spin, two_player);

                           }

                           else

                           {

                                  spin++;

                           }

                    }

             }

 

             /*Second Player controls same as First Player*/

             if (buttonB == right)

             {

                    bottomB = check_matrix_wall_tp(boardB, sB, 1);

                    if(sB.r_wall + x1B < right_B && bottomB == 0)

                    {

                           delete_shape(x1B, y1B, randomB, spinB, two_player);

                           x1B = x1B + 1;

                           sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                           buttonB = 0;

                    }

                    bottomB = 0;

            

             }

 

             if (buttonB == left)

             {

                    bottomB = check_matrix_wall_tp(boardB, sB, -1);

                    if(x1B - sB.l_wall > left_B && bottomB == 0)

                    {

                           delete_shape(x1B, y1B, randomB, spinB, two_player);

                           x1B = x1B - 1;

                           sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                           buttonB = 0;

                    }

                    bottomB = 0;

                   

             }                  

            

             if (buttonB == down)

             {

                    bottomB = check_matrix_tp(boardB, sB);

                    if (y1B + sB.floor < pit && bottomB == 0) {

                           delete_shape(x1B, y1B, randomB, spinB, two_player);

                           y1B = y1B + 1;

                           sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                    }

                    bottomB = 0;

                   

             }

 

             if (buttonB == swap)

             {

                    if(random_saveB == 10)

                    {

                           random_saveB = randomB;

                           delete_shape(x1B, y1B, randomB, spinB, two_player);

                           sB = draw_shape(13, 10, randomB, spinB, two_player);

                           spin_saveB = spinB;

                           randomB = rand() % 7;

                           x1B = xB;

                           y1B = yB;

                           spinB = 0;

                           sB = draw_shape(xB, yB, randomB, spinB, two_player);

                           game_over = check_matrix_tp(boardB, sB);

                    }

                    else

                    {

                           delete_shape(x1B, y1B, randomB, spinB, two_player);

                           delete_shape(13, 10, random_saveB, spin_saveB, two_player);

                           sB = draw_shape(13, 10, randomB, spinB, two_player);

                           sB = draw_shape(xB, yB, random_saveB, spin_saveB, two_player);

                           sB = draw_shape(xB, yB, random_saveB, spin_saveB, two_player);

                           x1B = xB;

                           y1B = yB;

                           tempB = randomB;

                           randomB = random_saveB;

                           random_saveB = tempB;

                           tempB = spinB;

                           spinB = spin_saveB;

                           spin_saveB = tempB;

                    }

             }

 

 

 

             if (buttonB == cw)

             {

                   

                    if( spinB == 3)

                    {

                           spinB = 0;

                           sB = spin_shape(x1B, y1B, randomB, spinB);

                           turnB = check_matrix_spin_B(boardB, sB);

                           if(turnB == 0)

                           {

                                 spinB = 3;

                                  delete_shape(x1B, y1B, randomB, spinB, two_player);

                                 spinB = 0;

                                 sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                           }

                           else if(turnB == 2)

                           {

                                 spinB = 3;

                                  delete_shape(x1B, y1B, randomB, spinB, two_player);

                                 spinB = 0;

                                 x1B = left_B + sB.l_wall;

                                 sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                           }

                           else if(turnB == 3)

                           {

                                 spinB = 3;

                                  delete_shape(x1B, y1B, randomB, spinB, two_player);

                                 spinB = 0;

                                 x1B = right_B - sB.r_wall;

                                 sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                           }

                           else if(turnB == 4)

                           {

                                 spinB = 3;

                                  delete_shape(x1B, y1B, randomB, spinB, two_player);

                                 spinB = 0;

                                 y1B = y1B - sB.floor;

                                 sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                           }

                           else

                           {

                                 spinB = 3;

                           }

                    }

                    else

                    {

                           spinB++;

                           sB = spin_shape(x1B, y1B, randomB, spinB);

                           turnB = check_matrix_spin_B(boardB, sB);

                           if(turnB == 0)

                           {

                                 spinB--;

                                  delete_shape(x1B, y1B, randomB, spinB, two_player);

                                  spinB++;

                                 sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                           }

                           else if(turnB == 2)

                           {

                                 spinB--;

                                  delete_shape(x1B, y1B, randomB, spinB, two_player);

                                  spinB++;

                                 x1B = left_B + sB.l_wall;

                                 sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                           }

                           else if(turnB == 3)

                           {

                                 spinB--;

                                  delete_shape(x1B, y1B, randomB, spinB, two_player);

                                  spinB++;

                                 x1B = right_B - sB.r_wall;

                                 sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                           }

                           else if(turn == 4)

                           {

                                 spinB--;

                                  delete_shape(x1B, y1B, randomB, spinB, two_player);

                                  spinB++;

                                 y1B = y1B - sB.floor;

                                 sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                           }

                           else

                           {

                                 spinB--;

                           }

                    }

             }     

            

             if (buttonB == ccw)

             {

                   

                    if( spinB == 0)

                    {

                           spinB = 3;

                           sB = spin_shape(x1B, y1B, randomB, spinB);

                           turnB = check_matrix_spin_B(boardB, sB);

                           if(turnB == 0)

                           {

                                 spinB = 0;

                                  delete_shape(x1B, y1B, randomB, spinB, two_player);

                                 spinB = 3;

                                 sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                           }

                           else if(turnB == 2)

                           {

                                 spinB = 0;

                                  delete_shape(x1B, y1B, randomB, spinB, two_player);

                                 spinB = 3;

                                 x1B = left_B + sB.l_wall;

                                 sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                           }

                           else if(turnB == 3)

                           {

                                 spinB = 0;

                                  delete_shape(x1B, y1B, randomB, spinB, two_player);

                                 spinB = 3;

                                 x1B = right_B - sB.r_wall;

                                 sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                           }

                           else if(turnB == 4)

                           {

                                 spinB = 0;

                                  delete_shape(x1B, y1B, randomB, spinB, two_player);

                                 spinB = 3;

                                 y1B = y1B - sB.floor;

                                 sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                           }

                           else

                           {

                                 spinB = 0;

                           }

                    }

                    else

                    {

                           spinB--;

                           sB = spin_shape(x1B, y1B, randomB, spinB);

                           turnB = check_matrix_spin_B(boardB, sB);

                           if(turnB == 0)

                           {

                                  spinB++;

                                  delete_shape(x1B, y1B, randomB, spinB, two_player);

                                 spinB--;

                                 sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                           }

                           else if(turnB == 2)

                           {

                                  spinB++;

                                  delete_shape(x1B, y1B, randomB, spinB, two_player);

                                 spinB--;

                                 x1B = left_B + sB.l_wall;

                                 sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                           }

                           else if(turnB == 3)

                           {

                                  spinB++;

                                  delete_shape(x1B, y1B, randomB, spinB, two_player);

                                 spinB--;

                                 x1B = right_B - sB.r_wall;

                                 sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                           }

                           else if(turnB == 4)

                           {

                                  spinB++;

                                  delete_shape(x1B, y1B, randomB, spinB, two_player);

                                 spinB--;

                                 y1B = y1B - sB.floor;

                                 sB = draw_shape(x1B, y1B, randomB, spinB, two_player);

                           }

                           else

                           {

                                  spinB++;

                           }

                    }

             }

            

 

            

             while (LineCount != ScreenTop) ;

            

     }  //line 231

  }  //for

  while(1){

       //video_putsmalls(screen_width-70,10,cu3);

       if(two_player)

       {

       video_puts(70,2,cu3);

       if( winner == 1 ) //Say Player 1 wins!

       {

             video_line     (75, 20, 85, 20, 1);

             video_line     (85, 20, 85, 110, 1);

             video_line     (65, 110, 105, 110, 1);

       }

       else if( winner == 2 ) //Say Player 2 Wins!

       {

             video_line     (65, 20, 105, 20, 1);

             video_line     (105, 20, 105, 65, 1);

             video_line     (105, 65, 65, 65, 1);

             video_line     (65, 65, 65, 110, 1);

             video_line     (65, 110, 105, 110, 1);

 

       }

       }

 

  }

}  //main

 

 

 

//the three task subroutines

//void task1(void);        //inc LEDs

//void task2(void); //non-debounced button 0

//int task3(void);  //debounced button 1

 

 

 

 

 

//**********************************************************         

//Task subroutines

//Task 1

void task1(void)

begin 

  time1=t1;  //reset the task timer

 

  if (PushFlag)  //check for a button press

  begin

       //reset flag

       PushFlag = 0;

       key = 0xff;

       //increment the LEDs      

       //++led;    

       //PORTC = ~led;

  end

end 

 

//*******************************

//Task 2 

void task2(void)

begin

  time2=t2;  //reset the task timer

       //get lower nibble

       PORTDIR = 0x0f;

       PORTDATA = 0xf0;

       _delay_us(5);

       key = PORTIN;

         

       //get upper nibble

       PORTDIR = 0xf0;

       PORTDATA = 0x0f;

       _delay_us(5);

       key = key | PORTIN;

  if (key != 0xff)//~PIND & 0x01)  //button push

  {

    PushFlag = 1;

  }

  else

  {

       PushFlag = 0;

      

  }

      

 

end 

 

//*******************************  

//Task 3 

int task3(void)

begin

  time3=t3;     //reset the task timer

  butval = 17;

  //get lower nibble

       PORTDIR = 0x0f;

       PORTDATA = 0xf0;

       _delay_us(5);

       key1 = PORTIN;

         

       //get upper nibble

       PORTDIR = 0xf0;

       PORTDATA = 0x0f;

       _delay_us(5);

       key1 = key1 | PORTIN;

  switch (PushState)

  begin

     case NoPush:

        if (key1 == key && PushFlag == 1)

             {

                    PushState=MaybePush;

             }

        else

             {

                    PushState=NoPush;

                   

             }

        break;

     case MaybePush:

        if (key1 == key && PushFlag == 1)

        begin

           PushState=Pushed;  

        end

        else PushState=NoPush;

        break;

     case Pushed: 

        if (key1 == key && PushFlag == 1)

             {

                    PushState=Pushed;

             }

        else PushState=MaybeNoPush;   

        break;

     case MaybeNoPush:

        if (key1 == key && PushFlag == 1) PushState=Pushed;

        else

        begin

           PushState=NoPush;

        end   

        break;

  end

 

       if(PushState == Pushed)

       {

            

             for (butnum=0; butnum<maxkeys; butnum++)

              {

                    if (keytbl[butnum]==key1)  break;  

              }

 

              if (butnum==maxkeys) butnum=0;

              else butnum++;         //adjust by one to make range 1-16

 

       switch(butnum)

             {

                   

                    case 10: butval = right; break; 

 

                    case 11: butval = down; break;

 

                    case 12: butval = left; break;

                                                    

                    case 14: butval = cw; break;

                                

                    case 15: butval = swap; break;

                   

                    case 16: butval = ccw; break;        

             }

            

       }

      

       return butval;

end

 

//**********************************************************         

//Task subroutines

//Task 4

void task4(void)

begin 

  time4=t4;  //reset the task timer

 

  if (PushFlagB)  //check for a button press

  begin

       //reset flag

       PushFlagB = 0;

       keyB = 0xff;

       //increment the LEDs      

       //++led;    

       //PORTC = ~led;

  end

end 

 

//*******************************

//Task 5 

void task5(void)

begin

  time5=t5;  //reset the task timer

       //get lower nibble

       PORTDIRB = 0x0f;

       PORTDATAB = 0xf0;

       _delay_us(5);

       keyB = PORTINB;

         

       //get upper nibble

       PORTDIRB = 0xf0;

       PORTDATAB = 0x0f;

       _delay_us(5);

       keyB = keyB | PORTINB;

  if (keyB != 0xff)//~PIND & 0x01)  //button push

  {

    PushFlagB = 1;

  }

  else

  {

       PushFlagB = 0;

      

  }

      

 

end 

 

//*******************************  

//Task 6 

int task6(void)

begin

  time6=t6;     //reset the task timer

  butvalB = 17;

  //get lower nibble

       PORTDIRB = 0x0f;

       PORTDATAB = 0xf0;

       _delay_us(5);

       key1B = PORTINB;

         

       //get upper nibble

       PORTDIRB = 0xf0;

       PORTDATAB = 0x0f;

       _delay_us(5);

       key1B = key1B | PORTINB;

  switch (PushStateB)

  begin

     case NoPush:

        if (key1B == keyB && PushFlagB == 1)

             {

                    PushStateB=MaybePush;

             }

        else

             {

                    PushStateB=NoPush;

                   

             }

        break;

     case MaybePush:

        if (key1B == keyB && PushFlagB == 1)

        begin

           PushStateB=Pushed;  

        end

        else PushStateB=NoPush;

        break;

     case Pushed: 

        if (key1B == keyB && PushFlagB == 1)

             {

                    PushStateB=Pushed;

             }

        else PushStateB=MaybeNoPush;   

        break;

     case MaybeNoPush:

        if (key1B == key && PushFlagB == 1) PushStateB=Pushed;

        else

        begin

           PushStateB=NoPush;

        end   

        break;

  end

 

       if(PushStateB == Pushed)

       {

            

             for (butnumB=0; butnumB<maxkeys; butnumB++)

              {

                    if (keytbl[butnumB]==key1B)  break;  

              }

 

              if (butnumB==maxkeys) butnum=0;

              else butnumB++;        //adjust by one to make range 1-16

 

       switch(butnumB)

             {

                   

                    case 9: butvalB = right; break; 

                    case 10: butvalB = down; break;

                    case 11: butvalB = left; break;

                    case 13: butvalB = cw; break;

                    case 14: butvalB = swap; break;

                    case 15: butvalB = ccw; break; 

                   

                                

             }

            

       }

      

       return butvalB;

end