1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * SDL Joystick code
5 *
6 * Copyright 1997 Bernd Schmidt
7 * Copyright 1998 Krister Walfridsson
8 * Copyright 2003-2005 Richard Drummond
9 */
10
11 #include "sysconfig.h"
12 #include "sysdeps.h"
13
14 #include "options.h"
15 #include "inputdevice.h"
16 #include <SDL.h>
17
18 #define MAX_MAPPINGS 256
19
20 /* external prototypes */
21 extern void setid (struct uae_input_device *uid, int i, int slot, int sub, int port, int evt);
22 extern void setid_af (struct uae_input_device *uid, int i, int slot, int sub, int port, int evt, int af);
23
24 /* internal members */
25 static unsigned int nr_joysticks;
26 static int initialized;
27
28 struct joyinfo {
29 SDL_Joystick *joy;
30 int axles;
31 int buttons;
32 };
33
34 static struct joyinfo joys[MAX_INPUT_DEVICES];
35
36
read_joy(int nr)37 static void read_joy (int nr)
38 {
39 unsigned int num, i, axes, axis;
40 SDL_Joystick *joy;
41
42 if (currprefs.input_selected_setting == 0) {
43 if (jsem_isjoy (0, &currprefs) != (int)nr && jsem_isjoy (1, &currprefs) != (int)nr)
44 return;
45 }
46 joy = joys[nr].joy;
47 axes = SDL_JoystickNumAxes (joy);
48 for (i = 0; i < axes; i++) {
49 axis = SDL_JoystickGetAxis (joy, i);
50 setjoystickstate (nr, i, axis, 32767);
51 }
52
53 num = SDL_JoystickNumButtons (joy);
54 for (i = 0; i < num; i++) {
55 int bs = SDL_JoystickGetButton (joy, i) ? 1 : 0;
56 setjoybuttonstate (nr, i, bs);
57 }
58 }
59
get_joystick_num(void)60 static int get_joystick_num (void)
61 {
62 return nr_joysticks;
63 }
64
get_joystick_widget_num(int joy)65 static int get_joystick_widget_num (int joy)
66 {
67 return joys[joy].axles + joys[joy].buttons;
68 }
69
get_joystick_widget_type(int joy,int num,TCHAR * name,uae_u32 * code)70 static int get_joystick_widget_type (int joy, int num, TCHAR *name, uae_u32 *code)
71 {
72 if (num >= joys[joy].axles && num < joys[joy].axles + joys[joy].buttons) {
73 if (name)
74 sprintf (name, "Button %d", num + 1 - joys[joy].axles);
75 return IDEV_WIDGET_BUTTON;
76 } else if (num < joys[joy].axles) {
77 if (name)
78 sprintf (name, "Axis %d", num + 1);
79 return IDEV_WIDGET_AXIS;
80 }
81 return IDEV_WIDGET_NONE;
82 }
83
get_joystick_widget_first(int joy,int type)84 static int get_joystick_widget_first (int joy, int type)
85 {
86 switch (type) {
87 case IDEV_WIDGET_BUTTON:
88 return joys[joy].axles;
89 case IDEV_WIDGET_AXIS:
90 return 0;
91 }
92 return -1;
93 }
94
get_joystick_friendlyname(int joy)95 static TCHAR *get_joystick_friendlyname (int joy)
96 {
97 return (TCHAR*)SDL_JoystickName (joy);
98 }
99
get_joystick_uniquename(int joy)100 static TCHAR *get_joystick_uniquename (int joy)
101 {
102 return (TCHAR*)SDL_JoystickName (joy);
103 }
104
read_joystick(void)105 static void read_joystick (void)
106 {
107 if (get_joystick_num ()) {
108 int i = 0;
109 SDL_JoystickUpdate ();
110 for ( ; i < get_joystick_num (); i++)
111 read_joy (i);
112 }
113 }
114
init_joystick(void)115 static int init_joystick (void)
116 {
117 int success = 0;
118
119 if (!initialized) {
120 if (SDL_InitSubSystem (SDL_INIT_JOYSTICK) == 0) {
121 int i = 0;
122
123 nr_joysticks = SDL_NumJoysticks ();
124 write_log ("Found %d joystick(s)\n", nr_joysticks);
125
126 if (nr_joysticks > MAX_INPUT_DEVICES)
127 nr_joysticks = MAX_INPUT_DEVICES;
128
129 for ( ; i < get_joystick_num (); i++) {
130 joys[i].joy = SDL_JoystickOpen (i);
131 joys[i].axles = SDL_JoystickNumAxes (joys[i].joy);
132 joys[i].buttons = SDL_JoystickNumButtons (joys[i].joy);
133 }
134 success = initialized = 1;
135 } else
136 write_log ("Failed to initialize joysticks\n");
137 }
138
139 return success;
140 }
141
close_joystick(void)142 static void close_joystick (void)
143 {
144 unsigned int i;
145 for (i = 0; i < nr_joysticks; i++) {
146 SDL_JoystickClose (joys[i].joy);
147 joys[i].joy = 0;
148 }
149 nr_joysticks = 0;
150
151 if (initialized) {
152 SDL_QuitSubSystem (SDL_INIT_JOYSTICK);
153 initialized = 0;
154 }
155 }
156
acquire_joystick(int num,int flags)157 static int acquire_joystick (int num, int flags)
158 {
159 return num < get_joystick_num ();
160 }
161
unacquire_joystick(int num)162 static void unacquire_joystick (int num)
163 {
164 }
165
get_joystick_flags(int num)166 static int get_joystick_flags (int num)
167 {
168 return 0;
169 }
170
171 struct inputdevice_functions inputdevicefunc_joystick = {
172 init_joystick,
173 close_joystick,
174 acquire_joystick,
175 unacquire_joystick,
176 read_joystick,
177 get_joystick_num,
178 get_joystick_friendlyname,
179 get_joystick_uniquename,
180 get_joystick_widget_num,
181 get_joystick_widget_type,
182 get_joystick_widget_first,
183 get_joystick_flags
184 };
185
186 /*
187 * Set default inputdevice config for SDL joysticks
188 */
input_get_default_joystick(struct uae_input_device * uid,int num,int port,int af,int mode,bool gp)189 int input_get_default_joystick (struct uae_input_device *uid, int num, int port, int af, int mode, bool gp)
190 {
191 int h,v;
192 // unsigned int j;
193 // struct didata *did;
194 SDL_Joystick *joy;
195 joy = joys[num].joy;
196
197 if (num >= get_joystick_num ())
198 return 0;
199
200 if (mode == JSEM_MODE_MOUSE_CDTV) {
201 h = INPUTEVENT_MOUSE_CDTV_HORIZ;
202 v = INPUTEVENT_MOUSE_CDTV_VERT;
203 } else if (port >= 2) {
204 h = port == 3 ? INPUTEVENT_PAR_JOY2_HORIZ : INPUTEVENT_PAR_JOY1_HORIZ;
205 v = port == 3 ? INPUTEVENT_PAR_JOY2_VERT : INPUTEVENT_PAR_JOY1_VERT;
206 } else {
207 h = port ? INPUTEVENT_JOY2_HORIZ : INPUTEVENT_JOY1_HORIZ;;
208 v = port ? INPUTEVENT_JOY2_VERT : INPUTEVENT_JOY1_VERT;
209 }
210 setid (uid, num, ID_AXIS_OFFSET + 0, 0, port, h);
211 setid (uid, num, ID_AXIS_OFFSET + 1, 0, port, v);
212
213 if (port >= 2) {
214 setid_af (uid, num, ID_BUTTON_OFFSET + 0, 0, port, port == 3 ? INPUTEVENT_PAR_JOY2_FIRE_BUTTON : INPUTEVENT_PAR_JOY1_FIRE_BUTTON, af);
215 } else {
216 setid_af (uid, num, ID_BUTTON_OFFSET + 0, 0, port, port ? INPUTEVENT_JOY2_FIRE_BUTTON : INPUTEVENT_JOY1_FIRE_BUTTON, af);
217 if (SDL_JoystickNumButtons(joy) > 0)
218 setid (uid, num, ID_BUTTON_OFFSET + 1, 0, port, port ? INPUTEVENT_JOY2_2ND_BUTTON : INPUTEVENT_JOY1_2ND_BUTTON);
219 if (SDL_JoystickNumButtons(joy) > 1)
220 setid (uid, num, ID_BUTTON_OFFSET + 2, 0, port, port ? INPUTEVENT_JOY2_3RD_BUTTON : INPUTEVENT_JOY1_3RD_BUTTON);
221 }
222
223 #if 0
224 for (j = 2; j < MAX_MAPPINGS - 1; j++) {
225 int am = did->axismappings[j];
226 if (am == DIJOFS_POV(0) || am == DIJOFS_POV(1) || am == DIJOFS_POV(2) || am == DIJOFS_POV(3)) {
227 setid (uid, num, ID_AXIS_OFFSET + j + 0, 0, port, h);
228 setid (uid, num, ID_AXIS_OFFSET + j + 1, 0, port, v);
229 j++;
230 }
231 }
232 #endif
233
234 if (mode == JSEM_MODE_JOYSTICK_CD32) {
235 setid_af (uid, num, ID_BUTTON_OFFSET + 0, 0, port, port ? INPUTEVENT_JOY2_CD32_RED : INPUTEVENT_JOY1_CD32_RED, af);
236 setid_af (uid, num, ID_BUTTON_OFFSET + 0, 1, port, port ? INPUTEVENT_JOY2_FIRE_BUTTON : INPUTEVENT_JOY1_FIRE_BUTTON, af);
237 if (SDL_JoystickNumButtons(joy) > 0) {
238 setid (uid, num, ID_BUTTON_OFFSET + 1, 0, port, port ? INPUTEVENT_JOY2_CD32_BLUE : INPUTEVENT_JOY1_CD32_BLUE);
239 setid (uid, num, ID_BUTTON_OFFSET + 1, 1, port, port ? INPUTEVENT_JOY2_2ND_BUTTON : INPUTEVENT_JOY1_2ND_BUTTON);
240 }
241 if (SDL_JoystickNumButtons(joy) > 1)
242 setid (uid, num, ID_BUTTON_OFFSET + 2, 0, port, port ? INPUTEVENT_JOY2_CD32_GREEN : INPUTEVENT_JOY1_CD32_GREEN);
243 if (SDL_JoystickNumButtons(joy) > 2)
244 setid (uid, num, ID_BUTTON_OFFSET + 3, 0, port, port ? INPUTEVENT_JOY2_CD32_YELLOW : INPUTEVENT_JOY1_CD32_YELLOW);
245 if (SDL_JoystickNumButtons(joy) > 3)
246 setid (uid, num, ID_BUTTON_OFFSET + 4, 0, port, port ? INPUTEVENT_JOY2_CD32_RWD : INPUTEVENT_JOY1_CD32_RWD);
247 if (SDL_JoystickNumButtons(joy) > 4)
248 setid (uid, num, ID_BUTTON_OFFSET + 5, 0, port, port ? INPUTEVENT_JOY2_CD32_FFW : INPUTEVENT_JOY1_CD32_FFW);
249 if (SDL_JoystickNumButtons(joy) > 5)
250 setid (uid, num, ID_BUTTON_OFFSET + 6, 0, port, port ? INPUTEVENT_JOY2_CD32_PLAY : INPUTEVENT_JOY1_CD32_PLAY);
251 }
252 if (num == 0)
253 return 1;
254 return 0;
255 }
256