/** * @brief Initializes force feedback for the loaded device. */ static void joystick_initHaptic (void) { #if SDL_VERSION_ATLEAST(1,3,0) if (has_haptic && SDL_JoystickIsHaptic(joystick)) { /* Close haptic if already open. */ if (haptic != NULL) { SDL_HapticClose(haptic); haptic = NULL; } /* Try to create haptic device. */ haptic = SDL_HapticOpenFromJoystick(joystick); if (haptic == NULL) { WARN("Unable to initialize force feedback: %s", SDL_GetError()); return; } /* Check to see what it supports. */ haptic_query = SDL_HapticQuery(haptic); if (!(haptic_query & SDL_HAPTIC_SINE)) { SDL_HapticClose(haptic); haptic = NULL; return; } DEBUG(" force feedback enabled"); } #endif /* SDL_VERSION_ATLEAST(1,3,0) */ }
void refresh_controllers() { for (s32 i = 0; i < MAX_GAMEPADS; i++) { if (haptics[i]) { SDL_HapticClose(haptics[i]); haptics[i] = nullptr; } if (controllers[i]) { SDL_GameControllerClose(controllers[i]); controllers[i] = nullptr; } } for (s32 i = 0; i < SDL_NumJoysticks(); i++) { if (SDL_IsGameController(i)) { controllers[i] = SDL_GameControllerOpen(i); SDL_Joystick* joystick = SDL_GameControllerGetJoystick(controllers[i]); if (SDL_JoystickIsHaptic(joystick)) { haptics[i] = SDL_HapticOpenFromJoystick(joystick); if (SDL_HapticRumbleInit(haptics[i])) // failed { SDL_HapticClose(haptics[i]); haptics[i] = nullptr; } } } } }
void JoyInitHaptic() { #if 0 uint8_t i; unsigned int haptic_query = 0; for (i = 0; i < 2; i++) { if (g.PadState[i].JoyDev && SDL_JoystickIsHaptic(g.PadState[i].JoyDev)) { if (g.PadState[i].haptic != NULL) { SDL_HapticClose(g.PadState[i].haptic); g.PadState[i].haptic = NULL; } g.PadState[i].haptic = SDL_HapticOpenFromJoystick(g.PadState[i].JoyDev); if (g.PadState[i].haptic == NULL) continue; if (SDL_HapticRumbleSupported(g.PadState[i].haptic) == SDL_FALSE) { printf("\nRumble not supported\n"); g.PadState[i].haptic = NULL; continue; } if (SDL_HapticRumbleInit(g.PadState[i].haptic) != 0) { printf("\nFailed to initialize rumble: %s\n", SDL_GetError()); g.PadState[i].haptic = NULL; continue; } } } #endif }
bool JoystickInfo::Init(int id) { Destroy(); _id = id; joy = SDL_JoystickOpen(id); if (joy == NULL) { PAD_LOG("failed to open joystick %d\n", id); return false; } numaxes = SDL_JoystickNumAxes(joy); numbuttons = SDL_JoystickNumButtons(joy); numhats = SDL_JoystickNumHats(joy); #if SDL_MAJOR_VERSION >= 2 devname = SDL_JoystickName(joy); #else devname = SDL_JoystickName(id); #endif vaxisstate.resize(numaxes); vbuttonstate.resize(numbuttons); vhatstate.resize(numhats); // Sixaxis, dualshock3 hack // Most buttons are actually axes due to analog pressure support. Only the first 4 buttons // are digital (select, start, l3, r3). To avoid conflict just forget the others. // Keep the 4 hat buttons too (usb driver). (left pressure does not work with recent kernel). Moreover the pressure // work sometime on half axis neg others time in fulll axis. So better keep them as button for the moment u32 found_hack = devname.find(string("PLAYSTATION(R)3")); if (found_hack != string::npos && numaxes > 4) { numbuttons = 4; // (select, start, l3, r3) // Enable this hack in bluetooth too. It avoid to restart the onepad gui numbuttons += 4; // the 4 hat buttons } #if SDL_MAJOR_VERSION >= 2 if ( haptic == NULL ) { if (!SDL_JoystickIsHaptic(joy)) { PAD_LOG("Haptic devices not supported!\n"); } else { haptic = SDL_HapticOpenFromJoystick(joy); // upload some default effect InitHapticEffect(); } } #endif //PAD_LOG("There are %d buttons, %d axises, and %d hats.\n", numbuttons, numaxes, numhats); return true; }
int _create_controler(int i) { SDL_GameController *controller = SDL_GameControllerOpen(i); SDL_Joystick *joy = SDL_GameControllerGetJoystick(controller); int idx = _new_controler(); _G.controller[idx] = controller; memory_set(_G.state[idx], 0, sizeof(int) * GAMEPAD_BTN_MAX); if (SDL_JoystickIsHaptic(joy) == 1) { SDL_Haptic *haptic = SDL_HapticOpenFromJoystick(joy); SDL_HapticRumbleInit(haptic); _G.haptic[idx] = haptic; log_info("input.gamepad", "Gamepad %d has haptic support", i); } else { _G.haptic[idx] = NULL; } return idx; }
bool SdlJoystick::init() { #if SDL_VERSION_ATLEAST(1,3,0) SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC); #else SDL_Init(SDL_INIT_JOYSTICK); #endif if (mDeviceNumber >= SDL_NumJoysticks()) { vprDEBUG(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL) << clrOutBOLD(clrRED, "ERROR") << ": Added for joystick number " << mDeviceNumber << " but there are only " << SDL_NumJoysticks() << " joysticks.\n" << vprDEBUG_FLUSH; return false; } mJoystick = SDL_JoystickOpen(mDeviceNumber); if (!mJoystick) { vprDEBUG(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL) << "ERROR: Failed to open joystick " << mDeviceNumber << ": " << SDL_GetError(); return false; } mButtons.resize(SDL_JoystickNumButtons(mJoystick), gadget::DigitalState::OFF); mAxes.resize(SDL_JoystickNumAxes(mJoystick), 0.0f); gadget::Digital::addDigitalSample(mButtons); gadget::Analog::addAnalogSample(mAxes); cout << "Found Joystick " << mDeviceNumber << ": " << SDL_JoystickName(mDeviceNumber) << endl << " Axis: " << mAxes.size() << endl << " Buttons: " << mButtons.size() << endl << " Hats: " << SDL_JoystickNumHats(mJoystick) << " (Unused)" << endl << " Balls: " << SDL_JoystickNumBalls(mJoystick) << " (Unused)" << endl #if SDL_VERSION_ATLEAST(1,3,0) << " Haptics: " << (SDL_JoystickIsHaptic(mJoystick) ? "YES" : "NO") #else << " Haptics: Not supported by SDL 1.2" #endif << endl; #if SDL_VERSION_ATLEAST(1,3,0) if (SDL_JoystickIsHaptic(mJoystick)) { mHaptic = SDL_HapticOpenFromJoystick(mJoystick); if (!mHaptic) { vprDEBUG(gadgetDBG_INPUT_MGR, vprDBG_CRITICAL_LVL) << "ERROR: Failed to initialize haptics on " << mDeviceNumber << ": " << SDL_GetError(); return true; } unsigned int cap = getCapabilities(); cout << " Loaded Effects: " << getMaxStoredEffects() << endl << " Played Effects: " << getMaxPlayingEffects() << endl << " Axes Count: " << getNumAxes() << endl << " Support for:"; if (cap & RumbleEffect::CONSTANT) cout << " constant"; if (cap & RumbleEffect::SINE) cout << " sine"; if (cap & RumbleEffect::SQUARE) cout << " square"; if (cap & RumbleEffect::TRIANGLE) cout << " triangle"; if (cap & RumbleEffect::SAWTOOTHUP) cout << " saw-tooth-up"; if (cap & RumbleEffect::SAWTOOTHDOWN) cout << " saw-tooth-down"; if (cap & RumbleEffect::RAMP) cout << " ramp"; if (cap & RumbleEffect::SPRING) cout << " spring"; if (cap & RumbleEffect::DAMPER) cout << " damper"; if (cap & RumbleEffect::INERTIA) cout << " inertia"; if (cap & RumbleEffect::FRICTION) cout << " friction"; if (cap & RumbleEffect::CUSTOM) cout << " custom"; if (cap & RumbleEffect::GAIN) cout << " gain"; if (cap & RumbleEffect::AUTOCENTER) cout << " auto-center"; if (cap & RumbleEffect::STATUS) cout << " status"; if (cap & RumbleEffect::PAUSE) cout << " pause"; cout << endl; } #endif mInitialized = true; return true; }
int main(int argc, char *argv[]) { SDL_Joystick *joystick = NULL; SDL_Haptic *haptic = NULL; SDL_JoystickID instance = -1; SDL_bool keepGoing = SDL_TRUE; int i; SDL_bool enable_haptic = SDL_TRUE; Uint32 init_subsystems = SDL_INIT_VIDEO | SDL_INIT_JOYSTICK; for (i = 1; i < argc; ++i) { if (SDL_strcasecmp(argv[i], "--nohaptic") == 0) { enable_haptic = SDL_FALSE; } } if(enable_haptic) { init_subsystems |= SDL_INIT_HAPTIC; } /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); /* Initialize SDL (Note: video is required to start event loop) */ if (SDL_Init(init_subsystems) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); exit(1); } //SDL_CreateWindow("Dummy", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 128, 128, 0); SDL_Log("There are %d joysticks at startup\n", SDL_NumJoysticks()); if (enable_haptic) SDL_Log("There are %d haptic devices at startup\n", SDL_NumHaptics()); while(keepGoing) { SDL_Event event; while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_QUIT: keepGoing = SDL_FALSE; break; case SDL_JOYDEVICEADDED: if (joystick != NULL) { SDL_Log("Only one joystick supported by this test\n"); } else { joystick = SDL_JoystickOpen(event.jdevice.which); instance = SDL_JoystickInstanceID(joystick); SDL_Log("Joy Added : %d : %s\n", event.jdevice.which, SDL_JoystickName(joystick)); if (enable_haptic) { if (SDL_JoystickIsHaptic(joystick)) { haptic = SDL_HapticOpenFromJoystick(joystick); if (haptic) { SDL_Log("Joy Haptic Opened\n"); if (SDL_HapticRumbleInit( haptic ) != 0) { SDL_Log("Could not init Rumble!: %s\n", SDL_GetError()); SDL_HapticClose(haptic); haptic = NULL; } } else { SDL_Log("Joy haptic open FAILED!: %s\n", SDL_GetError()); } } else { SDL_Log("No haptic found\n"); } } } break; case SDL_JOYDEVICEREMOVED: if (instance == event.jdevice.which) { SDL_Log("Joy Removed: %d\n", event.jdevice.which); instance = -1; if(enable_haptic && haptic) { SDL_HapticClose(haptic); haptic = NULL; } SDL_JoystickClose(joystick); joystick = NULL; } else { SDL_Log("Unknown joystick diconnected\n"); } break; case SDL_JOYAXISMOTION: // SDL_Log("Axis Move: %d\n", event.jaxis.axis); if (enable_haptic) SDL_HapticRumblePlay(haptic, 0.25, 250); break; case SDL_JOYBUTTONDOWN: SDL_Log("Button Press: %d\n", event.jbutton.button); if(enable_haptic && haptic) { SDL_HapticRumblePlay(haptic, 0.25, 250); } if (event.jbutton.button == 0) { SDL_Log("Exiting due to button press of button 0\n"); keepGoing = SDL_FALSE; } break; case SDL_JOYBUTTONUP: SDL_Log("Button Release: %d\n", event.jbutton.button); break; } } } SDL_Quit(); return 0; }
FDeviceInfoSDL FDeviceSDL::AddDevice(FDeviceIndex DeviceIndex) { FDeviceInfoSDL Device; if (SDL_IsGameController(DeviceIndex.value) && bIgnoreGameControllers) { // Let UE handle it return Device; } Device.DeviceIndex = DeviceIndex; Device.Joystick = SDL_JoystickOpen(DeviceIndex.value); if (Device.Joystick == nullptr) { return Device; } Device.InstanceId = FInstanceId(SDL_JoystickInstanceID(Device.Joystick)); // DEBUG Device.Name = FString(ANSI_TO_TCHAR(SDL_JoystickName(Device.Joystick))); UE_LOG(JoystickPluginLog, Log, TEXT("--- %s"), *Device.Name); UE_LOG(JoystickPluginLog, Log, TEXT("--- Number of Axis %i"), SDL_JoystickNumAxes(Device.Joystick)); UE_LOG(JoystickPluginLog, Log, TEXT("--- Number of Balls %i"), SDL_JoystickNumBalls(Device.Joystick)); UE_LOG(JoystickPluginLog, Log, TEXT("--- Number of Buttons %i"), SDL_JoystickNumButtons(Device.Joystick)); UE_LOG(JoystickPluginLog, Log, TEXT("--- Number of Hats %i"), SDL_JoystickNumHats(Device.Joystick)); if (SDL_JoystickIsHaptic(Device.Joystick)) { Device.Haptic = SDL_HapticOpenFromJoystick(Device.Joystick); if (Device.Haptic != nullptr) { UE_LOG(JoystickPluginLog, Log, TEXT("--- Rumble device detected")); if (SDL_HapticRumbleInit(Device.Haptic) != 0) { /*UE_LOG(JoystickPluginLog, Log, TEXT("--- testing Rumble device:")); if (SDL_HapticRumblePlay(OutDeviceInfo.Haptic, 0.5, 2000) != 0) { UE_LOG(JoystickPluginLog, Log, TEXT("--- play Rumble ....")); SDL_Delay(2000); } else { UE_LOG(JoystickPluginLog, Log, TEXT("--- not successful!")); SDL_HapticClose(OutDeviceInfo.Haptic); OutDeviceInfo.Haptic = nullptr; }*/ } } } for (auto &ExistingDevice : Devices) { if (ExistingDevice.Value.Joystick == nullptr && ExistingDevice.Value.Name == Device.Name) { Device.DeviceId = ExistingDevice.Key; Devices[Device.DeviceId] = Device; DeviceMapping.Add(Device.InstanceId, Device.DeviceId); EventInterface->JoystickPluggedIn(Device); return Device; } } Device.DeviceId = FDeviceId(Devices.Num()); Devices.Add(Device.DeviceId, Device); DeviceMapping.Add(Device.InstanceId, Device.DeviceId); EventInterface->JoystickPluggedIn(Device); return Device; }