void translate_coords(SDL_Surface * canvas,int angle) { int a,b; switch (angle) { case 90: translate_xy(canvas,right_arm_x,right_arm_y,&a,&b,90); right_arm_x=a; right_arm_y=b; translate_xy(canvas,left_arm_x,left_arm_y,&a,&b,90); left_arm_x=a; left_arm_y=b; break; case 180: right_arm_x=canvas->w-1-right_arm_x; right_arm_y=canvas->h-1-right_arm_y; left_arm_x=canvas->w-1-left_arm_x; left_arm_y=canvas->h-1-left_arm_y; break; case 270: translate_xy(canvas,right_arm_x,right_arm_y,&a,&b,270); right_arm_x=a; right_arm_y=b; translate_xy(canvas,left_arm_x, left_arm_y, &a, &b, 270); left_arm_x=a; left_arm_y=b; break; } }
void fold_release(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect) { int a,b; SDL_Surface * temp, *temp2; x=fold_x; y=fold_y; fold_ox=fold_oy=0; SDL_BlitSurface(snapshot, 0, canvas, 0); switch (corner) { case 1: translate_xy(canvas,x,y,&a,&b,90); translate_coords(canvas,90); temp=rotate(api, canvas, 90); fold_draw (api, which, temp, snapshot, a, b,update_rect); temp2=rotate(api,temp,270); SDL_BlitSurface(temp2,0,canvas,0); SDL_FreeSurface(temp); SDL_FreeSurface(temp2); break; case 2: fold_draw (api, which, canvas, snapshot, x,y,update_rect); break; case 3: translate_xy(canvas,x,y,&a,&b,270); translate_coords(canvas,270); temp=rotate(api, canvas, 270); fold_draw (api, which, temp, snapshot, a, b,update_rect); temp2=rotate(api,temp,90); SDL_BlitSurface(temp2,0,canvas,0); SDL_FreeSurface(temp); SDL_FreeSurface(temp2); break; case 4: translate_xy(canvas,x,y,&a,&b,180); translate_coords(canvas,180); temp=rotate(api, canvas, 180); fold_draw (api, which, temp, snapshot, a, b,update_rect); temp2=rotate(api,temp,180); SDL_BlitSurface(temp2,0,canvas,0); SDL_FreeSurface (temp); SDL_FreeSurface (temp2); break; } update_rect->x=update_rect->y=0; update_rect->w=canvas->w; update_rect->h=canvas->h; api->playsound(fold_snd, (x * 255) / canvas->w, 255); }
SDL_Surface * rotate(magic_api * api, SDL_Surface * canvas, int angle) { SDL_Surface * temp; int x,y; int a,b; if (angle==180) temp=SDL_CreateRGBSurface(SDL_ANYFORMAT, canvas->w, canvas->h, canvas->format->BitsPerPixel, canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask); else temp=SDL_CreateRGBSurface(SDL_ANYFORMAT, canvas->h, canvas->w, canvas->format->BitsPerPixel, canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask); switch (angle) { case 90: for (x=0; x<canvas->w; x++) for (y=0; y<canvas->h; y++) { translate_xy(canvas,x,y,&a,&b,90); api->putpixel(temp,a,b,api->getpixel(canvas, x, y)); } break; case 180: // printf("%i, %i\n",temp,canvas); for (x=0; x<canvas->w; x++) for (y=0; y<canvas->h; y++) { translate_xy(canvas,x,y,&a,&b,180); api->putpixel(temp,a,b,api->getpixel(canvas, x, y)); } break; case 270: for (x=0; x<canvas->w; x++) for (y=0; y<canvas->h; y++) { translate_xy(canvas,x,y,&a,&b,270); api->putpixel(temp,a,b,api->getpixel(canvas, x, y)); } break; } return temp; }
/* Don't bother to translate the cbox. */ int gx_path_translate(gx_path *ppath, fixed dx, fixed dy) { segment *pseg; #define translate_xy(pt)\ pt.x += dx, pt.y += dy translate_xy(ppath->bbox.p); translate_xy(ppath->bbox.q); translate_xy(ppath->position); pseg = (segment *)(ppath->first_subpath); while ( pseg ) { switch ( pseg->type ) { case s_curve: { curve_segment *pc = (curve_segment *)pseg; translate_xy(pc->p1); translate_xy(pc->p2); } default: translate_xy(pseg->pt); } pseg = pseg->next; } return 0; }
/** * @brief Updates the y position of the entity if it wants to move * (smooth version). */ void StraightMovement::update_smooth_y() { if (y_move != 0) { // The entity wants to move on y. // By default, next_move_date_y will be incremented by y_delay, // unless we modify the movement in such a way that the // y speed needs to be fixed. uint32_t next_move_date_y_increment = y_delay; if (!test_collision_with_obstacles(0, y_move)) { translate_y(y_move); // Make the move. if (x_move != 0 && test_collision_with_obstacles(x_move, 0)) { // If there is also an x move, and if this x move is illegal, // we still allow the y move and we give it all the speed. next_move_date_y_increment = (int) (1000.0 / get_speed()); } } else { if (x_move == 0) { // The move on y is not possible and there is no x move: // let's try to add a move on x to make a diagonal move, // but only if the wall is really diagonal: otherwise, the hero // could bypass sensors. if (!test_collision_with_obstacles(1, y_move) // Can move diagonally and: && (test_collision_with_obstacles(-1, 0) || // the wall is really diagonal test_collision_with_obstacles(1, 0)) // or we don't have a choice anyway. ) { translate_xy(1, y_move); next_move_date_y_increment = (int) (y_delay * Geometry::SQRT_2); // Fix the speed. } else if (!test_collision_with_obstacles(-1, y_move) && (test_collision_with_obstacles(1, 0) || test_collision_with_obstacles(-1, 0)) ) { translate_xy(-1, y_move); next_move_date_y_increment = (int) (y_delay * Geometry::SQRT_2); } else { // The diagonal moves didn't work either. // So we look for a place (up to 8 pixels on the left and on the right) // where the required move would be allowed. // If we find a such place, then we move towards this place. bool moved = false; for (int i = 1; i <= 8 && !moved; i++) { if (!test_collision_with_obstacles(i, y_move) && !test_collision_with_obstacles(1, 0)) { translate_x(1); moved = true; } else if (!test_collision_with_obstacles(-i, y_move) && !test_collision_with_obstacles(-1, 0)) { translate_x(-1); moved = true; } } } } else { // The move on y is not possible, but there is also a horizontal move. if (!test_collision_with_obstacles(x_move, y_move)) { // This case is only necessary in narrow diagonal passages. translate_xy(x_move, y_move); next_move_date_x += x_delay; // Delay the next update_smooth_x() since we just replaced it. } else if (!test_collision_with_obstacles(x_move, 0)) { // Do the horizontal move right now, don't wait uselessly. update_x(); } } } next_move_date_y += next_move_date_y_increment; } }
/** * \brief Moves the object. * \param dxy number of pixel of the move on x and y */ void Movement::translate_xy(const Point& dxy) { translate_xy(dxy.x, dxy.y); }
/** * \brief Moves the object on y. * \param dy number of pixels of the move */ void Movement::translate_y(int dy) { translate_xy(0, dy); }
/** * \brief Moves the object on x. * \param dx number of pixels of the move */ void Movement::translate_x(int dx) { translate_xy(dx, 0); }
/** * @brief Moves the object. * @param dxy number of pixel of the move on x and y * (the size of the rectangle is ignored) */ void Movement::translate_xy(const Rectangle &dxy) { translate_xy(dxy.get_x(), dxy.get_y()); }
/** * \brief Updates the x position of the entity if it wants to move * (smooth version). */ void StraightMovement::update_smooth_x() { if (x_move != 0) { // The entity wants to move on x. // By default, next_move_date_x will be incremented by x_delay, // unless we modify below the movement in such a way that the // x speed needs to be fixed. uint32_t next_move_date_x_increment = x_delay; if (!test_collision_with_obstacles(x_move, 0)) { translate_x(x_move); // Make the move. if (y_move != 0 && test_collision_with_obstacles(0, y_move)) { // If there is also a y move, and if this y move is illegal, // we still allow the x move and we give it all the speed. next_move_date_x_increment = (int) (1000.0 / get_speed()); } } else { if (y_move == 0) { // The move on x is not possible and there is no y move: // let's try to add a move on y to make a diagonal move, // but only if the wall is really diagonal: otherwise, the hero // could bypass sensors. if (!test_collision_with_obstacles(x_move, 1) // Can move diagonally and: && (test_collision_with_obstacles(0, -1) || // the wall is really diagonal test_collision_with_obstacles(0, 1)) // or we don't have a choice anyway. ) { translate_xy(x_move, 1); next_move_date_x_increment = (int) (x_delay * Geometry::SQRT_2); // Fix the speed. } else if (!test_collision_with_obstacles(x_move, -1) && (test_collision_with_obstacles(0, 1) || test_collision_with_obstacles(0, -1)) ) { translate_xy(x_move, -1); next_move_date_x_increment = (int) (x_delay * Geometry::SQRT_2); } else { // The diagonal moves didn't work either. // So we look for a place (up to 8 pixels up and down) // where the required move would be allowed. // If we find a such place, then we move towards this place. bool moved = false; for (int i = 1; i <= 8 && !moved; i++) { if (!test_collision_with_obstacles(x_move, i) && !test_collision_with_obstacles(0, 1)) { translate_y(1); moved = true; } else if (!test_collision_with_obstacles(x_move, -i) && !test_collision_with_obstacles(0, -1)) { translate_y(-1); moved = true; } } } } else { // The move on x is not possible, but there is also a vertical move. if (!test_collision_with_obstacles(0, y_move)) { // Do the vertical move right now, don't wait uselessly. update_y(); } else { // The x move is not possible and neither is the y move. // Last chance: do both x and y moves in one step. // This case is only necessary in narrow diagonal passages. // We do it as a last resort, because we want separate x and y // steps whenever possible: otherwise, the hero could bypass sensors. if (!test_collision_with_obstacles(x_move, y_move)) { translate_xy(x_move, y_move); next_move_date_y += y_delay; // Delay the next update_smooth_y() since we just replaced it. } } } } next_move_date_x += next_move_date_x_increment; } }
/** * @brief Updates the y position of the entity if it wants to move * (smooth version). */ void StraightMovement::update_smooth_y() { if (y_move != 0) { // the entity wants to move on y // by default, next_move_date_y will be incremented by y_delay, // unless we modify the movement in such a way that the // y speed needs to be fixed uint32_t next_move_date_y_increment = y_delay; if (!test_collision_with_obstacles(0, y_move)) { translate_y(y_move); // make the move if (x_move != 0 && test_collision_with_obstacles(x_move, 0)) { // if there is also an x move, and if this x move is illegal, // we still allow the y move and we give it all the speed next_move_date_y_increment = (int) (1000.0 / get_speed()); } } else { if (x_move == 0) { // The move on y is not possible: let's try // to add a move on x to make a diagonal move. if (!test_collision_with_obstacles(1, y_move) && test_collision_with_obstacles(-1, 0)) { translate_xy(1, y_move); next_move_date_y_increment = (int) (y_delay * Geometry::SQRT_2); // fix the speed } else if (!test_collision_with_obstacles(-1, y_move) && test_collision_with_obstacles(1, 0)) { translate_xy(-1, y_move); next_move_date_y_increment = (int) (y_delay * Geometry::SQRT_2); } else { /* The diagonal moves didn't work either. * So we look for a place (up to 8 pixels on the left and on the right) * where the required move would be allowed. * If we find a such place, then we move towards this place. */ bool moved = false; for (int i = 1; i <= 8 && !moved; i++) { if (!test_collision_with_obstacles(i, y_move) && !test_collision_with_obstacles(1, 0)) { translate_x(1); moved = true; } else if (!test_collision_with_obstacles(-i, y_move) && !test_collision_with_obstacles(-1, 0)) { translate_x(-1); moved = true; } } } } else { // no attractive place was found, but there is a horizontal move if (!test_collision_with_obstacles(x_move, 0)) { // do the horizontal move right now, don't wait uselessly update_x(); } } } next_move_date_y += next_move_date_y_increment; } }