OSDN Git Service

[UI][Qt][SDL] Plug'n playable Joysticks.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Sat, 9 Jan 2016 12:08:13 +0000 (21:08 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Sat, 9 Jan 2016 12:08:13 +0000 (21:08 +0900)
source/src/config.cpp
source/src/config.h
source/src/qt/common/joy_thread.cpp
source/src/qt/common/joy_thread.h
source/src/qt/common/qt_main.cpp
source/src/qt/osd.h
source/src/qt/osd_input.cpp

index 54596bd..a3b3710 100644 (file)
@@ -339,6 +339,14 @@ void load_config(const _TCHAR *config_path)
        config.disable_dwm = MyGetPrivateProfileBool(_T("Input"), _T("DisableDwm"), config.disable_dwm, config_path);
 #endif
        config.swap_joy_buttons = MyGetPrivateProfileBool(_T("Input"), _T("SwapJoyButtons"), config.swap_joy_buttons, config_path);
+#if defined(_USE_QT)
+       for(i = 0; i < 16; i++) {
+               _TCHAR name[256];
+               my_stprintf_s(name, 256, _T("AssignedJoystick"), i + 1);
+               MyGetPrivateProfileString(_T("Input"), (const _TCHAR *)name, _T(""),
+                                                                 config.assigned_joystick_name[i], 256, config_path);
+       }
+#endif 
        
        // printer
 #ifdef USE_PRINTER
@@ -531,6 +539,14 @@ void save_config(const _TCHAR *config_path)
        MyWritePrivateProfileBool(_T("Input"), _T("DisableDwm"), config.disable_dwm, config_path);
 #endif
        MyWritePrivateProfileBool(_T("Input"), _T("SwapJoyButtons"), config.swap_joy_buttons, config_path);
+#if defined(_USE_QT)
+       for(i = 0; i < 16; i++) {
+               _TCHAR name[256];
+               my_stprintf_s(name, 256, _T("AssignedJoystick%d"), i + 1);
+               MyWritePrivateProfileString(_T("Input"), (const _TCHAR *)name, 
+                                                                       config.assigned_joystick_name[i], config_path);
+       }
+#endif 
        
        // printer
 #ifdef USE_PRINTER
