Blender  V2.59
SCA_JoystickSensor.cpp
Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): none yet.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00032 #include "SCA_JoystickManager.h"
00033 #include "SCA_JoystickSensor.h"
00034 
00035 #include "SCA_EventManager.h"
00036 #include "SCA_LogicManager.h"
00037 
00038 #include "PyObjectPlus.h"
00039 
00040 #include <stdio.h>
00041 #include <stddef.h>
00042 #include <iostream>
00043 
00044 
00045 
00046 SCA_JoystickSensor::SCA_JoystickSensor(class SCA_JoystickManager* eventmgr,
00047                                                                            SCA_IObject* gameobj,
00048                                                                            short int joyindex,
00049                                                                            short int joymode,
00050                                                                            int axis, int axisf,int prec,
00051                                                                            int button,
00052                                                                            int hat, int hatf, bool allevents)
00053                                                                            :SCA_ISensor(gameobj,eventmgr),
00054                                                                            m_axis(axis),
00055                                                                            m_axisf(axisf),
00056                                                                            m_button(button),
00057                                                                            m_hat(hat),
00058                                                                            m_hatf(hatf),
00059                                                                            m_precision(prec),
00060                                                                            m_joymode(joymode),
00061                                                                            m_joyindex(joyindex),
00062                                                                            m_bAllEvents(allevents)
00063 {       
00064 /*
00065 std::cout << " axis "           << m_axis               << std::endl;
00066 std::cout << " axis flag "      << m_axisf              << std::endl;
00067 std::cout << " precision "      << m_precision  << std::endl;
00068 std::cout << " button "         << m_button     << std::endl;
00069 std::cout << " hat "            << m_hat                << std::endl;
00070 std::cout << " hat flag "       << m_hatf               << std::endl;
00071 */
00072         Init();
00073 }
00074 
00075 void SCA_JoystickSensor::Init()
00076 {
00077         m_istrig=(m_invert)?1:0;
00078         m_istrig_prev=0;
00079         m_reset = true;
00080 }
00081 
00082 SCA_JoystickSensor::~SCA_JoystickSensor()
00083 {
00084 }
00085 
00086 
00087 CValue* SCA_JoystickSensor::GetReplica()
00088 {
00089         SCA_JoystickSensor* replica = new SCA_JoystickSensor(*this);
00090         // this will copy properties and so on...
00091         replica->ProcessReplica();
00092         replica->Init();
00093         return replica;
00094 }
00095 
00096 
00097 bool SCA_JoystickSensor::IsPositiveTrigger()
00098 { 
00099         bool result =   m_istrig;
00100         if (m_invert)
00101                 result = !result;
00102         return result;
00103 }
00104 
00105 
00106 bool SCA_JoystickSensor::Evaluate()
00107 {
00108         SCA_Joystick *js = ((SCA_JoystickManager *)m_eventmgr)->GetJoystickDevice(m_joyindex);
00109         bool result = false;
00110         bool reset = m_reset && m_level;
00111         
00112         if(js==NULL) /* no joystick - dont do anything */
00113                 return false;
00114         
00115         m_reset = false;
00116         switch(m_joymode)
00117         {
00118         case KX_JOYSENSORMODE_AXIS:
00119                 {
00120                 /* what is what!
00121                         m_axisf == JOYAXIS_RIGHT, JOYAXIS_UP, JOYAXIS_DOWN, JOYAXIS_LEFT
00122                         m_axisf == 1 == up
00123                         m_axisf == 2 == left
00124                         m_axisf == 3 == down
00125                         
00126                         numberof== m_axis (1-4), range is half of JOYAXIS_MAX since 
00127                                 it assumes the axis joysticks are axis parirs (0,1), (2,3), etc
00128                                 also note that this starts at 1 where functions its used
00129                                 with expect a zero index.
00130                         */
00131                         
00132                         if (!js->IsTrigAxis() && !reset) /* No events from SDL? - dont bother */
00133                                 return false;
00134                         
00135                         js->cSetPrecision(m_precision);
00136                         if (m_bAllEvents) {
00137                                 if(js->aAxisPairIsPositive(m_axis-1)){ /* use zero based axis index internally */
00138                                         m_istrig = 1;
00139                                         result = true;
00140                                 }else{
00141                                         if(m_istrig){
00142                                                 m_istrig = 0;
00143                                                 result = true;
00144                                         }
00145                                 }
00146                         }
00147                         else {
00148                                 if(js->aAxisPairDirectionIsPositive(m_axis-1, m_axisf)){ /* use zero based axis index internally */
00149                                         m_istrig = 1;
00150                                         result = true;
00151                                 }else{
00152                                         if(m_istrig){
00153                                                 m_istrig = 0;
00154                                                 result = true;
00155                                         }
00156                                 }
00157                         }
00158                         break;
00159                 }
00160         case KX_JOYSENSORMODE_AXIS_SINGLE:
00161                 {
00162                         /* Like KX_JOYSENSORMODE_AXIS but dont pair up axis */
00163                         if (!js->IsTrigAxis() && !reset) /* No events from SDL? - dont bother */
00164                                 return false;
00165                         
00166                         /* No need for 'm_bAllEvents' check here since were only checking 1 axis */
00167                         js->cSetPrecision(m_precision);
00168                         if(js->aAxisIsPositive(m_axis-1)){ /* use zero based axis index internally */
00169                                 m_istrig = 1;
00170                                 result = true;
00171                         }else{
00172                                 if(m_istrig){
00173                                         m_istrig = 0;
00174                                         result = true;
00175                                 }
00176                         }
00177                         break;
00178                 }
00179                 
00180         case KX_JOYSENSORMODE_BUTTON:
00181                 {
00182                 /* what is what!
00183                         m_button = the actual button in question
00184                         */
00185                         if (!js->IsTrigButton() && !reset) /* No events from SDL? - dont bother */
00186                                 return false;
00187                         
00188                         if(( m_bAllEvents && js->aAnyButtonPressIsPositive()) || (!m_bAllEvents && js->aButtonPressIsPositive(m_button))) {
00189                                 m_istrig = 1;
00190                                 result = true;
00191                         }else {
00192                                 if(m_istrig){
00193                                         m_istrig = 0;
00194                                         result = true;
00195                                 }
00196                         }
00197                         break;
00198                 }
00199         case KX_JOYSENSORMODE_HAT:
00200                 {
00201                 /* what is what!
00202                         numberof = m_hat  -- max 4
00203                         direction= m_hatf -- max 12
00204                         */
00205                         
00206                         if (!js->IsTrigHat() && !reset) /* No events from SDL? - dont bother */
00207                                 return false;
00208                         
00209                         if((m_bAllEvents && js->GetHat(m_hat-1)) || js->aHatIsPositive(m_hat-1, m_hatf)) {
00210                                 m_istrig = 1;
00211                                 result = true;
00212                         }else{
00213                                 if(m_istrig){
00214                                         m_istrig = 0;
00215                                         result = true;
00216                                 }
00217                         }
00218                         break;
00219                 }
00220                 /* test for ball anyone ?*/
00221         default:
00222                 printf("Error invalid switch statement\n");
00223                 break;
00224         }
00225         
00226         /* if not all events are enabled, only send a positive pulse when 
00227          * the button state changes */
00228         if (!m_bAllEvents) {
00229                 if (m_istrig_prev == m_istrig) {
00230                         result = false;
00231                 } else {
00232                         m_istrig_prev = m_istrig;
00233                 }
00234         }
00235         
00236         if (reset)
00237                 result = true;
00238         
00239         return result;
00240 }
00241 
00242 
00243 bool SCA_JoystickSensor::isValid(SCA_JoystickSensor::KX_JOYSENSORMODE m)
00244 {
00245         bool res = false;
00246         res = ((m > KX_JOYSENSORMODE_NODEF) && (m < KX_JOYSENSORMODE_MAX));
00247         return res;
00248 }
00249 
00250 #ifdef WITH_PYTHON
00251 
00252 /* ------------------------------------------------------------------------- */
00253 /* Python functions                                                                                                              */
00254 /* ------------------------------------------------------------------------- */
00255 
00256 /* Integration hooks ------------------------------------------------------- */
00257 PyTypeObject SCA_JoystickSensor::Type = {
00258         PyVarObject_HEAD_INIT(NULL, 0)
00259         "SCA_JoystickSensor",
00260         sizeof(PyObjectPlus_Proxy),
00261         0,
00262         py_base_dealloc,
00263         0,
00264         0,
00265         0,
00266         0,
00267         py_base_repr,
00268         0,0,0,0,0,0,0,0,0,
00269         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
00270         0,0,0,0,0,0,0,
00271         Methods,
00272         0,
00273         0,
00274         &SCA_ISensor::Type,
00275         0,0,0,0,0,0,
00276         py_base_new
00277 };
00278 
00279 PyMethodDef SCA_JoystickSensor::Methods[] = {
00280         {"getButtonActiveList",(PyCFunction) SCA_JoystickSensor::sPyGetButtonActiveList,        METH_NOARGS,(const char *)GetButtonActiveList_doc},
00281         {"getButtonStatus",(PyCFunction) SCA_JoystickSensor::sPyGetButtonStatus,        METH_VARARGS,(const char *)GetButtonStatus_doc},
00282         {NULL,NULL} //Sentinel
00283 };
00284 
00285 PyAttributeDef SCA_JoystickSensor::Attributes[] = {
00286         KX_PYATTRIBUTE_SHORT_RW("index",0,JOYINDEX_MAX-1,true,SCA_JoystickSensor,m_joyindex),
00287         KX_PYATTRIBUTE_INT_RW("threshold",0,32768,true,SCA_JoystickSensor,m_precision),
00288         KX_PYATTRIBUTE_INT_RW("button",0,100,false,SCA_JoystickSensor,m_button),
00289         KX_PYATTRIBUTE_INT_LIST_RW_CHECK("axis",0,3,true,SCA_JoystickSensor,m_axis,2,CheckAxis),
00290         KX_PYATTRIBUTE_INT_LIST_RW_CHECK("hat",0,12,true,SCA_JoystickSensor,m_hat,2,CheckHat),
00291         KX_PYATTRIBUTE_RO_FUNCTION("axisValues",        SCA_JoystickSensor, pyattr_get_axis_values),
00292         KX_PYATTRIBUTE_RO_FUNCTION("axisSingle", SCA_JoystickSensor, pyattr_get_axis_single),
00293         KX_PYATTRIBUTE_RO_FUNCTION("hatValues", SCA_JoystickSensor, pyattr_get_hat_values),
00294         KX_PYATTRIBUTE_RO_FUNCTION("hatSingle", SCA_JoystickSensor, pyattr_get_hat_single),
00295         KX_PYATTRIBUTE_RO_FUNCTION("numAxis",           SCA_JoystickSensor, pyattr_get_num_axis),
00296         KX_PYATTRIBUTE_RO_FUNCTION("numButtons",        SCA_JoystickSensor, pyattr_get_num_buttons),
00297         KX_PYATTRIBUTE_RO_FUNCTION("numHats",           SCA_JoystickSensor, pyattr_get_num_hats),
00298         KX_PYATTRIBUTE_RO_FUNCTION("connected",         SCA_JoystickSensor, pyattr_get_connected),
00299         { NULL }        //Sentinel
00300 };
00301 
00302 /* get button active list  -------------------------------------------------- */
00303 const char SCA_JoystickSensor::GetButtonActiveList_doc[] = 
00304 "getButtonActiveList\n"
00305 "\tReturns a list containing the indices of the button currently pressed.\n";
00306 PyObject* SCA_JoystickSensor::PyGetButtonActiveList( ) {
00307         SCA_Joystick *joy = ((SCA_JoystickManager *)m_eventmgr)->GetJoystickDevice(m_joyindex);
00308         PyObject *ls = PyList_New(0);
00309         PyObject *value;
00310         int i;
00311         
00312         if(joy) {
00313                 for (i=0; i < joy->GetNumberOfButtons(); i++) {
00314                         if (joy->aButtonPressIsPositive(i)) {
00315                                 value = PyLong_FromSsize_t(i);
00316                                 PyList_Append(ls, value);
00317                                 Py_DECREF(value);
00318                         }
00319                 }
00320         }
00321         return ls;
00322 }
00323 
00324 /* get button status  -------------------------------------------------- */
00325 const char SCA_JoystickSensor::GetButtonStatus_doc[] = 
00326 "getButtonStatus(buttonIndex)\n"
00327 "\tReturns a bool of the current pressed state of the specified button.\n";
00328 PyObject* SCA_JoystickSensor::PyGetButtonStatus( PyObject* args ) {
00329         SCA_Joystick *joy = ((SCA_JoystickManager *)m_eventmgr)->GetJoystickDevice(m_joyindex);
00330         int index;
00331         
00332         if(!PyArg_ParseTuple(args, "i:getButtonStatus", &index)){
00333                 return NULL;
00334         }
00335         if(joy && index >= 0 && index < joy->GetNumberOfButtons()) {
00336                 return PyBool_FromLong(joy->aButtonPressIsPositive(index) ? 1 : 0);
00337         }
00338         return PyBool_FromLong(0);
00339 }
00340 
00341 PyObject* SCA_JoystickSensor::pyattr_get_axis_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
00342 {
00343         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
00344         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
00345         
00346         int axis_index= joy->GetNumberOfAxes();
00347         PyObject *list= PyList_New(axis_index);
00348         
00349         while(axis_index--) {
00350                 PyList_SET_ITEM(list, axis_index, PyLong_FromSsize_t(joy->GetAxisPosition(axis_index)));
00351         }
00352         
00353         return list;
00354 }
00355 
00356 PyObject* SCA_JoystickSensor::pyattr_get_axis_single(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
00357 {
00358         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
00359         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
00360         
00361         if(self->m_joymode != KX_JOYSENSORMODE_AXIS_SINGLE) {
00362                 PyErr_SetString(PyExc_TypeError, "val = sensor.axisSingle: Joystick Sensor, not 'Single Axis' type");
00363                 return NULL;
00364         }
00365         
00366         return PyLong_FromSsize_t(joy->GetAxisPosition(self->m_axis-1));
00367 }
00368 
00369 PyObject* SCA_JoystickSensor::pyattr_get_hat_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
00370 {
00371         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
00372         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
00373         
00374         int hat_index= joy->GetNumberOfHats();
00375         PyObject *list= PyList_New(hat_index);
00376         
00377         while(hat_index--) {
00378                 PyList_SET_ITEM(list, hat_index, PyLong_FromSsize_t(joy->GetHat(hat_index)));
00379         }
00380         
00381         return list;
00382 }
00383 
00384 PyObject* SCA_JoystickSensor::pyattr_get_hat_single(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
00385 {
00386         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
00387         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
00388         
00389         return PyLong_FromSsize_t(joy->GetHat(self->m_hat-1));
00390 }
00391 
00392 PyObject* SCA_JoystickSensor::pyattr_get_num_axis(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
00393 {
00394         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
00395         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
00396         return PyLong_FromSsize_t( joy ? joy->GetNumberOfAxes() : 0 );
00397 }
00398 
00399 PyObject* SCA_JoystickSensor::pyattr_get_num_buttons(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
00400 {
00401         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
00402         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
00403         return PyLong_FromSsize_t( joy ? joy->GetNumberOfButtons() : 0 );
00404 }
00405 
00406 PyObject* SCA_JoystickSensor::pyattr_get_num_hats(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
00407 {
00408         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
00409         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
00410         return PyLong_FromSsize_t( joy ? joy->GetNumberOfHats() : 0 );
00411 }
00412 
00413 PyObject* SCA_JoystickSensor::pyattr_get_connected(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
00414 {
00415         SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
00416         SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
00417         return PyBool_FromLong( joy ? joy->Connected() : 0 );
00418 }
00419 
00420 #endif