orka_b455160b/orka_awt/src/awt-inputs-gamepads.ads

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 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
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
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
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
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
322
323
324
325
326
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
--  SPDX-License-Identifier: Apache-2.0
--
--  Copyright (c) 2021 onox <denkpadje@gmail.com>
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.

private with Ada.Characters.Latin_1;
private with Ada.Finalization;

private with AWT.Gamepads;
private with AWT.IMUs;

with Orka.Transforms.Doubles.Quaternions;
with Orka.Transforms.Doubles.Vectors;

package AWT.Inputs.Gamepads is
   pragma Preelaborate;

   type Connection_Kind is (Disconnected, Wired, Wireless);

   type GUID_String is new String (1 .. 32)
     with Dynamic_Predicate => (for all C of GUID_String => C in '0' .. '9' | 'a' .. 'f');

   type Normalized is new Float range 0.0 .. 1.0;

   ----------------------------------------------------------------------------

   type Gamepad_Button is
     (Direction_Up,
      Direction_Right,
      Direction_Down,
      Direction_Left,
      Action_Down,
      Action_Right,
      Action_Left,
      Action_Up,
      Shoulder_Left,
      Shoulder_Right,
      Thumb_Left,
      Thumb_Right,
      Center_Left,
      Center_Right,
      Center_Logo);

   type Gamepad_Axis is
     (Stick_Left_X,
      Stick_Left_Y,
      Stick_Right_X,
      Stick_Right_Y);

   type Gamepad_Trigger is
     (Trigger_Left,
      Trigger_Right);

   type Gamepad_Buttons is array (Gamepad_Button) of Button_State
     with Component_Size => 1;

   type Changed_Gamepad_Buttons is array (Gamepad_Button) of Boolean
     with Component_Size => 1;

   type Axis_Position is delta 2.0 ** (-15) range -1.0 .. 1.0 - 2.0 ** (-15)
     with Size => 16;

   type Trigger_Position is delta 2.0 ** (-8) range 0.0 .. 1.0 - 2.0 ** (-8)
     with Size => 8;

   type Gamepad_Axes is array (Gamepad_Axis) of Axis_Position;

   type Gamepad_Triggers is array (Gamepad_Trigger) of Trigger_Position;

   type Gamepad_State is record
      Buttons   : Gamepad_Buttons         := (others => Released);
      Pressed   : Changed_Gamepad_Buttons := (others => False);
      Released  : Changed_Gamepad_Buttons := (others => False);

      Axes     : Gamepad_Axes     := (others => 0.0);
      Triggers : Gamepad_Triggers := (others => 0.0);
   end record;

   ----------------------------------------------------------------------------

   type Battery_Capacity is range 0 .. 100;

   type Battery_Status is (Discharging, Charging, Not_Charging);

   type Battery_State (Is_Present : Boolean := False) is record
      case Is_Present is
         when True =>
            Capacity : Battery_Capacity;
            Status   : Battery_Status;
         when False =>
            null;
      end case;
   end record;

   ----------------------------------------------------------------------------

   type Color_Kind is (Red, Green, Blue);

   type RGB_Color is array (Color_Kind) of Normalized;

   type LED_State (Is_Present : Boolean := False) is record
      case Is_Present is
         when True =>
            Brightness : Normalized;
            Color      : RGB_Color;
         when False =>
            null;
      end case;
   end record;

   ----------------------------------------------------------------------------

   package Quaternions renames Orka.Transforms.Doubles.Quaternions;
   package Vectors     renames Orka.Transforms.Doubles.Vectors;

   type Sensor_Axis_Value is delta 2.0 ** (-16) range -(2.0 ** 15) .. +(2.0 ** 15 - 2.0 ** (-16))
     with Size => 32;

   type Sensor_Axis is (X, Y, Z, Rx, Ry, Rz);

   type Sensor_Axes is array (Sensor_Axis) of Sensor_Axis_Value;

   type Motion_State (Is_Present, Has_Pose : Boolean := False)  is record
      case Is_Present is
         when True =>
            Axes : Sensor_Axes := (others => 0.0);
            case Has_Pose is
               when True =>
                  Orientation      : Quaternions.Quaternion;
                  Angular_Velocity : Vectors.Direction;
                  --  Estimated true angular velocity is (pitch up, yaw left, roll left) in rad/s
               when False =>
                  null;
            end case;
         when False =>
            null;
      end case;
   end record;

   ----------------------------------------------------------------------------

   type Effect is private;

   function Rumble_Effect
     (Length, Offset : Duration;
      Strong, Weak   : Normalized) return Effect;

   function Periodic_Effect
     (Length, Offset : Duration;
      Magnitude      : Normalized;
      Attack, Fade   : Duration) return Effect;

   ----------------------------------------------------------------------------

   type Gamepad is tagged limited private;

   function Name (Object : Gamepad) return String;

   function Serial_Number (Object : Gamepad) return String;

   function GUID (Object : Gamepad) return GUID_String;

   function Connection (Object : Gamepad) return Connection_Kind;

   function State (Object : in out Gamepad) return Gamepad_State;

   function State (Object : Gamepad) return Motion_State;

   function State (Object : Gamepad) return Battery_State;

   function State (Object : Gamepad) return LED_State;

   procedure Set_LED
     (Object     : in out Gamepad;
      Brightness : Normalized;
      Color      : RGB_Color);

   procedure Play_Effect (Object : in out Gamepad; Subject : Effect);

   procedure Cancel_Effect (Object : in out Gamepad; Subject : Effect);

   function Effects (Object : Gamepad) return Natural;

   procedure Log_Information (Gamepad : AWT.Inputs.Gamepads.Gamepad);

   ----------------------------------------------------------------------------

   procedure Set_Mappings (Text : String);

   procedure Initialize;

   procedure Poll (DT : Duration);
   --  Poll hardware state of connected gamepads
   --
   --  Some parts of the state (like the pose estimation, which uses the
   --  motion sensor) may depend on how often this procedure is called.
   --  Set DT to 0.0 if these parts should not be computed.

   type Gamepad_Ptr is not null access all Gamepad;

   type Gamepad_Array is array (Positive range <>) of Gamepad_Ptr;

   function Gamepads return Gamepad_Array;

   ----------------------------------------------------------------------------

   type Gamepad_Event_Listener is abstract tagged limited private;

   procedure On_Connect
     (Object  : Gamepad_Event_Listener;
      Gamepad : Gamepad_Ptr) is abstract;

   procedure On_Disconnect
     (Object  : Gamepad_Event_Listener;
      Gamepad : Gamepad_Ptr) is abstract;

