d0dc875da0b8c2a5d01a927dc623bfbe47a09132
[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                                                                            PyTypeObject* T )
51                                                                            :SCA_ISensor(gameobj,eventmgr,T),
52                                                                            m_pJoystickMgr(eventmgr),
53                                                                            m_axis(axis),
54                                                                            m_axisf(axisf),
55                                                                            m_button(button),
56                                                                            m_hat(hat),
57                                                                            m_hatf(hatf),
58                                                                            m_precision(prec),
59                                                                            m_joymode(joymode),
60                                                                            m_joyindex(joyindex),
61                                                                            m_bAllEvents(allevents)
62 {       
63 /*
64 std::cout << " axis "           << m_axis               << std::endl;
65 std::cout << " axis flag "      << m_axisf              << std::endl;
66 std::cout << " precision "      << m_precision  << std::endl;
67 std::cout << " button "         << m_button     << std::endl;
68 std::cout << " hat "            << m_hat                << std::endl;
69 std::cout << " hat flag "       << m_hatf               << std::endl;
70 */
71         Init();
72 }
73
74 void SCA_JoystickSensor::Init()
75 {
76         m_istrig=(m_invert)?1: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         CValue::AddDataToReplica(replica);
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(CValue* event)
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 == 0 == right
120                         m_axisf == 1 == up
121                         m_axisf == 2 == left
122                         m_axisf == 3 == down
123                         numberof== m_axis  -- max 2
124                         */
125                         
126                         if (!js->IsTrigAxis() && !reset) /* No events from SDL? - dont bother */
127                                 return false;
128                         
129                         js->cSetPrecision(m_precision);
130                         if (m_bAllEvents) {
131                                 if(js->aAnyAxisIsPositive(m_axis)){
132                                         m_istrig = 1;
133                                         result = true;
134                                 }else{
135                                         if(m_istrig){
136                                                 m_istrig = 0;
137                                                 result = true;
138                                         }
139                                 }
140                         }
141                         else if(m_axisf == 1){
142                                 if(js->aUpAxisIsPositive(m_axis)){
143                                         m_istrig = 1;
144                                         result = true;
145                                 }else{
146                                         if(m_istrig){
147                                                 m_istrig = 0;
148                                                 result = true;
149                                         }
150                                 }
151                         }
152                         else if(m_axisf == 3){
153                                 if(js->aDownAxisIsPositive(m_axis)){
154                                         m_istrig = 1;
155                                         result = true;
156                                 }else{
157                                         if(m_istrig){
158                                                 m_istrig = 0;
159                                                 result = true;
160                                         }
161                                 }
162                         }
163                         else if(m_axisf == 2){
164                                 if(js->aLeftAxisIsPositive(m_axis)){
165                                         m_istrig = 1;
166                                         result = true;
167                                 }else{
168                                         if(m_istrig){
169                                                 m_istrig = 0;
170                                                 result = true;
171                                         }
172                                 }
173                         }
174                         else if(m_axisf == 0){
175                                 if(js->aRightAxisIsPositive(m_axis)){
176                                         m_istrig = 1;
177                                         result = true;
178                                 }else{
179                                         if(m_istrig){
180                                                 m_istrig = 0;
181                                                 result = true;
182                                         }
183                                 }
184                         }
185                         break;
186                 }
187         case KX_JOYSENSORMODE_BUTTON:
188                 {
189                 /* what is what!
190                         m_button = the actual button in question
191                         */
192                         if (!js->IsTrigButton() && !reset) /* No events from SDL? - dont bother */
193                                 return false;
194                         
195                         if(( m_bAllEvents && js->aAnyButtonPressIsPositive()) || (!m_bAllEvents && js->aButtonPressIsPositive(m_button))) {
196                                 m_istrig = 1;
197                                 result = true;
198                         }else {
199                                 if(m_istrig){
200                                         m_istrig = 0;
201                                         result = true;
202                                 }
203                         }
204                         break;
205                 }
206         case KX_JOYSENSORMODE_HAT:
207                 {
208                 /* what is what!
209                         numberof = m_hat  -- max 2
210                         direction= m_hatf -- max 12
211                         */
212                         
213                         if (!js->IsTrigHat() && !reset) /* No events from SDL? - dont bother */
214                                 return false;
215                         
216                         if(m_hat == 1){
217                                 if(js->aHatIsPositive(m_hatf)){
218                                         m_istrig = 1;
219                                         result = true;
220                                 }else{
221                                         if(m_istrig){
222                                                 m_istrig = 0;
223                                                 result = true;
224                                         }
225                                 }
226                         }
227                         if(m_hat == 2){
228                                 if(js->aHatIsPositive(m_hatf)){
229                                         m_istrig = 1;
230                                         result = true;
231                                 }else{
232                                         if(m_istrig){
233                                                 m_istrig = 0;
234                                                 result = true;
235                                         }
236                                 }
237                         }
238                         break;
239                 }
240                 /* test for ball anyone ?*/
241         default:
242                 printf("Error invalid switch statement\n");
243                 break;
244         }
245         
246         /* if not all events are enabled, only send a positive pulse when 
247          * the button state changes */
248         if (!m_bAllEvents) {
249                 if (m_istrig_prev == m_istrig) {
250                         result = false;
251                 } else {
252                         m_istrig_prev = m_istrig;
253                 }
254         }
255         
256         if (reset)
257                 result = true;
258         
259         return result;
260 }
261
262
263 bool SCA_JoystickSensor::isValid(SCA_JoystickSensor::KX_JOYSENSORMODE m)
264 {
265         bool res = false;
266         res = ((m > KX_JOYSENSORMODE_NODEF) && (m < KX_JOYSENSORMODE_MAX));
267         return res;
268 }
269
270
271 /* ------------------------------------------------------------------------- */
272 /* Python functions                                                                                                              */
273 /* ------------------------------------------------------------------------- */
274
275 /* Integration hooks ------------------------------------------------------- */
276 PyTypeObject SCA_JoystickSensor::Type = {
277         PyObject_HEAD_INIT(&PyType_Type)
278                 0,
279                 "SCA_JoystickSensor",
280                 sizeof(SCA_JoystickSensor),
281                 0,
282                 PyDestructor,
283                 0,
284                 __getattr,
285                 __setattr,
286                 0, //&MyPyCompare,
287                 __repr,
288                 0, //&cvalue_as_number,
289                 0,
290                 0,
291                 0,
292                 0
293 };
294
295
296 PyParentObject SCA_JoystickSensor::Parents[] = {
297                 &SCA_JoystickSensor::Type,
298                 &SCA_ISensor::Type,
299                 &SCA_ILogicBrick::Type,
300                 &CValue::Type,
301                 NULL
302 };
303
304
305 PyMethodDef SCA_JoystickSensor::Methods[] = {
306         {"getIndex",     (PyCFunction) SCA_JoystickSensor::sPyGetIndex,         METH_NOARGS,    (PY_METHODCHAR)GetIndex_doc},
307         {"setIndex",     (PyCFunction) SCA_JoystickSensor::sPySetIndex,         METH_O,                 (PY_METHODCHAR)SetIndex_doc},
308         {"getAxis",      (PyCFunction) SCA_JoystickSensor::sPyGetAxis,          METH_NOARGS,    (PY_METHODCHAR)GetAxis_doc},
309         {"setAxis",      (PyCFunction) SCA_JoystickSensor::sPySetAxis,          METH_VARARGS,   (PY_METHODCHAR)SetAxis_doc},
310         {"getAxisValue", (PyCFunction) SCA_JoystickSensor::sPyGetAxisValue,     METH_NOARGS,    (PY_METHODCHAR)GetAxisValue_doc},
311         {"getThreshold", (PyCFunction) SCA_JoystickSensor::sPyGetThreshold, METH_NOARGS,        (PY_METHODCHAR)GetThreshold_doc},
312         {"setThreshold", (PyCFunction) SCA_JoystickSensor::sPySetThreshold, METH_VARARGS,       (PY_METHODCHAR)SetThreshold_doc},
313         {"getButton",    (PyCFunction) SCA_JoystickSensor::sPyGetButton,        METH_NOARGS,    (PY_METHODCHAR)GetButton_doc},
314         {"setButton",    (PyCFunction) SCA_JoystickSensor::sPySetButton,        METH_O,                 (PY_METHODCHAR)SetButton_doc},
315         {"getButtonValue",(PyCFunction) SCA_JoystickSensor::sPyGetButtonValue,  METH_NOARGS,(PY_METHODCHAR)GetButtonValue_doc},
316         {"getHat",               (PyCFunction) SCA_JoystickSensor::sPyGetHat,           METH_NOARGS,    (PY_METHODCHAR)GetHat_doc},
317         {"setHat",               (PyCFunction) SCA_JoystickSensor::sPySetHat,           METH_VARARGS,   (PY_METHODCHAR)SetHat_doc},
318         {"getNumAxes",   (PyCFunction) SCA_JoystickSensor::sPyNumberOfAxes,     METH_NOARGS,    (PY_METHODCHAR)NumberOfAxes_doc},
319         {"getNumButtons",(PyCFunction) SCA_JoystickSensor::sPyNumberOfButtons,METH_NOARGS,      (PY_METHODCHAR)NumberOfButtons_doc},
320         {"getNumHats",   (PyCFunction) SCA_JoystickSensor::sPyNumberOfHats,     METH_NOARGS,    (PY_METHODCHAR)NumberOfHats_doc},
321         {"isConnected", (PyCFunction) SCA_JoystickSensor::sPyConnected,         METH_NOARGS,    (PY_METHODCHAR)Connected_doc},
322         {NULL,NULL} //Sentinel
323 };
324
325
326 PyObject* SCA_JoystickSensor::_getattr(const STR_String& attr) {
327         _getattr_up(SCA_ISensor);
328 }
329
330
331 /* get index ---------------------------------------------------------- */
332 const char SCA_JoystickSensor::GetIndex_doc[] = 
333 "getIndex\n"
334 "\tReturns the joystick index to use.\n";
335 PyObject* SCA_JoystickSensor::PyGetIndex( PyObject* self ) {
336         return PyInt_FromLong(m_joyindex);
337 }
338
339
340 /* set index ---------------------------------------------------------- */
341 const char SCA_JoystickSensor::SetIndex_doc[] = 
342 "setIndex\n"
343 "\tSets the joystick index to use.\n";
344 PyObject* SCA_JoystickSensor::PySetIndex( PyObject* self, PyObject* value ) {
345         int index = PyInt_AsLong( value ); /* -1 on error, will raise an error in this case */
346         if (index < 0 || index >= JOYINDEX_MAX) {
347                 PyErr_SetString(PyExc_ValueError, "joystick index out of range or not an int");
348                 return NULL;
349         }
350         
351         m_joyindex = index;
352         Py_RETURN_NONE;
353 }
354
355 /* get axis  ---------------------------------------------------------- */
356 const char SCA_JoystickSensor::GetAxis_doc[] = 
357 "getAxis\n"
358 "\tReturns the current axis this sensor reacts to.\n";
359 PyObject* SCA_JoystickSensor::PyGetAxis( PyObject* self) {
360         return Py_BuildValue("[ii]",m_axis, m_axisf);
361 }
362
363
364 /* set axis  ---------------------------------------------------------- */
365 const char SCA_JoystickSensor::SetAxis_doc[] = 
366 "setAxis\n"
367 "\tSets the current axis this sensor reacts to.\n";
368 PyObject* SCA_JoystickSensor::PySetAxis( PyObject* self, PyObject* args ) {
369         
370         int axis,axisflag;
371         if(!PyArg_ParseTuple(args, "ii", &axis, &axisflag)){
372                 return NULL;
373         }
374         m_axis = axis;
375         m_axisf = axisflag;
376         Py_RETURN_NONE;
377 }
378
379
380 /* get axis value ----------------------------------------------------- */
381 const char SCA_JoystickSensor::GetAxisValue_doc[] = 
382 "getAxisValue\n"
383 "\tReturns a list of the values for the current state of each axis.\n";
384 PyObject* SCA_JoystickSensor::PyGetAxisValue( PyObject* self) {
385         SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
386         if(joy)
387                 return Py_BuildValue("[iiii]", joy->GetAxis10(), joy->GetAxis11(), joy->GetAxis20(), joy->GetAxis21());
388         else
389                 return Py_BuildValue("[iiii]", 0, 0, 0, 0);
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( PyObject* self) {
398         return PyInt_FromLong(m_precision);
399 }
400
401
402 /* set threshold  ----------------------------------------------------- */
403 const char SCA_JoystickSensor::SetThreshold_doc[] = 
404 "setThreshold\n"
405 "\tSets the threshold of the axis.\n";
406 PyObject* SCA_JoystickSensor::PySetThreshold( PyObject* self, PyObject* args ) {
407         int thresh;
408         if(!PyArg_ParseTuple(args, "i", &thresh)){
409                 return NULL;
410         }
411         m_precision = thresh;
412         Py_RETURN_NONE;
413 }
414
415 /* get button  -------------------------------------------------------- */
416 const char SCA_JoystickSensor::GetButton_doc[] = 
417 "getButton\n"
418 "\tReturns the current button this sensor is checking.\n";
419 PyObject* SCA_JoystickSensor::PyGetButton( PyObject* self) {
420         return PyInt_FromLong(m_button);
421 }
422
423 /* set button  -------------------------------------------------------- */
424 const char SCA_JoystickSensor::SetButton_doc[] = 
425 "setButton\n"
426 "\tSets the button the sensor reacts to.\n";
427 PyObject* SCA_JoystickSensor::PySetButton( PyObject* self, PyObject* value ) {
428         int button = PyInt_AsLong(value);
429         if(button==-1 && PyErr_Occurred()) {
430                 PyErr_SetString(PyExc_ValueError, "expected an int");
431                 return NULL;
432         }
433         m_button = button;
434         Py_RETURN_NONE; 
435 }
436
437 /* get button value  -------------------------------------------------- */
438 const char SCA_JoystickSensor::GetButtonValue_doc[] = 
439 "getButtonValue\n"
440 "\tReturns a list containing the indicies of the current pressed state of each button.\n";
441 PyObject* SCA_JoystickSensor::PyGetButtonValue( PyObject* self) {
442         SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
443         PyObject *ls = PyList_New(0);
444         PyObject *value;
445         int i;
446         
447         if(joy) {
448                 for (i=0; i < joy->GetNumberOfButtons(); i++) {
449                         if (joy->aButtonPressIsPositive(i)) {
450                                 value = PyInt_FromLong(i);
451                                 PyList_Append(ls, value);
452                                 Py_DECREF(value);
453                         }
454                 }
455         }
456         return ls;
457 }
458
459 /* get hat      ----------------------------------------------------------- */
460 const char SCA_JoystickSensor::GetHat_doc[] = 
461 "getHat\n"
462 "\tReturns the current direction of the hat.\n";
463 PyObject* SCA_JoystickSensor::PyGetHat( PyObject* self ) {
464         return Py_BuildValue("[ii]",m_hat, m_hatf);
465 }
466
467
468 /* set hat      ----------------------------------------------------------- */
469 const char SCA_JoystickSensor::SetHat_doc[] = 
470 "setHat\n"
471 "\tSets the hat the sensor reacts to.\n";
472 PyObject* SCA_JoystickSensor::PySetHat( PyObject* self, PyObject* args ) {
473         int hat,hatflag;
474         if(!PyArg_ParseTuple(args, "ii", &hat, &hatflag)){
475                 return NULL;
476         }
477         m_hat = hat;
478         m_hatf = hatflag;
479         Py_RETURN_NONE;
480 }
481
482
483 /* get # of ----------------------------------------------------- */
484 const char SCA_JoystickSensor::NumberOfAxes_doc[] = 
485 "getNumAxes\n"
486 "\tReturns the number of axes .\n";
487 PyObject* SCA_JoystickSensor::PyNumberOfAxes( PyObject* self ) {
488         SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
489         // when the joystick is null their is 0 exis still. dumb but scripters should use isConnected()
490         return PyInt_FromLong( joy ? joy->GetNumberOfAxes() : 0 );
491 }
492
493
494 const char SCA_JoystickSensor::NumberOfButtons_doc[] = 
495 "getNumButtons\n"
496 "\tReturns the number of buttons .\n";
497 PyObject* SCA_JoystickSensor::PyNumberOfButtons( PyObject* self ) {
498         SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
499         return PyInt_FromLong( joy ? joy->GetNumberOfButtons() : 0 );
500 }
501
502
503 const char SCA_JoystickSensor::NumberOfHats_doc[] = 
504 "getNumHats\n"
505 "\tReturns the number of hats .\n";
506 PyObject* SCA_JoystickSensor::PyNumberOfHats( PyObject* self ) {
507         SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
508         return PyInt_FromLong( joy ? joy->GetNumberOfHats() : 0 );
509 }
510
511 const char SCA_JoystickSensor::Connected_doc[] = 
512 "getConnected\n"
513 "\tReturns True if a joystick is connected at this joysticks index.\n";
514 PyObject* SCA_JoystickSensor::PyConnected( PyObject* self ) {
515         SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
516         return PyBool_FromLong( joy ? joy->Connected() : 0 );
517 }