From f772f882546ab982dc61074f298d6115c9909f32 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Mon, 13 Mar 2006 02:07:59 +0100 Subject: [PATCH] rnd-20060313-1-src * fixed some bugs in player focus switching in EMC and RND game engine --- ChangeLog | 3 + src/conftime.h | 2 +- src/engines.h | 4 +- src/events.c | 12 ++- src/game.c | 235 ++++++++++++++++++++++++++++++++++++++++- src/game_em/convert.c | 2 +- src/game_em/graphics.c | 56 ++++++++-- src/main.h | 1 + src/tools.c | 14 ++- 9 files changed, 310 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0844cc32..51d4a414 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2006-03-13 + * fixed some bugs in player focus switching in EMC and RND game engine + 2006-03-11 * added special Supaplex animations for Murphy digging and snapping * added special Supaplex animations for Murphy being bored and sleeping diff --git a/src/conftime.h b/src/conftime.h index d3dfeac7..f69b18c9 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "[2006-03-11 15:37]" +#define COMPILE_DATE_STRING "[2006-03-13 02:03]" diff --git a/src/engines.h b/src/engines.h index 243eb8ba..55352e0f 100644 --- a/src/engines.h +++ b/src/engines.h @@ -27,7 +27,9 @@ extern void DrawAllGameValues(int, int, int, int, int); extern void setCenteredPlayerNr_EM(int); extern int getCenteredPlayerNr_EM(); -extern int getActivePlayers_EM(); +extern void setSetCenteredPlayer_EM(boolean); +extern boolean getSetCenteredPlayer_EM(); +extern int getNumActivePlayers_EM(); extern int getGameFrameDelay_EM(int); extern void PlayLevelSound_EM(int, int, int, int); diff --git a/src/events.c b/src/events.c index 4d7a7a36..e8f20556 100644 --- a/src/events.c +++ b/src/events.c @@ -700,12 +700,20 @@ void HandleKey(Key key, int key_status) if (game_status == GAME_MODE_PLAYING) { + int centered_player_nr_next = -999; + if (key == setup.shortcut.focus_player_all) - game.centered_player_nr_next = -1; + centered_player_nr_next = -1; else for (i = 0; i < MAX_PLAYERS; i++) if (key == setup.shortcut.focus_player[i]) - game.centered_player_nr_next = i; + centered_player_nr_next = i; + + if (centered_player_nr_next != -999) + { + game.centered_player_nr_next = centered_player_nr_next; + game.set_centered_player = TRUE; + } } HandleKeysSpecial(key); diff --git a/src/game.c b/src/game.c index ed697892..18432748 100644 --- a/src/game.c +++ b/src/game.c @@ -1958,6 +1958,7 @@ void InitGame() game.envelope_active = FALSE; game.centered_player_nr = game.centered_player_nr_next = -1; /* focus all */ + game.set_centered_player = FALSE; for (i = 0; i < NUM_BELTS; i++) { @@ -3145,6 +3146,183 @@ void CheckDynamite(int x, int y) Bang(x, y); } +#if 1 + +static void setMinimalPlayerBoundaries(int *sx1, int *sy1, int *sx2, int *sy2) +{ + boolean num_checked_players = 0; + int i; + + for (i = 0; i < MAX_PLAYERS; i++) + { + if (stored_player[i].active) + { + int sx = stored_player[i].jx; + int sy = stored_player[i].jy; + + if (num_checked_players == 0) + { + *sx1 = *sx2 = sx; + *sy1 = *sy2 = sy; + } + else + { + *sx1 = MIN(*sx1, sx); + *sy1 = MIN(*sy1, sy); + *sx2 = MAX(*sx2, sx); + *sy2 = MAX(*sy2, sy); + } + + num_checked_players++; + } + } +} + +static boolean checkIfAllPlayersFitToScreen_RND() +{ + int sx1 = 0, sy1 = 0, sx2 = 0, sy2 = 0; + + setMinimalPlayerBoundaries(&sx1, &sy1, &sx2, &sy2); + + return (sx2 - sx1 < SCR_FIELDX && + sy2 - sy1 < SCR_FIELDY); +} + +static void setScreenCenteredToAllPlayers(int *sx, int *sy) +{ + int sx1 = scroll_x, sy1 = scroll_y, sx2 = scroll_x, sy2 = scroll_y; + + setMinimalPlayerBoundaries(&sx1, &sy1, &sx2, &sy2); + + *sx = (sx1 + sx2) / 2; + *sy = (sy1 + sy2) / 2; +} + +#if 0 +static void setMaxCenterDistanceForAllPlayers(int *max_dx, int *max_dy, + int center_x, int center_y) +{ + int sx1 = center_x, sy1 = center_y, sx2 = center_x, sy2 = center_y; + + setMinimalPlayerBoundaries(&sx1, &sy1, &sx2, &sy2); + + *max_dx = MAX(ABS(sx1 - center_x), ABS(sx2 - center_x)); + *max_dy = MAX(ABS(sy1 - center_y), ABS(sy2 - center_y)); +} + +static boolean checkIfAllPlayersAreVisible(int center_x, int center_y) +{ + int max_dx, max_dy; + + setMaxCenterDistanceForAllPlayers(&max_dx, &max_dy, center_x, center_y); + + return (max_dx <= SCR_FIELDX / 2 && + max_dy <= SCR_FIELDY / 2); +} +#endif + +#endif + +#if 1 + +void DrawRelocateScreen(int x, int y, int move_dir, boolean center_screen, + boolean quick_relocation) +{ + boolean ffwd_delay = (tape.playing && tape.fast_forward); + boolean no_delay = (tape.warp_forward); + int frame_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay); + int wait_delay_value = (no_delay ? 0 : frame_delay_value); + + if (quick_relocation) + { + int offset = (setup.scroll_delay ? 3 : 0); + +#if 0 + if (center_screen) + offset = 0; +#endif + + if (!IN_VIS_FIELD(SCREENX(x), SCREENY(y)) || center_screen) + { + scroll_x = (x < SBX_Left + MIDPOSX ? SBX_Left : + x > SBX_Right + MIDPOSX ? SBX_Right : + x - MIDPOSX); + + scroll_y = (y < SBY_Upper + MIDPOSY ? SBY_Upper : + y > SBY_Lower + MIDPOSY ? SBY_Lower : + y - MIDPOSY); + } + else + { + if ((move_dir == MV_LEFT && scroll_x > x - MIDPOSX + offset) || + (move_dir == MV_RIGHT && scroll_x < x - MIDPOSX - offset)) + scroll_x = x - MIDPOSX + (scroll_x < x - MIDPOSX ? -offset : +offset); + + if ((move_dir == MV_UP && scroll_y > y - MIDPOSY + offset) || + (move_dir == MV_DOWN && scroll_y < y - MIDPOSY - offset)) + scroll_y = y - MIDPOSY + (scroll_y < y - MIDPOSY ? -offset : +offset); + + /* don't scroll over playfield boundaries */ + if (scroll_x < SBX_Left || scroll_x > SBX_Right) + scroll_x = (scroll_x < SBX_Left ? SBX_Left : SBX_Right); + + /* don't scroll over playfield boundaries */ + if (scroll_y < SBY_Upper || scroll_y > SBY_Lower) + scroll_y = (scroll_y < SBY_Upper ? SBY_Upper : SBY_Lower); + } + + RedrawPlayfield(TRUE, 0,0,0,0); + } + else + { + int scroll_xx = (x < SBX_Left + MIDPOSX ? SBX_Left : + x > SBX_Right + MIDPOSX ? SBX_Right : + x - MIDPOSX); + + int scroll_yy = (y < SBY_Upper + MIDPOSY ? SBY_Upper : + y > SBY_Lower + MIDPOSY ? SBY_Lower : + y - MIDPOSY); + + ScrollScreen(NULL, SCROLL_GO_ON); /* scroll last frame to full tile */ + + while (scroll_x != scroll_xx || scroll_y != scroll_yy) + { + int dx = 0, dy = 0; + int fx = FX, fy = FY; + + dx = (scroll_xx < scroll_x ? +1 : scroll_xx > scroll_x ? -1 : 0); + dy = (scroll_yy < scroll_y ? +1 : scroll_yy > scroll_y ? -1 : 0); + + if (dx == 0 && dy == 0) /* no scrolling needed at all */ + break; + + scroll_x -= dx; + scroll_y -= dy; + + fx += dx * TILEX / 2; + fy += dy * TILEY / 2; + + ScrollLevel(dx, dy); + DrawAllPlayers(); + + /* scroll in two steps of half tile size to make things smoother */ + BlitBitmap(drawto_field, window, fx, fy, SXSIZE, SYSIZE, SX, SY); + FlushDisplay(); + Delay(wait_delay_value); + + /* scroll second step to align at full tile size */ + BackToFront(); + Delay(wait_delay_value); + } + + DrawAllPlayers(); + BackToFront(); + Delay(wait_delay_value); + } +} + +#else + void DrawRelocatePlayer(struct PlayerInfo *player, boolean quick_relocation) { boolean ffwd_delay = (tape.playing && tape.fast_forward); @@ -3237,6 +3415,8 @@ void DrawRelocatePlayer(struct PlayerInfo *player, boolean quick_relocation) } } +#endif + void RelocatePlayer(int jx, int jy, int el_player_raw) { int el_player = GET_PLAYER_ELEMENT(el_player_raw); @@ -3314,8 +3494,13 @@ void RelocatePlayer(int jx, int jy, int el_player_raw) #if 1 /* only visually relocate centered player */ +#if 1 + DrawRelocateScreen(player->jx, player->jy, player->MovDir, FALSE, + level.instant_relocation); +#else if (player->index_nr == game.centered_player_nr) DrawRelocatePlayer(player, level.instant_relocation); +#endif #else if (player == local_player) /* only visually relocate local player */ DrawRelocatePlayer(player, level.instant_relocation); @@ -8659,7 +8844,7 @@ static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting) #if 1 if (player->is_sleeping && player->use_murphy) { - /* special for Murphy: leaning against solid objects when sleeping */ + /* special case for sleeping Murphy when leaning against non-free tile */ if (!IN_LEV_FIELD(player->jx - 1, player->jy) || Feld[player->jx - 1][player->jy] != EL_EMPTY) @@ -8902,25 +9087,69 @@ void GameActions() InitPlayfieldScanModeVars(); - if (ScreenMovPos == 0) /* screen currently aligned at tile position */ + if (game.set_centered_player) + { + boolean all_players_fit_to_screen = checkIfAllPlayersFitToScreen_RND(); + + /* switching to "all players" only possible if all players fit to screen */ + if (game.centered_player_nr_next == -1 && !all_players_fit_to_screen) + { + game.centered_player_nr_next = game.centered_player_nr; + game.set_centered_player = FALSE; + } + + /* do not switch focus to non-existing (or non-active) player */ + if (game.centered_player_nr_next >= 0 && + !stored_player[game.centered_player_nr_next].active) + { + game.centered_player_nr_next = game.centered_player_nr; + game.set_centered_player = FALSE; + } + } + + if (game.set_centered_player && + ScreenMovPos == 0) /* screen currently aligned at tile position */ { +#if 0 struct PlayerInfo *player; int player_nr = game.centered_player_nr_next; +#endif + int sx, sy; if (game.centered_player_nr_next == -1) - player_nr = local_player->index_nr; + { + setScreenCenteredToAllPlayers(&sx, &sy); + } + else + { + sx = stored_player[game.centered_player_nr_next].jx; + sy = stored_player[game.centered_player_nr_next].jy; + } +#if 0 player = &stored_player[player_nr]; if (!player->active) game.centered_player_nr_next = game.centered_player_nr; + sx = player->jx; + sy = player->jy; +#endif + +#if 0 if (game.centered_player_nr != game.centered_player_nr_next) +#endif { +#if 1 + DrawRelocateScreen(sx, sy, MV_NONE, TRUE, setup.quick_switch); +#else DrawRelocatePlayer(player, setup.quick_switch); +#endif game.centered_player_nr = game.centered_player_nr_next; } + + game.set_centered_player = FALSE; } #if USE_ONE_MORE_CHANGE_PER_FRAME diff --git a/src/game_em/convert.c b/src/game_em/convert.c index f53bd21d..3aa00be4 100644 --- a/src/game_em/convert.c +++ b/src/game_em/convert.c @@ -975,7 +975,7 @@ void prepare_em_level(void) } } - num_tape_players = getActivePlayers_EM(); + num_tape_players = getNumActivePlayers_EM(); if (num_tape_players != -1) lev.home_initial = MIN(lev.home_initial, num_tape_players); diff --git a/src/game_em/graphics.c b/src/game_em/graphics.c index f623ac7a..331491cf 100644 --- a/src/game_em/graphics.c +++ b/src/game_em/graphics.c @@ -574,7 +574,7 @@ void DrawRelocatePlayer(struct PlayerInfo *player, boolean quick_relocation) } #endif -void setMinimalPlayerBoundaries(int *sx1, int *sy1, int *sx2, int *sy2) +static void setMinimalPlayerBoundaries(int *sx1, int *sy1, int *sx2, int *sy2) { boolean num_checked_players = 0; int i; @@ -614,7 +614,7 @@ boolean checkIfAllPlayersFitToScreen() sy2 - sy1 <= SCR_FIELDY * TILEY); } -void setScreenCenteredToAllPlayers(int *sx, int *sy) +static void setScreenCenteredToAllPlayers(int *sx, int *sy) { int sx1 = screen_x, sy1 = screen_y, sx2 = screen_x, sy2 = screen_y; @@ -624,8 +624,8 @@ void setScreenCenteredToAllPlayers(int *sx, int *sy) *sy = (sy1 + sy2) / 2; } -void setMaxCenterDistanceForAllPlayers(int *max_dx, int *max_dy, - int center_x, int center_y) +static void setMaxCenterDistanceForAllPlayers(int *max_dx, int *max_dy, + int center_x, int center_y) { int sx1 = center_x, sy1 = center_y, sx2 = center_x, sy2 = center_y; @@ -635,7 +635,7 @@ void setMaxCenterDistanceForAllPlayers(int *max_dx, int *max_dy, *max_dy = MAX(ABS(sy1 - center_y), ABS(sy2 - center_y)); } -boolean checkIfAllPlayersAreVisible(int center_x, int center_y) +static boolean checkIfAllPlayersAreVisible(int center_x, int center_y) { int max_dx, max_dy; @@ -650,12 +650,12 @@ void RedrawPlayfield_EM(boolean force_redraw) #if 0 boolean all_players_visible = checkIfAllPlayersAreVisible(); #endif - boolean all_players_fit_to_screen = checkIfAllPlayersFitToScreen(); boolean draw_new_player_location = FALSE; boolean quick_relocation = setup.quick_switch; #if 0 boolean scrolling = (screen_x % TILEX != 0 || screen_y % TILEY != 0); #endif + boolean set_centered_player = getSetCenteredPlayer_EM(); int centered_player_nr_next = getCenteredPlayerNr_EM(); int offset = (setup.scroll_delay ? 3 : 0) * TILEX; int offset_x = offset; @@ -665,12 +665,29 @@ void RedrawPlayfield_EM(boolean force_redraw) int x, y, sx, sy; int i; - /* switching to "all players" only possible if all players fit to screen */ - if (centered_player_nr_next == -1 && !all_players_fit_to_screen) + if (set_centered_player) { - setCenteredPlayerNr_EM(centered_player_nr); + boolean all_players_fit_to_screen = checkIfAllPlayersFitToScreen(); - centered_player_nr_next = centered_player_nr; + /* switching to "all players" only possible if all players fit to screen */ + if (centered_player_nr_next == -1 && !all_players_fit_to_screen) + { + centered_player_nr_next = centered_player_nr; + setCenteredPlayerNr_EM(centered_player_nr); + + set_centered_player = FALSE; + setSetCenteredPlayer_EM(FALSE); + } + + /* do not switch focus to non-existing (or non-active) player */ + if (centered_player_nr_next >= 0 && !ply[centered_player_nr_next].alive) + { + centered_player_nr_next = centered_player_nr; + setCenteredPlayerNr_EM(centered_player_nr); + + set_centered_player = FALSE; + setSetCenteredPlayer_EM(FALSE); + } } #if 1 @@ -679,12 +696,18 @@ void RedrawPlayfield_EM(boolean force_redraw) if (!scrolling) /* screen currently aligned at tile position */ #endif { +#if 1 + if (set_centered_player) +#else if (centered_player_nr != centered_player_nr_next) +#endif { centered_player_nr = centered_player_nr_next; draw_new_player_location = TRUE; force_redraw = TRUE; + + setSetCenteredPlayer_EM(FALSE); } } @@ -706,6 +729,19 @@ void RedrawPlayfield_EM(boolean force_redraw) sy = PLAYER_SCREEN_Y(centered_player_nr); } + if (draw_new_player_location && quick_relocation) + { + screen_x = VALID_SCREEN_X(sx); + screen_y = VALID_SCREEN_Y(sy); + screen_x_old = screen_x; + screen_y_old = screen_y; + +#if 0 + offset_x = 0; + offset_y = 0; +#endif + } + if (draw_new_player_location && !quick_relocation) { #if 1 diff --git a/src/main.h b/src/main.h index 87e68516..bb7d8766 100644 --- a/src/main.h +++ b/src/main.h @@ -2104,6 +2104,7 @@ struct GameInfo /* values for special game control */ int centered_player_nr; int centered_player_nr_next; + boolean set_centered_player; }; struct GlobalInfo diff --git a/src/tools.c b/src/tools.c index 04bb48de..f9b4f639 100644 --- a/src/tools.c +++ b/src/tools.c @@ -5132,9 +5132,11 @@ void setCenteredPlayerNr_EM(int centered_player_nr) int getCenteredPlayerNr_EM() { +#if 0 if (game.centered_player_nr_next >= 0 && !native_em_level.ply[game.centered_player_nr_next]->alive) game.centered_player_nr_next = game.centered_player_nr; +#endif if (game.centered_player_nr != game.centered_player_nr_next) game.centered_player_nr = game.centered_player_nr_next; @@ -5142,7 +5144,17 @@ int getCenteredPlayerNr_EM() return game.centered_player_nr; } -int getActivePlayers_EM() +void setSetCenteredPlayer_EM(boolean set_centered_player) +{ + game.set_centered_player = set_centered_player; +} + +boolean getSetCenteredPlayer_EM() +{ + return game.set_centered_player; +} + +int getNumActivePlayers_EM() { int num_players = 0; int i; -- 2.34.1