src/joystick/SDL_gamecontroller.c
changeset 7191 75360622e65f
parent 7181 d35a0936c674
child 7247 6a4570f12c20
equal deleted inserted replaced
7190:11612d544fcd 7191:75360622e65f
    37 static SDL_GameController *SDL_gamecontrollers = NULL;
    37 static SDL_GameController *SDL_gamecontrollers = NULL;
    38 
    38 
    39 /* keep track of the hat and mask value that transforms this hat movement into a button/axis press */
    39 /* keep track of the hat and mask value that transforms this hat movement into a button/axis press */
    40 struct _SDL_HatMapping
    40 struct _SDL_HatMapping
    41 {
    41 {
    42 	int hat;
    42     int hat;
    43 	Uint8 mask;
    43     Uint8 mask;
    44 };
    44 };
    45 
    45 
    46 #define k_nMaxReverseEntries 20
    46 #define k_nMaxReverseEntries 20
    47 
    47 
    48 /**
    48 /**
    52 #define k_nMaxHatEntries 0x3f + 1
    52 #define k_nMaxHatEntries 0x3f + 1
    53 
    53 
    54 /* our in memory mapping db between joystick objects and controller mappings*/
    54 /* our in memory mapping db between joystick objects and controller mappings*/
    55 struct _SDL_ControllerMapping
    55 struct _SDL_ControllerMapping
    56 {
    56 {
    57 	SDL_JoystickGUID guid;
    57     SDL_JoystickGUID guid;
    58 	const char *name;
    58     const char *name;
    59 
    59 
    60 	// mapping of axis/button id to controller version
    60     /* mapping of axis/button id to controller version */
    61 	int axes[SDL_CONTROLLER_AXIS_MAX];
    61     int axes[SDL_CONTROLLER_AXIS_MAX];
    62 	int buttonasaxis[SDL_CONTROLLER_AXIS_MAX];
    62     int buttonasaxis[SDL_CONTROLLER_AXIS_MAX];
    63 
    63 
    64 	int buttons[SDL_CONTROLLER_BUTTON_MAX];
    64     int buttons[SDL_CONTROLLER_BUTTON_MAX];
    65 	int axesasbutton[SDL_CONTROLLER_BUTTON_MAX];
    65     int axesasbutton[SDL_CONTROLLER_BUTTON_MAX];
    66 	struct _SDL_HatMapping hatasbutton[SDL_CONTROLLER_BUTTON_MAX];
    66     struct _SDL_HatMapping hatasbutton[SDL_CONTROLLER_BUTTON_MAX];
    67 
    67 
    68 	// reverse mapping, joystick indices to buttons
    68     /* reverse mapping, joystick indices to buttons */
    69 	SDL_GameControllerAxis raxes[k_nMaxReverseEntries];
    69     SDL_GameControllerAxis raxes[k_nMaxReverseEntries];
    70 	SDL_GameControllerAxis rbuttonasaxis[k_nMaxReverseEntries];
    70     SDL_GameControllerAxis rbuttonasaxis[k_nMaxReverseEntries];
    71 
    71 
    72 	SDL_GameControllerButton rbuttons[k_nMaxReverseEntries];
    72     SDL_GameControllerButton rbuttons[k_nMaxReverseEntries];
    73 	SDL_GameControllerButton raxesasbutton[k_nMaxReverseEntries];
    73     SDL_GameControllerButton raxesasbutton[k_nMaxReverseEntries];
    74 	SDL_GameControllerButton rhatasbutton[k_nMaxHatEntries];
    74     SDL_GameControllerButton rhatasbutton[k_nMaxHatEntries];
    75 
    75 
    76 };
    76 };
    77 
    77 
    78 
    78 
    79 /* our hard coded list of mapping support */
    79 /* our hard coded list of mapping support */
    80 typedef struct _ControllerMapping_t
    80 typedef struct _ControllerMapping_t
    81 {
    81 {
    82 	SDL_JoystickGUID guid;
    82     SDL_JoystickGUID guid;
    83 	char *name;
    83     char *name;
    84 	char *mapping;
    84     char *mapping;
    85 	struct _ControllerMapping_t *next;
    85     struct _ControllerMapping_t *next;
    86 } ControllerMapping_t;
    86 } ControllerMapping_t;
    87 
    87 
    88 
    88 
    89 /* default mappings we support */
    89 /* default mappings we support */
    90 const char *s_ControllerMappings [] =
    90 const char *s_ControllerMappings [] =
    91 {
    91 {
    92 #ifdef SDL_JOYSTICK_DINPUT
    92 #ifdef SDL_JOYSTICK_DINPUT
    93 	"xinput,X360 Controller,a:b10,b:b11,y:b13,x:b12,start:b4,guide:b14,back:b5,dpup:b0,dpleft:b2,dpdown:b1,dpright:b3,leftshoulder:b8,rightshoulder:b9,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5",
    93     "xinput,X360 Controller,a:b10,b:b11,y:b13,x:b12,start:b4,guide:b14,back:b5,dpup:b0,dpleft:b2,dpdown:b1,dpright:b3,leftshoulder:b8,rightshoulder:b9,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5",
    94 	"341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7",
    94     "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7",
    95 	"88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,x:b0,y:b3,start:b11,back:b8,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.4,dpdown:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b6,righttrigger:b7,guide:b12",
    95     "88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,x:b0,y:b3,start:b11,back:b8,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.4,dpdown:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b6,righttrigger:b7,guide:b12",
    96 	"4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,",
    96     "4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,",
    97 	"25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,x:b0,y:b3,start:b8,guide:,back:b9,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.4,dpdown:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5",
    97     "25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,x:b0,y:b3,start:b8,guide:,back:b9,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.4,dpdown:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5",
    98     "ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,y:b3,x:b2,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
    98     "ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,y:b3,x:b2,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
    99     "6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
    99     "6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
   100 #elif defined(__MACOSX__)
   100 #elif defined(__MACOSX__)
   101 	"5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,y:b3,x:b2,start:b8,guide:b10,back:b9,dpup:b11,dpleft:b13,dpdown:b12,dpright:b14,leftshoulder:b4,rightshoulder:b5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5",
   101     "5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,y:b3,x:b2,start:b8,guide:b10,back:b9,dpup:b11,dpleft:b13,dpdown:b12,dpright:b14,leftshoulder:b4,rightshoulder:b5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5",
   102 	"4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,x:b12,y:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b6,dpdown:b7,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9",
   102     "4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,x:b12,y:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b6,dpdown:b7,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9",
   103     "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,y:b3,x:b2,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
   103     "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,y:b3,x:b2,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
   104     "6d040000000000001fc2000000000000,Logitech F710 Gamepad Controller (XInput),a:b0,b:b1,y:b3,x:b2,start:b8,guide:b10,back:b9,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b11,dpleft:b13,dpdown:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
   104     "6d040000000000001fc2000000000000,Logitech F710 Gamepad Controller (XInput),a:b0,b:b1,y:b3,x:b2,start:b8,guide:b10,back:b9,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b11,dpleft:b13,dpdown:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
   105     "6d0400000000000016c2000000000000,Logitech F310 Gamepad Controller (DInput),a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", // Guide button doesn't seem to be sent in DInput mode.
   105     "6d0400000000000016c2000000000000,Logitech F310 Gamepad Controller (DInput),a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", /* Guide button doesn't seem to be sent in DInput mode. */
   106     "6d0400000000000019c2000000000000,Logitech Wireless Gamepad Controller (DInput),a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", // This includes F710 in DInput mode and the "Logitech Cordless RumblePad 2", at the very least.
   106     "6d0400000000000019c2000000000000,Logitech Wireless Gamepad Controller (DInput),a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", /* This includes F710 in DInput mode and the "Logitech Cordless RumblePad 2", at the very least. */
   107 #elif defined(__LINUX__)
   107 #elif defined(__LINUX__)
   108 	"030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5",
   108     "030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5",
   109     "030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
   109     "030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
   110     "030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
   110     "030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
   111 	"030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,x:b15,y:b12,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9",
   111     "030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,x:b15,y:b12,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9",
   112     "030000006d0400001fc2000005030000,Logitech F710 Gamepad Controller (XInput),a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
   112     "030000006d0400001fc2000005030000,Logitech F710 Gamepad Controller (XInput),a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
   113     "030000006d04000019c2000011010000,Logitech F710 Gamepad Controller (DInput),a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", // Guide button doesn't seem to be sent in DInput mode.
   113     "030000006d04000019c2000011010000,Logitech F710 Gamepad Controller (DInput),a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", /* Guide button doesn't seem to be sent in DInput mode. */
   114     "030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
   114     "030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
   115     "030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
   115     "030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
   116     "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,y:b3,x:b2,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
   116     "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,y:b3,x:b2,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
   117     "03000000ba2200002010000001010000,Jess Technology USB Game Controller,start:b9,a:b2,b:b1,x:b3,y:b0,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b6,righttrigger:b7,leftshoulder:b4,rightshoulder:b5,guide:,back:b8",
   117     "03000000ba2200002010000001010000,Jess Technology USB Game Controller,start:b9,a:b2,b:b1,x:b3,y:b0,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b6,righttrigger:b7,leftshoulder:b4,rightshoulder:b5,guide:,back:b8",
   118 #endif
   118 #endif
   119 	NULL
   119     NULL
   120 };
   120 };
   121 
   121 
   122 static ControllerMapping_t *s_pSupportedControllers = NULL;
   122 static ControllerMapping_t *s_pSupportedControllers = NULL;
   123 #ifdef SDL_JOYSTICK_DINPUT
   123 #ifdef SDL_JOYSTICK_DINPUT
   124 static ControllerMapping_t *s_pXInputMapping = NULL;
   124 static ControllerMapping_t *s_pXInputMapping = NULL;
   125 #endif
   125 #endif
   126 
   126 
   127 /* The SDL game controller structure */
   127 /* The SDL game controller structure */
   128 struct _SDL_GameController
   128 struct _SDL_GameController
   129 {
   129 {
   130 	SDL_Joystick *joystick;	/* underlying joystick device */
   130     SDL_Joystick *joystick; /* underlying joystick device */
   131 	int ref_count;
   131     int ref_count;
   132 	Uint8 hatState[4]; /* the current hat state for this controller */
   132     Uint8 hatState[4]; /* the current hat state for this controller */
   133 	struct _SDL_ControllerMapping mapping; /* the mapping object for this controller */
   133     struct _SDL_ControllerMapping mapping; /* the mapping object for this controller */
   134 	struct _SDL_GameController *next; /* pointer to next game controller we have allocated */
   134     struct _SDL_GameController *next; /* pointer to next game controller we have allocated */
   135 };
   135 };
   136 
   136 
   137 
   137 
   138 int SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value);
   138 int SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value);
   139 int	SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state);
   139 int SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state);
   140 
   140 
   141 /*
   141 /*
   142  * Event filter to fire controller events from joystick ones
   142  * Event filter to fire controller events from joystick ones
   143  */
   143  */
   144 int SDL_GameControllerEventWatcher(void *userdata, SDL_Event * event)
   144 int SDL_GameControllerEventWatcher(void *userdata, SDL_Event * event)
   145 {
   145 {
   146 	switch( event->type )
   146     switch( event->type )
   147 	{
   147     {
   148 	case SDL_JOYAXISMOTION:
   148     case SDL_JOYAXISMOTION:
   149 		{
   149         {
   150 			SDL_GameController *controllerlist;
   150             SDL_GameController *controllerlist;
   151 
   151 
   152 			if ( event->jaxis.axis >= k_nMaxReverseEntries ) break;
   152             if ( event->jaxis.axis >= k_nMaxReverseEntries ) break;
   153 
   153 
   154 			controllerlist = SDL_gamecontrollers;
   154             controllerlist = SDL_gamecontrollers;
   155 			while ( controllerlist )
   155             while ( controllerlist )
   156 			{
   156             {
   157 				if ( controllerlist->joystick->instance_id == event->jaxis.which )
   157                 if ( controllerlist->joystick->instance_id == event->jaxis.which )
   158 				{
   158                 {
   159 					if ( controllerlist->mapping.raxes[event->jaxis.axis] >= 0 ) // simple axis to axis, send it through
   159                     if ( controllerlist->mapping.raxes[event->jaxis.axis] >= 0 ) /* simple axis to axis, send it through */
   160 					{
   160                     {
   161 						SDL_GameControllerAxis axis = controllerlist->mapping.raxes[event->jaxis.axis];
   161                         SDL_GameControllerAxis axis = controllerlist->mapping.raxes[event->jaxis.axis];
   162                         Sint16 value = event->jaxis.value;
   162                         Sint16 value = event->jaxis.value;
   163 						switch (axis)
   163                         switch (axis)
   164 						{
   164                         {
   165 							case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
   165                             case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
   166 							case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
   166                             case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
   167 								/* Shift it to be 0 - 32767. */
   167                                 /* Shift it to be 0 - 32767. */
   168 								value = value / 2 + 16384;
   168                                 value = value / 2 + 16384;
   169 							default:
   169                             default:
   170 								break;
   170                                 break;
   171 						}
   171                         }
   172 						SDL_PrivateGameControllerAxis( controllerlist, axis, value );
   172                         SDL_PrivateGameControllerAxis( controllerlist, axis, value );
   173 					}
   173                     }
   174 					else if ( controllerlist->mapping.raxesasbutton[event->jaxis.axis] >= 0 ) // simulate an axis as a button
   174                     else if ( controllerlist->mapping.raxesasbutton[event->jaxis.axis] >= 0 ) /* simulate an axis as a button */
   175 					{
   175                     {
   176 						SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.raxesasbutton[event->jaxis.axis], ABS(event->jaxis.value) > 32768/2 ? SDL_PRESSED : SDL_RELEASED );
   176                         SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.raxesasbutton[event->jaxis.axis], ABS(event->jaxis.value) > 32768/2 ? SDL_PRESSED : SDL_RELEASED );
   177 					}
   177                     }
   178 					break;
   178                     break;
   179 				}
   179                 }
   180 				controllerlist = controllerlist->next;
   180                 controllerlist = controllerlist->next;
   181 			}
   181             }
   182 		}
   182         }
   183 		break;
   183         break;
   184 	case SDL_JOYBUTTONDOWN:
   184     case SDL_JOYBUTTONDOWN:
   185 	case SDL_JOYBUTTONUP:
   185     case SDL_JOYBUTTONUP:
   186 		{
   186         {
   187 			SDL_GameController *controllerlist;
   187             SDL_GameController *controllerlist;
   188 
   188 
   189 			if ( event->jbutton.button >= k_nMaxReverseEntries ) break;
   189             if ( event->jbutton.button >= k_nMaxReverseEntries ) break;
   190 
   190 
   191 			controllerlist = SDL_gamecontrollers;
   191             controllerlist = SDL_gamecontrollers;
   192 			while ( controllerlist )
   192             while ( controllerlist )
   193 			{
   193             {
   194 				if ( controllerlist->joystick->instance_id == event->jbutton.which )
   194                 if ( controllerlist->joystick->instance_id == event->jbutton.which )
   195 				{
   195                 {
   196 					if ( controllerlist->mapping.rbuttons[event->jbutton.button] >= 0 ) // simple button as button
   196                     if ( controllerlist->mapping.rbuttons[event->jbutton.button] >= 0 ) /* simple button as button */
   197 					{
   197                     {
   198 						SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rbuttons[event->jbutton.button], event->jbutton.state );
   198                         SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rbuttons[event->jbutton.button], event->jbutton.state );
   199 					}
   199                     }
   200 					else if ( controllerlist->mapping.rbuttonasaxis[event->jbutton.button] >= 0 ) // an button pretending to be an axis
   200                     else if ( controllerlist->mapping.rbuttonasaxis[event->jbutton.button] >= 0 ) /* an button pretending to be an axis */
   201 					{
   201                     {
   202 						SDL_PrivateGameControllerAxis( controllerlist, controllerlist->mapping.rbuttonasaxis[event->jbutton.button], event->jbutton.state > 0 ? 32767 : 0 );
   202                         SDL_PrivateGameControllerAxis( controllerlist, controllerlist->mapping.rbuttonasaxis[event->jbutton.button], event->jbutton.state > 0 ? 32767 : 0 );
   203 					}
   203                     }
   204 					break;
   204                     break;
   205 				}
   205                 }
   206 				controllerlist = controllerlist->next;
   206                 controllerlist = controllerlist->next;
   207 			}
   207             }
   208 		}
   208         }
   209 		break;
   209         break;
   210 	case SDL_JOYHATMOTION:
   210     case SDL_JOYHATMOTION:
   211 		{
   211         {
   212 			SDL_GameController *controllerlist;
   212             SDL_GameController *controllerlist;
   213 
   213 
   214 			if ( event->jhat.hat >= 4 ) break;
   214             if ( event->jhat.hat >= 4 ) break;
   215 
   215 
   216 			controllerlist = SDL_gamecontrollers;
   216             controllerlist = SDL_gamecontrollers;
   217 			while ( controllerlist )
   217             while ( controllerlist )
   218 			{
   218             {
   219 				if ( controllerlist->joystick->instance_id == event->jhat.which )
   219                 if ( controllerlist->joystick->instance_id == event->jhat.which )
   220 				{
   220                 {
   221 					Uint8 bSame = controllerlist->hatState[event->jhat.hat] & event->jhat.value;
   221                     Uint8 bSame = controllerlist->hatState[event->jhat.hat] & event->jhat.value;
   222 					// Get list of removed bits (button release)
   222                     /* Get list of removed bits (button release) */
   223 					Uint8 bChanged = controllerlist->hatState[event->jhat.hat] ^ bSame;
   223                     Uint8 bChanged = controllerlist->hatState[event->jhat.hat] ^ bSame;
   224 					// the hat idx in the high nibble
   224                     /* the hat idx in the high nibble */
   225 					int bHighHat = event->jhat.hat << 4;
   225                     int bHighHat = event->jhat.hat << 4;
   226 
   226 
   227 					if ( bChanged & SDL_HAT_DOWN )
   227                     if ( bChanged & SDL_HAT_DOWN )
   228 						SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_DOWN], SDL_RELEASED );
   228                         SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_DOWN], SDL_RELEASED );
   229 					if ( bChanged & SDL_HAT_UP )
   229                     if ( bChanged & SDL_HAT_UP )
   230 						SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_UP], SDL_RELEASED );
   230                         SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_UP], SDL_RELEASED );
   231 					if ( bChanged & SDL_HAT_LEFT )
   231                     if ( bChanged & SDL_HAT_LEFT )
   232 						SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_LEFT], SDL_RELEASED );
   232                         SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_LEFT], SDL_RELEASED );
   233 					if ( bChanged & SDL_HAT_RIGHT )
   233                     if ( bChanged & SDL_HAT_RIGHT )
   234 						SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_RIGHT], SDL_RELEASED );
   234                         SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_RIGHT], SDL_RELEASED );
   235 
   235 
   236 					// Get list of added bits (button press)
   236                     /* Get list of added bits (button press) */
   237 					bChanged = event->jhat.value ^ bSame;
   237                     bChanged = event->jhat.value ^ bSame;
   238 
   238 
   239 					if ( bChanged & SDL_HAT_DOWN )
   239                     if ( bChanged & SDL_HAT_DOWN )
   240 						SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_DOWN], SDL_PRESSED );
   240                         SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_DOWN], SDL_PRESSED );
   241 					if ( bChanged & SDL_HAT_UP )
   241                     if ( bChanged & SDL_HAT_UP )
   242 						SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_UP], SDL_PRESSED );
   242                         SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_UP], SDL_PRESSED );
   243 					if ( bChanged & SDL_HAT_LEFT )
   243                     if ( bChanged & SDL_HAT_LEFT )
   244 						SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_LEFT], SDL_PRESSED );
   244                         SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_LEFT], SDL_PRESSED );
   245 					if ( bChanged & SDL_HAT_RIGHT )
   245                     if ( bChanged & SDL_HAT_RIGHT )
   246 						SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_RIGHT], SDL_PRESSED );
   246                         SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_RIGHT], SDL_PRESSED );
   247 
   247 
   248 					// update our state cache
   248                     /* update our state cache */
   249 					controllerlist->hatState[event->jhat.hat] = event->jhat.value;
   249                     controllerlist->hatState[event->jhat.hat] = event->jhat.value;
   250 
   250 
   251 					break;
   251                     break;
   252 				}
   252                 }
   253 				controllerlist = controllerlist->next;
   253                 controllerlist = controllerlist->next;
   254 			}
   254             }
   255 		}
   255         }
   256 		break;
   256         break;
   257 	case SDL_JOYDEVICEADDED:
   257     case SDL_JOYDEVICEADDED:
   258 		{
   258         {
   259 			if ( SDL_IsGameController(event->jdevice.which ) )
   259             if ( SDL_IsGameController(event->jdevice.which ) )
   260 			{
   260             {
   261 				SDL_Event deviceevent;
   261                 SDL_Event deviceevent;
   262 				deviceevent.type = SDL_CONTROLLERDEVICEADDED;
   262                 deviceevent.type = SDL_CONTROLLERDEVICEADDED;
   263 				deviceevent.cdevice.which = event->jdevice.which;
   263                 deviceevent.cdevice.which = event->jdevice.which;
   264 				SDL_PushEvent(&deviceevent);
   264                 SDL_PushEvent(&deviceevent);
   265 			}
   265             }
   266 		}
   266         }
   267 		break;
   267         break;
   268 	case SDL_JOYDEVICEREMOVED:
   268     case SDL_JOYDEVICEREMOVED:
   269 		{
   269         {
   270 			SDL_GameController *controllerlist = SDL_gamecontrollers;
   270             SDL_GameController *controllerlist = SDL_gamecontrollers;
   271 			while ( controllerlist )
   271             while ( controllerlist )
   272 			{
   272             {
   273 				if ( controllerlist->joystick->instance_id == event->jdevice.which )
   273                 if ( controllerlist->joystick->instance_id == event->jdevice.which )
   274 				{
   274                 {
   275 					SDL_Event deviceevent;
   275                     SDL_Event deviceevent;
   276 					deviceevent.type = SDL_CONTROLLERDEVICEREMOVED;
   276                     deviceevent.type = SDL_CONTROLLERDEVICEREMOVED;
   277 					deviceevent.cdevice.which = event->jdevice.which;
   277                     deviceevent.cdevice.which = event->jdevice.which;
   278 					SDL_PushEvent(&deviceevent);
   278                     SDL_PushEvent(&deviceevent);
   279 					break;
   279                     break;
   280 				}
   280                 }
   281 				controllerlist = controllerlist->next;
   281                 controllerlist = controllerlist->next;
   282 			}
   282             }
   283 		}
   283         }
   284 		break;
   284         break;
   285 	default:
   285     default:
   286 		break;
   286         break;
   287 	}
   287     }
   288 
   288 
   289 	return 1;
   289     return 1;
   290 }
   290 }
   291 
   291 
   292 /*
   292 /*
   293  * Helper function to scan the mappings database for a controller with the specified GUID
   293  * Helper function to scan the mappings database for a controller with the specified GUID
   294  */
   294  */
   295 ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *guid)
   295 ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *guid)
   296 {
   296 {
   297 	ControllerMapping_t *pSupportedController = s_pSupportedControllers;
   297     ControllerMapping_t *pSupportedController = s_pSupportedControllers;
   298 	while ( pSupportedController )
   298     while ( pSupportedController )
   299 	{
   299     {
   300 		if ( !SDL_memcmp( guid, &pSupportedController->guid, sizeof(*guid) ) )
   300         if ( !SDL_memcmp( guid, &pSupportedController->guid, sizeof(*guid) ) )
   301 		{
   301         {
   302 			return pSupportedController;
   302             return pSupportedController;
   303 		}
   303         }
   304 		pSupportedController = pSupportedController->next;
   304         pSupportedController = pSupportedController->next;
   305 	}
   305     }
   306     return NULL;
   306     return NULL;
   307 }
   307 }
   308 
   308 
   309 /*
   309 /*
   310  * Helper function to determine pre-calculated offset to certain joystick mappings
   310  * Helper function to determine pre-calculated offset to certain joystick mappings
   311  */
   311  */
   312 ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
   312 ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
   313 {
   313 {
   314 #ifdef SDL_JOYSTICK_DINPUT
   314 #ifdef SDL_JOYSTICK_DINPUT
   315 	if ( SDL_SYS_IsXInputDeviceIndex(device_index) && s_pXInputMapping )
   315     if ( SDL_SYS_IsXInputDeviceIndex(device_index) && s_pXInputMapping )
   316 	{
   316     {
   317 		return s_pXInputMapping;
   317         return s_pXInputMapping;
   318 	}
   318     }
   319 	else
   319     else
   320 #endif
   320 #endif
   321 	{
   321     {
   322 		SDL_JoystickGUID jGUID = SDL_JoystickGetDeviceGUID( device_index );
   322         SDL_JoystickGUID jGUID = SDL_JoystickGetDeviceGUID( device_index );
   323 		return SDL_PrivateGetControllerMappingForGUID(&jGUID);
   323         return SDL_PrivateGetControllerMappingForGUID(&jGUID);
   324 	}
   324     }
   325 
   325 
   326 	return NULL;
   326     return NULL;
   327 }
   327 }
   328 
   328 
   329 static const char* map_StringForControllerAxis[] = {
   329 static const char* map_StringForControllerAxis[] = {
   330     "leftx",
   330     "leftx",
   331     "lefty",
   331     "lefty",
   340  * convert a string to its enum equivalent
   340  * convert a string to its enum equivalent
   341  */
   341  */
   342 SDL_GameControllerAxis SDL_GameControllerGetAxisFromString( const char *pchString )
   342 SDL_GameControllerAxis SDL_GameControllerGetAxisFromString( const char *pchString )
   343 {
   343 {
   344     int entry;
   344     int entry;
   345 	if ( !pchString || !pchString[0] )
   345     if ( !pchString || !pchString[0] )
   346 		return SDL_CONTROLLER_AXIS_INVALID;
   346         return SDL_CONTROLLER_AXIS_INVALID;
   347 
   347 
   348     for ( entry = 0; map_StringForControllerAxis[entry]; ++entry)
   348     for ( entry = 0; map_StringForControllerAxis[entry]; ++entry)
   349     {
   349     {
   350         if ( !SDL_strcasecmp( pchString, map_StringForControllerAxis[entry] ) )
   350         if ( !SDL_strcasecmp( pchString, map_StringForControllerAxis[entry] ) )
   351             return entry;
   351             return entry;
   388  * convert a string to its enum equivalent
   388  * convert a string to its enum equivalent
   389  */
   389  */
   390 SDL_GameControllerButton SDL_GameControllerGetButtonFromString( const char *pchString )
   390 SDL_GameControllerButton SDL_GameControllerGetButtonFromString( const char *pchString )
   391 {
   391 {
   392     int entry;
   392     int entry;
   393 	if ( !pchString || !pchString[0] )
   393     if ( !pchString || !pchString[0] )
   394 		return SDL_CONTROLLER_BUTTON_INVALID;
   394         return SDL_CONTROLLER_BUTTON_INVALID;
   395 
   395 
   396     for ( entry = 0; map_StringForControllerButton[entry]; ++entry)
   396     for ( entry = 0; map_StringForControllerButton[entry]; ++entry)
   397 	{
   397     {
   398 		if ( !SDL_strcasecmp( pchString, map_StringForControllerButton[entry] ) )
   398         if ( !SDL_strcasecmp( pchString, map_StringForControllerButton[entry] ) )
   399 		return entry;
   399         return entry;
   400 	}
   400     }
   401 	return SDL_CONTROLLER_BUTTON_INVALID;
   401     return SDL_CONTROLLER_BUTTON_INVALID;
   402 }
   402 }
   403 
   403 
   404 /*
   404 /*
   405  * convert an enum to its string equivalent
   405  * convert an enum to its string equivalent
   406  */
   406  */
   416 /*
   416 /*
   417  * given a controller button name and a joystick name update our mapping structure with it
   417  * given a controller button name and a joystick name update our mapping structure with it
   418  */
   418  */
   419 void SDL_PrivateGameControllerParseButton( const char *szGameButton, const char *szJoystickButton, struct _SDL_ControllerMapping *pMapping )
   419 void SDL_PrivateGameControllerParseButton( const char *szGameButton, const char *szJoystickButton, struct _SDL_ControllerMapping *pMapping )
   420 {
   420 {
   421 	int iSDLButton = 0;
   421     int iSDLButton = 0;
   422 	SDL_GameControllerButton button;
   422     SDL_GameControllerButton button;
   423 	SDL_GameControllerAxis axis;
   423     SDL_GameControllerAxis axis;
   424 	button = SDL_GameControllerGetButtonFromString( szGameButton );
   424     button = SDL_GameControllerGetButtonFromString( szGameButton );
   425 	axis = SDL_GameControllerGetAxisFromString( szGameButton );
   425     axis = SDL_GameControllerGetAxisFromString( szGameButton );
   426 	iSDLButton = SDL_atoi( &szJoystickButton[1] );
   426     iSDLButton = SDL_atoi( &szJoystickButton[1] );
   427 
   427 
   428 	if ( szJoystickButton[0] == 'a' )
   428     if ( szJoystickButton[0] == 'a' )
   429 	{
   429     {
   430 		if ( iSDLButton >= k_nMaxReverseEntries )
   430         if ( iSDLButton >= k_nMaxReverseEntries )
   431 		{
   431         {
   432 			SDL_SetError("Axis index too large: %d", iSDLButton );
   432             SDL_SetError("Axis index too large: %d", iSDLButton );
   433 			return;
   433             return;
   434 		}
   434         }
   435 		if ( axis != SDL_CONTROLLER_AXIS_INVALID )
   435         if ( axis != SDL_CONTROLLER_AXIS_INVALID )
   436 		{
   436         {
   437 			pMapping->axes[ axis ] = iSDLButton;
   437             pMapping->axes[ axis ] = iSDLButton;
   438 			pMapping->raxes[ iSDLButton ] = axis;
   438             pMapping->raxes[ iSDLButton ] = axis;
   439 		}
   439         }
   440 		else if ( button != SDL_CONTROLLER_BUTTON_INVALID )
   440         else if ( button != SDL_CONTROLLER_BUTTON_INVALID )
   441 		{
   441         {
   442 			pMapping->axesasbutton[ button ] = iSDLButton;
   442             pMapping->axesasbutton[ button ] = iSDLButton;
   443 			pMapping->raxesasbutton[ iSDLButton ] = button;
   443             pMapping->raxesasbutton[ iSDLButton ] = button;
   444 		}
   444         }
   445 		else
   445         else
   446 		{
   446         {
   447 			SDL_assert( !"How did we get here?" );
   447             SDL_assert( !"How did we get here?" );
   448 		}
   448         }
   449 
   449 
   450 	}
   450     }
   451 	else if ( szJoystickButton[0] == 'b' )
   451     else if ( szJoystickButton[0] == 'b' )
   452 	{
   452     {
   453 		if ( iSDLButton >= k_nMaxReverseEntries )
   453         if ( iSDLButton >= k_nMaxReverseEntries )
   454 		{
   454         {
   455 			SDL_SetError("Button index too large: %d", iSDLButton );
   455             SDL_SetError("Button index too large: %d", iSDLButton );
   456 			return;
   456             return;
   457 		}
   457         }
   458 		if ( button != SDL_CONTROLLER_BUTTON_INVALID )
   458         if ( button != SDL_CONTROLLER_BUTTON_INVALID )
   459 		{
   459         {
   460 			pMapping->buttons[ button ] = iSDLButton;
   460             pMapping->buttons[ button ] = iSDLButton;
   461 			pMapping->rbuttons[ iSDLButton ] = button;
   461             pMapping->rbuttons[ iSDLButton ] = button;
   462 		}
   462         }
   463 		else if ( axis != SDL_CONTROLLER_AXIS_INVALID )
   463         else if ( axis != SDL_CONTROLLER_AXIS_INVALID )
   464 		{
   464         {
   465 			pMapping->buttonasaxis[ axis ] = iSDLButton;
   465             pMapping->buttonasaxis[ axis ] = iSDLButton;
   466 			pMapping->rbuttonasaxis[ iSDLButton ] = axis;
   466             pMapping->rbuttonasaxis[ iSDLButton ] = axis;
   467 		}
   467         }
   468 		else
   468         else
   469 		{
   469         {
   470 			SDL_assert( !"How did we get here?" );
   470             SDL_assert( !"How did we get here?" );
   471 		}
   471         }
   472 	}
   472     }
   473 	else if ( szJoystickButton[0] == 'h' )
   473     else if ( szJoystickButton[0] == 'h' )
   474 	{
   474     {
   475 		int hat = SDL_atoi( &szJoystickButton[1] );
   475         int hat = SDL_atoi( &szJoystickButton[1] );
   476 		int mask = SDL_atoi( &szJoystickButton[3] );
   476         int mask = SDL_atoi( &szJoystickButton[3] );
   477 		if (hat >= 4) {
   477         if (hat >= 4) {
   478 			SDL_SetError("Hat index too large: %d", iSDLButton );
   478             SDL_SetError("Hat index too large: %d", iSDLButton );
   479 		}
   479         }
   480 
   480 
   481 		if ( button != SDL_CONTROLLER_BUTTON_INVALID )
   481         if ( button != SDL_CONTROLLER_BUTTON_INVALID )
   482 		{
   482         {
   483             int ridx;
   483             int ridx;
   484 			pMapping->hatasbutton[ button ].hat = hat;
   484             pMapping->hatasbutton[ button ].hat = hat;
   485 			pMapping->hatasbutton[ button ].mask = mask;
   485             pMapping->hatasbutton[ button ].mask = mask;
   486 			ridx = (hat << 4) | mask;
   486             ridx = (hat << 4) | mask;
   487 			pMapping->rhatasbutton[ ridx ] = button;
   487             pMapping->rhatasbutton[ ridx ] = button;
   488 		}
   488         }
   489 		else if ( axis != SDL_CONTROLLER_AXIS_INVALID )
   489         else if ( axis != SDL_CONTROLLER_AXIS_INVALID )
   490 		{
   490         {
   491 			SDL_assert( !"Support hat as axis" );
   491             SDL_assert( !"Support hat as axis" );
   492 		}
   492         }
   493 		else
   493         else
   494 		{
   494         {
   495 			SDL_assert( !"How did we get here?" );
   495             SDL_assert( !"How did we get here?" );
   496 		}
   496         }
   497 	}
   497     }
   498 }
   498 }
   499 
   499 
   500 
   500 
   501 /*
   501 /*
   502  * given a controller mapping string update our mapping object
   502  * given a controller mapping string update our mapping object
   503  */
   503  */
   504 static void
   504 static void
   505 SDL_PrivateGameControllerParseControllerConfigString( struct _SDL_ControllerMapping *pMapping, const char *pchString )
   505 SDL_PrivateGameControllerParseControllerConfigString( struct _SDL_ControllerMapping *pMapping, const char *pchString )
   506 {
   506 {
   507 	char szGameButton[20];
   507     char szGameButton[20];
   508 	char szJoystickButton[20];
   508     char szJoystickButton[20];
   509 	SDL_bool bGameButton = SDL_TRUE;
   509     SDL_bool bGameButton = SDL_TRUE;
   510 	int i = 0;
   510     int i = 0;
   511 	const char *pchPos = pchString;
   511     const char *pchPos = pchString;
   512 
   512 
   513 	SDL_memset( szGameButton, 0x0, sizeof(szGameButton) );
   513     SDL_memset( szGameButton, 0x0, sizeof(szGameButton) );
   514 	SDL_memset( szJoystickButton, 0x0, sizeof(szJoystickButton) );
   514     SDL_memset( szJoystickButton, 0x0, sizeof(szJoystickButton) );
   515 
   515 
   516 	while ( pchPos && *pchPos )
   516     while ( pchPos && *pchPos )
   517 	{
   517     {
   518 		if ( *pchPos == ':' )
   518         if ( *pchPos == ':' )
   519 		{
   519         {
   520 			i = 0;
   520             i = 0;
   521 			bGameButton = SDL_FALSE;
   521             bGameButton = SDL_FALSE;
   522 		}
   522         }
   523 		else if ( *pchPos == ' ' )
   523         else if ( *pchPos == ' ' )
   524 		{
   524         {
   525 
   525 
   526 		}
   526         }
   527 		else if ( *pchPos == ',' )
   527         else if ( *pchPos == ',' )
   528 		{
   528         {
   529 			i = 0;
   529             i = 0;
   530 			bGameButton = SDL_TRUE;
   530             bGameButton = SDL_TRUE;
   531 			SDL_PrivateGameControllerParseButton( szGameButton, szJoystickButton, pMapping );
   531             SDL_PrivateGameControllerParseButton( szGameButton, szJoystickButton, pMapping );
   532 			SDL_memset( szGameButton, 0x0, sizeof(szGameButton) );
   532             SDL_memset( szGameButton, 0x0, sizeof(szGameButton) );
   533 			SDL_memset( szJoystickButton, 0x0, sizeof(szJoystickButton) );
   533             SDL_memset( szJoystickButton, 0x0, sizeof(szJoystickButton) );
   534 
   534 
   535 		}
   535         }
   536 		else if ( bGameButton )
   536         else if ( bGameButton )
   537 		{
   537         {
   538 			if ( i >=  sizeof(szGameButton))
   538             if ( i >=  sizeof(szGameButton))
   539 			{
   539             {
   540 				SDL_SetError( "Button name too large: %s", szGameButton );
   540                 SDL_SetError( "Button name too large: %s", szGameButton );
   541 				return;
   541                 return;
   542 			}
   542             }
   543 			szGameButton[i] = *pchPos;
   543             szGameButton[i] = *pchPos;
   544 			i++;
   544             i++;
   545 		}
   545         }
   546 		else
   546         else
   547 		{
   547         {
   548 			if ( i >=  sizeof(szJoystickButton))
   548             if ( i >=  sizeof(szJoystickButton))
   549 			{
   549             {
   550 				SDL_SetError( "Joystick button name too large: %s", szJoystickButton );
   550                 SDL_SetError( "Joystick button name too large: %s", szJoystickButton );
   551 				return;
   551                 return;
   552 			}
   552             }
   553 			szJoystickButton[i] = *pchPos;
   553             szJoystickButton[i] = *pchPos;
   554 			i++;
   554             i++;
   555 		}
   555         }
   556 		pchPos++;
   556         pchPos++;
   557 	}
   557     }
   558 
   558 
   559 	SDL_PrivateGameControllerParseButton( szGameButton, szJoystickButton, pMapping );
   559     SDL_PrivateGameControllerParseButton( szGameButton, szJoystickButton, pMapping );
   560 
   560 
   561 }
   561 }
   562 
   562 
   563 /*
   563 /*
   564  * Make a new button mapping struct
   564  * Make a new button mapping struct
   565  */
   565  */
   566 void SDL_PrivateLoadButtonMapping( struct _SDL_ControllerMapping *pMapping, SDL_JoystickGUID guid, const char *pchName, const char *pchMapping )
   566 void SDL_PrivateLoadButtonMapping( struct _SDL_ControllerMapping *pMapping, SDL_JoystickGUID guid, const char *pchName, const char *pchMapping )
   567 {
   567 {
   568 	int j;
   568     int j;
   569 
   569 
   570 	pMapping->guid = guid;
   570     pMapping->guid = guid;
   571 	pMapping->name = pchName;
   571     pMapping->name = pchName;
   572 
   572 
   573 	// set all the button mappings to non defaults
   573     /* set all the button mappings to non defaults */
   574 	for ( j = 0; j < SDL_CONTROLLER_AXIS_MAX; j++ )
   574     for ( j = 0; j < SDL_CONTROLLER_AXIS_MAX; j++ )
   575 	{
   575     {
   576 		pMapping->axes[j] = -1;
   576         pMapping->axes[j] = -1;
   577 		pMapping->buttonasaxis[j] = -1;
   577         pMapping->buttonasaxis[j] = -1;
   578 	}
   578     }
   579 	for ( j = 0; j < SDL_CONTROLLER_BUTTON_MAX; j++ )
   579     for ( j = 0; j < SDL_CONTROLLER_BUTTON_MAX; j++ )
   580 	{
   580     {
   581 		pMapping->buttons[j] = -1;
   581         pMapping->buttons[j] = -1;
   582 		pMapping->axesasbutton[j] = -1;
   582         pMapping->axesasbutton[j] = -1;
   583 		pMapping->hatasbutton[j].hat = -1;
   583         pMapping->hatasbutton[j].hat = -1;
   584 	}
   584     }
   585 
   585 
   586 	for ( j = 0; j < k_nMaxReverseEntries; j++ )
   586     for ( j = 0; j < k_nMaxReverseEntries; j++ )
   587 	{
   587     {
   588 		pMapping->raxes[j] = SDL_CONTROLLER_AXIS_INVALID;
   588         pMapping->raxes[j] = SDL_CONTROLLER_AXIS_INVALID;
   589 		pMapping->rbuttonasaxis[j] = SDL_CONTROLLER_AXIS_INVALID;
   589         pMapping->rbuttonasaxis[j] = SDL_CONTROLLER_AXIS_INVALID;
   590 		pMapping->rbuttons[j] = SDL_CONTROLLER_BUTTON_INVALID;
   590         pMapping->rbuttons[j] = SDL_CONTROLLER_BUTTON_INVALID;
   591 		pMapping->raxesasbutton[j] = SDL_CONTROLLER_BUTTON_INVALID;
   591         pMapping->raxesasbutton[j] = SDL_CONTROLLER_BUTTON_INVALID;
   592 	}
   592     }
   593 
   593 
   594 	for (j = 0; j < k_nMaxHatEntries; j++)
   594     for (j = 0; j < k_nMaxHatEntries; j++)
   595 	{
   595     {
   596 		pMapping->rhatasbutton[j] = SDL_CONTROLLER_BUTTON_INVALID;
   596         pMapping->rhatasbutton[j] = SDL_CONTROLLER_BUTTON_INVALID;
   597 	}
   597     }
   598 
   598 
   599 	SDL_PrivateGameControllerParseControllerConfigString( pMapping, pchMapping );
   599     SDL_PrivateGameControllerParseControllerConfigString( pMapping, pchMapping );
   600 }
   600 }
   601 
   601 
   602 
   602 
   603 /*
   603 /*
   604  * grab the guid string from a mapping string
   604  * grab the guid string from a mapping string
   605  */
   605  */
   606 char *SDL_PrivateGetControllerGUIDFromMappingString( const char *pMapping )
   606 char *SDL_PrivateGetControllerGUIDFromMappingString( const char *pMapping )
   607 {
   607 {
   608 	const char *pFirstComma = SDL_strchr( pMapping, ',' );
   608     const char *pFirstComma = SDL_strchr( pMapping, ',' );
   609 	if ( pFirstComma )
   609     if ( pFirstComma )
   610 	{
   610     {
   611 		char *pchGUID = SDL_malloc( pFirstComma - pMapping + 1 );
   611         char *pchGUID = SDL_malloc( pFirstComma - pMapping + 1 );
   612 		if ( !pchGUID )
   612         if ( !pchGUID )
   613 		{
   613         {
   614 			SDL_OutOfMemory();
   614             SDL_OutOfMemory();
   615 			return NULL;
   615             return NULL;
   616 		}
   616         }
   617 		SDL_memcpy( pchGUID, pMapping, pFirstComma - pMapping );
   617         SDL_memcpy( pchGUID, pMapping, pFirstComma - pMapping );
   618 		pchGUID[ pFirstComma - pMapping ] = 0;
   618         pchGUID[ pFirstComma - pMapping ] = 0;
   619 		return pchGUID;
   619         return pchGUID;
   620 	}
   620     }
   621 	return NULL;
   621     return NULL;
   622 }
   622 }
   623 
   623 
   624 
   624 
   625 /*
   625 /*
   626  * grab the name string from a mapping string
   626  * grab the name string from a mapping string
   627  */
   627  */
   628 char *SDL_PrivateGetControllerNameFromMappingString( const char *pMapping )
   628 char *SDL_PrivateGetControllerNameFromMappingString( const char *pMapping )
   629 {
   629 {
   630 	const char *pFirstComma, *pSecondComma;
   630     const char *pFirstComma, *pSecondComma;
   631     char *pchName;
   631     char *pchName;
   632 
   632 
   633     pFirstComma = SDL_strchr( pMapping, ',' );
   633     pFirstComma = SDL_strchr( pMapping, ',' );
   634     if ( !pFirstComma )
   634     if ( !pFirstComma )
   635         return NULL;
   635         return NULL;
   636 
   636 
   637 	pSecondComma = SDL_strchr( pFirstComma + 1, ',' );
   637     pSecondComma = SDL_strchr( pFirstComma + 1, ',' );
   638     if ( !pSecondComma )
   638     if ( !pSecondComma )
   639         return NULL;
   639         return NULL;
   640 
   640 
   641     pchName = SDL_malloc( pSecondComma - pFirstComma );
   641     pchName = SDL_malloc( pSecondComma - pFirstComma );
   642     if ( !pchName )
   642     if ( !pchName )
   653 /*
   653 /*
   654  * grab the button mapping string from a mapping string
   654  * grab the button mapping string from a mapping string
   655  */
   655  */
   656 char *SDL_PrivateGetControllerMappingFromMappingString( const char *pMapping )
   656 char *SDL_PrivateGetControllerMappingFromMappingString( const char *pMapping )
   657 {
   657 {
   658 	const char *pFirstComma, *pSecondComma;
   658     const char *pFirstComma, *pSecondComma;
   659 
   659 
   660     pFirstComma = SDL_strchr( pMapping, ',' );
   660     pFirstComma = SDL_strchr( pMapping, ',' );
   661     if ( !pFirstComma )
   661     if ( !pFirstComma )
   662         return NULL;
   662         return NULL;
   663 
   663 
   664 	pSecondComma = SDL_strchr( pFirstComma + 1, ',' );
   664     pSecondComma = SDL_strchr( pFirstComma + 1, ',' );
   665     if ( !pSecondComma )
   665     if ( !pSecondComma )
   666         return NULL;
   666         return NULL;
   667 
   667 
   668     return SDL_strdup(pSecondComma + 1); /* mapping is everything after the 3rd comma */
   668     return SDL_strdup(pSecondComma + 1); /* mapping is everything after the 3rd comma */
   669 }
   669 }
   677         {
   677         {
   678             SDL_Event event;
   678             SDL_Event event;
   679             event.type = SDL_CONTROLLERDEVICEREMAPPED;
   679             event.type = SDL_CONTROLLERDEVICEREMAPPED;
   680             event.cdevice.which = gamecontrollerlist->joystick->instance_id;
   680             event.cdevice.which = gamecontrollerlist->joystick->instance_id;
   681             SDL_PushEvent(&event);
   681             SDL_PushEvent(&event);
   682             
   682 
   683             // Not really threadsafe.  Should this lock access within SDL_GameControllerEventWatcher?
   683             /* Not really threadsafe.  Should this lock access within SDL_GameControllerEventWatcher? */
   684             SDL_PrivateLoadButtonMapping(&gamecontrollerlist->mapping, pControllerMapping->guid, pControllerMapping->name, pControllerMapping->mapping);
   684             SDL_PrivateLoadButtonMapping(&gamecontrollerlist->mapping, pControllerMapping->guid, pControllerMapping->name, pControllerMapping->mapping);
   685         }
   685         }
   686         
   686 
   687         gamecontrollerlist = gamecontrollerlist->next;
   687         gamecontrollerlist = gamecontrollerlist->next;
   688     }
   688     }
   689 }
   689 }
   690 
   690 
   691 /*
   691 /*
   692  * Add or update an entry into the Mappings Database
   692  * Add or update an entry into the Mappings Database
   693  */
   693  */
   694 int
   694 int
   695 SDL_GameControllerAddMapping( const char *mappingString )
   695 SDL_GameControllerAddMapping( const char *mappingString )
   696 {
   696 {
   697 	char *pchGUID;
   697     char *pchGUID;
   698 	char *pchName;
   698     char *pchName;
   699 	char *pchMapping;
   699     char *pchMapping;
   700     SDL_JoystickGUID jGUID;
   700     SDL_JoystickGUID jGUID;
   701     ControllerMapping_t *pControllerMapping;
   701     ControllerMapping_t *pControllerMapping;
   702 #ifdef SDL_JOYSTICK_DINPUT
   702 #ifdef SDL_JOYSTICK_DINPUT
   703     SDL_bool is_xinput_mapping = SDL_FALSE;
   703     SDL_bool is_xinput_mapping = SDL_FALSE;
   704 #endif
   704 #endif
   713     }
   713     }
   714 #endif
   714 #endif
   715     jGUID = SDL_JoystickGetGUIDFromString(pchGUID);
   715     jGUID = SDL_JoystickGetGUIDFromString(pchGUID);
   716     SDL_free(pchGUID);
   716     SDL_free(pchGUID);
   717 
   717 
   718 	pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID);
   718     pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID);
   719 
   719 
   720 	pchName = SDL_PrivateGetControllerNameFromMappingString( mappingString );
   720     pchName = SDL_PrivateGetControllerNameFromMappingString( mappingString );
   721 	if (!pchName) return -1;
   721     if (!pchName) return -1;
   722 
   722 
   723 	pchMapping = SDL_PrivateGetControllerMappingFromMappingString( mappingString );
   723     pchMapping = SDL_PrivateGetControllerMappingFromMappingString( mappingString );
   724 	if (!pchMapping) {
   724     if (!pchMapping) {
   725 		SDL_free( pchName );
   725         SDL_free( pchName );
   726 		return -1;
   726         return -1;
   727 	}
   727     }
   728 
   728 
   729 	if (pControllerMapping) {
   729     if (pControllerMapping) {
   730 		// Update existing mapping
   730         /* Update existing mapping */
   731 		SDL_free( pControllerMapping->name );
   731         SDL_free( pControllerMapping->name );
   732 		pControllerMapping->name = pchName;
   732         pControllerMapping->name = pchName;
   733 		SDL_free( pControllerMapping->mapping );
   733         SDL_free( pControllerMapping->mapping );
   734 		pControllerMapping->mapping = pchMapping;
   734         pControllerMapping->mapping = pchMapping;
   735 		// refresh open controllers
   735         /* refresh open controllers */
   736 		SDL_PrivateGameControllerRefreshMapping( pControllerMapping );
   736         SDL_PrivateGameControllerRefreshMapping( pControllerMapping );
   737 		return 0;
   737         return 0;
   738 	} else {
   738     } else {
   739 		pControllerMapping = SDL_malloc( sizeof(*pControllerMapping) );
   739         pControllerMapping = SDL_malloc( sizeof(*pControllerMapping) );
   740 		if (!pControllerMapping) {
   740         if (!pControllerMapping) {
   741 			SDL_free( pchName );
   741             SDL_free( pchName );
   742 			SDL_free( pchMapping );
   742             SDL_free( pchMapping );
   743 			return SDL_OutOfMemory();
   743             return SDL_OutOfMemory();
   744 		}
   744         }
   745 #ifdef SDL_JOYSTICK_DINPUT
   745 #ifdef SDL_JOYSTICK_DINPUT
   746 		if ( is_xinput_mapping )
   746         if ( is_xinput_mapping )
   747 		{
   747         {
   748 			s_pXInputMapping = pControllerMapping;
   748             s_pXInputMapping = pControllerMapping;
   749 		}
   749         }
   750 #endif
   750 #endif
   751 		pControllerMapping->guid = jGUID;
   751         pControllerMapping->guid = jGUID;
   752 		pControllerMapping->name = pchName;
   752         pControllerMapping->name = pchName;
   753 		pControllerMapping->mapping = pchMapping;
   753         pControllerMapping->mapping = pchMapping;
   754 		pControllerMapping->next = s_pSupportedControllers;
   754         pControllerMapping->next = s_pSupportedControllers;
   755 		s_pSupportedControllers = pControllerMapping;
   755         s_pSupportedControllers = pControllerMapping;
   756 		return 1;
   756         return 1;
   757 	}
   757     }
   758 }
   758 }
   759 
   759 
   760 /*
   760 /*
   761  * Get the mapping string for this GUID
   761  * Get the mapping string for this GUID
   762  */
   762  */
   763 char *
   763 char *
   764 SDL_GameControllerMappingForGUID( SDL_JoystickGUID guid )
   764 SDL_GameControllerMappingForGUID( SDL_JoystickGUID guid )
   765 {
   765 {
   766 	char *pMappingString = NULL;
   766     char *pMappingString = NULL;
   767 	ControllerMapping_t *mapping = SDL_PrivateGetControllerMappingForGUID(&guid);
   767     ControllerMapping_t *mapping = SDL_PrivateGetControllerMappingForGUID(&guid);
   768 	if (mapping) {
   768     if (mapping) {
   769 		char pchGUID[33];
   769         char pchGUID[33];
   770         size_t needed;
   770         size_t needed;
   771 		SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID));
   771         SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID));
   772 		// allocate enough memory for GUID + ',' + name + ',' + mapping + \0
   772         /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
   773 		needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
   773         needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
   774 		pMappingString = SDL_malloc( needed );
   774         pMappingString = SDL_malloc( needed );
   775 		SDL_snprintf( pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping );
   775         SDL_snprintf( pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping );
   776 	}
   776     }
   777 	return pMappingString;
   777     return pMappingString;
   778 }
   778 }
   779 
   779 
   780 /*
   780 /*
   781  * Get the mapping string for this device
   781  * Get the mapping string for this device
   782  */
   782  */
   783 char *
   783 char *
   784 SDL_GameControllerMapping( SDL_GameController * gamecontroller )
   784 SDL_GameControllerMapping( SDL_GameController * gamecontroller )
   785 {
   785 {
   786 	return SDL_GameControllerMappingForGUID( gamecontroller->mapping.guid );
   786     return SDL_GameControllerMappingForGUID( gamecontroller->mapping.guid );
   787 }
   787 }
   788 
   788 
   789 static void
   789 static void
   790 SDL_GameControllerLoadHints()
   790 SDL_GameControllerLoadHints()
   791 {
   791 {
   817  * Initialize the game controller system, mostly load our DB of controller config mappings
   817  * Initialize the game controller system, mostly load our DB of controller config mappings
   818  */
   818  */
   819 int
   819 int
   820 SDL_GameControllerInit(void)
   820 SDL_GameControllerInit(void)
   821 {
   821 {
   822 	int i = 0;
   822     int i = 0;
   823 	const char *pMappingString = NULL;
   823     const char *pMappingString = NULL;
   824 	s_pSupportedControllers = NULL;
   824     s_pSupportedControllers = NULL;
   825 	pMappingString = s_ControllerMappings[i];
   825     pMappingString = s_ControllerMappings[i];
   826 	while ( pMappingString )
   826     while ( pMappingString )
   827 	{
   827     {
   828 		SDL_GameControllerAddMapping( pMappingString );
   828         SDL_GameControllerAddMapping( pMappingString );
   829 
   829 
   830 		i++;
   830         i++;
   831 		pMappingString = s_ControllerMappings[i];
   831         pMappingString = s_ControllerMappings[i];
   832 	}
   832     }
   833 
   833 
   834 	// load in any user supplied config
   834     /* load in any user supplied config */
   835     SDL_GameControllerLoadHints();
   835     SDL_GameControllerLoadHints();
   836 
   836 
   837 	/* watch for joy events and fire controller ones if needed */
   837     /* watch for joy events and fire controller ones if needed */
   838 	SDL_AddEventWatch( SDL_GameControllerEventWatcher, NULL );
   838     SDL_AddEventWatch( SDL_GameControllerEventWatcher, NULL );
   839 
   839 
   840 	return (0);
   840     return (0);
   841 }
   841 }
   842 
   842 
   843 
   843 
   844 /*
   844 /*
   845  * Get the implementation dependent name of a controller
   845  * Get the implementation dependent name of a controller
   846  */
   846  */
   847 const char *
   847 const char *
   848 SDL_GameControllerNameForIndex(int device_index)
   848 SDL_GameControllerNameForIndex(int device_index)
   849 {
   849 {
   850 	ControllerMapping_t *pSupportedController =  SDL_PrivateGetControllerMapping(device_index);
   850     ControllerMapping_t *pSupportedController =  SDL_PrivateGetControllerMapping(device_index);
   851 	if ( pSupportedController )
   851     if ( pSupportedController )
   852 	{
   852     {
   853 		return pSupportedController->name;
   853         return pSupportedController->name;
   854 	}
   854     }
   855     return NULL;
   855     return NULL;
   856 }
   856 }
   857 
   857 
   858 
   858 
   859 /*
   859 /*
   860  * Return 1 if the joystick at this device index is a supported controller
   860  * Return 1 if the joystick at this device index is a supported controller
   861  */
   861  */
   862 SDL_bool
   862 SDL_bool
   863 SDL_IsGameController(int device_index)
   863 SDL_IsGameController(int device_index)
   864 {
   864 {
   865 	ControllerMapping_t *pSupportedController =  SDL_PrivateGetControllerMapping(device_index);
   865     ControllerMapping_t *pSupportedController =  SDL_PrivateGetControllerMapping(device_index);
   866 	if ( pSupportedController )
   866     if ( pSupportedController )
   867 	{
   867     {
   868 		return SDL_TRUE;
   868         return SDL_TRUE;
   869 	}
   869     }
   870 
   870 
   871 	return SDL_FALSE;
   871     return SDL_FALSE;
   872 }
   872 }
   873 
   873 
   874 /*
   874 /*
   875  * Open a controller for use - the index passed as an argument refers to
   875  * Open a controller for use - the index passed as an argument refers to
   876  * the N'th controller on the system.  This index is the value which will
   876  * the N'th controller on the system.  This index is the value which will
   880  */
   880  */
   881 SDL_GameController *
   881 SDL_GameController *
   882 SDL_GameControllerOpen(int device_index)
   882 SDL_GameControllerOpen(int device_index)
   883 {
   883 {
   884     SDL_GameController *gamecontroller;
   884     SDL_GameController *gamecontroller;
   885 	SDL_GameController *gamecontrollerlist;
   885     SDL_GameController *gamecontrollerlist;
   886 	ControllerMapping_t *pSupportedController = NULL;
   886     ControllerMapping_t *pSupportedController = NULL;
   887 
   887 
   888     if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) {
   888     if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) {
   889         SDL_SetError("There are %d joysticks available", SDL_NumJoysticks());
   889         SDL_SetError("There are %d joysticks available", SDL_NumJoysticks());
   890         return (NULL);
   890         return (NULL);
   891     }
   891     }
   892 
   892 
   893 	gamecontrollerlist = SDL_gamecontrollers;
   893     gamecontrollerlist = SDL_gamecontrollers;
   894     // If the controller is already open, return it 
   894     /* If the controller is already open, return it */
   895 	while ( gamecontrollerlist )
   895     while ( gamecontrollerlist )
   896 	{
   896     {
   897 		if ( SDL_SYS_GetInstanceIdOfDeviceIndex(device_index) == gamecontrollerlist->joystick->instance_id ) {
   897         if ( SDL_SYS_GetInstanceIdOfDeviceIndex(device_index) == gamecontrollerlist->joystick->instance_id ) {
   898 				gamecontroller = gamecontrollerlist;
   898                 gamecontroller = gamecontrollerlist;
   899 				++gamecontroller->ref_count;
   899                 ++gamecontroller->ref_count;
   900 				return (gamecontroller);
   900                 return (gamecontroller);
   901 		}
   901         }
   902 		gamecontrollerlist = gamecontrollerlist->next;
   902         gamecontrollerlist = gamecontrollerlist->next;
   903     }
   903     }
   904 
   904 
   905 	// Find a controller mapping 
   905     /* Find a controller mapping */
   906 	pSupportedController =  SDL_PrivateGetControllerMapping(device_index);
   906     pSupportedController =  SDL_PrivateGetControllerMapping(device_index);
   907 	if ( !pSupportedController ) {
   907     if ( !pSupportedController ) {
   908 		SDL_SetError("Couldn't find mapping for device (%d)", device_index );
   908         SDL_SetError("Couldn't find mapping for device (%d)", device_index );
   909 		return (NULL);
   909         return (NULL);
   910 	}
   910     }
   911 
   911 
   912 	// Create and initialize the joystick 
   912     /* Create and initialize the joystick */
   913 	gamecontroller = (SDL_GameController *) SDL_malloc((sizeof *gamecontroller));
   913     gamecontroller = (SDL_GameController *) SDL_malloc((sizeof *gamecontroller));
   914 	if (gamecontroller == NULL) {
   914     if (gamecontroller == NULL) {
   915 		SDL_OutOfMemory();
   915         SDL_OutOfMemory();
   916 		return NULL;
   916         return NULL;
   917 	}
   917     }
   918 
   918 
   919     SDL_memset(gamecontroller, 0, (sizeof *gamecontroller));
   919     SDL_memset(gamecontroller, 0, (sizeof *gamecontroller));
   920     gamecontroller->joystick = SDL_JoystickOpen(device_index);
   920     gamecontroller->joystick = SDL_JoystickOpen(device_index);
   921 	if ( !gamecontroller->joystick ) {
   921     if ( !gamecontroller->joystick ) {
   922         SDL_free(gamecontroller);
   922         SDL_free(gamecontroller);
   923         return NULL;
   923         return NULL;
   924     }
   924     }
   925 
   925 
   926 	SDL_PrivateLoadButtonMapping( &gamecontroller->mapping, pSupportedController->guid, pSupportedController->name, pSupportedController->mapping );
   926     SDL_PrivateLoadButtonMapping( &gamecontroller->mapping, pSupportedController->guid, pSupportedController->name, pSupportedController->mapping );
   927 
   927 
   928     // Add joystick to list 
   928     /* Add joystick to list */
   929     ++gamecontroller->ref_count;
   929     ++gamecontroller->ref_count;
   930 	// Link the joystick in the list 
   930     /* Link the joystick in the list */
   931 	gamecontroller->next = SDL_gamecontrollers;
   931     gamecontroller->next = SDL_gamecontrollers;
   932 	SDL_gamecontrollers = gamecontroller;
   932     SDL_gamecontrollers = gamecontroller;
   933 
   933 
   934 	SDL_SYS_JoystickUpdate( gamecontroller->joystick );
   934     SDL_SYS_JoystickUpdate( gamecontroller->joystick );
   935 
   935 
   936     return (gamecontroller);
   936     return (gamecontroller);
   937 }
   937 }
   938 
   938 
   939 /*
   939 /*
   951  * Get the current state of an axis control on a controller
   951  * Get the current state of an axis control on a controller
   952  */
   952  */
   953 Sint16
   953 Sint16
   954 SDL_GameControllerGetAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis)
   954 SDL_GameControllerGetAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis)
   955 {
   955 {
   956 	if ( !gamecontroller )
   956     if ( !gamecontroller )
   957 		return 0;
   957         return 0;
   958 
   958 
   959 	if (gamecontroller->mapping.axes[axis] >= 0 )
   959     if (gamecontroller->mapping.axes[axis] >= 0 )
   960 	{
   960     {
   961 		return ( SDL_JoystickGetAxis( gamecontroller->joystick, gamecontroller->mapping.axes[axis]) );
   961         return ( SDL_JoystickGetAxis( gamecontroller->joystick, gamecontroller->mapping.axes[axis]) );
   962 	}
   962     }
   963 	else if (gamecontroller->mapping.buttonasaxis[axis] >= 0 )
   963     else if (gamecontroller->mapping.buttonasaxis[axis] >= 0 )
   964 	{
   964     {
   965 		Uint8 value;
   965         Uint8 value;
   966 		value = SDL_JoystickGetButton( gamecontroller->joystick, gamecontroller->mapping.buttonasaxis[axis] );
   966         value = SDL_JoystickGetButton( gamecontroller->joystick, gamecontroller->mapping.buttonasaxis[axis] );
   967 		if ( value > 0 )
   967         if ( value > 0 )
   968 			return 32767;
   968             return 32767;
   969 		return 0;
   969         return 0;
   970 	}
   970     }
   971 	return 0;
   971     return 0;
   972 }
   972 }
   973 
   973 
   974 
   974 
   975 /*
   975 /*
   976  * Get the current state of a button on a controller
   976  * Get the current state of a button on a controller
   977  */
   977  */
   978 Uint8
   978 Uint8
   979 SDL_GameControllerGetButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button)
   979 SDL_GameControllerGetButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button)
   980 {
   980 {
   981 	if ( !gamecontroller )
   981     if ( !gamecontroller )
   982 		return 0;
   982         return 0;
   983 
   983 
   984 	if ( gamecontroller->mapping.buttons[button] >= 0 )
   984     if ( gamecontroller->mapping.buttons[button] >= 0 )
   985 	{
   985     {
   986 		return ( SDL_JoystickGetButton( gamecontroller->joystick, gamecontroller->mapping.buttons[button] ) );
   986         return ( SDL_JoystickGetButton( gamecontroller->joystick, gamecontroller->mapping.buttons[button] ) );
   987 	}
   987     }
   988 	else if ( gamecontroller->mapping.axesasbutton[button] >= 0 )
   988     else if ( gamecontroller->mapping.axesasbutton[button] >= 0 )
   989 	{
   989     {
   990 		Sint16 value;
   990         Sint16 value;
   991 		value = SDL_JoystickGetAxis( gamecontroller->joystick, gamecontroller->mapping.axesasbutton[button] );
   991         value = SDL_JoystickGetAxis( gamecontroller->joystick, gamecontroller->mapping.axesasbutton[button] );
   992 		if ( ABS(value) > 32768/2 )
   992         if ( ABS(value) > 32768/2 )
   993 			return 1;
   993             return 1;
   994 		return 0;
   994         return 0;
   995 	}
   995     }
   996 	else if ( gamecontroller->mapping.hatasbutton[button].hat >= 0 )
   996     else if ( gamecontroller->mapping.hatasbutton[button].hat >= 0 )
   997 	{
   997     {
   998 		Uint8 value;
   998         Uint8 value;
   999 		value = SDL_JoystickGetHat( gamecontroller->joystick, gamecontroller->mapping.hatasbutton[button].hat );
   999         value = SDL_JoystickGetHat( gamecontroller->joystick, gamecontroller->mapping.hatasbutton[button].hat );
  1000 		
  1000 
  1001 		if ( value & gamecontroller->mapping.hatasbutton[button].mask )
  1001         if ( value & gamecontroller->mapping.hatasbutton[button].mask )
  1002 			return 1;
  1002             return 1;
  1003 		return 0;
  1003         return 0;
  1004 	}
  1004     }
  1005 
  1005 
  1006 	return 0;
  1006     return 0;
  1007 }
  1007 }
  1008 
  1008 
  1009 /*
  1009 /*
  1010  * Return if the joystick in question is currently attached to the system,
  1010  * Return if the joystick in question is currently attached to the system,
  1011  *  \return 0 if not plugged in, 1 if still present.
  1011  *  \return 0 if not plugged in, 1 if still present.
  1012  */
  1012  */
  1013 SDL_bool
  1013 SDL_bool
  1014 SDL_GameControllerGetAttached( SDL_GameController * gamecontroller )
  1014 SDL_GameControllerGetAttached( SDL_GameController * gamecontroller )
  1015 {
  1015 {
  1016 	if ( !gamecontroller )
  1016     if ( !gamecontroller )
  1017 		return SDL_FALSE;
  1017         return SDL_FALSE;
  1018 
  1018 
  1019 	return SDL_JoystickGetAttached(gamecontroller->joystick);
  1019     return SDL_JoystickGetAttached(gamecontroller->joystick);
  1020 }
  1020 }
  1021 
  1021 
  1022 
  1022 
  1023 /*
  1023 /*
  1024  * Get the number of multi-dimensional axis controls on a joystick
  1024  * Get the number of multi-dimensional axis controls on a joystick
  1025  */
  1025  */
  1026 const char *
  1026 const char *
  1027 SDL_GameControllerName(SDL_GameController * gamecontroller)
  1027 SDL_GameControllerName(SDL_GameController * gamecontroller)
  1028 {
  1028 {
  1029 	if ( !gamecontroller )
  1029     if ( !gamecontroller )
  1030 		return NULL;
  1030         return NULL;
  1031 
  1031 
  1032     return (gamecontroller->mapping.name);
  1032     return (gamecontroller->mapping.name);
  1033 }
  1033 }
  1034 
  1034 
  1035 
  1035 
  1036 /*
  1036 /*
  1037  * Get the joystick for this controller
  1037  * Get the joystick for this controller
  1038  */
  1038  */
  1039 SDL_Joystick *SDL_GameControllerGetJoystick(SDL_GameController * gamecontroller)
  1039 SDL_Joystick *SDL_GameControllerGetJoystick(SDL_GameController * gamecontroller)
  1040 {
  1040 {
  1041 	if ( !gamecontroller )
  1041     if ( !gamecontroller )
  1042 		return NULL;
  1042         return NULL;
  1043 
  1043 
  1044 	return gamecontroller->joystick;
  1044     return gamecontroller->joystick;
  1045 }
  1045 }
  1046 
  1046 
  1047 /**
  1047 /**
  1048  * Get the SDL joystick layer binding for this controller axis mapping
  1048  * Get the SDL joystick layer binding for this controller axis mapping
  1049  */
  1049  */
  1050 SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis)
  1050 SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis)
  1051 {
  1051 {
  1052 	SDL_GameControllerButtonBind bind;
  1052     SDL_GameControllerButtonBind bind;
  1053 	SDL_memset( &bind, 0x0, sizeof(bind) );
  1053     SDL_memset( &bind, 0x0, sizeof(bind) );
  1054 
  1054 
  1055 	if ( !gamecontroller || axis == SDL_CONTROLLER_AXIS_INVALID )
  1055     if ( !gamecontroller || axis == SDL_CONTROLLER_AXIS_INVALID )
  1056 		return bind;
  1056         return bind;
  1057 
  1057 
  1058 	if (gamecontroller->mapping.axes[axis] >= 0 )
  1058     if (gamecontroller->mapping.axes[axis] >= 0 )
  1059 	{
  1059     {
  1060 		bind.bindType = SDL_CONTROLLER_BINDTYPE_AXIS;
  1060         bind.bindType = SDL_CONTROLLER_BINDTYPE_AXIS;
  1061 		bind.value.button = gamecontroller->mapping.axes[axis];
  1061         bind.value.button = gamecontroller->mapping.axes[axis];
  1062 	}
  1062     }
  1063 	else if (gamecontroller->mapping.buttonasaxis[axis] >= 0 )
  1063     else if (gamecontroller->mapping.buttonasaxis[axis] >= 0 )
  1064 	{
  1064     {
  1065 		bind.bindType = SDL_CONTROLLER_BINDTYPE_BUTTON;
  1065         bind.bindType = SDL_CONTROLLER_BINDTYPE_BUTTON;
  1066 		bind.value.button = gamecontroller->mapping.buttonasaxis[axis];
  1066         bind.value.button = gamecontroller->mapping.buttonasaxis[axis];
  1067 	}
  1067     }
  1068 
  1068 
  1069 	return bind;
  1069     return bind;
  1070 }
  1070 }
  1071 
  1071 
  1072 
  1072 
  1073 /**
  1073 /**
  1074  * Get the SDL joystick layer binding for this controller button mapping
  1074  * Get the SDL joystick layer binding for this controller button mapping
  1075  */
  1075  */
  1076 SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button)
  1076 SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button)
  1077 {
  1077 {
  1078 	SDL_GameControllerButtonBind bind;
  1078     SDL_GameControllerButtonBind bind;
  1079 	SDL_memset( &bind, 0x0, sizeof(bind) );
  1079     SDL_memset( &bind, 0x0, sizeof(bind) );
  1080 
  1080 
  1081 	if ( !gamecontroller || button == SDL_CONTROLLER_BUTTON_INVALID )
  1081     if ( !gamecontroller || button == SDL_CONTROLLER_BUTTON_INVALID )
  1082 		return bind;
  1082         return bind;
  1083 
  1083 
  1084 	if ( gamecontroller->mapping.buttons[button] >= 0 )
  1084     if ( gamecontroller->mapping.buttons[button] >= 0 )
  1085 	{
  1085     {
  1086 		bind.bindType = SDL_CONTROLLER_BINDTYPE_BUTTON;
  1086         bind.bindType = SDL_CONTROLLER_BINDTYPE_BUTTON;
  1087 		bind.value.button = gamecontroller->mapping.buttons[button];
  1087         bind.value.button = gamecontroller->mapping.buttons[button];
  1088 	}
  1088     }
  1089 	else if ( gamecontroller->mapping.axesasbutton[button] >= 0 )
  1089     else if ( gamecontroller->mapping.axesasbutton[button] >= 0 )
  1090 	{
  1090     {
  1091 		bind.bindType = SDL_CONTROLLER_BINDTYPE_AXIS;
  1091         bind.bindType = SDL_CONTROLLER_BINDTYPE_AXIS;
  1092 		bind.value.axis = gamecontroller->mapping.axesasbutton[button];
  1092         bind.value.axis = gamecontroller->mapping.axesasbutton[button];
  1093 	}
  1093     }
  1094 	else if ( gamecontroller->mapping.hatasbutton[button].hat >= 0 )
  1094     else if ( gamecontroller->mapping.hatasbutton[button].hat >= 0 )
  1095 	{
  1095     {
  1096 		bind.bindType = SDL_CONTROLLER_BINDTYPE_HAT;
  1096         bind.bindType = SDL_CONTROLLER_BINDTYPE_HAT;
  1097 		bind.value.hat.hat = gamecontroller->mapping.hatasbutton[button].hat;
  1097         bind.value.hat.hat = gamecontroller->mapping.hatasbutton[button].hat;
  1098 		bind.value.hat.hat_mask = gamecontroller->mapping.hatasbutton[button].mask;
  1098         bind.value.hat.hat_mask = gamecontroller->mapping.hatasbutton[button].mask;
  1099 	}
  1099     }
  1100 
  1100 
  1101 	return bind;
  1101     return bind;
  1102 }
  1102 }
  1103 
  1103 
  1104 
  1104 
  1105 /*
  1105 /*
  1106  * Close a joystick previously opened with SDL_JoystickOpen()
  1106  * Close a joystick previously opened with SDL_JoystickOpen()
  1107  */
  1107  */
  1108 void
  1108 void
  1109 SDL_GameControllerClose(SDL_GameController * gamecontroller)
  1109 SDL_GameControllerClose(SDL_GameController * gamecontroller)
  1110 {
  1110 {
  1111 	SDL_GameController *gamecontrollerlist, *gamecontrollerlistprev;
  1111     SDL_GameController *gamecontrollerlist, *gamecontrollerlistprev;
  1112 
  1112 
  1113 	if ( !gamecontroller )
  1113     if ( !gamecontroller )
  1114 		return;
  1114         return;
  1115 
  1115 
  1116 	// First decrement ref count 
  1116     /* First decrement ref count */
  1117     if (--gamecontroller->ref_count > 0) {
  1117     if (--gamecontroller->ref_count > 0) {
  1118         return;
  1118         return;
  1119     }
  1119     }
  1120 
  1120 
  1121 	SDL_JoystickClose( gamecontroller->joystick );
  1121     SDL_JoystickClose( gamecontroller->joystick );
  1122 	
  1122 
  1123 	gamecontrollerlist = SDL_gamecontrollers;
  1123     gamecontrollerlist = SDL_gamecontrollers;
  1124 	gamecontrollerlistprev = NULL;
  1124     gamecontrollerlistprev = NULL;
  1125 	while ( gamecontrollerlist )
  1125     while ( gamecontrollerlist )
  1126 	{
  1126     {
  1127 		if (gamecontroller == gamecontrollerlist) 
  1127         if (gamecontroller == gamecontrollerlist)
  1128 		{
  1128         {
  1129 			if ( gamecontrollerlistprev )
  1129             if ( gamecontrollerlistprev )
  1130 			{
  1130             {
  1131 				// unlink this entry
  1131                 /* unlink this entry */
  1132 				gamecontrollerlistprev->next = gamecontrollerlist->next;
  1132                 gamecontrollerlistprev->next = gamecontrollerlist->next;
  1133 			}
  1133             }
  1134 			else
  1134             else
  1135 			{
  1135             {
  1136 				SDL_gamecontrollers = gamecontroller->next;
  1136                 SDL_gamecontrollers = gamecontroller->next;
  1137 			}
  1137             }
  1138 
  1138 
  1139 			break;
  1139             break;
  1140 		}
  1140         }
  1141 		gamecontrollerlistprev = gamecontrollerlist;
  1141         gamecontrollerlistprev = gamecontrollerlist;
  1142 		gamecontrollerlist = gamecontrollerlist->next;
  1142         gamecontrollerlist = gamecontrollerlist->next;
  1143 	}
  1143     }
  1144 
  1144 
  1145     SDL_free(gamecontroller);
  1145     SDL_free(gamecontroller);
  1146 }
  1146 }
  1147 
  1147 
  1148 
  1148 
  1150  * Quit the controller subsystem
  1150  * Quit the controller subsystem
  1151  */
  1151  */
  1152 void
  1152 void
  1153 SDL_GameControllerQuit(void)
  1153 SDL_GameControllerQuit(void)
  1154 {
  1154 {
  1155 	ControllerMapping_t *pControllerMap;
  1155     ControllerMapping_t *pControllerMap;
  1156 	while ( SDL_gamecontrollers )
  1156     while ( SDL_gamecontrollers )
  1157 	{
  1157     {
  1158 		SDL_gamecontrollers->ref_count = 1;
  1158         SDL_gamecontrollers->ref_count = 1;
  1159         SDL_GameControllerClose(SDL_gamecontrollers);
  1159         SDL_GameControllerClose(SDL_gamecontrollers);
  1160  	}
  1160     }
  1161 
  1161 
  1162 	while ( s_pSupportedControllers )
  1162     while ( s_pSupportedControllers )
  1163 	{
  1163     {
  1164 		pControllerMap = s_pSupportedControllers;
  1164         pControllerMap = s_pSupportedControllers;
  1165 		s_pSupportedControllers = s_pSupportedControllers->next;
  1165         s_pSupportedControllers = s_pSupportedControllers->next;
  1166 		SDL_free( pControllerMap->name );
  1166         SDL_free( pControllerMap->name );
  1167 		SDL_free( pControllerMap );
  1167         SDL_free( pControllerMap );
  1168 	}
  1168     }
  1169 
  1169 
  1170 	SDL_DelEventWatch( SDL_GameControllerEventWatcher, NULL );
  1170     SDL_DelEventWatch( SDL_GameControllerEventWatcher, NULL );
  1171 
  1171 
  1172 }
  1172 }
  1173 
  1173 
  1174 /*
  1174 /*
  1175  * Event filter to transform joystick events into appropriate game controller ones
  1175  * Event filter to transform joystick events into appropriate game controller ones
  1176  */
  1176  */
  1177 int
  1177 int
  1178 SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value)
  1178 SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value)
  1179 {
  1179 {
  1180 	int posted;
  1180     int posted;
  1181 
  1181 
  1182     /* translate the event, if desired */
  1182     /* translate the event, if desired */
  1183     posted = 0;
  1183     posted = 0;
  1184 #if !SDL_EVENTS_DISABLED
  1184 #if !SDL_EVENTS_DISABLED
  1185     if (SDL_GetEventState(SDL_CONTROLLERAXISMOTION) == SDL_ENABLE) {
  1185     if (SDL_GetEventState(SDL_CONTROLLERAXISMOTION) == SDL_ENABLE) {
  1186         SDL_Event event;
  1186         SDL_Event event;
  1187         event.type = SDL_CONTROLLERAXISMOTION;
  1187         event.type = SDL_CONTROLLERAXISMOTION;
  1188         event.caxis.which = gamecontroller->joystick->instance_id;
  1188         event.caxis.which = gamecontroller->joystick->instance_id;
  1189         event.caxis.axis = axis;
  1189         event.caxis.axis = axis;
  1190         event.caxis.value = value;
  1190         event.caxis.value = value;
  1191 		posted = SDL_PushEvent(&event) == 1;
  1191         posted = SDL_PushEvent(&event) == 1;
  1192     }
  1192     }
  1193 #endif /* !SDL_EVENTS_DISABLED */
  1193 #endif /* !SDL_EVENTS_DISABLED */
  1194     return (posted);
  1194     return (posted);
  1195 }
  1195 }
  1196 
  1196 
  1201 int
  1201 int
  1202 SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state)
  1202 SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state)
  1203 {
  1203 {
  1204     int posted;
  1204     int posted;
  1205 #if !SDL_EVENTS_DISABLED
  1205 #if !SDL_EVENTS_DISABLED
  1206 	SDL_Event event;
  1206     SDL_Event event;
  1207 
  1207 
  1208     if ( button == SDL_CONTROLLER_BUTTON_INVALID )
  1208     if ( button == SDL_CONTROLLER_BUTTON_INVALID )
  1209         return (0);
  1209         return (0);
  1210 
  1210 
  1211     switch (state) {
  1211     switch (state) {
  1226 #if !SDL_EVENTS_DISABLED
  1226 #if !SDL_EVENTS_DISABLED
  1227     if (SDL_GetEventState(event.type) == SDL_ENABLE) {
  1227     if (SDL_GetEventState(event.type) == SDL_ENABLE) {
  1228         event.cbutton.which = gamecontroller->joystick->instance_id;
  1228         event.cbutton.which = gamecontroller->joystick->instance_id;
  1229         event.cbutton.button = button;
  1229         event.cbutton.button = button;
  1230         event.cbutton.state = state;
  1230         event.cbutton.state = state;
  1231 		posted = SDL_PushEvent(&event) == 1;
  1231         posted = SDL_PushEvent(&event) == 1;
  1232     }
  1232     }
  1233 #endif /* !SDL_EVENTS_DISABLED */
  1233 #endif /* !SDL_EVENTS_DISABLED */
  1234     return (posted);
  1234     return (posted);
  1235 }
  1235 }
  1236 
  1236 
  1267     }
  1267     }
  1268     return (state);
  1268     return (state);
  1269 #endif /* SDL_EVENTS_DISABLED */
  1269 #endif /* SDL_EVENTS_DISABLED */
  1270 }
  1270 }
  1271 
  1271 
  1272 
       
  1273 /* vi: set ts=4 sw=4 expandtab: */
  1272 /* vi: set ts=4 sw=4 expandtab: */