FPLBase
An open source project by FPL.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
input.h
Go to the documentation of this file.
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef FPLBASE_INPUT_SYSTEM_H
16 #define FPLBASE_INPUT_SYSTEM_H
17 
18 #include <functional>
19 #include <map>
20 #include <queue>
21 #include <string>
22 #include <vector>
23 
24 #include "fplbase/config.h" // Must come first.
25 
26 #include "keyboard_keycodes.h"
27 #include "mathfu/constants.h"
28 #include "mathfu/glsl_mappings.h"
29 
30 #ifdef __ANDROID__
31 #include <jni.h>
32 #endif
33 
34 #if !defined(ANDROID_GAMEPAD) && defined(__ANDROID__) && \
35  !defined(FPLBASE_BACKEND_STDLIB)
36 // Enable the android gamepad code. It receives input events from java, via
37 // JNI, and creates a local representation of the state of any connected
38 // gamepads. Also enables the gamepad_controller controller class.
39 #define ANDROID_GAMEPAD 1
40 #include "pthread.h"
41 #endif // !defined(ANDROID_GAMEPAD) && defined(__ANDROID__)
42 
43 namespace fplbase {
44 
45 /// @file
46 /// @addtogroup fplbase_input
47 /// @{
48 
49 typedef uint64_t FingerId;
50 typedef void *JoystickData;
51 typedef uint64_t JoystickId;
52 
53 typedef void *Event;
54 typedef void *TouchFingerEvent;
55 
56 #if ANDROID_GAMEPAD
57 typedef int AndroidInputDeviceId;
58 #endif
59 
60 /// @class Button
61 /// @brief Used to record state for fingers, mousebuttons, keys and gamepad
62 /// buttons.
63 ///
64 /// Allows you to know if a button went up/down this frame.
65 class Button {
66  public:
67  Button() : is_down_(false) { AdvanceFrame(); }
68  /// @brief Advances the current state of the button by one frame.
69  ///
70  /// Important, because it tells the system where frame boundaries occur, so
71  /// that went_down() and went_up() can be updated correctly.
72  /// Normally called automatically by FPLBase.
73  void AdvanceFrame() { went_down_ = went_up_ = false; }
74 
75  /// @brief Updates the current state of the button.
76  ///
77  /// For buttons that are tracked by the input system (Keyboard buttons,
78  /// joysticks) this is invoked automatically by InputSystem::AdvanceFrame().)
79  void Update(bool down);
80 
81  /// @brief Returns true if the button is currently pressed.
82  bool is_down() const { return is_down_; }
83 
84  /// @brief Returns true if the button has been pressed since last update.
85  bool went_down() const { return went_down_; }
86 
87  /// @brief Returns true if the button has been released since last update.
88  bool went_up() const { return went_up_; }
89 
90  private:
91  bool is_down_;
92  bool went_down_;
93  bool went_up_;
94 };
95 
96 // This enum extends the FPL keycodes, which are normally positive values.
97 // Negative values will represent finger / mouse and gamepad buttons.
98 // `button_map` below maps from one of these values to a Button.
99 enum {
100  K_POINTER1 = -10, // Left mouse or first finger down.
101  K_POINTER2, // Right mouse or second finger.
102  K_POINTER3, // Middle mouse or third finger.
103  K_POINTER4,
104  K_POINTER5,
105  K_POINTER6,
106  K_POINTER7,
107  K_POINTER8,
108  K_POINTER9,
109  K_POINTER10,
110  K_PAD_UP = -20,
111  K_PAD_DOWN,
112  K_PAD_LEFT,
113  K_PAD_RIGHT,
114  K_PAD_A,
115  K_PAD_B
116 };
117 
118 /// @class InputPointer
119 /// @brief Stores information about the current and recent state of a pointer.
120 ///
121 /// An input pointer represents either a finger-touch on a touchscreen device,
122 /// or a mouse-pointer.
123 // Additional information stored for the pointer buttons.
124 struct InputPointer {
125  /// @brief The pointer's ID
126  ///
127  /// The mouse pointer always has a pointerID of 0. For fingertouches, they
128  /// are generally allocated in order as new touches happen.
129  FingerId id;
130 
131  /// @brief The position of the pointer, in pixels.
132  mathfu::vec2i mousepos;
133 
134  /// @brief The amount the pointer moved since the last update.
135  mathfu::vec2i mousedelta;
136 
137  /// @brief Whether this particular pointer is in use.
138  ///
139  /// When used is false, the pointer data is in an undefined state and
140  /// should be ignored.
141  bool used;
142 
143  InputPointer() : id(0), mousepos(-1), mousedelta(0), used(false){};
144 };
145 
146 /// @class Joystick
147 /// @brief Represents the state of a Joystick.
148 class Joystick {
149  public:
150  /// @brief Get the current state of a button.
151  /// @param button_index The index of the button to querry.
152  /// @return A button object representing the current button state.
153  Button &GetButton(size_t button_index);
154 
155  /// @brief Get the current state of a joystick axis control.
156  /// @param axis_index The index of the axis to querry.
157  /// @return A float representing the position of the axis control. Axis data
158  /// is automatically normalized to be within the range of [-1, 1].
159  float GetAxis(size_t axis_index);
160 
161  /// @brief Get the current state of a joystick hat control.
162  /// @param hat_index The index of the hat to querry.
163  /// @return A vec2 representing the direction the hat is pointing.
164  ///
165  /// The returned vector will always have an X, Y component of -1, 0, or 1.
166  /// (And thus will always be pointing in one of 8 possible directions, or
167  /// in the neutral position.)
168  mathfu::vec2 GetHat(size_t hat_index);
169 
170  /// @brief Sets the value of an axis
171  /// @param axis_index The index of the axis to modify.
172  /// @param axis The new value to record for the axis.
173  ///
174  /// Normally only called by input handlers in the Input class.
175  void SetAxis(size_t axis_index, float axis);
176 
177  /// @brief Sets the position of a hat.
178  /// @param hat_index The index of the hat to modify.
179  /// @param hat The new value to record for the hat.
180  ///
181  /// Normally only called by input handlers in the Input class.
182  void SetHat(size_t hat_index, const mathfu::vec2 &hat);
183 
184  /// @brief Updates the internal state of the joystick by one frame.
185  ///
186  /// This function ensures that the joystick readings are up-to-date, and that
187  /// buttons have their change-bits set correctly. Normally called
188  /// automatically by InputSystem::AdvanceFrame().
189  void AdvanceFrame();
190 
191  /// @brief Returns the pointer to the raw joystick data.
192  ///
193  /// The type and layout of the joystick_data are implementation specific,
194  /// and should not generally be used by code outside of the FPLBase library.
195  JoystickData joystick_data() { return joystick_data_; }
196 
197  /// @brief Sets the pointer to the raw joystick data.
198  /// @param joy A pointer to the joystick data.
199  ///
200  /// The type and layout of the joystick_data are implementation specific,
201  /// and should not generally be used by code outside of the FPLBase library.
202  void set_joystick_data(JoystickData joy) { joystick_data_ = joy; }
203 
204  /// @brief Gets the ID of the joystick.
205  ///
206  /// Joystick IDs are guaranteed to be unique between joysticks, and on some
207  /// platforms, will be preserved even if the same controller is unplugged and
208  /// reconnected. (Platform dependent.) The Joystick ID is used to reference
209  /// a particular device.
210  JoystickId GetJoystickId() const;
211 
212  /// @brief Returns the number of buttons available on the joystick.
213  int GetNumButtons() const;
214 
215  /// @brief Returns the number of control axes available on the joystick.
216  int GetNumAxes() const;
217 
218  /// @brief Returns the number of hats available on the joystick.
219  int GetNumHats() const;
220 
221  private:
222  JoystickData joystick_data_;
223  std::vector<float> axis_list_;
224  std::vector<Button> button_list_;
225  std::vector<mathfu::vec2> hat_list_;
226 };
227 
228 #if ANDROID_GAMEPAD
229 /// @class Gamepad
230 /// @brief Represents the state of a connected gamepad.
231 ///
232 /// Gamepads are an android-specific abstraction for controllers that are
233 /// specifically gamepad-like. (They have a d-pad and one or more buttons.)
234 /// This is only present if ANDROID_GAMEPAD is defined.
235 class Gamepad {
236  public:
237  /// @brief Enum describing all possible button inputs on a gamepad.
238  enum GamepadInputButton : int {
239  kInvalid = -1,
240  kUp = 0,
241  kDown,
242  kLeft,
243  kRight,
244  kButtonA,
245  kButtonB,
246  kButtonC,
247  kButtonX,
248  kButtonY,
249  kButtonZ,
250  kButtonL1,
251  kButtonR1,
252  kButtonL2,
253  kButtonR2,
254  kButtonThumbL,
255  kButtonThumbR,
256  kButtonBack,
257  kButtonStart,
258  kButtonSelect,
259  kButtonMode,
260  kControlCount
261  };
262 
263  /// @brief Default constructor for a Gamepad.
264  Gamepad() { button_list_.resize(Gamepad::kControlCount); }
265 
266  /// @brief Advances the internal state by one frame.
267  ///
268  /// This function ensures that the gamepad readings are up-to-date, and that
269  /// buttons have their change-bits set correctly. Normally called
270  /// automatically by InputSystem::AdvanceFrame().
271  void AdvanceFrame();
272 
273  /// @brief Get the Button from a given enum of all possible input buttons.
274  /// @param[in] i A GamepadInputButton enum describing all of the possible
275  /// button inputs on a gamepad.
277 
278  /// @brief Get the Button from a given enum of all possible input buttons.
279  /// @param[in] i A GamepadInputButton enum describing all of the possible
280  /// button inputs on a gamepad.
282  return const_cast<Gamepad *>(this)->GetButton(i);
283  }
284 
285  /// @brief Returns the Android controller_id of the gamepad
286  ///
287  /// The controller_id is the android-specific identifier for a given
288  /// gamepad.
289  AndroidInputDeviceId controller_id() { return controller_id_; }
290 
291  /// @brief Set the controller ID.
292  /// @param[in] controller_id An AndroidInputDeviceId to set as the controller
293  /// ID.
294  void set_controller_id(AndroidInputDeviceId controller_id) {
295  controller_id_ = controller_id;
296  }
297 
298  /// @brief Internal function for translating android input.
299  static int GetGamepadCodeFromJavaKeyCode(int java_keycode);
300 
301  private:
302  AndroidInputDeviceId controller_id_;
303  std::vector<Button> button_list_;
304 };
305 
306 // Threshold for when we register a hat direction. (The range is [0, 1]
307 const float kGamepadHatThreshold = 0.5f;
308 
309 /// @brief Structure used for storing gamepad events when we get them from jni
310 /// until we can handle them.
312  /// @brief AndroidInputEvent default constructor.
314  /// @brief Constructor for an AndroidInputeEvent.
315  /// @param[in] device_id_ The device ID of the Android device.
316  /// @param[in] event_code_ The event code for the gamepad event.
317  /// @param[in] control_code_ The control code for the gamepad event.
318  /// @param[in] x_ The x position of the event.
319  /// @param[in] y_ The y position for the event.
320  AndroidInputEvent(AndroidInputDeviceId device_id_, int event_code_,
321  int control_code_, float x_, float y_)
322  : device_id(device_id_),
323  event_code(event_code_),
324  control_code(control_code_),
325  x(x_),
326  y(y_) {}
327  /// @brief The device ID of the Android device.
328  AndroidInputDeviceId device_id;
329  /// @brief The event code.
331  /// @brief The control code.
333  /// @brief The `x` coordinate for the event.
334  float x;
335  /// @brief The `y` coordinate for the event.
336  float y;
337 };
338 #endif // ANDROID_GAMEPAD
339 
340 #if FPLBASE_ANDROID_VR
341 /// @class HeadMountedDisplayInput
342 /// @brief Represents the state of the device in a head mounted input device,
343 /// like Cardboard.
344 ///
345 /// Manages the state of the device in a head mounted input device based on
346 /// events passed in from java, and read via JNI. Depends on FPLBASE_ANDROID_VR being
347 /// defined.
348 class HeadMountedDisplayInput {
349  public:
350  /// @brief Default constructor for HeadMountedDisplayInput.
351  HeadMountedDisplayInput()
352  : head_transform_(),
353  left_eye_transform_(),
354  right_eye_transform_(),
355  is_in_head_mounted_display_(false),
356  triggered_(false),
357  pending_trigger_(false),
358  use_device_orientation_correction_(false),
359  device_orientation_(0) {}
360 
361  /// @brief Check if the device is in head mounted display mode.
362  /// @return Returns `true` if `set_is_in_head_mounted_display()` was set
363  /// to `true`.
364  bool is_in_head_mounted_display() const {
365  return is_in_head_mounted_display_;
366  }
367 
368  /// @brief Set whether or not hte device is in head mounted display mode.
369  /// @param[in] is_in_head_mounted_display A `bool` determining if the
370  /// device is set to be in head mounted display mode.
371  void set_is_in_head_mounted_display(bool is_in_head_mounted_display) {
372  is_in_head_mounted_display_ = is_in_head_mounted_display;
373  }
374 
375  /// @brief Check if triggered.
376  /// @return Returns `true` if the a pending trigger was handled in
377  /// `AdvanceFrame`.
378  bool triggered() const { return triggered_; }
379 
380  /// @brief Get the head transform.
381  /// @return Returns the head transform as a const `mathfu::mat4` reference.
382  const mathfu::mat4 &head_transform() const { return head_transform_; }
383 
384  /// @brief Get the left eye transform.
385  /// @return Returns the left eye transform as a const `mathfu::mat4`
386  /// reference.
387  const mathfu::mat4 &left_eye_transform() const { return left_eye_transform_; }
388 
389  /// @brief Get the right eye transform.
390  /// @return Returns the right eye transform as a const `mathfu::mat4`
391  /// reference.
392  const mathfu::mat4 &right_eye_transform() const {
393  return right_eye_transform_;
394  }
395 
396  /// @brief The rightwards direction of the head.
397  /// @return Returns the rightwards direction of the head as a `mathfu::vec3`.
398  mathfu::vec3 right() const {
399  return (mathfu::kAxisX4f * head_transform_).xyz();
400  }
401  /// @brief The upwards direction of the head.
402  /// @return Returns the upwards direction of the head as a `mathfu::vec3`.
403  mathfu::vec3 up() const { return (mathfu::kAxisY4f * head_transform_).xyz(); }
404 
405  /// @brief The forward direction of the head.
406  /// @note It points into -Z.
407  /// @return Returns the forward direction of the head as a `mathfu::vec3`.
408  mathfu::vec3 forward() const {
409  return (-mathfu::kAxisZ4f * head_transform_).xyz();
410  }
411 
412  /// @brief The translation of the left eye.
413  /// @return Returns the left eye translation as a `mathfu::vec`.
414  mathfu::vec3 left_eye_translation() const {
415  return (left_eye_transform_ * mathfu::kAxisW4f).xyz();
416  }
417 
418  /// @brief The translation of the right eye.
419  /// @return Returns the right eye translation as a `mathfu::vec`.
420  mathfu::vec3 right_eye_translation() const {
421  return (right_eye_transform_ * mathfu::kAxisW4f).xyz();
422  }
423 
424  /// @brief The translation of the left eye, factoring in the Cardboard
425  /// rotation.
426  /// @return Returns the left eye translation, factoring in the Cardboard
427  /// rotation.
428  mathfu::vec3 left_eye_rotated_translation() const {
429  return (mathfu::vec4(left_eye_translation(), 0) * left_eye_transform_)
430  .xyz();
431  }
432 
433  /// @brief The translation of the right eye, factoring in the Cardboard
434  /// rotation.
435  /// @return Returns the right eye translation, factoring in the Cardboard
436  /// rotation.
437  mathfu::vec3 right_eye_rotated_translation() const {
438  return (mathfu::vec4(right_eye_translation(), 0) * right_eye_transform_)
439  .xyz();
440  }
441 
442  /// @brief Called once per frame to handle the input.
443  void AdvanceFrame();
444 
445  /// @brief Sets `pending_trigger_` to `true` when called.
446  void OnTrigger() { pending_trigger_ = true; }
447 
448  /// @brief Realign the head tracking with the current phone heading
449  void ResetHeadTracker();
450 
451  /// @brief Enable correction for version 0.5.6 of the Cardboard SDK, which
452  /// has a bug concerning not handling a device's default orientation. Calling
453  /// this enables correction of that in the Cardboard Input.
454  void EnableDeviceOrientationCorrection();
455 
456  /// @brief Set the device orientation.
457  /// @param[in] rotation The rotation to set for the orientation.
458  void set_device_orientation(int rotation) { device_orientation_ = rotation; }
459 
460  /// @brief Get the device orientation.
461  /// @return Returns an `int` corresponding to the rotation of the device's
462  /// orientation.
463  int device_orientation() { return device_orientation_; }
464 
465 #if FPLBASE_ANDROID_VR
466  void InitHMDJNIReference();
467  void ClearHMDJNIReference();
468 #endif
469 
470  private:
471  void UpdateTransforms();
472 
473  mathfu::mat4 head_transform_;
474  mathfu::mat4 left_eye_transform_;
475  mathfu::mat4 right_eye_transform_;
476  bool is_in_head_mounted_display_;
477  bool triggered_;
478  bool pending_trigger_;
479  // Whether correction should be applied to the view matrices.
480  bool use_device_orientation_correction_;
481  // The device's default rotation, as defined here:
482  // http://developer.android.com/reference/android/view/Surface.html#ROTATION_0
483  int device_orientation_;
484  // The device's rotation the last time reset head tracker was called.
485  int device_orientation_at_reset_;
486 };
487 #endif // FPLBASE_ANDROID_VR
488 
489 // Text input structures and enums.
490 
491 // Text input event type.
492 enum TextInputEventType {
493  kTextInputEventTypeEdit = 0, // An event for a text edit in IME.
494  kTextInputEventTypeText = 1, // An event for a text input.
495  kTextInputEventTypeKey = 2, // An event for a key event.
496 };
497 
498 /// @brief An event parameter for a text edit in IME (Input Method Editor).
499 /// The information passed in the event is an intermediate state and only used
500 /// for UI represents. Once IME finalizes an edit, the user recieves an
501 /// TextInputEventText event for the finalized strings.
503  int32_t start; ///< @brief A start index of a focus region in the text.
504  int32_t length; ///< @brief A length of a focus region in the text.
505 };
506 
507 /// @brief An event parameter for a keyboard input.
508 ///
509 /// The user recieves all input strings through `kTextInputEventTypeText` type
510 /// of an event, these paremeters should be used for an input control such as
511 /// moving caret.
513  bool state; ///< @brief key state, true:pressed, false:released.
514  bool repeat; ///< @brief A flag indicates if the key is repeated
515  /// input.
516  FPL_Keycode symbol; ///< @brief Key symbol, refer `keyboard_keycodes.h` for
517  /// details.
518  FPL_Keymod modifier; ///< @brief Modifier key state, refer
519  /// `keyboard_keycodes.h` for details.
520 };
521 
522 /// @brief Holds text input events.
524  TextInputEventType type; ///< @brief Type of the event.
525  std::string text; ///< @brief Input string.
526  /// @brief Union of Text input events.
527  union {
528  TextInputEventKey key; ///< @brief An event parameter for a keyboard input.
529  TextInputEventEdit edit; ///< @brief An event parameter for a text edit in
530  /// IME (Input Method Editor).
531  };
532  /// @brief Constructor for TextInputEvent.
533  TextInputEvent(TextInputEventType t);
534  /// @brief Constructor for TextInputEvent.
535  TextInputEvent(TextInputEventType t, int32_t state, bool repeat,
536  int32_t symbol, int32_t modifier);
537  /// @brief Constructor for TextInputEvent.
538  TextInputEvent(TextInputEventType t, const char *str);
539  /// @brief Constructor for TextInputEvent.
540  TextInputEvent(TextInputEventType t, const char *str, int32_t start,
541  int32_t length);
542 };
543 
544 /// @class InputSystem
545 /// @brief Use to handle time, touch/mouse/keyboard/etc input, and lifecyle
546 /// events.
547 class InputSystem {
548  public:
549  /// @brief Construct an uninitialized InputSystem.
550  InputSystem();
551  ~InputSystem();
552 
553  static const int kMaxSimultanuousPointers = 10; // All current touch screens.
554 
555  /// @brief Initialize the input system.
556  ///
557  /// Call this after the Renderer is initialized.
558  void Initialize();
559 
560  /// @brief Call once a frame to update the input state.
561  ///
562  /// Call this once a frame to process all new events and update the input
563  /// state. The window_size argument may get updated whenever the window
564  /// resizes.
565  ///
566  /// @param window_size The current window size of the application.
567  void AdvanceFrame(mathfu::vec2i *window_size);
568 
569  /// @brief Get time in seconds since the start of the game. Updated once per
570  /// frame.
571  ///
572  /// This is the time you'd want to use for any gameplay simulation or
573  /// animation the game does, such that you are in sync with what's
574  /// rendered each frame.
575  ///
576  /// @return Return the time in seconds since the start of the game.
577  double Time() const;
578 
579  /// @brief Get time in seconds since start of the game. Updated every call.
580  ///
581  /// Unlike Time(), it is recomputed every time it is called (slower).
582  /// Mostly useful for profiling/benchmarking.
583  ///
584  /// @return Return the time in seconds since the start of the game.
585  double RealTime() const;
586 
587  /// @brief The time in seconds since the last frame. Updated once per frame.
588  ///
589  /// @return Return the incremental time, in seconds.
590  double DeltaTime() const;
591 
592  /// @brief Make the application go to sleep a certain duration.
593  void Delay(double seconds) const;
594 
595  /// @brief Get a Button object describing the input state of the specified
596  /// button ID.
597  ///
598  /// @param button The ID of the button.
599  /// @return Returns the corresponding button.
600  Button &GetButton(int button);
601 
602  /// @brief Checks if relative mouse mode is enabled.
603  ///
604  /// @return Returns the current state of relative mouse mode.
605  bool RelativeMouseMode() const;
606  /// @brief Enable / disable relative mouse mode (disabled by default).
607  ///
608  /// @param enabled The state to set relative mouse mode to.
609  /// @note Relative mouse mode is currently ignored on Android devices.
610  void SetRelativeMouseMode(bool enabled);
611 
612  /// @brief Get a Joystick object describing the input state of the specified
613  /// joystick ID.
614  ///
615  /// @param joystick_id The ID of the joystick, contained in every joystick
616  /// event.
617  /// @return Returns the corresponding button.
618  Joystick &GetJoystick(JoystickId joystick_id);
619 
620  /// @brief Get a map containing all currently connected joysticks.
621  ///
622  /// @return Returns the map of all joysticks.
623  const std::map<JoystickId, Joystick> &JoystickMap() const {
624  return joystick_map_;
625  }
626 
627 #if ANDROID_GAMEPAD
628  /// @brief Get a Gamepad object describing the input state of the specified
629  /// device ID.
630  ///
631  /// Get the ID either from an android event, or by checking a known gamepad.
632  ///
633  /// @param gamepad_device_id The ID of the gamepad device.
634  /// @return Returns the corresponding gamepad.
635  Gamepad &GetGamepad(AndroidInputDeviceId gamepad_device_id);
636 
637  /// @brief Get a map containing all currently connected gamepads.
638  ///
639  /// @return Returns the map of all gamepads.
640  const std::map<AndroidInputDeviceId, Gamepad> &GamepadMap() const {
641  return gamepad_map_;
642  }
643 
644  /// @brief Receives events from java, and stuffs them into a vector until
645  /// we're ready.
646  static void ReceiveGamepadEvent(int controller_id, int event_code,
647  int control_code, float x, float y);
648 
649  /// @brief Runs through all the received events and processes them.
650  void HandleGamepadEvents();
651 #endif // ANDROID_GAMEPAD
652 
653 #if FPLBASE_ANDROID_VR
654  /// @brief Get the current input state of the Head Mounted Display device.
655  ///
656  /// @return Returns the current input state.
657  HeadMountedDisplayInput &head_mounted_display_input() {
658  return head_mounted_display_input_;
659  }
660 
661  /// @brief Get the current input state of the Head Mounted Display device.
662  ///
663  /// @return Returns the current input state.
664  const HeadMountedDisplayInput &head_mounted_display_input() const {
665  return head_mounted_display_input_;
666  }
667 #endif // FPLBASE_ANDROID_VR
668 
669  /// @brief Get a Button object for a pointer index.
670  ///
671  /// @param pointer The FingerId of the button.
672  /// @return Returns the corresponding button.
673  Button &GetPointerButton(FingerId pointer) {
674  return GetButton(static_cast<int>(pointer + K_POINTER1));
675  }
676 
677  /// @brief Open all connected joysticks.
678  void OpenConnectedJoysticks();
679 
680  /// @brief Close all opened joysticks.
681  void CloseOpenJoysticks();
682 
683  /// @brief Close any open joysticks, and then refresh the list by opening any
684  /// joysticks that are still connected.
686 
687  /// @brief Handle a joystick event.
688  /// @param[in] event The joystick event that should be handled.
689  void HandleJoystickEvent(Event event);
690 
691  /// @brief A function pointer to an app event callback function.
692  typedef std::function<void(Event)> AppEventCallback;
693 
694  /// @brief Get the vector of all app event callbacks.
695  /// @return Returns a `std::vector<AppEventCallback>` with all app event
696  /// callbacks.
697  std::vector<AppEventCallback> &app_event_callbacks() {
698  return app_event_callbacks_;
699  }
700 
701  /// @brief Add an app event callback function.
702  void AddAppEventCallback(AppEventCallback callback);
703 
704  /// @brief Get the most recent frame at which we were minimized or maximized.
705  /// @return Returns the most recent frame at which we were minimized or
706  /// maximized.
707  int minimized_frame() const { return minimized_frame_; }
708 
709  /// @brief Set the most recent frame at which we were minimized or maximized.
710  /// @param[in] minimized_frame The most recent frame at which we were
711  /// minimized or maximized.
713  minimized_frame_ = minimized_frame;
714  }
715 
716  /// @brief The total number of frames elapsed so far.
717  int frames() const { return frames_; }
718  /// @brief Accumulated mousewheel delta since the previous frame.
719  mathfu::vec2i mousewheel_delta() { return mousewheel_delta_; }
720 
721  /// @brief Start/Stop recording text input events.
722  ///
723  /// Recorded event can be retrieved by GetTextInputEvents().
724  void RecordTextInput(bool b) {
725  record_text_input_ = b;
726  if (!b) text_input_events_.clear();
727  }
728  /// @brief Checks if text input is being recorded.
729  bool IsRecordingTextInput() { return record_text_input_; }
730 
731  /// @brief Retrieve a vector of text input events.
732  ///
733  /// The caller uses this API to retrieve text input related events
734  /// (all key down/up events, keyboard input and IME's intermediate states)
735  /// and use them to edit and display texts.
736  /// To start/stop a recording, call RecordTextInput() API.
737  ///
738  /// @return Returns a vector containing text input events.
739  const std::vector<TextInputEvent> *GetTextInputEvents();
740 
741  /// @brief Clear the recorded text input events.
742  ///
743  /// The user needs to call the API once they have handled input events.
744  void ClearTextInputEvents() { text_input_events_.clear(); }
745 
746  // Text input related APIs.
747 
748  /// @brief Start a text input.
749  ///
750  /// In mobile devices, it may show a software keyboard on the screen.
751  void StartTextInput();
752 
753  /// @brief Stop a text input.
754  ///
755  /// In mobile devices, it may dismiss a software keyboard.
756  void StopTextInput();
757 
758  /// @brief Indicates a text input region to IME(Input Method Editor).
759  ///
760  /// @param input_rect The input region rectangle.
761  void SetTextInputRect(const mathfu::vec4 &input_rect);
762 
763  /// @brief Gets the vector of all the input pointers in the system.
764  const std::vector<InputPointer> &get_pointers() const { return pointers_; }
765  std::vector<InputPointer> &get_pointers() { return pointers_; }
766 
767  /// @brief Gets if the application is currently minimized.
768  bool minimized() { return minimized_; }
769  /// @brief Sets if the application is currently minimized.
770  void set_minimized(bool b) { minimized_ = b; }
771 
772  /// @brief Gets if exit has been requested by the system.
773  bool exit_requested() { return exit_requested_; }
774  /// @brief Sets if exit has been requested.
775  void set_exit_requested(bool b) { exit_requested_ = b; }
776 
777  private:
778  // Reset pointer/gamepad input state to released state.
779  void ResetInputState();
780 
781  static const int kMillisecondsPerSecond = 1000;
782 
783  static int HandleAppEvents(void *userdata, void *event);
784 
785  // The event specific part of AdvanceFrame().
786  void UpdateEvents(mathfu::vec2i *window_size);
787 
788  bool exit_requested_;
789  bool minimized_;
790  std::vector<InputPointer> pointers_;
791  std::vector<JoystickData> open_joystick_list;
792  size_t FindPointer(FingerId id);
793  size_t UpdateDragPosition(TouchFingerEvent e, uint32_t event_type,
794  const mathfu::vec2i &window_size);
795  void RemovePointer(size_t i);
796  mathfu::vec2 ConvertHatToVector(uint32_t hat_enum) const;
797  std::vector<AppEventCallback> app_event_callbacks_;
798  std::map<int, Button> button_map_;
799  std::map<JoystickId, Joystick> joystick_map_;
800 
801 #if ANDROID_GAMEPAD
802  std::map<AndroidInputDeviceId, Gamepad> gamepad_map_;
803  static pthread_mutex_t android_event_mutex;
804  static std::queue<AndroidInputEvent> unhandled_java_input_events_;
805 #endif // ANDROID_GAMEPAD
806 
807 #if FPLBASE_ANDROID_VR
808  // Head mounted display input class.
809  HeadMountedDisplayInput head_mounted_display_input_;
810 #endif // FPLBASE_ANDROID_VR
811 
812  // Most recent frame delta, in seconds.
813  double frame_time_;
814 
815  // Time since start, in seconds.
816  double elapsed_time_;
817 
818  // World time at start, in seconds.
819  uint64_t start_time_;
820 
821  // Timer frequency.
822  uint64_t time_freq_;
823 
824  // Number of frames so far. That is, number of times AdvanceFrame() has been
825  // called.
826  int frames_;
827 
828  // Most recent frame at which we were minimized or maximized.
829  int minimized_frame_;
830 
831  // Accumulated mousewheel delta since the last frame.
832  mathfu::vec2i mousewheel_delta_;
833 
834  // Event queue for a text input events.
835  std::vector<TextInputEvent> text_input_events_;
836 
837  // A flag indicating a text input status.
838  bool record_text_input_;
839 
840  // True if most recent pointer events are coming from a touch screen,
841  // false if coming from a mouse or similar.
842  bool touch_device_;
843 
844 #ifdef __ANDROID__
845  // Store current relative mouse mode before entering background.
846  bool relative_mouse_mode_;
847 
848  // How long since we've sent a keypress event to keep the CPU alive.
849  double last_android_keypress_;
850 #endif // __ANDROID__
851 };
852 
853 /// @}
854 } // namespace fplbase
855 
856 #endif // FPLBASE_INPUT_SYSTEM_H
mathfu::vec2 GetHat(size_t hat_index)
Get the current state of a joystick hat control.
mathfu::vec2i mousewheel_delta()
Accumulated mousewheel delta since the previous frame.
Definition: input.h:719
void OpenConnectedJoysticks()
Open all connected joysticks.
void Delay(double seconds) const
Make the application go to sleep a certain duration.
int event_code
The event code.
Definition: input.h:330
void set_joystick_data(JoystickData joy)
Sets the pointer to the raw joystick data.
Definition: input.h:202
void HandleGamepadEvents()
Runs through all the received events and processes them.
void SetTextInputRect(const mathfu::vec4 &input_rect)
Indicates a text input region to IME(Input Method Editor).
void CloseOpenJoysticks()
Close all opened joysticks.
static void ReceiveGamepadEvent(int controller_id, int event_code, int control_code, float x, float y)
Receives events from java, and stuffs them into a vector until we're ready.
void SetHat(size_t hat_index, const mathfu::vec2 &hat)
Sets the position of a hat.
int minimized_frame() const
Get the most recent frame at which we were minimized or maximized.
Definition: input.h:707
Joystick & GetJoystick(JoystickId joystick_id)
Get a Joystick object describing the input state of the specified joystick ID.
float x
The x coordinate for the event.
Definition: input.h:334
Button & GetPointerButton(FingerId pointer)
Get a Button object for a pointer index.
Definition: input.h:673
int32_t start
A start index of a focus region in the text.
Definition: input.h:503
mathfu::vec2i mousepos
The position of the pointer, in pixels.
Definition: input.h:132
AndroidInputEvent()
AndroidInputEvent default constructor.
Definition: input.h:313
void AdvanceFrame(mathfu::vec2i *window_size)
Call once a frame to update the input state.
Gamepad & GetGamepad(AndroidInputDeviceId gamepad_device_id)
Get a Gamepad object describing the input state of the specified device ID.
bool state
key state, true:pressed, false:released.
Definition: input.h:513
static int GetGamepadCodeFromJavaKeyCode(int java_keycode)
Internal function for translating android input.
std::vector< AppEventCallback > & app_event_callbacks()
Get the vector of all app event callbacks.
Definition: input.h:697
FPL_Keymod modifier
Modifier key state, refer keyboard_keycodes.h for details.
Definition: input.h:518
TextInputEventType type
Type of the event.
Definition: input.h:524
int GetNumButtons() const
Returns the number of buttons available on the joystick.
bool is_down() const
Returns true if the button is currently pressed.
Definition: input.h:82
void set_exit_requested(bool b)
Sets if exit has been requested.
Definition: input.h:775
AndroidInputEvent(AndroidInputDeviceId device_id_, int event_code_, int control_code_, float x_, float y_)
Constructor for an AndroidInputeEvent.
Definition: input.h:320
float y
The y coordinate for the event.
Definition: input.h:336
double Time() const
Get time in seconds since the start of the game. Updated once per frame.
int control_code
The control code.
Definition: input.h:332
double DeltaTime() const
The time in seconds since the last frame. Updated once per frame.
FPL_Keycode symbol
Key symbol, refer keyboard_keycodes.h for details.
Definition: input.h:516
void set_controller_id(AndroidInputDeviceId controller_id)
Set the controller ID.
Definition: input.h:294
const std::map< AndroidInputDeviceId, Gamepad > & GamepadMap() const
Get a map containing all currently connected gamepads.
Definition: input.h:640
void SetRelativeMouseMode(bool enabled)
Enable / disable relative mouse mode (disabled by default).
const std::map< JoystickId, Joystick > & JoystickMap() const
Get a map containing all currently connected joysticks.
Definition: input.h:623
void Initialize()
Initialize the input system.
void AdvanceFrame()
Updates the internal state of the joystick by one frame.
InputSystem()
Construct an uninitialized InputSystem.
GamepadInputButton
Enum describing all possible button inputs on a gamepad.
Definition: input.h:238
TextInputEventEdit edit
An event parameter for a text edit in IME (Input Method Editor).
Definition: input.h:529
FingerId id
The pointer's ID.
Definition: input.h:129
std::function< void(Event)> AppEventCallback
A function pointer to an app event callback function.
Definition: input.h:692
void SetAxis(size_t axis_index, float axis)
Sets the value of an axis.
bool IsRecordingTextInput()
Checks if text input is being recorded.
Definition: input.h:729
JoystickId GetJoystickId() const
Gets the ID of the joystick.
void ClearTextInputEvents()
Clear the recorded text input events.
Definition: input.h:744
TextInputEvent(TextInputEventType t)
Constructor for TextInputEvent.
double RealTime() const
Get time in seconds since start of the game. Updated every call.
bool RelativeMouseMode() const
Checks if relative mouse mode is enabled.
Use to handle time, touch/mouse/keyboard/etc input, and lifecyle events.
Definition: input.h:547
Button & GetButton(GamepadInputButton i)
Get the Button from a given enum of all possible input buttons.
FPL_Keymod
Enumeration of valid key mods (possibly OR'd together).
Definition: keyboard_keycodes.h:300
AndroidInputDeviceId device_id
The device ID of the Android device.
Definition: input.h:328
An event parameter for a text edit in IME (Input Method Editor). The information passed in the event ...
Definition: input.h:502
const Button & GetButton(GamepadInputButton i) const
Get the Button from a given enum of all possible input buttons.
Definition: input.h:281
void StopTextInput()
Stop a text input.
int32_t length
A length of a focus region in the text.
Definition: input.h:504
void set_minimized(bool b)
Sets if the application is currently minimized.
Definition: input.h:770
An event parameter for a keyboard input.
Definition: input.h:512
bool went_up() const
Returns true if the button has been released since last update.
Definition: input.h:88
bool went_down() const
Returns true if the button has been pressed since last update.
Definition: input.h:85
bool repeat
A flag indicates if the key is repeated input.
Definition: input.h:514
int frames() const
The total number of frames elapsed so far.
Definition: input.h:717
void AdvanceFrame()
Advances the internal state by one frame.
Stores information about the current and recent state of a pointer.
Definition: input.h:124
bool used
Whether this particular pointer is in use.
Definition: input.h:141
Button & GetButton(int button)
Get a Button object describing the input state of the specified button ID.
int GetNumHats() const
Returns the number of hats available on the joystick.
void RecordTextInput(bool b)
Start/Stop recording text input events.
Definition: input.h:724
bool minimized()
Gets if the application is currently minimized.
Definition: input.h:768
const std::vector< InputPointer > & get_pointers() const
Gets the vector of all the input pointers in the system.
Definition: input.h:764
void StartTextInput()
Start a text input.
Represents the state of a Joystick.
Definition: input.h:148
Structure used for storing gamepad events when we get them from jni until we can handle them...
Definition: input.h:311
Represents the state of a connected gamepad.
Definition: input.h:235
mathfu::vec2i mousedelta
The amount the pointer moved since the last update.
Definition: input.h:135
void AddAppEventCallback(AppEventCallback callback)
Add an app event callback function.
Used to record state for fingers, mousebuttons, keys and gamepad buttons.
Definition: input.h:65
void UpdateConnectedJoystickList()
Close any open joysticks, and then refresh the list by opening any joysticks that are still connected...
JoystickData joystick_data()
Returns the pointer to the raw joystick data.
Definition: input.h:195
Gamepad()
Default constructor for a Gamepad.
Definition: input.h:264
float GetAxis(size_t axis_index)
Get the current state of a joystick axis control.
std::string text
Input string.
Definition: input.h:525
TextInputEventKey key
An event parameter for a keyboard input.
Definition: input.h:528
bool exit_requested()
Gets if exit has been requested by the system.
Definition: input.h:773
const std::vector< TextInputEvent > * GetTextInputEvents()
Retrieve a vector of text input events.
AndroidInputDeviceId controller_id()
Returns the Android controller_id of the gamepad.
Definition: input.h:289
void HandleJoystickEvent(Event event)
Handle a joystick event.
void set_minimized_frame(int minimized_frame)
Set the most recent frame at which we were minimized or maximized.
Definition: input.h:712
int GetNumAxes() const
Returns the number of control axes available on the joystick.
void AdvanceFrame()
Advances the current state of the button by one frame.
Definition: input.h:73
void Update(bool down)
Updates the current state of the button.
Holds text input events.
Definition: input.h:523
Button & GetButton(size_t button_index)
Get the current state of a button.