1 module Dgame.System.Joystick;
2 
3 private:
4 
5 import derelict.sdl2.sdl;
6 
7 import Dgame.Math.Vector2;
8 
9 import Dgame.Internal.Error;
10 
11 public:
12 
13 /**
14  * Represent a Joystick
15  *
16  * Author: Randy Schuett (rswhite4@googlemail.com)
17  */
18 struct Joystick {
19 private:
20     SDL_Joystick* _joystick;
21     bool _owned = false;
22 
23 public:
24     /**
25      * The supported Hat positions
26      */
27     enum Hat {
28         Centered = SDL_HAT_CENTERED, ///
29         Up = SDL_HAT_UP, ///
30         Right = SDL_HAT_RIGHT, ///
31         Down = SDL_HAT_DOWN, ///
32         Left = SDL_HAT_LEFT, ///
33         RightUp = SDL_HAT_RIGHTUP, ///
34         RightDown = SDL_HAT_RIGHTDOWN, ///
35         LeftUp = SDL_HAT_LEFTUP, ///
36         LeftDown = SDL_HAT_LEFTDOWN ///
37     }
38 
39     @nogc
40     package this(SDL_Joystick* joy) nothrow {
41         _joystick = joy;
42         _owned = true;
43     }
44 
45     /**
46      * CTor
47      */
48     @nogc
49     this(int device) nothrow {
50         _joystick = SDL_JoystickOpen(device);
51         if (!_joystick)
52             print_fmt("Warning: Unable to open joystick %d! Error: %s\n", device, SDL_GetError());
53     }
54 
55     /**
56      * Postblit is disabled
57      */
58     @disable
59     this(this);
60 
61     /**
62      * DTor
63      */
64     @nogc
65     ~this() nothrow {
66         if (_joystick && !_owned)
67             SDL_JoystickClose(_joystick);
68     }
69 
70     /**
71      * Returns true if the Joystick has been opened, false if not
72      */
73     @nogc
74     bool isAttached() nothrow {
75         return SDL_JoystickGetAttached(_joystick) == SDL_TRUE;
76     }
77 
78     /**
79      * Returns the delta position of the given Ball index since the last call
80      */
81     @nogc
82     Vector2i getBallDelta(int ball) nothrow {
83         int x, y;
84         SDL_JoystickGetBall(_joystick, ball, &x, &y);
85 
86         return Vector2i(x, y);
87     }
88 
89     /**
90      * Returns whether the given Button is pressed
91      */
92     @nogc
93     bool isPressed(int btn) nothrow {
94         return SDL_JoystickGetButton(_joystick, btn) == 1;
95     }
96 
97     /**
98      * Returns the value of the given Axis index in range of short.min .. short.max
99      */
100     @nogc
101     short getAxisValue(int axis) nothrow {
102         return SDL_JoystickGetAxis(_joystick, axis);
103     }
104 
105     /**
106      * Returns the position of the given Hat index
107      *
108      * See: Hat enum
109      */
110     @nogc
111     Hat getHat(int hat) nothrow {
112         return cast(Hat) SDL_JoystickGetHat(_joystick, hat);
113     }
114 
115     /**
116      * Returns the ID of the Joystick
117      */
118     @property
119     @nogc
120     int ID() nothrow {
121         return SDL_JoystickInstanceID(_joystick);
122     }
123 
124     /**
125      * Returns the name of the Joystick
126      */
127     @nogc
128     string getName() nothrow {
129         import core.stdc..string : strlen;
130 
131         const char* p = SDL_JoystickName(_joystick);
132         if (!p)
133             return null;
134 
135         return cast(immutable) p[0 .. strlen(p)];
136     }
137 
138     /**
139      * Returns the amount of Axes of this Joystick
140      */
141     @nogc
142     int getNumOfAxes() nothrow {
143         return SDL_JoystickNumAxes(_joystick);
144     }
145 
146     /**
147      * Returns the amount of Balls of this Joystick
148      */
149     @nogc
150     int getNumOfBalls() nothrow {
151         return SDL_JoystickNumBalls(_joystick);
152     }
153 
154     /**
155      * Returns the amount of Buttons of this Joystick
156      */
157     @nogc
158     int getNumOfButtons() nothrow {
159         return SDL_JoystickNumButtons(_joystick);
160     }
161 
162     /**
163      * Returns the amount of Hats of this Joystick
164      */
165     @nogc
166     int getNumOfHats() nothrow {
167         return SDL_JoystickNumHats(_joystick);
168     }
169 
170     /**
171      * Use this function to update the current state of the open joysticks.
172      * This is called automatically by the event loop
173      */
174     @nogc
175     static void update() nothrow {
176         //SDL_JoystickUpdate();
177     }
178 
179     /**
180      *  Returns the name of the Joystick of the given device
181      */
182     @nogc
183     static string getNameForIndex(int device) nothrow {
184         import core.stdc..string : strlen;
185 
186         const char* p = SDL_JoystickNameForIndex(device);
187         if (!p)
188             return null;
189 
190         return cast(immutable) p[0 .. strlen(p)];
191     }
192 
193     /**
194      * Returns the amount of plugged Joysticks
195      */
196     @nogc
197     static int count() nothrow {
198         return SDL_NumJoysticks();
199     }
200 }