/* Copyright (c) 2014 Alex Diener This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Alex Diener alex@ludobloom.com */ #ifndef __InputMap_H__ #define __InputMap_H__ #ifdef __cplusplus extern "C" { #endif typedef struct InputMap InputMap; #define InputMap_superclass StemObject #include "inputcontroller/GamepadMap.h" #include "serialization/DeserializationContext.h" #include "serialization/SerializationContext.h" #include "stemobject/StemObject.h" #include "utilities/Atom.h" #include #define INPUT_MAP_SERIALIZATION_FORMAT_TYPE "input_map" #define INPUT_MAP_SERIALIZATION_FORMAT_VERSION 5 struct InputMap_keyboardActionBinding { Atom actionID; unsigned int keyCode; }; struct InputMap_keyboardActionBindingWithModifiers { Atom actionID; unsigned int keyCode; unsigned int modifierFlags; }; struct InputMap_keyModifierActionBinding { Atom actionID; unsigned int modifierBit; }; struct InputMap_mouseButtonBinding { Atom actionID; unsigned int buttonNumber; }; struct InputMap_mouseScrollBinding { Atom actionID; int directionX; int directionY; }; struct InputMap_mouseMotion1DBinding { Atom actionID; unsigned int axisNumber; }; struct InputMap_mouseMotion2DBinding { Atom actionID; }; struct InputMap_gamepadPhysicalButtonActionBinding { Atom actionID; unsigned int buttonID; }; struct InputMap_gamepadPhysicalAxisActionBinding { Atom actionID; unsigned int axisID; float activateThreshold; float releaseThreshold; }; struct InputMap_gamepadPhysicalAxisMotionBinding { Atom actionID; unsigned int axisID; }; struct InputMap_gamepadPhysicalMap { int vendorID; int productID; unsigned int buttonActionBindingCount; struct InputMap_gamepadPhysicalButtonActionBinding * buttonActionBindings; unsigned int axisActionBindingCount; struct InputMap_gamepadPhysicalAxisActionBinding * axisActionBindings; unsigned int axisMotionBindingCount; struct InputMap_gamepadPhysicalAxisMotionBinding * axisMotionBindings; }; struct InputMap_gamepadAlias { int vendorID1; int productID1; int vendorID2; int productID2; }; struct InputMap_gamepadLogicalButtonActionBinding { Atom actionID; GamepadElement elementID; }; struct InputMap_gamepadLogicalAxisActionBinding { Atom actionID; GamepadElement elementID; int direction; // Ignored for elements that rest at logical -1 instead of 0 and use the full range of motion (such as shoulder triggers) }; struct InputMap_gamepadLogicalAxisMotion1DBinding { Atom actionID; GamepadElement elementID; }; struct InputMap_gamepadLogicalAxisMotion2DBinding { Atom actionID; GamepadElement elementIDX; GamepadElement elementIDY; }; struct InputMap_gamepadLogicalMap { unsigned int buttonActionBindingCount; struct InputMap_gamepadLogicalButtonActionBinding * buttonActionBindings; unsigned int axisActionBindingCount; struct InputMap_gamepadLogicalAxisActionBinding * axisActionBindings; unsigned int axisMotion1DBindingCount; struct InputMap_gamepadLogicalAxisMotion1DBinding * axisMotion1DBindings; unsigned int axisMotion2DBindingCount; struct InputMap_gamepadLogicalAxisMotion2DBinding * axisMotion2DBindings; }; typedef enum InputMap_bindingType { InputMap_bindingType_unknown, InputMap_bindingType_key, InputMap_bindingType_keyWithModifiers, InputMap_bindingType_keyModifier, InputMap_bindingType_mouseButton, InputMap_bindingType_mouseScrollWheel, InputMap_bindingType_mouseMotion1D, InputMap_bindingType_mouseMotion2D, InputMap_bindingType_gamepadButton, InputMap_bindingType_gamepadAxisAction, InputMap_bindingType_gamepadAxisMotion1D, InputMap_bindingType_gamepadAxisMotion2D } InputMap_bindingType; typedef struct InputMap_bindingGeneric { InputMap_bindingType type; union { struct InputMap_keyboardActionBinding key; struct InputMap_keyboardActionBindingWithModifiers keyWithModifiers; struct InputMap_keyModifierActionBinding keyModifier; struct InputMap_mouseButtonBinding mouseButton; struct InputMap_mouseScrollBinding mouseScrollWheel; struct InputMap_mouseMotion1DBinding mouseMotion1D; struct InputMap_mouseMotion2DBinding mouseMotion2D; struct InputMap_gamepadLogicalButtonActionBinding gamepadButton; struct InputMap_gamepadLogicalAxisActionBinding gamepadAxisAction; struct InputMap_gamepadLogicalAxisMotion1DBinding gamepadAxisMotion1D; struct InputMap_gamepadLogicalAxisMotion2DBinding gamepadAxisMotion2D; } binding; } InputMap_bindingGeneric; #define InputMap_genericUnknownBinding() ((InputMap_bindingGeneric) {.type = InputMap_bindingType_unknown}) #define InputMap_genericKeyBinding(key_binding) ((InputMap_bindingGeneric) {.type = InputMap_bindingType_key, .binding = {.key = key_binding}}) #define InputMap_genericKeyBindingWithModifiers(key_binding_with_modifiers) ((InputMap_bindingGeneric) {.type = InputMap_bindingType_keyWithModifiers, .binding = {.keyWithModifiers = key_binding_with_modifiers}}) #define InputMap_genericKeyModifierBinding(key_modifier_binding) ((InputMap_bindingGeneric) {.type = InputMap_bindingType_keyModifier, .binding = {.keyModifier = key_modifier_binding}}) #define InputMap_genericMouseButtonBinding(mouse_button_binding) ((InputMap_bindingGeneric) {.type = InputMap_bindingType_mouseButton, .binding = {.mouseButton = mouse_button_binding}}) #define InputMap_genericMouseScrollWheelBinding(mouse_scroll_wheel_binding) ((InputMap_bindingGeneric) {.type = InputMap_bindingType_mouseScrollWheel, .binding = {.mouseScrollWheel = mouse_scroll_wheel_binding}}) #define InputMap_genericMouseMotion1DBinding(mouse_motion_1d_binding) ((InputMap_bindingGeneric) {.type = InputMap_bindingType_mouseMotion1D, .binding = {.mouseMotion1D = mouse_motion_1d_binding}}) #define InputMap_genericMouseMotion2DBinding(mouse_motion_2d_binding) ((InputMap_bindingGeneric) {.type = InputMap_bindingType_mouseMotion2D, .binding = {.mouseMotion2D = mouse_motion_2d_binding}}) #define InputMap_genericGamepadButtonBinding(gamepad_button_binding) ((InputMap_bindingGeneric) {.type = InputMap_bindingType_gamepadButton, .binding = {.gamepadButton = gamepad_button_binding}}) #define InputMap_genericGamepadAxisActionBinding(gamepad_axis_action_binding) ((InputMap_bindingGeneric) {.type = InputMap_bindingType_gamepadAxisAction, .binding = {.gamepadAxisAction = gamepad_axis_action_binding}}) #define InputMap_genericGamepadAxisMotion1DBinding(gamepad_axis_motion_1d_binding) ((InputMap_bindingGeneric) {.type = InputMap_bindingType_gamepadAxisMotion1D, .binding = {.gamepadAxisMotion1D = gamepad_axis_motion_1d_binding}}) #define InputMap_genericGamepadAxisMotion2DBinding(gamepad_axis_motion_2d_binding) ((InputMap_bindingGeneric) {.type = InputMap_bindingType_gamepadAxisMotion2D, .binding = {.gamepadAxisMotion2D = gamepad_axis_motion_2d_binding}}) // Return true to continue enumeration, or false to terminate and return from the calling function typedef bool (* InputMap_enumerateBindingCallback)(InputMap * inputMap, InputMap_bindingGeneric binding, void * context); #define InputMap_ivars \ StemObject_ivars \ \ unsigned int keyboardBindingCount; \ struct InputMap_keyboardActionBinding * keyboardBindings; \ unsigned int keyboardBindingWithModifiersCount; \ struct InputMap_keyboardActionBindingWithModifiers * keyboardBindingsWithModifiers; \ unsigned int keyModifierBindingCount; \ struct InputMap_keyModifierActionBinding * keyModifierBindings; \ unsigned int mouseButtonBindingCount; \ struct InputMap_mouseButtonBinding * mouseButtonBindings; \ unsigned int mouseScrollBindingCount; \ struct InputMap_mouseScrollBinding * mouseScrollBindings; \ unsigned int mouseMotion1DBindingCount; \ struct InputMap_mouseMotion1DBinding * mouseMotion1DBindings; \ unsigned int mouseMotion2DBindingCount; \ struct InputMap_mouseMotion2DBinding * mouseMotion2DBindings; \ unsigned int gamepadPhysicalMapCount; \ struct InputMap_gamepadPhysicalMap * gamepadPhysicalMaps; \ unsigned int gamepadAliasCount; \ struct InputMap_gamepadAlias * gamepadAliases; \ struct InputMap_gamepadLogicalMap gamepadLogicalMap; #define InputMap_vtable(self_type) \ StemObject_vtable(self_type) stemobject_declare(InputMap) InputMap * InputMap_create(void); bool InputMap_init(InputMap * self); void InputMap_dispose(InputMap * self); InputMap * InputMap_deserialize(compat_type(DeserializationContext *) deserializationContext, bool tolerateErrors); bool InputMap_loadSerializedData(InputMap * self, compat_type(DeserializationContext *) deserializationContext, bool tolerateErrors); void InputMap_serialize(InputMap * self, compat_type(SerializationContext *) serializationContext); // If actionID is NULL, checks for any action binding; if non-NULL, only reports true for bindings to that specific action bool InputMap_isKeyBound(InputMap * self, Atom actionID, unsigned int keyCode); bool InputMap_isKeyWithModifiersBound(InputMap * self, Atom actionID, unsigned int keyCode, unsigned int modifierFlags); bool InputMap_isKeyModifierBound(InputMap * self, Atom actionID, unsigned int modifierBit); bool InputMap_isMouseButtonBound(InputMap * self, Atom actionID, unsigned int buttonNumber); bool InputMap_isMouseScrollDirectionBound(InputMap * self, Atom actionID, int directionX, int directionY); bool InputMap_isMouseMotion1DBound(InputMap * self, Atom actionID, unsigned int axisNumber); bool InputMap_isMouseMotion2DBound(InputMap * self, Atom actionID); bool InputMap_isPhysicalButtonActionBound(InputMap * self, Atom actionID, int vendorID, int productID, unsigned int buttonID); bool InputMap_isPhysicalAxisActionBound(InputMap * self, Atom actionID, int vendorID, int productID, unsigned int axisID); bool InputMap_isPhysicalAxisMotionBound(InputMap * self, Atom actionID, int vendorID, int productID, unsigned int axisID); bool InputMap_isLogicalButtonActionBound(InputMap * self, Atom actionID, GamepadElement elementID); bool InputMap_isLogicalAxisActionBound(InputMap * self, Atom actionID, GamepadElement elementID, int direction); bool InputMap_isLogicalAxisMotion1DBound(InputMap * self, Atom actionID, GamepadElement elementID); bool InputMap_isLogicalAxisMotion2DBound(InputMap * self, Atom actionID, GamepadElement elementIDX, GamepadElement elementIDY); void InputMap_bindKey(InputMap * self, Atom actionID, unsigned int keyCode); void InputMap_bindKeyWithModifiers(InputMap * self, Atom actionID, unsigned int keyCode, unsigned int modifierFlags); void InputMap_bindKeyModifier(InputMap * self, Atom actionID, unsigned int modifierBit); void InputMap_bindMouseButton(InputMap * self, Atom actionID, unsigned int buttonNumber); void InputMap_bindMouseScrollDirection(InputMap * self, Atom actionID, int directionX, int directionY); // 0 for X axis, 1 for Y axis void InputMap_bindMouseMotion1D(InputMap * self, Atom actionID, unsigned int axisNumber); void InputMap_bindMouseMotion2D(InputMap * self, Atom actionID); void InputMap_bindPhysicalButtonAction(InputMap * self, Atom actionID, int vendorID, int productID, unsigned int buttonID); void InputMap_bindPhysicalAxisAction(InputMap * self, Atom actionID, int vendorID, int productID, unsigned int axisID, float activateThreshold, float releaseThreshold); void InputMap_bindPhysicalAxisMotion(InputMap * self, Atom actionID, int vendorID, int productID, unsigned int axisID); void InputMap_bindLogicalButtonAction(InputMap * self, Atom actionID, GamepadElement elementID); void InputMap_bindLogicalAxisAction(InputMap * self, Atom actionID, GamepadElement elementID, int direction); void InputMap_bindLogicalAxisMotion1D(InputMap * self, Atom actionID, GamepadElement elementID); void InputMap_bindLogicalAxisMotion2D(InputMap * self, Atom actionID, GamepadElement elementIDX, GamepadElement elementIDY); void InputMap_unbindKey(InputMap * self, Atom actionID, unsigned int keyCode); void InputMap_unbindKeyWithModifiers(InputMap * self, Atom actionID, unsigned int keyCode, unsigned int modifierFlags); void InputMap_unbindKeyModifier(InputMap * self, Atom actionID, unsigned int modifierBit); void InputMap_unbindMouseButton(InputMap * self, Atom actionID, unsigned int buttonNumber); void InputMap_unbindMouseScrollDirection(InputMap * self, Atom actionID, int directionX, int directionY); void InputMap_unbindMouseMotion1D(InputMap * self, Atom actionID, unsigned int axisNumber); void InputMap_unbindMouseMotion2D(InputMap * self, Atom actionID); void InputMap_unbindPhysicalButtonAction(InputMap * self, Atom actionID, int vendorID, int productID, unsigned int buttonID); void InputMap_unbindPhysicalAxisAction(InputMap * self, Atom actionID, int vendorID, int productID, unsigned int axisID); void InputMap_unbindPhysicalAxisMotion(InputMap * self, Atom actionID, int vendorID, int productID, unsigned int axisID); void InputMap_unbindLogicalButtonAction(InputMap * self, Atom actionID, GamepadElement elementID); void InputMap_unbindLogicalAxisAction(InputMap * self, Atom actionID, GamepadElement elementID, int direction); void InputMap_unbindLogicalAxisMotion1D(InputMap * self, Atom actionID, GamepadElement elementID); void InputMap_unbindLogicalAxisMotion2D(InputMap * self, Atom actionID, GamepadElement elementIDX, GamepadElement elementIDY); void InputMap_unbindAllKeysForAction(InputMap * self, Atom actionID); void InputMap_unbindAllKeysWithModifiersForAction(InputMap * self, Atom actionID); void InputMap_unbindAllKeyModifiersForAction(InputMap * self, Atom actionID); void InputMap_unbindAllMouseButtonsForAction(InputMap * self, Atom actionID); // Includes both buttons and scroll wheel void InputMap_unbindAllMouseMotionForAction(InputMap * self, Atom actionID); // Includes both 1D and 2D motion void InputMap_unbindAllPhysicalButtonsForAction(InputMap * self, Atom actionID); void InputMap_unbindAllPhysicalAxesForAction(InputMap * self, Atom actionID); // Includes actions, 1D motion, and 2D motion void InputMap_unbindAllLogicalButtonsForAction(InputMap * self, Atom actionID); void InputMap_unbindAllLogicalAxesForAction(InputMap * self, Atom actionID); // Includes actions, 1D motion, and 2D motion void InputMap_unbindAllPhysicalButtonsOnDeviceForAction(InputMap * self, int vendorID, int productID, Atom actionID); void InputMap_unbindAllPhysicalAxesOnDeviceForAction(InputMap * self, int vendorID, int productID, Atom actionID); void InputMap_unbindAllActionsForKey(InputMap * self, unsigned int keyCode); void InputMap_unbindAllActionsForKeyWithModifiers(InputMap * self, unsigned int keyCode, unsigned int modifierFlags); void InputMap_unbindAllActionsForKeyModifier(InputMap * self, unsigned int modifierBit); void InputMap_unbindAllActionsForMouseButton(InputMap * self, unsigned int buttonNumber); void InputMap_unbindAllActionsForMouseScrollDirection(InputMap * self, int directionX, int directionY); void InputMap_unbindAllActionsForMouseMotion1D(InputMap * self, unsigned int axisNumber); void InputMap_unbindAllActionsForMouseMotion2D(InputMap * self); void InputMap_unbindAllActionsForPhysicalButton(InputMap * self, int vendorID, int productID, unsigned int buttonID); void InputMap_unbindAllActionsForPhysicalAxis(InputMap * self, int vendorID, int productID, unsigned int axisID, bool positive); void InputMap_unbindAllMotionsForPhysicalAxis(InputMap * self, int vendorID, int productID, unsigned int axisID); void InputMap_unbindAllActionsForLogicalButton(InputMap * self, GamepadElement elementID); void InputMap_unbindAllActionsForLogicalAxis(InputMap * self, GamepadElement elementID); void InputMap_unbindAllMotionsForLogicalAxis(InputMap * self, GamepadElement elementID); void InputMap_unbindAllKeys(InputMap * self); void InputMap_unbindAllKeysWithModifiers(InputMap * self); void InputMap_unbindAllKeyModifiers(InputMap * self); void InputMap_unbindAllMouseButtons(InputMap * self); // Includes both buttons and scroll wheel void InputMap_unbindAllMouseMotion(InputMap * self); // Includes both 1D and 2D motion void InputMap_unbindAllPhysicalButtons(InputMap * self); void InputMap_unbindAllPhysicalAxes(InputMap * self); // Includes actions, 1D motion, and 2D motion void InputMap_unbindAllLogicalButtons(InputMap * self); void InputMap_unbindAllLogicalAxes(InputMap * self); // Includes actions, 1D motion, and 2D motion // All inputs from gamepads identified as vendorID2/productID2 will be mapped using bindings associated // with vendorID1/productID1. Note that the reverse is not true. void InputMap_addGamepadAlias(InputMap * self, int vendorID1, int productID1, int vendorID2, int productID2); // Reassigns vendor and product IDs to the root of the alias chain if they exist in it void InputMap_resolveGamepadAlias(InputMap * self, int * ioVendorID, int * ioProductID); // Calls callback for every binding matching the specified actionID. If callback returns false at any point, // enumeration is terminated and this function returns. Note that this excludes physical gamepad bindings; // to enumerate gamepad controls, use logical bindings instead. void InputMap_enumerateBindingsForAction(InputMap * self, Atom actionID, InputMap_enumerateBindingCallback callback, void * callbackContext); #ifdef __cplusplus } #endif #endif