Archived

This topic is now archived and is closed to further replies.

Kanzetsu

[java] High-resolution timers

Recommended Posts

Kanzetsu    122
Is there any way to get a timer with higher resolution than System.currentTimeMilli's 10 ms under NT? Using JDK1.1? // Kanzetsu Edited by - Kanzetsu on December 9, 2001 8:50:38 PM

Share this post


Link to post
Share on other sites
a person    118
probally not, since java is designed to be cross platform excutable. though i am not a java expert, i do know that the most accurate clock the pc has is using the RDSTC instruction (or QueryPerformanceCounter of the windows api which basically does th RDSTC for you) its x86 specifc though and not what ou are lookig for, but may help if you can get hava to allow certain win32 api calls.

Share this post


Link to post
Share on other sites
Chaoslab    116
I ran into this problem when in Nebuloids a while ago.

As System.currentTimeMillis() is only good for about a 18 frames a secound game which is a little chunky....

I solved the problem by running a low priority thread that just sleep the right time and incremented a variable and I used that for my frame ticks and it works quite well....

:-)





Share this post


Link to post
Share on other sites
Kanzetsu    122
Hmm, this is very interesting. Could you please explain on how to achieve this? If I put a delay(25) in my main game loop, that will actually have the precise same effect as a delay(30) because of the 10 ms resolution. Is adjusting thread priorities the trick to gaining a more precise timer?

// Kanzetsu

Edited by - Kanzetsu on December 10, 2001 5:53:20 PM

Share this post


Link to post
Share on other sites
master_ball    132
Try timeGetTime() (Win32 API).

For Windows NT: The default precision of the timeGetTime function can be five milliseconds or more, depending on the machine. You can use the timeBeginPeriod and timeEndPeriod functions to increase the precision of timeGetTime. If you do so, the minimum difference between successive values returned by timeGetTime can be as large as the minimum period value set using timeBeginPeriod and timeEndPeriod.

Use the QueryPerformanceCounter and QueryPerformanceFrequency functions to measure short time intervals at a high resolution,

We R 138

Share this post


Link to post
Share on other sites
bslayerw    122
If you are not concerned about cross platform issues and are not wanting to do hi res timing in an applet then I can send you some code. I wrote a small dll that wraps the performanceCount and PerformanceFrequency API calls and a Java class that wraps the JNI calls.

You also might want to do a search on the javagaming.org forum, there were a stream of posts on this topic. There was even some code explaining how to do the low priority thread hack. Also, I heard that the J3DTimer is a high precision timer.

Oh well.....

Share this post


Link to post
Share on other sites
Chaoslab    116
Heres a my timer class for ya....

Nice and simple.... I looked at Nebs code and saw that I don''t even bother to set the thread priority.


public class mytimer
{
public int tick = 0;
public long sleep_time = 33; // 1000 / 30 for 30 frames a sec

new Thread()
{
public void run()
{
try
{
this.sleep(sleep_time);
tick++;
}

}.start();

}

}



Hope that helps

:-)

Share this post


Link to post
Share on other sites
Kanzetsu    122
What OSes have you tested it under? I'm doing something wrong, because I don't get the requested frequency of updates (requested 40 fps becomes 33, 33 becomes 24-25 etc), and on a WinME frame rate drops to about half . Also, there are also some lag, especially noticable in lower frame rates.

I don't know if this could be a priority problem or not (frames are about the same each time I run), maybe using wait() and notify() could help? This is my UpdateTimer class right now:

      
public class UpdateTimer implements Runnable {
private Thread thread;
private long delay;
private int ticks;
private boolean running;
private TimerObserver observer;

public UpdateTimer(long interval, TimerObserver observer) {
delay = interval;
this.observer = observer;
}

public void run() {
if (Thread.currentThread() == thread) {
while(running) {
try {
thread.sleep(delay);
}
catch (InterruptedException e) {}
ticks++;
if (observer != null)
observer.timerUpdate();
}
}
}

public void start() {
reset();
if (thread == null) {
thread = new Thread(this);
running = true;
thread.start();
}
}

public void stop() {
running = false;
}

public void resume() {
running = true;
}

public void destroy() {
if (thread != null) {
thread = null;
}
running = false;
}

public void reset() {
ticks = 0;
}

public int getTicks() {
return ticks;
}

public boolean running() {
return running;
}
}


// Kanzetsu

Edited by - Kanzetsu on December 11, 2001 5:52:43 PM

Share this post


Link to post
Share on other sites
javanerd    122
Snowmoon has done an autoadjusting thread timer class. I''ve added it to GameFrame for Java (GF4J) version 0.9.6-RC1. You can download the whole thing from http://www.gamedev.net/hosted/javanerd and see the sources of gameframe.implementations.ThreadSleepClock




-

Pasi Keränen

javanerd@geocities.com

Share this post


Link to post
Share on other sites
Kanzetsu    122
OK, I had a looked the class and apart from the adjustment part (which is the key to the functionality) it looked pretty similar to mine. However, I had some issues I wouldn't mind getting some comments on:

- Time polling. At first I had a

while(timer.getTime - startTime < minFrameTime)

at the end of each game loop iteration. This turned out to put the applet stutter, probably because hammering a synchronized method isn't that good. So, I implemented a waitForUpdate() method in the timer to wait for the notifyAll() called by the timer after each tick. At least things ran smooth now, but I still couldn't get higher timer resolutions. So I had a look at...

- Sleep time calibration. Every 50th tick? That doesn't do me any good, since I'm syncing *each* frame by the timer. So I took it down to every 2nd tick, which made things run smoothly and pretty close to the requested frame rates (30 fps could become 28-29, no biggie). HOWEVER - moving the mouse anywhere in the browser window would make the whole applet slow down considerably, and often freeze and not resume. This one is my big problem right now... got any clues?

// Kanzetsu

Edited by - Kanzetsu on December 13, 2001 6:54:32 PM

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
>HOWEVER - moving the mouse anywhere in the browser window would >make the whole applet slow down considerably, and often freeze >and not resume. This one is my big problem right now... got any >clues?
>
>// Kanzetsu


did you really set up a render thread?

post your code on the board so we all can check your source

heinrich

Share this post


Link to post
Share on other sites
Chaoslab    116
If you are having probs Rendering stuff, don''t use the paint method in your applet (just override it with an empty paint method, & update to)

Then grab the graphics var (I use Graphics gm, standing for graphics main) in the applet init as a reference to use for drawing, by gm = this.getGraphics();

This is good for real time stuff as run concurrently to paint is slower as your main loop and paint (& what ever else) will try to run at the same time.

:-)

Share this post


Link to post
Share on other sites
Kanzetsu    122
Yup, I read your post about this earlier, and it''s already there =). There still seems to be some slowdown but only by a couple of frames. I can live with that for now, I''ll go back to fine-tuning timers etc later.

// Kanzetsu

Share this post


Link to post
Share on other sites
Chaoslab    116
What speed is your dev plat?

I would be careful with getting to carried aournd with fine tuning timing as it may be a little inconsistant on different specked machines and other JVMS....

:-)

Share this post


Link to post
Share on other sites
snowmoon    122
Hmm..

Whell I chose even X ticks becase the ammount time must be high enough for the getCurrentTimeMills to to be more than junk. I tried doing a loop or modifiing it every time and every attempt to do so was a disaster with it ending up speeding up and slowing down untill it faulted for going to a 0 ms delay.

I have gone back over the code and I believe I might be able to make it a little more stable with a simple fix. I''ll give it another shot and report back.

Snowmoon

Share this post


Link to post
Share on other sites