void drawdisplay_rat(uint8_t inverted) { setscore_rat(); // erase old ball // *** THIS DOESN'T WORK WITH FIXED=256 glcdFillRectangle(INT_MSB(oldball_x), INT_MSB(oldball_y), BALL_RADIUS*2, BALL_RADIUS*2, inverted); // draw new ball glcdFillRectangle(INT_MSB(ball_x), INT_MSB(ball_y), BALL_RADIUS*2, BALL_RADIUS*2, ! inverted); // draw middle lines around where the ball may have intersected it? if (intersectrect(INT_MSB(oldball_x), INT_MSB(oldball_y), BALL_RADIUS*2, BALL_RADIUS*2, SCREEN_W/2-MIDLINE_W, 0, MIDLINE_W, SCREEN_H)) { // redraw it since we had an intersection drawmidline(inverted); } if (oldleftpaddle_y != leftpaddle_y) { // clear left paddle glcdFillRectangle(LEFTPADDLE_X, INT_MSB(oldleftpaddle_y), PADDLE_W, PADDLE_H, inverted); } // draw left paddle glcdFillRectangle(LEFTPADDLE_X, INT_MSB(leftpaddle_y), PADDLE_W, PADDLE_H, !inverted); if (oldrightpaddle_y != rightpaddle_y) { // clear right paddle glcdFillRectangle(RIGHTPADDLE_X, INT_MSB(oldrightpaddle_y), PADDLE_W, PADDLE_H, inverted); } // draw right paddle glcdFillRectangle(RIGHTPADDLE_X, INT_MSB(rightpaddle_y), PADDLE_W, PADDLE_H, !inverted); if (intersectrect(INT_MSB(oldball_x), INT_MSB(oldball_y), BALL_RADIUS*2, BALL_RADIUS*2, RIGHTPADDLE_X, INT_MSB(rightpaddle_y), PADDLE_W, PADDLE_H)) { glcdFillRectangle(RIGHTPADDLE_X, INT_MSB(rightpaddle_y), PADDLE_W, PADDLE_H, !inverted); } if (intersectrect(INT_MSB(oldball_x), INT_MSB(oldball_y), BALL_RADIUS*2, BALL_RADIUS*2, LEFTPADDLE_X, INT_MSB(leftpaddle_y), PADDLE_W, PADDLE_H)) { glcdFillRectangle(LEFTPADDLE_X, INT_MSB(leftpaddle_y), PADDLE_W, PADDLE_H, !inverted); } // draw time uint8_t redraw_digits; TIMSK2 = 0; //Disable Timer 2 interrupt, to prevent a race condition. if(redraw_time_rat) { redraw_digits = 1; redraw_time_rat = 0; } TIMSK2 = _BV(TOIE2); //Race issue gone, renable. draw_score_rat(redraw_digits,inverted); redraw_digits = 0; }
void check_ball_digit_collision(uint8_t redraw_digits, uint8_t digit_x, uint8_t digit, uint8_t inverted) { if (redraw_digits || intersectrect(INT_MSB(oldball_x), INT_MSB(oldball_y), BALL_RADIUS*2, BALL_RADIUS*2, digit_x, DISPLAY_TIME_Y_RAT, DISPLAY_DIGITW, DISPLAY_DIGITH)) { #ifdef OPTION_DOW_DATELONG if(digit > 10) drawbigfont(digit_x, DISPLAY_TIME_Y_RAT, digit, inverted); else #endif drawbigdigit(digit_x, DISPLAY_TIME_Y_RAT, digit, inverted); } }
void step_rat(void) { // The keepout is used to know where to -not- put the paddle // the 'bouncepos' is where we expect the ball's y-coord to be when // it intersects with the paddle area static uint8_t right_keepout_top, right_keepout_bot; static uint8_t left_keepout_top, left_keepout_bot; static uint16_t dest_paddle_pos; static uint16_t right_dest, left_dest; // Save old ball location so we can do some vector stuff oldball_x = ball_x; oldball_y = ball_y; // move ball according to the vector ball_x += ball_dx; ball_y += ball_dy; /************************************* TOP & BOTTOM WALLS */ // bouncing off bottom wall, reverse direction // if (ball_y > (SCREEN_H_FIXED - BALL_RADIUS*2*FIXED_MATH - BOTBAR_H_FIXED)) { if (ball_y > (SCREEN_H - BOTBAR_H - BALL_RADIUS*2)*FIXED_MATH) { //DEBUG(putstring_nl("bottom wall bounce")); ball_y = (SCREEN_H - BOTBAR_H - BALL_RADIUS*2)*FIXED_MATH; ball_dy = -ball_dy; } // bouncing off top wall, reverse direction if (ball_y < TOPBAR_H_FIXED) { //DEBUG(putstring_nl("top wall bounce")); ball_y = TOPBAR_H_FIXED; ball_dy = -ball_dy; } /************************************* LEFT & RIGHT WALLS */ // the ball hits either wall, the ball resets location & angle if ( ((INT_MSB(ball_x)) > (SCREEN_W - BALL_RADIUS*2)) || ((int8_t)(INT_MSB(ball_x)) <= 0) || ((ball_dx ==0) && (ball_dy==0)) ) { if(DEBUGGING) { if ((int8_t)(INT_MSB(ball_x)) <= 0) { putstring("Left wall collide"); if (! minute_changed) { putstring_nl("...on accident"); } else { putstring_nl("...on purpose"); } } else { putstring("Right wall collide"); if (! hour_changed) { putstring_nl("...on accident"); } else { putstring_nl("...on purpose"); } } } // place ball in the middle of the screen ball_x = (SCREEN_W/2 - BALL_RADIUS)*FIXED_MATH; ball_y = (SCREEN_H/2 - BALL_RADIUS)*FIXED_MATH; // TODO JMM: don't use cosine/sine... pick one randomly and calc the other one. int8_t angle = random_angle(); ball_dx = (int16_t) (((int32_t) MAX_BALL_SPEED * cosine(angle)) / 0x7FFF); ball_dy = (int16_t) (((int32_t) MAX_BALL_SPEED * sine(angle)) / 0x7FFF); glcdFillRectangle(LEFTPADDLE_X, left_keepout_top, PADDLE_W, left_keepout_bot - left_keepout_top, 0); glcdFillRectangle(RIGHTPADDLE_X, right_keepout_top, PADDLE_W, right_keepout_bot - right_keepout_top, 0); right_keepout_top = right_keepout_bot = 0; left_keepout_top = left_keepout_bot = 0; redraw_time_rat = 1; minute_changed = hour_changed = 0; ticksremaining = calculate_dest_pos(&left_dest, &right_dest, &dest_paddle_pos, ball_dx > 0); //left_score = time_h; //right_score = time_m; setscore_rat(); } // save old paddle position oldleftpaddle_y = leftpaddle_y; oldrightpaddle_y = rightpaddle_y; /* if(ball_dx > 0) { // For debugging, print the ball location DEBUG(putstring("ball @ (")); DEBUG(uart_putw_dec(ball_x)); DEBUG(putstring(", ")); DEBUG(uart_putw_dec(ball_y)); DEBUG(putstring(")")); DEBUG(putstring(" ball_dx @ (")); DEBUG(uart_putw_dec(ball_dx)); DEBUG(putstring(")")); DEBUG(putstring(" ball_dy @ (")); DEBUG(uart_putw_dec(ball_dy)); DEBUG(putstring(")")); DEBUG(putstring(" ball_dy @ (")); DEBUG(uart_putw_dec(ball_dy)); DEBUG(putstring(")")); }*/ /*if(!minute_changed) { if((ball_dx < 0) && (ball_x < (SCREEN_W/2)*FIXED_MATH)) { move_paddle(&leftpaddle_y, ball_y); } } else { //Minute changed. We now have to miss the ball on purpose, if at all possible. //If we don't succeed this time around, we will try again next time around. if((ball_dx < 0) && (ball_x < (SCREEN_W/2)*FIXED_MATH) ) { move_paddle(&leftpaddle_y, dest_paddle_pos); } }*/ //ticksremaining--; if((ball_dx < 0) && (ball_x < (SCREEN_W/2)*FIXED_MATH) ) { move_paddle(&leftpaddle_y, minute_changed?dest_paddle_pos:(ball_y-(PADDLE_H_FIXED/3))); } else if((ball_dx > 0) && (ball_x > (SCREEN_W/2)*FIXED_MATH) ) { move_paddle(&rightpaddle_y, hour_changed?dest_paddle_pos:(ball_y-(PADDLE_H_FIXED/3))); } else { if(ball_dx < 0) ticksremaining = calculate_dest_pos(&left_dest, &right_dest, &dest_paddle_pos, 1); else ticksremaining = calculate_dest_pos(&left_dest, &right_dest, &dest_paddle_pos, 0); } // make sure the paddles dont hit the top or bottom if (leftpaddle_y < TOPBAR_H_FIXED +1) leftpaddle_y = TOPBAR_H_FIXED + 1; if (rightpaddle_y < TOPBAR_H_FIXED + 1) rightpaddle_y = TOPBAR_H_FIXED + 1; if (leftpaddle_y > ((SCREEN_H - PADDLE_H - BOTBAR_H)*FIXED_MATH - 1)) leftpaddle_y = ((SCREEN_H - PADDLE_H - BOTBAR_H)*FIXED_MATH - 1); if (rightpaddle_y> ((SCREEN_H - PADDLE_H - BOTBAR_H)*FIXED_MATH - 1)) rightpaddle_y = ((SCREEN_H - PADDLE_H - BOTBAR_H)*FIXED_MATH - 1); if ((ball_dx > 0) && intersectrect(INT_MSB(ball_x), INT_MSB(ball_y), BALL_RADIUS*2, BALL_RADIUS*2, RIGHTPADDLE_X, INT_MSB(rightpaddle_y), PADDLE_W, PADDLE_H)) { ball_dx = -ball_dx; ball_x = RIGHTPADDLE_X_FIXED - (BALL_RADIUS*2*FIXED_MATH); //ball_y = right_dest; //ticksremaining = calculate_dest_pos(&left_dest, &right_dest, &dest_paddle_pos, 1); } if ((ball_dx < 0) && intersectrect(INT_MSB(ball_x), INT_MSB(ball_y), BALL_RADIUS*2, BALL_RADIUS*2, LEFTPADDLE_X, INT_MSB(leftpaddle_y), PADDLE_W, PADDLE_H)) { ball_dx = -ball_dx; ball_x = LEFTPADDLE_X_FIXED + PADDLE_W_FIXED; //ball_y = left_dest; //ticksremaining = calculate_dest_pos(&left_dest, &right_dest, &dest_paddle_pos, 0); } }
int compositelocalimage() { #ifdef MPI int rank, comsize; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &comsize); // create aabb array to store bboxes for all ranks AABB *abboxes=NULL, *bboxesorg=NULL; RECT *tiles=NULL; int hit=0; int numtiles = viewport.tilex * viewport.tiley; int x, y, w, h; bboxesorg = (AABB *) malloc(sizeof(AABB) * comsize); tiles = (RECT *) malloc(sizeof(RECT) * numtiles); abboxes = (AABB *) malloc(sizeof(AABB) * comsize); assert (bboxesorg != NULL && tiles != NULL && abboxes != NULL); // allgather parameters float *sbboxes=NULL; float *rbboxes=NULL; sbboxes = (float *) malloc(sizeof(float) * MAXPLANE); rbboxes = (float *) malloc(sizeof(float) * comsize * MAXPLANE); assert (sbboxes != NULL && rbboxes != NULL); sbboxes[0] = aabb.wincoord.x; sbboxes[1] = aabb.wincoord.y; sbboxes[2] = aabb.wincoord.z; sbboxes[3] = aabb.wincoord.w ; sbboxes[4] = aabb.wincoord.h ; sbboxes[5] = aabb.wincoord.d ; // Should we avoid doing this and just compute all teh bboxes for all ranks on each rank MPI_Allgather(sbboxes, MAXPLANE, MPI_FLOAT, rbboxes, MAXPLANE, MPI_FLOAT, MPI_COMM_WORLD); // could avoid this copy by splitting bboxes into two structures - rbboxes and bboxes for (int i=0, j=0; i<comsize; i++) { abboxes[i].wincoord.x = rbboxes[j++]; abboxes[i].wincoord.y = rbboxes[j++]; abboxes[i].wincoord.z = rbboxes[j++]; abboxes[i].wincoord.w = rbboxes[j++]; abboxes[i].wincoord.h = rbboxes[j++]; abboxes[i].wincoord.d = rbboxes[j++]; abboxes[i].wincoord.cx = abboxes[i].wincoord.x + abboxes[i].wincoord.w/2.0f; abboxes[i].wincoord.cy = abboxes[i].wincoord.y + abboxes[i].wincoord.h/2.0f; abboxes[i].rank = i; } memcpy(bboxesorg, abboxes, sizeof(aabb) * comsize); // sort by depth from near to far sortboxlist(0, comsize-1, abboxes); // compute overlap for each tile and subtile int (*rankspertile)[numtiles] = malloc(comsize * sizeof(*rankspertile)); assert(*rankspertile != NULL); //memset((void **) rankspertile, -1, sizeof(int) * comsize * numtiles); for (int m=0; m<comsize; m++) { for (int n=0; n<numtiles; n++) { rankspertile[m][n] = -1; } } // create tile parameters based on number of tiles and size of display createtiles(tiles, viewport); for (int j=0; j<numtiles; j++) { for (int i=0; i<comsize; i++) { // if the bbox overlaps the tile you compute the overlap region, // and place the rank # in the tiles[i] list array hit=intersectrect(abboxes[i].wincoord, tiles[j]); if (hit) { rankspertile[i][j] = abboxes[i].rank; PRINTDEBUG("%3d: TILE: %d -BOXRANK: %d - BBOXDEPTH: %f\n", rank, j, abboxes[i].rank, abboxes[i].wincoord.d); } } } #if 0 // there are h rows each representing a block // each row is the w of the tile times 4 floats (RGBA) // the next block is WINDOWWIDTH*4 (RGBA) floats from the current block position int w = (int) (tiles[rank].w/* + 0.5f*/); int h = (int) (tiles[rank].h/* + 0.5f*/); int x = (int) (tiles[rank].x/* + 0.5f*/); int y = (int) (tiles[rank].y/* + 0.5f*/); // init initbuffer initbuffer = (float *) malloc(sizeof(float) * w * h * ELEMENTSPERPIXEL); assert(initbuffer != NULL); for (int i=0,j=0; i<w*h; i++) { initbuffer[j] = 0.0f; initbuffer[j+1] = 0.0f; initbuffer[j+2] = 0.0f; initbuffer[j+3] = 1.0f; j += 4; } #endif int *r = (int *) malloc(sizeof(int) * comsize); int *s = (int *) malloc(sizeof(int) * comsize); assert (r != NULL && s != NULL); int rcv; int snd; MPI_Request rrequests[comsize]; MPI_Request srequests[comsize]; #ifdef IVR_DEBUG MPI_Status statuses[comsize]; #endif rcv = 0; snd = 0; for (int j=0; j<numtiles; j++) { w = (int) (tiles[j].w/* + 0.5f*/); h = (int) (tiles[j].h/* + 0.5f*/); x = (int) (tiles[j].x/* + 0.5f*/); y = (int) (tiles[j].y/* + 0.5f*/); fprintf(stderr,"tile=%d w,h=%d,%d\n", j,w,h); if (j == rank) owneroftile = j; for (int i=0; i<comsize; i++) { if (rankspertile[i][j] != -1) { if (owneroftile == j) { r[rcv] = rankspertile[i][j]; rcv++; } if (rankspertile[i][j] == rank) { s[snd] = j; snd++; } } } } int ns = 0; int nr = 0; float *rcolorbuf = NULL; if (rcv > 0) { rcolorbuf = (float *) malloc(sizeof(float) * w * h * rcv * ELEMENTSPERPIXEL); assert(rcolorbuf != NULL); #ifdef IVR_DEBUG for (int i=0; i<rcv; i++) { PRINTDEBUG("%3d: rcv=%d, i=%d, fromrnk %d\n", rank, rcv, i, r[i]); } #endif if (owneroftile == rank) { for (int i = 0; i < rcv; ++i) { float *rbuf = (rcolorbuf + w*h*ELEMENTSPERPIXEL*i); MPI_Irecv(rbuf, w*h*4, MPI_FLOAT, r[i], 0, MPI_COMM_WORLD, &rrequests[nr++]); } } } float *scolorbuf = NULL; if (snd > 0) { #ifdef IVR_DEBUG for (int i=0; i<snd; i++) { PRINTDEBUG("%3d: snd=%d, i=%d, torank %d\n", rank, snd, i, s[i]); } #endif scolorbuf = (float*) malloc(sizeof(float) * w *h * ELEMENTSPERPIXEL * snd); assert(scolorbuf != NULL); for (int i=0; i<snd; i++) { x = (int) (tiles[s[i]].x/* + 0.5f*/); y = (int) (tiles[s[i]].y/* + 0.5f*/); w = (int) (tiles[s[i]].w/* + 0.5f*/); h = (int) (tiles[s[i]].h/* + 0.5f*/); start = y*viewport.w + x; //PRINTDEBUG("%3d: START-XY =%d, %d, %f, %f\n", s[i], x, y); float *sbuf = (scolorbuf + w*h*ELEMENTSPERPIXEL*i); float *scolors = (float *) &(colorbuf[start]); stridememcpy(sbuf, scolors, h, w*ELEMENTSPERPIXEL, viewport.w*ELEMENTSPERPIXEL, sizeof(float)); MPI_Isend(sbuf, w*h*ELEMENTSPERPIXEL, MPI_FLOAT, s[i], 0, MPI_COMM_WORLD, &srequests[ns++]); } free(scolorbuf); } MPI_Waitall(nr, rrequests, MPI_STATUSES_IGNORE); MPI_Waitall(ns, srequests, MPI_STATUSES_IGNORE); // free(scolorbuf); //All data is in rcolorbuf on rank==r[0] if (owneroftile == rank) { //rank owns tile and there is something to composite int elements = w*h*ELEMENTSPERPIXEL; tilebuffer = (float *) malloc(elements*sizeof(float)); assert(tilebuffer != NULL); memcpy(tilebuffer, initbuffer, elements*sizeof(float)); if (rcv > 0) { PRINTDEBUGTILES(rcv, rank, elements, rcolorbuf); compositetiles(tilebuffer, rcolorbuf, rcv, w, h); free(rcolorbuf); } #ifdef IVR_DEBUG2 PRINTDEBUG("%3d: rcv=%d\n", rank, rcv); char fn[32]; sprintf(fn, "tile%d.raw", rank); FILE *fout = fopen(fn,"w+b"); fwrite(tilebuffer, elements,sizeof(float), fout); fclose(fout); #endif // free(rcolorbuf); } free(r); free(s); #if 0 free(initbuffer); #endif free((*rankspertile)); free(tiles); free(abboxes); free(sbboxes); free(rbboxes); free(bboxesorg); #endif return 0; }