//increment ctr and send button state, id and ctr void sendButton(uint8_t button) { struct packet p; p.len=sizeof(p); p.protocol='G'; // Proto p.command='B'; p.id= id; p.ctr= ++ctr; p.c.button.button=button; //lcdClear(); //lcdPrint("Key:"); lcdPrintInt(buf[2]); lcdNl(); if( flags & FLAGS_SHORT_PACKET ) nrf_snd_pkt_crc(16,(uint8_t*)&p); else nrf_snd_pkt_crc(sizeof(p),(uint8_t*)&p); }
void processNickRequest( struct nickrequest *nq) { struct packet p; p.len=sizeof(p); p.protocol='G'; // Proto p.command='n'; p.id= id; p.ctr= ++ctr; p.c.nick.flags = 0; uint8_t *nick = GLOBAL(nickname); strcpy(p.c.nick.nick, nick); nrf_snd_pkt_crc(sizeof(p),(uint8_t*)&p); }
uint8_t joinGame() { int i; struct packet p; struct packet ack; memset((void*)&p, 0, sizeof(p)); memset((void*)&ack, 0, sizeof(ack)); p.len=sizeof(p); p.protocol='G'; p.command='J'; p.id= id; p.ctr= ++ctr; p.c.join.gameId=gameId; lcdPrintln("Joining game"); lcdRefresh(); for(i=0; i<10; i++){ nrf_snd_pkt_crc(sizeof(p),(uint8_t*)&p); int len = nrf_rcv_pkt_time(30,sizeof(ack),(uint8_t*)&ack); if( len==sizeof(ack) ){ if( (ack.len==32) && (ack.protocol=='G') && ack.command=='a' ){ //check sanity, protocol if( ack.id == id && ack.ctr == ctr ){ if( ack.c.ack.flags & FLAGS_ACK_JOINOK ){ lcdPrintln("Join OK"); lcdRefresh(); return 1; }else{ lcdPrintln("Join rejected"); lcdRefresh(); getInputWait(); getInputWaitRelease(); return 0; } } } } delayms(70); } lcdPrintln("timeout :("); lcdRefresh(); getInputWait(); getInputWaitRelease(); return 0; }
void processPacket(struct packet *p) { if ((p->len==32) && (p->protocol=='G') && (p->id == id || p->id == 0) ){ //check sanity, protocol, id if (p->command=='T'){ struct packet ack; ack.len=sizeof(p); ack.protocol='G'; ack.command='a'; ack.id= id; ack.ctr= p->ctr; ack.c.ack.flags = 0; nrf_snd_pkt_crc(sizeof(ack),(uint8_t*)&ack); processText(&(p->c.text)); } else if (p->command=='N'){ processNickRequest(&(p->c.nickrequest)); } else if (p->command=='A'){ processAnnounce(&(p->c.announce)); } } }
void handle_packet(struct packet *p){ switch(p->type){ case PKT_ANNOUNCE: if(mode == MODE_CLIENT){ if(!started){ gameid = p->gameid; struct packet join; memset((void*)&join, 0, sizeof(join)); join.gameid = gameid; join.type = PKT_JOIN; memcpy(join.c.join.nick, GLOBAL(nickname), 16); join.seq = p->seq+1; nrf_snd_pkt_crc(sizeof(join), (uint8_t *)&join); player_joined = 1; } } break; case PKT_JOIN: if(mode == MODE_SERVER){ if(!started){ if(!player_joined){ started = 1; lcdClear(); lcdPrintln("Player joined"); lcdPrintln((char *)&p->c.join.nick); lcdRefresh(); struct packet ack; memset((void*)&ack, 0, sizeof(ack)); ack.gameid = gameid; ack.type = PKT_ACK; //memcpy(ack.c.ack.nick, GLOBAL(nickname), 16); ack.seq = p->seq+1; nrf_snd_pkt_crc(sizeof(ack), (uint8_t *)&ack); player_joined = 1; delayms(1000); init(); struct packet state; memset((void*)&state, 0, sizeof(state)); state.gameid = gameid; state.type = PKT_GAMESTATE; state.c.state.score1 = player1.score; state.c.state.score2 = player2.score; state.c.state.pad1 = player1.paddle_pos; state.c.state.pad2 = player2.paddle_pos; state.c.state.ball_x = ball1.x; state.c.state.ball_y = ball1.y; state.seq = p->seq+2; nrf_snd_pkt_crc(sizeof(state), (uint8_t *)&state); } } } break; case PKT_ACK: if(mode == MODE_CLIENT){ if(!started){ started = 1; lcdClear(); lcdPrintln("Joined!"); //lcdPrintln((char *)&p->c.announce.nick); init(); lcdRefresh(); } } break; case PKT_GAMESTATE: if(mode == MODE_CLIENT){ if(started){ player1.score = p->c.state.score1; player2.score = p->c.state.score2; player1.paddle_pos = p->c.state.pad1; player2.paddle_pos = p->c.state.pad2; ball1.x = p->c.state.ball_x; ball1.y = p->c.state.ball_y; if(!check_end()){ lcdClear(); print_score(); draw_paddles(); just_draw_ball(); lcdDisplay(); struct packet move; memset((void*)&move, 0, sizeof(move)); move.gameid = gameid; move.type = PKT_MOVEMENT; move.c.movement.dir = next_move; move.seq = p->seq+1; delayms(50); nrf_snd_pkt_crc(sizeof(move), (uint8_t *)&move); latest_packet = move; next_move = DIR_STAY; receive = 1; } } } break; case PKT_MOVEMENT: if(mode == MODE_SERVER){ if(started){ if(next_move != DIR_LEFT) // Only let valid keys through move_player(&player1, next_move); if(p->c.movement.dir != DIR_RIGHT) // Only let valid keys through move_player(&player2, p->c.movement.dir); check_collision_players(); draw_ball(); lcdClear(); print_score(); //check_collision_player(&player1); //check_collision_player(&player2); draw_paddles(); just_draw_ball(); lcdDisplay(); struct packet state; memset((void*)&state, 0, sizeof(state)); state.gameid = gameid; state.type = PKT_GAMESTATE; state.c.state.score1 = player1.score; state.c.state.score2 = player2.score; state.c.state.pad1 = player1.paddle_pos; state.c.state.pad2 = player2.paddle_pos; state.c.state.ball_x = ball1.x; state.c.state.ball_y = ball1.y; state.seq = p->seq+1; delayms(50); nrf_snd_pkt_crc(sizeof(state), (uint8_t *)&state); latest_packet = state; next_move = DIR_STAY; receive = 1; check_end(); } } break; case PKT_EXIT: if(started){ if(mode == MODE_CLIENT) player2.score = MAX_POINTS; else player1.score = MAX_POINTS; check_end(); } break; } }
void main(void){ started = 0; receive = 1; next_move = DIR_STAY; mode = MODE_INIT; player_joined = 0; lcdClear(); lcdPrintln("Up: server"); lcdPrintln("Down: client"); lcdPrintln("Enter: exit"); lcdRefresh(); int8_t priv = GLOBAL(privacy); GLOBAL(privacy) = 3; uint8_t btn; uint8_t cycles_wait; cycles_wait = 0; struct packet announce; do{ btn = getInputRaw(); if(mode == MODE_INIT){ if(btn == BTN_UP){ startServer(); } else { if(btn == BTN_DOWN){ startClient(); } } } if(!started){ if(mode == MODE_SERVER && !player_joined){ memset((void*)&announce, 0, sizeof(announce)); announce.gameid = gameid; announce.type = PKT_ANNOUNCE; memcpy(announce.c.announce.nick, GLOBAL(nickname), 16); announce.seq = 0; nrf_snd_pkt_crc(sizeof(announce), (uint8_t *)&announce); struct packet p; if(nrf_rcv_pkt_time(1000, sizeof(p), (uint8_t *)&p) == sizeof(p)){ handle_packet(&p); } } else if (mode == MODE_CLIENT){ struct packet p; if(nrf_rcv_pkt_time(100, sizeof(p), (uint8_t *)&p) == sizeof(p)){ handle_packet(&p); } } } else { if(receive){ struct packet p; if(nrf_rcv_pkt_time(50, sizeof(p), (uint8_t *)&p) == sizeof(p)){ cycles_wait = 0; handle_packet(&p); } else { cycles_wait++; } if(cycles_wait >= 3){ nrf_snd_pkt_crc(sizeof(latest_packet), (uint8_t *)&latest_packet); cycles_wait = 0; } } else { delayms(50); } next_move = btn; } }while(btn != BTN_ENTER); struct packet p; p.type = PKT_EXIT; for(uint8_t i = 0; i < 3; i++){ delayms(50); nrf_snd_pkt_crc(sizeof(p), (uint8_t *)&p); } GLOBAL(privacy) = priv; }