1 /*
2  * menu_joyport.c - Joyport menu for SDL UI.
3  *
4  * Written by
5  *  Marco van den Heuvel <blackystardust68@yahoo.com>
6  *
7  * This file is part of VICE, the Versatile Commodore Emulator.
8  * See README for copyright notice.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23  *  02111-1307  USA.
24  *
25  */
26 
27 #include "vice.h"
28 
29 #include <stdio.h>
30 
31 #include "types.h"
32 
33 #include "menu_common.h"
34 #include "joyport.h"
35 #include "uimenu.h"
36 #include "lib.h"
37 
38 #include "menu_joyport.h"
39 
40 UI_MENU_DEFINE_RADIO(JoyPort1Device)
41 UI_MENU_DEFINE_RADIO(JoyPort2Device)
42 UI_MENU_DEFINE_RADIO(JoyPort3Device)
43 UI_MENU_DEFINE_RADIO(JoyPort4Device)
44 UI_MENU_DEFINE_RADIO(JoyPort5Device)
45 
46 static ui_menu_entry_t joyport1_dyn_menu[JOYPORT_MAX_DEVICES + 1];
47 static ui_menu_entry_t joyport2_dyn_menu[JOYPORT_MAX_DEVICES + 1];
48 static ui_menu_entry_t joyport3_dyn_menu[JOYPORT_MAX_DEVICES + 1];
49 static ui_menu_entry_t joyport4_dyn_menu[JOYPORT_MAX_DEVICES + 1];
50 static ui_menu_entry_t joyport5_dyn_menu[JOYPORT_MAX_DEVICES + 1];
51 
52 static int joyport1_dyn_menu_init = 0;
53 static int joyport2_dyn_menu_init = 0;
54 static int joyport3_dyn_menu_init = 0;
55 static int joyport4_dyn_menu_init = 0;
56 static int joyport5_dyn_menu_init = 0;
57 
sdl_menu_joyport1_free(void)58 static void sdl_menu_joyport1_free(void)
59 {
60     int i;
61 
62     for (i = 0; joyport1_dyn_menu[i].string != NULL; i++) {
63         lib_free(joyport1_dyn_menu[i].string);
64     }
65 }
66 
sdl_menu_joyport2_free(void)67 static void sdl_menu_joyport2_free(void)
68 {
69     int i;
70 
71     for (i = 0; joyport2_dyn_menu[i].string != NULL; i++) {
72         lib_free(joyport2_dyn_menu[i].string);
73     }
74 }
75 
sdl_menu_joyport3_free(void)76 static void sdl_menu_joyport3_free(void)
77 {
78     int i;
79 
80     for (i = 0; joyport3_dyn_menu[i].string != NULL; i++) {
81         lib_free(joyport3_dyn_menu[i].string);
82     }
83 }
84 
sdl_menu_joyport4_free(void)85 static void sdl_menu_joyport4_free(void)
86 {
87     int i;
88 
89     for (i = 0; joyport4_dyn_menu[i].string != NULL; i++) {
90         lib_free(joyport4_dyn_menu[i].string);
91     }
92 }
93 
sdl_menu_joyport5_free(void)94 static void sdl_menu_joyport5_free(void)
95 {
96     int i;
97 
98     for (i = 0; joyport5_dyn_menu[i].string != NULL; i++) {
99         lib_free(joyport5_dyn_menu[i].string);
100     }
101 }
102 
UI_MENU_CALLBACK(JoyPort1Device_dynmenu_callback)103 static UI_MENU_CALLBACK(JoyPort1Device_dynmenu_callback)
104 {
105     joyport_desc_t *devices = joyport_get_valid_devices(JOYPORT_1);
106     int i;
107 
108     /* rebuild menu if it already exists. */
109     if (joyport1_dyn_menu_init != 0) {
110         sdl_menu_joyport1_free();
111     } else {
112         joyport1_dyn_menu_init = 1;
113     }
114 
115     for (i = 0; devices[i].name; ++i) {
116         joyport1_dyn_menu[i].string = (char *)lib_stralloc(devices[i].name);
117         joyport1_dyn_menu[i].type = MENU_ENTRY_RESOURCE_RADIO;
118         joyport1_dyn_menu[i].callback = radio_JoyPort1Device_callback;
119         joyport1_dyn_menu[i].data = (ui_callback_data_t)int_to_void_ptr(devices[i].id);
120     }
121 
122     joyport1_dyn_menu[i].string = NULL;
123     joyport1_dyn_menu[i].type = 0;
124     joyport1_dyn_menu[i].callback = NULL;
125     joyport1_dyn_menu[i].data = NULL;
126 
127     lib_free(devices);
128 
129     return MENU_SUBMENU_STRING;
130 }
131 
UI_MENU_CALLBACK(JoyPort2Device_dynmenu_callback)132 static UI_MENU_CALLBACK(JoyPort2Device_dynmenu_callback)
133 {
134     joyport_desc_t *devices = joyport_get_valid_devices(JOYPORT_2);
135     int i;
136 
137     /* rebuild menu if it already exists. */
138     if (joyport2_dyn_menu_init != 0) {
139         sdl_menu_joyport2_free();
140     } else {
141         joyport2_dyn_menu_init = 1;
142     }
143 
144     for (i = 0; devices[i].name; ++i) {
145         joyport2_dyn_menu[i].string = (char *)lib_stralloc(devices[i].name);
146         joyport2_dyn_menu[i].type = MENU_ENTRY_RESOURCE_RADIO;
147         joyport2_dyn_menu[i].callback = radio_JoyPort2Device_callback;
148         joyport2_dyn_menu[i].data = (ui_callback_data_t)int_to_void_ptr(devices[i].id);
149     }
150 
151     joyport2_dyn_menu[i].string = NULL;
152     joyport2_dyn_menu[i].type = 0;
153     joyport2_dyn_menu[i].callback = NULL;
154     joyport2_dyn_menu[i].data = NULL;
155 
156     lib_free(devices);
157 
158     return MENU_SUBMENU_STRING;
159 }
160 
UI_MENU_CALLBACK(JoyPort3Device_dynmenu_callback)161 static UI_MENU_CALLBACK(JoyPort3Device_dynmenu_callback)
162 {
163     joyport_desc_t *devices = joyport_get_valid_devices(JOYPORT_3);
164     int i;
165 
166     /* rebuild menu if it already exists. */
167     if (joyport3_dyn_menu_init != 0) {
168         sdl_menu_joyport3_free();
169     } else {
170         joyport3_dyn_menu_init = 1;
171     }
172 
173     for (i = 0; devices[i].name; ++i) {
174         joyport3_dyn_menu[i].string = (char *)lib_stralloc(devices[i].name);
175         joyport3_dyn_menu[i].type = MENU_ENTRY_RESOURCE_RADIO;
176         joyport3_dyn_menu[i].callback = radio_JoyPort3Device_callback;
177         joyport3_dyn_menu[i].data = (ui_callback_data_t)int_to_void_ptr(devices[i].id);
178     }
179 
180     joyport3_dyn_menu[i].string = NULL;
181     joyport3_dyn_menu[i].type = 0;
182     joyport3_dyn_menu[i].callback = NULL;
183     joyport3_dyn_menu[i].data = NULL;
184 
185     lib_free(devices);
186 
187     return MENU_SUBMENU_STRING;
188 }
189 
UI_MENU_CALLBACK(JoyPort4Device_dynmenu_callback)190 static UI_MENU_CALLBACK(JoyPort4Device_dynmenu_callback)
191 {
192     joyport_desc_t *devices = joyport_get_valid_devices(JOYPORT_4);
193     int i;
194 
195     /* rebuild menu if it already exists. */
196     if (joyport4_dyn_menu_init != 0) {
197         sdl_menu_joyport4_free();
198     } else {
199         joyport4_dyn_menu_init = 1;
200     }
201 
202     for (i = 0; devices[i].name; ++i) {
203         joyport4_dyn_menu[i].string = (char *)lib_stralloc(devices[i].name);
204         joyport4_dyn_menu[i].type = MENU_ENTRY_RESOURCE_RADIO;
205         joyport4_dyn_menu[i].callback = radio_JoyPort4Device_callback;
206         joyport4_dyn_menu[i].data = (ui_callback_data_t)int_to_void_ptr(devices[i].id);
207     }
208 
209     joyport4_dyn_menu[i].string = NULL;
210     joyport4_dyn_menu[i].type = 0;
211     joyport4_dyn_menu[i].callback = NULL;
212     joyport4_dyn_menu[i].data = NULL;
213 
214     lib_free(devices);
215 
216     return MENU_SUBMENU_STRING;
217 }
218 
219 
UI_MENU_CALLBACK(JoyPort5Device_dynmenu_callback)220 static UI_MENU_CALLBACK(JoyPort5Device_dynmenu_callback)
221 {
222     joyport_desc_t *devices = joyport_get_valid_devices(JOYPORT_5);
223     int i;
224 
225     /* rebuild menu if it already exists. */
226     if (joyport5_dyn_menu_init != 0) {
227         sdl_menu_joyport5_free();
228     } else {
229         joyport5_dyn_menu_init = 1;
230     }
231 
232     for (i = 0; devices[i].name; ++i) {
233         joyport5_dyn_menu[i].string = (char *)lib_stralloc(devices[i].name);
234         joyport5_dyn_menu[i].type = MENU_ENTRY_RESOURCE_RADIO;
235         joyport5_dyn_menu[i].callback = radio_JoyPort5Device_callback;
236         joyport5_dyn_menu[i].data = (ui_callback_data_t)int_to_void_ptr(devices[i].id);
237     }
238 
239     joyport5_dyn_menu[i].string = NULL;
240     joyport5_dyn_menu[i].type = 0;
241     joyport5_dyn_menu[i].callback = NULL;
242     joyport5_dyn_menu[i].data = NULL;
243 
244     lib_free(devices);
245 
246     return MENU_SUBMENU_STRING;
247 }
248 
249 ui_menu_entry_t joyport_menu[JOYPORT_MAX_PORTS + 2];
250 
UI_MENU_DEFINE_TOGGLE(BBRTCSave)251 UI_MENU_DEFINE_TOGGLE(BBRTCSave)
252 
253 void uijoyport_menu_create(int port1, int port2, int port3, int port4, int port5)
254 {
255     int j = 0;
256 
257     joyport_menu[j].string = "Save BBRTC data when changed";
258     joyport_menu[j].type = MENU_ENTRY_RESOURCE_TOGGLE;
259     joyport_menu[j].callback = toggle_BBRTCSave_callback;
260     joyport_menu[j].data = NULL;
261     ++j;
262 
263     if (port1) {
264         joyport_menu[j].string = joyport_get_port_name(JOYPORT_1);
265         joyport_menu[j].type = MENU_ENTRY_DYNAMIC_SUBMENU;
266         joyport_menu[j].callback = JoyPort1Device_dynmenu_callback;
267         joyport_menu[j].data = (ui_callback_data_t)joyport1_dyn_menu;
268         ++j;
269     }
270 
271     if (port2) {
272         joyport_menu[j].string = joyport_get_port_name(JOYPORT_2);
273         joyport_menu[j].type = MENU_ENTRY_DYNAMIC_SUBMENU;
274         joyport_menu[j].callback = JoyPort2Device_dynmenu_callback;
275         joyport_menu[j].data = (ui_callback_data_t)joyport2_dyn_menu;
276         ++j;
277     }
278 
279     if (port3) {
280         joyport_menu[j].string = joyport_get_port_name(JOYPORT_3);
281         joyport_menu[j].type = MENU_ENTRY_DYNAMIC_SUBMENU;
282         joyport_menu[j].callback = JoyPort3Device_dynmenu_callback;
283         joyport_menu[j].data = (ui_callback_data_t)joyport3_dyn_menu;
284         ++j;
285     }
286 
287     if (port4) {
288         joyport_menu[j].string = joyport_get_port_name(JOYPORT_4);
289         joyport_menu[j].type = MENU_ENTRY_DYNAMIC_SUBMENU;
290         joyport_menu[j].callback = JoyPort4Device_dynmenu_callback;
291         joyport_menu[j].data = (ui_callback_data_t)joyport4_dyn_menu;
292         ++j;
293     }
294 
295     if (port5) {
296         joyport_menu[j].string = joyport_get_port_name(JOYPORT_5);
297         joyport_menu[j].type = MENU_ENTRY_DYNAMIC_SUBMENU;
298         joyport_menu[j].callback = JoyPort5Device_dynmenu_callback;
299         joyport_menu[j].data = (ui_callback_data_t)joyport5_dyn_menu;
300         ++j;
301     }
302     joyport_menu[j].string = NULL;
303     joyport_menu[j].type = MENU_ENTRY_TEXT;
304     joyport_menu[j].callback = NULL;
305     joyport_menu[j].data = NULL;
306 }
307 
308 
309 /** \brief  Clean up memory used by the dynamically created joyport menus
310  */
uijoyport_menu_shutdown(void)311 void uijoyport_menu_shutdown(void)
312 {
313     if (joyport1_dyn_menu_init) {
314         sdl_menu_joyport1_free();
315     }
316     if (joyport2_dyn_menu_init) {
317         sdl_menu_joyport2_free();
318     }
319     if (joyport3_dyn_menu_init) {
320         sdl_menu_joyport3_free();
321     }
322     if (joyport4_dyn_menu_init) {
323         sdl_menu_joyport4_free();
324     }
325     if (joyport5_dyn_menu_init) {
326         sdl_menu_joyport5_free();
327     }
328 }
329 
330