1 #include <stdlib.h>
2 #include <string.h>
3 #include <unistd.h>
4 
5 #include "menu.h"
6 #include "sar.h"
7 #include "sarmenuop.h"
8 
9 void SARMenuSwitchToMenu(sar_core_struct *core_ptr, const char *name);
10 sar_menu_list_struct *SARMenuGetList(
11 	sar_menu_struct *m, int skip, int *list_num
12 );
13 sar_menu_spin_struct *SARMenuGetSpin(
14 	sar_menu_struct *m, int skip, int *spin_num
15 );
16 sar_menu_list_item_struct *SARMenuListGetSelectedItem(
17 	sar_menu_struct *m, int id
18 );
19 char *SARMenuGetCurrentMenuName(sar_core_struct *core_ptr);
20 
21 
22 #define MAX(a,b)        (((a) > (b)) ? (a) : (b))
23 #define MIN(a,b)        (((a) < (b)) ? (a) : (b))
24 #define CLIP(a,l,h)     (MIN(MAX((a),(l)),(h)))
25 #define STRDUP(s)       (((s) != NULL) ? strdup(s) : NULL)
26 
27 
28 /*
29  *	Switches to the specified menu.
30  *
31  *	If no menu is specified (name=NULL) then simulation will
32  *	begin.
33  */
SARMenuSwitchToMenu(sar_core_struct * core_ptr,const char * name)34 void SARMenuSwitchToMenu(sar_core_struct *core_ptr, const char *name)
35 {
36 	int new_menu_num, old_menu_num;
37 	gw_display_struct *display;
38 	const sar_option_struct *opt;
39 
40 	if(core_ptr == NULL)
41 	    return;
42 
43 	display = core_ptr->display;
44 	opt = &core_ptr->option;
45 
46 	/* Record previous menu number */
47 	old_menu_num = core_ptr->cur_menu;
48 
49 	/* No specified menu to switch to? */
50 	if(name == NULL)
51 	{
52 	    /* This implies we are going out of the menu system and
53 	     * entering simulation
54 	     */
55 	    sar_menu_struct *old_menu = SARIsMenuAllocated(core_ptr, old_menu_num) ?
56 		core_ptr->menu[old_menu_num] : NULL;
57 
58 	    /* Unload image on old menu */
59 /*	    if(opt->prioritize_memory && (old_menu != NULL)) */
60 	    if(old_menu != NULL)
61 		SARMenuUnloadBackgroundImage(old_menu);
62 
63 	    /* Unselect current menu on core structure, indicating that
64 	     * no menu is selected and that we are not in the menus
65 	     */
66 	    core_ptr->cur_menu = -1;
67 
68 	    /* Skip redrawing, since redrawing would be done rather
69 	     * frequently during the simulation
70 	     */
71 /*	    GWPostRedraw(display); */
72 
73 	    return;
74 	}
75 
76 	/* Get the number of the menu that we want to switch to */
77 	new_menu_num = SARMatchMenuByName(core_ptr, name);
78 	/* Got match and matched menu number is different from the one
79 	 * currently selected?
80 	 */
81 	if((new_menu_num > -1) && (new_menu_num != core_ptr->cur_menu))
82 	{
83 	    sar_menu_struct *old_menu = SARIsMenuAllocated(core_ptr, old_menu_num) ?
84 		core_ptr->menu[old_menu_num] : NULL;
85 	    sar_menu_struct *new_menu = SARIsMenuAllocated(core_ptr, new_menu_num) ?
86 		core_ptr->menu[new_menu_num] : NULL;
87 	    const char	*old_bg_image_path = (old_menu != NULL) ?
88 		old_menu->bg_image_path : NULL,
89 			*new_bg_image_path = (new_menu != NULL) ?
90 		new_menu->bg_image_path : NULL;
91 
92 	    GWSetInputBusy(display);
93 
94 	    /* Reset values on the previous menu */
95             /*
96 	    if(old_menu != NULL)
97 	    {
98 
99 
100 
101 
102 
103 	    }
104             */
105 
106 	    /* Check if background images are the same on both old and
107 	     * new menus by comparing the background image paths (if
108 	     * defined)
109 	     */
110 	    if(((old_bg_image_path != NULL) &&
111 		(new_bg_image_path != NULL)) ?
112 	         ((old_menu->bg_image != NULL) ?
113 		  !strcmp(old_bg_image_path, new_bg_image_path) : False)
114 		: False
115 	    )
116 	    {
117 		/* Image paths are the same, so unload the image on the
118 		 * new menu and transfer the image from the old menu to
119 		 * the new menu
120 		 *
121 		 * Mark the old menu's image NULL after transfer so
122 		 * that it dosen't get referenced again
123 		 *
124 		 * Note that both new_menu and old_menu are known to be
125 		 * not NULL from the above check
126 		 */
127 		SARMenuUnloadBackgroundImage(new_menu);
128 		if(new_menu->bg_image == NULL)
129 		{
130 		    new_menu->bg_image = old_menu->bg_image;
131 		    old_menu->bg_image = NULL;
132 		}
133 	    }
134 	    else
135 	    {
136 		/* Image paths are different, so unload background image
137 		 * on old menu and load new background image on new menu
138 		 */
139 /*		if(opt->prioritize_memory && (old_menu != NULL)) */
140 		if(old_menu != NULL)
141 		    SARMenuUnloadBackgroundImage(old_menu);
142 
143 		if(opt->menu_backgrounds &&
144 		   ((new_menu != NULL) ? (new_menu->bg_image == NULL) : False)
145 		)
146 		    SARMenuLoadBackgroundImage(new_menu);
147 	    }
148 
149             glClearColor(0, 0, 0, 0);
150             glClear(GL_COLOR_BUFFER_BIT);
151             GWSwapBuffer(core_ptr->display);
152             GWFlush(core_ptr->display);
153 
154 	    /* Is the new menu valid? */
155 	    if(new_menu != NULL)
156 	    {
157 		/* New menu is valid, so switch to it */
158 		int n;
159 		void *o;
160 		sar_menu_button_struct *btn;
161 		sar_menu_struct *m = new_menu;
162 
163 		/* Begin resetting object values on the new menu */
164 		for(n = 0; n < m->total_objects; n++)
165 		{
166 		    o = m->object[n];
167 		    if(o == NULL)
168 			continue;
169 
170 		    switch(SAR_MENU_OBJECT_TYPE(o))
171 		    {
172 		      case SAR_MENU_OBJECT_TYPE_BUTTON:
173 			btn = SAR_MENU_BUTTON(o);
174 			btn->state = SAR_MENU_BUTTON_STATE_UNARMED;
175 			break;
176 
177 		      case SAR_MENU_OBJECT_TYPE_PROGRESS:
178 			SARMenuProgressSet(
179 			    display, m, n,
180 			    0.0f, False
181 			);
182 			break;
183 		    }
184 		}
185 
186 		/* Select first object on menu */
187 		m->selected_object = 0;
188 
189 		/* Update index number of the current menu */
190 	        core_ptr->cur_menu = new_menu_num;
191 	    }
192 
193 	    /* Redraw */
194 	    GWPostRedraw(display);
195 
196 	    /* Mark input as ready */
197 	    GWSetInputReady(display);
198 	}
199 }
200 
201 /*
202  *	Returns the pointer to the list object on the menu,
203  *	skipping the indicated number of lists.
204  *
205  *	Can return NULL for no match.
206  */
SARMenuGetList(sar_menu_struct * m,int skip,int * list_num)207 sar_menu_list_struct *SARMenuGetList(
208 	sar_menu_struct *m, int skip, int *list_num
209 )
210 {
211 	int i;
212 	void *ptr;
213 	sar_menu_list_struct *list_ptr;
214 
215 
216 	if(m == NULL)
217 	    return(NULL);
218 
219 	if(list_num != NULL)
220 	    *list_num = -1;
221 
222 	for(i = 0; i < m->total_objects; i++)
223 	{
224 	    ptr = m->object[i];
225 	    if(ptr == NULL)
226 		continue;
227 
228 	    if(*(int *)ptr != SAR_MENU_OBJECT_TYPE_LIST)
229 		continue;
230 
231 	    /* Get pointer to list object. */
232 	    list_ptr = ptr;
233 
234 	    /* Skip this list object? */
235 	    if(skip > 0)
236 	    {
237 		skip--;
238 		continue;
239 	    }
240 	    else
241 	    {
242 		if(list_num != NULL)
243 		    *list_num = i;
244 		return(list_ptr);
245 	    }
246 	}
247 
248 	return(NULL);
249 }
250 
251 /*
252  *      Returns the pointer to the spin object on the menu,
253  *      skipping the indicated number of spin objects.
254  *
255  *	Can return NULL for no match.
256  */
SARMenuGetSpin(sar_menu_struct * m,int skip,int * spin_num)257 sar_menu_spin_struct *SARMenuGetSpin(
258 	sar_menu_struct *m, int skip, int *spin_num
259 )
260 {
261 	int i;
262 	void *ptr;
263 	sar_menu_spin_struct *spin_ptr;
264 
265 
266 	if(m == NULL)
267 	    return(NULL);
268 
269 	if(spin_num != NULL)
270 	    *spin_num = -1;
271 
272 	for(i = 0; i < m->total_objects; i++)
273 	{
274 	    ptr = m->object[i];
275 	    if(ptr == NULL)
276 		continue;
277 
278 	    if(*(int *)ptr != SAR_MENU_OBJECT_TYPE_SPIN)
279 		continue;
280 
281 	    /* Get pointer to spin object. */
282 	    spin_ptr = ptr;
283 
284 	    /* Skip this spin object? */
285 	    if(skip > 0)
286 	    {
287 		skip--;
288 		continue;
289 	    }
290 	    else
291 	    {
292 		if(spin_num != NULL)
293 		    *spin_num = i;
294 
295 		return(spin_ptr);
296 	    }
297 	}
298 
299 	return(NULL);
300 }
301 
302 /*
303  *	Returns the pointer to the selected list item on the list object
304  *	on the menu, skipping the indicated number of list objects.
305  */
SARMenuListGetSelectedItem(sar_menu_struct * m,int id)306 sar_menu_list_item_struct *SARMenuListGetSelectedItem(
307 	sar_menu_struct *m, int id
308 )
309 {
310 	int i;
311 	sar_menu_list_struct *list = SAR_MENU_LIST(
312 	    SARMenuGetObjectByID(m, id, NULL)
313 	);
314 	if(list == NULL)
315 	    return(NULL);
316 
317 	i = list->selected_item;
318 	if((i >= 0) && (i < list->total_items))
319 	    return(list->item[i]);
320 	else
321 	    return(NULL);
322 }
323 
324 /*
325  *	Returns the pointer to the name of the currently selected
326  *	menu or NULL on failure.
327  */
SARMenuGetCurrentMenuName(sar_core_struct * core_ptr)328 char *SARMenuGetCurrentMenuName(sar_core_struct *core_ptr)
329 {
330 	int cur_menu;
331 	sar_menu_struct *m;
332 
333 
334 	if(core_ptr == NULL)
335 	    return(NULL);
336 
337 	cur_menu = core_ptr->cur_menu;
338 	if(SARIsMenuAllocated(core_ptr, cur_menu))
339 	    m = core_ptr->menu[cur_menu];
340 	else
341 	    return(NULL);
342 
343 	return(m->name);
344 }
345