How, why?! Very strange bug.

Started by
5 comments, last by Westeria 19 years, 4 months ago
When the game runs, the menu functions perfectly normal. I input the account information to connect to the server, and than hit enter. The screen freezes, wondering whats going on, I move the mouse over the window, and than the game starts working at the FPS of the mouse movement (If I move the mouse around the window frantically, the game runs smoothly). Not just the mouse, but if I press keys on the keyboard, the game updates too... it seems any message that gets sent to the window, updates the game, if no messages are sent, the game freezes at whatever state it's at. How is this even possible?! I've checked and rechecked my WindowProcedure for any calls it might make to update "sAnimate", none at all! Some debug stuff I tried. - If I remove the if(intCurrentTickCount<intLastTickCount) thingy, the game runs slowly, but doesn't require the mouse to be moved around, however, when you move the mouse around, it improoves performance. - The MessageBox thingy doesn't appear untill I send some sort of messgae to the window (Keyboard Input, Mousemovement). I added the MessageBox just to make sure that was the case.
/* Main Window Information */
int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil)
{
    /* Create the absurdly abstract 'Window' (I hate Windows!) */
	MSG messages; WNDCLASSEX wincl;
	hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.hInstance = hThisInstance; wincl.lpszClassName = "WindowsApp"; wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS; wincl.cbSize = sizeof (WNDCLASSEX); wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wincl.hCursor = hCursor;
    wincl.lpszMenuName = NULL; wincl.cbClsExtra = 0; wincl.cbWndExtra = 0; wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    if (!RegisterClassEx (&wincl)) return 0;
    hwnd = CreateWindowEx (0, "WindowsApp","Fleebow RPG", WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,
           CW_USEDEFAULT,CW_USEDEFAULT, (640 + 6), (480 + 32), HWND_DESKTOP, NULL, hThisInstance, NULL);
	WindowDC = GetDC(hwnd);
	hFont = CreateFont(-MulDiv(6, GetDeviceCaps(WindowDC, LOGPIXELSY), 72), 0, 0, 0, 0, FALSE, 0, 0, 0, 0, 0, 0, 0, "Small Fonts");
    ShowWindow (hwnd, nFunsterStil);
	memset(chrUsername,0x0,10);
	memset(chrPassword,0x0,10);
	intLastTick = GetTickCount();
	intCurrentTick = intLastTick;
	
	
	SetCursor(hCursor);

    /* Creature the surfaces for the game. */
	sCreateSurfaces();
	SelectObject(hdcBackBuffer, hFont);
	SetTextColor(hdcBackBuffer, RGB(0,0,0));

	while(1)
	{
		Sleep(10);

		/* Deals with game content. */
		if(intProgramLocation==flag_Level)
		{

			
			Sleep(1);
			sCheckMessages();

			intCurrentTick = GetTickCount();
			if(intCurrentTick>intLastTick+100)
			{

				sSendAsk();

				if(bytRecievedGameState == 1)
				{
					MessageBox(0,"afs","asd",0);
					Sleep(1000);

					sGetPlayerInput();
					sAnimate();
					sRepositionCameras();
					sDrawMap();
					sDrawPanel();
					//sDrawTypedText();
					RedrawWindow(hwnd, 0, 0, 1);
				}
				intLastTick = intCurrentTick;
			}
		}
		/* Run the message loop. It will run until GetMessage() returns 0 */
		GetMessage (&messages, NULL, 0, 0);
		
		/* Deals with window messages. */
		TranslateMessage(&messages);
		DispatchMessage(&messages);

	}
}

Advertisement
Here is a piece of my WindowProcedure: I highly doubt the error resides in it though.
/*  This function is called by the Windows function DispatchMessage()  */LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){		if(message == WM_SETCURSOR){}		else if (message == WM_PAINT)		{			WindowDC = BeginPaint(hwnd, &ps);			StretchBlt(WindowDC,0,0,640,480,hdcBackBuffer,0,0,320,240, SRCCOPY);			EndPaint(hwnd, &ps);		}		else if (message == WM_MOUSEMOVE)		{			intMouseX = LOWORD(lParam);		    intMouseY = HIWORD(lParam);			intMouseX = intMouseX / 2;			intMouseY = intMouseY /2;					if(intProgramLocation == flag_Menu)			{				/* Restore all skins. */				BitBlt(hdcBackBuffer,102,141,20,15,hdcMenu,102,141, SRCCOPY);				BitBlt(hdcBackBuffer,104,159,21,15,hdcMenu,104,159, SRCCOPY);				BitBlt(hdcBackBuffer,195,118,20, 29,hdcMenu,195,118, SRCCOPY);						/* Draw HighLights *//* Help */		if(bolDetectCollision(102,141,20, 15, intMouseX,intMouseY,1,1) == 1) BitBlt(hdcBackBuffer,102,141,20,15,hdcMenuHighlights,102,141, SRCCOPY);/* Exit */		else if(bolDetectCollision(107,159,18, 15, intMouseX,intMouseY,1,1) == 1) BitBlt(hdcBackBuffer,104,159,21,15,hdcMenuHighlights,104,159, SRCCOPY);/* Go? */		else if(bolDetectCollision(195,118,20, 29, intMouseX,intMouseY,1,1) == 1) BitBlt(hdcBackBuffer,195,118,20, 29,hdcMenuHighlights,195,118, SRCCOPY);				RedrawWindow(hwnd,0,0,1);			}		}		/* When this program shuts down, unload all the resources! */        else if (message == WM_DESTROY)		{			sDestroySurfaces();			if (intProgramLocation == flag_Level)			{				sFreeMap();			}            PostQuitMessage (0);		}		/* This prevents the 'Alt' key from bringing up a stupid Windows menu. */		else if (message == WM_SYSCOMMAND)		{		  if (wParam==SC_KEYMENU)		  {			return 1;		  }		  else		  {			  return DefWindowProc (hwnd, message, wParam, lParam);		  }		}		/* For messages that this program doesn't deal with. */		else		{                                return DefWindowProc (hwnd, message, wParam, lParam);		}    return 0;}
GetMessage doesn't return until a message has been posted to the event queue. You probably want to use PeekMessage
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
your GetMessage() call won't return until another message is in the message queue for your app. It basically gives control over to windows until something happens that it needs to respond to. Here's how i'm doing it:

while( TRUE )
{
if( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) )
{
if( !GetMessage(&msg, NULL, 0, 0) )
{
break;
}
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
// let the 'game' class do the work
g_pGame->Go();
}
}
jeffzi: Why go to all that trouble? Might as well just use PM_REMOVE

Oh, and _DO NOT_ do if(message) process else run game because if you get many messages you're game will slow to a crawl. Instead, do something like
for i = 0 to 5   if message      process   else      exit looprun game
so you can still process some messages, but you're not going to stop the game for a second if you suddenly get tons of messages.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
omg, haha! That was it? Just GetMessage() thing not returning?!

Roughly a day of debugging, and turns out, its not neccesarily my own fault.

I HATE WINDOW'S SOO MUCH! [bawling]
(Don't worry, I don't like Linux or Mac either)


Anyways, Thanks jeffzi & Extrarius! [smile]
Erm.. I don't know how to use PeakMessage, lol. :(

Edit: nm jeffzi's code worked perfect. Thanks again! :D

[Edited by - Westeria on November 26, 2004 1:05:16 PM]

This topic is closed to new replies.

Advertisement