Archived

This topic is now archived and is closed to further replies.

clabinsky

Main Loop Variations

Recommended Posts

Hi there. I have been reading through books and articles on this forum and I see an inconsistency when describing the game main loop. There are several descriptions and most of them will work, but I am curious on your take on this. For example, two similar versions are
  
while()
{
  IF THERE IS A MESSAGE
  {
    HANDLE THE MESSAGE
  }
  ELSE
  {
    DO CALCULATIONS AND OTHER STUFF
    RENDER ONE FRAME OF THE GAME
  }
}

while()
{
  IF THERE IS A MESSAGE
  {
    HANDLE THE MESSAGE
  }
 
  DO CALCULATIONS AND OTHER STUFF
  RENDER ONE FRAME OF THE GAME
 }
  
Now, the only difference between these two is the else statement. Does that really matter? Well, here is my take on this. I have no idea on how fast windows generates messages when for example moving the mouse. In the first case, all messages are handled before rendering a frame. In the second one, one message is handled for every frame rendered. Just by looking at the structure, I would think that the first solution might create a problem of changing the state of the game in one message while reversing this change in the next. If no rendering is made between the messages, things might happen behind the scene while the user gets no feedback to know of this. Using the second option might fill up the queue of messages but each change in input will be reflected on the screen. If the rendering process does not take too long this should be fine and I would suggest the second approach. See, I am thinking of using the second version having a mouse and keyboard object. For each event the appropriate object will be set which will take no time at all. Then, the current state will be handled and the input objects will be checked to see if they affect the state. Depending on the result, the rendering might be affected. Before I start implementing a new solution in my game I feel I need to know what your take is on this. So go ahead..

Share this post


Link to post
Share on other sites
Actually, I do

  
while(true)
{
while(there are events)
process events;

do the game stuff
}


