ObjFW  Check-in [10cce4f6ef]

Overview
Comment:Merge trunk into 1.2 branch
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | 1.2
Files: files | file ages | folders
SHA3-256: 10cce4f6ef47ba95700f6e6bf194ece37db6da334c93665aa23535c79155a39c
User & Date: js on 2024-11-07 21:07:54
Other Links: branch diff | manifest | tags
Context
2024-11-08
20:57
Make ObjC++ exceptions work with libc++ on Windows check-in: 6bb25d33ac user: js tags: 1.2
2024-11-07
21:07
Merge trunk into 1.2 branch check-in: 10cce4f6ef user: js tags: 1.2
2024-11-06
21:28
objfw-compile: Remove handling of .bundle check-in: c5f91347e7 user: js tags: trunk
2024-11-02
19:36
Fix exclude glob for `make release` check-in: 7669b5f9d4 user: js tags: 1.2, 1.2-release
Changes

Added .github/workflows/CXXTest.mm version [9d47896274].































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#import <ObjFW/ObjFW.h>

#include <string>

@interface CXXTest: OFObject <OFApplicationDelegate>
@end

OF_APPLICATION_DELEGATE(CXXTest)

@implementation CXXTest
- (void)applicationDidFinishLaunching: (OFNotification *)notification
{
	std::string output;

	try {
		@try {
			throw @"Hello ";
		} @catch (OFString *string) {
			output += string.UTF8String;
		}

		throw std::string("C++");
	} catch (std::string &string) {
		output += "C++";
	}

	OFLog(@"%s", output.c_str());

	[OFApplication terminate];
}
@end

Added .github/workflows/fedora-mingw-gcc.yml version [4ba849b6d9].































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
name: fedora-mingw-gcc
on: [push, pull_request]
jobs:
  tests:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        include:
          - prefix: mingw32
            triple: i686-w64-mingw32
          - prefix: mingw64
            triple: x86_64-w64-mingw32
          - prefix: ucrt64
            triple: x86_64-w64-mingw32ucrt
    container: fedora
    steps:
    - name: Install dependencies
      run: |
        sudo dnf upgrade --refresh -y
        sudo dnf install -y ${{matrix.prefix}}-gcc-objc ${{matrix.prefix}}-openssl autoconf automake make wine
    - uses: actions/checkout@v4
    - name: autogen.sh
      run: ./autogen.sh
    - name: configure
      run: ./configure --host=${{matrix.triple}}
    - name: make
      run: make -j$(nproc)
    - name: make check
      run: WINEPATH=/usr/${{matrix.triple}}/sys-root/mingw/bin WINEPREFIX=/tmp/wineprefix make check
    - name: make install
      run: sudo make install

Modified .github/workflows/macos-14.yml from [31e00bb0dd] to [cf80eecb8f].

25
26
27
28
29
30
31




      run: ./configure ${{ matrix.configure_flags }}
    - name: make
      run: make -j$(sysctl -n hw.logicalcpu)
    - name: make check
      run: make check
    - name: make install
      run: sudo make install











>
>
>
>
25
26
27
28
29
30
31
32
33
34
35
      run: ./configure ${{ matrix.configure_flags }}
    - name: make
      run: make -j$(sysctl -n hw.logicalcpu)
    - name: make check
      run: make check
    - name: make install
      run: sudo make install
    - name: C++ test
      run: |
        objfw-compile -o cxxtest .github/workflows/CXXTest.mm
        ./cxxtest

Modified .github/workflows/ubuntu-latest-32bit.yml from [c27d1cf836] to [5330ff4082].

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37




          - --without-tls --disable-shared
          - --without-tls --disable-shared --enable-seluid24
          - --without-tls --disable-compiler-tls --disable-threads
    steps:
    - name: Install dependencies
      run: |
        sudo apt-get update
        sudo apt-get install gcc-multilib
    - uses: actions/checkout@v4
    - name: autogen.sh
      run: ./autogen.sh
    - name: configure
      run: ./configure OBJC="clang -m32" ${{ matrix.configure_flags }}
    - name: make
      run: make -j$(nproc)
    - name: make check
      run: make check
    - name: make install
      run: sudo make install











|











>
>
>
>
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
          - --without-tls --disable-shared
          - --without-tls --disable-shared --enable-seluid24
          - --without-tls --disable-compiler-tls --disable-threads
    steps:
    - name: Install dependencies
      run: |
        sudo apt-get update
        sudo apt-get install g++-multilib
    - uses: actions/checkout@v4
    - name: autogen.sh
      run: ./autogen.sh
    - name: configure
      run: ./configure OBJC="clang -m32" ${{ matrix.configure_flags }}
    - name: make
      run: make -j$(nproc)
    - name: make check
      run: make check
    - name: make install
      run: sudo make install
    - name: C++ test
      run: |
        objfw-compile -o cxxtest .github/workflows/CXXTest.mm
        ./cxxtest

Modified .github/workflows/ubuntu-latest.yml from [ffe8f603bc] to [e45a841261].

35
36
37
38
39
40
41




      run: ./configure ${{ matrix.configure_flags }}
    - name: make
      run: make -j$(nproc)
    - name: make check
      run: make check
    - name: make install
      run: sudo make install











>
>
>
>
35
36
37
38
39
40
41
42
43
44
45
      run: ./configure ${{ matrix.configure_flags }}
    - name: make
      run: make -j$(nproc)
    - name: make check
      run: make check
    - name: make install
      run: sudo make install
    - name: C++ test
      run: |
        objfw-compile -o cxxtest .github/workflows/CXXTest.mm
        ./cxxtest

Modified src/OFApplication.h from [ac4321c991] to [7a64d2e109].

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
		    (class_ *)[[class_ alloc] init]);			\
	}								\
									\
	WINAPI int							\
	WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,		\
	    LPSTR lpCmdLine, int nShowCmd)				\
	{								\
		extern void __getmainargs(int *, char ***, char ***,	\
		    int, int *);					\
		extern int _CRT_glob;					\
		int argc = 0, si = 0;					\
		char **argv = NULL, **envp = NULL;			\
									\
		__getmainargs(&argc, &argv, &envp, _CRT_glob, &si);	\
									\
		return OFApplicationMain(&argc, &argv,			\
		    (class_ *)[[class_ alloc] init]);			\
	}









#endif

#ifdef OF_HAVE_PLEDGE
# define OF_HAVE_SANDBOX
#endif

/**







<
<
<








>
>
>
>
>
>
>
>
>







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
		    (class_ *)[[class_ alloc] init]);			\
	}								\
									\
	WINAPI int							\
	WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,		\
	    LPSTR lpCmdLine, int nShowCmd)				\
	{								\



		int argc = 0, si = 0;					\
		char **argv = NULL, **envp = NULL;			\
									\
		__getmainargs(&argc, &argv, &envp, _CRT_glob, &si);	\
									\
		return OFApplicationMain(&argc, &argv,			\
		    (class_ *)[[class_ alloc] init]);			\
	}
# ifdef __cplusplus
extern "C" {
# endif
extern void __getmainargs(int *_Nonnull, char *_Nonnull *_Nullable *_Nullable,
    char *_Nonnull *_Nullable *_Nullable, int, int *_Nonnull);
extern int _CRT_glob;
# ifdef __cplusplus
}
# endif
#endif

#ifdef OF_HAVE_PLEDGE
# define OF_HAVE_SANDBOX
#endif

/**

Modified src/ObjFW.h from [5fa2f17ff8] to [700d623d15].

154
155
156
157
158
159
160

161

162
163
164
165
166
167
168
#ifdef OF_WINDOWS
# import "OFWindowsRegistryKey.h"
#endif

#import "OFAllocFailedException.h"
#import "OFAlreadyOpenException.h"
#import "OFException.h"

#import "OFChangeCurrentDirectoryFailedException.h"

#import "OFChecksumMismatchException.h"
#import "OFCopyItemFailedException.h"
#import "OFCreateDirectoryFailedException.h"
#import "OFCreateSymbolicLinkFailedException.h"
#import "OFEnumerationMutationException.h"
#ifdef OF_HAVE_FILES
# import "OFGetCurrentDirectoryFailedException.h"







>
|
>







154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#ifdef OF_WINDOWS
# import "OFWindowsRegistryKey.h"
#endif

#import "OFAllocFailedException.h"
#import "OFAlreadyOpenException.h"
#import "OFException.h"
#ifdef OF_HAVE_FILES
# import "OFChangeCurrentDirectoryFailedException.h"
#endif
#import "OFChecksumMismatchException.h"
#import "OFCopyItemFailedException.h"
#import "OFCreateDirectoryFailedException.h"
#import "OFCreateSymbolicLinkFailedException.h"
#import "OFEnumerationMutationException.h"
#ifdef OF_HAVE_FILES
# import "OFGetCurrentDirectoryFailedException.h"

Modified src/hid/OHDualSenseGamepad+Private.h from [59d2e877bc] to [c709fabb29].

21
22
23
24
25
26
27

28
29
30

31
32
33

#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# import "OHEvdevGameController.h"
#endif

OF_ASSUME_NONNULL_BEGIN


#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
@interface OHDualSenseGamepad () <OHEvdevMapping>
@end

#endif

OF_ASSUME_NONNULL_END







>

|
|
>
|


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# import "OHEvdevGameController.h"
#endif

OF_ASSUME_NONNULL_BEGIN

@interface OHDualSenseGamepad ()
#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
    <OHEvdevMapping>
#endif
- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHDualSenseGamepad.h from [34fd440b07] to [dce038230a].

24
25
26
27
28
29
30
31

32
33
34


35
36
37
/**
 * @class OHDualSenseGamepad OHDualSenseGamepad.h ObjFWHID/ObjFWHID.h
 *
 * @brief A Sony DualSense gamepad.
 */
@interface OHDualSenseGamepad: OFObject <OHExtendedGamepad>
{
	OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons;

	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}


@end

OF_ASSUME_NONNULL_END







|
>



>
>



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
 * @class OHDualSenseGamepad OHDualSenseGamepad.h ObjFWHID/ObjFWHID.h
 *
 * @brief A Sony DualSense gamepad.
 */
@interface OHDualSenseGamepad: OFObject <OHExtendedGamepad>
{
	OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *))
	    *_buttons;
	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}

- (instancetype)init OF_UNAVAILABLE;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHDualSenseGamepad.m from [ba8334f2eb] to [4a652fdc72].

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
#import "OHDualSenseGamepad.h"
#import "OHDualSenseGamepad+Private.h"
#import "OFDictionary.h"
#import "OHEmulatedGameControllerTriggerButton.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"




#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# include <linux/input.h>
# import "evdev_compat.h"
#endif

static OFString *const buttonNames[] = {
	@"Triangle", @"Cross", @"Square", @"Circle", @"L1", @"R1", @"L3", @"R3",
	@"Options", @"Create", @"PS"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHDualSenseGamepad
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init
{





	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OHGameControllerButton *button;
		OFMutableDictionary *directionalPads;
		OHGameControllerAxis *axis, *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;

		for (size_t i = 0; i < numButtons; i++) {
			button = [[[OHGameControllerButton alloc]
			    initWithName: buttonNames[i]
				  analog: false] autorelease];
			[buttons setObject: button forKey: buttonNames[i]];
		}

		axis = [[[OHGameControllerAxis alloc]
		    initWithName: @"L2"
			  analog: true] autorelease];
		button = [[[OHEmulatedGameControllerTriggerButton alloc]
		    initWithName: @"L2"
			    axis: axis] autorelease];
		[buttons setObject: button forKey: @"L2"];

		axis = [[[OHGameControllerAxis alloc]
		    initWithName: @"R2"
			  analog: true] autorelease];
		button = [[[OHEmulatedGameControllerTriggerButton alloc]
		    initWithName: @"R2"
			    axis: axis] autorelease];
		[buttons setObject: button forKey: @"R2"];

		[buttons makeImmutable];
		_buttons = [buttons retain];

		directionalPads =
		    [OFMutableDictionary dictionaryWithCapacity: 3];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"X"
			  analog: true] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"Y"
			  analog: true] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"Left Stick"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: true] autorelease];
		[directionalPads setObject: directionalPad
				    forKey: @"Left Stick"];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"RX"
			  analog: true] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"RY"
			  analog: true] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"Right Stick"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: true] autorelease];
		[directionalPads setObject: directionalPad
				    forKey: @"Right Stick"];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"D-Pad X"
			  analog: false] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"D-Pad Y"
			  analog: false] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"D-Pad"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: false] autorelease];
		[directionalPads setObject: directionalPad forKey: @"D-Pad"];

		[directionalPads makeImmutable];
		_directionalPads = [directionalPads retain];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {







>
>
>

















>
>
>
>
>












|
|
|



|
<
|
|
|
|


|
<
|
|
|
|








|
<
|
|
<
|
|
|
|
|
|



|
<
|
|
<
|
|
|
|
|
|



<
|
|
<
|
|
|
|
|
|
|







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
#import "OHDualSenseGamepad.h"
#import "OHDualSenseGamepad+Private.h"
#import "OFDictionary.h"
#import "OHEmulatedGameControllerTriggerButton.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHGameControllerDirectionalPad+Private.h"
#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"

#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# include <linux/input.h>
# import "evdev_compat.h"
#endif

static OFString *const buttonNames[] = {
	@"Triangle", @"Cross", @"Square", @"Circle", @"L1", @"R1", @"L3", @"R3",
	@"Options", @"Create", @"PS"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHDualSenseGamepad
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_init
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OHGameControllerButton *button;
		OFMutableDictionary *directionalPads;
		OHGameControllerAxis *axis, *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;

		for (size_t i = 0; i < numButtons; i++) {
			button = [OHGameControllerButton
			    oh_elementWithName: buttonNames[i]
					analog: false];
			[buttons setObject: button forKey: buttonNames[i]];
		}

		axis = [OHGameControllerAxis oh_elementWithName: @"L2"

							 analog: true];
		button = [OHEmulatedGameControllerTriggerButton
		    oh_buttonWithName: @"L2"
				 axis: axis];
		[buttons setObject: button forKey: @"L2"];

		axis = [OHGameControllerAxis oh_elementWithName: @"R2"

							 analog: true];
		button = [OHEmulatedGameControllerTriggerButton
		    oh_buttonWithName: @"R2"
				 axis: axis];
		[buttons setObject: button forKey: @"R2"];

		[buttons makeImmutable];
		_buttons = [buttons retain];

		directionalPads =
		    [OFMutableDictionary dictionaryWithCapacity: 3];

		xAxis = [OHGameControllerAxis oh_elementWithName: @"X"

							  analog: true];
		yAxis = [OHGameControllerAxis oh_elementWithName: @"Y"

							  analog: true];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"Left Stick"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: true];
		[directionalPads setObject: directionalPad
				    forKey: @"Left Stick"];

		xAxis = [OHGameControllerAxis oh_elementWithName: @"RX"

							  analog: true];
		yAxis = [OHGameControllerAxis oh_elementWithName: @"RY"

							  analog: true];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"Right Stick"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: true];
		[directionalPads setObject: directionalPad
				    forKey: @"Right Stick"];


		xAxis = [OHGameControllerAxis oh_elementWithName: @"D-Pad X"
							  analog: false];

		yAxis = [OHGameControllerAxis oh_elementWithName: @"D-Pad Y"
							  analog: false];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"D-Pad"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: false];
		[directionalPads setObject: directionalPad forKey: @"D-Pad"];

		[directionalPads makeImmutable];
		_directionalPads = [directionalPads retain];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
	case ABS_RY:
		return [[_directionalPads objectForKey: @"Right Stick"] yAxis];
	case ABS_HAT0X:
		return [[_directionalPads objectForKey: @"D-Pad"] xAxis];
	case ABS_HAT0Y:
		return [[_directionalPads objectForKey: @"D-Pad"] yAxis];
	case ABS_Z:
		return ((OHEmulatedGameControllerTriggerButton *)
		    [_buttons objectForKey: @"L2"]).axis;
	case ABS_RZ:
		return ((OHEmulatedGameControllerTriggerButton *)
		    [_buttons objectForKey: @"R2"]).axis;
	default:
		return nil;
	}
}
#endif
@end







<
|

<
|






287
288
289
290
291
292
293

294
295

296
297
298
299
300
301
302
	case ABS_RY:
		return [[_directionalPads objectForKey: @"Right Stick"] yAxis];
	case ABS_HAT0X:
		return [[_directionalPads objectForKey: @"D-Pad"] xAxis];
	case ABS_HAT0Y:
		return [[_directionalPads objectForKey: @"D-Pad"] yAxis];
	case ABS_Z:

		return [[_buttons objectForKey: @"L2"] oh_axis];
	case ABS_RZ:

		return [[_buttons objectForKey: @"R2"] oh_axis];
	default:
		return nil;
	}
}
#endif
@end

Modified src/hid/OHDualShock4Gamepad+Private.h from [a5fcaf715f] to [7cd9cfca62].

21
22
23
24
25
26
27

28
29
30

31
32
33

#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# import "OHEvdevGameController.h"
#endif

OF_ASSUME_NONNULL_BEGIN


#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
@interface OHDualShock4Gamepad () <OHEvdevMapping>
@end

#endif

OF_ASSUME_NONNULL_END







>

|
|
>
|


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# import "OHEvdevGameController.h"
#endif

OF_ASSUME_NONNULL_BEGIN

@interface OHDualShock4Gamepad ()
#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
    <OHEvdevMapping>
#endif
- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHDualShock4Gamepad.h from [52b3fd41a3] to [15e122415f].

24
25
26
27
28
29
30
31

32
33
34


35
36
37
/**
 * @class OHDualShock4Gamepad OHDualShock4Gamepad.h ObjFWHID/ObjFWHID.h
 *
 * @brief A Sony DualShock 4 gamepad.
 */
@interface OHDualShock4Gamepad: OFObject <OHExtendedGamepad>
{
	OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons;

	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}


@end

OF_ASSUME_NONNULL_END







|
>



>
>



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
 * @class OHDualShock4Gamepad OHDualShock4Gamepad.h ObjFWHID/ObjFWHID.h
 *
 * @brief A Sony DualShock 4 gamepad.
 */
@interface OHDualShock4Gamepad: OFObject <OHExtendedGamepad>
{
	OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *))
	    *_buttons;
	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}

- (instancetype)init OF_UNAVAILABLE;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHDualShock4Gamepad.m from [574ffee316] to [e1c38d8f5f].

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
#import "OHDualShock4Gamepad.h"
#import "OHDualShock4Gamepad+Private.h"
#import "OFDictionary.h"
#import "OHEmulatedGameControllerTriggerButton.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"




#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# include <linux/input.h>
# import "evdev_compat.h"
#endif

