Sign in to follow this  

Help with Windows game loop...

This topic is 3673 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everyone! I got this loop from some tutorial:
	do
	{
		/* Peek messages */
		if (PeekMessage(&msg, NULL, 0, 0, PM_NOYIELD | PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}

		/* Process logic */
		processLogic();

		/* Render screen */
		renderScreen();
	}
	while (msg.message != WM_QUIT);

It doesn't seem to ever get to processLogic; it gets stuck in PeekMessage, even though I specified PM_NOYIELD... How do you guys implement game loops with pure Windows API? Thanks! (Bonus question for an extra cookie: How do you do timers in Win16?)

Share this post


Link to post
Share on other sites
I always use something like:

if(Initialize())
{
while(true)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT){ break; }
TranslateMessage(&msg);
DispatchMessage(&msg);
}

ProcessLogic();

RenderScreen();
}

Shutdown();
}





For timing you could use GetTickCount() or QueryPerformanceCounter().

Share this post


Link to post
Share on other sites
My way of doing it in my 2d engine, MsgLoop is a function and message is passed to it

int MsgLoop(UINT message, WPARAM wParam, LPARAM lParam) {
while(message != WM_QUIT) {
while(PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) {
//process all messages so a que wont build up
TranslateMessage(&msg);
DispatchMessage(&msg);
}

ProcessLogic();
RenderScreen();
}
return message.wParam;
}


Could contain some erros, im at school and wrote it out of my head, I'll post my loop again when I'm home

you could add a way to get the time used to go through the entire loop and add this variable to the ProcessLogic() function, so you won't call ProcessLogic 250 times when your refreshrate is 60.

Share this post


Link to post
Share on other sites
Those two loops you guys showed... Here's the problem with them; they work correctly - but RenderScreen() doesn't do anything. As in, it gets called, I put MessageBoxes before and after the parts that do the drawing and they pop up on every frame, yet nothing gets drawn?

I put a call to that same function under the WM_PAINT message handler and guess what, it draws there... Why? Do you know? Maybe it only allows me to draw on WM_PAINT? Why would that be?

Thanks y'all!

P.S: MadMax1992, there doesn't seem a way to do the time thing under Win16... I'll wait for that book I bought to see if it says anything about that.

[edit]
Okay, here's the problem:
"An application should not call BeginPaint except in response to a WM_PAINT message."

No wonder... So how am I supposed to do RenderScreen in my main loop? :/
Thanks!
[/edit]

[edit2]
Okay, I'm using timers now and it works like a charm... But I see no one using that method (SetTimer, WM_TIMER, etc.), is there a drawback to using it?
[/edit2]

[Edited by - Leo28C on November 21, 2007 3:28:35 PM]

Share this post


Link to post
Share on other sites
To be honest, I haven't got an idea what win16 is. I'm back from school, so here's my messageloop:

int d3dApp::MsgLoop()
{
QueryPerformanceFrequency(&timerFreq);

MSG msg;
ZeroMemory(&msg, sizeof(msg));

//message loop
while (msg.message != WM_QUIT)
{
while (PeekMessage(&msg,0,0,0,PM_REMOVE)) {
//translate dispatch message
TranslateMessage(&msg);
DispatchMessage(&msg);
}

QueryPerformanceCounter(&timeStart);
lastElaspedFrame = lastElaspedFrame + anim_rate;

processLogic(&lastElaspedFrame, &frameDuration);
renderScreen();

anim_rate = (((float)timeEnd.QuadPart - (float)timeStart.QuadPart) / timerFreq.QuadPart);
}

CleanUpDirect3D();

return (int) msg.wParam;
}


//processlogic should look something like this
void processLogic(float lastElaspedFrame, float frameDuration)
{
if (lastElaspedFrame < frameDuration)
{
return;
}

lastElaspedFrame = 0;

//do stuff with your graphics
}


Im not sure if the timer-technique you use has any drawbacks. I wonder what the problem is with your processlogic function, could you perhaps post the entire function here so we can have a look at it?

Share this post


Link to post
Share on other sites
Quote:
Original post by Leo28C
[edit2]
Okay, I'm using timers now and it works like a charm... But I see no one using that method (SetTimer, WM_TIMER, etc.), is there a drawback to using it?
[/edit2]


I think those examples you are seeing probably aren't using GDI to do the display. Using OGL or D3D, you just redraw each frame instead of responding to display events.

If you really wanted to, you could use invalidate in your game loop to trigger a display event to handle. I'm not clear that this would be better than using timers though.

Share this post


Link to post
Share on other sites

This topic is 3673 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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