private

   package L1 renames Ada.Characters.Latin_1;

   type Axis_Value is delta 2.0 ** (-16)
     range -(2.0 ** 47) ..
           +(2.0 ** 47 - 2.0 ** (-16));

   type Output_Kind is (Button, Axis, Trigger, None);

   type Output_Mapping (Kind : Output_Kind := None) is record
      case Kind is
         when Axis =>
            Axis    : Gamepad_Axis;
            Scale   : Axis_Value := 2.0;
            Offset  : Axis_Value := 1.0;
         when Trigger =>
            Trigger : Gamepad_Trigger;
         when Button =>
            Button  : Gamepad_Button;
         when None =>
            null;
      end case;
   end record;

   type Side_Type is (Negative_Half, Positive_Half, Full_Range);

   subtype Hat_Side is Side_Type range Negative_Half .. Positive_Half;

   type Axis_Modifier is record
      Offset, Scale, Resolution : Axis_Value;
   end record;

   type Input_Mapping is record
      Modifier : Axis_Modifier;

      Side   : Side_Type := Full_Range;
      Invert : Boolean   := False;
   end record;

   type Mapping (Kind : Output_Kind := None) is record
      Input  : Input_Mapping;
      Output : Output_Mapping (Kind);
   end record;

   type Axis_Mappings is array (AWT.Gamepads.Input_Axis) of Mapping;
   type Key_Mappings  is array (AWT.Gamepads.Input_Button) of Mapping;
   type Hat_Mappings  is array (AWT.Gamepads.Input_Hat, Hat_Side) of Mapping;

   type Sensor_Modifiers is array (AWT.Gamepads.Sensor_Axis) of Axis_Modifier;

   type Gamepad_Object is limited new AWT.Gamepads.Abstract_Gamepad with record
      Name, ID : SU.Unbounded_String;
      GUID     : GUID_String;

      Gamepad : Gamepad_State;
      Sensor  : Motion_State;
      IMU     : AWT.IMUs.IMU;

      Axes : Axis_Mappings;
      Keys : Key_Mappings;
      Hats : Hat_Mappings;

      Sensors : Sensor_Modifiers;

      Max_Effects : Natural := 0;
   end record;

   protected type Gamepad_Hardware is
      function Name return String;

      function Serial_Number return String;

      function GUID return GUID_String;

      function Connection return Connection_Kind;

      procedure State (Result : in out Gamepad_State);

      function State return Motion_State;

      function State return Battery_State;

      function State return LED_State;

      procedure Set_LED
        (Brightness : Normalized;
         Color      : RGB_Color);

      procedure Play_Effect (Subject : Effect);

      procedure Cancel_Effect (Subject : Effect);

      function Effects return Natural;

      -------------------------------------------------------------------------
      --                              Internal                               --
      -------------------------------------------------------------------------

      procedure Initialize (Path : String; Result : out Boolean);

      procedure Finalize;

      function Initialized return Boolean;

      procedure Poll_State (DT : Duration);

      function Path return String;
   private
      Object : Gamepad_Object;
   end Gamepad_Hardware;

   type Gamepad is tagged limited record
      Hardware : Gamepad_Hardware;
   end record;

   ----------------------------------------------------------------------------

   type Effect is new AWT.Gamepads.Abstract_Effect;

   ----------------------------------------------------------------------------

   type Gamepad_Event_Listener is
     abstract limited new Ada.Finalization.Limited_Controlled with null record;

   overriding procedure Initialize (Object : in out Gamepad_Event_Listener);
   overriding procedure Finalize   (Object : in out Gamepad_Event_Listener);

end AWT.Inputs.Gamepads;