static OFString *const buttonNames[] = {
	@"Triangle", @"Cross", @"Square", @"Circle", @"L1", @"R1", @"L3", @"R3",
	@"Options", @"Share", @"PS"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHDualShock4Gamepad
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init
{





	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OHGameControllerButton *button;
		OFMutableDictionary *directionalPads;
		OHGameControllerAxis *axis, *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;

		for (size_t i = 0; i < numButtons; i++) {
			button = [[[OHGameControllerButton alloc]
			    initWithName: buttonNames[i]
				  analog: false] autorelease];
			[buttons setObject: button forKey: buttonNames[i]];
		}

		axis = [[[OHGameControllerAxis alloc]
		    initWithName: @"L2"
			  analog: true] autorelease];
		button = [[[OHEmulatedGameControllerTriggerButton alloc]
		    initWithName: @"L2"
			    axis: axis] autorelease];
		[buttons setObject: button forKey: @"L2"];

		axis = [[[OHGameControllerAxis alloc]
		    initWithName: @"R2"
			  analog: true] autorelease];
		button = [[[OHEmulatedGameControllerTriggerButton alloc]
		    initWithName: @"R2"
			    axis: axis] autorelease];
		[buttons setObject: button forKey: @"R2"];

		[buttons makeImmutable];
		_buttons = [buttons retain];

		directionalPads =
		    [OFMutableDictionary dictionaryWithCapacity: 3];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"X"
			  analog: true] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"Y"
			  analog: true] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"Left Stick"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: true] autorelease];
		[directionalPads setObject: directionalPad
				    forKey: @"Left Stick"];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"RX"
			  analog: true] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"RY"
			  analog: true] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"Right Stick"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: true] autorelease];
		[directionalPads setObject: directionalPad
				    forKey: @"Right Stick"];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"D-Pad X"
			  analog: false] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"D-Pad Y"
			  analog: false] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"D-Pad"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: false] autorelease];
		[directionalPads setObject: directionalPad forKey: @"D-Pad"];

		[directionalPads makeImmutable];
		_directionalPads = [directionalPads retain];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {







>
>
>

















>
>
>
>
>












|
|
|



|
<
|
|
|
|


|
<
|
|
|
|








|
<
|
|
<
|
|
|
|
|
|



|
<
|
|
<
|
|
|
|
|
|



<
|
|
<
|
|
|
|
|
|
|







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
#import "OHDualShock4Gamepad.h"
#import "OHDualShock4Gamepad+Private.h"
#import "OFDictionary.h"
#import "OHEmulatedGameControllerTriggerButton.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHGameControllerDirectionalPad+Private.h"
#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"

#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# include <linux/input.h>
# import "evdev_compat.h"
#endif

static OFString *const buttonNames[] = {
	@"Triangle", @"Cross", @"Square", @"Circle", @"L1", @"R1", @"L3", @"R3",
	@"Options", @"Share", @"PS"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHDualShock4Gamepad
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_init
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OHGameControllerButton *button;
		OFMutableDictionary *directionalPads;
		OHGameControllerAxis *axis, *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;

		for (size_t i = 0; i < numButtons; i++) {
			button = [OHGameControllerButton
			    oh_elementWithName: buttonNames[i]
					analog: false];
			[buttons setObject: button forKey: buttonNames[i]];
		}

		axis = [OHGameControllerAxis oh_elementWithName: @"L2"

							 analog: true];
		button = [OHEmulatedGameControllerTriggerButton
		    oh_buttonWithName: @"L2"
				 axis: axis];
		[buttons setObject: button forKey: @"L2"];

		axis = [OHGameControllerAxis oh_elementWithName: @"R2"

							 analog: true];
		button = [OHEmulatedGameControllerTriggerButton
		    oh_buttonWithName: @"R2"
				 axis: axis];
		[buttons setObject: button forKey: @"R2"];

		[buttons makeImmutable];
		_buttons = [buttons retain];

		directionalPads =
		    [OFMutableDictionary dictionaryWithCapacity: 3];

		xAxis = [OHGameControllerAxis oh_elementWithName: @"X"

							  analog: true];
		yAxis = [OHGameControllerAxis oh_elementWithName: @"Y"

							  analog: true];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"Left Stick"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: true];
		[directionalPads setObject: directionalPad
				    forKey: @"Left Stick"];

		xAxis = [OHGameControllerAxis oh_elementWithName: @"RX"

							  analog: true];
		yAxis = [OHGameControllerAxis oh_elementWithName: @"RY"

							  analog: true];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"Right Stick"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: true];
		[directionalPads setObject: directionalPad
				    forKey: @"Right Stick"];


		xAxis = [OHGameControllerAxis oh_elementWithName: @"D-Pad X"
							  analog: false];

		yAxis = [OHGameControllerAxis oh_elementWithName: @"D-Pad Y"
							  analog: false];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"D-Pad"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: false];
		[directionalPads setObject: directionalPad forKey: @"D-Pad"];

		[directionalPads makeImmutable];
		_directionalPads = [directionalPads retain];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
	case ABS_RY:
		return [[_directionalPads objectForKey: @"Right Stick"] yAxis];
	case ABS_HAT0X:
		return [[_directionalPads objectForKey: @"D-Pad"] xAxis];
	case ABS_HAT0Y:
		return [[_directionalPads objectForKey: @"D-Pad"] yAxis];
	case ABS_Z:
		return ((OHEmulatedGameControllerTriggerButton *)
		    [_buttons objectForKey: @"L2"]).axis;
	case ABS_RZ:
		return ((OHEmulatedGameControllerTriggerButton *)
		    [_buttons objectForKey: @"R2"]).axis;
	default:
		return nil;
	}
}
#endif
@end







<
|

<
|






287
288
289
290
291
292
293

294
295

296
297
298
299
300
301
302
	case ABS_RY:
		return [[_directionalPads objectForKey: @"Right Stick"] yAxis];
	case ABS_HAT0X:
		return [[_directionalPads objectForKey: @"D-Pad"] xAxis];
	case ABS_HAT0Y:
		return [[_directionalPads objectForKey: @"D-Pad"] yAxis];
	case ABS_Z:

		return [[_buttons objectForKey: @"L2"] oh_axis];
	case ABS_RZ:

		return [[_buttons objectForKey: @"R2"] oh_axis];
	default:
		return nil;
	}
}
#endif
@end

Modified src/hid/OHEmulatedGameControllerAxis.h from [d5464e93fd] to [3afaf898c0].

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

OF_SUBCLASSING_RESTRICTED
@interface OHEmulatedGameControllerAxis: OHGameControllerAxis
{
	OHGameControllerButton *_negativeButton, *_positiveButton;
}

- (instancetype)initWithName: (OFString *)name
		      analog: (bool)analog OF_UNAVAILABLE;
- (instancetype)
    initWithNegativeButton: (OHGameControllerButton *)negativeButton
	    positiveButton: (OHGameControllerButton *)positiveButton
    OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END







|
|

|
|
|



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

OF_SUBCLASSING_RESTRICTED
@interface OHEmulatedGameControllerAxis: OHGameControllerAxis
{
	OHGameControllerButton *_negativeButton, *_positiveButton;
}

- (instancetype)oh_initWithName: (OFString *)name
			 analog: (bool)analog OF_UNAVAILABLE;
- (instancetype)
    oh_initWithNegativeButton: (OHGameControllerButton *)negativeButton
	       positiveButton: (OHGameControllerButton *)positiveButton
    OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHEmulatedGameControllerAxis.m from [05ca2dc704] to [356c3af9b9].

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

#import "config.h"

#import "OHEmulatedGameControllerAxis.h"
#import "OHGameControllerButton.h"



@implementation OHEmulatedGameControllerAxis
- (instancetype)initWithName: (OFString *)name analog: (bool)analog
{
	OF_INVALID_INIT_METHOD
}


