Handling INPUT_TYPE (KEYBOARD_KEY / MOUSE_BUTTON)

edited January 2015 in Help request
Hello,

I have a problem about handling input events.

I simply want to create points according to the position of the mouse after a click on a button. And I also want to clean them.
But, before to do really it, I simulate it by orxLOG calls.

In my .ini file, I define :
[MainInput]
KEY_ESCAPE = Quit
KEY_SPACE  = CleanScreen
MOUSE_LEFT = CreatePoint

And, here is the source :
/** Event handler */
orxSTATUS orxFASTCALL InputHandler(const orxEVENT *_pstEvent)
{
  orxINPUT_EVENT_PAYLOAD *pstPayload = (orxINPUT_EVENT_PAYLOAD *)_pstEvent->pstPayload;

  /* Depending on event type */
  switch(_pstEvent->eID)
  {
    case orxINPUT_TYPE_KEYBOARD_KEY:
    {
      orxLOG("ID type = %d, ID event = %d", _pstEvent->eType, _pstEvent->eID);
      orxLOG("KEYBOARD : InputName = %s, SetName = %s
", pstPayload->zInputName, pstPayload->zSetName);
    }
    break;

    case orxINPUT_TYPE_MOUSE_BUTTON:
    {
      orxVECTOR pos;
      orxMouse_GetPosition(&pos);

      orxLOG("ID type = %d, ID event = %d", _pstEvent->eType, _pstEvent->eID);
      orxLOG("MOUSE : InputName = %s, SetName = %s, Position = (%d, %d, %d)
", pstPayload->zInputName, pstPayload->zSetName, (int) pos.fX, (int) pos.fY, (int) pos.fZ);
    }
    break;
  }

  return orxSTATUS_SUCCESS;
}


/** Update callback */
void orxFASTCALL Update(const orxCLOCK_INFO *_pstClockInfo, void *_pstContext)
{
  if(orxInput_IsActive("CleanScreen") && orxInput_HasNewStatus("CleanScreen"))
  {
    orxLOG("Screen Cleaned !!
");
  }
}


/** Inits the tutorial */
orxSTATUS orxFASTCALL Init()
{
  orxCLOCK       *pstClock;
  orxINPUT_TYPE   eType;
  orxENUM         eID;
  const orxSTRING zInputNettoyage;
  const orxSTRING zInputCreerPoint;
  
  orxInput_GetBinding("CleanScreen", 0, &eType, &eID);
  zInputNettoyage = orxInput_GetBindingName(eType, eID);
  orxInput_GetBinding("CreatePoint", 0, &eType, &eID);
  zInputCreerPoint = orxInput_GetBindingName(eType, eID);
  orxLOG("none
"
         "- '%s' will clean the screen
"
         "- '%s' will create a new point
",
         zInputNettoyage,
         zInputCreerPoint);

  orxViewport_CreateFromConfig("Viewport");

  pstClock = orxClock_FindFirst(orx2F(-1.0f), orxCLOCK_TYPE_CORE);
  orxClock_Register(pstClock, Update, orxNULL, orxMODULE_ID_MAIN, orxCLOCK_PRIORITY_NORMAL);

  orxEvent_AddHandler(orxEVENT_TYPE_INPUT, InputHandler);

  return orxSTATUS_SUCCESS;
}

With such a code, here are the logs I get :
[12:54:59] [LOG]
- 'KEY_SPACE' will clean the screen
- 'MOUSE_LEFT' will create a new point

[12:55:01] [LOG] ID type = 5, ID event = 0
[12:55:01] [LOG] KEYBOARD : InputName = CreatePoint, SetName = MainInput

[12:55:01] [LOG] ID type = 5, ID event = 1
[12:55:01] [LOG] MOUSE : InputName = CreatePoint, SetName = MainInput, Position = (620, 173, 0)

[12:55:05] [LOG] ID type = 5, ID event = 0
[12:55:05] [LOG] KEYBOARD : InputName = CleanScreen, SetName = MainInput

[12:55:05] [LOG] Screen Cleaned !!

[12:55:05] [LOG] ID type = 5, ID event = 1
[12:55:05] [LOG] MOUSE : InputName = CleanScreen, SetName = MainInput, Position = (620, 173, 0)

At 12:55:01, I have only clicked in my windows ; at 12:55:05, I have only pressed the space bar. But, in both cases, both the events are caught and it doesn't help me ...

Is such a behavior normal ?

Comments

  • edited January 2015
    I can't really run the code right now, but checking it I found that your switch case is comparing an event type with its eID (they are different variables).

    Most events in orx have a begin and an end event. So I believe this behavior is normal, one event should be for the key/button down and the other for the key/button up.
  • edited January 2015
    Oh .. you're right .. my bad
    Well, it seems that I had misunderstood how events were dealt with : I though that it was 1) source of the input (keyboard, mouse, etc.) then 2) type of input (on, off, etc.)
    But it was the contrary.

    Thank you : now it works as I wish.

    In another hand, as source of the input is dealt with an array, it makes me wonder "how can you have several types in the handle call ?"
    I add the "MOUSE_RIGHT" to "[Main Input]" to click both right and left buttons at the same time : it results with 2 handle calls, one for each button.
  • edited January 2015
    I am not sure if I understood your question. You want to determine which key triggered the event? If that is the case, once you have the key_down event you can use orxKeyboard_IsKeyPressed, orxInput_IsActive and/or orxMouse_IsButtonPressed to determine it.
  • edited January 2015
    Hi Saverio and welcome here! :)

    In addition to Knolan's answers, I wanted to point out that you could also handle the inputs directly in your logic code by calling orxInput_IsActive()/orxInput_HasNewStatus().

    For your last question, I'm not sure I understand it correctly either, but in case you're wondering how to use "combinations" ie. have an input trigger when both left *and* right click are pressed, you need to use the config property CombineList, which is a list of all inputs that will only be active when all their bound keys/buttons are pressed.

    Example:

    Config
    [MyInputs]
    MOUSE_LEFT = Attack # Parry
    MOUSE_RIGHT = Block # Parry
    CombineList = Parry
    

    Parry now requires both left and right clicks to be triggered simultaneously. If only one left or right is clicked, Parry will be inactive.
    However, when Parry is active, Attack & Block will also be active as Attack only requires left click and Block, right click.
    The easy way to handle this is to check for Parry before checking for Attack or Block:
    if(orxInput_IsActive("Parry"))
    {
      // Handle Parry but ignore Attack & Block
    }
    else
    {
      if(orxInput_IsActive("Attack"))
      {
        // Handle Attack
      }
    
      if(orxInput_IsActive("Block"))
      {
        // Handle Block
      }
    }
    

    There are other ways to handle combinations by switching from one input set to another (like for example, when "Ctrl" is pressed, you can switch to a different input set to handle all the ctrl+XXX combinations, and when it's released you go back to the original input set), but it might be overkill in most situations.

    On this topic, note that you can have more than input set active at a time (for example, the in-game console activates an input set in the background to handle all console-related inputs).
  • edited January 2015
    Thanks to both of you.
    I was so persuaded that I needed to use a handler to manage my inputs that I forgot that it existed a simpler way to do so (while, in the same time, I did use orxInput_isActive() in my Update function) :pinch:

    My second question was more a general one : what are the cases or do you have examples where the PayLoad arrays have more than one element ?
    As it's a general question, I guess the answer depends of the type of event to deal with.
    In my specific case, by trying the CombineList property, I succeeded to have more than one element in the PayLoad arrays.
  • edited January 2015
    Ah yes, the arrays in the input event payload are only used for combined inputs as you've experienced. :)

    Only entries with a type != orxINPUT_TYPE_NONE are filled and relevant. :)
Sign In or Register to comment.