Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Difference between my time loop and Allegro

This thread is locked; no one can reply to it. rss feed Print
Difference between my time loop and Allegro
tibor698
Member #16,837
April 2018

I created two time loops, one mine using deltaTime and one with Allegro event timer.
The first one looks something like this:

#SelectExpand
1timeFrameCurrent = al_get_time(); 2deltaTime = timeFrameCurrent - timeFrameLast; 3p_time->OnDeltaTime(deltaTime); 4... 5if(!al_event_queue_is_empty(p_queue)) 6{ 7al_wait_for_event(p_queue, &event); 8// Code for input here 9} 10... 11Update(); 12if(al_event_queue_is_empty(p_queue)) 13{ 14// Render code here 15} 16timeFrameLast = timeFrameCurrent;

And the second like this:

#SelectExpand
1al_wait_for_event(p_queue, &event); 2... 3// Code for input here 4... 5if(event.type == ALLEGRO_EVENT_TIMER) 6{ 7Update(); 8if(al_event_queue_is_empty(p_queue)) 9{ 10// Render code here 11} 12}

Second code works fine and I don't have any errors while in the first one everything works fine until I move a mouse. If I move it the game looks like it's in speed mode and everything moves faster.
I could not figure it why is this happening. I just created a logic for deltaTime and set to skip waiting for event if there are no currently any events to let the engine update itself and render.
Do you have any clue why would this happen?

Elias
Member #358
May 2000

tibor698 said:

if(!al_event_queue_is_empty(p_queue))
{
al_wait_for_event(p_queue, &event);
// Code for input here
}

What are you trying to accomplish there, logically? If the event queue is not empty why would you wait for an event (you already know there is one...)?

[edit:] Actually, it makes sense, if the queue is not empty you just retrieve the first event.

--
"Either help out or stop whining" - Evert

Izual
Member #2,756
September 2002
avatar

It is just my guess since you posted your code incomplete, but it looks like you do Update(); every event in your code. You should update only when ALLEGRO_EVENT_TIMER occurs, like in the second code.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Audric
Member #907
January 2001

If using delta time, the "logic update" itself is supposed to take into account how much time has passed since the last "logic update".
In other words, you will not see ship.x += 4, but rather ship.x += delta_t * ship.speed

tibor698
Member #16,837
April 2018

@Izual This was my intent, to not have a fixed FPS but to use a max possible one.
@Edgar This is exactly what is happening but I don't understand why. Shouldn't it be possible to call Update for every event but with deltaTime as @Audric noted like ship.x += deltaTime * speed?

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

tibor698 said:

@Edgar This is exactly what is happening but I don't understand why. Shouldn't it be possible to call Update for every event but with deltaTime as @Audric noted like ship.x += deltaTime * speed?

Update is equivalent to passing time in your world. Why would you want to make time pass for every mouse event? It doesn't make sense. Update() gets called on every TIMER event.

For example here is one of my typical game loops :

#SelectExpand
1 2int Game::Run() { 3 4 bool paused = false; 5 while (state != QUIT) { 6 Display(); 7 int nevents = 0; 8 do { 9 EagleEvent ee = sys->WaitForSystemEventAndUpdateState(); 10 if (ee.type == EAGLE_EVENT_DISPLAY_CLOSE) { 11 state = QUIT; 12 } 13 if (ee.type == EAGLE_EVENT_DISPLAY_SWITCH_OUT) { 14 paused = true; 15 } 16 if (ee.type == EAGLE_EVENT_DISPLAY_SWITCH_IN) { 17 paused = false; 18 } 19 if (!paused) { 20 if (ee.type == EAGLE_EVENT_TIMER) { 21 ++nevents; 22 if (nevents == 1) {/// Slow down gracefully if the gpu or cpu can't handle it 23 Update(ee.timer.eagle_timer_source->SPT()); 24 } 25 } 26 CheckInputs(); 27 state = HandleEvent(ee); 28 } 29 } while (sys->GetSystemQueue()->HasEvent(0)); 30 } 31 return 0; 32}

tibor698
Member #16,837
April 2018

Why would you want to make time pass for every mouse event? It doesn't make sense.

I thought that I was calling update for every event, including mouse events and others, even if there where no events (timeDelta should be smaller in this case). So generally I thought I was updateing/rendering as fast as possible and timeDelta giving me the exact frame time.
Is there maybe some error in my code? How could I make it independent of TIMER and other events and render as fast as possible?

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Your monitor can only display so many frames per second. This is known as your monitor's refresh rate. If you try to display more than this number of frames per second, then you will have partial frames. One problem that can come from this is screen tearing, where a horizontal line appears across your display as it updates.

Most monitors have a refresh rate of 60 or more Hz. Trying to display more frames than this in a second is pointless, as they won't be shown, or they will be shown partially, causing screen tearing.

I think your cause of confusion comes from trying to mash all your logic into an Update function. I understand you want to handle every event, that's good, you don't want to miss events. But calling update on every event is wrong. It should only be called when time passes in your game. To handle the other events, you should have a HandleEvent function. All events go to this function, and when it receives a timer event, then it calls Update. Other events get processed accordingly.

Your logic can run at any rate, but your display is locked to the refresh rate.

If you need perfectly smooth animation, then you can use interpolation to find the exact position of an object between frames based on delta time, but your logic should still run at a fixed rate.

Audric
Member #907
January 2001

I disagree, delta time system is valid. It can be considerably harder to implement than fixed frequency, but it can have the following advantages over it :

  • When there is a performance hit, delta time may be able to catch up quicker than if you have to call a fixed frequency Update() a dozen times in a row.

  • For competitive games, it makes it possible to accept inputs immediately, rather than waiting for the next "tick" : The player with better reflexes will act first

  • It makes it possible to take into account every mouse position that the system detects (precision of position/trajectory). Even non-gamer mice can have a reliable 200 Hz precision, and for a painting program for example you will draw much smoother curves if you can process them all. "Fruit ninja" games will also benefit from faithful mouse movement.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Variable delta timing is super tricky, and mostly non-deterministic. When dt gets too high, you start getting things like teleportation and moving through walls. Most amateur collision systems aren't robust enough to handle high dt. If they dealt with intercept times, it could be different, but that just makes it harder. At that point, you're probably better off using a physics engine, unless you're a masochist.

Go to: