Weird game behavior drops frame rate

Started by
7 comments, last by Endurion 17 years, 11 months ago
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).
Advertisement
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.
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
Joel Martinez
http://codecube.net
[twitter]joelmartinez[/twitter]
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.
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.
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
How does your message loop look like? Are you only processing one message per game frame or all messages from the queue?

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

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));}
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.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

This topic is closed to new replies.

Advertisement