BGE patch approved: BGE Multiple Joysticks
authorBenoit Bolsee <benoit.bolsee@online.be>
Sun, 31 Aug 2008 18:42:58 +0000 (18:42 +0000)
committerBenoit Bolsee <benoit.bolsee@online.be>
Sun, 31 Aug 2008 18:42:58 +0000 (18:42 +0000)
source/blender/makesdna/DNA_sensor_types.h
source/blender/src/buttons_logic.c
source/gameengine/Converter/KX_ConvertSensors.cpp
source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
source/gameengine/GameLogic/Joystick/SCA_Joystick.h
source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h
source/gameengine/GameLogic/SCA_JoystickManager.cpp
source/gameengine/GameLogic/SCA_JoystickManager.h
source/gameengine/GameLogic/SCA_JoystickSensor.cpp
source/gameengine/GameLogic/SCA_JoystickSensor.h

index d508ff3a55292af7bfcfd7090d145abc366ce3e8..3e0075c00bde7a7c5b49c2a812dff27a519b56ff 100644 (file)
@@ -164,7 +164,7 @@ typedef struct bSensor {
 typedef struct bJoystickSensor {
        char name[32];
        short type;
-       short pad;
+       short joyindex;
        int axis;
        int axisf;
        int button;
@@ -266,6 +266,7 @@ typedef struct bJoystickSensor {
 #define SENS_JOY_HAT_DIR               0
 
 #define SENS_DELAY_REPEAT              1
-
+// should match JOYINDEX_MAX in SCA_JoystickDefines.h */
+#define SENS_JOY_MAXINDEX              8
 #endif
 
index 9b41b646bc8914f54c4967a169ab53a4bdd4673b..0b6986c2c8ef7d1f5dbc6b7e921c1fb20cba36a6 100644 (file)
@@ -1444,10 +1444,13 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short
                        draw_default_sensor_header(sens, block, xco, yco, width);
 
                        joy= sens->data;
-                       
+
+                       uiDefButS(block, NUM, 1, "Index:", xco+10, yco-44, 0.6 * (width-120), 19,
+                       &joy->joyindex, 0, SENS_JOY_MAXINDEX-1, 100, 0,
+                       "Spesify which joystick to use");                       
 
                        str= "Type %t|Button %x0|Axis %x1|Hat%x2"; 
-                       uiDefButS(block, MENU, B_REDR, str, xco+10, yco-44, 0.6 * (width-20), 19,
+                       uiDefButS(block, MENU, B_REDR, str, xco+87, yco-44, 0.6 * (width-150), 19,
                                &joy->type, 0, 31, 0, 0,
                                "The type of event this joystick sensor is triggered on.");
                        
index db47dc2dd3d7416e6356b8c1be6943741eb84cff..74819431858a3c03ab9a80ad1aacc0a1071f586a 100644 (file)
@@ -713,6 +713,7 @@ void BL_ConvertSensors(struct Object* blenderobject,
                                        gamesensor = new SCA_JoystickSensor(
                                                eventmgr,
                                                gameobj,
+                                               bjoy->joyindex,
                                                joysticktype,
                                                axis,axisf,
                                                prec,
index 18d7b6ffcd055a536c46bce27237f4ae57a74a0e..b244bddcacd1ec1baf6133320f256ed99187dd43 100644 (file)
@@ -29,9 +29,9 @@
 #include "SCA_Joystick.h"
 #include "SCA_JoystickPrivate.h"
 
-
-SCA_Joystick::SCA_Joystick()
+SCA_Joystick::SCA_Joystick(short int index)
        :
+       m_joyindex(index),
        m_axis10(0),
        m_axis11(0),
        m_axis20(0),
@@ -52,50 +52,53 @@ SCA_Joystick::~SCA_Joystick()
        delete m_private;
 }
 
-SCA_Joystick *SCA_Joystick::m_instance = NULL;
+SCA_Joystick *SCA_Joystick::m_instance[JOYINDEX_MAX];
 int SCA_Joystick::m_refCount = 0;
 
-SCA_Joystick *SCA_Joystick::GetInstance()
+SCA_Joystick *SCA_Joystick::GetInstance( short int joyindex )
 {
-       if (m_instance == 0) 
+       if (joyindex < 0 || joyindex >= JOYINDEX_MAX) {
+               echo("Error-invalid joystick index: " << joyindex);
+               return NULL;
+       }
+
+       if (m_refCount == 0) 
        {
-               m_instance = new SCA_Joystick();
-               m_instance->CreateJoystickDevice();
+               int i;
+               // do this once only
+               if(SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO ) == -1 ){
+                       echo("Error-Initializing-SDL: " << SDL_GetError());
+                       return NULL;
+               }
+               for (i=0; i<JOYINDEX_MAX; i++) {
+                       m_instance[i] = new SCA_Joystick(i);
+                       m_instance[i]->CreateJoystickDevice();
+               }
                m_refCount = 1;
        }
        else
        {
                m_refCount++;
        }
-       return m_instance;
+       return m_instance[joyindex];
 }
 
 void SCA_Joystick::ReleaseInstance()
 {
        if (--m_refCount == 0)
        {
-               DestroyJoystickDevice();
-               delete m_instance;
-               m_instance = NULL;
+               int i;
+               for (i=0; i<JOYINDEX_MAX; i++) {
+                       if (m_instance[i]) {
+                               m_instance[i]->DestroyJoystickDevice();
+                               delete m_instance[i];
+                       }
+                       m_instance[i]= NULL;
+               }
+               SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO );
        }
 }
 
-
-bool SCA_Joystick::CreateJoystickDevice()
-{
-       bool init = false;
-       init = pCreateJoystickDevice();
-       return init;
-}
-
-
-void SCA_Joystick::DestroyJoystickDevice()
-{
-       if(m_isinit)
-               pDestroyJoystickDevice();
-}
-
-
 void SCA_Joystick::HandleEvents()
 {
        if(m_isinit)
@@ -334,40 +337,34 @@ int SCA_Joystick::GetNumberOfHats()
        return -1;
 }
 
-bool SCA_Joystick::pCreateJoystickDevice()
+bool SCA_Joystick::CreateJoystickDevice(void)
 {
        if(m_isinit == false){
-               if(SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO ) == -1 ){
-                       echo("Error-Initializing-SDL: " << SDL_GetError());
-                       return false;
-               }
-               if(SDL_NumJoysticks() > 0){
-                       for(int i=0; i<SDL_NumJoysticks();i++){
-                               m_private->m_joystick = SDL_JoystickOpen(i);
-                               SDL_JoystickEventState(SDL_ENABLE);
-                               m_numjoys = i;
-                       }
-                       echo("Joystick-initialized");
-                       m_isinit = true;
-                       return true;
-               }else{
-                       echo("Joystick-Error: " << SDL_NumJoysticks() << " avaiable joystick(s)");
+               if (m_joyindex>=SDL_NumJoysticks()) {
+                       // don't print a message, because this is done anyway
+                       //echo("Joystick-Error: " << SDL_NumJoysticks() << " avaiable joystick(s)");
                        return false;
                }
+
+               m_private->m_joystick = SDL_JoystickOpen(m_joyindex);
+               SDL_JoystickEventState(SDL_ENABLE);
+       
+               echo("Joystick " << m_joyindex << " initialized");
+               m_isinit = true;
        }
-       return false;
+       return true;
 }
 
 
-void SCA_Joystick::pDestroyJoystickDevice()
+void SCA_Joystick::DestroyJoystickDevice(void)
 {
-       echo("Closing-");
-       for(int i=0; i<SDL_NumJoysticks(); i++){
-               if(SDL_JoystickOpened(i)){
+       if (m_isinit){
+               if(SDL_JoystickOpened(m_joyindex)){
+                       echo("Closing-joystick " << m_joyindex);
                        SDL_JoystickClose(m_private->m_joystick);
                }
+               m_isinit = false;
        }
-       SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO );
 }
 
 
index 1e853070b099362d05a43de25e091d9a7f9b3e20..689efc72975d820416377e7b658d369919d30ea0 100644 (file)
@@ -76,7 +76,7 @@
 class SCA_Joystick
 
 {
-       static SCA_Joystick *m_instance;
+       static SCA_Joystick *m_instance[JOYINDEX_MAX];
        static int m_refCount;
 
        class PrivateData;
@@ -85,14 +85,6 @@ class SCA_Joystick
 
        int                             m_joyindex;
 
-       /*!
-
-        * the number of avail joysticks 
-
-        */
-
-       int                     m_numjoys;
-
        /* 
 
         *support for 2 axes 
@@ -185,7 +177,7 @@ class SCA_Joystick
 
         */
 
-       bool pCreateJoystickDevice(void);
+       bool CreateJoystickDevice(void);
 
        /*
 
@@ -193,7 +185,7 @@ class SCA_Joystick
 
         */
 
-       void pDestroyJoystickDevice(void);
+       void DestroyJoystickDevice(void);
 
        
 
@@ -259,18 +251,13 @@ class SCA_Joystick
 
        int pGetHat(int direction);
 
-       SCA_Joystick();
+       SCA_Joystick(short int index);
 
        ~SCA_Joystick();
        
-       bool CreateJoystickDevice(void);
-
-       void DestroyJoystickDevice(void);
-
-
 public:
 
-       static SCA_Joystick *GetInstance();
+       static SCA_Joystick *GetInstance( short int joyindex );
 
        void ReleaseInstance();
        
index 15a421188b90ce1cd2332ced1d650e250016f9f6..8d8f88ecaf237455f15358c1da7f5a9390c93812 100644 (file)
@@ -38,6 +38,8 @@
 #define echo(x) std::cout << x << std::endl;
 #endif
 
+#define JOYINDEX_MAX                   8
+
 /* function callbacks */
 #define HANDLE_AXISMOTION(fn)  ((fn)(), 0L)
 #define HANDLE_HATMOTION(fn)   ((fn)(), 0L)
index 8ff28ba0b519247925ebd5cf27cf4fcac570a31a..08c36326712a54c37415bc8209715b7875afda25 100644 (file)
@@ -40,13 +40,20 @@ SCA_JoystickManager::SCA_JoystickManager(class SCA_LogicManager* logicmgr)
        : SCA_EventManager(JOY_EVENTMGR),
        m_logicmgr(logicmgr)
 {
-       m_joystick = SCA_Joystick::GetInstance();
+       int i;
+       for (i=0; i<JOYINDEX_MAX; i++) {
+               m_joystick[i] = SCA_Joystick::GetInstance( i );
+       }
+       //m_joystick = NULL;
 }
 
 
 SCA_JoystickManager::~SCA_JoystickManager()
 {
-       m_joystick->ReleaseInstance();
+       int i;
+       for (i=0; i<JOYINDEX_MAX; i++) {
+               m_joystick[i]->ReleaseInstance();
+       }
 }
 
 
@@ -58,17 +65,17 @@ void SCA_JoystickManager::NextFrame(double curtime,double deltatime)
                SCA_JoystickSensor* joysensor = (SCA_JoystickSensor*)(*it);
                if(!joysensor->IsSuspended())
                {
-                       m_joystick->HandleEvents();
+                       m_joystick[joysensor->GetJoyIndex()]->HandleEvents();
                        joysensor->Activate(m_logicmgr, NULL);
                }
        }
 }
 
 
-SCA_Joystick *SCA_JoystickManager::GetJoystickDevice()
+SCA_Joystick *SCA_JoystickManager::GetJoystickDevice( short int joyindex)
 {
        /* 
         *Return the instance of SCA_Joystick for use 
         */
-       return m_joystick;
+       return m_joystick[joyindex];
 }
index f2bb27965fa660ff825ca621a8a0e49e2b93c4f9..d3a7ac95bea62da4340d944ae5c544a15cf012fc 100644 (file)
@@ -40,12 +40,12 @@ class SCA_JoystickManager : public SCA_EventManager
        /**
         * SDL Joystick Class Instance
         */
-       SCA_Joystick *m_joystick;
+       SCA_Joystick *m_joystick[JOYINDEX_MAX];
 public:
        SCA_JoystickManager(class SCA_LogicManager* logicmgr);
        virtual ~SCA_JoystickManager();
        virtual void NextFrame(double curtime,double deltatime);
-       SCA_Joystick* GetJoystickDevice(void);
+       SCA_Joystick* GetJoystickDevice(short int joyindex);
 
 };
 
index 3fb439eb25bf91ae201e7f069ea0f871a66fb3dd..4362a896f616efc38098e7256cdc8b475ea4b39f 100644 (file)
@@ -39,6 +39,7 @@
 
 SCA_JoystickSensor::SCA_JoystickSensor(class SCA_JoystickManager* eventmgr,
                                                                           SCA_IObject* gameobj,
+                                                                          short int joyindex,
                                                                           short int joymode,
                                                                           int axis, int axisf,int prec,
                                                                           int button, int buttonf,
@@ -53,7 +54,8 @@ SCA_JoystickSensor::SCA_JoystickSensor(class SCA_JoystickManager* eventmgr,
                                                                           m_hat(hat),
                                                                           m_hatf(hatf),
                                                                           m_precision(prec),
-                                                                          m_joymode(joymode)
+                                                                          m_joymode(joymode),
+                                                                          m_joyindex(joyindex)
 {      
 /*
 std::cout << " axis "          << m_axis               << std::endl;
@@ -99,7 +101,7 @@ bool SCA_JoystickSensor::IsPositiveTrigger()
 
 bool SCA_JoystickSensor::Evaluate(CValue* event)
 {
-       SCA_Joystick *js = m_pJoystickMgr->GetJoystickDevice();
+       SCA_Joystick *js = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
        bool result = false;
        bool reset = m_reset && m_level;
        
@@ -351,7 +353,7 @@ PyObject* SCA_JoystickSensor::PyGetRealAxis( PyObject* self,
                                                                                        PyObject* args, 
                                                                                        PyObject* kwds) {
        int a,b,c,d;
-       SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice();
+       SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
        a = joy->GetAxis10();
        b = joy->GetAxis11();
        c = joy->GetAxis20();
@@ -451,7 +453,7 @@ PyObject* SCA_JoystickSensor::PyNumberOfAxes( PyObject* self,
                                                                                        PyObject* args, 
                                                                                        PyObject* kwds) {
        int num;
-       SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice();
+       SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
        num = joy->GetNumberOfAxes();
        return Py_BuildValue("i",num);
 }
@@ -464,7 +466,7 @@ PyObject* SCA_JoystickSensor::PyNumberOfButtons( PyObject* self,
                                                                                        PyObject* args, 
                                                                                        PyObject* kwds) {
        int num;
-       SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice();
+       SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
        num = joy->GetNumberOfButtons();
        return Py_BuildValue("i",num);
 }
@@ -477,7 +479,7 @@ PyObject* SCA_JoystickSensor::PyNumberOfHats( PyObject* self,
                                                                                        PyObject* args, 
                                                                                        PyObject* kwds) {
        int num;
-       SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice();
+       SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
        num = joy->GetNumberOfHats();
        return Py_BuildValue("i",num);
 }
index 69068da6494762adbb7c76fcd03df055041d1bc4..e499d8cd0dc977cfa9344b16b8e0b0fc4d80bffe 100644 (file)
@@ -72,6 +72,10 @@ class SCA_JoystickSensor :public SCA_ISensor
         * The mode to determine axis,button or hat
         */
        short int m_joymode;
+       /**
+        * Select which joystick to use
+        */
+       short int m_joyindex;
 
        enum KX_JOYSENSORMODE {
                KX_JOYSENSORMODE_NODEF = 0,
@@ -85,6 +89,7 @@ class SCA_JoystickSensor :public SCA_ISensor
 public:
        SCA_JoystickSensor(class SCA_JoystickManager* eventmgr,
                                           SCA_IObject* gameobj,
+                                          short int joyindex,
                                           short int joymode,
                                           int axis, int axisf,int prec,
                                           int button, int buttonf,
@@ -97,6 +102,10 @@ public:
        virtual bool IsPositiveTrigger();
        virtual void Init();
        
+       short int GetJoyIndex(void){
+               return m_joyindex;
+       }
+
        /* --------------------------------------------------------------------- */
        /* Python interface ---------------------------------------------------- */
        /* --------------------------------------------------------------------- */