22 #if defined(_DEBUG) && defined(_WINDOWS)
23 #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
31 template class Singleton<Controllers>;
33 Controllers * Controllers::create() {
34 return new Controllers;
37 Singleton<Controllers>::Uninit Controllers::g_uninit;
38 Singleton<Controllers>::Reinit Controllers::g_reinit;
40 Controllers::Controllers() {
49 cr.lend_pre_uninit(&g_uninit);
50 cr.lend_post_reinit(&g_reinit);
53 Controllers::~Controllers() {
64 return m_joysticks.size();
68 for(
size_t i = 0, iend = m_joysticks.size();
i != iend; ++
i) {
69 if(m_joysticks[
i] && m_joysticks[
i]->joystick_id ==
id)
77 assert(index >= 0 &&
Uint32(index) < m_joysticks.size());
82 if(m_joysticks[index]->gamecontroller)
107 Joystick_Info * info =
new Joystick_Info;
108 info->joystick = joystick;
111 for(Joystick_Array::iterator it = m_joysticks.begin(), iend = m_joysticks.end(); ; ++it) {
119 m_joysticks.push_back(info);
129 if(info->gamecontroller) {
131 std::cerr <<
"Loaded game controller " << info->joystick_id <<
": " << mapping << std::endl;
135 std::cerr <<
"Failed to load game controller (" << szGUID <<
"): " <<
SDL_GetError() << std::endl;
145 std::cerr <<
"Failed to run effect on joystick (" << szGUID <<
")." << std::endl;
151 std::cerr <<
"Joystick (" << szGUID <<
") not recognized as haptic." << std::endl;
157 for(Joystick_Array::iterator it = m_joysticks.begin(), iend = m_joysticks.end(); it != iend; ++it) {
158 if(*it && (*it)->joystick_id ==
id) {
167 for(Joystick_Array::reverse_iterator it = m_joysticks.rbegin(), iend = m_joysticks.rend(); it != iend; ++it) {
188 void Controllers::device_add_all() {
194 if(index < m_joysticks.size() && m_joysticks[
index]) {
195 m_joysticks[
index]->haptic_effect.leftright.large_magnitude =
Uint16(left * 0xFFFF);
196 m_joysticks[
index]->haptic_effect.leftright.small_magnitude =
Uint16(right * 0xFFFF);
197 if(m_joysticks[index]->haptic_effect_id > -1) {
205 for(
int i = 0, iend = m_joysticks.size();
i != iend; ++
i)
209 Controllers::Joystick_Info::Joystick_Info()
220 Controllers::Joystick_Info::~Joystick_Info() {
223 if(haptic_effect_id > -1)
234 void Controllers::init() {
237 throw Controllers_Init_Failure();
240 const String user_normal = appdata_path +
"config/zenilib.xml";
241 const String local_normal =
"config/zenilib.xml";
244 if(file.try_load(local_normal)) {
245 XML_Element_c zenilib = file[
"Zenilib"];
246 XML_Element_c joysticks = zenilib[
"Controllers"];
247 if(joysticks.good()) {
248 for(XML_Element_c joystick = joysticks.first(); joystick.good(); joystick = joystick.next()) {
249 if(joystick.value() ==
"GameController") {
251 std::cerr <<
"Joystick mapping " << joystick.to_string().c_str() <<
" failed." << std::endl;
253 std::cerr <<
"Added/Updating joystick mapping: " << joystick.to_string().c_str() << std::endl;
259 if(file.try_load(user_normal)) {
260 XML_Element_c zenilib = file[
"Zenilib"];
261 XML_Element_c joysticks = zenilib[
"Controllers"];
262 if(joysticks.good()) {
263 for(XML_Element_c joystick = joysticks.first(); joystick.good(); joystick = joystick.next()) {
264 if(joystick.value() ==
"GameController") {
266 std::cerr <<
"Joystick mapping " << joystick.to_string().c_str() <<
" failed." << std::endl;
268 std::cerr <<
"Added/Updating joystick mapping: " << joystick.to_string().c_str() << std::endl;
281 void Controllers::uninit() {
286 for(Joystick_Array::iterator it = m_joysticks.begin(), iend = m_joysticks.end(); it != iend; ++it)
297 Controllers::XInputEnable_fcn Controllers::g_XInputEnable = 0;
298 Controllers::XInputGetCapabilities_fcn Controllers::g_XInputGetCapabilities = 0;
299 Controllers::XInputGetState_fcn Controllers::g_XInputGetState = 0;
300 Controllers::XInputSetState_fcn Controllers::g_XInputSetState = 0;
DECLSPEC void SDLCALL SDL_GameControllerClose(SDL_GameController *gamecontroller)
Controllers & get_Controllers()
Get access to the singleton.
static void assert_no_error()
If there is an SDL error, print it and assert(false)
int32_t Sint32
A signed 32-bit integer type.
DECLSPEC int SDLCALL SDL_HapticUpdateEffect(SDL_Haptic *haptic, int effect, SDL_HapticEffect *data)
Updates the properties of an effect.
bool is_controller_connected(const Sint32 &index) const
Check to see if the controller is currently connected.
DECLSPEC SDL_JoystickID SDLCALL SDL_JoystickInstanceID(SDL_Joystick *joystick)
#define SDL_INIT_JOYSTICK
DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAttached(SDL_Joystick *joystick)
DECLSPEC void SDLCALL SDL_JoystickClose(SDL_Joystick *joystick)
DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerOpen(int joystick_index)
void reset_vibration_all()
Set vibration for all controllers to <0,0>
void detect_removed()
Fix to broken SDL device removal detection.
DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpenFromJoystick(SDL_Joystick *joystick)
Opens a Haptic device for usage from a Joystick device.
DECLSPEC void SDLCALL SDL_free(void *mem)
DECLSPEC void SDLCALL SDL_HapticClose(SDL_Haptic *haptic)
Closes a Haptic device previously opened with SDL_HapticOpen().
void enable(const bool &enable_)
Temporarily turn controller input on/off.
DECLSPEC int SDLCALL SDL_GameControllerEventState(int state)
void device_added(const Sint32 &index)
Register a new device.
DECLSPEC const char *SDLCALL SDL_GetError(void)
static void remove_post_reinit(Event::Handler *const &handler)
DECLSPEC SDL_bool SDLCALL SDL_IsGameController(int joystick_index)
#define SDL_HAPTIC_INFINITY
Used to play a device an infinite number of times.
void reinit()
Reload all joysticks, flushing all SDL events and possibly changing 'which' values for controllers...
uint32_t Uint32
An unsigned 32-bit integer type.
DECLSPEC int SDLCALL SDL_JoystickIsHaptic(SDL_Joystick *joystick)
Checks to see if a joystick has haptic features.
DECLSPEC int SDLCALL SDL_HapticEffectSupported(SDL_Haptic *haptic, SDL_HapticEffect *effect)
Checks to see if effect is supported by haptic.
static void remove_pre_uninit(Event::Handler *const &handler)
Sint32 get_controller_index(const Sint32 &id) const
Get the index of a given controller from the true SDL_JoystickInstanceID.
DECLSPEC int SDLCALL SDL_HapticNewEffect(SDL_Haptic *haptic, SDL_HapticEffect *effect)
Creates a new haptic effect on the device.
const char * get_controller_name(const Sint32 &index) const
Get the name of a given controller.
DECLSPEC int SDLCALL SDL_InitSubSystem(Uint32 flags)
static Controllers & get()
#define SDL_INIT_GAMECONTROLLER
DECLSPEC char *SDLCALL SDL_GameControllerMapping(SDL_GameController *gamecontroller)
size_t get_num_controllers() const
Get the number of controllers attached to the system.
The Controllers Singleton.
DECLSPEC int SDLCALL SDL_JoystickEventState(int state)
DECLSPEC void SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID)
String get_appdata_path()
Get the path that should be used for user-modifiable storage.
void set_vibration(const size_t &index, const float &left, const float &right)
Set vibration for controller [0,...] to <[0,1],[0,1]>
DECLSPEC const char *SDLCALL SDL_JoystickName(SDL_Joystick *joystick)
DECLSPEC void SDLCALL SDL_ClearError(void)
DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetGUID(SDL_Joystick *joystick)
DECLSPEC SDL_bool SDLCALL SDL_GameControllerGetAttached(SDL_GameController *gamecontroller)
Core & get_Core()
Get access to the singleton.
DECLSPEC void SDLCALL SDL_HapticDestroyEffect(SDL_Haptic *haptic, int effect)
Destroys a haptic effect on the device.
DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickOpen(int device_index)
GLenum GLenum GLenum GLenum mapping
DECLSPEC int SDLCALL SDL_HapticRunEffect(SDL_Haptic *haptic, int effect, Uint32 iterations)
Runs the haptic effect on its associated haptic device.
DECLSPEC int SDLCALL SDL_GameControllerAddMapping(const char *mappingString)
uint16_t Uint16
An unsigned 16-bit integer type.
File_Ops & get_File_Ops()
Get access to the singleton.
#define SDL_HAPTIC_LEFTRIGHT
Left/Right effect supported.
void device_removed(const Sint32 &id)
Remove a device.
DECLSPEC void SDLCALL SDL_QuitSubSystem(Uint32 flags)
DECLSPEC int SDLCALL SDL_NumJoysticks(void)