- (instancetype)initWithNegativeButton: (OHGameControllerButton *)negativeButton
			positiveButton: (OHGameControllerButton *)positiveButton
{
	void *pool = objc_autoreleasePoolPush();
	OFString *name;

	@try {
		name = [OFString stringWithFormat:
		    @"%@ and %@ as emulated axis",
		    negativeButton.name, positiveButton.name];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	self = [super initWithName: name analog: false];

	objc_autoreleasePoolPop(pool);

	_negativeButton = [negativeButton retain];
	_positiveButton = [positiveButton retain];

	return self;







>
>


|




>
|
|













|







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

#import "config.h"

#import "OHEmulatedGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"

@implementation OHEmulatedGameControllerAxis
- (instancetype)oh_initWithName: (OFString *)name analog: (bool)analog
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)
    oh_initWithNegativeButton: (OHGameControllerButton *)negativeButton
	       positiveButton: (OHGameControllerButton *)positiveButton
{
	void *pool = objc_autoreleasePoolPush();
	OFString *name;

	@try {
		name = [OFString stringWithFormat:
		    @"%@ and %@ as emulated axis",
		    negativeButton.name, positiveButton.name];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	self = [super oh_initWithName: name analog: false];

	objc_autoreleasePoolPop(pool);

	_negativeButton = [negativeButton retain];
	_positiveButton = [positiveButton retain];

	return self;

Modified src/hid/OHEmulatedGameControllerButton.h from [52ccdea95f] to [134791865d].

26
27
28
29
30
31
32
33
34
35
36

37
38
39
OF_SUBCLASSING_RESTRICTED
@interface OHEmulatedGameControllerButton: OHGameControllerButton
{
	OHGameControllerAxis *_axis;
	bool _positive;
}

- (instancetype)initWithName: (OFString *)name
		      analog: (bool)analog OF_UNAVAILABLE;
- (instancetype)initWithAxis: (OHGameControllerAxis *)axis
		    positive: (bool)positive OF_DESIGNATED_INITIALIZER;

@end

OF_ASSUME_NONNULL_END







|
|
|
|
>



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
OF_SUBCLASSING_RESTRICTED
@interface OHEmulatedGameControllerButton: OHGameControllerButton
{
	OHGameControllerAxis *_axis;
	bool _positive;
}

- (instancetype)oh_initWithName: (OFString *)name
			 analog: (bool)analog OF_UNAVAILABLE;
- (instancetype)oh_initWithAxis: (OHGameControllerAxis *)axis
		       positive: (bool)positive
    OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHEmulatedGameControllerButton.m from [d381f03565] to [1565847692].

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

#include "config.h"

#import "OHEmulatedGameControllerButton.h"
#import "OHGameControllerAxis.h"



@implementation OHEmulatedGameControllerButton
- (instancetype)initWithName: (OFString *)name analog: (bool)analog
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithAxis: (OHGameControllerAxis *)axis
		    positive: (bool)positive
{
	void *pool = objc_autoreleasePoolPush();
	OFString *name;

	@try {
		name = [OFString stringWithFormat:
		    @"%@%c", axis.name, (positive ? '+' : '-')];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	self = [super initWithName: name analog: false];

	objc_autoreleasePoolPop(pool);

	_axis = [axis retain];
	_positive = positive;

	return self;







>
>


|




|
|












|







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

#include "config.h"

#import "OHEmulatedGameControllerButton.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"

@implementation OHEmulatedGameControllerButton
- (instancetype)oh_initWithName: (OFString *)name analog: (bool)analog
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_initWithAxis: (OHGameControllerAxis *)axis
		       positive: (bool)positive
{
	void *pool = objc_autoreleasePoolPush();
	OFString *name;

	@try {
		name = [OFString stringWithFormat:
		    @"%@%c", axis.name, (positive ? '+' : '-')];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	self = [super oh_initWithName: name analog: false];

	objc_autoreleasePoolPop(pool);

	_axis = [axis retain];
	_positive = positive;

	return self;

Modified src/hid/OHEmulatedGameControllerTriggerButton.h from [ca69b5094c] to [f7bd66afbb].

25
26
27
28
29
30
31
32
33




34
35
36
37
38
39
40
41

OF_SUBCLASSING_RESTRICTED
@interface OHEmulatedGameControllerTriggerButton: OHGameControllerButton
{
	OHGameControllerAxis *_axis;
}

@property (readonly, nonatomic) OHGameControllerAxis *axis;





- (instancetype)initWithName: (OFString *)name
		      analog: (bool)analog OF_UNAVAILABLE;
- (instancetype)initWithName: (OFString *)name
			axis: (OHGameControllerAxis *)axis
    OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END







|

>
>
>
>
|
|
|
|
|



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

OF_SUBCLASSING_RESTRICTED
@interface OHEmulatedGameControllerTriggerButton: OHGameControllerButton
{
	OHGameControllerAxis *_axis;
}

@property (readonly, nonatomic) OHGameControllerAxis *oh_axis;

+ (instancetype)oh_buttonWithName: (OFString *)name
			   analog: (bool)analog OF_UNAVAILABLE;
+ (instancetype)oh_buttonWithName: (OFString *)name
			     axis: (OHGameControllerAxis *)axis;
- (instancetype)oh_initWithName: (OFString *)name
			 analog: (bool)analog OF_UNAVAILABLE;
- (instancetype)oh_initWithName: (OFString *)name
			   axis: (OHGameControllerAxis *)axis
    OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHEmulatedGameControllerTriggerButton.m from [4b0da3fefb] to [71e08346d1].

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

#include "config.h"

#import "OHEmulatedGameControllerTriggerButton.h"
#import "OHGameControllerAxis.h"



@implementation OHEmulatedGameControllerTriggerButton
@synthesize axis = _axis;












- (instancetype)initWithName: (OFString *)name analog: (bool)analog
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithName: (OFString *)name
			axis: (OHGameControllerAxis *)axis
{
	self = [super initWithName: name analog: true];

	_axis = [axis retain];

	return self;
}

- (void)dealloc







>
>


|

>
>
>
>
>
>
>
>
>
>
>
|




|
|

|







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

#include "config.h"

#import "OHEmulatedGameControllerTriggerButton.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"

@implementation OHEmulatedGameControllerTriggerButton
@synthesize oh_axis = _axis;

+ (instancetype)oh_buttonWithName: (OFString *)name analog: (bool)analog
{
	OF_UNRECOGNIZED_SELECTOR
}

+ (instancetype)oh_buttonWithName: (OFString *)name
			     axis: (OHGameControllerAxis *)axis
{
	return [[[self alloc] oh_initWithName: name axis: axis] autorelease];
}

- (instancetype)oh_initWithName: (OFString *)name analog: (bool)analog
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_initWithName: (OFString *)name
			   axis: (OHGameControllerAxis *)axis
{
	self = [super oh_initWithName: name analog: true];

	_axis = [axis retain];

	return self;
}

- (void)dealloc

Modified src/hid/OHEvdevExtendedGamepad.m from [0605bcdccb] to [a68d516e59].

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
#include "config.h"

#import "OHEvdevExtendedGamepad.h"
#import "OFDictionary.h"
#import "OHEmulatedGameControllerTriggerButton.h"
#import "OHEvdevGameController.h"
#import "OHGameControllerDirectionalPad.h"


#import "OFInvalidArgumentException.h"

@implementation OHEvdevExtendedGamepad
- (instancetype)initWithKeyBits: (unsigned long *)keyBits
			 evBits: (unsigned long *)evBits
			absBits: (unsigned long *)absBits
		       vendorID: (uint16_t)vendorID
		      productID: (uint16_t)productID
{
	self = [super initWithKeyBits: keyBits
			       evBits: evBits
			      absBits: absBits
			     vendorID: vendorID
			    productID: productID];

	@try {
		void *pool = objc_autoreleasePoolPush();

		if (self.northButton == nil || self.southButton == nil ||
		    self.westButton == nil || self.eastButton == nil ||
		    self.leftShoulderButton == nil ||







>




|
|
|
|
|

|
|
|
|
|







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
#include "config.h"

#import "OHEvdevExtendedGamepad.h"
#import "OFDictionary.h"
#import "OHEmulatedGameControllerTriggerButton.h"
#import "OHEvdevGameController.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHGameControllerDirectionalPad+Private.h"

#import "OFInvalidArgumentException.h"

@implementation OHEvdevExtendedGamepad
- (instancetype)oh_initWithKeyBits: (unsigned long *)keyBits
			    evBits: (unsigned long *)evBits
			   absBits: (unsigned long *)absBits
			  vendorID: (uint16_t)vendorID
			 productID: (uint16_t)productID
{
	self = [super oh_initWithKeyBits: keyBits
				  evBits: evBits
				 absBits: absBits
				vendorID: vendorID
			       productID: productID];

	@try {
		void *pool = objc_autoreleasePoolPush();

		if (self.northButton == nil || self.southButton == nil ||
		    self.westButton == nil || self.eastButton == nil ||
		    self.leftShoulderButton == nil ||
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
}

- (OHGameControllerButton *)leftTriggerButton
{
	OHGameControllerAxis *axis = [_axes objectForKey: @"Z"];

	if (axis != nil)
		return [[[OHEmulatedGameControllerTriggerButton alloc]
		    initWithName: @"LT"
			    axis: axis] autorelease];

	return [_buttons objectForKey: @"LT"];
}

- (OHGameControllerButton *)rightTriggerButton
{
	OHGameControllerAxis *axis = [_axes objectForKey: @"RZ"];

	if (axis != nil)
		return [[[OHEmulatedGameControllerTriggerButton alloc]
		    initWithName: @"RT"
			    axis: axis] autorelease];

	return [_buttons objectForKey: @"RT"];
}

- (OHGameControllerButton *)leftThumbstickButton
{
	return [_buttons objectForKey: @"LSB"];







|
|
|









|
|
|







142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
}

- (OHGameControllerButton *)leftTriggerButton
{
	OHGameControllerAxis *axis = [_axes objectForKey: @"Z"];

	if (axis != nil)
		return [OHEmulatedGameControllerTriggerButton
		    oh_buttonWithName: @"LT"
				 axis: axis];

	return [_buttons objectForKey: @"LT"];
}

- (OHGameControllerButton *)rightTriggerButton
{
	OHGameControllerAxis *axis = [_axes objectForKey: @"RZ"];

	if (axis != nil)
		return [OHEmulatedGameControllerTriggerButton
		    oh_buttonWithName: @"RT"
				 axis: axis];

	return [_buttons objectForKey: @"RT"];
}

- (OHGameControllerButton *)leftThumbstickButton
{
	return [_buttons objectForKey: @"LSB"];
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
{
	OHGameControllerAxis *xAxis = [_axes objectForKey: @"X"];
	OHGameControllerAxis *yAxis = [_axes objectForKey: @"Y"];

	if (xAxis == nil || yAxis == nil)
		return nil;

	return [[[OHGameControllerDirectionalPad alloc]
	    initWithName: @"Left Thumbstick"
		   xAxis: xAxis
		   yAxis: yAxis
		  analog: true] autorelease];
}

- (OHGameControllerDirectionalPad *)rightThumbstick
{
	OHGameControllerAxis *xAxis = [_axes objectForKey: @"RX"];
	OHGameControllerAxis *yAxis = [_axes objectForKey: @"RY"];

	if (xAxis == nil || yAxis == nil)
		return nil;

	return [[[OHGameControllerDirectionalPad alloc]
	    initWithName: @"Right Thumbstick"
		   xAxis: xAxis
		   yAxis: yAxis
		  analog: true] autorelease];
}

- (OHGameControllerDirectionalPad *)dPad
{
	OHGameControllerAxis *xAxis = [_axes objectForKey: @"HAT0X"];
	OHGameControllerAxis *yAxis = [_axes objectForKey: @"HAT0Y"];
	OHGameControllerButton *up, *down, *left, *right;

	if (xAxis != nil && yAxis != nil)
		return [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"D-Pad"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: false] autorelease];

	up = [_buttons objectForKey: @"D-Pad Up"];
	down = [_buttons objectForKey: @"D-Pad Down"];
	left = [_buttons objectForKey: @"D-Pad Left"];
	right = [_buttons objectForKey: @"D-Pad Right"];

	if (up != nil && down != nil && left != nil && right != nil)
		return [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"D-Pad"
			      up: up
			    down: down
			    left: left
			   right: right
			  analog: false] autorelease];

	return nil;
}
@end







|
|
|
|
|










|
|
|
|
|









|
|
|
|
|







|
|
|
|
|
|
|




194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
{
	OHGameControllerAxis *xAxis = [_axes objectForKey: @"X"];
	OHGameControllerAxis *yAxis = [_axes objectForKey: @"Y"];

	if (xAxis == nil || yAxis == nil)
		return nil;

	return [OHGameControllerDirectionalPad
	    oh_padWithName: @"Left Thumbstick"
		     xAxis: xAxis
		     yAxis: yAxis
		    analog: true];
}

- (OHGameControllerDirectionalPad *)rightThumbstick
{
	OHGameControllerAxis *xAxis = [_axes objectForKey: @"RX"];
	OHGameControllerAxis *yAxis = [_axes objectForKey: @"RY"];

	if (xAxis == nil || yAxis == nil)
		return nil;

	return [OHGameControllerDirectionalPad
	    oh_padWithName: @"Right Thumbstick"
		     xAxis: xAxis
		     yAxis: yAxis
		    analog: true];
}

- (OHGameControllerDirectionalPad *)dPad
{
	OHGameControllerAxis *xAxis = [_axes objectForKey: @"HAT0X"];
	OHGameControllerAxis *yAxis = [_axes objectForKey: @"HAT0Y"];
	OHGameControllerButton *up, *down, *left, *right;

	if (xAxis != nil && yAxis != nil)
		return [OHGameControllerDirectionalPad
		    oh_padWithName: @"D-Pad"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: false];

	up = [_buttons objectForKey: @"D-Pad Up"];
	down = [_buttons objectForKey: @"D-Pad Down"];
	left = [_buttons objectForKey: @"D-Pad Left"];
	right = [_buttons objectForKey: @"D-Pad Right"];

	if (up != nil && down != nil && left != nil && right != nil)
		return [OHGameControllerDirectionalPad
		    oh_padWithName: @"D-Pad"
				up: up
			      down: down
			      left: left
			     right: right
			    analog: false];

	return nil;
}
@end

Modified src/hid/OHEvdevGameController.h from [d9553f88d1] to [0a1d016c47].

34
35
36
37
38
39
40

41

42
43
44
45
46
47
48
	bool _discardUntilReport;
	unsigned long *_evBits, *_keyBits, *_absBits;
	uint16_t _vendorID, _productID;
	OFString *_name;
	id <OHGameControllerProfile, OHEvdevMapping> _profile;
}


- (instancetype)initWithPath: (OFString *)path;

- (void)oh_pollState;
@end

extern const uint16_t OHEvdevButtonIDs[];
extern const size_t OHNumEvdevButtonIDs;
extern const uint16_t OHEvdevAxisIDs[];
extern const size_t OHNumEvdevAxisIDs;







>
|
>







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
	bool _discardUntilReport;
	unsigned long *_evBits, *_keyBits, *_absBits;
	uint16_t _vendorID, _productID;
	OFString *_name;
	id <OHGameControllerProfile, OHEvdevMapping> _profile;
}

- (instancetype)oh_init OF_UNAVAILABLE;
- (instancetype)oh_initWithPath: (OFString *)path
    OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
- (void)oh_pollState;
@end

extern const uint16_t OHEvdevButtonIDs[];
extern const size_t OHNumEvdevButtonIDs;
extern const uint16_t OHEvdevAxisIDs[];
extern const size_t OHNumEvdevAxisIDs;

Modified src/hid/OHEvdevGameController.m from [8882f3e69e] to [7866e864ec].

34
35
36
37
38
39
40


41
42
43
44
45
46
47

#import "OHDualSenseGamepad.h"
#import "OHDualSenseGamepad+Private.h"
#import "OHDualShock4Gamepad.h"
#import "OHDualShock4Gamepad+Private.h"
#import "OHEvdevExtendedGamepad.h"
#import "OHExtendedN64Controller.h"


#import "OHGameControllerAxis+Private.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerProfile.h"
#import "OHLeftJoyCon.h"
#import "OHLeftJoyCon+Private.h"
#import "OHN64Controller.h"







>
>







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

#import "OHDualSenseGamepad.h"
#import "OHDualSenseGamepad+Private.h"
#import "OHDualShock4Gamepad.h"
#import "OHDualShock4Gamepad+Private.h"
#import "OHEvdevExtendedGamepad.h"
#import "OHExtendedN64Controller.h"
#import "OHGameController.h"
#import "OHGameController+Private.h"
#import "OHGameControllerAxis+Private.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerProfile.h"
#import "OHLeftJoyCon.h"
#import "OHLeftJoyCon+Private.h"
#import "OHN64Controller.h"
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
		if (![device hasPrefix: @"event"])
			continue;

		path = [@"/dev/input" stringByAppendingPathComponent: device];

		@try {
			controller = [[[OHEvdevGameController alloc]
			    initWithPath: path] autorelease];
		} @catch (OFOpenItemFailedException *e) {
			if (e.errNo == EACCES)
				continue;

			@throw e;
		} @catch (OFInvalidArgumentException *e) {
			/* Not a game controller. */







|







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
		if (![device hasPrefix: @"event"])
			continue;

		path = [@"/dev/input" stringByAppendingPathComponent: device];

		@try {
			controller = [[[OHEvdevGameController alloc]
			    oh_initWithPath: path] autorelease];
		} @catch (OFOpenItemFailedException *e) {
			if (e.errNo == EACCES)
				continue;

			@throw e;
		} @catch (OFInvalidArgumentException *e) {
			/* Not a game controller. */
140
141
142
143
144
145
146
147
148





149
150
151
152
153
154
155
156
	[controllers makeImmutable];

	objc_autoreleasePoolPop(pool);

	return controllers;
}

- (instancetype)initWithPath: (OFString *)path
{





	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFStringEncoding encoding = [OFLocale encoding];
		struct input_id inputID;
		char name[128];








|

>
>
>
>
>
|







142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
	[controllers makeImmutable];

	objc_autoreleasePoolPop(pool);

	return controllers;
}

- (instancetype)oh_init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_initWithPath: (OFString *)path
{
	self = [super oh_init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFStringEncoding encoding = [OFLocale encoding];
		struct input_id inputID;
		char name[128];

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
			    sizeof(unsigned long)), _absBits) == -1)
				@throw [OFInitializationFailedException
				    exception];
		}

		if (_vendorID == OHVendorIDSony &&
		    _productID == OHProductIDDualSense)
			_profile = [[OHDualSenseGamepad alloc] init];
		else if (_vendorID == OHVendorIDSony &&
		    _productID == OHProductIDDualShock4)
			_profile = [[OHDualShock4Gamepad alloc] init];
		else if (_vendorID == OHVendorIDNintendo &&
		    _productID == OHProductIDN64Controller)
			_profile = [[OHExtendedN64Controller alloc] init];
		else if (_vendorID == OHVendorIDNintendo &&
		    _productID == OHProductIDLeftJoyCon)
			_profile = [[OHLeftJoyCon alloc] init];
		else if (_vendorID == OHVendorIDNintendo &&
		    _productID == OHProductIDRightJoyCon)
			_profile = [[OHRightJoyCon alloc] init];
		else if (_vendorID == OHVendorIDGoogle &&
		    _productID == OHProductIDStadiaController)
			_profile = [[OHStadiaGamepad alloc] init];
		else
			_profile = [[OHEvdevExtendedGamepad alloc]
			    initWithKeyBits: _keyBits
				     evBits: _evBits
				    absBits: _absBits
				   vendorID: _vendorID
				  productID: _productID];

		[self oh_pollState];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;







|


|


|


|


|


|


|
|
|
|
|







215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
			    sizeof(unsigned long)), _absBits) == -1)
				@throw [OFInitializationFailedException
				    exception];
		}

		if (_vendorID == OHVendorIDSony &&
		    _productID == OHProductIDDualSense)
			_profile = [[OHDualSenseGamepad alloc] oh_init];
		else if (_vendorID == OHVendorIDSony &&
		    _productID == OHProductIDDualShock4)
			_profile = [[OHDualShock4Gamepad alloc] oh_init];
		else if (_vendorID == OHVendorIDNintendo &&
		    _productID == OHProductIDN64Controller)
			_profile = [[OHExtendedN64Controller alloc] oh_init];
		else if (_vendorID == OHVendorIDNintendo &&
		    _productID == OHProductIDLeftJoyCon)
			_profile = [[OHLeftJoyCon alloc] oh_init];
		else if (_vendorID == OHVendorIDNintendo &&
		    _productID == OHProductIDRightJoyCon)
			_profile = [[OHRightJoyCon alloc] oh_init];
		else if (_vendorID == OHVendorIDGoogle &&
		    _productID == OHProductIDStadiaController)
			_profile = [[OHStadiaGamepad alloc] oh_init];
		else
			_profile = [[OHEvdevExtendedGamepad alloc]
			    oh_initWithKeyBits: _keyBits
					evBits: _evBits
				       absBits: _absBits
				      vendorID: _vendorID
				     productID: _productID];

		[self oh_pollState];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;

Modified src/hid/OHEvdevGameControllerProfile.h from [88f0042619] to [a2fd1c2755].

21
22
23
24
25
26
27
28

29
30
31
32
33


34
35
36
37

38
39
40
#import "OHGameControllerProfile.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHEvdevGameControllerProfile: OFObject <OHGameControllerProfile,
    OHEvdevMapping>
{
	OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons;

	OFDictionary OF_GENERIC(OFString *, OHGameControllerAxis *) *_axes;
	uint16_t _vendorID, _productID;
}

- (instancetype)initWithKeyBits: (unsigned long *)keyBits


			 evBits: (unsigned long *)evBits
			absBits: (unsigned long *)absBits
		       vendorID: (uint16_t)vendorID
		      productID: (uint16_t)productID;

@end

OF_ASSUME_NONNULL_END







|
>




|
>
>
|
|
|
|
>



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#import "OHGameControllerProfile.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHEvdevGameControllerProfile: OFObject <OHGameControllerProfile,
    OHEvdevMapping>
{
	OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *))
	    *_buttons;
	OFDictionary OF_GENERIC(OFString *, OHGameControllerAxis *) *_axes;
	uint16_t _vendorID, _productID;
}

- (instancetype)init OF_UNAVAILABLE;

- (instancetype)oh_initWithKeyBits: (unsigned long *)keyBits
			    evBits: (unsigned long *)evBits
			   absBits: (unsigned long *)absBits
			  vendorID: (uint16_t)vendorID
			 productID: (uint16_t)productID
    OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHEvdevGameControllerProfile.m from [ae6b4a8235] to [d2edb1ba13].

19
20
21
22
23
24
25


26
27
28
29
30
31
32

#include "config.h"

#import "OHEvdevGameControllerProfile.h"
#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"



#include <linux/input.h>

#import "evdev_compat.h"

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







>
>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

#include "config.h"

#import "OHEvdevGameControllerProfile.h"
#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"

#include <linux/input.h>

#import "evdev_compat.h"

static OFString *
buttonToName(uint16_t button, uint16_t vendorID, uint16_t productID)
201
202
203
204
205
206
207
208





209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
		return nil;
	}
}

@implementation OHEvdevGameControllerProfile
@synthesize buttons = _buttons, axes = _axes;

- (instancetype)initWithKeyBits: (unsigned long *)keyBits





			 evBits: (unsigned long *)evBits
			absBits: (unsigned long *)absBits
		       vendorID: (uint16_t)vendorID
		      productID: (uint16_t)productID
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons, *axes;

		buttons = [OFMutableDictionary dictionary];
		for (size_t i = 0; i < OHNumEvdevButtonIDs; i++) {
			if (OFBitSetIsSet(keyBits, OHEvdevButtonIDs[i])) {
				OFString *buttonName;
				OHGameControllerButton *button;

				buttonName = buttonToName(OHEvdevButtonIDs[i],
				    vendorID, productID);
				if (buttonName == nil)
					continue;

				button = [[[OHGameControllerButton alloc]
				    initWithName: buttonName
					  analog: false] autorelease];

				[buttons setObject: button forKey: buttonName];
			}
		}
		[buttons makeImmutable];

		axes = [OFMutableDictionary dictionary];
		if (OFBitSetIsSet(evBits, EV_ABS)) {
			for (size_t i = 0; i < OHNumEvdevAxisIDs; i++) {
				if (OFBitSetIsSet(absBits, OHEvdevAxisIDs[i])) {
					OFString *axisName;
					OHGameControllerAxis *axis;

					axisName =
					    axisToName(OHEvdevAxisIDs[i]);
					if (axisName == nil)
						continue;

					axis = [[[OHGameControllerAxis
					    alloc]
					    initWithName: axisName
						  analog: true] autorelease];

					[axes setObject: axis forKey: axisName];
				}
			}
		}
		[axes makeImmutable];








|
>
>
>
>
>
|
|
|
|


















|
|
|


















|
<
|
|







203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259

260
261
262
263
264
265
266
267
268
		return nil;
	}
}

@implementation OHEvdevGameControllerProfile
@synthesize buttons = _buttons, axes = _axes;

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_initWithKeyBits: (unsigned long *)keyBits
			    evBits: (unsigned long *)evBits
			   absBits: (unsigned long *)absBits
			  vendorID: (uint16_t)vendorID
			 productID: (uint16_t)productID
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons, *axes;

		buttons = [OFMutableDictionary dictionary];
		for (size_t i = 0; i < OHNumEvdevButtonIDs; i++) {
			if (OFBitSetIsSet(keyBits, OHEvdevButtonIDs[i])) {
				OFString *buttonName;
				OHGameControllerButton *button;

				buttonName = buttonToName(OHEvdevButtonIDs[i],
				    vendorID, productID);
				if (buttonName == nil)
					continue;

				button = [OHGameControllerButton
				    oh_elementWithName: buttonName
						analog: false];

				[buttons setObject: button forKey: buttonName];
			}
		}
		[buttons makeImmutable];

		axes = [OFMutableDictionary dictionary];
		if (OFBitSetIsSet(evBits, EV_ABS)) {
			for (size_t i = 0; i < OHNumEvdevAxisIDs; i++) {
				if (OFBitSetIsSet(absBits, OHEvdevAxisIDs[i])) {
					OFString *axisName;
					OHGameControllerAxis *axis;

					axisName =
					    axisToName(OHEvdevAxisIDs[i]);
					if (axisName == nil)
						continue;

					axis = [OHGameControllerAxis

					    oh_elementWithName: axisName
							analog: true];

					[axes setObject: axis forKey: axisName];
				}
			}
		}
		[axes makeImmutable];

Modified src/hid/OHExtendedN64Controller.m from [7c4cbd5732] to [74ce3488c3].

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
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHExtendedN64Controller.h"

#import "OHN64Controller+Private.h"
#import "OFDictionary.h"
#import "OHGameControllerButton.h"



#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# include <linux/input.h>
#endif

