#include #include "basic/basic.h" #include "basic/byteorder.h" #include "lcd/lcd.h" #include "lcd/print.h" #include "funk/nrf24l01p.h" //includes useful for r_game: //#include "usbcdc/usb.h" //#include "usbcdc/usbcore.h" //#include "usbcdc/usbhw.h" //#include "usbcdc/cdcuser.h" //#include "usbcdc/cdc_buf.h" //#include "usbcdc/util.h" #include #include "basic/random.h" #include "usetable.h" #define REMOTE_CHANNEL 81 //mac that the player receives #define PLAYER_MAC "\x1\x2\x3\x2\x1" //mac that the game receives #define GAME_MAC "\x1\x2\x3\x2\x1" //#if CFG_USBMSC //#error "MSC is defined" //#endif //#if !CFG_USBCDC //#error "CDC is not defined" //#endif struct NRF_CFG config; struct packet{ uint8_t len; uint8_t protocol; uint8_t command; uint32_t id; uint32_t ctr; //union with 19 bytes data union content{ struct button{ uint8_t button; uint8_t reserved[18]; }__attribute__((packed)) button; struct text{ uint8_t x; uint8_t y; uint8_t flags; uint8_t text[16]; }__attribute__((packed)) text; struct nick{ uint8_t flags; uint8_t text[18]; }__attribute__((packed)) nick; struct nickrequest{ uint8_t reserved[19]; }__attribute__((packed)) nickrequest; struct ack{ uint8_t flags; uint8_t reserved[18]; }__attribute__((packed)) ack; struct announce{ uint8_t gameMac[5]; uint8_t gameChannel; //uint8_t playerMac[5]; playerMac = gameMac+1; uint32_t gameId; uint8_t gameFlags; uint8_t gameTitle[8]; }__attribute__((packed)) announce; struct join{ uint32_t gameId; uint8_t reserved[15]; }__attribute__((packed)) join; }c; uint16_t crc; }__attribute__((packed)); #define sizeof(p) (sizeof(struct packet)) #define FLAGS_MASS_GAME 1 #define FLAGS_ACK_JOINOK 1 #define MASS_ID 1 /**************************************************************************/ /* l0dable for playing games which are announced by other r0kets with the l0dabel r_game */ /* Values of buf[3]: * B: packet sent by player, contain information which button is pressed * T: packet sent by game, contain text for display * N: packet sent by game, requesting nick * n: packet sent player, containing nick * A: packet sent by game, announcing game * J: packet sent by player, requesting to join game * a: ack, packet with $ctr was received */ uint32_t ctr; uint32_t id; uint32_t gameId; void sendButton(uint8_t button); void sendJoin(uint32_t game); void processPacket(struct packet *p); void processAnnounce(struct announce *a); uint8_t selectGame(); void playGame(); struct announce games[7]; uint8_t gamecount; void ram(void) { config.nrmacs=1; config.maclen[0] = 32; id = getRandom(); ctr = 1; while( selectGame() ){ playGame(); } }; void playGame(void) { int len; struct packet p; while(1){ uint8_t button = getInputRaw(); sendButton(button); while(1){ len = nrf_rcv_pkt_time(30,sizeof(p),(uint8_t*)&p); if(len==sizeof(p)){ processPacket(&p); }else{ break; } } delayms(20); }; } void showGames(uint8_t selected) { int i; lcdClear(); lcdPrintln("Games:"); if( gamecount ){ for(i=0;i 0 ){ selected--; } break; case BTN_LEFT: return 0; case BTN_ENTER: case BTN_RIGHT: if( gamecount == 0 ) return 0; gameId = games[selected].gameId; memcpy(config.txmac, games[selected].gameMac, 5); memcpy(config.mac0, games[selected].gameMac, 5); config.mac0[4]++; config.channel = games[selected].gameChannel; nrf_config_set(&config); if( games[selected].gameFlags & FLAGS_MASS_GAME ) return 1; else return joinGame(); } } } 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'){ //processText(&(p->c.text)); } else if (p->command=='N'){ //processNick(&(p->c.nickrequest)); } else if (p->command=='A'){ processAnnounce(&(p->c.announce)); } } } void processAnnounce(struct announce *a) { if( gamecount < sizeof(games)/sizeof(games[0]) ){ games[gamecount] = *a; gamecount++; } } //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(); nrf_snd_pkt_crc(sizeof(p),(uint8_t*)&p); } //send join request for game void sendJoin(uint32_t game) { struct packet p; p.len=sizeof(p); p.protocol='G'; p.command='J'; p.ctr= ++ctr; p.id=id; p.c.join.gameId=game; nrf_snd_pkt_crc(sizeof(p),(uint8_t*)&p); } /* void s_init(void){ usbCDCInit(); nrf_init(); struct NRF_CFG config = { .channel= REMOTE_CHANNEL, .txmac= REMOTE_MAC, .nrmacs=1, .mac0= REMOTE_MAC, .maclen ="\x10", }; nrf_config_set(&config); }; */ /* void process(uint8_t * input){ __attribute__ ((aligned (4))) uint8_t buf[32]; puts("process: "); puts(input); puts("\r\n"); if(input[0]=='M'){ buf[0]=0x10; // Length: 16 bytes buf[1]='M'; // Proto buf[2]=0x01; buf[3]=0x01; // Unused uint32touint8p(0,buf+4); uint32touint8p(0x41424344,buf+8); buf[12]=0xff; // salt (0xffff always?) buf[13]=0xff; nrf_snd_pkt_crc_encr(16,buf,remotekey); nrf_rcv_pkt_start(); }; }; */ /* #define INPUTLEN 99 void r_recv(void){ __attribute__ ((aligned (4))) uint8_t buf[32]; int len; uint8_t input[INPUTLEN+1]; int inputptr=0; nrf_rcv_pkt_start(); puts("D start"); getInputWaitRelease(); while(!getInputRaw()){ delayms(100); // Input int l=INPUTLEN-inputptr; CDC_OutBufAvailChar (&l); if(l>0){ CDC_RdOutBuf (input+inputptr, &l); input[inputptr+l+1]=0; for(int i=0;i