ObjFW  Check-in [5fe4c8c1bf]

Overview
Comment:ObjFWHID: Add support for DualShock 4 via evdev
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 5fe4c8c1bfc420b498e6db6d894653bc1e116180280518ac622f2debff2817e6
User & Date: js on 2024-06-09 01:34:53
Other Links: manifest | tags
Context
2024-06-09
01:59
ObjFWHID: Add support for Stadia controller check-in: 67c7e7c8ae user: js tags: trunk
01:34
ObjFWHID: Add support for DualShock 4 via evdev check-in: 5fe4c8c1bf user: js tags: trunk
2024-06-08
23:14
OHEvdevDualSense: Minor cleanup check-in: b67a849b51 user: js tags: trunk
Changes

Modified src/hid/Makefile from [fcd35a0ed7] to [60012a06af].

16
17
18
19
20
21
22
23

24
25

26
27
28
29
30
31
32
       OHGameControllerElement.m	\
       OHGameControllerProfile.m	\
       OHGamepad.m			\
       ${USE_SRCS_EVDEV}		\
       ${USE_SRCS_NINTENDO_3DS}		\
       ${USE_SRCS_NINTENDO_DS}		\
       ${USE_SRCS_XINPUT}
SRCS_EVDEV = OHEvdevDualSense.m		\

	     OHEvdevGameController.m	\
	     OHEvdevGamepad.m

SRCS_NINTENDO_3DS = OHNintendo3DSGameController.m	\
		    OHNintendo3DSGamepad.m
SRCS_NINTENDO_DS = OHNintendoDSGameController.m
SRCS_XINPUT = OHXInputGameController.m	\
	      OHXInputGamepad.m

INCLUDES := ${SRCS:.m=.h}	\







|
>
|
|
>







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
       OHGameControllerElement.m	\
       OHGameControllerProfile.m	\
       OHGamepad.m			\
       ${USE_SRCS_EVDEV}		\
       ${USE_SRCS_NINTENDO_3DS}		\
       ${USE_SRCS_NINTENDO_DS}		\
       ${USE_SRCS_XINPUT}
SRCS_EVDEV = OHEvdevDualSense.m			\
	     OHEvdevDualShock4.m		\
	     OHEvdevGameController.m		\
	     OHEvdevGamepad.m			\
	     OHEvdevPlayStationGamepad.m
SRCS_NINTENDO_3DS = OHNintendo3DSGameController.m	\
		    OHNintendo3DSGamepad.m
SRCS_NINTENDO_DS = OHNintendoDSGameController.m
SRCS_XINPUT = OHXInputGameController.m	\
	      OHXInputGamepad.m

INCLUDES := ${SRCS:.m=.h}	\

Modified src/hid/OHEvdevDualSense.h from [766fab2a8c] to [79e40a9eed].

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * version 3.0 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#import "OHEvdevGamepad.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHEvdevDualSense: OHEvdevGamepad
@end

OF_ASSUME_NONNULL_END







|



|



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * version 3.0 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#import "OHEvdevPlayStationGamepad.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHEvdevDualSense: OHEvdevPlayStationGamepad
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHEvdevDualSense.m from [5529e3d7e0] to [08296e1a60].

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
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHEvdevDualSense.h"
#import "OFDictionary.h"
#import "OHGameControllerEmulatedTriggerButton.h"

#import "OFInvalidArgumentException.h"

@implementation OHEvdevDualSense
- (OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *)buttons
{
	OFMutableDictionary *buttons =
	    [[_rawProfile.buttons mutableCopy] autorelease];

	[buttons setObject: self.leftTriggerButton forKey: @"L2"];
	[buttons setObject: self.rightTriggerButton forKey: @"R2"];

	[buttons makeImmutable];

	return buttons;
}

- (OHGameControllerButton *)northButton
{
	return [_rawProfile.buttons objectForKey: @"Triangle"];
}

- (OHGameControllerButton *)southButton
{
	return [_rawProfile.buttons objectForKey: @"Cross"];
}

