1 /*************************************************************************** 2 * Copyright (C) 2005-2019 by the FIFE team * 3 * http://www.fifengine.net * 4 * This file is part of FIFE. * 5 * * 6 * FIFE is free software; you can redistribute it and/or * 7 * modify it under the terms of the GNU Lesser General Public * 8 * License as published by the Free Software Foundation; either * 9 * version 2.1 of the License, or (at your option) any later version. * 10 * * 11 * This library is distributed in the hope that it will be useful, * 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 14 * Lesser General Public License for more details. * 15 * * 16 * You should have received a copy of the GNU Lesser General Public * 17 * License along with this library; if not, write to the * 18 * Free Software Foundation, Inc., * 19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * 20 ***************************************************************************/ 21 22 // Standard C++ library includes 23 #include <iostream> 24 25 // 3rd party library includes 26 #include <SDL.h> 27 28 // FIFE includes 29 // These includes are split up in two parts, separated by one empty line 30 // First block: files included from the FIFE root src directory 31 // Second block: files included from the same folder 32 #include "util/base/exception.h" 33 #include "util/log/logger.h" 34 #include "util/math/fife_math.h" 35 36 #include "joystick.h" 37 38 namespace FIFE { 39 static Logger _log(LM_EVTCHANNEL); 40 Joystick(int32_t joystickId,int32_t deviceIndex)41 Joystick::Joystick(int32_t joystickId, int32_t deviceIndex): 42 m_joystickHandle(NULL), 43 m_controllerHandle(NULL), 44 m_instanceId(-1), 45 m_joystickId(joystickId), 46 m_deviceIndex(deviceIndex), 47 m_guidStr(""), 48 m_name("") { 49 50 } 51 ~Joystick()52 Joystick::~Joystick() { 53 close(); 54 } 55 getInstanceId() const56 int32_t Joystick::getInstanceId() const { 57 return static_cast<int32_t>(m_instanceId); 58 } 59 getJoystickId() const60 int32_t Joystick::getJoystickId() const { 61 return m_joystickId; 62 } 63 setDeviceIndex(int32_t deviceIndex)64 void Joystick::setDeviceIndex(int32_t deviceIndex) { 65 m_deviceIndex = deviceIndex; 66 } 67 getDeviceIndex() const68 int32_t Joystick::getDeviceIndex() const { 69 return m_deviceIndex; 70 } 71 getGuid()72 const std::string& Joystick::getGuid() { 73 return m_guidStr; 74 } 75 getName()76 const std::string& Joystick::getName() { 77 return m_name; 78 } 79 open()80 void Joystick::open() { 81 if (m_joystickHandle) { 82 close(); 83 } 84 85 m_joystickHandle = SDL_JoystickOpen(m_deviceIndex); 86 if (m_joystickHandle) { 87 m_instanceId = SDL_JoystickInstanceID(m_joystickHandle); 88 89 char tmp[33]; 90 SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(m_deviceIndex); 91 SDL_JoystickGetGUIDString(guid, tmp, sizeof(tmp)); 92 m_guidStr = std::string(tmp); 93 94 openController(); 95 const char* name = SDL_JoystickNameForIndex(m_deviceIndex); 96 if (isController() && !name) { 97 name = SDL_GameControllerNameForIndex(m_deviceIndex); 98 } 99 m_name = std::string(name); 100 } else { 101 throw SDLException(SDL_GetError()); 102 } 103 } 104 close()105 void Joystick::close() { 106 closeController(); 107 if (m_joystickHandle) { 108 SDL_JoystickClose(m_joystickHandle); 109 m_joystickHandle = NULL; 110 } 111 m_instanceId = -1; 112 m_deviceIndex = -1; 113 } 114 isConnected() const115 bool Joystick::isConnected() const { 116 return m_joystickHandle && SDL_JoystickGetAttached(m_joystickHandle); 117 } 118 isController() const119 bool Joystick::isController() const { 120 return m_controllerHandle != NULL; 121 } 122 openController()123 void Joystick::openController() { 124 closeController(); 125 if (!SDL_IsGameController(m_deviceIndex)) { 126 return; 127 } 128 129 m_controllerHandle = SDL_GameControllerOpen(m_deviceIndex); 130 } 131 closeController()132 void Joystick::closeController() { 133 if (m_controllerHandle) { 134 SDL_GameControllerClose(m_controllerHandle); 135 m_controllerHandle = NULL; 136 } 137 } 138 getNumberOfAxes() const139 uint8_t Joystick::getNumberOfAxes() const { 140 uint8_t number = 0; 141 if (isConnected()) { 142 number = SDL_JoystickNumAxes(m_joystickHandle); 143 } 144 return number; 145 } 146 getNumberOfButtons() const147 uint8_t Joystick::getNumberOfButtons() const { 148 uint8_t number = 0; 149 if (isConnected()) { 150 number = SDL_JoystickNumButtons(m_joystickHandle); 151 } 152 return number; 153 } 154 getNumberOfHats() const155 uint8_t Joystick::getNumberOfHats() const { 156 uint8_t number = 0; 157 if (isConnected()) { 158 number = SDL_JoystickNumHats(m_joystickHandle); 159 } 160 return number; 161 } 162 getAxisValue(int8_t axis) const163 float Joystick::getAxisValue(int8_t axis) const { 164 if (axis < 0 || !isConnected()) { 165 return 0; 166 } 167 168 if (!isController()) { 169 return convertRange(SDL_JoystickGetAxis(m_joystickHandle, axis)); 170 } 171 172 SDL_GameControllerAxis sdlAxis = static_cast<SDL_GameControllerAxis>(axis); 173 return convertRange(SDL_GameControllerGetAxis(m_controllerHandle, sdlAxis)); 174 } 175 getHatValue(int8_t hat) const176 int8_t Joystick::getHatValue(int8_t hat) const { 177 if (hat < 0 || !isConnected()) { 178 return HAT_INVALID; 179 } 180 return SDL_JoystickGetHat(m_joystickHandle, hat); 181 } 182 isButtonPressed(int8_t button) const183 bool Joystick::isButtonPressed(int8_t button) const { 184 if (button < 0 || !isConnected()) { 185 return false; 186 } 187 if (!isController()) { 188 if (SDL_JoystickGetButton(m_joystickHandle, button) == 1) { 189 return true; 190 } 191 return false; 192 } 193 194 SDL_GameControllerButton sdlButton = static_cast<SDL_GameControllerButton>(button); 195 if (SDL_GameControllerGetButton(m_controllerHandle, sdlButton) == 1) { 196 return true; 197 } 198 return false; 199 } 200 convertRange(int16_t value) const201 float Joystick::convertRange(int16_t value) const { 202 float range = static_cast<float>(value) / 32768.0f; 203 if (Mathf::FAbs(range) < 0.01f) { 204 return 0.0f; 205 } 206 if (range < -0.99f) { 207 return -1.0f; 208 } else if (range > 0.99f) { 209 return 1.0f; 210 } 211 return range; 212 } 213 } 214