forked from MeloNX/MeloNX
Fix for virtual controller detach
This commit is contained in:
parent
5009474e14
commit
0933d6f097
@ -35,44 +35,44 @@ class NativeController: Hashable {
|
|||||||
var joystickDesc = SDL_VirtualJoystickDesc(
|
var joystickDesc = SDL_VirtualJoystickDesc(
|
||||||
version: UInt16(SDL_VIRTUAL_JOYSTICK_DESC_VERSION),
|
version: UInt16(SDL_VIRTUAL_JOYSTICK_DESC_VERSION),
|
||||||
type: Uint16(SDL_JOYSTICK_TYPE_GAMECONTROLLER.rawValue),
|
type: Uint16(SDL_JOYSTICK_TYPE_GAMECONTROLLER.rawValue),
|
||||||
naxes: 6,
|
naxes: 6,
|
||||||
nbuttons: 15,
|
nbuttons: 15,
|
||||||
nhats: 1,
|
nhats: 1,
|
||||||
vendor_id: 0,
|
vendor_id: 0,
|
||||||
product_id: 0,
|
product_id: 0,
|
||||||
padding: 0,
|
padding: 0,
|
||||||
button_mask: 0,
|
button_mask: 0,
|
||||||
axis_mask: 0,
|
axis_mask: 0,
|
||||||
name: (controllername as NSString).utf8String,
|
name: (controllername as NSString).utf8String,
|
||||||
userdata: Unmanaged.passUnretained(self).toOpaque(),
|
userdata: Unmanaged.passUnretained(self).toOpaque(),
|
||||||
Update: { userdata in
|
Update: { _ in
|
||||||
// Update joystick state here
|
// Update joystick state here
|
||||||
},
|
},
|
||||||
SetPlayerIndex: { userdata, playerIndex in
|
SetPlayerIndex: { _, playerIndex in
|
||||||
print("Player index set to \(playerIndex)")
|
print("Player index set to \(playerIndex)")
|
||||||
},
|
},
|
||||||
Rumble: { userdata, lowFreq, highFreq in
|
Rumble: { userdata, lowFreq, highFreq in
|
||||||
print("Rumble with \(lowFreq), \(highFreq)")
|
print("Rumble with \(lowFreq), \(highFreq)")
|
||||||
guard let userdata else { return 0 }
|
guard let userdata else { return 0 }
|
||||||
let _self = Unmanaged<NativeController>.fromOpaque(userdata).takeUnretainedValue()
|
let _self = Unmanaged<NativeController>.fromOpaque(userdata).takeUnretainedValue()
|
||||||
VirtualController.rumble(lowFreq: Float(lowFreq), highFreq: Float(highFreq), engine: _self.controllerHaptics)
|
VirtualController.rumble(lowFreq: Float(lowFreq), highFreq: Float(highFreq), engine: _self.controllerHaptics)
|
||||||
return 0
|
return 0
|
||||||
},
|
},
|
||||||
RumbleTriggers: { userdata, leftRumble, rightRumble in
|
RumbleTriggers: { _, leftRumble, rightRumble in
|
||||||
print("Trigger rumble with \(leftRumble), \(rightRumble)")
|
print("Trigger rumble with \(leftRumble), \(rightRumble)")
|
||||||
return 0
|
return 0
|
||||||
},
|
},
|
||||||
SetLED: { userdata, red, green, blue in
|
SetLED: { _, red, green, blue in
|
||||||
print("Set LED to RGB(\(red), \(green), \(blue))")
|
print("Set LED to RGB(\(red), \(green), \(blue))")
|
||||||
return 0
|
return 0
|
||||||
},
|
},
|
||||||
SendEffect: { userdata, data, size in
|
SendEffect: { _, _, size in
|
||||||
print("Effect sent with size \(size)")
|
print("Effect sent with size \(size)")
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
instanceID = SDL_JoystickAttachVirtualEx(&joystickDesc)// SDL_JoystickAttachVirtual(SDL_JoystickType(SDL_JOYSTICK_TYPE_GAMECONTROLLER.rawValue), 6, 15, 1)
|
instanceID = SDL_JoystickAttachVirtualEx(&joystickDesc) // SDL_JoystickAttachVirtual(SDL_JoystickType(SDL_JOYSTICK_TYPE_GAMECONTROLLER.rawValue), 6, 15, 1)
|
||||||
if instanceID < 0 {
|
if instanceID < 0 {
|
||||||
print("Failed to create virtual joystick: \(String(cString: SDL_GetError()))")
|
print("Failed to create virtual joystick: \(String(cString: SDL_GetError()))")
|
||||||
return
|
return
|
||||||
@ -80,6 +80,10 @@ class NativeController: Hashable {
|
|||||||
|
|
||||||
// Open a game controller for the virtual joystick
|
// Open a game controller for the virtual joystick
|
||||||
let joystick = SDL_JoystickFromInstanceID(instanceID)
|
let joystick = SDL_JoystickFromInstanceID(instanceID)
|
||||||
|
if joystick == nil {
|
||||||
|
print("Failed to create virtual joystick: \(String(cString: SDL_GetError()))")
|
||||||
|
}
|
||||||
|
|
||||||
controller = SDL_GameControllerOpen(Int32(instanceID))
|
controller = SDL_GameControllerOpen(Int32(instanceID))
|
||||||
|
|
||||||
if controller == nil {
|
if controller == nil {
|
||||||
@ -140,7 +144,7 @@ class NativeController: Hashable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setupTriggerChangeListener(_ button: GCControllerButtonInput, for key: ThumbstickType) {
|
func setupTriggerChangeListener(_ button: GCControllerButtonInput, for key: ThumbstickType) {
|
||||||
button.valueChangedHandler = { [unowned self] _, value, pressed in
|
button.valueChangedHandler = { [unowned self] _, value, _ in
|
||||||
// print("Value: \(value), Is pressed: \(pressed)")
|
// print("Value: \(value), Is pressed: \(pressed)")
|
||||||
let axis: SDL_GameControllerAxis = (key == .left) ? SDL_CONTROLLER_AXIS_TRIGGERLEFT : SDL_CONTROLLER_AXIS_TRIGGERRIGHT
|
let axis: SDL_GameControllerAxis = (key == .left) ? SDL_CONTROLLER_AXIS_TRIGGERLEFT : SDL_CONTROLLER_AXIS_TRIGGERRIGHT
|
||||||
let scaledValue = Sint16(value * 32767.0)
|
let scaledValue = Sint16(value * 32767.0)
|
||||||
@ -183,7 +187,6 @@ class NativeController: Hashable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func updateAxisValue(value: Sint16, forAxis axis: SDL_GameControllerAxis) {
|
func updateAxisValue(value: Sint16, forAxis axis: SDL_GameControllerAxis) {
|
||||||
guard controller != nil else { return }
|
guard controller != nil else { return }
|
||||||
let joystick = SDL_JoystickFromInstanceID(instanceID)
|
let joystick = SDL_JoystickFromInstanceID(instanceID)
|
||||||
@ -199,7 +202,7 @@ class NativeController: Hashable {
|
|||||||
if stick == .right {
|
if stick == .right {
|
||||||
updateAxisValue(value: scaledX, forAxis: SDL_GameControllerAxis(SDL_CONTROLLER_AXIS_RIGHTX.rawValue))
|
updateAxisValue(value: scaledX, forAxis: SDL_GameControllerAxis(SDL_CONTROLLER_AXIS_RIGHTX.rawValue))
|
||||||
updateAxisValue(value: scaledY, forAxis: SDL_GameControllerAxis(SDL_CONTROLLER_AXIS_RIGHTY.rawValue))
|
updateAxisValue(value: scaledY, forAxis: SDL_GameControllerAxis(SDL_CONTROLLER_AXIS_RIGHTY.rawValue))
|
||||||
} else { // ThumbstickType.left
|
} else { // ThumbstickType.left
|
||||||
updateAxisValue(value: scaledX, forAxis: SDL_GameControllerAxis(SDL_CONTROLLER_AXIS_LEFTX.rawValue))
|
updateAxisValue(value: scaledX, forAxis: SDL_GameControllerAxis(SDL_CONTROLLER_AXIS_LEFTX.rawValue))
|
||||||
updateAxisValue(value: scaledY, forAxis: SDL_GameControllerAxis(SDL_CONTROLLER_AXIS_LEFTY.rawValue))
|
updateAxisValue(value: scaledY, forAxis: SDL_GameControllerAxis(SDL_CONTROLLER_AXIS_LEFTY.rawValue))
|
||||||
}
|
}
|
||||||
@ -209,7 +212,7 @@ class NativeController: Hashable {
|
|||||||
guard controller != nil else { return }
|
guard controller != nil else { return }
|
||||||
|
|
||||||
// print("Button: \(button.rawValue) {state: \(state)}")
|
// print("Button: \(button.rawValue) {state: \(state)}")
|
||||||
if (button == .leftTrigger || button == .rightTrigger) && (state == 1 || state == 0) {
|
if button == .leftTrigger || button == .rightTrigger, state == 1 || state == 0 {
|
||||||
let axis: SDL_GameControllerAxis = (button == .leftTrigger) ? SDL_CONTROLLER_AXIS_TRIGGERLEFT : SDL_CONTROLLER_AXIS_TRIGGERRIGHT
|
let axis: SDL_GameControllerAxis = (button == .leftTrigger) ? SDL_CONTROLLER_AXIS_TRIGGERLEFT : SDL_CONTROLLER_AXIS_TRIGGERRIGHT
|
||||||
let value: Int = (state == 1) ? 32767 : 0
|
let value: Int = (state == 1) ? 32767 : 0
|
||||||
updateAxisValue(value: Sint16(value), forAxis: axis)
|
updateAxisValue(value: Sint16(value), forAxis: axis)
|
||||||
@ -220,11 +223,27 @@ class NativeController: Hashable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func cleanup() {
|
func cleanup() {
|
||||||
if let controller {
|
guard let controller else { return }
|
||||||
SDL_JoystickDetachVirtual(instanceID)
|
SDL_GameControllerClose(controller)
|
||||||
SDL_GameControllerClose(controller)
|
|
||||||
self.controller = nil
|
let num = SDL_NumJoysticks()
|
||||||
|
for i in 0 ..< num {
|
||||||
|
guard let _controller = SDL_GameControllerOpen(i)
|
||||||
|
else { continue }
|
||||||
|
|
||||||
|
let _controllerName = String(cString: SDL_GameControllerName(_controller))
|
||||||
|
SDL_GameControllerClose(_controller)
|
||||||
|
|
||||||
|
if controllername == _controllerName {
|
||||||
|
if SDL_JoystickDetachVirtual(i) == -1 {
|
||||||
|
let error = String(cString: SDL_GetError())
|
||||||
|
print("Error disconnecting virtual controller \(error) : \(_controllerName)")
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.controller = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func hash(into hasher: inout Hasher) {
|
func hash(into hasher: inout Hasher) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user