the place we got to by the end of the last session
Dependencies: LCDTFT TFT_fonts TSI mbed
Fork of ESP8266_MDM_CJS_KL25 by
main.cpp
- Committer:
- trapsis
- Date:
- 2016-06-10
- Revision:
- 5:882898bb83ed
- Parent:
- 4:354d278c0d52
- Child:
- 6:00d91197dd66
File content as of revision 5:882898bb83ed:
#include "mbed.h" #include "TSISensor.h" #include "LCDTFT.h" #include "Arial28x28.h" #define DEBUG #define INFOMESSAGES #define WARNMESSAGES #define ERRMESSAGES #define FUNCNAME "MAIN" #ifdef NoDEBUG #define DBG(x, ...) pc.printf(" ["FUNCNAME" : DBG] "x" <line %d>\r\n", ##__VA_ARGS__,__LINE__); #else #define DBG(x, ...) #endif #ifdef ERRMESSAGES #define ERR(x, ...) pc.printf(" ["FUNCNAME" : ERR] "x"\r\n", ##__VA_ARGS__); #else #define ERR(x, ...) #endif #ifdef WARNMESSAGES #define WARN(x, ...) printf("["FUNCNAME" : WARN] "x"\r\n", ##__VA_ARGS__); #else #define WARN(x, ...) #endif #ifdef INFOMESSAGES #define INFO(x, ...) pc.printf("["FUNCNAME" : INFO] "x"\r\n", ##__VA_ARGS__); #else #define INFO(x, ...) #endif #define BUFF_SIZE 1024 // PIN DEFS NOW FOR OLD FIRMWARE VERSION OF THE KL25Z Serial pc(USBTX, USBRX); //RawSerial dev(D1, D0); //Serial dev(PTD3,PTD2); //tx,rx Serial dev(D14,D15); //tx,rx DigitalOut led1(LED1); DigitalOut led4(LED3); // CHANGE TO LED 3 DigitalOut reset(D0,1); PortOut MyPort(PortD ,0xFF); // define a port with only the lower 8 bits included - that'llbe PTD0-PTD7 making a single 8 bit port. LCDTFT MyLCD(PTB0,PTB1,PTB2,PTB3,PTC2,&MyPort);//LCDTFT(PinName PIN_RD,PinName PIN_WR,PinName PIN_RS,PinName PIN_CS,PinName PIN_RESET, PortOut *PORTLCD); PwmOut led(LED_GREEN); TSISensor tsi; volatile int state=0; volatile int ready=0; //--- void run(); void countdown(); void changeDirec(); void nextmove(); void initGrid(); void updateGrid(); void drawGrid(); void checkposition(); void gameover1(); void gameover2(); void PrettyPrint(char *message,const unsigned char *font,short xpos,short ypos,short bcol, short fcol); void prettyputc(char c, const unsigned char *font,short xpos,short ypos,short bcol, short fcol); bool GameRunning = 1; const int gridWidth = 64; const int gridHeight = 48; char grid [48][64]; char snake [2][255]; //represent the grid as a 2 dimensional array char newDirectSnake = 2; char newDirectFood = 2; char newFoodVel = 0; //incoming values from the controller int snakexpos = 20; int snakeypos = 20; char directSnake = 2; char snakeSize = 3; //establish values for the snake int foodxpos = 2; int foodypos = 20; char foodvel = 1; char directFood = 1; //establish values for the food char message [32]; //for printing purposes int framecount = 0; //number of iterations in the main loop //----- char ipAddress[20]; char macAddress[32]; char *buffer; unsigned int bufferPnt=0; void commandReceived(char *buffer){ char identifier =buffer[0]; if (identifier == 1) { newDirectFood=buffer[4]; newFoodVel=buffer[8]; } if (identifier == 2) { newDirectSnake=buffer[4]; } if (identifier == 3) { GameRunning=buffer[4]; } } // next two functions need moving to the library..... // ok - a simple sub to put in a character from the fonts defined in TFT_fonts // c= charactetr to put // font = pointer to font to use // x,y locatoin of bottom lh of character, bcol = background color, fcol = foreground color //prettyputc("m",Arial12x12,50,50,ColorBlack,ColorWhite); void prettyputc(char c, const unsigned char *font,short xpos,short ypos,short bcol, short fcol) { // Length,horz,vert,byte/vert int length,hor,vert,bpver; // number of bytes per character, horizontal pixels, vertical pixels and bytes per column // int x,y,i,j,k,ptr; short coltowrite; char byte,point; length=font[0]; hor=font[1]; vert=font[2]; bpver=font[3]; for(i=0; i<hor; i++) { // loop over columns for(j=0; j<vert; j++) { x=xpos+i; y=ypos+j; // NB assumes colums stored from bottom to top.... ? ptr=((c -32) * length+1) + 4+i*bpver+(j/8); // pointer in font array to start of the character we want +1 to avoid the first byte that holds the char width byte=(char)font[ptr]; k=j%8; // number of the pixel in this byte point=byte & (1<<k); // get the next bit if(point>0) { coltowrite=fcol; } else { coltowrite=bcol; } MyLCD.vLCDTFTPoint(x,y,coltowrite); } } } // ok now a function to use pretty putc to write strings whose bottom left corner are at xpo,ypos // general idea is that the string is first formatted byb sprintf and the PrettyPrint is called // bcol and fcol are the backgroun adn foreground colors //NB max message length = 64 characters void PrettyPrint(char *message,const unsigned char *font,short xpos,short ypos,short bcol, short fcol) { short x,y,messlength,i,ptr; messlength=strlen(message); if (messlength >64) messlength=64; // avoid writing too large a string.... x=xpos; for(i=0; i<messlength; i++) { // x=xpos+i*(font[1]*8/10); // font[1]=char width 80% to avoid gaps //pointer = &font[((c -32) * offset) + 4]; // start of char bitmap // w = pointer[0]; // width of actual char ptr=((message[i] -32) * font[0]) + 4; y=ypos; // will have to add cod and more to deal with different screen orientations //prettyputc(char c, const unsigned char *font,short xpos,short ypos,short bcol, short fcol) prettyputc(message[i],font,x,y,bcol,fcol); x=x+font[ptr]+2; } } void run() //the main game program { while (1) { if (GameRunning == 1) { countdown(); initGrid(); while (1) { checkposition(); commandReceived(buffer); changeDirec(); nextmove(); updateGrid(); drawGrid(); framecount++; } } } } void countdown() //countdown before game begins { MyLCD.vLCDTFTInit(1); MyLCD.vLCDTFTFillScreen(ColorBlack); sprintf(message,"Get Ready!"); PrettyPrint(message,Arial28x28,10,50,ColorBlack,ColorLime); wait(1); MyLCD.vLCDTFTFillScreen(ColorBlack); sprintf(message,"3"); PrettyPrint(message,Arial28x28,10,50,ColorBlack,ColorLime); wait(1); MyLCD.vLCDTFTFillScreen(ColorBlack); sprintf(message,"2"); PrettyPrint(message,Arial28x28,10,50,ColorBlack,ColorLime); wait(1); MyLCD.vLCDTFTFillScreen(ColorBlack); sprintf(message,"1"); PrettyPrint(message,Arial28x28,10,50,ColorBlack,ColorLime); wait(1); MyLCD.vLCDTFTFillScreen(ColorBlack); sprintf(message,"Run!"); PrettyPrint(message,Arial28x28,10,50,ColorBlack,ColorLime); wait(1); } void initGrid() //initialize the grid { MyLCD.vLCDTFTInit(1); MyLCD.vLCDTFTFillScreen(ColorBlack); for(int x=0; x<gridHeight; x++) { for(int y=0; y<gridWidth; y++) { grid[x][y] = 0; } } //initialize the pixel grid as an array of zeros snake[0][0] = snakexpos; snake[1][0] = 20; snake[0][1] = 21; snake[1][1] = 20; snake[0][2] = 22; snake[1][2] = 20; for(int i=3; i<255; i++) { grid[snake[1][i]][snake[0][i]] = 0; } //initialize the snake as horizontal with respect to its initial size (1 = tile occupied by snake) grid[foodypos][foodxpos] = 2; //initialize the food (2 = tile occupied by food) } void updateGrid() //update the grid with positions { /*if (grid[snakexpos][snakeypos] == 1) gameover2(); else { */ for(int a=snakeSize-2; a>=0; a--) { snake[0][a+1] = snake [0][a]; snake[1][a+1] = snake [1][a]; // } snake[0][0] = snakexpos; snake[1][0] = snakeypos; } for(int x=0; x<gridHeight; x++) { for(int y=0; y<gridWidth; y++) { grid[x][y] = 0; } } for(int i=0; i<snakeSize; i++) { grid[snake[1][i]][snake[0][i]] = 1; } //update the snake, if the tile was previously occupied, snake has hit itself = gameover2 if (grid[foodypos][foodxpos] == 1) { gameover1(); } else { grid[foodypos][foodxpos] = 2; } //update the food, if the tile was previously occupied, food has hit snake = gameover1 } void drawGrid() //draw the grid { for(int x=0; x<gridHeight; x++) { for(int y=0; y<gridWidth; y++) { /* if (grid[x][y] == 0) { MyLCD.vLCDTFTRectangle(5*y,5*x,5*y+5,5*x+5,1,ColorBlack); } */ if (grid[x][y] == 1) { MyLCD.vLCDTFTRectangle(5*y,5*x,5*y+5,5*x+5,1,ColorBlue); } if (grid[x][y] == 2) { MyLCD.vLCDTFTRectangle(5*y,5*x,5*y+5,5*x+5,1,ColorWhite); } } } wait (0.1); //the game is 10fps (up for discussion we'll see how this goes) } void changeDirec() //changing direction, the command will have to come from the controller program //assume 0 for up, 1 for right, 2 for down, 3 for left { foodvel = newFoodVel; directFood = newDirectFood; //assign new direction and speed to food if ((newDirectSnake + directSnake)%2 == 0 && newDirectSnake != directSnake) gameover2(); //the snake loses if it tries to double up on itself else directSnake = newDirectSnake; //assign new direction to snake } void nextmove() //move the snake and the food by incrementing their coordinates (for the food increment by velocity) { if (framecount%5 == 0){ snakeSize++; } // every 5 iterations, the snake grows MyLCD.vLCDTFTRectangle(5*foodxpos,5*foodypos,5*foodxpos+5,5*foodypos+5,1,ColorBlack); MyLCD.vLCDTFTRectangle(5*snake[0][snakeSize-1],5*snake[1][snakeSize-1],5*snake[0][snakeSize-1]+5,5*snake[1][snakeSize-1]+5,1,ColorBlack); if (directFood == 0) { foodypos -= foodvel; } if (directFood == 1) { foodxpos += foodvel; } if (directFood == 2) { foodypos += foodvel; } if (directFood == 3) { foodxpos -= foodvel; } // check the direction of food and increment position according to velocity if (directSnake == 0) { snakeypos -= 1; } if (directSnake == 1) { snakexpos += 1; } if (directSnake == 2) { snakeypos += 1; } if (directSnake == 3) { snakexpos -= 1; } } void checkposition() //check position to see if either player is out of bounds { if (snakeypos > gridHeight || snakeypos < 0) gameover2(); if (snakexpos > gridWidth || snakexpos < 0) gameover2(); if (foodypos > gridHeight || foodypos < 0) gameover1(); if (foodxpos > gridWidth || foodxpos < 0) gameover1(); //end the game with the appropriate game over screen if either player is out of bounds } void gameover1() //print game over message and display final score { MyLCD.vLCDTFTFillScreen(ColorBlack); sprintf(message,"You are snake food!"); PrettyPrint(message,Arial28x28,10,50,ColorBlack,ColorLime); GameRunning = 0; } void gameover2() //an alternate ending is that the snake has made a mistake and that the food wins { MyLCD.vLCDTFTFillScreen(ColorBlack); sprintf(message,"The snake is dead!"); PrettyPrint(message,Arial28x28,10,50,ColorBlack,ColorLime); wait (1000); GameRunning = 0; } void dev_recv() { char c; int count = 0; led1 = !led1; if(bufferPnt==0) { memset(buffer,0,BUFF_SIZE); } while(dev.readable()) { c = (char)dev.getc(); #ifdef DEBUG pc.putc(c); #endif buffer[bufferPnt]=c; bufferPnt++; if (bufferPnt>1000) { ready=1; } // if ((c==0x0a)||(c==0x0d)){ // ready=1; // }else if (c==0x0a) { if (bufferPnt>1) { if (buffer[bufferPnt -2]==0x0d) { ready=1; break; } } } if (!dev.readable()) { wait_us(10); } } } void pc_recv() { char c; led4 = !led4; while(pc.readable()) { c=(char)pc.getc(); dev.putc(c); pc.putc(c); if(c==13) { dev.putc(10); pc.putc(10); } } } char * OKResponse(char *test, const char *pattern) { char *p= strstr(test,pattern); if (p==NULL) { // DBG("Test=<%s> Patter=<%s> NULL [p=%s]",test,pattern,p); return NULL; } else { // DBG("YAY Test=<%s> Patter=<%s> [p=%s]",test,pattern,p); } return p; } /*Game programme */ int main() { float touch; buffer=(char *)calloc(BUFF_SIZE,1); reset=0; int counter=0; pc.baud(115200); dev.baud(115200); pc.attach(&pc_recv, Serial::RxIrq); dev.attach(&dev_recv, Serial::RxIrq); pc.printf("Start up\n\r"); wait(1.5); reset=1; char * resp=NULL; pc.printf("Here \n\r"); while(1) { if (ready) { ready=0; bufferPnt=0; INFO("[%d],##%s##",state,buffer); switch (state) { case 0: { resp=OKResponse(buffer,"WIFI GOT IP"); if (resp!=NULL) { wait(1); dev.printf("AT\r\n"); state++; } break; } case 1: case 2: { resp=OKResponse(buffer,"OK"); if (resp!=NULL) { dev.printf("AT\r\n"); state++; } break; } case 3: { resp=OKResponse(buffer,"OK"); if (resp!=NULL) { dev.printf("AT+RST\r\n"); state++; } break; } case 4: { resp=OKResponse(buffer,"WIFI GOT IP"); if (resp!=NULL) { dev.printf("AT+CWMODE=1\r\n"); state++; } break; } case 5: { resp=OKResponse(buffer,"OK"); if (resp!=NULL) { dev.printf("AT+CWJAP=\"CWMWIFI\",\"CWM2016TT\"\r\n"); state++; } break; } case 6: { resp=OKResponse(buffer,"OK"); if (resp!=NULL) { wait(1); dev.printf("AT+CIFSR\r\n"); state++; } break; } case 7: { resp=OKResponse(buffer,"+CIFSR:STAIP,"); if (resp!=NULL) { char *strt = strtok(buffer,"\""); strcpy(ipAddress,strtok(NULL,"\"")); strtok(NULL,"\""); strcpy(macAddress,strtok(NULL,"\"")); INFO("mac Address = %s", macAddress); INFO("IP Address = %s", ipAddress); dev.printf("AT+CIPMUX=1\r\n"); state++; } break; } case 8: { resp=OKResponse(buffer,"OK"); if (resp!=NULL) { INFO("Ready"); dev.printf("AT+CIPSERVER=1,5050\r\n"); //Set it as a server state++; } break; } case 9: { resp=OKResponse(buffer,"+IPD"); if (resp!=NULL) { INFO("Got <%s>",buffer); commandReceived(buffer); // Interpret data run(); state=9; // Keep on waiting for data } break; } /* case 9: { resp=OKResponse(buffer,"OK"); if (resp!=NULL) { INFO("Ready"); state++; dev.printf("AT+CIPSEND=4,10\r\n"); } break; } case 10: { resp=OKResponse(buffer,">"); if (resp!=NULL) { INFO("SENDING"); state++; touch=tsi.readPercentage(); dev.printf("TSI=%1.2f\n\r",touch); pc.printf(" ############ tsi=%1.2f\n\r",touch); //INFO("sensor=%1.2f",float)tsi.readPercentage()); } case 11: { resp=OKResponse(buffer,"SEND OK"); if (resp!=NULL) { INFO("SEND OK"); state=9; //wait(2); } wait(1); state=9; } break; }*/ } } //__WFI(); // DELETED AS IT KILLS THE KL25 RESPONSIVITY } }