mirror of
https://git.743378673.xyz/MeloNX/MeloNX.git
synced 2025-06-27 19:06:23 +02:00
Update Rumble and Motion to use the iPhones sensors when using Backbone controllers
This commit is contained in:
parent
2348f5f4b1
commit
71056542c4
4 changed files with 32 additions and 41 deletions
17
README.md
17
README.md
|
@ -28,6 +28,10 @@ MeloNX works on iPhone XS/XR and later and iPad 8th Gen and later. Check out the
|
|||
- Recommended Device: iPhone 15 Pro or newer.
|
||||
- Low-End Recommended Device: iPhone 13 Pro.
|
||||
|
||||
## Discord Server
|
||||
|
||||
We have a discord server!
|
||||
- https://discord.gg/melonx
|
||||
|
||||
## How to install
|
||||
|
||||
|
@ -141,12 +145,12 @@ If having Issues installing firmware (Make sure your keys are installed first)
|
|||
|
||||
- **GPU**
|
||||
|
||||
The GPU emulator emulates the Switch's Maxwell GPU using Metal (via MoltenVK) APIs through a custom build of OpenTK or Silk.NET respectively.
|
||||
The GPU emulator emulates the Switch's Maxwell GPU using Metal (via MoltenVK) APIs through a custom build of Silk.NET.
|
||||
|
||||
- **Input**
|
||||
|
||||
We currently have support for keyboard, touch input, JoyCon input support, and nearly all controllers.
|
||||
Motion controls are natively supported in most cases.
|
||||
We currently have support for keyboard, touch input, JoyCon input support, and nearly all MFI controllers.
|
||||
Motion controls are natively supported in most cases, however JoyCons do not have motion support doe to an iOS limitation.
|
||||
|
||||
- **DLC & Modifications**
|
||||
|
||||
|
@ -157,14 +161,13 @@ If having Issues installing firmware (Make sure your keys are installed first)
|
|||
|
||||
The emulator has settings for enabling or disabling some logging, remapping controllers, and more.
|
||||
|
||||
## License
|
||||
# License
|
||||
|
||||
This software is licensed under the terms of the [MeloNX license (Based on MIT License)](LICENSE.txt).
|
||||
This software is licensed under the terms of the [MeloNX license](LICENSE.txt).
|
||||
This project makes use of code authored by the libvpx project, licensed under BSD and the ffmpeg project, licensed under LGPLv3.
|
||||
See [LICENSE.txt](LICENSE.txt) and [THIRDPARTY.md](distribution/legal/THIRDPARTY.md) for more details.
|
||||
|
||||
## Credits
|
||||
|
||||
# Credits
|
||||
- [Ryujinx](https://github.com/ryujinx-mirror/ryujinx) is used for the base of this emulator. (link is to ryujinx-mirror since they were supportive)
|
||||
- [LibHac](https://github.com/Thealexbarney/LibHac) is used for our file-system.
|
||||
- [AmiiboAPI](https://www.amiiboapi.com) is used in our Amiibo emulation.
|
||||
|
|
Binary file not shown.
|
@ -62,7 +62,6 @@ func allocateTest() -> Bool {
|
|||
|
||||
memcpy(jitMemory, code, code.count)
|
||||
|
||||
|
||||
if mprotect(jitMemory, pageSize, PROT_READ | PROT_EXEC) != 0 {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -12,8 +12,7 @@ class NativeController: Hashable, BaseController {
|
|||
private var instanceID: SDL_JoystickID = -1
|
||||
private var controller: OpaquePointer?
|
||||
private var nativeController: GCController
|
||||
private var controllerMotionProvider: ControllerMotionProvider?
|
||||
private var deviceMotionProvider: DeviceMotionProvider?
|
||||
private var controllerMotionProvider: DSUMotionProvider?
|
||||
|
||||
private let controllerHaptics: CHHapticEngine?
|
||||
private let rumbleController: RumbleController?
|
||||
|
@ -22,21 +21,21 @@ class NativeController: Hashable, BaseController {
|
|||
|
||||
init(_ controller: GCController) {
|
||||
nativeController = controller
|
||||
controllerHaptics = nativeController.haptics?.createEngine(withLocality: .default)
|
||||
var ncontrollerHaptics = nativeController.haptics?.createEngine(withLocality: .default)
|
||||
|
||||
let vendorName = nativeController.vendorName ?? "Unknown"
|
||||
var usesdeviceHaptics = (ncontrollerHaptics == nil || vendorName.lowercased().hasSuffix("backbone") || vendorName.lowercased() == "backbone one")
|
||||
controllerHaptics = usesdeviceHaptics ? ncontrollerHaptics : try? CHHapticEngine()
|
||||
|
||||
// Make sure the haptic engine exists before attempting to start it or initialize the controller.
|
||||
if let hapticsEngine = controllerHaptics {
|
||||
do {
|
||||
try hapticsEngine.start()
|
||||
rumbleController = RumbleController(engine: hapticsEngine, rumbleMultiplier: 2.5)
|
||||
|
||||
// print("CHHapticEngine started and RumbleController initialized.")
|
||||
rumbleController = RumbleController(engine: hapticsEngine, rumbleMultiplier: 1.2)
|
||||
} catch {
|
||||
// print("Error starting CHHapticEngine: \(error.localizedDescription)")
|
||||
rumbleController = nil
|
||||
}
|
||||
} else {
|
||||
// print("CHHapticEngine is nil. Cannot initialize RumbleController.")
|
||||
rumbleController = nil
|
||||
}
|
||||
setupHandheldController()
|
||||
|
@ -49,27 +48,17 @@ class NativeController: Hashable, BaseController {
|
|||
internal func tryRegisterMotion(slot: UInt8) {
|
||||
// Setup Motion
|
||||
let dsuServer = DSUServer.shared
|
||||
let vendorName = nativeController.vendorName ?? "Unknown"
|
||||
var usesdevicemotion = (vendorName.lowercased() == "Joy-Con (l/R)".lowercased() || vendorName.lowercased().hasSuffix("backbone") || vendorName.lowercased() == "backbone one")
|
||||
|
||||
controllerMotionProvider = usesdevicemotion ? DeviceMotionProvider(slot: slot) : ControllerMotionProvider(controller: nativeController, slot: slot)
|
||||
|
||||
if nativeController.vendorName?.lowercased() == "Joy-Con (l/R)".lowercased() {
|
||||
deviceMotionProvider = DeviceMotionProvider(slot: slot)
|
||||
if let provider = deviceMotionProvider {
|
||||
dsuServer.register(provider)
|
||||
}
|
||||
} else {
|
||||
controllerMotionProvider = ControllerMotionProvider(controller: nativeController, slot: slot)
|
||||
if let provider = controllerMotionProvider {
|
||||
dsuServer.register(provider)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal func tryGetMotionProvider() -> DSUMotionProvider? {
|
||||
if nativeController.vendorName == "Joy-Con (l/R)" {
|
||||
return deviceMotionProvider
|
||||
} else {
|
||||
return controllerMotionProvider
|
||||
}
|
||||
}
|
||||
internal func tryGetMotionProvider() -> DSUMotionProvider? { return controllerMotionProvider }
|
||||
|
||||
private func setupHandheldController() {
|
||||
if SDL_WasInit(Uint32(SDL_INIT_GAMECONTROLLER)) == 0 {
|
||||
|
@ -94,38 +83,39 @@ class NativeController: Hashable, BaseController {
|
|||
},
|
||||
SetPlayerIndex: { userdata, playerIndex in
|
||||
// print("Player index set to \(playerIndex)")
|
||||
guard let userdata, let player = GCControllerPlayerIndex(rawValue: Int(playerIndex)) else { return }
|
||||
let _self = Unmanaged<NativeController>.fromOpaque(userdata).takeUnretainedValue()
|
||||
_self.nativeController.playerIndex = player
|
||||
},
|
||||
Rumble: { userdata, lowFreq, highFreq in
|
||||
// print("Rumble with \(lowFreq), \(highFreq)")
|
||||
guard let userdata else { return 0 }
|
||||
let _self = Unmanaged<NativeController>.fromOpaque(userdata).takeUnretainedValue()
|
||||
_self.rumbleController?.rumble(lowFreq: Float(lowFreq), highFreq: Float(highFreq))
|
||||
return 0
|
||||
},
|
||||
RumbleTriggers: { userdata, leftRumble, rightRumble in
|
||||
// print("Trigger rumble with \(leftRumble), \(rightRumble)")
|
||||
return 0
|
||||
},
|
||||
SetLED: { userdata, red, green, blue in
|
||||
// print("Set LED to RGB(\(red), \(green), \(blue))")
|
||||
guard let userdata else { return 0 }
|
||||
let _self = Unmanaged<NativeController>.fromOpaque(userdata).takeUnretainedValue()
|
||||
guard let light = _self.nativeController.light else { return 0 }
|
||||
light.color = .init(red: Float(red), green: Float(green), blue: Float(blue))
|
||||
return 0
|
||||
},
|
||||
SendEffect: { userdata, data, size in
|
||||
// print("Effect sent with size \(size)")
|
||||
return 0
|
||||
}
|
||||
)
|
||||
|
||||
instanceID = SDL_JoystickAttachVirtualEx(&joystickDesc)// SDL_JoystickAttachVirtual(SDL_JoystickType(SDL_JOYSTICK_TYPE_GAMECONTROLLER.rawValue), 6, 15, 1)
|
||||
instanceID = SDL_JoystickAttachVirtualEx(&joystickDesc)
|
||||
if instanceID < 0 {
|
||||
// print("Failed to create virtual joystick: \(String(cString: SDL_GetError()))")
|
||||
return
|
||||
}
|
||||
|
||||
controller = SDL_GameControllerOpen(Int32(instanceID))
|
||||
|
||||
if controller == nil {
|
||||
// print("Failed to create virtual controller: \(String(cString: SDL_GetError()))")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -214,7 +204,6 @@ class NativeController: Hashable, BaseController {
|
|||
func setButtonState(_ state: Uint8, for button: VirtualControllerButton) {
|
||||
guard controller != nil else { return }
|
||||
|
||||
// // print("Button: \(button.rawValue) {state: \(state)}")
|
||||
if (button == .leftTrigger || button == .rightTrigger) && (state == 1 || state == 0) {
|
||||
let axis: SDL_GameControllerAxis = (button == .leftTrigger) ? SDL_CONTROLLER_AXIS_TRIGGERLEFT : SDL_CONTROLLER_AXIS_TRIGGERRIGHT
|
||||
let value: Int = (state == 1) ? 32767 : 0
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue