Best way to Set up game input (windows C++)

Started by
7 comments, last by vs322 16 years, 6 months ago
Hi, dealing with a problem of style atm, and I was wondering how many of you go about it. In the past I have done something like this for my main windows loop:

	while( msg.message!=WM_QUIT )
	{
		if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
			eEngine->PassMsg(msg.message,msg.wParam,msg.lParam); // my own input engine object
		}
		else
		{
			ltTimer.LoopStart();
			pUE->Update(gfLoopTime); // game logic and rendering
			gfLoopTime=ltTimer.GetLoopLength();
		}
		ltTimer.LoopEnd();
	}

my eEngine object then has a switch / case set up similarly to WndProc. My question is do most people do something similar to this, OR do they somehow pass a handle to the WndProc and have the game input as part of it? Hope that was clear.OR are people getting input in some entirely different way? In addition how do people usually deal with distributing user messages to different parts of there program / game. In the past I have used deep-pointer passing and a telegram-like system... which is not ideal imo. any help would be great. -v
Advertisement
I prefer got my input from the MsgProc callback function, just like this:

//Keyboard messages
case WM_KEYDOWN:
if(wParam == VK_ESCAPE){
PostQuitMessage(0);
break;
}
pKeyState[wParam] = true;
pVortez3DEngine->OnKeyDown(wParam);
break;
case WM_KEYUP:
pKeyState[wParam] = false;
pVortez3DEngine->OnKeyUp(wParam);
break;


pKeyState is simply an array of bool that is used to check multiple key at once.
Then i process my keystroke in there respective function. Hope that help.
That way your PassMsg function will not get most messages.

A lot of messages are indirectly creating during the call of TranslateMsg (WM_CHARs for example). You'll never see them outside the WndProc.

It depends though how much you need to handle via messages. You can get away with it if you don't need any keyboard input for example.

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

I also do things the way Vortez does, and I track WM_CHAR messages too for GUI style text input. It also means that your input system doesn't need to know or care about other window messages.
TY Vortez, one folow-up question though: Is pKeyState, or a pointer to it, passed around to all objects that need it? And would you put that code inside the WndProc, as the only way I have gotten my own variables into the WndProc is with globals... And if it is a plain vanilla array what is the max wParam value?

Seems that this method could be work very nicely; rather than having a massive case statement for all my objects just have them have a few if statements for the values that they are looking for - Thanks.

As to what Endurion said; I have not seen the behavior that you are talking about, I was able to use WM_CHAR for typing/text input successfully.I believe this is because my PassMsg function is after the TranslateMessage call, perhaps?

-v
(accidentally presses ctrl-shift-b rather than click the reply button)
..just read-up on TranslateMessage... it does not change the messages...so now I have no idea why WM_CHAR worked..
You're not using WM_CHAR messages at all in that code? TranslateMessage generates WM_CHAR messages, it doesn't change another message into a WM_CHAR message.

As for getting objects into your window procedure, there's all sorts of ways to do that. Google for using a WndProc as a member function for various methods.

If you're only dealing with ASCII, you can assume wParam won't exceed 255 (Well, make sure you clamp it).
My array are declared like that:

bool m_KeyState[256];
bool m_MouseBtnState[3];

And i prefer make them the most accessible possible,
but it's a matter of choice...

You should use this method because that is the purpose of having a WndProc function in a win32 program. It is done just for that...

PS: when the program start, use ZeroMemory(&m_KeyState[0], 256);
to initialize it.

EDIT: Oh, and yeah, pKeyState is a pointer to m_KeyState,
so i can use it wherever i want.
Thanks Steve and Vortez, I think that the 2 bool array method is exataly what I am going to change my input system to.

I was looking back over my code and I now realize that I was checking WM_KEYUP as well as WM_CHAR, which is why it worked before...glad to be getting away from my current mess of case statements.

thanks again.

This topic is closed to new replies.

Advertisement