zenilib: zenilib/jni/external/zenilib/zeni_core/Controllers.cpp Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Controllers.cpp
Go to the documentation of this file.
1 /* This file is part of the Zenipex Library (zenilib).
2 * Copyright (C) 2011 Mitchell Keith Bloch (bazald).
3 *
4 * zenilib is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * zenilib is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with zenilib. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <zeni_core.h>
19
20 #include <cassert>
21
22 #if defined(_DEBUG) && defined(_WINDOWS)
23 #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
24 #define new DEBUG_NEW
25 #endif
26
27 #include <Zeni/Singleton.hxx>
28
29 namespace Zeni {
30
31 template class Singleton<Controllers>;
32
33 Controllers * Controllers::create() {
34 return new Controllers;
35 }
36
37 Singleton<Controllers>::Uninit Controllers::g_uninit;
38 Singleton<Controllers>::Reinit Controllers::g_reinit;
39
40 Controllers::Controllers() {
41 Core::remove_post_reinit(&g_reinit);
42
44 Core &cr = get_Core();
45
47 init();
48
49 cr.lend_pre_uninit(&g_uninit);
50 cr.lend_post_reinit(&g_reinit);
51 }
52
53 Controllers::~Controllers() {
54 Core::remove_pre_uninit(&g_uninit);
55
56 uninit();
57 }
58
59 Controllers & get_Controllers() {
60 return Controllers::get();
61 }
62
63 size_t Controllers::get_num_controllers() const {
64 return m_joysticks.size();
65 }
66
67 Sint32 Controllers::get_controller_index(const Sint32 &id) const {
68 for(size_t i = 0, iend = m_joysticks.size(); i != iend; ++i) {
69 if(m_joysticks[i] && m_joysticks[i]->joystick_id == id)
70 return Sint32(i);
71 }
72
73 return -1;
74 }
75
76 const char * Controllers::get_controller_name(const Sint32 &index) const {
77 assert(index >= 0 && Uint32(index) < m_joysticks.size());
78 return SDL_JoystickName(m_joysticks[index]->joystick);
79 }
80
81 bool Controllers::is_controller_connected(const Sint32 &index) const {
82 if(m_joysticks[index]->gamecontroller)
83 return SDL_GameControllerGetAttached(m_joysticks[index]->gamecontroller) == SDL_TRUE;
84 return false;
85 }
86
87 void Controllers::reinit() {
88 uninit();
89 init();
90 }
91
92 void Controllers::enable(const bool &
93 #ifndef ANDROID
94 enable_
95 #endif
96 ) {
97 #ifndef ANDROID
98 SDL_GameControllerEventState(enable_ ? SDL_ENABLE : SDL_DISABLE);
99 #endif
100 }
101
102 void Controllers::device_added(const Sint32 &index) {
103 SDL_Joystick * const joystick = SDL_JoystickOpen(index);
104 if(!joystick)
105 return;
106
107 Joystick_Info * info = new Joystick_Info;
108 info->joystick = joystick;
109 info->joystick_id = SDL_JoystickInstanceID(joystick);
110
111 for(Joystick_Array::iterator it = m_joysticks.begin(), iend = m_joysticks.end(); ; ++it) {
112 if(it != iend) {
113 if(!*it) {
114 *it = info;
115 break;
116 }
117 }
118 else {
119 m_joysticks.push_back(info);
120 break;
121 }
122 }
123
124 char szGUID[33];
125 SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(info->joystick), szGUID, sizeof(szGUID));
126
127 if(SDL_IsGameController(index))
128 info->gamecontroller = SDL_GameControllerOpen(index);
129 if(info->gamecontroller) {
130 char * mapping = SDL_GameControllerMapping(info->gamecontroller);
131 std::cerr << "Loaded game controller " << info->joystick_id << ": " << mapping << std::endl;
132 SDL_free(mapping);
133 }
134 else {
135 std::cerr << "Failed to load game controller (" << szGUID << "): " << SDL_GetError() << std::endl;
136 SDL_ClearError();
137 }
138
139 if(SDL_JoystickIsHaptic(info->joystick) == 1)
140 info->haptic = SDL_HapticOpenFromJoystick(info->joystick);
141 if(info->haptic) {
142 if(SDL_HapticEffectSupported(info->haptic, &info->haptic_effect) == SDL_TRUE) {
143 info->haptic_effect_id = SDL_HapticNewEffect(info->haptic, &info->haptic_effect);
144 if(SDL_HapticRunEffect(info->haptic, info->haptic_effect_id, 1) == -1) {
145 std::cerr << "Failed to run effect on joystick (" << szGUID << ")." << std::endl;
146 SDL_ClearError();
147 }
148 }
149 }
150 else {
151 std::cerr << "Joystick (" << szGUID << ") not recognized as haptic." << std::endl;
152 SDL_ClearError();
153 }
154 }
155
156 void Controllers::device_removed(const Sint32 &id) {
157 for(Joystick_Array::iterator it = m_joysticks.begin(), iend = m_joysticks.end(); it != iend; ++it) {
158 if(*it && (*it)->joystick_id == id) {
159 delete *it;
160 *it = 0;
161 break;
162 }
163 }
164 }
165
166 void Controllers::detect_removed() {
167 for(Joystick_Array::reverse_iterator it = m_joysticks.rbegin(), iend = m_joysticks.rend(); it != iend; ++it) {
168 if(*it && SDL_JoystickGetAttached((*it)->joystick) == SDL_FALSE)
169 device_removed((*it)->joystick_id);
170 }
171
172 //for(int i = SDL_NumJoysticks() - 1; i > -1; --i) {
173 // SDL_Joystick * joystick = SDL_JoystickOpen(i);
174 // Sint32 joystick_id = SDL_JoystickInstanceID(joystick);
175 // SDL_JoystickClose(joystick);
176 // bool found = false;
177 // for(Joystick_Array::reverse_iterator it = m_joysticks.rbegin(), iend = m_joysticks.rend(); it != iend; ++it) {
178 // if((*it) && (*it)->joystick_id == joystick_id) {
179 // found = true;
180 // break;
181 // }
182 // }
183 // if(!found)
184 // device_added(i);
185 //}
186 }
187
188 void Controllers::device_add_all() {
189 for(int i = 0, iend = SDL_NumJoysticks(); i != iend; ++i)
190 device_added(i);
191 }
192
193 void Controllers::set_vibration(const size_t &index, const float &left, const float &right) {
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) {
198 if(SDL_HapticUpdateEffect(m_joysticks[index]->haptic, m_joysticks[index]->haptic_effect_id, &m_joysticks[index]->haptic_effect) == -1)
199 SDL_ClearError();
200 }
201 }
202 }
203
204 void Controllers::reset_vibration_all() {
205 for(int i = 0, iend = m_joysticks.size(); i != iend; ++i)
206 set_vibration(i, 0.0f, 0.0f);
207 }
208
209 Controllers::Joystick_Info::Joystick_Info()
210 : joystick(0),
211 gamecontroller(0),
212 haptic(0),
213 haptic_effect_id(-1)
214 {
215 memset(&haptic_effect, 0, sizeof(haptic_effect));
216 haptic_effect.type = SDL_HAPTIC_LEFTRIGHT;
217 haptic_effect.leftright.length = SDL_HAPTIC_INFINITY;
218 }
219
220 Controllers::Joystick_Info::~Joystick_Info() {
221 get_Core().assert_no_error();
222 if(haptic) {
223 if(haptic_effect_id > -1)
224 SDL_HapticDestroyEffect(haptic, haptic_effect_id);
225 SDL_HapticClose(haptic);
226 SDL_ClearError();
227 }
228 if(gamecontroller)
229 SDL_GameControllerClose(gamecontroller);
230 SDL_JoystickClose(joystick);
231 get_Core().assert_no_error();
232 }
233
234 void Controllers::init() {
235 #ifndef ANDROID
236 if(SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) == -1)
237 throw Controllers_Init_Failure();
238
239 const String appdata_path = get_File_Ops().get_appdata_path();
240 const String user_normal = appdata_path + "config/zenilib.xml";
241 const String local_normal = "config/zenilib.xml";
242 XML_Document file;
243
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") {
250 if(SDL_GameControllerAddMapping(joystick.to_string().c_str()) < 0)
251 std::cerr << "Joystick mapping " << joystick.to_string().c_str() << " failed." << std::endl;
252 else
253 std::cerr << "Added/Updating joystick mapping: " << joystick.to_string().c_str() << std::endl;
254 }
255 }
256 }
257 }
258
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") {
265 if(SDL_GameControllerAddMapping(joystick.to_string().c_str()) < 0)
266 std::cerr << "Joystick mapping " << joystick.to_string().c_str() << " failed." << std::endl;
267 else
268 std::cerr << "Added/Updating joystick mapping: " << joystick.to_string().c_str() << std::endl;
269 }
270 }
271 }
272 }
273
274 device_add_all();
275
276 SDL_JoystickEventState(SDL_ENABLE);
277 SDL_GameControllerEventState(SDL_ENABLE);
278 #endif
279 }
280
281 void Controllers::uninit() {
282 #ifndef ANDROID
283 SDL_GameControllerEventState(SDL_DISABLE);
284 SDL_JoystickEventState(SDL_DISABLE);
285
286 for(Joystick_Array::iterator it = m_joysticks.begin(), iend = m_joysticks.end(); it != iend; ++it)
287 delete *it;
288 m_joysticks.clear();
289
290 SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC);
291
292 get_Core().assert_no_error();
293 #endif
294 }
295
296 #ifdef ENABLE_XINPUT
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;
301 #endif
302
303 }
SDL_GameControllerClose
DECLSPEC void SDLCALL SDL_GameControllerClose(SDL_GameController *gamecontroller)
Definition: SDL_gamecontroller.c:1086
Zeni::get_Controllers
Controllers & get_Controllers()
Get access to the singleton.
Definition: Controllers.cpp:59
Zeni::Core::assert_no_error
static void assert_no_error()
If there is an SDL error, print it and assert(false)
Definition: Core.cpp:122
Sint32
int32_t Sint32
A signed 32-bit integer type.
Definition: SDL_stdinc.h:141
SDL_HapticUpdateEffect
DECLSPEC int SDLCALL SDL_HapticUpdateEffect(SDL_Haptic *haptic, int effect, SDL_HapticEffect *data)
Updates the properties of an effect.
Definition: SDL_haptic.c:511
SDL_INIT_HAPTIC
#define SDL_INIT_HAPTIC
Definition: SDL.h:112
left
GLint left
Definition: glew.h:7291
Zeni::Controllers::is_controller_connected
bool is_controller_connected(const Sint32 &index) const
Check to see if the controller is currently connected.
Definition: Controllers.cpp:81
SDL_JoystickInstanceID
DECLSPEC SDL_JoystickID SDLCALL SDL_JoystickInstanceID(SDL_Joystick *joystick)
Definition: SDL_joystick.c:372
f
GLclampf f
Definition: glew.h:3390
SDL_INIT_JOYSTICK
#define SDL_INIT_JOYSTICK
Definition: SDL.h:111
SDL_JoystickGetAttached
DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAttached(SDL_Joystick *joystick)
Definition: SDL_joystick.c:359
SDL_JoystickClose
DECLSPEC void SDLCALL SDL_JoystickClose(SDL_Joystick *joystick)
Definition: SDL_joystick.c:398
SDL_GameControllerOpen
DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerOpen(int joystick_index)
Definition: SDL_gamecontroller.c:849
Zeni::Controllers::reset_vibration_all
void reset_vibration_all()
Set vibration for all controllers to &lt;0,0&gt;
Definition: Controllers.cpp:204
SDL_TRUE
Definition: SDL_stdinc.h:119
Zeni::Controllers::detect_removed
void detect_removed()
Fix to broken SDL device removal detection.
Definition: Controllers.cpp:166
SDL_HapticOpenFromJoystick
DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpenFromJoystick(SDL_Joystick *joystick)
Opens a Haptic device for usage from a Joystick device.
Definition: SDL_haptic.c:272
SDL_free
DECLSPEC void SDLCALL SDL_free(void *mem)
memset
#define memset
Definition: SDL_malloc.c:633
SDL_ENABLE
#define SDL_ENABLE
Definition: SDL_events.h:688
file
FILE * file
Definition: visualinfo.c:88
SDL_HapticClose
DECLSPEC void SDLCALL SDL_HapticClose(SDL_Haptic *haptic)
Closes a Haptic device previously opened with SDL_HapticOpen().
Definition: SDL_haptic.c:339
Zeni::Controllers::enable
void enable(const bool &enable_)
Temporarily turn controller input on/off.
Definition: Controllers.cpp:92
SDL_GameControllerEventState
DECLSPEC int SDLCALL SDL_GameControllerEventState(int state)
Definition: SDL_gamecontroller.c:1218
assert
#define assert(x)
Definition: SDL_malloc.c:1234
Zeni::Controllers::device_added
void device_added(const Sint32 &index)
Register a new device.
Definition: Controllers.cpp:102
SDL_GetError
DECLSPEC const char *SDLCALL SDL_GetError(void)
Definition: SDL_error.c:204
Zeni::Singleton< Core >::remove_post_reinit
static void remove_post_reinit(Event::Handler *const &handler)
SDL_FALSE
Definition: SDL_stdinc.h:118
SDL_IsGameController
DECLSPEC SDL_bool SDLCALL SDL_IsGameController(int joystick_index)
Definition: SDL_gamecontroller.c:830
SDL_HAPTIC_INFINITY
#define SDL_HAPTIC_INFINITY
Used to play a device an infinite number of times.
Definition: SDL_haptic.h:344
Zeni::Controllers::reinit
void reinit()
Reload all joysticks, flushing all SDL events and possibly changing &#39;which&#39; values for controllers...
Definition: Controllers.cpp:87
Uint32
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
SDL_JoystickIsHaptic
DECLSPEC int SDLCALL SDL_JoystickIsHaptic(SDL_Joystick *joystick)
Checks to see if a joystick has haptic features.
Definition: SDL_haptic.c:248
SDL_HapticEffectSupported
DECLSPEC int SDLCALL SDL_HapticEffectSupported(SDL_Haptic *haptic, SDL_HapticEffect *effect)
Checks to see if effect is supported by haptic.
Definition: SDL_haptic.c:446
Zeni::Singleton< Core >::remove_pre_uninit
static void remove_pre_uninit(Event::Handler *const &handler)
Zeni::Controllers::get_controller_index
Sint32 get_controller_index(const Sint32 &id) const
Get the index of a given controller from the true SDL_JoystickInstanceID.
Definition: Controllers.cpp:67
Singleton.hxx
SDL_HapticNewEffect
DECLSPEC int SDLCALL SDL_HapticNewEffect(SDL_Haptic *haptic, SDL_HapticEffect *effect)
Creates a new haptic effect on the device.
Definition: SDL_haptic.c:461
Zeni::Controllers::get_controller_name
const char * get_controller_name(const Sint32 &index) const
Get the name of a given controller.
Definition: Controllers.cpp:76
SDL_InitSubSystem
DECLSPEC int SDLCALL SDL_InitSubSystem(Uint32 flags)
Definition: SDL.c:103
haptic_effect
Definition: SDL_syshaptic.h:33
Zeni::Singleton< Controllers >::get
static Controllers & get()
SDL_INIT_GAMECONTROLLER
#define SDL_INIT_GAMECONTROLLER
Definition: SDL.h:113
index
GLuint index
Definition: glew.h:1800
SDL_GameControllerMapping
DECLSPEC char *SDLCALL SDL_GameControllerMapping(SDL_GameController *gamecontroller)
Definition: SDL_gamecontroller.c:751
Zeni::Controllers::get_num_controllers
size_t get_num_controllers() const
Get the number of controllers attached to the system.
Definition: Controllers.cpp:63
Zeni::Controllers
The Controllers Singleton.
Definition: Controllers.h:50
SDL_JoystickEventState
DECLSPEC int SDLCALL SDL_JoystickEventState(int state)
Definition: SDL_joystick.c:708
SDL_JoystickGetGUIDString
DECLSPEC void SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID)
Definition: SDL_joystick.c:770
SDL_DISABLE
#define SDL_DISABLE
Definition: SDL_events.h:687
Zeni::File_Ops::get_appdata_path
String get_appdata_path()
Get the path that should be used for user-modifiable storage.
Definition: File_Ops.cpp:223
Zeni::Controllers::set_vibration
void set_vibration(const size_t &index, const float &left, const float &right)
Set vibration for controller [0,...] to &lt;[0,1],[0,1]&gt;
Definition: Controllers.cpp:193
zeni_core.h
SDL_JoystickName
DECLSPEC const char *SDLCALL SDL_JoystickName(SDL_Joystick *joystick)
Definition: SDL_joystick.c:385
SDL_ClearError
DECLSPEC void SDLCALL SDL_ClearError(void)
Definition: SDL_error.c:212
SDL_JoystickGetGUID
DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetGUID(SDL_Joystick *joystick)
Definition: SDL_joystick.c:764
SDL_GameControllerGetAttached
DECLSPEC SDL_bool SDLCALL SDL_GameControllerGetAttached(SDL_GameController *gamecontroller)
Definition: SDL_gamecontroller.c:991
_SDL_Joystick
Definition: SDL_sysjoystick.h:29
Zeni::get_Core
Core & get_Core()
Get access to the singleton.
Definition: Core.cpp:71
SDL_HapticDestroyEffect
DECLSPEC void SDLCALL SDL_HapticDestroyEffect(SDL_Haptic *haptic, int effect)
Destroys a haptic effect on the device.
Definition: SDL_haptic.c:576
SDL_JoystickOpen
DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickOpen(int device_index)
Definition: SDL_joystick.c:101
mapping
GLenum GLenum GLenum GLenum mapping
Definition: glew.h:12631
SDL_HapticRunEffect
DECLSPEC int SDLCALL SDL_HapticRunEffect(SDL_Haptic *haptic, int effect, Uint32 iterations)
Runs the haptic effect on its associated haptic device.
Definition: SDL_haptic.c:539
SDL_GameControllerAddMapping
DECLSPEC int SDLCALL SDL_GameControllerAddMapping(const char *mappingString)
Definition: SDL_gamecontroller.c:662
Uint16
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:137
i
int i
Definition: pngrutil.c:1377
right
GLfloat right
Definition: glew.h:13816
Zeni::get_File_Ops
File_Ops & get_File_Ops()
Get access to the singleton.
Definition: File_Ops.cpp:118
SDL_HAPTIC_LEFTRIGHT
#define SDL_HAPTIC_LEFTRIGHT
Left/Right effect supported.
Definition: SDL_haptic.h:177
Zeni::Controllers::device_removed
void device_removed(const Sint32 &id)
Remove a device.
Definition: Controllers.cpp:156
SDL_QuitSubSystem
DECLSPEC void SDLCALL SDL_QuitSubSystem(Uint32 flags)
Definition: SDL.c:241
SDL_NumJoysticks
DECLSPEC int SDLCALL SDL_NumJoysticks(void)
Definition: SDL_joystick.c:75