1 /*
2 Hatari - dlgJoystick.c
3
4 This file is distributed under the GNU General Public License, version 2
5 or at your option any later version. Read the file gpl.txt for details.
6 */
7 const char DlgJoystick_fileid[] = "Hatari dlgJoystick.c : " __DATE__ " " __TIME__;
8
9 #include "main.h"
10 #include "configuration.h"
11 #include "dialog.h"
12 #include "sdlgui.h"
13 #include "joy.h"
14
15 #define DLGJOY_STJOYNAME 3
16 #define DLGJOY_PREVSTJOY 4
17 #define DLGJOY_NEXTSTJOY 5
18 #define DLGJOY_DEFINEKEYS 7
19 #define DLGJOY_DISABLED 8
20 #define DLGJOY_USEKEYS 9
21 #define DLGJOY_USEREALJOY 10
22 #define DLGJOY_SDLJOYNAME 12
23 #define DLGJOY_PREVSDLJOY 13
24 #define DLGJOY_NEXTSDLJOY 14
25 #define DLGJOY_AUTOFIRE 15
26 #define DLGJOY_EXIT 16
27
28 /* The joysticks dialog: */
29
30 static char sSdlStickName[20];
31
32 static SGOBJ joydlg[] =
33 {
34 { SGBOX, 0, 0, 0,0, 32,18, NULL },
35 { SGTEXT, 0, 0, 8,1, 15,1, "Joysticks setup" },
36
37 { SGBOX, 0, 0, 4,3, 24,1, NULL },
38 { SGTEXT, 0, 0, 5,3, 22,1, NULL },
39 { SGBUTTON, 0, 0, 1,3, 3,1, "\x04", SG_SHORTCUT_LEFT },
40 { SGBUTTON, 0, 0, 28,3, 3,1, "\x03", SG_SHORTCUT_RIGHT },
41
42 { SGBOX, 0, 0, 1,4, 30,11, NULL },
43 { SGBUTTON, 0, 0, 19,7, 11,1, "D_efine keys" },
44
45 { SGRADIOBUT, 0, 0, 2,5, 10,1, "_disabled" },
46 { SGRADIOBUT, 0, 0, 2,7, 14,1, "use _keyboard" },
47 { SGRADIOBUT, 0, 0, 2,9, 20,1, "use real _joystick:" },
48
49 { SGBOX, 0, 0, 5,11, 22,1, NULL },
50 { SGTEXT, 0, 0, 6,11, 20,1, sSdlStickName },
51 { SGBUTTON, 0, 0, 4,11, 1,1, "\x04", SG_SHORTCUT_UP },
52 { SGBUTTON, 0, 0, 27,11, 1,1, "\x03", SG_SHORTCUT_DOWN },
53
54 { SGCHECKBOX, 0, 0, 2,13, 17,1, "Enable _autofire" },
55
56 { SGBUTTON, SG_DEFAULT, 0, 6,16, 20,1, "Back to main menu" },
57 { -1, 0, 0, 0,0, 0,0, NULL }
58 };
59
60
61 /* The joystick keys setup dialog: */
62
63 static char sKeyInstruction[24];
64 static char sKeyName[24];
65
66 static SGOBJ joykeysdlg[] =
67 {
68 { SGBOX, 0, 0, 0,0, 28,5, NULL },
69 { SGTEXT, 0, 0, 2,1, 24,1, sKeyInstruction },
70 { SGTEXT, 0, 0, 2,3, 24,1, sKeyName },
71 { -1, 0, 0, 0,0, 0,0, NULL }
72 };
73
74
75 static char *sJoystickNames[JOYSTICK_COUNT] =
76 {
77 "ST Joystick 0",
78 "ST Joystick 1",
79 "STE Joypad A",
80 "STE Joypad B",
81 "Parallel port stick 1",
82 "Parallel port stick 2"
83 };
84
85
86 /*-----------------------------------------------------------------------*/
87 /**
88 * Show dialogs for defining joystick keys and wait for a key press.
89 */
DlgJoystick_DefineOneKey(char * pType,int * pKey)90 static void DlgJoystick_DefineOneKey(char *pType, int *pKey)
91 {
92 SDL_Event sdlEvent;
93
94 if (bQuitProgram)
95 return;
96
97 snprintf(sKeyInstruction, sizeof(sKeyInstruction), "Press key for '%s'...", pType);
98 snprintf(sKeyName, sizeof(sKeyName), "(was: '%s')", SDL_GetKeyName(*pKey));
99
100 SDLGui_DrawDialog(joykeysdlg);
101
102 /* drain buffered key events */
103 SDL_Delay(200);
104 while (SDL_PollEvent(&sdlEvent))
105 {
106 if (sdlEvent.type == SDL_KEYUP || sdlEvent.type == SDL_KEYDOWN)
107 break;
108 }
109
110 /* get the real key */
111 do
112 {
113 SDL_WaitEvent(&sdlEvent);
114 if (sdlEvent.type == SDL_KEYDOWN)
115 {
116 *pKey = sdlEvent.key.keysym.sym;
117 snprintf(sKeyName, sizeof(sKeyName), "(now: '%s')", SDL_GetKeyName(*pKey));
118 SDLGui_DrawDialog(joykeysdlg);
119 }
120 else if (sdlEvent.type == SDL_QUIT)
121 {
122 bQuitProgram = true;
123 return;
124 }
125 } while (sdlEvent.type != SDL_KEYUP);
126 }
127
128
129 /*-----------------------------------------------------------------------*/
130 /**
131 * Let the user define joystick keys.
132 */
DlgJoystick_DefineKeys(int nActJoy)133 static void DlgJoystick_DefineKeys(int nActJoy)
134 {
135
136 SDLGui_CenterDlg(joykeysdlg);
137 DlgJoystick_DefineOneKey("up", &ConfigureParams.Joysticks.Joy[nActJoy].nKeyCodeUp);
138 DlgJoystick_DefineOneKey("down", &ConfigureParams.Joysticks.Joy[nActJoy].nKeyCodeDown);
139 DlgJoystick_DefineOneKey("left", &ConfigureParams.Joysticks.Joy[nActJoy].nKeyCodeLeft);
140 DlgJoystick_DefineOneKey("right", &ConfigureParams.Joysticks.Joy[nActJoy].nKeyCodeRight);
141 DlgJoystick_DefineOneKey("fire", &ConfigureParams.Joysticks.Joy[nActJoy].nKeyCodeFire);
142 }
143
144
145 /*-----------------------------------------------------------------------*/
146 /**
147 * Adapt dialog using the values from the configration structure.
148 */
DlgJoystick_ReadValuesFromConf(int nActJoy,int nMaxId)149 static void DlgJoystick_ReadValuesFromConf(int nActJoy, int nMaxId)
150 {
151 int i;
152
153 /* Check if joystick ID is available */
154 if (SDL_NumJoysticks() == 0)
155 {
156 strcpy(sSdlStickName, "0: (none available)");
157 }
158 else if (ConfigureParams.Joysticks.Joy[nActJoy].nJoyId <= nMaxId)
159 {
160 snprintf(sSdlStickName, 20, "%i: %s", ConfigureParams.Joysticks.Joy[nActJoy].nJoyId,
161 Joy_GetName(ConfigureParams.Joysticks.Joy[nActJoy].nJoyId));
162 }
163 else
164 {
165 snprintf(sSdlStickName, 20, "0: %s", Joy_GetName(0));
166 /* Unavailable joystick ID -> disable it if necessary*/
167 if (ConfigureParams.Joysticks.Joy[nActJoy].nJoystickMode == JOYSTICK_REALSTICK)
168 ConfigureParams.Joysticks.Joy[nActJoy].nJoystickMode = JOYSTICK_DISABLED;
169 }
170
171 for (i = DLGJOY_DISABLED; i <= DLGJOY_USEREALJOY; i++)
172 joydlg[i].state &= ~SG_SELECTED;
173 switch (ConfigureParams.Joysticks.Joy[nActJoy].nJoystickMode)
174 {
175 case JOYSTICK_DISABLED:
176 joydlg[DLGJOY_DISABLED].state |= SG_SELECTED;
177 break;
178 case JOYSTICK_KEYBOARD:
179 joydlg[DLGJOY_USEKEYS].state |= SG_SELECTED;
180 break;
181 case JOYSTICK_REALSTICK:
182 joydlg[DLGJOY_USEREALJOY].state |= SG_SELECTED;
183 break;
184 }
185
186 if (ConfigureParams.Joysticks.Joy[nActJoy].bEnableAutoFire)
187 joydlg[DLGJOY_AUTOFIRE].state |= SG_SELECTED;
188 else
189 joydlg[DLGJOY_AUTOFIRE].state &= ~SG_SELECTED;
190 }
191
192
193 /*-----------------------------------------------------------------------*/
194 /**
195 * Read values from dialog and write them to the configuration structure.
196 */
DlgJoystick_WriteValuesToConf(int nActJoy)197 static void DlgJoystick_WriteValuesToConf(int nActJoy)
198 {
199 if (joydlg[DLGJOY_DISABLED].state & SG_SELECTED)
200 ConfigureParams.Joysticks.Joy[nActJoy].nJoystickMode = JOYSTICK_DISABLED;
201 else if (joydlg[DLGJOY_USEKEYS].state & SG_SELECTED)
202 ConfigureParams.Joysticks.Joy[nActJoy].nJoystickMode = JOYSTICK_KEYBOARD;
203 else
204 ConfigureParams.Joysticks.Joy[nActJoy].nJoystickMode = JOYSTICK_REALSTICK;
205
206 ConfigureParams.Joysticks.Joy[nActJoy].bEnableAutoFire = (joydlg[DLGJOY_AUTOFIRE].state & SG_SELECTED);
207 ConfigureParams.Joysticks.Joy[nActJoy].nJoyId = joydlg[DLGJOY_SDLJOYNAME].txt[0] - '0';
208 }
209
210
211 /*-----------------------------------------------------------------------*/
212 /**
213 * Show and process the joystick dialog.
214 */
Dialog_JoyDlg(void)215 void Dialog_JoyDlg(void)
216 {
217 int but;
218 static int nActJoy = 1;
219 int nMaxJoyId;
220
221 SDLGui_CenterDlg(joydlg);
222
223 joydlg[DLGJOY_STJOYNAME].txt = sJoystickNames[nActJoy];
224
225 nMaxJoyId = SDL_NumJoysticks() - 1;
226 if (nMaxJoyId > 5)
227 nMaxJoyId = 5;
228
229 /* Set up dialog from actual values: */
230 DlgJoystick_ReadValuesFromConf(nActJoy, nMaxJoyId);
231
232 do
233 {
234 but = SDLGui_DoDialog(joydlg, NULL);
235 switch (but)
236 {
237 case DLGJOY_PREVSDLJOY: // Select the previous SDL joystick
238 if (ConfigureParams.Joysticks.Joy[nActJoy].nJoyId > 0)
239 {
240 ConfigureParams.Joysticks.Joy[nActJoy].nJoyId -= 1;
241 snprintf(sSdlStickName, 20, "%i: %s", ConfigureParams.Joysticks.Joy[nActJoy].nJoyId,
242 Joy_GetName(ConfigureParams.Joysticks.Joy[nActJoy].nJoyId));
243 }
244 break;
245 case DLGJOY_NEXTSDLJOY: // Select the next SDL joystick
246 if (ConfigureParams.Joysticks.Joy[nActJoy].nJoyId < nMaxJoyId)
247 {
248 ConfigureParams.Joysticks.Joy[nActJoy].nJoyId += 1;
249 snprintf(sSdlStickName, 20, "%i: %s", ConfigureParams.Joysticks.Joy[nActJoy].nJoyId,
250 Joy_GetName(ConfigureParams.Joysticks.Joy[nActJoy].nJoyId));
251 }
252 break;
253 case DLGJOY_DEFINEKEYS: // Define new keys for keyboard emulation
254 DlgJoystick_DefineKeys(nActJoy);
255 break;
256 case DLGJOY_PREVSTJOY: // Switch to the previous ST joystick setup tab
257 if (nActJoy > 0)
258 {
259 DlgJoystick_WriteValuesToConf(nActJoy);
260 nActJoy -= 1;
261 DlgJoystick_ReadValuesFromConf(nActJoy, nMaxJoyId);
262 joydlg[DLGJOY_STJOYNAME].txt = sJoystickNames[nActJoy];
263 }
264 break;
265 case DLGJOY_NEXTSTJOY: // Switch to the next ST joystick setup tab
266 if (nActJoy < 5)
267 {
268 DlgJoystick_WriteValuesToConf(nActJoy);
269 nActJoy += 1;
270 DlgJoystick_ReadValuesFromConf(nActJoy, nMaxJoyId);
271 joydlg[DLGJOY_STJOYNAME].txt = sJoystickNames[nActJoy];
272 }
273 break;
274 }
275 }
276 while (but != DLGJOY_EXIT && but != SDLGUI_QUIT
277 && but != SDLGUI_ERROR && !bQuitProgram);
278
279 DlgJoystick_WriteValuesToConf(nActJoy);
280 }
281