Sign in to follow this  
twoodbur

Cross-platform API

Recommended Posts

twoodbur    168
A group of friends and I just embarked on the perilous journey into the realm of cross-platform game programming. Sadly, most game programming is very window-centric, so there isn't a lot of information on cross-platform development (at least that I've found). We've all been doing professional work for a few years now in the Seattle region, so hopefully this won't seem too much a beginner question :P Although I already suspect the answer, is the QueryPerformanceFrequency/Timer call functional on any system but windows? We're targeting Windows and Linux right now, so if anyone knows of a Linux equivalent (if not cross-platform), that'd be awesome. Thanks all, Tim (FML) *Edit: If you could point us to a good cross-platform development reference, that'd be excellent too. [Edited by - twoodbur on April 23, 2008 10:26:40 PM]

Share this post


Link to post
Share on other sites
kiwibonga    183
For Windows, timeGetTime() from winmm.lib is recommended, as it's the most accurate solution for millisecond accuracy.

QueryPerformanceCounter() is risky, because not all processors have a constant frequency. Games that use this function often get choppy on laptops, because mobile processors have a tendency to throttle their speed to regulate power consumption and temperature.

For Linux, gettimeofday() seems like your best bet.

To make your code cross platform, you'll have to select the proper timer func using a bunch of defines...

Share this post


Link to post
Share on other sites
twoodbur    168
Quote:
To make your code cross platform, you'll have to select the proper timer func using a bunch of defines...


Yeah, that's kind of what I figured. Once you leave the standard...

Quote:

For Windows, timeGetTime() from winmm.lib is recommended, as it's the most accurate solution for millisecond accuracy.

QueryPerformanceCounter() is risky, because not all processors have a constant frequency.


Hmm... I'd always heard that timGetTime()'s resolution was kind of low (like 10ms range). I've never had problems with the Query functions, but I can definately understand variable frequency processors. I've not done much mobile development, so I never really thought about it much.

I appreciate the info. :)

Share this post


Link to post
Share on other sites
mutex    1111
Quote:
Original post by kiwibonga
For Windows, timeGetTime() from winmm.lib is recommended, as it's the most accurate solution for millisecond accuracy.

QueryPerformanceCounter() is risky, because not all processors have a constant frequency. Games that use this function often get choppy on laptops, because mobile processors have a tendency to throttle their speed to regulate power consumption and temperature.
timeGetTime is not the most accurate solution:
Quote:
Windows NT/2000: 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.


However kiwibonga sounds right about QueryPerformanceCounter problems judging from these search results.

Share this post


Link to post
Share on other sites
swiftcoder    18437
The handy thing is that gettimeofday() works across the board for all linux and Macs. The ugly side is that there is no single reliable method of timing under windows. You pretty much have to use QueryPerformanceCounter, and then crosscheck it with a less accurate function to figure out when it blows up.

Share this post


Link to post
Share on other sites
kiwibonga    183
What the MSDN article doesn't say though is that the "5 ms or more" is only applicable to Windows 9x/NT. On Windows XP and Vista, it's pretty much a guarantee that you'll get 1 ms resolution...

So if you want to support Windows 9x, there's two solutions... Either you never require a resolution of less than 5 ms, or you make an additional special case based on the windows version defines and interpolate... Realistically speaking, though, you'll rarely run into situations where you'll need to update things at regular intervals 200 times per second or more.

Share this post


Link to post
Share on other sites
Aressera    2919
Quote:
Original post by kiwibonga
QueryPerformanceCounter() is risky, because not all processors have a constant frequency. Games that use this function often get choppy on laptops, because mobile processors have a tendency to throttle their speed to regulate power consumption and temperature.


Nope, wrong. It works just fine and reliably on all systems as long as you also use QueryPerformanceFrequency() to retrieve the frequency of the counter and use that along with the data from QueryPerformanceCounter to calculate an accurate time. If the accuracy on laptop systems is really important, then you can call both functions every time you query the time, rather than just the performance counter function, in case the frequency changes (not likely).

Share this post


Link to post
Share on other sites
Lode    1003
I'm not sure about the gettimeofday functionality, but generally about multiplatform game development, I'd like to advice the SDL+OpenGL combination: this allows most things needed for making a game and compiles on many platforms.

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by Aressera
Nope, wrong. It works just fine and reliably on all systems as long as you also use QueryPerformanceFrequency() to retrieve the frequency of the counter and use that along with the data from QueryPerformanceCounter to calculate an accurate time. If the accuracy on laptop systems is really important, then you can call both functions every time you query the time, rather than just the performance counter function, in case the frequency changes (not likely).
Yes, but as soon as the frequency changes between two measurements it craps up.
If you use it to measure frame time, you'll have the start time and the end time. If you also know the start and end frequency, you've no idea if or when the frequency changed or how long the frame took.
Add to that the problem that if you have a dual-core system, QPC can give wrong results (My AMD 4600 does this without the processor patch installed, which isn't installed by default or via windows update).

The only way to handle it is to sanity check your times with timeGetTime as swiftcoder said.

Share this post


Link to post
Share on other sites
dmail    116
"Yes, but as soon as the frequency changes between two measurements it craps up."
Why would the frequency change? According to the docs "The frequency cannot change while the system is running." The counter can jump if that is what you mean.

It really depends on how low a level you want to interact with the application environment. You could go low and use gettimeofday or stay at a higher level and use middleware such as SDL etc
Here is a couple of book recommendations:
Programming Linux Games
Write Portable Code
Advanced Programming in the UNIX Environment

[Edited by - dmail on April 25, 2008 8:25:06 AM]

Share this post


Link to post
Share on other sites
hydroo    295
clock_gettime is POSIX.1-2001 at least (which windows doesn't care for, but most of the unix world.

It hardly depends on the linux kernel version how accurate it is and if it altering with processor speed (you have got to test it probably), but lately it should have gotten a really good resolution.

If that's not good you should go for gettimeofday,
which has a very very very good resolution (which never changes). This call is influenced by ntp-updates. So don't ask for the total time too often, and rely on it. For simple mainloop counters there shouldn't be a problem

Share this post


Link to post
Share on other sites
Krohm    5031
Quote:
Original post by Evil Steve
Quote:
Original post by Aressera
Nope, wrong. It works just fine and reliably on all systems as long as you also use QueryPerformanceFrequency() to retrieve the frequency of the counter and use that along with the data from QueryPerformanceCounter to calculate an accurate time. If the accuracy on laptop systems is really important, then you can call both functions every time you query the time, rather than just the performance counter function, in case the frequency changes (not likely).
Yes, but as soon as the frequency changes between two measurements it craps up.
If you use it to measure frame time, you'll have the start time and the end time. If you also know the start and end frequency, you've no idea if or when the frequency changed or how long the frame took.
Add to that the problem that if you have a dual-core system, QPC can give wrong results (My AMD 4600 does this without the processor patch installed, which isn't installed by default or via windows update).
Isn't the thread affinity mask working? I read somewhere it should suffice - it seemed to work on the dual cores I've tried out.

BTW, I still wonder how to get available mem in linux (for suballocation purposes) last time i checked it, the only available func was a deprecated syscall. (?)
Could someone shed some light for me as well?

Share this post


Link to post
Share on other sites
hydroo    295
You might want to take a look at QT.
You are forced to GPL your code, when releasing.
But if you stick to QTs functioniality you are garanteed to be cross platform on all listed platforms (mac, windows, linux, and some more).
It helps a great deal, and it's style is consistent and nice.
QT is very powerful especially the GUI-part, but apart from that there is an own implementation of stl-functionality, and much more. Please have a look.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this