1 module prova.input.input;
2 
3 import core.stdc..string,
4        derelict.sdl2.sdl,
5        prova.core,
6        prova.input,
7        prova.math;
8 
9 ///
10 class Input
11 {
12   private Game game;
13   private Vector2 mousePosition;
14   private Controller[int] controllers;
15   private bool[] keystate;
16   private bool[] oldKeystate;
17   private bool[] buttonState;
18   private bool[] oldButtonState;
19 
20   package(prova) this(Game game)
21   {
22     this.game = game;
23 
24     update();
25     oldKeystate = keystate;
26     oldButtonState = buttonState;
27   }
28 
29   package(prova) void update()
30   {
31     // update controller state
32     foreach(Controller controller; controllers)
33       controller.update();
34 
35     // update keystate
36     oldKeystate = keystate;
37     updateKeystate();
38 
39     // update mouse state
40     int x, y;
41     uint mouseState = SDL_GetMouseState(&x, &y);
42 
43     // update button state
44     oldButtonState = buttonState;
45     updateButtonState(mouseState);
46 
47     mousePosition.x = -1f + x / (game.screen.width * .5f);
48     mousePosition.y = 1f - y / (game.screen.height * .5f);
49   }
50 
51   private void updateKeystate()
52   {
53     int keystateLength;
54     const ubyte* SDLKeystate = SDL_GetKeyboardState(&keystateLength);
55 
56     keystate = [];
57     keystate.length = keystateLength;
58 
59     (cast(ubyte*)keystate)[0 .. keystateLength][] = SDLKeystate[0 .. keystateLength];
60   }
61 
62   private void updateButtonState(uint mouseState)
63   {
64     buttonState = [];
65     buttonState.length = 5;
66 
67     foreach(i; 0 .. 5) {
68       ubyte button = SDL_BUTTON(cast(ubyte) (i + 1));
69       buttonState[i] = cast(bool) (mouseState & button);
70     }
71   }
72 
73   /// 
74   Controller getController(int index)
75   {
76     // controller not found then add it to our list
77     // of updated controllers
78     if(!(index in controllers))
79       controllers[index] = new Controller(index);
80 
81     return controllers[index];
82   }
83 
84   /// Uses the WASD format, returns a normalized vector
85   Vector2 simulateStick(Key up, Key left, Key down, Key right)
86   {
87     Vector2 vector = Vector2(
88       isKeyDown(right) - isKeyDown(left),
89       isKeyDown(up) - isKeyDown(down)
90     );
91 
92     return vector.getNormalized();
93   }
94 
95   ///
96   bool isKeyDown(Key key)
97   {
98     return keystate[cast(int) key];
99   }
100 
101   ///
102   bool isKeyUp(Key key)
103   {
104     return !keystate[cast(int) key];
105   }
106 
107   /// Returns true if the key is pressed and was not pressed in the last tick
108   bool keyJustPressed(Key key)
109   {
110     return !oldKeystate[cast(int) key] && keystate[cast(int) key];
111   }
112 
113   ///
114   bool isMouseButtonDown(MouseButton button)
115   {
116     return buttonState[button];
117   }
118 
119   ///
120   bool isMouseButtonUp(MouseButton button)
121   {
122     return !buttonState[button];
123   }
124 
125   ///
126   bool mouseButtonClicked(MouseButton button)
127   {
128     return oldButtonState[button] && !buttonState[button];
129   }
130 
131   ///
132   Vector2 getMousePosition()
133   {
134     return mousePosition;
135   }
136 }