Repeating timers

I’ve been looking at the SDL_Timer API, and it appears that all the timer functions are for one-shot timers. I’m trying to redesign an existing engine to work under SDL, but some of the timer stuff looks like it’ll be difficult without a complete rewrite.

The existing game timer is an object that runs continuously. You can set an FPS property and it will figure out how often it should fire, and an Enabled property, which controls whether it runs or not. You register an event handler (callback) that it calls every time the timer fires, and it has a GetLatency function that you can call at any time to see how long has elapsed since the last time the timer went off.

Does SDL have support for anything like this, or will I have to build my own?

SDL_SetTimer() is deprecated. You want SDL_AddTimer().On Fri, Apr 10, 2009 at 11:36 AM, Mason Wheeler wrote:

Does SDL have support for anything like this, or will I have to build my own?


http://codebad.com/

Does SDL have support for anything like this, or will I have to build my own?

SDL_SetTimer() is deprecated. You want SDL_AddTimer().

Interesting. Although the callback is a bit unclear.

/* Function prototype for the new timer callback function.

  • The callback function is passed the current timer interval and returns
  • the next timer interval. If the returned value is the same as the one
  • passed in, the periodic alarm continues, otherwise a new alarm is
  • scheduled. If the callback returns 0, the periodic alarm is cancelled.
    */
    typedef Uint32(SDLCALL * SDL_NewTimerCallback) (Uint32 interval, void *param);

Let’s say I create a timer that goes off every 30 ms, with a callback that does
rendering, which can take between 5 and 15 ms depending on what needs to
be done, then returns the same value it received from variable. It looks like
that means that that will make the next alarm go off 30 ms after the previous
one did, but if I were to return a different number, say 29 for example, then
the next timer would go off 29 ms after… what? After the previous timer went
off, or after the callback returns?>----- Original Message ----

From: Donny Viszneki <donny.viszneki at gmail.com>
Subject: Re: [SDL] Repeating timers
On Fri, Apr 10, 2009 at 11:36 AM, Mason Wheeler <@Mason_Wheeler> wrote:

Mason Wheeler wrote:>> ----- Original Message ----

From: Donny Viszneki <donny.viszneki at gmail.com>
Subject: Re: [SDL] Repeating timers

On Fri, Apr 10, 2009 at 11:36 AM, Mason Wheeler wrote:

Does SDL have support for anything like this, or will I have to
build my own?

SDL_SetTimer() is deprecated. You want SDL_AddTimer().

Interesting. Although the callback is a bit unclear.

/* Function prototype for the new timer callback function.

  • The callback function is passed the current timer interval and
    returns
  • the next timer interval. If the returned value is the same as the
    one
  • passed in, the periodic alarm continues, otherwise a new alarm is
  • scheduled. If the callback returns 0, the periodic alarm is
    cancelled. */
    typedef Uint32(SDLCALL * SDL_NewTimerCallback) (Uint32 interval, void
    *param);

Let’s say I create a timer that goes off every 30 ms, with a callback
that does rendering, which can take between 5 and 15 ms depending on
what needs to
be done, then returns the same value it received from variable. It
looks like that means that that will make the next alarm go off 30 ms
after the previous one did, but if I were to return a different
number, say 29 for example, then the next timer would go off 29 ms
after… what? After the previous timer went off, or after the
callback returns?

That’s not what my tinkering showed. I found that if you set the timer for
30mS, each callback will begin 30mS apart, even if you delay 3mS in the
callback routine. AIUI, returning zero from the callback function cancels
the timer and any other value just continues the repitition. The timer only
has 10mS granularity. I hope they change this. :wink:

That’s not what my tinkering showed. I found that if you set the timer for
30mS, each callback will begin 30mS apart, even if you delay 3mS in the
callback routine. AIUI, returning zero from the callback function cancels
the timer and any other value just continues the repitition. The timer only
has 10mS granularity. I hope they change this. :wink:

Hang on. So returning some other number doesn’t reset the timer or change
the interval? The comment sure looks like it says that it should! Is this a
glitch, or am I misunderstanding something?>----- Original Message ----

From: michael brown
Subject: Re: [SDL] Repeating timers

If the comment is to be believed, then you just cannot use the
callback to schedule a new timer that is exactly ‘interval’ away from
this old one (instead, that would just cause the timer to continue and
fire at ‘interval’ - deltaT in the future).

Jonny DOn Fri, Apr 10, 2009 at 2:14 PM, Mason Wheeler wrote:

----- Original Message ----

From: michael brown
Subject: Re: [SDL] Repeating timers

That’s not what my tinkering showed. ?I found that if you set the timer for
30mS, each callback will begin 30mS apart, even if you delay 3mS in the
callback routine. ?AIUI, returning zero from the callback function cancels
the timer and any other value just continues the repitition. ?The timer only
has 10mS granularity. ?I hope they change this. ?:wink:

Hang on. ?So returning some other number doesn’t reset the timer or change
the interval? ?The comment sure looks like it says that it should! ?Is this a
glitch, or am I misunderstanding something?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Oh, I see. It does seem ambiguous, but I’m not currently in a
position to test whether the new timer starts at ‘oldStart +
newInterval’ or ‘oldEnd + newInterval’.

Jonny DOn Fri, Apr 10, 2009 at 2:18 PM, Jonathan Dearborn <@Jonathan_Dearborn> wrote:

If the comment is to be believed, then you just cannot use the
callback to schedule a new timer that is exactly ‘interval’ away from
this old one (instead, that would just cause the timer to continue and
fire at ‘interval’ - deltaT in the future).

Jonny D

On Fri, Apr 10, 2009 at 2:14 PM, Mason Wheeler wrote:

----- Original Message ----

From: michael brown
Subject: Re: [SDL] Repeating timers

That’s not what my tinkering showed. ?I found that if you set the timer for
30mS, each callback will begin 30mS apart, even if you delay 3mS in the
callback routine. ?AIUI, returning zero from the callback function cancels
the timer and any other value just continues the repitition. ?The timer only
has 10mS granularity. ?I hope they change this. ?:wink:

Hang on. ?So returning some other number doesn’t reset the timer or change
the interval? ?The comment sure looks like it says that it should! ?Is this a
glitch, or am I misunderstanding something?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Logically, though, the ‘oldStart + newInterval’ would not work for
newInterval values less than your deltaT (processing time). That
leads me to guess that the new timer starts at ‘oldEnd + newInterval’.

Sorry for the spam,
Jonny DOn Fri, Apr 10, 2009 at 2:20 PM, Jonathan Dearborn <@Jonathan_Dearborn> wrote:

Oh, I see. ?It does seem ambiguous, but I’m not currently in a
position to test whether the new timer starts at ‘oldStart +
newInterval’ or ‘oldEnd + newInterval’.

Jonny D

On Fri, Apr 10, 2009 at 2:18 PM, Jonathan Dearborn <@Jonathan_Dearborn> wrote:

If the comment is to be believed, then you just cannot use the
callback to schedule a new timer that is exactly ‘interval’ away from
this old one (instead, that would just cause the timer to continue and
fire at ‘interval’ - deltaT in the future).

Jonny D

On Fri, Apr 10, 2009 at 2:14 PM, Mason Wheeler wrote:

----- Original Message ----

From: michael brown
Subject: Re: [SDL] Repeating timers

That’s not what my tinkering showed. ?I found that if you set the timer for
30mS, each callback will begin 30mS apart, even if you delay 3mS in the
callback routine. ?AIUI, returning zero from the callback function cancels
the timer and any other value just continues the repitition. ?The timer only
has 10mS granularity. ?I hope they change this. ?:wink:

Hang on. ?So returning some other number doesn’t reset the timer or change
the interval? ?The comment sure looks like it says that it should! ?Is this a
glitch, or am I misunderstanding something?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Oh, I see. It does seem ambiguous, but I’m not currently in a
position to test whether the new timer starts at ‘oldStart +
newInterval’ or ‘oldEnd + newInterval’.

Yeah. And that can be a pretty significant difference if you’re doing
anything that requires a high-precision game timer in the first
place. (BTW what’s up with the 10 ms resolution thing? That’s
not all that high-precision, when you can set 33 FPS or 50 FPS
but nothing in between…)>----- Original Message ----

From: Jonathan Dearborn
Subject: Re: [SDL] Repeating timers

Mason Wheeler wrote:>> ----- Original Message ----

From: michael brown <@michael_brown>
Subject: Re: [SDL] Repeating timers

That’s not what my tinkering showed. I found that if you set the
timer for 30mS, each callback will begin 30mS apart, even if you
delay 3mS in the callback routine. AIUI, returning zero from the
callback function cancels the timer and any other value just
continues the repitition. The timer only has 10mS granularity. I
hope they change this. :wink:

Hang on. So returning some other number doesn’t reset the timer or
change the interval? The comment sure looks like it says that it
should! Is this a glitch, or am I misunderstanding something?

Yes, it appears that the documentation that I read on that part was wrong.
Some testing I just did shows that the return value is important. Returning
0 doesn’t appear to cancel the timer either. Still doing experiments…

Logically, though, the ‘oldStart + newInterval’ would not work for
newInterval values less than your deltaT (processing time). ?That
leads me to guess that the new timer starts at ‘oldEnd + newInterval’.

Sorry for the spam,
Jonny D

