@nativescript/canvas-gamepad 3.0.0-alpha.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +53 -0
- package/backend.android.d.ts +2 -0
- package/backend.android.js +13 -0
- package/backend.android.js.map +1 -0
- package/backend.d.ts +3 -0
- package/backend.ios.d.ts +2 -0
- package/backend.ios.js +8 -0
- package/backend.ios.js.map +1 -0
- package/backend.windows.d.ts +2 -0
- package/backend.windows.js +26 -0
- package/backend.windows.js.map +1 -0
- package/common.d.ts +59 -0
- package/common.js +141 -0
- package/common.js.map +1 -0
- package/index.d.ts +5 -0
- package/index.js +8 -0
- package/index.js.map +1 -0
- package/package.json +39 -0
- package/platforms/android/canvas_gamepad.aar +0 -0
- package/platforms/android/include.gradle +10 -0
- package/platforms/android/java/org/nativescript/canvas/gamepad/GamepadWindowCallback.java +161 -0
- package/platforms/android/java/org/nativescript/canvas/gamepad/NSCGamepadManager.java +367 -0
- package/platforms/ios/build.xcconfig +1 -0
- package/platforms/ios/src/NSCCanvasGamepadUmbrella.h +1 -0
- package/platforms/ios/src/NSCGamepadManager.h +17 -0
- package/platforms/ios/src/NSCGamepadManager.m +191 -0
- package/platforms/ios/src/module.modulemap +5 -0
- package/platforms/windows/arm64/canvasgamepad.node +0 -0
- package/platforms/windows/plugin.props +2 -0
- package/platforms/windows/plugin.targets +19 -0
- package/platforms/windows/x64/canvasgamepad.node +0 -0
- package/typings/android.d.ts +18 -0
- package/typings/objc!NSCCanvasGamepad.d.ts +11 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
#import "NSCGamepadManager.h"
|
|
2
|
+
#import <GameController/GameController.h>
|
|
3
|
+
|
|
4
|
+
// Keep in sync with packages/canvas-gamepad/common.ts.
|
|
5
|
+
static const NSInteger kMaxGamepads = 4;
|
|
6
|
+
static const NSInteger kMaxAxes = 8;
|
|
7
|
+
static const NSInteger kSlotConnected = 0;
|
|
8
|
+
static const NSInteger kSlotSequence = 1;
|
|
9
|
+
static const NSInteger kSlotMapping = 2;
|
|
10
|
+
static const NSInteger kSlotAxisCount = 3;
|
|
11
|
+
static const NSInteger kSlotButtonCount = 4;
|
|
12
|
+
static const NSInteger kSlotAxes = 5;
|
|
13
|
+
static const NSInteger kSlotButtons = kSlotAxes + kMaxAxes;
|
|
14
|
+
static const NSInteger kSlotStride = 80;
|
|
15
|
+
static const int kButtonPressed = 1;
|
|
16
|
+
static const int kButtonTouched = 2;
|
|
17
|
+
static const float kMappingStandard = 1;
|
|
18
|
+
static const NSInteger kStandardAxes = 4;
|
|
19
|
+
static const NSInteger kStandardButtons = 17;
|
|
20
|
+
// Float32 holds integers exactly up to 2^24.
|
|
21
|
+
static const float kSequenceWrap = 16777216.0f;
|
|
22
|
+
|
|
23
|
+
static inline void NSCWriteButton(float *slot, NSInteger index, GCControllerButtonInput *_Nullable button) {
|
|
24
|
+
float *out = slot + kSlotButtons + index * 2;
|
|
25
|
+
if (button == nil) {
|
|
26
|
+
out[0] = 0;
|
|
27
|
+
out[1] = 0;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
float value = button.value;
|
|
31
|
+
BOOL pressed = button.isPressed;
|
|
32
|
+
out[0] = value;
|
|
33
|
+
out[1] = (float) ((pressed ? kButtonPressed : 0) | ((pressed || value > 0) ? kButtonTouched : 0));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@implementation NSCGamepadManager {
|
|
37
|
+
float *_buffer;
|
|
38
|
+
NSCGamepadConnectionListener _listener;
|
|
39
|
+
NSMutableArray *_slots;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
+ (NSCGamepadManager *)shared {
|
|
43
|
+
static NSCGamepadManager *shared;
|
|
44
|
+
static dispatch_once_t once;
|
|
45
|
+
dispatch_once(&once, ^{
|
|
46
|
+
shared = [[NSCGamepadManager alloc] init];
|
|
47
|
+
});
|
|
48
|
+
return shared;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
- (instancetype)init {
|
|
52
|
+
if (self = [super init]) {
|
|
53
|
+
_slots = [NSMutableArray arrayWithCapacity:kMaxGamepads];
|
|
54
|
+
for (NSInteger i = 0; i < kMaxGamepads; i++) {
|
|
55
|
+
[_slots addObject:NSNull.null];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return self;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
- (void)startWithBuffer:(void *)buffer length:(NSInteger)length listener:(NSCGamepadConnectionListener)listener {
|
|
62
|
+
[self stop];
|
|
63
|
+
if (buffer == NULL || length < kMaxGamepads * kSlotStride) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
_buffer = (float *) buffer;
|
|
67
|
+
_listener = [listener copy];
|
|
68
|
+
memset(_buffer, 0, sizeof(float) * kMaxGamepads * kSlotStride);
|
|
69
|
+
|
|
70
|
+
NSNotificationCenter *center = NSNotificationCenter.defaultCenter;
|
|
71
|
+
[center addObserver:self selector:@selector(controllerDidConnect:) name:GCControllerDidConnectNotification object:nil];
|
|
72
|
+
[center addObserver:self selector:@selector(controllerDidDisconnect:) name:GCControllerDidDisconnectNotification object:nil];
|
|
73
|
+
|
|
74
|
+
for (GCController *controller in GCController.controllers) {
|
|
75
|
+
[self attach:controller];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
- (void)stop {
|
|
80
|
+
[NSNotificationCenter.defaultCenter removeObserver:self];
|
|
81
|
+
for (NSInteger i = 0; i < kMaxGamepads; i++) {
|
|
82
|
+
id controller = _slots[i];
|
|
83
|
+
if (controller != NSNull.null) {
|
|
84
|
+
((GCController *) controller).extendedGamepad.valueChangedHandler = nil;
|
|
85
|
+
_slots[i] = NSNull.null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
_buffer = NULL;
|
|
89
|
+
_listener = nil;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
- (void)controllerDidConnect:(NSNotification *)notification {
|
|
93
|
+
[self attach:notification.object];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
- (void)controllerDidDisconnect:(NSNotification *)notification {
|
|
97
|
+
GCController *controller = notification.object;
|
|
98
|
+
NSUInteger index = [_slots indexOfObjectIdenticalTo:controller];
|
|
99
|
+
if (index == NSNotFound || _buffer == NULL) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
controller.extendedGamepad.valueChangedHandler = nil;
|
|
103
|
+
_slots[index] = NSNull.null;
|
|
104
|
+
memset(_buffer + index * kSlotStride, 0, sizeof(float) * kSlotStride);
|
|
105
|
+
if (_listener) {
|
|
106
|
+
_listener(index, NO, @"");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
- (void)attach:(GCController *)controller {
|
|
111
|
+
GCExtendedGamepad *gamepad = controller.extendedGamepad;
|
|
112
|
+
// The Siri Remote stays on NSCCanvas's keyboard mapping.
|
|
113
|
+
if (gamepad == nil || _buffer == NULL || [_slots indexOfObjectIdenticalTo:controller] != NSNotFound) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
NSUInteger index = [_slots indexOfObjectIdenticalTo:NSNull.null];
|
|
117
|
+
if (index == NSNotFound) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
_slots[index] = controller;
|
|
121
|
+
|
|
122
|
+
float *slot = _buffer + index * kSlotStride;
|
|
123
|
+
slot[kSlotConnected] = 1;
|
|
124
|
+
slot[kSlotMapping] = kMappingStandard;
|
|
125
|
+
slot[kSlotAxisCount] = kStandardAxes;
|
|
126
|
+
slot[kSlotButtonCount] = kStandardButtons;
|
|
127
|
+
[self write:gamepad slot:slot];
|
|
128
|
+
|
|
129
|
+
__weak NSCGamepadManager *weakSelf = self;
|
|
130
|
+
gamepad.valueChangedHandler = ^(GCExtendedGamepad *changed, __unused GCControllerElement *element) {
|
|
131
|
+
[weakSelf update:changed];
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
if (_listener) {
|
|
135
|
+
NSString *name = controller.vendorName ?: @"Gamepad";
|
|
136
|
+
_listener(index, YES, [NSString stringWithFormat:@"%@ (STANDARD GAMEPAD)", name]);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
- (void)update:(GCExtendedGamepad *)gamepad {
|
|
141
|
+
if (_buffer == NULL) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
NSUInteger index = [_slots indexOfObjectIdenticalTo:gamepad.controller];
|
|
145
|
+
if (index == NSNotFound) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
[self write:gamepad slot:_buffer + index * kSlotStride];
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
- (void)write:(GCExtendedGamepad *)gamepad slot:(float *)slot {
|
|
152
|
+
float *axes = slot + kSlotAxes;
|
|
153
|
+
axes[0] = gamepad.leftThumbstick.xAxis.value;
|
|
154
|
+
axes[1] = -gamepad.leftThumbstick.yAxis.value;
|
|
155
|
+
axes[2] = gamepad.rightThumbstick.xAxis.value;
|
|
156
|
+
axes[3] = -gamepad.rightThumbstick.yAxis.value;
|
|
157
|
+
|
|
158
|
+
NSCWriteButton(slot, 0, gamepad.buttonA);
|
|
159
|
+
NSCWriteButton(slot, 1, gamepad.buttonB);
|
|
160
|
+
NSCWriteButton(slot, 2, gamepad.buttonX);
|
|
161
|
+
NSCWriteButton(slot, 3, gamepad.buttonY);
|
|
162
|
+
NSCWriteButton(slot, 4, gamepad.leftShoulder);
|
|
163
|
+
NSCWriteButton(slot, 5, gamepad.rightShoulder);
|
|
164
|
+
NSCWriteButton(slot, 6, gamepad.leftTrigger);
|
|
165
|
+
NSCWriteButton(slot, 7, gamepad.rightTrigger);
|
|
166
|
+
GCControllerButtonInput *options = nil, *menu = nil, *home = nil, *leftStick = nil, *rightStick = nil;
|
|
167
|
+
if (@available(iOS 12.1, tvOS 12.1, *)) {
|
|
168
|
+
leftStick = gamepad.leftThumbstickButton;
|
|
169
|
+
rightStick = gamepad.rightThumbstickButton;
|
|
170
|
+
}
|
|
171
|
+
if (@available(iOS 13.0, tvOS 13.0, *)) {
|
|
172
|
+
options = gamepad.buttonOptions;
|
|
173
|
+
menu = gamepad.buttonMenu;
|
|
174
|
+
}
|
|
175
|
+
if (@available(iOS 14.0, tvOS 14.0, *)) {
|
|
176
|
+
home = gamepad.buttonHome;
|
|
177
|
+
}
|
|
178
|
+
NSCWriteButton(slot, 8, options);
|
|
179
|
+
NSCWriteButton(slot, 9, menu);
|
|
180
|
+
NSCWriteButton(slot, 10, leftStick);
|
|
181
|
+
NSCWriteButton(slot, 11, rightStick);
|
|
182
|
+
NSCWriteButton(slot, 12, gamepad.dpad.up);
|
|
183
|
+
NSCWriteButton(slot, 13, gamepad.dpad.down);
|
|
184
|
+
NSCWriteButton(slot, 14, gamepad.dpad.left);
|
|
185
|
+
NSCWriteButton(slot, 15, gamepad.dpad.right);
|
|
186
|
+
NSCWriteButton(slot, 16, home);
|
|
187
|
+
|
|
188
|
+
slot[kSlotSequence] = fmodf(slot[kSlotSequence] + 1, kSequenceWrap);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
@end
|
|
Binary file
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<Project>
|
|
3
|
+
<PropertyGroup>
|
|
4
|
+
<_NSCanvasGamepadArch Condition="'$(NSLibPlatform)' != ''">$(NSLibPlatform)</_NSCanvasGamepadArch>
|
|
5
|
+
<_NSCanvasGamepadArch Condition="'$(_NSCanvasGamepadArch)' == '' and ('$(Platform)' == 'ARM64' or '$(Platform)' == 'arm64')">arm64</_NSCanvasGamepadArch>
|
|
6
|
+
<!-- x64 when $(Platform) is unset/AnyCPU during evaluation. -->
|
|
7
|
+
<_NSCanvasGamepadArch Condition="'$(_NSCanvasGamepadArch)' == '' or '$(_NSCanvasGamepadArch)' == 'x86_64'">x64</_NSCanvasGamepadArch>
|
|
8
|
+
<_NSCanvasGamepadDir>$(MSBuildThisFileDirectory)$(_NSCanvasGamepadArch)\</_NSCanvasGamepadDir>
|
|
9
|
+
</PropertyGroup>
|
|
10
|
+
|
|
11
|
+
<!-- An explicit Copy: with EnableMsixTooling, Content items do not reliably reach $(OutDir). -->
|
|
12
|
+
<Target Name="CopyNativeScriptCanvasGamepad" AfterTargets="Build">
|
|
13
|
+
<ItemGroup>
|
|
14
|
+
<_NSCanvasGamepadFiles Include="$(_NSCanvasGamepadDir)*.node" />
|
|
15
|
+
</ItemGroup>
|
|
16
|
+
<Warning Text="[@nativescript/canvas-gamepad] No native module for $(_NSCanvasGamepadArch) in $(_NSCanvasGamepadDir); build it with `make windows-gamepad`." Condition="!Exists('$(_NSCanvasGamepadDir)canvasgamepad.node')" />
|
|
17
|
+
<Copy SourceFiles="@(_NSCanvasGamepadFiles)" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true" />
|
|
18
|
+
</Target>
|
|
19
|
+
</Project>
|
|
Binary file
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
declare namespace org {
|
|
2
|
+
export namespace nativescript {
|
|
3
|
+
export namespace canvas {
|
|
4
|
+
export namespace gamepad {
|
|
5
|
+
export class NSCGamepadManager {
|
|
6
|
+
static start(context: android.content.Context, activity: android.app.Activity | null, buffer: java.nio.FloatBuffer, listener: NSCGamepadManager.Listener): void;
|
|
7
|
+
static stop(): void;
|
|
8
|
+
}
|
|
9
|
+
export namespace NSCGamepadManager {
|
|
10
|
+
export class Listener {
|
|
11
|
+
constructor(implementation: { onConnection(index: number, connected: boolean, id: string): void });
|
|
12
|
+
onConnection(index: number, connected: boolean, id: string): void;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare class NSCGamepadManager extends NSObject {
|
|
2
|
+
static alloc(): NSCGamepadManager; // inherited from NSObject
|
|
3
|
+
|
|
4
|
+
static new(): NSCGamepadManager; // inherited from NSObject
|
|
5
|
+
|
|
6
|
+
static readonly shared: NSCGamepadManager;
|
|
7
|
+
|
|
8
|
+
startWithBufferLengthListener(buffer: interop.Pointer | interop.Reference<any>, length: number, listener: (p1: number, p2: boolean, p3: string) => void): void;
|
|
9
|
+
|
|
10
|
+
stop(): void;
|
|
11
|
+
}
|