timing loop
William Labbett

hi,

I'd appreciate it if I could get a bit of guidance with my timing loop - if only to confirm my understanding.

Have been trying to understand timing loops. It's one of the things I find really hard to get although I can write the code.

This code below shows the timing loop I'm using at the moment.

After the while() the drawing takes place and then when it gets back to the while loop al_get_timer_count(timer) will be a new higher value and old_time will be
what it was left as.

..but as I understand it, each time the condition is tested al_get_timer_count(timer) gets called again - so if the logic in

while( old_time < al_get_timer_count(timer))

takes a while, then old_time will have more catching up to do and so more logic calls happen.

Is this the way to do things ?

#SelectExpand
1while( old_time < al_get_timer_count(timer)) 2 { 3 ++old_time; 4 5 pf("old_time = %d\n", old_time); 6 7 //update_animations( draw_data_ptr->grid_squares, land_map_dimensions[0], land_map_dimensions[1] ); 8 9 --hero_frame_counter; 10 if(hero_frame_counter <= 0) 11 { 12 hero_frame_counter = HERO_TICKS_PER_FRAMEUPDATE; 13 14 update_hero_frame(); 15 } 16 17 --hero_move_counter; 18 19 if(hero_move_counter <= 0) 20 { 21 hero_move_counter = HERO_TICKS_PER_MOVEUPDATE; 22 23 //printf(" calling main_world_logic().\n"); 24 25 #ifdef INCLUDE_TEXT_LOG_CODE 26 lg( MAIN_WORLD_MAIN_LOG, " calling main_world_logic().\n", AA); 27 #endif 28 29 hero_move_result = process_hero_input( cdata, teffects, draw_data_ptr->map_dimensions[0] * 8, draw_data_ptr->map_dimensions[1] * 8); 30 31 32 33 34 //printf(" hero.x = %d,", hero.x); 35 36 } 37 38 39 }

Audric

You understood correctly: This kind of fixed-delta logic requires the computer to be able to run the logic faster than the timer frequency. Otherwise, you never reach the part where you compute the image and send it to screen.

The decision-making part of a program is generally fast so it's not a problem, except in some notable cases :
- unit-to-unit collision detection and response. An algorithm with O(n²) can kill the performances.
- pathfinding when many units are concerned in big maps.

William Labbett

Thanks Audric.

So,

new_time = al_get_timer_count(timer);

while( old_time < new_time)
{
   ...

}

would this be a bad way to do things ?

Edgar Reynaldo

No, just make sure not to draw again if you don't do any logic. It would run as many ticks as there are extra.

Arthur Kalliokoski

I have something like this: (not Allegro)

#SelectExpand
1#define DELAY 85.0 2extern double gettime(void); //returns time(0) as double with milliseconds 3double thistime; 4double waittime; 5double currtime; 6double nexttime; 7int delay; 8int maxdelay; 9int mindelay = 0x7FFFFFFF; 10int numwaits; 11 12 thistime = gettime(); //in-game timer 13 nexttime = thistime + 1.0/DELAY; 14 while(!quit) 15 { 16 thistime = gettime(); 17 nexttime = thistime + 1.0/DELAY; 18 . 19 . 20 do stuff 21 . 22 . 23 waittime = gettime(); 24 if(waittime > nexttime) 25 { 26 printf("wait %lf\n",waittime - nexttime); 27 thistime = waittime; 28 nexttime = thistime + 1.0/DELAY; 29 numwaits++; 30 continue; 31 } 32 currtime = nexttime - waittime; 33 delay = (double)currtime * 1000000.0; 34 if(mindelay > delay) 35 mindelay = delay; 36 if(maxdelay < delay) 37 maxdelay = delay; 38 usleep(delay); 39 nexttime = thistime + 1.0/DELAY; 40 }

The maxdelay and mindelay are for debugging, not strictly necessary.

Thread #606804. Printed from Allegro.cc