ObjFW  Diff

Differences From Artifact [3d4dad17ed]:

To Artifact [36b2c982f2]:


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
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 "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFOpenItemFailedException.h"
#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"

static const uint16_t vendorIDMicrosoft = 0x045E;
static const uint16_t vendorIDNintendo = 0x057E;

static const uint16_t productIDXbox360Controller = 0x028E;
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 OFGameControllerButton
buttonToName(uint16_t button, uint16_t vendorID, uint16_t productID)
{
	if (vendorID == vendorIDMicrosoft &&
	if (vendorID == vendorIDNintendo &&
	    productID == productIDXbox360Controller) {
		switch (button) {
		case BTN_C:
		case BTN_Z:
			return nil;
		}
	} else if (vendorID == vendorIDNintendo &&
	    productID == productIDN64Controller) {
		switch (button) {
		case BTN_TL2:
			return OFGameControllerButtonZ;
		case BTN_Y:
			return OFGameControllerButtonCPadLeft;
		case BTN_C:
			return OFGameControllerButtonCPadRight;
		case BTN_SELECT:
			return OFGameControllerButtonCPadUp;
		case BTN_X:
			return OFGameControllerButtonCPadDown;
		case BTN_MODE:
			return OFGameControllerButtonHome;
		case BTN_Z:
			return OFGameControllerButtonCapture;
		case BTN_THUMBL:
		case BTN_THUMBR:
			return nil;
		}
	}

	switch (button) {
	case BTN_A:
		return OFGameControllerButtonA;
	case BTN_B:
239
240
241
242
243
244
245
246

247
248
249

250
251

252

253
254
255
256
257
258
259
226
227
228
229
230
231
232

233



234


235

236
237
238
239
240
241
242
243







-
+
-
-
-
+
-
-
+
-
+







			@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++) {
		    i++)
			OFGameControllerButton buttonName =
			    buttonToName(buttons[i], _vendorID, _productID);

			if (OFBitSetIsSet(keyBits, buttons[i]))
			if (buttonName != nil)
				[_buttons addObject: buttonName];
				[_buttons addObject: buttonToName(
		}
				    buttons[i], _vendorID, _productID)];

		_pressedButtons = [[OFMutableSet alloc] init];

		if (OFBitSetIsSet(evBits, EV_ABS)) {
			if (ioctl(_fd, EVIOCGBIT(EV_ABS, sizeof(absBits)),
			    absBits) == -1)
				@throw [OFInitializationFailedException
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394





395

396
397
398
399
400
401
402
350
351
352
353
354
355
356


357
358
359
360
361
362
363
364
365
366
367
368
369
370






371
372
373
374
375

376
377
378
379
380
381
382
383







-
-














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







}

- (void)of_processEvents
{
	struct input_event event;

	for (;;) {
		OFGameControllerButton 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: name];
				else
					[_pressedButtons removeObject: name];
			if (event.value)
				[_pressedButtons addObject: buttonToName(
				    event.code, _vendorID, _productID)];
			else
				[_pressedButtons removeObject: buttonToName(
			}
				    event.code, _vendorID, _productID)];
			break;
		case EV_ABS:
			switch (event.code) {
			case ABS_X:
				_leftAnalogStickPosition.x = scale(event.value,
				    _leftAnalogStickMinX, _leftAnalogStickMaxX);
				break;