Jump to content
  • Advertisement
Sign in to follow this  

Run game loop while window is dragged?

This topic is 3413 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

I'm trying to get an application to continue rendering and running even while the user is dragging the window. I've read some stuff about it, and the only methods I've heard that might be feasible are to listen to windows messages through hooks and continue running the application that way. To be honest I'm not a big Windows programmer, I'm more of a gameplay programmer (cameras, controls, combat, etc....) so some of the .NET stuff is a bit confusing still. Does anyone have a small demo or snippet of code that demostrates how to continue a normal game loop while a window is being dragged?

Share this post


Link to post
Share on other sites
Advertisement
This is a frequently asked question on the boards. Please use the search function.


Summary of the FAQ:

Many messages and events are intercepted while a window is being resized or dragged. There are some pretty good reasons for that behavior, and you need to know the low-level stuff if before you mess with it.


One of the easiest solutions is just have your application use a timer, with the timer's function to run your main update loop. For a regular Windows application, you should either use a system timer as above or a high frequency waitable event. Sorry, no code snippets, I'll leave that as an exercise for the search engines.

Share this post


Link to post
Share on other sites
I've spent the last 8 hours on search engines. I've found no demos or snippets of this occuring.

I also searched through the forums here and found threads on this same topic, they did not result in any answers, just links to other threads with others asking the same thing.

I agree there are likely good reasons why this occurs, nevertheless the game I'm working on needs to run while the window is moving, just like games like World of Warcraft.

I am willing to learn the low-level reasons why this occurs. It just seems like noone has the complete answer or solution to this, and the MSDN sources give seemingly partial/incomplete explanations and examples that are missing most of the source so you're just left with more questions about what might be missing.

Share this post


Link to post
Share on other sites
Ok, I've got a callback timer calling my main loop, and it works. Thanks for the tip.

Seems to me that this callback timer would get called all the time no matter what, is there anything I should be worried about?

Also, I have to set the timer update time. If I set it really low, like something ridiculous like 1ms, and the system can only run at 5ms, will I only get a call to the timer after 5ms? Furthermore, if I set it to something more reasonable, like 10ms, and the system is fluctuating between 5-20ms, what will happen?

For example (10ms timer):
5ms passes
5ms passes - timer fires
5ms passes
15ms passes - timer fires once?

Share this post


Link to post
Share on other sites
Quote:
Original post by lordikon
If I set it really low, like something ridiculous like 1ms, and the system can only run at 5ms, will I only get a call to the timer after 5ms? Furthermore, if I set it to something more reasonable, like 10ms, and the system is fluctuating between 5-20ms, what will happen?
It all depends on how Windows schedules your app.

You should write your code to be tolerant of skipped frames and bad OS scheduling. You never know when another process will cause yours to stall.

You said you are more focused on the gameplay rather than the main engine, and these are engine details. If your simulation is running behind, you need to run the simulation's update multiple times. Rendering, on the other hand, should be decoupled from the simulation update and be run as frequently as possible. If you want to be able to render more frequently than your timer allows, you will need to do additional processing that your post implied you would rather avoid.

Share this post


Link to post
Share on other sites
A Timer isn't very reliable for that exact reason. When your application loses control of the thread, like in a Sleep(time) operation, what you're telling windows is to return control to you after a MINIMUM of time has passes - if more time passes, that's your loss.

The same is true with a timer. If your application doesn't recieve control in time, you really can't do anything about it. The smart thing to do would be to make all of your updates (well, most of them) time dependent, and when you perform their respective updates, use the change in time since the last update.

Instead of using a timer, why don't you use the typical game loop? Which is something like this:

MSG mMessage;
DWORD dStartTime = GetTickCount();
DWORD dLastTime = dStartTime - 25;
DWORD dUpdateTime = dStartTime;
while (1)
{
if( PeekMessage( &mMessage, 0, 0, 0, PM_REMOVE ) )
{
if( mMessage.message == WM_QUIT )
{
break;
}
TranslateMessage( &mMessage );
DispatchMessage( &mMessage );
}

while( (dStartTime = GetTickCount()) - dLastTime < 25 );
dLastTime = dStartTime;

Update( dLastTime - (dUpdateTime = GetTickCount()) );
RenderFrame();
}

Of course, this is just an example, and it's not very effective. There can be errors of up to a few milliseconds, but atleast your app will still be updating, no matter what.

I use the same logic, but with a very accurate timer that I built to do pretty much the same thing, but with ~4 nanoseconds precision.

Share this post


Link to post
Share on other sites
Within the timer callback I can use GetTickCount to get a very accurate time delta over the course of a frame, that isn't the issue. What I'm wondering is if I will get calls to the program less frequently than if I were not using a timer callback. Either way my timedelta would be accurate, but if I'm getting a lower framerate through a timer callback then I might have to find a better way to do this.

Additionally, I see no reason to use the timer callback except in the condition where a the window title bar is being used to move the window, that is the entire reason I started this endeavor. Would it make sense to register for a callback only once the window title bar is being used to move the window?

Anyway, thanks for the help guys, I'll let you know how it all goes once I get it into the game itself, right now I'm just using a very simple 3D program to test with.

Share this post


Link to post
Share on other sites
frob, the 3rd link was the winner. Works like a charm, and only uses timers when the window is being moved around. Of course, I will do a variant of this and rather than start the timer on WM_ENTERSIZEMOVE, I will do it on WM_SYSCOMMAND and use the wparam (SC_MOVE + HT_CAPTION) which will occur only when the title bar is used to move the window.

But now that I think of it, I still want the game to update during a size change, just not rendering.

Thanks again.

Share this post


Link to post
Share on other sites
Not really. It seems like you're worried about the user doing something that bombards windows with messages, therby preventing you from updating or rendering. Dragging the window is only one of several ways for that to happen. Therefore, the timer callback should either always be utilized, or never. Conceptually, it's just ugly to have to monitor 20 different messages and set your callback function and timer appropriately.

But to answer your question, yes, with the callback function mechanism, you are getting less control than through other methods.

You said "normal game loop" in your first message - is there anything keeping you from going fullscreen and getting rid of that problem?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!