- (OHGameControllerButton *)westButton
{
	return [_rawProfile.buttons objectForKey: @"Square"];
}

- (OHGameControllerButton *)eastButton
{
	return [_rawProfile.buttons objectForKey: @"Circle"];
}

- (OHGameControllerButton *)leftShoulderButton
{
	return [_rawProfile.buttons objectForKey: @"L1"];
}

- (OHGameControllerButton *)leftTriggerButton
{
	return [[[OHGameControllerEmulatedTriggerButton alloc]
	    initWithName: @"L2"
		    axis: [_rawProfile.axes objectForKey: @"Z"]] autorelease];
}

- (OHGameControllerButton *)rightTriggerButton
{
	return [[[OHGameControllerEmulatedTriggerButton alloc]
	    initWithName: @"R2"
		    axis: [_rawProfile.axes objectForKey: @"RZ"]] autorelease];
}

- (OHGameControllerButton *)rightShoulderButton
{
	return [_rawProfile.buttons objectForKey: @"R1"];
}

- (OHGameControllerButton *)leftThumbstickButton
{
	return [_rawProfile.buttons objectForKey: @"L3"];
}

- (OHGameControllerButton *)rightThumbstickButton
{
	return [_rawProfile.buttons objectForKey: @"R3"];
}

- (OHGameControllerButton *)menuButton
{
	return [_rawProfile.buttons objectForKey: @"Options"];
}

- (OHGameControllerButton *)optionsButton
{
	return [_rawProfile.buttons objectForKey: @"Create"];
}

- (OHGameControllerButton *)homeButton
{
	return [_rawProfile.buttons objectForKey: @"PS"];
}
@end







<

<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




<
<
<
<
<

17
18
19
20
21
22
23

24


25








































































26
27
28
29





30
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHEvdevDualSense.h"
#import "OFDictionary.h"




@implementation OHEvdevDualSense








































































- (OHGameControllerButton *)optionsButton
{
	return [_rawProfile.buttons objectForKey: @"Create"];
}





@end

Added src/hid/OHEvdevDualShock4.h version [0ed4cfaf34].























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License version 3.0 only,
 * as published by the Free Software Foundation.
 *
 * This program 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 Lesser General Public License
 * version 3.0 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#import "OHEvdevPlayStationGamepad.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHEvdevDualShock4: OHEvdevPlayStationGamepad
@end

OF_ASSUME_NONNULL_END

Added src/hid/OHEvdevDualShock4.m version [8fd86b557a].





























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License version 3.0 only,
 * as published by the Free Software Foundation.
 *
 * This program 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 Lesser General Public License
 * version 3.0 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHEvdevDualShock4.h"
#import "OFDictionary.h"

@implementation OHEvdevDualShock4
- (OHGameControllerButton *)optionsButton
{
	return [_rawProfile.buttons objectForKey: @"Share"];
}
@end

Modified src/hid/OHEvdevGameController.m from [c2e9c0c45a] to [453f7a0173].

28
29
30
31
32
33
34

35
36
37
38
39
40
41
#import "OFArray.h"
#import "OFDictionary.h"
#import "OFFileManager.h"
#import "OFLocale.h"
#import "OFNumber.h"

#import "OHEvdevDualSense.h"

#import "OHEvdevGamepad.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerProfile.h"

#include <sys/ioctl.h>
#include <linux/input.h>







>







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#import "OFArray.h"
#import "OFDictionary.h"
#import "OFFileManager.h"
#import "OFLocale.h"
#import "OFNumber.h"

#import "OHEvdevDualSense.h"
#import "OHEvdevDualShock4.h"
#import "OHEvdevGamepad.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerProfile.h"

#include <sys/ioctl.h>
#include <linux/input.h>
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
	ABS_WHEEL, ABS_GAS, ABS_BRAKE, ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X,
	ABS_HAT1Y, ABS_HAT2X, ABS_HAT2Y, ABS_HAT3X, ABS_HAT3Y
};

