1 /* file created on Mon Aug 26 15:30:05 CEST 2002 by doom */
2 
3 #include "menu.h"
4 #include <stdlib.h>
5 #include <math.h>
6 #include <string.h>
7 
8 
9 struct _MENU
10 {
11   MenuItems items;
12   int     active_item;
13   int     nb_items;
14   IIM_Surface * menuselector;
15 
16   int     sep_size;
17 
18   Sound  *sound_move;
19   Sound  *sound_valid;
20 
21   int     appears;
22   int     visible;
23   int     hide;
24 
25   int     hauteur;
26 };
27 
28 
29 void    menu_update_hauteur (Menu * menu);
30 
31 
32   Menu   *
menu_new(MenuItems items,IIM_Surface * selimage)33 menu_new (MenuItems items,IIM_Surface * selimage)
34 {
35   Menu   *m = (Menu *)malloc (sizeof (Menu));
36 
37   m->items = items;
38 
39   m->nb_items = 0;
40   while (items[m->nb_items++].name);
41 
42   m->sep_size = 20;							// taille d'un separateur.
43 
44   m->active_item = -1;
45   m->sound_move = m->sound_valid = NULL;
46 
47   m->visible = m->appears = m->hide = 0;
48   menu_update_hauteur (m);
49 
50   menu_next_item (m);
51 
52 
53   m->menuselector = selimage;;
54 
55   return m;
56 }
57 
58 
menu_get_active_item(Menu * menu)59 int menu_get_active_item (Menu * menu)
60 {
61   return menu->active_item;
62 }
63 
menu_get_active_item_string(Menu * menu)64 const char * menu_get_active_item_string (Menu * menu)
65 {
66   return menu->items[menu_get_active_item (menu)].name;
67 }
68 
menu_active_is(Menu * menu,const char * it_name)69 int menu_active_is (Menu * menu, const char *it_name)
70 {
71   return (!strcmp (it_name, menu_get_active_item_string (menu)));
72 }
73 
74 
menu_change_item_done(Menu * menu)75 void menu_change_item_done (Menu * menu)
76 {
77   menu->items[menu->active_item].priv_must_anim = 1;
78   if (menu->sound_move) {
79     audio_sound_play (menu->sound_move);
80   }
81 }
82 
83 
84   void
menu_next_item(Menu * menu)85 menu_next_item (Menu * menu)
86 {
87   do {
88     menu->active_item++;
89     menu->active_item %= menu->nb_items;
90   }
91   while (menu_items_is_delimiter (menu->items, menu->active_item));
92   menu_change_item_done (menu);
93 }
94 
95   void
menu_prev_item(Menu * menu)96 menu_prev_item (Menu * menu)
97 {
98   do {
99     if (menu->active_item)
100       menu->active_item--;
101     else
102       menu->active_item = menu->nb_items - 1;
103   }
104   while (menu_items_is_delimiter (menu->items, menu->active_item));
105   menu_change_item_done (menu);
106 }
107 
108 
menu_update(Menu * menu,SDL_Surface * surf)109 void menu_update (Menu * menu, SDL_Surface * surf)
110 {
111   int     c;
112 
113   if (menu->visible) {
114     if (menu->hide) {
115       menu->hide *= 2;
116     }
117 
118     if (menu->hide > surf->h) {
119       menu->visible = 0;
120       menu->hide = 0;
121     }
122 
123     if (menu->appears) {
124       for (c = 0; c < menu->nb_items; c++) {
125         menu->items[c].priv_vx = 0;
126         menu->items[c].priv_x =
127           ((rand () % 2) ? -1 : 1) * (16 + (rand () % 4)) * surf->w / 16;
128       }
129       menu->appears = 0;
130     }
131 
132     for (c = 0; c < menu->nb_items; c++) {
133       SDL_Surface *item_surf = menu->items[c].bitmap;
134       SoFont *item_font = menu->items[c].font;
135 
136       if (item_surf || item_font) {
137         if (menu->items[c].priv_must_anim) {
138           static int alt = -1;
139 
140           menu->items[c].priv_vx += alt * 15;
141           menu->items[c].priv_must_anim = 0;
142           alt = -alt;
143         }
144 
145         if ((fabs (menu->items[c].priv_vx) < 0.02)
146             && (fabs (menu->items[c].priv_x) < 0.1))
147           menu->items[c].priv_x = menu->items[c].priv_vx = 0;
148 
149         menu->items[c].priv_vx -= menu->items[c].priv_x / 8;
150         menu->items[c].priv_vx *= 0.85;
151 
152         menu->items[c].priv_x += menu->items[c].priv_vx;
153       }
154     }
155   }
156 }
157 
menu_draw(Menu * menu,SDL_Surface * surf)158 void menu_draw (Menu * menu, SDL_Surface * surf)
159 {
160   if (menu->visible) {
161     int     c;									// compteur d'items
162     int     center = surf->w / 2;
163     int     hauteur = (surf->h - menu->hauteur) / 2;
164 
165     hauteur += menu->hide;
166 
167     for (c = 0; c < menu->nb_items; c++) {
168       SDL_Surface *item_surf = menu->items[c].bitmap;
169       SoFont *item_font = menu->items[c].font;
170 
171       if (item_surf || item_font) {
172         int     center_x;
173 
174         center_x = (int)(center + menu->items[c].priv_x);
175 
176         if (item_surf != NULL) {
177           SDL_Rect rect;
178 
179           rect.x = center_x - item_surf->w / 2;
180           rect.y = hauteur;
181           rect.w = item_surf->w;
182           rect.h = item_surf->h;
183 
184           SDL_BlitSurface (item_surf, NULL, surf, &rect);
185           hauteur += item_surf->h;
186         }
187         else {									// font..
188           static char item_name[1024];
189 
190           if (c == menu->active_item) {
191 
192             SDL_Rect rect;
193             if (menu->menuselector==NULL)
194             {
195               rect.x = center - 140; rect.w = 280;
196               rect.y = hauteur; rect.h = SoFont_FontHeight (item_font);
197               SDL_FillRect (surf, &rect, 0);
198               rect.x = center - 150; rect.w = 300;
199               rect.y = hauteur + 3; rect.h = SoFont_FontHeight (item_font) - 6;
200               SDL_FillRect (surf, &rect, 0);
201             }
202             else
203             {
204               rect.x = center - 150; rect.w = menu->menuselector->w;
205               rect.y = hauteur - 3; rect.h = menu->menuselector->h;
206               SDL_BlitSurface (menu->menuselector->surf, NULL, surf, &rect);
207             }
208           }
209 
210           strcpy (item_name, menu->items[c].name);
211           if (menu->items[c].value) {
212             strcat (item_name, menu->items[c].value);
213           }
214 
215           char *pc = item_name;
216           int nbTab = 0;
217           for (; *pc; pc++)
218           {
219             if (*pc == '\t') {
220               while (*pc == '\t') {
221                 *pc = 0;
222                 pc    ++;
223                 nbTab ++;
224               }
225               break;
226             }
227           }
228 
229           if (nbTab > 0)
230           {
231             int w = 80 + nbTab * 50;
232             SoFont_PutString (item_font, surf, center_x-w, hauteur, item_name, NULL);
233             SoFont_PutString (item_font, surf, center_x+w - SoFont_TextWidth(item_font, pc), hauteur, pc, NULL);
234           }
235           else
236           {
237             SoFont_PutString (item_font, surf,
238                 center_x - SoFont_TextWidth (item_font,
239                   item_name) / 2,
240                 hauteur, item_name, NULL);
241           }
242           hauteur += SoFont_FontHeight (item_font);
243         }
244       }
245       else
246         hauteur += menu->sep_size;
247     }
248   }
249 }
250 
menu_update_hauteur(Menu * menu)251 void menu_update_hauteur (Menu * menu)
252 {
253   int     c;										// compteur d'items
254   int     hauteur = 0;
255 
256   for (c = 0; c < menu->nb_items; c++) {
257     SDL_Surface *item_surf = menu->items[c].bitmap;
258     SoFont *item_font = menu->items[c].font;
259 
260     if (item_surf || item_font) {
261       if (item_surf != NULL) {
262         hauteur += item_surf->h;
263       }
264       else {										// font..
265         hauteur += SoFont_FontHeight (item_font);
266       }
267     }
268     else
269       hauteur += menu->sep_size;
270   }
271   menu->hauteur = hauteur;
272 }
273 
274 
275   void
menu_set_sounds(Menu * menu,Sound * s_move,Sound * s_validate)276 menu_set_sounds (Menu * menu, Sound * s_move, Sound * s_validate)
277 {
278   menu->sound_move = s_move;
279   menu->sound_valid = s_validate;
280 }
281 
282   void
menu_validate(Menu * menu)283 menu_validate (Menu * menu)
284 {
285   if (menu->sound_valid)
286     audio_sound_play (menu->sound_valid);
287   menu->items[menu->active_item].priv_must_anim = 1;
288 }
289 
290   void
menu_show(Menu * menu)291 menu_show (Menu * menu)
292 {
293   if (!menu_visible (menu)) {
294     menu->appears = 1;
295     menu->visible = 1;
296     menu->hide = 0;
297   }
298 }
299 
300   void
menu_hide(Menu * menu)301 menu_hide (Menu * menu)
302 {
303   if (menu_visible (menu))
304     menu->hide = 1;
305 }
306 
307   int
menu_visible(Menu * menu)308 menu_visible (Menu * menu)
309 {
310   return (menu->visible) && (!menu->hide);
311 }
312 
313   int
menu_switch_on_off(Menu * menu,const char * name)314 menu_switch_on_off (Menu * menu, const char *name)
315 {
316   const char *value = menu_items_get_value (menu->items, name);
317 
318   if (!strcmp (value, "ON")) {
319     menu_set_value (menu, name, "OFF");
320     return 0;
321   }
322   else {
323     menu_set_value (menu, name, "ON");
324     return 1;
325   }
326 }
327 
328   int
menu_progress_bar(Menu * menu,const char * name,int increment)329 menu_progress_bar (Menu * menu, const char *name, int increment)
330 {
331   const char *svalue = menu_items_get_value (menu->items, name);
332   int     value = atoi (svalue);
333   static char nval[5];
334 
335   if (increment == 0)
336     return value;
337   else {
338     value += increment;
339     if (value > 100)
340       value = 100;
341     if (value < 0)
342       value = 0;
343   }
344 
345   sprintf (nval, "%d %%", value);
346   menu_set_value (menu, name, nval);
347   return value;
348 }
349 
350 
351   const char *
menu_get_value(Menu * menu,const char * name)352 menu_get_value (Menu * menu, const char *name)
353 {
354   return menu_items_get_value (menu->items, name);
355 }
356 
357   void
menu_set_value(Menu * menu,const char * name,const char * value,int doValide)358 menu_set_value (Menu * menu, const char *name, const char *value, int doValide)
359 {
360   menu_items_set_value_for (menu->items, name, value);
361   if (doValide)
362     menu_validate (menu);
363 }
364