- BGE, Some sensors, stored the event manager in 2 places (became confusing to do...
[blender-staging.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                                                                            PyTypeObject* T )
51                                                                            :SCA_ISensor(gameobj,eventmgr,T),
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 = ((SCA_JoystickManager *)m_eventmgr)->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 #if (PY_VERSION_HEX >= 0x02060000)
256         PyVarObject_HEAD_INIT(NULL, 0)
257 #else
258         /* python 2.5 and below */
259         PyObject_HEAD_INIT( NULL )  /* required py macro */
260         0,                          /* ob_size */
261 #endif
262                 "SCA_JoystickSensor",
263                 sizeof(PyObjectPlus_Proxy),
264                 0,
265                 py_base_dealloc,
266                 0,
267                 0,
268                 0,
269                 0,
270                 py_base_repr,
271                 0,0,0,0,0,0,
272                 py_base_getattro,
273                 py_base_setattro,
274                 0,0,0,0,0,0,0,0,0,
275                 Methods
276 };
277
278
279 PyParentObject SCA_JoystickSensor::Parents[] = {
280                 &SCA_JoystickSensor::Type,
281                 &SCA_ISensor::Type,
282                 &SCA_ILogicBrick::Type,
283                 &CValue::Type,
284                 NULL
285 };
286
287
288 PyMethodDef SCA_JoystickSensor::Methods[] = {
289         //Deprecated functions ------>
290         {"getIndex",     (PyCFunction) SCA_JoystickSensor::sPyGetIndex,         METH_NOARGS,    (PY_METHODCHAR)GetIndex_doc},
291         {"setIndex",     (PyCFunction) SCA_JoystickSensor::sPySetIndex,         METH_O,                 (PY_METHODCHAR)SetIndex_doc},
292         {"getAxis",      (PyCFunction) SCA_JoystickSensor::sPyGetAxis,          METH_NOARGS,    (PY_METHODCHAR)GetAxis_doc},
293         {"setAxis",      (PyCFunction) SCA_JoystickSensor::sPySetAxis,          METH_VARARGS,   (PY_METHODCHAR)SetAxis_doc},
294         {"getAxisValue", (PyCFunction) SCA_JoystickSensor::sPyGetAxisValue,     METH_NOARGS,    (PY_METHODCHAR)GetAxisValue_doc},
295         {"getThreshold", (PyCFunction) SCA_JoystickSensor::sPyGetThreshold, METH_NOARGS,        (PY_METHODCHAR)GetThreshold_doc},
296         {"setThreshold", (PyCFunction) SCA_JoystickSensor::sPySetThreshold, METH_VARARGS,       (PY_METHODCHAR)SetThreshold_doc},
297         {"getButton",    (PyCFunction) SCA_JoystickSensor::sPyGetButton,        METH_NOARGS,    (PY_METHODCHAR)GetButton_doc},
298         {"setButton",    (PyCFunction) SCA_JoystickSensor::sPySetButton,        METH_O,                 (PY_METHODCHAR)SetButton_doc},
299         {"getHat",               (PyCFunction) SCA_JoystickSensor::sPyGetHat,           METH_NOARGS,    (PY_METHODCHAR)GetHat_doc},
300         {"setHat",               (PyCFunction) SCA_JoystickSensor::sPySetHat,           METH_VARARGS,   (PY_METHODCHAR)SetHat_doc},
301         {"getNumAxes",   (PyCFunction) SCA_JoystickSensor::sPyNumberOfAxes,     METH_NOARGS,    (PY_METHODCHAR)NumberOfAxes_doc},
302         {"getNumButtons",(PyCFunction) SCA_JoystickSensor::sPyNumberOfButtons,METH_NOARGS,      (PY_METHODCHAR)NumberOfButtons_doc},
303         {"getNumHats",   (PyCFunction) SCA_JoystickSensor::sPyNumberOfHats,     METH_NOARGS,    (PY_METHODCHAR)NumberOfHats_doc},
304         {"isConnected", (PyCFunction) SCA_JoystickSensor::sPyConnected,         METH_NOARGS,    (PY_METHODCHAR)Connected_doc},
305         {"getButtonValue",(PyCFunction) SCA_JoystickSensor::sPyGetButtonValue,  METH_NOARGS,(PY_METHODCHAR)GetButtonValue_doc},
306         //<----- Deprecated
307         {"getButtonActiveList",(PyCFunction) SCA_JoystickSensor::sPyGetButtonActiveList,        METH_NOARGS,(PY_METHODCHAR)GetButtonActiveList_doc},
308         {"getButtonStatus",(PyCFunction) SCA_JoystickSensor::sPyGetButtonStatus,        METH_VARARGS,(PY_METHODCHAR)GetButtonStatus_doc},
309         {NULL,NULL} //Sentinel
310 };
311
312 PyAttributeDef SCA_JoystickSensor::Attributes[] = {
313         KX_PYATTRIBUTE_SHORT_RW("index",0,JOYINDEX_MAX-1,true,SCA_JoystickSensor,m_joyindex),
314         KX_PYATTRIBUTE_INT_RW("threshold",0,32768,true,SCA_JoystickSensor,m_precision),
315         KX_PYATTRIBUTE_INT_RW("button",0,100,false,SCA_JoystickSensor,m_button),
316         KX_PYATTRIBUTE_INT_LIST_RW_CHECK("axis",0,3,true,SCA_JoystickSensor,m_axis,2,CheckAxis),
317         KX_PYATTRIBUTE_INT_LIST_RW_CHECK("hat",0,12,true,SCA_JoystickSensor,m_hat,2,CheckHat),
318         KX_PYATTRIBUTE_RO_FUNCTION("axisValues",        SCA_JoystickSensor, pyattr_get_axis_values),
319         KX_PYATTRIBUTE_RO_FUNCTION("axisSingle", SCA_JoystickSensor, pyattr_get_axis_single),
320         KX_PYATTRIBUTE_RO_FUNCTION("hatValues", SCA_JoystickSensor, pyattr_get_hat_values),
321         KX_PYATTRIBUTE_RO_FUNCTION("hatSingle", SCA_JoystickSensor, pyattr_get_hat_single),
322         KX_PYATTRIBUTE_RO_FUNCTION("numAxis",           SCA_JoystickSensor, pyattr_get_num_axis),
323         KX_PYATTRIBUTE_RO_FUNCTION("numButtons",        SCA_JoystickSensor, pyattr_get_num_buttons),
324         KX_PYATTRIBUTE_RO_FUNCTION("numHats",           SCA_JoystickSensor, pyattr_get_num_hats),
325         KX_PYATTRIBUTE_RO_FUNCTION("connected",         SCA_JoystickSensor, pyattr_get_connected),
326         //KX_PYATTRIBUTE_TODO("events"),
327         { NULL }        //Sentinel
328 };
329
330 PyObject* SCA_JoystickSensor::py_getattro(PyObject *attr)
331 {
332         py_getattro_up(SCA_ISensor);
333 }
334
335 PyObject* SCA_JoystickSensor::py_getattro_dict() {
336         py_getattro_dict_up(SCA_ISensor);
337 }
338
339 int SCA_JoystickSensor::py_setattro(PyObject *attr, PyObject *value) 
340 {
341         py_setattro_up(SCA_ISensor);
342 }
343
344
345 /* get index ---------------------------------------------------------- */
346 const char SCA_JoystickSensor::GetIndex_doc[] = 
347 "getIndex\n"
348 "\tReturns the joystick index to use.\n";
349 PyObject* SCA_JoystickSensor::PyGetIndex( ) {
350         ShowDeprecationWarning("getIndex()", "the index property");
351         return PyInt_FromLong(m_joyindex);
352 }
353
354
355 /* set index ---------------------------------------------------------- */
356 const char SCA_JoystickSensor::SetIndex_doc[] = 
357 "setIndex\n"
358 "\tSets the joystick index to use.\n";
359 PyObject* SCA_JoystickSensor::PySetIndex( PyObject* value ) {
360         ShowDeprecationWarning("setIndex()", "the index property");
361         int index = PyInt_AsLong( value ); /* -1 on error, will raise an error in this case */
362         if (index < 0 || index >= JOYINDEX_MAX) {
363                 PyErr_SetString(PyExc_ValueError, "joystick index out of range or not an int");
364                 return NULL;
365         }
366         
367         m_joyindex = index;
368         Py_RETURN_NONE;
369 }
370
371 /* get axis  ---------------------------------------------------------- */
372 const char SCA_JoystickSensor::GetAxis_doc[] = 
373 "getAxis\n"
374 "\tReturns the current axis this sensor reacts to.\n";
375 PyObject* SCA_JoystickSensor::PyGetAxis( ) {
376         ShowDeprecationWarning("getAxis()", "the axis property");
377         return Py_BuildValue("[ii]",m_axis, m_axisf);
378 }
379
380
381 /* set axis  ---------------------------------------------------------- */
382 const char SCA_JoystickSensor::SetAxis_doc[] = 
383 "setAxis\n"
384 "\tSets the current axis this sensor reacts to.\n";
385 PyObject* SCA_JoystickSensor::PySetAxis( PyObject* args ) {
386         ShowDeprecationWarning("setAxis()", "the axis property");
387         
388         int axis,axisflag;
389         if(!PyArg_ParseTuple(args, "ii:setAxis", &axis, &axisflag)){
390                 return NULL;
391         }
392         m_axis = axis;
393         m_axisf = axisflag;
394         
395         CheckAxis((void *)this, NULL); /* clamp values */
396         Py_RETURN_NONE;
397 }
398
399
400 /* get axis value ----------------------------------------------------- */
401 const char SCA_JoystickSensor::GetAxisValue_doc[] = 
402 "getAxisValue\n"
403 "\tReturns a list of the values for the current state of each axis.\n";
404 PyObject* SCA_JoystickSensor::PyGetAxisValue( ) {
405         ShowDeprecationWarning("getAxisValue()", "the axisPosition property");
406         SCA_Joystick *joy = ((SCA_JoystickManager *)m_eventmgr)->GetJoystickDevice(m_joyindex);
407         
408         int axis_index= joy->GetNumberOfAxes();
409         PyObject *list= PyList_New(axis_index);
410         
411         while(axis_index--) {
412                 PyList_SET_ITEM(list, axis_index, PyInt_FromLong(joy->GetAxisPosition(axis_index)));
413         }
414         
415         return list;
416 }
417
418
419 /* get threshold  ----------------------------------------------------- */
420 const char SCA_JoystickSensor::GetThreshold_doc[] = 
421 "getThreshold\n"
422 "\tReturns the threshold of the axis.\n";
423 PyObject* SCA_JoystickSensor::PyGetThreshold( ) {
424         ShowDeprecationWarning("getThreshold()", "the threshold property");
425         return PyInt_FromLong(m_precision);
426 }
427
428
429 /* set threshold  ----------------------------------------------------- */
430 const char SCA_JoystickSensor::SetThreshold_doc[] = 
431 "setThreshold\n"
432 "\tSets the threshold of the axis.\n";
433 PyObject* SCA_JoystickSensor::PySetThreshold( PyObject* args ) {
434         ShowDeprecationWarning("setThreshold()", "the threshold property");
435         int thresh;
436         if(!PyArg_ParseTuple(args, "i:setThreshold", &thresh)){
437                 return NULL;
438         }
439         m_precision = thresh;
440         Py_RETURN_NONE;
441 }
442
443 /* get button  -------------------------------------------------------- */
444 const char SCA_JoystickSensor::GetButton_doc[] = 
445 "getButton\n"
446 "\tReturns the current button this sensor is checking.\n";
447 PyObject* SCA_JoystickSensor::PyGetButton( ) {
448         ShowDeprecationWarning("getButton()", "the button property");
449         return PyInt_FromLong(m_button);
450 }
451
452 /* set button  -------------------------------------------------------- */
453 const char SCA_JoystickSensor::SetButton_doc[] = 
454 "setButton\n"
455 "\tSets the button the sensor reacts to.\n";
456 PyObject* SCA_JoystickSensor::PySetButton( PyObject* value ) {
457         ShowDeprecationWarning("setButton()", "the button property");
458         int button = PyInt_AsLong(value);
459         if(button==-1 && PyErr_Occurred()) {
460                 PyErr_SetString(PyExc_ValueError, "expected an int");
461                 return NULL;
462         }
463         m_button = button;
464         Py_RETURN_NONE; 
465 }
466
467 /* get button value  -------------------------------------------------- */
468 const char SCA_JoystickSensor::GetButtonValue_doc[] = 
469 "getButtonValue\n"
470 "\tReturns a list containing the indicies of the current pressed state of each button.\n";
471 PyObject* SCA_JoystickSensor::PyGetButtonValue( ) {
472         ShowDeprecationWarning("getButtonValue()", "getButtonActiveList");
473         return PyGetButtonActiveList( );
474 }
475
476 /* get button active list  -------------------------------------------------- */
477 const char SCA_JoystickSensor::GetButtonActiveList_doc[] = 
478 "getButtonActiveList\n"
479 "\tReturns a list containing the indicies of the button currently pressed.\n";
480 PyObject* SCA_JoystickSensor::PyGetButtonActiveList( ) {
481         SCA_Joystick *joy = ((SCA_JoystickManager *)m_eventmgr)->GetJoystickDevice(m_joyindex);
482         PyObject *ls = PyList_New(0);
483         PyObject *value;
484         int i;
485         
486         if(joy) {
487                 for (i=0; i < joy->GetNumberOfButtons(); i++) {
488                         if (joy->aButtonPressIsPositive(i)) {
489                                 value = PyInt_FromLong(i);
490                                 PyList_Append(ls, value);
491                                 Py_DECREF(value);
492                         }
493                 }
494         }
495         return ls;
496 }
497
498 /* get button status  -------------------------------------------------- */
499 const char SCA_JoystickSensor::GetButtonStatus_doc[] = 
500 "getButtonStatus(buttonIndex)\n"
501 "\tReturns a bool of the current pressed state of the specified button.\n";
502 PyObject* SCA_JoystickSensor::PyGetButtonStatus( PyObject* args ) {
503         SCA_Joystick *joy = ((SCA_JoystickManager *)m_eventmgr)->GetJoystickDevice(m_joyindex);
504         int index;
505         
506         if(!PyArg_ParseTuple(args, "i:getButtonStatus", &index)){
507                 return NULL;
508         }
509         if(joy && index >= 0 && index < joy->GetNumberOfButtons()) {
510                 return PyBool_FromLong(joy->aButtonPressIsPositive(index) ? 1 : 0);
511         }
512         return PyBool_FromLong(0);
513 }
514
515 /* get hat      ----------------------------------------------------------- */
516 const char SCA_JoystickSensor::GetHat_doc[] = 
517 "getHat\n"
518 "\tReturns the current direction of the hat.\n";
519 PyObject* SCA_JoystickSensor::PyGetHat( ) {
520         ShowDeprecationWarning("getHat()", "the hat property");
521         return Py_BuildValue("[ii]",m_hat, m_hatf);
522 }
523
524
525 /* set hat      ----------------------------------------------------------- */
526 const char SCA_JoystickSensor::SetHat_doc[] = 
527 "setHat\n"
528 "\tSets the hat the sensor reacts to.\n";
529 PyObject* SCA_JoystickSensor::PySetHat( PyObject* args ) {
530         ShowDeprecationWarning("setHat()", "the hat property");
531         int hat,hatflag;
532         if(!PyArg_ParseTuple(args, "ii:setHat", &hat, &hatflag)){
533                 return NULL;
534         }
535         m_hat = hat;
536         m_hatf = hatflag;
537         
538         CheckHat((void *)this, NULL); /* clamp values */
539         Py_RETURN_NONE;
540 }
541
542
543 /* get # of ----------------------------------------------------- */
544 const char SCA_JoystickSensor::NumberOfAxes_doc[] = 
545 "getNumAxes\n"
546 "\tReturns the number of axes .\n";
547 PyObject* SCA_JoystickSensor::PyNumberOfAxes( ) {
548         ShowDeprecationWarning("getNumAxes()", "the numAxis property");
549         SCA_Joystick *joy = ((SCA_JoystickManager *)m_eventmgr)->GetJoystickDevice(m_joyindex);
550         // when the joystick is null their is 0 exis still. dumb but scripters should use isConnected()
551         return PyInt_FromLong( joy ? joy->GetNumberOfAxes() : 0 );
552 }
553
554
555 const char SCA_JoystickSensor::NumberOfButtons_doc[] = 
556 "getNumButtons\n"
557 "\tReturns the number of buttons .\n";
558 PyObject* SCA_JoystickSensor::PyNumberOfButtons( ) {
559         ShowDeprecationWarning("getNumButtons()", "the numButtons property");
560         SCA_Joystick *joy = ((SCA_JoystickManager *)m_eventmgr)->GetJoystickDevice(m_joyindex);
561         return PyInt_FromLong( joy ? joy->GetNumberOfButtons() : 0 );
562 }
563
564
565 const char SCA_JoystickSensor::NumberOfHats_doc[] = 
566 "getNumHats\n"
567 "\tReturns the number of hats .\n";
568 PyObject* SCA_JoystickSensor::PyNumberOfHats( ) {
569         ShowDeprecationWarning("getNumHats()", "the numHats property");
570         SCA_Joystick *joy = ((SCA_JoystickManager *)m_eventmgr)->GetJoystickDevice(m_joyindex);
571         return PyInt_FromLong( joy ? joy->GetNumberOfHats() : 0 );
572 }
573
574 const char SCA_JoystickSensor::Connected_doc[] = 
575 "getConnected\n"
576 "\tReturns True if a joystick is connected at this joysticks index.\n";
577 PyObject* SCA_JoystickSensor::PyConnected( ) {
578         ShowDeprecationWarning("getConnected()", "the connected property");
579         SCA_Joystick *joy = ((SCA_JoystickManager *)m_eventmgr)->GetJoystickDevice(m_joyindex);
580         return PyBool_FromLong( joy ? joy->Connected() : 0 );
581 }
582
583
584 PyObject* SCA_JoystickSensor::pyattr_get_axis_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
585 {
586         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
587         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
588         
589         int axis_index= joy->GetNumberOfAxes();
590         PyObject *list= PyList_New(axis_index);
591         
592         while(axis_index--) {
593                 PyList_SET_ITEM(list, axis_index, PyInt_FromLong(joy->GetAxisPosition(axis_index)));
594         }
595         
596         return list;
597 }
598
599 PyObject* SCA_JoystickSensor::pyattr_get_axis_single(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
600 {
601         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
602         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
603         
604         if(self->m_joymode != KX_JOYSENSORMODE_AXIS_SINGLE) {
605                 PyErr_SetString(PyExc_TypeError, "val = sensor.axisSingle: Joystick Sensor, not 'Single Axis' type");
606                 return NULL;
607         }
608         
609         return PyInt_FromLong(joy->GetAxisPosition(self->m_axis-1));
610 }
611
612 PyObject* SCA_JoystickSensor::pyattr_get_hat_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
613 {
614         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
615         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
616         
617         int hat_index= joy->GetNumberOfHats();
618         PyObject *list= PyList_New(hat_index);
619         
620         while(hat_index--) {
621                 PyList_SET_ITEM(list, hat_index, PyInt_FromLong(joy->GetHat(hat_index)));
622         }
623         
624         return list;
625 }
626
627 PyObject* SCA_JoystickSensor::pyattr_get_hat_single(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
628 {
629         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
630         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
631         
632         return PyInt_FromLong(joy->GetHat(self->m_hat-1));
633 }
634
635 PyObject* SCA_JoystickSensor::pyattr_get_num_axis(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
636 {
637         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
638         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
639         return PyInt_FromLong( joy ? joy->GetNumberOfAxes() : 0 );
640 }
641
642 PyObject* SCA_JoystickSensor::pyattr_get_num_buttons(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
643 {
644         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
645         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
646         return PyInt_FromLong( joy ? joy->GetNumberOfButtons() : 0 );
647 }
648
649 PyObject* SCA_JoystickSensor::pyattr_get_num_hats(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
650 {
651         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
652         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
653         return PyInt_FromLong( joy ? joy->GetNumberOfHats() : 0 );
654 }
655
656 PyObject* SCA_JoystickSensor::pyattr_get_connected(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
657 {
658         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
659         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
660         return PyBool_FromLong( joy ? joy->Connected() : 0 );
661 }