static OFString *const buttonNames[] = {
	@"ZR", @"Home", @"Capture"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHExtendedN64Controller
- (instancetype)init
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [[_buttons mutableCopy] autorelease];

		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button =
			    [[[OHGameControllerButton alloc]
			    initWithName: buttonNames[i]
				  analog: false] autorelease];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		[_buttons release];
		_buttons = [buttons retain];

		objc_autoreleasePoolPop(pool);







>



>
>











|

|







|
<
|
|







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
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHExtendedN64Controller.h"
#import "OHN64Controller.h"
#import "OHN64Controller+Private.h"
#import "OFDictionary.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"

#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# include <linux/input.h>
#endif

static OFString *const buttonNames[] = {
	@"ZR", @"Home", @"Capture"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHExtendedN64Controller
- (instancetype)oh_init
{
	self = [super oh_init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [[_buttons mutableCopy] autorelease];

		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button = [OHGameControllerButton

			    oh_elementWithName: buttonNames[i]
					analog: false];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		[_buttons release];
		_buttons = [buttons retain];

		objc_autoreleasePoolPop(pool);

Added src/hid/OHGameController+Private.h version [fcf1771c7f].

























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * 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 "OHGameController.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHGameController ()
- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHGameController.h from [5a0ee8476d] to [adf99e5588].

88
89
90
91
92
93
94


95
96
97
98
99
100
101

/**
 * @brief Returns the available controllers.
 *
 * @return The available controllers
 */
+ (OFArray OF_GENERIC(OHGameController *) *)controllers;



/**
 * @brief Updates the current state from the game controller.
 *
 * The state returned by @ref OHGameController's methods does not change until
 * this method is called.
 *







>
>







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

/**
 * @brief Returns the available controllers.
 *
 * @return The available controllers
 */
+ (OFArray OF_GENERIC(OHGameController *) *)controllers;

- (instancetype)init OF_UNAVAILABLE;

/**
 * @brief Updates the current state from the game controller.
 *
 * The state returned by @ref OHGameController's methods does not change until
 * this method is called.
 *

Modified src/hid/OHGameController.m from [12f0e8227c] to [86efc7b0c1].

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
#else
	return [OFArray array];
#endif
}

- (instancetype)init
{
	if ([self isMemberOfClass: [OHGameController class]]) {
		@try {
			[self doesNotRecognizeSelector: _cmd];
		} @catch (id e) {
			[self release];
			@throw e;
		}

		abort();
	}


	return [super init];
}

- (OFNumber *)vendorID
{
	return nil;
}







|
<
<
<
<
<
|

<
<
>
|







73
74
75
76
77
78
79
80





81
82


83
84
85
86
87
88
89
90
91
#else
	return [OFArray array];
#endif
}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD





}



- (instancetype)oh_init
{
	return [super init];
}

- (OFNumber *)vendorID
{
	return nil;
}

Added src/hid/OHGameControllerDirectionalPad+Private.h version [c4b9214019].



































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * 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 "OHGameControllerDirectionalPad.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHGameControllerDirectionalPad ()
+ (instancetype)oh_padWithName: (OFString *)name
			 xAxis: (OHGameControllerAxis *)xAxis
			 yAxis: (OHGameControllerAxis *)yAxis
			analog: (bool)analog;
+ (instancetype)oh_padWithName: (OFString *)name
			    up: (OHGameControllerButton *)up
			  down: (OHGameControllerButton *)down
			  left: (OHGameControllerButton *)left
			 right: (OHGameControllerButton *)right
			analog: (bool)analog;
- (instancetype)oh_initWithName: (OFString *)name
			 analog: (bool)analog OF_UNAVAILABLE;
- (instancetype)oh_initWithName: (OFString *)name
			  xAxis: (OHGameControllerAxis *)xAxis
			  yAxis: (OHGameControllerAxis *)yAxis
			 analog: (bool)analog OF_METHOD_FAMILY(init);
- (instancetype)oh_initWithName: (OFString *)name
			     up: (OHGameControllerButton *)up
			   down: (OHGameControllerButton *)down
			   left: (OHGameControllerButton *)left
			  right: (OHGameControllerButton *)right
			 analog: (bool)analog OF_METHOD_FAMILY(init);
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHGameControllerDirectionalPad.h from [9f3d209aa4] to [6b7f55ae89].

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

OF_ASSUME_NONNULL_BEGIN

/**
 * @class OHGameControllerDirectionalPad OHGameControllerDirectionalPad.h
 *	  ObjFWHID/ObjFWID.h
 *
 * @brief An directional pad or thumb stick of a game controller.
 */
OF_SUBCLASSING_RESTRICTED
@interface OHGameControllerDirectionalPad: OHGameControllerElement
{
	OHGameControllerAxis *_xAxis, *_yAxis;
	OHGameControllerButton *_up, *_down, *_left, *_right;
}







|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

OF_ASSUME_NONNULL_BEGIN

/**
 * @class OHGameControllerDirectionalPad OHGameControllerDirectionalPad.h
 *	  ObjFWHID/ObjFWID.h
 *
 * @brief A directional pad or thumb stick of a game controller.
 */
OF_SUBCLASSING_RESTRICTED
@interface OHGameControllerDirectionalPad: OHGameControllerElement
{
	OHGameControllerAxis *_xAxis, *_yAxis;
	OHGameControllerButton *_up, *_down, *_left, *_right;
}
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
 */
@property (readonly, nonatomic) OHGameControllerButton *left;

/**
 * @brief The right button of the directional pad.
 */
@property (readonly, nonatomic) OHGameControllerButton *right;

- (instancetype)initWithName: (OFString *)name
		      analog: (bool)analog OF_UNAVAILABLE;

- (instancetype)initWithName: (OFString *)name
		       xAxis: (OHGameControllerAxis *)xAxis
		       yAxis: (OHGameControllerAxis *)yAxis
		      analog: (bool)analog;

- (instancetype)initWithName: (OFString *)name
			  up: (OHGameControllerButton *)up
			down: (OHGameControllerButton *)down
			left: (OHGameControllerButton *)left
		       right: (OHGameControllerButton *)right
		      analog: (bool)analog;
@end

OF_ASSUME_NONNULL_END







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



61
62
63
64
65
66
67















68
69
70
 */
@property (readonly, nonatomic) OHGameControllerButton *left;

/**
 * @brief The right button of the directional pad.
 */
@property (readonly, nonatomic) OHGameControllerButton *right;















@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHGameControllerDirectionalPad.m from [ea3786c95c] to [99e27b345d].

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
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHGameControllerDirectionalPad.h"

#import "OHEmulatedGameControllerAxis.h"
#import "OHEmulatedGameControllerButton.h"



@implementation OHGameControllerDirectionalPad
@synthesize xAxis = _xAxis, yAxis = _yAxis;
@synthesize up = _up, down = _down, left = _left, right = _right;



























- (instancetype)initWithName: (OFString *)name analog: (bool)analog
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithName: (OFString *)name
		       xAxis: (OHGameControllerAxis *)xAxis
		       yAxis: (OHGameControllerAxis *)yAxis
		      analog: (bool)analog
{
	self = [super initWithName: name analog: analog];

	@try {
		_xAxis = [xAxis retain];
		_yAxis = [yAxis retain];

		_up = [[OHEmulatedGameControllerButton alloc]
		    initWithAxis: _yAxis
			positive: false];
		_down = [[OHEmulatedGameControllerButton alloc]
		    initWithAxis: _yAxis
			positive: true];
		_left = [[OHEmulatedGameControllerButton alloc]
		    initWithAxis: _xAxis
			positive: false];
		_right = [[OHEmulatedGameControllerButton alloc]
		    initWithAxis: _xAxis
			positive: true];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithName: (OFString *)name
			  up: (OHGameControllerButton *)up
			down: (OHGameControllerButton *)down
			left: (OHGameControllerButton *)left
		       right: (OHGameControllerButton *)right
		      analog: (bool)analog
{
	self = [super initWithName: name analog: analog];

	@try {
		_up = [up retain];
		_down = [down retain];
		_left = [left retain];
		_right = [right retain];

		_xAxis = [[OHEmulatedGameControllerAxis alloc]
		    initWithNegativeButton: _left
			    positiveButton: _right];
		_yAxis = [[OHEmulatedGameControllerAxis alloc]
		    initWithNegativeButton: _up
			    positiveButton: _down];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}







>


>
>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|




|
|
|
|

|






|
|

|
|

|
|

|
|








|
|
|
|
|
|

|








|
|

|
|







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
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHGameControllerDirectionalPad.h"
#import "OHGameControllerDirectionalPad+Private.h"
#import "OHEmulatedGameControllerAxis.h"
#import "OHEmulatedGameControllerButton.h"
#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"

@implementation OHGameControllerDirectionalPad
@synthesize xAxis = _xAxis, yAxis = _yAxis;
@synthesize up = _up, down = _down, left = _left, right = _right;

+ (instancetype)oh_padWithName: (OFString *)name
			 xAxis: (OHGameControllerAxis *)xAxis
			 yAxis: (OHGameControllerAxis *)yAxis
			analog: (bool)analog
{
	return [[[self alloc] oh_initWithName: name
					xAxis: xAxis
					yAxis: yAxis
				       analog: analog] autorelease];
}

+ (instancetype)oh_padWithName: (OFString *)name
			    up: (OHGameControllerButton *)up
			  down: (OHGameControllerButton *)down
			  left: (OHGameControllerButton *)left
			 right: (OHGameControllerButton *)right
			analog: (bool)analog
{
	return [[[self alloc] oh_initWithName: name
					   up: up
					 down: down
					 left: left
					right: right
				       analog: analog] autorelease];
}

- (instancetype)oh_initWithName: (OFString *)name analog: (bool)analog
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_initWithName: (OFString *)name
			  xAxis: (OHGameControllerAxis *)xAxis
			  yAxis: (OHGameControllerAxis *)yAxis
			 analog: (bool)analog
{
	self = [super oh_initWithName: name analog: analog];

	@try {
		_xAxis = [xAxis retain];
		_yAxis = [yAxis retain];

		_up = [[OHEmulatedGameControllerButton alloc]
		    oh_initWithAxis: _yAxis
			   positive: false];
		_down = [[OHEmulatedGameControllerButton alloc]
		    oh_initWithAxis: _yAxis
			   positive: true];
		_left = [[OHEmulatedGameControllerButton alloc]
		    oh_initWithAxis: _xAxis
			   positive: false];
		_right = [[OHEmulatedGameControllerButton alloc]
		    oh_initWithAxis: _xAxis
			   positive: true];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)oh_initWithName: (OFString *)name
			     up: (OHGameControllerButton *)up
			   down: (OHGameControllerButton *)down
			   left: (OHGameControllerButton *)left
			  right: (OHGameControllerButton *)right
			 analog: (bool)analog
{
	self = [super oh_initWithName: name analog: analog];

	@try {
		_up = [up retain];
		_down = [down retain];
		_left = [left retain];
		_right = [right retain];

		_xAxis = [[OHEmulatedGameControllerAxis alloc]
		    oh_initWithNegativeButton: _left
			       positiveButton: _right];
		_yAxis = [[OHEmulatedGameControllerAxis alloc]
		    oh_initWithNegativeButton: _up
			       positiveButton: _down];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

Added src/hid/OHGameControllerElement+Private.h version [71db15a22e].































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * 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 "OHGameControllerElement.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHGameControllerElement ()
+ (instancetype)oh_elementWithName: (OFString *)name analog: (bool)analog;
- (instancetype)oh_initWithName: (OFString *)name
			 analog: (bool)analog
    OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHGameControllerElement.h from [3b9ea1e52c] to [fd11aae561].

51
52
53
54
55
56
57
58
59
60
61
62
63

/**
 * @brief Whether the game controller element is analog.
 */
@property (readonly, nonatomic, getter=isAnalog) bool analog;

- (instancetype)init OF_UNAVAILABLE;

- (instancetype)initWithName: (OFString *)name
		      analog: (bool)analog OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END







<
<
<



51
52
53
54
55
56
57



58
59
60

/**
 * @brief Whether the game controller element is analog.
 */
@property (readonly, nonatomic, getter=isAnalog) bool analog;

- (instancetype)init OF_UNAVAILABLE;



@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHGameControllerElement.m from [a3cd067a48] to [903f44a676].

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
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHGameControllerElement.h"


@implementation OHGameControllerElement
@synthesize name = _name, analog = _analog;







- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithName: (OFString *)name
		      analog: (bool)analog
{
	self = [super init];

	@try {
		_name = [name copy];
		_analog = analog;
	} @catch (id e) {







>



>
>
>
>
>
>






|
<







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
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"

@implementation OHGameControllerElement
@synthesize name = _name, analog = _analog;

+ (instancetype)oh_elementWithName: (OFString *)name analog: (bool)analog
{
	return [[[self alloc] oh_initWithName: name
				       analog: analog] autorelease];
}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_initWithName: (OFString *)name analog: (bool)analog

{
	self = [super init];

	@try {
		_name = [name copy];
		_analog = analog;
	} @catch (id e) {

Modified src/hid/OHJoyConPair.h from [343333c252] to [5a32c92419].

59
60
61
62
63
64
65
66

67
68
69
 *	  and right Joy-Con.
 *
 * @param leftJoyCon The left Joy-Con for the pair
 * @param rightJoyCon The right Joy-Con for the pair
 * @return An initialized Joy-Con pair
 */
- (instancetype)initWithLeftJoyCon: (OHLeftJoyCon *)leftJoyCon
		       rightJoyCon: (OHRightJoyCon *)rightJoyCon;

@end

OF_ASSUME_NONNULL_END







|
>



59
60
61
62
63
64
65
66
67
68
69
70
 *	  and right Joy-Con.
 *
 * @param leftJoyCon The left Joy-Con for the pair
 * @param rightJoyCon The right Joy-Con for the pair
 * @return An initialized Joy-Con pair
 */
- (instancetype)initWithLeftJoyCon: (OHLeftJoyCon *)leftJoyCon
		       rightJoyCon: (OHRightJoyCon *)rightJoyCon
    OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHLeftJoyCon+Private.h from [7ebb30c3cd] to [64c33a2717].

21
22
23
24
25
26
27

28
29
30

31
32
33

#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# import "OHEvdevGameController.h"
#endif

OF_ASSUME_NONNULL_BEGIN


#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
@interface OHLeftJoyCon () <OHEvdevMapping>
@end

#endif

OF_ASSUME_NONNULL_END







>

|
|
>
|


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# import "OHEvdevGameController.h"
#endif

OF_ASSUME_NONNULL_BEGIN

@interface OHLeftJoyCon ()
#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
    <OHEvdevMapping>
#endif
- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHLeftJoyCon.h from [1a2b03b667] to [b8da3ac968].

24
25
26
27
28
29
30
31

32
33
34


35
36
37
/**
 * @class OHLeftJoyCon OHLeftJoyCon.h ObjFWHID/ObjFWHID.h
 *
 * @brief A left Nintendo Switch Joy-Con.
 */
@interface OHLeftJoyCon: OFObject <OHGameControllerProfile>
{
	OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons;

	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}


@end

OF_ASSUME_NONNULL_END







|
>



>
>



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
 * @class OHLeftJoyCon OHLeftJoyCon.h ObjFWHID/ObjFWHID.h
 *
 * @brief A left Nintendo Switch Joy-Con.
 */
@interface OHLeftJoyCon: OFObject <OHGameControllerProfile>
{
	OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *))
	    *_buttons;
	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}

- (instancetype)init OF_UNAVAILABLE;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHLeftJoyCon.m from [a38d580513] to [3ad9df20b4].

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

#import "OHLeftJoyCon.h"
#import "OHLeftJoyCon+Private.h"
#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"




#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# include <linux/input.h>
# import "evdev_compat.h"
#endif

static OFString *const buttonNames[] = {
	@"L", @"ZL", @"Left Thumbstick", @"-", @"Capture", @"SL", @"SR"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHLeftJoyCon
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init
{





	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OFMutableDictionary *directionalPads;
		OHGameControllerAxis *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;
		OHGameControllerButton *up, *down, *left, *right;

		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button =
			    [[[OHGameControllerButton alloc]
			    initWithName: buttonNames[i]
				  analog: false] autorelease];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		_buttons = [buttons retain];

		directionalPads =
		    [OFMutableDictionary dictionaryWithCapacity: 2];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"X"
			  analog: true] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"Y"
			  analog: true] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"Left Thumbstick"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: true] autorelease];
		[directionalPads setObject: directionalPad
				    forKey: @"Left Thumbstick"];

		up = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Up"
			  analog: false] autorelease];
		down = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Down"
			  analog: false] autorelease];
		left = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Left"
			  analog: false] autorelease];
		right = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Right"
			  analog: false] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"D-Pad"
			      up: up
			    down: down
			    left: left
			   right: right
			  analog: false] autorelease];
		[directionalPads setObject: directionalPad forKey: @"D-Pad"];

		[directionalPads makeImmutable];
		_directionalPads = [directionalPads retain];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {







>
>
>
















>
>
>
>
>












|
<
|
|








|
<
|
|
<
|
|
|
|
|
|



|
<
|
<
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|







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

#import "OHLeftJoyCon.h"
#import "OHLeftJoyCon+Private.h"
#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHGameControllerDirectionalPad+Private.h"
#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"

#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# include <linux/input.h>
# import "evdev_compat.h"
#endif

static OFString *const buttonNames[] = {
	@"L", @"ZL", @"Left Thumbstick", @"-", @"Capture", @"SL", @"SR"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHLeftJoyCon
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_init
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OFMutableDictionary *directionalPads;
		OHGameControllerAxis *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;
		OHGameControllerButton *up, *down, *left, *right;

		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button = [OHGameControllerButton

			    oh_elementWithName: buttonNames[i]
					analog: false];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		_buttons = [buttons retain];

		directionalPads =
		    [OFMutableDictionary dictionaryWithCapacity: 2];

		xAxis = [OHGameControllerAxis oh_elementWithName: @"X"

							  analog: true];
		yAxis = [OHGameControllerAxis oh_elementWithName: @"Y"

							  analog: true];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"Left Thumbstick"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: true];
		[directionalPads setObject: directionalPad
				    forKey: @"Left Thumbstick"];

		up = [OHGameControllerButton oh_elementWithName: @"D-Pad Up"

							 analog: false];

		down = [OHGameControllerButton oh_elementWithName: @"D-Pad Down"
							   analog: false];

		left = [OHGameControllerButton oh_elementWithName: @"D-Pad Left"
							   analog: false];
		right = [OHGameControllerButton
		    oh_elementWithName: @"D-Pad Right"
				analog: false];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"D-Pad"
				up: up
			      down: down
			      left: left
			     right: right
			    analog: false];
		[directionalPads setObject: directionalPad forKey: @"D-Pad"];

		[directionalPads makeImmutable];
		_directionalPads = [directionalPads retain];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {

Modified src/hid/OHN64Controller+Private.h from [888278bf3d] to [11c03bea55].

21
22
23
24
25
26
27

28
29
30

31
32
33

#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# import "OHEvdevGameController.h"
#endif

OF_ASSUME_NONNULL_BEGIN


#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
@interface OHN64Controller () <OHEvdevMapping>
@end

#endif

OF_ASSUME_NONNULL_END







>

|
|
>
|


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# import "OHEvdevGameController.h"
#endif

OF_ASSUME_NONNULL_BEGIN

@interface OHN64Controller ()
#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
    <OHEvdevMapping>
#endif
- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHN64Controller.h from [214e4b0857] to [a09d540cf6].

24
25
26
27
28
29
30
31

32
33
34


35
36
37
/**
 * @class OHN64Controller OHN64Controller.h ObjFWHID/ObjFWHID.h
 *
 * @brief A Nintendo 64 controller.
 */
@interface OHN64Controller: OFObject <OHGameControllerProfile>
{
	OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons;

	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}


@end

OF_ASSUME_NONNULL_END







|
>



>
>



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
 * @class OHN64Controller OHN64Controller.h ObjFWHID/ObjFWHID.h
 *
 * @brief A Nintendo 64 controller.
 */
@interface OHN64Controller: OFObject <OHGameControllerProfile>
{
	OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *))
	    *_buttons;
	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}

- (instancetype)init OF_UNAVAILABLE;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHN64Controller.m from [623858fd4c] to [7e5e39d255].

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

#import "OHN64Controller.h"
#import "OHN64Controller+Private.h"
#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"




#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# include <linux/input.h>
#endif

static OFString *const buttonNames[] = {
	@"A", @"B", @"L", @"R", @"Z", @"Start"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHN64Controller
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init
{





	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OFMutableDictionary *directionalPads;
		OHGameControllerAxis *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;
		OHGameControllerButton *up, *down, *left, *right;

		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button =
			    [[[OHGameControllerButton alloc]
			    initWithName: buttonNames[i]
				  analog: false] autorelease];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		_buttons = [buttons retain];

		directionalPads =
		    [OFMutableDictionary dictionaryWithCapacity: 3];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"X"
			  analog: true] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"Y"
			  analog: true] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"Thumbstick"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: true] autorelease];
		[directionalPads setObject: directionalPad
				    forKey: @"Thumbstick"];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"D-Pad X"
			  analog: false] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"D-Pad Y"
			  analog: false] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"D-Pad"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: false] autorelease];
		[directionalPads setObject: directionalPad forKey: @"D-Pad"];

		up = [[[OHGameControllerButton alloc]
		    initWithName: @"C-Up"
			  analog: false] autorelease];
		down = [[[OHGameControllerButton alloc]
		    initWithName: @"C-Down"
			  analog: false] autorelease];
		left = [[[OHGameControllerButton alloc]
		    initWithName: @"C-Left"
			  analog: false] autorelease];
		right = [[[OHGameControllerButton alloc]
		    initWithName: @"C-Right"
			  analog: false] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"C-Buttons"
			      up: up
			    down: down
			    left: left
			   right: right
			  analog: false] autorelease];
		[directionalPads setObject: directionalPad
				    forKey: @"C-Buttons"];

		[directionalPads makeImmutable];
		_directionalPads = [directionalPads retain];

		objc_autoreleasePoolPop(pool);







