py api cleanup, replace use...
[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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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
28 /** \file gameengine/GameLogic/SCA_JoystickSensor.cpp
29  *  \ingroup gamelogic
30  */
31
32 #include "SCA_JoystickManager.h"
33 #include "SCA_JoystickSensor.h"
34
35 #include "SCA_EventManager.h"
36 #include "SCA_LogicManager.h"
37
38 #include "PyObjectPlus.h"
39
40 #include <stdio.h>
41 #include <stddef.h>
42 #include <iostream>
43
44
45
46 SCA_JoystickSensor::SCA_JoystickSensor(class SCA_JoystickManager* eventmgr,
47                                                                            SCA_IObject* gameobj,
48                                                                            short int joyindex,
49                                                                            short int joymode,
50                                                                            int axis, int axisf,int prec,
51                                                                            int button,
52                                                                            int hat, int hatf, bool allevents)
53                                                                            :SCA_ISensor(gameobj,eventmgr),
54                                                                            m_axis(axis),
55                                                                            m_axisf(axisf),
56                                                                            m_button(button),
57                                                                            m_hat(hat),
58                                                                            m_hatf(hatf),
59                                                                            m_precision(prec),
60                                                                            m_joymode(joymode),
61                                                                            m_joyindex(joyindex),
62                                                                            m_bAllEvents(allevents)
63 {
64 /*
65 std::cout << " axis "           << m_axis               << std::endl;
66 std::cout << " axis flag "      << m_axisf              << std::endl;
67 std::cout << " precision "      << m_precision  << std::endl;
68 std::cout << " button "         << m_button     << std::endl;
69 std::cout << " hat "            << m_hat                << std::endl;
70 std::cout << " hat flag "       << m_hatf               << std::endl;
71 */
72         Init();
73 }
74
75 void SCA_JoystickSensor::Init()
76 {
77         m_istrig=(m_invert)?1:0;
78         m_istrig_prev=0;
79         m_reset = true;
80 }
81
82 SCA_JoystickSensor::~SCA_JoystickSensor()
83 {
84 }
85
86
87 CValue* SCA_JoystickSensor::GetReplica()
88 {
89         SCA_JoystickSensor* replica = new SCA_JoystickSensor(*this);
90         // this will copy properties and so on...
91         replica->ProcessReplica();
92         replica->Init();
93         return replica;
94 }
95
96
97 bool SCA_JoystickSensor::IsPositiveTrigger()
98
99         bool result =   m_istrig;
100         if (m_invert)
101                 result = !result;
102         return result;
103 }
104
105
106 bool SCA_JoystickSensor::Evaluate()
107 {
108         SCA_Joystick *js = ((SCA_JoystickManager *)m_eventmgr)->GetJoystickDevice(m_joyindex);
109         bool result = false;
110         bool reset = m_reset && m_level;
111         
112         if (js==NULL) /* no joystick - don't do anything */
113                 return false;
114         
115         m_reset = false;
116
117         switch (m_joymode) {
118                 case KX_JOYSENSORMODE_AXIS:
119                 {
120                         /* what is what!
121                          *  m_axisf == JOYAXIS_RIGHT, JOYAXIS_UP, JOYAXIS_DOWN, JOYAXIS_LEFT
122                          *  m_axisf == 1 == up
123                          *  m_axisf == 2 == left
124                          *  m_axisf == 3 == down
125                          *
126                          *  numberof== m_axis (1-4), range is half of JOYAXIS_MAX since
127                          *      it assumes the axis joysticks are axis parirs (0,1), (2,3), etc
128                          *      also note that this starts at 1 where functions its used
129                          *      with expect a zero index.
130                          */
131                         
132                         if (!js->IsTrigAxis() && !reset) /* No events from SDL? - don't bother */
133                                 return false;
134                         
135                         js->cSetPrecision(m_precision);
136                         if (m_bAllEvents) {
137                                 if (js->aAxisPairIsPositive(m_axis-1)) { /* use zero based axis index internally */
138                                         m_istrig = 1;
139                                         result = true;
140                                 }
141                                 else {
142                                         if (m_istrig) {
143                                                 m_istrig = 0;
144                                                 result = true;
145                                         }
146                                 }
147                         }
148                         else {
149                                 if (js->aAxisPairDirectionIsPositive(m_axis-1, m_axisf)) { /* use zero based axis index internally */
150                                         m_istrig = 1;
151                                         result = true;
152                                 }
153                                 else {
154                                         if (m_istrig) {
155                                                 m_istrig = 0;
156                                                 result = true;
157                                         }
158                                 }
159                         }
160                         break;
161                 }
162                 case KX_JOYSENSORMODE_AXIS_SINGLE:
163                 {
164                         /* Like KX_JOYSENSORMODE_AXIS but don't pair up axis */
165                         if (!js->IsTrigAxis() && !reset) /* No events from SDL? - don't bother */
166                                 return false;
167                         
168                         /* No need for 'm_bAllEvents' check here since were only checking 1 axis */
169                         js->cSetPrecision(m_precision);
170                         if (js->aAxisIsPositive(m_axis-1)) { /* use zero based axis index internally */
171                                 m_istrig = 1;
172                                 result = true;
173                         }
174                         else {
175                                 if (m_istrig) {
176                                         m_istrig = 0;
177                                         result = true;
178                                 }
179                         }
180                         break;
181                 }
182
183                 case KX_JOYSENSORMODE_BUTTON:
184                 {
185                         /* what is what!
186                          *  m_button = the actual button in question
187                          */
188                         if (!js->IsTrigButton() && !reset) /* No events from SDL? - don't bother */
189                                 return false;
190                         
191                         if (( m_bAllEvents && js->aAnyButtonPressIsPositive()) || (!m_bAllEvents && js->aButtonPressIsPositive(m_button))) {
192                                 m_istrig = 1;
193                                 result = true;
194                         }
195                         else {
196                                 if (m_istrig) {
197                                         m_istrig = 0;
198                                         result = true;
199                                 }
200                         }
201                         break;
202                 }
203                 case KX_JOYSENSORMODE_HAT:
204                 {
205                         /* what is what!
206                          *  numberof = m_hat  -- max 4
207                          *  direction= m_hatf -- max 12
208                          */
209                         
210                         if (!js->IsTrigHat() && !reset) /* No events from SDL? - don't bother */
211                                 return false;
212                         
213                         if ((m_bAllEvents && js->GetHat(m_hat-1)) || js->aHatIsPositive(m_hat-1, m_hatf)) {
214                                 m_istrig = 1;
215                                 result = true;
216                         }
217                         else {
218                                 if (m_istrig) {
219                                         m_istrig = 0;
220                                         result = true;
221                                 }
222                         }
223                         break;
224                 }
225                         /* test for ball anyone ?*/
226                 default:
227                         printf("Error invalid switch statement\n");
228                         break;
229         }
230         
231         /* if not all events are enabled, only send a positive pulse when
232          * the button state changes */
233         if (!m_bAllEvents) {
234                 if (m_istrig_prev == m_istrig) {
235                         result = false;
236                 }
237                 else {
238                         m_istrig_prev = m_istrig;
239                 }
240         }
241         
242         if (reset)
243                 result = true;
244         
245         return result;
246 }
247
248
249 bool SCA_JoystickSensor::isValid(SCA_JoystickSensor::KX_JOYSENSORMODE m)
250 {
251         bool res = false;
252         res = ((m > KX_JOYSENSORMODE_NODEF) && (m < KX_JOYSENSORMODE_MAX));
253         return res;
254 }
255
256 #ifdef WITH_PYTHON
257
258 /* ------------------------------------------------------------------------- */
259 /* Python functions                                                                                                              */
260 /* ------------------------------------------------------------------------- */
261
262 /* Integration hooks ------------------------------------------------------- */
263 PyTypeObject SCA_JoystickSensor::Type = {
264         PyVarObject_HEAD_INIT(NULL, 0)
265         "SCA_JoystickSensor",
266         sizeof(PyObjectPlus_Proxy),
267         0,
268         py_base_dealloc,
269         0,
270         0,
271         0,
272         0,
273         py_base_repr,
274         0,0,0,0,0,0,0,0,0,
275         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
276         0,0,0,0,0,0,0,
277         Methods,
278         0,
279         0,
280         &SCA_ISensor::Type,
281         0,0,0,0,0,0,
282         py_base_new
283 };
284
285 PyMethodDef SCA_JoystickSensor::Methods[] = {
286         {"getButtonActiveList",(PyCFunction) SCA_JoystickSensor::sPyGetButtonActiveList,        METH_NOARGS,(const char *)GetButtonActiveList_doc},
287         {"getButtonStatus",(PyCFunction) SCA_JoystickSensor::sPyGetButtonStatus,        METH_VARARGS,(const char *)GetButtonStatus_doc},
288         {NULL,NULL} //Sentinel
289 };
290
291 PyAttributeDef SCA_JoystickSensor::Attributes[] = {
292         KX_PYATTRIBUTE_SHORT_RW("index",0,JOYINDEX_MAX-1,true,SCA_JoystickSensor,m_joyindex),
293         KX_PYATTRIBUTE_INT_RW("threshold",0,32768,true,SCA_JoystickSensor,m_precision),
294         KX_PYATTRIBUTE_INT_RW("button",0,100,false,SCA_JoystickSensor,m_button),
295         KX_PYATTRIBUTE_INT_LIST_RW_CHECK("axis",0,3,true,SCA_JoystickSensor,m_axis,2,CheckAxis),
296         KX_PYATTRIBUTE_INT_LIST_RW_CHECK("hat",0,12,true,SCA_JoystickSensor,m_hat,2,CheckHat),
297         KX_PYATTRIBUTE_RO_FUNCTION("axisValues",        SCA_JoystickSensor, pyattr_get_axis_values),
298         KX_PYATTRIBUTE_RO_FUNCTION("axisSingle", SCA_JoystickSensor, pyattr_get_axis_single),
299         KX_PYATTRIBUTE_RO_FUNCTION("hatValues", SCA_JoystickSensor, pyattr_get_hat_values),
300         KX_PYATTRIBUTE_RO_FUNCTION("hatSingle", SCA_JoystickSensor, pyattr_get_hat_single),
301         KX_PYATTRIBUTE_RO_FUNCTION("numAxis",           SCA_JoystickSensor, pyattr_get_num_axis),
302         KX_PYATTRIBUTE_RO_FUNCTION("numButtons",        SCA_JoystickSensor, pyattr_get_num_buttons),
303         KX_PYATTRIBUTE_RO_FUNCTION("numHats",           SCA_JoystickSensor, pyattr_get_num_hats),
304         KX_PYATTRIBUTE_RO_FUNCTION("connected",         SCA_JoystickSensor, pyattr_get_connected),
305         { NULL }        //Sentinel
306 };
307
308 /* get button active list  -------------------------------------------------- */
309 const char SCA_JoystickSensor::GetButtonActiveList_doc[] = 
310 "getButtonActiveList\n"
311 "\tReturns a list containing the indices of the button currently pressed.\n";
312 PyObject *SCA_JoystickSensor::PyGetButtonActiveList( )
313 {
314         SCA_Joystick *joy = ((SCA_JoystickManager *)m_eventmgr)->GetJoystickDevice(m_joyindex);
315         PyObject *ls = PyList_New(0);
316         PyObject *value;
317         int i;
318         
319         if (joy) {
320                 for (i=0; i < joy->GetNumberOfButtons(); i++) {
321                         if (joy->aButtonPressIsPositive(i)) {
322                                 value = PyLong_FromLong(i);
323                                 PyList_Append(ls, value);
324                                 Py_DECREF(value);
325                         }
326                 }
327         }
328         return ls;
329 }
330
331 /* get button status  -------------------------------------------------- */
332 const char SCA_JoystickSensor::GetButtonStatus_doc[] = 
333 "getButtonStatus(buttonIndex)\n"
334 "\tReturns a bool of the current pressed state of the specified button.\n";
335 PyObject *SCA_JoystickSensor::PyGetButtonStatus( PyObject *args )
336 {
337         SCA_Joystick *joy = ((SCA_JoystickManager *)m_eventmgr)->GetJoystickDevice(m_joyindex);
338         int index;
339         
340         if (!PyArg_ParseTuple(args, "i:getButtonStatus", &index)) {
341                 return NULL;
342         }
343         if (joy && index >= 0 && index < joy->GetNumberOfButtons()) {
344                 return PyBool_FromLong(joy->aButtonPressIsPositive(index) ? 1 : 0);
345         }
346         return PyBool_FromLong(0);
347 }
348
349 PyObject *SCA_JoystickSensor::pyattr_get_axis_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
350 {
351         SCA_JoystickSensor* self = static_cast<SCA_JoystickSensor*>(self_v);
352         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
353         
354         int axis_index= joy->GetNumberOfAxes();
355         PyObject *list= PyList_New(axis_index);
356         
357         while (axis_index--) {
358                 PyList_SET_ITEM(list, axis_index, PyLong_FromLong(joy->GetAxisPosition(axis_index)));
359         }
360         
361         return list;
362 }
363
364 PyObject *SCA_JoystickSensor::pyattr_get_axis_single(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
365 {
366         SCA_JoystickSensor* self = static_cast<SCA_JoystickSensor*>(self_v);
367         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
368         
369         if (self->m_joymode != KX_JOYSENSORMODE_AXIS_SINGLE) {
370                 PyErr_SetString(PyExc_TypeError, "val = sensor.axisSingle: Joystick Sensor, not 'Single Axis' type");
371                 return NULL;
372         }
373         
374         return PyLong_FromLong(joy->GetAxisPosition(self->m_axis-1));
375 }
376
377 PyObject *SCA_JoystickSensor::pyattr_get_hat_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
378 {
379         SCA_JoystickSensor* self = static_cast<SCA_JoystickSensor*>(self_v);
380         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
381         
382         int hat_index= joy->GetNumberOfHats();
383         PyObject *list= PyList_New(hat_index);
384         
385         while (hat_index--) {
386                 PyList_SET_ITEM(list, hat_index, PyLong_FromLong(joy->GetHat(hat_index)));
387         }
388         
389         return list;
390 }
391
392 PyObject *SCA_JoystickSensor::pyattr_get_hat_single(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
393 {
394         SCA_JoystickSensor* self = static_cast<SCA_JoystickSensor*>(self_v);
395         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
396         
397         return PyLong_FromLong(joy->GetHat(self->m_hat-1));
398 }
399
400 PyObject *SCA_JoystickSensor::pyattr_get_num_axis(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
401 {
402         SCA_JoystickSensor* self = static_cast<SCA_JoystickSensor*>(self_v);
403         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
404         return PyLong_FromLong( joy ? joy->GetNumberOfAxes() : 0 );
405 }
406
407 PyObject *SCA_JoystickSensor::pyattr_get_num_buttons(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
408 {
409         SCA_JoystickSensor* self = static_cast<SCA_JoystickSensor*>(self_v);
410         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
411         return PyLong_FromLong( joy ? joy->GetNumberOfButtons() : 0 );
412 }
413
414 PyObject *SCA_JoystickSensor::pyattr_get_num_hats(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
415 {
416         SCA_JoystickSensor* self = static_cast<SCA_JoystickSensor*>(self_v);
417         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
418         return PyLong_FromLong( joy ? joy->GetNumberOfHats() : 0 );
419 }
420
421 PyObject *SCA_JoystickSensor::pyattr_get_connected(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
422 {
423         SCA_JoystickSensor* self = static_cast<SCA_JoystickSensor*>(self_v);
424         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
425         return PyBool_FromLong( joy ? joy->Connected() : 0 );
426 }
427
428 #endif