From d0409bd76aa84a8745ec2ea6d8a5480c8bea0bcd Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Wed, 20 Apr 2016 00:16:28 +0200 Subject: [PATCH] moved video frame synchronization to single location (screen update) --- src/cartoons.c | 7 +------ src/events.c | 9 +++------ src/game.c | 21 ++++++++++++++------- src/libgame/sdl.c | 13 +++++++------ src/libgame/system.c | 13 +++++++++++++ src/libgame/system.h | 5 +++++ src/screens.c | 11 +---------- src/tools.c | 18 ++++++++++++------ src/tools.h | 1 + 9 files changed, 57 insertions(+), 41 deletions(-) diff --git a/src/cartoons.c b/src/cartoons.c index 2e74c72b..b1ecf694 100644 --- a/src/cartoons.c +++ b/src/cartoons.c @@ -1127,13 +1127,8 @@ static void DoAnimationExt() printf("::: DoAnimation [%d, %d]\n", anim_sync_frame, Counter()); #endif -#if 1 - WaitUntilDelayReached(&anim_sync_frame_delay, anim_sync_frame_delay_value); + // global animations now synchronized with frame delay of screen update anim_sync_frame++; -#else - if (DelayReached(&anim_sync_frame_delay, anim_sync_frame_delay_value)) - anim_sync_frame++; -#endif for (i = 0; i < NUM_GAME_MODES; i++) HandleGlobalAnim(ANIM_CONTINUE, i); diff --git a/src/events.c b/src/events.c index e371b634..2127242f 100644 --- a/src/events.c +++ b/src/events.c @@ -289,9 +289,6 @@ void HandleMouseCursor() void EventLoop(void) { - unsigned int sync_frame_delay = 0; - unsigned int sync_frame_delay_value = GAME_FRAME_DELAY; - while (1) { if (PendingEvent()) @@ -308,11 +305,11 @@ void EventLoop(void) if (game_status == GAME_MODE_PLAYING) HandleGameActions(); - /* refresh window contents from drawing buffer, if needed */ + /* always copy backbuffer to visible screen for every video frame */ BackToFront(); - if (game_status != GAME_MODE_PLAYING) - WaitUntilDelayReached(&sync_frame_delay, sync_frame_delay_value); + /* reset video frame delay to default (may change again while playing) */ + SetVideoFrameDelay(GAME_FRAME_DELAY); if (game_status == GAME_MODE_QUIT) return; diff --git a/src/game.c b/src/game.c index fb6691a7..d3c403fe 100644 --- a/src/game.c +++ b/src/game.c @@ -4894,6 +4894,7 @@ static void setScreenCenteredToAllPlayers(int *sx, int *sy) void DrawRelocateScreen(int old_x, int old_y, int x, int y, int move_dir, boolean center_screen, boolean quick_relocation) { + unsigned int frame_delay_value_old = GetVideoFrameDelay(); boolean ffwd_delay = (tape.playing && tape.fast_forward); boolean no_delay = (tape.warp_forward); int frame_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay); @@ -4961,6 +4962,8 @@ void DrawRelocateScreen(int old_x, int old_y, int x, int y, int move_dir, ScrollScreen(NULL, SCROLL_GO_ON); /* scroll last frame to full tile */ + SetVideoFrameDelay(wait_delay_value); + while (scroll_x != new_scroll_x || scroll_y != new_scroll_y) { int dx = 0, dy = 0; @@ -4983,16 +4986,15 @@ void DrawRelocateScreen(int old_x, int old_y, int x, int y, int move_dir, /* scroll in two steps of half tile size to make things smoother */ BlitBitmap(drawto_field, window, fx, fy, SXSIZE, SYSIZE, SX, SY); - Delay(wait_delay_value); /* scroll second step to align at full tile size */ - BackToFront(); - Delay(wait_delay_value); + BlitScreenToBitmap(window); } DrawAllPlayers(); BackToFront(); - Delay(wait_delay_value); + + SetVideoFrameDelay(frame_delay_value_old); } void RelocatePlayer(int jx, int jy, int el_player_raw) @@ -5042,8 +5044,7 @@ void RelocatePlayer(int jx, int jy, int el_player_raw) DrawPlayer(player); - BackToFront(); - Delay(wait_delay_value); + BackToFront_WithFrameDelay(wait_delay_value); } DrawPlayer(player); /* needed here only to cleanup last field */ @@ -10958,7 +10959,9 @@ void StartGameActions(boolean init_network_game, boolean record_tape, void GameActions() { +#if 0 static unsigned int game_frame_delay = 0; +#endif unsigned int game_frame_delay_value; byte *recorded_player_action; byte summarized_player_action = 0; @@ -11036,6 +11039,9 @@ void GameActions() if (tape.playing && tape.warp_forward && !tape.pausing) game_frame_delay_value = 0; + SetVideoFrameDelay(game_frame_delay_value); + +#if 0 #if 0 /* ---------- main game synchronization point ---------- */ @@ -11047,6 +11053,7 @@ void GameActions() /* ---------- main game synchronization point ---------- */ WaitUntilDelayReached(&game_frame_delay, game_frame_delay_value); +#endif #endif if (network_playing && !network_player_action_received) @@ -12059,7 +12066,7 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy) AdvanceFrameAndPlayerCounters(player->index_nr); DrawAllPlayers(); - BackToFront(); + BackToFront_WithFrameDelay(0); } player->move_delay_value = original_move_delay_value; diff --git a/src/libgame/sdl.c b/src/libgame/sdl.c index 2507be4c..480677c3 100644 --- a/src/libgame/sdl.c +++ b/src/libgame/sdl.c @@ -145,10 +145,14 @@ static void UpdateScreen(SDL_Rect *rect) SDL_SetRenderTarget(sdl_renderer, NULL); SDL_RenderCopy(sdl_renderer, sdl_texture_target, NULL, NULL); } +#endif - // show render target buffer on screen - SDL_RenderPresent(sdl_renderer); + // global synchronization point of the game to align video frame delay + WaitUntilDelayReached(&video.frame_delay, video.frame_delay_value); +#if defined(TARGET_SDL2) + // show render target buffer on screen + SDL_RenderPresent(sdl_renderer); #else // TARGET_SDL if (rect) SDL_UpdateRects(screen, 1, rect); @@ -1169,10 +1173,7 @@ void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height, while (time_current < time_post_delay) { - // do not wait longer than 10 ms at a time to be able to ... - Delay(MIN(10, time_post_delay - time_current)); - - // ... continue drawing global animations during post delay + // updating the screen contains waiting for frame delay (non-busy) UpdateScreen(NULL); time_current = SDL_GetTicks(); diff --git a/src/libgame/system.c b/src/libgame/system.c index 595daad7..a5ebc4f0 100644 --- a/src/libgame/system.c +++ b/src/libgame/system.c @@ -378,6 +378,9 @@ void InitVideoBuffer(int width, int height, int depth, boolean fullscreen) video.window_scaling_available = WINDOW_SCALING_STATUS; + video.frame_delay = 0; + video.frame_delay_value = GAME_FRAME_DELAY; + SDLInitVideoBuffer(fullscreen); video.initialized = TRUE; @@ -885,6 +888,16 @@ boolean SetVideoMode(boolean fullscreen) return SDLSetVideoMode(fullscreen); } +void SetVideoFrameDelay(unsigned int frame_delay_value) +{ + video.frame_delay_value = frame_delay_value; +} + +unsigned int GetVideoFrameDelay() +{ + return video.frame_delay_value; +} + boolean ChangeVideoModeIfNeeded(boolean fullscreen) { if ((fullscreen && !video.fullscreen_enabled && video.fullscreen_available)|| diff --git a/src/libgame/system.h b/src/libgame/system.h index 110e18c2..1011f1a9 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -768,6 +768,9 @@ struct VideoSystemInfo char *window_scaling_quality; int screen_rendering_mode; + unsigned int frame_delay; + unsigned int frame_delay_value; + boolean initialized; }; @@ -1407,6 +1410,8 @@ Pixel GetPixelFromRGBcompact(Bitmap *, unsigned int); void KeyboardAutoRepeatOn(void); void KeyboardAutoRepeatOff(void); boolean SetVideoMode(boolean); +void SetVideoFrameDelay(unsigned int); +unsigned int GetVideoFrameDelay(); boolean ChangeVideoModeIfNeeded(boolean); Bitmap *LoadImage(char *); diff --git a/src/screens.c b/src/screens.c index 1743be63..94eb8895 100644 --- a/src/screens.c +++ b/src/screens.c @@ -235,9 +235,6 @@ static TreeInfo *drop_distance_current = NULL; static TreeInfo *level_number = NULL; static TreeInfo *level_number_current = NULL; -static unsigned int sync_frame_delay = 0; -static unsigned int sync_frame_delay_value = GAME_FRAME_DELAY; - static struct { int value; @@ -5595,8 +5592,6 @@ static Key getSetupKey() DoAnimation(); BackToFront(); - - WaitUntilDelayReached(&sync_frame_delay, sync_frame_delay_value); } return key; @@ -6311,8 +6306,6 @@ void CustomizeKeyboard(int player_nr) DoAnimation(); BackToFront(); - - WaitUntilDelayReached(&sync_frame_delay, sync_frame_delay_value); } /* write new key bindings back to player setup */ @@ -6466,8 +6459,6 @@ static boolean CalibrateJoystickMain(int player_nr) DoAnimation(); BackToFront(); - - WaitUntilDelayReached(&sync_frame_delay, sync_frame_delay_value); } /* calibrated center position (joystick should now be centered) */ @@ -6489,7 +6480,7 @@ static boolean CalibrateJoystickMain(int player_nr) NextEvent(&event); HandleOtherEvents(&event); - WaitUntilDelayReached(&sync_frame_delay, sync_frame_delay_value); + BackToFront(); } } diff --git a/src/tools.c b/src/tools.c index 9f6526a3..7f870a64 100644 --- a/src/tools.c +++ b/src/tools.c @@ -174,9 +174,6 @@ static int el_act2crm(int, int); static struct GadgetInfo *tool_gadget[NUM_TOOL_BUTTONS]; static int request_gadget_id = -1; -static unsigned int sync_frame_delay = 0; -static unsigned int sync_frame_delay_value = GAME_FRAME_DELAY; - static char *print_if_not_empty(int element) { static char *s = NULL; @@ -590,6 +587,17 @@ void BackToFront() #endif } +void BackToFront_WithFrameDelay(unsigned int frame_delay_value) +{ + unsigned int frame_delay_value_old = GetVideoFrameDelay(); + + SetVideoFrameDelay(frame_delay_value); + + BackToFront(); + + SetVideoFrameDelay(frame_delay_value_old); +} + static void FadeCrossSaveBackbuffer() { BlitBitmap(backbuffer, bitmap_db_cross, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); @@ -3547,7 +3555,7 @@ void WaitForEventToContinue() DoAnimation(); - WaitUntilDelayReached(&sync_frame_delay, sync_frame_delay_value); + BackToFront(); } } @@ -3721,8 +3729,6 @@ static int RequestHandleEvents(unsigned int req_state) } BackToFront(); - - WaitUntilDelayReached(&sync_frame_delay, sync_frame_delay_value); } return result; diff --git a/src/tools.h b/src/tools.h index 53a1af65..703a5223 100644 --- a/src/tools.h +++ b/src/tools.h @@ -83,6 +83,7 @@ void RedrawPlayfield(); void BlitScreenToBitmap_RND(Bitmap *); void BlitScreenToBitmap(Bitmap *); void BackToFront(); +void BackToFront_WithFrameDelay(unsigned int); void FadeIn(int); void FadeOut(int); -- 2.34.1