Jump to content
  • Advertisement
Sign in to follow this  
Alundra

Keyboard/Mouse input missing because of low FPS

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

Hi,

I actually have an action manager which process events using poll event from SDL2.

The problem is when you have low FPS you miss events and gives issues (keyboard, mouse,...).

What is the best way to handle event to avoid issues ?

Thanks

Share this post


Link to post
Share on other sites
Advertisement

You shouldn't miss those events? There may be a delay but you missing events shouldnt happen?
?

Would you post you event polling code please?

Edited by imoogiBG

Share this post


Link to post
Share on other sites

I missed one information you right, it only happens on action in the mode "Press Once" (example : character punch on the mouse left click).

It's surely because of mouse down + mouse up events ? On this case the state of the action is then not actionned and the game code will never do the action.

I use 3 modes "Hold", "Press Once" and "Release Once", surely the "Release Once" mode has the same issue.

Edited by Alundra

Share this post


Link to post
Share on other sites
Maybe you clear the event queue somewhere?
Maybe you don't loop until the queue is empty (and discard the event at some other place?)

But yeah, as imoogiBG said, we need to see the polling code for less random guesses about what may be wrong.

Share this post


Link to post
Share on other sites

The poll event while loop :

SDL_Event Event;
while( SDL_PollEvent( &Event ) )
{
  switch( Event.type )
  {
    ...
    ...
    default: ActionManager.ProcessEvent( Event );
  }
}

Process event does simply a switch to handle input events, here the two cases for the mouse :

case SDL_MOUSEBUTTONDOWN :
{
  // Each action.
  for( UInt32 i = 0; i < m_ActionArray.GetSize(); ++i )
  {
    // Each input.
    for( UInt32 k = 0; k < m_ActionArray[ i ].InputArray.GetSize(); ++k )
    {
      // Get the input.
      const TInput& Input = m_ActionArray[ i ].InputArray[ k ];

      // Check if the input type is not mouse.
      if( Input.InputType != IT_MOUSE )
        continue;

      // Check if the mouse button is not the same.
      if( Input.MouseButton != Event.button.button )
        continue;

      // Check if the mod state is not the same only if the mod is not none.
      if( ( Input.KeyMod != KMOD_NONE ) && ( SDL_GetModState() != Input.KeyMod ) )
        continue;

      // Change the action activated state.
      m_ActionActivatedArray[ i ] = m_ActionArray[ i ].ActionType != AT_RELEASE_ONCE;
    }
  }

  // Stop here.
  break;
}

case SDL_MOUSEBUTTONUP :
{
  // Each action.
  for( UInt32 i = 0; i < m_ActionArray.GetSize(); ++i )
  {
    // Each input.
    for( UInt32 k = 0; k < m_ActionArray[ i ].InputArray.GetSize(); ++k )
    {
      // Get the input.
      const TInput& Input = m_ActionArray[ i ].InputArray[ k ];

      // Check if the input type is not mouse.
      if( Input.InputType != IT_MOUSE )
        continue;

      // Check if the mouse button is not the same.
      if( Input.MouseButton != Event.button.button )
        continue;

      // Check if the mod state is not the same only if the action type is not hold and if the mod is not none.
      if( ( m_ActionArray[ i ].ActionType != AT_HOLD ) && ( Input.KeyMod != KMOD_NONE ) && ( SDL_GetModState() != Input.KeyMod ) )
        continue;

      // Change the action activated state.
      m_ActionActivatedArray[ i ] = m_ActionArray[ i ].ActionType == AT_RELEASE_ONCE;
    }
  }

  // Stop here.
  break;
}
Edited by Alundra

Share this post


Link to post
Share on other sites
Hmm, still too many things that can go wrong. Simplest way to find the problem is debug it, I think.
If you use a normal debugger, set a break-point at the button-up handler, triggger it, and then see what condition fails.
If you use printf-style debugging, add a few printf-lines between the ifs, compile, and trigger it, to see which printf lines get reached.


BTW: Why does your comment repeat exactly what the code says? In this way, you write every line of code twice, once as code and once as text.
The usual approach is to read the code to tell you what it does, and read the comment to you *why* that code has to be done here.

Share this post


Link to post
Share on other sites

You have to be careful with functions like SDL_GetModState(), this gets the state at the time you call it, which can be different than when the event is consumed. Do you do any other non-event related input handling, e.g. calling SDL_GetKeyboardState()?

Share this post


Link to post
Share on other sites

I have logged in the two mouse case and before activation checking called in game code :

[2016/01/02-21:07:33] Try Fire Action
[2016/01/02-21:07:33] Try Fire Action
[2016/01/02-21:07:33] Try Fire Action
[2016/01/02-21:07:33] SDL_MOUSEBUTTONDOWN
[2016/01/02-21:07:33] SDL_MOUSEBUTTONUP
[2016/01/02-21:07:33] Try Fire Action
[2016/01/02-21:07:33] Try Fire Action
[2016/01/02-21:07:33] Try Fire Action

It's a case when the fire action is not called, and the logger shows the problem, down and up is generated the same frame.

 

Do you do any other non-event related input handling, e.g. calling SDL_GetKeyboardState()?

I don't, I simply check the mod using SDL_GetModState().

Edited by Alundra

Share this post


Link to post
Share on other sites

Yes, you are effectively "losing" events due to the way that code is written. You will need to either buffer some kind of custom input actions yourself (if necessary, for game replays or something), or just react to SDL events in a more direct fashion (e.g. a callback handling function of some kind).

Share this post


Link to post
Share on other sites
Keep in mind input generally comes in two forms: events and polling.

Events are like what you get from windows messaging(the OS, or more specifically the things you drag around that the OS of the same name creates for you), you get messages posted to a queue that happily sit there until doomsday until you process them, so you can package them up and ship them off wherever to process when you need them, you don't 'lose' messages that way.

Polling is usually just checking the state of some array that is being updated for you, or calling an OS function that will actually return the state it has on the device as soon as the function call is made. Problem with polling is that it happens essentially in realtime, if someone clicks a mouse button and releases it and you poll the state at a certain speed, you might flat out miss the message(because it is a state existing between two time periods, not an actual event.)

Theoretically you could make your own events by polling constantly and packaging up the data so you don't 'miss' it but that's hacky at best and would probably need a dedicated thread, usually you'll want to set your input up to deal with the message side of things to generate your own events. Edited by Satharis

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!