>
>
>















>
>
>
>
>












|
<
|
|








|
<
|
|
<
|
|
|
|
|
|



<
|
|
<
|
|
|
|
|
|
|


|
<
|
|
<
|
|
<
|
|
<
|
|
|
|
|
|
|
|







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

#import "OHN64Controller.h"
#import "OHN64Controller+Private.h"
#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHGameControllerDirectionalPad+Private.h"
#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"

#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# include <linux/input.h>
#endif

static OFString *const buttonNames[] = {
	@"A", @"B", @"L", @"R", @"Z", @"Start"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHN64Controller
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_init
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OFMutableDictionary *directionalPads;
		OHGameControllerAxis *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;
		OHGameControllerButton *up, *down, *left, *right;

		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button = [OHGameControllerButton

			    oh_elementWithName: buttonNames[i]
					analog: false];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		_buttons = [buttons retain];

		directionalPads =
		    [OFMutableDictionary dictionaryWithCapacity: 3];

		xAxis = [OHGameControllerAxis oh_elementWithName: @"X"

							  analog: true];
		yAxis = [OHGameControllerAxis oh_elementWithName: @"Y"

							  analog: true];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"Thumbstick"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: true];
		[directionalPads setObject: directionalPad
				    forKey: @"Thumbstick"];


		xAxis = [OHGameControllerAxis oh_elementWithName: @"D-Pad X"
							  analog: false];

		yAxis = [OHGameControllerAxis oh_elementWithName: @"D-Pad Y"
							  analog: false];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"D-Pad"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: false];
		[directionalPads setObject: directionalPad forKey: @"D-Pad"];

		up = [OHGameControllerButton oh_elementWithName: @"C-Up"

							 analog: false];
		down = [OHGameControllerButton oh_elementWithName: @"C-Down"

							   analog: false];
		left = [OHGameControllerButton oh_elementWithName: @"C-Left"

							   analog: false];
		right = [OHGameControllerButton oh_elementWithName: @"C-Right"

							    analog: false];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"C-Buttons"
				up: up
			      down: down
			      left: left
			     right: right
			    analog: false];
		[directionalPads setObject: directionalPad
				    forKey: @"C-Buttons"];

		[directionalPads makeImmutable];
		_directionalPads = [directionalPads retain];

		objc_autoreleasePoolPop(pool);

Added src/hid/OHNintendo3DSExtendedGamepad+Private.h version [71e1e47b25].

























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * 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 "OHNintendo3DSExtendedGamepad.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHNintendo3DSExtendedGamepad ()
- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHNintendo3DSExtendedGamepad.h from [20fc31d17d] to [d346b8a699].

19
20
21
22
23
24
25
26

27
28
29


30
31
32

#import "OHExtendedGamepad.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHNintendo3DSExtendedGamepad: OFObject <OHExtendedGamepad>
{
	OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons;

	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}


@end

OF_ASSUME_NONNULL_END







|
>



>
>



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

#import "OHExtendedGamepad.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHNintendo3DSExtendedGamepad: OFObject <OHExtendedGamepad>
{
	OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *))
	    *_buttons;
	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}

- (instancetype)init OF_UNAVAILABLE;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHNintendo3DSExtendedGamepad.m from [2b5e0e2bfe] to [2ad5cbb462].

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
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHNintendo3DSExtendedGamepad.h"

#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"




static OFString *const buttonNames[] = {
	@"A", @"B", @"X", @"Y", @"L", @"R", @"ZL", @"ZR", @"Start", @"Select"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHNintendo3DSExtendedGamepad
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init





{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OFMutableDictionary *directionalPads;
		OHGameControllerAxis *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;
		OHGameControllerButton *up, *down, *left, *right;

		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button =
			    [[[OHGameControllerButton alloc]
			    initWithName: buttonNames[i]
				  analog: false] autorelease];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		_buttons = [buttons retain];

		directionalPads =
		    [OFMutableDictionary dictionaryWithCapacity: 3];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"X"
			  analog: true] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"Y"
			  analog: true] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"Circle Pad"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: true] autorelease];
		[directionalPads setObject: directionalPad
				    forKey: @"Circle Pad"];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"CX"
			  analog: true] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"CY"
			  analog: true] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"C-Stick"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: true] autorelease];
		[directionalPads setObject: directionalPad
				    forKey: @"C-Stick"];

		up = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Up"
			  analog: false] autorelease];
		down = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Down"
			  analog: false] autorelease];
		left = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Left"
			  analog: false] autorelease];
		right = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Right"
			  analog: false] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"D-Pad"
			      up: up
			    down: down
			    left: left
			   right: right
			  analog: false] autorelease];
		[directionalPads setObject: directionalPad forKey: @"D-Pad"];

		[directionalPads makeImmutable];
		_directionalPads = [directionalPads retain];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {







>




>
>
>










>
>
>
>
>













|
<
|
|








|
<
|
|
<
|
|
|
|
|
|



|
<
|
|
<
|
|
|
|
|
|



|
<
|
<
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|







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
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHNintendo3DSExtendedGamepad.h"
#import "OHNintendo3DSExtendedGamepad+Private.h"
#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHGameControllerDirectionalPad+Private.h"
#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"

static OFString *const buttonNames[] = {
	@"A", @"B", @"X", @"Y", @"L", @"R", @"ZL", @"ZR", @"Start", @"Select"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHNintendo3DSExtendedGamepad
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_init
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OFMutableDictionary *directionalPads;
		OHGameControllerAxis *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;
		OHGameControllerButton *up, *down, *left, *right;

		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button = [OHGameControllerButton

			    oh_elementWithName: buttonNames[i]
					analog: false];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		_buttons = [buttons retain];

		directionalPads =
		    [OFMutableDictionary dictionaryWithCapacity: 3];

		xAxis = [OHGameControllerAxis oh_elementWithName: @"X"

							  analog: true];
		yAxis = [OHGameControllerAxis oh_elementWithName: @"Y"

							  analog: true];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"Circle Pad"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: true];
		[directionalPads setObject: directionalPad
				    forKey: @"Circle Pad"];

		xAxis = [OHGameControllerAxis oh_elementWithName: @"CX"

							  analog: true];
		yAxis = [OHGameControllerAxis oh_elementWithName: @"CY"

							  analog: true];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"C-Stick"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: true];
		[directionalPads setObject: directionalPad
				    forKey: @"C-Stick"];

		up = [OHGameControllerButton oh_elementWithName: @"D-Pad Up"

							 analog: false];

		down = [OHGameControllerButton oh_elementWithName: @"D-Pad Down"
							   analog: false];

		left = [OHGameControllerButton oh_elementWithName: @"D-Pad Left"
							   analog: false];
		right = [OHGameControllerButton
		    oh_elementWithName: @"D-Pad Right"
				analog: false];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"D-Pad"
				up: up
			      down: down
			      left: left
			     right: right
			    analog: false];
		[directionalPads setObject: directionalPad forKey: @"D-Pad"];

		[directionalPads makeImmutable];
		_directionalPads = [directionalPads retain];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {

Modified src/hid/OHNintendo3DSGameController.m from [2ceda08904] to [65d65bf5a5].

18
19
20
21
22
23
24


25
26
27
28

29
30
31
32
33
34
35
 */

#include "config.h"

#import "OHNintendo3DSGameController.h"
#import "OFArray.h"
#import "OFDictionary.h"


#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHNintendo3DSExtendedGamepad.h"


#import "OFInitializationFailedException.h"
#import "OFReadFailedException.h"

#define id id_3ds
#include <3ds.h>
#undef id







>
>




>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 */

#include "config.h"

#import "OHNintendo3DSGameController.h"
#import "OFArray.h"
#import "OFDictionary.h"
#import "OHGameController.h"
#import "OHGameController+Private.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHNintendo3DSExtendedGamepad.h"
#import "OHNintendo3DSExtendedGamepad+Private.h"

#import "OFInitializationFailedException.h"
#import "OFReadFailedException.h"

#define id id_3ds
#include <3ds.h>
#undef id
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
	void *pool;

	if (self != [OHNintendo3DSGameController class])
		return;

	pool = objc_autoreleasePoolPush();
	controllers = [[OFArray alloc] initWithObject:
	    [[[OHNintendo3DSGameController alloc] init] autorelease]];
	objc_autoreleasePoolPop(pool);
}

+ (OFArray OF_GENERIC(OHGameController *) *)controllers
{
	return controllers;
}

- (instancetype)init
{
	self = [super init];

	@try {

		_extendedGamepad = [[OHNintendo3DSExtendedGamepad alloc] init];

		[self updateState];
	} @catch (id e) {
		[self release];
		@throw e;
	}








|








|

|


>
|







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
	void *pool;

	if (self != [OHNintendo3DSGameController class])
		return;

	pool = objc_autoreleasePoolPush();
	controllers = [[OFArray alloc] initWithObject:
	    [[[OHNintendo3DSGameController alloc] oh_init] autorelease]];
	objc_autoreleasePoolPop(pool);
}

+ (OFArray OF_GENERIC(OHGameController *) *)controllers
{
	return controllers;
}

- (instancetype)oh_init
{
	self = [super oh_init];

	@try {
		_extendedGamepad =
		    [[OHNintendo3DSExtendedGamepad alloc] oh_init];

		[self updateState];
	} @catch (id e) {
		[self release];
		@throw e;
	}

Modified src/hid/OHNintendoDSGameController.m from [e8178e5420] to [ca937bebcc].

18
19
20
21
22
23
24


25
26
27

28
29
30
31
32
33
34
 */

#include "config.h"

#import "OHNintendoDSGameController.h"
#import "OFArray.h"
#import "OFDictionary.h"


#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHNintendoDSGamepad.h"


#import "OFInitializationFailedException.h"
#import "OFReadFailedException.h"

#define asm __asm__
#include <nds.h>
#undef asm







>
>



>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 */

#include "config.h"

#import "OHNintendoDSGameController.h"
#import "OFArray.h"
#import "OFDictionary.h"
#import "OHGameController.h"
#import "OHGameController+Private.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHNintendoDSGamepad.h"
#import "OHNintendoDSGamepad+Private.h"

#import "OFInitializationFailedException.h"
#import "OFReadFailedException.h"

#define asm __asm__
#include <nds.h>
#undef asm
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
	void *pool;

	if (self != [OHNintendoDSGameController class])
		return;

	pool = objc_autoreleasePoolPush();
	controllers = [[OFArray alloc] initWithObject:
	    [[[OHNintendoDSGameController alloc] init] autorelease]];
	objc_autoreleasePoolPop(pool);
}

+ (OFArray OF_GENERIC(OHGameController *) *)controllers
{
	return controllers;
}

- (instancetype)init
{
	self = [super init];

	@try {
		_gamepad = [[OHNintendoDSGamepad alloc] init];

		[self updateState];
	} @catch (id e) {
		[self release];
		@throw e;
	}








|








|

|


|







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
	void *pool;

	if (self != [OHNintendoDSGameController class])
		return;

	pool = objc_autoreleasePoolPush();
	controllers = [[OFArray alloc] initWithObject:
	    [[[OHNintendoDSGameController alloc] oh_init] autorelease]];
	objc_autoreleasePoolPop(pool);
}

+ (OFArray OF_GENERIC(OHGameController *) *)controllers
{
	return controllers;
}

- (instancetype)oh_init
{
	self = [super oh_init];

	@try {
		_gamepad = [[OHNintendoDSGamepad alloc] oh_init];

		[self updateState];
	} @catch (id e) {
		[self release];
		@throw e;
	}

Added src/hid/OHNintendoDSGamepad+Private.h version [cd863ff816].

























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * 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 "OHNintendoDSGamepad.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHNintendoDSGamepad ()
- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHNintendoDSGamepad.h from [cfe0e81593] to [4f03ae1a2d].

19
20
21
22
23
24
25
26

27
28
29


30
31
32

#import "OHGamepad.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHNintendoDSGamepad: OFObject <OHGamepad>
{
	OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons;

	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}


@end

OF_ASSUME_NONNULL_END







|
>



>
>



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

#import "OHGamepad.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHNintendoDSGamepad: OFObject <OHGamepad>
{
	OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *))
	    *_buttons;
	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}

- (instancetype)init OF_UNAVAILABLE;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHNintendoDSGamepad.m from [9daef32bf6] to [5ff13c9373].

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
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHNintendoDSGamepad.h"

#import "OFDictionary.h"


#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"




static OFString *const buttonNames[] = {
	@"A", @"B", @"X", @"Y", @"L", @"R", @"Start", @"Select"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHNintendoDSGamepad
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init





{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OHGameControllerButton *up, *down, *left, *right;
		OHGameControllerDirectionalPad *dPad;

		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button =
			    [[[OHGameControllerButton alloc]
			    initWithName: buttonNames[i]
				  analog: false] autorelease];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		_buttons = [buttons retain];

		up = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Up"
			  analog: false] autorelease];
		down = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Down"
			  analog: false] autorelease];
		left = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Left"
			  analog: false] autorelease];
		right = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Right"
			  analog: false] autorelease];
		dPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"D-Pad"
			      up: up
			    down: down
			    left: left
			   right: right
			  analog: false] autorelease];

		_directionalPads = [[OFDictionary alloc]
		    initWithObject: dPad
			    forKey: @"D-Pad"];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {







>

>
>


>
>
>










>
>
>
>
>











|
<
|
|





|
<
|
<
|
|
<
|
|
|
|
|
|
<
|
|
|
|
|







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
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHNintendoDSGamepad.h"
#import "OHNintendoDSGamepad+Private.h"
#import "OFDictionary.h"
#import "OHGameController.h"
#import "OHGameController+Private.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHGameControllerDirectionalPad+Private.h"
#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"

static OFString *const buttonNames[] = {
	@"A", @"B", @"X", @"Y", @"L", @"R", @"Start", @"Select"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHNintendoDSGamepad
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_init
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OHGameControllerButton *up, *down, *left, *right;
		OHGameControllerDirectionalPad *dPad;

		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button = [OHGameControllerButton

			    oh_elementWithName: buttonNames[i]
					analog: false];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		_buttons = [buttons retain];

		up = [OHGameControllerButton oh_elementWithName: @"D-Pad Up"

							 analog: false];

		down = [OHGameControllerButton oh_elementWithName: @"D-Pad Down"
							   analog: false];

		left = [OHGameControllerButton oh_elementWithName: @"D-Pad Left"
							   analog: false];
		right = [OHGameControllerButton
		    oh_elementWithName: @"D-Pad Right"
				analog: false];
		dPad = [OHGameControllerDirectionalPad oh_padWithName: @"D-Pad"

								   up: up
								 down: down
								 left: left
								right: right
							       analog: false];

		_directionalPads = [[OFDictionary alloc]
		    initWithObject: dPad
			    forKey: @"D-Pad"];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {

Added src/hid/OHNintendoSwitchExtendedGamepad+Private.h version [f2f071698a].

























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * 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 "OHNintendoSwitchExtendedGamepad.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHNintendoSwitchExtendedGamepad ()
- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHNintendoSwitchExtendedGamepad.h from [506fd309d9] to [66981f3fa6].

19
20
21
22
23
24
25
26

27
28
29


30
31
32

#import "OHExtendedGamepad.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHNintendoSwitchExtendedGamepad: OFObject <OHExtendedGamepad>
{
	OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons;

	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}


@end

OF_ASSUME_NONNULL_END







|
>



>
>



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

#import "OHExtendedGamepad.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHNintendoSwitchExtendedGamepad: OFObject <OHExtendedGamepad>
{
	OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *))
	    *_buttons;
	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}

- (instancetype)init OF_UNAVAILABLE;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHNintendoSwitchExtendedGamepad.m from [50efe01c0d] to [70416dbdb2].

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
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHNintendoSwitchExtendedGamepad.h"

#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"




static OFString *const buttonNames[] = {
	@"A", @"B", @"X", @"Y", @"L", @"R", @"ZL", @"ZR", @"Left Thumbstick",
	@"Right Thumbstick", @"+", @"-"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHNintendoSwitchExtendedGamepad
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init





{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OFMutableDictionary *directionalPads;
		OHGameControllerAxis *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;
		OHGameControllerButton *up, *down, *left, *right;

		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button =
			    [[[OHGameControllerButton alloc]
			    initWithName: buttonNames[i]
				  analog: false] autorelease];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		_buttons = [buttons retain];

		directionalPads =
		    [OFMutableDictionary dictionaryWithCapacity: 3];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"X"
			  analog: true] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"Y"
			  analog: true] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"Left Thumbstick"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: true] autorelease];
		[directionalPads setObject: directionalPad
				    forKey: @"Left Thumbstick"];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"RX"
			  analog: true] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"RY"
			  analog: true] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"Right Thumbstick"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: true] autorelease];
		[directionalPads setObject: directionalPad
				    forKey: @"Right Thumbstick"];

		up = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Up"
			  analog: false] autorelease];
		down = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Down"
			  analog: false] autorelease];
		left = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Left"
			  analog: false] autorelease];
		right = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Right"
			  analog: false] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"D-Pad"
			      up: up
			    down: down
			    left: left
			   right: right
			  analog: false] autorelease];
		[directionalPads setObject: directionalPad forKey: @"D-Pad"];

		[directionalPads makeImmutable];
		_directionalPads = [directionalPads retain];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {







>




>
>
>











>
>
>
>
>













|
<
|
|








|
<
|
|
<
|
|
|
|
|
|



|
<
|
|
<
|
|
|
|
|
|



|
<
|
<
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|







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
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHNintendoSwitchExtendedGamepad.h"
#import "OHNintendoSwitchExtendedGamepad+Private.h"
#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHGameControllerDirectionalPad+Private.h"
#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"

static OFString *const buttonNames[] = {
	@"A", @"B", @"X", @"Y", @"L", @"R", @"ZL", @"ZR", @"Left Thumbstick",
	@"Right Thumbstick", @"+", @"-"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHNintendoSwitchExtendedGamepad
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_init
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OFMutableDictionary *directionalPads;
		OHGameControllerAxis *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;
		OHGameControllerButton *up, *down, *left, *right;

		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button = [OHGameControllerButton

			    oh_elementWithName: buttonNames[i]
					analog: false];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		_buttons = [buttons retain];

		directionalPads =
		    [OFMutableDictionary dictionaryWithCapacity: 3];

		xAxis = [OHGameControllerAxis oh_elementWithName: @"X"

							  analog: true];
		yAxis = [OHGameControllerAxis oh_elementWithName: @"Y"

							  analog: true];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"Left Thumbstick"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: true];
		[directionalPads setObject: directionalPad
				    forKey: @"Left Thumbstick"];

		xAxis = [OHGameControllerAxis oh_elementWithName: @"RX"

							  analog: true];
		yAxis = [OHGameControllerAxis oh_elementWithName: @"RY"

							  analog: true];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"Right Thumbstick"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: true];
		[directionalPads setObject: directionalPad
				    forKey: @"Right Thumbstick"];

		up = [OHGameControllerButton oh_elementWithName: @"D-Pad Up"

							 analog: false];

		down = [OHGameControllerButton oh_elementWithName: @"D-Pad Down"
							   analog: false];

		left = [OHGameControllerButton oh_elementWithName: @"D-Pad Left"
							   analog: false];
		right = [OHGameControllerButton
		    oh_elementWithName: @"D-Pad Right"
				analog: false];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"D-Pad"
				up: up
			      down: down
			      left: left
			     right: right
			    analog: false];
		[directionalPads setObject: directionalPad forKey: @"D-Pad"];

		[directionalPads makeImmutable];
		_directionalPads = [directionalPads retain];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {

Modified src/hid/OHNintendoSwitchGameController.h from [ed7820b3e1] to [1610daa529].

29
30
31
32
33
34
35

36

37
38
39

@interface OHNintendoSwitchGameController: OHGameController
{
	PadState _pad;
	OHNintendoSwitchExtendedGamepad *_extendedGamepad;
}


- (instancetype)initWithIndex: (size_t)index;

@end

OF_ASSUME_NONNULL_END







>
|
>



29
30
31
32
33
34
35
36
37
38
39
40
41

@interface OHNintendoSwitchGameController: OHGameController
{
	PadState _pad;
	OHNintendoSwitchExtendedGamepad *_extendedGamepad;
}

- (instancetype)oh_init OF_UNAVAILABLE;
- (instancetype)oh_initWithIndex: (size_t)index
    OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHNintendoSwitchGameController.m from [6bf69b44e2] to [0e698ea509].

18
19
20
21
22
23
24


25
26
27
28

29
30
31
32
33
34
35
 */

#include "config.h"

#import "OHNintendoSwitchGameController.h"
#import "OFArray.h"
#import "OFDictionary.h"


#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHNintendoSwitchExtendedGamepad.h"


#import "OFInitializationFailedException.h"
#import "OFReadFailedException.h"

#define id nx_id
#include <switch.h>
#undef id







>
>




>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 */

#include "config.h"

#import "OHNintendoSwitchGameController.h"
#import "OFArray.h"
#import "OFDictionary.h"
#import "OHGameController.h"
#import "OHGameController+Private.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHNintendoSwitchExtendedGamepad.h"
#import "OHNintendoSwitchExtendedGamepad+Private.h"

#import "OFInitializationFailedException.h"
#import "OFReadFailedException.h"

#define id nx_id
#include <switch.h>
#undef id
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
	void *pool = objc_autoreleasePoolPush();

	for (size_t i = 0; i < maxControllers; i++) {
		OHGameController *controller;

		@try {
			controller = [[[OHNintendoSwitchGameController alloc]
			    initWithIndex: i] autorelease];
		} @catch (OFInitializationFailedException *e) {
			/* Controller does not exist. */
			continue;
		}

		[controllers addObject: controller];
	}

	[controllers makeImmutable];

	objc_autoreleasePoolPop(pool);

	return controllers;
}

