[java] High-resolution timers

Started by
15 comments, last by Kanzetsu 22 years, 3 months ago
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
// Kanzetsu
Advertisement
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.
Has anyone tried J3DTimer? Any better?
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....

:-)





ujhkfkfk
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
// Kanzetsu
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
-- master_ball --------------------------------student seeking future game dev career, advice welcome
Wow, we''ve been having a lot of people have trouble realizing that this is a JAVA forum recently...
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.....

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

:-)
ujhkfkfk
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
// Kanzetsu

This topic is closed to new replies.

Advertisement