Skip to main content
gamedev.net
🔒 Locked

[java] High-resolution timers

Started by Kanzetsu 15 replies 2.9k views
Original Post
Kanzetsu
Kanzetsu
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
a person
a person
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.
buh
buh
Has anyone tried J3DTimer? Any better?
Chaoslab
Chaoslab
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
Kanzetsu
Kanzetsu
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
master_ball
master_ball
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
c_wraith
c_wraith
Wow, we''ve been having a lot of people have trouble realizing that this is a JAVA forum recently...
bslayerw
bslayerw
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.....

Chaoslab
Chaoslab
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
Kanzetsu
Kanzetsu
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
javanerd
javanerd
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
-Pasi Keranen
Kanzetsu
Kanzetsu
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
// Kanzetsu
Chaoslab
Chaoslab
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.

:-)

ujhkfkfk
Kanzetsu
Kanzetsu
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
// Kanzetsu
Chaoslab
Chaoslab
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....

:-)
ujhkfkfk
snowmoon
snowmoon
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

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.