SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
JoyKit/JOYAxes3D.m
1 #import "JOYAxes3D.h"
2 #import "JOYElement.h"
3
4 @interface JOYAxes3D()
5 @property unsigned rotation; // in 90 degrees units, clockwise
6 @end
7
8 @implementation JOYAxes3D
9 {
10 JOYElement *_element1, *_element2, *_element3;
11 double _state1, _state2, _state3;
12 int32_t _minX, _minY, _minZ;
13 int32_t _maxX, _maxY, _maxZ;
14 double _gApproximation;
15 }
16
17 + (NSString *)usageToString: (JOYAxes3DUsage) usage
18 {
19 if (usage < JOYAxes3DUsageNonGenericMax) {
20 return inline_const(NSString *[], {
21 @"None",
22 @"Acceleretion",
23 @"Orientation",
24 @"Gyroscope",
25 })[usage];
26 }
27 if (usage >= JOYAxes3DUsageGeneric0) {
28 return [NSString stringWithFormat:@"Generic 3D Analog Control %d", usage - JOYAxes3DUsageGeneric0];
29 }
30
31 return [NSString stringWithFormat:@"Unknown Usage 3D Axes %d", usage];
32 }
33
34 - (NSString *)usageString
35 {
36 return [self.class usageToString:_usage];
37 }
38
39 - (uint64_t)uniqueID
40 {
41 return _element1.uniqueID | (uint64_t)self.combinedIndex << 32;
42 }
43
44 - (NSString *)description
45 {
46 return [NSString stringWithFormat:@"<%@: %p, %@ (%llx); State: (%.2f, %.2f, %.2f)>", self.className, self, self.usageString, self.uniqueID, _state1, _state2, _state3];
47 }
48
49 - (instancetype)initWithFirstElement:(JOYElement *)element1 secondElement:(JOYElement *)element2 thirdElement:(JOYElement *)element3
50 {
51 self = [super init];
52 if (!self) return self;
53
54 _element1 = element1;
55 _element2 = element2;
56 _element3 = element3;
57
58 _maxX = element1? element1.max : 1;
59 _maxY = element2? element2.max : 1;
60 _maxZ = element3? element3.max : 1;
61 _minX = element1? element1.min : -1;
62 _minY = element2? element2.min : -1;
63 _minZ = element3? element3.min : -1;
64
65 return self;
66 }
67
68 - (JOYPoint3D)rawValue
69 {
70 return (JOYPoint3D){_state1, _state2, _state3};
71 }
72
73 - (JOYPoint3D)normalizedValue
74 {
75 double distance = sqrt(_state1 * _state1 + _state2 * _state2 + _state3 * _state3);
76 if (distance == 0) {
77 distance = 1;
78 }
79 return (JOYPoint3D){_state1 / distance, _state2 / distance, _state3 / distance};
80 }
81
82 - (JOYPoint3D)gUnitsValue
83 {
84 double distance = _gApproximation ?: 1;
85 return (JOYPoint3D){_state1 / distance, _state2 / distance, _state3 / distance};
86 }
87
88 - (bool)updateState
89 {
90 int32_t x = [_element1 value];
91 int32_t y = [_element2 value];
92 int32_t z = [_element3 value];
93
94 if (x == 0 && y == 0 && z == 0) return false;
95
96 double old1 = _state1, old2 = _state2, old3 = _state3;
97 _state1 = (x - _minX) / (double)(_maxX - _minX) * 2 - 1;
98 _state2 = (y - _minY) / (double)(_maxY - _minY) * 2 - 1;
99 _state3 = (z - _minZ) / (double)(_maxZ - _minZ) * 2 - 1;
100
101 double distance = sqrt(_state1 * _state1 + _state2 * _state2 + _state3 * _state3);
102 if (_gApproximation == 0) {
103 _gApproximation = distance;
104 }
105 else {
106 _gApproximation = _gApproximation * 0.9999 + distance * 0.0001;
107 }
108
109 double temp = _state1;
110 switch (_rotation & 3) {
111 case 0: break;
112 case 1:
113 _state1 = -_state3;
114 _state3 = temp;
115 break;
116 case 2:
117 _state1 = -_state1;
118 _state3 = -_state3;
119 break;
120 case 3:
121 _state1 = _state3;
122 _state3 = -temp;
123 break;
124 }
125
126 return old1 != _state1 || old2 != _state2 || old3 != _state3;
127 }
128
129 @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.