diff --git a/desmume/src/ctrlssdl.cpp b/desmume/src/ctrlssdl.cpp
index 74bb64afc..98edc5910 100644
--- a/desmume/src/ctrlssdl.cpp
+++ b/desmume/src/ctrlssdl.cpp
@@ -46,22 +46,35 @@ const char *key_names[NB_KEYS] =
"Debug", "Boost"
};
+/* Joypad Key Codes -- 4-digit Hexadecimal number
+ * 1st digit: device ID (0 is first joypad, 1 is second, etc.)
+ * 2nd digit: 0 - Axis, 1 - Hat/POV/D-Pad, 2 - Button
+ * 3rd & 4th digit: (depends on input type)
+ * Negative Axis - 2 * axis index
+ * Positive Axis - 2 * axis index + 1
+ * Hat Right - 4 * hat index
+ * Hat Left - 4 * hat index + 1
+ * Hat Up - 4 * hat index + 2
+ * Hat Down - 4 * hat index + 3
+ * Button - button index
+ */
+
/* Default joypad configuration */
const u16 default_joypad_cfg[NB_KEYS] =
- { 1, // A
- 0, // B
- 5, // select
- 8, // start
- 256, // Right -- Start cheating abit...
- 256, // Left
- 512, // Up
- 512, // Down -- End of cheating.
- 7, // R
- 6, // L
- 4, // X
- 3, // Y
- -1, // DEBUG
- -1 // BOOST
+ { 0x0201, // A
+ 0x0200, // B
+ 0x0205, // select
+ 0x0208, // start
+ 0x0001, // Right
+ 0x0000, // Left
+ 0x0002, // Up
+ 0x0003, // Down
+ 0x0207, // R
+ 0x0206, // L
+ 0x0204, // X
+ 0x0203, // Y
+ 0xFFFF, // DEBUG
+ 0xFFFF // BOOST
};
const u16 plain_keyboard_cfg[NB_KEYS] =
@@ -184,22 +197,6 @@ u16 lookup_key (u16 keyval) {
return Key;
}
-/* Empty SDL Events' queue */
-static void clear_events( void)
-{
- SDL_Event event;
- /* IMPORTANT: Reenable joystick events iif needed. */
- if(SDL_JoystickEventState(SDL_QUERY) == SDL_IGNORE)
- SDL_JoystickEventState(SDL_ENABLE);
-
- /* There's an event waiting to be processed? */
- while (SDL_PollEvent(&event))
- {
- }
-
- return;
-}
-
/* Get pressed joystick key */
u16 get_joy_key(int index) {
BOOL done = FALSE;
@@ -215,10 +212,49 @@ u16 get_joy_key(int index) {
switch(event.type)
{
case SDL_JOYBUTTONDOWN:
- printf( "Got joykey: %d\n", event.jbutton.button );
- key = event.jbutton.button;
+ printf( "Device: %d; Button: %d\n", event.jbutton.which, event.jbutton.button );
+ key = ((event.jbutton.which & 15) << 12) | JOY_BUTTON << 8 | (event.jbutton.button & 255);
done = TRUE;
break;
+ case SDL_JOYAXISMOTION:
+ /* Dead zone of 50% */
+ if( (abs(event.jaxis.value) >> 14) != 0 )
+ {
+ key = ((event.jaxis.which & 15) << 12) | JOY_AXIS << 8 | ((event.jaxis.axis & 127) << 1);
+ if (event.jaxis.value > 0) {
+ printf( "Device: %d; Axis: %d (+)\n", event.jaxis.which, event.jaxis.axis );
+ key |= 1;
+ }
+ else
+ printf( "Device: %d; Axis: %d (-)\n", event.jaxis.which, event.jaxis.axis );
+ done = TRUE;
+ }
+ break;
+ case SDL_JOYHATMOTION:
+ /* Diagonal positions will be treated as two separate keys being activated, rather than a single diagonal key. */
+ /* JOY_HAT_* are sequential integers, rather than a bitmask */
+ if (event.jhat.value != SDL_HAT_CENTERED) {
+ key = ((event.jhat.which & 15) << 12) | JOY_HAT << 8 | ((event.jhat.hat & 63) << 2);
+ /* Can't just use a switch here because SDL_HAT_* make up a bitmask. We only want one of these when assigning keys. */
+ if ((event.jhat.value & SDL_HAT_UP) != 0) {
+ key |= JOY_HAT_UP;
+ printf( "Device: %d; Hat: %d (Up)\n", event.jhat.which, event.jhat.hat );
+ }
+ else if ((event.jhat.value & SDL_HAT_RIGHT) != 0) {
+ key |= JOY_HAT_RIGHT;
+ printf( "Device: %d; Hat: %d (Right)\n", event.jhat.which, event.jhat.hat );
+ }
+ else if ((event.jhat.value & SDL_HAT_DOWN) != 0) {
+ key |= JOY_HAT_DOWN;
+ printf( "Device: %d; Hat: %d (Down)\n", event.jhat.which, event.jhat.hat );
+ }
+ else if ((event.jhat.value & SDL_HAT_LEFT) != 0) {
+ key |= JOY_HAT_LEFT;
+ printf( "Device: %d; Hat: %d (Left)\n", event.jhat.which, event.jhat.hat );
+ }
+ done = TRUE;
+ }
+ break;
}
}
@@ -235,61 +271,6 @@ u16 get_set_joy_key(int index) {
return joypad_cfg[index];
}
-/* Reset corresponding key and its twin axis key */
-static u16 get_joy_axis_twin(u16 key)
-{
- switch(key)
- {
- case KEYMASK_( KEY_RIGHT-1 ):
- return KEYMASK_( KEY_LEFT-1 );
- case KEYMASK_( KEY_UP-1 ):
- return KEYMASK_( KEY_DOWN-1 );
- default:
- return 0;
- }
-}
-
-/* Get a new joystick axis */
-u16 get_joy_axis(int index, int index_o) {
- BOOL done = FALSE;
- SDL_Event event;
- u16 key = joypad_cfg[index];
-
- /* Clear events */
- clear_events();
- /* Enable joystick events if needed */
- if( SDL_JoystickEventState(SDL_QUERY) == SDL_IGNORE )
- SDL_JoystickEventState(SDL_ENABLE);
-
- while(SDL_WaitEvent(&event) && !done)
- {
- switch(event.type)
- {
- case SDL_JOYAXISMOTION:
- /* Discriminate small movements */
- if( (event.jaxis.value >> 5) != 0 )
- {
- key = JOY_AXIS_(event.jaxis.axis);
- done = TRUE;
- }
- break;
- }
- }
- if( SDL_JoystickEventState(SDL_QUERY) == SDL_ENABLE )
- SDL_JoystickEventState(SDL_IGNORE);
-
- return key;
-}
-
-/* Get and set a new joystick axis */
-void get_set_joy_axis(int index, int index_o) {
- u16 key = get_joy_axis(index, index_o);
-
- /* Update configuration */
- joypad_cfg[index] = key;
- joypad_cfg[index_o] = joypad_cfg[index];
-}
-
static signed long
screen_to_touch_range_x( signed long scr_x, float size_ratio) {
signed long touch_x = (signed long)((float)scr_x * size_ratio);
@@ -355,45 +336,84 @@ u16 get_keypad( void)
static int
do_process_joystick_events( u16 *keypad, SDL_Event *event) {
int processed = 1;
+ u16 key_code;
u16 key;
+ u16 key_o;
+ u16 key_u;
+ u16 key_r;
+ u16 key_d;
+ u16 key_l;
switch ( event->type)
{
/* Joystick axis motion
Note: button constants have a 1bit offset. */
case SDL_JOYAXISMOTION:
- key = lookup_joy_key( JOY_AXIS_(event->jaxis.axis) );
- if( key == 0 ) break; /* Not an axis of interest? */
+ key_code = ((event->jaxis.which & 15) << 12) | JOY_AXIS << 8 | ((event->jaxis.axis & 127) << 1);
+ if( (abs(event->jaxis.value) >> 14) != 0 )
+ {
+ if (event->jaxis.value > 0)
+ key_code |= 1;
+ key = lookup_joy_key( key_code );
+ key_o = lookup_joy_key( key_code ^ 1 );
+ if (key != 0)
+ ADD_KEY( *keypad, key );
+ if (key_o != 0)
+ RM_KEY( *keypad, key_o );
+ }
+ else
+ {
+ // Axis is zeroed
+ key = lookup_joy_key( key_code );
+ key_o = lookup_joy_key( key_code ^ 1 );
+ if (key != 0)
+ RM_KEY( *keypad, key );
+ if (key_o != 0)
+ RM_KEY( *keypad, key_o );
+ }
+ break;
- /* Axis is back to initial position */
- if( event->jaxis.value == 0 )
- RM_KEY( *keypad, key | get_joy_axis_twin(key) );
- /* Key should have been down but its currently set to up? */
- else if( (event->jaxis.value > 0) &&
- (key == KEYMASK_( KEY_UP-1 )) )
- key = KEYMASK_( KEY_DOWN-1 );
- /* Key should have been left but its currently set to right? */
- else if( (event->jaxis.value < 0) &&
- (key == KEYMASK_( KEY_RIGHT-1 )) )
- key = KEYMASK_( KEY_LEFT-1 );
-
- /* Remove some sensitivity before checking if different than zero...
- Fixes some badly behaving joypads [like one of mine]. */
- if( (event->jaxis.value >> 5) != 0 )
- ADD_KEY( *keypad, key );
+ case SDL_JOYHATMOTION:
+ /* Diagonal positions will be treated as two separate keys being activated, rather than a single diagonal key. */
+ /* JOY_HAT_* are sequential integers, rather than a bitmask */
+ key_code = ((event->jhat.which & 15) << 12) | JOY_HAT << 8 | ((event->jhat.hat & 63) << 2);
+ key_u = lookup_joy_key( key_code | JOY_HAT_UP );
+ key_r = lookup_joy_key( key_code | JOY_HAT_RIGHT );
+ key_d = lookup_joy_key( key_code | JOY_HAT_DOWN );
+ key_l = lookup_joy_key( key_code | JOY_HAT_LEFT );
+ if ((key_u != 0) && ((event->jhat.value & SDL_HAT_UP) != 0))
+ ADD_KEY( *keypad, key_u );
+ else if (key_u != 0)
+ RM_KEY( *keypad, key_u );
+ if ((key_r != 0) && ((event->jhat.value & SDL_HAT_RIGHT) != 0))
+ ADD_KEY( *keypad, key_r );
+ else if (key_r != 0)
+ RM_KEY( *keypad, key_r );
+ if ((key_d != 0) && ((event->jhat.value & SDL_HAT_DOWN) != 0))
+ ADD_KEY( *keypad, key_d );
+ else if (key_d != 0)
+ RM_KEY( *keypad, key_d );
+ if ((key_l != 0) && ((event->jhat.value & SDL_HAT_LEFT) != 0))
+ ADD_KEY( *keypad, key_l );
+ else if (key_l != 0)
+ RM_KEY( *keypad, key_l );
break;
/* Joystick button pressed */
/* FIXME: Add support for BOOST */
case SDL_JOYBUTTONDOWN:
- key = lookup_joy_key( event->jbutton.button );
- ADD_KEY( *keypad, key );
+ key_code = ((event->jbutton.which & 15) << 12) | JOY_BUTTON << 8 | (event->jbutton.button & 255);
+ key = lookup_joy_key( key_code );
+ if (key != 0)
+ ADD_KEY( *keypad, key );
break;
/* Joystick button released */
case SDL_JOYBUTTONUP:
- key = lookup_joy_key(event->jbutton.button);
- RM_KEY( *keypad, key );
+ key_code = ((event->jbutton.which & 15) << 12) | JOY_BUTTON << 8 | (event->jbutton.button & 255);
+ key = lookup_joy_key( key_code );
+ if (key != 0)
+ RM_KEY( *keypad, key );
break;
default:
diff --git a/desmume/src/ctrlssdl.h b/desmume/src/ctrlssdl.h
index 6b368cbed..d63c477d8 100644
--- a/desmume/src/ctrlssdl.h
+++ b/desmume/src/ctrlssdl.h
@@ -35,7 +35,15 @@
#define ADD_KEY(keypad,key) ( (keypad) |= (key) )
#define RM_KEY(keypad,key) ( (keypad) &= ~(key) )
#define KEYMASK_(k) (1 << (k))
-#define JOY_AXIS_(k) (((k)+1) << 8)
+
+#define JOY_AXIS 0
+#define JOY_HAT 1
+#define JOY_BUTTON 2
+
+#define JOY_HAT_RIGHT 0
+#define JOY_HAT_LEFT 1
+#define JOY_HAT_UP 2
+#define JOY_HAT_DOWN 3
#define NB_KEYS 14
#define KEY_NONE 0
@@ -95,8 +103,6 @@ void set_joy_keys(const u16 joyCfg[]);
void set_kb_keys(const u16 kbCfg[]);
u16 get_joy_key(int index);
u16 get_set_joy_key(int index);
-u16 get_joy_axis(int index, int index_opp);
-void get_set_joy_axis(int index, int index_opp);
void update_keypad(u16 keys);
u16 get_keypad( void);
u16 lookup_key (u16 keyval);
diff --git a/desmume/src/gtk-glade/callbacks_IO.cpp b/desmume/src/gtk-glade/callbacks_IO.cpp
index 9449229aa..2cccd9537 100755
--- a/desmume/src/gtk-glade/callbacks_IO.cpp
+++ b/desmume/src/gtk-glade/callbacks_IO.cpp
@@ -386,37 +386,6 @@ static void ask_joy_key(GtkButton*b, int key)
gtk_widget_hide((GtkWidget*)dlg);
}
-/* Joystick configuration / Key definition */
-static void ask_joy_axis(u8 key, u8 opposite_key)
-{
- char text[50];
- char current_button[50], opposite_button[50];
- GtkWidget * dlg;
- GtkButton * btn;
-
- key--; /* remove 1 to get index */
- opposite_key--;
-
- snprintf(current_button, 50, "button_joy_%s",key_names[key]);
- snprintf(opposite_button, 50, "button_joy_%s",key_names[opposite_key]);
- dlg = (GtkWidget*)glade_xml_get_widget(xml, "wJoyDlg");
-
- gtk_widget_show(dlg);
- /* Need to force event processing. Otherwise, popup won't show up. */
- while ( gtk_events_pending() ) gtk_main_iteration();
- get_set_joy_axis(key, opposite_key);
-
- snprintf(text, 50, "%s : %d",key_names[key],joypad_cfg[key]);
- btn = (GtkButton*)glade_xml_get_widget(xml, current_button);
- gtk_button_set_label(btn,text);
-
- snprintf(text, 50, "%s : %d",key_names[opposite_key],joypad_cfg[opposite_key]);
- btn = (GtkButton*)glade_xml_get_widget(xml, opposite_button);
- gtk_button_set_label(btn,text);
-
- gtk_widget_hide((GtkWidget*)dlg);
-}
-
/* Bind a keyboard key to a keypad key */
void on_button_kb_key_clicked (GtkButton *b, gpointer user_data)
{
@@ -424,13 +393,6 @@ void on_button_kb_key_clicked (GtkButton *b, gpointer user_data)
ask( b, key );
}
-/* Bind a joystick axis to a keypad directionnal pad */
-void on_button_joy_axis_clicked (GtkButton *b, gpointer user_data)
-{
- int key = dyn_CAST( int, user_data );
- ask_joy_axis( key, key+1 );
-}
-
/* Bind a joystick button to a keypad key */
void on_button_joy_key_clicked (GtkButton *b, gpointer user_data)
{
diff --git a/desmume/src/gtk-glade/callbacks_IO.h b/desmume/src/gtk-glade/callbacks_IO.h
index a8530ff34..0822a9554 100755
--- a/desmume/src/gtk-glade/callbacks_IO.h
+++ b/desmume/src/gtk-glade/callbacks_IO.h
@@ -46,7 +46,6 @@ G_MODULE_EXPORT void on_wKeybConfDlg_response (GtkDialog *dialog, gint arg1, gp
G_MODULE_EXPORT void on_button_kb_key_clicked (GtkButton *button, gpointer user_data);
/* Joystick configuration / Key definition */
-G_MODULE_EXPORT void on_button_joy_axis_clicked (GtkButton *button, gpointer user_data);
G_MODULE_EXPORT void on_button_joy_key_clicked (GtkButton *button, gpointer user_data);
}
diff --git a/desmume/src/gtk-glade/glade/DeSmuMe.glade b/desmume/src/gtk-glade/glade/DeSmuMe.glade
index f5bdc2247..62d4329d8 100755
--- a/desmume/src/gtk-glade/glade/DeSmuMe.glade
+++ b/desmume/src/gtk-glade/glade/DeSmuMe.glade
@@ -2121,7 +2121,7 @@ Contributors:
True
GTK_RELIEF_NORMAL
True
-
+
1
@@ -2141,7 +2141,7 @@ Contributors:
True
GTK_RELIEF_NORMAL
True
-
+
1
@@ -2161,7 +2161,7 @@ Contributors:
True
GTK_RELIEF_NORMAL
True
-
+
0
@@ -2181,7 +2181,7 @@ Contributors:
True
GTK_RELIEF_NORMAL
True
-
+
2
diff --git a/desmume/src/gtk/main.cpp b/desmume/src/gtk/main.cpp
index d3e14ff7d..c408d5384 100644
--- a/desmume/src/gtk/main.cpp
+++ b/desmume/src/gtk/main.cpp
@@ -1402,19 +1402,7 @@ static void AcceptNewJoyKey(GtkWidget *w, GdkEventFocus *e, struct modify_key_ct
{
gchar *YouPressed;
- switch (ctx->key_id) {
- case KEY_RIGHT:
- case KEY_LEFT:
- ctx->mk_key_chosen = get_joy_axis(KEY_LEFT, KEY_RIGHT);
- break;
- case KEY_UP:
- case KEY_DOWN:
- ctx->mk_key_chosen = get_joy_axis(KEY_UP, KEY_DOWN);
- break;
- default:
- ctx->mk_key_chosen = get_joy_key(ctx->key_id);
- break;
- }
+ ctx->mk_key_chosen = get_joy_key(ctx->key_id);
YouPressed = g_strdup_printf("You pressed : %d\nClick OK to keep this key.", ctx->mk_key_chosen);
gtk_label_set(GTK_LABEL(ctx->label), YouPressed);
@@ -1450,16 +1438,7 @@ static void Modify_JoyKey(GtkWidget* widget, gpointer data)
switch(gtk_dialog_run(GTK_DIALOG(mkDialog))) {
case GTK_RESPONSE_OK:
- switch (ctx.key_id) {
- case KEY_RIGHT:
- case KEY_LEFT:
- Keypad_Temp[KEY_RIGHT-1] = Keypad_Temp[KEY_LEFT-1] = ctx.mk_key_chosen;
- case KEY_UP:
- case KEY_DOWN:
- Keypad_Temp[KEY_UP-1] = Keypad_Temp[KEY_DOWN-1] = ctx.mk_key_chosen;
- default:
- Keypad_Temp[Key] = ctx.mk_key_chosen;
- }
+ Keypad_Temp[Key] = ctx.mk_key_chosen;
Key_Label = g_strdup_printf("%s (%d)", key_names[Key], Keypad_Temp[Key]);
gtk_button_set_label(GTK_BUTTON(widget), Key_Label);
g_free(Key_Label);