Oh, I see. ?It does seem ambiguous, but I’m not currently in a
position to test whether the new timer starts at ‘oldStart +
newInterval’ or ‘oldEnd + newInterval’.

Here is the relevant code from SDL:

if ( (int)(now - t->last_alarm) > (int)ms ) {
struct _SDL_TimerID timer;

if ( (now - t->last_alarm) < t->interval ) {
    t->last_alarm += t->interval;
} else {
    t->last_alarm = now;
}On Fri, Apr 10, 2009 at 2:22 PM, Jonathan Dearborn <grimfang4 at gmail.com> wrote:

On Fri, Apr 10, 2009 at 2:20 PM, Jonathan Dearborn wrote:


http://codebad.com/

Here is the relevant code from SDL:

This code is the same in the SDL 1.2.13 release and SVN revision 4474On Fri, Apr 10, 2009 at 3:01 PM, Donny Viszneki <@Donny_Viszneki> wrote:

if ( (int)(now - t->last_alarm) > (int)ms ) {
? ?struct _SDL_TimerID timer;

? ?if ( (now - t->last_alarm) < t->interval ) {
? ? ? ?t->last_alarm += t->interval;
? ?} else {
? ? ? ?t->last_alarm = now;
? ?}


http://codebad.com/


http://codebad.com/

michael brown wrote:

Mason Wheeler wrote:

That’s not what my tinkering showed. I found that if you set the
timer for 30mS, each callback will begin 30mS apart, even if you
delay 3mS in the callback routine. AIUI, returning zero from the
callback function cancels the timer and any other value just
continues the repitition. The timer only has 10mS granularity. I
hope they change this. :wink:

Hang on. So returning some other number doesn’t reset the timer or
change the interval? The comment sure looks like it says that it
should! Is this a glitch, or am I misunderstanding something?

Yes, it appears that the documentation that I read on that part was
wrong. Some testing I just did shows that the return value is
important. Returning 0 doesn’t appear to cancel the timer either. Still
doing experiments…

Returning 0 does cancel the timer. The callback function is called early
the first time. I know this to be true since I set the timer for 30mS, yet
SDL_GetTicks returned 21 on the first entry to the callback routine. This
is clearly an impossible situation. This makes canceling the timer by
returning 0, and scheduling a new one in the callback unworkable. I want a
33mS delay and there is no way for me to make it work. Ideally I should be
able to usleep(3000) at the beginning of the callback, call SDL_AddTimer to
create a new callback 30mS later, and finally returning 0 to cancel the
previous timer. When I do this, I get a callback every 4mS. :-(>>> ----- Original Message ----

From: michael brown <@michael_brown>
Subject: Re: [SDL] Repeating timers

Returning 0 does cancel the timer. ?The callback function is called early
the first time. ?I know this to be true since I set the timer for 30mS, yet
SDL_GetTicks returned 21 on the first entry to the callback routine.

Here is the relevant code from SDL 1.2.13 release and SDL SVN rev 4474:

for (prev = NULL, t = SDL_timers; t; t = next) {
    removed = SDL_FALSE;
    ms = t->interval - SDL_TIMESLICE;
    next = t->next;
    if ((int) (now - t->last_alarm) > (int) ms) {

This macro is used to round each interval before it’s added/updated:

#define ROUND_RESOLUTION(X)
(((X+TIMER_RESOLUTION-1)/TIMER_RESOLUTION)*TIMER_RESOLUTION)

As the documentation says, you can only depend on "10ms resolution."
That’s a little ambiguous, but from looking at the code, it’s clear
that 21 ms is exactly the earliest you could expect to get for any
interval between 21-39 ms, and 39 ms would be the latest.

?Ideally I should be
able to usleep(3000) at the beginning of the callback, call SDL_AddTimer to
create a new callback 30mS later, and finally returning 0 to cancel the
previous timer. ?When I do this, I get a callback every 4mS. ?:frowning:

That is absolute craziness.

SDL timers are not good for much because their resolution is too low.
You clearly need very precise timing (which is typical of games) and
you should not be using an SDL timer for this.On Fri, Apr 10, 2009 at 3:05 PM, michael brown wrote:


http://codebad.com/

err… i guess that’s 21-30 (inclusive?)

y=(x+9)/10*10

x=21, y=(21+9)/1010=30
x=31, y=(31+9)/10
10=40On Fri, Apr 10, 2009 at 3:12 PM, Donny Viszneki <@Donny_Viszneki> wrote:

As the documentation says, you can only depend on "10ms resolution."
That’s a little ambiguous, but from looking at the code, it’s clear
that 21 ms is exactly the earliest you could expect to get for any
interval between 21-39 ms, and 39 ms would be the latest.


http://codebad.com/

That is absolute craziness.

SDL timers are not good for much because their resolution is too low.
You clearly need very precise timing (which is typical of games) and
you should not be using an SDL timer for this.

Which begs the question: why do SDL timers suck so badly? The
rest of the library is a very nice, high-quality package, but it sticks
us with a timer that’s completely unsuitable for real-world game
development?

This may not work quite as well on embedded systems, but
modern desktops and laptops, at least, run CPUs measured in
gigahertz. If you have 1 GHz of processing power, you get 1M
CPU cycles per millisecond. I believe I heard somewhere that
a context switch generally costs ~2000 cycles. If so, why
shouldn’t we be able to have a timer with a resolution of 1 ms,
on desktop OSes at least?>----- Original Message ----

From: Donny Viszneki <donny.viszneki at gmail.com>
Subject: Re: [SDL] Repeating timers

I agree… I think SDL should use the available precision that is
closest to 1ms on the systems that support such. This is one of the
loudest complaints I hear of SDL.

Jonny DOn Fri, Apr 10, 2009 at 3:19 PM, Mason Wheeler wrote:

----- Original Message ----

From: Donny Viszneki <donny.viszneki at gmail.com>
Subject: Re: [SDL] Repeating timers

That is absolute craziness.

SDL timers are not good for much because their resolution is too low.
You clearly need very precise timing (which is typical of games) and
you should not be using an SDL timer for this.

Which begs the question: why do SDL timers suck so badly? The
rest of the library is a very nice, high-quality package, but it sticks
us with a timer that’s completely unsuitable for real-world game
development?

This may not work quite as well on embedded systems, but
modern desktops and laptops, at least, run CPUs measured in
gigahertz. ?If you have 1 GHz of processing power, you get 1M
CPU cycles per millisecond. ?I believe I heard somewhere that
a context switch generally costs ~2000 cycles. ?If so, why
shouldn’t we be able to have a timer with a resolution of 1 ms,
on desktop OSes at least?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

No one has written a better SDL timer yet, that’s the only real reason.On Fri, Apr 10, 2009 at 3:19 PM, Mason Wheeler wrote:

Which begs the question: why do SDL timers suck so badly?


http://codebad.com/

Which begs the question: why do SDL timers suck so badly?

No one has written a better SDL timer yet, that’s the only real reason.

I’ve got a better timer from another library that I could probably port to
C with a bit of work. Two problems, though.

  1. It’s full of Windows API calls. (Not too portable.)
  2. It’s MPL licensed, not LGPL.>----- Original Message ----

From: Donny Viszneki <donny.viszneki at gmail.com>
Subject: Re: [SDL] Repeating timers
On Fri, Apr 10, 2009 at 3:19 PM, Mason Wheeler <@Mason_Wheeler> wrote:

Donny Viszneki wrote:

Returning 0 does cancel the timer. The callback function is called
early the first time. I know this to be true since I set the timer
for 30mS, yet SDL_GetTicks returned 21 on the first entry to the
callback routine.

Here is the relevant code from SDL 1.2.13 release and SDL SVN rev
4474:

for (prev = NULL, t = SDL_timers; t; t = next) {
    removed = SDL_FALSE;
    ms = t->interval - SDL_TIMESLICE;
    next = t->next;
    if ((int) (now - t->last_alarm) > (int) ms) {

This macro is used to round each interval before it’s added/updated:

#define ROUND_RESOLUTION(X)
(((X+TIMER_RESOLUTION-1)/TIMER_RESOLUTION)*TIMER_RESOLUTION)

As the documentation says, you can only depend on "10ms resolution."
That’s a little ambiguous, but from looking at the code, it’s clear
that 21 ms is exactly the earliest you could expect to get for any
interval between 21-39 ms, and 39 ms would be the latest.

Ideally I should be
able to usleep(3000) at the beginning of the callback, call
SDL_AddTimer to create a new callback 30mS later, and finally
returning 0 to cancel the previous timer. When I do this, I get a
callback every 4mS. :frowning:

That is absolute craziness.

LOL Just trying to work with what I have at hand. :wink:

SDL timers are not good for much because their resolution is too low.
You clearly need very precise timing (which is typical of games) and
you should not be using an SDL timer for this.

I thought it’d be smart to do my frame flipping during the callback to try
for a nice even frame presentation. In the callback I push an event to
trigger the main thread to start decompressing another JPG image (if
present). When the image is finally decompressed (about 11mS later now :slight_smile:
I draw it on the surface and set a flag indicating that the frame is ready
for display. The callback checks the flag and does an SDL_Flip on the
screen if the flag is set. I’ll find a better timer, but keep the design.> On Fri, Apr 10, 2009 at 3:05 PM, michael brown <@michael_brown> wrote: