Added game pad button mapping profile logic.

This commit is contained in:
mjbudd77 2020-07-24 16:56:48 -04:00
parent 675b73cbed
commit b71630379a
7 changed files with 559 additions and 79 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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. ^_^