diff --git a/src/drivers/sdl/config.cpp b/src/drivers/sdl/config.cpp
index 8389d65a..f4631980 100644
--- a/src/drivers/sdl/config.cpp
+++ b/src/drivers/sdl/config.cpp
@@ -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);
}
@@ -242,7 +242,7 @@ InitConfig()
config->addOption("input4", "SDL.Input.3", "Gamepad.3");
// allow for input configuration
- config->addOption('i', "inputcfg", "SDL.InputCfg", InputCfg);
+ //config->addOption('i', "inputcfg", "SDL.InputCfg", InputCfg);
// display input
config->addOption("inputdisplay", "SDL.InputDisplay", 0);
@@ -286,8 +286,6 @@ InitConfig()
//TODO implement this
config->addOption("periodicsaves", "SDL.PeriodicSaves", 0);
-
- #ifdef _GTK
char* home_dir = getenv("HOME");
// prefixed with _ because they are internal (not cli options)
config->addOption("_lastopenfile", "SDL.LastOpenFile", home_dir);
@@ -295,7 +293,9 @@ InitConfig()
config->addOption("_lastopennsf", "SDL.LastOpenNSF", home_dir);
config->addOption("_lastsavestateas", "SDL.LastSaveStateAs", home_dir);
config->addOption("_lastloadlua", "SDL.LastLoadLua", "");
- #endif
+
+ config->addOption("_useNativeFileDialog", "SDL.UseNativeFileDialog", false);
+ config->addOption("_useNativeMenuBar" , "SDL.UseNativeMenuBar", false);
// fcm -> fm2 conversion
config->addOption("fcmconvert", "SDL.FCMConvert", "");
@@ -317,10 +317,8 @@ InitConfig()
prefix = buf;
config->addOption(prefix + "DeviceType", DefaultGamePadDevice[i]);
- config->addOption(prefix + "DeviceNum", 0);
- for(unsigned int j = 0; j < GAMEPAD_NUM_BUTTONS; j++) {
- config->addOption(prefix + GamePadNames[j], DefaultGamePad[i][j]);
- }
+ config->addOption(prefix + "DeviceGUID", "");
+ config->addOption(prefix + "Profile" , "");
}
// PowerPad 0 - 1
diff --git a/src/drivers/sdl/dface.h b/src/drivers/sdl/dface.h
index f753f3ca..827bbfaf 100644
--- a/src/drivers/sdl/dface.h
+++ b/src/drivers/sdl/dface.h
@@ -18,6 +18,8 @@ void SilenceSound(int s); /* DOS and SDL */
int InitJoysticks(void);
int KillJoysticks(void);
+int AddJoystick( int which );
+int RemoveJoystick( int which );
uint32 *GetJSOr(void);
int InitVideo(FCEUGI *gi);
diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp
index 6e6211c8..3e791ac6 100644
--- a/src/drivers/sdl/gui.cpp
+++ b/src/drivers/sdl/gui.cpp
@@ -19,6 +19,7 @@
#include "memview.h"
#include "ramwatch.h"
#include "debugger.h"
+#include "sdl-joystick.h"
#include "fceux_git_info.h"
#ifdef _S9XLUA_H
@@ -74,7 +75,6 @@ extern bool gtk_gui_run;
GtkWidget *MainWindow = NULL;
GtkWidget *evbox = NULL;
GtkWidget *padNoCombo = NULL;
-GtkWidget *configNoCombo = NULL;
GtkWidget *buttonMappings[10] = { NULL };
static GtkWidget *Menubar = NULL;
static GtkRadioMenuItem *stateSlot[10] = { NULL };
@@ -137,9 +137,6 @@ int configGamepadButton (GtkButton * button, gpointer p)
int padNo =
atoi (gtk_combo_box_text_get_active_text
(GTK_COMBO_BOX_TEXT (padNoCombo))) - 1;
- int configNo =
- atoi (gtk_combo_box_text_get_active_text
- (GTK_COMBO_BOX_TEXT (configNoCombo))) - 1;
char buf[256];
std::string prefix;
@@ -154,28 +151,28 @@ int configGamepadButton (GtkButton * button, gpointer p)
snprintf (buf, sizeof(buf)-1, "SDL.Input.GamePad.%d.", padNo);
prefix = buf;
- DWaitButton (NULL, &GamePadConfig[padNo][x], configNo, &buttonConfigStatus );
+ DWaitButton (NULL, &GamePad[padNo].bmap[x], &buttonConfigStatus );
- g_config->setOption (prefix + GamePadNames[x],
- GamePadConfig[padNo][x].ButtonNum[configNo]);
-
- if (GamePadConfig[padNo][x].ButtType[0] == BUTTC_KEYBOARD)
- {
- g_config->setOption (prefix + "DeviceType", "Keyboard");
- }
- else if (GamePadConfig[padNo][x].ButtType[0] == BUTTC_JOYSTICK)
- {
- g_config->setOption (prefix + "DeviceType", "Joystick");
- }
- else
- {
- g_config->setOption (prefix + "DeviceType", "Unknown");
- }
- g_config->setOption (prefix + "DeviceNum",
- GamePadConfig[padNo][x].DeviceNum[configNo]);
+// g_config->setOption (prefix + GamePadNames[x],
+// GamePadConfig[padNo][x].ButtonNum[configNo]);
+//
+// if (GamePadConfig[padNo][x].ButtType[0] == BUTTC_KEYBOARD)
+// {
+// g_config->setOption (prefix + "DeviceType", "Keyboard");
+// }
+// else if (GamePadConfig[padNo][x].ButtType[0] == BUTTC_JOYSTICK)
+// {
+// g_config->setOption (prefix + "DeviceType", "Joystick");
+// }
+// else
+// {
+// g_config->setOption (prefix + "DeviceType", "Unknown");
+// }
+// g_config->setOption (prefix + "DeviceNum",
+// GamePadConfig[padNo][x].DeviceNum[configNo]);
snprintf (buf, sizeof (buf), "%s",
- ButtonName (&GamePadConfig[padNo][x], configNo));
+ ButtonName (&GamePad[padNo].bmap[x]));
if ( buttonMappings[x] != NULL )
{
@@ -698,28 +695,25 @@ void updateGamepadConfig (GtkWidget * w, gpointer p)
int i;
char strBuf[128];
- if ( (padNoCombo == NULL) || (configNoCombo == NULL) )
+ if ( (padNoCombo == NULL) )
{
return;
}
int padNo =
atoi (gtk_combo_box_text_get_active_text
(GTK_COMBO_BOX_TEXT (padNoCombo))) - 1;
- int configNo =
- atoi (gtk_combo_box_text_get_active_text
- (GTK_COMBO_BOX_TEXT (configNoCombo))) - 1;
for (i = 0; i < 10; i++)
{
GtkWidget *mappedKey = buttonMappings[i];
- if (GamePadConfig[padNo][i].ButtType[configNo] == BUTTC_KEYBOARD)
+ if (GamePad[padNo].bmap[i].ButtType == BUTTC_KEYBOARD)
{
snprintf (strBuf, sizeof (strBuf), "%s",
- SDL_GetKeyName (GamePadConfig[padNo][i].
- ButtonNum[configNo]));
+ SDL_GetKeyName (GamePad[padNo].bmap[i].
+ ButtonNum));
}
else
- sprintf (strBuf, "%s", ButtonName( &GamePadConfig[padNo][i], configNo ) );
+ sprintf (strBuf, "%s", ButtonName( &GamePad[padNo].bmap[i] ) );
if ( mappedKey != NULL )
{
@@ -734,7 +728,6 @@ static void closeGamepadConfig (GtkWidget * w, GdkEvent * e, gpointer p)
gtk_widget_destroy (w);
padNoCombo = NULL;
- configNoCombo = NULL;
for (int i = 0; i < 10; i++)
{
@@ -799,20 +792,6 @@ void openGamepadConfig (void)
g_signal_connect (padNoCombo, "changed",
G_CALLBACK (updateGamepadConfig), NULL);
- configNoCombo = gtk_combo_box_text_new ();
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (configNoCombo),
- "1");
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (configNoCombo),
- "2");
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (configNoCombo),
- "3");
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (configNoCombo),
- "4");
- gtk_combo_box_set_active (GTK_COMBO_BOX (configNoCombo), 0);
- g_signal_connect (padNoCombo, "changed",
- G_CALLBACK (updateGamepadConfig), NULL);
-
-
//g_signal_connect (typeCombo, "changed", G_CALLBACK (setInputDevice),
// gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT
// (typeCombo)));
@@ -827,8 +806,6 @@ void openGamepadConfig (void)
gtk_box_pack_start (GTK_BOX (hboxPadNo), padNoLabel, TRUE, TRUE, 5);
gtk_box_pack_start (GTK_BOX (hboxPadNo), padNoCombo, TRUE, TRUE, 5);
- //gtk_box_pack_start(GTK_BOX(hboxPadNo), configNoLabel, TRUE, TRUE, 5);
- //gtk_box_pack_start(GTK_BOX(hboxPadNo), configNoCombo, TRUE, TRUE, 5);
gtk_box_pack_start (GTK_BOX (vbox), hboxPadNo, FALSE, TRUE, 5);
//gtk_box_pack_start_defaults(GTK_BOX(vbox), typeCombo);
diff --git a/src/drivers/sdl/input.cpp b/src/drivers/sdl/input.cpp
index 36d2199f..93cb7f78 100644
--- a/src/drivers/sdl/input.cpp
+++ b/src/drivers/sdl/input.cpp
@@ -24,8 +24,9 @@
#include "config.h"
-#include "sdl-video.h"
#include "sdl.h"
+#include "sdl-video.h"
+#include "sdl-joystick.h"
#include "../common/cheat.h"
#include "../../movie.h"
@@ -60,6 +61,7 @@ extern bool bindSavestate, frameAdvanceLagSkip, lagCounterDisplay;
static int UsrInputType[NUM_INPUT_DEVICES] = { SI_GAMEPAD, SI_GAMEPAD, SI_NONE };
static int CurInputType[NUM_INPUT_DEVICES] = { SI_GAMEPAD, SI_GAMEPAD, SI_NONE };
static int cspec = 0;
+static int buttonConfigInProgress = 0;
extern int gametype;
@@ -618,10 +620,10 @@ static void KeyboardCommands (void)
if (_keyonly (Hotkeys[HK_DECREASE_SPEED]))
{
- DecreaseEmulationSpeed ();
+ DecreaseEmulationSpeed();
}
- if (_keyonly (Hotkeys[HK_INCREASE_SPEED]))
+ if (_keyonly(Hotkeys[HK_INCREASE_SPEED]))
{
IncreaseEmulationSpeed ();
}
@@ -693,17 +695,10 @@ static void KeyboardCommands (void)
//}
if (_keyonly (Hotkeys[HK_QUIT]))
{
- if (noGui == 1)
- {
- CloseGame ();
- }
- else
- {
- CloseGame();
- FCEUI_Kill();
- SDL_Quit();
- exit(0);
- }
+ CloseGame();
+ FCEUI_Kill();
+ SDL_Quit();
+ exit(0);
}
else
#ifdef _S9XLUA_H
@@ -985,6 +980,12 @@ UpdatePhysicalInput ()
g_keyState[ event.key.keysym.scancode ] = (event.type == SDL_KEYDOWN) ? 1 : 0;
//checkKeyBoardState( event.key.keysym.scancode );
break;
+ case SDL_JOYDEVICEADDED:
+ AddJoystick( event.jdevice.which );
+ break;
+ case SDL_JOYDEVICEREMOVED:
+ RemoveJoystick( event.jdevice.which );
+ break;
default:
break;
}
@@ -993,8 +994,6 @@ UpdatePhysicalInput ()
}
-static int bcpv, bcpj;
-
/**
* Begin configuring the buttons by placing the video and joystick
* subsystems into a well-known state. Button configuration really
@@ -1002,31 +1001,11 @@ static int bcpv, bcpj;
*/
int ButtonConfigBegin ()
{
-//dont shut down video subsystem if we are using gtk to prevent the sdl window from becoming detached to GTK window
-// prg318 - 10-2-2011
-#ifdef _GTK
- int noGui;
- g_config->getOption ("SDL.NoGUI", &noGui);
- if (noGui == 1)
- {
- //SDL_QuitSubSystem (SDL_INIT_VIDEO);
- bcpv = KillVideo ();
- }
-#else
- // XXX soules - why are we doing this right before KillVideo()?
- //SDL_QuitSubSystem (SDL_INIT_VIDEO);
-
- // shut down the video and joystick subsystems
- bcpv = KillVideo ();
-#endif
- //SDL_Surface *screen;
-
- bcpj = KillJoysticks ();
-
- // XXX soules - why did we shut this down?
- // initialize the joystick subsystem
+ // initialize the joystick subsystem (if not already inited)
InitJoysticks ();
+ buttonConfigInProgress = 1;
+
return 1;
}
@@ -1038,18 +1017,7 @@ int ButtonConfigBegin ()
void
ButtonConfigEnd ()
{
- // shutdown the joystick and video subsystems
- KillJoysticks ();
- //SDL_QuitSubSystem(SDL_INIT_VIDEO);
-
- // re-initialize joystick and video subsystems if they were active before
- /*if(!bcpv) {
- InitVideo(GameInfo);
- } */
- if (!bcpj)
- {
- InitJoysticks ();
- }
+ buttonConfigInProgress = 0;
}
/**
@@ -1058,48 +1026,50 @@ ButtonConfigEnd ()
static int
DTestButton (ButtConfig * bc)
{
- int x;
- for (x = 0; x < bc->NumC; x++)
+ if (bc->ButtType == BUTTC_KEYBOARD)
{
- if (bc->ButtType[x] == BUTTC_KEYBOARD)
+ if (g_keyState[SDL_GetScancodeFromKey (bc->ButtonNum)])
{
- if (g_keyState[SDL_GetScancodeFromKey (bc->ButtonNum[x])])
- {
- return 1;
- }
+ bc->state = 1;
+ return 1;
}
- else if (bc->ButtType[x] == BUTTC_JOYSTICK)
+ else
+ {
+ bc->state = 0;
+ }
+ }
+ else if (bc->ButtType == BUTTC_JOYSTICK)
+ {
+ if (DTestButtonJoy (bc))
{
- if (DTestButtonJoy (bc))
- {
- return 1;
- }
+ return 1;
}
}
return 0;
}
-#define MK(x) {{BUTTC_KEYBOARD},{0},{MKK(x)},1}
-#define MK2(x1,x2) {{BUTTC_KEYBOARD},{0},{MKK(x1),MKK(x2)},2}
-#define MKZ() {{0},{0},{0},0}
+#define MK(x) {BUTTC_KEYBOARD,0,MKK(x),0}
+//#define MK2(x1,x2) {BUTTC_KEYBOARD,0,MKK(x1)}
+#define MKZ() {0,0,-1,0}
#define GPZ() {MKZ(), MKZ(), MKZ(), MKZ()}
-ButtConfig GamePadConfig[4][10] = {
-/* Gamepad 1 */
- {MK (KP_3), MK (KP_2), MK (SLASH), MK (ENTER),
- MK (W), MK (Z), MK (A), MK (S), MKZ (), MKZ ()},
-
- /* Gamepad 2 */
- GPZ (),
-
- /* Gamepad 3 */
- GPZ (),
-
- /* Gamepad 4 */
- GPZ ()
-};
+//ButtConfig GamePadConfig[ GAMEPAD_NUM_DEVICES ][ GAMEPAD_NUM_BUTTONS ] =
+//{
+///* Gamepad 1 */
+// {MK (KP_3), MK (KP_2), MK (SLASH), MK (ENTER),
+// MK (w), MK (z), MK (a), MK (s), MKZ (), MKZ ()},
+//
+// /* Gamepad 2 */
+// GPZ (),
+//
+// /* Gamepad 3 */
+// GPZ (),
+//
+// /* Gamepad 4 */
+// GPZ ()
+//};
/**
* Update the status of the gamepad input devices.
@@ -1131,7 +1101,7 @@ UpdateGamepad(void)
// a, b, select, start, up, down, left, right
for (x = 0; x < 8; x++)
{
- if (DTestButton (&GamePadConfig[wg][x]))
+ if (DTestButton (&GamePad[wg].bmap[x]))
{
//printf("GamePad%i Button Hit: %i \n", wg, x );
if(opposite_dirs == 0)
@@ -1169,7 +1139,7 @@ UpdateGamepad(void)
{
for (x = 0; x < 2; x++)
{
- if (DTestButton (&GamePadConfig[wg][8 + x]))
+ if (DTestButton (&GamePad[wg].bmap[8 + x]))
{
JS |= (1 << x) << (wg << 3);
}
@@ -1238,11 +1208,15 @@ static uint8 fkbkeys[0x48];
/**
* Update all of the input devices required for the active game.
*/
-void FCEUD_UpdateInput ()
+void FCEUD_UpdateInput(void)
{
int x;
int t = 0;
+ if ( buttonConfigInProgress )
+ {
+ return;
+ }
UpdatePhysicalInput ();
KeyboardCommands ();
@@ -1600,36 +1574,42 @@ UpdateFTrainer ()
* @param bc the NES gamepad's button config
* @param which the index of the button
*/
-const char * ButtonName (const ButtConfig * bc, int which)
+const char * ButtonName (const ButtConfig * bc)
{
static char name[256];
- switch (bc->ButtType[which])
+ name[0] = 0;
+
+ if (bc->ButtonNum == -1)
+ {
+ return name;
+ }
+ switch (bc->ButtType)
{
case BUTTC_KEYBOARD:
- return SDL_GetKeyName (bc->ButtonNum[which]);
+ return SDL_GetKeyName (bc->ButtonNum);
break;
case BUTTC_JOYSTICK:
{
int joyNum, inputNum;
const char *inputType, *inputDirection;
- joyNum = bc->DeviceNum[which];
+ joyNum = bc->DeviceNum;
- if (bc->ButtonNum[which] & 0x8000)
+ if (bc->ButtonNum & 0x8000)
{
inputType = "Axis";
- inputNum = bc->ButtonNum[which] & 0x3FFF;
- inputDirection = bc->ButtonNum[which] & 0x4000 ? "-" : "+";
+ inputNum = bc->ButtonNum & 0x3FFF;
+ inputDirection = bc->ButtonNum & 0x4000 ? "-" : "+";
}
- else if (bc->ButtonNum[which] & 0x2000)
+ else if (bc->ButtonNum & 0x2000)
{
int inputValue;
char direction[128] = "";
inputType = "Hat";
- inputNum = (bc->ButtonNum[which] >> 8) & 0x1F;
- inputValue = bc->ButtonNum[which] & 0xF;
+ inputNum = (bc->ButtonNum >> 8) & 0x1F;
+ inputValue = bc->ButtonNum & 0xF;
if (inputValue & SDL_HAT_UP)
strncat (direction, "Up ", sizeof (direction)-1);
@@ -1648,7 +1628,7 @@ const char * ButtonName (const ButtConfig * bc, int which)
else
{
inputType = "Button";
- inputNum = bc->ButtonNum[which];
+ inputNum = bc->ButtonNum;
inputDirection = "";
}
sprintf( name, "js%i:%s%i%s", joyNum, inputType, inputNum, inputDirection );
@@ -1663,11 +1643,12 @@ const char * ButtonName (const ButtConfig * bc, int which)
* Waits for a button input and returns the information as to which
* button was pressed. Used in button configuration.
*/
-int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigStatus )
+int DWaitButton (const uint8_t * text, ButtConfig * bc, int *buttonConfigStatus )
{
SDL_Event event;
static int32 LastAx[64][64];
int x, y;
+ int timeout_ms = 10000;
if (text)
{
@@ -1686,9 +1667,24 @@ int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigS
}
}
+ // Purge all pending events, so that this next button press
+ // will be the one we want.
+ while (SDL_PollEvent (&event))
+ {
+
+ }
+
while (1)
{
int done = 0;
+
+ usleep(10000);
+ timeout_ms -= 10;
+
+ if ( timeout_ms <= 0 )
+ {
+ break;
+ }
#ifdef _GTK
while (gtk_events_pending ())
gtk_main_iteration_do (FALSE);
@@ -1699,23 +1695,24 @@ int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigS
switch (event.type)
{
case SDL_KEYDOWN:
- bc->ButtType[wb] = BUTTC_KEYBOARD;
- bc->DeviceNum[wb] = 0;
- bc->ButtonNum[wb] = event.key.keysym.sym;
+ //printf("SDL KeyDown:%i \n", event.key.keysym.sym );
+ bc->ButtType = BUTTC_KEYBOARD;
+ bc->DeviceNum = 0;
+ bc->ButtonNum = event.key.keysym.sym;
return (1);
case SDL_JOYBUTTONDOWN:
- bc->ButtType[wb] = BUTTC_JOYSTICK;
- bc->DeviceNum[wb] = event.jbutton.which;
- bc->ButtonNum[wb] = event.jbutton.button;
+ bc->ButtType = BUTTC_JOYSTICK;
+ bc->DeviceNum = event.jbutton.which;
+ bc->ButtonNum = event.jbutton.button;
return (1);
case SDL_JOYHATMOTION:
if (event.jhat.value == SDL_HAT_CENTERED)
done--;
else
{
- bc->ButtType[wb] = BUTTC_JOYSTICK;
- bc->DeviceNum[wb] = event.jhat.which;
- bc->ButtonNum[wb] =
+ bc->ButtType = BUTTC_JOYSTICK;
+ bc->DeviceNum = event.jhat.which;
+ bc->ButtonNum =
(0x2000 | ((event.jhat.hat & 0x1F) << 8) | event.
jhat.value);
return (1);
@@ -1737,9 +1734,9 @@ int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigS
(LastAx[event.jaxis.which][event.jaxis.axis] -
event.jaxis.value) >= 8192)
{
- bc->ButtType[wb] = BUTTC_JOYSTICK;
- bc->DeviceNum[wb] = event.jaxis.which;
- bc->ButtonNum[wb] = (0x8000 | event.jaxis.axis |
+ bc->ButtType = BUTTC_JOYSTICK;
+ bc->DeviceNum = event.jaxis.which;
+ bc->ButtonNum = (0x8000 | event.jaxis.axis |
((event.jaxis.value < 0)
? 0x4000 : 0));
return (1);
@@ -1776,213 +1773,206 @@ int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigS
* used as input for the specified button, thus allowing up to four
* possible settings for each input button.
*/
- void
-ConfigButton (char *text, ButtConfig * bc)
-{
- uint8 buf[256];
- int wc;
-
- for (wc = 0; wc < MAXBUTTCONFIG; wc++)
- {
- sprintf ((char *) buf, "%s (%d)", text, wc + 1);
- DWaitButton (buf, bc, wc, NULL);
-
- if (wc &&
- bc->ButtType[wc] == bc->ButtType[wc - 1] &&
- bc->DeviceNum[wc] == bc->DeviceNum[wc - 1] &&
- bc->ButtonNum[wc] == bc->ButtonNum[wc - 1])
- {
- break;
- }
- }
- bc->NumC = wc;
-}
+// void
+//ConfigButton (char *text, ButtConfig * bc)
+//{
+// uint8 buf[256];
+// int wc;
+//
+// for (wc = 0; wc < MAXBUTTCONFIG; wc++)
+// {
+// sprintf ((char *) buf, "%s (%d)", text, wc + 1);
+// DWaitButton (buf, bc, wc, NULL);
+//
+// if (wc &&
+// bc->ButtType[wc] == bc->ButtType[wc - 1] &&
+// bc->DeviceNum[wc] == bc->DeviceNum[wc - 1] &&
+// bc->ButtonNum[wc] == bc->ButtonNum[wc - 1])
+// {
+// break;
+// }
+// }
+//}
/**
* Update the button configuration for a specified device.
*/
extern Config *g_config;
-void ConfigDevice (int which, int arg)
-{
- char buf[256];
- int x;
- std::string prefix;
- const char *str[10] =
- { "A", "B", "SELECT", "START", "UP", "DOWN", "LEFT", "RIGHT", "Rapid A",
- "Rapid B"
- };
-
- // XXX soules - set the configuration options so that later calls
- // don't override these. This is a temp hack until I
- // can clean up this file.
-
- ButtonConfigBegin ();
- switch (which)
- {
- case FCFGD_QUIZKING:
- prefix = "SDL.Input.QuizKing.";
- for (x = 0; x < 6; x++)
- {
- sprintf (buf, "Quiz King Buzzer #%d", x + 1);
- ConfigButton (buf, &QuizKingButtons[x]);
-
- g_config->setOption (prefix + QuizKingNames[x],
- QuizKingButtons[x].ButtonNum[0]);
- }
-
- if (QuizKingButtons[0].ButtType[0] == BUTTC_KEYBOARD)
- {
- g_config->setOption (prefix + "DeviceType", "Keyboard");
- }
- else if (QuizKingButtons[0].ButtType[0] == BUTTC_JOYSTICK)
- {
- g_config->setOption (prefix + "DeviceType", "Joystick");
- }
- else
- {
- g_config->setOption (prefix + "DeviceType", "Unknown");
- }
- g_config->setOption (prefix + "DeviceNum",
- QuizKingButtons[0].DeviceNum[0]);
- break;
- case FCFGD_HYPERSHOT:
- prefix = "SDL.Input.HyperShot.";
- for (x = 0; x < 4; x++)
- {
- sprintf (buf, "Hyper Shot %d: %s",
- ((x & 2) >> 1) + 1, (x & 1) ? "JUMP" : "RUN");
- ConfigButton (buf, &HyperShotButtons[x]);
-
- g_config->setOption (prefix + HyperShotNames[x],
- HyperShotButtons[x].ButtonNum[0]);
- }
-
- if (HyperShotButtons[0].ButtType[0] == BUTTC_KEYBOARD)
- {
- g_config->setOption (prefix + "DeviceType", "Keyboard");
- }
- else if (HyperShotButtons[0].ButtType[0] == BUTTC_JOYSTICK)
- {
- g_config->setOption (prefix + "DeviceType", "Joystick");
- }
- else
- {
- g_config->setOption (prefix + "DeviceType", "Unknown");
- }
- g_config->setOption (prefix + "DeviceNum",
- HyperShotButtons[0].DeviceNum[0]);
- break;
- case FCFGD_POWERPAD:
- snprintf (buf, 256, "SDL.Input.PowerPad.%d", (arg & 1));
- prefix = buf;
- for (x = 0; x < 12; x++)
- {
- sprintf (buf, "PowerPad %d: %d", (arg & 1) + 1, x + 11);
- ConfigButton (buf, &powerpadsc[arg & 1][x]);
-
- g_config->setOption (prefix + PowerPadNames[x],
- powerpadsc[arg & 1][x].ButtonNum[0]);
- }
-
- if (powerpadsc[arg & 1][0].ButtType[0] == BUTTC_KEYBOARD)
- {
- g_config->setOption (prefix + "DeviceType", "Keyboard");
- }
- else if (powerpadsc[arg & 1][0].ButtType[0] == BUTTC_JOYSTICK)
- {
- g_config->setOption (prefix + "DeviceType", "Joystick");
- }
- else
- {
- g_config->setOption (prefix + "DeviceType", "Unknown");
- }
- g_config->setOption (prefix + "DeviceNum",
- powerpadsc[arg & 1][0].DeviceNum[0]);
- break;
-
- case FCFGD_GAMEPAD:
- snprintf (buf, 256, "SDL.Input.GamePad.%d", arg);
- prefix = buf;
- for (x = 0; x < 10; x++)
- {
- sprintf (buf, "GamePad #%d: %s", arg + 1, str[x]);
- ConfigButton (buf, &GamePadConfig[arg][x]);
-
- g_config->setOption (prefix + GamePadNames[x],
- GamePadConfig[arg][x].ButtonNum[0]);
- }
-
- if (GamePadConfig[arg][0].ButtType[0] == BUTTC_KEYBOARD)
- {
- g_config->setOption (prefix + "DeviceType", "Keyboard");
- }
- else if (GamePadConfig[arg][0].ButtType[0] == BUTTC_JOYSTICK)
- {
- g_config->setOption (prefix + "DeviceType", "Joystick");
- }
- else
- {
- g_config->setOption (prefix + "DeviceType", "Unknown");
- }
- g_config->setOption (prefix + "DeviceNum",
- GamePadConfig[arg][0].DeviceNum[0]);
- break;
- }
-
- ButtonConfigEnd ();
-}
+//void ConfigDevice (int which, int arg)
+//{
+// char buf[256];
+// int x;
+// std::string prefix;
+// const char *str[10] =
+// { "A", "B", "SELECT", "START", "UP", "DOWN", "LEFT", "RIGHT", "Rapid A",
+// "Rapid B"
+// };
+//
+// // XXX soules - set the configuration options so that later calls
+// // don't override these. This is a temp hack until I
+// // can clean up this file.
+//
+// ButtonConfigBegin ();
+// switch (which)
+// {
+// case FCFGD_QUIZKING:
+// prefix = "SDL.Input.QuizKing.";
+// for (x = 0; x < 6; x++)
+// {
+// sprintf (buf, "Quiz King Buzzer #%d", x + 1);
+// ConfigButton (buf, &QuizKingButtons[x]);
+//
+// g_config->setOption (prefix + QuizKingNames[x],
+// QuizKingButtons[x].ButtonNum);
+// }
+//
+// if (QuizKingButtons[0].ButtType == BUTTC_KEYBOARD)
+// {
+// g_config->setOption (prefix + "DeviceType", "Keyboard");
+// }
+// else if (QuizKingButtons[0].ButtType == BUTTC_JOYSTICK)
+// {
+// g_config->setOption (prefix + "DeviceType", "Joystick");
+// }
+// else
+// {
+// g_config->setOption (prefix + "DeviceType", "Unknown");
+// }
+// g_config->setOption (prefix + "DeviceNum",
+// QuizKingButtons[0].DeviceNum);
+// break;
+// case FCFGD_HYPERSHOT:
+// prefix = "SDL.Input.HyperShot.";
+// for (x = 0; x < 4; x++)
+// {
+// sprintf (buf, "Hyper Shot %d: %s",
+// ((x & 2) >> 1) + 1, (x & 1) ? "JUMP" : "RUN");
+// ConfigButton (buf, &HyperShotButtons[x]);
+//
+// g_config->setOption (prefix + HyperShotNames[x],
+// HyperShotButtons[x].ButtonNum);
+// }
+//
+// if (HyperShotButtons[0].ButtType == BUTTC_KEYBOARD)
+// {
+// g_config->setOption (prefix + "DeviceType", "Keyboard");
+// }
+// else if (HyperShotButtons[0].ButtType == BUTTC_JOYSTICK)
+// {
+// g_config->setOption (prefix + "DeviceType", "Joystick");
+// }
+// else
+// {
+// g_config->setOption (prefix + "DeviceType", "Unknown");
+// }
+// g_config->setOption (prefix + "DeviceNum",
+// HyperShotButtons[0].DeviceNum);
+// break;
+// case FCFGD_POWERPAD:
+// snprintf (buf, 256, "SDL.Input.PowerPad.%d", (arg & 1));
+// prefix = buf;
+// for (x = 0; x < 12; x++)
+// {
+// sprintf (buf, "PowerPad %d: %d", (arg & 1) + 1, x + 11);
+// ConfigButton (buf, &powerpadsc[arg & 1][x]);
+//
+// g_config->setOption (prefix + PowerPadNames[x],
+// powerpadsc[arg & 1][x].ButtonNum);
+// }
+//
+// if (powerpadsc[arg & 1][0].ButtType == BUTTC_KEYBOARD)
+// {
+// g_config->setOption (prefix + "DeviceType", "Keyboard");
+// }
+// else if (powerpadsc[arg & 1][0].ButtType == BUTTC_JOYSTICK)
+// {
+// g_config->setOption (prefix + "DeviceType", "Joystick");
+// }
+// else
+// {
+// g_config->setOption (prefix + "DeviceType", "Unknown");
+// }
+// g_config->setOption (prefix + "DeviceNum",
+// powerpadsc[arg & 1][0].DeviceNum);
+// break;
+//
+// case FCFGD_GAMEPAD:
+// snprintf (buf, 256, "SDL.Input.GamePad.%d", arg);
+// prefix = buf;
+// for (x = 0; x < 10; x++)
+// {
+// sprintf (buf, "GamePad #%d: %s", arg + 1, str[x]);
+// ConfigButton (buf, &GamePadConfig[arg][x]);
+//
+// g_config->setOption (prefix + GamePadNames[x],
+// GamePadConfig[arg][x].ButtonNum);
+// }
+//
+// if (GamePadConfig[arg][0].ButtType == BUTTC_KEYBOARD)
+// {
+// g_config->setOption (prefix + "DeviceType", "Keyboard");
+// }
+// else if (GamePadConfig[arg][0].ButtType == BUTTC_JOYSTICK)
+// {
+// g_config->setOption (prefix + "DeviceType", "Joystick");
+// }
+// else
+// {
+// g_config->setOption (prefix + "DeviceType", "Unknown");
+// }
+// g_config->setOption (prefix + "DeviceNum",
+// GamePadConfig[arg][0].DeviceNum);
+// break;
+// }
+//
+// ButtonConfigEnd ();
+//}
/**
* Update the button configuration for a device, specified by a text string.
*/
-void InputCfg (const std::string & text)
-{
-#ifdef _GTK
- // enable noGui to prevent the gtk x11 hack from executing
- noGui = 1;
- // this is only called at the begininng of execution; make sure the video subsystem is initialized
- InitVideo (GameInfo);
-#endif
-
- if (noGui)
- {
- if (text.find ("gamepad") != std::string::npos)
- {
- int device = (text[strlen ("gamepad")] - '1');
- if (device < 0 || device > 3)
- {
- FCEUD_PrintError
- ("Invalid gamepad device specified; must be one of gamepad1 through gamepad4");
- exit (-1);
- }
- ConfigDevice (FCFGD_GAMEPAD, device);
- }
- else if (text.find ("powerpad") != std::string::npos)
- {
- int device = (text[strlen ("powerpad")] - '1');
- if (device < 0 || device > 1)
- {
- FCEUD_PrintError
- ("Invalid powerpad device specified; must be powerpad1 or powerpad2");
- exit (-1);
- }
- ConfigDevice (FCFGD_POWERPAD, device);
- }
- else if (text.find ("hypershot") != std::string::npos)
- {
- ConfigDevice (FCFGD_HYPERSHOT, 0);
- }
- else if (text.find ("quizking") != std::string::npos)
- {
- ConfigDevice (FCFGD_QUIZKING, 0);
- }
- }
- else
- printf ("Please run \"fceux --nogui\" before using --inputcfg\n");
-
-}
+//void InputCfg (const std::string & text)
+//{
+//
+// if (noGui)
+// {
+// if (text.find ("gamepad") != std::string::npos)
+// {
+// int device = (text[strlen ("gamepad")] - '1');
+// if (device < 0 || device > 3)
+// {
+// FCEUD_PrintError
+// ("Invalid gamepad device specified; must be one of gamepad1 through gamepad4");
+// exit (-1);
+// }
+// ConfigDevice (FCFGD_GAMEPAD, device);
+// }
+// else if (text.find ("powerpad") != std::string::npos)
+// {
+// int device = (text[strlen ("powerpad")] - '1');
+// if (device < 0 || device > 1)
+// {
+// FCEUD_PrintError
+// ("Invalid powerpad device specified; must be powerpad1 or powerpad2");
+// exit (-1);
+// }
+// ConfigDevice (FCFGD_POWERPAD, device);
+// }
+// else if (text.find ("hypershot") != std::string::npos)
+// {
+// ConfigDevice (FCFGD_HYPERSHOT, 0);
+// }
+// else if (text.find ("quizking") != std::string::npos)
+// {
+// ConfigDevice (FCFGD_QUIZKING, 0);
+// }
+// }
+// else
+// printf ("Please run \"fceux --nogui\" before using --inputcfg\n");
+//
+//}
/**
@@ -1994,7 +1984,9 @@ void InputCfg (const std::string & text)
UpdateInput (Config * config)
{
char buf[64];
- std::string device, prefix;
+ std::string device, prefix, guid, mapping;
+
+ InitJoysticks();
for (unsigned int i = 0; i < 3; i++)
{
@@ -2087,37 +2079,18 @@ UpdateInput (Config * config)
snprintf (buf, sizeof(buf)-1, "SDL.Input.GamePad.%u.", i);
prefix = buf;
- config->getOption (prefix + "DeviceType", &device);
- if (device.find ("Keyboard") != std::string::npos)
- {
- type = BUTTC_KEYBOARD;
- }
- else if (device.find ("Joystick") != std::string::npos)
- {
- type = BUTTC_JOYSTICK;
- }
- else
- {
- type = 0;
- }
+ config->getOption (prefix + "DeviceType", &device );
+ config->getOption (prefix + "DeviceGUID", &guid );
+ config->getOption (prefix + "Profile" , &mapping);
- config->getOption (prefix + "DeviceNum", &devnum);
- for (unsigned int j = 0; j < GAMEPAD_NUM_BUTTONS; j++)
- {
- config->getOption (prefix + GamePadNames[j], &button);
-
- GamePadConfig[i][j].ButtType[0] = type;
- GamePadConfig[i][j].DeviceNum[0] = devnum;
- GamePadConfig[i][j].ButtonNum[0] = button;
- GamePadConfig[i][j].NumC = 1;
- }
+ GamePad[i].init( i, guid.c_str(), mapping.c_str() );
}
// PowerPad 0 - 1
for (unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++)
{
char buf[64];
- snprintf (buf, 32, "SDL.Input.PowerPad.%u.", i);
+ snprintf (buf, sizeof(buf)-1, "SDL.Input.PowerPad.%u.", i);
prefix = buf;
config->getOption (prefix + "DeviceType", &device);
@@ -2139,10 +2112,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + PowerPadNames[j], &button);
- powerpadsc[i][j].ButtType[0] = type;
- powerpadsc[i][j].DeviceNum[0] = devnum;
- powerpadsc[i][j].ButtonNum[0] = button;
- powerpadsc[i][j].NumC = 1;
+ powerpadsc[i][j].ButtType = type;
+ powerpadsc[i][j].DeviceNum = devnum;
+ powerpadsc[i][j].ButtonNum = button;
}
}
@@ -2166,10 +2138,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + QuizKingNames[j], &button);
- QuizKingButtons[j].ButtType[0] = type;
- QuizKingButtons[j].DeviceNum[0] = devnum;
- QuizKingButtons[j].ButtonNum[0] = button;
- QuizKingButtons[j].NumC = 1;
+ QuizKingButtons[j].ButtType = type;
+ QuizKingButtons[j].DeviceNum = devnum;
+ QuizKingButtons[j].ButtonNum = button;
}
// HyperShot
@@ -2192,10 +2163,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + HyperShotNames[j], &button);
- HyperShotButtons[j].ButtType[0] = type;
- HyperShotButtons[j].DeviceNum[0] = devnum;
- HyperShotButtons[j].ButtonNum[0] = button;
- HyperShotButtons[j].NumC = 1;
+ HyperShotButtons[j].ButtType = type;
+ HyperShotButtons[j].DeviceNum = devnum;
+ HyperShotButtons[j].ButtonNum = button;
}
// Mahjong
@@ -2218,10 +2188,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + MahjongNames[j], &button);
- MahjongButtons[j].ButtType[0] = type;
- MahjongButtons[j].DeviceNum[0] = devnum;
- MahjongButtons[j].ButtonNum[0] = button;
- MahjongButtons[j].NumC = 1;
+ MahjongButtons[j].ButtType = type;
+ MahjongButtons[j].DeviceNum = devnum;
+ MahjongButtons[j].ButtonNum = button;
}
// TopRider
@@ -2244,10 +2213,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + TopRiderNames[j], &button);
- TopRiderButtons[j].ButtType[0] = type;
- TopRiderButtons[j].DeviceNum[0] = devnum;
- TopRiderButtons[j].ButtonNum[0] = button;
- TopRiderButtons[j].NumC = 1;
+ TopRiderButtons[j].ButtType = type;
+ TopRiderButtons[j].DeviceNum = devnum;
+ TopRiderButtons[j].ButtonNum = button;
}
// FTrainer
@@ -2270,10 +2238,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + FTrainerNames[j], &button);
- FTrainerButtons[j].ButtType[0] = type;
- FTrainerButtons[j].DeviceNum[0] = devnum;
- FTrainerButtons[j].ButtonNum[0] = button;
- FTrainerButtons[j].NumC = 1;
+ FTrainerButtons[j].ButtType = type;
+ FTrainerButtons[j].DeviceNum = devnum;
+ FTrainerButtons[j].ButtonNum = button;
}
// FamilyKeyBoard
@@ -2296,10 +2263,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + FamilyKeyBoardNames[j], &button);
- fkbmap[j].ButtType[0] = type;
- fkbmap[j].DeviceNum[0] = devnum;
- fkbmap[j].ButtonNum[0] = button;
- fkbmap[j].NumC = 1;
+ fkbmap[j].ButtType = type;
+ fkbmap[j].DeviceNum = devnum;
+ fkbmap[j].ButtonNum = button;
}
}
@@ -2311,11 +2277,11 @@ const char *GamePadNames[GAMEPAD_NUM_BUTTONS] = { "A", "B", "Select", "Start",
const char *DefaultGamePadDevice[GAMEPAD_NUM_DEVICES] =
{ "Keyboard", "None", "None", "None" };
const int DefaultGamePad[GAMEPAD_NUM_DEVICES][GAMEPAD_NUM_BUTTONS] =
-{ {SDLK_F, SDLK_D, SDLK_S, SDLK_RETURN,
- SDLK_UP, SDLK_DOWN, SDLK_LEFT, SDLK_RIGHT, 0, 0},
-{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+{ {SDLK_f, SDLK_d, SDLK_s, SDLK_RETURN,
+ SDLK_UP, SDLK_DOWN, SDLK_LEFT, SDLK_RIGHT, -1, -1},
+{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
};
// PowerPad defaults
diff --git a/src/drivers/sdl/input.h b/src/drivers/sdl/input.h
index 2a1a2d85..07dc1d04 100644
--- a/src/drivers/sdl/input.h
+++ b/src/drivers/sdl/input.h
@@ -1,34 +1,39 @@
#ifndef _aosdfjk02fmasf
#define _aosdfjk02fmasf
-#include "../common/configSys.h"
+#include
-#define MAXBUTTCONFIG 4
-typedef struct {
- uint8 ButtType[MAXBUTTCONFIG];
- uint8 DeviceNum[MAXBUTTCONFIG];
- //uint16 ButtonNum[MAXBUTTCONFIG];
- int ButtonNum[MAXBUTTCONFIG];
- uint32 NumC;
+#include "common/configSys.h"
+
+//#define MAXBUTTCONFIG 4
+
+enum {
+ BUTTC_KEYBOARD = 0,
+ BUTTC_JOYSTICK = 1,
+ BUTTC_MOUSE = 2
+};
+struct ButtConfig
+{
+ int ButtType; //[MAXBUTTCONFIG];
+ int DeviceNum; //[MAXBUTTCONFIG];
+ int ButtonNum; //[MAXBUTTCONFIG];
+ int state;
+ //uint32_t NumC;
//uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */
-} ButtConfig;
-
+};
extern int NoWaiting;
extern CFGSTRUCT InputConfig[];
extern ARGPSTRUCT InputArgs[];
extern int Hotkeys[];
void ParseGIInput(FCEUGI *GI);
-void setHotKeys();
+void setHotKeys(void);
int getKeyState( int k );
int ButtonConfigBegin();
void ButtonConfigEnd();
void ConfigButton(char *text, ButtConfig *bc);
-int DWaitButton(const uint8 *text, ButtConfig *bc, int wb, int *buttonConfigStatus = NULL);
+int DWaitButton(const uint8_t *text, ButtConfig *bc, int *buttonConfigStatus = NULL);
-#define BUTTC_KEYBOARD 0x00
-#define BUTTC_JOYSTICK 0x01
-#define BUTTC_MOUSE 0x02
#define FCFGD_GAMEPAD 1
#define FCFGD_POWERPAD 2
@@ -41,7 +46,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];
@@ -54,9 +59,9 @@ int DTestButtonJoy(ButtConfig *bc);
void FCEUD_UpdateInput(void);
void UpdateInput(Config *config);
-void InputCfg(const std::string &);
+//void InputCfg(const std::string &);
std::string GetUserText(const char* title);
-const char* ButtonName(const ButtConfig* bc, int which);
+const char* ButtonName(const ButtConfig* bc);
#endif
diff --git a/src/drivers/sdl/sdl-joystick.cpp b/src/drivers/sdl/sdl-joystick.cpp
index 690b012b..6e3bedf6 100644
--- a/src/drivers/sdl/sdl-joystick.cpp
+++ b/src/drivers/sdl/sdl-joystick.cpp
@@ -22,102 +22,1015 @@
/// \file
/// \brief Handles joystick input using the SDL.
-#include "sdl.h"
+//#include
+#include "Qt/sdl.h"
+#include "Qt/sdl-joystick.h"
#include
#include
#include
#include
-#define MAX_JOYSTICKS 32
-static SDL_Joystick *s_Joysticks[MAX_JOYSTICKS] = {NULL};
+//#define MAX_JOYSTICKS 32
+// Public Variables
+GamePad_t GamePad[4];
+
+// Static Functions
+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)
+{
+ js = NULL;
+ gc = NULL;
+ devIdx = 0;
+ portBindMask = 0;
+};
+
+//********************************************************************************
+int jsDev_t::close(void)
+{
+ if ( gc )
+ {
+ SDL_GameControllerClose( gc ); gc = NULL; js = NULL;
+ }
+ else
+ {
+ if ( js )
+ {
+ SDL_JoystickClose( js ); js = NULL;
+ }
+ }
+ return 0;
+}
+
+//********************************************************************************
+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() );
+}
+
+//********************************************************************************
+int jsDev_t::bindPort( int idx )
+{
+ portBindMask |= (0x00000001 << idx);
+
+ return portBindMask;
+}
+//********************************************************************************
+int jsDev_t::unbindPort( int idx )
+{
+ portBindMask &= ~(0x00000001 << idx);
+
+ return portBindMask;
+}
+//********************************************************************************
+int jsDev_t::getBindPorts(void)
+{
+ return portBindMask;
+}
+//********************************************************************************
+bool jsDev_t::isGameController(void)
+{
+ return ( gc != NULL );
+}
+
+//********************************************************************************
+bool jsDev_t::isConnected(void)
+{
+ return ( (js != NULL) || (gc != NULL) );
+}
+
+//********************************************************************************
+void jsDev_t::init( int idx )
+{
+ SDL_JoystickGUID guid;
+ char stmp[64];
+
+ devIdx = idx;
+
+ if ( gc )
+ {
+ js = SDL_GameControllerGetJoystick( gc );
+
+ guid = SDL_JoystickGetGUID( js );
+
+ name.assign( SDL_GameControllerName(gc) );
+ }
+ else
+ {
+ guid = SDL_JoystickGetGUID( js );
+
+ 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 )
+ {
+ printf("GameController Name: '%s'\n", SDL_GameControllerName(gc) );
+ printf("GameController Mapping: %s\n", SDL_GameControllerMapping(gc) );
+ }
+}
+
+static jsDev_t jsDev[ MAX_JOYSTICKS ];
+
+//********************************************************************************
+nesGamePadMap_t::nesGamePadMap_t(void)
+{
+ 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= 0 )
+ {
+ strcpy( btn[bIdx], val[i] );
+ }
+ else if ( strcmp( id[i], "platform" ) == 0 )
+ {
+ strcpy( os, val[i] );
+ }
+ }
+ return 0;
+}
+//********************************************************************************
+GamePad_t::GamePad_t(void)
+{
+ devIdx = -1;
+ portNum = 0;
+
+ for (int i=0; i= 0 )
+ {
+ jsDev[ devIdx ].unbindPort( portNum );
+ }
+
+ devIdx = in;
+
+ if ( devIdx >= 0 )
+ {
+ jsDev[ devIdx ].bindPort( portNum );
+ }
+ 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 i, idx = -1;
+
+ for (i=0; ibtn[i][0] == 0)
+ {
+ continue;
+ }
+ if (gpm->btn[i][0] == 'k')
+ {
+ SDL_Keycode key;
+
+ bmap[i].ButtType = BUTTC_KEYBOARD;
+ 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] ) )
+ {
+ bmap[i].ButtType = BUTTC_JOYSTICK;
+ bmap[i].DeviceNum = devIdx;
+ bmap[i].ButtonNum = atoi( &gpm->btn[i][1] );
+ }
+ else if ( (gpm->btn[i][0] == 'h') && isdigit( gpm->btn[i][1] ) &&
+ (gpm->btn[i][2] == '.') && isdigit( gpm->btn[i][3] ) )
+ {
+ int hatIdx, hatVal;
+
+ hatIdx = gpm->btn[i][1] - '0';
+ hatVal = atoi( &gpm->btn[i][3] );
+
+ bmap[i].ButtType = BUTTC_JOYSTICK;
+ bmap[i].DeviceNum = devIdx;
+ bmap[i].ButtonNum = 0x2000 | ( (hatIdx & 0x1F) << 8) | (hatVal & 0xFF);
+ }
+ else if ( (gpm->btn[i][0] == 'a') || (gpm->btn[i][1] == 'a') )
+ {
+ int l=0, axisIdx=0, axisSign=0;
+
+ l=0;
+ if ( gpm->btn[i][l] == '-' )
+ {
+ axisSign = 1; l++;
+ }
+ else if ( gpm->btn[i][l] == '+' )
+ {
+ axisSign = 0; l++;
+ }
+
+ if ( gpm->btn[i][l] == 'a' )
+ {
+ l++;
+ }
+ if ( isdigit( gpm->btn[i][l] ) )
+ {
+ axisIdx = atoi( &gpm->btn[i][l] );
+
+ while ( isdigit(gpm->btn[i][l]) ) l++;
+ }
+ if ( gpm->btn[i][l] == '-' )
+ {
+ axisSign = 1; l++;
+ }
+ else if ( gpm->btn[i][l] == '+' )
+ {
+ axisSign = 0; l++;
+ }
+ bmap[i].ButtType = BUTTC_JOYSTICK;
+ bmap[i].DeviceNum = devIdx;
+ bmap[i].ButtonNum = 0x8000 | (axisSign ? 0x4000 : 0) | (axisIdx & 0xFF);
+ }
+ }
+ return 0;
+}
+//********************************************************************************
+int GamePad_t::setMapping( const char *map )
+{
+ nesGamePadMap_t gpm;
+
+ gpm.parseMapping( map );
+ setMapping( &gpm );
+
+ 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;
+ }
+ }
+ else
+ {
+ if ( strcmp( guid, "keyboard" ) == 0 )
+ {
+ for (int x=0; x= 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> 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 )
+{
+ 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() );
+
+ saveCurrentMapToFile( name );
+
+ return 0;
+}
+//********************************************************************************
+int GamePad_t::deleteMapping( const char *name )
+{
+ const char *guid = NULL;
+ const char *baseDir = FCEUI_GetBaseDirectory();
+ std::string path;
+
+ 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) +
+ "/" + std::string(name) + ".txt";
+
+ //printf("File: '%s'\n", path.c_str() );
+
+ return remove( path.c_str() );
+}
+//********************************************************************************
+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.
*/
int
DTestButtonJoy(ButtConfig *bc)
{
- int x;
+ SDL_Joystick *js;
- for(x = 0; x < bc->NumC; x++)
+ if (bc->ButtonNum == -1)
{
- if(bc->ButtonNum[x] & 0x2000)
- {
- /* Hat "button" */
- if(SDL_JoystickGetHat(s_Joysticks[bc->DeviceNum[x]],
- ((bc->ButtonNum[x] >> 8) & 0x1F)) &
- (bc->ButtonNum[x]&0xFF))
- return 1;
- }
- else if(bc->ButtonNum[x] & 0x8000)
- {
- /* Axis "button" */
- int pos;
- pos = SDL_JoystickGetAxis(s_Joysticks[bc->DeviceNum[x]],
- bc->ButtonNum[x] & 16383);
- if ((bc->ButtonNum[x] & 0x4000) && pos <= -16383) {
- return 1;
- } else if (!(bc->ButtonNum[x] & 0x4000) && pos >= 16363) {
- return 1;
- }
- }
- else if(SDL_JoystickGetButton(s_Joysticks[bc->DeviceNum[x]],
- bc->ButtonNum[x]))
- return 1;
+ return 0;
}
+ if ( bc->DeviceNum < 0 )
+ {
+ return 0;
+ }
+ js = jsDev[bc->DeviceNum].getJS();
+
+ if (bc->ButtonNum & 0x2000)
+ {
+ /* Hat "button" */
+ if (SDL_JoystickGetHat( js,
+ ((bc->ButtonNum >> 8) & 0x1F)) &
+ (bc->ButtonNum&0xFF))
+ {
+ bc->state = 1;
+ return 1;
+ }
+ else
+ {
+ bc->state = 0;
+ }
+ }
+ else if (bc->ButtonNum & 0x8000)
+ {
+ /* Axis "button" */
+ int pos;
+ pos = SDL_JoystickGetAxis( js,
+ bc->ButtonNum & 0x3FFF);
+ if ((bc->ButtonNum & 0x4000) && pos <= -16383)
+ {
+ bc->state = 1;
+ return 1;
+ }
+ else if (!(bc->ButtonNum & 0x4000) && pos >= 16363)
+ {
+ bc->state = 1;
+ return 1;
+ }
+ else
+ {
+ bc->state = 0;
+ }
+ }
+ else if (SDL_JoystickGetButton( js,
+ bc->ButtonNum))
+ {
+ bc->state = 1;
+ return 1;
+ }
+ else
+ {
+ bc->state = 0;
+ }
+
return 0;
}
+//********************************************************************************
+
+//static void printJoystick( SDL_Joystick *js )
+//{
+// char guidStr[64];
+// SDL_Joystick *js;
+//
+// js = jsDev[i].getJS();
+//
+// 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) );
+//
+//}
+
+//********************************************************************************
/**
* Shutdown the SDL joystick subsystem.
*/
int
-KillJoysticks()
+KillJoysticks(void)
{
int n; /* joystick index */
- if(!s_jinited) {
+ if (!s_jinited) {
return -1;
}
- for(n = 0; n < MAX_JOYSTICKS; n++) {
- if (s_Joysticks[n] != 0) {
- SDL_JoystickClose(s_Joysticks[n]);
- }
- s_Joysticks[n]=0;
+ for (n = 0; n < MAX_JOYSTICKS; n++)
+ {
+ jsDev[n].close();
}
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+
+ s_jinited = 0;
+
return 0;
}
+//********************************************************************************
+int AddJoystick( int which )
+{
+ if ( jsDev[ which ].isConnected() )
+ {
+ //printf("Error: Joystick already exists at device index %i \n", which );
+ return -1;
+ }
+ else
+ {
+ if ( SDL_IsGameController(which) )
+ {
+ jsDev[which].gc = SDL_GameControllerOpen(which);
+
+ if ( jsDev[which].gc == NULL )
+ {
+ printf("Could not open game controller %d: %s.\n",
+ which, SDL_GetError());
+ }
+ else
+ {
+ //printf("Added Joystick: %i \n", which );
+ jsDev[which].init(which);
+ //jsDev[which].print();
+ //printJoystick( s_Joysticks[which] );
+ }
+ }
+ else
+ {
+ jsDev[which].js = SDL_JoystickOpen(which);
+
+ if ( jsDev[which].js == NULL )
+ {
+ printf("Could not open joystick %d: %s.\n",
+ which, SDL_GetError());
+ }
+ else
+ {
+ //printf("Added Joystick: %i \n", which );
+ jsDev[which].init(which);
+ //jsDev[which].print();
+ //printJoystick( s_Joysticks[which] );
+ }
+ }
+ }
+ return 0;
+}
+
+//********************************************************************************
+int RemoveJoystick( int which )
+{
+ //printf("Remove Joystick: %i \n", which );
+
+ for (int i=0; iMAX_JOYSTICKS) {
+ if (total > MAX_JOYSTICKS)
+ {
total = MAX_JOYSTICKS;
}
- for(n = 0; n < total; n++) {
+ for (n = 0; n < total; n++)
+ {
/* Open the joystick under SDL. */
- s_Joysticks[n] = SDL_JoystickOpen(n);
- //printf("Could not open joystick %d: %s.\n",
- //joy[n] - 1, SDL_GetError());
- continue;
+ AddJoystick(n);
}
s_jinited = 1;
return 1;
}
+//********************************************************************************
diff --git a/src/drivers/sdl/sdl-joystick.h b/src/drivers/sdl/sdl-joystick.h
new file mode 100644
index 00000000..568f736b
--- /dev/null
+++ b/src/drivers/sdl/sdl-joystick.h
@@ -0,0 +1,92 @@
+// sdl-joystick.h
+
+#ifndef __SDL_JOYSTICK_H__
+#define __SDL_JOYSTICK_H__
+
+#include
+
+#include "Qt/main.h"
+#include "Qt/input.h"
+#include "Qt/sdl.h"
+
+#define MAX_JOYSTICKS 32
+
+struct nesGamePadMap_t
+{
+ char guid[64];
+ char name[128];
+ char btn[GAMEPAD_NUM_BUTTONS][32];
+ char os[64];
+
+ nesGamePadMap_t(void);
+ ~nesGamePadMap_t(void);
+
+ void clearMapping(void);
+ int parseMapping( const char *text );
+};
+
+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 isConnected(void);
+ void print(void);
+ int bindPort( int idx );
+ int unbindPort( int idx );
+ int getBindPorts(void);
+ const char *getName(void);
+ const char *getGUID(void);
+
+ private:
+ int devIdx;
+ int portBindMask;
+ std::string guidStr;
+ std::string name;
+};
+
+class GamePad_t
+{
+ public:
+
+ ButtConfig bmap[GAMEPAD_NUM_BUTTONS];
+
+ GamePad_t(void);
+ ~GamePad_t(void);
+
+ int init( int port, const char *guid, const char *profile = NULL );
+ const char *getGUID(void);
+
+ int loadDefaults(void);
+ int loadProfile( const char *name, const char *guid = NULL );
+
+ int getDeviceIndex(void){ return devIdx; }
+ 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 );
+ int deleteMapping( const char *name );
+
+ private:
+ int devIdx;
+ int portNum;
+
+};
+
+extern GamePad_t GamePad[4];
+
+jsDev_t *getJoystickDevice( int devNum );
+
+#endif
diff --git a/src/drivers/sdl/sdl.cpp b/src/drivers/sdl/sdl.cpp
index cc79ebf7..3c92e1fa 100644
--- a/src/drivers/sdl/sdl.cpp
+++ b/src/drivers/sdl/sdl.cpp
@@ -615,12 +615,14 @@ int main(int argc, char *argv[])
std::string s;
- g_config->getOption("SDL.InputCfg", &s);
- if(s.size() != 0)
- {
- InitVideo(GameInfo);
- InputCfg(s);
- }
+ //g_config->getOption("SDL.InputCfg", &s);
+ //
+ //if(s.size() != 0)
+ //{
+ // InitVideo(GameInfo);
+ // InputCfg(s);
+ //}
+
// set the FAMICOM PAD 2 Mic thing
{
int t;