//======================= Refresh ========================= // //Does Ball calculations and Draws the necessary elements on the screen static PT_THREAD (protothread_refresh(struct pt *pt)) { PT_BEGIN(pt); PT_YIELD_TIME_msec(100); //waits for the scoreboard to be set up while(1) { while (timeElapsed <=60) { PT_YIELD_TIME_msec(10); DmaChnDisable(dmaChn); DmaChnDisable(dmaChn2); //Generates a new ball at a given interval if(ballgen >= 10) { int troll1 = -((rand()) % 2)-1; int troll2 = ((rand()) % 6) - 3; struct Ball *temp = Ball_create(320,120,troll1,troll2,(numBalls+1)*500,0,NULL); temp->b = head; head = temp; ballgen = 0; numBalls++; } else ballgen ++; //collision calculations struct Ball *ti = head; struct Ball *tj = NULL; if(ti != NULL) tj = ti->b; while(ti !=NULL){ //Calculates the collisions between every ball while(tj != NULL) { int rij_x = ti->xpos - tj->xpos; int rij_y = ti->ypos - tj->ypos; int mag_rij = pow(rij_x,2) + pow(rij_y,2); //Checks if ti and tj are not pointing to the same ball, //If they close enough for a collision and there is no collision //delay. if( ti->delay + tj->delay == 0 && mag_rij < dist) { int vij_x = ti->xvel - tj->xvel; int vij_y = ti->yvel - tj->yvel; if (mag_rij==0) { mag_rij=dist; } int deltaVi_x = (int)((-1*(rij_x) * ((((rij_x * vij_x)+ (rij_y*vij_y)) << 7)/mag_rij)) >> 7); int deltaVi_y = (int)((-1*(rij_y) * ((((rij_x * vij_x)+ (rij_y*vij_y)) << 7)/mag_rij)) >> 7); /* tft_fillRoundRect(0,30, 320, 14, 1, ILI9340_BLACK);// x,y,w,h,radius,color tft_setCursor(0, 30); tft_setTextColor(ILI9340_WHITE); tft_setTextSize(2); sprintf(buffer,"%d:%d", (-1*(rij_x)/128 * (128*((rij_x * vij_x)+ (rij_y*vij_y))/mag_rij)), mag_rij); tft_writeString(buffer); */ //Updates the velocity ti->xvel = ti->xvel + deltaVi_x; ti->yvel = ti->yvel + deltaVi_y; tj->xvel = tj->xvel - deltaVi_x; tj->yvel = tj->yvel - deltaVi_y; ti->delay = delay_master; tj->delay = delay_master; } tj = tj->b; } //checks for wall collisions if(ti->xpos >= 320*scale || ti->xpos <= 0) ti->xvel = -1*ti->xvel; if(ti->ypos >= 240*scale || ti->ypos <= 35*scale) { ti->yvel = -1*ti->yvel; if (ti->xpos > 120*scale && ti->xpos < 200*scale) { //check for catch bin ti->delay=-1; //set to -1 to indicate +1 point } } //calculates the drag if(ti->xvel > 0) ti->xvel = ti->xvel - ti->xvel/drag; else ti->xvel = ti->xvel + ti->xvel/drag; if(ti->yvel > 0) ti->yvel = ti->yvel - ti->yvel/drag; else ti->yvel = ti->yvel - ti->yvel/drag; // Check for paddle Collisions if(abs(paddle_xpos-ti->xpos/scale) <= ballradius && ti->delay == 0) if(ti->ypos/scale > paddle_ypos - half_paddle_length && ti->ypos/scale < paddle_ypos + half_paddle_length) { ti->xvel = -1*ti->xvel; ti->yvel = ti->yvel + paddle_drag*paddle_v; ti->delay=delay_master; } //Decrement the collide delay if(ti->delay > 0) ti->delay = ti->delay -1; //iterates through the next set ti = ti->b; if(ti != NULL) tj = ti->b; //removes the last element if the limit is reached if(numBalls > maxBalls && tj->b == NULL) { tft_fillCircle(tj->xpos/scale,tj->ypos/scale,ballradius,ILI9340_BLACK); //erases from the screen ti->b = NULL; numBalls--; score++; //free(tj); } } // Calculates position of the paddle and draw //TODO: Calculate paddle position tft_drawLine(paddle_xpos,paddle_ypos - half_paddle_length, paddle_xpos, paddle_ypos + half_paddle_length, ILI9340_BLACK); paddle_v=paddle_ypos; paddle_ypos=(adc_9*240)/1023; paddle_v=paddle_ypos-paddle_v; tft_drawLine(paddle_xpos,paddle_ypos - half_paddle_length, paddle_xpos, paddle_ypos + half_paddle_length, ILI9340_WHITE); // Now it calculates the new position ti = head; tj = head; while(ti != NULL){ //"Clears" the image of the last ball tft_fillCircle(ti->xpos/scale,ti->ypos/scale,ballradius,ILI9340_BLACK); //Updates the new position of the ball ti->xpos = ti->xpos + ti->xvel; ti->ypos = ti->ypos + ti->yvel; //ensures the positions are within bounds //If the pos is less than 0 then we remove it //delay must also not be -1 (ie >=0) if(ti->xpos > paddle_xpos && ti->delay != -1) { if(ti->xpos > 320*scale) ti->xpos = 320*scale; if(ti->ypos > 240*scale) ti->ypos = 240*scale; else if(ti->ypos < 35*scale) ti->ypos = 35*scale; if(ti->delay > 0) tft_fillCircle(ti->xpos/scale, ti->ypos/scale, ballradius, ILI9340_WHITE); else tft_fillCircle(ti->xpos/scale, ti->ypos/scale, ballradius, ti->color); } else { //REMOVES THE BALL IF IT CROSSES THE BOUNDARY if (ti->delay==-1) { //check if went into catch bins score++; DmaChnEnable(dmaChn2); } else { DmaChnEnable(dmaChn); score--; } if(ti == head) head = head->b; else tj->b = ti->b; numBalls--; //free(ti); } tj = ti;//what does this do? ti = ti->b; } frames ++; } tft_fillRoundRect(0,35, 320, 205, 1, ILI9340_BLACK);// x,y,w,h,radius,color DmaChnDisable(dmaChn); DmaChnDisable(dmaChn2); DmaChnEnable(dmaChn3); while (1) { tft_setCursor(20, 120); tft_setTextColor(ILI9340_WHITE); tft_setTextSize(4); sprintf(buffer,"Game Over!"); tft_writeString(buffer); } }
static void drawLine( int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t color) { tft_drawLine(x0 + MAX_TFT_X/2, y0 + MAX_TFT_Y/2, x1 + MAX_TFT_X/2, y1 + MAX_TFT_Y/2, color); }
void drawSVG(window *win, int16_t x, int16_t y, int16_t c, float scale, uint16_t color, int16_t fill) { p2_int16_t Ctl,T; p2_int16_t Cur; p2_int16_t Move; int16_t Xsize,Ysize; int state; p2_int16_t p[3]; p2_int16_t B[BEZIER_STEPS]; int ind; int t; int i,j,count; int16_t *v; if( c >= 32 && c <= 127) { c -= 32; v = vfont[c]->v; Xsize = (scale * vfont[c]->xinc); Ysize = (scale * vfont[c]->yinc); // CLear tft_fillRectWH(win, x, y, Xsize, Ysize, win->bg); } else { printf("DrawSVG: invalid character\n"); return; } printf("DrawSVG:(%d,%d) scale:%e)\n", x,y,(double)scale); ind = 0; state = 0; while(1) { char t = v[ind]; if (t == 'M') { // Move takes to move points Move.X = x + (scale * v[ind + 1]); Move.Y = y + (scale * v[ind + 2]); //printf("M: Move.X:%d,Move.Y:%d\n", (int)Move.X,(int)Move.Y); Cur.X = Move.X; Cur.Y = Move.Y; if(state < 3) { p[state].X = Cur.X; p[state].Y = Cur.Y; ++state; } ind += 3; } else if (t == 'L' ) { // Line takes Cur.X,Cur.Y and to target points T.X = x + (scale * v[ind + 1]); T.Y = y + (scale * v[ind + 2]); //printf("L: Curx:%d,Cury:%d,T.X:%d,T.Y:%d\n", (int)Cur.X,(int)Cur.Y,(int)T.X,(int)T.Y); if(T.X != Cur.X || T.Y != Cur.Y) { tft_drawLine(win, Cur.X, Cur.Y, T.X, T.Y, color); if(state < 3) { p[state].X = T.X; p[state].Y = T.Y; ++state; } } Cur.X = T.X; Cur.Y = T.Y; ind += 3; } else if (t == 'Q' ) { // Q Bezier takes Cur.X,Cur.Y, two control points and to target points Ctl.X = x + (scale * v[ind + 1]); Ctl.Y = y + (scale * v[ind + 2]); T.X = x + (scale * v[ind + 3]); T.Y = y + (scale * v[ind + 4]); //printf("Q: Cur.X:%d,Cury:%d,Ctl.X:%d,Ctl.Y:%d,T.X:%d,T.Y:%d\n", (int)Cur.X,(int)Cur.Y,(int)Ctl.X,(int)Ctl.Y,(int)T.X,(int)T.Y); if(T.X != Cur.X || T.Y != Cur.Y) { #if 1 count = tft_Bezier2(win, Cur, Ctl, T, BEZIER_STEPS, color); #else if(T.X != Cur.X || T.Y != Cur.Y) tft_drawLine(win, Cur.X, Cur.Y, T.X, T.Y, color); #endif if(state < 3) { p[state].X = T.X; p[state].Y = T.Y; ++state; } } Cur.X = T.X; Cur.Y = T.Y; ind += 5; } else if (t == 'Z') { // CLOSE takes no params //printf("Z: Curx:%d,Cury:%d,Move.X:%d,Move.Y:%d\n", (int)Cur.X,(int)Cur.Y,(int)Move.X,(int)Move.Y); if(Cur.X != Move.X || Cur.Y != Move.Y) { tft_drawLine(win, Cur.X, Cur.Y, Move.X, Move.Y, color); if(state < 3) { p[state].X = T.X; p[state].Y = T.Y; ++state; } } Cur.X = Move.X; Cur.Y = Move.Y; ind += 1; } else if (t == '.') { break; } else { printf("bad type:%c @ index:%d\n", (int)t, (int)ind); break; } } #if 1 if(state == 3) { int i; printf("Fill\n"); for(i=0;i<3;++i) { printf("%d,%d\n", p[i].X, p[i].Y); } } #else if(fill) { for(i=0;i<Ysize;++i) { count = tft_FillPolyLine( win , x, y + i, Xsize, color ); // optimistic_yield(1000); } } #endif }