Re: [Super-tux-devel] Last meter to 0.0.6
Brought to you by:
wkendrick
From: Martin R. <mar...@gm...> - 2004-03-13 10:26:21
|
Hi, On Sat, Mar 13, 2004 at 03:37:50AM -0500, Tobias Gläßer wrote: > - If you have low FPS (<~20) [...] > - Again, if you have low FPS (<~20) [...] This patch makes sure the engine never runs slower than 50 fps (and never faster than 100 fps, as before). On my machine, the cost is that it slows the visible framerate from ~23fps down to ~19fps. I haven't tested it on a fast machine. Maybe someone has a better solution ready? bye, Martin Index: src/gameloop.c =================================================================== RCS file: /cvsroot/super-tux/supertux/src/gameloop.c,v retrieving revision 1.55 diff -u -p -r1.55 gameloop.c --- src/gameloop.c 9 Mar 2004 15:33:18 -0000 1.55 +++ src/gameloop.c 13 Mar 2004 09:50:25 -0000 @@ -54,8 +54,6 @@ static char level_subset[100]; static char str[60]; static float fps_fps; static int st_gl_mode; -static unsigned int last_update_time; -static unsigned int update_time; static int pause_menu_frame; /* Local function prototypes: */ @@ -92,7 +90,6 @@ void start_timers(void) { timer_start(&time_left,current_level.time_left*1000); st_pause_ticks_init(); - update_time = st_get_ticks(); } void activate_bad_guys(void) @@ -561,7 +558,9 @@ void game_draw(void) int gameloop(char * subset, int levelnb, int mode) { - int fps_cnt, jump, done; + int fps_cnt, done, draw_frame; + double frames_left; + unsigned int update_time, last_update_time; timer_type fps_timer, frame_timer; timer_init(&fps_timer, YES); timer_init(&frame_timer, YES); @@ -602,7 +601,8 @@ int gameloop(char * subset, int levelnb, /* --- MAIN GAME LOOP!!! --- */ - jump = NO; + frames_left = 0.0; + update_time = st_get_ticks(); done = 0; quit = 0; frame = 0; @@ -622,10 +622,43 @@ int gameloop(char * subset, int levelnb, game_draw(); do { - jump = NO; - /* Calculate the movement-factor */ - frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE); + last_update_time = update_time; + update_time = st_get_ticks(); + draw_frame = YES; + if(!game_pause && !show_menu) + { + frames_left += ((double)(update_time-last_update_time))/((double)FRAME_DURATION); + if(frames_left < 1.0) + { + /* running too fast */ + SDL_Delay(FRAME_DURATION / 2); + continue; + } + else if(frames_left < 2.0) + { + /* running normal */ + frame_ratio = frames_left; + frames_left = 0.0; + } + else if(frames_left < 5000/FRAME_DURATION) + { + /* running too slow */ + frame_ratio = 2.0; + frames_left -= 2.0; + draw_frame = NO; + } + else + { + /* running way too slow */ + printf("Help! Can't even calculate the game in real time, expect bugs.\n"); + printf("(frames_left = %f)\n", frames_left); + /* FIXME: slowdown buggy because the timers still tick in realtime */ + frame_ratio = 2.0; + frames_left = 0.0; + draw_frame = YES; + } + } if(!timer_check(&frame_timer)) { @@ -696,15 +729,25 @@ int gameloop(char * subset, int levelnb, if(debug_mode && tux.input.down == DOWN) SDL_Delay(45); - /*Draw the current scene to the screen */ - /*If the machine running the game is too slow - skip the drawing of the frame (so the calculations are more precise and - the FPS aren't affected).*/ - /*if( ! fps_fps < 50.0 ) - game_draw(); - else - jump = YES;*/ /*FIXME: Implement this tweak right.*/ - game_draw(); + /* draw the current scene to the screen if the game is not running too slow */ + if (draw_frame) + { + game_draw(); + + /* Calculate frames per second */ + if(show_fps) + { + ++fps_cnt; + fps_fps = (1000.0 / (float)timer_get_gone(&fps_timer)) * (float)fps_cnt; + + if(!timer_check(&fps_timer)) + { + timer_start(&fps_timer,1000); + fps_cnt = 0; + } + } + } + /* Time stops in pause mode */ if(game_pause || show_menu ) @@ -712,20 +755,6 @@ int gameloop(char * subset, int levelnb, continue; } - /* Set the time the last update and the time of the current update */ - last_update_time = update_time; - update_time = st_get_ticks(); - - - /* Pause till next frame, if the machine running the game is too fast: */ - /* FIXME: Works great for in OpenGl mode, where the CPU doesn't have to do that much. But - the results in SDL mode aren't perfect (thought the 100 FPS are reached), even on an AMD2500+. */ - if(last_update_time >= update_time - 12 && jump != YES ) - SDL_Delay(10); - /*if((update_time - last_update_time) < 10) - SDL_Delay((11 - (update_time - last_update_time))/2);*/ - - /* Handle time: */ @@ -755,19 +784,6 @@ int gameloop(char * subset, int levelnb, play_current_music(); } - /* Calculate frames per second */ - if(show_fps) - { - ++fps_cnt; - fps_fps = (1000.0 / (float)timer_get_gone(&fps_timer)) * (float)fps_cnt; - - if(!timer_check(&fps_timer)) - { - timer_start(&fps_timer,1000); - fps_cnt = 0; - } - } - } while (!done && !quit); @@ -1792,7 +1808,6 @@ void loadgame(int slot) level_free_song(); level_load_song(¤t_level); levelintro(); - update_time = st_get_ticks(); fread(&score,sizeof(int),1,fi); fread(&distros,sizeof(int),1,fi); Index: src/scene.h =================================================================== RCS file: /cvsroot/super-tux/supertux/src/scene.h,v retrieving revision 1.6 diff -u -p -r1.6 scene.h --- src/scene.h 24 Feb 2004 15:34:00 -0000 1.6 +++ src/scene.h 13 Mar 2004 09:50:25 -0000 @@ -21,7 +21,7 @@ #include "special.h" #include "level.h" -#define FRAME_RATE 10 // 100 Frames per second (10ms) +#define FRAME_DURATION 10 // 100 Frames per second (10ms) extern int score, distros, level, next_level, game_pause, quit, score_multiplier, endpos, counting_distros, distro_counter; extern timer_type super_bkgd_timer; extern float scroll_x; |