diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..2ec04056 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +github: [franticrain] + diff --git a/.gitignore b/.gitignore index 07868758..f0a93633 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,9 @@ # ######################### +# Xcode configuration files used for storing developer information +*.xcconfig + ##### # OS X temporary files that should never be committed # @@ -31,7 +34,7 @@ *.swp # *.lock - this is used and abused by many editors for many different things. -# For the main ones I use (e.g. Eclipse), it should be excluded +# For the main ones I use (e.g. Eclipse), it should be excluded # from source-control, but YMMV *.lock @@ -43,7 +46,7 @@ #### # Xcode temporary files that should never be committed -# +# # NB: NIB/XIB files still exist even on Storyboard projects, so we want this... *~.nib @@ -161,3 +164,8 @@ xcuserdata # UNKNOWN: recommended by others, but I can't discover what these files are # # ...none. Everything is now explained. + +# Ignore build products +builds/ +*.dmg +*.dmg.zip diff --git a/360 Driver.xcodeproj/project.pbxproj b/360 Driver.xcodeproj/project.pbxproj index f53d0823..57144446 100644 --- a/360 Driver.xcodeproj/project.pbxproj +++ b/360 Driver.xcodeproj/project.pbxproj @@ -43,6 +43,12 @@ 55699CD61971D96E00C40A31 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 55699CD51971D96E00C40A31 /* Images.xcassets */; }; 55699CD71971DA8100C40A31 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 55699CD51971D96E00C40A31 /* Images.xcassets */; }; 55750C09190AFB5B0047FF41 /* DaemonLEDs.m in Sources */ = {isa = PBXBuildFile; fileRef = 55750C08190AFB5B0047FF41 /* DaemonLEDs.m */; }; + 5579514B1F7300EE001880D1 /* XBOBTFF.plugin in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5579513E1F73006F001880D1 /* XBOBTFF.plugin */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 5579514C1F7301F9001880D1 /* FFDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 557951451F7300C9001880D1 /* FFDriver.cpp */; }; + 5579514D1F73021A001880D1 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55B6375818C109E600CE933D /* ForceFeedback.framework */; }; + 557951501F73037B001880D1 /* FeedbackXBOEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5579514E1F73037B001880D1 /* FeedbackXBOEffect.cpp */; }; + 557951511F730CA3001880D1 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 553BDB43196DF3BA00D1F569 /* IOKit.framework */; }; + 557951521F730CAF001880D1 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55B6372018C108A500CE933D /* CoreFoundation.framework */; }; 55852E1F18D6B5580009BF55 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 55852E2118D6B5580009BF55 /* Localizable.strings */; }; 55A2B8D518C116BD006829A2 /* 360Daemon.m in Sources */ = {isa = PBXBuildFile; fileRef = 55B637C718C10CB400CE933D /* 360Daemon.m */; }; 55A2B8D818C116E0006829A2 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 55A2B8DA18C116E0006829A2 /* Localizable.strings */; }; @@ -51,8 +57,6 @@ 55B636C218C104DB00CE933D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 55B636C018C104DB00CE933D /* InfoPlist.strings */; }; 55B6371618C1058E00CE933D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 55B636F918C1054F00CE933D /* InfoPlist.strings */; }; 55B6371718C105B800CE933D /* _60Controller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 55B636EF18C1054F00CE933D /* _60Controller.cpp */; }; - 55B6371818C105B800CE933D /* ChatPad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 55B636F118C1054F00CE933D /* ChatPad.cpp */; }; - 55B6371918C105B800CE933D /* chatpadkeys.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 55B636F418C1054F00CE933D /* chatpadkeys.cpp */; }; 55B6371A18C105B800CE933D /* Controller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 55B636F618C1054F00CE933D /* Controller.cpp */; }; 55B6372118C108A500CE933D /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55B6372018C108A500CE933D /* CoreFoundation.framework */; }; 55B6373C18C108D200CE933D /* devlink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 55B6372D18C108D200CE933D /* devlink.cpp */; }; @@ -60,9 +64,6 @@ 55B6373E18C108D200CE933D /* Feedback360.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 55B6373118C108D200CE933D /* Feedback360.cpp */; }; 55B6373F18C108D200CE933D /* Feedback360Effect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 55B6373618C108D200CE933D /* Feedback360Effect.cpp */; }; 55B6374F18C1098D00CE933D /* _60Controller.h in Headers */ = {isa = PBXBuildFile; fileRef = 55B636F018C1054F00CE933D /* _60Controller.h */; }; - 55B6375018C1098D00CE933D /* ChatPad.h in Headers */ = {isa = PBXBuildFile; fileRef = 55B636F218C1054F00CE933D /* ChatPad.h */; }; - 55B6375118C1098D00CE933D /* chatpadhid.h in Headers */ = {isa = PBXBuildFile; fileRef = 55B636F318C1054F00CE933D /* chatpadhid.h */; }; - 55B6375218C1098D00CE933D /* chatpadkeys.h in Headers */ = {isa = PBXBuildFile; fileRef = 55B636F518C1054F00CE933D /* chatpadkeys.h */; }; 55B6375318C1098D00CE933D /* Controller.h in Headers */ = {isa = PBXBuildFile; fileRef = 55B636F718C1054F00CE933D /* Controller.h */; }; 55B6375418C1098D00CE933D /* ControlStruct.h in Headers */ = {isa = PBXBuildFile; fileRef = 55B636F818C1054F00CE933D /* ControlStruct.h */; }; 55B6375518C1098D00CE933D /* xbox360hid.h in Headers */ = {isa = PBXBuildFile; fileRef = 55B636FD18C1054F00CE933D /* xbox360hid.h */; }; @@ -103,6 +104,11 @@ 55FE3CAD18D7B7B600D69E84 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FE3CAC18D7B7B600D69E84 /* SDL2.framework */; }; 5B943BE11A83EC6600E77A79 /* MyAnalogStick.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B943BDF1A83EC6600E77A79 /* MyAnalogStick.h */; }; 5B943BE21A83EC6600E77A79 /* MyAnalogStick.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B943BE01A83EC6600E77A79 /* MyAnalogStick.m */; }; + 62035D1620C04F7D003E70C1 /* chatpadkeys.h in Headers */ = {isa = PBXBuildFile; fileRef = 62035D1120C04F7D003E70C1 /* chatpadkeys.h */; }; + 62035D1720C04F7D003E70C1 /* chatpadkeys.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 62035D1220C04F7D003E70C1 /* chatpadkeys.cpp */; }; + 62035D1820C04F7D003E70C1 /* chatpadhid.h in Headers */ = {isa = PBXBuildFile; fileRef = 62035D1320C04F7D003E70C1 /* chatpadhid.h */; }; + 62035D1920C04F7D003E70C1 /* ChatPad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 62035D1420C04F7D003E70C1 /* ChatPad.cpp */; }; + 62035D1A20C04F7D003E70C1 /* ChatPad.h in Headers */ = {isa = PBXBuildFile; fileRef = 62035D1520C04F7D003E70C1 /* ChatPad.h */; }; 622A73C21A7C339000784C02 /* MyWhole360ControllerMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 622A73C01A7C339000784C02 /* MyWhole360ControllerMapper.h */; }; 622A73C31A7C339000784C02 /* MyWhole360ControllerMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 622A73C11A7C339000784C02 /* MyWhole360ControllerMapper.m */; }; 622A73CE1A7C879300784C02 /* BindingTableView.h in Headers */ = {isa = PBXBuildFile; fileRef = 622A73CC1A7C879300784C02 /* BindingTableView.h */; }; @@ -110,6 +116,13 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 557951491F7300E4001880D1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 55B636AC18C104DB00CE933D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5579513D1F73006F001880D1; + remoteInfo = XBOBTFF; + }; 55B6374D18C1097D00CE933D /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 55B636AC18C104DB00CE933D /* Project object */; @@ -169,6 +182,16 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ + 557951481F7300DC001880D1 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + 5579514B1F7300EE001880D1 /* XBOBTFF.plugin in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 55A2B8DC18C11A21006829A2 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; @@ -225,8 +248,17 @@ 55699CD51971D96E00C40A31 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 55750C07190AFB5B0047FF41 /* DaemonLEDs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DaemonLEDs.h; sourceTree = ""; usesTabs = 1; }; 55750C08190AFB5B0047FF41 /* DaemonLEDs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DaemonLEDs.m; sourceTree = ""; usesTabs = 1; }; + 5579513E1F73006F001880D1 /* XBOBTFF.plugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XBOBTFF.plugin; sourceTree = BUILT_PRODUCTS_DIR; }; + 557951401F73006F001880D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 557951441F7300C9001880D1 /* FFDriver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FFDriver.h; sourceTree = ""; }; + 557951451F7300C9001880D1 /* FFDriver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FFDriver.cpp; sourceTree = ""; }; + 557951461F7300CA001880D1 /* XBoxOneBTHID.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XBoxOneBTHID.h; sourceTree = ""; }; + 5579514E1F73037B001880D1 /* FeedbackXBOEffect.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FeedbackXBOEffect.cpp; sourceTree = ""; }; + 5579514F1F73037B001880D1 /* FeedbackXBOEffect.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = FeedbackXBOEffect.hpp; sourceTree = ""; }; 55852E2018D6B5580009BF55 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 55A2B8DB18C116E2006829A2 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 55ACBFE01D5B9E2E00E4F677 /* XboxOneBluetooth.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XboxOneBluetooth.kext; sourceTree = BUILT_PRODUCTS_DIR; }; + 55ACBFE41D5B9E2F00E4F677 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 55B13FC018C51DD400ACD9AC /* Feedback360.exp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.exports; path = Feedback360.exp; sourceTree = ""; }; 55B636B418C104DB00CE933D /* 360Daemon.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 360Daemon.app; sourceTree = BUILT_PRODUCTS_DIR; }; 55B636B718C104DB00CE933D /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; @@ -238,11 +270,6 @@ 55B636C518C104DB00CE933D /* 360DaemonApp-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "360DaemonApp-Prefix.pch"; sourceTree = ""; }; 55B636EF18C1054F00CE933D /* _60Controller.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = _60Controller.cpp; sourceTree = ""; }; 55B636F018C1054F00CE933D /* _60Controller.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _60Controller.h; sourceTree = ""; }; - 55B636F118C1054F00CE933D /* ChatPad.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ChatPad.cpp; sourceTree = ""; }; - 55B636F218C1054F00CE933D /* ChatPad.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ChatPad.h; sourceTree = ""; }; - 55B636F318C1054F00CE933D /* chatpadhid.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = chatpadhid.h; sourceTree = ""; }; - 55B636F418C1054F00CE933D /* chatpadkeys.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = chatpadkeys.cpp; sourceTree = ""; usesTabs = 1; }; - 55B636F518C1054F00CE933D /* chatpadkeys.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = chatpadkeys.h; sourceTree = ""; }; 55B636F618C1054F00CE933D /* Controller.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Controller.cpp; sourceTree = ""; }; 55B636F718C1054F00CE933D /* Controller.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Controller.h; sourceTree = ""; }; 55B636F818C1054F00CE933D /* ControlStruct.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ControlStruct.h; sourceTree = ""; }; @@ -307,13 +334,38 @@ 55FE3CAC18D7B7B600D69E84 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = ""; }; 5B943BDF1A83EC6600E77A79 /* MyAnalogStick.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyAnalogStick.h; sourceTree = ""; }; 5B943BE01A83EC6600E77A79 /* MyAnalogStick.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyAnalogStick.m; sourceTree = ""; }; + 62035D1120C04F7D003E70C1 /* chatpadkeys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chatpadkeys.h; sourceTree = ""; }; + 62035D1220C04F7D003E70C1 /* chatpadkeys.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = chatpadkeys.cpp; sourceTree = ""; }; + 62035D1320C04F7D003E70C1 /* chatpadhid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chatpadhid.h; sourceTree = ""; }; + 62035D1420C04F7D003E70C1 /* ChatPad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ChatPad.cpp; sourceTree = ""; }; + 62035D1520C04F7D003E70C1 /* ChatPad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatPad.h; sourceTree = ""; }; 622A73C01A7C339000784C02 /* MyWhole360ControllerMapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyWhole360ControllerMapper.h; sourceTree = ""; }; 622A73C11A7C339000784C02 /* MyWhole360ControllerMapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyWhole360ControllerMapper.m; sourceTree = ""; }; 622A73CC1A7C879300784C02 /* BindingTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BindingTableView.h; sourceTree = ""; }; 622A73CD1A7C879300784C02 /* BindingTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BindingTableView.m; sourceTree = ""; }; + 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DeveloperSettings.xcconfig; sourceTree = SOURCE_ROOT; }; + 96A383052223A4FA00A27767 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 96A383062223A4FA00A27767 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 96A383072223A4FA00A27767 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 96A383082223A4FB00A27767 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 96A383092223A4FB00A27767 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 96A3830A2223A4FB00A27767 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; + 96A3830C2223A4FB00A27767 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 96A3830D2223A4FB00A27767 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; + 96A3830E2223A50700A27767 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Pref360ControlPref.strings"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 5579513B1F73006F001880D1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 557951521F730CAF001880D1 /* CoreFoundation.framework in Frameworks */, + 557951511F730CA3001880D1 /* IOKit.framework in Frameworks */, + 5579514D1F73021A001880D1 /* ForceFeedback.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 55B636B118C104DB00CE933D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -390,6 +442,7 @@ 551CDFFE196EFD0A000869B6 /* Distribution */ = { isa = PBXGroup; children = ( + 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */, 551CDFFF196EFD34000869B6 /* Install360Controller.pkgproj */, 551CE000196EFD34000869B6 /* Scripts */, 551CE003196EFD34000869B6 /* Text */, @@ -418,6 +471,20 @@ path = Text; sourceTree = ""; }; + 5579513F1F73006F001880D1 /* XBOBTFF */ = { + isa = PBXGroup; + children = ( + 557951441F7300C9001880D1 /* FFDriver.h */, + 557951451F7300C9001880D1 /* FFDriver.cpp */, + 557951461F7300CA001880D1 /* XBoxOneBTHID.h */, + 5579514F1F73037B001880D1 /* FeedbackXBOEffect.hpp */, + 5579514E1F73037B001880D1 /* FeedbackXBOEffect.cpp */, + 557951401F73006F001880D1 /* Info.plist */, + ); + path = XBOBTFF; + sourceTree = ""; + usesTabs = 1; + }; 55A2B8E018C11C7E006829A2 /* Resources */ = { isa = PBXGroup; children = ( @@ -468,6 +535,14 @@ name = Resources; sourceTree = ""; }; + 55ACBFE11D5B9E2E00E4F677 /* XboxOneBluetooth */ = { + isa = PBXGroup; + children = ( + 55ACBFE41D5B9E2F00E4F677 /* Info.plist */, + ); + path = XboxOneBluetooth; + sourceTree = ""; + }; 55B636AB18C104DB00CE933D = { isa = PBXGroup; children = ( @@ -479,6 +554,8 @@ 55B6376A18C10A5400CE933D /* DriverTool */, 55B6378118C10B0B00CE933D /* Pref360Control */, 551CDFFE196EFD0A000869B6 /* Distribution */, + 55ACBFE11D5B9E2E00E4F677 /* XboxOneBluetooth */, + 5579513F1F73006F001880D1 /* XBOBTFF */, 55B636B618C104DB00CE933D /* Frameworks */, 55B636B518C104DB00CE933D /* Products */, ); @@ -496,6 +573,8 @@ 55B637E818C10D5000CE933D /* Wireless360Controller.kext */, 55B6380E18C10E8700CE933D /* WirelessGamingReceiver.kext */, 55FE3CA118D7B77800D69E84 /* testhaptic */, + 55ACBFE01D5B9E2E00E4F677 /* XboxOneBluetooth.kext */, + 5579513E1F73006F001880D1 /* XBOBTFF.plugin */, ); name = Products; sourceTree = ""; @@ -559,11 +638,11 @@ children = ( 55B636F018C1054F00CE933D /* _60Controller.h */, 55B636EF18C1054F00CE933D /* _60Controller.cpp */, - 55B636F218C1054F00CE933D /* ChatPad.h */, - 55B636F118C1054F00CE933D /* ChatPad.cpp */, - 55B636F318C1054F00CE933D /* chatpadhid.h */, - 55B636F518C1054F00CE933D /* chatpadkeys.h */, - 55B636F418C1054F00CE933D /* chatpadkeys.cpp */, + 62035D1520C04F7D003E70C1 /* ChatPad.h */, + 62035D1420C04F7D003E70C1 /* ChatPad.cpp */, + 62035D1320C04F7D003E70C1 /* chatpadhid.h */, + 62035D1120C04F7D003E70C1 /* chatpadkeys.h */, + 62035D1220C04F7D003E70C1 /* chatpadkeys.cpp */, 55B636F718C1054F00CE933D /* Controller.h */, 55B636F618C1054F00CE933D /* Controller.cpp */, 55B636F818C1054F00CE933D /* ControlStruct.h */, @@ -666,16 +745,23 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ + 55ACBFDD1D5B9E2E00E4F677 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 55B6370318C1057100CE933D /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 55B6375218C1098D00CE933D /* chatpadkeys.h in Headers */, 55B6375318C1098D00CE933D /* Controller.h in Headers */, 55B6375518C1098D00CE933D /* xbox360hid.h in Headers */, - 55B6375018C1098D00CE933D /* ChatPad.h in Headers */, - 55B6375118C1098D00CE933D /* chatpadhid.h in Headers */, + 62035D1620C04F7D003E70C1 /* chatpadkeys.h in Headers */, + 62035D1A20C04F7D003E70C1 /* ChatPad.h in Headers */, 55B6374F18C1098D00CE933D /* _60Controller.h in Headers */, + 62035D1820C04F7D003E70C1 /* chatpadhid.h in Headers */, 55B6375418C1098D00CE933D /* ControlStruct.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -720,6 +806,41 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ + 5579513D1F73006F001880D1 /* XBOBTFF */ = { + isa = PBXNativeTarget; + buildConfigurationList = 557951431F73006F001880D1 /* Build configuration list for PBXNativeTarget "XBOBTFF" */; + buildPhases = ( + 5579513A1F73006F001880D1 /* Sources */, + 5579513B1F73006F001880D1 /* Frameworks */, + 5579513C1F73006F001880D1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = XBOBTFF; + productName = XBOBTFF; + productReference = 5579513E1F73006F001880D1 /* XBOBTFF.plugin */; + productType = "com.apple.product-type.bundle"; + }; + 55ACBFDF1D5B9E2E00E4F677 /* XboxOneBluetooth */ = { + isa = PBXNativeTarget; + buildConfigurationList = 55ACBFE71D5B9E2F00E4F677 /* Build configuration list for PBXNativeTarget "XboxOneBluetooth" */; + buildPhases = ( + 55ACBFDD1D5B9E2E00E4F677 /* Headers */, + 55ACBFDE1D5B9E2E00E4F677 /* Resources */, + 557951481F7300DC001880D1 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + 5579514A1F7300E4001880D1 /* PBXTargetDependency */, + ); + name = XboxOneBluetooth; + productName = XboxOneBluetooth; + productReference = 55ACBFE01D5B9E2E00E4F677 /* XboxOneBluetooth.kext */; + productType = "com.apple.product-type.kernel-extension"; + }; 55B636B318C104DB00CE933D /* 360Daemon */ = { isa = PBXNativeTarget; buildConfigurationList = 55B636E518C104DB00CE933D /* Build configuration list for PBXNativeTarget "360Daemon" */; @@ -872,6 +993,54 @@ attributes = { LastUpgradeCheck = 0610; ORGANIZATIONNAME = GitHub; + TargetAttributes = { + 5579513D1F73006F001880D1 = { + CreatedOnToolsVersion = 9.0; + DevelopmentTeam = G947KKM5RL; + ProvisioningStyle = Manual; + }; + 55ACBFDF1D5B9E2E00E4F677 = { + CreatedOnToolsVersion = 7.3.1; + DevelopmentTeam = G947KKM5RL; + ProvisioningStyle = Manual; + }; + 55B636B318C104DB00CE933D = { + DevelopmentTeam = G947KKM5RL; + ProvisioningStyle = Manual; + }; + 55B6370618C1057100CE933D = { + DevelopmentTeam = G947KKM5RL; + ProvisioningStyle = Manual; + }; + 55B6371E18C108A500CE933D = { + DevelopmentTeam = G947KKM5RL; + ProvisioningStyle = Manual; + }; + 55B6375F18C10A3200CE933D = { + DevelopmentTeam = G947KKM5RL; + ProvisioningStyle = Manual; + }; + 55B6377C18C10B0B00CE933D = { + DevelopmentTeam = G947KKM5RL; + ProvisioningStyle = Manual; + }; + 55B637E718C10D5000CE933D = { + DevelopmentTeam = G947KKM5RL; + ProvisioningStyle = Manual; + }; + 55B6380D18C10E8700CE933D = { + DevelopmentTeam = G947KKM5RL; + ProvisioningStyle = Manual; + }; + 55B6383818C10F8E00CE933D = { + DevelopmentTeam = G947KKM5RL; + ProvisioningStyle = Manual; + }; + 55FE3CA018D7B77800D69E84 = { + DevelopmentTeam = G947KKM5RL; + ProvisioningStyle = Manual; + }; + }; }; buildConfigurationList = 55B636AF18C104DB00CE933D /* Build configuration list for PBXProject "360 Driver" */; compatibilityVersion = "Xcode 3.2"; @@ -881,6 +1050,7 @@ en, Base, English, + "zh-Hans", ); mainGroup = 55B636AB18C104DB00CE933D; productRefGroup = 55B636B518C104DB00CE933D /* Products */; @@ -895,12 +1065,28 @@ 55B6370618C1057100CE933D /* 360Controller */, 55B637E718C10D5000CE933D /* Wireless360Controller */, 55B6380D18C10E8700CE933D /* WirelessGamingReceiver */, + 5579513D1F73006F001880D1 /* XBOBTFF */, + 55ACBFDF1D5B9E2E00E4F677 /* XboxOneBluetooth */, 55FE3CA018D7B77800D69E84 /* testhaptic */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 5579513C1F73006F001880D1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 55ACBFDE1D5B9E2E00E4F677 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 55B636B218C104DB00CE933D /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -960,6 +1146,15 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 5579513A1F73006F001880D1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5579514C1F7301F9001880D1 /* FFDriver.cpp in Sources */, + 557951501F73037B001880D1 /* FeedbackXBOEffect.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 55B636B018C104DB00CE933D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -974,9 +1169,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 55B6371918C105B800CE933D /* chatpadkeys.cpp in Sources */, + 62035D1720C04F7D003E70C1 /* chatpadkeys.cpp in Sources */, + 62035D1920C04F7D003E70C1 /* ChatPad.cpp in Sources */, 55B6371718C105B800CE933D /* _60Controller.cpp in Sources */, - 55B6371818C105B800CE933D /* ChatPad.cpp in Sources */, 55B6371A18C105B800CE933D /* Controller.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1047,6 +1242,11 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 5579514A1F7300E4001880D1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5579513D1F73006F001880D1 /* XBOBTFF */; + targetProxy = 557951491F7300E4001880D1 /* PBXContainerItemProxy */; + }; 55B6374E18C1097D00CE933D /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 55B6371E18C108A500CE933D /* Feedback360 */; @@ -1094,6 +1294,7 @@ isa = PBXVariantGroup; children = ( 551B911F1A68BDB000EA6527 /* en */, + 96A3830E2223A50700A27767 /* zh-Hans */, ); name = Pref360ControlPref.xib; sourceTree = ""; @@ -1102,6 +1303,7 @@ isa = PBXVariantGroup; children = ( 55852E2018D6B5580009BF55 /* en */, + 96A3830D2223A4FB00A27767 /* zh-Hans */, ); name = Localizable.strings; sourceTree = ""; @@ -1110,6 +1312,7 @@ isa = PBXVariantGroup; children = ( 55A2B8DB18C116E2006829A2 /* en */, + 96A3830A2223A4FB00A27767 /* zh-Hans */, ); name = Localizable.strings; sourceTree = ""; @@ -1118,6 +1321,7 @@ isa = PBXVariantGroup; children = ( 55B636C118C104DB00CE933D /* en */, + 96A383092223A4FB00A27767 /* zh-Hans */, ); name = InfoPlist.strings; sourceTree = ""; @@ -1126,6 +1330,7 @@ isa = PBXVariantGroup; children = ( 55B636FA18C1054F00CE933D /* English */, + 96A383062223A4FA00A27767 /* zh-Hans */, ); name = InfoPlist.strings; sourceTree = ""; @@ -1134,6 +1339,7 @@ isa = PBXVariantGroup; children = ( 55B6373018C108D200CE933D /* English */, + 96A383052223A4FA00A27767 /* zh-Hans */, ); name = InfoPlist.strings; sourceTree = ""; @@ -1142,6 +1348,7 @@ isa = PBXVariantGroup; children = ( 55B6378518C10B0B00CE933D /* en */, + 96A3830C2223A4FB00A27767 /* zh-Hans */, ); name = InfoPlist.strings; sourceTree = ""; @@ -1150,6 +1357,7 @@ isa = PBXVariantGroup; children = ( 55B637F818C10DA300CE933D /* English */, + 96A383072223A4FA00A27767 /* zh-Hans */, ); name = InfoPlist.strings; sourceTree = ""; @@ -1158,6 +1366,7 @@ isa = PBXVariantGroup; children = ( 55B6381F18C10EBE00CE933D /* English */, + 96A383082223A4FB00A27767 /* zh-Hans */, ); name = InfoPlist.strings; sourceTree = ""; @@ -1165,8 +1374,127 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 557951411F73006F001880D1 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_STYLE = Manual; + COMBINE_HIDPI_IMAGES = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = XBOBTFF/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = NO; + PRODUCT_BUNDLE_IDENTIFIER = com.mice.driver.XBOBTFF; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = macosx10.10; + SKIP_INSTALL = YES; + WRAPPER_EXTENSION = plugin; + }; + name = Debug; + }; + 557951421F73006F001880D1 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; + CODE_SIGN_STYLE = Manual; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = XBOBTFF/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = com.mice.driver.XBOBTFF; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = macosx10.10; + SKIP_INSTALL = YES; + WRAPPER_EXTENSION = plugin; + }; + name = Release; + }; + 55ACBFE51D5B9E2F00E4F677 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_STYLE = Manual; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = XboxOneBluetooth/Info.plist; + MODULE_NAME = com.mice.driver.XboxOneBluetooth; + MODULE_START = XboxOneBluetooth_start; + MODULE_STOP = XboxOneBluetooth_stop; + MODULE_VERSION = 1.0.0d1; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.mice.driver.XboxOneBluetooth; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; + WRAPPER_EXTENSION = kext; + }; + name = Debug; + }; + 55ACBFE61D5B9E2F00E4F677 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; + CODE_SIGN_STYLE = Manual; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = XboxOneBluetooth/Info.plist; + MODULE_NAME = com.mice.driver.XboxOneBluetooth; + MODULE_START = XboxOneBluetooth_start; + MODULE_STOP = XboxOneBluetooth_stop; + MODULE_VERSION = 1.0.0d1; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = com.mice.driver.XboxOneBluetooth; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; + WRAPPER_EXTENSION = kext; + }; + name = Release; + }; 55B636E318C104DB00CE933D /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; @@ -1183,8 +1511,9 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1.0.0d15; + CURRENT_PROJECT_VERSION = 0.16.11; DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; @@ -1201,8 +1530,9 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.9; + MIN_MACOS_VERSION = 10.11; ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; + SDKROOT = macosx10.10; STRIP_INSTALLED_PRODUCT = NO; VERSIONING_SYSTEM = "apple-generic"; WARNING_CFLAGS = ( @@ -1214,6 +1544,7 @@ }; 55B636E418C104DB00CE933D /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; @@ -1231,7 +1562,7 @@ CODE_SIGN_IDENTITY = "3rd Party Mac Developer Application"; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 1.0.0d15; + CURRENT_PROJECT_VERSION = 0.16.11; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -1243,7 +1574,8 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.9; - SDKROOT = macosx; + MIN_MACOS_VERSION = 10.11; + SDKROOT = macosx10.10; STRINGS_FILE_OUTPUT_ENCODING = binary; VERSIONING_SYSTEM = "apple-generic"; WARNING_CFLAGS = ( @@ -1255,64 +1587,88 @@ }; 55B636E618C104DB00CE933D /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = 360Control; + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = YES; + CODE_SIGN_STYLE = Manual; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "360Daemon/360DaemonApp-Prefix.pch"; INFOPLIST_FILE = "360Daemon/360DaemonApp-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Application Support/MICE"; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; WRAPPER_EXTENSION = app; }; name = Debug; }; 55B636E718C104DB00CE933D /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = 360Control; + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; + CODE_SIGN_STYLE = Manual; DEAD_CODE_STRIPPING = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "360Daemon/360DaemonApp-Prefix.pch"; INFOPLIST_FILE = "360Daemon/360DaemonApp-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Application Support/MICE"; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; WRAPPER_EXTENSION = app; }; name = Release; }; 55B6371418C1057100CE933D /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { "CLANG_CXX_LANGUAGE_STANDARD[arch=i386]" = "compiler-default"; + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_STYLE = Manual; INFOPLIST_FILE = 360Controller/Info.plist; MODULE_NAME = com.mice.driver.Xbox360Controller; MODULE_VERSION = "${CURRENT_PROJECT_VERSION}"; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; WRAPPER_EXTENSION = kext; }; name = Debug; }; 55B6371518C1057100CE933D /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { "CLANG_CXX_LANGUAGE_STANDARD[arch=i386]" = "compiler-default"; + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; + CODE_SIGN_STYLE = Manual; INFOPLIST_FILE = 360Controller/Info.plist; MODULE_NAME = com.mice.driver.Xbox360Controller; MODULE_VERSION = "${CURRENT_PROJECT_VERSION}"; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; WRAPPER_EXTENSION = kext; }; name = Release; }; 55B6372A18C108A500CE933D /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_STYLE = Manual; EXPORTED_SYMBOLS_FILE = Feedback360/Feedback360.exp; INFOPLIST_FILE = Feedback360/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; + ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; SKIP_INSTALL = YES; WRAPPER_EXTENSION = plugin; }; @@ -1320,14 +1676,19 @@ }; 55B6372B18C108A500CE933D /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; + CODE_SIGN_STYLE = Manual; DEAD_CODE_STRIPPING = YES; EXPORTED_SYMBOLS_FILE = Feedback360/Feedback360.exp; INFOPLIST_FILE = Feedback360/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; SKIP_INSTALL = YES; WRAPPER_EXTENSION = plugin; }; @@ -1335,20 +1696,29 @@ }; 55B6376818C10A3200CE933D /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = YES; + CODE_SIGN_STYLE = Manual; CREATE_INFOPLIST_SECTION_IN_BINARY = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = DriverTool/DriverTool_Prefix.pch; INFOPLIST_FILE = DriverTool/Info.plist; MACH_O_TYPE = mh_execute; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; SKIP_INSTALL = YES; }; name = Debug; }; 55B6376918C10A3200CE933D /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; + CODE_SIGN_STYLE = Manual; CREATE_INFOPLIST_SECTION_IN_BINARY = YES; DEAD_CODE_STRIPPING = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -1356,14 +1726,18 @@ INFOPLIST_FILE = DriverTool/Info.plist; MACH_O_TYPE = mh_execute; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; SKIP_INSTALL = YES; }; name = Release; }; 55B6379118C10B0B00CE933D /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = 360Control; + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_STYLE = Manual; DEPLOYMENT_LOCATION = NO; DSTROOT = /; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -1375,14 +1749,19 @@ INFOPLIST_FILE = Pref360Control/Info.plist; INSTALL_PATH = "${LOCAL_LIBRARY_DIR}/PreferencePanes"; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; WRAPPER_EXTENSION = prefPane; }; name = Debug; }; 55B6379218C10B0B00CE933D /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = 360Control; + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; + CODE_SIGN_STYLE = Manual; DEAD_CODE_STRIPPING = YES; DEPLOYMENT_LOCATION = NO; DSTROOT = /; @@ -1395,75 +1774,107 @@ INFOPLIST_FILE = Pref360Control/Info.plist; INSTALL_PATH = "${LOCAL_LIBRARY_DIR}/PreferencePanes"; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; WRAPPER_EXTENSION = prefPane; }; name = Release; }; 55B637F418C10D5000CE933D /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { "CLANG_CXX_LANGUAGE_STANDARD[arch=i386]" = "compiler-default"; + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_STYLE = Manual; INFOPLIST_FILE = Wireless360Controller/Info.plist; MODULE_NAME = com.mice.driver.Wireless360Controller; MODULE_VERSION = "${CURRENT_PROJECT_VERSION}"; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; WRAPPER_EXTENSION = kext; }; name = Debug; }; 55B637F518C10D5000CE933D /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { "CLANG_CXX_LANGUAGE_STANDARD[arch=i386]" = "compiler-default"; + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; + CODE_SIGN_STYLE = Manual; INFOPLIST_FILE = Wireless360Controller/Info.plist; MODULE_NAME = com.mice.driver.Wireless360Controller; MODULE_VERSION = "${CURRENT_PROJECT_VERSION}"; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; WRAPPER_EXTENSION = kext; }; name = Release; }; 55B6381A18C10E9500CE933D /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { "CLANG_CXX_LANGUAGE_STANDARD[arch=i386]" = "compiler-default"; + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_STYLE = Manual; INFOPLIST_FILE = WirelessGamingReceiver/Info.plist; MODULE_NAME = com.mice.driver.WirelessGamingReceiver; MODULE_VERSION = "${CURRENT_PROJECT_VERSION}"; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; WRAPPER_EXTENSION = kext; }; name = Debug; }; 55B6381B18C10E9500CE933D /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { "CLANG_CXX_LANGUAGE_STANDARD[arch=i386]" = "compiler-default"; + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; + CODE_SIGN_STYLE = Manual; INFOPLIST_FILE = WirelessGamingReceiver/Info.plist; MODULE_NAME = com.mice.driver.WirelessGamingReceiver; MODULE_VERSION = "${CURRENT_PROJECT_VERSION}"; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; WRAPPER_EXTENSION = kext; }; name = Release; }; 55B6383A18C10F8E00CE933D /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { + CODE_SIGN_IDENTITY = "3rd Party Mac Developer Application"; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = YES; + CODE_SIGN_STYLE = Manual; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; }; name = Debug; }; 55B6383B18C10F8E00CE933D /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { + CODE_SIGN_IDENTITY = "3rd Party Mac Developer Application"; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; + CODE_SIGN_STYLE = Manual; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; }; name = Release; }; 55FE3CA818D7B77800D69E84 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_STYLE = Manual; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(LOCAL_LIBRARY_DIR)/Frameworks", @@ -1471,12 +1882,17 @@ GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; LD_RUNPATH_SEARCH_PATHS = /Library/Frameworks; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; }; name = Debug; }; 55FE3CA918D7B77800D69E84 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 62DD3D4920C044980073EC19 /* DeveloperSettings.xcconfig */; buildSettings = { + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; + CODE_SIGN_STYLE = Manual; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(LOCAL_LIBRARY_DIR)/Frameworks", @@ -1484,12 +1900,31 @@ GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; LD_RUNPATH_SEARCH_PATHS = /Library/Frameworks; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx10.10; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 557951431F73006F001880D1 /* Build configuration list for PBXNativeTarget "XBOBTFF" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 557951411F73006F001880D1 /* Debug */, + 557951421F73006F001880D1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 55ACBFE71D5B9E2F00E4F677 /* Build configuration list for PBXNativeTarget "XboxOneBluetooth" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 55ACBFE51D5B9E2F00E4F677 /* Debug */, + 55ACBFE61D5B9E2F00E4F677 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 55B636AF18C104DB00CE933D /* Build configuration list for PBXProject "360 Driver" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/360 Driver.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/360 Driver.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/360 Driver.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/360Controller/ChatPad.cpp b/360Controller/ChatPad.cpp index 7b8feee8..61ea3f97 100644 --- a/360Controller/ChatPad.cpp +++ b/360Controller/ChatPad.cpp @@ -1,21 +1,21 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + ChatPad.cpp - Implementation of the ChatPad Accessory driver - + This file is part of Xbox360Controller. - + Xbox360Controller is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + Xbox360Controller is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA @@ -34,8 +34,8 @@ OSDefineMetaClassAndStructors(ChatPadKeyboardClass, IOHIDDevice) IOReturn ChatPadKeyboardClass::newReportDescriptor(IOMemoryDescriptor **descriptor) const { IOBufferMemoryDescriptor *buffer; - - buffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, sizeof(HID_ChatPad::ReportDescriptor)); + + buffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, kIODirectionOut, sizeof(HID_ChatPad::ReportDescriptor)); if (buffer == NULL) return kIOReturnNoResources; buffer->writeBytes(0, HID_ChatPad::ReportDescriptor, sizeof(HID_ChatPad::ReportDescriptor)); @@ -106,7 +106,7 @@ OSNumber* ChatPadKeyboardClass::newProductIDNumber() const static IOHIDDevice* GetParent(const IOService *current) { Xbox360Peripheral *owner; - + owner = OSDynamicCast(Xbox360Peripheral, current->getProvider()); if (owner == NULL) return NULL; diff --git a/360Controller/ChatPad.h b/360Controller/ChatPad.h index c7afdfaf..89de84c0 100644 --- a/360Controller/ChatPad.h +++ b/360Controller/ChatPad.h @@ -1,21 +1,21 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + ChatPad.h - Driver class for the ChatPad accessory - + This file is part of Xbox360Controller. - + Xbox360Controller is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + Xbox360Controller is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA @@ -26,7 +26,7 @@ class ChatPadKeyboardClass : public IOHIDDevice { OSDeclareDefaultStructors(ChatPadKeyboardClass) - + private: public: @@ -34,12 +34,12 @@ class ChatPadKeyboardClass : public IOHIDDevice // IOHidDevice methods virtual IOReturn newReportDescriptor(IOMemoryDescriptor **descriptor) const; - + virtual IOReturn setReport(IOMemoryDescriptor *report,IOHIDReportType reportType,IOOptionBits options=0); virtual IOReturn getReport(IOMemoryDescriptor *report,IOHIDReportType reportType,IOOptionBits options); virtual IOReturn handleReport(IOMemoryDescriptor *report, IOHIDReportType reportType = kIOHIDReportTypeInput, IOOptionBits options = 0); - + virtual OSString* newManufacturerString() const; virtual OSNumber* newPrimaryUsageNumber() const; virtual OSNumber* newPrimaryUsagePageNumber() const; @@ -48,6 +48,6 @@ class ChatPadKeyboardClass : public IOHIDDevice virtual OSString* newSerialNumberString() const; virtual OSString* newTransportString() const; virtual OSNumber* newVendorIDNumber() const; - + virtual OSNumber* newLocationIDNumber() const; }; diff --git a/360Controller/ControlStruct.h b/360Controller/ControlStruct.h index 6fe8e722..68f4026f 100644 --- a/360Controller/ControlStruct.h +++ b/360Controller/ControlStruct.h @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + ControlStruct.h - Structures used by the device - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -23,9 +23,9 @@ #ifndef __CONTROLSTRUCT_H__ #define __CONTROLSTRUCT_H__ -typedef UInt8 XBox360_Byte; -typedef UInt16 XBox360_Short; -typedef SInt16 XBox360_SShort; +typedef UInt8 Xbox360_Byte; +typedef UInt16 Xbox360_Short; +typedef SInt16 Xbox360_SShort; #define Xbox360_Prepare(x,t) {memset(&x,0,sizeof(x));x.header.command=t;x.header.size=sizeof(x);} @@ -33,36 +33,36 @@ typedef SInt16 XBox360_SShort; // Common structure format typedef struct XBOX360_PACKET { - XBox360_Byte command; - XBox360_Byte size; + Xbox360_Byte command; + Xbox360_Byte size; } PACKED XBOX360_PACKET; // Analog stick format typedef struct XBOX360_HAT { - XBox360_SShort x,y; + Xbox360_SShort x,y; } PACKED XBOX360_HAT; // Structure describing the report had back from the controller typedef struct XBOX360_IN_REPORT { XBOX360_PACKET header; - XBox360_Short buttons; - XBox360_Byte trigL,trigR; + Xbox360_Short buttons; + Xbox360_Byte trigL,trigR; XBOX360_HAT left,right; - XBox360_Byte reserved[6]; + Xbox360_Byte reserved[6]; } PACKED XBOX360_IN_REPORT; // Structure describing the command to change LED status typedef struct XBOX360_OUT_LED { XBOX360_PACKET header; - XBox360_Byte pattern; + Xbox360_Byte pattern; } PACKED XBOX360_OUT_LED; // Structure describing the command to change rumble motor status typedef struct XBOX360_OUT_RUMBLE { XBOX360_PACKET header; - XBox360_Byte reserved1; - XBox360_Byte big,little; - XBox360_Byte reserved[3]; + Xbox360_Byte reserved1; + Xbox360_Byte big,little; + Xbox360_Byte reserved[3]; } PACKED XBOX360_OUT_RUMBLE; // Enumeration of command types diff --git a/360Controller/Controller.cpp b/360Controller/Controller.cpp index 98f7d5d6..8fd4a191 100644 --- a/360Controller/Controller.cpp +++ b/360Controller/Controller.cpp @@ -1,21 +1,21 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + Controller.cpp - driver class for the 360 controller - + This file is part of Xbox360Controller. - + Xbox360Controller is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + Xbox360Controller is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA @@ -24,18 +24,19 @@ #include #include #include "Controller.h" -#include "ControlStruct.h" namespace HID_360 { #include "xbox360hid.h" } #include "_60Controller.h" +#pragma mark - Xbox360ControllerClass + OSDefineMetaClassAndStructors(Xbox360ControllerClass, IOHIDDevice) static Xbox360Peripheral* GetOwner(IOService *us) { IOService *prov = us->getProvider(); - + if (prov == NULL) return NULL; return OSDynamicCast(Xbox360Peripheral, prov); @@ -44,7 +45,7 @@ static Xbox360Peripheral* GetOwner(IOService *us) static IOUSBDevice* GetOwnerProvider(const IOService *us) { IOService *prov = us->getProvider(), *provprov; - + if (prov == NULL) return NULL; provprov = prov->getProvider(); @@ -71,8 +72,8 @@ IOReturn Xbox360ControllerClass::setProperties(OSObject *properties) // Returns the HID descriptor for this device IOReturn Xbox360ControllerClass::newReportDescriptor(IOMemoryDescriptor **descriptor) const { - IOBufferMemoryDescriptor *buffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task,0,sizeof(HID_360::ReportDescriptor)); - + IOBufferMemoryDescriptor *buffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task,kIODirectionOut,sizeof(HID_360::ReportDescriptor)); + if (buffer == NULL) return kIOReturnNoResources; buffer->writeBytes(0,HID_360::ReportDescriptor,sizeof(HID_360::ReportDescriptor)); *descriptor=buffer; @@ -83,7 +84,7 @@ IOReturn Xbox360ControllerClass::newReportDescriptor(IOMemoryDescriptor **descri IOReturn Xbox360ControllerClass::setReport(IOMemoryDescriptor *report,IOHIDReportType reportType,IOOptionBits options) { char data[2]; - + report->readBytes(0, data, 2); if (GetOwner(this)->rumbleType == 1) // Don't Rumble return kIOReturnSuccess; @@ -92,7 +93,7 @@ IOReturn Xbox360ControllerClass::setReport(IOMemoryDescriptor *report,IOHIDRepor if((data[1]!=report->getLength()) || (data[1]!=0x04)) return kIOReturnUnsupported; { XBOX360_OUT_RUMBLE rumble; - + Xbox360_Prepare(rumble,outRumble); report->readBytes(2,data,2); rumble.big=data[0]; @@ -105,7 +106,7 @@ IOReturn Xbox360ControllerClass::setReport(IOMemoryDescriptor *report,IOHIDRepor if((data[1]!=report->getLength())||(data[1]!=0x03)) return kIOReturnUnsupported; { XBOX360_OUT_LED led; - + report->readBytes(2,data,1); Xbox360_Prepare(led,outLed); led.pattern=data[0]; @@ -132,8 +133,9 @@ IOReturn Xbox360ControllerClass::handleReport(IOMemoryDescriptor * descriptor, I if (desc != NULL) { XBOX360_IN_REPORT *report=(XBOX360_IN_REPORT*)desc->getBytesNoCopy(); if ((report->header.command==inReport) && (report->header.size==sizeof(XBOX360_IN_REPORT))) { - GetOwner(this)->fiddleReport(desc); - remapButtons(report); + GetOwner(this)->fiddleReport(report->left, report->right); + if (!(GetOwner(this)->noMapping)) + remapButtons(report); if (GetOwner(this)->swapSticks) remapAxes(report); } @@ -150,7 +152,7 @@ OSString* Xbox360ControllerClass::getDeviceString(UInt8 index,const char *def) c IOReturn err; char buf[1024]; const char *string; - + err = GetOwnerProvider(this)->GetStringDescriptor(index, buf, sizeof(buf)); if(err==kIOReturnSuccess) string=buf; else { @@ -205,7 +207,7 @@ OSNumber* Xbox360ControllerClass::newLocationIDNumber() const IOUSBDevice *device; OSNumber *number; UInt32 location = 0; - + device = GetOwnerProvider(this); if (device) { @@ -218,12 +220,12 @@ OSNumber* Xbox360ControllerClass::newLocationIDNumber() const // Make up an address if ((number = OSDynamicCast(OSNumber, device->getProperty("USB Address")))) location |= number->unsigned8BitValue() << 24; - + if ((number = OSDynamicCast(OSNumber, device->getProperty("idProduct")))) location |= number->unsigned8BitValue() << 16; } } - + return (location != 0) ? OSNumber::withNumber(location, 32) : 0; } @@ -247,22 +249,48 @@ void Xbox360ControllerClass::remapButtons(void *buffer) new_buttons |= ((report360->buttons & 8192) == 8192) << GetOwner(this)->mapping[12]; new_buttons |= ((report360->buttons & 16384) == 16384) << GetOwner(this)->mapping[13]; new_buttons |= ((report360->buttons & 32768) == 32768) << GetOwner(this)->mapping[14]; - + // IOLog("BUTTON PACKET - %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n", GetOwner(this)->mapping[0], GetOwner(this)->mapping[1], GetOwner(this)->mapping[2], GetOwner(this)->mapping[3], GetOwner(this)->mapping[4], GetOwner(this)->mapping[5], GetOwner(this)->mapping[6], GetOwner(this)->mapping[7], GetOwner(this)->mapping[8], GetOwner(this)->mapping[9], GetOwner(this)->mapping[10], GetOwner(this)->mapping[11], GetOwner(this)->mapping[12], GetOwner(this)->mapping[13], GetOwner(this)->mapping[14]); - + report360->buttons = new_buttons; } void Xbox360ControllerClass::remapAxes(void *buffer) { XBOX360_IN_REPORT *report360 = (XBOX360_IN_REPORT*)buffer; - + XBOX360_HAT temp = report360->left; report360->left = report360->right; report360->right = temp; } +#pragma mark - XboxOnePretend360Class + +/* + * Xbox 360 controller. + * Fake PID and VID of Xbox 360 controller + */ + +OSDefineMetaClassAndStructors(Xbox360Pretend360Class, Xbox360ControllerClass) + +OSString* Xbox360Pretend360Class::newProductString() const +{ + return OSString::withCString("Xbox 360 Wired Controller"); +} + +OSNumber* Xbox360Pretend360Class::newProductIDNumber() const +{ + return OSNumber::withNumber(654,16); +} + +OSNumber* Xbox360Pretend360Class::newVendorIDNumber() const +{ + return OSNumber::withNumber(1118,16); +} + +#pragma mark - XboxOriginalControllerClass + /* * Xbox original controller. * Convert reports to Xbox 360 controller format and fake product ids @@ -270,20 +298,20 @@ void Xbox360ControllerClass::remapAxes(void *buffer) typedef struct { XBOX360_PACKET header; - XBox360_Byte buttons; - XBox360_Byte reserved1; - XBox360_Byte a, b, x, y, black, white; - XBox360_Byte trigL,trigR; - XBox360_Short xL,yL; - XBox360_Short xR,yR; + Xbox360_Byte buttons; + Xbox360_Byte reserved1; + Xbox360_Byte a, b, x, y, black, white; + Xbox360_Byte trigL,trigR; + Xbox360_Short xL,yL; + Xbox360_Short xR,yR; } PACKED XBOX_IN_REPORT; typedef struct { XBOX360_PACKET header; - XBox360_Byte reserved1; - XBox360_Byte left; - XBox360_Byte reserved2; - XBox360_Byte right; + Xbox360_Byte reserved1; + Xbox360_Byte left; + Xbox360_Byte reserved2; + Xbox360_Byte right; } PACKED XBOX_OUT_RUMBLE; @@ -314,9 +342,9 @@ static void logData(UInt8 *data, int len) { IOLog("\n"); } -// This converts XBox original controller report into XBox360 form +// This converts Xbox original controller report into Xbox360 form // See https://github.com/Grumbel/xboxdrv/blob/master/src/controller/xbox_controller.cpp -static void convertFromXBoxOriginal(UInt8 *data) { +static void convertFromXboxOriginal(UInt8 *data) { if (data[0] != 0x00 || data[1] != 0x14) { IOLog("Unknown report command %d, length %d\n", (int)data[0], (int)data[1]); return; @@ -324,7 +352,7 @@ static void convertFromXBoxOriginal(UInt8 *data) { XBOX360_IN_REPORT report; Xbox360_Prepare (report, 0); XBOX_IN_REPORT *in = (XBOX_IN_REPORT*)data; - XBox360_Short buttons = in->buttons; + Xbox360_Short buttons = in->buttons; if (in->a) buttons |= 1 << 12; // a if (in->b) buttons |= 1 << 13; // b if (in->x) buttons |= 1 << 14; // x @@ -348,7 +376,7 @@ IOReturn XboxOriginalControllerClass::handleReport(IOMemoryDescriptor * descript descriptor->readBytes(0, data, sizeof(XBOX360_IN_REPORT)); const XBOX360_IN_REPORT *report=(const XBOX360_IN_REPORT*)data; if ((report->header.command==inReport) && (report->header.size==sizeof(XBOX360_IN_REPORT))) { - convertFromXBoxOriginal(data); + convertFromXboxOriginal(data); if (memcmp(data, lastData, sizeof(XBOX360_IN_REPORT)) == 0) { repeatCount ++; // drop triplicate reports @@ -369,7 +397,7 @@ IOReturn XboxOriginalControllerClass::handleReport(IOMemoryDescriptor * descript IOLog("%s %d \n", __FUNCTION__, (int)reportType); logData(data, (int)descriptor->getLength()); } - + } else { descriptor->readBytes(0, data, descriptor->getLength()); if (reportType != 0 && data[0] != 0) { @@ -378,7 +406,7 @@ IOReturn XboxOriginalControllerClass::handleReport(IOMemoryDescriptor * descript logData(data, (int)descriptor->getLength()); } } - + IOReturn ret = Xbox360ControllerClass::handleReport(descriptor, reportType, options); //IOLog("%s END\n", __FUNCTION__); return ret; @@ -387,7 +415,7 @@ IOReturn XboxOriginalControllerClass::handleReport(IOMemoryDescriptor * descript IOReturn XboxOriginalControllerClass::setReport(IOMemoryDescriptor *report,IOHIDReportType reportType,IOOptionBits options) { char data[2]; - + report->readBytes(0, data, 2); if (GetOwner(this)->rumbleType == 1) // Don't Rumble return kIOReturnSuccess; @@ -408,16 +436,19 @@ IOReturn XboxOriginalControllerClass::setReport(IOMemoryDescriptor *report,IOHID if((data[1]!=report->getLength())||(data[1]!=0x03)) return kIOReturnUnsupported; // No leds return kIOReturnSuccess; - + default: IOLog("Unknown escape %d\n", data[0]); return kIOReturnUnsupported; } } + +#pragma mark - XboxOneControllerClass + /* * Xbox One controller. - * Convert reports to Xbox 360 controller format and fake product ids + * Does not pretend to be an Xbox 360 controller. */ typedef struct { @@ -434,6 +465,49 @@ typedef struct { XBOX360_HAT left, right; } PACKED XBOXONE_IN_REPORT; +typedef struct { + XBOXONE_HEADER header; + UInt16 buttons; + UInt16 trigL, trigR; + XBOX360_HAT left, right; + UInt8 unknown1[6]; + UInt8 triggersAsButtons; // 0x40 is RT. 0x80 is LT + UInt8 unknown2[7]; +} PACKED XBOXONE_IN_FIGHTSTICK_REPORT; + +typedef struct { + XBOXONE_HEADER header; + UInt16 buttons; + union { + UInt16 steering; // leftX + SInt16 leftX; + }; + union { + UInt16 accelerator; + UInt16 trigR; + }; + union { + UInt16 brake; + UInt16 trigL; + }; + union { + UInt8 clutch; + UInt8 leftY; + }; + UInt8 unknown3[8]; +} PACKED XBOXONE_IN_WHEEL_REPORT; + +typedef struct { + XBOXONE_HEADER header; + UInt16 buttons; + UInt16 trigL, trigR; + XBOX360_HAT left, right; + UInt16 true_buttons; + UInt16 true_trigL, true_trigR; + XBOX360_HAT true_left, true_right; + UInt8 paddle; +} PACKED XBOXONE_ELITE_IN_REPORT; + typedef struct { XBOXONE_HEADER header; UInt8 state; @@ -441,135 +515,220 @@ typedef struct { } PACKED XBOXONE_IN_GUIDE_REPORT; typedef struct { - UInt8 command; // 0x09 - UInt8 reserved1; // So far 0x08 - UInt8 reserved2; // So far always 0x00 - UInt8 substructure; // 0x08 - Continuous, 0x09 - Single + XBOXONE_HEADER header; + UInt8 data[4]; + UInt8 zero[5]; +} PACKED XBOXONE_OUT_GUIDE_REPORT; + +typedef struct { + XBOXONE_HEADER header; UInt8 mode; // So far always 0x00 UInt8 rumbleMask; // So far always 0x0F UInt8 trigL, trigR; UInt8 little, big; UInt8 length; // Length of time to rumble UInt8 period; // Period of time between pulses. DO NOT INCLUDE WHEN SUBSTRUCTURE IS 0x09 + UInt8 extra; } PACKED XBOXONE_OUT_RUMBLE; +typedef struct { + XBOXONE_HEADER header; // 0x0a 0x20 0x04 0x03 + UInt8 zero; + UInt8 command; + UInt8 brightness; // 0x00 - 0x20 +} PACKED XBOXONE_OUT_LED; + +typedef enum { + XONE_SYNC = 0x0001, // Bit 00 + XONE_MENU = 0x0004, // Bit 02 + XONE_VIEW = 0x0008, // Bit 03 + XONE_A = 0x0010, // Bit 04 + XONE_B = 0x0020, // Bit 05 + XONE_X = 0x0040, // Bit 06 + XONE_Y = 0x0080, // Bit 07 + XONE_DPAD_UP = 0x0100, // Bit 08 + XONE_DPAD_DOWN = 0x0200, // Bit 09 + XONE_DPAD_LEFT = 0x0400, // Bit 10 + XONE_DPAD_RIGHT = 0x0800, // Bit 11 + XONE_LEFT_SHOULDER = 0x1000, // Bit 12 + XONE_RIGHT_SHOULDER = 0x2000, // Bit 13 + XONE_LEFT_THUMB = 0x4000, // Bit 14 + XONE_RIGHT_THUMB = 0x8000, // Bit 15 +} GAMEPAD_XONE; + +typedef enum { + XONE_PADDLE_UPPER_LEFT = 0x0001, // Bit 00 + XONE_PADDLE_UPPER_RIGHT = 0x0002, // Bit 01 + XONE_PADDLE_LOWER_LEFT = 0x0004, // Bit 02 + XONE_PADDLE_LOWER_RIGHT = 0x0008, // Bit 03 + XONE_PADDLE_PRESET_NUM = 0x0010, // Bit 04 +} GAMEPAD_XONE_ELITE_PADDLE; + +typedef enum { + XONE_LED_OFF_1 = 0x00, + XONE_LED_SOLID = 0x01, + XONE_LED_BLINK_FAST = 0x02, + XONE_LED_BLINK_SLOW = 0x03, + XONE_LED_BLINK_VERY_SLOW = 0x04, + XONE_LED_SOLD_1 = 0x05, + XONE_LED_SOLD_2 = 0x06, + XONE_LED_SOLD_3 = 0x07, + XONE_LED_PHASE_SLOW = 0x08, + XONE_LED_PHASE_FAST = 0x09, + XONE_LED_REBOOT_1 = 0x0a, + XONE_LED_OFF = 0x0b, + XONE_LED_FLICKER = 0x0c, + XONE_LED_SOLID_4 = 0x0d, + XONE_LED_SOLID_5 = 0x0e, + XONE_LED_REBOOT_2 = 0x0f, +} LED_XONE; + OSDefineMetaClassAndStructors(XboxOneControllerClass, Xbox360ControllerClass) -OSNumber* XboxOneControllerClass::newVendorIDNumber() const +OSString* XboxOneControllerClass::newProductString() const { - return OSNumber::withNumber(1118,16); + return OSString::withCString("Xbox One Wired Controller"); } -OSString* XboxOneControllerClass::newManufacturerString() const +UInt16 XboxOneControllerClass::convertButtonPacket(UInt16 buttons) { - return OSString::withCString("Microsoft"); -} + UInt16 new_buttons = 0; -OSNumber* XboxOneControllerClass::newProductIDNumber() const -{ - return OSNumber::withNumber(654,16); -} + new_buttons |= ((buttons & 4) == 4) << 4; + new_buttons |= ((buttons & 8) == 8) << 5; + new_buttons |= ((buttons & 16) == 16) << 12; + new_buttons |= ((buttons & 32) == 32) << 13; + new_buttons |= ((buttons & 64) == 64) << 14; + new_buttons |= ((buttons & 128) == 128) << 15; + new_buttons |= ((buttons & 256) == 256) << 0; + new_buttons |= ((buttons & 512) == 512) << 1; + new_buttons |= ((buttons & 1024) == 1024) << 2; + new_buttons |= ((buttons & 2048) == 2048) << 3; + new_buttons |= ((buttons & 4096) == 4096) << 8; + new_buttons |= ((buttons & 8192) == 8192) << 9; + new_buttons |= ((buttons & 16384) == 16384) << 6; + new_buttons |= ((buttons & 32768) == 32768) << 7; -OSString* XboxOneControllerClass::newProductString() const -{ - return OSString::withCString("Xbox One Wired Controller"); + new_buttons |= (isXboxOneGuideButtonPressed) << 10; + + return new_buttons; } -// This converts Xbox One controller report into Xbox360 form -void XboxOneControllerClass::convertFromXboxOne(void *buffer, void* override) { - -// if (data[0] != 0x00 || data[1] != 0x14) { -// IOLog("Unknown report command %d, length %d\n", (int)data[0], (int)data[1]); -// return; -// } - +void XboxOneControllerClass::convertFromXboxOne(void *buffer, UInt8 packetSize) +{ + XBOXONE_ELITE_IN_REPORT *reportXone = (XBOXONE_ELITE_IN_REPORT*)buffer; XBOX360_IN_REPORT *report360 = (XBOX360_IN_REPORT*)buffer; UInt8 trigL = 0, trigR = 0; - UInt16 new_buttons = 0; XBOX360_HAT left, right; - - if (override == NULL) { - XBOXONE_IN_REPORT *reportXone = (XBOXONE_IN_REPORT*)buffer; - report360->header.command = reportXone->header.command - 0x20; // Change 0x20 into 0x00 - report360->header.size = reportXone->header.size + 0x06; // Change 0x0E into 0x14 + + report360->header.command = 0x00; + report360->header.size = 0x14; + + if (packetSize == 0x1a) // Fight Stick + { + if ((0x80 & reportXone->true_trigR) == 0x80) { trigL = 255; } + if ((0x40 & reportXone->true_trigR) == 0x40) { trigR = 255; } - new_buttons |= ((reportXone->buttons & 4) == 4) << 4; - new_buttons |= ((reportXone->buttons & 8) == 8) << 5; - new_buttons |= ((reportXone->buttons & 16) == 16) << 12; - new_buttons |= ((reportXone->buttons & 32) == 32) << 13; - new_buttons |= ((reportXone->buttons & 64) == 64) << 14; - new_buttons |= ((reportXone->buttons & 128) == 128) << 15; - new_buttons |= ((reportXone->buttons & 256) == 256) << 0; - new_buttons |= ((reportXone->buttons & 512) == 512) << 1; - new_buttons |= ((reportXone->buttons & 1024) == 1024) << 2; - new_buttons |= ((reportXone->buttons & 2048) == 2048) << 3; - new_buttons |= ((reportXone->buttons & 4096) == 4096) << 8; - new_buttons |= ((reportXone->buttons & 8192) == 8192) << 9; - new_buttons |= ((reportXone->buttons & 16384) == 16384) << 6; - new_buttons |= ((reportXone->buttons & 32768) == 32768) << 7; - new_buttons |= (isXboxOneGuideButtonPressed) << 10; + left = reportXone->left; + right = reportXone->right; + } + else if (packetSize == 0x11) // Racing Wheel + { + XBOXONE_IN_WHEEL_REPORT *wheelReport=(XBOXONE_IN_WHEEL_REPORT*)buffer; + + trigR = (wheelReport->accelerator / 1023.0) * 255; // UInt16 -> UInt8 + trigL = (wheelReport->brake / 1023.0) * 255; // UInt16 -> UInt8 + left.x = wheelReport->steering - 32768; // UInt16 -> SInt16 + left.y = wheelReport->clutch * 128; // Clutch is 0-255. Upconvert to half signed 16 range. (0 - 32640) + right = {}; + } + else // Traditional Controllers + { trigL = (reportXone->trigL / 1023.0) * 255; trigR = (reportXone->trigR / 1023.0) * 255; + left = reportXone->left; right = reportXone->right; - - report360->buttons = new_buttons; - report360->trigL = trigL; - report360->trigR = trigR; - report360->left = left; - report360->right = right; - } else { - XBOX360_IN_REPORT *reportOverride = (XBOX360_IN_REPORT*)override; - report360->header = reportOverride->header; - report360->buttons = reportOverride->buttons; - report360->buttons |= (isXboxOneGuideButtonPressed) << 10; - report360->trigL = reportOverride->trigL; - report360->trigR = reportOverride->trigR; - report360->left = reportOverride->left; - report360->right = reportOverride->right; } + + report360->buttons = convertButtonPacket(reportXone->buttons); + report360->trigL = trigL; + report360->trigR = trigR; + report360->left = left; + report360->right = right; } -IOReturn XboxOneControllerClass::handleReport(IOMemoryDescriptor * descriptor, IOHIDReportType reportType, IOOptionBits options) { - UInt8 data[sizeof(XBOXONE_IN_REPORT)]; - descriptor->readBytes(0, data, sizeof(XBOXONE_IN_REPORT)); - const XBOXONE_IN_REPORT *report=(const XBOXONE_IN_REPORT*)data; - if ((report->header.command==0x20) && report->header.size==(sizeof(XBOXONE_IN_REPORT)-4)) { - convertFromXboxOne(data, NULL); - memcpy(lastData, data, sizeof(XBOX360_IN_REPORT)); - descriptor->writeBytes(0, data, sizeof(XBOX360_IN_REPORT)); - } - else if (report->header.command==0x07 && report->header.size==(sizeof(XBOXONE_IN_GUIDE_REPORT)-4)) - { - const XBOXONE_IN_GUIDE_REPORT *guideReport=(const XBOXONE_IN_GUIDE_REPORT*)report; - isXboxOneGuideButtonPressed = (bool)guideReport->state; - convertFromXboxOne(data, lastData); - descriptor->writeBytes(0, data, sizeof(XBOX360_IN_REPORT)); +IOReturn XboxOneControllerClass::handleReport(IOMemoryDescriptor * descriptor, IOHIDReportType reportType, IOOptionBits options) +{ + if (descriptor->getLength() >= sizeof(XBOXONE_IN_GUIDE_REPORT)) { + IOBufferMemoryDescriptor *desc = OSDynamicCast(IOBufferMemoryDescriptor, descriptor); + if (desc != NULL) { + XBOXONE_ELITE_IN_REPORT *report=(XBOXONE_ELITE_IN_REPORT*)desc->getBytesNoCopy(); + if ((report->header.command==0x07) && (report->header.size==(sizeof(XBOXONE_IN_GUIDE_REPORT)-4))) + { + XBOXONE_IN_GUIDE_REPORT *guideReport=(XBOXONE_IN_GUIDE_REPORT*)report; + + if (guideReport->header.reserved1 == 0x30) // 2016 Controller + { + XBOXONE_OUT_GUIDE_REPORT outReport = {}; + outReport.header.command = 0x01; + outReport.header.reserved1 = 0x20; + outReport.header.counter = guideReport->header.counter; + outReport.header.size = 0x09; + outReport.data[0] = 0x00; + outReport.data[1] = 0x07; + outReport.data[2] = 0x20; + outReport.data[3] = 0x02; + + GetOwner(this)->QueueWrite(&outReport, 13); + } + + isXboxOneGuideButtonPressed = (bool)guideReport->state; + XBOX360_IN_REPORT *oldReport = (XBOX360_IN_REPORT*)lastData; + oldReport->buttons ^= (-isXboxOneGuideButtonPressed ^ oldReport->buttons) & (1 << GetOwner(this)->mapping[10]); + memcpy(report, lastData, sizeof(XBOX360_IN_REPORT)); + } + else if (report->header.command==0x20) + { + convertFromXboxOne(report, report->header.size); + XBOX360_IN_REPORT *report360=(XBOX360_IN_REPORT*)report; + if (!(GetOwner(this)->noMapping)) + remapButtons(report360); + GetOwner(this)->fiddleReport(report360->left, report360->right); + + if (GetOwner(this)->swapSticks) + remapAxes(report360); + + memcpy(lastData, report360, sizeof(XBOX360_IN_REPORT)); + } + } } - - IOReturn ret = Xbox360ControllerClass::handleReport(descriptor, reportType, options); + IOReturn ret = IOHIDDevice::handleReport(descriptor, reportType, options); return ret; } IOReturn XboxOneControllerClass::setReport(IOMemoryDescriptor *report,IOHIDReportType reportType,IOOptionBits options) { -// IOLog("Xbox One Controller - setReport\n"); + // IOLog("Xbox One Controller - setReport\n"); unsigned char data[4]; report->readBytes(0, &data, 4); -// IOLog("Attempting to send: %d %d %d %d\n",((unsigned char*)data)[0], ((unsigned char*)data)[1], ((unsigned char*)data)[2], ((unsigned char*)data)[3]); +// IOLog("Attempting to send: %d %d %d %d\n",((unsigned char*)data)[0], ((unsigned char*)data)[1], ((unsigned char*)data)[2], ((unsigned char*)data)[3]); UInt8 rumbleType; switch(data[0])//(header.command) { case 0x00: // Set force feedback XBOXONE_OUT_RUMBLE rumble; - rumble.command = 0x09; - rumble.reserved1 = 0x08; - rumble.reserved2 = 0x00; - rumble.substructure = 0x09; + rumble.header.command = 0x09; + rumble.header.reserved1 = 0x00; + rumble.header.counter = (GetOwner(this)->outCounter)++; + rumble.header.size = 0x09; rumble.mode = 0x00; rumble.rumbleMask = 0x0F; - rumble.length = 0x80; - + rumble.length = 0xFF; + rumble.period = 0x00; + rumble.extra = 0x00; +// IOLog("Data: %d %d %d %d, outCounter: %d\n", data[0], data[1], data[2], data[3], rumble.reserved2); + rumbleType = GetOwner(this)->rumbleType; if (rumbleType == 0) // Default { @@ -596,8 +755,8 @@ IOReturn XboxOneControllerClass::setReport(IOMemoryDescriptor *report,IOHIDRepor rumble.little = data[2]; rumble.big = data[3]; } - - GetOwner(this)->QueueWrite(&rumble,11); + + GetOwner(this)->QueueWrite(&rumble,13); return kIOReturnSuccess; case 0x01: // Unsupported LED return kIOReturnSuccess; @@ -606,3 +765,28 @@ IOReturn XboxOneControllerClass::setReport(IOMemoryDescriptor *report,IOHIDRepor return kIOReturnUnsupported; } } + + +#pragma mark - XboxOnePretend360Class + +/* + * Xbox One controller. + * Fake PID and VID of Xbox 360 controller + */ + +OSDefineMetaClassAndStructors(XboxOnePretend360Class, XboxOneControllerClass) + +OSString* XboxOnePretend360Class::newProductString() const +{ + return OSString::withCString("Xbox 360 Wired Controller"); +} + +OSNumber* XboxOnePretend360Class::newProductIDNumber() const +{ + return OSNumber::withNumber(654,16); +} + +OSNumber* XboxOnePretend360Class::newVendorIDNumber() const +{ + return OSNumber::withNumber(1118,16); +} diff --git a/360Controller/Controller.h b/360Controller/Controller.h index 0d9c7319..db24d4af 100644 --- a/360Controller/Controller.h +++ b/360Controller/Controller.h @@ -1,21 +1,21 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + Controller.h - Driver class for the 360 controller - + This file is part of Xbox360Controller. - + Xbox360Controller is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + Xbox360Controller is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA @@ -25,7 +25,10 @@ class Xbox360ControllerClass : public IOHIDDevice { - OSDeclareDefaultStructors(Xbox360ControllerClass) + OSDeclareDefaultStructors(Xbox360ControllerClass) + +private: + bool pretend360; private: OSString* getDeviceString(UInt8 index,const char *def=NULL) const; @@ -36,14 +39,14 @@ class Xbox360ControllerClass : public IOHIDDevice virtual IOReturn setProperties(OSObject *properties); virtual IOReturn newReportDescriptor(IOMemoryDescriptor **descriptor) const; - + virtual IOReturn setReport(IOMemoryDescriptor *report,IOHIDReportType reportType,IOOptionBits options=0); virtual IOReturn getReport(IOMemoryDescriptor *report,IOHIDReportType reportType,IOOptionBits options); virtual IOReturn handleReport( IOMemoryDescriptor * report, IOHIDReportType reportType = kIOHIDReportTypeInput, IOOptionBits options = 0 ); - + virtual OSString* newManufacturerString() const; virtual OSNumber* newPrimaryUsageNumber() const; virtual OSNumber* newPrimaryUsagePageNumber() const; @@ -52,29 +55,40 @@ class Xbox360ControllerClass : public IOHIDDevice virtual OSString* newSerialNumberString() const; virtual OSString* newTransportString() const; virtual OSNumber* newVendorIDNumber() const; - + virtual OSNumber* newLocationIDNumber() const; - + virtual void remapButtons(void *buffer); virtual void remapAxes(void *buffer); }; +class Xbox360Pretend360Class : public Xbox360ControllerClass +{ + OSDeclareDefaultStructors(Xbox360Pretend360Class) + +public: + virtual OSString* newProductString() const; + virtual OSNumber* newProductIDNumber() const; + virtual OSNumber* newVendorIDNumber() const; +}; + + class XboxOriginalControllerClass : public Xbox360ControllerClass { OSDeclareDefaultStructors(XboxOriginalControllerClass) - + private: UInt8 lastData[32]; UInt32 repeatCount; - + public: virtual IOReturn setReport(IOMemoryDescriptor *report,IOHIDReportType reportType,IOOptionBits options=0); virtual IOReturn handleReport( IOMemoryDescriptor * report, IOHIDReportType reportType = kIOHIDReportTypeInput, IOOptionBits options = 0 ); - + virtual OSString* newManufacturerString() const; virtual OSNumber* newProductIDNumber() const; virtual OSNumber* newVendorIDNumber() const; @@ -85,23 +99,33 @@ class XboxOriginalControllerClass : public Xbox360ControllerClass class XboxOneControllerClass : public Xbox360ControllerClass { OSDeclareDefaultStructors(XboxOneControllerClass) - + #define XboxOne_Prepare(x,t) {memset(&x,0,sizeof(x));x.header.command=t;x.header.size=sizeof(x-4);} - -private: + +protected: UInt8 lastData[20]; bool isXboxOneGuideButtonPressed; - + void reorderButtons(UInt16* buttons, UInt8 mapping[]); + UInt16 convertButtonPacket(UInt16 buttons); + public: virtual IOReturn setReport(IOMemoryDescriptor *report,IOHIDReportType reportType,IOOptionBits options=0); virtual IOReturn handleReport( IOMemoryDescriptor * report, IOHIDReportType reportType = kIOHIDReportTypeInput, IOOptionBits options = 0 ); - - virtual OSString* newManufacturerString() const; + + virtual void convertFromXboxOne(void *buffer, UInt8 packetSize); + virtual OSString* newProductString() const; +}; + + +class XboxOnePretend360Class : public XboxOneControllerClass +{ + OSDeclareDefaultStructors(XboxOnePretend360Class) + +public: + virtual OSString* newProductString() const; virtual OSNumber* newProductIDNumber() const; virtual OSNumber* newVendorIDNumber() const; - virtual OSString* newProductString() const; - virtual void convertFromXboxOne(void *buffer, void* override); }; diff --git a/360Controller/Info.plist b/360Controller/Info.plist index a18c49c4..e6893f5b 100644 --- a/360Controller/Info.plist +++ b/360Controller/Info.plist @@ -14,10 +14,14 @@ ${PRODUCT_NAME} CFBundlePackageType KEXT + CFBundleShortVersionString + $(CURRENT_PROJECT_VERSION) CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} + LSMinimumSystemVersion + ${MIN_MACOS_VERSION} IOKitPersonalities AfterglowGamepad1 @@ -36,11 +40,11 @@ IOProviderClass IOUSBDevice idProduct - 1043 + 64252 idVendor - 3695 + 9414 - ArcadeGameStick + AfterglowGamepad2 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -56,11 +60,11 @@ IOProviderClass IOUSBDevice idProduct - 18264 + 63751 idVendor - 1848 + 7085 - BETOPGAMEFORWINDOWS + AfterglowGamepad3 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -76,11 +80,11 @@ IOProviderClass IOUSBDevice idProduct - 21766 + 64253 idVendor - 4544 + 9414 - BatarangWired + AfterglowGamepad4 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -96,11 +100,11 @@ IOProviderClass IOUSBDevice idProduct - 16144 + 742 idVendor - 5604 + 1118 - BigBenController + AfterglowGamepad5 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -116,22 +120,31 @@ IOProviderClass IOUSBDevice idProduct - 1537 + 768 idVendor - 5227 + 7085 - ChatPadKeyboardEvents + AfterglowGamepad6 CFBundleIdentifier - com.apple.iokit.IOHIDFamily + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + IOClass - IOHIDEventDriver + Xbox360Peripheral + IOKitDebug + 65535 IOProviderClass - IOHIDInterface - VendorID - 100 + IOUSBDevice + idProduct + 22554 + idVendor + 9414 - Chinese-madeXboxController + AfterglowGamepadForXbox360 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -147,11 +160,31 @@ IOProviderClass IOUSBDevice idProduct - 65535 + 1043 idVendor + 3695 + + AfterglowPrismaticOne1 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug 65535 + IOProviderClass + IOUSBDevice + idProduct + 313 + idVendor + 3695 - Controller + AfterglowPrismaticOne2 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -167,11 +200,11 @@ IOProviderClass IOUSBDevice idProduct - 654 + 691 idVendor - 1118 + 3695 - DOA4Stick + AfterglowPrismaticOne3 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -187,11 +220,11 @@ IOProviderClass IOUSBDevice idProduct - 10 + 696 idVendor - 3853 + 3695 - GEMPADEX + AtplayController1 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -207,11 +240,11 @@ IOProviderClass IOUSBDevice idProduct - 21773 + 64250 idVendor 9414 - GameStopGamepad3 + AtplayController2 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -227,11 +260,11 @@ IOProviderClass IOUSBDevice idProduct - 1025 + 64251 idVendor - 3695 + 9414 - GameStopGamepad4 + AtplayController3 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -247,11 +280,11 @@ IOProviderClass IOUSBDevice idProduct - 769 + 690 idVendor 3695 - GamestopGamepad + ArcadeGameStick CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -267,11 +300,11 @@ IOProviderClass IOUSBDevice idProduct - 770 + 18264 idVendor - 4779 + 1848 - GamestopGamepad2 + Ardwiino CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -287,11 +320,11 @@ IOProviderClass IOUSBDevice idProduct - 63745 + 10370 idVendor - 7085 + 4617 - GenericController + BETOPGAMEFORWINDOWS CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -307,11 +340,11 @@ IOProviderClass IOUSBDevice idProduct - 62209 + 21766 idVendor - 1133 + 4544 - GuitarHero + BatarangWired CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -327,11 +360,11 @@ IOProviderClass IOUSBDevice idProduct - 18248 + 16144 idVendor - 5168 + 5604 - HoriFSVX + BD&AAirFloController CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -347,11 +380,11 @@ IOProviderClass IOUSBDevice idProduct - 62723 + 21251 idVendor - 7085 + 9414 - HoriFightingStickEX2 + BigBenController CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -367,11 +400,11 @@ IOProviderClass IOUSBDevice idProduct - 10 + 1537 idVendor - 3853 + 5227 - HoriFightingStickEX2B + BrookNEOGEOConverter CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -387,11 +420,11 @@ IOProviderClass IOUSBDevice idProduct - 62725 + 2036 idVendor - 7085 + 3090 - HoriFightingStickEX2C + BrookPS2Converter CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -407,11 +440,22 @@ IOProviderClass IOUSBDevice idProduct - 13 + 2289 idVendor - 3853 + 3090 - HoriPadEX2Turbo + ChatPadKeyboardEvents + + CFBundleIdentifier + com.apple.iokit.IOHIDFamily + IOClass + IOHIDEventDriver + IOProviderClass + IOHIDInterface + VendorID + 100 + + Chinese-madeXboxController CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -427,11 +471,11 @@ IOProviderClass IOUSBDevice idProduct - 62721 + 65535 idVendor - 7085 + 65535 - HoriPadEXTurbo + Controller CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -447,11 +491,11 @@ IOProviderClass IOUSBDevice idProduct - 12 + 654 idVendor - 3853 + 1118 - HoriPadOne + Controller2 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -467,11 +511,11 @@ IOProviderClass IOUSBDevice idProduct - 103 + 655 idVendor - 3853 + 1118 - HoriRAPHayabusaXboxOne + Controller3 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -487,11 +531,11 @@ IOProviderClass IOUSBDevice idProduct - 99 + 307 idVendor - 3853 + 3695 - HoriRAPVXSA + Controller4 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -507,11 +551,11 @@ IOProviderClass IOUSBDevice idProduct - 62722 + 63233 idVendor - 7085 + 3695 - HoriUnnamed + Counterfeit360Controller1 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -527,11 +571,11 @@ IOProviderClass IOUSBDevice idProduct - 21760 + 672 idVendor - 7085 + 3695 - HoriUnnamedBlueSolo + Counterfeit360Controller2 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -547,11 +591,11 @@ IOProviderClass IOUSBDevice idProduct - 64001 + 62721 idVendor - 7085 + 3695 - IonDrumRocker + DOA4Stick CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -567,11 +611,11 @@ IOProviderClass IOUSBDevice idProduct - 304 + 10 idVendor - 7085 + 3853 - JoytekXbox360 + DragonRiseFightStick CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -587,11 +631,11 @@ IOProviderClass IOUSBDevice idProduct - 48879 + 6268 idVendor - 5678 + 121 - KonamiDancePad + ElecomJCU3613M CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -607,11 +651,11 @@ IOProviderClass IOUSBDevice idProduct - 4 + 8196 idVendor - 4779 + 1390 - LogitechF310 + FUSIONProXboxOne CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -627,11 +671,11 @@ IOProviderClass IOUSBDevice idProduct - 49693 + 21786 idVendor - 1133 + 9414 - LogitechF510 + FUSIONXboxOne CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -647,11 +691,11 @@ IOProviderClass IOUSBDevice idProduct - 49694 + 22042 idVendor - 1133 + 9414 - LogitechF710 + GEMPADEX CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -667,11 +711,11 @@ IOProviderClass IOUSBDevice idProduct - 49695 + 21773 idVendor - 1133 + 9414 - MLGGamePadforXbox360 + GameStopGamepad3 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -687,11 +731,11 @@ IOProviderClass IOUSBDevice idProduct - 61475 + 1025 idVendor - 7085 + 3695 - MVC2TEStick + GameStopGamepad4 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -707,11 +751,11 @@ IOProviderClass IOUSBDevice idProduct - 61497 + 769 idVendor - 7085 + 3695 - MVC2TEStick2 + GamestopGamepad CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -727,11 +771,11 @@ IOProviderClass IOUSBDevice idProduct - 46904 + 770 idVendor - 1848 + 4779 - MadCatzBrawlStick + GamestopGamepad2 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -747,11 +791,11 @@ IOProviderClass IOUSBDevice idProduct - 61465 + 63745 idVendor 7085 - MadCatzFPSPro + GenericController CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -767,11 +811,11 @@ IOProviderClass IOUSBDevice idProduct - 61479 + 62209 idVendor - 7085 + 1133 - MadCatzFightPad + GuitarHero CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -787,11 +831,11 @@ IOProviderClass IOUSBDevice idProduct - 61486 + 18248 idVendor - 7085 + 5168 - MadCatzFightStickNeo + HarmonixDrumKit360 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -807,11 +851,11 @@ IOProviderClass IOUSBDevice idProduct - 61498 + 4408 idVendor 7085 - MadCatzFightStickSoulCaliber + HarmonixKeyboard360 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -827,11 +871,11 @@ IOProviderClass IOUSBDevice idProduct - 61503 + 4920 idVendor 7085 - MadCatzFightStickTE2 + HarmonixGuitar360 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -847,11 +891,11 @@ IOProviderClass IOUSBDevice idProduct - 61568 + 5432 idVendor 7085 - MadCatzGamepad + HoneyBee360Gamepad CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -867,11 +911,11 @@ IOProviderClass IOUSBDevice idProduct - 18198 + 21760 idVendor - 1848 + 4779 - MadCatzGamepad2 + HORI Real Arcade Pro.EX Premium VLX CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -887,11 +931,11 @@ IOProviderClass IOUSBDevice idProduct - 63746 + 62726 idVendor 7085 - MadCatzGamepad3 + HoriClassicControllerSwitch CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -907,11 +951,11 @@ IOProviderClass IOUSBDevice idProduct - 61642 + 220 idVendor - 7085 + 3853 - MadCatzMicroConGamepad + HoriEdge301 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -927,11 +971,2491 @@ IOProviderClass IOUSBDevice idProduct - 18230 + 109 + idVendor + 3853 + + HoriEX2 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 13 + idVendor + 3853 + + HoriFSVX + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 62723 + idVendor + 7085 + + HoriFSVXAlt + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 21762 + idVendor + 9414 + + HoriFightingCommander + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 197 + idVendor + 3853 + + HoriFightingCommander2 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 21776 + idVendor + 9414 + + HoriFightingCommanderPS4 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 134 + idVendor + 3853 + + HoriFightingEdge + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 21763 + idVendor + 9414 + + HoriFightingStickEX2 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 10 + idVendor + 3853 + + HoriFightingStickEX2B + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 62725 + idVendor + 7085 + + HoriFightingStickEX2C + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 13 + idVendor + 3853 + + HoriFightingStickMini + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 237 + idVendor + 3853 + + HoriPadEX2Turbo1 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 62721 + idVendor + 7085 + + HoriPadEX2Turbo2 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 21760 + idVendor + 9414 + + HoriPadEXTurbo + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 12 + idVendor + 3853 + + HoriPadOne1 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 103 + idVendor + 3853 + + HoriPadOne2 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 256 + idVendor + 3853 + + HoriPadUltimate + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 144 + idVendor + 3853 + + HoriRAP4 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 140 + idVendor + 3853 + + HoriRAPHayabusaXboxOne + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 99 + idVendor + 3853 + + HoriRAPN4 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 174 + idVendor + 3853 + + HoriRAPVHayabusaSwitch + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 216 + idVendor + 3853 + + HoriRAPVKai360 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 21774 + idVendor + 9414 + + HoriRAPVKaiXboxOne + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 120 + idVendor + 3853 + + HoriRAPVX + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 27 + idVendor + 3853 + + HoriRAPVXSA + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 62722 + idVendor + 7085 + + HoriRAPVXSA2 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 21761 + idVendor + 9414 + + HoriUnnamed + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 21760 + idVendor + 7085 + + HoriUnnamed2 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 654 + idVendor + 7085 + + HoriUnnamedBlueSolo + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 64001 + idVendor + 7085 + + HyperkinX91 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 5768 + idVendor + 11812 + + INJUSTICEFightStick360 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 293 + idVendor + 3695 + + IonDrumRocker + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 304 + idVendor + 7085 + + JoytekXbox360 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 48879 + idVendor + 5678 + + KonamiDancePad + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 4 + idVendor + 4779 + + LogitechChillStream + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 49730 + idVendor + 1133 + + LogitechDriveFx + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 51875 + idVendor + 1133 + + LogitechF310 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 49693 + idVendor + 1133 + + LogitechF310Alt + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 49686 + idVendor + 1133 + + LogitechF510 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 49694 + idVendor + 1133 + + LogitechF710 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 49695 + idVendor + 1133 + + LogitechG920 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 49761 + idVendor + 1133 + + LogitechTHUNDERPAD + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 51848 + idVendor + 1133 + + MKKlassicFightStick + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 771 + idVendor + 4779 + + MLGGamePadforXbox360 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 61475 + idVendor + 7085 + + MVC2TEStick + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 61497 + idVendor + 7085 + + MVC2TEStick2 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 46904 + idVendor + 1848 + + MadCatzBrawlStick + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 61465 + idVendor + 7085 + + MadCatzCallOfDuty + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 61477 + idVendor + 7085 + + MadCatzFPSPro + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 61479 + idVendor + 7085 + + MadCatzFightPad + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 61486 + idVendor + 7085 + + MadCatzFightStickNeo + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 61498 + idVendor + 7085 + + MadCatzFightStickSoulCaliber + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 61503 + idVendor + 7085 + + MadCatzFightStickTE2 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 61568 + idVendor + 7085 + + MadCatzFightStickTES+ + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 61506 + idVendor + 7085 + + MadCatzGamepad + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 18198 + idVendor + 1848 + + MadCatzGamepad2 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 63746 + idVendor + 7085 + + MadCatzGamepad3 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 61642 + idVendor + 7085 + + MadCatzGamepad4 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 672 + idVendor + 1848 + + MadCatzGhostReconFS + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 61473 + idVendor + 7085 + + MadCatzInnoGamePad + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 62465 + idVendor + 1848 + + MadCatzMC2 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 61472 + idVendor + 7085 + + MadCatzMLGFightStickTE + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 61502 + idVendor + 7085 + + MadCatzMicroConGamepad + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 18230 + idVendor + 1848 + + MadCatzMicroGamepad + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 18230 + idVendor + 1848 + + MadCatzPad3 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 61462 + idVendor + 7085 + + MadCatzPortableDrum + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 39025 + idVendor + 1848 + + MadCatzProGamepad + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 18214 + idVendor + 1848 + + MayflashMAGICNS + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 6355 + idVendor + 121 + + McbazelPlaystationToXbox360 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 654 + idVendor + 3695 + + MicrosoftBigButtonController + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 672 + idVendor + 1118 + + MicrosoftCorp.XboxControllerS - 2 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 649 + idVendor + 1118 + + MicrosoftCorp.XboxControllerSHub + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 648 + idVendor + 1118 + + MicrosoftX-Boxpad(Japan) + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 645 + idVendor + 1118 + + MicrosoftX-Boxpadv1(US) + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 514 + idVendor + 1118 + + MicrosoftXboxControllerS + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 647 + idVendor + 1118 + + MicrosoftXboxControllerS - 2 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 648 + idVendor + 1118 + + MicrosoftXboxOneController2013 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 721 + idVendor + 1118 + + MicrosoftXboxOneController2015 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 733 + idVendor + 1118 + + MicrosoftXboxOneController2016 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 746 + idVendor + 1118 + + MicrosoftXboxOneController2018 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 765 + idVendor + 1118 + + MicrosoftXboxOneControllerAdaptive + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 2826 + idVendor + 1118 + + MicrosoftXboxOneControllerElite + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 739 + idVendor + 1118 + + NaconGC100XF + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 22000 + idVendor + 4553 + + PDPAfterglow + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 63744 + idVendor + 7085 + + PDPAfterglowAX.1 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 63744 + idVendor + 3695 + + PDPAfterglowAX1 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 275 + idVendor + 3695 + + PDPAfterglowV2 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 531 + idVendor + 3695 + + PDPAfterglowV3 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 769 + idVendor + 4779 + + PDPAfterglowV4 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 4371 + idVendor + 3695 + + PDPBattlefieldOne + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 356 + idVendor + 3695 + + PDPEASports + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 305 + idVendor + 3695 + + PDPMarvelXboxOneController + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 327 + idVendor + 3695 + + PDPMetallicsLEXbox360 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 345 + idVendor + 3695 + + PDPStealthPhantomBlack + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 676 + idVendor + 3695 + + PDPStealthVioletSpectral + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 715 + idVendor + 3695 + + PDPTitanfall2 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 357 + idVendor + 3695 + + PDPTron + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 63747 + idVendor + 7085 + + PDPVersusPad + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 63748 + idVendor + 7085 + + PDPXbox360 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 1281 + idVendor + 3695 + + PDPXboxOne1 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 314 + idVendor + 3695 + + PDPXboxOne2 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 354 + idVendor + 3695 + + PDPXboxOne3 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 22042 + idVendor + 9414 + + PDPXboxOne4 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 353 + idVendor + 3695 + + PDPXboxOne5 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 355 + idVendor + 3695 + + PDPXboxOne6 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 683 + idVendor + 3695 + + PDPXboxOne7 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 352 + idVendor + 3695 + + PDPXboxOneArcticWhite + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 680 + idVendor + 3695 + + PDPXboxOneArcadeStick + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 348 + idVendor + 3695 + + PDPXboxOneCrimsonRed + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 674 + idVendor + 3695 + + PDPXboxOneFallout4 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 347 + idVendor + 3695 + + PDPXboxOneGhostWhite + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 677 + idVendor + 3695 + + PDPXboxOnePhantomBlack + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 685 + idVendor + 3695 + + PDPXboxOnePhantomBlack - 2 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 704 + idVendor + 3695 + + PDPXboxOneRavenBlack + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 679 + idVendor + 3695 + + PDPXboxOneRevenantBlue + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 678 + idVendor + 3695 + + PowerAAirflow + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 16138 + idVendor + 5604 + + PowerAFUS1ONTournament + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 21399 + idVendor + 9414 + + PowerAMiniProEXGreen + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 16128 + idVendor + 5604 + + PowerAMiniProEXGreen2 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 21274 + idVendor + 9414 + + PowerAMiniProEXWhite + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 21248 + idVendor + 9414 + + PowerAMiniXboxOne + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 21530 + idVendor + 9414 + + PowerAMiniXboxOne2 + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 21562 + idVendor + 9414 + + PowerASpectraIlluminatedXboxOne + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 21546 + idVendor + 9414 + + QanBaJoystickPlus + + CFBundleIdentifier + com.mice.driver.Xbox360Controller + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + 360Controller.kext/Contents/PlugIns/Feedback360.plugin + + IOClass + Xbox360Peripheral + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice + idProduct + 48879 idVendor 1848 - MadCatzMicroGamepad + RAPEXSE CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -947,11 +3471,11 @@ IOProviderClass IOUSBDevice idProduct - 18230 + 22 idVendor - 1848 + 3853 - MadCatzPad3 + REALARCADEPROEX CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -967,11 +3491,11 @@ IOProviderClass IOUSBDevice idProduct - 61462 + 62724 idVendor 7085 - MadCatzPortableDrum + RazerAtrox CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -987,11 +3511,11 @@ IOProviderClass IOUSBDevice idProduct - 39025 + 2560 idVendor - 1848 + 5426 - MadCatzProGamepad + RazerAtrox2 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1007,11 +3531,11 @@ IOProviderClass IOUSBDevice idProduct - 18214 + 20480 idVendor - 1848 + 9414 - MicrosoftCorp.XboxControllerS + RazerOnza CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1027,11 +3551,11 @@ IOProviderClass IOUSBDevice idProduct - 649 + 64769 idVendor - 1118 + 7085 - MicrosoftCorp.XboxControllerSHub + RazerOnza2 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1047,11 +3571,11 @@ IOProviderClass IOUSBDevice idProduct - 648 + 64769 idVendor - 1118 + 5769 - MicrosoftX-Boxpad(Japan) + RazerOnzaTE CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1067,11 +3591,11 @@ IOProviderClass IOUSBDevice idProduct - 645 + 64768 idVendor - 1118 + 7085 - MicrosoftX-Boxpadv1(US) + RazerOnzaTE2 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1087,11 +3611,11 @@ IOProviderClass IOUSBDevice idProduct - 514 + 64768 idVendor - 1118 + 5769 - MicrosoftXboxControllerS + RazerSabertoothElite CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1107,11 +3631,11 @@ IOProviderClass IOUSBDevice idProduct - 647 + 65024 idVendor - 1118 + 5769 - MicrosoftXboxOneController2013 + RazerSabertoothElite2 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1127,11 +3651,11 @@ IOProviderClass IOUSBDevice idProduct - 721 + 23812 idVendor - 1118 + 9414 - MicrosoftXboxOneController2015 + RazerWildcat CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1147,11 +3671,11 @@ IOProviderClass IOUSBDevice idProduct - 733 + 2563 idVendor - 1118 + 5426 - PDPAfterglow + RazerWolverineUltimate CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1167,11 +3691,11 @@ IOProviderClass IOUSBDevice idProduct - 63744 + 2580 idVendor - 7085 + 5426 - PDPAfterglowAX1 + RedOctaneController CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1187,11 +3711,11 @@ IOProviderClass IOUSBDevice idProduct - 275 + 63489 idVendor - 3695 + 5168 - PDPAfterglowV2 + RedOctaneControllerAdapter CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1207,11 +3731,11 @@ IOProviderClass IOUSBDevice idProduct - 531 + 672 idVendor - 3695 + 5168 - PDPMarvelXboxOneController + RockBandDrums CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1227,11 +3751,11 @@ IOProviderClass IOUSBDevice idProduct - 327 + 3 idVendor - 3695 + 7085 - PDPTron + RockBandGuitar CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1247,11 +3771,11 @@ IOProviderClass IOUSBDevice idProduct - 63747 + 2 idVendor 7085 - PDPVersusPad + RockCandy CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1267,11 +3791,11 @@ IOProviderClass IOUSBDevice idProduct - 63748 + 287 idVendor - 7085 + 3695 - PowerAAirflow + RockCandyGamepadForXbox360 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1287,11 +3811,11 @@ IOProviderClass IOUSBDevice idProduct - 16138 + 543 idVendor - 5604 + 3695 - PowerAMiniProEXGreen + RockCandyGamepadForXbox360 - 2 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1307,11 +3831,11 @@ IOProviderClass IOUSBDevice idProduct - 16128 + 64254 idVendor - 5604 + 9414 - PowerAMiniProEXGreen2 + RockCandyGamepadForXbox360 - 3 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1327,11 +3851,11 @@ IOProviderClass IOUSBDevice idProduct - 21274 + 338 idVendor - 9414 + 3695 - PowerAMiniProEXWhite + RockCandyGamepadForXboxOne2013 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1347,11 +3871,11 @@ IOProviderClass IOUSBDevice idProduct - 21248 + 326 idVendor - 9414 + 3695 - PowerAMiniXboxOne + RockCandyGamepadForXboxOne2015 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1367,11 +3891,11 @@ IOProviderClass IOUSBDevice idProduct - 21530 + 582 idVendor - 9414 + 3695 - PowerASpectraIlluminatedXboxOne + RockCandyGamepadForXboxOne2016 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1387,11 +3911,11 @@ IOProviderClass IOUSBDevice idProduct - 21546 + 838 idVendor - 9414 + 3695 - QanBaJoystickPlus + RockCandyGamepadForXboxOne2019 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1407,11 +3931,11 @@ IOProviderClass IOUSBDevice idProduct - 48879 + 719 idVendor - 1848 + 3695 - RAPEXSE + RockCandyGamepadforPS3 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1427,11 +3951,11 @@ IOProviderClass IOUSBDevice idProduct - 22 + 286 idVendor - 3853 + 3695 - REALARCADEPROEX + SC4VF5Stick CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1447,11 +3971,11 @@ IOProviderClass IOUSBDevice idProduct - 62724 + 13 idVendor - 7085 + 3853 - RazerOnza + SF4FightPad CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1467,11 +3991,11 @@ IOProviderClass IOUSBDevice idProduct - 64769 + 61480 idVendor 7085 - RazerOnza2 + SF4FightPad2 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1487,11 +4011,11 @@ IOProviderClass IOUSBDevice idProduct - 64769 + 18216 idVendor - 5769 + 1848 - RazerOnzaTE + SF4StickSE CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1507,11 +4031,11 @@ IOProviderClass IOUSBDevice idProduct - 64768 + 18200 idVendor - 7085 + 1848 - RazerOnzaTE2 + SF4StickTE CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1527,11 +4051,11 @@ IOProviderClass IOUSBDevice idProduct - 64768 + 18232 idVendor - 5769 + 1848 - RazerSabertoothElite + SF4StickTER2 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1547,11 +4071,11 @@ IOProviderClass IOUSBDevice idProduct - 65024 + 61496 idVendor - 5769 + 7085 - RazerSabertoothElite2 + SSF4StickTE CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1567,11 +4091,11 @@ IOProviderClass IOUSBDevice idProduct - 23812 + 63288 idVendor - 9414 + 1848 - RedOctaneController + SSFIVTEChunLi CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1587,11 +4111,11 @@ IOProviderClass IOUSBDevice idProduct - 63489 + 61501 idVendor - 5168 + 7085 - RockBandDrums + SaitekAV8R02 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1607,11 +4131,11 @@ IOProviderClass IOUSBDevice idProduct - 3 + 52009 idVendor - 7085 + 1848 - RockBandGuitar + SaitekCB360 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1627,11 +4151,11 @@ IOProviderClass IOUSBDevice idProduct - 2 + 51970 idVendor - 7085 + 1848 - RockCandy + StrikeController CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1647,11 +4171,11 @@ IOProviderClass IOUSBDevice idProduct - 287 + 1 idVendor - 3695 + 5769 - RockCandyGamepadForXbox360 + TSZPelican CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1667,11 +4191,11 @@ IOProviderClass IOUSBDevice idProduct - 543 + 513 idVendor 3695 - RockCandyGamepadforXboxOne + ThrustmasterFerrari430 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1687,11 +4211,11 @@ IOProviderClass IOUSBDevice idProduct - 326 + 46683 idVendor - 3695 + 1103 - SC4VF5Stick + ThrustMasterFerrari458 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1707,11 +4231,11 @@ IOProviderClass IOUSBDevice idProduct - 13 + 23296 idVendor - 3853 + 9414 - SF4FightPad + ThrustMasterFerrari458Italia CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1727,11 +4251,11 @@ IOProviderClass IOUSBDevice idProduct - 61480 + 23299 idVendor - 7085 + 9414 - SF4FightPad2 + ThrustMasterFerrari458Spider CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1747,11 +4271,11 @@ IOProviderClass IOUSBDevice idProduct - 18216 + 46705 idVendor - 1848 + 1103 - SF4StickSE + ThrustMasterGPXGamepad CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1767,11 +4291,11 @@ IOProviderClass IOUSBDevice idProduct - 18200 + 45862 idVendor - 1848 + 1103 - SF4StickTE + ThrustmasterGPXLightback CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1787,11 +4311,11 @@ IOProviderClass IOUSBDevice idProduct - 18232 + 23298 idVendor - 1848 + 9414 - SF4StickTER2 + ThrustmasterTXGIP CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1807,11 +4331,11 @@ IOProviderClass IOUSBDevice idProduct - 61496 + 46692 idVendor - 7085 + 1103 - SSF4StickTE + ThrustmasterTMX CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1827,11 +4351,11 @@ IOProviderClass IOUSBDevice idProduct - 63288 + 46718 idVendor - 1848 + 1103 - SSFIVTEChunLi + TrustPredator CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1847,11 +4371,11 @@ IOProviderClass IOUSBDevice idProduct - 61501 + 3 idVendor - 7085 + 2064 - SaitekCB360 + XB360MortalKombatFightStick CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1867,11 +4391,11 @@ IOProviderClass IOUSBDevice idProduct - 51970 + 63750 idVendor - 1848 + 7085 - StrikeController + Xbox360ProEXController CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1887,11 +4411,11 @@ IOProviderClass IOUSBDevice idProduct - 1 + 21258 idVendor - 5769 + 9414 - TSZPelican + Xbox360ProEXController2 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1907,11 +4431,11 @@ IOProviderClass IOUSBDevice idProduct - 513 + 10271 idVendor - 3695 + 8406 - ThrustMasterGPXGamepad + XboxOneProEXController CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1927,11 +4451,11 @@ IOProviderClass IOUSBDevice idProduct - 45862 + 21562 idVendor - 1103 + 9414 - ThrustmasterGPXLightback + MadCatzBeatPad CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1947,11 +4471,11 @@ IOProviderClass IOUSBDevice idProduct - 23298 + 18240 idVendor - 9414 + 1848 - XB360MortalKombatFightStick + RedOctane guitar hero guitar CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1967,11 +4491,11 @@ IOProviderClass IOUSBDevice idProduct - 63750 + 1803 idVendor - 7085 + 5168 - Xbox360ProEXController + MADCATZ 360 MC2 CFBundleIdentifier com.mice.driver.Xbox360Controller @@ -1987,9 +4511,9 @@ IOProviderClass IOUSBDevice idProduct - 21258 + 18208 idVendor - 9414 + 1848 NSHumanReadableCopyright diff --git a/360Controller/_60Controller.cpp b/360Controller/_60Controller.cpp index 3aa6b4bc..91c7a2b3 100644 --- a/360Controller/_60Controller.cpp +++ b/360Controller/_60Controller.cpp @@ -1,31 +1,30 @@ /* - MICE Xbox 360 Controller driver for Mac OS X - Copyright (C) 2006-2013 Colin Munro - Bug fixes contributed by Cody "codeman38" Boisclair - - _60Controller.cpp - main source of the driver - - This file is part of Xbox360Controller. - - Xbox360Controller is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Xbox360Controller is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Foobar; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + MICE Xbox 360 Controller driver for Mac OS X + Copyright (C) 2006-2013 Colin Munro + Bug fixes contributed by Cody "codeman38" Boisclair + + _60Controller.cpp - main source of the driver + + This file is part of Xbox360Controller. + + Xbox360Controller is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Xbox360Controller is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Foobar; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ #include #include #include #include "_60Controller.h" -#include "ControlStruct.h" #include "ChatPad.h" #include "Controller.h" @@ -56,48 +55,48 @@ class LockRequired static UInt32 GetMaxPacketSize(IOUSBPipe *pipe) { const IOUSBEndpointDescriptor *ed = pipe->GetEndpointDescriptor(); - + if(ed==NULL) return 0; else return ed->wMaxPacketSize; } void Xbox360Peripheral::SendSpecial(UInt16 value) { - IOUSBDevRequest controlReq; - - controlReq.bmRequestType = USBmakebmRequestType(kUSBOut, kUSBVendor, kUSBInterface); - controlReq.bRequest = 0x00; - controlReq.wValue = value; - controlReq.wIndex = 0x0002; - controlReq.wLength = 0; - controlReq.pData = NULL; - if (device->DeviceRequest(&controlReq, 100, 100, NULL) != kIOReturnSuccess) - IOLog("Failed to send special message %.4x\n", value); + IOUSBDevRequest controlReq; + + controlReq.bmRequestType = USBmakebmRequestType(kUSBOut, kUSBVendor, kUSBInterface); + controlReq.bRequest = 0x00; + controlReq.wValue = value; + controlReq.wIndex = 0x0002; + controlReq.wLength = 0; + controlReq.pData = NULL; + if (device->DeviceRequest(&controlReq, 100, 100, NULL) != kIOReturnSuccess) + IOLog("Failed to send special message %.4x\n", value); } void Xbox360Peripheral::SendInit(UInt16 value, UInt16 index) { - IOUSBDevRequest controlReq; - - controlReq.bmRequestType = USBmakebmRequestType(kUSBOut, kUSBVendor, kUSBDevice); - controlReq.bRequest = 0xa9; - controlReq.wValue = value; - controlReq.wIndex = index; - controlReq.wLength = 0; - controlReq.pData = NULL; - device->DeviceRequest(&controlReq, 100, 100, NULL); // Will fail - but device should still act on it + IOUSBDevRequest controlReq; + + controlReq.bmRequestType = USBmakebmRequestType(kUSBOut, kUSBVendor, kUSBDevice); + controlReq.bRequest = 0xa9; + controlReq.wValue = value; + controlReq.wIndex = index; + controlReq.wLength = 0; + controlReq.pData = NULL; + device->DeviceRequest(&controlReq, 100, 100, NULL); // Will fail - but device should still act on it } bool Xbox360Peripheral::SendSwitch(bool sendOut) { - IOUSBDevRequest controlReq; - - controlReq.bmRequestType = USBmakebmRequestType(sendOut ? kUSBOut : kUSBIn, kUSBVendor, kUSBDevice); - controlReq.bRequest = 0xa1; - controlReq.wValue = 0x0000; - controlReq.wIndex = 0xe416; - controlReq.wLength = sizeof(chatpadInit); - controlReq.pData = chatpadInit; + IOUSBDevRequest controlReq; + + controlReq.bmRequestType = USBmakebmRequestType(sendOut ? kUSBOut : kUSBIn, kUSBVendor, kUSBDevice); + controlReq.bRequest = 0xa1; + controlReq.wValue = 0x0000; + controlReq.wIndex = 0xe416; + controlReq.wLength = sizeof(chatpadInit); + controlReq.pData = chatpadInit; IOReturn err = device->DeviceRequest(&controlReq, 100, 100, NULL); if (err == kIOReturnSuccess) return true; @@ -110,117 +109,117 @@ bool Xbox360Peripheral::SendSwitch(bool sendOut) void Xbox360Peripheral::SendToggle(void) { - SendSpecial(serialToggle ? 0x1F : 0x1E); - serialToggle = !serialToggle; + SendSpecial(serialToggle ? 0x1F : 0x1E); + serialToggle = !serialToggle; } void Xbox360Peripheral::ChatPadTimerActionWrapper(OSObject *owner, IOTimerEventSource *sender) { - Xbox360Peripheral *controller; + Xbox360Peripheral *controller; - controller = OSDynamicCast(Xbox360Peripheral, owner); - controller->ChatPadTimerAction(sender); + controller = OSDynamicCast(Xbox360Peripheral, owner); + controller->ChatPadTimerAction(sender); } void Xbox360Peripheral::ChatPadTimerAction(IOTimerEventSource *sender) { - int nextTime, serialGot; - - serialGot = 0; - nextTime = 1000; - switch (serialTimerState) - { - case tsToggle: - SendToggle(); - if (serialActive) - { - if (!serialHeard) - { - serialActive = false; - serialGot = 2; - } - } - else - { - if (serialHeard) - { - serialTimerState = tsReset1; - serialResetCount = 0; - nextTime = 40; - } - } - break; - - case tsMiniToggle: - SendToggle(); - if (serialHeard) - { - serialTimerState = tsSet1; - nextTime = 40; - } - else - { - serialResetCount++; - if (serialResetCount > 3) - { - serialTimerState = tsToggle; - } - else - { - serialTimerState = tsReset1; - nextTime = 40; - } - } - break; - - case tsReset1: - SendSpecial(0x1B); - serialTimerState = tsReset2; - nextTime = 35; - break; - - case tsReset2: - SendSpecial(0x1B); - serialTimerState = tsMiniToggle; - nextTime = 150; - break; - - case tsSet1: - SendSpecial(0x18); - serialTimerState = tsSet2; - nextTime = 10; - break; - - case tsSet2: - SendSpecial(0x10); - serialTimerState = tsSet3; - nextTime = 10; - break; - - case tsSet3: - SendSpecial(0x03); - serialTimerState = tsToggle; - nextTime = 940; - serialActive = true; - serialGot = 1; - break; - } - sender->setTimeoutMS(nextTime); // Todo: Make it take into account function execution time? - serialHeard = false; - // Make it happen after the timer's set, for minimum impact - switch (serialGot) - { - case 1: - SerialConnect(); - break; - - case 2: - SerialDisconnect(); - break; - - default: - break; - } + int nextTime, serialGot; + + serialGot = 0; + nextTime = 1000; + switch (serialTimerState) + { + case tsToggle: + SendToggle(); + if (serialActive) + { + if (!serialHeard) + { + serialActive = false; + serialGot = 2; + } + } + else + { + if (serialHeard) + { + serialTimerState = tsReset1; + serialResetCount = 0; + nextTime = 40; + } + } + break; + + case tsMiniToggle: + SendToggle(); + if (serialHeard) + { + serialTimerState = tsSet1; + nextTime = 40; + } + else + { + serialResetCount++; + if (serialResetCount > 3) + { + serialTimerState = tsToggle; + } + else + { + serialTimerState = tsReset1; + nextTime = 40; + } + } + break; + + case tsReset1: + SendSpecial(0x1B); + serialTimerState = tsReset2; + nextTime = 35; + break; + + case tsReset2: + SendSpecial(0x1B); + serialTimerState = tsMiniToggle; + nextTime = 150; + break; + + case tsSet1: + SendSpecial(0x18); + serialTimerState = tsSet2; + nextTime = 10; + break; + + case tsSet2: + SendSpecial(0x10); + serialTimerState = tsSet3; + nextTime = 10; + break; + + case tsSet3: + SendSpecial(0x03); + serialTimerState = tsToggle; + nextTime = 940; + serialActive = true; + serialGot = 1; + break; + } + sender->setTimeoutMS(nextTime); // Todo: Make it take into account function execution time? + serialHeard = false; + // Make it happen after the timer's set, for minimum impact + switch (serialGot) + { + case 1: + SerialConnect(); + break; + + case 2: + SerialDisconnect(); + break; + + default: + break; + } } // Read the settings from the registry @@ -229,7 +228,7 @@ void Xbox360Peripheral::readSettings(void) OSBoolean *value = NULL; OSNumber *number = NULL; OSDictionary *dataDictionary = OSDynamicCast(OSDictionary, getProperty(kDriverSettingKey)); - + if (dataDictionary == NULL) return; value = OSDynamicCast(OSBoolean, dataDictionary->getObject("InvertLeftX")); if (value != NULL) invertLeftX = value->getValue(); @@ -251,8 +250,7 @@ void Xbox360Peripheral::readSettings(void) if (value != NULL) deadOffLeft = value->getValue(); value = OSDynamicCast(OSBoolean, dataDictionary->getObject("DeadOffRight")); if (value != NULL) deadOffRight = value->getValue(); -// number = OSDynamicCast(OSNumber, dataDictionary->getObject("ControllerType")); // No use currently. - number = OSDynamicCast(OSNumber, dataDictionary->getObject("rumbleType")); + number = OSDynamicCast(OSNumber, dataDictionary->getObject("RumbleType")); if (number != NULL) rumbleType = number->unsigned8BitValue(); number = OSDynamicCast(OSNumber, dataDictionary->getObject("BindingUp")); if (number != NULL) mapping[0] = number->unsigned32BitValue(); @@ -286,12 +284,14 @@ void Xbox360Peripheral::readSettings(void) if (number != NULL) mapping[14] = number->unsigned32BitValue(); value = OSDynamicCast(OSBoolean, dataDictionary->getObject("SwapSticks")); if (value != NULL) swapSticks = value->getValue(); + value = OSDynamicCast(OSBoolean, dataDictionary->getObject("Pretend360")); + if (value != NULL) pretend360 = value->getValue(); #if 0 IOLog("Xbox360Peripheral preferences loaded:\n invertLeft X: %s, Y: %s\n invertRight X: %s, Y:%s\n deadzone Left: %d, Right: %d\n\n", - invertLeftX?"True":"False",invertLeftY?"True":"False", - invertRightX?"True":"False",invertRightY?"True":"False", - deadzoneLeft,deadzoneRight); + invertLeftX?"True":"False",invertLeftY?"True":"False", + invertRightX?"True":"False",invertRightY?"True":"False", + deadzoneLeft,deadzoneRight); #endif } @@ -305,12 +305,12 @@ bool Xbox360Peripheral::init(OSDictionary *propTable) inPipe=NULL; outPipe=NULL; inBuffer=NULL; - padHandler = NULL; - serialIn = NULL; - serialInPipe = NULL; - serialInBuffer = NULL; - serialTimer = NULL; - serialHandler = NULL; + padHandler = NULL; + serialIn = NULL; + serialInPipe = NULL; + serialInBuffer = NULL; + serialTimer = NULL; + serialHandler = NULL; // Default settings invertLeftX=invertLeftY=false; invertRightX=invertRightY=false; @@ -319,9 +319,11 @@ bool Xbox360Peripheral::init(OSDictionary *propTable) deadOffLeft = false; deadOffRight = false; swapSticks = false; + pretend360 = false; // Controller Specific rumbleType = 0; // Bindings + noMapping = true; for (int i = 0; i < 11; i++) { mapping[i] = i; @@ -348,27 +350,9 @@ bool Xbox360Peripheral::start(IOService *provider) IOUSBFindEndpointRequest pipe; XBOX360_OUT_LED led; IOWorkLoop *workloop = NULL; - /* - * Xbox One controller init packets. - * The Rock Candy Xbox One controller requires more than just 0x05 - * Minimum required packets unknown. - */ - - UInt8 xoneInitFirst[] = { 0x04, 0x20, 0x01, 0x00 }; - UInt8 xoneInitSecond[] = { 0x01, 0x20, 0x01, 0x09, 0x00, 0x04, 0x20, 0x3a, 0x00, 0x00, 0x00, 0x9c, 0x00 }; - UInt8 xoneInitThird[] = { 0x01, 0x20, 0x02, 0x09, 0x00, 0x04, 0x20, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00 }; - UInt8 xoneInitFourth[] = { 0x05, 0x20, 0x02, 0x09, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x53 }; - UInt8 xoneInitFifth[] = { 0x05, 0x20, 0x03, 0x01, 0x00 }; - UInt8 xoneInitSixth[] = { 0x0a, 0x20, 0x04, 0x03, 0x00, 0x01, 0x14 }; - UInt8 xoneInitSeventh[] = { 0x06, 0x20, 0x01, 0x02, 0x01, 0x00 }; - -// UInt8 xoneInitFirst[] = { 0x02, 0x20, 0x01, 0x1C, 0x7E, 0xED, 0x8B, 0x11, 0x0F, 0xA8, 0x00, 0x00, 0x5E, 0x04, 0xD1, 0x02, 0x01, 0x00, 0x01, 0x00, 0x17, 0x01, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00 }; -// UInt8 xoneInitSecond[] = { 0x05, 0x20, 0x00, 0x09, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x53 }; -// UInt8 xoneInitThird[] = { 0x05, 0x20, 0x01, 0x01, 0x00 }; -// UInt8 xoneInitFourth[] = { 0x0A, 0x20, 0x02, 0x03, 0x00, 0x01, 0x14 }; - + if (!super::start(provider)) - return false; + return false; // Get device device=OSDynamicCast(IOUSBDevice,provider); if(device==NULL) { @@ -468,95 +452,98 @@ bool Xbox360Peripheral::start(IOService *provider) } outPipe->retain(); // Get a buffer - inBuffer=IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task,0,GetMaxPacketSize(inPipe)); + inBuffer=IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task,kIODirectionIn,GetMaxPacketSize(inPipe)); if(inBuffer==NULL) { IOLog("start - failed to allocate input buffer\n"); goto fail; } - // Find chatpad interface - intf.bInterfaceClass = kIOUSBFindInterfaceDontCare; - intf.bInterfaceSubClass = 93; - intf.bInterfaceProtocol = 2; - intf.bAlternateSetting = kIOUSBFindInterfaceDontCare; - serialIn = device->FindNextInterface(NULL, &intf); - if (serialIn == NULL) { - IOLog("start - unable to find chatpad interface\n"); + // Find chatpad interface + intf.bInterfaceClass = kIOUSBFindInterfaceDontCare; + intf.bInterfaceSubClass = 93; + intf.bInterfaceProtocol = 2; + intf.bAlternateSetting = kIOUSBFindInterfaceDontCare; + serialIn = device->FindNextInterface(NULL, &intf); + if (serialIn == NULL) { + IOLog("start - unable to find chatpad interface\n"); goto nochat; } - serialIn->open(this); - // Find chatpad pipe - pipe.direction = kUSBIn; - pipe.interval = 0; - pipe.type = kUSBInterrupt; - pipe.maxPacketSize = 0; - serialInPipe = serialIn->FindNextPipe(NULL, &pipe); - if (serialInPipe == NULL) - { - IOLog("start - unable to find chatpad in pipe\n"); - goto fail; - } - serialInPipe->retain(); - // Get a buffer for the chatpad - serialInBuffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, GetMaxPacketSize(serialInPipe)); - if (serialInBuffer == NULL) - { - IOLog("start - failed to allocate input buffer for chatpad\n"); - goto fail; - } - // Create timer for chatpad - serialTimer = IOTimerEventSource::timerEventSource(this, ChatPadTimerActionWrapper); - if (serialTimer == NULL) - { - IOLog("start - failed to create timer for chatpad\n"); - goto fail; - } + serialIn->open(this); + // Find chatpad pipe + pipe.direction = kUSBIn; + pipe.interval = 0; + pipe.type = kUSBInterrupt; + pipe.maxPacketSize = 0; + serialInPipe = serialIn->FindNextPipe(NULL, &pipe); + if (serialInPipe == NULL) + { + IOLog("start - unable to find chatpad in pipe\n"); + goto fail; + } + serialInPipe->retain(); + // Get a buffer for the chatpad + serialInBuffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, kIODirectionIn, GetMaxPacketSize(serialInPipe)); + if (serialInBuffer == NULL) + { + IOLog("start - failed to allocate input buffer for chatpad\n"); + goto fail; + } + // Create timer for chatpad + serialTimer = IOTimerEventSource::timerEventSource(this, ChatPadTimerActionWrapper); + if (serialTimer == NULL) + { + IOLog("start - failed to create timer for chatpad\n"); + goto fail; + } workloop = getWorkLoop(); - if ((workloop == NULL) || (workloop->addEventSource(serialTimer) != kIOReturnSuccess)) - { - IOLog("start - failed to connect timer for chatpad\n"); - goto fail; - } - // Configure ChatPad - // Send 'configuration' - SendInit(0xa30c, 0x4423); - SendInit(0x2344, 0x7f03); - SendInit(0x5839, 0x6832); - // Set 'switch' + if ((workloop == NULL) || (workloop->addEventSource(serialTimer) != kIOReturnSuccess)) + { + IOLog("start - failed to connect timer for chatpad\n"); + goto fail; + } + // Configure ChatPad + // Send 'configuration' + SendInit(0xa30c, 0x4423); + SendInit(0x2344, 0x7f03); + SendInit(0x5839, 0x6832); + // Set 'switch' if ((!SendSwitch(false)) || (!SendSwitch(true)) || (!SendSwitch(false))) { // Commenting goto fail fixes the driver for the Hori Real Arcade Pro EX //goto fail; - } - // Begin toggle - serialHeard = false; - serialActive = false; - serialToggle = false; - serialResetCount = 0; - serialTimerState = tsToggle; - serialTimer->setTimeoutMS(1000); + } + // Begin toggle + serialHeard = false; + serialActive = false; + serialToggle = false; + serialResetCount = 0; + serialTimerState = tsToggle; + serialTimer->setTimeoutMS(1000); // Begin reading if (!QueueSerialRead()) goto fail; nochat: if (!QueueRead()) - goto fail; - if (controllerType == XboxOne) { - QueueWrite(&xoneInitFirst, sizeof(xoneInitFirst)); - QueueWrite(&xoneInitSecond, sizeof(xoneInitSecond)); - QueueWrite(&xoneInitThird, sizeof(xoneInitThird)); - QueueWrite(&xoneInitFourth, sizeof(xoneInitFourth)); - QueueWrite(&xoneInitFifth, sizeof(xoneInitFifth)); - QueueWrite(&xoneInitSixth, sizeof(xoneInitSixth)); - QueueWrite(&xoneInitSeventh, sizeof(xoneInitSeventh)); + goto fail; + if (controllerType == XboxOne || controllerType == XboxOnePretend360) { + UInt8 xoneInit0[] = { 0x01, 0x20, 0x00, 0x09, 0x00, 0x04, 0x20, 0x3a, 0x00, 0x00, 0x00, 0x80, 0x00 }; + UInt8 xoneInit1[] = { 0x05, 0x20, 0x00, 0x01, 0x00 }; + UInt8 xoneInit2[] = { 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, + 0x1D, 0x1D, 0xFF, 0x00, 0x00 }; + UInt8 xoneInit3[] = { 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 }; + QueueWrite(&xoneInit0, sizeof(xoneInit0)); + QueueWrite(&xoneInit1, sizeof(xoneInit1)); + QueueWrite(&xoneInit2, sizeof(xoneInit2)); + QueueWrite(&xoneInit3, sizeof(xoneInit3)); } else { // Disable LED Xbox360_Prepare(led,outLed); led.pattern=ledOff; QueueWrite(&led,sizeof(led)); } - + // Done - PadConnect(); - registerService(); + PadConnect(); + registerService(); return true; fail: ReleaseAll(); @@ -586,7 +573,7 @@ bool Xbox360Peripheral::QueueSerialRead(void) { IOUSBCompletion complete; IOReturn err; - + if ((serialInPipe == NULL) || (serialInBuffer == NULL)) return false; complete.target = this; @@ -594,11 +581,11 @@ bool Xbox360Peripheral::QueueSerialRead(void) complete.parameter = serialInBuffer; err = serialInPipe->Read(serialInBuffer, 0, 0, serialInBuffer->getLength(), &complete); if (err == kIOReturnSuccess) - { - return true; - } + { + return true; + } else - { + { IOLog("read - failed to start for chatpad (0x%.8x)\n",err); return false; } @@ -610,8 +597,8 @@ bool Xbox360Peripheral::QueueWrite(const void *bytes,UInt32 length) IOBufferMemoryDescriptor *outBuffer; IOUSBCompletion complete; IOReturn err; - - outBuffer=IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task,0,length); + + outBuffer=IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task,kIODirectionOut,length); if(outBuffer==NULL) { IOLog("send - unable to allocate buffer\n"); return false; @@ -628,9 +615,17 @@ bool Xbox360Peripheral::QueueWrite(const void *bytes,UInt32 length) } } +bool Xbox360Peripheral::willTerminate(IOService *provider, IOOptionBits options) +{ + ReleaseAll(); + + return super::willTerminate(provider, options); +} + void Xbox360Peripheral::stop(IOService *provider) { ReleaseAll(); + super::stop(provider); } @@ -638,32 +633,32 @@ void Xbox360Peripheral::stop(IOService *provider) void Xbox360Peripheral::ReleaseAll(void) { LockRequired locker(mainLock); - - SerialDisconnect(); - PadDisconnect(); - if (serialTimer != NULL) - { - serialTimer->cancelTimeout(); - getWorkLoop()->removeEventSource(serialTimer); - serialTimer->release(); - serialTimer = NULL; - } - if (serialInPipe != NULL) - { - serialInPipe->Abort(); - serialInPipe->release(); - serialInPipe = NULL; - } - if (serialInBuffer != NULL) - { - serialInBuffer->release(); - serialInBuffer = NULL; - } - if (serialIn != NULL) - { - serialIn->close(this); - serialIn = NULL; - } + + SerialDisconnect(); + PadDisconnect(); + if (serialTimer != NULL) + { + serialTimer->cancelTimeout(); + getWorkLoop()->removeEventSource(serialTimer); + serialTimer->release(); + serialTimer = NULL; + } + if (serialInPipe != NULL) + { + serialInPipe->Abort(); + serialInPipe->release(); + serialInPipe = NULL; + } + if (serialInBuffer != NULL) + { + serialInBuffer->release(); + serialInBuffer = NULL; + } + if (serialIn != NULL) + { + serialIn->close(this); + serialIn = NULL; + } if(outPipe!=NULL) { outPipe->Abort(); outPipe->release(); @@ -709,10 +704,10 @@ IOReturn Xbox360Peripheral::message(UInt32 type,IOService *provider,void *argume } // This returns the abs() value of a short, swapping it if necessary -static inline XBox360_SShort getAbsolute(XBox360_SShort value) +static inline Xbox360_SShort getAbsolute(Xbox360_SShort value) { - XBox360_SShort reverse; - + Xbox360_SShort reverse; + #ifdef __LITTLE_ENDIAN__ reverse=value; #elif __BIG_ENDIAN__ @@ -723,142 +718,75 @@ static inline XBox360_SShort getAbsolute(XBox360_SShort value) return (reverse<0)?~reverse:reverse; } -// Adjusts the report for any settings speciified by the user -void Xbox360Peripheral::fiddleReport(IOBufferMemoryDescriptor *buffer) +void Xbox360Peripheral::normalizeAxis(SInt16& axis, short deadzone) { - XBOX360_IN_REPORT *report=(XBOX360_IN_REPORT*)buffer->getBytesNoCopy(); - if(invertLeftX) report->left.x=~report->left.x; - if(!invertLeftY) report->left.y=~report->left.y; - if(invertRightX) report->right.x=~report->right.x; - if(!invertRightY) report->right.y=~report->right.y; + static const UInt16 max16=32767; + const float current=getAbsolute(axis); + const float maxVal=max16-deadzone; + + if (current>deadzone) { + if (axis<0) { + axis=max16*(current-deadzone)/maxVal; + axis=~axis; + } else { + axis=max16*(current-deadzone)/maxVal; + } + } else { + axis=0; + } +} + +void Xbox360Peripheral::fiddleReport(XBOX360_HAT& left, XBOX360_HAT& right) +{ + // deadOff - Normalize checkbox is checked if true + // relative - Linked checkbox is checked if true + + if(invertLeftX) left.x=~left.x; + if(!invertLeftY) left.y=~left.y; + if(invertRightX) right.x=~right.x; + if(!invertRightY) right.y=~right.y; + if(deadzoneLeft!=0) { if(relativeLeft) { - if((getAbsolute(report->left.x)left.y)left.x=0; - report->left.y=0; + if((getAbsolute(left.x)left.x); - if (valX>deadzoneLeft) { - if (report->left.x<0) { - report->left.x=max16*(valX-deadzoneLeft)/maxVal; - report->left.x=~report->left.x; - } else { - report->left.x=max16*(valX-deadzoneLeft)/maxVal; - } - } else { - report->left.x=0; - } - float valY=getAbsolute(report->left.y); - if (valY>deadzoneLeft) { - if (report->left.y<0) { - report->left.y=max16*(valY-deadzoneLeft)/maxVal; - report->left.y=~report->left.y; - } else { - report->left.y=max16*(valY-deadzoneLeft)/maxVal; - } - } else { - report->left.y=0; - } + normalizeAxis(left.x, deadzoneLeft); + normalizeAxis(left.y, deadzoneLeft); } - } else { - if(getAbsolute(report->left.x)left.x=0; + } else { // Linked checkbox has no check + if(getAbsolute(left.x)left.x<0) { - float valX=getAbsolute(report->left.x); - report->left.x=max16*(valX-deadzoneLeft)/maxVal; - report->left.x=~report->left.x; - } else { - float valX=getAbsolute(report->left.x); - report->left.x=max16*(valX-deadzoneLeft)/maxVal; - } - } - if(getAbsolute(report->left.y)left.y=0; + normalizeAxis(left.x, deadzoneLeft); + + if(getAbsolute(left.y)left.y<0) { - float valY=getAbsolute(report->left.y); - report->left.y=max16*(valY-deadzoneLeft)/maxVal; - report->left.y=~report->left.y; - } else { - float valY=getAbsolute(report->left.y); - report->left.y=max16*(valY-deadzoneLeft)/maxVal; - } - } + normalizeAxis(left.y, deadzoneLeft); } } if(deadzoneRight!=0) { if(relativeRight) { - if((getAbsolute(report->right.x)right.y)right.x=0; - report->right.y=0; + if((getAbsolute(right.x)right.x); - if (valX>deadzoneRight) { - if (report->right.x<0) { - report->right.x=max16*(valX-deadzoneRight)/maxVal; - report->right.x=~report->right.x; - } else { - report->right.x=max16*(valX-deadzoneRight)/maxVal; - } - } else { - report->right.x = 0; - } - float valY=getAbsolute(report->right.y); - if (valY>deadzoneRight) { - if (report->right.y<0) { - report->right.y=max16*(valY-deadzoneRight)/maxVal; - report->right.y=~report->right.y; - } else { - report->right.y=max16*(valY-deadzoneRight)/maxVal; - } - } else { - report->right.y = 0; - } + normalizeAxis(left.x, deadzoneRight); + normalizeAxis(left.y, deadzoneRight); } } else { - if(getAbsolute(report->right.x)right.x=0; + if(getAbsolute(right.x)right.x<0) { - float valX=getAbsolute(report->right.x); - report->right.x=max16*(valX-deadzoneRight)/maxVal; - report->right.x=~report->right.x; - } else { - float valX=getAbsolute(report->right.x); - report->right.x=max16*(valX-deadzoneRight)/maxVal; - } - } - if(getAbsolute(report->right.y)right.y=0; + normalizeAxis(right.x, deadzoneRight); + if(getAbsolute(right.y)right.y<0) { - float valY=getAbsolute(report->right.y); - report->right.y=max16*(valY-deadzoneRight)/maxVal; - report->right.y=~report->right.y; - } else { - float valY=getAbsolute(report->right.y); - report->right.y=max16*(valY-deadzoneRight)/maxVal; - } - } + normalizeAxis(right.y, deadzoneRight); } } } @@ -872,8 +800,8 @@ void Xbox360Peripheral::ReadCompleteInternal(void *target,void *parameter,IORetu void Xbox360Peripheral::SerialReadCompleteInternal(void *target, void *parameter, IOReturn status, UInt32 bufferSizeRemaining) { - if (target != NULL) - ((Xbox360Peripheral*)target)->SerialReadComplete(parameter, status, bufferSizeRemaining); + if (target != NULL) + ((Xbox360Peripheral*)target)->SerialReadComplete(parameter, status, bufferSizeRemaining); } // This forwards a completed write notification to a member function @@ -891,7 +819,7 @@ void Xbox360Peripheral::ReadComplete(void *parameter,IOReturn status,UInt32 buff LockRequired locker(mainLock); IOReturn err; bool reread=!isInactive(); - + switch(status) { case kIOReturnOverrun: IOLog("read - kIOReturnOverrun, clearing stall\n"); @@ -925,36 +853,36 @@ void Xbox360Peripheral::ReadComplete(void *parameter,IOReturn status,UInt32 buff void Xbox360Peripheral::SerialReadComplete(void *parameter, IOReturn status, UInt32 bufferSizeRemaining) { - if (padHandler != NULL) // avoid deadlock with release - { - LockRequired locker(mainLock); - bool reread = !isInactive(); - - switch (status) - { - case kIOReturnOverrun: - IOLog("read (serial) - kIOReturnOverrun, clearing stall\n"); - if (serialInPipe != NULL) - serialInPipe->ClearStall(); - // Fall through - case kIOReturnSuccess: - serialHeard = true; - if (serialInBuffer != NULL) - SerialMessage(serialInBuffer, serialInBuffer->getCapacity() - bufferSizeRemaining); - break; - - case kIOReturnNotResponding: - IOLog("read (serial) - kIOReturnNotResponding\n"); - reread = false; - break; - - default: - reread = false; - break; - } - if (reread) - QueueSerialRead(); - } + if (padHandler != NULL) // avoid deadlock with release + { + LockRequired locker(mainLock); + bool reread = !isInactive(); + + switch (status) + { + case kIOReturnOverrun: + IOLog("read (serial) - kIOReturnOverrun, clearing stall\n"); + if (serialInPipe != NULL) + serialInPipe->ClearStall(); + // Fall through + case kIOReturnSuccess: + serialHeard = true; + if (serialInBuffer != NULL) + SerialMessage(serialInBuffer, serialInBuffer->getCapacity() - bufferSizeRemaining); + break; + + case kIOReturnNotResponding: + IOLog("read (serial) - kIOReturnNotResponding\n"); + reread = false; + break; + + default: + reread = false; + break; + } + if (reread) + QueueSerialRead(); + } } // Handle a completed asynchronous write @@ -968,88 +896,144 @@ void Xbox360Peripheral::WriteComplete(void *parameter,IOReturn status,UInt32 buf } +void Xbox360Peripheral::MakeSettingsChanges() +{ + if (controllerType == XboxOne) + { + if (pretend360) + { + controllerType = XboxOnePretend360; + PadConnect(); + } + } + else if (controllerType == XboxOnePretend360) + { + if (!pretend360) + { + controllerType = XboxOne; + PadConnect(); + } + } + + if (controllerType == Xbox360) + { + if (pretend360) + { + controllerType = Xbox360Pretend360; + PadConnect(); + } + } + else if (controllerType == Xbox360Pretend360) + { + if (!pretend360) + { + controllerType = Xbox360; + PadConnect(); + } + } + + noMapping = true; + UInt8 normalMapping[15] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15 }; + for (int i = 0; i < 15; i++) + { + if (normalMapping[i] != mapping[i]) + { + noMapping = false; + break; + } + } +} + + // Called by the userspace IORegistryEntrySetCFProperties function IOReturn Xbox360Peripheral::setProperties(OSObject *properties) { OSDictionary *dictionary; - + dictionary=OSDynamicCast(OSDictionary,properties); - + if(dictionary!=NULL) { dictionary->setObject(OSString::withCString("ControllerType"), OSNumber::withNumber(controllerType, 8)); setProperty(kDriverSettingKey,dictionary); readSettings(); + + MakeSettingsChanges(); + return kIOReturnSuccess; } else return kIOReturnBadArgument; } IOHIDDevice* Xbox360Peripheral::getController(int index) { - switch (index) - { - case 0: - return padHandler; - case 1: - return serialHandler; - default: - return NULL; - } + switch (index) + { + case 0: + return padHandler; + case 1: + return serialHandler; + default: + return NULL; + } } // Main controller support void Xbox360Peripheral::PadConnect(void) { - PadDisconnect(); + PadDisconnect(); if (controllerType == XboxOriginal) { padHandler = new XboxOriginalControllerClass; } else if (controllerType == XboxOne) { padHandler = new XboxOneControllerClass; + } else if (controllerType == XboxOnePretend360) { + padHandler = new XboxOnePretend360Class; + } else if (controllerType == Xbox360Pretend360) { + padHandler = new Xbox360Pretend360Class; } else { padHandler = new Xbox360ControllerClass; } - if (padHandler != NULL) - { + if (padHandler != NULL) + { const OSString *keys[] = { OSString::withCString(kIOSerialDeviceType), - OSString::withCString("IOCFPlugInTypes"), - OSString::withCString("IOKitDebug"), + OSString::withCString("IOCFPlugInTypes"), + OSString::withCString("IOKitDebug"), }; const OSObject *objects[] = { OSNumber::withNumber((unsigned long long)1, 32), - getProperty("IOCFPlugInTypes"), + getProperty("IOCFPlugInTypes"), OSNumber::withNumber((unsigned long long)65535, 32), }; OSDictionary *dictionary = OSDictionary::withObjects(objects, keys, sizeof(keys) / sizeof(keys[0])); - if (padHandler->init(dictionary)) - { - padHandler->attach(this); - padHandler->start(this); - } - else - { - padHandler->release(); - padHandler = NULL; - } - } + if (padHandler->init(dictionary)) + { + padHandler->attach(this); + padHandler->start(this); + } + else + { + padHandler->release(); + padHandler = NULL; + } + } } void Xbox360Peripheral::PadDisconnect(void) { - if (padHandler != NULL) - { - padHandler->terminate(kIOServiceRequired | kIOServiceSynchronous); - padHandler->release(); - padHandler = NULL; - } + if (padHandler != NULL) + { + padHandler->terminate(kIOServiceRequired | kIOServiceSynchronous); + padHandler->release(); + padHandler = NULL; + } } // Serial peripheral support void Xbox360Peripheral::SerialConnect(void) { - SerialDisconnect(); - serialHandler = new ChatPadKeyboardClass; + SerialDisconnect(); + serialHandler = new ChatPadKeyboardClass; if (serialHandler != NULL) { const OSString *keys[] = { @@ -1062,7 +1046,7 @@ void Xbox360Peripheral::SerialConnect(void) if (serialHandler->init(dictionary)) { serialHandler->attach(this); - serialHandler->start(this); + serialHandler->start(this); } else { @@ -1074,21 +1058,21 @@ void Xbox360Peripheral::SerialConnect(void) void Xbox360Peripheral::SerialDisconnect(void) { - if (serialHandler != NULL) - { + if (serialHandler != NULL) + { // Hope it's okay to terminate twice... - serialHandler->terminate(kIOServiceRequired | kIOServiceSynchronous); - serialHandler->release(); - serialHandler = NULL; - } + serialHandler->terminate(kIOServiceRequired | kIOServiceSynchronous); + serialHandler->release(); + serialHandler = NULL; + } } void Xbox360Peripheral::SerialMessage(IOBufferMemoryDescriptor *data, size_t length) { - if (serialHandler != NULL) - { - char *buffer = (char*)data->getBytesNoCopy(); - if ((length == 5) && (buffer[0] == 0x00)) - serialHandler->handleReport(data, kIOHIDReportTypeInput); - } + if (serialHandler != NULL) + { + char *buffer = (char*)data->getBytesNoCopy(); + if ((length == 5) && (buffer[0] == 0x00)) + serialHandler->handleReport(data, kIOHIDReportTypeInput); + } } diff --git a/360Controller/_60Controller.h b/360Controller/_60Controller.h index 86b07f2e..cccf9c11 100644 --- a/360Controller/_60Controller.h +++ b/360Controller/_60Controller.h @@ -1,31 +1,32 @@ /* - MICE Xbox 360 Controller driver for Mac OS X - Copyright (C) 2006-2013 Colin Munro - - _60Controller.h - declaration of the driver main class - - This file is part of Xbox360Controller. - - Xbox360Controller is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Xbox360Controller is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Foobar; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + MICE Xbox 360 Controller driver for Mac OS X + Copyright (C) 2006-2013 Colin Munro + + _60Controller.h - declaration of the driver main class + + This file is part of Xbox360Controller. + + Xbox360Controller is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Xbox360Controller is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Foobar; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ #ifndef __XBOX360CONTROLLER_H__ #define __XBOX360CONTROLLER_H__ #include #include #include +#include "ControlStruct.h" class Xbox360ControllerClass; class ChatPadKeyboardClass; @@ -37,65 +38,69 @@ class Xbox360Peripheral : public IOService private: void ReleaseAll(void); bool QueueRead(void); - bool QueueSerialRead(void); + bool QueueSerialRead(void); - static void SerialReadCompleteInternal(void *target,void *parameter,IOReturn status,UInt32 bufferSizeRemaining); + static void SerialReadCompleteInternal(void *target,void *parameter,IOReturn status,UInt32 bufferSizeRemaining); static void ReadCompleteInternal(void *target,void *parameter,IOReturn status,UInt32 bufferSizeRemaining); static void WriteCompleteInternal(void *target,void *parameter,IOReturn status,UInt32 bufferSizeRemaining); - - void SerialReadComplete(void *parameter, IOReturn status, UInt32 bufferSizeRemaining); + + void SerialReadComplete(void *parameter, IOReturn status, UInt32 bufferSizeRemaining); void readSettings(void); - static void ChatPadTimerActionWrapper(OSObject *owner, IOTimerEventSource *sender); - void ChatPadTimerAction(IOTimerEventSource *sender); - void SendToggle(void); - void SendSpecial(UInt16 value); - void SendInit(UInt16 value, UInt16 index); + static void ChatPadTimerActionWrapper(OSObject *owner, IOTimerEventSource *sender); + void ChatPadTimerAction(IOTimerEventSource *sender); + void SendToggle(void); + void SendSpecial(UInt16 value); + void SendInit(UInt16 value, UInt16 index); bool SendSwitch(bool sendOut); - - void PadConnect(void); - void PadDisconnect(void); - - void SerialConnect(void); - void SerialDisconnect(void); - void SerialMessage(IOBufferMemoryDescriptor *data, size_t length); + + void PadConnect(void); + void PadDisconnect(void); + + void SerialConnect(void); + void SerialDisconnect(void); + void SerialMessage(IOBufferMemoryDescriptor *data, size_t length); + + void MakeSettingsChanges(void); protected: - typedef enum TIMER_STATE { - tsToggle, - tsReset1, - tsReset2, - tsMiniToggle, - tsSet1, - tsSet2, - tsSet3, - } TIMER_STATE; - + typedef enum TIMER_STATE { + tsToggle, + tsReset1, + tsReset2, + tsMiniToggle, + tsSet1, + tsSet2, + tsSet3, + } TIMER_STATE; + typedef enum CONTROLLER_TYPE { Xbox360 = 0, XboxOriginal = 1, - XboxOne = 2 + XboxOne = 2, + XboxOnePretend360 = 3, + Xbox360Pretend360 = 4, } CONTROLLER_TYPE; - + IOUSBDevice *device; IOLock *mainLock; - - // Joypad + + // Joypad IOUSBInterface *interface; IOUSBPipe *inPipe,*outPipe; IOBufferMemoryDescriptor *inBuffer; - - // Keyboard - IOUSBInterface *serialIn; - IOUSBPipe *serialInPipe; + + // Keyboard + IOUSBInterface *serialIn; + IOUSBPipe *serialInPipe; IOBufferMemoryDescriptor *serialInBuffer; - IOTimerEventSource *serialTimer; - bool serialToggle, serialHeard, serialActive; - int serialResetCount; - TIMER_STATE serialTimerState; - ChatPadKeyboardClass *serialHandler; - Xbox360ControllerClass *padHandler; + IOTimerEventSource *serialTimer; + bool serialToggle, serialHeard, serialActive; + int serialResetCount; + TIMER_STATE serialTimerState; + ChatPadKeyboardClass *serialHandler; + Xbox360ControllerClass *padHandler; UInt8 chatpadInit[2]; CONTROLLER_TYPE controllerType; @@ -105,21 +110,27 @@ class Xbox360Peripheral : public IOService short deadzoneLeft,deadzoneRight; bool relativeLeft,relativeRight; bool deadOffLeft, deadOffRight; - + + void normalizeAxis(SInt16& axis, short deadzone); + public: // Controller specific UInt8 rumbleType; bool swapSticks; UInt8 mapping[15]; - + bool noMapping = true; + bool pretend360; // Change VID and PID to MS 360 Controller + UInt8 outCounter = 6; + // this is from the IORegistryEntry - no provider yet virtual bool init(OSDictionary *propTable); virtual void free(void); - bool start(IOService *provider); - void stop(IOService *provider); - + bool start(IOService *provider); + bool willTerminate(IOService *provider, IOOptionBits options); + void stop(IOService *provider); + // IOKit methods. These methods are defines in virtual IOReturn setProperties(OSObject *properties); @@ -127,15 +138,17 @@ class Xbox360Peripheral : public IOService virtual IOReturn message(UInt32 type, IOService *provider, void *argument); virtual bool didTerminate(IOService *provider, IOOptionBits options, bool *defer); - - // Hooks + + // Hooks virtual void ReadComplete(void *parameter,IOReturn status,UInt32 bufferSizeRemaining); virtual void WriteComplete(void *parameter,IOReturn status,UInt32 bufferSizeRemaining); bool QueueWrite(const void *bytes,UInt32 length); - virtual void fiddleReport(IOBufferMemoryDescriptor *buffer); - - IOHIDDevice* getController(int index); + void fiddleReport(XBOX360_HAT& left, XBOX360_HAT& right); + + IOHIDDevice* getController(int index); + + }; #endif /* __XBOX360CONTROLLER_H__ */ diff --git a/360Controller/chatpadhid.h b/360Controller/chatpadhid.h index dcd7d514..642141a7 100644 --- a/360Controller/chatpadhid.h +++ b/360Controller/chatpadhid.h @@ -1,21 +1,21 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + chatpadhid.h - a HID descriptor for the Microsoft ChatPad accessory - + This file is part of Xbox360Controller. - + Xbox360Controller is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + Xbox360Controller is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/360Controller/chatpadkeys.cpp b/360Controller/chatpadkeys.cpp index 7c46b791..9ec2cc04 100644 --- a/360Controller/chatpadkeys.cpp +++ b/360Controller/chatpadkeys.cpp @@ -1,21 +1,21 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + chatpadkeys.cpp - Converts a chatpad scancode to a USB key value - + This file is part of Xbox360Controller. - + Xbox360Controller is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + Xbox360Controller is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA @@ -44,7 +44,7 @@ unsigned char ChatPad2USB(unsigned char input) { unsigned char row = input & 0x0F; unsigned char column = (input & 0xF0) >> 4; - + if (row >= ROW_SIZE) return 0x00; if (column >= (sizeof(columns) / sizeof(columns[0]))) diff --git a/360Controller/chatpadkeys.h b/360Controller/chatpadkeys.h index 4add680d..756989c2 100644 --- a/360Controller/chatpadkeys.h +++ b/360Controller/chatpadkeys.h @@ -1,21 +1,21 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + chatpadkeys.h - public functions of the ChatPad key handling - + This file is part of Xbox360Controller. - + Xbox360Controller is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + Xbox360Controller is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/360Controller/xbox360hid.h b/360Controller/xbox360hid.h index e8ae1850..5ccc2d8c 100644 --- a/360Controller/xbox360hid.h +++ b/360Controller/xbox360hid.h @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + xbox360hid.h - HID descriptor for the driver - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify diff --git a/360Controller/zh-Hans.lproj/InfoPlist.strings b/360Controller/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 00000000..4a8156e4 --- /dev/null +++ b/360Controller/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,4 @@ +/* Localized versions of Info.plist keys */ + +CFBundleName = "360Controller"; +NSHumanReadableCopyright = "© Colin Munro, 2005-11"; diff --git a/360Daemon/360Daemon.m b/360Daemon/360Daemon.m index ffe21455..7b284b43 100644 --- a/360Daemon/360Daemon.m +++ b/360Daemon/360Daemon.m @@ -1,21 +1,21 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + 360Daemon.m - main functionality of the support daemon - + This file is part of Xbox360Controller. - + Xbox360Controller is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + Xbox360Controller is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include #import "ControlPrefs.h" #import "DaemonLEDs.h" @@ -43,6 +45,8 @@ static io_iterator_t onIteratorOther; static io_iterator_t offIteratorWired; static io_iterator_t offIteratorWireless; +static io_object_t powerNotifier; +static io_connect_t root_power_port; // a reference to the Root Power Domain IOService static BOOL foundWirelessReceiver; static DaemonLEDs *leds; @@ -55,7 +59,7 @@ }; NSString *alertStrings[] = { - @"You have attached a Microsoft Play & Charge cable for your XBox 360 Wireless Controller. While this cable will allow you to charge your wireless controller, you will require the Microsoft Wireless Gaming Receiver for Windows to use your wireless controller in Mac OS X!", + @"You have attached a Microsoft Play & Charge cable for your Xbox 360 Wireless Controller. While this cable will allow you to charge your wireless controller, you will require the Microsoft Wireless Gaming Receiver for Windows to use your wireless controller in Mac OS X!", }; static void releaseAlert(void) @@ -80,11 +84,11 @@ static void ShowAlert(NSInteger index) { SInt32 error; NSArray *checkBoxes = @[NSLocalizedString(CHECK_SHOWAGAIN, nil)]; - NSDictionary *dictionary = @{(NSString*)kCFUserNotificationAlertHeaderKey: NSLocalizedString(@"XBox 360 Controller Driver", nil), + NSDictionary *dictionary = @{(NSString*)kCFUserNotificationAlertHeaderKey: NSLocalizedString(@"Xbox 360 Controller Driver", nil), (NSString*)kCFUserNotificationAlertMessageKey: NSLocalizedString(alertStrings[index], nil), (NSString*)kCFUserNotificationCheckBoxTitlesKey: checkBoxes, (NSString*)kCFUserNotificationIconURLKey: [[NSBundle mainBundle] URLForImageResource:@"Alert"]}; - + if (AlertDisabled(index)) return; @@ -106,7 +110,7 @@ static void ConfigureDevice(io_service_t object) IOUSBDeviceInterface **dev; IOReturn err; SInt32 score; - + if ((!IOCreatePlugInInterfaceForService(object, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &iodev, &score))&&iodev) { err = (*iodev)->QueryInterface(iodev, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID)&dev); @@ -116,7 +120,7 @@ static void ConfigureDevice(io_service_t object) if ((*dev)->USBDeviceOpen(dev) == 0) { IOUSBConfigurationDescriptorPtr confDesc; - + if ((*dev)->GetConfigurationDescriptorPtr(dev, 0, &confDesc) == 0) { (*dev)->SetConfiguration(dev, confDesc->bConfigurationValue); @@ -134,7 +138,7 @@ static void callbackConnected(void *param,io_iterator_t iterator) { @autoreleasepool { io_service_t object = 0; - + while ((object = IOIteratorNext(iterator)) != 0) { #if 0 @@ -146,7 +150,7 @@ static void callbackConnected(void *param,io_iterator_t iterator) { FFDeviceObjectReference forceFeedback = 0; NSString *serialNumber = GetSerialNumber(object); - + // Supported device - load settings ConfigController(object, GetController(serialNumber)); // Set LEDs @@ -157,7 +161,7 @@ static void callbackConnected(void *param,io_iterator_t iterator) FFEFFESCAPE escape = {0}; unsigned char c; int i; - + c = 0x0a; if (serialNumber != nil) { @@ -220,7 +224,7 @@ static void callbackDisconnected(void *param, io_iterator_t iterator) io_service_t object = 0; NSString *serial; int i; - + while ((object = IOIteratorNext(iterator)) != 0) { #if 0 @@ -247,12 +251,50 @@ static void callbackDisconnected(void *param, io_iterator_t iterator) } } +static void callbackPower(void *refCon, io_service_t service, natural_t messageType, void *messageArgument) +{ + switch (messageType) + { + case kIOMessageCanSystemSleep: + // we will allow idle sleep + IOAllowPowerChange(root_power_port, (long)messageArgument); + break; + + case kIOMessageSystemWillSleep: + IOAllowPowerChange(root_power_port, (long)messageArgument); + break; + + case kIOMessageSystemHasPoweredOn: + //System has finished waking up... + { + io_iterator_t newItr; + IOServiceGetMatchingServices(masterPort, IOServiceMatching(kIOUSBDeviceClassName), &newItr); + callbackConnected(NULL, newItr); + IOObjectRelease(newItr); + // Wired 360 devices + IOServiceGetMatchingServices(masterPort, IOServiceMatching("Xbox360ControllerClass"), &newItr); + callbackConnected(NULL, newItr); + IOObjectRelease(newItr); + // Wireless 360 devices + IOServiceGetMatchingServices(masterPort, IOServiceMatching("WirelessHIDDevice"), &newItr); + callbackConnected(NULL, newItr); + IOObjectRelease(newItr); + } + break; + + default: + break; + } +} + // Entry point int main (int argc, const char * argv[]) { @autoreleasepool { foundWirelessReceiver = NO; leds = [[DaemonLEDs alloc] init]; + // notification port allocated by IORegisterForSystemPower + IONotificationPortRef sleepNotifyPort; // Get master port, for accessing I/O Kit IOMasterPort(MACH_PORT_NULL,&masterPort); // Set up notification of USB device addition/removal @@ -273,6 +315,18 @@ int main (int argc, const char * argv[]) callbackConnected(NULL, onIteratorWireless); IOServiceAddMatchingNotification(notifyPort, kIOTerminatedNotification, IOServiceMatching("WirelessHIDDevice"), callbackDisconnected, NULL, &offIteratorWireless); callbackDisconnected(NULL, offIteratorWireless); + // wake/sleep watching + root_power_port = IORegisterForSystemPower(NULL, &sleepNotifyPort, callbackPower, &powerNotifier); + if (root_power_port == 0) + { + printf("IORegisterForSystemPower failed\n"); + } + else + { + CFRunLoopAddSource(CFRunLoopGetCurrent(), + IONotificationPortGetRunLoopSource(sleepNotifyPort), kCFRunLoopCommonModes); + } + // Run loop CFRunLoopRun(); // Stop listening @@ -284,6 +338,14 @@ int main (int argc, const char * argv[]) CFRunLoopRemoveSource(CFRunLoopGetCurrent(), notifySource, kCFRunLoopCommonModes); CFRunLoopSourceInvalidate(notifySource); IONotificationPortDestroy(notifyPort); + if (root_power_port) { + CFRunLoopRemoveSource(CFRunLoopGetCurrent(), + IONotificationPortGetRunLoopSource(sleepNotifyPort), + kCFRunLoopCommonModes); + IODeregisterForSystemPower(&powerNotifier); + IOServiceClose(root_power_port); + IONotificationPortDestroy(sleepNotifyPort); + } // End } return 0; diff --git a/360Daemon/360DaemonApp-Info.plist b/360Daemon/360DaemonApp-Info.plist index a522ed4c..12973fce 100644 --- a/360Daemon/360DaemonApp-Info.plist +++ b/360Daemon/360DaemonApp-Info.plist @@ -21,7 +21,7 @@ CFBundleVersion ${CURRENT_PROJECT_VERSION} LSMinimumSystemVersion - ${MACOSX_DEPLOYMENT_TARGET} + ${MIN_MACOS_VERSION} LSUIElement NSHumanReadableCopyright diff --git a/360Daemon/ControlPrefs.h b/360Daemon/ControlPrefs.h index a7481a77..f7929662 100644 --- a/360Daemon/ControlPrefs.h +++ b/360Daemon/ControlPrefs.h @@ -1,21 +1,21 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + ControlPrefs.h - interface to the preferences functionality - + This file is part of Xbox360Controller. - + Xbox360Controller is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + Xbox360Controller is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/360Daemon/ControlPrefs.m b/360Daemon/ControlPrefs.m index 3cb4f823..a69ed673 100644 --- a/360Daemon/ControlPrefs.m +++ b/360Daemon/ControlPrefs.m @@ -1,21 +1,21 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + ControlPrefs.m - code to read and write shared preferences - + This file is part of Xbox360Controller. - + Xbox360Controller is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + Xbox360Controller is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA @@ -35,7 +35,7 @@ BOOL AlertDisabled(NSInteger index) NSString *prop = [NSString stringWithFormat:@"%@%li", D_SHOWONCE, (long)index]; BOOL result = NO; CFPropertyListRef value = CFPreferencesCopyValue((__bridge CFStringRef)prop, DOM_DAEMON, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost); - + if (value != NULL) { result = [CFBridgingRelease(value) boolValue]; @@ -45,22 +45,22 @@ BOOL AlertDisabled(NSInteger index) void SetController(NSString *serial, NSDictionary *data) { - CFPreferencesSetValue((__bridge CFStringRef)serial, (__bridge CFPropertyListRef)(data), DOM_CONTROLLERS, kCFPreferencesAnyUser, kCFPreferencesCurrentHost); - CFPreferencesSynchronize(DOM_CONTROLLERS, kCFPreferencesAnyUser, kCFPreferencesCurrentHost); + CFPreferencesSetValue((__bridge CFStringRef)serial, (__bridge CFPropertyListRef)(data), DOM_CONTROLLERS, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost); + CFPreferencesSynchronize(DOM_CONTROLLERS, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost); } NSDictionary* GetController(NSString *serial) { CFPropertyListRef value; - CFPreferencesSynchronize(DOM_CONTROLLERS, kCFPreferencesAnyUser, kCFPreferencesCurrentHost); - value = CFPreferencesCopyValue((__bridge CFStringRef)serial, DOM_CONTROLLERS, kCFPreferencesAnyUser, kCFPreferencesCurrentHost); + CFPreferencesSynchronize(DOM_CONTROLLERS, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost); + value = CFPreferencesCopyValue((__bridge CFStringRef)serial, DOM_CONTROLLERS, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost); return CFBridgingRelease(value); } NSString* GetSerialNumber(io_service_t device) { CFTypeRef value = IORegistryEntrySearchCFProperty(device, kIOServicePlane, CFSTR("USB Serial Number"), kCFAllocatorDefault, kIORegistryIterateRecursively); - + if (value == NULL) value = IORegistryEntrySearchCFProperty(device, kIOServicePlane, CFSTR("SerialNumber"), kCFAllocatorDefault, kIORegistryIterateRecursively); return CFBridgingRelease(value); @@ -75,17 +75,17 @@ void SetKnownDevices(NSDictionary *devices) { // Setting the dictionary should work? NSData *data = [NSKeyedArchiver archivedDataWithRootObject:devices]; - CFPreferencesSetValue((CFStringRef)D_KNOWNDEV, (__bridge CFPropertyListRef)(data), DOM_CONTROLLERS, kCFPreferencesAnyUser, kCFPreferencesCurrentHost); - CFPreferencesSynchronize(DOM_CONTROLLERS, kCFPreferencesAnyUser, kCFPreferencesCurrentHost); + CFPreferencesSetValue((CFStringRef)D_KNOWNDEV, (__bridge CFPropertyListRef)(data), DOM_CONTROLLERS, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost); + CFPreferencesSynchronize(DOM_CONTROLLERS, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost); } NSDictionary* GetKnownDevices(void) { CFPropertyListRef value; NSData *data; - - CFPreferencesSynchronize(DOM_CONTROLLERS, kCFPreferencesAnyUser, kCFPreferencesCurrentHost); - value = CFPreferencesCopyValue((CFStringRef)D_KNOWNDEV, DOM_CONTROLLERS, kCFPreferencesAnyUser, kCFPreferencesCurrentHost); + + CFPreferencesSynchronize(DOM_CONTROLLERS, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost); + value = CFPreferencesCopyValue((CFStringRef)D_KNOWNDEV, DOM_CONTROLLERS, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost); data = CFBridgingRelease(value); if (data == nil) return nil; diff --git a/360Daemon/DaemonLEDs.m b/360Daemon/DaemonLEDs.m index a9b5fd23..01ea829f 100644 --- a/360Daemon/DaemonLEDs.m +++ b/360Daemon/DaemonLEDs.m @@ -23,15 +23,15 @@ - (void)setLED:(int)theLED toSerialNumber:(NSString*)serialNum case 0: self.theLED0 = serialNum; break; - + case 1: self.theLED1 = serialNum; break; - + case 2: self.theLED2 = serialNum; break; - + case 3: self.theLED3 = serialNum; break; @@ -47,19 +47,19 @@ - (NSString *)serialNumberAtLED:(int)theLED case 0: return self.theLED0; break; - + case 1: return self.theLED1; break; - + case 2: return self.theLED2; break; - + case 3: return self.theLED3; break; - + default: return @""; break; @@ -72,19 +72,19 @@ - (BOOL)serialNumberAtLEDIsBlank:(int)theLED case 0: return self.theLED0 == nil; break; - + case 1: return self.theLED1 == nil; break; - + case 2: return self.theLED2 == nil; break; - + case 3: return self.theLED3 == nil; break; - + default: return NO; break; @@ -97,19 +97,19 @@ - (void)clearSerialNumberAtLED:(int)theLED case 0: self.theLED0 = nil; break; - + case 1: self.theLED1 = nil; break; - + case 2: self.theLED2 = nil; break; - + case 3: self.theLED3 = nil; break; - + default: break; } diff --git a/360Daemon/Images.xcassets/360Control.appiconset/Contents.json b/360Daemon/Images.xcassets/360Control.appiconset/Contents.json index b60be381..9e67b1e5 100644 --- a/360Daemon/Images.xcassets/360Control.appiconset/Contents.json +++ b/360Daemon/Images.xcassets/360Control.appiconset/Contents.json @@ -65,4 +65,4 @@ "version" : 1, "author" : "xcode" } -} \ No newline at end of file +} diff --git a/360Daemon/en.lproj/InfoPlist.strings b/360Daemon/en.lproj/InfoPlist.strings index 477b28ff..b92732c7 100644 --- a/360Daemon/en.lproj/InfoPlist.strings +++ b/360Daemon/en.lproj/InfoPlist.strings @@ -1,2 +1 @@ /* Localized versions of Info.plist keys */ - diff --git a/360Daemon/en.lproj/Localizable.strings b/360Daemon/en.lproj/Localizable.strings index 864e6ed7..bdfcc203 100644 --- a/360Daemon/en.lproj/Localizable.strings +++ b/360Daemon/en.lproj/Localizable.strings @@ -7,5 +7,5 @@ */ "Do not show this message again" = "Do not show this message again"; -"You have attached a Microsoft Play & Charge cable for your XBox 360 Wireless Controller. While this cable will allow you to charge your wireless controller, you will require the Microsoft Wireless Gaming Receiver for Windows to use your wireless controller in Mac OS X!" = "You have attached a Microsoft Play & Charge cable for your XBox 360 Wireless Controller. While this cable will allow you to charge your wireless controller, you will require the Microsoft Wireless Gaming Receiver for Windows to use your wireless controller in Mac OS X!"; -"XBox 360 Controller Driver" = "XBox 360 Controller Driver"; +"You have attached a Microsoft Play & Charge cable for your Xbox 360 Wireless Controller. While this cable will allow you to charge your wireless controller, you will require the Microsoft Wireless Gaming Receiver for Windows to use your wireless controller in Mac OS X!" = "You have attached a Microsoft Play & Charge cable for your Xbox 360 Wireless Controller. While this cable will allow you to charge your wireless controller, you will require the Microsoft Wireless Gaming Receiver for Windows to use your wireless controller in Mac OS X!"; +"Xbox 360 Controller Driver" = "Xbox 360 Controller Driver"; diff --git a/360Daemon/zh-Hans.lproj/InfoPlist.strings b/360Daemon/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 00000000..b92732c7 --- /dev/null +++ b/360Daemon/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1 @@ +/* Localized versions of Info.plist keys */ diff --git a/360Daemon/zh-Hans.lproj/Localizable.strings b/360Daemon/zh-Hans.lproj/Localizable.strings new file mode 100644 index 00000000..52f25b7a --- /dev/null +++ b/360Daemon/zh-Hans.lproj/Localizable.strings @@ -0,0 +1,11 @@ +/* + Localizable.strings + 360 Driver + + Created by C.W. Betts on 2/28/14. + Copyright (c) 2014 GitHub. All rights reserved. +*/ + +"Do not show this message again" = "不要再显示此消息"; +"You have attached a Microsoft Play & Charge cable for your Xbox 360 Wireless Controller. While this cable will allow you to charge your wireless controller, you will require the Microsoft Wireless Gaming Receiver for Windows to use your wireless controller in Mac OS X!" = "您已为Xbox 360无线控制器连接了Microsoft Play&Charge电缆。虽然此电缆允许您为无线控制器充电,但您需要Microsoft无线游戏接收器才能在Mac OS X中使用您的无线控制器!"; +"Xbox 360 Controller Driver" = "Xbox 360 控制器驱动"; diff --git a/DriverTool/DriverTool.m b/DriverTool/DriverTool.m index 94cdde3d..9d721c1f 100644 --- a/DriverTool/DriverTool.m +++ b/DriverTool/DriverTool.m @@ -1,21 +1,21 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + DriverTool.m - implementation of driver info tweaking tool - + This file is part of Xbox360Controller. - + Xbox360Controller is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + Xbox360Controller is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA @@ -45,7 +45,7 @@ NSString *filename = GetDriverConfigPath(driver); NSError *error; NSData *data; - + infoPlistAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filename error:&error]; if (infoPlistAttributes == nil) { @@ -61,13 +61,13 @@ static void WriteDriverConfig(NSString *driver, id config) NSString *filename = GetDriverConfigPath(driver); NSError *error; NSData *data = [NSPropertyListSerialization dataWithPropertyList:config format:NSPropertyListXMLFormat_v1_0 options:0 error:&error]; - + if (data == nil) NSLog(@"Error writing config for driver: %@", error); - + if (![data writeToFile:filename atomically:NO]) NSLog(@"Failed to write file!"); - + if (infoPlistAttributes != nil) { if (![[NSFileManager defaultManager] setAttributes:infoPlistAttributes ofItemAtPath:filename error:&error]) { NSLog(@"Error setting attributes on '%@': %@", filename, error); @@ -78,7 +78,7 @@ static void WriteDriverConfig(NSString *driver, id config) static void ScrubDevices(NSMutableDictionary *devices) { NSMutableArray *deviceKeys = [[NSMutableArray alloc] initWithCapacity:10]; - + for (NSString *key in devices) { NSDictionary *device = devices[key]; if ([(NSString*)device[@"IOClass"] compare:@"Xbox360Peripheral"] == NSOrderedSame) @@ -97,18 +97,18 @@ static id MakeMutableCopy(id object) static void AddDevice(NSMutableDictionary *personalities, NSString *name, int vendor, int product) { NSMutableDictionary *controller = [[NSMutableDictionary alloc] initWithCapacity:10]; - + // Standard controller[@"CFBundleIdentifier"] = @"com.mice.driver.Xbox360Controller"; controller[@"IOCFPlugInTypes"] = @{@"F4545CE5-BF5B-11D6-A4BB-0003933E3E3E": @"360Controller.kext/Contents/PlugIns/Feedback360.plugin"}; controller[@"IOClass"] = @"Xbox360Peripheral"; controller[@"IOProviderClass"] = @"IOUSBDevice"; controller[@"IOKitDebug"] = @65535; - + // Device-specific controller[@"idVendor"] = @(vendor); controller[@"idProduct"] = @(product); - + // Add it to the tree personalities[name] = controller; } @@ -145,7 +145,7 @@ int main (int argc, const char * argv[]) { } else if ((argc > 1) && (strcmp(argv[1], "edit") == 0) && (((argc - 2) % 3) == 0)) { NSMutableDictionary *saving; NSMutableDictionary *devices; - + saving = MakeMutableCopy(config); devices = saving[@"IOKitPersonalities"]; ScrubDevices(devices); @@ -156,7 +156,7 @@ int main (int argc, const char * argv[]) { } else NSLog(@"Invalid number of parameters (%i)", argc); - + return 0; } } diff --git a/DriverTool/Info.plist b/DriverTool/Info.plist index d092a1bf..31834f80 100644 --- a/DriverTool/Info.plist +++ b/DriverTool/Info.plist @@ -13,7 +13,7 @@ CFBundleShortVersionString ${CURRENT_PROJECT_VERSION} LSMinimumSystemVersion - ${MACOSX_DEPLOYMENT_TARGET} + ${MIN_MACOS_VERSION} CFBundleInfoDictionaryVersion 6.0 diff --git a/Feedback360/Feedback360.cpp b/Feedback360/Feedback360.cpp index 7c2f3069..32efbf28 100644 --- a/Feedback360/Feedback360.cpp +++ b/Feedback360/Feedback360.cpp @@ -1,10 +1,10 @@ /* - MICE Xbox 360 Controller driver for Mac OS X - Force Feedback module - Copyright (C) 2013 David Ryskalczyk - based on xi, Copyright (C) 2011 Masahiko Morii + MICE Xbox 360 Controller driver for Mac OS X + Force Feedback module + Copyright (C) 2013 David Ryskalczyk + based on xi, Copyright (C) 2011 Masahiko Morii - Feedback360.cpp - Main code for the FF plugin + Feedback360.cpp - Main code for the FF plugin This file is part of Xbox360Controller. @@ -33,12 +33,17 @@ using std::min; double CurrentTimeUsingMach() { - mach_timebase_info_data_t info = {0}; - if (mach_timebase_info(&info) != KERN_SUCCESS) { - //FIXME: why would this fail/set to fail more gracefully. - return -1.0; - } - + static mach_timebase_info_data_t info = {0}; + if (!info.denom) + { + if (mach_timebase_info(&info) != KERN_SUCCESS) + { + //Generally it can't fail here. Look at XNU sources //FIXME + info.denom = 0; + return -1.0; + } + } + uint64_t start = mach_absolute_time(); uint64_t nanos = start * info.numer / info.denom; @@ -548,7 +553,7 @@ HRESULT Feedback360::Escape(FFEffectDownloadID downloadID, FFEFFESCAPE *escape) Manual=((unsigned char*)escape->lpvInBuffer)[0]!=0x00; }); break; - + case 0x01: // Set motors if (escape->cbInBuffer!=2) return FFERR_INVALIDPARAM; dispatch_sync(Queue, ^{ @@ -559,7 +564,7 @@ HRESULT Feedback360::Escape(FFEffectDownloadID downloadID, FFEFFESCAPE *escape) } }); break; - + case 0x02: // Set LED if (escape->cbInBuffer!=1) return FFERR_INVALIDPARAM; { @@ -570,7 +575,7 @@ HRESULT Feedback360::Escape(FFEffectDownloadID downloadID, FFEFFESCAPE *escape) }); } break; - + case 0x03: // Power off { dispatch_sync(Queue, ^{ @@ -579,7 +584,7 @@ HRESULT Feedback360::Escape(FFEffectDownloadID downloadID, FFEFFESCAPE *escape) }); } break; - + default: fprintf(stderr, "Xbox360Controller FF plugin: Unknown escape (%i)\n", (int)escape->dwCommand); return FFERR_UNSUPPORTED; @@ -607,7 +612,7 @@ void Feedback360::EffectProc( void *params ) { for (Feedback360EffectIterator effectIterator = cThis->EffectList.begin(); effectIterator != cThis->EffectList.end(); ++effectIterator) { - if((CurrentTimeUsingMach() - cThis->LastTime*1000*1000) >= effectIterator->DiEffect.dwSamplePeriod) { + if(((CurrentTimeUsingMach() - cThis->LastTime)*1000*1000) >= effectIterator->DiEffect.dwSamplePeriod) { CalcResult = effectIterator->Calc(&LeftLevel, &RightLevel); } } diff --git a/Feedback360/Feedback360.h b/Feedback360/Feedback360.h index cea2dcbf..3320c776 100644 --- a/Feedback360/Feedback360.h +++ b/Feedback360/Feedback360.h @@ -122,7 +122,7 @@ class Feedback360 : IUnknown // event loop func static void EffectProc( void *params ); - + // actual member functions ultimately called by the FF API (through the static functions) virtual IOReturn Probe ( CFDictionaryRef propertyTable, io_service_t service, SInt32 * order ); virtual IOReturn Start ( CFDictionaryRef propertyTable, io_service_t service ); diff --git a/Feedback360/Feedback360Effect.cpp b/Feedback360/Feedback360Effect.cpp index 87d4fe0b..a10fe538 100644 --- a/Feedback360/Feedback360Effect.cpp +++ b/Feedback360/Feedback360Effect.cpp @@ -5,7 +5,7 @@ Based on xi, Copyright (C) 2011 Masahiko Morii Feedback360Effect.cpp - Main code for the FF plugin - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -34,7 +34,7 @@ Feedback360Effect::Feedback360Effect() : Type(NULL), Status(0), PlayCount(0), StartTime(0), Index(0), LastTime(0), Handle(0), DiEffect({0}), DiEnvelope({0}), DiCustomForce({0}), DiConstantForce({0}), DiPeriodic({0}), DiRampforce({0}) { - + } Feedback360Effect::Feedback360Effect(FFEffectDownloadID theHand) : Feedback360Effect() diff --git a/Feedback360/Feedback360Effect.h b/Feedback360/Feedback360Effect.h index c63573a3..254965e8 100644 --- a/Feedback360/Feedback360Effect.h +++ b/Feedback360/Feedback360Effect.h @@ -5,7 +5,7 @@ based on xi, Copyright (C) 2011 Masahiko Morii Feedback360Effect.cpp - Main code for the FF plugin - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify diff --git a/Feedback360/Info.plist b/Feedback360/Info.plist index 5e1ff4a5..02d7ba5f 100644 --- a/Feedback360/Info.plist +++ b/Feedback360/Info.plist @@ -14,10 +14,14 @@ ${PRODUCT_NAME} CFBundlePackageType BNDL + CFBundleShortVersionString + $(CURRENT_PROJECT_VERSION) CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} + LSMinimumSystemVersion + ${MIN_MACOS_VERSION} CFPlugInDynamicRegistration NO CFPlugInFactories diff --git a/Feedback360/devlink.cpp b/Feedback360/devlink.cpp index d343a7ec..85869ed5 100644 --- a/Feedback360/devlink.cpp +++ b/Feedback360/devlink.cpp @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + devlink.c - code to speak to the driver itself - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -30,7 +30,7 @@ bool Device_Initialise(DeviceLink *link,io_object_t device) IOCFPlugInInterface **plugInInterface = NULL; SInt32 score = 0; IOReturn ret = IOCreatePlugInInterfaceForService(device, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); - + if (ret!=kIOReturnSuccess) return false; ret=(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID121), (LPVOID*)(&link->interface)); (*plugInInterface)->Release(plugInInterface); diff --git a/Feedback360/devlink.h b/Feedback360/devlink.h index f620cd77..ef4f06e6 100644 --- a/Feedback360/devlink.h +++ b/Feedback360/devlink.h @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + devlink.h - Interface to the device link - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify diff --git a/Feedback360/zh-Hans.lproj/InfoPlist.strings b/Feedback360/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 00000000..0d04b229 --- /dev/null +++ b/Feedback360/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,4 @@ +/* Localized versions of Info.plist keys */ + +CFBundleName = "Feedback360"; +NSHumanReadableCopyright = "© Colin Munro, 2005-2011"; diff --git a/Install360Controller/Install360Controller.pkgproj b/Install360Controller/Install360Controller.pkgproj index 5cf658b8..7dc48512 100644 --- a/Install360Controller/Install360Controller.pkgproj +++ b/Install360Controller/Install360Controller.pkgproj @@ -5,6 +5,10 @@ PACKAGES + MUST-CLOSE-APPLICATION-ITEMS + + MUST-CLOSE-APPLICATIONS + PACKAGE_FILES DEFAULT_INSTALL_LOCATION @@ -134,38 +138,6 @@ UID 0 - - CHILDREN - - GID - 0 - PATH - ../build/Release/Wireless360Controller.kext - PATH_TYPE - 1 - PERMISSIONS - 493 - TYPE - 3 - UID - 0 - - - CHILDREN - - GID - 0 - PATH - ../build/Release/WirelessGamingReceiver.kext - PATH_TYPE - 1 - PERMISSIONS - 493 - TYPE - 3 - UID - 0 - GID 0 @@ -297,6 +269,18 @@ CHILDREN + BUNDLE_CAN_DOWNGRADE + + BUNDLE_POSTINSTALL_PATH + + PATH_TYPE + 0 + + BUNDLE_PREINSTALL_PATH + + PATH_TYPE + 0 + CHILDREN GID @@ -368,7 +352,7 @@ PATH_TYPE 0 PERMISSIONS - 493 + 1005 TYPE 1 UID @@ -470,6 +454,22 @@ UID 0 + + CHILDREN + + GID + 0 + PATH + Automator + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + GID 0 @@ -583,8 +583,14 @@ PAYLOAD_TYPE 0 + SHOW_INVISIBLE + + SPLIT_FORKS + + TREAT_MISSING_FILES_AS_WARNING + VERSION - 2 + 5 PACKAGE_SCRIPTS @@ -611,15 +617,29 @@ 1 CONCLUSION_ACTION 2 + FOLLOW_SYMBOLIC_LINKS + IDENTIFIER com.mice.pkg.Xbox360controller + LOCATION + 0 NAME Install360Controller OVERWRITE_PERMISSIONS + PAYLOAD_SIZE + -1 + REFERENCE_PATH + + RELOCATABLE + + USE_HFS+_COMPRESSION + VERSION - 0.15 + 0.16.11 + TYPE + 0 UUID 95C3DB03-4C99-4A29-AEC7-C73B3D9F6A04 @@ -645,6 +665,8 @@ PROJECT_PRESENTATION + BACKGROUND + INSTALLATION TYPE HIERARCHIES @@ -681,8 +703,6 @@ - INSTALLATION TYPE - 0 MODE 1 @@ -764,8 +784,6 @@ LICENSE - KEYWORDS - LOCALIZATIONS @@ -824,7 +842,7 @@ BEHAVIOR - 2 + 3 DICTIONARY IC_REQUIREMENT_OS_DISK_TYPE @@ -832,24 +850,29 @@ IC_REQUIREMENT_OS_DISTRIBUTION_TYPE 0 IC_REQUIREMENT_OS_MINIMUM_VERSION - 100800 + 101100 IC_REQUIREMENT_CHECK_TYPE 0 IDENTIFIER fr.whitebox.Packages.requirement.os MESSAGE - + + + LANGUAGE + English + SECONDARY_VALUE + This driver can only be installed on macOS 10.11 or later. + VALUE + Operating System Version Too Low + + NAME Operating System STATE - POSTINSTALL_PATH - - PREINSTALL_PATH - RESOURCES ROOT_VOLUME_ONLY @@ -857,8 +880,6 @@ PROJECT_SETTINGS - ADVANCED_OPTIONS - BUILD_FORMAT 0 BUILD_PATH @@ -868,13 +889,6 @@ PATH_TYPE 1 - CERTIFICATE - - NAME - Developer ID Application: Rodrigo Rocha (CDMF3S9CTN) - PATH - /Users/Rodrigo/Library/Keychains/login.keychain - EXCLUDED_FILES @@ -1045,6 +1059,10 @@ NAME Install360Controller + PAYLOAD_ONLY + + TREAT_MISSING_PRESENTATION_DOCUMENTS_AS_WARNING + TYPE diff --git a/Install360Controller/Scripts/finish.sh b/Install360Controller/Scripts/finish.sh index d172e1e3..ed1fa640 100644 --- a/Install360Controller/Scripts/finish.sh +++ b/Install360Controller/Scripts/finish.sh @@ -5,6 +5,7 @@ /usr/bin/touch /System/Library/Extensions /usr/bin/touch /Library/Extensions + /bin/launchctl load -w /Library/LaunchDaemons/com.mice.360Daemon.plist exit 0 diff --git a/Install360Controller/Scripts/upgrade.sh b/Install360Controller/Scripts/upgrade.sh index da266b52..f52ff5fc 100644 --- a/Install360Controller/Scripts/upgrade.sh +++ b/Install360Controller/Scripts/upgrade.sh @@ -64,4 +64,11 @@ if [ -d /Library/Extensions/WirelessGamingReceiver.kext ]; then /bin/rm -r /Library/Extensions/WirelessGamingReceiver.kext fi +# Remove bluetooth driver + +if [ -d /Library/Extensions/XboxOneBluetooth.kext ]; then + kextunload /Library/Extensions/XboxOneBluetooth.kext + /bin/rm -r /Library/Extensions/XboxOneBluetooth.kext +fi + exit 0 diff --git a/Install360Controller/Text/Readme.rtf b/Install360Controller/Text/Readme.rtf index c8a4f1c6..2fe80874 100644 --- a/Install360Controller/Text/Readme.rtf +++ b/Install360Controller/Text/Readme.rtf @@ -5,29 +5,29 @@ \deftab720 \pard\pardeftab720\sb240\sa283 -\f0\b\fs42 \cf0 XBox 360 Controller Driver\ +\f0\b\fs42 \cf0 Xbox 360 Controller Driver\ \pard\pardeftab720\sb200\sa120 \fs36 \cf0 About\ \pard\pardeftab720\sa283 -\b0\fs24 \cf0 This driver supports the -\b Microsoft Xbox 360 controller, Original Xbox Controller, Xbox One Controller -\b0 and various licensed third party controllers from brands like Hori, MadCatz, Logitech, etc. Including access to rumble motors and LEDs, on the Mac OS X platform. It includes a plugin for the Apple Force Feedback Framework so some games will be able to activate them, along with a Preference Pane with which allows you to test everything is installed correctly. Both wire controllers connected via USB, and wireless 360 controllers connected via the Wireless Gaming Receiver for Windows, are supported.\ +\b0\fs24 \cf0 This driver supports the +\b Microsoft Xbox 360 controller, Original Xbox Controller, Xbox One Controller +\b0 , and various licensed third party controllers from brands like Hori, MadCatz, Logitech, etc. Including access to rumble motors and LEDs, on the macOS platform. It includes a plugin for the Apple Force Feedback Framework so some games will be able to activate them, along with a Preference Pane with which allows you to test everything is installed correctly. Both wire controllers connected via USB and Bluetooth Xbox One S controllers. Wireless 360 controllers, connected via the Wireless Gaming Receiver for Windows, are NOT supported.\ This project is a fork of the {\field{\*\fldinst{HYPERLINK "http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller"}}{\fldrslt \cf2 \ul \ulc0 Xbox360Controller project}} originally created by Colin Munro, and includes hard work from {\field{\*\fldinst{HYPERLINK "https://github.com/d235j/"}}{\fldrslt d235j}} (who forked the project and fixed Force Feedback), {\field{\*\fldinst{HYPERLINK "https://github.com/MaddTheSane"}}{\fldrslt C.W. Betts}} (dozens of improvements and fixes!), {\field{\*\fldinst{HYPERLINK "https://github.com/FranticRain"}}{\fldrslt FranticRain}} (Xbox One Controller support and other improvements), {\field{\*\fldinst{HYPERLINK "https://github.com/kasbert"}}{\fldrslt kasbert}} (Original Xbox Controller Support), {\field{\*\fldinst{HYPERLINK "https://github.com/Pyroh"}}{\fldrslt Pyroh}} (User Interface overhaul), {\field{\*\fldinst{HYPERLINK "https://github.com/RodrigoCard"}}{\fldrslt RodrigoCard}} (kext sign and some scripts) and others (please forgive us if we forgot to include someone).\ \pard\pardeftab720\sb200\sa120 \b\fs36 \cf0 Installation\ \pard\pardeftab720\sa283 -\b0\fs24 \cf0 See the {\field{\*\fldinst{HYPERLINK "https://github.com/d235j/360Controller/releases"}}{\fldrslt \cf2 \ul \ulc0 releases page}} for the latest compiled and signed version of the driver. Most users will want to install and run this.\ +\b0\fs24 \cf0 See the {\field{\*\fldinst{HYPERLINK "https://github.com/360Controller/360Controller/releases"}}{\fldrslt \cf2 \ul \ulc0 releases page}} for the latest compiled and signed version of the driver. Most users will want to install and run this.\ If you are interested in installing as a developer please see below.\ \pard\pardeftab720\sb200\sa120 \b\fs36 \cf0 Usage\ \pard\pardeftab720\sa283 -\b0\fs24 \cf0 The driver exposes a standard game pad with a number of standard controls, so any game that supports gaming devices should work. In some cases this may need an update from the manufacturer of the game or a patched version. The Preference Pane uses the standard Mac OS X Frameworks for accessing HID devices and accessing Force Feedback capabilities, so should be a good test that the installation is functional.\ +\b0\fs24 \cf0 The driver exposes a standard game pad with a number of standard controls, so any game that supports gaming devices should work. In some cases this may need an update from the manufacturer of the game or a patched version. The Preference Pane uses the standard macOS Frameworks for accessing HID devices and accessing Force Feedback capabilities, so should be a good test that the installation is functional.\ \pard\pardeftab720\sb200\sa120 \b\fs36 \cf0 Developer info\ @@ -74,4 +74,4 @@ If you'd like to avoid paying apple for the developer account and want to disabl \b0\fs24 \cf0 Copyright (C) 2006-2013 Colin Munro\ This driver is licensed under the GNU Public License. A copy of this license is included in the distribution file, please inspect it before using the binary or source.\ -} \ No newline at end of file +} diff --git a/Install360Controller/Text/Welcome.rtf b/Install360Controller/Text/Welcome.rtf index 5962024d..0f8c2807 100644 --- a/Install360Controller/Text/Welcome.rtf +++ b/Install360Controller/Text/Welcome.rtf @@ -1,6 +1,7 @@ -{\rtf1\ansi\ansicpg1252\cocoartf1348\cocoasubrtf170 -{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf200 +{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} +{\*\expandedcolortbl;;} {\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1} {\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid101\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid2} {\list\listtemplateid3\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid201\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid3} @@ -18,242 +19,455 @@ {\list\listtemplateid15\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1401\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid15} {\list\listtemplateid16\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1501\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid16} {\list\listtemplateid17\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1601\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid17} -{\list\listtemplateid18\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1701\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid18}} -{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}{\listoverride\listid3\listoverridecount0\ls3}{\listoverride\listid4\listoverridecount0\ls4}{\listoverride\listid5\listoverridecount0\ls5}{\listoverride\listid6\listoverridecount0\ls6}{\listoverride\listid7\listoverridecount0\ls7}{\listoverride\listid8\listoverridecount0\ls8}{\listoverride\listid9\listoverridecount0\ls9}{\listoverride\listid10\listoverridecount0\ls10}{\listoverride\listid11\listoverridecount0\ls11}{\listoverride\listid12\listoverridecount0\ls12}{\listoverride\listid13\listoverridecount0\ls13}{\listoverride\listid14\listoverridecount0\ls14}{\listoverride\listid15\listoverridecount0\ls15}{\listoverride\listid16\listoverridecount0\ls16}{\listoverride\listid17\listoverridecount0\ls17}{\listoverride\listid18\listoverridecount0\ls18}} -\paperw12240\paperh15840\margl1440\margr1440\vieww10240\viewh12600\viewkind0 -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural - -\f0\b\fs42 \cf0 XBox 360 Controller Driver\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural - -\b0\fs24 \cf0 Version 0.15 (beta 3) -\i unofficial -\i0 \ -Copyright (C) 2005-2013 Colin Munro\ +{\list\listtemplateid18\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1701\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid18} +{\list\listtemplateid19\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1801\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid19} +{\list\listtemplateid20\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1901\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid20} +{\list\listtemplateid21\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid2001\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid21} +{\list\listtemplateid22\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid2101\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid22} +{\list\listtemplateid23\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid2201\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid23} +{\list\listtemplateid24\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid2301\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid24} +{\list\listtemplateid25\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid2401\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid25} +{\list\listtemplateid26\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid2501\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid26} +{\list\listtemplateid27\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid2601\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid27} +{\list\listtemplateid28\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid2701\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid28} +{\list\listtemplateid29\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid2801\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid29} +{\list\listtemplateid30\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid2901\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid30} +{\list\listtemplateid31\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid3001\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid31} +{\list\listtemplateid32\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid3101\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid32}} +{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}{\listoverride\listid3\listoverridecount0\ls3}{\listoverride\listid4\listoverridecount0\ls4}{\listoverride\listid5\listoverridecount0\ls5}{\listoverride\listid6\listoverridecount0\ls6}{\listoverride\listid7\listoverridecount0\ls7}{\listoverride\listid8\listoverridecount0\ls8}{\listoverride\listid9\listoverridecount0\ls9}{\listoverride\listid10\listoverridecount0\ls10}{\listoverride\listid11\listoverridecount0\ls11}{\listoverride\listid12\listoverridecount0\ls12}{\listoverride\listid13\listoverridecount0\ls13}{\listoverride\listid14\listoverridecount0\ls14}{\listoverride\listid15\listoverridecount0\ls15}{\listoverride\listid16\listoverridecount0\ls16}{\listoverride\listid17\listoverridecount0\ls17}{\listoverride\listid18\listoverridecount0\ls18}{\listoverride\listid19\listoverridecount0\ls19}{\listoverride\listid20\listoverridecount0\ls20}{\listoverride\listid21\listoverridecount0\ls21}{\listoverride\listid22\listoverridecount0\ls22}{\listoverride\listid23\listoverridecount0\ls23}{\listoverride\listid24\listoverridecount0\ls24}{\listoverride\listid25\listoverridecount0\ls25}{\listoverride\listid26\listoverridecount0\ls26}{\listoverride\listid27\listoverridecount0\ls27}{\listoverride\listid28\listoverridecount0\ls28}{\listoverride\listid29\listoverridecount0\ls29}{\listoverride\listid30\listoverridecount0\ls30}{\listoverride\listid31\listoverridecount0\ls31}{\listoverride\listid32\listoverridecount0\ls32}} +\margl1440\margr1440\vieww10240\viewh12600\viewkind0 +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 + +\f0\b\fs42 \cf0 Xbox 360 Controller Driver\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 + +\f1\b0\fs24 \cf0 Version 0.16.11\ +Copyright \'a9 2005\'962013 Colin Munro\ +Copyright \'a9 2013\'962019 {\field{\*\fldinst{HYPERLINK "https://github.com/360Controller/360Controller/graphs/contributors"}}{\fldrslt 360Controller contributors}}\ \ -Welcome to the installer for the XBox 360 Controller driver for Mac OS X.\ - -\b \ +Welcome to the installer for the Xbox 360 Controller driver for macOS.\ + +\f0\b \ +Update 0.16.11: 03/03/2019\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f1\b0 \cf0 This update includes:\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\cf0 \'95 Chinese localization\ + \'95 Add various new devices +\f0\b \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Update 0.16.10: 10/09/2018\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f1\b0 \cf0 This update includes:\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\cf0 \'95 Adds removal of Bluetooth kexts to installer, to prevent carry-over hangs on boot\ + \'95 Removed wireless 360 kexts that snuck back in to the install\ + \'95 Add various new devices +\f0\b \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Update 0.16.9: 09/15/2018\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f1\b0 \cf0 This update includes:\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\cf0 \'95 Resolves issues with hang in boot after installation\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\ls1\ilvl0\cf0 {\listtext \uc0\u8226 } +\f0\b Removes all hooks for Bluetooth controllers +\f1\b0 (Caused hang in boot)\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\cf0 \'95 Fixed an issue where Xbox One racing wheel pedals didn't work correctly\ + \'95 Add various new devices +\f0\b \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Update 0.16.8: 05/31/2018\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f1\b0 \cf0 This update includes:\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\cf0 \'95 Fixes for Xbox One guide button issues\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\ls2\ilvl0\cf0 {\listtext \uc0\u8226 }Fixes force feedback issues present since 0.16.6\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\cf0 \'95 Issues involving settings failing to be saved should be resolved\ + \'95 Appropriate rumble options should now be visible for Xbox One controllers in the preference pane +\f0\b \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Update 0.16.7: 05/16/2018\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f1\b0 \cf0 This update includes:\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\cf0 \'95 DMG fixes for macOS earlier than 10.13\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\ls3\ilvl0\cf0 {\listtext \uc0\u8226 }New devices +\f0\b \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Update 0.16.6: 04/03/2018\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f1\b0 \cf0 This update includes:\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 + +\f0\b \cf0 \'95 REMOVED XBOX 360 WIRELESS DRIVER +\f1\b0 \ + \'95 Enhancements for Bluetooth Xbox One S controllers\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\ls4\ilvl0\cf0 {\listtext \uc0\u8226 }Preferences should properly save now\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\ls4\ilvl0 +\f0\b \cf0 {\listtext \uc0\u8226 } +\f1\b0 New devices +\f0\b \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Update 0.16.5: 04/18/2017\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f1\b0 \cf0 This update includes:\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\cf0 \'95 New devices +\f0\b \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Update 0.16.4: 08/28/2016\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f1\b0 \cf0 This update includes:\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\cf0 \'95 Tons of new devices including the wired version of the new Xbox One controller\ + \'95 Third party Xbox 360 controllers can pretend to be Microsoft ones for better game compatibility\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\ls5\ilvl0\cf0 {\listtext \uc0\u8226 }Wireless controllers show a raw battery percentage value now\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\cf0 \'95 Preference pane doesn't complain about constraints in the Console anymore\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\ls6\ilvl0\cf0 {\listtext \uc0\u8226 }Xbox One racing wheel support\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\cf0 \'95 Enable/disable feature is more stable +\f0\b \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Update 0.16.3: 07/14/2016\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f1\b0 \cf0 This update includes:\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\ls7\ilvl0\cf0 {\listtext \uc0\u8226 }Actually resolves issue with Xbox One controller initialization\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\cf0 \'95 Third party Xbox One controllers still don't work, though +\f0\b \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Update 0.16.2: 07/09/2016\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f1\b0 \cf0 This update includes:\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\ls8\ilvl0\cf0 {\listtext \uc0\u8226 }Potentially resolves issue with Xbox One controller initialization +\f0\b \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Update 0.16.1: 07/06/2016\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f1\b0 \cf0 This update includes:\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\ls9\ilvl0\cf0 {\listtext \uc0\u8226 }New devices\ +{\listtext \uc0\u8226 }Fixed "normalize" not staying checked +\f0\b \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Update 0.16: 04/26/2016\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f1\b0 \cf0 This update includes:\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\ls10\ilvl0\cf0 {\listtext \uc0\u8226 }New devices\ +{\listtext \uc0\u8226 }The remapping tool is more robust\ +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls11\ilvl0\cf0 {\listtext \uc0\u8226 }Remapping works on wireless 360 controllers\ +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls11\ilvl0 +\f0\b \cf0 {\listtext \uc0\u8226 } +\f1\b0 Settings load properly\ +\ls11\ilvl0 +\f0\b {\listtext \uc0\u8226 } +\f1\b0 Xbox One controller pretends to be a 360 controller better ("Xbox One Controller (Xbox 360)" -> "Xbox 360 Wired Controller")\ +\ls11\ilvl0 +\f0\b {\listtext \uc0\u8226 } +\f1\b0 New rumble options for Xbox One controllers\ +\ls11\ilvl0 +\f0\b {\listtext \uc0\u8226 }OFFICIAL!\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Update 0.15 (beta 6): 04/09/2016\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f1\b0 \cf0 This update includes:\ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 +\ls12\ilvl0\cf0 {\listtext \uc0\u8226 }New wired Xbox One devices\ +{\listtext \uc0\u8226 }New Xbox 360 devices +\f0\b \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Update 0.15 (beta 5): 01/25/2016\ + +\f1\b0 This update includes:\ +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls13\ilvl0\cf0 {\listtext \uc0\u8226 }Fixed Xbox One Elite implementation.\ +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls13\ilvl0 +\f0\b \cf0 {\listtext \uc0\u8226 } +\f1\b0 Fix Xbox One rumble. +\f0\b \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Update 0.15 (beta 4): 01/14/2016\ + +\f1\b0 This update includes:\ +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls14\ilvl0\cf0 {\listtext \uc0\u8226 }Added fix for Rock Candy Xbox One controllers.\ +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls14\ilvl0 +\f0\b \cf0 {\listtext \uc0\u8226 } +\f1\b0 Added various new Xbox 360 controllers.\ +\ls14\ilvl0 +\f0\b {\listtext \uc0\u8226 } +\f1\b0 Xbox One controllers no longer pretend to be 360 controllers.\ +\ls14\ilvl0 +\f0\b {\listtext \uc0\u8226 } +\f1\b0 Added support for the Xbox One Elite controller. +\f0\b \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ Update 0.15 (beta 3): 09/15/2015\ -\b0 This update includes:\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls1\ilvl0\cf0 {\listtext \'95 }Removed Wireless Controller Remapping temporarily, as it was causing problems with these controllers\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\f1\b0 This update includes:\ +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls15\ilvl0\cf0 {\listtext \uc0\u8226 }Removed Wireless Controller Remapping temporarily, as it was causing problems with these controllers\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 -\b \cf0 \ +\f0\b \cf0 \ Update 0.15 (beta 2): 08/28/2015\ -\b0 This update includes:\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls2\ilvl0\cf0 {\listtext \'95 }New Xbox One Controller (2015 model) Support\ -{\listtext \'95 }Swappable sticks\ -{\listtext \'95 }A few more devices\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\f1\b0 This update includes:\ +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls16\ilvl0\cf0 {\listtext \uc0\u8226 }New Xbox One Controller (2015 model) Support\ +{\listtext \uc0\u8226 }Swappable sticks\ +{\listtext \uc0\u8226 }A few more devices\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 -\b \cf0 \ +\f0\b \cf0 \ Update 0.15 (beta): 07/28/2015\ -\b0 This update includes:\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls3\ilvl0\cf0 {\listtext \'95 }Completely reworked User Interface by {\field{\*\fldinst{HYPERLINK "https://github.com/Pyroh"}}{\fldrslt Pyroh}}\ -{\listtext \'95 }Xbox One Controller Support with Force Feedback by {\field{\*\fldinst{HYPERLINK "https://github.com/FranticRain"}}{\fldrslt FranticRain}}.\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls3\ilvl0 -\b \cf0 {\listtext \'95 } -\b0 Added dozens of device IDs provided by users, so most of Xbox compatible controllers should work\ -\ls3\ilvl0 -\b {\listtext \'95 } -\b0 Swappable button ids and Deadzone adjustment improvements by FranticRain\ -\ls3\ilvl0 -\b {\listtext \'95 } -\b0 General bug fixes and improvements mostrly from {\field{\*\fldinst{HYPERLINK "https://github.com/MaddTheSane/"}}{\fldrslt C.W. Betts}}\ -\ls3\ilvl0 -\b {\listtext \'95 } -\b0 You can now temporarily disable or completely uninstall the driver from the Preference Panel itself by {\field{\*\fldinst{HYPERLINK "https://github.com/RodrigoCard"}}{\fldrslt RodrigoCard}}. -\b \ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\f1\b0 This update includes:\ +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls17\ilvl0\cf0 {\listtext \uc0\u8226 }Completely reworked User Interface by {\field{\*\fldinst{HYPERLINK "https://github.com/Pyroh"}}{\fldrslt Pyroh}}\ +{\listtext \uc0\u8226 }Xbox One Controller Support with Force Feedback by {\field{\*\fldinst{HYPERLINK "https://github.com/FranticRain"}}{\fldrslt FranticRain}}.\ +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls17\ilvl0 +\f0\b \cf0 {\listtext \uc0\u8226 } +\f1\b0 Added dozens of device IDs provided by users, so most of Xbox compatible controllers should work\ +\ls17\ilvl0 +\f0\b {\listtext \uc0\u8226 } +\f1\b0 Swappable button ids and Deadzone adjustment improvements by FranticRain\ +\ls17\ilvl0 +\f0\b {\listtext \uc0\u8226 } +\f1\b0 General bug fixes and improvements mostrly from {\field{\*\fldinst{HYPERLINK "https://github.com/MaddTheSane/"}}{\fldrslt C.W. Betts}}\ +\ls17\ilvl0 +\f0\b {\listtext \uc0\u8226 } +\f1\b0 You can now temporarily disable or completely uninstall the driver from the Preference Panel itself by {\field{\*\fldinst{HYPERLINK "https://github.com/RodrigoCard"}}{\fldrslt RodrigoCard}}. +\f0\b \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 \cf0 \ Update 0.14: 12/23/2014\ -\b0 This update includes:\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls4\ilvl0\cf0 {\listtext \'95 }Fixes Force Feedback and the controller lights that were broken on the beta\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls4\ilvl0 -\b \cf0 {\listtext \'95 } -\b0 Bug fixes for Force feedback with < 1 second duration\ -\ls4\ilvl0 -\b {\listtext \'95 } -\b0 Bug fixes for some devices\ -{\listtext \'95 }Fixed the compilation of 32bit code.\ -\ls4\ilvl0 -\b {\listtext \'95 } -\b0 Original Xbox's Controller Support with Force Feedback -\b \ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\f1\b0 This update includes:\ +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls18\ilvl0\cf0 {\listtext \uc0\u8226 }Fixes Force Feedback and the controller lights that were broken on the beta\ +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls18\ilvl0 +\f0\b \cf0 {\listtext \uc0\u8226 } +\f1\b0 Bug fixes for Force feedback with < 1 second duration\ +\ls18\ilvl0 +\f0\b {\listtext \uc0\u8226 } +\f1\b0 Bug fixes for some devices\ +{\listtext \uc0\u8226 }Fixed the compilation of 32bit code.\ +\ls18\ilvl0 +\f0\b {\listtext \uc0\u8226 } +\f1\b0 Original Xbox's Controller Support with Force Feedback +\f0\b \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 \cf0 \ Update 0.14 (beta): 10/30/2014\ -\b0 This update includes:\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls5\ilvl0\cf0 {\listtext \'95 }Cocoa code modernization by C.W. Betts. This includes synthesized getters/setters, KVO/KVC, and migration to ARC.\ -{\listtext \'95 }General code readability improvements\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls5\ilvl0 -\b \cf0 {\listtext \'95 } -\b0 Better handling of feedback effects\ -{\listtext \'95 }Force Feedback is currently broken in this beta, {\field{\*\fldinst{HYPERLINK "https://github.com/d235j/360Controller/issues/22"}}{\fldrslt apparently due to an upstream Apple bug}}\ -\ls5\ilvl0 -\b {\listtext \'95 } -\b0 Updated code signing to be compatible with 10.10 Yosemite\ -\ls5\ilvl0 -\b {\listtext \'95 } -\b0 Package and Kexts Signed by {\field{\*\fldinst{HYPERLINK "https://twitter.com/RodrigoRodrigoR"}}{\fldrslt Rodrigo C. Rocha}} -\b \ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\f1\b0 This update includes:\ +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls19\ilvl0\cf0 {\listtext \uc0\u8226 }Cocoa code modernization by C.W. Betts. This includes synthesized getters/setters, KVO/KVC, and migration to ARC.\ +{\listtext \uc0\u8226 }General code readability improvements\ +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls19\ilvl0 +\f0\b \cf0 {\listtext \uc0\u8226 } +\f1\b0 Better handling of feedback effects\ +{\listtext \uc0\u8226 }Force Feedback is currently broken in this beta, {\field{\*\fldinst{HYPERLINK "https://github.com/360Controller/360Controller/issues/22"}}{\fldrslt apparently due to an upstream Apple bug}}\ +\ls19\ilvl0 +\f0\b {\listtext \uc0\u8226 } +\f1\b0 Updated code signing to be compatible with 10.10 Yosemite\ +\ls19\ilvl0 +\f0\b {\listtext \uc0\u8226 } +\f1\b0 Package and Kexts Signed by {\field{\*\fldinst{HYPERLINK "https://twitter.com/RodrigoRodrigoR"}}{\fldrslt Rodrigo C. Rocha}} +\f0\b \ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 \cf0 \ Update 0.13.1: 10/11/2013\ -\b0 This update includes:\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls6\ilvl0\cf0 {\listtext \'95 }Fix for kernel panics when Android File Transfer is also installed\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\f1\b0 This update includes:\ +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls20\ilvl0\cf0 {\listtext \uc0\u8226 }Fix for kernel panics when Android File Transfer is also installed\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 -\b \cf0 \ +\f0\b \cf0 \ Update 0.13: 9/29/2013\ -\b0 \ +\f1\b0 \ This update includes:\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls7\ilvl0\cf0 {\listtext \'95 }Near-total rewrite of the Feedback component\ -{\listtext \'95 }Bug fixes in the preference pane\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls21\ilvl0\cf0 {\listtext \uc0\u8226 }Near-total rewrite of the Feedback component\ +{\listtext \uc0\u8226 }Bug fixes in the preference pane\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 \cf0 \ -\b Update 0.12: 4/01/2013\ +\f0\b Update 0.12: 4/01/2013\ -\b0 \ +\f1\b0 \ This update includes:\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls8\ilvl0\cf0 {\listtext \'95 }Fix that prevents non-ChatPad-compatible controllers from working\ -{\listtext \'95 }Improvement to ChatPad support\ -{\listtext \'95 }Improvement to wireless support (automatic and manual power-off)\ -{\listtext \'95 }Updated Info.plist with many common devices\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls22\ilvl0\cf0 {\listtext \uc0\u8226 }Fix that prevents non-ChatPad-compatible controllers from working\ +{\listtext \uc0\u8226 }Improvement to ChatPad support\ +{\listtext \uc0\u8226 }Improvement to wireless support (automatic and manual power-off)\ +{\listtext \uc0\u8226 }Updated Info.plist with many common devices\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 \cf0 \ -\b Update 0.11: 10/01/2012\ +\f0\b Update 0.11: 10/01/2012\ -\b0 \ +\f1\b0 \ This update includes:\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls9\ilvl0\cf0 {\listtext \'95 }Temporary Lion fix (thanks to "codeman38")\ -{\listtext \'95 }Adjustment to the automatic device match function\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls23\ilvl0\cf0 {\listtext \uc0\u8226 }Temporary Lion fix (thanks to "codeman38")\ +{\listtext \uc0\u8226 }Adjustment to the automatic device match function\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 \cf0 \ -\b Update 0.10: 8/05/2011\ +\f0\b Update 0.10: 8/05/2011\ -\b0 \ +\f1\b0 \ This update includes:\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls10\ilvl0\cf0 {\listtext \'95 }Various bugfixes\ -{\listtext \'95 }New product IDs for Wireless Gaming Receiver\ -{\listtext \'95 }Automatic device match function, allowing you to select and deselect which controllers you want it to match with\ -{\listtext \'95 }Fix the incompatibility with Bioshock introduced with ChatPad support\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls24\ilvl0\cf0 {\listtext \uc0\u8226 }Various bugfixes\ +{\listtext \uc0\u8226 }New product IDs for Wireless Gaming Receiver\ +{\listtext \uc0\u8226 }Automatic device match function, allowing you to select and deselect which controllers you want it to match with\ +{\listtext \uc0\u8226 }Fix the incompatibility with Bioshock introduced with ChatPad support\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 \cf0 \ -\b Update 0.09: 21/11/2009\ +\f0\b Update 0.09: 21/11/2009\ -\b0 \ +\f1\b0 \ This update includes:\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls11\ilvl0\cf0 {\listtext \'95 }Driver rearchitecture\ -{\listtext \'95 }ChatPad support in wired controller\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls25\ilvl0\cf0 {\listtext \uc0\u8226 }Driver rearchitecture\ +{\listtext \uc0\u8226 }ChatPad support in wired controller\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 -\b \cf0 \ +\f0\b \cf0 \ Update 0.08: 10/09/2009\ -\b0 \ +\f1\b0 \ This update includes:\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls12\ilvl0\cf0 {\listtext \'95 }64-bit support (untested)\ -{\listtext \'95 }Fix for Snow Leopard\ -{\listtext \'95 }Minor bugfixes\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls26\ilvl0\cf0 {\listtext \uc0\u8226 }64-bit support (untested)\ +{\listtext \uc0\u8226 }Fix for Snow Leopard\ +{\listtext \uc0\u8226 }Minor bugfixes\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 \cf0 \ -\b Update 0.07: 16/12/2007\ +\f0\b Update 0.07: 16/12/2007\ -\b0 \ +\f1\b0 \ This update includes:\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls13\ilvl0\cf0 {\listtext \'95 }10.4 bugfix\ -{\listtext \'95 }Extra controller IDs\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls27\ilvl0\cf0 {\listtext \uc0\u8226 }10.4 bugfix\ +{\listtext \uc0\u8226 }Extra controller IDs\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 \cf0 \ -\b Update 0.06: 10/11/2007 -\b0 \ +\f0\b Update 0.06: 10/11/2007 +\f1\b0 \ \ This update includes:\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls14\ilvl0\cf0 {\listtext \'95 }Improvements to the wireless support\ -{\listtext \'95 }Daemon providing persistent settings and LED setting\ -{\listtext \'95 }Bugfix to support Halo\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls28\ilvl0\cf0 {\listtext \uc0\u8226 }Improvements to the wireless support\ +{\listtext \uc0\u8226 }Daemon providing persistent settings and LED setting\ +{\listtext \uc0\u8226 }Bugfix to support Halo\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 \cf0 \ -\b Update 0.05: 21/4/2007 -\b0 \ +\f0\b Update 0.05: 21/4/2007 +\f1\b0 \ \ This update includes:\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls15\ilvl0\cf0 {\listtext \'95 }Improvements to the wireless support\ -{\listtext \'95 }New increased compatibility with games\ -{\listtext \'95 }Support for the Guitar Hero controller\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls29\ilvl0\cf0 {\listtext \uc0\u8226 }Improvements to the wireless support\ +{\listtext \uc0\u8226 }New increased compatibility with games\ +{\listtext \uc0\u8226 }Support for the Guitar Hero controller\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 \cf0 \ -\b Update 0.04: 27/2/2007\ +\f0\b Update 0.04: 27/2/2007\ -\b0 \ +\f1\b0 \ This update includes:\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls16\ilvl0\cf0 {\listtext \'95 }Driver for the Microsoft Wireless Gaming Receiver for Windows\ -{\listtext \'95 }Driver for the above to use the Wireless 360 Controller\ -{\listtext \'95 }Updates to the Preference Pane to support the Wireless 360 Controller\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls30\ilvl0\cf0 {\listtext \uc0\u8226 }Driver for the Microsoft Wireless Gaming Receiver for Windows\ +{\listtext \uc0\u8226 }Driver for the above to use the Wireless 360 Controller\ +{\listtext \uc0\u8226 }Updates to the Preference Pane to support the Wireless 360 Controller\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 \cf0 \ -\b Update 0.03: 22/7/2006\ +\f0\b Update 0.03: 22/7/2006\ -\b0 \ +\f1\b0 \ This update includes:\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls17\ilvl0\cf0 {\listtext \'95 }More 3rd party vendor/product IDs\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls31\ilvl0\cf0 {\listtext \uc0\u8226 }More 3rd party vendor/product IDs\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 \cf0 \ -\b Update 0.02: 11/2/2006 -\b0 \ +\f0\b Update 0.02: 11/2/2006 +\f1\b0 \ \ This update includes:\ -\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural -\ls18\ilvl0\cf0 {\listtext \'95 }Universal binaries, for Intel Mac support\ -{\listtext \'95 }Additional 3rd party vendor/product IDs (support for matching on interface instead of IDs still isn't working)\ -{\listtext \'95 }Preference Pane now correctly detects devices being connected/disconnected\ -{\listtext \'95 }Alternative deadzone mode\ -{\listtext \'95 }D-pad moved from pointer to plain joypad buttons, for better support in games\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural +\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0 +\ls32\ilvl0\cf0 {\listtext \uc0\u8226 }Universal binaries, for Intel Mac support\ +{\listtext \uc0\u8226 }Additional 3rd party vendor/product IDs (support for matching on interface instead of IDs still isn't working)\ +{\listtext \uc0\u8226 }Preference Pane now correctly detects devices being connected/disconnected\ +{\listtext \uc0\u8226 }Alternative deadzone mode\ +{\listtext \uc0\u8226 }D-pad moved from pointer to plain joypad buttons, for better support in games\ +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 \cf0 \ Please visit {\field{\*\fldinst{HYPERLINK "http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller/OsxDriver"}}{\fldrslt http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller/OsxDriver}} for information on this software. Consider donating or buying via the Amazon associate links to support development of this driver!\ \ -\b Update: -\b0 Since the version 0.13 you can find new releases of this software here: {\field{\*\fldinst{HYPERLINK "https://github.com/d235j/360Controller/releases/"}}{\fldrslt https://github.com/d235j/360Controller/releases/}} , this is a fork of the driver initially developed by TattieBogle.\ +\f0\b Update: +\f1\b0 Since the version 0.13 you can find new releases of this software here: {\field{\*\fldinst{HYPERLINK "https://github.com/360Controller/360Controller/releases/"}}{\fldrslt https://github.com/360Controller/360Controller/releases/}} , this is a fork of the driver initially developed by TattieBogle.\ \ Ensure to read the following Read Me and License sections before installing!} \ No newline at end of file diff --git a/Install360Controller/makedmg.sh b/Install360Controller/makedmg.sh index 63f35c5a..3ad3cb1d 100755 --- a/Install360Controller/makedmg.sh +++ b/Install360Controller/makedmg.sh @@ -1,2 +1,3 @@ #!/bin/sh -hdiutil create -volname 360ControllerInstall -srcfolder ./build -ov -format UDZO 360ControllerInstall.dmg \ No newline at end of file + +hdiutil create -volname 360ControllerInstall -srcfolder ./build -ov -fs HFS+ -format UDZO 360ControllerInstall.dmg diff --git a/Install360Controller/notarize.sh b/Install360Controller/notarize.sh new file mode 100755 index 00000000..1461836e --- /dev/null +++ b/Install360Controller/notarize.sh @@ -0,0 +1,9 @@ +#!/bin/sh +DEV_EMAIL=`echo | grep DEVELOPER_EMAIL ../DeveloperSettings.xcconfig` +NOTARIZATION_PASSWORD=`echo | grep NOTARIZATION_PASSWORD ../DeveloperSettings.xcconfig` +DMG_NAME=`echo | ls | grep '360ControllerInstall.*.dmg'` +USERNAME="${DEV_EMAIL//\DEVELOPER_EMAIL = }" +PASSWORD="${NOTARIZATION_PASSWORD//\NOTARIZATION_PASSWORD = }" + +xcrun altool --notarize-app --primary-bundle-id "com.mice.driver" --username ${USERNAME} --password ${PASSWORD} --file ${DMG_NAME} + diff --git a/Install360Controller/staple.sh b/Install360Controller/staple.sh new file mode 100755 index 00000000..87f6019b --- /dev/null +++ b/Install360Controller/staple.sh @@ -0,0 +1,5 @@ +#!/bin/sh +DMG_NAME=`echo | ls | grep '360ControllerInstall.*.dmg'` +xcrun stapler staple ${DMG_NAME} +xcrun stapler validate ${DMG_NAME} + diff --git a/Pref360Control/DeviceItem.h b/Pref360Control/DeviceItem.h index 748f1ee2..922c03d8 100644 --- a/Pref360Control/DeviceItem.h +++ b/Pref360Control/DeviceItem.h @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + DeviceItem.h - declaration of wrapper class for device handles - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -26,9 +26,11 @@ #include #include #include +#import "Pref360ControlPref.h" @interface DeviceItem : NSObject -@property (strong, readonly) NSString *name; +@property (strong, readonly) NSString *displayName; +@property (readonly) ControllerType controllerType; @property (readonly) io_service_t rawDevice; @property (readonly) FFDeviceObjectReference ffDevice; @property (readonly) IOHIDDeviceInterface122 **hidDevice; diff --git a/Pref360Control/DeviceItem.m b/Pref360Control/DeviceItem.m index 4f38f0a9..9f0d7d63 100644 --- a/Pref360Control/DeviceItem.m +++ b/Pref360Control/DeviceItem.m @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + DeviceItem.m - implementation of device wrapper class - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -27,7 +27,7 @@ CFMutableDictionaryRef serviceProperties; NSDictionary *properties; NSString *deviceName = nil; - + if (IORegistryEntryCreateCFProperties(device, &serviceProperties, kCFAllocatorDefault, kNilOptions) != KERN_SUCCESS) return nil; properties = CFBridgingRelease(serviceProperties); @@ -37,15 +37,56 @@ return deviceName; } +static ControllerType GetControllerType(io_service_t device) +{ + io_service_t parent; + CFMutableDictionaryRef serviceProperties; + + // Check for the DeviceData dictionary in device + if (IORegistryEntryCreateCFProperties(device, &serviceProperties, kCFAllocatorDefault, kNilOptions) == KERN_SUCCESS) + { + NSDictionary *properties = CFBridgingRelease(serviceProperties); + NSDictionary *deviceData = properties[@"DeviceData"]; + + if (deviceData != nil) + { + NSNumber *controllerType = deviceData[@"ControllerType"]; + if (controllerType != nil) + return (ControllerType)[controllerType intValue]; + } + } + + // Check for the DeviceData dictionary in the device's parent + if (IORegistryEntryGetParentEntry(device, kIOServicePlane, &parent) == KERN_SUCCESS) + { + if(IORegistryEntryCreateCFProperties(parent, &serviceProperties, kCFAllocatorDefault, kNilOptions) == KERN_SUCCESS) + { + NSDictionary *properties = CFBridgingRelease(serviceProperties); + NSDictionary *deviceData = properties[@"DeviceData"]; + + if (deviceData != nil) + { + NSNumber *controllerType = deviceData[@"ControllerType"]; + if (controllerType != nil) + return (ControllerType)[controllerType intValue]; + } + } + } + + NSLog(@"Error: couldn't find ControllerType"); + return Xbox360Controller; +} + @interface DeviceItem () -@property (strong, readwrite) NSString *name; +@property (strong, readwrite) NSString *deviceName; +@property (readwrite) ControllerType controllerType; @property (readwrite) io_service_t rawDevice; @property (readwrite) FFDeviceObjectReference ffDevice; @property (readwrite) IOHIDDeviceInterface122 **hidDevice; @end @implementation DeviceItem -@synthesize name = deviceName; +@synthesize controllerType = controllerType; @synthesize rawDevice = deviceHandle; @synthesize ffDevice = forceFeedback; @synthesize hidDevice = interface; @@ -56,7 +97,7 @@ - (instancetype)initWithItemForDevice:(io_service_t)device IOReturn ret; IOCFPlugInInterface **plugInInterface; SInt32 score=0; - + ret = IOCreatePlugInInterfaceForService(device, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); if (ret != kIOReturnSuccess) { return nil; @@ -69,7 +110,8 @@ - (instancetype)initWithItemForDevice:(io_service_t)device forceFeedback = 0; FFCreateDevice(device, &forceFeedback); self.rawDevice = device; - self.name = GetDeviceName(device); + self.deviceName = GetDeviceName(device); + self.controllerType = GetControllerType(device); } return self; } @@ -77,10 +119,10 @@ - (instancetype)initWithItemForDevice:(io_service_t)device + (instancetype)allocateDeviceItemForDevice:(io_service_t)device { DeviceItem *item = [[[self class] alloc] initWithItemForDevice:device]; - + if (item) return item; - + IOObjectRelease(device); return nil; } @@ -95,4 +137,11 @@ - (void)dealloc FFReleaseDevice(forceFeedback); } +- (NSString *)displayName { + if (self.deviceName == nil) + return @"Generic Controller"; + else + return self.deviceName; +} + @end diff --git a/Pref360Control/DeviceLister.h b/Pref360Control/DeviceLister.h index 8eb32839..b553cc1e 100644 --- a/Pref360Control/DeviceLister.h +++ b/Pref360Control/DeviceLister.h @@ -1,21 +1,21 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + DeviceLister.h - decleration of a class to display supported devices - + This file is part of Xbox360Controller. - + Xbox360Controller is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + Xbox360Controller is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/Pref360Control/DeviceLister.m b/Pref360Control/DeviceLister.m index 9cb8c89b..5e781985 100644 --- a/Pref360Control/DeviceLister.m +++ b/Pref360Control/DeviceLister.m @@ -1,21 +1,21 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + DeviceLister.m - implementation of a class to list supported devices - + This file is part of Xbox360Controller. - + Xbox360Controller is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + Xbox360Controller is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA @@ -33,7 +33,7 @@ static id GetDeviceValue(io_service_t device, NSString *key) { CFTypeRef value = IORegistryEntrySearchCFProperty(device, kIOServicePlane, (__bridge CFStringRef)key, kCFAllocatorDefault, kIORegistryIterateRecursively); - + return CFBridgingRelease(value); } @@ -42,7 +42,7 @@ static id GetDeviceValue(io_service_t device, NSString *key) { NSMutableString *output = [[NSMutableString alloc] initWithCapacity:100]; NSInteger i; - + for (i = 0; i < [name length]; i++) { unichar c = [name characterAtIndex:i]; @@ -62,7 +62,7 @@ static id GetDeviceValue(io_service_t device, NSString *key) IOUSBDeviceInterface **dev; IOReturn err; SInt32 score; - + if ((IOCreatePlugInInterfaceForService(device, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &iodev, &score) == kIOReturnSuccess) && (iodev != NULL)) { err = (*iodev)->QueryInterface(iodev, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID)&dev); @@ -80,7 +80,7 @@ static id GetDeviceValue(io_service_t device, NSString *key) IOUSBInterfaceInterface **intf; IOReturn err; SInt32 score; - + if ((IOCreatePlugInInterfaceForService(interface, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &iodev, &score) == kIOReturnSuccess) && (iodev != NULL)) { err = (*iodev)->QueryInterface(iodev, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOID)&intf); @@ -104,17 +104,17 @@ static id GetDeviceValue(io_service_t device, NSString *key) }; // Detect if an IO service object is a Microsoft controller by running through and checking some things -static BOOL IsXBox360Controller(io_service_t device) +static BOOL IsXbox360Controller(io_service_t device) { IOUSBDeviceInterface **interface = GetDeviceInterface(device); IOUSBFindInterfaceRequest iRq; io_iterator_t iterator; io_service_t devInterface; IOUSBInterfaceInterface **interfaceInterface; - + int interfaceCount; UInt8 interfaceNum, classNum, subClassNum, protocolNum, endpointCount; - + BOOL devValid; // Get the interface to the device @@ -124,7 +124,7 @@ static BOOL IsXBox360Controller(io_service_t device) (*interface)->GetDeviceSubClass(interface, &subClassNum); (*interface)->GetDeviceProtocol(interface, &protocolNum); devValid = (classNum == 0xFF) && (subClassNum == 0xFF) && (protocolNum == 0xFF); - + // Search the interfaces iRq.bInterfaceClass = kIOUSBFindInterfaceDontCare; iRq.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; @@ -160,10 +160,10 @@ static BOOL IsXBox360Controller(io_service_t device) } IOObjectRelease(iterator); } - + // Done (*interface)->Release(interface); - + return devValid && (interfaceCount >= 3); // Only 3 in case the security descriptor is missing? } @@ -213,32 +213,32 @@ - (NSString*)readTool NSData *data; NSString *response; NSArray *lines; - + // Prepare to run the tool task = [[NSTask alloc] init]; [task setLaunchPath:[self toolPath]]; - + // Hook up the pipe to catch the output pipe = [NSPipe pipe]; [task setStandardOutput:pipe]; error = [NSPipe pipe]; [task setStandardError:error]; - + // Run the tool [task launch]; [task waitUntilExit]; - + // Check result if ([task terminationStatus] != 0) { data = [[error fileHandleForReading] readDataToEndOfFile]; return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; } - + // Read the data back data = [[pipe fileHandleForReading] readDataToEndOfFile]; response = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - + // Parse the results lines = [response componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; for (NSString *line in lines) @@ -253,7 +253,7 @@ - (NSString*)readTool if (entries[key] == nil) entries[key] = SanitiseName(values[0]); } - + return nil; } @@ -262,7 +262,7 @@ - (NSString*)readKnownDevices { NSDictionary *known; NSArray *keys; - + known = GetKnownDevices(); keys = [known allKeys]; for (NSNumber *key in keys) @@ -278,27 +278,27 @@ - (NSString*)readIOKit { io_iterator_t iterator = 0; io_service_t object; - + IOServiceGetMatchingServices([owner masterPort], IOServiceMatching(kIOUSBDeviceClassName), &iterator); if (iterator != 0) { while ((object = IOIteratorNext(iterator)) != 0) { - if (IsXBox360Controller(object)) + if (IsXbox360Controller(object)) { NSNumber *vendorValue, *productValue; UInt16 vendor,product; - + vendorValue = GetDeviceValue(object, @"idVendor"); vendor = [vendorValue intValue]; - + productValue = GetDeviceValue(object, @"idProduct"); product = [productValue intValue]; - + if ((vendorValue != nil) && (productValue != nil)) { NSNumber *key = @((UInt32)((vendor << 16) | product)); - + [connected addObject:key]; if (entries[key] == nil) { @@ -331,12 +331,12 @@ - (void)showFailure:(NSString*)message - (BOOL)loadDevices { NSString *error; - + // Initialise [entries removeAllObjects]; [connected removeAllObjects]; [enabled removeAllObjects]; - + // These can be done in any order, depending on the behaviour desired if (error == nil) error = [self readKnownDevices]; @@ -344,14 +344,14 @@ - (BOOL)loadDevices error = [self readTool]; if (error == nil) error = [self readIOKit]; - + // Check for errors if (error != nil) { [self showFailure:error]; return NO; } - + // Done SetKnownDevices(entries); [list reloadData]; @@ -365,7 +365,7 @@ - (BOOL)trySave OSStatus status; AuthorizationRef authorisationRef; BOOL success = NO; - + status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, @@ -375,7 +375,7 @@ - (BOOL)trySave [self showFailure:Three60LocalizedString(@"Unable to create authorisation request", @"")]; return NO; } - + AuthorizationItem right = {kAuthorizationRightExecute, 0, NULL, 0}; AuthorizationRights rights = {1, &right}; status = AuthorizationCopyRights(authorisationRef, @@ -388,16 +388,16 @@ - (BOOL)trySave [self showFailure:Three60LocalizedString(@"Unable to acquire authorisation", @"")]; goto fail; } - + status = [self writeToolWithAuthorisation:authorisationRef]; if (status != errAuthorizationSuccess) { [self showFailure:Three60LocalizedString(@"Failed to execute the driver tool", @"")]; goto fail; } - + success = YES; - + fail: AuthorizationFree(authorisationRef, kAuthorizationFlagDestroyRights); return success; @@ -430,7 +430,7 @@ - (NSArray*)allEntries NSNumber *str2 = obj2; UInt32 num1 = str1.unsignedIntValue; UInt32 num2 = str2.unsignedIntValue; - + NSComparisonResult retval; if (num1 > num2) { retval = NSOrderedAscending; @@ -460,7 +460,7 @@ - (id)tableView:(NSTableView*)aTableView objectValueForTableColumn:(NSTableColum if ([identifier compare:@"name"] == NSOrderedSame) { NSColor *colour; - + if ([connected containsObject:key]) colour = [NSColor blueColor]; else diff --git a/Pref360Control/Info.plist b/Pref360Control/Info.plist index 1d69d937..b23cea4a 100644 --- a/Pref360Control/Info.plist +++ b/Pref360Control/Info.plist @@ -11,7 +11,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - XBox 360 Controllers + Xbox 360 Controllers CFBundlePackageType BNDL CFBundleShortVersionString @@ -21,7 +21,7 @@ CFBundleVersion ${CURRENT_PROJECT_VERSION} LSMinimumSystemVersion - ${MACOSX_DEPLOYMENT_TARGET} + ${MIN_MACOS_VERSION} NSMainNibFile Pref360ControlPref NSPrefPaneIconFile diff --git a/Pref360Control/MyAnalogStick.h b/Pref360Control/MyAnalogStick.h index 047eb4bd..dd76df88 100644 --- a/Pref360Control/MyAnalogStick.h +++ b/Pref360Control/MyAnalogStick.h @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + MyAnalogStick.h - declaration of analog stick view - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify diff --git a/Pref360Control/MyAnalogStick.m b/Pref360Control/MyAnalogStick.m index 37299976..c1538bf6 100644 --- a/Pref360Control/MyAnalogStick.m +++ b/Pref360Control/MyAnalogStick.m @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + MyAnalogStick.m - implementation of analog stick view - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -50,12 +50,12 @@ - (void)setDeadzone:(int)adeadzone - (void)setPositionX:(int)positionX { x = positionX; - + if (normalized) { const UInt16 max16 = 32767; float maxVal = max16 - deadzone; - + if (x > 0) realX = (abs(x) * maxVal / max16) + deadzone + 1; else if (x < 0) @@ -67,19 +67,19 @@ - (void)setPositionX:(int)positionX { realX = 0; } - + self.needsDisplay = YES; } - (void)setPositionY:(int)positionY { y = positionY; - + if (normalized) { const UInt16 max16 = 32767; float maxVal = max16 - deadzone; - + if (y > 0) realY = (abs(y) * maxVal / max16) + deadzone + 1; else if (y < 0) @@ -91,7 +91,7 @@ - (void)setPositionY:(int)positionY { realY = 0; } - + self.needsDisplay = YES; } @@ -109,7 +109,7 @@ - (void)setLinked:(BOOL)alinked - (void)drawRect:(NSRect)rect { NSRect area = [self bounds], deadRect, posRect, realPosRect; - + // Compute positions // Deadzone deadRect.size.width = (deadzone * area.size.width) / 32768; @@ -131,7 +131,7 @@ - (void)drawRect:(NSRect)rect // Draw pressed state if(pressed) { NSRect pressArea; - + pressArea=area; pressArea.origin.x += PRESSED_INSET; pressArea.origin.y += PRESSED_INSET; @@ -146,7 +146,7 @@ - (void)drawRect:(NSRect)rect if (linked) NSFrameRect(deadRect); else { NSRect trueRect; - + trueRect = deadRect; trueRect.origin.x = area.origin.x; trueRect.size.width = area.size.width; diff --git a/Pref360Control/MyBatteryMonitor.h b/Pref360Control/MyBatteryMonitor.h index e46a4070..87013dba 100644 --- a/Pref360Control/MyBatteryMonitor.h +++ b/Pref360Control/MyBatteryMonitor.h @@ -10,5 +10,6 @@ @interface MyBatteryMonitor : NSView @property (nonatomic) int bars; +@property (nonatomic) int percentage; @end diff --git a/Pref360Control/MyBatteryMonitor.m b/Pref360Control/MyBatteryMonitor.m index 06ae33eb..2d8884fd 100644 --- a/Pref360Control/MyBatteryMonitor.m +++ b/Pref360Control/MyBatteryMonitor.m @@ -15,10 +15,15 @@ - (void)setBars:(int)value { [self setNeedsDisplay:YES]; } +- (void)setPercentage:(int)value { + _percentage = value; + [self setNeedsDisplay:YES]; +} + - (void)drawRect:(NSRect)dirtyRect { [super drawRect:dirtyRect]; - - [Pref360StyleKit drawBatteryMonitorWithBars:_bars]; + + [Pref360StyleKit drawBatteryMonitorWithBars:_bars andPercentage:_percentage]; } @end diff --git a/Pref360Control/MyCentreButtons.h b/Pref360Control/MyCentreButtons.h index f149d7f3..52a8927a 100644 --- a/Pref360Control/MyCentreButtons.h +++ b/Pref360Control/MyCentreButtons.h @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + MyCentreButtons.h - definition of view to draw the central buttons - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify diff --git a/Pref360Control/MyCentreButtons.m b/Pref360Control/MyCentreButtons.m index 705b261f..3bef7623 100644 --- a/Pref360Control/MyCentreButtons.m +++ b/Pref360Control/MyCentreButtons.m @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + MyCentreButtons.m - implementation of central button view - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -53,7 +53,7 @@ + (void)drawButton:(NSString*)button inRectangle:(NSRect)rect pressed:(BOOL)down NSDictionary *attributes; NSPoint point; NSColor *colour = [NSColor blackColor]; - + // Draw circle [colour set]; if(down) { diff --git a/Pref360Control/MyDeadZoneViewer.m b/Pref360Control/MyDeadZoneViewer.m index 383693cf..0812c27d 100644 --- a/Pref360Control/MyDeadZoneViewer.m +++ b/Pref360Control/MyDeadZoneViewer.m @@ -22,7 +22,7 @@ - (void)setLinked:(BOOL)linked { - (void)drawRect:(NSRect)dirtyRect { [super drawRect:dirtyRect]; - + [Pref360StyleKit drawDeadZoneViewerWithValue:_val / 32768 linked:_linked]; } diff --git a/Pref360Control/MyDigitalStick.h b/Pref360Control/MyDigitalStick.h index ceeb0789..d647a063 100644 --- a/Pref360Control/MyDigitalStick.h +++ b/Pref360Control/MyDigitalStick.h @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + MyDigitalStick.h - declaration of view to draw digital stick view - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify diff --git a/Pref360Control/MyDigitalStick.m b/Pref360Control/MyDigitalStick.m index 258301a1..2bd8a20b 100644 --- a/Pref360Control/MyDigitalStick.m +++ b/Pref360Control/MyDigitalStick.m @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + MyDigitalStick.m - implementation of digital stick view - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -70,7 +70,7 @@ + (NSBezierPath*)makeTriangle:(int)start inRectangle:(NSRect)rect; {0,1}, {0,0} }; - + // Find central part centre.x = rect.origin.x + (rect.size.width / 2); centre.y = rect.origin.y + (rect.size.height / 2); @@ -91,7 +91,7 @@ - (id)initWithFrame:(NSRect)frameRect { if ((self = [super initWithFrame:frameRect]) != nil) { NSRect rect = [self bounds], triangle; - + triangle.origin.x = INSET_AMOUNT; triangle.origin.y = INSET_AMOUNT; triangle.size.width =- INSET_AMOUNT * 2; @@ -115,7 +115,7 @@ - (id)initWithFrame:(NSRect)frameRect - (void)drawRect:(NSRect)rect { NSRect area = [self bounds]; - + NSDrawLightBezel(area, area); [[NSColor blackColor] set]; if (bUp) [up fill]; diff --git a/Pref360Control/MyMainButtons.h b/Pref360Control/MyMainButtons.h index 765294cc..8e12ca5e 100644 --- a/Pref360Control/MyMainButtons.h +++ b/Pref360Control/MyMainButtons.h @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + MyMainButtons.h - declaration of A/B/X/Y button view - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify diff --git a/Pref360Control/MyMainButtons.m b/Pref360Control/MyMainButtons.m index 3fc9ba88..f69bd5af 100644 --- a/Pref360Control/MyMainButtons.m +++ b/Pref360Control/MyMainButtons.m @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + MyMainButtons.m - implementation of A/B/X/Y button view - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -62,7 +62,7 @@ + (void)drawButton:(NSString*)button inRectangle:(NSRect)rect pressed:(BOOL)down NSPoint point; NSColor *colour = [NSColor blackColor]; NSRect bling = rect; - + // Draw circle if(down) { [path fill]; @@ -87,7 +87,7 @@ + (void)drawButton:(NSString*)button inRectangle:(NSRect)rect pressed:(BOOL)down - (void)drawRect:(NSRect)rect { NSRect area = [self bounds], bit; - + bit.size.width = area.size.width / 3; bit.size.height = area.size.height / 3; bit.origin.x = area.origin.x + bit.size.width; diff --git a/Pref360Control/MyShoulderButton.h b/Pref360Control/MyShoulderButton.h index af173178..527c6324 100644 --- a/Pref360Control/MyShoulderButton.h +++ b/Pref360Control/MyShoulderButton.h @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + MyShoulderButton.h - simple button view declaration - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify diff --git a/Pref360Control/MyShoulderButton.m b/Pref360Control/MyShoulderButton.m index d4f62c53..cdc5397a 100644 --- a/Pref360Control/MyShoulderButton.m +++ b/Pref360Control/MyShoulderButton.m @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + MyShoulderButton.m - implementation of simple button view - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -36,7 +36,7 @@ - (void)setPressed:(BOOL)apressed - (void)drawRect:(NSRect)rect { NSRect area = [self bounds]; - + NSDrawLightBezel(area, area); if (pressed) { area.origin.x += INSET_AMOUNT; diff --git a/Pref360Control/MyTrigger.m b/Pref360Control/MyTrigger.m index def691fd..53653d6b 100644 --- a/Pref360Control/MyTrigger.m +++ b/Pref360Control/MyTrigger.m @@ -23,7 +23,7 @@ - (void)setVal:(int)value { - (void)drawRect:(NSRect)dirtyRect { [super drawRect:dirtyRect]; - + if (_name == NULL) _name = @""; [Pref360StyleKit drawTriggerMetterWithIntensity:(_val / 255.0) triggerTitle:_name]; diff --git a/Pref360Control/MyWhole360Controller.m b/Pref360Control/MyWhole360Controller.m index ee29bc4d..bda7756d 100644 --- a/Pref360Control/MyWhole360Controller.m +++ b/Pref360Control/MyWhole360Controller.m @@ -171,7 +171,7 @@ - (void)awakeFromNib { - (void)drawRect:(NSRect)dirtyRect { [super drawRect:dirtyRect]; - + [Pref360StyleKit drawX360ControllerWithControllerNumber:0 aPressed:_aPressed bPressed:_bPressed xPressed:_xPressed yPressed:_yPressed leftPressed:_leftPressed upPressed:_upPressed rightPressed:_rightPressed downPressed:_downPressed backPressed:_backPressed startPressed:_startPressed lbPressed:_lbPressed rbPressed:_rbPressed homePressed:_homePressed leftStickPressed:_leftStickPressed rightStickPressed:_rightStickPressed leftStick:_leftStickPosition rightStick:_rightStickPosition leftStickDeadzone:_leftStickDeadzone rightStickDeadzone:_rightStickDeadzone isLeftNormalized:_leftNormalized isRightNormalized:_rightNormalized]; } diff --git a/Pref360Control/MyWhole360ControllerMapper.h b/Pref360Control/MyWhole360ControllerMapper.h index f144c23d..d8227adf 100644 --- a/Pref360Control/MyWhole360ControllerMapper.h +++ b/Pref360Control/MyWhole360ControllerMapper.h @@ -14,8 +14,10 @@ @property BOOL isMapping; -- (void)runMapperWithButton:(NSButton *)button andOwner:(Pref360ControlPref *)pref; +- (void)runMapperWithButton:(NSButton *)button andOwner:(Pref360ControlPref *)pref; +- (void)cancelMappingWithButton:(NSButton *)button andOwner:(Pref360ControlPref *)pref; +- (void)resetWithOwner:(Pref360ControlPref *)pref; - (void)buttonPressedAtIndex:(int)index; + (UInt8 *)mapping; -@end \ No newline at end of file +@end diff --git a/Pref360Control/MyWhole360ControllerMapper.m b/Pref360Control/MyWhole360ControllerMapper.m index 336a650b..0c8b8bb9 100644 --- a/Pref360Control/MyWhole360ControllerMapper.m +++ b/Pref360Control/MyWhole360ControllerMapper.m @@ -18,22 +18,61 @@ @implementation MyWhole360ControllerMapper } static UInt8 mapping[15]; +static UInt8 previousMapping[15]; + (UInt8 *)mapping { return mapping; } -- (void)runMapperWithButton:(NSButton *)button andOwner:(Pref360ControlPref *)prefPref { - pref = prefPref; - remappingButton = button; -// [self resetMapping]; -// [pref changeSetting:nil]; +- (void)startMapping +{ currentMappingIndex = 0; _isMapping = YES; [self setUpPressed:YES]; } +- (void)stopMapping +{ + [super reset]; + currentMappingIndex = 0; + _isMapping = NO; + if (remappingButton != nil) + [remappingButton setState:NSOffState]; + [pref changeSetting:nil]; + [[BindingTableView tableView] reloadData]; + [pref changeSetting:nil]; +} + +- (void)saveCurrentMapping { + for (int i = 0; i < 15; i++) { + previousMapping[i] = mapping[i]; + } +} + +- (void)restorePreviousMapping { + for (int i = 0; i < 15; i++) { + mapping[i] = previousMapping[i]; + } +} + +- (void)runMapperWithButton:(NSButton *)button andOwner:(Pref360ControlPref *)prefPref { + pref = prefPref; + remappingButton = button; + [self saveCurrentMapping]; + [self resetMapping]; + [pref changeSetting:nil]; + [self startMapping]; +} + +- (void)cancelMappingWithButton:(NSButton *)button andOwner:(Pref360ControlPref *)prefPref { + pref = prefPref; + remappingButton = button; + + [self restorePreviousMapping]; + [self stopMapping]; +} + - (int)realignButtonToByte:(int)index { if (index == 0) return 12; if (index == 1) return 13; @@ -57,13 +96,8 @@ - (void)buttonPressedAtIndex:(int)index { mapping[currentMappingIndex] = [self realignButtonToByte:index]; currentMappingIndex++; [self setButtonAtIndex:currentMappingIndex]; - if (currentMappingIndex == 15) { - _isMapping = NO; - currentMappingIndex = 0; - [remappingButton setState:NSOffState]; - [[BindingTableView tableView] reloadData]; - [pref changeSetting:nil]; - } + if (currentMappingIndex == 15) + [self stopMapping]; } - (void)setButtonAtIndex:(int)index { @@ -72,76 +106,76 @@ - (void)setButtonAtIndex:(int)index { [self setUpPressed:NO]; [self setDownPressed:YES]; break; - + case 2: [self setDownPressed:NO]; [self setLeftPressed:YES]; break; - + case 3: [self setLeftPressed:NO]; [self setRightPressed:YES]; break; - + case 4: [self setRightPressed:NO]; [self setStartPressed:YES]; break; - + case 5: [self setStartPressed:NO]; [self setBackPressed:YES]; break; - + case 6: [self setBackPressed:NO]; [self setLeftStickPressed:YES]; break; - + case 7: [self setLeftStickPressed:NO]; [self setRightStickPressed:YES]; break; - + case 8: [self setRightStickPressed:NO]; [self setLbPressed:YES]; break; - + case 9: [self setLbPressed:NO]; [self setRbPressed:YES]; break; - + case 10: [self setRbPressed:NO]; [self setHomePressed:YES]; break; - + case 11: [self setHomePressed:NO]; [self setAPressed:YES]; break; - + case 12: [self setAPressed:NO]; [self setBPressed:YES]; break; - + case 13: [self setBPressed:NO]; [self setXPressed:YES]; break; - + case 14: [self setXPressed:NO]; [self setYPressed:YES]; break; - + case 15: [self setYPressed:NO]; break; - + default: break; } @@ -156,14 +190,16 @@ - (void)resetMapping { } } +- (void)resetWithOwner:(Pref360ControlPref *)prefPref { + pref = prefPref; + [self reset]; +} + - (void)reset { - [super reset]; - _isMapping = NO; + if (pref == nil) + NSLog(@"Unable to reset remapping (pref is nil)"); [self resetMapping]; - [remappingButton setState:NSOffState]; - [pref changeSetting:nil]; - [[BindingTableView tableView] reloadData]; -// [pref changeSetting:nil]; + [self stopMapping]; } - (void)awakeFromNib { @@ -173,4 +209,4 @@ - (void)awakeFromNib { [[BindingTableView tableView] reloadData]; } -@end \ No newline at end of file +@end diff --git a/Pref360Control/Pref360ControlPref.h b/Pref360Control/Pref360ControlPref.h index fc31d300..e7096000 100644 --- a/Pref360Control/Pref360ControlPref.h +++ b/Pref360Control/Pref360ControlPref.h @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + Pref360ControlPref.h - definition for the pref pane class - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -40,7 +40,9 @@ typedef NS_ENUM(NSUInteger, ControllerType) { Xbox360Controller = 0, XboxOriginalController = 1, - XboxOneController = 2 + XboxOneController = 2, + XboxOnePretend360Controller = 3, + Xbox360Pretend360Controller = 4 } controllerType; @interface Pref360ControlPref : NSPreferencePane @@ -86,12 +88,13 @@ typedef NS_ENUM(NSUInteger, ControllerType) { @property (weak) IBOutlet NSSlider *leftStickDeadzoneAlt; @property (weak) IBOutlet NSButton *leftStickInvertXAlt; @property (weak) IBOutlet NSButton *leftStickInvertYAlt; +@property (weak) IBOutlet NSButton *leftStickNormalize; @property (weak) IBOutlet NSButton *rightLinkedAlt; @property (weak) IBOutlet NSSlider *rightStickDeadzoneAlt; @property (weak) IBOutlet NSButton *rightStickInvertXAlt; @property (weak) IBOutlet NSButton *rightStickInvertYAlt; -@property (weak) IBOutlet NSButton *normalizeDeadzoneLeft; -@property (weak) IBOutlet NSButton *normalizeDeadzoneRight; +@property (weak) IBOutlet NSButton *rightStickNormalize; +@property (weak) IBOutlet NSButton *pretend360Button; // About Tab /* put About Tab's @properties here */ diff --git a/Pref360Control/Pref360ControlPref.m b/Pref360Control/Pref360ControlPref.m index 420ee220..4669940c 100644 --- a/Pref360Control/Pref360ControlPref.m +++ b/Pref360Control/Pref360ControlPref.m @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + Pref360ControlPref.m - main source of the pref pane - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -35,6 +35,18 @@ #define NO_ITEMS @"No devices found" +@interface NSLayoutConstraint (Description) + +@end + +@implementation NSLayoutConstraint (Description) + +-(NSString *)description { + return [NSString stringWithFormat:@"id: %@, constant: %f", self.identifier, self.constant]; +} + +@end + // Passes a C callback back to the Objective C class static void CallbackFunction(void *target,IOReturn result,void *refCon,void *sender) { @@ -47,12 +59,12 @@ static void callbackHandleDevice(void *param,io_iterator_t iterator) { io_service_t object = 0; BOOL update = NO; - + while ((object = IOIteratorNext(iterator))) { IOObjectRelease(object); update = YES; } - + if (update) [(__bridge Pref360ControlPref*)param handleDeviceChange]; } @@ -65,19 +77,19 @@ @implementation Pref360ControlPref @private // Internal info IOHIDElementCookie axis[6],buttons[15]; - + IOHIDDeviceInterface122 **device; IOHIDQueueInterface **hidQueue; FFDeviceObjectReference ffDevice; io_registry_entry_t registryEntry; - + int largeMotor, smallMotor; - + IONotificationPortRef notifyPort; CFRunLoopSourceRef notifySource; io_iterator_t onIteratorWired, offIteratorWired; io_iterator_t onIteratorWireless, offIteratorWireless; - + FFEFFECT *effect; FFCUSTOMFORCE *customforce; FFEffectObjectReference effectRef; @@ -88,8 +100,6 @@ -(void)awakeFromNib { [_aboutPopover setAppearance:NSPopoverAppearanceHUD]; [_rumbleOptions removeAllItems]; [_rumbleOptions addItemsWithTitles:@[@"Default", @"None"]]; - if (controllerType == XboxOneController) - [_rumbleOptions addItemsWithTitles:@[@"Triggers Only", @"Both"]]; } // Set the pattern on the LEDs @@ -97,7 +107,7 @@ - (void)updateLED:(int)ledIndex { FFEFFESCAPE escape = {0}; unsigned char c = ledIndex; - + if (ffDevice == 0) return; escape.dwSize = sizeof(escape); escape.dwCommand = 0x02; @@ -172,28 +182,28 @@ - (void)testMotorsLarge:(unsigned char)large small:(unsigned char)small - (void)axisChanged:(int)index newValue:(int)value { NSInteger tabIndex = [_tabView indexOfTabViewItem:[_tabView selectedTabViewItem]]; - + switch(index) { case 0: [_wholeController setLeftStickXPos:value]; [_leftStickAnalog setPositionX:value]; break; - + case 1: [_wholeController setLeftStickYPos:value]; [_leftStickAnalog setPositionY:value]; break; - + case 2: [_wholeController setRightStickXPos:value]; [_rightStickAnalog setPositionX:value]; break; - + case 3: [_wholeController setRightStickYPos:value]; [_rightStickAnalog setPositionY:value]; break; - + case 4: if (tabIndex == 0) { // Controller Test [_leftTrigger setVal:value]; @@ -201,7 +211,7 @@ - (void)axisChanged:(int)index newValue:(int)value [self testMotorsLarge:largeMotor small:smallMotor]; } break; - + case 5: if (tabIndex == 0) { [_rightTrigger setVal:value]; @@ -209,7 +219,7 @@ - (void)axisChanged:(int)index newValue:(int)value [self testMotorsLarge:largeMotor small:smallMotor]; } break; - + default: break; } @@ -220,69 +230,69 @@ - (void)buttonChanged:(int)index newValue:(int)value { BOOL b = (value != 0); NSInteger tabIndex = [_tabView indexOfTabViewItem:[_tabView selectedTabViewItem]]; - + if (tabIndex == 0) { // Controller Test switch (index) { case 0: [_wholeController setAPressed:b]; break; - + case 1: [_wholeController setBPressed:b]; break; - + case 2: [_wholeController setXPressed:b]; break; - + case 3: [_wholeController setYPressed:b]; break; - + case 4: [_wholeController setLbPressed:b]; break; - + case 5: [_wholeController setRbPressed:b]; break; - + case 6: [_wholeController setLeftStickPressed:b]; break; - + case 7: [_wholeController setRightStickPressed:b]; break; - + case 8: [_wholeController setStartPressed:b]; break; - + case 9: [_wholeController setBackPressed:b]; break; - + case 10: [_wholeController setHomePressed:b]; break; - + case 11: [_wholeController setUpPressed:b]; break; - + case 12: [_wholeController setDownPressed:b]; break; - + case 13: [_wholeController setLeftPressed:b]; break; - + case 14: [_wholeController setRightPressed:b]; break; - + default: break; } @@ -303,7 +313,7 @@ - (void)eventQueueFired:(void*)sender withResult:(IOReturn)result IOHIDEventStruct event; BOOL found = NO; int i; - + if (sender != hidQueue) return; while (result == kIOReturnSuccess) { result = (*hidQueue)->getNextEvent(hidQueue,&event,zeroTime,0); @@ -339,6 +349,7 @@ - (void)inputEnable:(BOOL)enable [_leftStickInvertYAlt setEnabled:enable]; [_leftLinked setEnabled:enable]; [_leftLinkedAlt setEnabled:enable]; + [_leftStickNormalize setEnabled:enable]; [_rightStickDeadzone setEnabled:enable]; [_rightStickDeadzoneAlt setEnabled:enable]; [_rightStickInvertX setEnabled:enable]; @@ -347,10 +358,10 @@ - (void)inputEnable:(BOOL)enable [_rightStickInvertYAlt setEnabled:enable]; [_rightLinked setEnabled:enable]; [_rightLinkedAlt setEnabled:enable]; - [_normalizeDeadzoneLeft setEnabled:enable]; - [_normalizeDeadzoneRight setEnabled:enable]; + [_rightStickNormalize setEnabled:enable]; [_rumbleOptions setEnabled:enable]; [_swapSticks setEnabled:enable]; + [_pretend360Button setEnabled:enable]; } // Reset GUI components @@ -396,7 +407,7 @@ - (void)stopDevice [self testMotorsCleanUp]; if (hidQueue) { CFRunLoopSourceRef eventSource; - + (*hidQueue)->stop(hidQueue); eventSource=(*hidQueue)->getAsyncEventSource(hidQueue); if((eventSource!=NULL)&&CFRunLoopContainsSource(CFRunLoopGetCurrent(),eventSource,kCFRunLoopCommonModes)) @@ -421,7 +432,7 @@ - (void)startDevice long usage,usagePage; CFRunLoopSourceRef eventSource; IOReturn ret; - + [self resetDisplay]; if(([_deviceArray count]==0)||(i==-1)) { NSLog(@"No devices found? :( device count==%i, i==%i",(int)[_deviceArray count], i); @@ -429,20 +440,21 @@ - (void)startDevice } { DeviceItem *item = _deviceArray[i]; - + device = [item hidDevice]; ffDevice = [item ffDevice]; registryEntry = [item rawDevice]; + controllerType = [item controllerType]; } - + if((*device)->copyMatchingElements(device,NULL,&CFelements)!=kIOReturnSuccess) { NSLog(@"Can't get elements list"); // Make note of failure? return; } - + NSArray *elements = CFBridgingRelease(CFelements); - + for (NSDictionary *element in elements) { id object; // Get cookie @@ -548,7 +560,7 @@ - (void)startDevice if(dict) { CFBooleanRef boolValue; CFNumberRef intValue; - + if(CFDictionaryGetValueIfPresent(dict,CFSTR("InvertLeftX"),(void*)&boolValue)) { [_leftStickInvertX setState:CFBooleanGetValue(boolValue)?NSOnState:NSOffState]; [_leftStickInvertXAlt setState:CFBooleanGetValue(boolValue)?NSOnState:NSOffState]; @@ -564,9 +576,15 @@ - (void)startDevice [_leftDeadZone setLinked:enable]; [_leftStickAnalog setLinked:enable]; } else NSLog(@"No value for RelativeLeft\n"); + if(CFDictionaryGetValueIfPresent(dict,CFSTR("DeadOffLeft"),(void*)&boolValue)) { + BOOL enable=CFBooleanGetValue(boolValue); + [_leftStickNormalize setState:enable]; + [_wholeController setLeftNormalized:enable]; + [_leftStickAnalog setNormalized:enable]; + } else NSLog(@"No value for DeadOffLeft\n"); if(CFDictionaryGetValueIfPresent(dict,CFSTR("DeadzoneLeft"),(void*)&intValue)) { UInt16 i; - + CFNumberGetValue(intValue,kCFNumberShortType,&i); [_leftStickDeadzone setIntValue:i]; [_leftStickDeadzoneAlt setIntValue:i]; @@ -590,25 +608,34 @@ - (void)startDevice [_wholeController setRightStickDeadzone:i]; [_rightStickAnalog setLinked:enable]; } else NSLog(@"No value for RelativeRight\n"); + if(CFDictionaryGetValueIfPresent(dict,CFSTR("DeadOffRight"),(void*)&boolValue)) { + BOOL enable=CFBooleanGetValue(boolValue); + [_rightStickNormalize setState:enable]; + [_wholeController setRightNormalized:enable]; + [_rightStickAnalog setNormalized:enable]; + } else NSLog(@"No value for DeadOffRight\n"); if(CFDictionaryGetValueIfPresent(dict,CFSTR("DeadzoneRight"),(void*)&intValue)) { UInt16 i; - + CFNumberGetValue(intValue,kCFNumberShortType,&i); [_rightStickDeadzone setIntValue:i]; [_rightStickDeadzoneAlt setIntValue:i]; [_rightDeadZone setVal:i]; [_rightStickAnalog setDeadzone:i]; } else NSLog(@"No value for DeadzoneRight\n"); - + if(CFDictionaryGetValueIfPresent(dict,CFSTR("ControllerType"),(void*)&intValue)) { NSNumber *num = (__bridge NSNumber *)intValue; - controllerType = (ControllerType)[num integerValue]; + ControllerType controllerTypePrefs = (ControllerType)[num integerValue]; + if (controllerTypePrefs != controllerType) + NSLog(@"ControllerType from prefs was %d, expected %d", (int)controllerTypePrefs, (int)controllerType); } else NSLog(@"No value for ControllerType\n"); if(CFDictionaryGetValueIfPresent(dict,CFSTR("RumbleType"),(void*)&intValue)) { NSNumber *num = (__bridge NSNumber *)intValue; - [_rumbleOptions setState:[num integerValue]]; + [_rumbleOptions selectItemAtIndex:[num integerValue]]; +// [_rumbleOptions setState:[num integerValue]]; } else NSLog(@"No value for RumbleType\n"); - + if(CFDictionaryGetValueIfPresent(dict,CFSTR("BindingUp"),(void*)&intValue)) { NSNumber *num = (__bridge NSNumber *)intValue; [MyWhole360ControllerMapper mapping][0] = [num intValue]; @@ -669,12 +696,29 @@ - (void)startDevice NSNumber *num = (__bridge NSNumber *)intValue; [MyWhole360ControllerMapper mapping][14] = [num intValue]; } else NSLog(@"No value for BindingY\n"); - + if(CFDictionaryGetValueIfPresent(dict,CFSTR("SwapSticks"),(void*)&boolValue)) { [_swapSticks setState:CFBooleanGetValue(boolValue)?NSOnState:NSOffState]; } else NSLog(@"No value for SwapSticks\n"); + + if(CFDictionaryGetValueIfPresent(dict,CFSTR("Pretend360"),(void*)&boolValue)) { + [_pretend360Button setState:CFBooleanGetValue(boolValue)?NSOnState:NSOffState]; + } else NSLog(@"No value for Pretend360"); } else NSLog(@"No settings found\n"); } + + // Set force feedback options + if (controllerType == XboxOneController || controllerType == XboxOnePretend360Controller) + { + [_rumbleOptions removeAllItems]; + [_rumbleOptions addItemsWithTitles:@[@"Default", @"None", @"Triggers Only", @"Both"]]; + } + else + { + [_rumbleOptions removeAllItems]; + [_rumbleOptions addItemsWithTitles:@[@"Default", @"None"]]; + } + // Enable GUI components [self inputEnable:YES]; // Set device capabilities @@ -686,32 +730,32 @@ - (void)startDevice // Battery level? { int batteryLevel = -1; + int batteryPercentage = -1; CFTypeRef prop; - + if (IOObjectConformsTo(registryEntry, "WirelessHIDDevice")) { prop = IORegistryEntryCreateCFProperty(registryEntry, CFSTR("BatteryLevel"), NULL, 0); if (prop != nil) { unsigned char level; - - if (CFNumberGetValue(prop, kCFNumberCharType, &level)) + + if (CFNumberGetValue(prop, kCFNumberCharType, &level)) { batteryLevel = level / 64; + batteryPercentage = level * 100 / 255.0f + 0.5f; + } CFRelease(prop); } [_powerOff setHidden:NO]; } if ( batteryLevel >= 0) { [_batteryStatus setBars:batteryLevel]; + [_batteryStatus setPercentage:batteryPercentage]; [_batteryStatus setHidden:NO]; } else { [_batteryStatus setHidden:YES]; } } - - [_mappingTable reloadData]; - // Allows the kext to be disabled when you connect a controller once - // FIXME: Allow disabling the driver at any time. - [self.enableDriverCheckBox setEnabled:YES]; + [_mappingTable reloadData]; } // Clear out the device lists @@ -731,7 +775,7 @@ - (void)updateDeviceList io_iterator_t iterator; io_object_t hidDevice; int count = 0; - + // Scrub old items [self stopDevice]; [self deleteDeviceList]; @@ -744,7 +788,7 @@ - (void)updateDeviceList [_deviceListAdvanced addItemWithTitle:NO_ITEMS]; return; } - + while ((hidDevice = IOIteratorNext(iterator))) { io_object_t parent = 0; IORegistryEntryGetParentEntry(hidDevice, kIOServicePlane, &parent); @@ -758,9 +802,7 @@ - (void)updateDeviceList DeviceItem *item = [DeviceItem allocateDeviceItemForDevice:hidDevice]; if (item == nil) continue; // Add to item - NSString *name = item.name; - if (name == nil) - name = @"Generic Controller"; + NSString *name = item.displayName; [_deviceList addItemWithTitle:[NSString stringWithFormat:@"%i: %@ (%@)", ++count, name, deviceWireless ? @"Wireless" : @"Wired"]]; [_deviceListBinding addItemWithTitle:[NSString stringWithFormat:@"%i: %@ (%@)", count, name, deviceWireless ? @"Wireless" : @"Wired"]]; [_deviceListAdvanced addItemWithTitle:[NSString stringWithFormat:@"%i: %@ (%@)", count, name, deviceWireless ? @"Wireless" : @"Wired"]]; @@ -779,7 +821,7 @@ - (void)updateDeviceList - (void)didSelect { io_object_t object; - + // Get master port, for accessing I/O Kit IOMasterPort(MACH_PORT_NULL,&_masterPort); // Set up notification of USB device addition/removal @@ -806,9 +848,11 @@ - (void)didSelect // TEMP: Enable the "enable driver" checkbox if the kext is loaded in the memory int result = system("kextstat | grep com.mice.driver.Xbox360Controller"); - NSLog(@"Result of kextstat = %d", result); +// NSLog(@"Result of kextstat = %d", result); if (result == 0) { - [self.enableDriverCheckBox setEnabled:YES]; + [self.enableDriverCheckBox setState:NSOnState]; + } else { + [self.enableDriverCheckBox setState:NSOffState]; } } @@ -863,7 +907,7 @@ - (IBAction)selectDevice:(id)sender [_deviceList selectItemAtIndex:[_deviceListAdvanced indexOfSelectedItem]]; [_deviceListBinding selectItemAtIndex:[_deviceListAdvanced indexOfSelectedItem]]; } - + [self startDevice]; } @@ -871,14 +915,14 @@ - (IBAction)selectDevice:(id)sender - (IBAction)changeSetting:(id)sender { // Send normalize to joysticks - [_wholeController setLeftNormalized:(BOOL)[_normalizeDeadzoneLeft state]]; - [_leftStickAnalog setNormalized:(BOOL)[_normalizeDeadzoneLeft state]]; - [_wholeController setRightNormalized:(BOOL)[_normalizeDeadzoneRight state]]; - [_rightStickAnalog setNormalized:(BOOL)[_normalizeDeadzoneRight state]]; - + [_wholeController setLeftNormalized:(BOOL)[_leftStickNormalize state]]; + [_leftStickAnalog setNormalized:(BOOL)[_leftStickNormalize state]]; + [_wholeController setRightNormalized:(BOOL)[_rightStickNormalize state]]; + [_rightStickAnalog setNormalized:(BOOL)[_rightStickNormalize state]]; + // Sync settings between tabs NSInteger tabIndex = [_tabView indexOfTabViewItem:[_tabView selectedTabViewItem]]; - + if (tabIndex == 0) { // Controller Test [_leftLinkedAlt setState:[_leftLinked state]]; [_leftStickDeadzoneAlt setDoubleValue:[_leftStickDeadzone doubleValue]]; @@ -899,7 +943,16 @@ - (IBAction)changeSetting:(id)sender [_rightStickInvertX setState:[_rightStickInvertXAlt state]]; [_rightStickInvertY setState:[_rightStickInvertYAlt state]]; } - + + BOOL pretend360 = ([_pretend360Button state] == NSOnState); + if (controllerType == XboxOneController || controllerType == XboxOnePretend360Controller) + { + if (pretend360) + controllerType = XboxOnePretend360Controller; + else + controllerType = XboxOneController; + } + // Create dictionary NSDictionary *dict = @{@"InvertLeftX": @((BOOL)([_leftStickInvertX state]==NSOnState)), @"InvertLeftY": @((BOOL)([_leftStickInvertY state]==NSOnState)), @@ -909,8 +962,8 @@ - (IBAction)changeSetting:(id)sender @"DeadzoneRight": @((UInt16)[_rightStickDeadzone doubleValue]), @"RelativeLeft": @((BOOL)([_leftLinked state]==NSOnState)), @"RelativeRight": @((BOOL)([_rightLinked state]==NSOnState)), - @"DeadOffLeft": @((BOOL)([_normalizeDeadzoneLeft state]==NSOnState)), - @"DeadOffRight": @((BOOL)([_normalizeDeadzoneRight state]==NSOnState)), + @"DeadOffLeft": @((BOOL)([_leftStickNormalize state]==NSOnState)), + @"DeadOffRight": @((BOOL)([_rightStickNormalize state]==NSOnState)), @"ControllerType": @((UInt8)(controllerType)), @"RumbleType": @((UInt8)([_rumbleOptions indexOfSelectedItem])), @"BindingUp": @((UInt8)([MyWhole360ControllerMapper mapping][0])), @@ -928,8 +981,9 @@ - (IBAction)changeSetting:(id)sender @"BindingB": @((UInt8)([MyWhole360ControllerMapper mapping][12])), @"BindingX": @((UInt8)([MyWhole360ControllerMapper mapping][13])), @"BindingY": @((UInt8)([MyWhole360ControllerMapper mapping][14])), - @"SwapSticks": @((BOOL)([_swapSticks state]==NSOnState))}; - + @"SwapSticks": @((BOOL)([_swapSticks state]==NSOnState)), + @"Pretend360": @((BOOL)pretend360)}; + // Set property IORegistryEntrySetCFProperties(registryEntry, (__bridge CFTypeRef)(dict)); SetController(GetSerialNumber(registryEntry), dict); @@ -1070,6 +1124,7 @@ - (IBAction)willPerformUninstallation:(id)sender rm -rf /Library/Extensions/360Controller.kext\n\ rm -rf /Library/Extensions/Wireless360Controller.kext\n\ rm -rf /Library/Extensions/WirelessGamingReceiver.kext\n\ + rm -rf /Library/Extensions/XboxOneBluetooth.kext\n\ rm -rf /Library/PreferencePanes/Pref360Control.prefPane\n\ pkgutil --forget com.mice.pkg.Xbox360controller\ \" with administrator privileges"; @@ -1108,7 +1163,7 @@ - (void)handleDeviceChange - (IBAction)powerOff:(id)sender { FFEFFESCAPE escape = {0}; - + if (ffDevice == 0) return; escape.dwSize=sizeof(escape); escape.dwCommand=0x03; @@ -1119,12 +1174,17 @@ - (IBAction)startRemappingPressed:(id)sender { if (![_wholeControllerMapper isMapping]) [_wholeControllerMapper runMapperWithButton:_remappingButton andOwner:self]; else - [_wholeControllerMapper reset]; + [_wholeControllerMapper cancelMappingWithButton:_remappingButton andOwner:self]; } - (IBAction)resetRemappingPressed:(id)sender { [_remappingButton setState:NSOffState]; - [_wholeControllerMapper reset]; + [_wholeControllerMapper resetWithOwner:self]; +} + +- (IBAction)pretend360Checked:(id)sender { + [self changeSetting:NULL]; + [self performSelector:@selector(updateDeviceList) withObject:nil afterDelay:0.5]; } @end diff --git a/Pref360Control/Pref360StyleKit.h b/Pref360Control/Pref360StyleKit.h index 1b1cf9b9..b85a5727 100644 --- a/Pref360Control/Pref360StyleKit.h +++ b/Pref360Control/Pref360StyleKit.h @@ -17,7 +17,7 @@ // Drawing Methods + (void)drawX360ControllerWithControllerNumber: (CGFloat)controllerNumber aPressed: (BOOL)aPressed bPressed: (BOOL)bPressed xPressed: (BOOL)xPressed yPressed: (BOOL)yPressed leftPressed: (BOOL)leftPressed upPressed: (BOOL)upPressed rightPressed: (BOOL)rightPressed downPressed: (BOOL)downPressed backPressed: (BOOL)backPressed startPressed: (BOOL)startPressed lbPressed: (BOOL)lbPressed rbPressed: (BOOL)rbPressed homePressed: (BOOL)homePressed leftStickPressed: (BOOL)leftStickPressed rightStickPressed: (BOOL)rightStickPressed leftStick: (NSPoint)leftStick rightStick: (NSPoint)rightStick leftStickDeadzone: (CGFloat)leftDeadzone rightStickDeadzone: (CGFloat)rightDeadzone isLeftNormalized: (BOOL)leftNormalized isRightNormalized: (BOOL)rightNormalized; + (void)drawTriggerMetterWithIntensity: (CGFloat)intensity triggerTitle: (NSString*)triggerTitle; -+ (void)drawBatteryMonitorWithBars: (CGFloat)bars; ++ (void)drawBatteryMonitorWithBars: (CGFloat)bars andPercentage: (int)percentage; + (void)drawDeadZoneViewerWithValue: (CGFloat)value linked: (BOOL)linked; @end diff --git a/Pref360Control/Pref360StyleKit.m b/Pref360Control/Pref360StyleKit.m index 92e32f49..c09356b8 100644 --- a/Pref360Control/Pref360StyleKit.m +++ b/Pref360Control/Pref360StyleKit.m @@ -791,14 +791,14 @@ + (void)drawX360ControllerWithControllerNumber: (CGFloat)controllerNumber aPress CGFloat rightDead = rightDeadzone * 15; const CGFloat max16 = 15; CGFloat maxVal = max16 - rightDead; - + if (rightStickPosition.x > 0) rightStickPosition.x = (fabs(rightStickPosition.x) * maxVal / max16) + rightDead; else if (rightStickPosition.x < 0) rightStickPosition.x = -((fabs(rightStickPosition.x) * maxVal / max16) + rightDead); else rightStickPosition.x = 0; - + if (rightStickPosition.y > 0) rightStickPosition.y = (fabs(rightStickPosition.y) * maxVal / max16) + rightDead; else if (rightStickPosition.y < 0) @@ -899,14 +899,14 @@ + (void)drawX360ControllerWithControllerNumber: (CGFloat)controllerNumber aPress CGFloat leftDead = leftDeadzone * 15; const CGFloat max16 = 15; CGFloat maxVal = max16 - leftDead; - + if (leftStickPosition.x > 0) leftStickPosition.x = (fabs(leftStickPosition.x) * maxVal / max16) + leftDead; else if (leftStickPosition.x < 0) leftStickPosition.x = -((fabs(leftStickPosition.x) * maxVal / max16) + leftDead); else leftStickPosition.x = 0; - + if (leftStickPosition.y > 0) leftStickPosition.y = (fabs(leftStickPosition.y) * maxVal / max16) + leftDead; else if (leftStickPosition.y < 0) @@ -998,8 +998,8 @@ + (void)drawX360ControllerWithControllerNumber: (CGFloat)controllerNumber aPress [NSGraphicsContext restoreGraphicsState]; } - - + + //// LEDs { //// Bezier Drawing @@ -1013,8 +1013,8 @@ + (void)drawX360ControllerWithControllerNumber: (CGFloat)controllerNumber aPress [bezierPath closePath]; [led1Color setFill]; [bezierPath fill]; - - + + //// Bezier 3 Drawing NSBezierPath* bezier3Path = NSBezierPath.bezierPath; [bezier3Path moveToPoint: NSMakePoint(235.47, 261.06)]; @@ -1025,8 +1025,8 @@ + (void)drawX360ControllerWithControllerNumber: (CGFloat)controllerNumber aPress [bezier3Path closePath]; [led2Color setFill]; [bezier3Path fill]; - - + + //// Bezier 2 Drawing NSBezierPath* bezier2Path = NSBezierPath.bezierPath; [bezier2Path moveToPoint: NSMakePoint(259.43, 231.1)]; @@ -1037,8 +1037,8 @@ + (void)drawX360ControllerWithControllerNumber: (CGFloat)controllerNumber aPress [bezier2Path closePath]; [led4Color setFill]; [bezier2Path fill]; - - + + //// Bezier 4 Drawing NSBezierPath* bezier4Path = NSBezierPath.bezierPath; [bezier4Path moveToPoint: NSMakePoint(205.51, 231.1)]; @@ -1182,7 +1182,7 @@ + (void)drawTriggerMetterWithIntensity: (CGFloat)intensity triggerTitle: (NSStri [ovalPath stroke]; } -+ (void)drawBatteryMonitorWithBars: (CGFloat)bars ++ (void)drawBatteryMonitorWithBars: (CGFloat)bars andPercentage: (int)percentage { //// Color Declarations NSColor* buttonB = [NSColor colorWithCalibratedRed: 1 green: 0.094 blue: 0.072 alpha: 1]; @@ -1243,6 +1243,23 @@ + (void)drawBatteryMonitorWithBars: (CGFloat)bars NSBezierPath* rectangle5Path = [NSBezierPath bezierPathWithRoundedRect: NSMakeRect(36, 6, 5, 9) xRadius: 1 yRadius: 1]; [batteryColor setFill]; [rectangle5Path fill]; + + + //// Battery Text + NSRect batteryTextBoundingRect = NSMakeRect(1, 1, 36, 19); + + NSMutableParagraphStyle* batteryTextStyle = NSMutableParagraphStyle.defaultParagraphStyle.mutableCopy; + batteryTextStyle.alignment = NSCenterTextAlignment; + + NSDictionary* batteryTextFontAttributes = @{NSFontAttributeName: [NSFont boldSystemFontOfSize: NSFont.systemFontSize], NSForegroundColorAttributeName: NSColor.whiteColor, NSParagraphStyleAttributeName: batteryTextStyle, NSStrokeColorAttributeName: NSColor.blackColor, NSStrokeWidthAttributeName: @-6.0 }; + + NSString* percentageString = [NSString stringWithFormat:@"%d%%", percentage]; + CGFloat batteryTextHeight = NSHeight([percentageString boundingRectWithSize: batteryTextBoundingRect.size options: NSStringDrawingUsesLineFragmentOrigin attributes: batteryTextFontAttributes]); + NSRect batteryTextRect = NSMakeRect(NSMinX(batteryTextBoundingRect), NSMinY(batteryTextBoundingRect) + (NSHeight(batteryTextBoundingRect) - batteryTextHeight) / 2, NSWidth(batteryTextBoundingRect), batteryTextHeight); + [NSGraphicsContext saveGraphicsState]; + NSRectClip(batteryTextRect); + [percentageString drawInRect: NSOffsetRect(batteryTextRect, 0, 1) withAttributes: batteryTextFontAttributes]; + [NSGraphicsContext restoreGraphicsState]; } + (void)drawDeadZoneViewerWithValue: (CGFloat)value linked: (BOOL)linked diff --git a/Pref360Control/Resources/artworks.xcassets/AboutTemplate.imageset/Contents.json b/Pref360Control/Resources/artworks.xcassets/AboutTemplate.imageset/Contents.json index f02f1808..7c9a5abf 100644 --- a/Pref360Control/Resources/artworks.xcassets/AboutTemplate.imageset/Contents.json +++ b/Pref360Control/Resources/artworks.xcassets/AboutTemplate.imageset/Contents.json @@ -15,4 +15,4 @@ "version" : 1, "author" : "xcode" } -} \ No newline at end of file +} diff --git a/Pref360Control/Resources/artworks.xcassets/PowerOffTemplate.imageset/Contents.json b/Pref360Control/Resources/artworks.xcassets/PowerOffTemplate.imageset/Contents.json index ed9a4937..b1f2d2bd 100644 --- a/Pref360Control/Resources/artworks.xcassets/PowerOffTemplate.imageset/Contents.json +++ b/Pref360Control/Resources/artworks.xcassets/PowerOffTemplate.imageset/Contents.json @@ -15,4 +15,4 @@ "version" : 1, "author" : "xcode" } -} \ No newline at end of file +} diff --git a/Pref360Control/en.lproj/Pref360ControlPref.xib b/Pref360Control/en.lproj/Pref360ControlPref.xib index 66019a56..d4bb3d94 100644 --- a/Pref360Control/en.lproj/Pref360ControlPref.xib +++ b/Pref360Control/en.lproj/Pref360ControlPref.xib @@ -1,15 +1,16 @@ - - + + - + + + - @@ -25,13 +26,11 @@ + - - - - + @@ -44,6 +43,7 @@ + @@ -51,7 +51,6 @@ - @@ -60,13 +59,13 @@ - + - - + + @@ -80,19 +79,12 @@ - - + + + + + @@ -833,63 +824,111 @@ Due to some internal limitations, you need to connect your device once to be abl - - + + - - - + + + - - + + - - + + - XBox 360 Controller Driver + Xbox 360 Controller Driver - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -903,40 +942,88 @@ Downloaded from: - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -950,40 +1037,88 @@ Project Home: - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -996,18 +1131,42 @@ Cg - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1020,18 +1179,42 @@ Cg - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1208,31 +1391,26 @@ This driver is licensed under the GNU Public License. A copy of this license is - - - - - - - - + + + + - - @@ -1247,15 +1425,15 @@ This driver is licensed under the GNU Public License. A copy of this license is - - - - - - - - - + + + + + + + + + diff --git a/Pref360Control/zh-Hans.lproj/InfoPlist.strings b/Pref360Control/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 00000000..f9b04f1b --- /dev/null +++ b/Pref360Control/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,4 @@ +/* Localized versions of Info.plist keys */ + +NSHumanReadableCopyright = "Copyright (c) 2006-2013, Colin Munro."; +NSPrefPaneIconLabel = "Xbox 360\nControllers"; diff --git a/Pref360Control/zh-Hans.lproj/Localizable.strings b/Pref360Control/zh-Hans.lproj/Localizable.strings new file mode 100644 index 00000000..c8984513 --- /dev/null +++ b/Pref360Control/zh-Hans.lproj/Localizable.strings @@ -0,0 +1,11 @@ +/* + Localizable.strings + 360 Driver + + Created by C.W. Betts on 3/16/14. + Copyright (c) 2014 GitHub. All rights reserved. +*/ + +"Unable to create authorisation request" = "无法创建授权请求"; +"Unable to acquire authorisation" = "无法获得授权"; +"Failed to execute the driver tool" = "无法执行驱动程序工具"; diff --git a/Pref360Control/zh-Hans.lproj/Pref360ControlPref.strings b/Pref360Control/zh-Hans.lproj/Pref360ControlPref.strings new file mode 100644 index 00000000..9fb2c5b6 --- /dev/null +++ b/Pref360Control/zh-Hans.lproj/Pref360ControlPref.strings @@ -0,0 +1,178 @@ + +/* Class = "NSWindow"; title = "<< do not localize >>"; ObjectID = "3g4-A8-wfV"; */ +"3g4-A8-wfV.title" = "<< do not localize >>"; + +/* Class = "NSSegmentedCell"; 4as-1K-roV.ibShadowedLabels[0] = "Controller Test"; ObjectID = "4as-1K-roV"; */ +"4as-1K-roV.ibShadowedLabels[0]" = "控制器测试"; + +/* Class = "NSSegmentedCell"; 4as-1K-roV.ibShadowedLabels[1] = "Binding"; ObjectID = "4as-1K-roV"; */ +"4as-1K-roV.ibShadowedLabels[1]" = "绑定"; + +/* Class = "NSSegmentedCell"; 4as-1K-roV.ibShadowedLabels[2] = "Advanced"; ObjectID = "4as-1K-roV"; */ +"4as-1K-roV.ibShadowedLabels[2]" = "高级"; + +/* Class = "NSSegmentedCell"; 4as-1K-roV.ibShadowedLabels[3] = "About"; ObjectID = "4as-1K-roV"; */ +"4as-1K-roV.ibShadowedLabels[3]" = "关于"; + +/* Class = "NSMenuItem"; title = "Item 2"; ObjectID = "4up-mH-0Mb"; */ +"4up-mH-0Mb.title" = "Item 2"; + +/* Class = "NSMenuItem"; title = "Item2"; ObjectID = "5Iy-WS-PHG"; */ +"5Iy-WS-PHG.title" = "Item2"; + +/* Class = "NSButtonCell"; title = "Normalize"; ObjectID = "5TH-CS-wl6"; */ +"5TH-CS-wl6.title" = "标准化"; + +/* Class = "NSButtonCell"; title = "Invert X"; ObjectID = "5wf-7e-ekz"; */ +"5wf-7e-ekz.title" = "反转 X"; + +/* Class = "NSTabViewItem"; label = "Tweaking"; ObjectID = "6In-9m-Iqh"; */ +"6In-9m-Iqh.label" = "Tweaking"; + +/* Class = "NSButtonCell"; title = "Invert Y"; ObjectID = "6Kn-lQ-AaB"; */ +"6Kn-lQ-AaB.title" = "反转 Y"; + +/* Class = "NSButtonCell"; title = "Swap Sticks"; ObjectID = "7VQ-hw-19d"; */ +"7VQ-hw-19d.title" = "交换左右遥感"; + +/* Class = "NSButtonCell"; title = "Invert Y"; ObjectID = "8Vm-ce-hhc"; */ +"8Vm-ce-hhc.title" = "反转 Y"; + +/* Class = "NSButtonCell"; title = "Pretend to be an Xbox 360 Controller"; ObjectID = "8Yr-CF-I6K"; */ +"8Yr-CF-I6K.title" = "假装是一个Xbox 360控制器"; + +/* Class = "NSButtonCell"; title = "Invert Y"; ObjectID = "C6W-9e-zqx"; */ +"C6W-9e-zqx.title" = "反转 Y"; + +/* Class = "NSTableColumn"; headerCell.title = "Input"; ObjectID = "CU8-av-rwl"; */ +"CU8-av-rwl.headerCell.title" = "输入"; + +/* Class = "NSMenuItem"; title = "Item 3"; ObjectID = "Dr1-vW-fhR"; */ +"Dr1-vW-fhR.title" = "Item 3"; + +/* Class = "NSButtonCell"; title = "Linked"; ObjectID = "FRy-4y-nnb"; */ +"FRy-4y-nnb.title" = "绑定"; + +/* Class = "NSButtonCell"; title = "Enable Driver"; ObjectID = "FhM-1g-G1s"; */ +"FhM-1g-G1s.title" = "启用驱动"; + +/* Class = "NSMenuItem"; title = "Item1"; ObjectID = "Fqs-9N-l7A"; */ +"Fqs-9N-l7A.title" = "Item1"; + +/* Class = "NSMenuItem"; title = "Item3"; ObjectID = "GKV-5p-R8F"; */ +"GKV-5p-R8F.title" = "Item3"; + +/* Class = "NSBox"; title = "Spoofing Preferences"; ObjectID = "HND-46-X0K"; */ +"HND-46-X0K.title" = "欺骗首选项"; + +/* Class = "NSButtonCell"; title = "Invert X"; ObjectID = "I8N-Ll-Q29"; */ +"I8N-Ll-Q29.title" = "反转 X"; + +/* Class = "NSTextFieldCell"; title = "You can disable the driver temporarily so your Xbox device can be used in games that access the hardware directly.\n\nThis may be useful when playing some games ported by Aspyr if it supports your device.\n\nDue to some internal limitations, you need to connect your device once to be able to disable this."; ObjectID = "IRF-DH-74j"; */ +"IRF-DH-74j.title" = "您可以暂时禁用该驱动程序,以便您的Xbox设备可以在直接访问硬件的游戏中使用。\n\n当游玩由Aspyr移植的某些游戏时,如果它支持您的设备,这可能很有用。\n\n由于某些内部限制,您需要连接一次设备才能禁用此功能。"; + +/* Class = "NSMenuItem"; title = "Item2"; ObjectID = "J5j-fZ-9W4"; */ +"J5j-fZ-9W4.title" = "Item2"; + +/* Class = "NSMenuItem"; title = "Rumble"; ObjectID = "JAa-MJ-QBl"; */ +"JAa-MJ-QBl.title" = "Rumble"; + +/* Class = "NSButtonCell"; title = "Normalize"; ObjectID = "Nbf-a1-ZeT"; */ +"Nbf-a1-ZeT.title" = "标准化"; + +/* Class = "NSMenuItem"; title = "Item2"; ObjectID = "OZ9-jd-gMM"; */ +"OZ9-jd-gMM.title" = "Item2"; + +/* Class = "NSBox"; title = "Options"; ObjectID = "Q4L-nM-vW8"; */ +"Q4L-nM-vW8.title" = "选项"; + +/* Class = "NSMenu"; title = "OtherViews"; ObjectID = "Qc5-fW-pcw"; */ +"Qc5-fW-pcw.title" = "OtherViews"; + +/* Class = "NSButtonCell"; title = "Uninstall..."; ObjectID = "QvN-mn-giT"; */ +"QvN-mn-giT.title" = "卸载..."; + +/* Class = "NSButtonCell"; title = "Invert Y"; ObjectID = "RFR-wA-1SW"; */ +"RFR-wA-1SW.title" = "反转 Y"; + +/* Class = "NSTabViewItem"; label = "About"; ObjectID = "SuI-sa-Ula"; */ +"SuI-sa-Ula.label" = "关于"; + +/* Class = "NSBox"; title = "Right Stick"; ObjectID = "TKg-sh-mjm"; */ +"TKg-sh-mjm.title" = "右摇杆"; + +/* Class = "NSButtonCell"; title = "Linked"; ObjectID = "Uce-Uv-Hq5"; */ +"Uce-Uv-Hq5.title" = "绑定"; + +/* Class = "NSTableColumn"; headerCell.title = "Binding"; ObjectID = "VVi-lm-klv"; */ +"VVi-lm-klv.headerCell.title" = "绑定"; + +/* Class = "NSBox"; title = "Left Stick"; ObjectID = "XdF-ba-S8X"; */ +"XdF-ba-S8X.title" = "左摇杆"; + +/* Class = "NSMenu"; title = "OtherViews"; ObjectID = "Xzo-Df-CjB"; */ +"Xzo-Df-CjB.title" = "OtherViews"; + +/* Class = "NSMenuItem"; title = "Item1"; ObjectID = "ZBC-oI-z5d"; */ +"ZBC-oI-z5d.title" = "Item1"; + +/* Class = "NSBox"; title = "Left Stick"; ObjectID = "ZlQ-UU-WB8"; */ +"ZlQ-UU-WB8.title" = "左摇杆"; + +/* Class = "NSButtonCell"; title = "Invert X"; ObjectID = "acH-i4-MwR"; */ +"acH-i4-MwR.title" = "反转 X"; + +/* Class = "NSBox"; title = "Right Stick"; ObjectID = "cqy-WX-TEQ"; */ +"cqy-WX-TEQ.title" = "右摇杆"; + +/* Class = "NSButtonCell"; title = "Invert X"; ObjectID = "elG-G6-ZET"; */ +"elG-G6-ZET.title" = "反转 X"; + +/* Class = "NSTextFieldCell"; title = "Rumble Options:"; ObjectID = "eqi-tt-Lwa"; */ +"eqi-tt-Lwa.title" = "Rumble Options:"; + +/* Class = "NSButtonCell"; title = "Reset Mapping"; ObjectID = "fLu-85-Jz7"; */ +"fLu-85-Jz7.title" = "重置映射"; + +/* Class = "NSTabViewItem"; label = "Advanced"; ObjectID = "fN4-Zi-Mei"; */ +"fN4-Zi-Mei.label" = "Advanced"; + +/* Class = "NSButtonCell"; title = "Linked"; ObjectID = "hyw-2p-8xu"; */ +"hyw-2p-8xu.title" = "绑定"; + +/* Class = "NSTextFieldCell"; title = "Click on this button to completely remove this driver from your computer (you may need to restart):"; ObjectID = "ix8-GT-Crq"; */ +"ix8-GT-Crq.title" = "单击此按钮可从计算机中完全删除此驱动程序(您可能需要重新启动):"; + +/* Class = "NSBox"; title = "Deadzones"; ObjectID = "k7f-mn-n3T"; */ +"k7f-mn-n3T.title" = "死区"; + +/* Class = "NSButtonCell"; title = "Linked"; ObjectID = "k9z-Ya-OO3"; */ +"k9z-Ya-OO3.title" = "绑定"; + +/* Class = "NSMenuItem"; title = "Item1"; ObjectID = "l7B-sk-a7S"; */ +"l7B-sk-a7S.title" = "Item1"; + +/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "mve-gU-Nz5"; */ +"mve-gU-Nz5.title" = "Text Cell"; + +/* Class = "NSTabViewItem"; label = "Controller test"; ObjectID = "nsf-fv-1ul"; */ +"nsf-fv-1ul.label" = "Controller test"; + +/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "qSp-FJ-2fV"; */ +"qSp-FJ-2fV.title" = "Text Cell"; + +/* Class = "NSMenu"; title = "OtherViews"; ObjectID = "rYq-DA-bYc"; */ +"rYq-DA-bYc.title" = "OtherViews"; + +/* Class = "NSMenuItem"; title = "Item3"; ObjectID = "xdj-AB-T4C"; */ +"xdj-AB-T4C.title" = "Item3"; + +/* Class = "NSMenuItem"; title = "Item3"; ObjectID = "yZ7-Jb-sd7"; */ +"yZ7-Jb-sd7.title" = "Item3"; + +/* Class = "NSButtonCell"; alternateTitle = "Cancel Remapping"; ObjectID = "zgp-Mz-PQL"; */ +"zgp-Mz-PQL.alternateTitle" = "取消重新映射"; + +/* Class = "NSButtonCell"; title = "Start Remapping"; ObjectID = "zgp-Mz-PQL"; */ +"zgp-Mz-PQL.title" = "开始重新映射"; + diff --git a/Readme.md b/Readme.md index bd1eff4a..dd8c2a38 100644 --- a/Readme.md +++ b/Readme.md @@ -1,116 +1,220 @@ -# XBox 360 Controller driver for Mac OS X - -## About ## - -This driver supports the Microsoft Xbox 360 controller, including access to -rumble motors and LEDs, on the Mac OS X platform. It includes a plugin for the -Apple Force Feedback Framework so some games will be able to activate them, -along with a Preference Pane with which allows you to test everything is -installed correctly. Both wired 360 controllers connected via USB, and wireless -360 controllers connected via the Wireless Gaming Receiver for Windows, are -supported. - -This project is a fork of the [Xbox360Controller project][1] originally created -by Colin Munro. - -[1]: http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller - - -## Installation ## - -See the [releases page][2] for the latest compiled and signed version of the -driver. Most users will want to install and run this. - -If you are interested in installing as a developer please see below. - -[2]: https://github.com/d235j/360Controller/releases - - -## Usage ## - -The driver exposes a standard game pad with a number of standard controls, so -any game that supports gaming devices should work. In some cases this may need -an update from the manufacturer of the game or a patched version. The -Preference Pane uses the standard Mac OS X Frameworks for accessing HID devices -and accessing Force Feedback capabilities, so should be a good test that the -installation is functional. - -[List of working and non-working games.](https://github.com/d235j/360Controller/wiki/Games) - - -## Developer info ## - -Anything below this probably doesn't affect end users, so you can stop reading -now if you just want to use the driver. - - -### Building ### - -You'll need the full xcode installed via the app store. The command line tools -are not enough. - -From the command line, run: `./build.sh` - -If you'd like to build the .pkg file, there is an installer project for -Packages. Download packages at -[http://s.sudre.free.fr/Software/Packages/about.html][3] -and the resulting dmg file will be copied to the build directory. - -[3]: http://s.sudre.free.fr/Software/Packages/about.html - -The distribution currently consists of 3 projects - one for the driver -(implemented in C++, as an I/O Kit C++ class), one for the force feedback -support plugin (implemented in C, as an I/O Kit COM plugin) and one for the -Preference Pane (implemented in Objective C as a preference pane plugin). -Ideally these 3 targets should be in the same project, but I've not worked on -this yet. - -To build, use the standard Xcode build for Deployment on each of the 3 -projects. Build Feedback360 before 360Controller, as the 360Controller project -includes a script to copy the Feedback360 bundle to the correct place in the -.kext to make it work. - -To debug the driver, `sudo cp -R 360Controller.kext /tmp/` to assign the -correct properties - note that the Force Feedback plugin only seems to be found -by OSX if the driver is in `/System/Library/Extensions` so I could only debug -it in place. - -To test the Preference Pane, just double-click the resulting file. - - -### Yosemite and signed drivers ### - -Since Yosemite (Mac OS X 10.10) all global kexts are required to be signed. -This means if you want to build the drivers and install locally, you need to -have a mac developer account. - -If you'd like to avoid paying apple for the developer account and want to -disable the signature checking, execute the following commands inside a -terminal: - -``` bash -sudo nvram boot-args="kext-dev-mode=1" -sudo kextcache -m /System/Library/Caches/com.apple.kext.caches/Startup/Extensions.mkext /System/Library/Extensions -``` - -Note that this is probably a bad idea unless you understand the implications of -running unsigned driver code. - - -### Debugging ### - -Most of the debugging I did was via printing out text. In 360Controller, you -can use IOLog(), and the output will appear in system.log. In Feedback360 -normal `fprintf(stderr,...)`, and the output will appear on the console of -whatever application is attempting to use Force Feedback. In Pref360Control, -`NSLog()` works as it's an Objective C program, and will output to the console -of the Preferences application. - - -## Licence ## - -Copyright (C) 2006-2013 Colin Munro - -This driver is licensed under the GNU Public License. A copy of this license is -included in the distribution file, please inspect it before using the binary or -source. +# Xbox Controller Driver for macOS + +## Table of Contents +1. [About](#about) +2. [Installation](#installation) +3. [Uninstallation](#uninstallation) +4. [Usage](#usage) +5. [My controller doesn't work!](#my-controller-doesnt-work) + 1. [I'm using a driver from the Tattiebogle website](#im-using-a-driver-from-the-tattiebogle-website) + 2. [My controller doesn't work with a game!](#my-controller-doesnt-work-with-a-game) + 3. [How do I find my Vendor ID and Product ID?](#how-do-i-find-my-vendor-id-and-product-id) + 4. [Original Xbox Controllers](#original-xbox-controllers) + 5. [Wired Xbox 360 Controllers](#wired-xbox-360-controllers) + 6. [Wireless Xbox 360 Controllers](#wireless-xbox-360-controllers) + 7. [Xbox One Controllers connected with USB](#xbox-one-controllers-connected-with-usb) + 8. [Xbox One Controllers connected with Wireless Adapter](#xbox-one-controllers-connected-with-wireless-adapter) + 9. [Xbox One Controllers connected with Bluetooth](#xbox-one-controllers-connected-with-bluetooth) + 10. [Xbox One Adaptive Controller](#xbox-one-adaptive-controller) +6. [Adding Third Party Controllers](#adding-third-party-controllers) +7. [Developer Info](#developer-info) + 1. [Building](#building) + 2. [Building the .pkg](#building-the-pkg) + 3. [Disabling signing requirements](#disabling-signing-requirements) + 4. [Re-Enabling signing requirements](#re-enabling-signing-requirements) + 5. [Debugging the driver](#debugging-the-driver) + 6. [Debugging the preference pane](#debugging-the-preference-pane) + 7. [A note on Unity mappings](#a-note-on-unity-mappings) +8. [Licence](#licence) + +## About + +**As of December 28, 2020, there are not plans to add Big Sur support, including Apple Silicon support. It will most likely not work on Big Sur.** + +This driver supports the Microsoft Xbox series of controllers including: + +1. Original Xbox + - Original Xbox controllers are supported by using a USB adapter. + +2. Xbox 360 + - Wired Xbox 360 controllers are supported directly. + - **As of macOS 10.11, Wireless Xbox 360 controller support causes kernel panics. This issue cannot be resolved with minor changes to the driver, and requires that the driver be re-written from scratch to resolve the issue. Due to an excess of caution, we have disabled Wireless Xbox 360 controller support as of 0.16.6. If you want to use a wireless controller, download 0.16.5 or earlier and disable the driver before the computer enters a "sleep" state in order to prevent kernel panics. Alternatively, you can revert to a macOS version before 10.11 to avoid this issue.** + +3. Xbox One + - Xbox One controllers are supported when connected with a micro USB cable. Using the controller with the Wireless Adapter is not currently supported. + - Bluetooth capable Xbox One controllers (released after August 2016) are natively supported by macOS without the use of this driver. However, installing this driver will allow you to use the controller via USB. + +The driver provides developers with access to both force feedback and the LEDs of the controllers. Additionally, a preference pane has been provided so that users can configure their controllers and ensure that the driver has been installed properly. + +Controller support includes ALL devices that work with an Xbox series piece of hardware. All wheels, fight sticks, and controllers should work. This includes things like the Xbox One Elite controller. If your hardware does not work with an Xbox console we cannot support it. Sorry. + +This project is a fork of the [Xbox360Controller project](http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller) originally created by Colin Munro. + +## Installation +See the [releases page](https://github.com/360Controller/360Controller/releases) for the latest compiled and signed version of the driver. Most users will want to run this installer. If you are using macOS 10.13.4 or later, then you will have to allow the signing certificate of "Drew Mills" in order for the software to run. Usually, the installer will prompt you to complete this process: +![System prompt: System Extension Blocked](https://imgur.com/zXM5JlU.png) +You can either click "Open Security Preferences" to quickly fix this. If you didn't see this prompt, you can navigate to the same window using the Apple menu in the top left hand corner of your screen, navigating the "System Preferences" and then clicking on "Security & Privacy." This will open up the following page. All you need to do is click the "Allow" button near the bottom right. +![Security & Privacy Preference Pane displaying prompt to user: System software from user "Drew Mills" was blocked from loading](https://imgur.com/HrL77Ii.png) +This prompt has been known to have issues with software or hardware that interferes with mouse movement. If you are using software that impacts the movement of your mouse, such as MagicKeys, or are using a special interface device, such as a Wacom tablet, please using a standard input device, such as a mouse, to click this button. This is a security feature of macOS and is out of our control. + +## Uninstallation +In order to uninstall the driver: navigate to the preference pane by opening your "System Preferences," navigating to the "Xbox 360 Controllers" pane, clicking on the "Advanced" tab and pressing the "Uninstall" button. This will prompt you to enter your password so that the uninstaller can remove all of the bundled software from your machine. + +## Usage +The driver exposes a standard game pad with a number of standard controls, so any game that supports gaming devices should work. In some cases, this may require an update from the developer of the game. The preference pane uses the standard macOS frameworks for accessing HID devices in addition to access of Force Feedback capabilities. This means that the preference pane is a good indicator that the driver is functional for other programs. + +It is important to note that this driver does not work, and can never work, with Apple's "Game Controller Framework." This GCController framework corresponds to physical gamepads that have been offically reviewed by Apple and accepted into the mFi program. Due to the fact that we are not Microsoft, we cannot get their gamepad certified to be a GCController. This is an unfortunate oversight on Apple's part. If you would like to discuss this, please do so at [this location.](https://github.com/360Controller/360Controller/issues/55) + +Users have been maintaining a [partial list of working and non-working games.](https://github.com/360Controller/360Controller/wiki/Games) Please contribute your findings so that you can help others debug their controller issues. + +## My controller doesn't work! + +### I'm using a driver from the Tattiebogle website +The Tattiebogle driver is NOT the same driver as this Github project. We do NOT support that driver. Under NO circumstances will we support that driver. If you download the latest version of this driver from the [releases page](https://github.com/360Controller/360Controller/releases) we will do our best to help you out. This driver will install over the Tattiebogle driver. You don't have to worry about uninstalling the Tattiebogle driver first. + +### My controller doesn't work with a game! +We cannot fix game specific issues. This driver does its absolute best to put out a standardized format for games to use. If they don't take advantage of that, there is **ABSOLUTELY NOTHING** we can do. The best we can do for you is give you the "Pretend to be an Xbox 360 Controller" option in the "Advanced" tab. This will make any wired Xbox 360 or wired Xbox One controller appear to games as if it were an official Microsoft Xbox 360 Controller. That way if the game is only looking for Xbox 360 controllers and isn't looking for other devices like third party Xbox 360 controllers or Xbox One controllers, you should be able to trick the game. If you experience an issue with a game that this toggle does not fix, we cannot help you, sorry. That is just the nature of drivers. + +### How do I find my Vendor ID and Product ID? +Navigate to the Apple menu at the top left corner of your screen. Select the `About This Mac` option. This will open a new window, where you need to select `System Report...` in the `Overview` tab. This will open another new window. On the left hand side of this window, there will be a number of options. Select `USB`. It will be somewhere near the bottom of the `Hardware` section. This will show you the USB device tree. Find and click on the entry that corresponds to your controller. This will provide you with the information needed at the bottom of the window. If you cannot find your device, make sure that all devices are properly connected to the computer. Try different cables if the controller still is not found. + +### Original Xbox Controllers +Make an issue describing your problem. + +### Wired Xbox 360 Controllers +Always check your controller with the preference pane found at: `Apple Menu -> System Preferences -> Xbox 360 Controllers` before creating an issue. If the controller works in this menu, then the driver is operating as intended. If your controller works with this menu, but not with a specific game, then read the [My controller doesn't work with a game!](#my-controller-doesnt-work-with-a-game) section. +If you have a third party controller, make an issue following the template with the "Product ID" and "Vendor ID" of the controller. Follow [How do I find my Vendor ID and Product ID?](#how-do-i-find-my-vendor-id-and-product-id) for instructions on how to find this information. + +### Wireless Xbox 360 Controllers +**As of macOS 10.11, Wireless Xbox 360 controller support causes kernel panics. This issue cannot be resolved with minor changes to the driver, and requires that the driver be re-written from scratch to resolve the issue. Due to an excess of caution, we have disabled Wireless Xbox 360 controller support as of 0.16.6. If you want to use a wireless controller, download 0.16.5 or earlier and disable the driver before the computer enters a "sleep" state in order to prevent kernel panics. Alternatively, you can revert to a macOS version before 10.11 to avoid this issue.** + +### Xbox One Controllers connected with USB +Always check your controller with the preference pane found at: `Apple Menu -> System Preferences -> Xbox 360 Controllers` before creating an issue. If the controller works in this menu, then the driver is operating as intended. If your controller works with this menu, but not with a specific game, then read the [My controller doesn't work with a game!](#my-controller-doesnt-work-with-a-game) section. +If your controller is recognized by the preference pane, but you aren't getting any response from button presses, this is likely due to an issue with macOS 10.11 and later. Apple changed some of the underlying USB code with this release and broke compatibility with some controllers. This is specifically found in controllers from PDP and PowerA. If you revert to macOS 10.10 or earlier, these controllers will work. +If the preference pane can't find your controller, make sure that it is listed in `Apple Menu -> About this Mac -> System Report -> Overview -> Hardware -> USB`. This menu should list a device called "Controller." If it isn't listed there, then you likely have a "charge" Micro USB cable instead of a "data" cable. If the cable isn't sending data, then you can't use the driver. Try a different cable. +If you have a third party controller, make an issue following the template with the "Product ID" and "Vendor ID" of the controller. Follow [How do I find my Vendor ID and Product ID?](#how-do-i-find-my-vendor-id-and-product-id) for instructions on how to find this information. +**At this time, PDP and PowerA controllers are unsupported by this driver as of macOS 10.11+ thanks to a rewrite of the macOS USB kernel. We cannot resolve this issue. It is a bug in Apple's core OS code.** + +### Xbox One Controllers connected with Wireless Adapter +Xbox One controllers connected with the Wireless Adapter are currently not supported. Please be patient as we figure out this complicated protocol. + +### Xbox One Controllers connected with Bluetooth +The Xbox One controller works with macOS automatically when connected over Bluetooth via System Preferences. Only specific Xbox One controllers released after August 2016 have Bluetooth capability. See [Microsoft's support page](https://support.xbox.com/en-US/xbox-on-windows/accessories/connect-and-troubleshoot-xbox-one-bluetooth-issues-windows-10) for determining if your controller supports Bluetooth. Due to the fact that this controller works by default, it will not be supported by this driver. If you choose to plug this controller in via USB, you will need this driver. If you do not wish to connect the controller via USB, then you do not need this driver. Any problems with game compatibility in Bluetooth mode are completely out of our control and are up to you to solve in conjunction with the game developer. + +### Xbox One Adaptive Controller +The Xbox One adaptive controller can connect to your macOS machine through either a Bluetooth or wired connection. In Bluetooth mode, it is not controlled by the driver in any way, and will not show up in the "Xbox 360 Controllers" preference pane. If you are having issues with a wired connection, where the preference pane is recognizing your controller, but isn't recieving inputs, please connect it to a PC or VM running Windows in order to recieve a crucial firmware update. This update may also be possible through an Xbox One console. + +## Adding Third Party Controllers +First, [disable signing requirements](#disabling-signing-requirements) so that you can run your custom build with your third party controller added. Then edit `360Controller/360Controller/Info.plist`. Add your controller following the pattern of pre-existing controllers by adding your vendor and product IDs to a new entry. After this, follow the information in the [building](#building) section, following the "If you don't have a signing certificate" path to build your new .kext. Then, place your shiny new `360Controller.kext` in to `/Library/Extensions` over the old one. You may need to take ownership of the driver in order for it to operate properly. You can do this with `sudo chown -R root:wheel /Library/Extensions/360Controller.kext`. Then, to make sure everything went according to plan, run `sudo kextutil /Library/Extensions/360Controller.kext`. This will load your kext into the OS and you should be able to use your controller. Once you reboot, your custom driver should be loaded automatically. + +## Developer Info +Drivers inherently modify the core operating system kernel. Using the driver as a developer can lead to dangerous kernel panics that can cause data loss or other permanent damage to your computer. Be very careful about how you use this information. We are not responsible for anything this driver does to your computer, or any loss it may incur. Normal users will never have to worry about the developer section of this README. + +### Building + +##### Apple has recently changed how drivers work in Xcode 7. In order to build the driver, you will need Xcode 6.4 or earlier. +Additionally, to use the included build scripts, you will need to change your preferred Xcode installation using `xcode-select`. + +##### You must have a signing certificate to install a locally built driver. Alternatively, you can disable driver signing on your machine, however this is a major security hole and the decision should not be taken lightly. + +You will need a full installation of Xcode to build this project. The command line tools are not enough. + +The project consists of three main parts: The driver (implemented in C++, as an I/O Kit C++ class), the force feedback plugin (implemented in C, as an I/O Kit COM plugin) and the preference pane (implemented in Objective C as a preference pane plugin). To build, use the standard Xcode build for Deployment on each of the 3 projects. Build Feedback360 before 360Controller, as the 360Controller project includes a script to copy the Feedback360 bundle to the correct place in the .kext to make it work. + +To debug the driver, `sudo cp -R 360Controller.kext /tmp/` to assign the correct properties - note that the Force Feedback plugin only seems to be found by OSX if the driver is in /System/Library/Extensions so it can only be debugged in place. Due to the fact that drivers are now stored in /Library/Extenions, this means that you must create a symlink between the location of the driver and /System/Library/Extensions so that the force feedback plugin can operate properly. + +### Building the .pkg + +In order to build the .pkg, you will need to install [Packages.app](http://s.sudre.free.fr/Software/Packages/about.html). + +#### If you don't have a signing certificate + +* Open `360 Driver.xcodeproj` using Xcode. +* Select the `360 Driver` project in the Navigator. +* Select the `360Daemon` target from the top right corner. +* Select the `Build Settings` tab from the top of the screen. +* In the `Code Signing` section, find `Code Signing Identity` section and expand it. +* In the `Release` section, change the selection to `Don't Code Sign`. +* Set the code signing identity for `360Daemon`, `Feedback360`, `360Controller`, `DriverTool`, `Pref360Control`, `Wireless360Controller`, `WirelessGamingReceiver` and `Whole Driver`. +* Run `./build.sh` to build the .pkg. This .pkg can be found in the `Install360Controller` directory. + +#### If you have a signing certificate + +* Create a file named `DeveloperSettings.xcconfig` +* Select the `360 Driver` project in the Navigator. +* In this file, add the following lines: + * `DEVELOPMENT_TEAM = XXXXXXXXXX` where `XXXXXXXXXX` is the development team on your Developer ID Application and Installer certificates. + * `DEVELOPER_NAME = First Last` where `First Last` is the name on the Developer ID Installer certificate. + * `DEVELOPER_EMAIL = my.address@email.com` where `my.address@email.com` is the email address of your Apple account that has your Developer ID Application and Installer certificates. + * `NOTARIZATION_PASSWORD = abcd-efgh-ijkl-mnop` where `abcd-efgh-ijkl-mnop` is a temporary password that you have generated for your Apple account for the purposes of notarization. + +### Disabling signing requirements + +Since Yosemite (macOS 10.10) all global kexts are required to be signed. This means if you want to build the drivers and install locally, you need a very specific signing certificate that Apple closely controls. If you want to disable the signing requirement from macOS, you will need to do several things. + +First, execute these commands in your terminal: +``` +sudo nvram boot-args="kext-dev-mode=1" +sudo kextcache -m /System/Library/Caches/com.apple.kext.caches/Startup/Extensions.mkext /System/Library/Extensions +``` + +Next, you must disable System Integrity Protection. To do this, boot into recovery mode by holding down `CMD + R` while the computer is starting. Once recovery mode has been loaded, open the terminal from the `Utilites` menu item. Execute the following command: +``` +csrutil disable +``` + +### Re-Enabling signing requirements + +From recovery mode, execute the following command: +``` +csrutil enable +``` + +Reboot into macOS like normal. You can reset the boot arguments by executing this command: +``` +sudo nvram -d boot-args +``` +This will remove ALL boot-args. If you have previously manipulated your boot-args, those changes will be erased as well! + +### Notarization of the driver + +This is only possible if you have a signing certificate, but it is a relatively straightforward process. + +* Build the driver as previously instructed and make sure to include the necessary information in your `DeveloperSettings.xcconfig` file, as they will be used during this process. +* Make sure to `cd` into the `Install360Controller` directory and run `./makedmg.sh` +* Run `./notarize.sh` +* This should finish with the message: `The validate action worked!` + +Then you can distribute the notarized and stapled version of the driver. + +### Debugging the driver + +Debugging the driver depends on which part you intend to debug. For the 360Controller driver itself, it uses `IOLog` to output to the `system.log` which can be accessed using Console.app. Feedback360 uses `fprintf(stderr, ...)`, which should appear within the console of the program attempting to use force feedback. + +### Debugging the preference pane + +Most of these instructions are pulled directly from [this blog post.](http://www.condition-alpha.com/blog/?p=1314) Please visit it for futher information. + +First, create a copy of `System Preferences.app` called `System Preferences (signed).app`. Then sign this new System Preferences with the command: + +```codesign -s "Developer ID Application: First Last (XXXXXXXXXX)" -f /Applications/System\ Preferences\ \(signed\).app/``` + +where `Developer ID Application: First Last (XXXXXXXXXX)` is the name of your Developer ID Application signing certificate. + +Edit your build scheme for Pref360Control, and select the "Run" scheme, and make sure you are editing "Debug" (A). In the environment variables section, click on "+" to add a new environment variable (B). Name the new variable OBJC_DISABLE_GC, and set its value to YES. + +Next, click the little disclosure triangle for the run scheme to reveal its detailed settings. Then select pre-actions. Click the "+" at the bottom to add a run script action. Enter /bin/sh as the shell, make sure that your target is selected to provide build settings, and type a shell command line to install the newly compiled pref pane in your personal Library folder: + +```cp -Rf ${CONFIGURATION_BUILD_DIR}/Pref360Control.prefPane ~/Library/PreferencePanes``` + +Finally, select the run step, choose "other" from the executable drop-down menu, and select `System Preferences (signed)` in the Applications folder. Verify that "Debug executable" and "Automatically" are both checked. + +### A note on Unity mappings + +The issues with the button and axis mappings in the Unity game engine are outside of our control. Unity mangles the button and axis values provided by the controller and remaps them to different values. There is absolutely no way that we can introduce a shim to fix it. Complaints about this should be directed at Unity, not at us. + +## Licence + +Copyright (C) 2006-2013 Colin Munro + +This driver is licensed under the GNU Public License. A copy of this license is included in the distribution file, please inspect it before using the binary or source. diff --git a/Wireless360Controller/Info.plist b/Wireless360Controller/Info.plist index 1072cefb..82b41461 100644 --- a/Wireless360Controller/Info.plist +++ b/Wireless360Controller/Info.plist @@ -14,10 +14,14 @@ ${PRODUCT_NAME} CFBundlePackageType KEXT + CFBundleShortVersionString + $(CURRENT_PROJECT_VERSION) CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} + LSMinimumSystemVersion + ${MIN_MACOS_VERSION} IOKitPersonalities Wireless360Controller diff --git a/Wireless360Controller/Wireless360Controller.cpp b/Wireless360Controller/Wireless360Controller.cpp index 980522c5..2577ce36 100644 --- a/Wireless360Controller/Wireless360Controller.cpp +++ b/Wireless360Controller/Wireless360Controller.cpp @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + Wireless360Controller.cpp - main source of the standard wireless controller driver - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -31,10 +31,10 @@ OSDefineMetaClassAndStructors(Wireless360Controller, WirelessHIDDevice) #define super WirelessHIDDevice -static inline XBox360_SShort getAbsolute(XBox360_SShort value) +static inline Xbox360_SShort getAbsolute(Xbox360_SShort value) { - XBox360_SShort reverse; - + Xbox360_SShort reverse; + #ifdef __LITTLE_ENDIAN__ reverse=value; #elif __BIG_ENDIAN__ @@ -48,14 +48,24 @@ static inline XBox360_SShort getAbsolute(XBox360_SShort value) bool Wireless360Controller::init(OSDictionary *propTable) { bool res = super::init(propTable); - + // Default settings invertLeftX = invertLeftY = false; invertRightX = invertRightY = false; deadzoneLeft = deadzoneRight = 0; relativeLeft = relativeRight = false; readSettings(); - + // Bindings + noMapping = true; + for (int i = 0; i < 11; i++) + { + mapping[i] = i; + } + for (int i = 12; i < 16; i++) + { + mapping[i-1] = i; + } + // Done return res; } @@ -66,7 +76,7 @@ void Wireless360Controller::readSettings(void) OSBoolean *value; OSNumber *number; OSDictionary *dataDictionary = OSDynamicCast(OSDictionary, getProperty(kDriverSettingKey)); - + if(dataDictionary==NULL) return; value = OSDynamicCast(OSBoolean, dataDictionary->getObject("InvertLeftX")); if (value != NULL) invertLeftX = value->getValue(); @@ -88,8 +98,7 @@ void Wireless360Controller::readSettings(void) if (value != NULL) deadOffLeft = value->getValue(); value = OSDynamicCast(OSBoolean, dataDictionary->getObject("DeadOffRight")); if (value != NULL) deadOffRight = value->getValue(); - // number = OSDynamicCast(OSNumber, dataDictionary->getObject("ControllerType")); // No use currently. - number = OSDynamicCast(OSNumber, dataDictionary->getObject("rumbleType")); + number = OSDynamicCast(OSNumber, dataDictionary->getObject("RumbleType")); if (number != NULL) rumbleType = number->unsigned8BitValue(); number = OSDynamicCast(OSNumber, dataDictionary->getObject("BindingUp")); if (number != NULL) mapping[0] = number->unsigned32BitValue(); @@ -123,6 +132,17 @@ void Wireless360Controller::readSettings(void) if (number != NULL) mapping[14] = number->unsigned32BitValue(); value = OSDynamicCast(OSBoolean, dataDictionary->getObject("SwapSticks")); if (value != NULL) swapSticks = value->getValue(); + + noMapping = true; + UInt8 normalMapping[15] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15 }; + for (int i = 0; i < 15; i++) + { + if (normalMapping[i] != mapping[i]) + { + noMapping = false; + break; + } + } #if 0 IOLog("Xbox360ControllerClass preferences loaded:\n invertLeft X: %s, Y: %s\n invertRight X: %s, Y:%s\n deadzone Left: %d, Right: %d\n\n", invertLeftX?"True":"False",invertLeftY?"True":"False", @@ -275,7 +295,7 @@ void Wireless360Controller::remapButtons(void *buffer) { XBOX360_IN_REPORT *report360 = (XBOX360_IN_REPORT*)buffer; UInt16 new_buttons = 0; - + new_buttons |= ((report360->buttons & 1) == 1) << mapping[0]; new_buttons |= ((report360->buttons & 2) == 2) << mapping[1]; new_buttons |= ((report360->buttons & 4) == 4) << mapping[2]; @@ -291,16 +311,16 @@ void Wireless360Controller::remapButtons(void *buffer) new_buttons |= ((report360->buttons & 8192) == 8192) << mapping[12]; new_buttons |= ((report360->buttons & 16384) == 16384) << mapping[13]; new_buttons |= ((report360->buttons & 32768) == 32768) << mapping[14]; - + // IOLog("BUTTON PACKET - %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n", mapping[0], mapping[1], mapping[2], mapping[3], mapping[4], mapping[5], mapping[6], mapping[7], mapping[8], mapping[9], mapping[10], mapping[11], mapping[12], mapping[13], mapping[14]); - + report360->buttons = new_buttons; } void Wireless360Controller::remapAxes(void *buffer) { XBOX360_IN_REPORT *report360 = (XBOX360_IN_REPORT*)buffer; - + XBOX360_HAT temp = report360->left; report360->left = report360->right; report360->right = temp; @@ -309,7 +329,8 @@ void Wireless360Controller::remapAxes(void *buffer) void Wireless360Controller::receivedHIDupdate(unsigned char *data, int length) { fiddleReport(data, length); -// remapButtons(data); + if (!noMapping) + remapButtons(data); if (swapSticks) remapAxes(data); super::receivedHIDupdate(data, length); @@ -319,7 +340,7 @@ void Wireless360Controller::SetRumbleMotors(unsigned char large, unsigned char s { unsigned char buf[] = {0x00, 0x01, 0x0f, 0xc0, 0x00, large, small, 0x00, 0x00, 0x00, 0x00, 0x00}; WirelessDevice *device = OSDynamicCast(WirelessDevice, getProvider()); - + if (device != NULL) device->SendPacket(buf, sizeof(buf)); } @@ -327,11 +348,11 @@ void Wireless360Controller::SetRumbleMotors(unsigned char large, unsigned char s IOReturn Wireless360Controller::setReport(IOMemoryDescriptor *report, IOHIDReportType reportType, IOOptionBits options) { char data[2]; - + // IOLog("setReport(%p, %d, %d)\n", report, reportType, options); if (report->readBytes(0, data, 2) < 2) return kIOReturnUnsupported; - + // Rumble if (data[0] == 0x00) { @@ -341,14 +362,14 @@ IOReturn Wireless360Controller::setReport(IOMemoryDescriptor *report, IOHIDRepor SetRumbleMotors(data[0], data[1]); return kIOReturnSuccess; } - + return super::setReport(report, reportType, options); } IOReturn Wireless360Controller::newReportDescriptor(IOMemoryDescriptor ** descriptor ) const { - IOBufferMemoryDescriptor *buffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, sizeof(ReportDescriptor)); - + IOBufferMemoryDescriptor *buffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, kIODirectionOut, sizeof(ReportDescriptor)); + if (buffer == NULL) return kIOReturnNoResources; buffer->writeBytes(0, ReportDescriptor, sizeof(ReportDescriptor)); @@ -360,7 +381,7 @@ IOReturn Wireless360Controller::newReportDescriptor(IOMemoryDescriptor ** descri IOReturn Wireless360Controller::setProperties(OSObject *properties) { OSDictionary *dictionary = OSDynamicCast(OSDictionary,properties); - + if(dictionary!=NULL) { setProperty(kDriverSettingKey,dictionary); readSettings(); diff --git a/Wireless360Controller/Wireless360Controller.h b/Wireless360Controller/Wireless360Controller.h index f2f04cef..af38494e 100644 --- a/Wireless360Controller/Wireless360Controller.h +++ b/Wireless360Controller/Wireless360Controller.h @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + Wireless360Controller.h - declaration of the wireless controller driver class - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -32,7 +32,7 @@ class Wireless360Controller : public WirelessHIDDevice bool init(OSDictionary *propTable = NULL); void SetRumbleMotors(unsigned char large, unsigned char small); - + IOReturn setReport(IOMemoryDescriptor *report, IOHIDReportType reportType, IOOptionBits options); IOReturn newReportDescriptor(IOMemoryDescriptor ** descriptor ) const; @@ -55,12 +55,13 @@ class Wireless360Controller : public WirelessHIDDevice short deadzoneLeft,deadzoneRight; bool relativeLeft,relativeRight; bool deadOffLeft, deadOffRight; - + UInt8 rumbleType; - + bool swapSticks; UInt8 mapping[15]; - + bool noMapping = true; + private: void fiddleReport(unsigned char *data, int length); void remapButtons(void *buffer); diff --git a/Wireless360Controller/zh-Hans.lproj/InfoPlist.strings b/Wireless360Controller/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 00000000..e15e7bbd --- /dev/null +++ b/Wireless360Controller/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Localized versions of Info.plist keys */ + +NSHumanReadableCopyright = "© Colin Munro, 2007-13"; diff --git a/WirelessGamingReceiver/Info.plist b/WirelessGamingReceiver/Info.plist index 03c5a228..a94ffe96 100644 --- a/WirelessGamingReceiver/Info.plist +++ b/WirelessGamingReceiver/Info.plist @@ -14,41 +14,60 @@ ${PRODUCT_NAME} CFBundlePackageType KEXT + CFBundleShortVersionString + $(CURRENT_PROJECT_VERSION) CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} + LSMinimumSystemVersion + ${MIN_MACOS_VERSION} IOKitPersonalities WirelessGamingReceiverForWindows CFBundleIdentifier com.mice.driver.WirelessGamingReceiver - idProduct - 1817 - idVendor - 1118 IOClass WirelessGamingReceiver IOKitDebug 65535 IOProviderClass IOUSBDevice + idProduct + 1817 + idVendor + 1118 WirelessGamingReceiverForWindowsAlternate CFBundleIdentifier com.mice.driver.WirelessGamingReceiver + IOClass + WirelessGamingReceiver + IOKitDebug + 65535 + IOProviderClass + IOUSBDevice idProduct 657 idVendor 1118 + + WirelessGamingReceiverForWindowsAlternateAlternate + + CFBundleIdentifier + com.mice.driver.WirelessGamingReceiver IOClass WirelessGamingReceiver IOKitDebug 65535 IOProviderClass IOUSBDevice + idProduct + 681 + idVendor + 1118 OSBundleCompatibleVersion diff --git a/WirelessGamingReceiver/WirelessDevice.cpp b/WirelessGamingReceiver/WirelessDevice.cpp index ddad5101..0a3790f9 100644 --- a/WirelessGamingReceiver/WirelessDevice.cpp +++ b/WirelessGamingReceiver/WirelessDevice.cpp @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + WirelessDevice.cpp - generic Wireless 360 device driver - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -97,7 +97,7 @@ OSNumber* WirelessDevice::newLocationIDNumber() const { OSNumber *owner; UInt32 location = 0; - + if (index == -1) return NULL; WirelessGamingReceiver *receiver = OSDynamicCast(WirelessGamingReceiver, getProvider()); diff --git a/WirelessGamingReceiver/WirelessDevice.h b/WirelessGamingReceiver/WirelessDevice.h index 1815ef34..348114f0 100644 --- a/WirelessGamingReceiver/WirelessDevice.h +++ b/WirelessGamingReceiver/WirelessDevice.h @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + WirelessDevice.h - declaration of the base wireless 360 device driver class - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -32,20 +32,20 @@ typedef void (*WirelessDeviceWatcher)(void *target, WirelessDevice *sender, void class WirelessDevice : public IOService { OSDeclareDefaultStructors(WirelessDevice); - + public: bool init(OSDictionary *dictionary = 0); // Controller interface bool IsDataAvailable(void); IOMemoryDescriptor* NextPacket(void); - + void SendPacket(const void *data, size_t length); - + void RegisterWatcher(void *target, WirelessDeviceWatcher function, void *parameter); OSNumber* newLocationIDNumber() const; - + private: friend class WirelessGamingReceiver; void SetIndex(int i); diff --git a/WirelessGamingReceiver/WirelessGamingReceiver.cpp b/WirelessGamingReceiver/WirelessGamingReceiver.cpp index 141640f6..4ed9b001 100644 --- a/WirelessGamingReceiver/WirelessGamingReceiver.cpp +++ b/WirelessGamingReceiver/WirelessGamingReceiver.cpp @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + WirelessGamingReceiver.cpp - main source of the wireless receiver driver - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -39,7 +39,7 @@ typedef struct WGRREAD static UInt32 GetMaxPacketSize(IOUSBPipe *pipe) { const IOUSBEndpointDescriptor *ed = pipe->GetEndpointDescriptor(); - + if (ed == NULL) return 0; else return ed->wMaxPacketSize; } @@ -52,7 +52,7 @@ bool WirelessGamingReceiver::start(IOService *provider) IOUSBFindEndpointRequest pipeRequest; IOUSBInterface *interface; int iConnection, iOther, i; - + if (!IOService::start(provider)) { // IOLog("start - superclass failed\n"); @@ -73,7 +73,7 @@ bool WirelessGamingReceiver::start(IOService *provider) // IOLog("start - device has no configurations!\n"); goto fail; } - + // Set configuration cd = device->GetFullConfigurationDescriptor(0); if (cd == NULL) @@ -82,7 +82,7 @@ bool WirelessGamingReceiver::start(IOService *provider) // IOLog("start - couldn't get configuration descriptor\n"); goto fail; } - + if (!device->open(this)) { device = NULL; @@ -94,7 +94,7 @@ bool WirelessGamingReceiver::start(IOService *provider) // IOLog("start - unable to set configuration\n"); goto fail; } - + for (i = 0; i < WIRELESS_CONNECTIONS; i++) { connections[i].controller = NULL; @@ -107,7 +107,7 @@ bool WirelessGamingReceiver::start(IOService *provider) connections[i].service = NULL; connections[i].controllerStarted = false; } - + pipeRequest.interval = 0; pipeRequest.maxPacketSize = 0; pipeRequest.type = kUSBInterrupt; @@ -149,7 +149,7 @@ bool WirelessGamingReceiver::start(IOService *provider) connections[iConnection].controllerOut->retain(); iConnection++; break; - + case 130: // It is a mystery if (!interface->open(this)) { @@ -177,17 +177,17 @@ bool WirelessGamingReceiver::start(IOService *provider) connections[iOther].otherOut->retain(); iOther++; break; - + default: // IOLog("start: Ignoring interface (protocol %d)\n", interface->GetInterfaceProtocol()); break; } } - + if (iConnection != iOther) IOLog("start - interface mismatch?\n"); connectionCount = iConnection; - + for (i = 0; i < connectionCount; i++) { connections[i].inputArray = OSArray::withCapacity(5); @@ -202,10 +202,10 @@ bool WirelessGamingReceiver::start(IOService *provider) goto fail; } } - + // IOLog("start: Transform and roll out (%d interfaces)\n", connectionCount); return true; - + fail: ReleaseAll(); return false; @@ -251,11 +251,11 @@ bool WirelessGamingReceiver::QueueRead(int index) IOUSBCompletion complete; IOReturn err; WGRREAD *data = (WGRREAD*)IOMalloc(sizeof(WGRREAD)); - + if (data == NULL) return false; data->index = index; - data->buffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, GetMaxPacketSize(connections[index].controllerIn)); + data->buffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, kIODirectionIn, GetMaxPacketSize(connections[index].controllerIn)); if (data->buffer == NULL) { IOFree(data, sizeof(WGRREAD)); @@ -265,14 +265,14 @@ bool WirelessGamingReceiver::QueueRead(int index) complete.target = this; complete.action = _ReadComplete; complete.parameter = data; - + err = connections[index].controllerIn->Read(data->buffer, 0, 0, data->buffer->getLength(), &complete); if (err == kIOReturnSuccess) return true; - + data->buffer->release(); IOFree(data, sizeof(WGRREAD)); - + // IOLog("read - failed to start (0x%.8x)\n", err); return false; } @@ -282,7 +282,7 @@ void WirelessGamingReceiver::ReadComplete(void *parameter, IOReturn status, UInt { WGRREAD *data = (WGRREAD*)parameter; bool reread = true; - + switch (status) { case kIOReturnOverrun: @@ -292,7 +292,7 @@ void WirelessGamingReceiver::ReadComplete(void *parameter, IOReturn status, UInt case kIOReturnSuccess: ProcessMessage(data->index, (unsigned char*)data->buffer->getBytesNoCopy(), (int)data->buffer->getLength() - bufferSizeRemaining); break; - + case kIOReturnNotResponding: // IOLog("read - kIOReturnNotResponding\n"); // fall through @@ -300,11 +300,11 @@ void WirelessGamingReceiver::ReadComplete(void *parameter, IOReturn status, UInt reread = false; break; } - + int newIndex = data->index; data->buffer->release(); IOFree(data, sizeof(WGRREAD)); - + if (reread) QueueRead(newIndex); } @@ -315,19 +315,19 @@ bool WirelessGamingReceiver::QueueWrite(int index, const void *bytes, UInt32 len IOBufferMemoryDescriptor *outBuffer; IOUSBCompletion complete; IOReturn err; - - outBuffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, length); + + outBuffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, kIODirectionOut, length); if (outBuffer == NULL) { // IOLog("send - unable to allocate buffer\n"); return false; } outBuffer->writeBytes(0, bytes, length); - + complete.target = this; complete.action = _WriteComplete; complete.parameter = outBuffer; - + err = connections[index].controllerOut->Write(outBuffer, 0, 0, length, &complete); if (err == kIOReturnSuccess) return true; @@ -428,7 +428,7 @@ void WirelessGamingReceiver::ProcessMessage(int index, const unsigned char *data #ifdef PROTOCOL_DEBUG char s[1024]; int i; - + for (i = 0; i < length; i++) { s[(i * 2) + 0] = "0123456789ABCDEF"[(data[i] & 0xF0) >> 4]; @@ -469,7 +469,7 @@ void WirelessGamingReceiver::ProcessMessage(int index, const unsigned char *data int i, j; IOMemoryDescriptor *data; char c; - + ready = false; j = connections[index].inputArray->getCount(); for (i = 0; !ready && (i < j); i++) @@ -492,9 +492,9 @@ void WirelessGamingReceiver::ProcessMessage(int index, const unsigned char *data } return; } - + // Add anything else to the queue - IOMemoryDescriptor *copy = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, length); + IOMemoryDescriptor *copy = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, kIODirectionOut, length); copy->writeBytes(0, data, length); connections[index].inputArray->setObject(copy); if (connections[index].service == NULL) @@ -505,7 +505,7 @@ void WirelessGamingReceiver::ProcessMessage(int index, const unsigned char *data if (!connections[index].controllerStarted) { char c; - + copy->readBytes(1, &c, 1); if (c == 0x0f) { @@ -562,7 +562,7 @@ bool WirelessGamingReceiver::IsDataQueued(int index) IOMemoryDescriptor* WirelessGamingReceiver::ReadBuffer(int index) { IOMemoryDescriptor *data; - + data = OSDynamicCast(IOMemoryDescriptor, connections[index].inputArray->getObject(0)); if (data != NULL) data->retain(); @@ -575,23 +575,23 @@ OSNumber* WirelessGamingReceiver::newLocationIDNumber() const { OSNumber *number; UInt32 location = 0; - + if (device) { if ((number = OSDynamicCast(OSNumber, device->getProperty("locationID")))) { location = number->unsigned32BitValue(); } - else + else { // Make up an address if ((number = OSDynamicCast(OSNumber, device->getProperty("USB Address")))) location |= number->unsigned8BitValue() << 24; - + if ((number = OSDynamicCast(OSNumber, device->getProperty("idProduct")))) location |= number->unsigned8BitValue() << 16; } } - + return OSNumber::withNumber(location, 32); } diff --git a/WirelessGamingReceiver/WirelessGamingReceiver.h b/WirelessGamingReceiver/WirelessGamingReceiver.h index 13135ab9..afb0e72d 100644 --- a/WirelessGamingReceiver/WirelessGamingReceiver.h +++ b/WirelessGamingReceiver/WirelessGamingReceiver.h @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + WirelessGamingReceiver.h - declaration of the wireless receiver driver - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -36,11 +36,11 @@ typedef struct WIRELESS_CONNECTION // Controller IOUSBInterface *controller; IOUSBPipe *controllerIn, *controllerOut; - + // Mystery IOUSBInterface *other; IOUSBPipe *otherIn, *otherOut; - + // Runtime data OSArray *inputArray; WirelessDevice *service; @@ -59,31 +59,31 @@ class WirelessGamingReceiver : public IOService // For WirelessDevice to use OSNumber* newLocationIDNumber() const; - + private: friend class WirelessDevice; bool IsDataQueued(int index); IOMemoryDescriptor* ReadBuffer(int index); bool QueueWrite(int index, const void *bytes, UInt32 length); - + private: IOUSBDevice *device; WIRELESS_CONNECTION connections[WIRELESS_CONNECTIONS]; int connectionCount; - + void InstantiateService(int index); - + void ProcessMessage(int index, const unsigned char *data, int length); - + bool QueueRead(int index); void ReadComplete(void *parameter, IOReturn status, UInt32 bufferSizeRemaining); - + void WriteComplete(void *parameter, IOReturn status, UInt32 bufferSizeRemaining); - + void ReleaseAll(void); bool didTerminate(IOService *provider, IOOptionBits options, bool *defer); - + static void _ReadComplete(void *target, void *parameter, IOReturn status, UInt32 bufferSizeRemaining); static void _WriteComplete(void *target, void *parameter, IOReturn status, UInt32 bufferSizeRemaining); }; diff --git a/WirelessGamingReceiver/WirelessHIDDevice.cpp b/WirelessGamingReceiver/WirelessHIDDevice.cpp index dd4e4374..9aa8a532 100644 --- a/WirelessGamingReceiver/WirelessHIDDevice.cpp +++ b/WirelessGamingReceiver/WirelessHIDDevice.cpp @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + WirelessHIDDevice.cpp - generic wireless 360 device driver with HID support - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -37,7 +37,7 @@ const char weirdStart[] = {0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, void WirelessHIDDevice::ChatPadTimerActionWrapper(OSObject *owner, IOTimerEventSource *sender) { WirelessHIDDevice *device = OSDynamicCast(WirelessHIDDevice, owner); - + // Automatic shutoff device->serialTimerCount++; if (device->serialTimerCount > POWEROFF_TIMEOUT) @@ -69,7 +69,7 @@ void WirelessHIDDevice::PowerOff(void) { static const unsigned char buf[] = {0x00, 0x00, 0x08, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; WirelessDevice *device = OSDynamicCast(WirelessDevice, getProvider()); - + if (device != NULL) { device->SendPacket(buf, sizeof(buf)); @@ -84,7 +84,7 @@ IOReturn WirelessHIDDevice::setReport(IOMemoryDescriptor *report, IOHIDReportTyp if (report->readBytes(0, data, 2) < 2) return kIOReturnUnsupported; - + switch (data[0]) { case 0x01: // LED if ((data[1] != report->getLength()) || (data[1] != 0x03)) @@ -105,16 +105,16 @@ bool WirelessHIDDevice::handleStart(IOService *provider) { WirelessDevice *device; IOWorkLoop *workloop; - + if (!super::handleStart(provider)) goto fail; device = OSDynamicCast(WirelessDevice, provider); if (device == NULL) goto fail; - + serialTimerCount = 0; - + serialTimer = IOTimerEventSource::timerEventSource(this, ChatPadTimerActionWrapper); if (serialTimer == NULL) { @@ -127,15 +127,15 @@ bool WirelessHIDDevice::handleStart(IOService *provider) IOLog("start - failed to connect timer for chatpad\n"); goto fail; } - + device->RegisterWatcher(this, _receivedData, NULL); - + device->SendPacket(weirdStart, sizeof(weirdStart)); serialTimer->setTimeoutMS(1000); return true; - + fail: return false; } @@ -156,7 +156,7 @@ void WirelessHIDDevice::handleStop(IOService *provider) serialTimer->release(); serialTimer = NULL; } - + super::handleStop(provider); } @@ -167,7 +167,7 @@ void WirelessHIDDevice::receivedData(void) WirelessDevice *device = OSDynamicCast(WirelessDevice, getProvider()); if (device == NULL) return; - + while ((data = device->NextPacket()) != NULL) { receivedMessage(data); @@ -181,12 +181,12 @@ const char *HexData = "0123456789ABCDEF"; void WirelessHIDDevice::receivedMessage(IOMemoryDescriptor *data) { unsigned char buf[29]; - + if (data->getLength() != 29) return; - + data->readBytes(0, buf, 29); - + switch (buf[1]) { case 0x0f: // Initial info @@ -203,16 +203,16 @@ void WirelessHIDDevice::receivedMessage(IOMemoryDescriptor *data) serialString[8] = '\0'; IOLog("Got serial number: %s", serialString); break; - + case 0x01: // HID info update if (buf[3] == 0xf0) receivedHIDupdate(buf + 4, buf[5]); break; - + case 0x00: // Info update receivedUpdate(buf[3], buf + 4); break; - + default: break; } @@ -234,7 +234,7 @@ void WirelessHIDDevice::receivedUpdate(unsigned char type, unsigned char *data) } } break; - + default: break; } @@ -245,7 +245,7 @@ void WirelessHIDDevice::receivedHIDupdate(unsigned char *data, int length) { IOReturn err; IOMemoryDescriptor *report; - + serialTimerCount = 0; report = IOMemoryDescriptor::withAddress(data, length, kIODirectionNone); err = handleReport(report); diff --git a/WirelessGamingReceiver/WirelessHIDDevice.h b/WirelessGamingReceiver/WirelessHIDDevice.h index b2f3521f..24231f74 100644 --- a/WirelessGamingReceiver/WirelessHIDDevice.h +++ b/WirelessGamingReceiver/WirelessHIDDevice.h @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + WirelessHIDDevice.h - declaration of generic wireless HID device - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify @@ -34,7 +34,7 @@ class WirelessHIDDevice : public IOHIDDevice void SetLEDs(int mode); void PowerOff(void); unsigned char GetBatteryLevel(void); - + IOReturn setReport(IOMemoryDescriptor *report, IOHIDReportType reportType, IOOptionBits options); OSNumber* newLocationIDNumber() const; @@ -49,10 +49,10 @@ class WirelessHIDDevice : public IOHIDDevice private: static void _receivedData(void *target, WirelessDevice *sender, void *parameter); static void ChatPadTimerActionWrapper(OSObject *owner, IOTimerEventSource *sender); - + IOTimerEventSource *serialTimer; int serialTimerCount; - + unsigned char battery; char serialString[10]; }; diff --git a/WirelessGamingReceiver/devices.h b/WirelessGamingReceiver/devices.h index 81045194..ccaabcb3 100644 --- a/WirelessGamingReceiver/devices.h +++ b/WirelessGamingReceiver/devices.h @@ -1,9 +1,9 @@ /* MICE Xbox 360 Controller driver for Mac OS X Copyright (C) 2006-2013 Colin Munro - + devics.h - contains constants for the wireless driver - + This file is part of Xbox360Controller. Xbox360Controller is free software; you can redistribute it and/or modify diff --git a/WirelessGamingReceiver/zh-Hans.lproj/InfoPlist.strings b/WirelessGamingReceiver/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 00000000..e85e4cf7 --- /dev/null +++ b/WirelessGamingReceiver/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Localized versions of Info.plist keys */ + +NSHumanReadableCopyright = "© Colin Munro, 2007-11"; diff --git a/XBOBTFF/FFDriver.cpp b/XBOBTFF/FFDriver.cpp new file mode 100644 index 00000000..32f5fbe7 --- /dev/null +++ b/XBOBTFF/FFDriver.cpp @@ -0,0 +1,799 @@ +// +// FFDriver.c +// XBoxBTFFPlug +// +// Created by C.W. Betts on 9/20/17. +// Copyright © 2017 C.W. Betts. All rights reserved. +// + +#include +#include +#include "FFDriver.h" +#include "XBoxOneBTHID.h" +#include +#include +using std::max; +using std::min; + +static bool goodProbe(io_service_t theService) +{ + if (!IOObjectConformsTo(theService, kIOHIDDeviceKey)) { + return false; + } + CFMutableDictionaryRef dict; + + IORegistryEntryCreateCFProperties(theService, &dict, kCFAllocatorDefault, 0); + CFTypeRef aNum = CFDictionaryGetValue(dict, CFSTR(kIOHIDProductIDKey)); + int tmpNum; + ::CFNumberGetValue((CFNumberRef)aNum, kCFNumberIntType, &tmpNum); + if (tmpNum != 765) { + CFRelease(dict); + return false; + } + aNum = CFDictionaryGetValue(dict, CFSTR(kIOHIDVendorIDKey)); + ::CFNumberGetValue((CFNumberRef)aNum, kCFNumberIntType, &tmpNum); + if (tmpNum != 1118) { + CFRelease(dict); + return false; + } + + CFRelease(dict); + return true; +} + +#define LoopGranularity 10000 // Microseconds + +double CurrentTimeUsingMach() +{ + static mach_timebase_info_data_t info = {0}; + if (!info.denom) + { + if (mach_timebase_info(&info) != KERN_SUCCESS) + { + //Generally it can't fail here. Look at XNU sources //FIXME + info.denom = 0; + return -1.0; + } + } + + uint64_t start = mach_absolute_time(); + + uint64_t nanos = start * info.numer / info.denom; + return (double)nanos / NSEC_PER_SEC; +} + +static IOCFPlugInInterface functionMapXBOBT_IOCFPlugInInterface = { + // Padding required for COM + NULL, + // IUnknown + &FeedbackXBOBT::sQueryInterface, + &FeedbackXBOBT::sAddRef, + &FeedbackXBOBT::sRelease, + // IOCFPlugInInterface + 1,0, // Version + &FeedbackXBOBT::sProbe, + &FeedbackXBOBT::sStart, + &FeedbackXBOBT::sStop +}; + + +static IOForceFeedbackDeviceInterface functionMapXBOBT_IOForceFeedbackDeviceInterface = { + // Padding required for COM + NULL, + // IUnknown + &FeedbackXBOBT::sQueryInterface, + &FeedbackXBOBT::sAddRef, + &FeedbackXBOBT::sRelease, + // IOForceFeedbackDevice + &FeedbackXBOBT::sGetVersion, + &FeedbackXBOBT::sInitializeTerminate, + &FeedbackXBOBT::sDestroyEffect, + &FeedbackXBOBT::sDownloadEffect, + &FeedbackXBOBT::sEscape, + &FeedbackXBOBT::sGetEffectStatus, + &FeedbackXBOBT::sGetForceFeedbackCapabilities, + &FeedbackXBOBT::sGetForceFeedbackState, + &FeedbackXBOBT::sSendForceFeedbackCommand, + &FeedbackXBOBT::sSetProperty, + &FeedbackXBOBT::sStartEffect, + &FeedbackXBOBT::sStopEffect +}; + +FeedbackXBOBT::FeedbackXBOBT() : fRefCount(1), EffectIndex(1), Stopped(true), +Paused(false), PausedTime(0), LastTime(0), Gain(10000), PrvLeftLevel(0), +PrvRightLevel(0), Actuator(true), Manual(false) +{ + EffectList = FeedbackXBOEffectVector(); + + iIOCFPlugInInterface.pseudoVTable = (IUnknownVTbl *) &functionMapXBOBT_IOCFPlugInInterface; + iIOCFPlugInInterface.obj = this; + + iIOForceFeedbackDeviceInterface.pseudoVTable = (IUnknownVTbl *) &functionMapXBOBT_IOForceFeedbackDeviceInterface; + iIOForceFeedbackDeviceInterface.obj = this; + + FactoryID = BTFFPLUGINTERFACE; + CFRetain(FactoryID); + CFPlugInAddInstanceForFactory(FactoryID); +} + +FeedbackXBOBT::~FeedbackXBOBT() +{ + CFPlugInRemoveInstanceForFactory(FactoryID); + CFRelease(FactoryID); +} + +HRESULT FeedbackXBOBT::QueryInterface(REFIID iid, LPVOID *ppv) +{ + CFUUIDRef interface = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, iid); + + if(CFEqual(interface, kIOForceFeedbackDeviceInterfaceID)) + *ppv = &this->iIOForceFeedbackDeviceInterface; + // IUnknown || IOCFPlugInInterface + else if(CFEqual(interface, IUnknownUUID) || CFEqual(interface, kIOCFPlugInInterfaceID)) + *ppv = &this->iIOCFPlugInInterface; + else + *ppv = NULL; + + // Done + CFRelease(interface); + if ((*ppv) == NULL) return E_NOINTERFACE; + else { + this->iIOCFPlugInInterface.pseudoVTable->AddRef(*ppv); + } + return FF_OK; +} + +ULONG FeedbackXBOBT::AddRef() +{ + return ++fRefCount; +} + +ULONG FeedbackXBOBT::Release() +{ + ULONG returnValue = fRefCount - 1; + if(returnValue > 0) { + fRefCount = returnValue; + } else if(returnValue == 0) { + fRefCount = returnValue; + delete this; + } else { + returnValue = 0; + } + return returnValue; +} + +void** FeedbackXBOBT::Alloc(void) +{ + FeedbackXBOBT *me = new FeedbackXBOBT(); + if (!me) { + return NULL; + } + return (void **)(&me->iIOCFPlugInInterface.pseudoVTable); +} + +IOReturn FeedbackXBOBT::Probe(CFDictionaryRef propertyTable, io_service_t service, SInt32 *order) +{ + if (service == 0) { + return kIOReturnBadArgument; + } + if (goodProbe(service)) { + return 0; + } else { + return kIOReturnBadArgument; + } +} + +IOReturn FeedbackXBOBT::Start(CFDictionaryRef propertyTable,io_service_t service) +{ + return FF_OK; +} + +IOReturn FeedbackXBOBT::Stop(void) +{ + return FF_OK; +} + +HRESULT FeedbackXBOBT::SetProperty(FFProperty property, void *value) +{ + if(property != FFPROP_FFGAIN) { + return FFERR_UNSUPPORTED; + } + + UInt32 NewGain = *((UInt32*)value); + __block HRESULT Result = FF_OK; + + dispatch_sync(Queue, ^{ + if (1 <= NewGain && NewGain <= 10000) + { + Gain = NewGain; + } else { + Gain = max((UInt32)1, min(NewGain, (UInt32)10000)); + Result = FF_TRUNCATED; + } + }); + + return Result; +} + +HRESULT FeedbackXBOBT::StartEffect(FFEffectDownloadID EffectHandle, FFEffectStartFlag Mode, UInt32 Count) +{ + dispatch_sync(Queue, ^{ + for (FeedbackXBOEffectIterator effectIterator = EffectList.begin() ; effectIterator != EffectList.end(); ++effectIterator) + { + if (effectIterator->Handle == EffectHandle) + { + effectIterator->Status = FFEGES_PLAYING; + effectIterator->PlayCount = Count; + effectIterator->StartTime = CurrentTimeUsingMach(); + Stopped = false; + } else { + if (Mode & FFES_SOLO) { + effectIterator->Status = NULL; + } + } + } + }); + return FF_OK; +} + +HRESULT FeedbackXBOBT::StopEffect(UInt32 EffectHandle) +{ + dispatch_sync(Queue, ^{ + for (FeedbackXBOEffectIterator effectIterator = EffectList.begin() ; effectIterator != EffectList.end(); ++effectIterator) + { + if (effectIterator->Handle == EffectHandle) + { + effectIterator->Status = NULL; + break; + } + } + }); + return FF_OK; +} + +HRESULT FeedbackXBOBT::DownloadEffect(CFUUIDRef EffectType, FFEffectDownloadID *EffectHandle, FFEFFECT *DiEffect, FFEffectParameterFlag Flags) +{ + __block HRESULT Result = FF_OK; + + if (Flags & FFEP_NODOWNLOAD) + { + return FF_OK; + } + + dispatch_sync(Queue, ^{ + FeedbackXBOEffect *Effect = NULL; + if (*EffectHandle == 0) { + EffectList.push_back(FeedbackXBOEffect(EffectIndex++)); + Effect = &(EffectList.back()); + *EffectHandle = Effect->Handle; + } else { + for (LONG Index = 0; Index < EffectList.size(); Index++) { + if (EffectList[Index].Handle == *EffectHandle) { + Effect = &(EffectList[Index]); + break; + } + } + } + + if (Effect == NULL || Result == -1) { + Result = FFERR_INTERNAL; + } + else { + Effect->Type = EffectType; + Effect->DiEffect.dwFlags = DiEffect->dwFlags; + + if( Flags & FFEP_DURATION ) + { + Effect->DiEffect.dwDuration = DiEffect->dwDuration; + } + + if( Flags & FFEP_SAMPLEPERIOD ) + { + Effect->DiEffect.dwSamplePeriod = DiEffect->dwSamplePeriod; + } + + if( Flags & FFEP_GAIN ) + { + Effect->DiEffect.dwGain = DiEffect->dwGain; + } + + if( Flags & FFEP_TRIGGERBUTTON ) + { + Effect->DiEffect.dwTriggerButton = DiEffect->dwTriggerButton; + } + + if( Flags & FFEP_TRIGGERREPEATINTERVAL ) + { + Effect->DiEffect.dwTriggerRepeatInterval = DiEffect->dwTriggerRepeatInterval; + } + + if( Flags & FFEP_AXES ) + { + Effect->DiEffect.cAxes = DiEffect->cAxes; + Effect->DiEffect.rgdwAxes = NULL; + } + + if( Flags & FFEP_DIRECTION ) + { + Effect->DiEffect.cAxes = DiEffect->cAxes; + Effect->DiEffect.rglDirection = NULL; + } + + if( ( Flags & FFEP_ENVELOPE ) && DiEffect->lpEnvelope != NULL ) + { + memcpy( &Effect->DiEnvelope, DiEffect->lpEnvelope, sizeof( FFENVELOPE ) ); + if( Effect->DiEffect.dwDuration - Effect->DiEnvelope.dwFadeTime + < Effect->DiEnvelope.dwAttackTime ) + { + Effect->DiEnvelope.dwFadeTime = Effect->DiEnvelope.dwAttackTime; + } + Effect->DiEffect.lpEnvelope = &Effect->DiEnvelope; + } + + Effect->DiEffect.cbTypeSpecificParams = DiEffect->cbTypeSpecificParams; + + if( Flags & FFEP_TYPESPECIFICPARAMS ) + { + if(CFEqual(EffectType, kFFEffectType_CustomForce_ID)) { + memcpy( + &Effect->DiCustomForce + ,DiEffect->lpvTypeSpecificParams + ,DiEffect->cbTypeSpecificParams ); + Effect->DiEffect.lpvTypeSpecificParams = &Effect->DiCustomForce; + } + + else if(CFEqual(EffectType, kFFEffectType_ConstantForce_ID)) { + memcpy( + &Effect->DiConstantForce + ,DiEffect->lpvTypeSpecificParams + ,DiEffect->cbTypeSpecificParams ); + Effect->DiEffect.lpvTypeSpecificParams = &Effect->DiConstantForce; + } + else if(CFEqual(EffectType, kFFEffectType_Square_ID) || CFEqual(EffectType, kFFEffectType_Sine_ID) || CFEqual(EffectType, kFFEffectType_Triangle_ID) || CFEqual(EffectType, kFFEffectType_SawtoothUp_ID) || CFEqual(EffectType, kFFEffectType_SawtoothDown_ID) ) { + memcpy( + &Effect->DiPeriodic + ,DiEffect->lpvTypeSpecificParams + ,DiEffect->cbTypeSpecificParams ); + Effect->DiEffect.lpvTypeSpecificParams = &Effect->DiPeriodic; + } + else if(CFEqual(EffectType, kFFEffectType_RampForce_ID)) { + memcpy( + &Effect->DiRampforce + ,DiEffect->lpvTypeSpecificParams + ,DiEffect->cbTypeSpecificParams ); + Effect->DiEffect.lpvTypeSpecificParams = &Effect->DiRampforce; + } + } + + if( Flags & FFEP_STARTDELAY ) + { + Effect->DiEffect.dwStartDelay = DiEffect->dwStartDelay; + } + + if( Flags & FFEP_START ) + { + Effect->Status = FFEGES_PLAYING; + Effect->PlayCount = 1; + Effect->StartTime = CurrentTimeUsingMach(); + } + + if( Flags & FFEP_NORESTART ) + { + ; + } + Result = FF_OK; + } + }); + return Result; +} + +HRESULT FeedbackXBOBT::GetForceFeedbackState(ForceFeedbackDeviceState *DeviceState) +{ + if (DeviceState->dwSize != sizeof(FFDEVICESTATE)) + { + return FFERR_INVALIDPARAM; + } + + dispatch_sync(Queue, ^{ + DeviceState->dwState = NULL; + if( EffectList.size() == 0 ) + { + DeviceState->dwState |= FFGFFS_EMPTY; + } + if( Stopped == true ) + { + DeviceState->dwState |= FFGFFS_STOPPED; + } + if( Paused == true ) + { + DeviceState->dwState |= FFGFFS_PAUSED; + } + if (Actuator == true) + { + DeviceState->dwState |= FFGFFS_ACTUATORSON; + } else { + DeviceState->dwState |= FFGFFS_ACTUATORSOFF; + } + DeviceState->dwState |= FFGFFS_POWERON; + DeviceState->dwState |= FFGFFS_SAFETYSWITCHOFF; + DeviceState->dwState |= FFGFFS_USERFFSWITCHON; + + DeviceState->dwLoad = 0; + }); + + return FF_OK; +} + +HRESULT FeedbackXBOBT::GetForceFeedbackCapabilities(FFCAPABILITIES *capabilities) +{ + capabilities->ffSpecVer.majorRev=kFFPlugInAPIMajorRev; + capabilities->ffSpecVer.minorAndBugRev=kFFPlugInAPIMinorAndBugRev; + capabilities->ffSpecVer.stage=kFFPlugInAPIStage; + capabilities->ffSpecVer.nonRelRev=kFFPlugInAPINonRelRev; + capabilities->supportedEffects=FFCAP_ET_CUSTOMFORCE|FFCAP_ET_CONSTANTFORCE|FFCAP_ET_RAMPFORCE|FFCAP_ET_SQUARE|FFCAP_ET_SINE|FFCAP_ET_TRIANGLE|FFCAP_ET_SAWTOOTHUP|FFCAP_ET_SAWTOOTHDOWN; + capabilities->emulatedEffects=0; + capabilities->subType=FFCAP_ST_VIBRATION; + capabilities->numFfAxes=4; + capabilities->ffAxes[0]=FFJOFS_X; + capabilities->ffAxes[1]=FFJOFS_Y; + capabilities->ffAxes[2]=FFJOFS_Z; + capabilities->ffAxes[3]=FFJOFS_RZ; + capabilities->storageCapacity=256; + capabilities->playbackCapacity=1; + capabilities->driverVer.majorRev=FeedbackDriverVersionMajor; + capabilities->driverVer.minorAndBugRev=FeedbackDriverVersionMinor; + capabilities->driverVer.stage=FeedbackDriverVersionStage; + capabilities->driverVer.nonRelRev=FeedbackDriverVersionNonRelRev; + capabilities->firmwareVer.majorRev=1; + capabilities->firmwareVer.minorAndBugRev=0; + capabilities->firmwareVer.stage=developStage; + capabilities->firmwareVer.nonRelRev=0; + capabilities->hardwareVer.majorRev=1; + capabilities->hardwareVer.minorAndBugRev=0; + capabilities->hardwareVer.stage=developStage; + capabilities->hardwareVer.nonRelRev=0; + return FF_OK; +} + +HRESULT FeedbackXBOBT::SendForceFeedbackCommand(FFCommandFlag state) +{ + __block HRESULT Result = FF_OK; + + dispatch_sync(Queue, ^{ + switch (state) { + case FFSFFC_RESET: + EffectList.clear(); + Stopped = true; + Paused = false; + break; + + case FFSFFC_STOPALL: + for (FeedbackXBOEffectIterator effectIterator = EffectList.begin() ; effectIterator != EffectList.end(); ++effectIterator) + { + effectIterator->Status = NULL; + } + Stopped = true; + Paused = false; + break; + + case FFSFFC_PAUSE: + Paused = true; + PausedTime = CurrentTimeUsingMach(); + break; + + case FFSFFC_CONTINUE: + for (FeedbackXBOEffectIterator effectIterator = EffectList.begin() ; effectIterator != EffectList.end(); ++effectIterator) + { + effectIterator->StartTime += ( CurrentTimeUsingMach() - PausedTime ); + } + Paused = false; + break; + + case FFSFFC_SETACTUATORSON: + Actuator = true; + break; + + case FFSFFC_SETACTUATORSOFF: + Actuator = false; + break; + + default: + Result = FFERR_INVALIDPARAM; + break; + } + }); + //return Result; + return FF_OK; +} + +HRESULT FeedbackXBOBT::InitializeTerminate(NumVersion APIversion, io_object_t hidDevice, boolean_t begin) +{ + if(begin) { + if (APIversion.majorRev != kFFPlugInAPIMajorRev) + { + // fprintf(stderr,"Feedback: Invalid version\n"); + return FFERR_INVALIDPARAM; + } + // From probe + if( (hidDevice==0) + || !goodProbe(hidDevice) ) + { + // fprintf(stderr,"Feedback: Invalid device\n"); + return FFERR_INVALIDPARAM; + } + this->device = IOHIDDeviceCreate(kCFAllocatorDefault, hidDevice); + if(!this->device) { + // fprintf(stderr,"Feedback: Failed to initialise\n"); + return FFERR_NOINTERFACE; + } + IOHIDDeviceOpen(this->device, 0); + Queue = dispatch_queue_create("com.mice.driver.FeedbackXBOBT", NULL); + Timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, Queue); + dispatch_source_set_timer(Timer, dispatch_walltime(NULL, 0), LoopGranularity*1000, 10); + dispatch_set_context(Timer, this); + dispatch_source_set_event_handler_f(Timer, EffectProc); + dispatch_resume(Timer); + } + else { + dispatch_sync(Queue, ^{ + dispatch_source_cancel(Timer); + SetForce(0, 0, 0, 0); + IOHIDDeviceClose(this->device, 0); + CFRelease(this->device); + }); + + } + return FF_OK; +} + +HRESULT FeedbackXBOBT::DestroyEffect(FFEffectDownloadID EffectHandle) +{ + __block HRESULT Result = FF_OK; + dispatch_sync(Queue, ^{ + for (FeedbackXBOEffectIterator effectIterator = EffectList.begin() ; effectIterator != EffectList.end(); ++effectIterator) + { + if (effectIterator->Handle == EffectHandle) + { + EffectList.erase(effectIterator); + break; + } + } + }); + return Result; +} + +HRESULT FeedbackXBOBT::Escape(FFEffectDownloadID downloadID, FFEFFESCAPE *escape) +{ + if (downloadID!=0) return FFERR_UNSUPPORTED; + if (escape->dwSize < sizeof(FFEFFESCAPE)) return FFERR_INVALIDPARAM; + escape->cbOutBuffer=0; + switch (escape->dwCommand) { +#if 0 + case 0x00: // Control motors + if(escape->cbInBuffer!=1) return FFERR_INVALIDPARAM; + dispatch_sync(Queue, ^{ + Manual=((unsigned char*)escape->lpvInBuffer)[0]!=0x00; + }); + break; + + case 0x01: // Set motors + if (escape->cbInBuffer!=2) return FFERR_INVALIDPARAM; + dispatch_sync(Queue, ^{ + if(Manual) { + unsigned char *data=(unsigned char *)escape->lpvInBuffer; + unsigned char buf[]={0x00,0x04,data[0],data[1]}; + Device_Send(&this->device,buf,sizeof(buf)); + } + }); + break; + + case 0x02: // Set LED + if (escape->cbInBuffer!=1) return FFERR_INVALIDPARAM; + { + dispatch_sync(Queue, ^{ + unsigned char *data=(unsigned char *)escape->lpvInBuffer; + unsigned char buf[]={0x01,0x03,data[0]}; + Device_Send(&this->device,buf,sizeof(buf)); + }); + } + break; + + case 0x03: // Power off + { + dispatch_sync(Queue, ^{ + unsigned char buf[] = {0x02, 0x02}; + Device_Send(&this->device, buf, sizeof(buf)); + }); + } + break; +#endif + default: + fprintf(stderr, "XboxOneBTController FF plugin: Unknown escape (%i)\n", (int)escape->dwCommand); + return FFERR_UNSUPPORTED; + } + return FF_OK; +} + +void FeedbackXBOBT::SetForce(LONG LeftLevel, LONG RightLevel, LONG ltLevel, LONG rtLevel) +{ + //fprintf(stderr, "LS: %d; RS: %d\n", (unsigned char)MIN( 255, LeftLevel * Gain / 10000 ), (unsigned char)MIN( 255, RightLevel * Gain / 10000 )); + XboxOneBluetoothReport_t report = {0}; + report.reportID = 0x03; + report.activationMask = 0x0f; + report.ltMagnitude = (unsigned char)min(SCALE_MAX, ltLevel * (LONG)Gain / 10000 ); + report.rtMagnitude = (unsigned char)min(SCALE_MAX, rtLevel * (LONG)Gain / 10000 ); + report.leftMagnitude = (unsigned char)min(SCALE_MAX, LeftLevel * (LONG)Gain / 10000 ); + report.rightMagnitude = (unsigned char)min(SCALE_MAX, RightLevel * (LONG)Gain / 10000 ); + report.duration = 0x7f; + report.loopCount = 10; + + if (!Manual) { + IOReturn retVal = IOHIDDeviceSetReport(device, kIOHIDReportTypeOutput, report.reportID, (const uint8_t*)&report, sizeof(XboxOneBluetoothReport_t)); + if (retVal != 0) { + printf("IOHIDDeviceSetReport returned %d (system %d, subsystem %d, code %d)\n", retVal, err_get_system(retVal), err_get_sub(retVal), err_get_code(retVal)); + } + } +} + +void FeedbackXBOBT::EffectProc( void *params ) +{ + FeedbackXBOBT *cThis = (FeedbackXBOBT *)params; + + LONG LeftLevel = 0; + LONG RightLevel = 0; + LONG ltLevel = 0; + LONG rtLevel = 0; + LONG Gain = cThis->Gain; + LONG CalcResult = 0; + + if (cThis->Actuator == true) + { + for (FeedbackXBOEffectIterator effectIterator = cThis->EffectList.begin(); effectIterator != cThis->EffectList.end(); ++effectIterator) + { + if(((CurrentTimeUsingMach() - cThis->LastTime)*1000*1000) >= effectIterator->DiEffect.dwSamplePeriod) { + CalcResult = effectIterator->Calc(&LeftLevel, &RightLevel, <Level, &rtLevel); + } + } + } + + if ((cThis->PrvLeftLevel != LeftLevel || cThis->PrvRightLevel != RightLevel) && (CalcResult != -1)) + { + //fprintf(stderr, "PL: %d, PR: %d; L: %d, R: %d; \n", cThis->PrvLeftLevel, cThis->PrvRightLevel, LeftLevel, RightLevel); + cThis->SetForce((unsigned char)min(SCALE_MAX, LeftLevel * Gain / 10000),(unsigned char)min(SCALE_MAX, RightLevel * Gain / 10000 ), (unsigned char)min(SCALE_MAX, ltLevel * Gain / 10000), (unsigned char)min(SCALE_MAX, rtLevel * Gain / 10000)); + + cThis->PrvLeftLevel = LeftLevel; + cThis->PrvRightLevel = RightLevel; + } +} + +HRESULT FeedbackXBOBT::GetEffectStatus(FFEffectDownloadID EffectHandle, FFEffectStatusFlag *Status) +{ + dispatch_sync(Queue, ^{ + for (FeedbackXBOEffectIterator effectIterator = EffectList.begin() ; effectIterator != EffectList.end(); ++effectIterator) + { + if (effectIterator->Handle == EffectHandle) + { + *Status = effectIterator->Status; + break; + } + } + }); + return FF_OK; +} + +HRESULT FeedbackXBOBT::GetVersion(ForceFeedbackVersion *version) +{ + version->apiVersion.majorRev = kFFPlugInAPIMajorRev; + version->apiVersion.minorAndBugRev = kFFPlugInAPIMinorAndBugRev; + version->apiVersion.stage = kFFPlugInAPIStage; + version->apiVersion.nonRelRev = kFFPlugInAPINonRelRev; + version->plugInVersion.majorRev = FeedbackDriverVersionMajor; + version->plugInVersion.minorAndBugRev = FeedbackDriverVersionMinor; + version->plugInVersion.stage = FeedbackDriverVersionStage; + version->plugInVersion.nonRelRev = FeedbackDriverVersionNonRelRev; + return FF_OK; +} + +// static c->c++ glue functions +HRESULT FeedbackXBOBT::sQueryInterface(void *self, REFIID iid, LPVOID *ppv) +{ + FeedbackXBOBT *obj = ((XboxOneBTInterfaceMap *)self)->obj; + return obj->QueryInterface(iid, ppv); +} + +ULONG FeedbackXBOBT::sAddRef(void *self) +{ + FeedbackXBOBT *obj = ( (XboxOneBTInterfaceMap *) self)->obj; + return obj->AddRef(); +} + +ULONG FeedbackXBOBT::sRelease(void *self) +{ + FeedbackXBOBT *obj = ( (XboxOneBTInterfaceMap *) self)->obj; + return obj->Release(); +} + +IOReturn FeedbackXBOBT::sProbe(void *self, CFDictionaryRef propertyTable, io_service_t service, SInt32 *order) +{ + return getThis(self)->Probe(propertyTable, service, order); +} + +IOReturn FeedbackXBOBT::sStart(void *self, CFDictionaryRef propertyTable, io_service_t service) +{ + return getThis(self)->Start(propertyTable, service); +} + +IOReturn FeedbackXBOBT::sStop(void *self) +{ + return getThis(self)->Stop(); +} + +HRESULT FeedbackXBOBT::sGetVersion(void * self, ForceFeedbackVersion * version) +{ + return FeedbackXBOBT::getThis(self)->GetVersion(version); +} + +HRESULT FeedbackXBOBT::sInitializeTerminate(void * self, NumVersion forceFeedbackAPIVersion, io_object_t hidDevice, boolean_t begin) +{ + return FeedbackXBOBT::getThis(self)->InitializeTerminate(forceFeedbackAPIVersion, hidDevice, begin); +} + +HRESULT FeedbackXBOBT::sDestroyEffect(void * self, FFEffectDownloadID downloadID) +{ + return FeedbackXBOBT::getThis(self)->DestroyEffect(downloadID); +} + +HRESULT FeedbackXBOBT::sDownloadEffect(void * self, CFUUIDRef effectType, FFEffectDownloadID *pDownloadID, FFEFFECT * pEffect, FFEffectParameterFlag flags) +{ + return FeedbackXBOBT::getThis(self)->DownloadEffect(effectType, pDownloadID, pEffect, flags); +} + +HRESULT FeedbackXBOBT::sEscape(void * self, FFEffectDownloadID downloadID, FFEFFESCAPE * pEscape) +{ + return FeedbackXBOBT::getThis(self)->Escape(downloadID, pEscape); +} + +HRESULT FeedbackXBOBT::sGetEffectStatus(void * self, FFEffectDownloadID downloadID, FFEffectStatusFlag * pStatusCode) +{ + return FeedbackXBOBT::getThis(self)->GetEffectStatus(downloadID, pStatusCode); +} + +HRESULT FeedbackXBOBT::sGetForceFeedbackState(void * self, ForceFeedbackDeviceState * pDeviceState) +{ + return FeedbackXBOBT::getThis(self)->GetForceFeedbackState(pDeviceState); +} + +HRESULT FeedbackXBOBT::sGetForceFeedbackCapabilities(void * self, FFCAPABILITIES * capabilities) +{ + return FeedbackXBOBT::getThis(self)->GetForceFeedbackCapabilities(capabilities); +} + +HRESULT FeedbackXBOBT::sSendForceFeedbackCommand(void * self, FFCommandFlag state) +{ + return FeedbackXBOBT::getThis(self)->SendForceFeedbackCommand(state); +} + +HRESULT FeedbackXBOBT::sSetProperty(void * self, FFProperty property, void * pValue) +{ + return FeedbackXBOBT::getThis(self)->SetProperty(property, pValue); +} + +HRESULT FeedbackXBOBT::sStartEffect(void * self, FFEffectDownloadID downloadID, FFEffectStartFlag mode, UInt32 iterations) +{ + return FeedbackXBOBT::getThis(self)->StartEffect(downloadID, mode, iterations); +} + +HRESULT FeedbackXBOBT::sStopEffect(void * self, UInt32 downloadID) +{ + return FeedbackXBOBT::getThis(self)->StopEffect(downloadID); +} + +// External factory function +extern "C" void* FeedbackXBOBTFactory(CFAllocatorRef allocator, CFUUIDRef typeID) +{ + void* result = NULL; + if (CFEqual(typeID, kIOForceFeedbackLibTypeID)) + result = (void*)FeedbackXBOBT::Alloc(); + return result; +} + diff --git a/XBOBTFF/FFDriver.h b/XBOBTFF/FFDriver.h new file mode 100644 index 00000000..ac7a5361 --- /dev/null +++ b/XBOBTFF/FFDriver.h @@ -0,0 +1,131 @@ +// +// FFDriver.h +// XBoxBTFFPlug +// +// Created by C.W. Betts on 9/20/17. +// Copyright © 2017 C.W. Betts. All rights reserved. +// + +#ifndef FFDriver_h +#define FFDriver_h + +#include +#include +#include +#include +#include +#include "FeedbackXBOEffect.hpp" + +// 0F793F56-8C17-4BA0-9201-D52FEC6C2702 +#define BTFFPLUGINTERFACE CFUUIDGetConstantUUIDWithBytes(kCFAllocatorSystemDefault, 0x0F, 0x79, 0x3F, 0x56, 0x8C, 0x17, 0x4B, 0xA0, 0x92, 0x01, 0xD5, 0x2F, 0xEC, 0x6C, 0x27, 0x02) + +#define FeedbackDriverVersionMajor 1 +#define FeedbackDriverVersionMinor 0 +#define FeedbackDriverVersionStage developStage +#define FeedbackDriverVersionNonRelRev 0 + +class FeedbackXBOBT : IUnknown +{ +public: + // constructor/destructor + FeedbackXBOBT(void); + virtual ~FeedbackXBOBT(void); + +private: + //disable copy constructor + FeedbackXBOBT(FeedbackXBOBT &src); + void operator = (FeedbackXBOBT &src); + + UInt32 fRefCount; + + typedef struct _Xbox360InterfaceMap + { + IUnknownVTbl *pseudoVTable; + FeedbackXBOBT *obj; + } XboxOneBTInterfaceMap; + + // IOCFPlugin interfacing variables and functions +public: + static void** Alloc(void); + + // static functions called by the ForceFeedback API + static HRESULT sQueryInterface(void *self, REFIID iid, LPVOID *ppv); + static ULONG sAddRef(void *self); + static ULONG sRelease(void *self); + + static IOReturn sProbe ( void * self, CFDictionaryRef propertyTable, io_service_t service, SInt32 * order ); + static IOReturn sStart ( void * self, CFDictionaryRef propertyTable, io_service_t service ); + static IOReturn sStop ( void * self ); + + static HRESULT sGetVersion(void * interface, ForceFeedbackVersion * version); + static HRESULT sInitializeTerminate(void * interface, NumVersion forceFeedbackAPIVersion, io_object_t hidDevice, boolean_t begin ); + static HRESULT sDestroyEffect(void * interface, FFEffectDownloadID downloadID ); + static HRESULT sDownloadEffect( void * interface, CFUUIDRef effectType, FFEffectDownloadID *pDownloadID, FFEFFECT * pEffect, FFEffectParameterFlag flags ); + static HRESULT sEscape( void * interface, FFEffectDownloadID downloadID, FFEFFESCAPE * pEscape ); + static HRESULT sGetEffectStatus( void * interface, FFEffectDownloadID downloadID, FFEffectStatusFlag * pStatusCode ); + static HRESULT sGetForceFeedbackState( void * interface, ForceFeedbackDeviceState * pDeviceState ); + static HRESULT sGetForceFeedbackCapabilities( void * interface, FFCAPABILITIES *capabilities ); + static HRESULT sSendForceFeedbackCommand( void * interface, FFCommandFlag state ); + static HRESULT sSetProperty( void * interface, FFProperty property, void * pValue ); + static HRESULT sStartEffect( void * interface, FFEffectDownloadID downloadID, FFEffectStartFlag mode, UInt32 iterations ); + static HRESULT sStopEffect( void * interface, UInt32 downloadID ); + + virtual HRESULT QueryInterface(REFIID iid, LPVOID* ppv); + virtual ULONG AddRef(void); + virtual ULONG Release(void); + +private: + typedef std::vector FeedbackXBOEffectVector; + typedef FeedbackXBOEffectVector::iterator FeedbackXBOEffectIterator; + // helper function + static inline FeedbackXBOBT *getThis (void *self) { return (FeedbackXBOBT *) ((XboxOneBTInterfaceMap *) self)->obj; } + + // interfacing + XboxOneBTInterfaceMap iIOCFPlugInInterface; + XboxOneBTInterfaceMap iIOForceFeedbackDeviceInterface; + IOHIDDeviceRef device; + + // GCD queue and timer + dispatch_queue_t Queue; + dispatch_source_t Timer; + + // effects handling + FeedbackXBOEffectVector EffectList; + UInt32 EffectIndex; + + DWORD Gain; + bool Actuator; + + LONG PrvLeftLevel, PrvRightLevel; + bool Stopped; + bool Paused; + bool Manual; + double LastTime; + double PausedTime; + CFUUIDRef FactoryID; + + void SetForce(LONG LeftLevel, LONG RightLevel, LONG ltLevel, LONG rtLevel); + + // event loop func + static void EffectProc( void *params ); + + // actual member functions ultimately called by the FF API (through the static functions) + virtual IOReturn Probe ( CFDictionaryRef propertyTable, io_service_t service, SInt32 * order ); + virtual IOReturn Start ( CFDictionaryRef propertyTable, io_service_t service ); + virtual IOReturn Stop ( void ); + + virtual HRESULT GetVersion(ForceFeedbackVersion * version); + virtual HRESULT InitializeTerminate(NumVersion forceFeedbackAPIVersion, io_object_t hidDevice, boolean_t begin); + virtual HRESULT DestroyEffect(FFEffectDownloadID downloadID); + virtual HRESULT DownloadEffect(CFUUIDRef effectType, FFEffectDownloadID *pDownloadID, FFEFFECT * pEffect, FFEffectParameterFlag flags); + virtual HRESULT Escape(FFEffectDownloadID downloadID, FFEFFESCAPE * pEscape); + virtual HRESULT GetEffectStatus(FFEffectDownloadID downloadID, FFEffectStatusFlag * pStatusCode); + virtual HRESULT GetForceFeedbackState(ForceFeedbackDeviceState * pDeviceState); + virtual HRESULT GetForceFeedbackCapabilities(FFCAPABILITIES *capabilities); + virtual HRESULT SendForceFeedbackCommand(FFCommandFlag state); + virtual HRESULT SetProperty(FFProperty property, void * pValue); + virtual HRESULT StartEffect(FFEffectDownloadID downloadID, FFEffectStartFlag mode, UInt32 iterations); + virtual HRESULT StopEffect(UInt32 downloadID); +}; + +#endif /* FFDriver_h */ diff --git a/XBOBTFF/FeedbackXBOEffect.cpp b/XBOBTFF/FeedbackXBOEffect.cpp new file mode 100644 index 00000000..ddb0b138 --- /dev/null +++ b/XBOBTFF/FeedbackXBOEffect.cpp @@ -0,0 +1,281 @@ +// +// FeedbackXBOEffect.cpp +// XBOBTFF +// +// Created by C.W. Betts on 9/20/17. +// Copyright © 2017 GitHub. All rights reserved. +// + +#include "FeedbackXBOEffect.hpp" + +using std::max; +using std::min; + +//---------------------------------------------------------------------------------------------- +// CEffect +//---------------------------------------------------------------------------------------------- +FeedbackXBOEffect::FeedbackXBOEffect() : Type(NULL), Status(0), PlayCount(0), +StartTime(0), Index(0), LastTime(0), Handle(0), DiEffect({0}), DiEnvelope({0}), +DiCustomForce({0}), DiConstantForce({0}), DiPeriodic({0}), DiRampforce({0}) +{ + +} + +FeedbackXBOEffect::FeedbackXBOEffect(FFEffectDownloadID theHand) : FeedbackXBOEffect() +{ + Handle = theHand; +} + +FeedbackXBOEffect::FeedbackXBOEffect(const FeedbackXBOEffect &src) : Type(src.Type), +Handle(src.Handle), Status(src.Status), PlayCount(src.PlayCount), +StartTime(src.StartTime), Index(src.Index), LastTime(src.LastTime) +{ + memcpy(&DiEffect, &src.DiEffect, sizeof(FFEFFECT)); + memcpy(&DiEnvelope, &src.DiEnvelope, sizeof(FFENVELOPE)); + memcpy(&DiCustomForce, &src.DiCustomForce, sizeof(FFCUSTOMFORCE)); + memcpy(&DiConstantForce, &src.DiConstantForce, sizeof(FFCONSTANTFORCE)); + memcpy(&DiPeriodic, &src.DiPeriodic, sizeof(FFPERIODIC)); + memcpy(&DiRampforce, &src.DiRampforce, sizeof(FFRAMPFORCE)); +} + +//---------------------------------------------------------------------------------------------- +// Calc +//---------------------------------------------------------------------------------------------- +LONG FeedbackXBOEffect::Calc(LONG *LeftLevel, LONG *RightLevel, LONG *ltLevel, LONG *rtLevel) +{ + CFTimeInterval Duration = 0; + if(DiEffect.dwDuration != FF_INFINITE) { + Duration = max(1., DiEffect.dwDuration / 1000.) / 1000.; + } else { + Duration = DBL_MAX; + } + double BeginTime = StartTime + ( DiEffect.dwStartDelay / 1000. / 1000.); + double EndTime = DBL_MAX; + if (PlayCount != -1) + { + EndTime = BeginTime + Duration * PlayCount; + } + double CurrentTime = CurrentTimeUsingMach(); + + if (Status == FFEGES_PLAYING && BeginTime <= CurrentTime && CurrentTime <= EndTime) + { + // Used for force calculation + LONG NormalLevel; + LONG WorkLeftLevel; + LONG WorkRightLevel; + LONG WorkLTLevel; + LONG WorkRTLevel; + + // Used for envelope calculation + LONG NormalRate; + LONG AttackLevel; + LONG FadeLevel; + + CalcEnvelope((ULONG)(Duration*1000) + ,(ULONG)(fmod(CurrentTime - BeginTime, Duration)*1000) + ,&NormalRate + ,&AttackLevel + ,&FadeLevel); + + // CustomForce allows setting each channel separately + if(CFEqual(Type, kFFEffectType_CustomForce_ID)) { + if((CurrentTimeUsingMach() - LastTime)*1000*1000 < DiCustomForce.dwSamplePeriod) { + return -1; + } + else { + if (DiCustomForce.cChannels == 2) { + WorkLeftLevel = ((DiCustomForce.rglForceData[2*Index] * NormalRate + AttackLevel + FadeLevel) / 100) * DiEffect.dwGain / 10000; + WorkRightLevel = ((DiCustomForce.rglForceData[2*Index + 1] * NormalRate + AttackLevel + FadeLevel) / 100) * DiEffect.dwGain / 10000; + WorkLTLevel = 0; + WorkRTLevel = 0; + //fprintf(stderr, "L:%d; R:%d\n", WorkLeftLevel, WorkRightLevel); + Index = (Index + 1) % (DiCustomForce.cSamples/2); + LastTime = CurrentTimeUsingMach(); + } else { + WorkLeftLevel = ((DiCustomForce.rglForceData[4*Index] * NormalRate + AttackLevel + FadeLevel) / 100) * DiEffect.dwGain / 10000; + WorkRightLevel = ((DiCustomForce.rglForceData[4*Index + 1] * NormalRate + AttackLevel + FadeLevel) / 100) * DiEffect.dwGain / 10000; + WorkLTLevel = ((DiCustomForce.rglForceData[4*Index + 2] * NormalRate + AttackLevel + FadeLevel) / 100) * DiEffect.dwGain / 10000; + WorkRTLevel = ((DiCustomForce.rglForceData[4*Index + 3] * NormalRate + AttackLevel + FadeLevel) / 100) * DiEffect.dwGain / 10000; + //fprintf(stderr, "L:%d; R:%d\n", WorkLeftLevel, WorkRightLevel); + Index = (Index + 1) % (DiCustomForce.cSamples/4); + LastTime = CurrentTimeUsingMach(); + } + } + } + // Regular commands treat controller as a single output (both channels are together as one) + else { + CalcForce( + (ULONG)(Duration*1000) + ,(ULONG)(fmod(CurrentTime - BeginTime, Duration)*1000) + ,NormalRate + ,AttackLevel + ,FadeLevel + ,&NormalLevel ); + //fprintf(stderr, "DeltaT %f\n", CurrentTime - BeginTime); + //fprintf(stderr, "Duration %f; NormalRate: %d; AttackLevel: %d; FadeLevel: %d\n", Duration, NormalRate, AttackLevel, FadeLevel); + + WorkLeftLevel = (NormalLevel > 0) ? NormalLevel : -NormalLevel; + WorkRightLevel = (NormalLevel > 0) ? NormalLevel : -NormalLevel; + WorkLTLevel = 0; + WorkRTLevel = 0; + } + WorkLeftLevel = min( SCALE_MAX, WorkLeftLevel * SCALE_MAX / 10000 ); + WorkRightLevel = min( SCALE_MAX, WorkRightLevel * SCALE_MAX / 10000 ); + WorkLTLevel = min( SCALE_MAX, WorkLTLevel * SCALE_MAX / 10000 ); + WorkRTLevel = min( SCALE_MAX, WorkRTLevel * SCALE_MAX / 10000 ); + + *LeftLevel = *LeftLevel + WorkLeftLevel; + *RightLevel = *RightLevel + WorkRightLevel; + *ltLevel = *ltLevel + WorkLTLevel; + *rtLevel = *rtLevel + WorkRTLevel; + } + return 0; +} + +//---------------------------------------------------------------------------------------------- +// CalcEnvelope +//---------------------------------------------------------------------------------------------- +void FeedbackXBOEffect::CalcEnvelope(ULONG Duration, ULONG CurrentPos, LONG *NormalRate, LONG *AttackLevel, LONG *FadeLevel) +{ + if( ( DiEffect.dwFlags & FFEP_ENVELOPE ) && DiEffect.lpEnvelope != NULL ) + { + // Calculate attack factor + LONG AttackRate = 0; + ULONG AttackTime = max( (DWORD)1, DiEnvelope.dwAttackTime / 1000 ); + if (CurrentPos < AttackTime) + { + AttackRate = ( AttackTime - CurrentPos ) * 100 / AttackTime; + } + + // Calculate fade factor + LONG FadeRate = 0; + ULONG FadeTime = max( (DWORD)1, DiEnvelope.dwFadeTime / 1000 ); + ULONG FadePos = Duration - FadeTime; + if (FadePos < CurrentPos) + { + FadeRate = ( CurrentPos - FadePos ) * 100 / FadeTime; + } + + *NormalRate = 100 - AttackRate - FadeRate; + *AttackLevel = DiEnvelope.dwAttackLevel * AttackRate; + *FadeLevel = DiEnvelope.dwFadeLevel * FadeRate; + } else { + *NormalRate = 100; + *AttackLevel = 0; + *FadeLevel = 0; + } +} + +void FeedbackXBOEffect::CalcForce(ULONG Duration, ULONG CurrentPos, LONG NormalRate, LONG AttackLevel, LONG FadeLevel, LONG * NormalLevel) +{ + LONG Magnitude = 0; + LONG Period; + LONG R; + LONG Rate; + + if (CFEqual(Type, kFFEffectType_ConstantForce_ID)) { + Magnitude = DiConstantForce.lMagnitude; + Magnitude = ( Magnitude * NormalRate + AttackLevel + FadeLevel ) / 100; + } + else if (CFEqual(Type, kFFEffectType_Square_ID)) { + Period = max( (DWORD)1, ( DiPeriodic.dwPeriod / 1000 ) ); + R = ( CurrentPos%Period) * 360 / Period; + R = ( R + ( DiPeriodic.dwPhase / 100 ) ) % 360; + + Magnitude = DiPeriodic.dwMagnitude; + Magnitude = ( Magnitude * NormalRate + AttackLevel + FadeLevel ) / 100; + + if (180 <= R) + { + Magnitude = Magnitude * -1; + } + + Magnitude = Magnitude + DiPeriodic.lOffset; + } + else if (CFEqual(Type, kFFEffectType_Sine_ID)) { + Period = max( (DWORD)1, ( DiPeriodic.dwPeriod / 1000 ) ); + R = (CurrentPos%Period) * 360 / Period; + R = ( R + ( DiPeriodic.dwPhase / 100 ) ) % 360; + + Magnitude = DiPeriodic.dwMagnitude; + Magnitude = ( Magnitude * NormalRate + AttackLevel + FadeLevel ) / 100; + + Magnitude = ( int)( Magnitude * sin( R * M_PI / 180.0 ) ); + + Magnitude = Magnitude + DiPeriodic.lOffset; + } + else if (CFEqual(Type, kFFEffectType_Triangle_ID)) { + Period = max( (DWORD)1, ( DiPeriodic.dwPeriod / 1000 ) ); + R = (CurrentPos%Period) * 360 / Period; + R = ( R + ( DiPeriodic.dwPhase / 100 ) ) % 360; + + Magnitude = DiPeriodic.dwMagnitude; + Magnitude = ( Magnitude * NormalRate + AttackLevel + FadeLevel ) / 100; + + if (0 <= R && R < 90) + { + Magnitude = -Magnitude * ( 90 - R ) / 90; + } + if (90 <= R && R < 180) + { + Magnitude = Magnitude * ( R - 90 ) / 90; + } + if (180 <= R && R < 270) + { + Magnitude = Magnitude * ( 90 - ( R - 180 ) ) / 90; + } + if (270 <= R && R < 360) + { + Magnitude = -Magnitude * ( R - 270 ) / 90; + } + + Magnitude = Magnitude + DiPeriodic.lOffset; + } + else if(CFEqual(Type, kFFEffectType_SawtoothUp_ID)) { + Period = max( (DWORD)1, ( DiPeriodic.dwPeriod / 1000 ) ); + R = (CurrentPos%Period) * 360 / Period; + R = ( R + ( DiPeriodic.dwPhase / 100 ) ) % 360; + + Magnitude = DiPeriodic.dwMagnitude; + Magnitude = ( Magnitude * NormalRate + AttackLevel + FadeLevel ) / 100; + + if (0 <= R && R < 180) + { + Magnitude = -Magnitude * ( 180 - R ) / 180; + } + if (180 <= R && R < 360) + { + Magnitude = Magnitude * ( R - 180 ) / 180; + } + + Magnitude = Magnitude + DiPeriodic.lOffset; + } + else if (CFEqual(Type, kFFEffectType_SawtoothDown_ID)) { + Period = max( (DWORD)1, ( DiPeriodic.dwPeriod / 1000 ) ); + R = (CurrentPos%Period) * 360 / Period; + R = ( R + ( DiPeriodic.dwPhase / 100 ) ) % 360; + + Magnitude = DiPeriodic.dwMagnitude; + Magnitude = ( Magnitude * NormalRate + AttackLevel + FadeLevel ) / 100; + if( 0 <= R && R < 180 ) + { + Magnitude = Magnitude * ( 180 - R ) / 180; + } + if( 180 <= R && R < 360 ) + { + Magnitude = -Magnitude * ( R - 180 ) / 180; + } + + Magnitude = Magnitude + DiPeriodic.lOffset; + } + else if (CFEqual(Type, kFFEffectType_RampForce_ID)) { + Rate = ( Duration - CurrentPos ) * 100 + / Duration;//MAX( 1, DiEffect.dwDuration / 1000 ); + + Magnitude = ( DiRampforce.lStart * Rate + + DiRampforce.lEnd * ( 100 - Rate ) ) / 100; + Magnitude = ( Magnitude * NormalRate + AttackLevel + FadeLevel ) / 100; + } + + *NormalLevel = Magnitude * (LONG)DiEffect.dwGain / 10000; +} diff --git a/XBOBTFF/FeedbackXBOEffect.hpp b/XBOBTFF/FeedbackXBOEffect.hpp new file mode 100644 index 00000000..96974a8c --- /dev/null +++ b/XBOBTFF/FeedbackXBOEffect.hpp @@ -0,0 +1,69 @@ +// +// FeedbackXBOEffect.hpp +// XBOBTFF +// +// Created by C.W. Betts on 9/20/17. +// Copyright © 2017 GitHub. All rights reserved. +// + +#ifndef FeedbackXBOEffect_hpp +#define FeedbackXBOEffect_hpp + +#include +#include +#include +#include + +//---------------------------------------------------------------------------------------------- +// Effects +//---------------------------------------------------------------------------------------------- + +#define CONSTANT_FORCE 0x00 +#define RAMP_FORCE 0x01 +#define SQUARE 0x02 +#define SINE 0x03 +#define TRIANGLE 0x04 +#define SAWTOOTH_UP 0x05 +#define SAWTOOTH_DOWN 0x06 +#define SPRING 0x07 +#define DAMPER 0x08 +#define INERTIA 0x09 +#define FRICTION 0x0A +#define CUSTOM_FORCE 0x0B + +#define SCALE_MAX (LONG)101 + +double CurrentTimeUsingMach(); + +class FeedbackXBOEffect +{ +public: + FeedbackXBOEffect(FFEffectDownloadID theHand); + FeedbackXBOEffect(const FeedbackXBOEffect &src); + + LONG Calc(LONG *LeftLevel, LONG *RightLevel, LONG *ltLevel, LONG *rtLevel); + + CFUUIDRef Type; + FFEffectDownloadID Handle; + + FFEFFECT DiEffect; + FFENVELOPE DiEnvelope; + FFCONSTANTFORCE DiConstantForce; + FFCUSTOMFORCE DiCustomForce; + FFPERIODIC DiPeriodic; + FFRAMPFORCE DiRampforce; + + DWORD Status; + DWORD PlayCount; + double StartTime; + + double LastTime; + DWORD Index; + +private: + FeedbackXBOEffect(); + void CalcEnvelope(ULONG Duration, ULONG CurrentPos, LONG *NormalRate, LONG *AttackLevel, LONG *FadeLevel); + void CalcForce(ULONG Duration, ULONG CurrentPos, LONG NormalRate, LONG AttackLevel, LONG FadeLevel, LONG * NormalLevel); +}; + +#endif /* FeedbackXBOEffect_hpp */ diff --git a/XBOBTFF/Info.plist b/XBOBTFF/Info.plist new file mode 100644 index 00000000..a86914e6 --- /dev/null +++ b/XBOBTFF/Info.plist @@ -0,0 +1,40 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundleSignature + ???? + CFBundlePackageType + BNDL + CFBundleShortVersionString + $(CURRENT_PROJECT_VERSION) + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + CFPlugInDynamicRegistration + + CFPlugInFactories + + 0F793F56-8C17-4BA0-9201-D52FEC6C2702 + FeedbackXBOBTFactory + + CFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + + 0F793F56-8C17-4BA0-9201-D52FEC6C2702 + + + NSHumanReadableCopyright + Copyright © 2017 C.W. Betts. All rights reserved. + + diff --git a/XBOBTFF/XBoxOneBTHID.h b/XBOBTFF/XBoxOneBTHID.h new file mode 100644 index 00000000..5ea1f812 --- /dev/null +++ b/XBOBTFF/XBoxOneBTHID.h @@ -0,0 +1,38 @@ +// +// XBoxOneBTHID.h +// XBoxBTFF +// +// Created by C.W. Betts on 9/20/17. +// Copyright © 2017 C.W. Betts. All rights reserved. +// + +#ifndef XBoxOneBTHID_h +#define XBoxOneBTHID_h + +#include +#include + +#pragma pack(push, 1) + +typedef CF_OPTIONS(uint8_t, XBOBTActivationMask) { + XBOBTActivationMaskRightRumble = 1 << 0, + XBOBTActivationMaskLeftRumble = 1 << 1, + XBOBTActivationMaskRTRumble = 1 << 2, + XBOBTActivationMaskLTRumble = 1 << 3, +}; + +struct XboxOneBluetoothReport_t { + uint8_t reportID; //!< 0x03 + XBOBTActivationMask activationMask; + uint8_t ltMagnitude; //!< 0x00 to 0x65, 0x65 is default + uint8_t rtMagnitude; + uint8_t leftMagnitude; + uint8_t rightMagnitude; + uint8_t duration; //!< time in ms, 255 = 2.55s + uint8_t startDelay; + uint8_t loopCount; +}; + +#pragma pack(pop) + +#endif /* XBoxOneBTHID_h */ diff --git a/XboxOneBluetooth/Info.plist b/XboxOneBluetooth/Info.plist new file mode 100644 index 00000000..e02350a1 --- /dev/null +++ b/XboxOneBluetooth/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + KEXT + CFBundleShortVersionString + $(CURRENT_PROJECT_VERSION) + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + IOKitPersonalities + + XboxOneBluetooth + + CFBundleIdentifier + com.apple.driver.IOBluetoothHIDDriver + IOCFPlugInTypes + + F4545CE5-BF5B-11D6-A4BB-0003933E3E3E + XboxOneBluetooth.kext/Contents/PlugIns/XBOBTFF.plugin + + IOClass + IOBluetoothHIDDriver + IOProbeScore + 200 + IOProviderClass + IOBluetoothL2CAPChannel + PSM + 17 + IOKitDebug + 65535 + ProductID + 765 + VendorID + 1118 + + + NSHumanReadableCopyright + Copyright © 2016 GitHub. All rights reserved. + OSBundleLibraries + + com.apple.driver.IOBluetoothHIDDriver + 4.1.7f2 + com.apple.iokit.IOHIDFamily + 1.8.1 + com.apple.kpi.iokit + 12.5 + com.apple.kpi.libkern + 12.5 + + + diff --git a/build.sh b/build.sh index fa1bda8b..4dd3b534 100755 --- a/build.sh +++ b/build.sh @@ -1,8 +1,13 @@ #!/bin/bash + +DEV_NAME=`echo | grep DEVELOPER_NAME DeveloperSettings.xcconfig` +DEV_TEAM=`echo | grep DEVELOPMENT_TEAM DeveloperSettings.xcconfig` +CERT_ID="${DEV_NAME//\DEVELOPER_NAME = } (${DEV_TEAM//\DEVELOPMENT_TEAM = })" + mkdir -p build zip -r build/360ControllerSource.zip * -x "build*" -xcrun xcodebuild -configuration Release -target "Whole Driver" +xcrun xcodebuild -configuration Release -target "Whole Driver" -xcconfig "DeveloperSettings.xcconfig" OTHER_CODE_SIGN_FLAGS="--timestamp --options=runtime" if [ $? -ne 0 ] then echo "******** BUILD FAILED ********" @@ -10,9 +15,9 @@ if [ $? -ne 0 ] fi cd Install360Controller -packagesbuild -v Install360Controller.pkgproj +packagesbuild -v Install360Controller.pkgproj --identity "Developer ID Installer: ""${CERT_ID}" mv build 360ControllerInstall -hdiutil create -srcfolder 360ControllerInstall -format UDZO ../build/360ControllerInstall.dmg +hdiutil create -srcfolder 360ControllerInstall -fs HFS+ -format UDZO ../build/360ControllerInstall.dmg mv 360ControllerInstall build cd .. echo "** File contents **" @@ -21,15 +26,15 @@ xcrun lipo -info build/Release/360Controller.kext/Contents/PlugIns/Feedback360.p xcrun lipo -info build/Release/360Daemon.app/Contents/MacOS/360Daemon xcrun lipo -info build/Release/Pref360Control.prefPane/Contents/MacOS/Pref360Control xcrun lipo -info build/Release/Pref360Control.prefPane/Contents/Resources/DriverTool -xcrun lipo -info build/Release/WirelessGamingReceiver.kext/Contents/MacOS/WirelessGamingReceiver -xcrun lipo -info build/Release/Wireless360Controller.kext/Contents/MacOS/Wireless360Controller +# xcrun lipo -info build/Release/WirelessGamingReceiver.kext/Contents/MacOS/WirelessGamingReceiver +# xcrun lipo -info build/Release/Wireless360Controller.kext/Contents/MacOS/Wireless360Controller echo "** File signatures **" xcrun spctl -a -v build/Release/360Controller.kext xcrun spctl -a -v build/Release/360Controller.kext/Contents/PlugIns/Feedback360.plugin xcrun spctl -a -v build/Release/360Daemon.app/Contents/MacOS/360Daemon xcrun spctl -a -v build/Release/Pref360Control.prefPane xcrun spctl -a -v build/Release/Pref360Control.prefPane/Contents/Resources/DriverTool -xcrun spctl -a -v build/Release/WirelessGamingReceiver.kext -xcrun spctl -a -v build/Release/Wireless360Controller.kext +# xcrun spctl -a -v build/Release/WirelessGamingReceiver.kext +# xcrun spctl -a -v build/Release/Wireless360Controller.kext xcrun spctl -a -v --type install Install360Controller/build/Install360Controller.pkg echo "*** DONE ***" diff --git a/issue_template.md b/issue_template.md new file mode 100644 index 00000000..0d41d331 --- /dev/null +++ b/issue_template.md @@ -0,0 +1,26 @@ +### Type of Controller +Replace this text with: Original Xbox, Xbox 360, Xbox One, All or N/A + +### OS Version +Replace this text with the version of macOS that you are running + +### Driver Version +Replate this text with the version or versions of the driver that you are using or have tested + +### Connection Method +Replace this text with: Wired, Wireless Adapter, Bluetooth, N/A or more specific method if applicable + +### Device Name and Info +(If you don't know this information, please refer to the README for how to find it. Enter N/A if not applicable) +>Device Name: +
Product ID: +
Vendor ID: + +### Response of Controller +Replace this text with information on how the physical controller reacts. Does the guide button light up? Does it vibrate? Etc. + +### Response in Preference Pane +Replace this text with information about the controller's reaction in the preference pane. Does the controller appear in the preference pane? Do all of the buttons, joysticks, and triggers act as expected? + +### Detailed Explaination of Issue +Replace this text with a detailed explaination of your issue. Simply saying "it doesn't work" is a quick way to ensure that your issue is never fixed. Without detailed information on your specific issue, we cannot fix your issue. Including as much information as possible in this section increases the likelyhood of getting your issue quickly and effectively resolved.