static OFString *
buttonToName(uint16_t button, uint16_t vendorID, uint16_t productID)
{

	if (vendorID == OHVendorIDSony && productID == OHProductIDDualSense) {
		switch (button) {
		case BTN_NORTH:
			return @"Triangle";
		case BTN_SOUTH:
			return @"Cross";
		case BTN_WEST:
			return @"Square";







>
|







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
	ABS_WHEEL, ABS_GAS, ABS_BRAKE, ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X,
	ABS_HAT1Y, ABS_HAT2X, ABS_HAT2Y, ABS_HAT3X, ABS_HAT3Y
};

static OFString *
buttonToName(uint16_t button, uint16_t vendorID, uint16_t productID)
{
	if (vendorID == OHVendorIDSony && (productID == OHProductIDDualSense ||
	    productID == OHProductIDDualShock4)) {
		switch (button) {
		case BTN_NORTH:
			return @"Triangle";
		case BTN_SOUTH:
			return @"Cross";
		case BTN_WEST:
			return @"Square";
106
107
108
109
110
111
112
113
114
115
116
117
118







119
120
121
122
123
124
125
			return @"R2";
		case BTN_THUMBL:
			return @"L3";
		case BTN_THUMBR:
			return @"R3";
		case BTN_START:
			return @"Options";
		case BTN_SELECT:
			return @"Create";
		case BTN_MODE:
			return @"PS";
		}
	}








	switch (button) {
	case BTN_A:
		return @"A";
	case BTN_B:
		return @"B";
	case BTN_C:







<
<




>
>
>
>
>
>
>







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
			return @"R2";
		case BTN_THUMBL:
			return @"L3";
		case BTN_THUMBR:
			return @"R3";
		case BTN_START:
			return @"Options";


		case BTN_MODE:
			return @"PS";
		}
	}

	if (vendorID == OHVendorIDSony && productID == OHProductIDDualSense)
		if (button == BTN_SELECT)
			return @"Create";
	if (vendorID == OHVendorIDSony && productID == OHProductIDDualShock4)
		if (button == BTN_SELECT)
			return @"Share";

	switch (button) {
	case BTN_A:
		return @"A";
	case BTN_B:
		return @"B";
	case BTN_C:
631
632
633
634
635
636
637




638
639
640
641
642
643
644

- (OHGamepad *)gamepad
{
	@try {
		if (_vendorID == OHVendorIDSony &&
		    _productID == OHProductIDDualSense)
			return [[[OHEvdevDualSense alloc]




			    initWithController: self] autorelease];
		else
			return [[[OHEvdevGamepad alloc]
			    initWithController: self] autorelease];
	} @catch (OFInvalidArgumentException *e) {
		return nil;
	}







>
>
>
>







638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655

- (OHGamepad *)gamepad
{
	@try {
		if (_vendorID == OHVendorIDSony &&
		    _productID == OHProductIDDualSense)
			return [[[OHEvdevDualSense alloc]
			    initWithController: self] autorelease];
		else if (_vendorID == OHVendorIDSony &&
		    _productID == OHProductIDDualShock4)
			return [[[OHEvdevDualShock4 alloc]
			    initWithController: self] autorelease];
		else
			return [[[OHEvdevGamepad alloc]
			    initWithController: self] autorelease];
	} @catch (OFInvalidArgumentException *e) {
		return nil;
	}

Renamed and modified src/hid/OHEvdevDualSense.h [766fab2a8c] to src/hid/OHEvdevPlayStationGamepad.h [db950effb0].

17
18
19
20
21
22
23
24
25
26
27
 * <https://www.gnu.org/licenses/>.
 */

#import "OHEvdevGamepad.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHEvdevDualSense: OHEvdevGamepad
@end

OF_ASSUME_NONNULL_END







|



17
18
19
20
21
22
23
24
25
26
27
 * <https://www.gnu.org/licenses/>.
 */

#import "OHEvdevGamepad.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHEvdevPlayStationGamepad: OHEvdevGamepad
@end

OF_ASSUME_NONNULL_END

Renamed and modified src/hid/OHEvdevDualSense.m [5529e3d7e0] to src/hid/OHEvdevPlayStationGamepad.m [c89b2d0c0b].

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 * You should have received a copy of the GNU Lesser General Public License
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHEvdevDualSense.h"
#import "OFDictionary.h"
#import "OHGameControllerEmulatedTriggerButton.h"

#import "OFInvalidArgumentException.h"

@implementation OHEvdevDualSense
- (OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *)buttons
{
	OFMutableDictionary *buttons =
	    [[_rawProfile.buttons mutableCopy] autorelease];

	[buttons setObject: self.leftTriggerButton forKey: @"L2"];
	[buttons setObject: self.rightTriggerButton forKey: @"R2"];







|



<
<
|







15
16
17
18
19
20
21
22
23
24
25


26
27
28
29
30
31
32
33
 * You should have received a copy of the GNU Lesser General Public License
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHEvdevPlayStationGamepad.h"
#import "OFDictionary.h"
#import "OHGameControllerEmulatedTriggerButton.h"



@implementation OHEvdevPlayStationGamepad
- (OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *)buttons
{
	OFMutableDictionary *buttons =
	    [[_rawProfile.buttons mutableCopy] autorelease];

	[buttons setObject: self.leftTriggerButton forKey: @"L2"];
	[buttons setObject: self.rightTriggerButton forKey: @"R2"];
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
}

- (OHGameControllerButton *)menuButton
{
	return [_rawProfile.buttons objectForKey: @"Options"];
}

- (OHGameControllerButton *)optionsButton
{
	return [_rawProfile.buttons objectForKey: @"Create"];
}

- (OHGameControllerButton *)homeButton
{
	return [_rawProfile.buttons objectForKey: @"PS"];
}
@end







<
<
<
<
<





92
93
94
95
96
97
98





99
100
101
102
103
}

- (OHGameControllerButton *)menuButton
{
	return [_rawProfile.buttons objectForKey: @"Options"];
}






- (OHGameControllerButton *)homeButton
{
	return [_rawProfile.buttons objectForKey: @"PS"];
}
@end

Modified src/hid/OHGameController.h from [c319f82148] to [6042a397f5].

96
97
98
99
100
101
102

103
104
105
106
107
108
- (void)retrieveState;
@end

#ifdef __cplusplus
extern "C" {
#endif
extern const uint16_t OHVendorIDSony;

extern const uint16_t OHProductIDDualSense;
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END







>






96
97
98
99
100
101
102
103
104
105
106
107
108
109
- (void)retrieveState;
@end

#ifdef __cplusplus
extern "C" {
#endif
extern const uint16_t OHVendorIDSony;
extern const uint16_t OHProductIDDualShock4;
extern const uint16_t OHProductIDDualSense;
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/hid/OHGameController.m from [cbf85ef3d3] to [f186a4854f].

35
36
37
38
39
40
41

42
43
44
45
46
47
48
# import "OHNintendoDSGameController.h"
#endif
#ifdef OF_NINTENDO_3DS
# import "OHNintendo3DSGameController.h"
#endif

const uint16_t OHVendorIDSony = 0x054C;

const uint16_t OHProductIDDualSense = 0x0CE6;

@implementation OHGameController
@dynamic name, rawProfile;

+ (OFArray OF_GENERIC(OHGameController *) *)controllers
{







>







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# import "OHNintendoDSGameController.h"
#endif
#ifdef OF_NINTENDO_3DS
# import "OHNintendo3DSGameController.h"
#endif

const uint16_t OHVendorIDSony = 0x054C;
const uint16_t OHProductIDDualShock4 = 0x09CC;
const uint16_t OHProductIDDualSense = 0x0CE6;

@implementation OHGameController
@dynamic name, rawProfile;

+ (OFArray OF_GENERIC(OHGameController *) *)controllers
{