SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
JoyKit/JOYSubElement.m
1 #import "JOYSubElement.h"
2
3 @interface JOYElement ()
4 {
5 @public uint16_t _usage;
6 @public uint16_t _usagePage;
7 @public uint32_t _uniqueID;
8 @public int32_t _min;
9 @public int32_t _max;
10 @public int32_t _reportID;
11 @public int32_t _parentID;
12 }
13 @end
14
15 @implementation JOYSubElement
16 {
17 JOYElement *_parent;
18 size_t _size; // in bits
19 size_t _offset; // in bits
20 }
21
22 - (instancetype)initWithRealElement:(JOYElement *)element
23 size:(size_t) size // in bits
24 offset:(size_t) offset // in bits
25 usagePage:(uint16_t)usagePage
26 usage:(uint16_t)usage
27 min:(int32_t)min
28 max:(int32_t)max
29 {
30 if ((self = [super init])) {
31 _parent = element;
32 _size = size;
33 _offset = offset;
34 _usage = usage;
35 _usagePage = usagePage;
36 _uniqueID = (uint32_t)((_parent.uniqueID << 16) | offset);
37 _min = min;
38 _max = max;
39 _reportID = _parent.reportID;
40 _parentID = _parent.parentID;
41 }
42 return self;
43 }
44
45 - (int32_t)value
46 {
47 NSData *parentValue = [_parent dataValue];
48 if (!parentValue) return 0;
49 if (_size > 32) return 0;
50 if (_size + (_offset % 8) > 32) return 0;
51 size_t parentLength = parentValue.length;
52 if (_size > parentLength * 8) return 0;
53 if (_size + _offset >= parentLength * 8) return 0;
54 const uint8_t *bytes = parentValue.bytes;
55
56 uint8_t temp[4] = {0,};
57 memcpy(temp, bytes + _offset / 8, (_offset + _size - 1) / 8 - _offset / 8 + 1);
58 uint32_t ret = (*(uint32_t *)temp) >> (_offset % 8);
59 ret &= (1 << _size) - 1;
60 //
61 if (_min < 0 || _max < 0) { // Uses unsigned values
62 if (ret & (1 << (_size - 1)) ) { // Is negative
63 ret |= ~((1 << _size) - 1); // Fill with 1s
64 }
65 }
66
67 if (_max < _min) {
68 return _max + _min - ret;
69 }
70
71 return ret;
72 }
73
74 - (IOReturn)setValue: (uint32_t) value
75 {
76 NSMutableData *dataValue = [[_parent dataValue] mutableCopy];
77 if (!dataValue) return -1;
78 if (_size > 32) return -1;
79 if (_size + (_offset % 8) > 32) return -1;
80 size_t parentLength = dataValue.length;
81 if (_size > parentLength * 8) return -1;
82 if (_size + _offset >= parentLength * 8) return -1;
83 uint8_t *bytes = dataValue.mutableBytes;
84
85 uint8_t temp[4] = {0,};
86 memcpy(temp, bytes + _offset / 8, (_offset + _size - 1) / 8 - _offset / 8 + 1);
87 (*(uint32_t *)temp) &= ~((1 << (_size - 1)) << (_offset % 8));
88 (*(uint32_t *)temp) |= (value) << (_offset % 8);
89 memcpy(bytes + _offset / 8, temp, (_offset + _size - 1) / 8 - _offset / 8 + 1);
90 return [_parent setDataValue:dataValue];
91 }
92
93 - (NSData *)dataValue
94 {
95 [self doesNotRecognizeSelector:_cmd];
96 return nil;
97 }
98
99 - (IOReturn)setDataValue:(NSData *)data
100 {
101 [self doesNotRecognizeSelector:_cmd];
102 return -1;
103 }
104
105
106 @end
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.