Re: [Tuxnes-devel] Smoother scrolling
Brought to you by:
tmmm
|
From: Jason D. S. <jd...@us...> - 2004-01-19 10:00:20
|
Mike Mestnik wrote:
> I was chasing a simular problem, but I coulden't get any thing to work. I don't think it's
> correct to cahnge the usleep, as it's based on the NTSC standared. I.E. 16666 = 1 frame and if
> were n frames ahead 16666 * ( n - 1 ) is how long we wait.
You don't want to usleep for a fixed amount of time, or you'll get
*behind*. For instance if you sleep for 10 useconds and then do some
calculations that take 5 useconds, your tick length is actually 5
useconds instead of 10 useconds as you wanted it to be. (Just using 10
as an example.)
Instead you want to do your 5 usecond calculations then sleep for just
the remaining 5 useconds.
The easiest solution is to track the time of each tick. Use a timeval
struct to tell when the next "tick" should occur. Then before sleeping
figure out how long is left between now and then, and sleep for that long.
Something like:
struct timeval next, now;
int usec;
/* This is the only time we call gettimeofday on 'next'. After
* this we just increment it. */
gettimeofday(&next, NULL);
while (1) {
next.usec += TICK_TIME;
if (next.usec >= 1000000) {
next.usec -= 1000000;
next.sec++;
}
do_something();
gettimeofday(&now, NULL);
usec = 1000000 * (next.sec - now.sec) + (next.usec - now.usec);
if (usec > 0) usleep(usec);
}
In short, something like the attached patch should work. I haven't
tested it, though.
--- digression ---
There are also external events that generally need to be handled. You
generally shouldn't poll for these (however this is NES emulation so
it's probably okay to be inefficient).
I've generally written network code where you want to call select()
while having a "tick" in place as well. This works great since select
just takes the timeval struct as an argument.
In GUI code you want to either get interrupts or pass the waiting off to
a GUI function that can handle the interrupts directly. My experience
is in GTK where you call a function to set a timer, then pass control
back to GTK. While GTK has control it can do updates (like redrawing
windows), handle events (if a key is pressed GTK will call your
program's handler for that key), or handle the tick when the time comes
(GTK will call your program's handler for that tick). SDL has something
similar, although it's generally implemented with polling anyway.
jason
|