Sign in to follow this  
Haytil

Weird game behavior drops frame rate

Recommended Posts

Hi, My game (a pong clone) is behaving oddly, and I can't figure out why. Sometimes, while I hold down a key (whether this key controls anything in the game or not), the frame rate drops by half (from 60 fps to 30 fps - a noticeable drop, resulting in choppy movement of the ball). If I then hold another key, sometimes the frame rate jumps back to 60. If I let go of all the keys, the frame rate is steady at 60. The weird thing is that this happens whether or not the key being held is part of the game or not (so it shouldn't be necessarily be doing more calculations or anything to slow the game down). I'm using DirectInput8, on Windows XP. Does anyone have any ideas as to why this might be happening? It's frustrating, as the ball no longer moves smoothly (nor do any of the paddles) when this happens. -Gauvir_Mucca (Note: As I write this, I suspect it might be a DirectInput thing, though I'm not sure. If no one has any ideas, I'll ask in the DirectX forum - but for all I know, it's a Windows thign in general).

Share this post


Link to post
Share on other sites
Further data:

My post above was relating figures to windowed mode. When I try to run the program in fullscreen mode, the standard fps is about 900. I still have the slowdown when holding down keys sometimes, though. When this slowdown occurs, as long as the key is held down, the frame rate continuously shifts between 30-40 fps and 800-900 fps.

Share this post


Link to post
Share on other sites
I think the thing you need to be looking into is what code is being run when you hold the key down?

If for some reason you find that some intensive code is run to process that key, then maybe you should manually throttle that code to run at 30 or 60 fps

Share this post


Link to post
Share on other sites
Sounds like something excessive you're doing in your windows event loop, for example, whenever there is a key down event. I'd take a look there, if you have such a thing in your code.

Share this post


Link to post
Share on other sites
This is most likely not a DirectInput problem, but a problem with your code. If your input handling code is not very big then try showing out what you do when a key is pressed, and how you detect a key press. Many games using DirectInput can achieve higher than 60 FPS when a key is pressed, and they have much more processing to do than Pong.

Share this post


Link to post
Share on other sites
I don't handle keydown messages or anything related to the keyboard in my windows message WindowProc() function. I only handle WM_CREATE, WM_PAINT, WM_DESTROY, and WM_ACTIVATE messages.

However, any messages that I don't handle, I let Windows deal with, by passing the message on to the DefWindowProc() function. Could it be that holding down a key fires a message every frame, which clogs up the default DefWindowProc() function? (I didn't think a message was fired every frame when a key was being held down - only once, when it's initially pressed).

Handling messages once every 10 frames seems to take care of the issue. However, I want to be sure that my explanation for this behavior is a plausible one, so that I know this problem has been taken care of, and not just swept under the rug by changing an irrelevant section of code and fixing the problem by chance.

-Gauvir_Mucca

Share this post


Link to post
Share on other sites
This is my relevant code:


WinMain(...)
{
// Stuff
// ...

// main event loop
while (1)
{
// Handle messages once every 10 frames
if (Timer_System.m_Ticks % 10 == 0)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// test if this is a quit message
if (msg.message == WM_QUIT)
{
break;
}

// translate any accelerate keys
TranslateMessage(&msg);

// send the message to the window proc
DispatchMessage(&msg);
}
}

if (main_game_loop() == false)
{
// main_game_loop() returns false when the game is
// ready to quit

PostMessage(main_window_handle, WM_QUIT, 0, 0);
}
}

// Stuff
...
}


LRESULT CALLBACK WindowProc(HWND hwnd,UINT msg,
WPARAM wparam,
LPARAM lparam)
{
PAINTSTRUCT ps; // used in WM_PAINT
HDC hdc; // handle to a device context

// check the message
switch(msg)
{
case WM_CREATE:
{
// do initialization stuff here
return(0);
} break;

case WM_PAINT:
{
// start painting
hdc = BeginPaint(hwnd,&ps);

// end painting
EndPaint(hwnd,&ps);
return(0);
} break;

case WM_DESTROY:
{
// kill the application
PostQuitMessage(0);
return(0);
} break;

case WM_ACTIVATE:
{
// Do initialization stuff

// Don't return, as we also want Windows to handle any activation
// messages
} break;

default:break;

} // end switch

// process any messages that we didn't take care of
return (DefWindowProc(hwnd, msg, wparam, lparam));

}



Share this post


Link to post
Share on other sites
You might want to process all available messages every frame. Make a while loop with PeekMessage and use PM_NOREMOVE:


while ( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
{
GetMessage( &msg, NULL, 0, 0 );
TranslateMessage( &msg );
DispatchMessage( &msg );
}


Usually there won't be that many messages but if there are you're processing them at once.

I'd guess that in the state right now dragging the window will work very sluggish if at all.

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