- (instancetype)initWithIndex: (size_t)index
{





	self = [super init];

	@try {
		padInitialize(&_pad, HidNpadIdType_No1 + index,
		    (index == 0 ? HidNpadIdType_Handheld : 0));
		padUpdate(&_pad);

		if (!padIsConnected(&_pad))
			@throw [OFInitializationFailedException
			    exceptionWithClass: self.class];

		_extendedGamepad =
		    [[OHNintendoSwitchExtendedGamepad alloc] init];

		[self updateState];
	} @catch (id e) {
		[self release];
		@throw e;
	}








|















|

>
>
>
>
>
|











|







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
	void *pool = objc_autoreleasePoolPush();

	for (size_t i = 0; i < maxControllers; i++) {
		OHGameController *controller;

		@try {
			controller = [[[OHNintendoSwitchGameController alloc]
			    oh_initWithIndex: i] autorelease];
		} @catch (OFInitializationFailedException *e) {
			/* Controller does not exist. */
			continue;
		}

		[controllers addObject: controller];
	}

	[controllers makeImmutable];

	objc_autoreleasePoolPop(pool);

	return controllers;
}

- (instancetype)oh_init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_initWithIndex: (size_t)index
{
	self = [super oh_init];

	@try {
		padInitialize(&_pad, HidNpadIdType_No1 + index,
		    (index == 0 ? HidNpadIdType_Handheld : 0));
		padUpdate(&_pad);

		if (!padIsConnected(&_pad))
			@throw [OFInitializationFailedException
			    exceptionWithClass: self.class];

		_extendedGamepad =
		    [[OHNintendoSwitchExtendedGamepad alloc] oh_init];

		[self updateState];
	} @catch (id e) {
		[self release];
		@throw e;
	}

Modified src/hid/OHRightJoyCon+Private.h from [4b9a80f5a0] to [802121ee0a].

21
22
23
24
25
26
27

28
29
30

31
32
33

#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# import "OHEvdevGameController.h"
#endif

OF_ASSUME_NONNULL_BEGIN


#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
@interface OHRightJoyCon () <OHEvdevMapping>
@end

#endif

OF_ASSUME_NONNULL_END







>

|
|
>
|


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# import "OHEvdevGameController.h"
#endif

OF_ASSUME_NONNULL_BEGIN

@interface OHRightJoyCon ()
#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
    <OHEvdevMapping>
#endif
- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHRightJoyCon.h from [99c6b39cda] to [a3b8190dff].

24
25
26
27
28
29
30
31

32
33
34


35
36
37
/**
 * @class OHRightJoyCon OHRightJoyCon.h ObjFWHID/ObjFWHID.h
 *
 * @brief A right Nintendo Switch Joy-Con.
 */
@interface OHRightJoyCon: OFObject <OHGameControllerProfile>
{
	OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons;

	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}


@end

OF_ASSUME_NONNULL_END







|
>



>
>



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
 * @class OHRightJoyCon OHRightJoyCon.h ObjFWHID/ObjFWHID.h
 *
 * @brief A right Nintendo Switch Joy-Con.
 */
@interface OHRightJoyCon: OFObject <OHGameControllerProfile>
{
	OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *))
	    *_buttons;
	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}

- (instancetype)init OF_UNAVAILABLE;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHRightJoyCon.m from [a138914b11] to [8b5dc7ba55].

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

#import "OHRightJoyCon.h"
#import "OHRightJoyCon+Private.h"
#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"




#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# include <linux/input.h>
# import "evdev_compat.h"
#endif

static OFString *const buttonNames[] = {
	@"X", @"B", @"A", @"Y", @"R", @"ZR", @"Right Thumbstick", @"+",
	@"Home", @"SL", @"SR"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHRightJoyCon
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init
{





	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OHGameControllerAxis *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;

		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button =
			    [[[OHGameControllerButton alloc]
			    initWithName: buttonNames[i]
				  analog: false] autorelease];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		_buttons = [buttons retain];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"X"
			  analog: true] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"Y"
			  analog: true] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"Right Thumbstick"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: true] autorelease];

		_directionalPads = [[OFDictionary alloc]
		    initWithObject: directionalPad
			    forKey: @"Right Thumbstick"];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {







>
>
>

















>
>
>
>
>










|
<
|
|





|
<
|
|
<
|
|
|
|
|
|







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

#import "OHRightJoyCon.h"
#import "OHRightJoyCon+Private.h"
#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHGameControllerDirectionalPad+Private.h"
#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"

#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# include <linux/input.h>
# import "evdev_compat.h"
#endif

static OFString *const buttonNames[] = {
	@"X", @"B", @"A", @"Y", @"R", @"ZR", @"Right Thumbstick", @"+",
	@"Home", @"SL", @"SR"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHRightJoyCon
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_init
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OHGameControllerAxis *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;

		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button = [OHGameControllerButton

			    oh_elementWithName: buttonNames[i]
					analog: false];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		_buttons = [buttons retain];

		xAxis = [OHGameControllerAxis oh_elementWithName: @"X"

							  analog: true];
		yAxis = [OHGameControllerAxis oh_elementWithName: @"Y"

							  analog: true];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"Right Thumbstick"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: true];

		_directionalPads = [[OFDictionary alloc]
		    initWithObject: directionalPad
			    forKey: @"Right Thumbstick"];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {

Modified src/hid/OHStadiaGamepad+Private.h from [6469bc0d6a] to [a442bf59a0].

21
22
23
24
25
26
27

28
29
30

31
32
33

#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# import "OHEvdevGameController.h"
#endif

OF_ASSUME_NONNULL_BEGIN


#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
@interface OHStadiaGamepad () <OHEvdevMapping>
@end

#endif

OF_ASSUME_NONNULL_END







>

|
|
>
|


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# import "OHEvdevGameController.h"
#endif

OF_ASSUME_NONNULL_BEGIN

@interface OHStadiaGamepad ()
#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
    <OHEvdevMapping>
#endif
- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHStadiaGamepad.h from [65ae611c46] to [e229c39258].

24
25
26
27
28
29
30
31

32
33
34


35
36
37
/**
 * @class OHStadiaGamepad OHStadiaGamepad.h ObjFWHID/ObjFWHID.h
 *
 * @brief A Stadia gamepad.
 */
@interface OHStadiaGamepad: OFObject <OHExtendedGamepad>
{
	OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons;

	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}


@end

OF_ASSUME_NONNULL_END







|
>



>
>



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
 * @class OHStadiaGamepad OHStadiaGamepad.h ObjFWHID/ObjFWHID.h
 *
 * @brief A Stadia gamepad.
 */
@interface OHStadiaGamepad: OFObject <OHExtendedGamepad>
{
	OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *))
	    *_buttons;
	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}

- (instancetype)init OF_UNAVAILABLE;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHStadiaGamepad.m from [59e1f24ccf] to [276a08dcca].

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
#import "OHStadiaGamepad.h"
#import "OHStadiaGamepad+Private.h"
#import "OFDictionary.h"
#import "OHEmulatedGameControllerTriggerButton.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"




#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# include <linux/input.h>
#endif

static OFString *const buttonNames[] = {
	@"A", @"B", @"X", @"Y", @"L1", @"R1", @"L3", @"R3", @"Menu", @"Options",
	@"Capture", @"Stadia", @"Assistant"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHStadiaGamepad
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init
{





	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OHGameControllerButton *button;
		OFMutableDictionary *directionalPads;
		OHGameControllerAxis *axis, *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;

		for (size_t i = 0; i < numButtons; i++) {
			button = [[[OHGameControllerButton alloc]
			    initWithName: buttonNames[i]
				  analog: false] autorelease];
			[buttons setObject: button forKey: buttonNames[i]];
		}

		axis = [[[OHGameControllerAxis alloc]
		    initWithName: @"L2"
			  analog: true] autorelease];
		button = [[[OHEmulatedGameControllerTriggerButton alloc]
		    initWithName: @"L2"
			    axis: axis] autorelease];
		[buttons setObject: button forKey: @"L2"];

		axis = [[[OHGameControllerAxis alloc]
		    initWithName: @"R2"
			  analog: true] autorelease];
		button = [[[OHEmulatedGameControllerTriggerButton alloc]
		    initWithName: @"R2"
			    axis: axis] autorelease];
		[buttons setObject: button forKey: @"R2"];

		[buttons makeImmutable];
		_buttons = [buttons retain];

		directionalPads =
		    [OFMutableDictionary dictionaryWithCapacity: 3];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"X"
			  analog: true] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"Y"
			  analog: true] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"Left Stick"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: true] autorelease];
		[directionalPads setObject: directionalPad
				    forKey: @"Left Stick"];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"RX"
			  analog: true] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"RY"
			  analog: true] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"Right Stick"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: true] autorelease];
		[directionalPads setObject: directionalPad
				    forKey: @"Right Stick"];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"D-Pad X"
			  analog: false] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"D-Pad Y"
			  analog: false] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"D-Pad"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: false] autorelease];
		[directionalPads setObject: directionalPad forKey: @"D-Pad"];

		[directionalPads makeImmutable];
		_directionalPads = [directionalPads retain];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {







>
>
>
















>
>
>
>
>












|
|
|



|
<
|
|
|
|


|
<
|
|
|
|








|
<
|
|
<
|
|
|
|
|
|



|
<
|
|
<
|
|
|
|
|
|



<
|
|
<
|
|
|
|
|
|
|







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
#import "OHStadiaGamepad.h"
#import "OHStadiaGamepad+Private.h"
#import "OFDictionary.h"
#import "OHEmulatedGameControllerTriggerButton.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHGameControllerDirectionalPad+Private.h"
#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"

#if defined(OF_LINUX) && defined(OF_HAVE_FILES)
# include <linux/input.h>
#endif

static OFString *const buttonNames[] = {
	@"A", @"B", @"X", @"Y", @"L1", @"R1", @"L3", @"R3", @"Menu", @"Options",
	@"Capture", @"Stadia", @"Assistant"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHStadiaGamepad
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_init
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OHGameControllerButton *button;
		OFMutableDictionary *directionalPads;
		OHGameControllerAxis *axis, *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;

		for (size_t i = 0; i < numButtons; i++) {
			button = [OHGameControllerButton
			    oh_elementWithName: buttonNames[i]
					analog: false];
			[buttons setObject: button forKey: buttonNames[i]];
		}

		axis = [OHGameControllerAxis oh_elementWithName: @"L2"

							 analog: true];
		button = [OHEmulatedGameControllerTriggerButton
		    oh_buttonWithName: @"L2"
				 axis: axis];
		[buttons setObject: button forKey: @"L2"];

		axis = [OHGameControllerAxis oh_elementWithName: @"R2"

							 analog: true];
		button = [OHEmulatedGameControllerTriggerButton
		    oh_buttonWithName: @"R2"
				 axis: axis];
		[buttons setObject: button forKey: @"R2"];

		[buttons makeImmutable];
		_buttons = [buttons retain];

		directionalPads =
		    [OFMutableDictionary dictionaryWithCapacity: 3];

		xAxis = [OHGameControllerAxis oh_elementWithName: @"X"

							  analog: true];
		yAxis = [OHGameControllerAxis oh_elementWithName: @"Y"

							  analog: true];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"Left Stick"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: true];
		[directionalPads setObject: directionalPad
				    forKey: @"Left Stick"];

		xAxis = [OHGameControllerAxis oh_elementWithName: @"RX"

							  analog: true];
		yAxis = [OHGameControllerAxis oh_elementWithName: @"RY"

							  analog: true];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"Right Stick"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: true];
		[directionalPads setObject: directionalPad
				    forKey: @"Right Stick"];


		xAxis = [OHGameControllerAxis oh_elementWithName: @"D-Pad X"
							  analog: false];

		yAxis = [OHGameControllerAxis oh_elementWithName: @"D-Pad Y"
							  analog: false];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"D-Pad"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: false];
		[directionalPads setObject: directionalPad forKey: @"D-Pad"];

		[directionalPads makeImmutable];
		_directionalPads = [directionalPads retain];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
	case ABS_RZ:
		return [[_directionalPads objectForKey: @"Right Stick"] yAxis];
	case ABS_HAT0X:
		return [[_directionalPads objectForKey: @"D-Pad"] xAxis];
	case ABS_HAT0Y:
		return [[_directionalPads objectForKey: @"D-Pad"] yAxis];
	case ABS_BRAKE:
		return ((OHEmulatedGameControllerTriggerButton *)
		    [_buttons objectForKey: @"L2"]).axis;
	case ABS_GAS:
		return ((OHEmulatedGameControllerTriggerButton *)
		    [_buttons objectForKey: @"R2"]).axis;
	default:
		return nil;
	}
}
#endif
@end







<
|

<
|






292
293
294
295
296
297
298

299
300

301
302
303
304
305
306
307
	case ABS_RZ:
		return [[_directionalPads objectForKey: @"Right Stick"] yAxis];
	case ABS_HAT0X:
		return [[_directionalPads objectForKey: @"D-Pad"] xAxis];
	case ABS_HAT0Y:
		return [[_directionalPads objectForKey: @"D-Pad"] yAxis];
	case ABS_BRAKE:

		return [[_buttons objectForKey: @"L2"] oh_axis];
	case ABS_GAS:

		return [[_buttons objectForKey: @"R2"] oh_axis];
	default:
		return nil;
	}
}
#endif
@end

Added src/hid/OHWiiClassicController+Private.h version [349a2e57f0].

























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * 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 "OHWiiClassicController.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHWiiClassicController ()
- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHWiiClassicController.h from [88de8f00f1] to [b79cb7ea67].

23
24
25
26
27
28
29


30
31
32

@interface OHWiiClassicController: OFObject <OHExtendedGamepad>
{
	OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons;
	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}


@end

OF_ASSUME_NONNULL_END







>
>



23
24
25
26
27
28
29
30
31
32
33
34

@interface OHWiiClassicController: OFObject <OHExtendedGamepad>
{
	OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons;
	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}

- (instancetype)init OF_UNAVAILABLE;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHWiiClassicController.m from [cc27368578] to [71daa63334].

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
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHWiiClassicController.h"

#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"