index bb4cac5..e7ebfcc 100644 (file)
@@ -160,7 +160,9 @@ typedef struct {
        bool disable_dwm;
 #endif
        bool swap_joy_buttons;
-       
+#ifdef _USE_QT
+       _TCHAR assigned_joystick_name[16][256];
+#endif 
        // printer
 #ifdef USE_PRINTER
        int printer_device_type;
index 10b45a4..83d026f 100644 (file)
 JoyThreadClass::JoyThreadClass(EMU *p, QObject *parent) : QThread(parent)
 {
        int i, j;
-       
+       int n;
        p_emu = p;
 #if defined(USE_JOYSTICK)      
-       joy_num = SDL_NumJoysticks();
+# if defined(USE_SDL2)
+       for(i = 0; i < 16; i++) {
+               controller_table[i] = NULL;
+       }
+# endif        
+       n = SDL_NumJoysticks();
        for(i = 0; i < 16; i++) {
                joyhandle[i] = NULL;
-# if defined(USE_SDL2)  
-               for(j = 0; j < 16; j++) guid_list[i].data[j] = 0;
-               for(j = 0; j < 16; j++) guid_assign[i].data[j] = 0;
-# endif           
                names[i] = QString::fromUtf8("");
+               joy_num[i] = 0;
        }
-       if(joy_num > 0) {
-               if(joy_num >= 16) joy_num = 16;
-               for(i = 0; i < joy_num; i++) {
-                  
-                       joyhandle[i] = SDL_JoystickOpen(i);
-                       if(joyhandle[i] != NULL) {
-# if defined(USE_SDL2)                    
-                               guid_list[i] = SDL_JoystickGetGUID(joyhandle[i]);
-                               guid_assign[i] = SDL_JoystickGetGUID(joyhandle[i]);
-                               names[i] = QString::fromUtf8(SDL_JoystickNameForIndex(i));
-# else
-                               names[i] = QString::fromUtf8(SDL_JoystickName(i));
-# endif                           
-                               AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : Joystick %d : %s.", i, names[i].toUtf8().data());
-                       }
+       if(n > 0) {
+               if(n >= 16) n = 16;
+# if !defined(USE_SDL2)
+               for(i = 0; i < n; i++) {
+                       joystick_plugged(i);
                }
+# endif                
                AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : Start.");
-               bRunThread = true;
        } else {
                AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : Any joysticks were not connected.");
-               bRunThread = false;
        }
+       bRunThread = true;
 #else
-       joy_num = 0;
        for(i = 0; i < 16; i++) {
                joyhandle[i] = NULL;
-# if defined(USE_SDL2)  
-               for(j = 0; j < 16; j++) guid_list[i].data[j] = 0;
-               for(j = 0; j < 16; j++) guid_assign[i].data[j] = 0;
-#  endif          
                names[i] = QString::fromUtf8("None");
        }
        AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : None launched because this VM has not supported joystick.");
@@ -76,19 +63,112 @@ JoyThreadClass::JoyThreadClass(EMU *p, QObject *parent) : QThread(parent)
    
 JoyThreadClass::~JoyThreadClass()
 {
-#if defined(USE_JOYSTICK)      
        int i;
+#if defined(USE_JOYSTICK)
+# if defined(USE_SDL2)
+       for(i = 0; i < 16; i++) {
+               SDL_GameControllerClose(controller_table[i]);
+               controller_table[i] = NULL;
+       }
+       AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : EXIT");
+# else
        for(i = 0; i < 16; i++) {
-               if(joyhandle[i] != NULL) SDL_JoystickClose(joyhandle[i]);
+               SDL_JoystickClose(joyhandle[i]);
+               joyhandle[i] = NULL;
        }
        AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : EXIT");
+# endif        
 #endif 
 }
  
 #if defined(USE_JOYSTICK)      
+
+
+void JoyThreadClass::joystick_plugged(int num)
+{
+       int i,j;
+       bool found = false;
+# if defined(USE_SDL2)
+       if(SDL_IsGameController(num) == SDL_TRUE) {
+               if(controller_table[num] != NULL) return;
+               controller_table[num] = SDL_GameControllerOpen(num);
+               joyhandle[num] = SDL_GameControllerGetJoystick(controller_table[num]);
+               if(controller_table[num] != NULL) {
+                       names[num] = QString::fromUtf8(SDL_GameControllerNameForIndex(num));
+                       AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : Controller %d : %s : is plugged.", num, names[num].toUtf8().constData());
+                       strncpy(config.assigned_joystick_name[num], names[num].toUtf8().constData(), 255);
+                       joy_num[num] = num;
+               }
+       } else 
+# endif
+       {
+               bool matched = false;
+               QString tmps;
+# if 0         
+               for(i = 0; i < 16; i++) {
+                       tmps = QString::fromUtf8(SDL_JoystickNameForIndex(num));
+                       if((strlen(config.assigned_joystick_name[i]) > 0) &&
+                          (strncmp(config.assigned_joystick_name[i], tmps.toUtf8().constData(), 255) == 0)) {
+                               if(joyhandle[i] == NULL) {
+                                       joyhandle[i] = SDL_JoystickOpen(num);
+                                       joy_num[i] = SDL_JoystickInstanceID(joyhandle[i]);
+                                       names[i] = tmps;
+                                       AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : Joystick %d : %s : is plugged.",
+                                                                 i, names[i].toUtf8().constData());
+                                       strncpy(config.assigned_joystick_name[num], names[num].toUtf8().constData(), 255);
+                                       matched = true;
+                                       break;
+                               }
+                       }
+               }
+# endif                
+               if(!matched) {
+                       for(i = 0; i < 16; i++) {
+                               if(joyhandle[i] == NULL) {
+                                       joyhandle[i] = SDL_JoystickOpen(num);
+                                       joy_num[i] = SDL_JoystickInstanceID(joyhandle[i]);
+                                       names[i] = QString::fromUtf8(SDL_JoystickNameForIndex(num));
+                                       AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : Joystick %d : %s : is plugged.", num, names[i].toUtf8().data());
+                                       strncpy(config.assigned_joystick_name[num], names[num].toUtf8().constData(), 255);
+                                       break;
+                               }
+                       }
+               }
+       }
+}
+
+void JoyThreadClass::joystick_unplugged(int num)
+{
+       int i, j;
+       if(num < 0) return;
+       
+# if defined(USE_SDL2)
+       if(SDL_IsGameController(num)) {
+               if(controller_table[num] != NULL) {
+                       SDL_GameControllerClose(controller_table[num]);
+                       controller_table[num] = NULL;
+                       AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : Controller %d : %s : is removed.", num, names[num].toUtf8().data());
+                       joy_num[num] = -1;
+               }
+               joyhandle[num] = NULL;
+       } else 
+# endif
+       {
+               if(joyhandle[num] != NULL) {
+                       SDL_JoystickClose(joyhandle[num]);
+                       joyhandle[num] = NULL;
+                       AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : Joystick %d : %s : is removed.", num, names[num].toUtf8().data());
+                       joy_num[num] = -1;
+               }
+       }
+       names[num] = QString::fromUtf8("");
+       memset(config.assigned_joystick_name[num], 0x00, 255);
+}      
+
 void JoyThreadClass::x_axis_changed(int index, int value)
 {
        if(p_emu == NULL) return;
+       if((index < 0) || (index >= 2)) return;
        p_emu->lock_vm();
        uint32_t *joy_status = p_emu->joy_buffer();
    
@@ -107,6 +187,7 @@ void JoyThreadClass::x_axis_changed(int index, int value)
 void JoyThreadClass::y_axis_changed(int index, int value)
 {
        if(p_emu == NULL) return;
+       if((index < 0) || (index >= 2)) return;
        p_emu->lock_vm();
        uint32_t *joy_status = p_emu->joy_buffer();
    
@@ -125,6 +206,7 @@ void JoyThreadClass::y_axis_changed(int index, int value)
 void JoyThreadClass::button_down(int index, unsigned int button)
 {
        if(p_emu == NULL) return;
+       if((index < 0) || (index >= 2)) return;
        p_emu->lock_vm();
        uint32_t *joy_status = p_emu->joy_buffer();
        if(joy_status != NULL) {
@@ -136,7 +218,7 @@ void JoyThreadClass::button_down(int index, unsigned int button)
 void JoyThreadClass::button_up(int index, unsigned int button)
 {
        if(p_emu == NULL) return;
-   
+       if((index < 0) || (index >= 2)) return;
        p_emu->lock_vm();
        uint32_t *joy_status = p_emu->joy_buffer();
        if(joy_status != NULL) {
@@ -145,27 +227,28 @@ void JoyThreadClass::button_up(int index, unsigned int button)
        p_emu->unlock_vm();
 }
 
-#if defined(USE_SDL2)
-// SDL Event Handler
-bool JoyThreadClass::MatchJoyGUID(SDL_JoystickGUID *a, SDL_JoystickGUID *b)
-{ 
+#if defined(USE_SDL2)                     
+int JoyThreadClass::get_joyid_from_instanceID(SDL_JoystickID id)
+{
        int i;
+       SDL_Joystick *js;
        for(i = 0; i < 16; i++) {
-               if(a->data[i] != b->data[i]) return false;
+               if(controller_table[i] == NULL) continue;
+               js = SDL_GameControllerGetJoystick(controller_table[i]);
+               if(js == NULL) continue;
+               if(id == SDL_JoystickInstanceID(js)) return i;
        }
-       return true;
+       return -1;
 }
-
-bool JoyThreadClass::CheckJoyGUID(SDL_JoystickGUID *a)
-{ 
+#endif
+int JoyThreadClass::get_joy_num(int id)
+{
        int i;
-       bool b = false;
        for(i = 0; i < 16; i++) {
-               if(a->data[i] != 0) b = true;
+               if(joy_num[i] == id) return i;
        }
-       return b;
+       return -1;
 }
-#endif
 
 bool  JoyThreadClass::EventSDL(SDL_Event *eventQueue)
 {
@@ -176,67 +259,73 @@ bool  JoyThreadClass::EventSDL(SDL_Event *eventQueue)
        uint32_t sym;
        uint32_t mod;
 # if defined(USE_SDL2)
-       SDL_JoystickGUID guid;
+       SDL_JoystickID id;
+       SDL_GameControllerButton cont_button;
 # endif   
-       int i;
+       int i, j;
        if(eventQueue == NULL) return false;
        /*
         * JoyStickなどはSDLが管理する
         */
        switch (eventQueue->type){
+# if defined(USE_SDL2)
+               case SDL_CONTROLLERAXISMOTION:
+                       value = eventQueue->caxis.value;
+                       if(eventQueue->caxis.axis == SDL_CONTROLLER_AXIS_LEFTX) {
+                               id = (int)eventQueue->caxis.which;
+                               i = get_joyid_from_instanceID(id);
+                               x_axis_changed(i, value);
+                       } else if(eventQueue->caxis.axis == SDL_CONTROLLER_AXIS_LEFTY) {
+                               id = (int)eventQueue->caxis.which;
+                               i = get_joyid_from_instanceID(id);
+                               y_axis_changed(i, value);
+                       }
+                       break;
+               case SDL_CONTROLLERBUTTONDOWN:
+                       button = eventQueue->cbutton.button;
+                       id = eventQueue->cbutton.which;
+                       i = get_joyid_from_instanceID(id);
+                       //button = SDL_GameControllerGetButton(controller_table[i], cont_button);
+                       button_down(i, button);
+                       break;
+               case SDL_CONTROLLERBUTTONUP:
+                       button = eventQueue->cbutton.button;
+                       id = eventQueue->cbutton.which;
+                       i = get_joyid_from_instanceID(id);
+                       //button = SDL_GameControllerGetButton(controller_table[i], cont_button);
+                       button_up(i, button);
+                       break;
+               case SDL_JOYDEVICEADDED:
+                       i = eventQueue->jdevice.which;
+                       joystick_plugged(i);
+                       break;
+               case SDL_JOYDEVICEREMOVED:
+                       i = eventQueue->jdevice.which;
+                       i = get_joy_num(i);
+                       joystick_unplugged(i);
+                       break;
+# endif                
                case SDL_JOYAXISMOTION:
                        value = eventQueue->jaxis.value;
                        i = eventQueue->jaxis.which;
-          
-# if defined(USE_SDL2)
-                       guid = SDL_JoystickGetDeviceGUID(i);
-                       if(!CheckJoyGUID(&guid)) break;
-                       for(i = 0; i < 2; i++) {
-                               if(MatchJoyGUID(&guid, &(guid_assign[i]))) {
-                                       if(eventQueue->jaxis.axis == 0) { // X
-                                               x_axis_changed(i, value);
-                                       } else if(eventQueue->jaxis.axis == 1) { // Y
-                                               y_axis_changed(i, value);
-                                       }
-                               }
-                       }
-# else
+                       i = get_joy_num(i);
                        if(eventQueue->jaxis.axis == 0) { // X
                                x_axis_changed(i, value);
                        } else if(eventQueue->jaxis.axis == 1) { // Y
                                y_axis_changed(i, value);
                        }
-# endif
                        break;
                case SDL_JOYBUTTONDOWN:
                        button = eventQueue->jbutton.button;
                        i = eventQueue->jbutton.which;
-# if defined(USE_SDL2)
-                       guid = SDL_JoystickGetDeviceGUID(i);
-                       if(!CheckJoyGUID(&guid)) break;
-                       for(i = 0; i < 2; i++) {
-                               if(MatchJoyGUID(&guid, &(guid_assign[i]))) {
-                                       button_down(i, button);
-                               }
-                       }
-# else    
+                       i = get_joy_num(i);
                        button_down(i, button);
-# endif           
                        break;
                case SDL_JOYBUTTONUP:      
                        button = eventQueue->jbutton.button;
                        i = eventQueue->jbutton.which;
-# if defined(USE_SDL2)
-                       guid = SDL_JoystickGetDeviceGUID(i);
-                       if(!CheckJoyGUID(&guid)) break;
-                       for(i = 0; i < 2; i++) {
-                               if(MatchJoyGUID(&guid, &(guid_assign[i]))) {
-                                       button_up(i, button);
-                               }
-                       }
-# else    
+                       i = get_joy_num(i);
                        button_up(i, button);
-# endif           
                        break;
                default:
                        break;
index c3c7667..141255b 100644 (file)
@@ -23,27 +23,28 @@ QT_BEGIN_NAMESPACE
 class JoyThreadClass : public QThread {
        Q_OBJECT
  private:
-       int joy_num;
+       int joy_num[16];
        SDL_Event event;
-       SDL_Joystick *joyhandle[16];
 #if defined(USE_SDL2)   
-       SDL_JoystickGUID guid_list[16];
-       SDL_JoystickGUID guid_assign[16];
-#endif   
+       SDL_GameController *controller_table[16];
+#endif 
+       SDL_Joystick *joyhandle[16];
        QString names[16];
        EMU *p_emu;
  protected:
        bool bRunThread;
 #if defined(USE_JOYSTICK)      
+       void joystick_plugged(int num);
+       void joystick_unplugged(int num);
        bool EventSDL(SDL_Event *);
        void x_axis_changed(int, int);
        void y_axis_changed(int, int);
        void button_down(int, unsigned int);
        void button_up(int, unsigned int);
-#if defined(USE_SDL2)
-       bool CheckJoyGUID(SDL_JoystickGUID *a);
-       bool MatchJoyGUID(SDL_JoystickGUID *a, SDL_JoystickGUID *b);
-#endif
+       int get_joy_num(int id);
+# if defined(USE_SDL2)
+       int get_joyid_from_instanceID(SDL_JoystickID id);
+# endif
 #endif 
  public:
        JoyThreadClass(EMU *p, QObject *parent = 0);
index 3f202ef..f4589bf 100644 (file)
@@ -567,7 +567,7 @@ int MainLoop(int argc, char *argv[])
         * Into Qt's Loop.
         */
 #if defined(USE_SDL2)
-       SDL_Init(SDL_INIT_AUDIO | SDL_INIT_JOYSTICK );
+       SDL_Init(SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);
 #else
        SDL_Init(SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_VIDEO);
        //SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO);
index d9c7916..e9410c6 100644 (file)
@@ -215,9 +215,9 @@ protected:
        uint32_t modkey_status;
        bool lost_focus;
        
-       uint32 joy_status[2];   // joystick #1, #2 (b0 = up, b1 = down, b2 = left, b3 = right, b4- = buttons
+       uint32 joy_status[4];   // joystick #1, #2 (b0 = up, b1 = down, b2 = left, b3 = right, b4- = buttons
        int joy_num;
-       uint32 joy_mask[2];
+       uint32 joy_mask[4];
        
        int mouse_status[3];    // x, y, button (b0 = left, b1 = right)
        bool mouse_enabled;
index 1b2272d..99cba88 100644 (file)
@@ -274,10 +274,6 @@ void OSD::initialize_input()
        mouse_enabled = false;
        mouse_ptrx = mouse_oldx = SCREEN_WIDTH / 2;
        mouse_ptry = mouse_oldy = SCREEN_HEIGHT / 2;
-        joy_num = SDL_NumJoysticks();
-        for(int i = 0; i < joy_num && i < 2; i++) {
-               joy_mask[i] = 0x0f; // 4buttons
-       }
        // initialize keycode convert table
        FILEIO* fio = new FILEIO();
        if(fio->Fopen(bios_path(_T("keycode.cfg")), FILEIO_READ_BINARY)) {
@@ -438,7 +434,7 @@ void OSD::update_input()
 
        // swap joystick buttons
        if(config.swap_joy_buttons) {
-               for(int i = 0; i < joy_num && i < 2; i++) {
+               for(int i = 0; i < 4; i++) {
                        uint32 b0 = joy_status[i] & 0xaaaaaaa0;
                        uint32 b1 = joy_status[i] & 0x55555550;
                        joy_status[i] = (joy_status[i] & 0x0f) | (b0 >> 1) | (b1 << 1);