X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame_em%2Fgraphics.c;h=7f303a2a6510b78fda2ae33728a6037669e5cf6d;hb=5eec6f3a02cb8a6171a37a209aae3e3665aff514;hp=43c5e4b22cb715e311858766d3d0642c6e90900c;hpb=a335ab0bab1ccd58275b03f0bc3cada75a3dc389;p=rocksndiamonds.git diff --git a/src/game_em/graphics.c b/src/game_em/graphics.c index 43c5e4b2..7f303a2a 100644 --- a/src/game_em/graphics.c +++ b/src/game_em/graphics.c @@ -25,9 +25,9 @@ #define VALID_SCREEN_Y(y) ((y) < MIN_SCREEN_Y ? MIN_SCREEN_Y : \ (y) > MAX_SCREEN_Y ? MAX_SCREEN_Y : (y)) -#define PLAYER_POS_X(nr) (((7 - frame) * ply[nr].oldx + \ +#define PLAYER_POS_X(nr) (((7 - frame) * ply[nr].prev_x + \ (1 + frame) * ply[nr].x) * TILEX / 8) -#define PLAYER_POS_Y(nr) (((7 - frame) * ply[nr].oldy + \ +#define PLAYER_POS_Y(nr) (((7 - frame) * ply[nr].prev_y + \ (1 + frame) * ply[nr].y) * TILEY / 8) #define PLAYER_SCREEN_X(nr) (PLAYER_POS_X(nr) - \ @@ -49,6 +49,8 @@ static int crumbled_state[MAX_PLAYFIELD_WIDTH + 2][MAX_PLAYFIELD_HEIGHT + 2]; struct GraphicInfo_EM graphic_info_em_object[GAME_TILE_MAX][8]; struct GraphicInfo_EM graphic_info_em_player[MAX_PLAYERS][PLY_MAX][8]; +static void setScreenCenteredToAllPlayers(int *, int *); + int getFieldbufferOffsetX_EM(void) { return screen_x % TILEX; @@ -75,8 +77,8 @@ void BlitScreenToBitmap_EM(Bitmap *target_bitmap) int sysize = (full_ysize < ysize ? full_ysize : ysize); int xxsize = MAX_BUF_XSIZE * TILEX - x; int yysize = MAX_BUF_YSIZE * TILEY - y; - int xoffset = 2 * TILEX; - int yoffset = 2 * TILEY; + int xoffset = 2 * CAVE_BUFFER_XOFFSET * TILEX; + int yoffset = 2 * CAVE_BUFFER_YOFFSET * TILEY; if (x < xoffset && y < yoffset) { @@ -368,7 +370,7 @@ static void animscreen(void) * handles transparency and movement */ -static void blitplayer(int nr) +static void blitplayer_ext(int nr) { int x1, y1, x2, y2; @@ -385,10 +387,10 @@ static void blitplayer(int nr) (int)(y2 - screen_y) < ((MAX_BUF_YSIZE - 1) * TILEY - 1)) { /* some casts to "int" are needed because of negative calculation values */ - int dx = (int)ply[nr].x - (int)ply[nr].oldx; - int dy = (int)ply[nr].y - (int)ply[nr].oldy; - int old_x = (int)ply[nr].oldx + (int)frame * dx / 8; - int old_y = (int)ply[nr].oldy + (int)frame * dy / 8; + int dx = (int)ply[nr].x - (int)ply[nr].prev_x; + int dy = (int)ply[nr].y - (int)ply[nr].prev_y; + int old_x = (int)ply[nr].prev_x + (int)frame * dx / 8; + int old_y = (int)ply[nr].prev_y + (int)frame * dy / 8; int new_x = old_x + SIGN(dx); int new_y = old_y + SIGN(dy); int old_sx = old_x % MAX_BUF_XSIZE; @@ -430,17 +432,54 @@ static void blitplayer(int nr) } } +static void blitplayer(int nr) +{ + blitplayer_ext(nr); + + /* check for wrap-around movement ... */ + if (ply[nr].x < lev.left || + ply[nr].x > lev.right - 1) + { + struct PLAYER ply_last = ply[nr]; + int dx = ply[nr].x - ply[nr].prev_x; + + ply[nr].x = (ply[nr].x < lev.left ? lev.right - 1 : lev.left); + ply[nr].prev_x = ply[nr].x - dx; + + if (!lev.infinite_true) + { + int dy = ply[nr].y - ply[nr].prev_y; + + ply[nr].y += (ply[nr].x == lev.left ? 1 : -1); + ply[nr].prev_y = ply[nr].y - dy; + } + + /* draw player entering playfield from the opposite side */ + blitplayer_ext(nr); + + /* ... but keep the old player position until game logic */ + ply[nr] = ply_last; + } +} + void game_initscreen(void) { - int player_nr; - int x,y; + int x, y, sx, sy; frame = 1; - player_nr = (game.centered_player_nr != -1 ? game.centered_player_nr : 0); + if (game.centered_player_nr == -1) + { + setScreenCenteredToAllPlayers(&sx, &sy); + } + else + { + sx = PLAYER_SCREEN_X(game.centered_player_nr); + sy = PLAYER_SCREEN_Y(game.centered_player_nr); + } - screen_x = VALID_SCREEN_X(PLAYER_SCREEN_X(player_nr)); - screen_y = VALID_SCREEN_Y(PLAYER_SCREEN_Y(player_nr)); + screen_x = VALID_SCREEN_X(sx); + screen_y = VALID_SCREEN_Y(sy); for (y = 0; y < MAX_BUF_YSIZE; y++) { @@ -554,7 +593,7 @@ static boolean checkIfAllPlayersAreVisible(int center_x, int center_y) void RedrawPlayfield_EM(boolean force_redraw) { boolean draw_new_player_location = FALSE; - boolean draw_new_player_location_fast = FALSE; + boolean draw_new_player_location_wrap = FALSE; boolean quick_relocation = setup.quick_switch; int max_center_distance_player_nr = getMaxCenterDistancePlayerNr(screen_x, screen_y); @@ -593,11 +632,11 @@ void RedrawPlayfield_EM(boolean force_redraw) game.centered_player_nr = game.centered_player_nr_next; draw_new_player_location = TRUE; - draw_new_player_location_fast = game.set_centered_player_fast; + draw_new_player_location_wrap = game.set_centered_player_wrap; force_redraw = TRUE; game.set_centered_player = FALSE; - game.set_centered_player_fast = FALSE; + game.set_centered_player_wrap = FALSE; } if (game.centered_player_nr == -1) @@ -633,8 +672,17 @@ void RedrawPlayfield_EM(boolean force_redraw) int screen_xx = VALID_SCREEN_X(sx); int screen_yy = VALID_SCREEN_Y(sy); - if (draw_new_player_location_fast) + if (draw_new_player_location_wrap) + { + if (lev.infinite_true) + { + // when wrapping around (horizontally), keep vertical player position + screen_yy = screen_y; + } + + // scrolling for wrapping should be faster than for switching players wait_delay_value /= 4; + } SetVideoFrameDelay(wait_delay_value);