Added game pad button mapping profile logic.
This commit is contained in:
parent
675b73cbed
commit
b71630379a
|
@ -142,6 +142,7 @@ void FCEUI_SetRenderedLines(int ntscf, int ntscl, int palf, int pall);
|
|||
|
||||
//Sets the base directory(save states, snapshots, etc. are saved in directories below this directory.
|
||||
void FCEUI_SetBaseDirectory(std::string const & dir);
|
||||
const char *FCEUI_GetBaseDirectory(void);
|
||||
|
||||
bool FCEUI_GetUserPaletteAvail(void);
|
||||
void FCEUI_SetUserPalette(uint8 *pal, int nEntries);
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
// GamePadConf.cpp
|
||||
//
|
||||
#include <QDir>
|
||||
#include <QInputDialog>
|
||||
|
||||
#include "Qt/GamePadConf.h"
|
||||
#include "Qt/main.h"
|
||||
#include "Qt/dface.h"
|
||||
|
@ -13,13 +16,16 @@
|
|||
GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
|
||||
: QDialog( parent )
|
||||
{
|
||||
QHBoxLayout *hbox1, *hbox2, *hbox3, *hbox4;
|
||||
QHBoxLayout *hbox, *hbox1, *hbox2, *hbox3, *hbox4;
|
||||
QVBoxLayout *vbox;
|
||||
QGridLayout *grid;
|
||||
QCheckBox *efs_chkbox, *udlr_chkbox;
|
||||
QGroupBox *frame1, *frame2;
|
||||
QLabel *label;
|
||||
QPushButton *newProfileButton;
|
||||
QPushButton *saveProfileButton;
|
||||
QPushButton *applyProfileButton;
|
||||
QPushButton *removeProfileButton;
|
||||
QPushButton *loadDefaultButton;
|
||||
QPushButton *clearAllButton;
|
||||
QPushButton *closebutton;
|
||||
|
@ -64,7 +70,7 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
|
|||
|
||||
if ( js != NULL )
|
||||
{
|
||||
if ( js->inUse() )
|
||||
if ( js->isConnected() )
|
||||
{
|
||||
char stmp[128];
|
||||
sprintf( stmp, "%i: %s", i, js->getName() );
|
||||
|
@ -80,19 +86,45 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
|
|||
hbox3->addWidget( guidLbl );
|
||||
|
||||
frame1 = new QGroupBox(tr("Mapping Profile:"));
|
||||
grid = new QGridLayout();
|
||||
//grid = new QGridLayout();
|
||||
vbox = new QVBoxLayout();
|
||||
|
||||
frame1->setLayout( grid );
|
||||
//frame1->setLayout( grid );
|
||||
frame1->setLayout( vbox );
|
||||
|
||||
hbox = new QHBoxLayout();
|
||||
vbox->addLayout( hbox );
|
||||
|
||||
mapSel = new QComboBox();
|
||||
hbox->addWidget( mapSel );
|
||||
|
||||
mapSel->setWhatsThis( tr("Combo box for selection of a saved button mapping profile for the selected device"));
|
||||
mapSel->addItem( tr("default"), 0 );
|
||||
|
||||
hbox = new QHBoxLayout();
|
||||
vbox->addLayout( hbox );
|
||||
|
||||
applyProfileButton = new QPushButton( tr("Load") );
|
||||
applyProfileButton->setWhatsThis(tr("Sets Current Active Map to the Selected Profile"));
|
||||
hbox->addWidget( applyProfileButton );
|
||||
|
||||
saveProfileButton = new QPushButton( tr("Save") );
|
||||
saveProfileButton->setWhatsThis(tr("Stores Current Active Map to the Selected Profile"));
|
||||
hbox->addWidget( saveProfileButton );
|
||||
|
||||
hbox = new QHBoxLayout();
|
||||
vbox->addLayout( hbox );
|
||||
|
||||
newProfileButton = new QPushButton( tr("New") );
|
||||
newProfileButton->setWhatsThis(tr("Create a New Map Profile"));
|
||||
hbox->addWidget( newProfileButton );
|
||||
|
||||
grid->addWidget( mapSel , 0, 0, Qt::AlignCenter );
|
||||
grid->addWidget( applyProfileButton, 0, 1, Qt::AlignCenter );
|
||||
grid->addWidget( newProfileButton , 0, 2, Qt::AlignCenter );
|
||||
removeProfileButton = new QPushButton( tr("Delete") );
|
||||
removeProfileButton->setWhatsThis(tr("Deletes the Selected Map Profile"));
|
||||
hbox->addWidget( removeProfileButton );
|
||||
|
||||
mapSel->addItem( tr("Default"), 0 );
|
||||
mapMsg = new QLabel();
|
||||
vbox->addWidget(mapMsg);
|
||||
|
||||
efs_chkbox = new QCheckBox( tr("Enable Four Score") );
|
||||
udlr_chkbox = new QCheckBox( tr("Allow Up+Down/Left+Right") );
|
||||
|
@ -169,6 +201,10 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
|
|||
connect(clearButton[8], SIGNAL(clicked()), this, SLOT(clearButton8(void)) );
|
||||
connect(clearButton[9], SIGNAL(clicked()), this, SLOT(clearButton9(void)) );
|
||||
|
||||
connect(newProfileButton , SIGNAL(clicked()), this, SLOT(newProfileCallback(void)) );
|
||||
connect(applyProfileButton, SIGNAL(clicked()), this, SLOT(loadProfileCallback(void)) );
|
||||
connect(saveProfileButton , SIGNAL(clicked()), this, SLOT(saveProfileCallback(void)) );
|
||||
|
||||
connect(loadDefaultButton, SIGNAL(clicked()), this, SLOT(loadDefaults(void)) );
|
||||
connect(clearAllButton , SIGNAL(clicked()), this, SLOT(clearAllCallback(void)) );
|
||||
connect(closebutton , SIGNAL(clicked()), this, SLOT(closeWindow(void)) );
|
||||
|
@ -192,6 +228,8 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
|
|||
setLayout( mainLayout );
|
||||
|
||||
inputTimer->start( 33 ); // 30hz
|
||||
|
||||
loadMapList();
|
||||
}
|
||||
|
||||
//----------------------------------------------------
|
||||
|
@ -212,6 +250,62 @@ void GamePadConfDialog_t::keyReleaseEvent(QKeyEvent *event)
|
|||
pushKeyEvent( event, 0 );
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void GamePadConfDialog_t::loadMapList(void)
|
||||
{
|
||||
QDir dir;
|
||||
QStringList filters, fileList;
|
||||
const char *baseDir = FCEUI_GetBaseDirectory();
|
||||
const char *guid;
|
||||
std::string path;
|
||||
int index, devIdx;
|
||||
jsDev_t *js;
|
||||
|
||||
index = devSel->currentIndex();
|
||||
devIdx = devSel->itemData(index).toInt();
|
||||
|
||||
if ( devIdx < 0 )
|
||||
{
|
||||
guid = "keyboard";
|
||||
}
|
||||
else
|
||||
{
|
||||
js = getJoystickDevice( devIdx );
|
||||
|
||||
guid = js->getGUID();
|
||||
}
|
||||
|
||||
if ( guid == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
path = std::string(baseDir) + "/input/" + std::string(guid);
|
||||
|
||||
dir.setPath( QString::fromStdString(path) );
|
||||
|
||||
filters << "*.txt";
|
||||
dir.setNameFilters(filters);
|
||||
|
||||
fileList = dir.entryList( filters, QDir::Files, QDir::NoSort );
|
||||
|
||||
mapSel->clear();
|
||||
mapSel->addItem( tr("default"), 0 );
|
||||
|
||||
for (size_t i=0; i < fileList.size(); i++)
|
||||
{
|
||||
size_t suffixIdx;
|
||||
std::string fileName = fileList[i].toStdString();
|
||||
|
||||
suffixIdx = fileName.find_last_of('.');
|
||||
|
||||
fileName.erase( suffixIdx );
|
||||
|
||||
//printf("File: %s \n", fileName.c_str() );
|
||||
|
||||
mapSel->addItem( tr(fileName.c_str()), (int)i+1 );
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void GamePadConfDialog_t::updateCntrlrDpy(void)
|
||||
{
|
||||
char keyNameStr[128];
|
||||
|
@ -247,7 +341,7 @@ void GamePadConfDialog_t::deviceSelect(int index)
|
|||
|
||||
if ( js != NULL )
|
||||
{
|
||||
if ( js->inUse() )
|
||||
if ( js->isConnected() )
|
||||
{
|
||||
guidLbl->setText( js->getGUID() );
|
||||
}
|
||||
|
@ -256,6 +350,9 @@ void GamePadConfDialog_t::deviceSelect(int index)
|
|||
{
|
||||
guidLbl->setText("");
|
||||
}
|
||||
GamePad[portNum].setDeviceIndex( devIdx );
|
||||
|
||||
loadMapList();
|
||||
|
||||
updateCntrlrDpy();
|
||||
}
|
||||
|
@ -472,7 +569,7 @@ void GamePadConfDialog_t::loadDefaults(void)
|
|||
index = devSel->currentIndex();
|
||||
devIdx = devSel->itemData(index).toInt();
|
||||
|
||||
printf("Selected Device:%i : %i \n", index, devIdx );
|
||||
//printf("Selected Device:%i : %i \n", index, devIdx );
|
||||
|
||||
if ( devIdx == -1 )
|
||||
{
|
||||
|
@ -506,12 +603,95 @@ void GamePadConfDialog_t::loadDefaults(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
GamePad[portNum].devIdx = devIdx;
|
||||
GamePad[portNum].setDeviceIndex( devIdx );
|
||||
GamePad[portNum].loadDefaults();
|
||||
}
|
||||
updateCntrlrDpy();
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void GamePadConfDialog_t::createNewProfile( const char *name )
|
||||
{
|
||||
printf("Creating: %s \n", name );
|
||||
|
||||
GamePad[portNum].createProfile(name);
|
||||
|
||||
mapSel->addItem( tr(name) );
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void GamePadConfDialog_t::newProfileCallback(void)
|
||||
{
|
||||
int ret;
|
||||
QInputDialog dialog(this);
|
||||
|
||||
dialog.setWindowTitle( tr("New Profile") );
|
||||
dialog.setLabelText( tr("Specify New Profile Name") );
|
||||
dialog.setOkButtonText( tr("Create") );
|
||||
|
||||
dialog.show();
|
||||
ret = dialog.exec();
|
||||
|
||||
if ( QDialog::Accepted == ret )
|
||||
{
|
||||
createNewProfile( dialog.textValue().toStdString().c_str() );
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void GamePadConfDialog_t::loadProfileCallback(void)
|
||||
{
|
||||
char stmp[256];
|
||||
int index, devIdx, ret;
|
||||
std::string mapName;
|
||||
|
||||
index = devSel->currentIndex();
|
||||
devIdx = devSel->itemData(index).toInt();
|
||||
|
||||
mapName = mapSel->currentText().toStdString();
|
||||
|
||||
GamePad[portNum].setDeviceIndex( devIdx );
|
||||
|
||||
if ( mapName.compare("default") == 0 )
|
||||
{
|
||||
ret =GamePad[portNum].loadDefaults();
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = GamePad[portNum].loadProfile( mapName.c_str() );
|
||||
}
|
||||
if ( ret == 0 )
|
||||
{
|
||||
sprintf( stmp, "Mapping Loaded: %s/%s \n", GamePad[portNum].getGUID(), mapName.c_str() );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( stmp, "Error: Failed to Load Mapping: %s/%s \n", GamePad[portNum].getGUID(), mapName.c_str() );
|
||||
}
|
||||
mapMsg->setText( tr(stmp) );
|
||||
|
||||
updateCntrlrDpy();
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void GamePadConfDialog_t::saveProfileCallback(void)
|
||||
{
|
||||
int ret;
|
||||
std::string mapName;
|
||||
char stmp[256];
|
||||
|
||||
mapName = mapSel->currentText().toStdString();
|
||||
|
||||
ret = GamePad[portNum].saveCurrentMapToFile( mapName.c_str() );
|
||||
|
||||
if ( ret == 0 )
|
||||
{
|
||||
sprintf( stmp, "Mapping Saved: %s/%s \n", GamePad[portNum].getGUID(), mapName.c_str() );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( stmp, "Error: Failed to Save Mapping: %s \n", mapName.c_str() );
|
||||
}
|
||||
mapMsg->setText( tr(stmp) );
|
||||
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void GamePadConfDialog_t::updatePeriodic(void)
|
||||
{
|
||||
for (int i=0; i<GAMEPAD_NUM_BUTTONS; i++)
|
||||
|
|
|
@ -44,6 +44,7 @@ class GamePadConfDialog_t : public QDialog
|
|||
QComboBox *mapSel;
|
||||
QComboBox *profSel;
|
||||
QLabel *guidLbl;
|
||||
QLabel *mapMsg;
|
||||
QLabel *keyName[GAMEPAD_NUM_BUTTONS];
|
||||
QLabel *keyState[GAMEPAD_NUM_BUTTONS];
|
||||
GamePadConfigButton_t *button[GAMEPAD_NUM_BUTTONS];
|
||||
|
@ -58,6 +59,8 @@ class GamePadConfDialog_t : public QDialog
|
|||
void closeEvent(QCloseEvent *bar);
|
||||
private:
|
||||
void updateCntrlrDpy(void);
|
||||
void createNewProfile( const char *name );
|
||||
void loadMapList(void);
|
||||
|
||||
public slots:
|
||||
void closeWindow(void);
|
||||
|
@ -88,6 +91,9 @@ class GamePadConfDialog_t : public QDialog
|
|||
void oppDirEna(int state);
|
||||
void portSelect(int index);
|
||||
void deviceSelect(int index);
|
||||
void newProfileCallback(void);
|
||||
void loadProfileCallback(void);
|
||||
void saveProfileCallback(void);
|
||||
void updatePeriodic(void);
|
||||
|
||||
};
|
||||
|
|
|
@ -102,20 +102,20 @@ LoadCPalette(const std::string &file)
|
|||
static void
|
||||
CreateDirs(const std::string &dir)
|
||||
{
|
||||
const char *subs[8]={"fcs","snaps","gameinfo","sav","cheats","movies","cfg.d"};
|
||||
const char *subs[9]={"fcs","snaps","gameinfo","sav","cheats","movies","input"};
|
||||
std::string subdir;
|
||||
int x;
|
||||
|
||||
#if defined(WIN32) || defined(NEED_MINGW_HACKS)
|
||||
mkdir(dir.c_str());
|
||||
chmod(dir.c_str(), 755);
|
||||
for(x = 0; x < 6; x++) {
|
||||
for(x = 0; x < 7; x++) {
|
||||
subdir = dir + PSS + subs[x];
|
||||
mkdir(subdir.c_str());
|
||||
}
|
||||
#else
|
||||
mkdir(dir.c_str(), S_IRWXU);
|
||||
for(x = 0; x < 6; x++) {
|
||||
for(x = 0; x < 7; x++) {
|
||||
subdir = dir + PSS + subs[x];
|
||||
mkdir(subdir.c_str(), S_IRWXU);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
/// \file
|
||||
/// \brief Handles joystick input using the SDL.
|
||||
|
||||
#include <QDir>
|
||||
#include "Qt/sdl.h"
|
||||
#include "Qt/sdl-joystick.h"
|
||||
|
||||
|
@ -41,6 +42,13 @@ static int sdlButton2NesGpIdx( const char *id );
|
|||
// Static Variables
|
||||
static int s_jinited = 0;
|
||||
|
||||
static const char *buttonNames[ GAMEPAD_NUM_BUTTONS ] =
|
||||
{
|
||||
"a", "b","back","start",
|
||||
"dpup","dpdown","dpleft","dpright",
|
||||
"turboA","turboB"
|
||||
};
|
||||
|
||||
//********************************************************************************
|
||||
// Joystick Device
|
||||
jsDev_t::jsDev_t(void)
|
||||
|
@ -91,7 +99,7 @@ bool jsDev_t::isGameController(void)
|
|||
}
|
||||
|
||||
//********************************************************************************
|
||||
bool jsDev_t::inUse(void)
|
||||
bool jsDev_t::isConnected(void)
|
||||
{
|
||||
return ( (js != NULL) || (gc != NULL) );
|
||||
}
|
||||
|
@ -151,15 +159,23 @@ static jsDev_t jsDev[ MAX_JOYSTICKS ];
|
|||
//********************************************************************************
|
||||
nesGamePadMap_t::nesGamePadMap_t(void)
|
||||
{
|
||||
memset( guid, 0, sizeof(guid) );
|
||||
memset( name, 0, sizeof(name) );
|
||||
memset( os , 0, sizeof(os) );
|
||||
memset( btn , 0, sizeof(btn) );
|
||||
clearMapping();
|
||||
}
|
||||
//********************************************************************************
|
||||
nesGamePadMap_t::~nesGamePadMap_t(void)
|
||||
{
|
||||
|
||||
}
|
||||
//********************************************************************************
|
||||
void nesGamePadMap_t::clearMapping(void)
|
||||
{
|
||||
guid[0] = 0;
|
||||
name[0] = 0;
|
||||
os[0] = 0;
|
||||
for (int i=0; i<GAMEPAD_NUM_BUTTONS; i++)
|
||||
{
|
||||
btn[i][0] = 0;
|
||||
}
|
||||
}
|
||||
//********************************************************************************
|
||||
int nesGamePadMap_t::parseMapping( const char *map )
|
||||
|
@ -168,6 +184,8 @@ int nesGamePadMap_t::parseMapping( const char *map )
|
|||
char id[32][64];
|
||||
char val[32][64];
|
||||
|
||||
clearMapping();
|
||||
|
||||
i=0; j=0; k=0;
|
||||
|
||||
while ( map[i] )
|
||||
|
@ -220,11 +238,12 @@ int nesGamePadMap_t::parseMapping( const char *map )
|
|||
strcpy( os, val[i] );
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//********************************************************************************
|
||||
GamePad_t::GamePad_t(void)
|
||||
{
|
||||
devIdx = 0;
|
||||
devIdx = -1;
|
||||
|
||||
for (int i=0; i<GAMEPAD_NUM_BUTTONS; i++)
|
||||
{
|
||||
|
@ -237,51 +256,37 @@ GamePad_t::GamePad_t(void)
|
|||
GamePad_t::~GamePad_t(void)
|
||||
{
|
||||
|
||||
}
|
||||
//********************************************************************************
|
||||
int GamePad_t::setDeviceIndex( int in )
|
||||
{
|
||||
devIdx = in;
|
||||
return 0;
|
||||
}
|
||||
//********************************************************************************
|
||||
const char *GamePad_t::getGUID(void)
|
||||
{
|
||||
if ( devIdx < 0 )
|
||||
{
|
||||
return "keyboard";
|
||||
}
|
||||
if ( jsDev[ devIdx ].isConnected() )
|
||||
{
|
||||
return jsDev[ devIdx ].getGUID();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
//********************************************************************************
|
||||
static int sdlButton2NesGpIdx( const char *id )
|
||||
{
|
||||
int idx = -1;
|
||||
int i, 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;
|
||||
}
|
||||
else if ( strcmp( id, "turboA" ) == 0 )
|
||||
{
|
||||
idx = 8;
|
||||
}
|
||||
else if ( strcmp( id, "turboB" ) == 0 )
|
||||
{
|
||||
idx = 9;
|
||||
for (i=0; i<GAMEPAD_NUM_BUTTONS; i++)
|
||||
{
|
||||
if ( strcmp( id, buttonNames[i] ) == 0 )
|
||||
{
|
||||
idx = i; break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
|
@ -297,9 +302,21 @@ int GamePad_t::setMapping( nesGamePadMap_t *gpm )
|
|||
|
||||
if (gpm->btn[i][0] == 'k')
|
||||
{
|
||||
SDL_Keycode key;
|
||||
|
||||
bmap[i].ButtType = BUTTC_KEYBOARD;
|
||||
bmap[i].DeviceNum = 0;
|
||||
bmap[i].ButtonNum = 0; // FIXME
|
||||
bmap[i].DeviceNum = -1;
|
||||
|
||||
key = SDL_GetKeyFromName( &gpm->btn[i][1] );
|
||||
|
||||
if ( key != SDLK_UNKNOWN )
|
||||
{
|
||||
bmap[i].ButtonNum = key;
|
||||
}
|
||||
else
|
||||
{
|
||||
bmap[i].ButtonNum = -1;
|
||||
}
|
||||
}
|
||||
else if ( (gpm->btn[i][0] == 'b') && isdigit( gpm->btn[i][1] ) )
|
||||
{
|
||||
|
@ -369,24 +386,280 @@ int GamePad_t::setMapping( const char *map )
|
|||
return 0;
|
||||
}
|
||||
//********************************************************************************
|
||||
int GamePad_t::getMapFromFile( const char *filename, char *out )
|
||||
{
|
||||
int i=0,j=0;
|
||||
FILE *fp;
|
||||
char line[256];
|
||||
|
||||
out[0] = 0;
|
||||
|
||||
fp = ::fopen( filename, "r" );
|
||||
|
||||
if ( fp == NULL )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
while ( fgets( line, sizeof(line), fp ) != 0 )
|
||||
{
|
||||
i=0;
|
||||
while (line[i] != 0)
|
||||
{
|
||||
if ( line[i] == '#' )
|
||||
{
|
||||
line[i] = 0; break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if ( i < 32 ) continue; // need at least 32 chars for a valid line entry
|
||||
|
||||
i=0; j=0;
|
||||
while ( isspace(line[i]) ) i++;
|
||||
|
||||
while ( line[i] != 0 )
|
||||
{
|
||||
out[j] = line[i]; i++; j++;
|
||||
}
|
||||
out[j] = 0;
|
||||
|
||||
if ( j < 34 ) continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
::fclose(fp);
|
||||
|
||||
return (j < 34);
|
||||
}
|
||||
//********************************************************************************
|
||||
int GamePad_t::getDefaultMap( char *out, const char *guid )
|
||||
{
|
||||
char txtMap[256];
|
||||
const char *baseDir = FCEUI_GetBaseDirectory();
|
||||
std::string path;
|
||||
|
||||
out[0] = 0;
|
||||
|
||||
if ( devIdx < 0 )
|
||||
{
|
||||
guid = "keyboard";
|
||||
}
|
||||
if ( guid == NULL )
|
||||
{
|
||||
if ( jsDev[ devIdx ].isConnected() )
|
||||
{
|
||||
guid = jsDev[ devIdx ].getGUID();
|
||||
}
|
||||
}
|
||||
if ( guid == NULL )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
path = std::string(baseDir) + "/input/" + std::string(guid) + "/default.txt";
|
||||
|
||||
if ( getMapFromFile( path.c_str(), txtMap ) == 0 )
|
||||
{
|
||||
printf("Using Mapping From File: %s\n", path.c_str() );
|
||||
strcpy( out, txtMap );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( devIdx >= 0 )
|
||||
{
|
||||
if ( jsDev[ devIdx ].gc )
|
||||
{
|
||||
char *sdlMapping;
|
||||
|
||||
sdlMapping = SDL_GameControllerMapping( jsDev[ devIdx ].gc );
|
||||
|
||||
if ( sdlMapping == NULL ) return -1;
|
||||
|
||||
strcpy( out, sdlMapping );
|
||||
|
||||
SDL_free(sdlMapping);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
//********************************************************************************
|
||||
int GamePad_t::loadDefaults(void)
|
||||
{
|
||||
char txtMap[256];
|
||||
|
||||
if ( jsDev[ devIdx ].gc )
|
||||
{
|
||||
char *mapping;
|
||||
if ( getDefaultMap( txtMap ) == 0 )
|
||||
{
|
||||
setMapping( txtMap );
|
||||
}
|
||||
|
||||
mapping = SDL_GameControllerMapping( jsDev[ devIdx ].gc );
|
||||
|
||||
if ( mapping == NULL ) return -1;
|
||||
|
||||
setMapping( mapping );
|
||||
|
||||
SDL_free(mapping);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//********************************************************************************
|
||||
int GamePad_t::loadProfile( const char *name, const char *guid )
|
||||
{
|
||||
char txtMap[256];
|
||||
const char *baseDir = FCEUI_GetBaseDirectory();
|
||||
std::string path;
|
||||
|
||||
if ( devIdx < 0 )
|
||||
{
|
||||
guid = "keyboard";
|
||||
}
|
||||
if ( guid == NULL )
|
||||
{
|
||||
if ( jsDev[ devIdx ].isConnected() )
|
||||
{
|
||||
guid = jsDev[ devIdx ].getGUID();
|
||||
}
|
||||
}
|
||||
if ( guid == NULL )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
path = std::string(baseDir) + "/input/" + std::string(guid) +
|
||||
"/" + std::string(name) + ".txt";
|
||||
|
||||
//printf("Using File: %s\n", path.c_str() );
|
||||
|
||||
if ( getMapFromFile( path.c_str(), txtMap ) == 0 )
|
||||
{
|
||||
setMapping( txtMap );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
//********************************************************************************
|
||||
int GamePad_t::saveCurrentMapToFile( const char *name )
|
||||
{
|
||||
int i;
|
||||
char stmp[64];
|
||||
const char *guid = NULL;
|
||||
const char *baseDir = FCEUI_GetBaseDirectory();
|
||||
std::string path, output;
|
||||
QDir dir;
|
||||
|
||||
if ( devIdx >= 0 )
|
||||
{
|
||||
if ( !jsDev[devIdx].isConnected() )
|
||||
{
|
||||
printf("Error: JS%i Not Connected\n", devIdx );
|
||||
return -1;
|
||||
}
|
||||
guid = jsDev[devIdx].getGUID();
|
||||
}
|
||||
else
|
||||
{
|
||||
guid = "keyboard";
|
||||
}
|
||||
path = std::string(baseDir) + "/input/" + std::string(guid);
|
||||
|
||||
dir.mkpath( QString::fromStdString(path) );
|
||||
|
||||
path += "/" + std::string(name) + ".txt";
|
||||
|
||||
output.assign( guid );
|
||||
output.append( "," );
|
||||
output.append( name );
|
||||
output.append( "," );
|
||||
|
||||
for (i=0; i<GAMEPAD_NUM_BUTTONS; i++)
|
||||
{
|
||||
if ( bmap[i].ButtType == BUTTC_KEYBOARD )
|
||||
{
|
||||
sprintf( stmp, "k%s", SDL_GetKeyName (bmap[i].ButtonNum) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bmap[i].ButtonNum & 0x2000)
|
||||
{
|
||||
/* Hat "button" */
|
||||
sprintf( stmp, "h%i.%i",
|
||||
(bmap[i].ButtonNum >> 8) & 0x1F, bmap[i].ButtonNum & 0xFF );
|
||||
}
|
||||
else if (bmap[i].ButtonNum & 0x8000)
|
||||
{
|
||||
/* Axis "button" */
|
||||
sprintf( stmp, "%ca%i",
|
||||
(bmap[i].ButtonNum & 0x4000) ? '-' : '+', bmap[i].ButtonNum & 0x3FFF );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Button */
|
||||
sprintf( stmp, "b%i", bmap[i].ButtonNum );
|
||||
}
|
||||
}
|
||||
output.append( buttonNames[i] );
|
||||
output.append( ":" );
|
||||
output.append( stmp );
|
||||
output.append( "," );
|
||||
}
|
||||
|
||||
return saveMappingToFile( path.c_str(), output.c_str() );
|
||||
}
|
||||
//********************************************************************************
|
||||
int GamePad_t::saveMappingToFile( const char *filename, const char *txtMap )
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp = ::fopen(filename, "w");
|
||||
|
||||
if ( fp == NULL )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
fprintf( fp, "%s\n", txtMap );
|
||||
|
||||
::fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
//********************************************************************************
|
||||
int GamePad_t::createProfile( const char *name )
|
||||
{
|
||||
char txtMap[256];
|
||||
const char *guid = NULL;
|
||||
const char *baseDir = FCEUI_GetBaseDirectory();
|
||||
std::string path;
|
||||
QDir dir;
|
||||
|
||||
if ( baseDir[0] == 0 )
|
||||
{
|
||||
printf("Error: Invalid base directory\n");
|
||||
return -1;
|
||||
}
|
||||
if ( devIdx >= 0 )
|
||||
{
|
||||
if ( !jsDev[devIdx].isConnected() )
|
||||
{
|
||||
printf("Error: JS%i Not Connected\n", devIdx );
|
||||
return -1;
|
||||
}
|
||||
guid = jsDev[devIdx].getGUID();
|
||||
}
|
||||
else
|
||||
{
|
||||
guid = "keyboard";
|
||||
}
|
||||
path = std::string(baseDir) + "/input/" + std::string(guid);
|
||||
|
||||
dir.mkpath( QString::fromStdString(path) );
|
||||
//printf("DIR: '%s'\n", path.c_str() );
|
||||
|
||||
path += "/" + std::string(name) + ".txt";
|
||||
|
||||
//printf("File: '%s'\n", path.c_str() );
|
||||
|
||||
getDefaultMap( txtMap, guid );
|
||||
|
||||
saveMappingToFile( path.c_str(), txtMap );
|
||||
|
||||
return 0;
|
||||
}
|
||||
//********************************************************************************
|
||||
jsDev_t *getJoystickDevice( int devNum )
|
||||
{
|
||||
|
@ -410,6 +683,10 @@ DTestButtonJoy(ButtConfig *bc)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
if ( bc->DeviceNum < 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
js = jsDev[bc->DeviceNum].getJS();
|
||||
|
||||
if (bc->ButtonNum & 0x2000)
|
||||
|
@ -432,7 +709,7 @@ DTestButtonJoy(ButtConfig *bc)
|
|||
/* Axis "button" */
|
||||
int pos;
|
||||
pos = SDL_JoystickGetAxis( js,
|
||||
bc->ButtonNum & 16383);
|
||||
bc->ButtonNum & 0x3FFF);
|
||||
if ((bc->ButtonNum & 0x4000) && pos <= -16383)
|
||||
{
|
||||
bc->state = 1;
|
||||
|
@ -508,7 +785,7 @@ KillJoysticks(void)
|
|||
//********************************************************************************
|
||||
int AddJoystick( int which )
|
||||
{
|
||||
if ( jsDev[ which ].inUse() )
|
||||
if ( jsDev[ which ].isConnected() )
|
||||
{
|
||||
//printf("Error: Joystick already exists at device index %i \n", which );
|
||||
return -1;
|
||||
|
@ -560,7 +837,7 @@ int RemoveJoystick( int which )
|
|||
|
||||
for (int i=0; i<MAX_JOYSTICKS; i++)
|
||||
{
|
||||
if ( jsDev[i].inUse() )
|
||||
if ( jsDev[i].isConnected() )
|
||||
{
|
||||
if ( SDL_JoystickInstanceID( jsDev[i].getJS() ) == which )
|
||||
{
|
||||
|
|
|
@ -21,6 +21,7 @@ struct nesGamePadMap_t
|
|||
nesGamePadMap_t(void);
|
||||
~nesGamePadMap_t(void);
|
||||
|
||||
void clearMapping(void);
|
||||
int parseMapping( const char *text );
|
||||
};
|
||||
|
||||
|
@ -36,7 +37,7 @@ struct jsDev_t
|
|||
int close(void);
|
||||
SDL_Joystick *getJS(void);
|
||||
bool isGameController(void);
|
||||
bool inUse(void);
|
||||
bool isConnected(void);
|
||||
void print(void);
|
||||
const char *getName(void);
|
||||
const char *getGUID(void);
|
||||
|
@ -51,7 +52,7 @@ class GamePad_t
|
|||
{
|
||||
public:
|
||||
|
||||
int type;
|
||||
//int type;
|
||||
int devIdx;
|
||||
|
||||
ButtConfig bmap[GAMEPAD_NUM_BUTTONS];
|
||||
|
@ -59,10 +60,20 @@ class GamePad_t
|
|||
GamePad_t(void);
|
||||
~GamePad_t(void);
|
||||
|
||||
int loadDefaults(void);
|
||||
const char *getGUID(void);
|
||||
|
||||
int loadDefaults(void);
|
||||
int loadProfile( const char *name, const char *guid = NULL );
|
||||
|
||||
int setDeviceIndex( int devIdx );
|
||||
int setMapping( const char *map );
|
||||
int setMapping( nesGamePadMap_t *map );
|
||||
|
||||
int createProfile( const char *name );
|
||||
int getMapFromFile( const char *filename, char *out );
|
||||
int getDefaultMap( char *out, const char *guid = NULL );
|
||||
int saveMappingToFile( const char *filename, const char *txtMap );
|
||||
int saveCurrentMapToFile( const char *filename );
|
||||
};
|
||||
|
||||
extern GamePad_t GamePad[4];
|
||||
|
|
|
@ -465,6 +465,11 @@ void FCEUI_SetBaseDirectory(std::string const & dir)
|
|||
{
|
||||
BaseDirectory = dir;
|
||||
}
|
||||
/// Gets the base directory
|
||||
const char *FCEUI_GetBaseDirectory(void)
|
||||
{
|
||||
return BaseDirectory.c_str();
|
||||
}
|
||||
|
||||
static char *odirs[FCEUIOD__COUNT]={0,0,0,0,0,0,0,0,0,0,0,0,0}; // odirs, odors. ^_^
|
||||
|
||||
|
|
Loading…
Reference in New Issue