Input Management

chainsawmcgraw
Unregistered
 
Post: #1
Hey all,

I'm working on a program and am getting Carbon Event Handling going (no problems there... so far Wink ) and before I start writing my event handlers I was wondering how you all handle input. This is my idea for how to do it:
Keep an list of all my in-game event types (ie fire, run forward) and the keys or mouse button associated with it and then test each event to determine whether it fits under one of those actions and then set that action in the list to the equivalent of true. Also, during the game loop, all actions set to true would be processed (that way if one holds down a mouse button, it handles the continual firing, for example). Then, when the key or mouse button comes up, the associated event would be set to false.

Does anyone have any comments or suggestions on this? I'm not sure if there's a better way and wanted to know.

Thanks,
Quote this message in a reply
Nibbie
Posts: 1
Joined: 2010.01
Post: #2
Everything you
need is in the HID Utilities at:

<http://developer.apple.com/samplecode/Sa...dware/HID_
Manager/HID_Utilities_Source.htm>.

The "interesting" API's are:

HIDBuildDeviceList - This creates a list of all the HID devices.
HIDReleaseDeviceList - call this when you're done with the list.
HIDGetFirst/NextDevice - used to iterate the devices
HIDGetFirst/NextDeviceElement - used to iterate elements of a device.
HIDGetElementNameFromVendorProduct[Cookie|Usage] - Get text name of an
element.

HIDQueueDevice - Add all device elements to event queue
HIDDequeueDevice - remove device from event queue
HIDQueueElement - Add element to event queue
HIDDequeueElement - remove element from event queue
HIDGetEvent - poll queue for events

You may incorporate the entire HID Utilities into your project as-is or cut
& paste the pieces that you need.
Quote this message in a reply
Member
Posts: 116
Joined: 2002.04
Post: #3
Be aware though, there's a bug under 10.3 that currently breaks CH products sticks, and possibly some models of Logitech.

Wade
Quote this message in a reply
Moderator
Posts: 133
Joined: 2008.05
Post: #4
I think he wants something a lot more simple than HID.

What I've done is make a class that handles input. I'm sure you could make it static and that'd be fine, unless you want to implement multiple window's with their own input controller.

Inside the class I just have a boolean array of all supported event types, such as mouseDown, mouseUp, keyDown, keyUp, etc. I install event handlers to those targets, and whenever it gets one I toggle that part of the array to true. Whenever I get a keyUp/mouseUp event, I just set it to false.

Then in my Update function, I just check the array of the input controller to see if it's currently being pressed.

This is the relevant code:
Code:
pascal OSStatus MouseDown(EventHandlerCallRef inCallRef, EventRef inEvent, void* inUser)
{
    #pragma unused(inCallRef)
    
    InputController* input = (InputController*)inUser;
    EventMouseButton mouseButton;
    
    GetEventParameter(inEvent,kEventParamMouseLocation,typeQDPoint,NULL,sizeof(​Point),NULL,&(input->mouseLoc));
    GetEventParameter(inEvent,kEventParamMouseButton,typeMouseButton,NULL,sizeo​f(UInt16),NULL,&mouseButton);
    if(mouseButton == kEventMouseButtonPrimary)
        input->inputQuery[CONTROL_CLICK] = true;
    else if(mouseButton == kEventMouseButtonSecondary)
        input->inputQuery[CONTROL_RIGHT_CLICK] = true;
    else
        input->inputQuery[CONTROL_MIDDLE_CLICK] = true;
    
    return eventNotHandledErr;
}

Code:
pascal void Update(EventLoopTimerRef  theTimer, void* userData)
{
    #pragma unused(theTimer)
    Engine* engine = (Engine*)userData;
    XCamera* cam = engine->GetGameCamera();
    XWorld* world = engine->GetGameWorld();
    XTerrain* terrain = world->terrain;
    InputController* input = engine->GetInputController();
    
    //Handle input to XWindows
    XWindow* windowIterator = engine->GetXWindows();
    while(windowIterator != NULL)
    {
        windowIterator->Update();
        if(windowIterator->IsModal())
            engine->Pause();
        windowIterator = windowIterator->next;
    }
    if(!engine->IsPaused())
    {
        //HANDLE ENGINE INPUT
        if(input->QueryPressed(CONTROL_LEFT))
        {                    
            cam->RotateLeft();
        }
        else if(input->QueryPressed(CONTROL_RIGHT))
        {
            cam->RotateRight();
        }
        else if(input->QueryPressed(CONTROL_UP))
        {            
            cam->MoveForward(5);
        }
        else if(input->QueryPressed(CONTROL_DOWN))
        {                    
            cam->TiltDown(1);
        }
        /*else if(input->QueryPressed(CONTROL_CLICK))
        {
            cam->MoveDown(1);
        }
        else if(input->QueryPressed(CONTROL_RIGHT_CLICK))
        {
            cam->MoveUp(1);
        }*/
    }
Quote this message in a reply
DoG
Moderator
Posts: 869
Joined: 2003.01
Post: #5
The way I do it is find out which keys are pressed, keep the previous state where necessary, and dispatch some higher level commands to the game instead of the actual key presses or mouse movement, or whatever.

To handle continual firing, i would solve it by giving the weapon class some methods StartFiring() and EndFiring(), and calling them when mouseDown/mouseUp (or whatever you do for firing) occurs. This way, the state of the weapon is kept where it belongs (in the weapon object), and the game code is not cluttered by global state information.

What you suggested was a polling model, which checks every game loop iteration for some flags. While this works, it is neither efficient nor pretty.

By using an event driven model, it is easier to encapsulate state information, and performance is potentially better, too. And, it is also easier to debug, imho.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Process/ Memopry Management in Cocos2D GameGeeeky 0 1,441 Nov 8, 2014 01:49 AM
Last Post: GameGeeeky
  Importance of memory management johncmurphy 11 6,639 Aug 27, 2009 02:54 PM
Last Post: AnotherJake
  Objective C memory management Madrayken 3 2,947 Jul 10, 2009 10:13 AM
Last Post: DoG
  Input Management bmantzey 9 4,037 Sep 24, 2008 06:26 AM
Last Post: bmantzey
  GUI Management Design Nick 14 5,307 Nov 24, 2006 06:07 AM
Last Post: memon