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