//Laser Simon Board //Cathy Chen -cc464 //4/28/2008 #include #include #include #include "radio.h" #include "simon.h" #include "messages.h" #include "radio_addr.h" //Signals to be used in game unsigned char fired = 0; unsigned char current_player = RADIO_ADDR_CONTROL_A; unsigned char pattern[10] = {0}; unsigned char target = 0; unsigned char next =0; unsigned char current_level = 11; unsigned char counter = 0; unsigned char rotate_enabled = 0; unsigned char show_pattern_enable = 0; unsigned char winner = 0; unsigned char rotate = 0; unsigned int playerA_score = 0; unsigned int playerB_score = 0; unsigned int led_rate=500; unsigned int led_timer=0; unsigned int simon_led = 0; void message_decode(void); void initialize(void); void hit_detection(void); void show_pattern(void); void rotate_leds(void); void set_pattern(void); void scan_photosensors(void); #include "radio_def.h" void main(void) { initialize(); set_pattern(); while(1) { radio_exec(); message_decode(); hit_detection(); if(rotate_enabled)rotate_leds(); if(show_pattern_enable) show_pattern(); if(led_timer == 0) { PORTD.4 = ~PORTD.4; led_timer = led_rate; } } } void initialize(void) { //PortB as outputs DDRB=0xFF; PORTB=0xFF; //PortD.4 as output DDRD.4=0x01; PORTD.4=0x01; //Set Analog Input ADMUX = 0b00100000; ADCSRA = 0b11100000; radio_init(); TIMSK1 = 0b00000010;//Enable output compare interrupt. TCCR1B = 0b00001010;//Enable reset on compare match, 1:8 clock. OCR1AH = 1; OCR1AL = 244;//Set register #asm("sei") } //Takes message and extracts information void message_decode(void) { unsigned char data[10]; unsigned char length; unsigned char ret; unsigned char src; ret=radio_receive(&src,&length,data); if (ret==RET_RX_PACKET_REC) { switch(data[0]) { case LB_MSG_FIRE: if (src == current_player)fired = 1; break; case LB_MSG_RESET: current_player = RADIO_ADDR_CONTROL_A; target = 0; next =0; current_level = 1; counter = 0; rotate_enabled = 0; winner = 0; rotate = 0; fired = 0; data[0] = LB_MSG_LEVEL; data[1] = current_level; radio_send(RADIO_ADDR_CONTROL_A, 1, 2, data); radio_send(RADIO_ADDR_CONTROL_B, 1, 2, data); data[0] = LB_MSG_PLAYER; data[1] = current_player; radio_send(RADIO_ADDR_CONTROL_A, 1, 2, data); radio_send(RADIO_ADDR_CONTROL_B, 1, 2, data); set_pattern(); show_pattern_enable = 1; break; } } } //Hit Calculation void hit_detection(void) { if(!fired||current_level>MAX_LEVELS) return; fired = 0; if(ADCH > 0b00000001) // PHOTODIODE NUMBER //when correct player hits, go onto next thing in pattern, send hit report, give points { unsigned char data[2] = {LB_MSG_HIT_REPORT, LB_DATA_HIT}; radio_send(current_player, 0, 2, data); // repeat, message length, payload if (current_player == RADIO_ADDR_CONTROL_A)playerA_score = playerA_score + current_level; else playerB_score = playerB_score + current_level; } else { unsigned char data[2] = {LB_MSG_HIT_REPORT, LB_DATA_MISS}; radio_send(current_player, 0, 2, data); // repeat, message length, payload } next++; scan_photosensors(); //FIXME move this until after setting the target? if (next == current_level)// end of current player's turn { unsigned char data[2] = {LB_MSG_PLAYER}; if(current_player == RADIO_ADDR_CONTROL_A) { current_player = RADIO_ADDR_CONTROL_B; show_pattern_enable = 1; counter = 0; } else { current_player =RADIO_ADDR_CONTROL_A; current_level++; data[0] = LB_MSG_LEVEL; data[1] = current_level; if(current_level<=MAX_LEVELS) { radio_send(RADIO_ADDR_CONTROL_A, 1, 2, data); radio_send(RADIO_ADDR_CONTROL_B, 1, 2, data); } counter = 0; set_pattern(); } if(current_level MAX_LEVELS)// end of game { unsigned char data[2]={LB_MSG_GAME_OVER,RADIO_ADDR_NULL}; if( playerA_score > playerB_score) { data[1] = RADIO_ADDR_CONTROL_A; winner = PLAYER_A; } if (playerB_score > playerA_score) { data[1] = RADIO_ADDR_CONTROL_B; winner = PLAYER_B; } else { winner = TIE; } radio_send(RADIO_ADDR_CONTROL_A, 1, 2, data); radio_send(RADIO_ADDR_CONTROL_B, 1, 2, data); rotate_enabled = 1; rotate = 0; counter = 0; } } void show_pattern(void)//blink leds in next pattern { if (simon_led != 0 ) return; simon_led = 700; if (counter < current_level) { if(pattern[counter]== PHOTO0) LED0= 1; else LED0 = 0; if(pattern[counter]== PHOTO1) LED1= 1; else LED1 = 0; if(pattern[counter]== PHOTO2) LED2= 1; else LED2 = 0; if(pattern[counter]== PHOTO3) LED3= 1; else LED3 = 0; if(pattern[counter]== PHOTO4) LED4= 1; else LED4 = 0; counter++; } else { PORTB=PORTB&0xE0; show_pattern_enable = 0; } } void rotate_leds(void) { if(simon_led != 0) return; simon_led = 500; if(rotate < ROTATE_TIMES) { if(counter == 0) LED0 = 1; else LED0 = 0; if(counter == 1) LED1 = 1; else LED1 = 0; if(counter == 2) LED2 = 1; else LED2 = 0; if(counter == 3) LED3 = 1; else LED3 = 0; if(counter == 4) { LED4 = 1; counter = 0; rotate++; } else { LED4 = 0; counter++; } } else { if(winner == PLAYER_A) { PORTB=PORTB&0xE0|0x18; } if (winner == PLAYER_B) { PORTB=PORTB&0xE0|0x06; } else { PORTB=PORTB&0xE0|0x1F; } rotate_enabled = 0; } } void set_pattern(void) { unsigned char i; for(i=0; i< current_level; i++) pattern[i]=rand()%5; } void scan_photosensors(void) { if (target == PHOTO0)ADMUX = ADCPORT0; if (target == PHOTO1)ADMUX = ADCPORT1; if (target == PHOTO2)ADMUX = ADCPORT2; if (target == PHOTO3)ADMUX = ADCPORT3; if (target == PHOTO4)ADMUX = ADCPORT4; } interrupt [TIM1_COMPA] void timer_1ms() { if(radio_tx_timer!=RADIO_TIMER_OFF&&radio_tx_timer>0)radio_tx_timer--; if(radio_rx_timer!=RADIO_TIMER_OFF&&radio_rx_timer>0)radio_rx_timer--; if(led_timer>0)led_timer--; if(simon_led >0) simon_led--; }