Archived

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

iNsAn1tY

Movement in an MFC app...

Recommended Posts

I've come to implementing movement in my MFC map editor, but I've hit something of a problem. I used the WM_KEYDOWN/OnKeyDown message to do it, but the movement is blocky and not at all smooth. Plus, when I press the up arrow for instance, it jerks forward, then stops for a second or two before resuming forward movement. Needless to say, this isn't what I want. In my Win32 programs, I poll the keyboard directly every time the message loop fires, and base movement on time. I can't do this in MFC, so I've come to something of a brick wall. I'm trying to replicate the movement in Hammer editor and GTKradiant, and I've got the mouse working fine, but this movement problem has stumped me a little. Is there any way that I could use the CWinApp::Run() to update every time the MFC message loop runs? Thanks in advance for any replies...

Coding Stuff ->  [ iNsAn1tY Games | DarkVertex | How To Do CSG | Direct3D Vs. OpenGL | Google ]
Fun Stuff    ->  [ Evil T-Shirts | Stick-Based Comedy | You're Already Here | The Best Film Reviews ]
[edited by - iNsAn1tY on August 11, 2003 7:33:26 AM]

Share this post


Link to post
Share on other sites
If you use the standard Windows feedback mechanisms you are restricted by the keyboard repeat rate and keyboard repeat delay (this jerkiness you are experiencing).

Instead, create yourself a game loop (many tutorials on this) and use GetAsyncKeyState instead to find out if the key is pressed at any time - rather than waiting for the message.



"Absorb what is useful, reject what is useless, and add what is specifically your own." - Lee Jun Fan

Share this post


Link to post
Share on other sites
your problem is about that you are drawing only when WM_ANYMESSAGE comes. Try to do NeHe style bool keys[256] for storing state of keys/mouse (faster) and create a timer (-->draw and update on WM_TIMER).
is it that problem or my brain missed it again?

Share this post


Link to post
Share on other sites
That's the way I handle movement in my Win32 apps (using GetAsyncKeyState() or DirectInput), but I don't think it's possible in MFC. MFC is, by it's very nature, event-driven. Perhaps there's some way of creating or hooking into the MFC message pump, like I have to do in VB when I want continuously updating graphics (with the Sub Main()/DoEvents mechanism). I did try putting my window refresh and time code in the CWinApp::OnIdle virtual overridable, but one compile told me that didn't work for mouse movement in a window (I'm forced to use SetCursorPos() in OnMouseMove() messages, which creates a cascade of WM_MOUSEMOVE messages, so CWinApp is never idle).

Thanks for the replies, can anyone else shed some light on this?



Coding Stuff ->  [ iNsAn1tY Games | DarkVertex | How To Do CSG | Direct3D Vs. OpenGL | Google ]
Fun Stuff    ->  [ Evil T-Shirts | Stick-Based Comedy | You're Already Here | The Best Film Reviews ]


[edited by - iNsAn1tY on August 11, 2003 1:08:16 PM]

Share this post


Link to post
Share on other sites
I''m doing some Win32 programming for the past 6 years and i can tell you that to mix non-event driven routines and MFC will break it appart after a while.Normaly the MFC was constructed to ASSURE the even driven system and the future windows''es will be based on it.I suggest not to using it if you''re building a application that requires real-time input/graphics and etc.

"Tonight we strike,there is thunder in the sky,together we''ll fight,some of us will die,but they''ll always remember that we''ve made a stand and many will die by hand!" - ManOwaR

Share this post


Link to post
Share on other sites
quote:
Original post by evillive2
cant you use GetAsyncKeyState inside the WM_KEYDOWN message of the current window? I have never tried this in an MFC program but I use it in my Win32 map builder and it works fine.
Well, then the problem still remains. Movement is still only occuring when WM_MOUSEMOVE messages are recieved, and that isn't often enough to ensure smooth movement.

quote:
Original post by Mihail121
I'm doing some Win32 programming for the past 6 years and i can tell you that to mix non-event driven routines and MFC will break it appart after a while.Normaly the MFC was constructed to ASSURE the even driven system and the future windows'es will be based on it.I suggest not to using it if you're building a application that requires real-time input/graphics and etc.
OK, so say I don't mix event-driven and non-event-driven routines. Have do I achieve fluid movement, relying solely on the WM_MOUSEMOVE messages? And anyway, why shouldn't I mix event-driven and non-event-driven routines? I do it all the time in VB. MFC is based on different architecture, but the basic principle is the same. Every time the message loop fires, certain functions are executed, like time management and frame updating. Then, MFC sends events to be processed, like the DoEvents keyword in VB. Anyway, do you have any idea how to run code every time the message loop updates in MFC? I'll take my chances



Coding Stuff ->  [ iNsAn1tY Games | DarkVertex | How To Do CSG | Direct3D Vs. OpenGL | Google ]
Fun Stuff    ->  [ Evil T-Shirts | Stick-Based Comedy | You're Already Here | The Best Film Reviews ]


[edited by - iNsAn1tY on August 12, 2003 6:26:11 AM]

Share this post


Link to post
Share on other sites
You need to overwrite OnIdle.
refs:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_CWinThread.3a3a.OnIdle.asp

[edited by - Cahaan on August 12, 2003 6:49:40 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Cahaan
You need to overwrite OnIdle.
refs:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_CWinThread.3a3a.OnIdle.asp

[edited by - Cahaan on August 12, 2003 6:49:40 AM]


That won''t work either.Normaly windows prevents the flooding of the message queve and send messages rarely.So if you resieve an idle message there will be a loooooong delay till u resieve another.

"Tonight we strike,there is thunder in the sky,together we''ll fight,some of us will die,but they''ll always remember that we''ve made a stand and many will die by hand!" - ManOwaR

Share this post


Link to post
Share on other sites
I already overrode OnIdle(). It didn't work, for the reasons I stated. And I can't prevent the WM_MOUSEMOVE message cascade. I have found the method I was after, though. It seems that overriding the CWinApp::Run() function is the answer; then timer and window update functions can be called from a modified message loop inside. The method is described on page 2 of this writeup on modelling with DirectX: 3D Shape Creation, Part II.

I've written a custom CWinApp::Run() override, and it seems to be working quite nicely. Thanks for the replies...



Coding Stuff ->  [ iNsAn1tY Games | DarkVertex | How To Do CSG | Direct3D Vs. OpenGL | Google ]
Fun Stuff    ->  [ Evil T-Shirts | Stick-Based Comedy | You're Already Here | The Best Film Reviews ]


[edited by - iNsAn1tY on August 12, 2003 7:31:06 AM]

Share this post


Link to post
Share on other sites