Getting more precise timing and telling if a key is pressed - how?

G

Guest

I've had two issues plaguing me for 4 months now and I haven't gotten
anywhere. I'm into making 2D games and these things are essential to games.
These are my issues:

1. I need timing precise to about 4 milliseconds at most. Currently, I've
been using the clock() function, but it's only precise to 1/64 second (or
about 15.6 milliseconds). For those running their monitor at 60 Hz, this
isn't much of a problem, but for those running above 64 Hz (70 and 75 are
common), this would mean either processing two frames in one causing jerky
motions, or running at half the refresh rate. By using something with 4
milliseconds precision, up to 250 Hz works and the highest I've seen is 160
Hz. There's another one with 1/4 microsecond precision, but that's not
supported by every system and it's far more than I need. How do I get the 4
millisecond timing I'm after?
2. Lastly, how do I tell if a key is pressed or not. That is, if I press
the right arrow key, I expect the character to move right. I know how to
program the movement (and practically everything else in a 2D game like an
RPG), but I don't know how to tell if a key is pressed or not.

These are my requirements:
1. It must work with systems as old as Windows 95.
2. It must not use DirectX. If it is required for either of these, then
something that works with Windows 95. I strongly prefer going without
DirectX though.

I'm using Visual C++ 2005 Express if that helps.
 
N

Nathan Mates

1. I need timing precise to about 4 milliseconds at most.

Use QueryPerformanceFrequency/QueryPerformanceCounter. See
http://msdn.microsoft.com/library/d...ce/timerfunctions/queryperformancecounter.asp
for more info. Works all the way back to Win95.
2. Lastly, how do I tell if a key is pressed or not. That is, if I press
the right arrow key, I expect the character to move right. I know how to
program the movement (and practically everything else in a 2D game like an
RPG), but I don't know how to tell if a key is pressed or not.

Tried GetAsyncKeyState()? See
http://msdn.microsoft.com/library/d...e/keyboardinputfunctions/getasynckeystate.asp

These are my requirements:
1. It must work with systems as old as Windows 95.

Do you have a *really* good reason for doing so, other than you
can't get some grandparent to upgrade? When MS doesn't support Win98,
Win95 support is asking for pain.
2. It must not use DirectX. If it is required for either of these, then
something that works with Windows 95. I strongly prefer going without
DirectX though.

Read the links I posted above. They document what they need in
terms of OS, etc. I do feel that using DirectInput, even an early
version, is probably going to be easier and more reliable than using
GetAsyncKeyState().

Nathan Mates
 
G

Guest

That's the same timer thing I mentioned in the first. What bothers me about
using it is the "return value" section. Hardware supporting it? How common
are these high-res timers?

As to the GetAsyncKeyState thing, I've looked into it before, but didn't
know what values I needed to use for the "vKey" thing. I have the solution
for that and this is exactly what I was after for that.

All I need now are more details about the timers and how common they are (my
system supports them, but that doesn't mean all systems do). One last thing
I thought of, but not required - how do you switch to fullscreen mode and
back to windowed mode?

The reason for targeting Windows 95 is due to the high simplicity of my
early intended games/programs. 2D at 640x480 renders very fast. From tests
using another tool, it hardly used any of the CPU to display the graphics, so
little that even after an hour at running the poorly designed code (due to
limits with the tool), only 7 seconds or so of the CPU time was used and
that's with a rather outdated 3 GHz Pentium 4 processor. Windows 95 systems
would likely have a 200 MHz processor or so and the game would still not be
"hard" on it. With C, I can get a much better design so it could run even
faster.
 
G

Guest

I don't know how to edit my previous message, but I thought of a potential
problem with the high-res timer. If I don't use sleep(), the CPU usage would
go to 100%. Sleep is only precise to 1/64 second. What other alternative
can I use for this?
 
N

Nathan Mates

That's the same timer thing I mentioned in the first. What bothers
me about using it is the "return value" section. Hardware
supporting it? How common are these high-res timers?

For QueryPerformanceCounter(), the high-res timers are usually from
the RDTSC assembly instruction. Intel was the first one to add them,
and they did so in the Pentium 1 (the original, which also had that
FDIV) bug. Non-Intel brands added this instruction eventually; see
http://en.wikipedia.org/wiki/RDTSC for more info. I'd guess that
anything made in the last 5 years probably supports it fine. But,
you're trying to target OSs nearly 12 years old, which means it can
probably run on HW 14+ years old.

If you read the docs on QPC(), MS does the right thing and falls
back to less-precise timers if RDTSC instruction isn't present. Which
means you can ship your title, and recommend that people to get with
the 21st century if it doesn't work.
One last thing I thought of, but not required - how do you switch to
fullscreen mode and back to windowed mode?

Give up your foolish tilting at windmills and use DirectX,
already. That's what it's built to do. DX3 did this fine. You don't
have do use DX9.
The reason for targeting Windows 95 is due to the high simplicity of
my early intended games/programs.

You're mistaking simplicity of your system requirements with
simplicity of OS. How many people *realistically* are out there with
Win95? And able to download/acquire/run your code on such a system?
Just because you can do something doesn't mean you *should* do
that. Make your game run w/ very low system requirements-- that's
good. Making yourself jump thru a lot more hoops to support a handful
of users -- that's pointless. Just because you "could" mow your lawn
with a elementary-school safety scissors doesn't mean you
should. Newer OSs and APIs like DirectX give you the power tools to
achieve your ends much faster.

Nathan Mates
 
N

Nathan Mates

I don't know how to edit my previous message, but I thought of a
potential problem with the high-res timer. If I don't use sleep(),
the CPU usage would go to 100%. Sleep is only precise to 1/64
second. What other alternative can I use for this?

You really seem to be obsessed over things that are contradictory
and meaningless. First, you're obsessed about running on obsolete and
unsupported OSs like Win95, simply because you can. You want good
timers, but you're worried about pegging the CPU at 100%. Well, if
you're going to get any sort of smooth animation, etc, you *DO* want
to peg the CPU. Please, go to websites like http://www.gamedev.net/ or
http://www.flipcode.com/ where people have talked over how to program
games for Windows.

As to keeping your game running, basically, you should do something
like what I posted years ago, see
http://groups.google.com/group/comp...5bcd731aea5?lnk=st&q=&rnum=1#c01c85bcd731aea5

void GameMainLoop(void)
{
// Local varbs snipped.

while(KeepRunning)
{
// Process all windows messages
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
return; // We're done.
TranslateMessage(&msg);
DispatchMessage(&msg);
}

// Functions in the rest of your code to do one frame's worth of work.
// You may have slightly different names.
BeginFrame();
UpdateEverything();
DrawEverything();
EndFrame();
}

}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top