This is my favorite, and I don''t see any problems with it (except that new messages will appear so fast that the main stuff isn''t executed, but that is unlikely.


"Reality is merely an illusion, albeit a very persistent one." (Albert Einstein)
My Homepage

Share this post


Link to post
Share on other sites
well, if you only deal with one message at a time and the user is constantly moving the mouse (as with many games) then the responsiveness of the game will drop remarkedly. say the user moves the mouse really quickly (spins around in an FPS) and windows suddenly throws 10 MW_MOUSEMOVE messages at you. If you only process them one pre frame then the game will take 10 frames to catch up with something that the user did instantly (well, close enough to anyway). While I can't really think of any other messages that would be sent that quicly (WM_TIMER perhaps, depending on the time interval and if your using WindowProc to handle it and not a callback) this alone would be a major problem.

[edit]
Actually, you'd have problems even if your WindowProc wasn't handling the timers, since I'd imagine that the windows standard WindowProc that you have to call at the end would dispatch to the callback so you would still only be doing one timer tick each frame anyway.
[/edit]


Joanus D'Mentia
---------------
The three phases of me...
The twit, the tool and the lonely fool.

[edited by - joanusdmentia on December 26, 2002 3:43:21 PM]

Share this post


Link to post
Share on other sites
Got ya, randomZ

joanusdmentia, this is what I was afraid of. In my case it is only the WM_MOUSEMOVE that causes the problem.

The interesting part is then: when the mouse moves over hotspots which should be highlighted, the won''t be, if the movement is fast. If you''re painting on the screen there might be spots which will be missed. I know, I know, can''g get everything but it would be intersesting to know anyone using the second method.

I think the problem of a clogged queue seems worse than missing spots here and there.


Share this post


Link to post
Share on other sites
quote:
Original post by clabinsky
Got ya, randomZ

when the mouse moves over hotspots which should be highlighted, the won''t be, if the movement is fast. If you''re painting on the screen there might be spots which will be missed.


Hmm. Right. Well, I''m kinda new to this
Well, you have "Missing Spots" on one hand, and "Low Responsiveness" on the other. A compromise would probably be, in the painter example, to make the "Painting" part of the event handling. But in most games, this is impossible, since you need to render a frame at a time.
I still prefer my method, since, if a user moves the mouse really fast over a hotspot, he probably isn''t interested in it anyways. I think the responsiveness thing is more important.
And as I said, if it is important to not miss a spot, make "noticing that (e.g.)the mouse was there" (I''m lacking a better term) part of the event handling.

Probably I''m also wrong with this, I''m not too experienced with this.


"Reality is merely an illusion, albeit a very persistent one." (Albert Einstein)
My Homepage

Share this post


Link to post
Share on other sites
quote:
A compromise would probably be, in the painter example, to make the "Painting" part of the event handling. But in most games, this is impossible, since you need to render a frame at a time.


Might be an idea. However, it seems to create a very special case which would slow down the major part of the game to accomplish one task. As you imply, I''d avoid it.

quote:
I still prefer my method, since, if a user moves the mouse really fast over a hotspot, he probably isn''t interested in it anyways.



Agree. In most cases I would not care because of what you say. Intersting to this point is if you move your mouse fast, back and forth, over a button with a tooltip, the tooltip wont display. Might not be a good comparison but anyway.

Then since you do it that way, do you store the change to be implemented when the other stuff executes or do you call game functions to change state of objects in each event?

Share this post


Link to post
Share on other sites
I use the first method. And as for the debate of "hotspots" : did you realy experienced this? I mean let''s think for a second:
an average game is runing at lets say 30 FPS , right? so in a single second the screen is refreshed 30 times. And I didn''t made so far a game that would run slower than 65 FPS (but I only made 2 games so far ) . But let''s stick to the more general 30 FPS . So do you have any idea how fast must you move the mouse in order that the hotspot not to be acctivated meaning that the hotspot would have to be acctivated and deacctivated ( via messages ) in les than 33.33333 ms ??? If this would hapen then as RandomZ said the user is probably not interested in that spot.

Share this post


Link to post
Share on other sites
MAD_Mask, you are probably right.

I am going to test it later in January.

One thing which would be of interest to know is if you guys are calling update functions from the event case or instead save the input change in an object or something. Then adjust the frame based on the last saved state of the mouse or keyboard?

I save the changes in mouse coordinates and keyboard in a separate object which can be queried by other objects.

How do you do that?

Share this post


Link to post
Share on other sites
quote:
One thing which would be of interest to know is if you guys are calling update functions from the event case or instead save the input change in an object or something. Then adjust the frame based on the last saved state of the mouse or keyboard?

That''s what I do. In my loop the else statement remains. In the case when say for a FPS the player whips around quickly, a bunch of WM_MOUSEMOVE will be received by the ''mouse'' object and summed up. Then when there are no messages to process and the game code gets to run, it gets that ''summed up'' movement from the mouse object as if it were one WM_MOUSEMOVE message.
This kills the "Low Responsiveness" problem, but the "Missing spots" problem still remains. However I don''t consider that a problem: can you, the human, tell the difference between say 6 individual mousemoves:
(1,2) (2,1) (1,1) (-2,3) (0,4) (-1,1)
and one that adds to the sum of those six:
(1,12)
over a time of say 0.15 seconds? I can''t.

----------
http://www.zppz.com <- game dev stuff

Share this post


Link to post
Share on other sites
quote:
can you, the human, tell the difference between say 6 individual mousemoves:
(1,2) (2,1) (1,1) (-2,3) (0,4) (-1,1)
and one that adds to the sum of those six:
(1,12)
over a time of say 0.15 seconds? I can''t.

I can''t and you''re right. I am using the first alternative now and will be testing i january.

I guess the key point here is, if one uses the WM messages, to process each message as fast as possible. One way of doing that would be to just simply save each message and process it or them just before the frame is rendered.

Thanks!

Share this post


Link to post
Share on other sites
Is there anyway to turn off the mouse messages that are bweing sent to the app. Because then it wont be a problem. Just turn the mouse messages off. and you can use something like directinput once per frame to handle all the mouse input.

[Edit]: Just remembered that I read somewhere that the mouse was handled on a different thread by windows. Is this correct? and if it is then I dont see a problem here with mouse moves.


::: Al:::
[Triple Buffer V2.0] - Resource leak imminent. Memory status: Fragile

[edited by - IFooBar on December 28, 2002 2:00:49 AM]

Share this post


Link to post
Share on other sites
quote:
Is there anyway to turn off the mouse messages

I did have the same thought but I did not investigate it further, assuming its not possible.

I''ll stick with saving the messages and using the last processed to update the frame.

Share this post


Link to post
Share on other sites
one other way of having the windows msgpump is to use it as follows (and specified in game programming gems #2, and here on gamedev as an article). This is to have a separate thread to handle the windows messages and a separate thread for the actual game code.
I use this and have no probs with it. It means coding in a different style, sometimes harder, sometimes easier. Not sure of any FPS gain.

Aface

Share this post


Link to post
Share on other sites