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.
|
//Sets the base directory(save states, snapshots, etc. are saved in directories below this directory.
|
||||||
void FCEUI_SetBaseDirectory(std::string const & dir);
|
void FCEUI_SetBaseDirectory(std::string const & dir);
|
||||||
|
const char *FCEUI_GetBaseDirectory(void);
|
||||||
|
|
||||||
bool FCEUI_GetUserPaletteAvail(void);
|
bool FCEUI_GetUserPaletteAvail(void);
|
||||||
void FCEUI_SetUserPalette(uint8 *pal, int nEntries);
|
void FCEUI_SetUserPalette(uint8 *pal, int nEntries);
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
// GamePadConf.cpp
|
// GamePadConf.cpp
|
||||||
//
|
//
|
||||||
|
#include <QDir>
|
||||||
|
#include <QInputDialog>
|
||||||
|
|
||||||
#include "Qt/GamePadConf.h"
|
#include "Qt/GamePadConf.h"
|
||||||
#include "Qt/main.h"
|
#include "Qt/main.h"
|
||||||
#include "Qt/dface.h"
|
#include "Qt/dface.h"
|
||||||
|
@ -13,13 +16,16 @@
|
||||||
GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
|
GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
|
||||||
: QDialog( parent )
|
: QDialog( parent )
|
||||||
{
|
{
|
||||||
QHBoxLayout *hbox1, *hbox2, *hbox3, *hbox4;
|
QHBoxLayout *hbox, *hbox1, *hbox2, *hbox3, *hbox4;
|
||||||
|
QVBoxLayout *vbox;
|
||||||
QGridLayout *grid;
|
QGridLayout *grid;
|
||||||
QCheckBox *efs_chkbox, *udlr_chkbox;
|
QCheckBox *efs_chkbox, *udlr_chkbox;
|
||||||
QGroupBox *frame1, *frame2;
|
QGroupBox *frame1, *frame2;
|
||||||
QLabel *label;
|
QLabel *label;
|
||||||
QPushButton *newProfileButton;
|
QPushButton *newProfileButton;
|
||||||
|
QPushButton *saveProfileButton;
|
||||||
QPushButton *applyProfileButton;
|
QPushButton *applyProfileButton;
|
||||||
|
QPushButton *removeProfileButton;
|
||||||
QPushButton *loadDefaultButton;
|
QPushButton *loadDefaultButton;
|
||||||
QPushButton *clearAllButton;
|
QPushButton *clearAllButton;
|
||||||
QPushButton *closebutton;
|
QPushButton *closebutton;
|
||||||
|
@ -64,7 +70,7 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
|
||||||
|
|
||||||
if ( js != NULL )
|
if ( js != NULL )
|
||||||
{
|
{
|
||||||
if ( js->inUse() )
|
if ( js->isConnected() )
|
||||||
{
|
{
|
||||||
char stmp[128];
|
char stmp[128];
|
||||||
sprintf( stmp, "%i: %s", i, js->getName() );
|
sprintf( stmp, "%i: %s", i, js->getName() );
|
||||||
|
@ -80,19 +86,45 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
|
||||||
hbox3->addWidget( guidLbl );
|
hbox3->addWidget( guidLbl );
|
||||||
|
|
||||||
frame1 = new QGroupBox(tr("Mapping Profile:"));
|
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();
|
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 = 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 = new QPushButton( tr("New") );
|
||||||
|
newProfileButton->setWhatsThis(tr("Create a New Map Profile"));
|
||||||
|
hbox->addWidget( newProfileButton );
|
||||||
|
|
||||||
grid->addWidget( mapSel , 0, 0, Qt::AlignCenter );
|
removeProfileButton = new QPushButton( tr("Delete") );
|
||||||
grid->addWidget( applyProfileButton, 0, 1, Qt::AlignCenter );
|
removeProfileButton->setWhatsThis(tr("Deletes the Selected Map Profile"));
|
||||||
grid->addWidget( newProfileButton , 0, 2, Qt::AlignCenter );
|
hbox->addWidget( removeProfileButton );
|
||||||
|
|
||||||
mapSel->addItem( tr("Default"), 0 );
|
mapMsg = new QLabel();
|
||||||
|
vbox->addWidget(mapMsg);
|
||||||
|
|
||||||
efs_chkbox = new QCheckBox( tr("Enable Four Score") );
|
efs_chkbox = new QCheckBox( tr("Enable Four Score") );
|
||||||
udlr_chkbox = new QCheckBox( tr("Allow Up+Down/Left+Right") );
|
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[8], SIGNAL(clicked()), this, SLOT(clearButton8(void)) );
|
||||||
connect(clearButton[9], SIGNAL(clicked()), this, SLOT(clearButton9(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(loadDefaultButton, SIGNAL(clicked()), this, SLOT(loadDefaults(void)) );
|
||||||
connect(clearAllButton , SIGNAL(clicked()), this, SLOT(clearAllCallback(void)) );
|
connect(clearAllButton , SIGNAL(clicked()), this, SLOT(clearAllCallback(void)) );
|
||||||
connect(closebutton , SIGNAL(clicked()), this, SLOT(closeWindow(void)) );
|
connect(closebutton , SIGNAL(clicked()), this, SLOT(closeWindow(void)) );
|
||||||
|
@ -192,6 +228,8 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
|
||||||
setLayout( mainLayout );
|
setLayout( mainLayout );
|
||||||
|
|
||||||
inputTimer->start( 33 ); // 30hz
|
inputTimer->start( 33 ); // 30hz
|
||||||
|
|
||||||
|
loadMapList();
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------
|
//----------------------------------------------------
|
||||||
|
@ -212,6 +250,62 @@ void GamePadConfDialog_t::keyReleaseEvent(QKeyEvent *event)
|
||||||
pushKeyEvent( event, 0 );
|
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)
|
void GamePadConfDialog_t::updateCntrlrDpy(void)
|
||||||
{
|
{
|
||||||
char keyNameStr[128];
|
char keyNameStr[128];
|
||||||
|
@ -247,7 +341,7 @@ void GamePadConfDialog_t::deviceSelect(int index)
|
||||||
|
|
||||||
if ( js != NULL )
|
if ( js != NULL )
|
||||||
{
|
{
|
||||||
if ( js->inUse() )
|
if ( js->isConnected() )
|
||||||
{
|
{
|
||||||
guidLbl->setText( js->getGUID() );
|
guidLbl->setText( js->getGUID() );
|
||||||
}
|
}
|
||||||
|
@ -256,6 +350,9 @@ void GamePadConfDialog_t::deviceSelect(int index)
|
||||||
{
|
{
|
||||||
guidLbl->setText("");
|
guidLbl->setText("");
|
||||||
}
|
}
|
||||||
|
GamePad[portNum].setDeviceIndex( devIdx );
|
||||||
|
|
||||||
|
loadMapList();
|
||||||
|
|
||||||
updateCntrlrDpy();
|
updateCntrlrDpy();
|
||||||
}
|
}
|
||||||
|
@ -472,7 +569,7 @@ void GamePadConfDialog_t::loadDefaults(void)
|
||||||
index = devSel->currentIndex();
|
index = devSel->currentIndex();
|
||||||
devIdx = devSel->itemData(index).toInt();
|
devIdx = devSel->itemData(index).toInt();
|
||||||
|
|
||||||
printf("Selected Device:%i : %i \n", index, devIdx );
|
//printf("Selected Device:%i : %i \n", index, devIdx );
|
||||||
|
|
||||||
if ( devIdx == -1 )
|
if ( devIdx == -1 )
|
||||||
{
|
{
|
||||||
|
@ -506,12 +603,95 @@ void GamePadConfDialog_t::loadDefaults(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GamePad[portNum].devIdx = devIdx;
|
GamePad[portNum].setDeviceIndex( devIdx );
|
||||||
GamePad[portNum].loadDefaults();
|
GamePad[portNum].loadDefaults();
|
||||||
}
|
}
|
||||||
updateCntrlrDpy();
|
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)
|
void GamePadConfDialog_t::updatePeriodic(void)
|
||||||
{
|
{
|
||||||
for (int i=0; i<GAMEPAD_NUM_BUTTONS; i++)
|
for (int i=0; i<GAMEPAD_NUM_BUTTONS; i++)
|
||||||
|
|
|
@ -44,6 +44,7 @@ class GamePadConfDialog_t : public QDialog
|
||||||
QComboBox *mapSel;
|
QComboBox *mapSel;
|
||||||
QComboBox *profSel;
|
QComboBox *profSel;
|
||||||
QLabel *guidLbl;
|
QLabel *guidLbl;
|
||||||
|
QLabel *mapMsg;
|
||||||
QLabel *keyName[GAMEPAD_NUM_BUTTONS];
|
QLabel *keyName[GAMEPAD_NUM_BUTTONS];
|
||||||
QLabel *keyState[GAMEPAD_NUM_BUTTONS];
|
QLabel *keyState[GAMEPAD_NUM_BUTTONS];
|
||||||
GamePadConfigButton_t *button[GAMEPAD_NUM_BUTTONS];
|
GamePadConfigButton_t *button[GAMEPAD_NUM_BUTTONS];
|
||||||
|
@ -58,6 +59,8 @@ class GamePadConfDialog_t : public QDialog
|
||||||
void closeEvent(QCloseEvent *bar);
|
void closeEvent(QCloseEvent *bar);
|
||||||
private:
|
private:
|
||||||
void updateCntrlrDpy(void);
|
void updateCntrlrDpy(void);
|
||||||
|
void createNewProfile( const char *name );
|
||||||
|
void loadMapList(void);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void closeWindow(void);
|
void closeWindow(void);
|
||||||
|
@ -88,6 +91,9 @@ class GamePadConfDialog_t : public QDialog
|
||||||
void oppDirEna(int state);
|
void oppDirEna(int state);
|
||||||
void portSelect(int index);
|
void portSelect(int index);
|
||||||
void deviceSelect(int index);
|
void deviceSelect(int index);
|
||||||
|
void newProfileCallback(void);
|
||||||
|
void loadProfileCallback(void);
|
||||||
|
void saveProfileCallback(void);
|
||||||
void updatePeriodic(void);
|
void updatePeriodic(void);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -102,20 +102,20 @@ LoadCPalette(const std::string &file)
|
||||||
static void
|
static void
|
||||||
CreateDirs(const std::string &dir)
|
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;
|
std::string subdir;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
#if defined(WIN32) || defined(NEED_MINGW_HACKS)
|
#if defined(WIN32) || defined(NEED_MINGW_HACKS)
|
||||||
mkdir(dir.c_str());
|
mkdir(dir.c_str());
|
||||||
chmod(dir.c_str(), 755);
|
chmod(dir.c_str(), 755);
|
||||||
for(x = 0; x < 6; x++) {
|
for(x = 0; x < 7; x++) {
|
||||||
subdir = dir + PSS + subs[x];
|
subdir = dir + PSS + subs[x];
|
||||||
mkdir(subdir.c_str());
|
mkdir(subdir.c_str());
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
mkdir(dir.c_str(), S_IRWXU);
|
mkdir(dir.c_str(), S_IRWXU);
|
||||||
for(x = 0; x < 6; x++) {
|
for(x = 0; x < 7; x++) {
|
||||||
subdir = dir + PSS + subs[x];
|
subdir = dir + PSS + subs[x];
|
||||||
mkdir(subdir.c_str(), S_IRWXU);
|
mkdir(subdir.c_str(), S_IRWXU);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
/// \file
|
/// \file
|
||||||
/// \brief Handles joystick input using the SDL.
|
/// \brief Handles joystick input using the SDL.
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
#include "Qt/sdl.h"
|
#include "Qt/sdl.h"
|
||||||
#include "Qt/sdl-joystick.h"
|
#include "Qt/sdl-joystick.h"
|
||||||
|
|
||||||
|
@ -41,6 +42,13 @@ static int sdlButton2NesGpIdx( const char *id );
|
||||||
// Static Variables
|
// Static Variables
|
||||||
static int s_jinited = 0;
|
static int s_jinited = 0;
|
||||||
|
|
||||||
|
static const char *buttonNames[ GAMEPAD_NUM_BUTTONS ] =
|
||||||
|
{
|
||||||
|
"a", "b","back","start",
|
||||||
|
"dpup","dpdown","dpleft","dpright",
|
||||||
|
"turboA","turboB"
|
||||||
|
};
|
||||||
|
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
// Joystick Device
|
// Joystick Device
|
||||||
jsDev_t::jsDev_t(void)
|
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) );
|
return ( (js != NULL) || (gc != NULL) );
|
||||||
}
|
}
|
||||||
|
@ -151,15 +159,23 @@ static jsDev_t jsDev[ MAX_JOYSTICKS ];
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
nesGamePadMap_t::nesGamePadMap_t(void)
|
nesGamePadMap_t::nesGamePadMap_t(void)
|
||||||
{
|
{
|
||||||
memset( guid, 0, sizeof(guid) );
|
clearMapping();
|
||||||
memset( name, 0, sizeof(name) );
|
|
||||||
memset( os , 0, sizeof(os) );
|
|
||||||
memset( btn , 0, sizeof(btn) );
|
|
||||||
}
|
}
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
nesGamePadMap_t::~nesGamePadMap_t(void)
|
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 )
|
int nesGamePadMap_t::parseMapping( const char *map )
|
||||||
|
@ -168,6 +184,8 @@ int nesGamePadMap_t::parseMapping( const char *map )
|
||||||
char id[32][64];
|
char id[32][64];
|
||||||
char val[32][64];
|
char val[32][64];
|
||||||
|
|
||||||
|
clearMapping();
|
||||||
|
|
||||||
i=0; j=0; k=0;
|
i=0; j=0; k=0;
|
||||||
|
|
||||||
while ( map[i] )
|
while ( map[i] )
|
||||||
|
@ -220,11 +238,12 @@ int nesGamePadMap_t::parseMapping( const char *map )
|
||||||
strcpy( os, val[i] );
|
strcpy( os, val[i] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
GamePad_t::GamePad_t(void)
|
GamePad_t::GamePad_t(void)
|
||||||
{
|
{
|
||||||
devIdx = 0;
|
devIdx = -1;
|
||||||
|
|
||||||
for (int i=0; i<GAMEPAD_NUM_BUTTONS; i++)
|
for (int i=0; i<GAMEPAD_NUM_BUTTONS; i++)
|
||||||
{
|
{
|
||||||
|
@ -237,51 +256,37 @@ GamePad_t::GamePad_t(void)
|
||||||
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 )
|
static int sdlButton2NesGpIdx( const char *id )
|
||||||
{
|
{
|
||||||
int idx = -1;
|
int i, idx = -1;
|
||||||
|
|
||||||
if ( strcmp( id, "a" ) == 0 )
|
for (i=0; i<GAMEPAD_NUM_BUTTONS; i++)
|
||||||
{
|
{
|
||||||
idx = 0;
|
if ( strcmp( id, buttonNames[i] ) == 0 )
|
||||||
}
|
{
|
||||||
else if ( strcmp( id, "b" ) == 0 )
|
idx = i; break;
|
||||||
{
|
}
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return idx;
|
return idx;
|
||||||
|
@ -297,9 +302,21 @@ int GamePad_t::setMapping( nesGamePadMap_t *gpm )
|
||||||
|
|
||||||
if (gpm->btn[i][0] == 'k')
|
if (gpm->btn[i][0] == 'k')
|
||||||
{
|
{
|
||||||
|
SDL_Keycode key;
|
||||||
|
|
||||||
bmap[i].ButtType = BUTTC_KEYBOARD;
|
bmap[i].ButtType = BUTTC_KEYBOARD;
|
||||||
bmap[i].DeviceNum = 0;
|
bmap[i].DeviceNum = -1;
|
||||||
bmap[i].ButtonNum = 0; // FIXME
|
|
||||||
|
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] ) )
|
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;
|
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)
|
int GamePad_t::loadDefaults(void)
|
||||||
{
|
{
|
||||||
|
char txtMap[256];
|
||||||
|
|
||||||
if ( jsDev[ devIdx ].gc )
|
if ( getDefaultMap( txtMap ) == 0 )
|
||||||
{
|
{
|
||||||
char *mapping;
|
setMapping( txtMap );
|
||||||
|
}
|
||||||
|
|
||||||
mapping = SDL_GameControllerMapping( jsDev[ devIdx ].gc );
|
|
||||||
|
|
||||||
if ( mapping == NULL ) return -1;
|
|
||||||
|
|
||||||
setMapping( mapping );
|
|
||||||
|
|
||||||
SDL_free(mapping);
|
|
||||||
}
|
|
||||||
return 0;
|
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 )
|
jsDev_t *getJoystickDevice( int devNum )
|
||||||
{
|
{
|
||||||
|
@ -410,6 +683,10 @@ DTestButtonJoy(ButtConfig *bc)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if ( bc->DeviceNum < 0 )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
js = jsDev[bc->DeviceNum].getJS();
|
js = jsDev[bc->DeviceNum].getJS();
|
||||||
|
|
||||||
if (bc->ButtonNum & 0x2000)
|
if (bc->ButtonNum & 0x2000)
|
||||||
|
@ -432,7 +709,7 @@ DTestButtonJoy(ButtConfig *bc)
|
||||||
/* Axis "button" */
|
/* Axis "button" */
|
||||||
int pos;
|
int pos;
|
||||||
pos = SDL_JoystickGetAxis( js,
|
pos = SDL_JoystickGetAxis( js,
|
||||||
bc->ButtonNum & 16383);
|
bc->ButtonNum & 0x3FFF);
|
||||||
if ((bc->ButtonNum & 0x4000) && pos <= -16383)
|
if ((bc->ButtonNum & 0x4000) && pos <= -16383)
|
||||||
{
|
{
|
||||||
bc->state = 1;
|
bc->state = 1;
|
||||||
|
@ -508,7 +785,7 @@ KillJoysticks(void)
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
int AddJoystick( int which )
|
int AddJoystick( int which )
|
||||||
{
|
{
|
||||||
if ( jsDev[ which ].inUse() )
|
if ( jsDev[ which ].isConnected() )
|
||||||
{
|
{
|
||||||
//printf("Error: Joystick already exists at device index %i \n", which );
|
//printf("Error: Joystick already exists at device index %i \n", which );
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -560,7 +837,7 @@ int RemoveJoystick( int which )
|
||||||
|
|
||||||
for (int i=0; i<MAX_JOYSTICKS; i++)
|
for (int i=0; i<MAX_JOYSTICKS; i++)
|
||||||
{
|
{
|
||||||
if ( jsDev[i].inUse() )
|
if ( jsDev[i].isConnected() )
|
||||||
{
|
{
|
||||||
if ( SDL_JoystickInstanceID( jsDev[i].getJS() ) == which )
|
if ( SDL_JoystickInstanceID( jsDev[i].getJS() ) == which )
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,6 +21,7 @@ struct nesGamePadMap_t
|
||||||
nesGamePadMap_t(void);
|
nesGamePadMap_t(void);
|
||||||
~nesGamePadMap_t(void);
|
~nesGamePadMap_t(void);
|
||||||
|
|
||||||
|
void clearMapping(void);
|
||||||
int parseMapping( const char *text );
|
int parseMapping( const char *text );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ struct jsDev_t
|
||||||
int close(void);
|
int close(void);
|
||||||
SDL_Joystick *getJS(void);
|
SDL_Joystick *getJS(void);
|
||||||
bool isGameController(void);
|
bool isGameController(void);
|
||||||
bool inUse(void);
|
bool isConnected(void);
|
||||||
void print(void);
|
void print(void);
|
||||||
const char *getName(void);
|
const char *getName(void);
|
||||||
const char *getGUID(void);
|
const char *getGUID(void);
|
||||||
|
@ -51,7 +52,7 @@ class GamePad_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
int type;
|
//int type;
|
||||||
int devIdx;
|
int devIdx;
|
||||||
|
|
||||||
ButtConfig bmap[GAMEPAD_NUM_BUTTONS];
|
ButtConfig bmap[GAMEPAD_NUM_BUTTONS];
|
||||||
|
@ -59,10 +60,20 @@ class GamePad_t
|
||||||
GamePad_t(void);
|
GamePad_t(void);
|
||||||
~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( const char *map );
|
||||||
int setMapping( nesGamePadMap_t *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];
|
extern GamePad_t GamePad[4];
|
||||||
|
|
|
@ -465,6 +465,11 @@ void FCEUI_SetBaseDirectory(std::string const & dir)
|
||||||
{
|
{
|
||||||
BaseDirectory = 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. ^_^
|
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