|
|
@@ -10,12 +10,12 @@
|
|
|
#include <SDL/SDL.h>
|
|
|
#include <cstring>
|
|
|
|
|
|
-bool KeyboardState::GetKeyValue(int keyCode) const
|
|
|
+bool KeyboardState::GetKeyValue(SDL_Scancode keyCode) const
|
|
|
{
|
|
|
return mCurrState[keyCode] == 1;
|
|
|
}
|
|
|
|
|
|
-ButtonState KeyboardState::GetKeyState(int keyCode) const
|
|
|
+ButtonState KeyboardState::GetKeyState(SDL_Scancode keyCode) const
|
|
|
{
|
|
|
if (mPrevState[keyCode] == 0)
|
|
|
{
|
|
|
@@ -73,6 +73,37 @@ ButtonState MouseState::GetButtonState(int button) const
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+bool ControllerState::GetButtonValue(SDL_GameControllerButton button) const
|
|
|
+{
|
|
|
+ return mCurrButtons[button] == 1;
|
|
|
+}
|
|
|
+
|
|
|
+ButtonState ControllerState::GetButtonState(SDL_GameControllerButton button) const
|
|
|
+{
|
|
|
+ if (mPrevButtons[button] == 0)
|
|
|
+ {
|
|
|
+ if (mCurrButtons[button] == 0)
|
|
|
+ {
|
|
|
+ return ENone;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return EPressed;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else // Prev state must be 1
|
|
|
+ {
|
|
|
+ if (mCurrButtons[button] == 0)
|
|
|
+ {
|
|
|
+ return EReleased;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return EHeld;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
bool InputSystem::Initialize()
|
|
|
{
|
|
|
// Keyboard
|
|
|
@@ -85,6 +116,16 @@ bool InputSystem::Initialize()
|
|
|
// Mouse (just set everything to 0)
|
|
|
mState.Mouse.mCurrButtons = 0;
|
|
|
mState.Mouse.mPrevButtons = 0;
|
|
|
+
|
|
|
+ // Get the connected controller, if it exists
|
|
|
+ mController = SDL_GameControllerOpen(0);
|
|
|
+ // Initialize controller state
|
|
|
+ mState.Controller.mIsConnected = (mController != nullptr);
|
|
|
+ memset(mState.Controller.mCurrButtons, 0,
|
|
|
+ SDL_CONTROLLER_BUTTON_MAX);
|
|
|
+ memset(mState.Controller.mPrevButtons, 0,
|
|
|
+ SDL_CONTROLLER_BUTTON_MAX);
|
|
|
+
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
@@ -104,6 +145,11 @@ void InputSystem::PrepareForUpdate()
|
|
|
mState.Mouse.mPrevButtons = mState.Mouse.mCurrButtons;
|
|
|
mState.Mouse.mIsRelative = false;
|
|
|
mState.Mouse.mScrollWheel = Vector2::Zero;
|
|
|
+
|
|
|
+ // Controller
|
|
|
+ memcpy(mState.Controller.mPrevButtons,
|
|
|
+ mState.Controller.mCurrButtons,
|
|
|
+ SDL_CONTROLLER_BUTTON_MAX);
|
|
|
}
|
|
|
|
|
|
void InputSystem::Update()
|
|
|
@@ -123,6 +169,36 @@ void InputSystem::Update()
|
|
|
|
|
|
mState.Mouse.mMousePos.x = static_cast<float>(x);
|
|
|
mState.Mouse.mMousePos.y = static_cast<float>(y);
|
|
|
+
|
|
|
+ // Controller
|
|
|
+ // Buttons
|
|
|
+ for (int i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++)
|
|
|
+ {
|
|
|
+ mState.Controller.mCurrButtons[i] =
|
|
|
+ SDL_GameControllerGetButton(mController,
|
|
|
+ SDL_GameControllerButton(i));
|
|
|
+ }
|
|
|
+
|
|
|
+ // Triggers
|
|
|
+ mState.Controller.mLeftTrigger =
|
|
|
+ Filter1D(SDL_GameControllerGetAxis(mController,
|
|
|
+ SDL_CONTROLLER_AXIS_TRIGGERLEFT));
|
|
|
+ mState.Controller.mRightTrigger =
|
|
|
+ Filter1D(SDL_GameControllerGetAxis(mController,
|
|
|
+ SDL_CONTROLLER_AXIS_TRIGGERRIGHT));
|
|
|
+
|
|
|
+ // Sticks
|
|
|
+ x = SDL_GameControllerGetAxis(mController,
|
|
|
+ SDL_CONTROLLER_AXIS_LEFTX);
|
|
|
+ y = -SDL_GameControllerGetAxis(mController,
|
|
|
+ SDL_CONTROLLER_AXIS_LEFTY);
|
|
|
+ mState.Controller.mLeftStick = Filter2D(x, y);
|
|
|
+
|
|
|
+ x = SDL_GameControllerGetAxis(mController,
|
|
|
+ SDL_CONTROLLER_AXIS_RIGHTX);
|
|
|
+ y = -SDL_GameControllerGetAxis(mController,
|
|
|
+ SDL_CONTROLLER_AXIS_RIGHTY);
|
|
|
+ mState.Controller.mRightStick = Filter2D(x, y);
|
|
|
}
|
|
|
|
|
|
void InputSystem::ProcessEvent(SDL_Event& event)
|
|
|
@@ -146,3 +222,61 @@ void InputSystem::SetRelativeMouseMode(bool value)
|
|
|
|
|
|
mState.Mouse.mIsRelative = value;
|
|
|
}
|
|
|
+
|
|
|
+float InputSystem::Filter1D(int input)
|
|
|
+{
|
|
|
+ // A value < dead zone is interpreted as 0%
|
|
|
+ const int deadZone = 250;
|
|
|
+ // A value > max value is interpreted as 100%
|
|
|
+ const int maxValue = 30000;
|
|
|
+
|
|
|
+ float retVal = 0.0f;
|
|
|
+
|
|
|
+ // Take absolute value of input
|
|
|
+ int absValue = input > 0 ? input : -input;
|
|
|
+ // Ignore input within dead zone
|
|
|
+ if (absValue > deadZone)
|
|
|
+ {
|
|
|
+ // Compute fractional value between dead zone and max value
|
|
|
+ retVal = static_cast<float>(absValue - deadZone) /
|
|
|
+ (maxValue - deadZone);
|
|
|
+ // Make sure sign matches original value
|
|
|
+ retVal = input > 0 ? retVal : -1.0f * retVal;
|
|
|
+ // Clamp between -1.0f and 1.0f
|
|
|
+ retVal = Math::Clamp(retVal, -1.0f, 1.0f);
|
|
|
+ }
|
|
|
+
|
|
|
+ return retVal;
|
|
|
+}
|
|
|
+
|
|
|
+Vector2 InputSystem::Filter2D(int inputX, int inputY)
|
|
|
+{
|
|
|
+ const float deadZone = 8000.0f;
|
|
|
+ const float maxValue = 30000.0f;
|
|
|
+
|
|
|
+ // Make into 2D vector
|
|
|
+ Vector2 dir;
|
|
|
+ dir.x = static_cast<float>(inputX);
|
|
|
+ dir.y = static_cast<float>(inputY);
|
|
|
+
|
|
|
+ float length = dir.Length();
|
|
|
+
|
|
|
+ // If length < deadZone, should be no input
|
|
|
+ if (length < deadZone)
|
|
|
+ {
|
|
|
+ dir = Vector2::Zero;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // Calculate fractional value between
|
|
|
+ // dead zone and max value circles
|
|
|
+ float f = (length - deadZone) / (maxValue - deadZone);
|
|
|
+ // Clamp f between 0.0f and 1.0f
|
|
|
+ f = Math::Clamp(f, 0.0f, 1.0f);
|
|
|
+ // Normalize the vector, and then scale it to the
|
|
|
+ // fractional value
|
|
|
+ dir *= f / length;
|
|
|
+ }
|
|
|
+
|
|
|
+ return dir;
|
|
|
+}
|