-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathds3activate.c
138 lines (129 loc) · 3.63 KB
/
ds3activate.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//
// Copyright (c) 2021 vit9696. All Rights Reserved.
// SPDX-License-Identifier: BSD-3-Clause
//
#include <IOKit/hid/IOHIDLib.h>
#include <CoreFoundation/CoreFoundation.h>
#include <stdio.h>
#include <stdlib.h>
static void activate_gamepad(void *device) {
IOReturn r = IOHIDDeviceOpen(device, kIOHIDOptionsTypeNone);
if (r != kIOReturnSuccess) {
printf(" Failed to open device - %d\n", r);
return;
}
uint8_t controlBlob[] = { 0x42, 0x0C, 0x00, 0x00};
IOHIDDeviceSetReport(device, kIOHIDReportTypeFeature, 0xF4, controlBlob, sizeof(controlBlob));
printf(" Activating device...\n");
sleep(1);
uint8_t rumbleBlob[] = {
0x01,
0x00,
0x00,
0x00,
0x00,
0x00, // rumble values [0x00, right-timeout, right-force, left-timeout, left-force]
0x00,
0x00, // Gyro
0x00,
0x00,
0x00, // 0x02=LED1 .. 0x10=LED4
/*
* the total time the led is active (0xff means forever)
* | duty_length: how long a cycle is in deciseconds:
* | | (0 means "blink very fast")
* | | ??? (Maybe a phase shift or duty_length multiplier?)
* | | | % of duty_length led is off (0xff means 100%)
* | | | | % of duty_length led is on (0xff is 100%)
* | | | | |
* 0xff, 0x27, 0x10, 0x00, 0x32,
*/
0xff,
0x27,
0x10,
0x00,
0x32, // LED 4
0xff,
0x27,
0x10,
0x00,
0x32, // LED 3
0xff,
0x27,
0x10,
0x00,
0x32, // LED 2
0xff,
0x27,
0x10,
0x00,
0x32, // LED 1
0x00,
0x00,
0x00,
0x00,
0x00,
// Necessary for Fake DS3
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
};
static const size_t RumbleLengthL = 4;
static const size_t RumblePowerL = 5;
static const size_t RumbleLengthR = 2;
static const size_t RumblePowerR = 3;
rumbleBlob[RumbleLengthL] = rumbleBlob[RumbleLengthR] = 80;
rumbleBlob[RumblePowerL] = 255;
rumbleBlob[RumblePowerR] = 1;
IOHIDDeviceSetReport(device, kIOHIDReportTypeOutput, 1, rumbleBlob, sizeof(rumbleBlob));
IOHIDDeviceClose(device, kIOHIDOptionsTypeNone);
printf(" Should be rumbling!\n");
}
int main() {
static const SInt32 VendorId = 0x054C;
static const SInt32 ProductId = 0x0268;
CFNumberRef vendorIdNum = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &VendorId);
CFNumberRef productIdNum = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &ProductId);
const void *keys[2] = {
CFSTR(kIOHIDVendorIDKey),
CFSTR(kIOHIDProductIDKey),
};
const void *values[2] = {
vendorIdNum,
productIdNum
};
IOHIDManagerRef manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
CFDictionaryRef matching = CFDictionaryCreate(NULL, keys, values, 2, NULL, NULL);
IOHIDManagerSetDeviceMatching(manager, matching);
CFSetRef deviceSet = IOHIDManagerCopyDevices(manager);
if (deviceSet != NULL) {
CFIndex count = CFSetGetCount(deviceSet);
if (count > 0) {
printf("Discovered %ld DualShock 3 gamepads\n", count);
void **gamepads = calloc(count, sizeof(void *));
CFSetGetValues(deviceSet, (const void **)gamepads);
for (CFIndex i = 0; i < count; i++) {
printf("Handling device %ld:\n", i);
activate_gamepad(gamepads[i]);
}
free(gamepads);
} else {
printf("No DualShock 3 gamepads found!\n");
}
CFRelease(deviceSet);
}
CFRelease(productIdNum);
CFRelease(vendorIdNum);
CFRelease(matching);
CFRelease(manager);
}