static OFString *const buttonNames[] = {
	@"A", @"B", @"X", @"Y", @"L", @"R", @"ZL", @"ZR", @"+", @"-", @"Home"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHWiiClassicController
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init





{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OFMutableDictionary *directionalPads;
		OHGameControllerAxis *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;
		OHGameControllerButton *up, *down, *left, *right;

		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button =
			    [[OHGameControllerButton alloc]
			    initWithName: buttonNames[i]
				  analog: false];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		_buttons = [buttons retain];

		directionalPads =
		    [OFMutableDictionary dictionaryWithCapacity: 3];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"X"
			  analog: true] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"Y"
			  analog: true] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"Left Thumbstick"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: true] autorelease];
		[directionalPads setObject: directionalPad
				    forKey: @"Left Thumbstick"];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"RX"
			  analog: true] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"RY"
			  analog: true] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"Right Thumbstick"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: true] autorelease];
		[directionalPads setObject: directionalPad
				    forKey: @"Right Thumbstick"];

		up = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Up"
			  analog: false] autorelease];
		down = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Down"
			  analog: false] autorelease];
		left = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Left"
			  analog: false] autorelease];
		right = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Right"
			  analog: false] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"D-Pad"
			      up: up
			    down: down
			    left: left
			   right: right
			  analog: false] autorelease];
		[directionalPads setObject: directionalPad forKey: @"D-Pad"];

		[directionalPads makeImmutable];
		_directionalPads = [directionalPads retain];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {







>




>
>
>










>
>
>
>
>













|
<
|
|








|
<
|
|
<
|
|
|
|
|
|



|
<
|
|
<
|
|
|
|
|
|



|
<
|
<
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|







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
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHWiiClassicController.h"
#import "OHWiiClassicController+Private.h"
#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHGameControllerDirectionalPad+Private.h"
#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"

static OFString *const buttonNames[] = {
	@"A", @"B", @"X", @"Y", @"L", @"R", @"ZL", @"ZR", @"+", @"-", @"Home"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHWiiClassicController
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_init
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		OFMutableDictionary *directionalPads;
		OHGameControllerAxis *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;
		OHGameControllerButton *up, *down, *left, *right;

		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button = [OHGameControllerButton

			    oh_elementWithName: buttonNames[i]
					analog: false];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		_buttons = [buttons retain];

		directionalPads =
		    [OFMutableDictionary dictionaryWithCapacity: 3];

		xAxis = [OHGameControllerAxis oh_elementWithName: @"X"

							  analog: true];
		yAxis = [OHGameControllerAxis oh_elementWithName: @"Y"

							  analog: true];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"Left Thumbstick"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: true];
		[directionalPads setObject: directionalPad
				    forKey: @"Left Thumbstick"];

		xAxis = [OHGameControllerAxis oh_elementWithName: @"RX"

							  analog: true];
		yAxis = [OHGameControllerAxis oh_elementWithName: @"RY"

							  analog: true];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"Right Thumbstick"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: true];
		[directionalPads setObject: directionalPad
				    forKey: @"Right Thumbstick"];

		up = [OHGameControllerButton oh_elementWithName: @"D-Pad Up"

							 analog: false];

		down = [OHGameControllerButton oh_elementWithName: @"D-Pad Down"
							   analog: false];

		left = [OHGameControllerButton oh_elementWithName: @"D-Pad Left"
							   analog: false];
		right = [OHGameControllerButton
		    oh_elementWithName: @"D-Pad Right"
				analog: false];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"D-Pad"
				up: up
			      down: down
			      left: left
			     right: right
			    analog: false];
		[directionalPads setObject: directionalPad forKey: @"D-Pad"];

		[directionalPads makeImmutable];
		_directionalPads = [directionalPads retain];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {

Modified src/hid/OHWiiGameController.h from [7fb9593e8b] to [8f82a3a691].

24
25
26
27
28
29
30


31

32
33
34
@interface OHWiiGameController: OHGameController
{
	int32_t _index;
	uint32_t _type;
	id <OHGameControllerProfile> _profile;
}



- (instancetype)initWithIndex: (int32_t)index type: (uint32_t)type;

@end

OF_ASSUME_NONNULL_END







>
>
|
>



24
25
26
27
28
29
30
31
32
33
34
35
36
37
@interface OHWiiGameController: OHGameController
{
	int32_t _index;
	uint32_t _type;
	id <OHGameControllerProfile> _profile;
}

- (instancetype)oh_init OF_UNAVAILABLE;
- (instancetype)oh_initWithIndex: (int32_t)index
			    type: (uint32_t)type
    OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHWiiGameController.m from [e32aeb7c28] to [27d5c09680].

18
19
20
21
22
23
24


25
26
27

28

29
30
31
32
33
34
35
 */

#include "config.h"

#import "OHWiiGameController.h"
#import "OFArray.h"
#import "OFDictionary.h"


#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHWiiClassicController.h"

#import "OHWiimote.h"

#import "OHWiimoteWithNunchuk.h"

#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFReadFailedException.h"

#define asm __asm__







>
>



>

>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 */

#include "config.h"

#import "OHWiiGameController.h"
#import "OFArray.h"
#import "OFDictionary.h"
#import "OHGameController.h"
#import "OHGameController+Private.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHWiiClassicController.h"
#import "OHWiiClassicController+Private.h"
#import "OHWiimote.h"
#import "OHWiimote+Private.h"
#import "OHWiimoteWithNunchuk.h"

#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFReadFailedException.h"

#define asm __asm__
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
	for (int32_t i = 0; i < WPAD_MAX_WIIMOTES; i++) {
		uint32_t type;

		if (WPAD_Probe(i, &type) == WPAD_ERR_NONE &&
		    (type == WPAD_EXP_NONE || type == WPAD_EXP_NUNCHUK ||
		    type == WPAD_EXP_CLASSIC))
			[controllers addObject: [[[OHWiiGameController alloc]
			    initWithIndex: i
				     type: type] autorelease]];
	}

	[controllers makeImmutable];

	objc_autoreleasePoolPop(pool);

	return controllers;
}






- (instancetype)initWithIndex: (int32_t)index type: (uint32_t)type
{
	self = [super init];

	@try {
		_index = index;
		_type = type;

		if (type == WPAD_EXP_CLASSIC)
			_profile = [[OHWiiClassicController alloc] init];
		else if (type == WPAD_EXP_NUNCHUK)
			_profile = [[OHWiimoteWithNunchuk alloc] init];
		else
			_profile = [[OHWiimote alloc] init];

		[self updateState];
	} @catch (id e) {
		[self release];
		@throw e;
	}








|
|









>
>
>
>
>
|

|






|

|

|







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
	for (int32_t i = 0; i < WPAD_MAX_WIIMOTES; i++) {
		uint32_t type;

		if (WPAD_Probe(i, &type) == WPAD_ERR_NONE &&
		    (type == WPAD_EXP_NONE || type == WPAD_EXP_NUNCHUK ||
		    type == WPAD_EXP_CLASSIC))
			[controllers addObject: [[[OHWiiGameController alloc]
			    oh_initWithIndex: i
					type: type] autorelease]];
	}

	[controllers makeImmutable];

	objc_autoreleasePoolPop(pool);

	return controllers;
}

- (instancetype)oh_init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_initWithIndex: (int32_t)index type: (uint32_t)type
{
	self = [super oh_init];

	@try {
		_index = index;
		_type = type;

		if (type == WPAD_EXP_CLASSIC)
			_profile = [[OHWiiClassicController alloc] oh_init];
		else if (type == WPAD_EXP_NUNCHUK)
			_profile = [[OHWiimoteWithNunchuk alloc] oh_init];
		else
			_profile = [[OHWiimote alloc] oh_init];

		[self updateState];
	} @catch (id e) {
		[self release];
		@throw e;
	}

Added src/hid/OHWiimote+Private.h version [2b1ff9eae2].

























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * 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 "OHWiimote.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHWiimote ()
- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHWiimote.h from [776944f0bb] to [bab7922722].

23
24
25
26
27
28
29


30
31
32

@interface OHWiimote: OFObject <OHGameControllerProfile>
{
	OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons;
	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}


@end

OF_ASSUME_NONNULL_END







>
>



23
24
25
26
27
28
29
30
31
32
33
34

@interface OHWiimote: OFObject <OHGameControllerProfile>
{
	OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons;
	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}

- (instancetype)init OF_UNAVAILABLE;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHWiimote.m from [f4ccfcaf1a] to [428268d86d].

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
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHWiimote.h"

#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"




static OFString *const buttonNames[] = {
	@"A", @"B", @"1", @"2", @"+", @"-", @"Home"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHWiimote
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init





{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons;
		OHGameControllerDirectionalPad *dPad;
		OHGameControllerButton *up, *down, *left, *right;

		buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button =
			    [[[OHGameControllerButton alloc]
			    initWithName: buttonNames[i]
				  analog: false] autorelease];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		_buttons = [buttons retain];

		up = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Up"
			  analog: false] autorelease];
		down = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Down"
			  analog: false] autorelease];
		left = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Left"
			  analog: false] autorelease];
		right = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Right"
			  analog: false] autorelease];
		dPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"D-Pad"
			      up: up
			    down: down
			    left: left
			   right: right
			  analog: false] autorelease];

		_directionalPads = [[OFDictionary alloc]
		    initWithObject: dPad
			    forKey: @"D-Pad"];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {







>




>
>
>










>
>
>
>
>












|
<
|
|





|
<
|
<
|
|
<
|
|
|
|
|
|
<
|
|
|
|
|







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
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHWiimote.h"
#import "OHWiimote+Private.h"
#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHGameControllerDirectionalPad+Private.h"
#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"

static OFString *const buttonNames[] = {
	@"A", @"B", @"1", @"2", @"+", @"-", @"Home"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHWiimote
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_init
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons;
		OHGameControllerDirectionalPad *dPad;
		OHGameControllerButton *up, *down, *left, *right;

		buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button = [OHGameControllerButton

			    oh_elementWithName: buttonNames[i]
					analog: false];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		_buttons = [buttons retain];

		up = [OHGameControllerButton oh_elementWithName: @"D-Pad Up"

							 analog: false];

		down = [OHGameControllerButton oh_elementWithName: @"D-Pad Down"
							   analog: false];

		left = [OHGameControllerButton oh_elementWithName: @"D-Pad Left"
							   analog: false];
		right = [OHGameControllerButton
		    oh_elementWithName: @"D-Pad Right"
				analog: false];
		dPad = [OHGameControllerDirectionalPad oh_padWithName: @"D-Pad"

								   up: up
								 down: down
								 left: left
								right: right
							       analog: false];

		_directionalPads = [[OFDictionary alloc]
		    initWithObject: dPad
			    forKey: @"D-Pad"];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {

Modified src/hid/OHWiimoteWithNunchuk.m from [7c176b4a85] to [513c0fa137].

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
#include "config.h"

#import "OHWiimoteWithNunchuk.h"
#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"





static OFString *const buttonNames[] = {
	@"C", @"Z"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHWiimoteWithNunchuk
- (instancetype)init
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [[_buttons mutableCopy] autorelease];
		OFMutableDictionary *directionalPads =
		    [[_directionalPads mutableCopy] autorelease];
		OHGameControllerAxis *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;

		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button =
			    [[[OHGameControllerButton alloc]
			    initWithName: buttonNames[i]
				  analog: false] autorelease];

			[buttons setObject: button forKey: buttonNames[i]];
		}

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"X"
			  analog: true] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"Y"
			  analog: true] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"Analog Stick"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: true] autorelease];
		[directionalPads setObject: directionalPad
				    forKey: @"Analog Stick"];

		[buttons makeImmutable];
		[_buttons release];
		_buttons = [buttons retain];








>
>
>
>







|

|











|
<
|
|




|
<
|
|
<
|
|
|
|
|
|







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
#include "config.h"

#import "OHWiimoteWithNunchuk.h"
#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHGameControllerDirectionalPad+Private.h"
#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"
#import "OHWiimote+Private.h"

static OFString *const buttonNames[] = {
	@"C", @"Z"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHWiimoteWithNunchuk
- (instancetype)oh_init
{
	self = [super oh_init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [[_buttons mutableCopy] autorelease];
		OFMutableDictionary *directionalPads =
		    [[_directionalPads mutableCopy] autorelease];
		OHGameControllerAxis *xAxis, *yAxis;
		OHGameControllerDirectionalPad *directionalPad;

		for (size_t i = 0; i < numButtons; i++) {
			OHGameControllerButton *button = [OHGameControllerButton

			    oh_elementWithName: buttonNames[i]
					analog: false];

			[buttons setObject: button forKey: buttonNames[i]];
		}

		xAxis = [OHGameControllerAxis oh_elementWithName: @"X"

							  analog: true];
		yAxis = [OHGameControllerAxis oh_elementWithName: @"Y"

							  analog: true];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"Analog Stick"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: true];
		[directionalPads setObject: directionalPad
				    forKey: @"Analog Stick"];

		[buttons makeImmutable];
		[_buttons release];
		_buttons = [buttons retain];

Modified src/hid/OHXInputGameController.h from [986c587ab0] to [6ebbc4a0ee].

28
29
30
31
32
33
34

35

36
37
38
@interface OHXInputGameController: OHGameController
{
	DWORD _index;
	OFNumber *_Nullable _vendorID, *_Nullable _productID;
	OHXboxGamepad *_extendedGamepad;
}


- (instancetype)initWithIndex: (DWORD)index;

@end

OF_ASSUME_NONNULL_END







>
|
>



28
29
30
31
32
33
34
35
36
37
38
39
40
@interface OHXInputGameController: OHGameController
{
	DWORD _index;
	OFNumber *_Nullable _vendorID, *_Nullable _productID;
	OHXboxGamepad *_extendedGamepad;
}

- (instancetype)oh_init OF_UNAVAILABLE;
- (instancetype)oh_initWithIndex: (DWORD)index
    OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHXInputGameController.m from [1bec2a2275] to [13dd789839].

19
20
21
22
23
24
25


26
27
28
29

30
31
32
33
34
35
36

#include "config.h"

#import "OHXInputGameController.h"
#import "OFArray.h"
#import "OFDictionary.h"
#import "OFNumber.h"


#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHXboxGamepad.h"


#import "OFInitializationFailedException.h"
#import "OFReadFailedException.h"

#include <xinput.h>

#ifndef XINPUT_GAMEPAD_GUIDE







>
>




>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

#include "config.h"

#import "OHXInputGameController.h"
#import "OFArray.h"
#import "OFDictionary.h"
#import "OFNumber.h"
#import "OHGameController.h"
#import "OHGameController+Private.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHXboxGamepad.h"
#import "OHXboxGamepad+Private.h"

#import "OFInitializationFailedException.h"
#import "OFReadFailedException.h"

#include <xinput.h>

#ifndef XINPUT_GAMEPAD_GUIDE
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
		void *pool = objc_autoreleasePoolPush();

		for (DWORD i = 0; i < XUSER_MAX_COUNT; i++) {
			OHGameController *controller;

			@try {
				controller = [[[OHXInputGameController alloc]
				    initWithIndex: i] autorelease];
			} @catch (OFInitializationFailedException *e) {
				/* Controller does not exist. */
				continue;
			}

			[controllers addObject: controller];
		}

		objc_autoreleasePoolPop(pool);
	}

	[controllers makeImmutable];

	return controllers;
}

- (instancetype)initWithIndex: (DWORD)index
{





	self = [super init];

	@try {
		XINPUT_STATE state = { 0 };

		if (XInputGetStateFuncPtr(index, &state) ==
		    ERROR_DEVICE_NOT_CONNECTED)
			@throw [OFInitializationFailedException







|
















|

>
>
>
>
>
|







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
		void *pool = objc_autoreleasePoolPush();

		for (DWORD i = 0; i < XUSER_MAX_COUNT; i++) {
			OHGameController *controller;

			@try {
				controller = [[[OHXInputGameController alloc]
				    oh_initWithIndex: i] autorelease];
			} @catch (OFInitializationFailedException *e) {
				/* Controller does not exist. */
				continue;
			}

			[controllers addObject: controller];
		}

		objc_autoreleasePoolPop(pool);
	}

	[controllers makeImmutable];

	return controllers;
}

- (instancetype)oh_init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_initWithIndex: (DWORD)index
{
	self = [super oh_init];

	@try {
		XINPUT_STATE state = { 0 };

		if (XInputGetStateFuncPtr(index, &state) ==
		    ERROR_DEVICE_NOT_CONNECTED)
			@throw [OFInitializationFailedException
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
				_productID = [[OFNumber alloc]
				    initWithUnsignedShort:
				    capabilities.productID];
			}
		}

		_extendedGamepad = [[OHXboxGamepad alloc]
		    initWithHasGuideButton: (XInputVersion != 910)];

		[self updateState];
	} @catch (id e) {
		[self release];
		@throw e;
	}








|







146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
				_productID = [[OFNumber alloc]
				    initWithUnsignedShort:
				    capabilities.productID];
			}
		}

		_extendedGamepad = [[OHXboxGamepad alloc]
		    oh_initWithHasGuideButton: (XInputVersion != 910)];

		[self updateState];
	} @catch (id e) {
		[self release];
		@throw e;
	}

167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
	XINPUT_STATE state = { 0 };

	if (XInputGetStateFuncPtr(_index, &state) != ERROR_SUCCESS)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: sizeof(state)
							    errNo: 0];

	_extendedGamepad.northButton.value =
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_Y);
	_extendedGamepad.southButton.value =
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_A);
	_extendedGamepad.westButton.value =
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_X);
	_extendedGamepad.eastButton.value =
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_B);
	_extendedGamepad.leftShoulderButton.value =
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER);
	_extendedGamepad.rightShoulderButton.value =
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER);
	_extendedGamepad.leftThumbstickButton.value =
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB);
	_extendedGamepad.rightThumbstickButton.value =
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB);
	_extendedGamepad.menuButton.value =
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_START);
	_extendedGamepad.optionsButton.value =
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK);
	if (XInputVersion != 910)
		_extendedGamepad.homeButton.value =
		    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_GUIDE);

	_extendedGamepad.leftTriggerButton.value =
	    (float)state.Gamepad.bLeftTrigger / 255;
	_extendedGamepad.rightTriggerButton.value =
	    (float)state.Gamepad.bRightTrigger / 255;

	_extendedGamepad.leftThumbstick.xAxis.value =
	    (float)state.Gamepad.sThumbLX /
	    (state.Gamepad.sThumbLX < 0 ? -INT16_MIN : INT16_MAX);
	_extendedGamepad.leftThumbstick.yAxis.value =
	    -(float)state.Gamepad.sThumbLY /
	    (state.Gamepad.sThumbLY < 0 ? -INT16_MIN : INT16_MAX);
	_extendedGamepad.rightThumbstick.xAxis.value =
	    (float)state.Gamepad.sThumbRX /
	    (state.Gamepad.sThumbRX < 0 ? -INT16_MIN : INT16_MAX);
	_extendedGamepad.rightThumbstick.yAxis.value =
	    -(float)state.Gamepad.sThumbRY /
	    (state.Gamepad.sThumbRY < 0 ? -INT16_MIN : INT16_MAX);

	_extendedGamepad.dPad.up.value =
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP);
	_extendedGamepad.dPad.down.value =
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN);
	_extendedGamepad.dPad.left.value =
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT);
	_extendedGamepad.dPad.right.value =
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT);
}

