Added logic to load default game pad button bindings from SDL database.

This commit is contained in:
Matthew Budd 2020-07-24 00:11:11 -04:00
parent e018b4b945
commit e50d6e22ed
6 changed files with 452 additions and 137 deletions

View File

@ -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; i<MAX_JOYSTICKS; i++)
{
jsDev_t *js = getJoystickDevice( i );
if ( js != NULL )
{
if ( js->inUse() )
{
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; i<GAMEPAD_NUM_BUTTONS; i++)
{
if (GamePadConfig[portNum][i].ButtType == BUTTC_KEYBOARD)
if (GamePad[portNum].bmap[i].ButtType == BUTTC_KEYBOARD)
{
snprintf( keyNameStr, sizeof (keyNameStr), "%s",
SDL_GetKeyName (GamePadConfig[portNum][i].ButtonNum));
SDL_GetKeyName (GamePad[portNum].bmap[i].ButtonNum));
}
else
{
strcpy( keyNameStr, ButtonName( &GamePadConfig[portNum][i] ) );
strcpy( keyNameStr, ButtonName( &GamePad[portNum].bmap[i] ) );
}
keyName[i]->setText( 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; x<GAMEPAD_NUM_BUTTONS; x++)
{
GamePad[portNum].bmap[x].ButtType = BUTTC_KEYBOARD;
GamePad[portNum].bmap[x].DeviceNum = 0;
GamePad[portNum].bmap[x].ButtonNum = DefaultGamePad[portNum][x];
g_config->setOption (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; x<GAMEPAD_NUM_BUTTONS; x++)
else
{
GamePadConfig[portNum][x].ButtType = BUTTC_KEYBOARD;
GamePadConfig[portNum][x].DeviceNum = 0;
GamePadConfig[portNum][x].ButtonNum = DefaultGamePad[portNum][x];
g_config->setOption (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();
}

View File

@ -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);
};

View File

@ -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);

View File

@ -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];

View File

@ -23,97 +23,303 @@
/// \brief Handles joystick input using the SDL.
#include "Qt/sdl.h"
#include "Qt/sdl-joystick.h"
#include <cstdlib>
#include <unistd.h>
#include <fcntl.h>
#include <cerrno>
#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<GAMEPAD_NUM_BUTTONS; i++)
{
bmap[i].ButtType = BUTTC_KEYBOARD;
bmap[i].DeviceNum = -1;
bmap[i].ButtonNum = -1;
}
}
//********************************************************************************
GamePad_t::~GamePad_t(void)
{
}
//********************************************************************************
static int sdlButton2NesGpIdx( const char *id )
{
int idx = -1;
if ( strcmp( id, "a" ) == 0 )
{
idx = 0;
}
else if ( strcmp( id, "b" ) == 0 )
{
idx = 1;
}
else if ( strcmp( id, "back" ) == 0 )
{
idx = 2;
}
else if ( strcmp( id, "start" ) == 0 )
{
idx = 3;
}
else if ( strcmp( id, "dpup" ) == 0 )
{
idx = 4;
}
else if ( strcmp( id, "dpdown" ) == 0 )
{
idx = 5;
}
else if ( strcmp( id, "dpleft" ) == 0 )
{
idx = 6;
}
else if ( strcmp( id, "dpright" ) == 0 )
{
idx = 7;
}
return idx;
}
//********************************************************************************
int GamePad_t::setMapping( const char *map )
{
int i,j,k,bIdx;
char id[32][64];
char val[32][64];
//char guidStr[64];
i=0; j=0; k=0;
while ( map[i] )
{
while ( isspace(map[i]) ) i++;
j=0;
while ( (map[i] != 0) && (map[i] != ',') && (map[i] != ':') )
{
id[k][j] = map[i]; i++; j++;
}
id[k][j] = 0;
val[k][0] = 0;
if ( map[i] == ':' )
{
i++; j=0;
while ( (map[i] != 0) && (map[i] != ',') )
{
val[k][j] = map[i]; i++; j++;
}
val[k][j] = 0;
}
if ( map[i] == ',' )
{
k++; i++;
}
else
{
break;
}
}
for (i=0; i<k; i++)
{
bIdx = sdlButton2NesGpIdx( id[i] );
printf(" '%s' = '%s' %i \n", id[i], val[i], bIdx );
if ( bIdx >= 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;

View File

@ -0,0 +1,58 @@
// sdl-joystick.h
#ifndef __SDL_JOYSTICK_H__
#define __SDL_JOYSTICK_H__
#include <string>
#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