1 /**
2  * Copyright:       Copyright (C) 2018 Gabriel Gheorghe, All Rights Reserved
3  * Authors:         $(Gabriel Gheorghe)
4  * License:         $(LINK2 https://www.gnu.org/licenses/gpl-3.0.txt, GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007)
5  * Source:          $(LINK2 https://github.com/GabyForceQ/LibertyEngine/blob/master/source/liberty/input/joystick/impl.d)
6  * Documentation:
7  * Coverage:
8 **/
9 module liberty.input.joystick.impl;
10 
11 import bindbc.glfw;
12 
13 import liberty.core.platform;
14 import liberty.input.joystick.constants;
15 
16 /**
17  *
18 **/
19 final class Joystick {
20   private {
21     bool connected;
22     bool[JOYSTICK_BUTTONS] buttonsState;
23     ubyte* pButtons;
24   }
25 
26   /**
27    *
28   **/
29   this()  {
30     const int present1 = glfwJoystickPresent(JoystickNumber.NO_1);
31     if (present1)
32       connected = true;
33 
34     processButtons();
35   }
36 
37   /**
38    * Returns true if joystick button was just pressed in an event loop.
39   **/
40   bool isButtonDown(JoystickButton button)   const {
41     return isButtonHold(button) && !buttonsState[button];
42   }
43 
44   /**
45    * Returns true if joystick button was just released in an event loop.
46   **/
47   bool isButtonUp(JoystickButton button)   const {
48     return !isButtonHold(button) && buttonsState[button];
49   }
50 
51   /**
52    * Returns true if joystick button is still pressed in an event loop.
53    * Use case: shooting something.
54   **/
55   bool isButtonHold(JoystickButton button)   const {
56     return connected ? pButtons[button] == GLFW_PRESS : false;
57   }
58 
59   /**
60    * Returns true if joystick button has no input action in an event loop.
61   **/
62   bool isButtonNone(JoystickButton button)   const {
63     return connected ? pButtons[button] == GLFW_RELEASE : false;
64   }
65 
66   /**
67    *
68   **/
69   bool isUnfolding(JoystickButton button, JoystickAction action)   const {
70     final switch (action) with (JoystickAction) {
71       case NONE:
72         return isButtonNone(button);
73       case DOWN:
74         return isButtonDown(button);
75       case UP:
76         return isButtonUp(button);
77       case HOLD:
78         return isButtonHold(button);
79     }
80   }
81 
82   /**
83    * Returns true if joystick is connected.
84   **/
85   bool isConnected()   const {
86     return connected;
87   }
88 
89   package(liberty.input) void update()  {
90     if (connected)
91       static foreach (i; 0..JOYSTICK_BUTTONS)
92         buttonsState[i] = isButtonHold(cast(JoystickButton)i);
93   
94     processButtons();
95   }
96 
97   package(liberty.input) Joystick processButtons()  {
98     int count;
99     pButtons = glfwGetJoystickButtons(JoystickNumber.NO_1, &count);
100     return this;
101   }
102 
103   package(liberty.input) Joystick setConnected(bool value)   {
104     connected = value;
105     return this;
106   }
107 }