- (OFString *)name
{
	switch (XInputVersion) {
	case 14:
		return @"XInput 1.4 device";







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|

|
|
|
|

|

|
|

|
|

|
|

|

|
|
|
|
|
|
|
|







175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
	XINPUT_STATE state = { 0 };

	if (XInputGetStateFuncPtr(_index, &state) != ERROR_SUCCESS)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: sizeof(state)
							    errNo: 0];

	[_extendedGamepad.northButton setValue:
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_Y)];
	[_extendedGamepad.southButton setValue:
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_A)];
	[_extendedGamepad.westButton setValue:
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_X)];
	[_extendedGamepad.eastButton setValue:
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_B)];
	[_extendedGamepad.leftShoulderButton setValue:
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER)];
	[_extendedGamepad.rightShoulderButton setValue:
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER)];
	[_extendedGamepad.leftThumbstickButton setValue:
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB)];
	[_extendedGamepad.rightThumbstickButton setValue:
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB)];
	[_extendedGamepad.menuButton setValue:
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_START)];
	[_extendedGamepad.optionsButton setValue:
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK)];
	if (XInputVersion != 910)
		[_extendedGamepad.homeButton setValue:
		    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_GUIDE)];

	[_extendedGamepad.leftTriggerButton setValue:
	    (float)state.Gamepad.bLeftTrigger / 255];
	[_extendedGamepad.rightTriggerButton setValue:
	    (float)state.Gamepad.bRightTrigger / 255];

	[_extendedGamepad.leftThumbstick.xAxis setValue:
	    (float)state.Gamepad.sThumbLX /
	    (state.Gamepad.sThumbLX < 0 ? -INT16_MIN : INT16_MAX)];
	[_extendedGamepad.leftThumbstick.yAxis setValue:
	    -(float)state.Gamepad.sThumbLY /
	    (state.Gamepad.sThumbLY < 0 ? -INT16_MIN : INT16_MAX)];
	[_extendedGamepad.rightThumbstick.xAxis setValue:
	    (float)state.Gamepad.sThumbRX /
	    (state.Gamepad.sThumbRX < 0 ? -INT16_MIN : INT16_MAX)];
	[_extendedGamepad.rightThumbstick.yAxis setValue:
	    -(float)state.Gamepad.sThumbRY /
	    (state.Gamepad.sThumbRY < 0 ? -INT16_MIN : INT16_MAX)];

	[_extendedGamepad.dPad.up setValue:
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)];
	[_extendedGamepad.dPad.down setValue:
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)];
	[_extendedGamepad.dPad.left setValue:
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)];
	[_extendedGamepad.dPad.right setValue:
	    !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)];
}

- (OFString *)name
{
	switch (XInputVersion) {
	case 14:
		return @"XInput 1.4 device";

Added src/hid/OHXboxGamepad+Private.h version [d4ee9c13d5].



























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * 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 "OHXboxGamepad.h"

OF_ASSUME_NONNULL_BEGIN

@interface OHXboxGamepad ()
- (instancetype)oh_initWithHasGuideButton: (bool)hasGuideButton
    OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHXboxGamepad.h from [b8cf8dd88d] to [e3f1adf622].

24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
/**
 * @class OHXboxGamepad OHXboxGamepad.h ObjFWHID/ObjFWHID.h
 *
 * @brief A Microsoft Xbox gamepad.
 */
@interface OHXboxGamepad: OFObject <OHExtendedGamepad>
{
	OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons;

	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}

- (instancetype)initWithHasGuideButton: (bool)hasGuideButton;
@end

OF_ASSUME_NONNULL_END







|
>




|



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
 * @class OHXboxGamepad OHXboxGamepad.h ObjFWHID/ObjFWHID.h
 *
 * @brief A Microsoft Xbox gamepad.
 */
@interface OHXboxGamepad: OFObject <OHExtendedGamepad>
{
	OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *))
	    *_buttons;
	OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *)
	    *_directionalPads;
}

- (instancetype)init OF_UNAVAILABLE;
@end

OF_ASSUME_NONNULL_END

Modified src/hid/OHXboxGamepad.m from [2b505e6c37] to [9716e4f3d7].

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
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHXboxGamepad.h"

#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"




static OFString *const buttonNames[] = {
	@"A", @"B", @"X", @"Y", @"LB", @"RB", @"LT", @"RT", @"LSB", @"RSB",
	@"Start", @"Back", @"Guide"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHXboxGamepad
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init
{
	return [self initWithHasGuideButton: true];
}

- (instancetype)initWithHasGuideButton: (bool)hasGuideButton
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];







>




>
>
>












|


|







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
 * version 3.0 along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#import "OHXboxGamepad.h"
#import "OHXboxGamepad+Private.h"
#import "OFDictionary.h"
#import "OHGameControllerAxis.h"
#import "OHGameControllerButton.h"
#import "OHGameControllerDirectionalPad.h"
#import "OHGameControllerDirectionalPad+Private.h"
#import "OHGameControllerElement.h"
#import "OHGameControllerElement+Private.h"

static OFString *const buttonNames[] = {
	@"A", @"B", @"X", @"Y", @"LB", @"RB", @"LT", @"RT", @"LSB", @"RSB",
	@"Start", @"Back", @"Guide"
};
static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames);

@implementation OHXboxGamepad
@synthesize buttons = _buttons, directionalPads = _directionalPads;

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)oh_initWithHasGuideButton: (bool)hasGuideButton
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableDictionary *buttons =
		    [OFMutableDictionary dictionaryWithCapacity: numButtons];
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
			    [buttonNames[i] isEqual: @"RT"]);
			OHGameControllerButton *button;

			if ([buttonNames[i] isEqual: @"Guide"] &&
			    !hasGuideButton)
				continue;

			button = [[[OHGameControllerButton alloc]
			    initWithName: buttonNames[i]
				  analog: analog] autorelease];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		_buttons = [buttons retain];

		directionalPads =
		    [OFMutableDictionary dictionaryWithCapacity: 3];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"X"
			  analog: true] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"Y"
			  analog: true] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"Left Thumbstick"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: true] autorelease];
		[directionalPads setObject: directionalPad
				    forKey: @"Left Thumbstick"];

		xAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"RX"
			  analog: true] autorelease];
		yAxis = [[[OHGameControllerAxis alloc]
		    initWithName: @"RY"
			  analog: true] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"Right Thumbstick"
			   xAxis: xAxis
			   yAxis: yAxis
			  analog: true] autorelease];
		[directionalPads setObject: directionalPad
				    forKey: @"Right Thumbstick"];

		up = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Up"
			  analog: false] autorelease];
		down = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Down"
			  analog: false] autorelease];
		left = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Left"
			  analog: false] autorelease];
		right = [[[OHGameControllerButton alloc]
		    initWithName: @"D-Pad Right"
			  analog: false] autorelease];
		directionalPad = [[[OHGameControllerDirectionalPad alloc]
		    initWithName: @"D-Pad"
			      up: up
			    down: down
			    left: left
			   right: right
			  analog: false] autorelease];
		[directionalPads setObject: directionalPad forKey: @"D-Pad"];

		[directionalPads makeImmutable];
		_directionalPads = [directionalPads retain];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {







|
|
|








|
<
|
|
<
|
|
|
|
|
|



|
<
|
|
<
|
|
|
|
|
|



|
<
|
<
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|







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
			    [buttonNames[i] isEqual: @"RT"]);
			OHGameControllerButton *button;

			if ([buttonNames[i] isEqual: @"Guide"] &&
			    !hasGuideButton)
				continue;

			button = [OHGameControllerButton
			    oh_elementWithName: buttonNames[i]
					analog: analog];
			[buttons setObject: button forKey: buttonNames[i]];
		}
		[buttons makeImmutable];
		_buttons = [buttons retain];

		directionalPads =
		    [OFMutableDictionary dictionaryWithCapacity: 3];

		xAxis = [OHGameControllerAxis oh_elementWithName: @"X"

							  analog: true];
		yAxis = [OHGameControllerAxis oh_elementWithName: @"Y"

							  analog: true];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"Left Thumbstick"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: true];
		[directionalPads setObject: directionalPad
				    forKey: @"Left Thumbstick"];

		xAxis = [OHGameControllerAxis oh_elementWithName: @"RX"

							  analog: true];
		yAxis = [OHGameControllerAxis oh_elementWithName: @"RY"

							  analog: true];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"Right Thumbstick"
			     xAxis: xAxis
			     yAxis: yAxis
			    analog: true];
		[directionalPads setObject: directionalPad
				    forKey: @"Right Thumbstick"];

		up = [OHGameControllerButton oh_elementWithName: @"D-Pad Up"

							 analog: false];

		down = [OHGameControllerButton oh_elementWithName: @"D-Pad Down"
							   analog: false];

		left = [OHGameControllerButton oh_elementWithName: @"D-Pad Left"
							   analog: false];
		right = [OHGameControllerButton
		    oh_elementWithName: @"D-Pad Right"
				analog: false];
		directionalPad = [OHGameControllerDirectionalPad
		    oh_padWithName: @"D-Pad"
				up: up
			      down: down
			      left: left
			     right: right
			    analog: false];
		[directionalPads setObject: directionalPad forKey: @"D-Pad"];

		[directionalPads makeImmutable];
		_directionalPads = [directionalPads retain];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {

Modified src/macros.h from [f36695b45c] to [8192233b66].

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
#ifdef __GNUC__
# define OF_INLINE inline __attribute__((__always_inline__))
# define OF_LIKELY(cond) (__builtin_expect(!!(cond), 1))
# define OF_UNLIKELY(cond) (__builtin_expect(!!(cond), 0))
# define OF_CONST_FUNC __attribute__((__const__))
# define OF_NO_RETURN_FUNC __attribute__((__noreturn__))
# define OF_WEAK_REF(sym) __attribute__((__weakref__(sym)))





#else
# define OF_INLINE inline
# define OF_LIKELY(cond) (cond)
# define OF_UNLIKELY(cond) (cond)
# define OF_CONST_FUNC
# define OF_NO_RETURN_FUNC
# define OF_WEAK_REF(sym)
#endif

#ifndef OF_DJGPP
# define OF_VISIBILITY_HIDDEN __attribute__((__visibility__("hidden")))
#else
# define OF_VISIBILITY_HIDDEN
#endif

#if __STDC_VERSION__ >= 201112L
# define OF_ALIGN(size) _Alignas(size)
# define OF_ALIGNOF(type) _Alignof(type)
# define OF_ALIGNAS(type) _Alignas(type)







>
>
>
>
>







<
<
<
<
<







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
#ifdef __GNUC__
# define OF_INLINE inline __attribute__((__always_inline__))
# define OF_LIKELY(cond) (__builtin_expect(!!(cond), 1))
# define OF_UNLIKELY(cond) (__builtin_expect(!!(cond), 0))
# define OF_CONST_FUNC __attribute__((__const__))
# define OF_NO_RETURN_FUNC __attribute__((__noreturn__))
# define OF_WEAK_REF(sym) __attribute__((__weakref__(sym)))
# if defined(OF_ELF) || defined(OF_MACHO)
#  define OF_VISIBILITY_HIDDEN __attribute__((__visibility__("hidden")))
# else
#  define OF_VISIBILITY_HIDDEN
# endif
#else
# define OF_INLINE inline
# define OF_LIKELY(cond) (cond)
# define OF_UNLIKELY(cond) (cond)
# define OF_CONST_FUNC
# define OF_NO_RETURN_FUNC
# define OF_WEAK_REF(sym)





# define OF_VISIBILITY_HIDDEN
#endif

#if __STDC_VERSION__ >= 201112L
# define OF_ALIGN(size) _Alignas(size)
# define OF_ALIGNOF(type) _Alignof(type)
# define OF_ALIGNAS(type) _Alignas(type)

Modified src/runtime/exception.m from [a631c06b73] to [7f6288ce90].

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#endif

#ifdef __SEH__
# include <windows.h>
#endif

#if defined(__SEH__)
# define PERSONALITY	 gnu_objc_personality
#elif defined(__USING_SJLJ_EXCEPTIONS__)
# define PERSONALITY __gnu_objc_personality_sj0
# define CXX_PERSONALITY_STR "__gxx_personality_sj0"
# define _Unwind_RaiseException _Unwind_SjLj_RaiseException
# define __builtin_eh_return_data_regno(i) (i)
#else
# define PERSONALITY __gnu_objc_personality_v0







|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#endif

#ifdef __SEH__
# include <windows.h>
#endif

#if defined(__SEH__)
# define PERSONALITY gnu_objc_personality
#elif defined(__USING_SJLJ_EXCEPTIONS__)
# define PERSONALITY __gnu_objc_personality_sj0
# define CXX_PERSONALITY_STR "__gxx_personality_sj0"
# define _Unwind_RaiseException _Unwind_SjLj_RaiseException
# define __builtin_eh_return_data_regno(i) (i)
#else
# define PERSONALITY __gnu_objc_personality_v0
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
_Unwind_SetIP(struct _Unwind_Context *ctx, uintptr_t value)
{
	uintptr_t thumb = _Unwind_GetGR(ctx, 15) & 1;
	_Unwind_SetGR(ctx, 15, (value | thumb));
}
#endif

#ifdef CXX_PERSONALITY
static PERSONALITY_FUNC(cxx_personality) OF_WEAK_REF(CXX_PERSONALITY_STR);
#endif

#ifdef __SEH__
extern EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void *,
    PCONTEXT, PDISPATCHER_CONTEXT, _Unwind_Reason_Code (*)(int, int, uint64_t,
    struct _Unwind_Exception *, struct _Unwind_Context *));







|







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
_Unwind_SetIP(struct _Unwind_Context *ctx, uintptr_t value)
{
	uintptr_t thumb = _Unwind_GetGR(ctx, 15) & 1;
	_Unwind_SetGR(ctx, 15, (value | thumb));
}
#endif

#if defined(CXX_PERSONALITY_STR) && !defined(OF_AMIGAOS_M68K)
static PERSONALITY_FUNC(cxx_personality) OF_WEAK_REF(CXX_PERSONALITY_STR);
#endif

#ifdef __SEH__
extern EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void *,
    PCONTEXT, PDISPATCHER_CONTEXT, _Unwind_Reason_Code (*)(int, int, uint64_t,
    struct _Unwind_Exception *, struct _Unwind_Context *));
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
	struct LSDA LSDA;
	uintptr_t landingpad = 0;
	uint8_t found = 0;
	intptr_t filter = 0;

	if (foreign) {
		switch (exClass) {
#ifdef CXX_PERSONALITY
		case GNUCCXX0_EXCEPTION_CLASS:
		case CLNGCXX0_EXCEPTION_CLASS:
			if (cxx_personality != NULL)
				return CALL_PERSONALITY(cxx_personality);
			break;
#endif
		}







|







611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
	struct LSDA LSDA;
	uintptr_t landingpad = 0;
	uint8_t found = 0;
	intptr_t filter = 0;

	if (foreign) {
		switch (exClass) {
#if defined(CXX_PERSONALITY_STR) && !defined(OF_AMIGAOS_M68K)
		case GNUCCXX0_EXCEPTION_CLASS:
		case CLNGCXX0_EXCEPTION_CLASS:
			if (cxx_personality != NULL)
				return CALL_PERSONALITY(cxx_personality);
			break;
#endif
		}

Modified tests/OFSCTPSocketTests.m from [749f241e9f] to [0fc5034587].

49
50
51
52
53
54
55

56
57












58
59
60
61
62
63
64
		default:
			@throw e;
		}
	}

	[server listen];


	[client connectToHost: @"127.0.0.1"
			 port: OFSocketAddressIPPort(&address)];













	accepted = [server accept];
	OTAssertEqualObjects(OFSocketAddressString(accepted.remoteAddress),
	    @"127.0.0.1");

	streamID = [OFNumber numberWithUnsignedShort: 1];
	PPID = [OFNumber numberWithUnsignedLong: 1234];







>
|
|
>
>
>
>
>
>
>
>
>
>
>
>







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
		default:
			@throw e;
		}
	}

	[server listen];

	@try {
		[client connectToHost: @"127.0.0.1"
				 port: OFSocketAddressIPPort(&address)];
	} @catch (OFConnectSocketFailedException *e) {
		switch (e.errNo) {
		case ENOPROTOOPT:
			/*
			 * When running in qemu-user, binding works but
			 * connecting fails?!
			 */
			OTSkip(@"SCTP unsupported");
		default:
			@throw e;
		}
	}

	accepted = [server accept];
	OTAssertEqualObjects(OFSocketAddressString(accepted.remoteAddress),
	    @"127.0.0.1");

	streamID = [OFNumber numberWithUnsignedShort: 1];
	PPID = [OFNumber numberWithUnsignedLong: 1234];

Modified tests/OFUNIXSequencedPacketSocketTests.m from [6176995a50] to [6f19c6b757].

57
58
59
60
61
62
63

64

65
66
67
68
69
70
71
	@try {
		[sockServer bindToPath: path];
	} @catch (OFBindSocketFailedException *e) {
		switch (e.errNo) {
		case EAFNOSUPPORT:
		case EPERM:
		case EPROTONOSUPPORT:

		case ESOCKTNOSUPPORT:

			OTSkip(@"UNIX sequenced packet sockets unsupported");
		default:
			@throw e;
		}
	}

	@try {







>

>







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
	@try {
		[sockServer bindToPath: path];
	} @catch (OFBindSocketFailedException *e) {
		switch (e.errNo) {
		case EAFNOSUPPORT:
		case EPERM:
		case EPROTONOSUPPORT:
#ifdef ESOCKTNOSUPPORT
		case ESOCKTNOSUPPORT:
#endif
			OTSkip(@"UNIX sequenced packet sockets unsupported");
		default:
			@throw e;
		}
	}

	@try {

Modified utils/objfw-compile from [e35f021548] to [aa288d7464].

326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
test x"$link_stdcpp" = x"yes" && LIBS="$LIBS -lstdc++"

if test x"$lib" = x"yes"; then
	export SHARED_LIB="$out_prefix$out$out_suffix"
	LDFLAGS="$LDFLAGS $($OBJFW_CONFIG --lib-ldflags)"
fi

if test x"$plugin" = x"yes" -a x"$out_suffix" = x".bundle"; then
	# If $out_suffix is .bundle, it means we are creating a macOS bundle.
	# These are not just a single file, but have a certain directory
	# structure. Therefore we amend the output path to match the expected
	# directory structure.
	mkdir -p $out$out_suffix/Contents/MacOS
	out="$out$out_suffix/Contents/MacOS/$(basename $out)"
	out_suffix=""
fi

if test ! -f "$out_prefix$out$out_suffix" -o x"$link" = x"yes"; then
	status_linking $out_prefix$out$out_suffix
	$OBJC -o $out_prefix$out$out_suffix $objs $LIBS $LDFLAGS || \
		status_link_failed $out $?
	status_linked $out_prefix$out$out_suffix
fi







<
<
<
<
<
<
<
<
<
<






326
327
328
329
330
331
332










333
334
335
336
337
338
test x"$link_stdcpp" = x"yes" && LIBS="$LIBS -lstdc++"

if test x"$lib" = x"yes"; then
	export SHARED_LIB="$out_prefix$out$out_suffix"
	LDFLAGS="$LDFLAGS $($OBJFW_CONFIG --lib-ldflags)"
fi











if test ! -f "$out_prefix$out$out_suffix" -o x"$link" = x"yes"; then
	status_linking $out_prefix$out$out_suffix
	$OBJC -o $out_prefix$out$out_suffix $objs $LIBS $LDFLAGS || \
		status_link_failed $out $?
	status_linked $out_prefix$out$out_suffix
fi