ObjFW  Diff

Differences From Artifact [5c8b1cd04f]:

To Artifact [c15cf8d62a]:


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
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







+
+
+












-
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








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

static const uint16_t vendorIDNintendo = 0x057E;
static const uint16_t productIDN64Controller = 0x2019;

@interface OFGameController ()
- (instancetype)of_initWithPath: (OFString *)path OF_METHOD_FAMILY(init);
- (void)of_processEvents;
@end

static const uint16_t buttons[] = {
	BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_TL2,
	BTN_TR2, BTN_SELECT, BTN_START, BTN_MODE, BTN_THUMBL, BTN_THUMBR,
	BTN_DPAD_UP, BTN_DPAD_DOWN, BTN_DPAD_LEFT, BTN_DPAD_RIGHT
};

static OFString *
buttonToName(uint16_t button)
buttonToName(uint16_t button, uint16_t vendorID, uint16_t productID)
{
	if (vendorID == vendorIDNintendo &&
	    productID == productIDN64Controller) {
		switch (button) {
		case BTN_TL2:
			return @"Z";
		case BTN_Y:
			return @"C-Stick Left";
		case BTN_C:
			return @"C-Stick Right";
		case BTN_SELECT:
			return @"C-Stick Up";
		case BTN_X:
			return @"C-Stick Down";
		case BTN_MODE:
			return @"Home";
		case BTN_Z:
			return @"Capture";
		case BTN_THUMBL:
		case BTN_THUMBR:
			return nil;
		}
	}

	switch (button) {
	case BTN_A:
		return @"A";
	case BTN_B:
		return @"B";
	case BTN_C:
		return @"C";
164
165
166
167
168
169
170

171
172
173
174
175
176
177
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204







+







		OFStringEncoding encoding = [OFLocale encoding];
		unsigned long evBits[OFRoundUpToPowerOf2(OF_ULONG_BIT,
		    EV_MAX) / OF_ULONG_BIT] = { 0 };
		unsigned long keyBits[OFRoundUpToPowerOf2(OF_ULONG_BIT,
		    KEY_MAX) / OF_ULONG_BIT] = { 0 };
		unsigned long absBits[OFRoundUpToPowerOf2(OF_ULONG_BIT,
		    ABS_MAX) / OF_ULONG_BIT] = { 0 };
		struct input_id inputID;
		char name[128];

		_path = [path copy];

		if ((_fd = open([_path cStringWithEncoding: encoding],
		    O_RDONLY | O_NONBLOCK)) == -1)
			@throw [OFOpenItemFailedException
187
188
189
190
191
192
193






194
195
196
197
198
199
200
201
202
203








204
205
206
207
208
209
210
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







+
+
+
+
+
+








-
-
+
+
+
+
+
+
+
+








		if (ioctl(_fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) ==
		    -1)
			@throw [OFInitializationFailedException exception];

		if (!OFBitSetIsSet(keyBits, BTN_GAMEPAD))
			@throw [OFInvalidArgumentException exception];

		if (ioctl(_fd, EVIOCGID, &inputID) == -1)
			@throw [OFInvalidArgumentException exception];

		_vendorID = inputID.vendor;
		_productID = inputID.product;

		if (ioctl(_fd, EVIOCGNAME(sizeof(name)), name) == -1)
			@throw [OFInitializationFailedException exception];

		_name = [[OFString alloc] initWithCString: name
						 encoding: encoding];

		_buttons = [[OFMutableSet alloc] init];
		for (size_t i = 0; i < sizeof(buttons) / sizeof(*buttons); i++)
			[_buttons addObject: buttonToName(buttons[i])];
		for (size_t i = 0; i < sizeof(buttons) / sizeof(*buttons);
		    i++) {
			OFString *buttonName =
			    buttonToName(buttons[i], _vendorID, _productID);

			if (buttonName != nil)
				[_buttons addObject: buttonName];
		}

		_pressedButtons = [[OFMutableSet alloc] init];

		if (OFBitSetIsSet(evBits, EV_ABS)) {
			if (ioctl(_fd, EVIOCGBIT(EV_ABS, sizeof(absBits)),
			    absBits) == -1)
				@throw [OFInitializationFailedException
288
289
290
291
292
293
294


295
296
297
298
299
300
301
302
303
304
305
306
307
308


309
310


311
312
313


314

315
316
317
318
319
320
321
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351


352
353



354
355

356
357
358
359
360
361
362
363







+
+














+
+
-
-
+
+
-
-
-
+
+
-
+







}

- (void)of_processEvents
{
	struct input_event event;

	for (;;) {
		OFString *name;

		errno = 0;

		if (read(_fd, &event, sizeof(event)) < (int)sizeof(event)) {
			if (errno == EWOULDBLOCK)
				return;

			@throw [OFReadFailedException
			    exceptionWithObject: self
				requestedLength: sizeof(event)
					  errNo: errno];
		}

		switch (event.type) {
		case EV_KEY:
			if ((name = buttonToName(event.code, _vendorID,
			    _productID)) != nil) {
			if (event.value)
				[_pressedButtons addObject:
				if (event.value)
					[_pressedButtons addObject: name];
				    buttonToName(event.code)];
			else
				[_pressedButtons removeObject:
				else
					[_pressedButtons removeObject: name];
				    buttonToName(event.code)];
			}
			break;
		case EV_ABS:
			switch (event.code) {
			case ABS_X:
				_leftAnalogStickPosition.x = scale(event.value,
				    _leftAnalogStickMinX, _leftAnalogStickMaxX);
				break;