Undo revision 23130 which was a merge with 2.5, a messy one because I did something...
[blender.git] / source / gameengine / GameLogic / SCA_JoystickSensor.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program 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 General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27 #include "SCA_JoystickManager.h"
28 #include "SCA_JoystickSensor.h"
29
30 #include "SCA_EventManager.h"
31 #include "SCA_LogicManager.h"
32
33 #include "PyObjectPlus.h"
34
35 #include <iostream>
36
37
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42
43 SCA_JoystickSensor::SCA_JoystickSensor(class SCA_JoystickManager* eventmgr,
44                                                                            SCA_IObject* gameobj,
45                                                                            short int joyindex,
46                                                                            short int joymode,
47                                                                            int axis, int axisf,int prec,
48                                                                            int button,
49                                                                            int hat, int hatf, bool allevents)
50                                                                            :SCA_ISensor(gameobj,eventmgr),
51                                                                            m_pJoystickMgr(eventmgr),
52                                                                            m_axis(axis),
53                                                                            m_axisf(axisf),
54                                                                            m_button(button),
55                                                                            m_hat(hat),
56                                                                            m_hatf(hatf),
57                                                                            m_precision(prec),
58                                                                            m_joymode(joymode),
59                                                                            m_joyindex(joyindex),
60                                                                            m_bAllEvents(allevents)
61 {       
62 /*
63 std::cout << " axis "           << m_axis               << std::endl;
64 std::cout << " axis flag "      << m_axisf              << std::endl;
65 std::cout << " precision "      << m_precision  << std::endl;
66 std::cout << " button "         << m_button     << std::endl;
67 std::cout << " hat "            << m_hat                << std::endl;
68 std::cout << " hat flag "       << m_hatf               << std::endl;
69 */
70         Init();
71 }
72
73 void SCA_JoystickSensor::Init()
74 {
75         m_istrig=(m_invert)?1:0;
76         m_istrig_prev=0;
77         m_reset = true;
78 }
79
80 SCA_JoystickSensor::~SCA_JoystickSensor()
81 {
82 }
83
84
85 CValue* SCA_JoystickSensor::GetReplica()
86 {
87         SCA_JoystickSensor* replica = new SCA_JoystickSensor(*this);
88         // this will copy properties and so on...
89         replica->ProcessReplica();
90         replica->Init();
91         return replica;
92 }
93
94
95 bool SCA_JoystickSensor::IsPositiveTrigger()
96
97         bool result =   m_istrig;
98         if (m_invert)
99                 result = !result;
100         return result;
101 }
102
103
104 bool SCA_JoystickSensor::Evaluate()
105 {
106         SCA_Joystick *js = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
107         bool result = false;
108         bool reset = m_reset && m_level;
109         
110         if(js==NULL) /* no joystick - dont do anything */
111                 return false;
112         
113         m_reset = false;
114         switch(m_joymode)
115         {
116         case KX_JOYSENSORMODE_AXIS:
117                 {
118                 /* what is what!
119                         m_axisf == JOYAXIS_RIGHT, JOYAXIS_UP, JOYAXIS_DOWN, JOYAXIS_LEFT
120                         m_axisf == 1 == up
121                         m_axisf == 2 == left
122                         m_axisf == 3 == down
123                         
124                         numberof== m_axis (1-4), range is half of JOYAXIS_MAX since 
125                                 it assumes the axis joysticks are axis parirs (0,1), (2,3), etc
126                                 also note that this starts at 1 where functions its used
127                                 with expect a zero index.
128                         */
129                         
130                         if (!js->IsTrigAxis() && !reset) /* No events from SDL? - dont bother */
131                                 return false;
132                         
133                         js->cSetPrecision(m_precision);
134                         if (m_bAllEvents) {
135                                 if(js->aAxisPairIsPositive(m_axis-1)){ /* use zero based axis index internally */
136                                         m_istrig = 1;
137                                         result = true;
138                                 }else{
139                                         if(m_istrig){
140                                                 m_istrig = 0;
141                                                 result = true;
142                                         }
143                                 }
144                         }
145                         else {
146                                 if(js->aAxisPairDirectionIsPositive(m_axis-1, m_axisf)){ /* use zero based axis index internally */
147                                         m_istrig = 1;
148                                         result = true;
149                                 }else{
150                                         if(m_istrig){
151                                                 m_istrig = 0;
152                                                 result = true;
153                                         }
154                                 }
155                         }
156                         break;
157                 }
158         case KX_JOYSENSORMODE_AXIS_SINGLE:
159                 {
160                         /* Like KX_JOYSENSORMODE_AXIS but dont pair up axis */
161                         if (!js->IsTrigAxis() && !reset) /* No events from SDL? - dont bother */
162                                 return false;
163                         
164                         /* No need for 'm_bAllEvents' check here since were only checking 1 axis */
165                         js->cSetPrecision(m_precision);
166                         if(js->aAxisIsPositive(m_axis-1)){ /* use zero based axis index internally */
167                                 m_istrig = 1;
168                                 result = true;
169                         }else{
170                                 if(m_istrig){
171                                         m_istrig = 0;
172                                         result = true;
173                                 }
174                         }
175                         break;
176                 }
177                 
178         case KX_JOYSENSORMODE_BUTTON:
179                 {
180                 /* what is what!
181                         m_button = the actual button in question
182                         */
183                         if (!js->IsTrigButton() && !reset) /* No events from SDL? - dont bother */
184                                 return false;
185                         
186                         if(( m_bAllEvents && js->aAnyButtonPressIsPositive()) || (!m_bAllEvents && js->aButtonPressIsPositive(m_button))) {
187                                 m_istrig = 1;
188                                 result = true;
189                         }else {
190                                 if(m_istrig){
191                                         m_istrig = 0;
192                                         result = true;
193                                 }
194                         }
195                         break;
196                 }
197         case KX_JOYSENSORMODE_HAT:
198                 {
199                 /* what is what!
200                         numberof = m_hat  -- max 4
201                         direction= m_hatf -- max 12
202                         */
203                         
204                         if (!js->IsTrigHat() && !reset) /* No events from SDL? - dont bother */
205                                 return false;
206                         
207                         if((m_bAllEvents && js->GetHat(m_hat-1)) || js->aHatIsPositive(m_hat-1, m_hatf)) {
208                                 m_istrig = 1;
209                                 result = true;
210                         }else{
211                                 if(m_istrig){
212                                         m_istrig = 0;
213                                         result = true;
214                                 }
215                         }
216                         break;
217                 }
218                 /* test for ball anyone ?*/
219         default:
220                 printf("Error invalid switch statement\n");
221                 break;
222         }
223         
224         /* if not all events are enabled, only send a positive pulse when 
225          * the button state changes */
226         if (!m_bAllEvents) {
227                 if (m_istrig_prev == m_istrig) {
228                         result = false;
229                 } else {
230                         m_istrig_prev = m_istrig;
231                 }
232         }
233         
234         if (reset)
235                 result = true;
236         
237         return result;
238 }
239
240
241 bool SCA_JoystickSensor::isValid(SCA_JoystickSensor::KX_JOYSENSORMODE m)
242 {
243         bool res = false;
244         res = ((m > KX_JOYSENSORMODE_NODEF) && (m < KX_JOYSENSORMODE_MAX));
245         return res;
246 }
247
248
249 /* ------------------------------------------------------------------------- */
250 /* Python functions                                                                                                              */
251 /* ------------------------------------------------------------------------- */
252
253 /* Integration hooks ------------------------------------------------------- */
254 PyTypeObject SCA_JoystickSensor::Type = {
255         PyVarObject_HEAD_INIT(NULL, 0)
256         "SCA_JoystickSensor",
257         sizeof(PyObjectPlus_Proxy),
258         0,
259         py_base_dealloc,
260         0,
261         0,
262         0,
263         0,
264         py_base_repr,
265         0,0,0,0,0,0,0,0,0,
266         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
267         0,0,0,0,0,0,0,
268         Methods,
269         0,
270         0,
271         &SCA_ISensor::Type,
272         0,0,0,0,0,0,
273         py_base_new
274 };
275
276 PyMethodDef SCA_JoystickSensor::Methods[] = {
277         //Deprecated functions ------>
278         {"getIndex",     (PyCFunction) SCA_JoystickSensor::sPyGetIndex,         METH_NOARGS,    (const char *)GetIndex_doc},
279         {"setIndex",     (PyCFunction) SCA_JoystickSensor::sPySetIndex,         METH_O,                 (const char *)SetIndex_doc},
280         {"getAxis",      (PyCFunction) SCA_JoystickSensor::sPyGetAxis,          METH_NOARGS,    (const char *)GetAxis_doc},
281         {"setAxis",      (PyCFunction) SCA_JoystickSensor::sPySetAxis,          METH_VARARGS,   (const char *)SetAxis_doc},
282         {"getAxisValue", (PyCFunction) SCA_JoystickSensor::sPyGetAxisValue,     METH_NOARGS,    (const char *)GetAxisValue_doc},
283         {"getThreshold", (PyCFunction) SCA_JoystickSensor::sPyGetThreshold, METH_NOARGS,        (const char *)GetThreshold_doc},
284         {"setThreshold", (PyCFunction) SCA_JoystickSensor::sPySetThreshold, METH_VARARGS,       (const char *)SetThreshold_doc},
285         {"getButton",    (PyCFunction) SCA_JoystickSensor::sPyGetButton,        METH_NOARGS,    (const char *)GetButton_doc},
286         {"setButton",    (PyCFunction) SCA_JoystickSensor::sPySetButton,        METH_O,                 (const char *)SetButton_doc},
287         {"getHat",               (PyCFunction) SCA_JoystickSensor::sPyGetHat,           METH_NOARGS,    (const char *)GetHat_doc},
288         {"setHat",               (PyCFunction) SCA_JoystickSensor::sPySetHat,           METH_VARARGS,   (const char *)SetHat_doc},
289         {"getNumAxes",   (PyCFunction) SCA_JoystickSensor::sPyNumberOfAxes,     METH_NOARGS,    (const char *)NumberOfAxes_doc},
290         {"getNumButtons",(PyCFunction) SCA_JoystickSensor::sPyNumberOfButtons,METH_NOARGS,      (const char *)NumberOfButtons_doc},
291         {"getNumHats",   (PyCFunction) SCA_JoystickSensor::sPyNumberOfHats,     METH_NOARGS,    (const char *)NumberOfHats_doc},
292         {"isConnected", (PyCFunction) SCA_JoystickSensor::sPyConnected,         METH_NOARGS,    (const char *)Connected_doc},
293         {"getButtonValue",(PyCFunction) SCA_JoystickSensor::sPyGetButtonValue,  METH_NOARGS,(const char *)GetButtonValue_doc},
294         //<----- Deprecated
295         {"getButtonActiveList",(PyCFunction) SCA_JoystickSensor::sPyGetButtonActiveList,        METH_NOARGS,(const char *)GetButtonActiveList_doc},
296         {"getButtonStatus",(PyCFunction) SCA_JoystickSensor::sPyGetButtonStatus,        METH_VARARGS,(const char *)GetButtonStatus_doc},
297         {NULL,NULL} //Sentinel
298 };
299
300 PyAttributeDef SCA_JoystickSensor::Attributes[] = {
301         KX_PYATTRIBUTE_SHORT_RW("index",0,JOYINDEX_MAX-1,true,SCA_JoystickSensor,m_joyindex),
302         KX_PYATTRIBUTE_INT_RW("threshold",0,32768,true,SCA_JoystickSensor,m_precision),
303         KX_PYATTRIBUTE_INT_RW("button",0,100,false,SCA_JoystickSensor,m_button),
304         KX_PYATTRIBUTE_INT_LIST_RW_CHECK("axis",0,3,true,SCA_JoystickSensor,m_axis,2,CheckAxis),
305         KX_PYATTRIBUTE_INT_LIST_RW_CHECK("hat",0,12,true,SCA_JoystickSensor,m_hat,2,CheckHat),
306         KX_PYATTRIBUTE_RO_FUNCTION("axisValues",        SCA_JoystickSensor, pyattr_get_axis_values),
307         KX_PYATTRIBUTE_RO_FUNCTION("axisSingle", SCA_JoystickSensor, pyattr_get_axis_single),
308         KX_PYATTRIBUTE_RO_FUNCTION("hatValues", SCA_JoystickSensor, pyattr_get_hat_values),
309         KX_PYATTRIBUTE_RO_FUNCTION("hatSingle", SCA_JoystickSensor, pyattr_get_hat_single),
310         KX_PYATTRIBUTE_RO_FUNCTION("numAxis",           SCA_JoystickSensor, pyattr_get_num_axis),
311         KX_PYATTRIBUTE_RO_FUNCTION("numButtons",        SCA_JoystickSensor, pyattr_get_num_buttons),
312         KX_PYATTRIBUTE_RO_FUNCTION("numHats",           SCA_JoystickSensor, pyattr_get_num_hats),
313         KX_PYATTRIBUTE_RO_FUNCTION("connected",         SCA_JoystickSensor, pyattr_get_connected),
314         //KX_PYATTRIBUTE_TODO("events"),
315         { NULL }        //Sentinel
316 };
317
318
319 /* get index ---------------------------------------------------------- */
320 const char SCA_JoystickSensor::GetIndex_doc[] = 
321 "getIndex\n"
322 "\tReturns the joystick index to use.\n";
323 PyObject* SCA_JoystickSensor::PyGetIndex( ) {
324         ShowDeprecationWarning("getIndex()", "the index property");
325         return PyLong_FromSsize_t(m_joyindex);
326 }
327
328
329 /* set index ---------------------------------------------------------- */
330 const char SCA_JoystickSensor::SetIndex_doc[] = 
331 "setIndex\n"
332 "\tSets the joystick index to use.\n";
333 PyObject* SCA_JoystickSensor::PySetIndex( PyObject* value ) {
334         ShowDeprecationWarning("setIndex()", "the index property");
335         int index = PyLong_AsSsize_t( value ); /* -1 on error, will raise an error in this case */
336         if (index < 0 || index >= JOYINDEX_MAX) {
337                 PyErr_SetString(PyExc_ValueError, "joystick index out of range or not an int");
338                 return NULL;
339         }
340         
341         m_joyindex = index;
342         Py_RETURN_NONE;
343 }
344
345 /* get axis  ---------------------------------------------------------- */
346 const char SCA_JoystickSensor::GetAxis_doc[] = 
347 "getAxis\n"
348 "\tReturns the current axis this sensor reacts to.\n";
349 PyObject* SCA_JoystickSensor::PyGetAxis( ) {
350         ShowDeprecationWarning("getAxis()", "the axis property");
351         return Py_BuildValue("[ii]",m_axis, m_axisf);
352 }
353
354
355 /* set axis  ---------------------------------------------------------- */
356 const char SCA_JoystickSensor::SetAxis_doc[] = 
357 "setAxis\n"
358 "\tSets the current axis this sensor reacts to.\n";
359 PyObject* SCA_JoystickSensor::PySetAxis( PyObject* args ) {
360         ShowDeprecationWarning("setAxis()", "the axis property");
361         
362         int axis,axisflag;
363         if(!PyArg_ParseTuple(args, "ii:setAxis", &axis, &axisflag)){
364                 return NULL;
365         }
366         m_axis = axis;
367         m_axisf = axisflag;
368         
369         CheckAxis((void *)this, NULL); /* clamp values */
370         Py_RETURN_NONE;
371 }
372
373
374 /* get axis value ----------------------------------------------------- */
375 const char SCA_JoystickSensor::GetAxisValue_doc[] = 
376 "getAxisValue\n"
377 "\tReturns a list of the values for the current state of each axis.\n";
378 PyObject* SCA_JoystickSensor::PyGetAxisValue( ) {
379         ShowDeprecationWarning("getAxisValue()", "the axisPosition property");
380         SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
381         
382         int axis_index= joy->GetNumberOfAxes();
383         PyObject *list= PyList_New(axis_index);
384         
385         while(axis_index--) {
386                 PyList_SET_ITEM(list, axis_index, PyLong_FromSsize_t(joy->GetAxisPosition(axis_index)));
387         }
388         
389         return list;
390 }
391
392
393 /* get threshold  ----------------------------------------------------- */
394 const char SCA_JoystickSensor::GetThreshold_doc[] = 
395 "getThreshold\n"
396 "\tReturns the threshold of the axis.\n";
397 PyObject* SCA_JoystickSensor::PyGetThreshold( ) {
398         ShowDeprecationWarning("getThreshold()", "the threshold property");
399         return PyLong_FromSsize_t(m_precision);
400 }
401
402
403 /* set threshold  ----------------------------------------------------- */
404 const char SCA_JoystickSensor::SetThreshold_doc[] = 
405 "setThreshold\n"
406 "\tSets the threshold of the axis.\n";
407 PyObject* SCA_JoystickSensor::PySetThreshold( PyObject* args ) {
408         ShowDeprecationWarning("setThreshold()", "the threshold property");
409         int thresh;
410         if(!PyArg_ParseTuple(args, "i:setThreshold", &thresh)){
411                 return NULL;
412         }
413         m_precision = thresh;
414         Py_RETURN_NONE;
415 }
416
417 /* get button  -------------------------------------------------------- */
418 const char SCA_JoystickSensor::GetButton_doc[] = 
419 "getButton\n"
420 "\tReturns the current button this sensor is checking.\n";
421 PyObject* SCA_JoystickSensor::PyGetButton( ) {
422         ShowDeprecationWarning("getButton()", "the button property");
423         return PyLong_FromSsize_t(m_button);
424 }
425
426 /* set button  -------------------------------------------------------- */
427 const char SCA_JoystickSensor::SetButton_doc[] = 
428 "setButton\n"
429 "\tSets the button the sensor reacts to.\n";
430 PyObject* SCA_JoystickSensor::PySetButton( PyObject* value ) {
431         ShowDeprecationWarning("setButton()", "the button property");
432         int button = PyLong_AsSsize_t(value);
433         if(button==-1 && PyErr_Occurred()) {
434                 PyErr_SetString(PyExc_ValueError, "expected an int");
435                 return NULL;
436         }
437         m_button = button;
438         Py_RETURN_NONE; 
439 }
440
441 /* get button value  -------------------------------------------------- */
442 const char SCA_JoystickSensor::GetButtonValue_doc[] = 
443 "getButtonValue\n"
444 "\tReturns a list containing the indicies of the current pressed state of each button.\n";
445 PyObject* SCA_JoystickSensor::PyGetButtonValue( ) {
446         ShowDeprecationWarning("getButtonValue()", "getButtonActiveList");
447         return PyGetButtonActiveList( );
448 }
449
450 /* get button active list  -------------------------------------------------- */
451 const char SCA_JoystickSensor::GetButtonActiveList_doc[] = 
452 "getButtonActiveList\n"
453 "\tReturns a list containing the indicies of the button currently pressed.\n";
454 PyObject* SCA_JoystickSensor::PyGetButtonActiveList( ) {
455         SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
456         PyObject *ls = PyList_New(0);
457         PyObject *value;
458         int i;
459         
460         if(joy) {
461                 for (i=0; i < joy->GetNumberOfButtons(); i++) {
462                         if (joy->aButtonPressIsPositive(i)) {
463                                 value = PyLong_FromSsize_t(i);
464                                 PyList_Append(ls, value);
465                                 Py_DECREF(value);
466                         }
467                 }
468         }
469         return ls;
470 }
471
472 /* get button status  -------------------------------------------------- */
473 const char SCA_JoystickSensor::GetButtonStatus_doc[] = 
474 "getButtonStatus(buttonIndex)\n"
475 "\tReturns a bool of the current pressed state of the specified button.\n";
476 PyObject* SCA_JoystickSensor::PyGetButtonStatus( PyObject* args ) {
477         SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
478         int index;
479         
480         if(!PyArg_ParseTuple(args, "i:getButtonStatus", &index)){
481                 return NULL;
482         }
483         if(joy && index >= 0 && index < joy->GetNumberOfButtons()) {
484                 return PyBool_FromLong(joy->aButtonPressIsPositive(index) ? 1 : 0);
485         }
486         return PyBool_FromLong(0);
487 }
488
489 /* get hat      ----------------------------------------------------------- */
490 const char SCA_JoystickSensor::GetHat_doc[] = 
491 "getHat\n"
492 "\tReturns the current direction of the hat.\n";
493 PyObject* SCA_JoystickSensor::PyGetHat( ) {
494         ShowDeprecationWarning("getHat()", "the hat property");
495         return Py_BuildValue("[ii]",m_hat, m_hatf);
496 }
497
498
499 /* set hat      ----------------------------------------------------------- */
500 const char SCA_JoystickSensor::SetHat_doc[] = 
501 "setHat\n"
502 "\tSets the hat the sensor reacts to.\n";
503 PyObject* SCA_JoystickSensor::PySetHat( PyObject* args ) {
504         ShowDeprecationWarning("setHat()", "the hat property");
505         int hat,hatflag;
506         if(!PyArg_ParseTuple(args, "ii:setHat", &hat, &hatflag)){
507                 return NULL;
508         }
509         m_hat = hat;
510         m_hatf = hatflag;
511         
512         CheckHat((void *)this, NULL); /* clamp values */
513         Py_RETURN_NONE;
514 }
515
516
517 /* get # of ----------------------------------------------------- */
518 const char SCA_JoystickSensor::NumberOfAxes_doc[] = 
519 "getNumAxes\n"
520 "\tReturns the number of axes .\n";
521 PyObject* SCA_JoystickSensor::PyNumberOfAxes( ) {
522         ShowDeprecationWarning("getNumAxes()", "the numAxis property");
523         SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
524         // when the joystick is null their is 0 exis still. dumb but scripters should use isConnected()
525         return PyLong_FromSsize_t( joy ? joy->GetNumberOfAxes() : 0 );
526 }
527
528
529 const char SCA_JoystickSensor::NumberOfButtons_doc[] = 
530 "getNumButtons\n"
531 "\tReturns the number of buttons .\n";
532 PyObject* SCA_JoystickSensor::PyNumberOfButtons( ) {
533         ShowDeprecationWarning("getNumButtons()", "the numButtons property");
534         SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
535         return PyLong_FromSsize_t( joy ? joy->GetNumberOfButtons() : 0 );
536 }
537
538
539 const char SCA_JoystickSensor::NumberOfHats_doc[] = 
540 "getNumHats\n"
541 "\tReturns the number of hats .\n";
542 PyObject* SCA_JoystickSensor::PyNumberOfHats( ) {
543         ShowDeprecationWarning("getNumHats()", "the numHats property");
544         SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
545         return PyLong_FromSsize_t( joy ? joy->GetNumberOfHats() : 0 );
546 }
547
548 const char SCA_JoystickSensor::Connected_doc[] = 
549 "getConnected\n"
550 "\tReturns True if a joystick is connected at this joysticks index.\n";
551 PyObject* SCA_JoystickSensor::PyConnected( ) {
552         ShowDeprecationWarning("getConnected()", "the connected property");
553         SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
554         return PyBool_FromLong( joy ? joy->Connected() : 0 );
555 }
556
557
558 PyObject* SCA_JoystickSensor::pyattr_get_axis_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
559 {
560         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
561         SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex);
562         
563         int axis_index= joy->GetNumberOfAxes();
564         PyObject *list= PyList_New(axis_index);
565         
566         while(axis_index--) {
567                 PyList_SET_ITEM(list, axis_index, PyLong_FromSsize_t(joy->GetAxisPosition(axis_index)));
568         }
569         
570         return list;
571 }
572
573 PyObject* SCA_JoystickSensor::pyattr_get_axis_single(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
574 {
575         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
576         SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex);
577         
578         if(self->m_joymode != KX_JOYSENSORMODE_AXIS_SINGLE) {
579                 PyErr_SetString(PyExc_TypeError, "val = sensor.axisSingle: Joystick Sensor, not 'Single Axis' type");
580                 return NULL;
581         }
582         
583         return PyLong_FromSsize_t(joy->GetAxisPosition(self->m_axis-1));
584 }
585
586 PyObject* SCA_JoystickSensor::pyattr_get_hat_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
587 {
588         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
589         SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex);
590         
591         int hat_index= joy->GetNumberOfHats();
592         PyObject *list= PyList_New(hat_index);
593         
594         while(hat_index--) {
595                 PyList_SET_ITEM(list, hat_index, PyLong_FromSsize_t(joy->GetHat(hat_index)));
596         }
597         
598         return list;
599 }
600
601 PyObject* SCA_JoystickSensor::pyattr_get_hat_single(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
602 {
603         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
604         SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex);
605         
606         return PyLong_FromSsize_t(joy->GetHat(self->m_hat-1));
607 }
608
609 PyObject* SCA_JoystickSensor::pyattr_get_num_axis(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
610 {
611         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
612         SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex);
613         return PyLong_FromSsize_t( joy ? joy->GetNumberOfAxes() : 0 );
614 }
615
616 PyObject* SCA_JoystickSensor::pyattr_get_num_buttons(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
617 {
618         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
619         SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex);
620         return PyLong_FromSsize_t( joy ? joy->GetNumberOfButtons() : 0 );
621 }
622
623 PyObject* SCA_JoystickSensor::pyattr_get_num_hats(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
624 {
625         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
626         SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex);
627         return PyLong_FromSsize_t( joy ? joy->GetNumberOfHats() : 0 );
628 }
629
630 PyObject* SCA_JoystickSensor::pyattr_get_connected(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
631 {
632         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
633         SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex);
634         return PyBool_FromLong( joy ? joy->Connected() : 0 );
635 }