extern "C" jboolean JNICALL Java_org_ppsspp_ppsspp_NativeApp_accelerometer(JNIEnv *, jclass, float x, float y, float z) { if (!renderer_inited) return false; // Theoretically this needs locking but I doubt it matters. Worst case, the X // from one "sensor frame" will be used together with Y from the next. // Should look into quantization though, for compressed movement storage. input_state.accelerometer_valid = true; input_state.acc.x = x; input_state.acc.y = y; input_state.acc.z = z; AxisInput axis; axis.deviceId = DEVICE_ID_ACCELEROMETER; axis.flags = 0; axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_X; axis.value = x; bool retvalX = NativeAxis(axis); axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Y; axis.value = y; bool retvalY = NativeAxis(axis); axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Z; axis.value = z; bool retvalZ = NativeAxis(axis); return retvalX || retvalY || retvalZ; }
void MainUI::updateAccelerometer() { #if defined(MOBILE_DEVICE) && !defined(MAEMO) // TODO: Toggle it depending on whether it is enabled QAccelerometerReading *reading = acc->reading(); if (reading) { input_state.acc.x = reading->x(); input_state.acc.y = reading->y(); input_state.acc.z = reading->z(); AxisInput axis; axis.deviceId = DEVICE_ID_ACCELEROMETER; axis.flags = 0; axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_X; axis.value = input_state.acc.x; NativeAxis(axis); axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Y; axis.value = input_state.acc.y; NativeAxis(axis); axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Z; axis.value = input_state.acc.z; NativeAxis(axis); } #endif }
void WindowsHost::PollControllers() { bool doPad = true; for (auto iter = this->input.begin(); iter != this->input.end(); iter++) { auto device = *iter; if (!doPad && device->IsPad()) continue; if (device->UpdateState() == InputDevice::UPDATESTATE_SKIP_PAD) doPad = false; } float scaleFactor_x = g_dpi_scale_x * 0.1 * g_Config.fMouseSensitivity; float scaleFactor_y = g_dpi_scale_y * 0.1 * g_Config.fMouseSensitivity; float mx = std::max(-1.0f, std::min(1.0f, g_mouseDeltaX * scaleFactor_x)); float my = std::max(-1.0f, std::min(1.0f, g_mouseDeltaY * scaleFactor_y)); AxisInput axisX, axisY; axisX.axisId = JOYSTICK_AXIS_MOUSE_REL_X; axisX.deviceId = DEVICE_ID_MOUSE; axisX.value = mx; axisY.axisId = JOYSTICK_AXIS_MOUSE_REL_Y; axisY.deviceId = DEVICE_ID_MOUSE; axisY.value = my; // Disabled by default, needs a workaround to map to psp keys. if (g_Config.bMouseControl){ if (GetUIState() == UISTATE_INGAME || g_Config.bMapMouse) { if (fabsf(mx) > 0.01f) NativeAxis(axisX); if (fabsf(my) > 0.01f) NativeAxis(axisY); } } g_mouseDeltaX *= g_Config.fMouseSmoothing; g_mouseDeltaY *= g_Config.fMouseSmoothing; }
extern "C" jboolean Java_org_ppsspp_ppsspp_NativeApp_joystickAxis( JNIEnv *env, jclass, jint deviceId, jint axisId, jfloat value) { if (!renderer_inited) return false; switch (axisId) { case JOYSTICK_AXIS_X: left_joystick_x_async = value; break; case JOYSTICK_AXIS_Y: left_joystick_y_async = -value; break; case JOYSTICK_AXIS_Z: right_joystick_x_async = value; break; case JOYSTICK_AXIS_RZ: right_joystick_y_async = -value; break; case JOYSTICK_AXIS_HAT_X: hat_joystick_x_async = value; break; case JOYSTICK_AXIS_HAT_Y: hat_joystick_y_async = -value; break; } AxisInput axis; axis.axisId = axisId; axis.deviceId = deviceId; axis.value = value; return NativeAxis(axis); }
extern "C" void Java_com_henrikrydgard_libnative_NativeApp_joystickAxis( JNIEnv *env, jclass, jint deviceId, jint axisId, jfloat value) { if (!renderer_inited) return; switch (axisId) { case JOYSTICK_AXIS_X: left_joystick_x_async = value; break; case JOYSTICK_AXIS_Y: left_joystick_y_async = -value; break; case JOYSTICK_AXIS_Z: right_joystick_x_async = value; break; case JOYSTICK_AXIS_RZ: right_joystick_y_async = -value; break; case JOYSTICK_AXIS_HAT_X: hat_joystick_x_async = value; break; case JOYSTICK_AXIS_HAT_Y: hat_joystick_y_async = -value; break; } AxisInput axis; axis.axisId = axisId; axis.deviceId = deviceId; axis.value = value; NativeAxis(axis); }
void SendNativeAxis(int deviceId, short value, short &lastValue, int axisId) { if (value == lastValue) return; AxisInput axis; axis.deviceId = deviceId; axis.axisId = axisId; axis.value = NormalizedDeadzoneFilter(value); NativeAxis(axis); lastValue = value; }
extern "C" jboolean JNICALL Java_org_ppsspp_ppsspp_NativeApp_accelerometer(JNIEnv *, jclass, float x, float y, float z) { if (!renderer_inited) return false; AxisInput axis; axis.deviceId = DEVICE_ID_ACCELEROMETER; axis.flags = 0; axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_X; axis.value = x; bool retvalX = NativeAxis(axis); axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Y; axis.value = y; bool retvalY = NativeAxis(axis); axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Z; axis.value = z; bool retvalZ = NativeAxis(axis); return retvalX || retvalY || retvalZ; }
void SDLJoystick::ProcessInput(SDL_Event &event){ switch (event.type) { case SDL_JOYAXISMOTION: { std::map<int, int>::const_iterator i = SDLJoyAxisMap.find(event.jaxis.axis); if (i != SDLJoyAxisMap.end()) { AxisInput axis; axis.axisId = i->second; // 1.2 to try to approximate the PSP's clamped rectangular range. axis.value = 1.2 * event.jaxis.value / 32767.0f; if (axis.value > 1.0f) axis.value = 1.0f; if (axis.value < -1.0f) axis.value = -1.0f; axis.deviceId = DEVICE_ID_PAD_0 + event.jaxis.which; axis.flags = 0; NativeAxis(axis); } break; } case SDL_JOYBUTTONDOWN: { std::map<int, int>::const_iterator i = SDLJoyButtonMap.find(event.jbutton.button); if (i != SDLJoyButtonMap.end()) { KeyInput key; key.flags = KEY_DOWN; key.keyCode = i->second; key.deviceId = DEVICE_ID_PAD_0 + event.jbutton.which; NativeKey(key); } break; } case SDL_JOYBUTTONUP: { std::map<int, int>::const_iterator i = SDLJoyButtonMap.find(event.jbutton.button); if (i != SDLJoyButtonMap.end()) { KeyInput key; key.flags = KEY_UP; key.keyCode = i->second; key.deviceId = DEVICE_ID_PAD_0 + event.jbutton.which; NativeKey(key); } break; } case SDL_JOYHATMOTION: { #ifdef _WIN32 KeyInput key; key.deviceId = DEVICE_ID_PAD_0 + event.jhat.which; key.flags = (event.jhat.value & SDL_HAT_UP)?KEY_DOWN:KEY_UP; key.keyCode = NKCODE_DPAD_UP; NativeKey(key); key.flags = (event.jhat.value & SDL_HAT_LEFT)?KEY_DOWN:KEY_UP; key.keyCode = NKCODE_DPAD_LEFT; NativeKey(key); key.flags = (event.jhat.value & SDL_HAT_DOWN)?KEY_DOWN:KEY_UP; key.keyCode = NKCODE_DPAD_DOWN; NativeKey(key); key.flags = (event.jhat.value & SDL_HAT_RIGHT)?KEY_DOWN:KEY_UP; key.keyCode = NKCODE_DPAD_RIGHT; NativeKey(key); #else AxisInput axisX; AxisInput axisY; axisX.axisId = JOYSTICK_AXIS_HAT_X; axisY.axisId = JOYSTICK_AXIS_HAT_Y; axisX.deviceId = DEVICE_ID_PAD_0 + event.jhat.which; axisY.deviceId = DEVICE_ID_PAD_0 + event.jhat.which; axisX.value = 0.0f; axisY.value = 0.0f; if (event.jhat.value & SDL_HAT_LEFT) axisX.value = -1.0f; if (event.jhat.value & SDL_HAT_RIGHT) axisX.value = 1.0f; if (event.jhat.value & SDL_HAT_DOWN) axisY.value = 1.0f; if (event.jhat.value & SDL_HAT_UP) axisY.value = -1.0f; NativeAxis(axisX); NativeAxis(axisY); #endif break; } } }
int XinputDevice::UpdateState(InputState &input_state) { if (!s_pXInputDLL) return 0; if (this->check_delay-- > 0) return -1; XINPUT_STATE state; ZeroMemory( &state, sizeof(XINPUT_STATE) ); DWORD dwResult; if (this->gamepad_idx >= 0) dwResult = PPSSPP_XInputGetState( this->gamepad_idx, &state ); else { // use the first gamepad that responds for (int i = 0; i < XUSER_MAX_COUNT; i++) { dwResult = PPSSPP_XInputGetState( i, &state ); if (dwResult == ERROR_SUCCESS) { this->gamepad_idx = i; break; } } } if ( dwResult == ERROR_SUCCESS ) { ApplyButtons(state, input_state); if (prevState.Gamepad.sThumbLX != state.Gamepad.sThumbLX || prevState.Gamepad.sThumbLY != state.Gamepad.sThumbLY) { Stick left = NormalizedDeadzoneFilter(state.Gamepad.sThumbLX, state.Gamepad.sThumbLY); AxisInput axis; axis.deviceId = DEVICE_ID_X360_0; axis.axisId = JOYSTICK_AXIS_X; axis.value = left.x; NativeAxis(axis); axis.axisId = JOYSTICK_AXIS_Y; axis.value = left.y; NativeAxis(axis); } if (prevState.Gamepad.sThumbRX != state.Gamepad.sThumbRX || prevState.Gamepad.sThumbRY != state.Gamepad.sThumbRY) { Stick right = NormalizedDeadzoneFilter(state.Gamepad.sThumbRX, state.Gamepad.sThumbRY); AxisInput axis; axis.deviceId = DEVICE_ID_X360_0; axis.axisId = JOYSTICK_AXIS_Z; axis.value = right.x; NativeAxis(axis); axis.axisId = JOYSTICK_AXIS_RZ; axis.value = right.y; NativeAxis(axis); } if (prevState.Gamepad.bLeftTrigger != state.Gamepad.bLeftTrigger) { AxisInput axis; axis.deviceId = DEVICE_ID_X360_0; axis.axisId = JOYSTICK_AXIS_LTRIGGER; axis.value = (float)state.Gamepad.bLeftTrigger / 255.0f; NativeAxis(axis); } if (prevState.Gamepad.bRightTrigger != state.Gamepad.bRightTrigger) { AxisInput axis; axis.deviceId = DEVICE_ID_X360_0; axis.axisId = JOYSTICK_AXIS_RTRIGGER; axis.value = (float)state.Gamepad.bRightTrigger / 255.0f; NativeAxis(axis); } this->prevState = state; this->check_delay = 0; // If there's an XInput pad, skip following pads. This prevents DInput and XInput // from colliding. return UPDATESTATE_SKIP_PAD; } else { // wait check_delay frames before polling the controller again this->gamepad_idx = -1; this->check_delay = 100; return -1; } }
void BlackberryMain::runMain() { bool running = true; while (running && !g_quitRequested) { input_state.mouse_valid = false; input_state.accelerometer_valid = false; while (true) { // Handle Blackberry events bps_event_t *event = NULL; bps_get_event(&event, 0); if (event == NULL) break; // Ran out of events int domain = bps_event_get_domain(event); if (domain == screen_get_domain()) { handleInput(screen_event_get_event(event)); } else if (domain == navigator_get_domain()) { switch(bps_event_get_code(event)) { case NAVIGATOR_INVOKE_TARGET: { const navigator_invoke_invocation_t *invoke = navigator_invoke_event_get_invocation(event); if(invoke) { boot_filename = navigator_invoke_invocation_get_uri(invoke)+7; // Remove file:// } } break; case NAVIGATOR_ORIENTATION: sensor_remap_coordinates(navigator_event_get_orientation_angle(event)); break; case NAVIGATOR_BACK: case NAVIGATOR_SWIPE_DOWN: NativeKey(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_ESCAPE, KEY_DOWN)); break; case NAVIGATOR_EXIT: return; } } else if (domain == sensor_get_domain()) { if (SENSOR_ACCELEROMETER_READING == bps_event_get_code(event)) { sensor_event_get_xyz(event, &(input_state.acc.y), &(input_state.acc.x), &(input_state.acc.z)); AxisInput axis; axis.deviceId = DEVICE_ID_ACCELEROMETER; axis.flags = 0; axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_X; axis.value = input_state.acc.x; NativeAxis(axis); axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Y; axis.value = input_state.acc.y; NativeAxis(axis); axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Z; axis.value = input_state.acc.z; NativeAxis(axis); } } } UpdateInputState(&input_state); NativeUpdate(input_state); // Work in Progress // Currently: Render to HDMI port (eg. 1080p) when in game. Render to device when in menu. // Idea: Render to all displays. Controls go to internal, game goes to external(s). if (GetUIState() == UISTATE_INGAME && !emulating) { emulating = true; switchDisplay(screen_emu); if (g_Config.iShowFPSCounter == 4) { int options = SCREEN_DEBUG_STATISTICS; screen_set_window_property_iv(screen_win[0], SCREEN_PROPERTY_DEBUG, &options); } } else if (GetUIState() != UISTATE_INGAME && emulating) { emulating = false; switchDisplay(screen_ui); } NativeRender(); EndInputState(&input_state); time_update(); // This handles VSync if (emulating) eglSwapBuffers(egl_disp[screen_emu], egl_surf[screen_emu]); else eglSwapBuffers(egl_disp[screen_ui], egl_surf[screen_ui]); } }
void BlackberryMain::handleInput(screen_event_t screen_event) { TouchInput input; KeyInput key; int val, buttons, pointerId; int pair[2]; screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &val); screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_SOURCE_POSITION, pair); input_state.mouse_valid = true; switch(val) { // Touchscreen case SCREEN_EVENT_MTOUCH_TOUCH: case SCREEN_EVENT_MTOUCH_RELEASE: // Up, down screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TOUCH_ID, &pointerId); input_state.pointer_down[pointerId] = (val == SCREEN_EVENT_MTOUCH_TOUCH); input_state.pointer_x[pointerId] = pair[0] * g_dpi_scale; input_state.pointer_y[pointerId] = pair[1] * g_dpi_scale; input.x = pair[0] * g_dpi_scale; input.y = pair[1] * g_dpi_scale; input.flags = (val == SCREEN_EVENT_MTOUCH_TOUCH) ? TOUCH_DOWN : TOUCH_UP; input.id = pointerId; NativeTouch(input); break; case SCREEN_EVENT_MTOUCH_MOVE: screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TOUCH_ID, &pointerId); input_state.pointer_x[pointerId] = pair[0] * g_dpi_scale; input_state.pointer_y[pointerId] = pair[1] * g_dpi_scale; input.x = pair[0] * g_dpi_scale; input.y = pair[1] * g_dpi_scale; input.flags = TOUCH_MOVE; input.id = pointerId; NativeTouch(input); break; // Mouse, Simulator case SCREEN_EVENT_POINTER: screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_BUTTONS, &buttons); if (buttons == SCREEN_LEFT_MOUSE_BUTTON) { // Down input_state.pointer_x[0] = pair[0] * g_dpi_scale; input_state.pointer_y[0] = pair[1] * g_dpi_scale; input_state.pointer_down[0] = true; input.x = pair[0] * g_dpi_scale; input.y = pair[1] * g_dpi_scale; input.flags = TOUCH_DOWN; input.id = 0; NativeTouch(input); } else if (input_state.pointer_down[0]) { // Up input_state.pointer_x[0] = pair[0] * g_dpi_scale; input_state.pointer_y[0] = pair[1] * g_dpi_scale; input_state.pointer_down[0] = false; input.x = pair[0] * g_dpi_scale; input.y = pair[1] * g_dpi_scale; input.flags = TOUCH_UP; input.id = 0; NativeTouch(input); } break; // Keyboard case SCREEN_EVENT_KEYBOARD: int flags, value; screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_FLAGS, &flags); screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_SYM, &value); NativeKey(KeyInput(DEVICE_ID_KEYBOARD, KeyMapRawBlackberrytoNative.find(value)->second, (flags & KEY_DOWN) ? KEY_DOWN : KEY_UP)); break; // Gamepad case SCREEN_EVENT_GAMEPAD: case SCREEN_EVENT_JOYSTICK: int analog0[3]; screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_BUTTONS, &buttons); for (int i = 0; i < 32; i++) { int mask = 1 << i; if ((old_buttons & mask) != (buttons & mask)) NativeKey(KeyInput(DEVICE_ID_PAD_0, KeyMapPadBlackberrytoNative.find(mask)->second, (buttons & mask) ? KEY_DOWN : KEY_UP)); } if (!screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_ANALOG0, analog0)) { for (int i = 0; i < 2; i++) { AxisInput axis; axis.axisId = JOYSTICK_AXIS_X + i; // 1.2 to try to approximate the PSP's clamped rectangular range. axis.value = 1.2 * analog0[i] / 128.0f; if (axis.value > 1.0f) axis.value = 1.0f; if (axis.value < -1.0f) axis.value = -1.0f; axis.deviceId = DEVICE_ID_PAD_0; axis.flags = 0; NativeAxis(axis); } } old_buttons = buttons; break; case SCREEN_EVENT_DISPLAY: screen_display_t new_dpy = NULL; screen_get_event_property_pv(screen_event, SCREEN_PROPERTY_DISPLAY, (void **)&new_dpy); for (int i = 0; i < ndisplays; i++) { if (new_dpy != screen_dpy[i]) continue; int active = 0; screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_ATTACHED, &active); if (active) { int size[2]; screen_get_display_property_iv(screen_dpy[i], SCREEN_PROPERTY_SIZE, size); if (size[0] == 0 || size[1] == 0) active = 0; } if (active && !displays[i].attached) realiseDisplay(i); else if (!active && displays[i].attached && displays[i].realised) unrealiseDisplay(i); displays[i].attached = active; } break; } }
int XinputDevice::UpdateState(InputState &input_state) { if (!s_pXInputDLL) return 0; if (this->check_delay-- > 0) return -1; XINPUT_STATE state; ZeroMemory( &state, sizeof(XINPUT_STATE) ); DWORD dwResult; if (this->gamepad_idx >= 0) { dwResult = PPSSPP_XInputGetState( this->gamepad_idx, &state ); } else { // use the first gamepad that responds for (int i = 0; i < XUSER_MAX_COUNT; i++) { dwResult = PPSSPP_XInputGetState( i, &state ); if (dwResult == ERROR_SUCCESS) { this->gamepad_idx = i; break; } } } if ( dwResult == ERROR_SUCCESS ) { static bool notified = false; if (!notified) { notified = true; KeyMap::NotifyPadConnected("Xbox 360 Pad"); } ApplyButtons(state, input_state); const float STICK_DEADZONE = g_Config.fXInputAnalogDeadzone; const int STICK_INV_MODE = g_Config.iXInputAnalogInverseMode; const float STICK_INV_DEADZONE = g_Config.fXInputAnalogInverseDeadzone; const float STICK_SENSITIVITY = g_Config.fXInputAnalogSensitivity; if (NormalizedDeadzoneDiffers(prevState.Gamepad.sThumbLX, prevState.Gamepad.sThumbLY, state.Gamepad.sThumbLX, state.Gamepad.sThumbLY, STICK_DEADZONE)) { Stick left = NormalizedDeadzoneFilter(state.Gamepad.sThumbLX, state.Gamepad.sThumbLY, STICK_DEADZONE, STICK_INV_MODE, STICK_INV_DEADZONE, STICK_SENSITIVITY); AxisInput axis; axis.deviceId = DEVICE_ID_X360_0; axis.axisId = JOYSTICK_AXIS_X; axis.value = left.x; if (prevState.Gamepad.sThumbLX != state.Gamepad.sThumbLX) { NativeAxis(axis); } axis.axisId = JOYSTICK_AXIS_Y; axis.value = left.y; if (prevState.Gamepad.sThumbLY != state.Gamepad.sThumbLY) { NativeAxis(axis); } } if (NormalizedDeadzoneDiffers(prevState.Gamepad.sThumbRX, prevState.Gamepad.sThumbRY, state.Gamepad.sThumbRX, state.Gamepad.sThumbRY, STICK_DEADZONE)) { Stick right = NormalizedDeadzoneFilter(state.Gamepad.sThumbRX, state.Gamepad.sThumbRY, STICK_DEADZONE, STICK_INV_MODE, STICK_INV_DEADZONE, STICK_SENSITIVITY); AxisInput axis; axis.deviceId = DEVICE_ID_X360_0; axis.axisId = JOYSTICK_AXIS_Z; axis.value = right.x; if (prevState.Gamepad.sThumbRX != state.Gamepad.sThumbRX) { NativeAxis(axis); } axis.axisId = JOYSTICK_AXIS_RZ; axis.value = right.y; if (prevState.Gamepad.sThumbRY != state.Gamepad.sThumbRY) { NativeAxis(axis); } } if (NormalizedDeadzoneDiffers(prevState.Gamepad.bLeftTrigger, state.Gamepad.bLeftTrigger, XINPUT_GAMEPAD_TRIGGER_THRESHOLD)) { AxisInput axis; axis.deviceId = DEVICE_ID_X360_0; axis.axisId = JOYSTICK_AXIS_LTRIGGER; axis.value = (float)state.Gamepad.bLeftTrigger / 255.0f; NativeAxis(axis); } if (NormalizedDeadzoneDiffers(prevState.Gamepad.bRightTrigger, state.Gamepad.bRightTrigger, XINPUT_GAMEPAD_TRIGGER_THRESHOLD)) { AxisInput axis; axis.deviceId = DEVICE_ID_X360_0; axis.axisId = JOYSTICK_AXIS_RTRIGGER; axis.value = (float)state.Gamepad.bRightTrigger / 255.0f; NativeAxis(axis); } this->prevState = state; this->check_delay = 0; // If there's an XInput pad, skip following pads. This prevents DInput and XInput // from colliding. return UPDATESTATE_SKIP_PAD; } else { // wait check_delay frames before polling the controller again this->gamepad_idx = -1; this->check_delay = 100; return -1; } }
void XinputDevice::UpdatePad(int pad, const XINPUT_STATE &state, InputState &input_state) { static bool notified = false; if (!notified) { notified = true; KeyMap::NotifyPadConnected("Xbox 360 Pad"); } ApplyButtons(pad, state, input_state); const float STICK_DEADZONE = g_Config.fXInputAnalogDeadzone; const int STICK_INV_MODE = g_Config.iXInputAnalogInverseMode; const float STICK_INV_DEADZONE = g_Config.fXInputAnalogInverseDeadzone; const float STICK_SENSITIVITY = g_Config.fXInputAnalogSensitivity; if (NormalizedDeadzoneDiffers(prevState[pad].Gamepad.sThumbLX, prevState[pad].Gamepad.sThumbLY, state.Gamepad.sThumbLX, state.Gamepad.sThumbLY, STICK_DEADZONE)) { Stick left = NormalizedDeadzoneFilter(state.Gamepad.sThumbLX, state.Gamepad.sThumbLY, STICK_DEADZONE, STICK_INV_MODE, STICK_INV_DEADZONE, STICK_SENSITIVITY); AxisInput axis; axis.deviceId = DEVICE_ID_X360_0 + pad; axis.axisId = JOYSTICK_AXIS_X; axis.value = left.x; if (prevState[pad].Gamepad.sThumbLX != state.Gamepad.sThumbLX) { NativeAxis(axis); } axis.axisId = JOYSTICK_AXIS_Y; axis.value = left.y; if (prevState[pad].Gamepad.sThumbLY != state.Gamepad.sThumbLY) { NativeAxis(axis); } } if (NormalizedDeadzoneDiffers(prevState[pad].Gamepad.sThumbRX, prevState[pad].Gamepad.sThumbRY, state.Gamepad.sThumbRX, state.Gamepad.sThumbRY, STICK_DEADZONE)) { Stick right = NormalizedDeadzoneFilter(state.Gamepad.sThumbRX, state.Gamepad.sThumbRY, STICK_DEADZONE, STICK_INV_MODE, STICK_INV_DEADZONE, STICK_SENSITIVITY); AxisInput axis; axis.deviceId = DEVICE_ID_X360_0 + pad; axis.axisId = JOYSTICK_AXIS_Z; axis.value = right.x; if (prevState[pad].Gamepad.sThumbRX != state.Gamepad.sThumbRX) { NativeAxis(axis); } axis.axisId = JOYSTICK_AXIS_RZ; axis.value = right.y; if (prevState[pad].Gamepad.sThumbRY != state.Gamepad.sThumbRY) { NativeAxis(axis); } } if (NormalizedDeadzoneDiffers(prevState[pad].Gamepad.bLeftTrigger, state.Gamepad.bLeftTrigger, XINPUT_GAMEPAD_TRIGGER_THRESHOLD)) { AxisInput axis; axis.deviceId = DEVICE_ID_X360_0 + pad; axis.axisId = JOYSTICK_AXIS_LTRIGGER; axis.value = (float)state.Gamepad.bLeftTrigger / 255.0f; NativeAxis(axis); } if (NormalizedDeadzoneDiffers(prevState[pad].Gamepad.bRightTrigger, state.Gamepad.bRightTrigger, XINPUT_GAMEPAD_TRIGGER_THRESHOLD)) { AxisInput axis; axis.deviceId = DEVICE_ID_X360_0 + pad; axis.axisId = JOYSTICK_AXIS_RTRIGGER; axis.value = (float)state.Gamepad.bRightTrigger / 255.0f; NativeAxis(axis); } this->prevState[pad] = state; this->check_delay[pad] = 0; }