#include "unittest/TestSuite.h" #include "inputcontroller/InputController.h" static void verifyInit(InputController * inputController, InputMap * inputMap, unsigned int lineNumber, ...) { va_list args; unsigned int actionCount = 0; const char * actionID; TestCase_assert(inputController != NULL, "Expected non-NULL but got NULL (%u)", lineNumber); TestCase_assert(inputController->eventDispatcher != NULL, "Expected non-NULL but got NULL (%u)", lineNumber); TestCase_assert(inputController->inputMap == inputMap, "Expected %p but got %p (%u)", inputMap, inputController->inputMap, lineNumber); va_start(args, lineNumber); while ((actionID = ATOM(va_arg(args, const char *))) != NULL) { TestCase_assert(inputController->actions[actionCount].actionID == actionID, "Expected \"%s\" (%p) but got \"%s\" (%p) (line %u, arg %u)", actionID, actionID, inputController->actions[actionCount].actionID, inputController->actions[actionCount].actionID, lineNumber, actionCount); TestCase_assert(!inputController->actions[actionCount].active, "Expected false but got true (line %u, arg %u)", lineNumber, actionCount); actionCount++; } va_end(args); TestCase_assert(inputController->actionCount == actionCount, "Expected %u but got %u (%u)", actionCount, inputController->actionCount, lineNumber); TestCase_assert(inputController->vtable == &InputController_class, "Expected %p but got %p (%u)", &InputController_class, inputController->vtable, lineNumber); } static void testInit(void) { InputController inputController, * inputControllerPtr; memset(&inputController, 0x00, sizeof(InputController)); stemobject_assign_vtable(inputController, InputController); InputController_init(&inputController, NULL, NULL, NULL); verifyInit(&inputController, NULL, __LINE__, NULL); InputController_dispose(&inputController); InputMap * inputMap = InputMap_create(); GamepadMap * gamepadMap = GamepadMap_create(); memset(&inputController, 0xFF, sizeof(InputController)); stemobject_assign_vtable(inputController, InputController); InputController_init(&inputController, gamepadMap, inputMap, "a", NULL); verifyInit(&inputController, inputMap, __LINE__, "a", NULL); InputController_dispose(&inputController); inputControllerPtr = InputController_create(gamepadMap, inputMap, "b", "c", NULL); verifyInit(inputControllerPtr, inputMap, __LINE__, "b", "c", NULL); InputController_dispose(inputControllerPtr); InputMap_dispose(inputMap); } static unsigned int actionDownCallCount; static unsigned int actionUpCallCount; static unsigned int motionCallCount; static struct InputController_event lastActionDownEvent, lastLastActionDownEvent; static struct InputController_event lastActionUpEvent, lastLastActionUpEvent; static struct InputController_motionEvent lastMotionEvent, lastLastMotionEvent; static bool actionDown(Atom eventID, void * eventData, void * context) { struct InputController_event * event = eventData; actionDownCallCount++; lastLastActionDownEvent = lastActionDownEvent; lastActionDownEvent = *event; return true; } static bool actionUp(Atom eventID, void * eventData, void * context) { struct InputController_event * event = eventData; actionUpCallCount++; lastLastActionUpEvent = lastActionUpEvent; lastActionUpEvent = *event; return true; } static bool motion(Atom eventID, void * eventData, void * context) { struct InputController_motionEvent * event = eventData; motionCallCount++; lastLastMotionEvent = lastMotionEvent; lastMotionEvent = *event; return true; } static void testActions(void) { InputController * inputController; actionDownCallCount = actionUpCallCount = 0; inputController = InputController_create(NULL, NULL, "a", "b", NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_DOWN), actionDown, NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_UP), actionUp, NULL); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; TestCase_assert(!InputController_isActionActive(inputController, ATOM("a")), "Expected false but got true"); call_virtual(startAction, inputController, ATOM("a"), 0.1, false, InputMap_genericUnknownBinding()); TestCase_assertUIntEqual(actionDownCallCount, 1); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 0.1); TestCase_assertBoolTrue(InputController_isActionActive(inputController, ATOM("a"))); call_virtual(startAction, inputController, ATOM("a"), 0.1, false, InputMap_genericUnknownBinding()); TestCase_assertUIntEqual(actionDownCallCount, 1); TestCase_assertBoolTrue(InputController_isActionActive(inputController, ATOM("a"))); lastActionUpEvent.actionID = NULL; lastActionUpEvent.timestamp = 0.0; call_virtual(stopAction, inputController, ATOM("a"), 0.2, false); TestCase_assertUIntEqual(actionUpCallCount, 1); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionUpEvent.timestamp, 0.2); TestCase_assertBoolFalse(InputController_isActionActive(inputController, ATOM("a"))); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; call_virtual(startAction, inputController, ATOM("a"), 1.0, false, InputMap_genericUnknownBinding()); TestCase_assertUIntEqual(actionDownCallCount, 2); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 1.0); TestCase_assertBoolTrue(InputController_isActionActive(inputController, ATOM("a"))); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; TestCase_assertBoolFalse(InputController_isActionActive(inputController, ATOM("b"))); call_virtual(startAction, inputController, ATOM("b"), 2.3, false, InputMap_genericUnknownBinding()); TestCase_assertUIntEqual(actionDownCallCount, 3); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("b")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 2.3); TestCase_assertBoolTrue(InputController_isActionActive(inputController, ATOM("b"))); InputController_dispose(inputController); } static void testKeyboardBindings(void) { InputController * inputController; InputMap * inputMap; actionDownCallCount = actionUpCallCount = 0; inputMap = InputMap_create(); inputController = InputController_create(NULL, inputMap, "a", "b", NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_DOWN), actionDown, NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_UP), actionUp, NULL); InputMap_bindKey(inputMap, ATOM("a"), 1); InputMap_bindKey(inputMap, ATOM("b"), 2); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; TestCase_assertBoolTrue(InputController_keyDown(inputController, 1, 0x0, 1.0, true)); TestCase_assertUIntEqual(actionDownCallCount, 0); TestCase_assertBoolTrue(InputController_keyDown(inputController, 1, 0x0, 1.0, false)); TestCase_assertUIntEqual(actionDownCallCount, 1); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 1.0); TestCase_assertBoolFalse(InputController_keyDown(inputController, 1, 0x0, 1.1, true)); TestCase_assertUIntEqual(actionDownCallCount, 1); TestCase_assertBoolFalse(InputController_keyDown(inputController, 1, 0x0, 1.1, false)); TestCase_assertUIntEqual(actionDownCallCount, 1); lastActionUpEvent.actionID = NULL; lastActionUpEvent.timestamp = 0.0; InputController_keyUp(inputController, 1, 2.0, false); TestCase_assertUIntEqual(actionUpCallCount, 1); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionUpEvent.timestamp, 2.0); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; InputController_keyDown(inputController, 1, 0x0, 3.0, false); TestCase_assertUIntEqual(actionDownCallCount, 2); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 3.0); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; InputController_keyDown(inputController, 2, 0x0, 4.0, false); TestCase_assertUIntEqual(actionDownCallCount, 3); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("b")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 4.0); InputController_dispose(inputController); InputMap_dispose(inputMap); } static void testKeyboardBindingsWithModifiers(void) { InputController * inputController; InputMap * inputMap; actionDownCallCount = actionUpCallCount = 0; inputMap = InputMap_create(); inputController = InputController_create(NULL, inputMap, "a", "b", NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_DOWN), actionDown, NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_UP), actionUp, NULL); InputMap_bindKeyWithModifiers(inputMap, ATOM("a"), 1, 0x0); InputMap_bindKeyWithModifiers(inputMap, ATOM("b"), 1, 0x1); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; TestCase_assertBoolTrue(InputController_keyDown(inputController, 1, 0x0, 1.1, true)); TestCase_assertUIntEqual(actionDownCallCount, 0); TestCase_assertBoolTrue(InputController_keyDown(inputController, 1, 0x0, 1.1, false)); TestCase_assertUIntEqual(actionDownCallCount, 1); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 1.1); TestCase_assertBoolFalse(InputController_keyDown(inputController, 1, 0x0, 1.2, true)); TestCase_assertUIntEqual(actionDownCallCount, 1); TestCase_assertBoolFalse(InputController_keyDown(inputController, 1, 0x0, 1.2, false)); TestCase_assertUIntEqual(actionDownCallCount, 1); lastActionUpEvent.actionID = NULL; lastActionUpEvent.timestamp = 0.0; InputController_keyUp(inputController, 1, 1.2, false); TestCase_assertUIntEqual(actionUpCallCount, 1); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionUpEvent.timestamp, 1.2); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; InputController_keyDown(inputController, 1, 0x0, 1.3, false); TestCase_assertUIntEqual(actionDownCallCount, 2); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 1.3); InputController_keyUp(inputController, 1, 1.5, false); TestCase_assertUIntEqual(actionUpCallCount, 2); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionUpEvent.timestamp, 1.5); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; InputController_keyDown(inputController, 1, 0x1, 1.7, false); TestCase_assertUIntEqual(actionDownCallCount, 3); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("b")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 1.7); InputController_dispose(inputController); InputMap_dispose(inputMap); } static void testKeyModifierBindings(void) { InputController * inputController; InputMap * inputMap; actionDownCallCount = actionUpCallCount = 0; inputMap = InputMap_create(); inputController = InputController_create(NULL, inputMap, "a", "b", NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_DOWN), actionDown, NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_UP), actionUp, NULL); InputMap_bindKeyModifier(inputMap, ATOM("a"), 0x1); InputMap_bindKeyModifier(inputMap, ATOM("b"), 0x2); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; TestCase_assertBoolTrue(InputController_keyModifiersChanged(inputController, 0x1, 0x0, 1.0, true)); TestCase_assertUIntEqual(actionDownCallCount, 0); TestCase_assertBoolTrue(InputController_keyModifiersChanged(inputController, 0x1, 0x0, 1.0, false)); TestCase_assertUIntEqual(actionDownCallCount, 1); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 1.0); TestCase_assertBoolFalse(InputController_keyModifiersChanged(inputController, 0x5, 0x1, 2.0, true)); TestCase_assertUIntEqual(actionDownCallCount, 1); TestCase_assertBoolFalse(InputController_keyModifiersChanged(inputController, 0x5, 0x1, 2.0, false)); TestCase_assertUIntEqual(actionDownCallCount, 1); lastActionUpEvent.actionID = NULL; lastActionUpEvent.timestamp = 0.0; InputController_keyModifiersChanged(inputController, 0x4, 0x5, 3.0, false); TestCase_assertUIntEqual(actionUpCallCount, 1); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionUpEvent.timestamp, 3.0); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; InputController_keyModifiersChanged(inputController, 0x1, 0x4, 4.0, false); TestCase_assertUIntEqual(actionDownCallCount, 2); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 4.0); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; InputController_keyModifiersChanged(inputController, 0x3, 0x1, 5.0, false); TestCase_assertUIntEqual(actionDownCallCount, 3); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("b")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 5.0); InputController_dispose(inputController); InputMap_dispose(inputMap); } static void testMouseButtonBindings(void) { InputMap * inputMap = InputMap_create(); InputController * inputController = InputController_create(NULL, inputMap, "a", "b", NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_DOWN), actionDown, NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_UP), actionUp, NULL); actionDownCallCount = 0; actionUpCallCount = 0; bool handled = InputController_mouseDown(inputController, 0, 0.0, false); TestCase_assertBoolFalse(handled); TestCase_assertUIntEqual(actionDownCallCount, 0); handled = InputController_mouseUp(inputController, 0, 0.0, false); TestCase_assertBoolFalse(handled); TestCase_assertUIntEqual(actionUpCallCount, 0); InputMap_bindMouseButton(inputMap, ATOM("a"), 0); InputMap_bindMouseButton(inputMap, ATOM("b"), 1); handled = InputController_mouseDown(inputController, 0, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 1); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); handled = InputController_mouseDown(inputController, 1, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 2); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("b")); handled = InputController_mouseUp(inputController, 0, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 1); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("a")); handled = InputController_mouseUp(inputController, 1, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 2); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("b")); InputController_dispose(inputController); InputMap_dispose(inputMap); } static void testMouseScrollBindings(void) { InputMap * inputMap = InputMap_create(); InputController * inputController = InputController_create(NULL, inputMap, "a", "b", "c", "d", NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_DOWN), actionDown, NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_UP), actionUp, NULL); actionDownCallCount = 0; actionUpCallCount = 0; bool handled = InputController_mouseScrollWheel(inputController, 0, -1, 0.0, false); TestCase_assertBoolFalse(handled); TestCase_assertUIntEqual(actionDownCallCount, 0); TestCase_assertUIntEqual(actionUpCallCount, 0); handled = InputController_mouseScrollWheel(inputController, 1, 0, 0.0, false); TestCase_assertBoolFalse(handled); TestCase_assertUIntEqual(actionDownCallCount, 0); TestCase_assertUIntEqual(actionUpCallCount, 0); InputMap_bindMouseScrollDirection(inputMap, ATOM("a"), -1, 0); InputMap_bindMouseScrollDirection(inputMap, ATOM("b"), 1, 0); InputMap_bindMouseScrollDirection(inputMap, ATOM("c"), 0, -1); InputMap_bindMouseScrollDirection(inputMap, ATOM("d"), 0, 1); lastActionDownEvent.actionID = lastActionUpEvent.actionID = NULL; handled = InputController_mouseScrollWheel(inputController, -1, 0, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 1); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); TestCase_assertUIntEqual(actionUpCallCount, 1); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("a")); handled = InputController_mouseScrollWheel(inputController, 2, 0, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 3); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("b")); TestCase_assertUIntEqual(actionUpCallCount, 3); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("b")); handled = InputController_mouseScrollWheel(inputController, 0, -3, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 6); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("c")); TestCase_assertUIntEqual(actionUpCallCount, 6); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("c")); handled = InputController_mouseScrollWheel(inputController, 0, 1, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 7); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("d")); TestCase_assertUIntEqual(actionUpCallCount, 7); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("d")); InputController_dispose(inputController); InputMap_dispose(inputMap); } static void testMouseMotion1DBindings(void) { InputMap * inputMap = InputMap_create(); InputController * inputController = InputController_create(NULL, inputMap, "a", "b", NULL); inputController->mouseSensitivityX = 1.0f; inputController->mouseSensitivityY = 1.0f; EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_MOTION), motion, NULL); motionCallCount = 0; bool handled = InputController_mouseMoved(inputController, 1.0f, 1.0f, 0.0, false); TestCase_assertBoolFalse(handled); TestCase_assertUIntEqual(motionCallCount, 0); InputMap_bindMouseMotion1D(inputMap, ATOM("a"), 0); InputMap_bindMouseMotion1D(inputMap, ATOM("b"), 1); handled = InputController_mouseMoved(inputController, 1.0f, 0.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(motionCallCount, 1); TestCase_assertStringPointerEqual(lastMotionEvent.actionID, ATOM("a")); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x10000); handled = InputController_mouseMoved(inputController, 0.0f, -2.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(motionCallCount, 2); TestCase_assertStringPointerEqual(lastMotionEvent.actionID, ATOM("b")); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, -0x20000); handled = InputController_mouseMoved(inputController, -1.0f, 1.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(motionCallCount, 4); TestCase_assertStringPointerEqual(lastLastMotionEvent.actionID, ATOM("a")); TestCase_assertFixed16_16Equal(lastLastMotionEvent.valueX, -0x10000); TestCase_assertStringPointerEqual(lastMotionEvent.actionID, ATOM("b")); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x10000); InputController_dispose(inputController); InputMap_dispose(inputMap); } static void testMouseMotion2DBindings(void) { InputMap * inputMap = InputMap_create(); InputController * inputController = InputController_create(NULL, inputMap, "a", NULL); inputController->mouseSensitivityX = 1.0f; inputController->mouseSensitivityY = 1.0f; EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_MOTION), motion, NULL); motionCallCount = 0; bool handled = InputController_mouseMoved(inputController, 1.0f, 1.0f, 0.0, false); TestCase_assertBoolFalse(handled); TestCase_assertUIntEqual(motionCallCount, 0); InputMap_bindMouseMotion2D(inputMap, ATOM("a")); handled = InputController_mouseMoved(inputController, 1.0f, 0.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(motionCallCount, 1); TestCase_assertStringPointerEqual(lastMotionEvent.actionID, ATOM("a")); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.valueY, 0x00000); handled = InputController_mouseMoved(inputController, -1.0f, 2.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(motionCallCount, 2); TestCase_assertStringPointerEqual(lastMotionEvent.actionID, ATOM("a")); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, -0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.valueY, 0x20000); InputController_dispose(inputController); InputMap_dispose(inputMap); } static void testPhysicalButtonBindings(void) { InputController * inputController; InputMap * inputMap; actionDownCallCount = actionUpCallCount = 0; inputMap = InputMap_create(); inputController = InputController_create(NULL, inputMap, "a", "b", "c", "d", NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_DOWN), actionDown, NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_UP), actionUp, NULL); InputMap_bindPhysicalButtonAction(inputMap, ATOM("a"), 1, 2, 3); InputMap_bindPhysicalButtonAction(inputMap, ATOM("b"), 4, 2, 3); InputMap_bindPhysicalButtonAction(inputMap, ATOM("c"), 1, 5, 3); InputMap_bindPhysicalButtonAction(inputMap, ATOM("d"), 1, 2, 6); struct Gamepad_device device1_2 = {.vendorID = 1, .productID = 2}; struct Gamepad_device device4_2 = {.vendorID = 4, .productID = 2}; struct Gamepad_device device1_5 = {.vendorID = 1, .productID = 5}; lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; TestCase_assertBoolTrue(InputController_gamepadButtonDown(inputController, &device1_2, 3, 1.0, true)); TestCase_assertUIntEqual(actionDownCallCount, 0); TestCase_assertBoolTrue(InputController_gamepadButtonDown(inputController, &device1_2, 3, 1.0, false)); TestCase_assertUIntEqual(actionDownCallCount, 1); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 1.0); TestCase_assertBoolFalse(InputController_gamepadButtonDown(inputController, &device1_2, 3, 1.1, true)); TestCase_assertUIntEqual(actionDownCallCount, 1); TestCase_assertBoolFalse(InputController_gamepadButtonDown(inputController, &device1_2, 3, 1.1, false)); TestCase_assertUIntEqual(actionDownCallCount, 1); lastActionUpEvent.actionID = NULL; lastActionUpEvent.timestamp = 0.0; InputController_gamepadButtonUp(inputController, &device1_2, 3, 1.2, false); TestCase_assertUIntEqual(actionUpCallCount, 1); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionUpEvent.timestamp, 1.2); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; InputController_gamepadButtonDown(inputController, &device1_2, 3, 1.3, false); TestCase_assertUIntEqual(actionDownCallCount, 2); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 1.3); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; InputController_gamepadButtonDown(inputController, &device4_2, 3, 1.4, false); TestCase_assertUIntEqual(actionDownCallCount, 3); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("b")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 1.4); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; InputController_gamepadButtonDown(inputController, &device1_5, 3, 1.5, false); TestCase_assertUIntEqual(actionDownCallCount, 4); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("c")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 1.5); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; InputController_gamepadButtonDown(inputController, &device1_2, 6, 1.6, false); TestCase_assertUIntEqual(actionDownCallCount, 5); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("d")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 1.6); InputController_dispose(inputController); InputMap_dispose(inputMap); } static void testPhysicalAxisActionBindings(void) { InputController * inputController; InputMap * inputMap; actionDownCallCount = actionUpCallCount = 0; inputMap = InputMap_create(); inputController = InputController_create(NULL, inputMap, "a", "b", "c", "d", "e", NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_DOWN), actionDown, NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_UP), actionUp, NULL); InputMap_bindPhysicalAxisAction(inputMap, ATOM("a"), 1, 2, 3, 0.75f, 0.25f); InputMap_bindPhysicalAxisAction(inputMap, ATOM("b"), 4, 2, 3, 0.75f, 0.25f); InputMap_bindPhysicalAxisAction(inputMap, ATOM("c"), 1, 5, 3, 0.75f, 0.25f); InputMap_bindPhysicalAxisAction(inputMap, ATOM("d"), 1, 2, 6, 0.75f, 0.25f); InputMap_bindPhysicalAxisAction(inputMap, ATOM("e"), 1, 2, 3, -0.75f, -0.25f); struct Gamepad_device device1_2 = {.vendorID = 1, .productID = 2}; struct Gamepad_device device4_2 = {.vendorID = 4, .productID = 2}; struct Gamepad_device device1_5 = {.vendorID = 1, .productID = 5}; lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; TestCase_assertBoolTrue(InputController_gamepadAxisMoved(inputController, &device1_2, 3, 1.0f, 0.0f, 1.0, true)); TestCase_assertUIntEqual(actionDownCallCount, 0); TestCase_assertBoolTrue(InputController_gamepadAxisMoved(inputController, &device1_2, 3, 1.0f, 0.0f, 1.0, false)); TestCase_assertUIntEqual(actionDownCallCount, 1); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 1.0); TestCase_assertBoolFalse(InputController_gamepadAxisMoved(inputController, &device1_2, 3, 1.0f, 0.0f, 1.1, true)); TestCase_assertUIntEqual(actionDownCallCount, 1); TestCase_assertBoolFalse(InputController_gamepadAxisMoved(inputController, &device1_2, 3, 1.0f, 0.0f, 1.1, false)); TestCase_assertUIntEqual(actionDownCallCount, 1); lastActionUpEvent.actionID = NULL; lastActionUpEvent.timestamp = 0.0; InputController_gamepadAxisMoved(inputController, &device1_2, 3, 0.0f, 1.0f, 1.2, false); TestCase_assertUIntEqual(actionUpCallCount, 1); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionUpEvent.timestamp, 1.2); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; InputController_gamepadAxisMoved(inputController, &device1_2, 3, 1.0f, 0.0f, 1.3, false); TestCase_assertUIntEqual(actionDownCallCount, 2); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 1.3); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; InputController_gamepadAxisMoved(inputController, &device4_2, 3, 1.0f, 0.0f, 1.4, false); TestCase_assertUIntEqual(actionDownCallCount, 3); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("b")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 1.4); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; InputController_gamepadAxisMoved(inputController, &device1_5, 3, 1.0f, 0.0f, 1.5, false); TestCase_assertUIntEqual(actionDownCallCount, 4); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("c")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 1.5); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; InputController_gamepadAxisMoved(inputController, &device1_2, 6, 1.0f, 0.0f, 1.6, false); TestCase_assertUIntEqual(actionDownCallCount, 5); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("d")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 1.6); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; InputController_gamepadAxisMoved(inputController, &device1_2, 3, -1.0f, 0.0f, 1.7, false); TestCase_assertUIntEqual(actionDownCallCount, 6); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("e")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 1.7); InputController_gamepadAxisMoved(inputController, &device1_2, 3, 0.0f, 1.0f, 1.8, false); TestCase_assertUIntEqual(actionUpCallCount, 2); InputMap_bindPhysicalAxisAction(inputMap, ATOM("a"), 1, 2, 3, 1.0f, 0.0f); InputController_gamepadAxisMoved(inputController, &device1_2, 3, 0.875f, 0.0f, 1.9, false); TestCase_assertUIntEqual(actionDownCallCount, 6); lastActionDownEvent.actionID = NULL; lastActionDownEvent.timestamp = 0.0; InputController_gamepadAxisMoved(inputController, &device1_2, 3, 1.0f, 0.875f, 2.0, false); TestCase_assertUIntEqual(actionDownCallCount, 7); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionDownEvent.timestamp, 2.0); InputController_gamepadAxisMoved(inputController, &device1_2, 3, 0.125f, 1.0f, 2.1, false); TestCase_assertUIntEqual(actionUpCallCount, 2); lastActionUpEvent.actionID = NULL; lastActionUpEvent.timestamp = 0.0; InputController_gamepadAxisMoved(inputController, &device1_2, 3, -0.125f, 0.125f, 2.2, false); TestCase_assertUIntEqual(actionUpCallCount, 3); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("a")); TestCase_assertDoubleEqual(lastActionUpEvent.timestamp, 2.2); InputController_dispose(inputController); InputMap_dispose(inputMap); } static void testPhysicalAxisMotionBindings(void) { InputMap * inputMap = InputMap_create(); InputController * inputController = InputController_create(NULL, inputMap, "a", "b", NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_MOTION), motion, NULL); motionCallCount = 0; struct Gamepad_device device1_2 = {.vendorID = 1, .productID = 2}; bool handled = InputController_gamepadAxisMoved(inputController, &device1_2, 0, 1.0f, 0.0f, 0.0, false); TestCase_assertBoolFalse(handled); TestCase_assertUIntEqual(motionCallCount, 0); InputMap_bindPhysicalAxisMotion(inputMap, ATOM("a"), 0x1, 0x2, 0); InputMap_bindPhysicalAxisMotion(inputMap, ATOM("b"), 0x1, 0x2, 1); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 0, 1.0f, 0.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(motionCallCount, 1); TestCase_assertStringPointerEqual(lastMotionEvent.actionID, ATOM("a")); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x10000); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 1, -0.25f, -1.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(motionCallCount, 2); TestCase_assertStringPointerEqual(lastMotionEvent.actionID, ATOM("b")); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, -0x04000); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.0f, 0.5f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(motionCallCount, 3); TestCase_assertStringPointerEqual(lastMotionEvent.actionID, ATOM("a")); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x00000); InputController_dispose(inputController); InputMap_dispose(inputMap); } static void testLogicalGamepadBindings(void) { GamepadMap * gamepadMap = GamepadMap_create(); GamepadMap_registerHardwareElement(gamepadMap, 0x1, 0x2, GAMEPAD_ELEMENT_AXIS, 0, GAMEPAD_DPAD_X, 1); GamepadMap_registerHardwareElement(gamepadMap, 0x1, 0x2, GAMEPAD_ELEMENT_AXIS, 1, GAMEPAD_DPAD_Y, -1); GamepadMap_registerHardwareElement(gamepadMap, 0x1, 0x2, GAMEPAD_ELEMENT_BUTTON, 0, GAMEPAD_BOTTOM_FACE_BUTTON, 0); InputMap * inputMap = InputMap_create(); InputMap_bindLogicalButtonAction(inputMap, ATOM("a"), GAMEPAD_BOTTOM_FACE_BUTTON); InputMap_bindLogicalAxisAction(inputMap, ATOM("b"), GAMEPAD_DPAD_X, -1); InputMap_bindLogicalAxisAction(inputMap, ATOM("c"), GAMEPAD_DPAD_X, 1); InputMap_bindLogicalAxisAction(inputMap, ATOM("d"), GAMEPAD_DPAD_Y, -1); InputMap_bindLogicalAxisAction(inputMap, ATOM("e"), GAMEPAD_DPAD_Y, 1); InputController * inputController = InputController_create(gamepadMap, inputMap, "a", "b", "c", "d", "e", NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_DOWN), actionDown, NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_UP), actionUp, NULL); actionDownCallCount = 0; actionUpCallCount = 0; struct Gamepad_device device1_2 = {.vendorID = 1, .productID = 2}; bool handled = InputController_gamepadButtonDown(inputController, &device1_2, 0, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 1); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); handled = InputController_gamepadButtonUp(inputController, &device1_2, 0, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 1); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("a")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 0, -1.0f, 0.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 2); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("b")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 0, 1.0f, -1.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 2); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("b")); TestCase_assertUIntEqual(actionDownCallCount, 3); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("c")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 1, 1.0f, 0.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 4); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("d")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 1, 0.0f, 1.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 3); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("d")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 1, -1.0f, 0.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 5); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("e")); InputController_dispose(inputController); InputMap_dispose(inputMap); GamepadMap_dispose(gamepadMap); } static void testLogicalMotion1DBindings(void) { GamepadMap * gamepadMap = GamepadMap_create(); GamepadMap_registerHardwareElement(gamepadMap, 0x1, 0x2, GAMEPAD_ELEMENT_AXIS, 0, GAMEPAD_LEFT_STICK_X, 1); GamepadMap_registerHardwareElement(gamepadMap, 0x1, 0x2, GAMEPAD_ELEMENT_AXIS, 1, GAMEPAD_LEFT_STICK_Y, -1); InputMap * inputMap = InputMap_create(); InputMap_bindLogicalAxisMotion1D(inputMap, ATOM("a"), GAMEPAD_LEFT_STICK_X); InputMap_bindLogicalAxisMotion1D(inputMap, ATOM("b"), GAMEPAD_LEFT_STICK_Y); InputController * inputController = InputController_create(gamepadMap, inputMap, "a", "b", NULL); inputController->gamepadInputController->analogStickInnerDeadZone = 0.0f; inputController->gamepadInputController->analogStickOuterDeadZone = 0.0f; EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_MOTION), motion, NULL); motionCallCount = 0; struct Gamepad_device device1_2 = {.vendorID = 1, .productID = 2}; bool handled = InputController_gamepadAxisMoved(inputController, &device1_2, 0, -0.5f, -0.25f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(motionCallCount, 1); TestCase_assertStringPointerEqual(lastMotionEvent.actionID, ATOM("a")); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, -0x08000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, -0x08000); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 1, 1.0f, 0.25f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(motionCallCount, 2); TestCase_assertStringPointerEqual(lastMotionEvent.actionID, ATOM("b")); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, -0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, -0x10000); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.0f, -0.5f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(motionCallCount, 3); TestCase_assertStringPointerEqual(lastMotionEvent.actionID, ATOM("a")); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x00000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, 0x00000); InputController_dispose(inputController); InputMap_dispose(inputMap); GamepadMap_dispose(gamepadMap); } static void testLogicalMotion2DBindings(void) { GamepadMap * gamepadMap = GamepadMap_create(); GamepadMap_registerHardwareElement(gamepadMap, 0x1, 0x2, GAMEPAD_ELEMENT_AXIS, 0, GAMEPAD_LEFT_STICK_X, 1); GamepadMap_registerHardwareElement(gamepadMap, 0x1, 0x2, GAMEPAD_ELEMENT_AXIS, 1, GAMEPAD_LEFT_STICK_Y, -1); InputMap * inputMap = InputMap_create(); InputMap_bindLogicalAxisMotion2D(inputMap, ATOM("a"), GAMEPAD_LEFT_STICK_X, GAMEPAD_LEFT_STICK_Y); InputController * inputController = InputController_create(gamepadMap, inputMap, "a", NULL); inputController->gamepadInputController->analogStickInnerDeadZone = 0.0f; inputController->gamepadInputController->analogStickOuterDeadZone = 0.0f; EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_MOTION), motion, NULL); motionCallCount = 0; struct Gamepad_device device1_2 = {.vendorID = 1, .productID = 2}; bool handled = InputController_gamepadAxisMoved(inputController, &device1_2, 0, -0.5f, -0.25f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(motionCallCount, 1); TestCase_assertStringPointerEqual(lastMotionEvent.actionID, ATOM("a")); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, -0x08000); TestCase_assertFixed16_16Equal(lastMotionEvent.valueY, 0x00000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, -0x08000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueY, 0x00000); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 1, 1.0f, 0.25f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(motionCallCount, 2); TestCase_assertStringPointerEqual(lastMotionEvent.actionID, ATOM("a")); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, -0x08000); TestCase_assertFixed16_16Equal(lastMotionEvent.valueY, -0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, -0x08000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueY, -0x10000); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.0f, -0.5f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(motionCallCount, 3); TestCase_assertStringPointerEqual(lastMotionEvent.actionID, ATOM("a")); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x00000); TestCase_assertFixed16_16Equal(lastMotionEvent.valueY, -0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, 0x00000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueY, -0x10000); InputController_dispose(inputController); InputMap_dispose(inputMap); GamepadMap_dispose(gamepadMap); } static void testAnalogStickDeadZones(void) { GamepadMap * gamepadMap = GamepadMap_create(); GamepadMap_registerHardwareElement(gamepadMap, 0x1, 0x2, GAMEPAD_ELEMENT_AXIS, 0, GAMEPAD_LEFT_STICK_X, 1); GamepadMap_registerHardwareElement(gamepadMap, 0x1, 0x2, GAMEPAD_ELEMENT_AXIS, 1, GAMEPAD_LEFT_STICK_Y, 1); InputMap * inputMap = InputMap_create(); InputMap_bindLogicalAxisMotion1D(inputMap, ATOM("a"), GAMEPAD_LEFT_STICK_X); InputMap_bindLogicalAxisMotion1D(inputMap, ATOM("b"), GAMEPAD_LEFT_STICK_Y); InputController * inputController = InputController_create(gamepadMap, inputMap, "a", "b", "c", NULL); inputController->gamepadInputController->analogStickInnerDeadZone = 0.25f; inputController->gamepadInputController->analogStickOuterDeadZone = 0.5f; EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_MOTION), motion, NULL); motionCallCount = 0; struct Gamepad_device device1_2 = {.vendorID = 1, .productID = 2}; // 1D motion with inner and outer dead zones InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.25f, 0.0f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 1); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x00000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, 0x04000); InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.375f, 0.25f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 2); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x08000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, 0x06000); InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.5f, 0.375f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 3); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, 0x08000); InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.75f, 0.5f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 4); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, 0x0C000); InputController_gamepadAxisMoved(inputController, &device1_2, 1, -0.375f, -0.5f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 5); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, -0x08000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, -0x06000); // 2D motion with inner and outer dead zones InputMap_unbindLogicalAxisMotion1D(inputMap, ATOM("a"), GAMEPAD_LEFT_STICK_X); InputMap_unbindLogicalAxisMotion1D(inputMap, ATOM("b"), GAMEPAD_LEFT_STICK_Y); InputMap_bindLogicalAxisMotion2D(inputMap, ATOM("c"), GAMEPAD_LEFT_STICK_X, GAMEPAD_LEFT_STICK_Y); inputController->gamepadInputController->analogStickInnerDeadZone = 0.25f; inputController->gamepadInputController->analogStickOuterDeadZone = 0.25f; motionCallCount = 0; InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.0f, 0.3125f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 1); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x00000); TestCase_assertFixed16_16Equal(lastMotionEvent.valueY, 0x00000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, 0x00000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueY, 0x00000); InputController_gamepadAxisMoved(inputController, &device1_2, 1, 0.625f, 0.25f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 2); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x00000); TestCase_assertFixed16_16Equal(lastMotionEvent.valueY, 0x0C000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, 0x00000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueY, 0x0A000); InputController_gamepadAxisMoved(inputController, &device1_2, 1, -0.75f, 0.625f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 3); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x00000); TestCase_assertFixed16_16Equal(lastMotionEvent.valueY, -0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, 0x00000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueY, -0x0C000); InputController_gamepadAxisMoved(inputController, &device1_2, 0, -1.0f, 0.0f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 4); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, -0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.valueY, -0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, -0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueY, -0x0C000); // 2D motion with axis center dead zone (this is actually the same thing as inner dead zone above; used to be a separate mechanism) inputController->gamepadInputController->analogStickInnerDeadZone = 0.25f; inputController->gamepadInputController->analogStickOuterDeadZone = 0.0f; InputController_gamepadAxisMoved(inputController, &device1_2, 1, 0.0f, 0.0f, 0.0, false); motionCallCount = 0; InputController_gamepadAxisMoved(inputController, &device1_2, 0, 1.0f, 0.0f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 1); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.valueY, 0x00000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, 0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueY, 0x00000); InputController_gamepadAxisMoved(inputController, &device1_2, 1, 0.25f, 0.0f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 2); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.valueY, 0x00000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, 0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueY, 0x04000); InputController_gamepadAxisMoved(inputController, &device1_2, 1, 0.625f, 0.25f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 3); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.valueY, 0x08000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, 0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueY, 0x0A000); InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.4375f, 1.0f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 4); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x04000); TestCase_assertFixed16_16Equal(lastMotionEvent.valueY, 0x08000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, 0x07000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueY, 0x0A000); InputController_dispose(inputController); InputMap_dispose(inputMap); GamepadMap_dispose(gamepadMap); } static void testAnalogTriggerDeadZones(void) { GamepadMap * gamepadMap = GamepadMap_create(); GamepadMap_registerHardwareElement(gamepadMap, 0x1, 0x2, GAMEPAD_ELEMENT_AXIS, 0, GAMEPAD_LEFT_BACK_SHOULDER, 1); GamepadMap_registerHardwareElement(gamepadMap, 0x1, 0x2, GAMEPAD_ELEMENT_AXIS, 1, GAMEPAD_RIGHT_BACK_SHOULDER, 1); InputMap * inputMap = InputMap_create(); InputMap_bindLogicalAxisMotion1D(inputMap, ATOM("a"), GAMEPAD_LEFT_BACK_SHOULDER); InputMap_bindLogicalAxisMotion1D(inputMap, ATOM("b"), GAMEPAD_RIGHT_BACK_SHOULDER); InputController * inputController = InputController_create(gamepadMap, inputMap, "a", "b", NULL); inputController->gamepadInputController->analogTriggerInnerDeadZone = 0.25f; inputController->gamepadInputController->analogTriggerOuterDeadZone = 0.5f; EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_MOTION), motion, NULL); motionCallCount = 0; struct Gamepad_device device1_2 = {.vendorID = 1, .productID = 2}; InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.25f, 0.0f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 1); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x00000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, 0x04000); InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.375f, 0.25f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 2); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x08000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, 0x06000); InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.5f, 0.375f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 3); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, 0x08000); InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.75f, 0.5f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 4); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, 0x0C000); InputController_gamepadAxisMoved(inputController, &device1_2, 1, -0.375f, -0.5f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 5); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, -0x08000); TestCase_assertFixed16_16Equal(lastMotionEvent.rawValueX, -0x06000); InputController_dispose(inputController); InputMap_dispose(inputMap); GamepadMap_dispose(gamepadMap); } static void testLogicalAxisActivateThresholds(void) { GamepadMap * gamepadMap = GamepadMap_create(); GamepadMap_registerHardwareElement(gamepadMap, 0x1, 0x2, GAMEPAD_ELEMENT_AXIS, 0, GAMEPAD_LEFT_STICK_X, 1); GamepadMap_registerHardwareElement(gamepadMap, 0x1, 0x2, GAMEPAD_ELEMENT_AXIS, 1, GAMEPAD_LEFT_BACK_SHOULDER, 1); InputMap * inputMap = InputMap_create(); InputMap_bindLogicalAxisAction(inputMap, ATOM("a"), GAMEPAD_LEFT_STICK_X, 1); InputMap_bindLogicalAxisAction(inputMap, ATOM("b"), GAMEPAD_LEFT_STICK_X, -1); InputMap_bindLogicalAxisAction(inputMap, ATOM("c"), GAMEPAD_LEFT_BACK_SHOULDER, 1); InputController * inputController = InputController_create(gamepadMap, inputMap, "a", "b", "c", NULL); inputController->gamepadInputController->analogStickActionActivateThreshold = 0.5f; inputController->gamepadInputController->analogStickActionReleaseThreshold = 0.25f; inputController->gamepadInputController->analogTriggerActionActivateThreshold = -0.75f; inputController->gamepadInputController->analogTriggerActionReleaseThreshold = -0.5f; EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_DOWN), actionDown, NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_UP), actionUp, NULL); actionDownCallCount = 0; actionUpCallCount = 0; struct Gamepad_device device1_2 = {.vendorID = 1, .productID = 2}; // +x activate at >= 0.5 InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.375f, 0.0f, 0.0, false); TestCase_assertUIntEqual(actionDownCallCount, 0); InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.4999f, 0.375f, 0.0, false); TestCase_assertUIntEqual(actionDownCallCount, 0); InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.5f, 0.4999f, 0.0, false); TestCase_assertUIntEqual(actionDownCallCount, 1); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); InputController_gamepadAxisMoved(inputController, &device1_2, 0, 1.0f, 0.5f, 0.0, false); TestCase_assertUIntEqual(actionDownCallCount, 1); // +x release at <= 0.25 InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.2501f, 1.0f, 0.0, false); TestCase_assertUIntEqual(actionUpCallCount, 0); InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.25f, 0.2501f, 0.0, false); TestCase_assertUIntEqual(actionUpCallCount, 1); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("a")); InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.0f, 0.25f, 0.0, false); TestCase_assertUIntEqual(actionUpCallCount, 1); // -x activate at <= -0.5 InputController_gamepadAxisMoved(inputController, &device1_2, 0, -0.375f, 0.0f, 0.0, false); TestCase_assertUIntEqual(actionDownCallCount, 1); InputController_gamepadAxisMoved(inputController, &device1_2, 0, -0.4999f, -0.375f, 0.0, false); TestCase_assertUIntEqual(actionDownCallCount, 1); InputController_gamepadAxisMoved(inputController, &device1_2, 0, -0.5f, -0.4999f, 0.0, false); TestCase_assertUIntEqual(actionDownCallCount, 2); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("b")); InputController_gamepadAxisMoved(inputController, &device1_2, 0, -1.0f, -0.5f, 0.0, false); TestCase_assertUIntEqual(actionDownCallCount, 2); // -x release at >= -0.25 InputController_gamepadAxisMoved(inputController, &device1_2, 0, -0.2501f, -1.0f, 0.0, false); TestCase_assertUIntEqual(actionUpCallCount, 1); InputController_gamepadAxisMoved(inputController, &device1_2, 0, -0.25f, -0.2501f, 0.0, false); TestCase_assertUIntEqual(actionUpCallCount, 2); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("b")); InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.0f, -0.25f, 0.0, false); TestCase_assertUIntEqual(actionUpCallCount, 2); // +x activate at >= 0.75 inputController->gamepadInputController->analogStickActionActivateThreshold = 0.75f; inputController->gamepadInputController->analogStickActionReleaseThreshold = 0.625f; InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.7499f, 0.0f, 0.0, false); TestCase_assertUIntEqual(actionDownCallCount, 2); InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.75f, 0.7499f, 0.0, false); TestCase_assertUIntEqual(actionDownCallCount, 3); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); // +x release at <= 0.625 InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.6251f, 0.75f, 0.0, false); TestCase_assertUIntEqual(actionUpCallCount, 2); InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.625f, 0.6251f, 0.0, false); TestCase_assertUIntEqual(actionUpCallCount, 3); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("a")); // trigger activate at -0.75 InputController_gamepadAxisMoved(inputController, &device1_2, 1, -0.7501f, -1.0f, 0.0, false); TestCase_assertUIntEqual(actionDownCallCount, 3); InputController_gamepadAxisMoved(inputController, &device1_2, 1, -0.75f, -0.7501f, 0.0, false); TestCase_assertUIntEqual(actionDownCallCount, 4); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("c")); InputController_gamepadAxisMoved(inputController, &device1_2, 1, 1.0f, -0.75f, 0.0, false); TestCase_assertUIntEqual(actionDownCallCount, 4); // trigger release at -0.5 InputController_gamepadAxisMoved(inputController, &device1_2, 1, -0.4999f, 1.0f, 0.0, false); TestCase_assertUIntEqual(actionUpCallCount, 3); InputController_gamepadAxisMoved(inputController, &device1_2, 1, -0.5f, -0.4999f, 0.0, false); TestCase_assertUIntEqual(actionUpCallCount, 4); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("c")); InputController_gamepadAxisMoved(inputController, &device1_2, 1, -1.0f, -0.5f, 0.0, false); TestCase_assertUIntEqual(actionUpCallCount, 4); InputController_dispose(inputController); InputMap_dispose(inputMap); GamepadMap_dispose(gamepadMap); } static void testMouseSensitivity(void) { InputMap * inputMap = InputMap_create(); InputMap_bindMouseMotion1D(inputMap, ATOM("a"), 0); InputMap_bindMouseMotion1D(inputMap, ATOM("b"), 1); InputController * inputController = InputController_create(NULL, inputMap, "a", "b", "c", NULL); inputController->mouseSensitivityX = 0.5f; inputController->mouseSensitivityY = 0.25f; EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_MOTION), motion, NULL); motionCallCount = 0; InputController_mouseMoved(inputController, 1.0f, 0.0f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 1); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x08000); InputController_mouseMoved(inputController, 0.0f, -2.0f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 2); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, -0x08000); InputController_mouseMoved(inputController, -1.0f, 1.0f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 4); TestCase_assertFixed16_16Equal(lastLastMotionEvent.valueX, -0x08000); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x04000); inputController->mouseSensitivityX = 2.0f; inputController->mouseSensitivityY = 1.5f; InputController_mouseMoved(inputController, 0.5f, -1.0f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 6); TestCase_assertFixed16_16Equal(lastLastMotionEvent.valueX, 0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, -0x18000); InputMap_unbindMouseMotion1D(inputMap, ATOM("a"), 0); InputMap_unbindMouseMotion1D(inputMap, ATOM("b"), 1); InputMap_bindMouseMotion2D(inputMap, ATOM("c")); motionCallCount = 0; InputController_mouseMoved(inputController, 1.0f, 1.0f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 1); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x20000); TestCase_assertFixed16_16Equal(lastMotionEvent.valueY, 0x18000); inputController->mouseSensitivityX = 0.5f; inputController->mouseSensitivityY = 0.25f; InputController_mouseMoved(inputController, 2.0f, -2.0f, 0.0, false); TestCase_assertUIntEqual(motionCallCount, 2); TestCase_assertFixed16_16Equal(lastMotionEvent.valueX, 0x10000); TestCase_assertFixed16_16Equal(lastMotionEvent.valueY, -0x08000); InputController_dispose(inputController); InputMap_dispose(inputMap); } static void testLogicalGamepadElementEquivalents(void) { GamepadMap * gamepadMap = GamepadMap_create(); GamepadMap_registerHardwareElement(gamepadMap, 0x1, 0x2, GAMEPAD_ELEMENT_AXIS, 0, GAMEPAD_DPAD_X, 1); GamepadMap_registerHardwareElement(gamepadMap, 0x1, 0x2, GAMEPAD_ELEMENT_AXIS, 1, GAMEPAD_DPAD_Y, 1); GamepadMap_registerHardwareElement(gamepadMap, 0x1, 0x2, GAMEPAD_ELEMENT_AXIS, 2, GAMEPAD_LEFT_STICK_X, 1); GamepadMap_registerHardwareElement(gamepadMap, 0x1, 0x2, GAMEPAD_ELEMENT_AXIS, 3, GAMEPAD_LEFT_STICK_Y, 1); GamepadMap_registerHardwareElement(gamepadMap, 0x1, 0x2, GAMEPAD_ELEMENT_AXIS, 4, GAMEPAD_RIGHT_STICK_X, 1); GamepadMap_registerHardwareElement(gamepadMap, 0x1, 0x2, GAMEPAD_ELEMENT_AXIS, 5, GAMEPAD_RIGHT_STICK_Y, 1); GamepadMap_registerHardwareElement(gamepadMap, 0x3, 0x4, GAMEPAD_ELEMENT_BUTTON, 0, GAMEPAD_DPAD_LEFT, 0); GamepadMap_registerHardwareElement(gamepadMap, 0x3, 0x4, GAMEPAD_ELEMENT_BUTTON, 1, GAMEPAD_DPAD_RIGHT, 0); GamepadMap_registerHardwareElement(gamepadMap, 0x3, 0x4, GAMEPAD_ELEMENT_BUTTON, 2, GAMEPAD_DPAD_DOWN, 0); GamepadMap_registerHardwareElement(gamepadMap, 0x3, 0x4, GAMEPAD_ELEMENT_BUTTON, 3, GAMEPAD_DPAD_UP, 0); GamepadMap_registerHardwareElement(gamepadMap, 0x3, 0x4, GAMEPAD_ELEMENT_BUTTON, 4, GAMEPAD_LEFT_STICK_LEFT, 0); GamepadMap_registerHardwareElement(gamepadMap, 0x3, 0x4, GAMEPAD_ELEMENT_BUTTON, 5, GAMEPAD_LEFT_STICK_RIGHT, 0); GamepadMap_registerHardwareElement(gamepadMap, 0x3, 0x4, GAMEPAD_ELEMENT_BUTTON, 6, GAMEPAD_LEFT_STICK_DOWN, 0); GamepadMap_registerHardwareElement(gamepadMap, 0x3, 0x4, GAMEPAD_ELEMENT_BUTTON, 7, GAMEPAD_LEFT_STICK_UP, 0); GamepadMap_registerHardwareElement(gamepadMap, 0x3, 0x4, GAMEPAD_ELEMENT_BUTTON, 8, GAMEPAD_RIGHT_STICK_LEFT, 0); GamepadMap_registerHardwareElement(gamepadMap, 0x3, 0x4, GAMEPAD_ELEMENT_BUTTON, 9, GAMEPAD_RIGHT_STICK_RIGHT, 0); GamepadMap_registerHardwareElement(gamepadMap, 0x3, 0x4, GAMEPAD_ELEMENT_BUTTON, 10, GAMEPAD_RIGHT_STICK_DOWN, 0); GamepadMap_registerHardwareElement(gamepadMap, 0x3, 0x4, GAMEPAD_ELEMENT_BUTTON, 11, GAMEPAD_RIGHT_STICK_UP, 0); InputMap * inputMap = InputMap_create(); InputMap_bindLogicalButtonAction(inputMap, ATOM("a"), GAMEPAD_DPAD_LEFT); InputMap_bindLogicalButtonAction(inputMap, ATOM("b"), GAMEPAD_DPAD_RIGHT); InputMap_bindLogicalButtonAction(inputMap, ATOM("c"), GAMEPAD_DPAD_DOWN); InputMap_bindLogicalButtonAction(inputMap, ATOM("d"), GAMEPAD_DPAD_UP); InputMap_bindLogicalButtonAction(inputMap, ATOM("e"), GAMEPAD_LEFT_STICK_LEFT); InputMap_bindLogicalButtonAction(inputMap, ATOM("f"), GAMEPAD_LEFT_STICK_RIGHT); InputMap_bindLogicalButtonAction(inputMap, ATOM("g"), GAMEPAD_LEFT_STICK_DOWN); InputMap_bindLogicalButtonAction(inputMap, ATOM("h"), GAMEPAD_LEFT_STICK_UP); InputMap_bindLogicalButtonAction(inputMap, ATOM("i"), GAMEPAD_RIGHT_STICK_LEFT); InputMap_bindLogicalButtonAction(inputMap, ATOM("j"), GAMEPAD_RIGHT_STICK_RIGHT); InputMap_bindLogicalButtonAction(inputMap, ATOM("k"), GAMEPAD_RIGHT_STICK_DOWN); InputMap_bindLogicalButtonAction(inputMap, ATOM("l"), GAMEPAD_RIGHT_STICK_UP); InputMap_bindLogicalAxisAction(inputMap, ATOM("m"), GAMEPAD_DPAD_X, -1); InputMap_bindLogicalAxisAction(inputMap, ATOM("n"), GAMEPAD_DPAD_X, 1); InputMap_bindLogicalAxisAction(inputMap, ATOM("o"), GAMEPAD_DPAD_Y, -1); InputMap_bindLogicalAxisAction(inputMap, ATOM("p"), GAMEPAD_DPAD_Y, 1); InputMap_bindLogicalAxisAction(inputMap, ATOM("q"), GAMEPAD_LEFT_STICK_X, -1); InputMap_bindLogicalAxisAction(inputMap, ATOM("r"), GAMEPAD_LEFT_STICK_X, 1); InputMap_bindLogicalAxisAction(inputMap, ATOM("s"), GAMEPAD_LEFT_STICK_Y, -1); InputMap_bindLogicalAxisAction(inputMap, ATOM("t"), GAMEPAD_LEFT_STICK_Y, 1); InputMap_bindLogicalAxisAction(inputMap, ATOM("u"), GAMEPAD_RIGHT_STICK_X, -1); InputMap_bindLogicalAxisAction(inputMap, ATOM("v"), GAMEPAD_RIGHT_STICK_X, 1); InputMap_bindLogicalAxisAction(inputMap, ATOM("w"), GAMEPAD_RIGHT_STICK_Y, -1); InputMap_bindLogicalAxisAction(inputMap, ATOM("x"), GAMEPAD_RIGHT_STICK_Y, 1); InputController * inputController = InputController_create(gamepadMap, inputMap, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_DOWN), actionDown, NULL); EventDispatcher_registerForEvent(inputController->eventDispatcher, ATOM(INPUT_CONTROLLER_EVENT_ACTION_UP), actionUp, NULL); actionDownCallCount = 0; actionUpCallCount = 0; struct Gamepad_device device1_2 = {.vendorID = 1, .productID = 2}; struct Gamepad_device device3_4 = {.vendorID = 3, .productID = 4}; bool handled = InputController_gamepadButtonDown(inputController, &device3_4, 0, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 2); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("a")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("m")); handled = InputController_gamepadButtonUp(inputController, &device3_4, 0, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 2); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("a")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("m")); handled = InputController_gamepadButtonDown(inputController, &device3_4, 1, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 4); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("b")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("n")); handled = InputController_gamepadButtonUp(inputController, &device3_4, 1, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 4); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("b")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("n")); handled = InputController_gamepadButtonDown(inputController, &device3_4, 2, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 6); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("c")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("o")); handled = InputController_gamepadButtonUp(inputController, &device3_4, 2, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 6); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("c")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("o")); handled = InputController_gamepadButtonDown(inputController, &device3_4, 3, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 8); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("d")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("p")); handled = InputController_gamepadButtonUp(inputController, &device3_4, 3, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 8); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("d")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("p")); handled = InputController_gamepadButtonDown(inputController, &device3_4, 4, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 10); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("e")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("q")); handled = InputController_gamepadButtonUp(inputController, &device3_4, 4, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 10); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("e")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("q")); handled = InputController_gamepadButtonDown(inputController, &device3_4, 5, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 12); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("f")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("r")); handled = InputController_gamepadButtonUp(inputController, &device3_4, 5, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 12); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("f")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("r")); handled = InputController_gamepadButtonDown(inputController, &device3_4, 6, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 14); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("g")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("s")); handled = InputController_gamepadButtonUp(inputController, &device3_4, 6, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 14); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("g")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("s")); handled = InputController_gamepadButtonDown(inputController, &device3_4, 7, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 16); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("h")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("t")); handled = InputController_gamepadButtonUp(inputController, &device3_4, 7, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 16); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("h")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("t")); handled = InputController_gamepadButtonDown(inputController, &device3_4, 8, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 18); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("i")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("u")); handled = InputController_gamepadButtonUp(inputController, &device3_4, 8, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 18); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("i")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("u")); handled = InputController_gamepadButtonDown(inputController, &device3_4, 9, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 20); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("j")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("v")); handled = InputController_gamepadButtonUp(inputController, &device3_4, 9, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 20); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("j")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("v")); handled = InputController_gamepadButtonDown(inputController, &device3_4, 10, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 22); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("k")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("w")); handled = InputController_gamepadButtonUp(inputController, &device3_4, 10, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 22); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("k")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("w")); handled = InputController_gamepadButtonDown(inputController, &device3_4, 11, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 24); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("l")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("x")); handled = InputController_gamepadButtonUp(inputController, &device3_4, 11, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 24); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("l")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("x")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 0, -1.0f, 0.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 26); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("m")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.0f, -1.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 26); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("m")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("a")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 0, 1.0f, 0.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 28); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("n")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("b")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 0, 0.0f, 1.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 28); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("n")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("b")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 1, -1.0f, 0.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 30); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("o")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("c")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 1, 0.0f, -1.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 30); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("o")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("c")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 1, 1.0f, 0.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 32); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("p")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("d")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 1, 0.0f, 1.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 32); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("p")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("d")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 2, -1.0f, 0.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 34); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("q")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("e")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 2, 0.0f, -1.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 34); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("q")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("e")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 2, 1.0f, 0.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 36); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("r")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("f")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 2, 0.0f, 1.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 36); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("r")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("f")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 3, -1.0f, 0.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 38); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("s")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("g")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 3, 0.0f, -1.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 38); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("s")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("g")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 3, 1.0f, 0.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 40); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("t")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("h")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 3, 0.0f, 1.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 40); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("t")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("h")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 4, -1.0f, 0.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 42); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("u")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("i")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 4, 0.0f, -1.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 42); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("u")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("i")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 4, 1.0f, 0.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 44); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("v")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("j")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 4, 0.0f, 1.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 44); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("v")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("j")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 5, -1.0f, 0.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 46); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("w")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("k")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 5, 0.0f, -1.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 46); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("w")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("k")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 5, 1.0f, 0.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 48); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("x")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("l")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 5, 0.0f, 1.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 48); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("x")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("l")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 0, -1.0f, 0.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionDownCallCount, 50); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("m")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("a")); handled = InputController_gamepadAxisMoved(inputController, &device1_2, 0, 1.0f, -1.0f, 0.0, false); TestCase_assertBoolTrue(handled); TestCase_assertUIntEqual(actionUpCallCount, 50); TestCase_assertStringPointerEqual(lastLastActionUpEvent.actionID, ATOM("m")); TestCase_assertStringPointerEqual(lastActionUpEvent.actionID, ATOM("a")); TestCase_assertUIntEqual(actionDownCallCount, 52); TestCase_assertStringPointerEqual(lastLastActionDownEvent.actionID, ATOM("n")); TestCase_assertStringPointerEqual(lastActionDownEvent.actionID, ATOM("b")); InputController_dispose(inputController); InputMap_dispose(inputMap); GamepadMap_dispose(gamepadMap); } TEST_SUITE(InputControllerTest, testInit, testActions, testKeyboardBindings, testKeyboardBindingsWithModifiers, testKeyModifierBindings, testMouseButtonBindings, testMouseScrollBindings, testMouseMotion1DBindings, testMouseMotion2DBindings, testPhysicalButtonBindings, testPhysicalAxisActionBindings, testPhysicalAxisMotionBindings, testLogicalGamepadBindings, testLogicalMotion1DBindings, testLogicalMotion2DBindings, testAnalogStickDeadZones, testAnalogTriggerDeadZones, testLogicalAxisActivateThresholds, testMouseSensitivity, testLogicalGamepadElementEquivalents)