Hi
I've recently moved from directInput to using win32 for input and I've been experienced some hold ups in my program.
The window stops responding for a split second and works again, And the longer the program runs the longer the stops gets.
If the program loses focus and gets it back then the program stops responding completely and has to be terminated.
I'm suspecting it's the game loop and/or use of peekmessage()!
GameLoop
MSG msg;
bool gameRunning = true;
uint lastFrame = frameTimeStamp;
while(gameRunning)
{
lastFrameTimeStamp = frameTimeStamp;
frameTimeStamp = timeGetTime();
if(frameTimeStamp - lastFrame > 17)
{
elapsedTime = (float)(frameTimeStamp - lastFrame) * 0.001f;
input.Update();
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT)
{
gameRunning = false;
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
game.Update();
game.Render();
lastFrame = frameTimeStamp;
}
}
input class:
void HInput::Update()
{
if (!wndHandle)
return;
keyEventCount = 0;
mouseEventCount = 0;
MSG msg;
// shift current keystates to last keystates
memcpy(lastKeyStates, currentKeyStates, sizeof(bool) * INPUT_KEY_COUNT);
// intercept input messages from the window
while (PeekMessage(&msg, wndHandle, WM_KEYFIRST , WM_KEYLAST, PM_REMOVE))
{
TranslateMessage(&msg);
INPUT_KEY key = TranslateWin32Key(msg.wParam);
INPUT_KEY button;
int x = GET_X_LPARAM(msg.lParam);
int y = GET_Y_LPARAM(msg.lParam);
switch(msg.message)
{
case WM_KEYDOWN:
if (key == KEY_UNSUPPORTED)
break;
SET_KEY(key);
AddKeyEvent(key);
break;
case WM_KEYUP:
if (key == KEY_UNSUPPORTED)
break;
CLEAR_KEY(key);
break;
case WM_CHAR:
AddCharEvent(msg.wParam);
break;
}
}
POINT pos;
GetCursorPos(&pos);
ScreenToClient(wndHandle, &pos);
deltaX = pos.x - mouseX;
deltaY = pos.y - mouseY;
mouseX = pos.x;
mouseY = pos.y;
while (PeekMessage(&msg, wndHandle, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE))
{
INPUT_KEY button;
int x = GET_X_LPARAM(msg.lParam);
int y = GET_Y_LPARAM(msg.lParam);
switch(msg.message)
{
case WM_LBUTTONDOWN:
SET_KEY(MOUSE_LMB);
AddMouseEvent(IMET_CLICK, MOUSE_LMB, x, y);
break;
case WM_LBUTTONUP:
CLEAR_KEY(MOUSE_LMB);
AddMouseEvent(IMET_RELEASE, MOUSE_LMB, x, y);
break;
case WM_LBUTTONDBLCLK:
AddMouseEvent(IMET_DOUBLECLICK, MOUSE_LMB, x, y);
break;
case WM_RBUTTONDOWN:
SET_KEY(MOUSE_RMB);
AddMouseEvent(IMET_CLICK, MOUSE_RMB, x, y);
break;
case WM_RBUTTONUP:
CLEAR_KEY(MOUSE_RMB);
AddMouseEvent(IMET_RELEASE, MOUSE_RMB, x, y);
break;
case WM_RBUTTONDBLCLK:
AddMouseEvent(IMET_DOUBLECLICK, MOUSE_RMB, x, y);
break;
case WM_MBUTTONDOWN:
SET_KEY(MOUSE_MMB);
AddMouseEvent(IMET_CLICK, MOUSE_MMB, x, y);
break;
case WM_MBUTTONUP:
CLEAR_KEY(MOUSE_MMB);
AddMouseEvent(IMET_RELEASE, MOUSE_MMB, x, y);
break;
case WM_MBUTTONDBLCLK:
AddMouseEvent(IMET_DOUBLECLICK, MOUSE_MMB, x, y);
break;
case WM_XBUTTONDOWN: // for both x buttons
if (HIWORD(msg.wParam) & XBUTTON1)
button = MOUSE_M4B;
else if (HIWORD(msg.wParam) & XBUTTON2)
button = MOUSE_M5B;
SET_KEY(button);
AddMouseEvent(IMET_CLICK, button, x, y);
break;
case WM_XBUTTONUP:
if (HIWORD(msg.wParam) & XBUTTON1)
button = MOUSE_M4B;
else if (HIWORD(msg.wParam) & XBUTTON2)
button = MOUSE_M5B;
CLEAR_KEY(button);
AddMouseEvent(IMET_RELEASE, button, x, y);
break;
case WM_XBUTTONDBLCLK:
if (HIWORD(msg.wParam) & XBUTTON1)
button = MOUSE_M4B;
else if (HIWORD(msg.wParam) & XBUTTON2)
button = MOUSE_M5B;
AddMouseEvent(IMET_DOUBLECLICK, button, x, y);
break;
}
}
}