///////////////// //CODE for PONG// ///////////////// #include #include // sprintf #include // delay_ms #include //#define t1 104 //#define t2 #define begin { #define end } #define PADDLE1 0 #define BALL 1 #define PADDLE2 2 #define MAX_SCORE 7 /*/flash unsigned char paddle[16]={0x80, 0xb1, 0xda, 0xf6, 0xff, 0xf6, 0xda, 0xb1, 0x80, 0x4f, 0x26, 0x0a, 0x00, 0x0a, 0x26, 0x4f}; */ flash unsigned char paddle[16]={0x03, 0x06, 0x09, 0x0c, 0x0f, 0x12, 0x15, 0x18, 0x1b, 0x1e, 0x21, 0x24, 0x27, 0x2b, 0x2f, 0x33}; bit statechange,sound; unsigned char state; unsigned char sample, pad1_pos, pad2_pos, ballx, bally, xvel, yvel; unsigned char p1_score, p2_score, next_point,restart,start, pause,ghetto_test; unsigned char Ain; unsigned char counter; void initialize (void); void task1 (void); //-------------------------------------------------------------------------- void main(void) { initialize(); while (1) { if (statechange==1) task1(); //call state machine...for state transition } } //---------------------ADC INTERRUPT---------------------------------------- interrupt [ADC_INT] void adc_done(void) { Ain=ADCH; } //-------------------TIMER1 COMPARE INTERRUPT------------------------------- interrupt [TIM1_COMPA] void cmpA_overflow(void) { statechange=1; //interrupt to call state machine } //-------------------STATE MACHINE------------------------------------------ void task1(void) begin statechange=0; //reset state change switch (state) { //STATE 'PADDLE1' case PADDLE1: if (sample<16){ PORTC=pad1_pos+paddle[sample++];//Draw Paddle1 } //paddle1 offset position + paddle table else { //sample=0; state = BALL; //next state: BALL PORTC= bally; //y-coordinate of ball PORTD= ballx; //x-coordinate of ball ADMUX.0=1; //read ADC1 ADCSR.6=1; //ADC START Conversion while (ADCSR.6==1){ } //wait for conversion to finish pad2_pos=Ain; //paddle2 offset position = Output of ADC } break; //STATE 'BALL' case BALL: //if (sample<16){ // sample++; //} //else { ADMUX.0=0; //read ADC0 ADCSR.6=1; //ADC START Conversion while(ADCSR.6==1){ } //wait for conversion to finish pad1_pos=Ain; //paddle1 offset position = Output of ADC sample=0; //reset sample PORTC= pad2_pos;//paddle2 offset position PORTD=0xff; //paddle2 at right side of the screen state=PADDLE2; //next state //BALL is all the way to the RIGHT of the screen if (ballx== 0xfe){ //BALL MISSES PADDLE2!!! if (((bally+yvel)(pad2_pos+0x33)) && (xvel==1)){ ballx=0xff; //ball stays at right wall bally=bally+yvel; //preserve y position if (ghetto_test==1) ++p1_score; else ghetto_test=1; //Increment Player 1 score PORTB=(~p1_score<<5)+(~p2_score);//SHOW score on LEDs xvel=0; //STOP Ball yvel=0; //STOP Ball } //BALL HITS PADDLE2!!! else{ sound=1; xvel=-1; //Reverse the xvel so that the ball bounces off if ((bally+ yvel)==pad2_pos){ //DEPENDING on WHERE the ball hits paddle, yvel=-3; //ThERE will be a differet yvel... } //This allows variation in the bounce. else if ((bally+ yvel)<=(pad2_pos +0x05)){ yvel=-2; } else if ((bally+ yvel)<=(pad2_pos +0x15)){ yvel=-1; } else if ((bally+ yvel)<=(pad2_pos +0x2d)){ yvel=1; } else if ((bally+ yvel)<=(pad2_pos +0x32)){ yvel=2; } else if ((bally+ yvel)==(pad2_pos +0x33)){ yvel=3; } } } //BALL is all the way to the LEFT of the screen else if (ballx==0x01){ //BALL MISSES PADDLE1!!! if (((bally+ yvel)< pad1_pos) || ((bally+ yvel) > (pad1_pos + 0x33)) && (xvel==-1)){ ballx=0x00; bally=bally +yvel; xvel=0; yvel=0; p2_score++;//same comments as above if (ghetto_test==0) p1_score=0; PORTB=(~p1_score<<5)+(~p2_score); } //BALL HITS PADDLE1!!! else{ xvel=1; //same comments as above if ((bally+ yvel)==pad1_pos){ yvel=-3; } else if ((bally+ yvel)<=(pad1_pos +0x05)){ yvel=-2; } else if ((bally+ yvel)<=(pad1_pos +0x15)){ yvel=-1; } else if ((bally+ yvel)<=(pad1_pos +0x2d)){ yvel=1; } else if ((bally+ yvel)<=(pad1_pos +0x32)){ yvel=2; } else if ((bally+ yvel)==(pad1_pos +0x33)){ yvel=3; } } } //BALL bounces off TOP and BOTTOM walls if ((bally>=0xcc) || (bally<=0)){ yvel=-yvel; } //Determine what to do now after a ball has been MISSED if ((ballx == 0xff)|| (ballx==0x00)){ //Reset Game after MAX Score has been reached if ((p1_score==MAX_SCORE)|| (p2_score==MAX_SCORE)){ //Wait for reset command...Button 3 if (PINB.3==0) initialize(); } //Universal Reset else if ((PINB.3==0) & (PINB.4==0)) initialize(); //Advance to next point? else if (next_point==0){ //wait for another button push if (PINB.4==0) next_point=1; } //Serve the ball again, after it has been missed on the right side else if (ballx==0xff && (bally>=pad2_pos) &&(bally<=(pad2_pos+0x33))){ next_point=0; xvel=-1; ballx=0xfd; } //Serve the ball again, after it has been missed on the right side else if (ballx==0x00 &&(bally>=pad1_pos) &&(bally<=(pad1_pos+0x33))){ next_point=0; xvel=1; ballx=0x02; } } //Ball is in a position in middle the screen, (it is in motion) else{ //Wait for Button 4 to play point if (PINB.4==0){ start=1; } //Ball can only be moving after Button 4 has been pushed during that point if (start==1){ counter=0; ballx= ballx + xvel; bally= bally + yvel; } } break; //STATE 'PADDLE2' case PADDLE2: if (sample <16){ PORTC=pad2_pos+paddle[sample++];//DRAW PADDLE2 // if (sound==1) // PORTA.6=(~(PORTA.6)); } //paddle2 offset position + paddle table else { sound=0; sample=1; //reset sample PORTC= pad1_pos; //PORTC= pad1_pos;//paddle2 offset position PORTD= 0; //paddle1 at left side of the screen state = PADDLE1; //next state } break; } end //--------------------------------------------------------------- void initialize(void) begin //PORT SET-UP's // Analog-Digital Converter does input control // for variable resistor to move the paddles DDRA = 0x00; // INPUT (ANALOG PORT) USED DDRB = 0xe7; // OUTPUT x-coordinate control DDRC = 0xff; // OUTPUT y-coordinate control // DDRD = 0xe7; // OUTPUT bit4, bit3 / INPUT bit7:5, bit2:0 - //button pushes, lights, speaker DDRD=0xff; //set up timer 1 TIMSK= 0x10; //turn on timer 1 compare match interrupt TCNT1 = 0; //and zero the timer OCR1A = 104; //set to match after 104 cycles=.000208s appx = 100Hz *3 states *16 paddle positions TCCR1B= 0x0a; //allow clr on match //initialize values PORTD=0x00; PORTB=0xff; p1_score=0; p2_score=0; ballx=0x80; //start ball in the middle of the screen bally=0x66; start=0; sample = 0; //SET TO 2V xvel=1; ghetto_test=0; //setup ADC ADMUX = 0b01100000; /* makes information left adjusted with regards to AVcc*/ ADCSR = 0x80 + 0x06 + 0x08; MCUCR = 0b01010000; //enable sleep and choose ADC modeto AREF pin ADCSR.6=1; while (ADCSR.6==1){ } pad1_pos=Ain; //crank up the ISRs #asm sei #endasm end