1010#include < SDL/SDL.h>
1111#include < cstring>
1212
13- bool KeyboardState::GetKeyValue (int keyCode) const
13+ bool KeyboardState::GetKeyValue (SDL_Scancode keyCode) const
1414{
1515 return mCurrState [keyCode] == 1 ;
1616}
1717
18- ButtonState KeyboardState::GetKeyState (int keyCode) const
18+ ButtonState KeyboardState::GetKeyState (SDL_Scancode keyCode) const
1919{
2020 if (mPrevState [keyCode] == 0 )
2121 {
@@ -73,6 +73,37 @@ ButtonState MouseState::GetButtonState(int button) const
7373 }
7474}
7575
76+ bool ControllerState::GetButtonValue (SDL_GameControllerButton button) const
77+ {
78+ return mCurrButtons [button] == 1 ;
79+ }
80+
81+ ButtonState ControllerState::GetButtonState (SDL_GameControllerButton button) const
82+ {
83+ if (mPrevButtons [button] == 0 )
84+ {
85+ if (mCurrButtons [button] == 0 )
86+ {
87+ return ENone;
88+ }
89+ else
90+ {
91+ return EPressed;
92+ }
93+ }
94+ else // Prev state must be 1
95+ {
96+ if (mCurrButtons [button] == 0 )
97+ {
98+ return EReleased;
99+ }
100+ else
101+ {
102+ return EHeld;
103+ }
104+ }
105+ }
106+
76107bool InputSystem::Initialize ()
77108{
78109 // Keyboard
@@ -85,6 +116,16 @@ bool InputSystem::Initialize()
85116 // Mouse (just set everything to 0)
86117 mState .Mouse .mCurrButtons = 0 ;
87118 mState .Mouse .mPrevButtons = 0 ;
119+
120+ // Get the connected controller, if it exists
121+ mController = SDL_GameControllerOpen (0 );
122+ // Initialize controller state
123+ mState .Controller .mIsConnected = (mController != nullptr );
124+ memset (mState .Controller .mCurrButtons , 0 ,
125+ SDL_CONTROLLER_BUTTON_MAX );
126+ memset (mState .Controller .mPrevButtons , 0 ,
127+ SDL_CONTROLLER_BUTTON_MAX );
128+
88129 return true ;
89130}
90131
@@ -104,6 +145,11 @@ void InputSystem::PrepareForUpdate()
104145 mState .Mouse .mPrevButtons = mState .Mouse .mCurrButtons ;
105146 mState .Mouse .mIsRelative = false ;
106147 mState .Mouse .mScrollWheel = Vector2::Zero;
148+
149+ // Controller
150+ memcpy (mState .Controller .mPrevButtons ,
151+ mState .Controller .mCurrButtons ,
152+ SDL_CONTROLLER_BUTTON_MAX );
107153}
108154
109155void InputSystem::Update ()
@@ -123,6 +169,36 @@ void InputSystem::Update()
123169
124170 mState .Mouse .mMousePos .x = static_cast <float >(x);
125171 mState .Mouse .mMousePos .y = static_cast <float >(y);
172+
173+ // Controller
174+ // Buttons
175+ for (int i = 0 ; i < SDL_CONTROLLER_BUTTON_MAX ; i++)
176+ {
177+ mState .Controller .mCurrButtons [i] =
178+ SDL_GameControllerGetButton (mController ,
179+ SDL_GameControllerButton (i));
180+ }
181+
182+ // Triggers
183+ mState .Controller .mLeftTrigger =
184+ Filter1D (SDL_GameControllerGetAxis (mController ,
185+ SDL_CONTROLLER_AXIS_TRIGGERLEFT ));
186+ mState .Controller .mRightTrigger =
187+ Filter1D (SDL_GameControllerGetAxis (mController ,
188+ SDL_CONTROLLER_AXIS_TRIGGERRIGHT ));
189+
190+ // Sticks
191+ x = SDL_GameControllerGetAxis (mController ,
192+ SDL_CONTROLLER_AXIS_LEFTX );
193+ y = -SDL_GameControllerGetAxis (mController ,
194+ SDL_CONTROLLER_AXIS_LEFTY );
195+ mState .Controller .mLeftStick = Filter2D (x, y);
196+
197+ x = SDL_GameControllerGetAxis (mController ,
198+ SDL_CONTROLLER_AXIS_RIGHTX );
199+ y = -SDL_GameControllerGetAxis (mController ,
200+ SDL_CONTROLLER_AXIS_RIGHTY );
201+ mState .Controller .mRightStick = Filter2D (x, y);
126202}
127203
128204void InputSystem::ProcessEvent (SDL_Event& event)
@@ -146,3 +222,61 @@ void InputSystem::SetRelativeMouseMode(bool value)
146222
147223 mState .Mouse .mIsRelative = value;
148224}
225+
226+ float InputSystem::Filter1D (int input)
227+ {
228+ // A value < dead zone is interpreted as 0%
229+ const int deadZone = 250 ;
230+ // A value > max value is interpreted as 100%
231+ const int maxValue = 30000 ;
232+
233+ float retVal = 0 .0f ;
234+
235+ // Take absolute value of input
236+ int absValue = input > 0 ? input : -input;
237+ // Ignore input within dead zone
238+ if (absValue > deadZone)
239+ {
240+ // Compute fractional value between dead zone and max value
241+ retVal = static_cast <float >(absValue - deadZone) /
242+ (maxValue - deadZone);
243+ // Make sure sign matches original value
244+ retVal = input > 0 ? retVal : -1 .0f * retVal;
245+ // Clamp between -1.0f and 1.0f
246+ retVal = Math::Clamp (retVal, -1 .0f , 1 .0f );
247+ }
248+
249+ return retVal;
250+ }
251+
252+ Vector2 InputSystem::Filter2D (int inputX, int inputY)
253+ {
254+ const float deadZone = 8000 .0f ;
255+ const float maxValue = 30000 .0f ;
256+
257+ // Make into 2D vector
258+ Vector2 dir;
259+ dir.x = static_cast <float >(inputX);
260+ dir.y = static_cast <float >(inputY);
261+
262+ float length = dir.Length ();
263+
264+ // If length < deadZone, should be no input
265+ if (length < deadZone)
266+ {
267+ dir = Vector2::Zero;
268+ }
269+ else
270+ {
271+ // Calculate fractional value between
272+ // dead zone and max value circles
273+ float f = (length - deadZone) / (maxValue - deadZone);
274+ // Clamp f between 0.0f and 1.0f
275+ f = Math::Clamp (f, 0 .0f , 1 .0f );
276+ // Normalize the vector, and then scale it to the
277+ // fractional value
278+ dir *= f / length;
279+ }
280+
281+ return dir;
282+ }
0 commit comments