From e50d6e22edf7c17f02292c7c2a6e60f27dd9f78e Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 24 Jul 2020 00:11:11 -0400 Subject: [PATCH] Added logic to load default game pad button bindings from SDL database. --- src/drivers/Qt/GamePadConf.cpp | 161 +++++++++----- src/drivers/Qt/GamePadConf.h | 7 +- src/drivers/Qt/input.cpp | 2 + src/drivers/Qt/input.h | 3 +- src/drivers/Qt/sdl-joystick.cpp | 358 ++++++++++++++++++++++++-------- src/drivers/Qt/sdl-joystick.h | 58 ++++++ 6 files changed, 452 insertions(+), 137 deletions(-) create mode 100644 src/drivers/Qt/sdl-joystick.h diff --git a/src/drivers/Qt/GamePadConf.cpp b/src/drivers/Qt/GamePadConf.cpp index 66c05783..6a149f60 100644 --- a/src/drivers/Qt/GamePadConf.cpp +++ b/src/drivers/Qt/GamePadConf.cpp @@ -6,16 +6,18 @@ #include "Qt/input.h" #include "Qt/config.h" #include "Qt/keyscan.h" +#include "Qt/sdl-joystick.h" #include "Qt/fceuWrapper.h" //---------------------------------------------------- GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) : QDialog( parent ) { - QHBoxLayout *hbox1, *hbox2; + QHBoxLayout *hbox1, *hbox2, *hbox3, *hbox4; QGridLayout *grid; QCheckBox *efs_chkbox, *udlr_chkbox; QGroupBox *frame; + QLabel *label; QPushButton *loadDefaultButton; QPushButton *clearAllButton; QPushButton *closebutton; @@ -30,8 +32,10 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) hbox1 = new QHBoxLayout(); hbox2 = new QHBoxLayout(); + hbox3 = new QHBoxLayout(); + hbox4 = new QHBoxLayout(); - QLabel *label = new QLabel(tr("Port:")); + label = new QLabel(tr("Port:")); portSel = new QComboBox(); hbox1->addWidget( label ); hbox1->addWidget( portSel ); @@ -41,6 +45,34 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) portSel->addItem( tr("3"), 2 ); portSel->addItem( tr("4"), 3 ); + label = new QLabel(tr("Device:")); + devSel = new QComboBox(); + hbox2->addWidget( label ); + hbox2->addWidget( devSel ); + + devSel->addItem( tr("Keyboard"), -1 ); + + for (int i=0; iinUse() ) + { + char stmp[128]; + sprintf( stmp, "%i: %s", i, js->getName() ); + devSel->addItem( tr(stmp), i ); + } + } + } + + label = new QLabel(tr("GUID:")); + guidLbl = new QLabel(); + + hbox3->addWidget( label ); + hbox3->addWidget( guidLbl ); + efs_chkbox = new QCheckBox( tr("Enable Four Score") ); udlr_chkbox = new QCheckBox( tr("Allow Up+Down/Left+Right") ); @@ -87,9 +119,9 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) clearAllButton = new QPushButton(tr("Clear All")); closebutton = new QPushButton(tr("Close")); - hbox2->addWidget( loadDefaultButton ); - hbox2->addWidget( clearAllButton ); - hbox2->addWidget( closebutton ); + hbox4->addWidget( loadDefaultButton ); + hbox4->addWidget( clearAllButton ); + hbox4->addWidget( closebutton ); connect(button[0], SIGNAL(clicked()), this, SLOT(changeButton0(void)) ); connect(button[1], SIGNAL(clicked()), this, SLOT(changeButton1(void)) ); @@ -117,17 +149,20 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) connect(clearAllButton , SIGNAL(clicked()), this, SLOT(clearAllCallback(void)) ); connect(closebutton , SIGNAL(clicked()), this, SLOT(closeWindow(void)) ); - connect(portSel , SIGNAL(activated(int)), this, SLOT(controllerSelect(int)) ); + connect(portSel , SIGNAL(activated(int)), this, SLOT(portSelect(int)) ); + connect(devSel , SIGNAL(activated(int)), this, SLOT(deviceSelect(int)) ); connect(efs_chkbox , SIGNAL(stateChanged(int)), this, SLOT(ena4score(int)) ); connect(udlr_chkbox, SIGNAL(stateChanged(int)), this, SLOT(oppDirEna(int)) ); QVBoxLayout *mainLayout = new QVBoxLayout(); mainLayout->addLayout( hbox1 ); + mainLayout->addLayout( hbox2 ); + mainLayout->addLayout( hbox3 ); mainLayout->addWidget( efs_chkbox ); mainLayout->addWidget( udlr_chkbox ); mainLayout->addWidget( frame ); - mainLayout->addLayout( hbox2 ); + mainLayout->addLayout( hbox4 ); setLayout( mainLayout ); @@ -156,26 +191,48 @@ void GamePadConfDialog_t::updateCntrlrDpy(void) for (int i=0; isetText( tr(keyNameStr) ); } } //---------------------------------------------------- -void GamePadConfDialog_t::controllerSelect(int index) +void GamePadConfDialog_t::portSelect(int index) { //printf("Port Number:%i \n", index); portNum = index; updateCntrlrDpy(); } //---------------------------------------------------- +void GamePadConfDialog_t::deviceSelect(int index) +{ + jsDev_t *js; + int devIdx = devSel->itemData(index).toInt(); + + js = getJoystickDevice( devIdx ); + + if ( js != NULL ) + { + if ( js->inUse() ) + { + guidLbl->setText( js->getGUID() ); + } + } + else + { + guidLbl->setText(""); + } + + updateCntrlrDpy(); +} +//---------------------------------------------------- void GamePadConfDialog_t::ena4score(int state) { int value = (state == Qt::Unchecked) ? 0 : 1; @@ -209,16 +266,16 @@ void GamePadConfDialog_t::changeButton(int padNo, int x) snprintf (buf, sizeof(buf)-1, "SDL.Input.GamePad.%d.", padNo); prefix = buf; - DWaitButton (NULL, &GamePadConfig[padNo][x], &buttonConfigStatus ); + DWaitButton (NULL, &GamePad[padNo].bmap[x], &buttonConfigStatus ); g_config->setOption (prefix + GamePadNames[x], - GamePadConfig[padNo][x].ButtonNum); + GamePad[padNo].bmap[x].ButtonNum); - if (GamePadConfig[padNo][x].ButtType == BUTTC_KEYBOARD) + if (GamePad[padNo].bmap[x].ButtType == BUTTC_KEYBOARD) { g_config->setOption (prefix + "DeviceType", "Keyboard"); } - else if (GamePadConfig[padNo][x].ButtType == BUTTC_JOYSTICK) + else if (GamePad[padNo].bmap[x].ButtType == BUTTC_JOYSTICK) { g_config->setOption (prefix + "DeviceType", "Joystick"); } @@ -227,9 +284,9 @@ void GamePadConfDialog_t::changeButton(int padNo, int x) g_config->setOption (prefix + "DeviceType", "Unknown"); } g_config->setOption (prefix + "DeviceNum", - GamePadConfig[padNo][x].DeviceNum); + GamePad[padNo].bmap[x].DeviceNum); - keyNameStr = ButtonName( &GamePadConfig[padNo][x] ); + keyNameStr = ButtonName( &GamePad[padNo].bmap[x] ); keyName[x]->setText( keyNameStr ); button[x]->setText("Change"); @@ -244,7 +301,7 @@ void GamePadConfDialog_t::clearButton( int padNo, int x ) char buf[256]; std::string prefix; - GamePadConfig[padNo][x].ButtonNum = -1; + GamePad[padNo].bmap[x].ButtonNum = -1; keyName[x]->setText(""); @@ -252,7 +309,7 @@ void GamePadConfDialog_t::clearButton( int padNo, int x ) prefix = buf; g_config->setOption (prefix + GamePadNames[x], - GamePadConfig[padNo][x].ButtonNum); + GamePad[padNo].bmap[x].ButtonNum); } //---------------------------------------------------- @@ -381,41 +438,49 @@ void GamePadConfDialog_t::clearAllCallback(void) //---------------------------------------------------- void GamePadConfDialog_t::loadDefaults(void) { + int index, devIdx; char buf[256]; std::string prefix; - if ( portNum > 0 ) + index = devSel->currentIndex(); + devIdx = devSel->itemData(index).toInt(); + + printf("Selected Device:%i : %i \n", index, devIdx ); + + if ( devIdx == -1 ) { - clearAllCallback(); - return; + snprintf (buf, sizeof(buf)-1, "SDL.Input.GamePad.%d.", portNum); + prefix = buf; + + for (int x=0; xsetOption (prefix + GamePadNames[x], + GamePad[portNum].bmap[x].ButtonNum); + + if (GamePad[portNum].bmap[x].ButtType == BUTTC_KEYBOARD) + { + g_config->setOption (prefix + "DeviceType", "Keyboard"); + } + else if (GamePad[portNum].bmap[x].ButtType == BUTTC_JOYSTICK) + { + g_config->setOption (prefix + "DeviceType", "Joystick"); + } + else + { + g_config->setOption (prefix + "DeviceType", "Unknown"); + } + g_config->setOption (prefix + "DeviceNum", + GamePad[portNum].bmap[x].DeviceNum); + } } - - snprintf (buf, sizeof(buf)-1, "SDL.Input.GamePad.%d.", portNum); - prefix = buf; - - for (int x=0; xsetOption (prefix + GamePadNames[x], - GamePadConfig[portNum][x].ButtonNum); - - if (GamePadConfig[portNum][x].ButtType == BUTTC_KEYBOARD) - { - g_config->setOption (prefix + "DeviceType", "Keyboard"); - } - else if (GamePadConfig[portNum][x].ButtType == BUTTC_JOYSTICK) - { - g_config->setOption (prefix + "DeviceType", "Joystick"); - } - else - { - g_config->setOption (prefix + "DeviceType", "Unknown"); - } - g_config->setOption (prefix + "DeviceNum", - GamePadConfig[portNum][x].DeviceNum); + GamePad[portNum].devIdx = devIdx; + GamePad[portNum].loadDefaults(); } updateCntrlrDpy(); } diff --git a/src/drivers/Qt/GamePadConf.h b/src/drivers/Qt/GamePadConf.h index 0f83000c..fdf1c466 100644 --- a/src/drivers/Qt/GamePadConf.h +++ b/src/drivers/Qt/GamePadConf.h @@ -38,11 +38,13 @@ class GamePadConfDialog_t : public QDialog protected: QComboBox *portSel; + QComboBox *devSel; + QComboBox *profSel; + QLabel *guidLbl; QLabel *keyName[GAMEPAD_NUM_BUTTONS]; GamePadConfigButton_t *button[GAMEPAD_NUM_BUTTONS]; int portNum; - int configNo; int buttonConfigStatus; void changeButton( int port, int button ); @@ -80,6 +82,7 @@ class GamePadConfDialog_t : public QDialog void loadDefaults(void); void ena4score(int state); void oppDirEna(int state); - void controllerSelect(int index); + void portSelect(int index); + void deviceSelect(int index); }; diff --git a/src/drivers/Qt/input.cpp b/src/drivers/Qt/input.cpp index 6da51b33..b688b1a5 100644 --- a/src/drivers/Qt/input.cpp +++ b/src/drivers/Qt/input.cpp @@ -1956,6 +1956,8 @@ UpdateInput (Config * config) char buf[64]; std::string device, prefix; + InitJoysticks(); + for (unsigned int i = 0; i < 3; i++) { snprintf (buf, 64, "SDL.Input.%u", i); diff --git a/src/drivers/Qt/input.h b/src/drivers/Qt/input.h index 53eeda0a..14862205 100644 --- a/src/drivers/Qt/input.h +++ b/src/drivers/Qt/input.h @@ -21,7 +21,6 @@ struct ButtConfig //uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */ }; - extern int NoWaiting; extern CFGSTRUCT InputConfig[]; extern ARGPSTRUCT InputArgs[]; @@ -46,7 +45,7 @@ void InitInputInterface(void); void InputUserActiveFix(void); extern bool replaceP2StartWithMicrophone; -extern ButtConfig GamePadConfig[4][10]; +//extern ButtConfig GamePadConfig[4][10]; //extern ButtConfig powerpadsc[2][12]; //extern ButtConfig QuizKingButtons[6]; //extern ButtConfig FTrainerButtons[12]; diff --git a/src/drivers/Qt/sdl-joystick.cpp b/src/drivers/Qt/sdl-joystick.cpp index 1d02e988..705c8f1d 100644 --- a/src/drivers/Qt/sdl-joystick.cpp +++ b/src/drivers/Qt/sdl-joystick.cpp @@ -23,97 +23,303 @@ /// \brief Handles joystick input using the SDL. #include "Qt/sdl.h" +#include "Qt/sdl-joystick.h" #include #include #include #include -#define MAX_JOYSTICKS 32 -struct jsDev_t +//#define MAX_JOYSTICKS 32 + +GamePad_t GamePad[4]; + +jsDev_t::jsDev_t(void) { - SDL_Joystick *js; - SDL_GameController *gc; + js = NULL; + gc = NULL; +}; - jsDev_t(void) +int jsDev_t::close(void) +{ + if ( gc ) { - js = NULL; - gc = NULL; - }; - - //~jsDev_t(void) - //{ - // if ( js ) - // { - // SDL_JoystickClose( js ); js = NULL; - // } - // if ( gc ) - // { - // SDL_GameControllerClose( gc ); gc = NULL; - // } - //} - - int close(void) + SDL_GameControllerClose( gc ); gc = NULL; js = NULL; + } + else { if ( js ) { SDL_JoystickClose( js ); js = NULL; } - if ( gc ) - { - SDL_GameControllerClose( gc ); gc = NULL; - } - return 0; } + return 0; +} - SDL_Joystick *getJS(void) +SDL_Joystick *jsDev_t::getJS(void) +{ + return js; +} + +const char *jsDev_t::getName(void) +{ + return ( name.c_str() ); +} + +const char *jsDev_t::getGUID(void) +{ + return ( guidStr.c_str() ); +} + +bool jsDev_t::isGameController(void) +{ + return ( gc != NULL ); +} + +bool jsDev_t::inUse(void) +{ + return ( (js != NULL) || (gc != NULL) ); +} + +void jsDev_t::init( int idx ) +{ + SDL_JoystickGUID guid; + char stmp[64]; + + devIdx = idx; + + if ( gc ) { - if ( gc != NULL ) - { - return SDL_GameControllerGetJoystick( gc ); - } - return js; - } + js = SDL_GameControllerGetJoystick( gc ); - bool isGameController(void) + guid = SDL_JoystickGetGUID( js ); + + name.assign( SDL_GameControllerName(gc) ); + } + else { - return ( gc != NULL ); - } + guid = SDL_JoystickGetGUID( js ); - bool inUse(void) + name.assign( SDL_JoystickName(js) ); + } + SDL_JoystickGetGUIDString( guid, stmp, sizeof(stmp) ); + + guidStr.assign( stmp ); + +} + +void jsDev_t::print(void) +{ + char guidStr[64]; + + SDL_JoystickGUID guid = SDL_JoystickGetGUID( js ); + + SDL_JoystickGetGUIDString( guid, guidStr, sizeof(guidStr) ); + + printf("JoyStickID: %i: '%s' \n", + SDL_JoystickInstanceID( js ), SDL_JoystickName( js ) ); + printf("GUID: %s \n", guidStr ); + printf("NumAxes: %i \n", SDL_JoystickNumAxes(js) ); + printf("NumButtons: %i \n", SDL_JoystickNumButtons(js) ); + printf("NumHats: %i \n", SDL_JoystickNumHats(js) ); + + if ( gc ) { - return ( (js != NULL) || (gc != NULL) ); + printf("GameController Name: '%s'\n", SDL_GameControllerName(gc) ); + printf("GameController Mapping: %s\n", SDL_GameControllerMapping(gc) ); } - - void print(void) - { - char guidStr[64]; - - SDL_JoystickGUID guid = SDL_JoystickGetGUID( getJS() ); - - SDL_JoystickGetGUIDString( guid, guidStr, sizeof(guidStr) ); - - printf("JoyStickID: %i: '%s' \n", - SDL_JoystickInstanceID( getJS() ), SDL_JoystickName( getJS() ) ); - printf("GUID: %s \n", guidStr ); - printf("NumAxes: %i \n", SDL_JoystickNumAxes(getJS()) ); - printf("NumButtons: %i \n", SDL_JoystickNumButtons(getJS()) ); - printf("NumHats: %i \n", SDL_JoystickNumHats(getJS()) ); - - if ( gc ) - { - printf("GameController Name: '%s'\n", SDL_GameControllerName(gc) ); - printf("GameController Mapping: %s\n", SDL_GameControllerMapping(gc) ); - } - } -}; +} static jsDev_t jsDev[ MAX_JOYSTICKS ]; -//static SDL_Joystick *s_Joysticks[MAX_JOYSTICKS] = {NULL}; + +//******************************************************************************** +GamePad_t::GamePad_t(void) +{ + devIdx = 0; + + for (int i=0; i= 0 ) + { + bmap[bIdx].ButtType = BUTTC_JOYSTICK; + bmap[bIdx].DeviceNum = devIdx; + + if ( (val[i][0] == 'b') && isdigit( val[i][1] ) ) + { + bmap[bIdx].ButtonNum = atoi( &val[i][1] ); + } + else if ( (val[i][0] == 'h') && isdigit( val[i][1] ) && + (val[i][2] == '.') && isdigit( val[i][3] ) ) + { + int hatIdx, hatVal; + + hatIdx = val[i][1] - '0'; + hatVal = atoi( &val[i][3] ); + + bmap[bIdx].ButtonNum = 0x2000 | ( (hatIdx & 0x1F) << 8) | (hatVal & 0xFF); + } + else if ( (val[i][0] == 'a') || (val[i][1] == 'a') ) + { + int l, axisIdx, axisSign = 0; + + l=0; + if ( val[i][l] == '-' ) + { + axisSign = 1; l++; + } + else if ( val[i][l] == '+' ) + { + axisSign = 0; l++; + } + + if ( val[i][l] == 'a' ) + { + l++; + } + if ( isdigit( val[i][l] ) ) + { + axisIdx = atoi( &val[i][l] ); + + bmap[bIdx].ButtonNum = 0x8000 | (axisSign ? 0x4000 : 0) | (axisIdx & 0xFF); + } + } + } + } + + return 0; +} +//******************************************************************************** +int GamePad_t::loadDefaults(void) +{ + + if ( jsDev[ devIdx ].gc ) + { + char *mapping; + + mapping = SDL_GameControllerMapping( jsDev[ devIdx ].gc ); + + if ( mapping == NULL ) return -1; + + setMapping( mapping ); + + SDL_free(mapping); + } + return 0; +} +//******************************************************************************** static int s_jinited = 0; +//******************************************************************************** +jsDev_t *getJoystickDevice( int devNum ) +{ + if ( (devNum >= 0) && (devNum < MAX_JOYSTICKS) ) + { + return &jsDev[ devNum ]; + } + return NULL; +} +//******************************************************************************** /** * Tests if the given button is active on the joystick. */ @@ -219,7 +425,8 @@ int AddJoystick( int which ) else { printf("Added Joystick: %i \n", which ); - jsDev[which].print(); + jsDev[which].init(which); + //jsDev[which].print(); //printJoystick( s_Joysticks[which] ); } } @@ -235,7 +442,8 @@ int AddJoystick( int which ) else { printf("Added Joystick: %i \n", which ); - jsDev[which].print(); + jsDev[which].init(which); + //jsDev[which].print(); //printJoystick( s_Joysticks[which] ); } } @@ -286,26 +494,6 @@ InitJoysticks(void) { /* Open the joystick under SDL. */ AddJoystick(n); - //if ( SDL_IsGameController(n) ) - //{ - // SDL_GameController *gc = SDL_GameControllerOpen(n); - // printf("Is Game Controller: %i \n", n); - - // printf("Mapping: %s \n", SDL_GameControllerMapping(gc) ); - //} - // s_Joysticks[n] = SDL_JoystickOpen(n); - - //if ( s_Joysticks[n] == NULL ) - //{ - // printf("Could not open joystick %d: %s.\n", - // n, SDL_GetError()); - //} - //else - //{ - // printf("Opened JS %i: \n", SDL_JoystickInstanceID( s_Joysticks[n] ) ); - // jsDev[which].print(); - // //printJoystick( s_Joysticks[n] ); - //} } s_jinited = 1; diff --git a/src/drivers/Qt/sdl-joystick.h b/src/drivers/Qt/sdl-joystick.h new file mode 100644 index 00000000..2f992e01 --- /dev/null +++ b/src/drivers/Qt/sdl-joystick.h @@ -0,0 +1,58 @@ +// sdl-joystick.h + +#ifndef __SDL_JOYSTICK_H__ +#define __SDL_JOYSTICK_H__ + +#include + +#include "Qt/main.h" +#include "Qt/input.h" +#include "Qt/sdl.h" + +#define MAX_JOYSTICKS 32 + +struct jsDev_t +{ + SDL_Joystick *js; + SDL_GameController *gc; + + jsDev_t(void); + //~jsDev_t(void); + + void init( int idx ); + int close(void); + SDL_Joystick *getJS(void); + bool isGameController(void); + bool inUse(void); + void print(void); + const char *getName(void); + const char *getGUID(void); + + private: + int devIdx; + std::string guidStr; + std::string name; +}; + +class GamePad_t +{ + public: + + int type; + int devIdx; + + ButtConfig bmap[GAMEPAD_NUM_BUTTONS]; + + GamePad_t(void); + ~GamePad_t(void); + + int loadDefaults(void); + + int setMapping( const char *map ); +}; + +extern GamePad_t GamePad[4]; + +jsDev_t *getJoystickDevice( int devNum ); + +#endif