Hopefully fixes ticket:78 and hopefully doesn't break anything.
[neverball] / ball / util.c
1 /*
2  * Copyright (C) 2003 Robert Kooima
3  *
4  * NEVERBALL is  free software; you can redistribute  it and/or modify
5  * it under the  terms of the GNU General  Public License as published
6  * by the Free  Software Foundation; either version 2  of the License,
7  * or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT  ANY  WARRANTY;  without   even  the  implied  warranty  of
11  * MERCHANTABILITY or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU
12  * General Public License for more details.
13  */
14
15 #include <ctype.h>
16 #include <string.h>
17
18 #include "gui.h"
19 #include "util.h"
20 #include "config.h"
21
22 /*---------------------------------------------------------------------------*/
23
24 static int is_special_name(const char *n)
25 {
26     return (strcmp(n, N_("Hard")) == 0 || strcmp(n, N_("Medium")) == 0
27             || strcmp(n, N_("Easy")) == 0);
28 }
29
30 /*---------------------------------------------------------------------------*/
31
32 static int coin_c[4];
33 static int coin_n[4];
34 static int coin_t[4];
35 static int coin_extrarow;
36
37 /* Build a Most Coins top three list with default values. */
38
39 void gui_most_coins(int id, int e)
40 {
41     const char *s = "1234567";
42
43     int j, jd, kd, ld, md;
44
45     coin_extrarow = e;
46
47     if ((jd = gui_hstack(id)))
48     {
49         gui_filler(jd);
50
51         if ((kd = gui_vstack(jd)))
52         {
53             gui_label(kd, _("Most Coins"), GUI_SML, GUI_TOP, 0, 0);
54
55             if ((ld = gui_hstack(kd)))
56             {
57                 if ((md = gui_vstack(ld)))
58                 {
59                     for (j = 0; j < NSCORE - 1; j++)
60                         coin_c[j] = gui_count(md, 1000, GUI_SML, 0);
61
62                     coin_c[j++] = gui_count(md, 1000, GUI_SML, GUI_SE);
63
64                     if (e)
65                     {
66                        gui_space(md);
67                        coin_c[j++] = gui_count(md, 1000, GUI_SML, GUI_RGT);
68                     }
69                 }
70
71                 if ((md = gui_vstack(ld)))
72                 {
73                     for (j = 0; j < NSCORE ; j++)
74                         coin_n[j] = gui_label(md, s, GUI_SML, 0, gui_yel, gui_wht);
75
76                     if (e)
77                     {
78                         gui_space(md);
79                         coin_n[j++] = gui_label(md, s, GUI_SML, 0, gui_yel, gui_wht);
80                     }
81                 }
82
83                 if ((md = gui_vstack(ld)))
84                 {
85                     for (j = 0; j < NSCORE - 1; j++)
86                         coin_t[j] = gui_clock(md, 359999, GUI_SML, 0);
87
88                     coin_t[j++] = gui_clock(md, 359999,  GUI_SML, GUI_SW);
89
90                     if (e)
91                     {
92                        gui_space(md);
93                        coin_t[j++] = gui_clock(md, 359999,  GUI_SML, GUI_LFT);
94                     }
95                 }
96             }
97         }
98         gui_filler(jd);
99     }
100 }
101
102 /* Set the Most Coins top three list values for level i. */
103
104 void set_most_coins(const struct score *s, int hilight)
105 {
106     int j, spe;
107     const char *name;
108
109     if (s == NULL)
110     {
111         for (j = 0; j < NSCORE + coin_extrarow ; j++)
112         {
113             gui_set_count(coin_c[j], -1);
114             gui_set_label(coin_n[j], "");
115             gui_set_clock(coin_t[j], -1);
116         }
117     }
118     else
119     {
120         for (j = 0; j < NSCORE + coin_extrarow; j++)
121         {
122             name = s->player[j];
123             spe = is_special_name(name);
124
125             if (spe)
126                 gui_set_color(coin_n[j], 0, 0);
127             else if (j != hilight)
128                 gui_set_color(coin_n[j], gui_yel, gui_wht);
129             else if (j>= NSCORE)
130                 gui_set_color(coin_n[j], gui_red, gui_red);
131             else
132                 gui_set_color(coin_n[j], gui_grn, gui_grn);
133
134             gui_set_count(coin_c[j], s->coins[j]);
135             gui_set_label(coin_n[j], spe ? _(name) : name);
136             gui_set_clock(coin_t[j], s->timer[j]);
137         }
138     }
139 }
140
141 /*---------------------------------------------------------------------------*/
142
143 static int time_l;
144 static int time_c[4];
145 static int time_n[4];
146 static int time_t2[4]; /* Renamed to time_t2 to avoid multiple declaration (in sys/types.h) */
147 static int time_extrarow;
148
149 /* Build a Best Times top three list with default values. */
150
151 void gui_best_times(int id, int e)
152 {
153     const char *s = "1234567";
154
155     int j, jd, kd, ld, md;
156
157     time_extrarow = e;
158
159     if ((jd = gui_hstack(id)))
160     {
161         gui_filler(jd);
162
163         if ((kd = gui_vstack(jd)))
164         {
165             time_l = gui_label(kd, "XXX", GUI_SML, GUI_TOP, 0, 0);
166
167             if ((ld = gui_hstack(kd)))
168             {
169                 if ((md = gui_vstack(ld)))
170                 {
171                     for (j = 0; j < NSCORE - 1; j++)
172                         time_t2[j] = gui_clock(md, 359999, GUI_SML, 0);
173
174                     time_t2[j++] = gui_clock(md, 359999, GUI_SML, GUI_SE);
175
176                     if (e)
177                     {
178                         gui_space(md);
179                         time_t2[j++] = gui_clock(md, 359999, GUI_SML, GUI_RGT);
180                     }
181                 }
182
183                 if ((md = gui_vstack(ld)))
184                 {
185                     for (j = 0; j < NSCORE; j++)
186                         time_n[j] = gui_label(md, s, GUI_SML, 0, gui_yel, gui_wht);
187
188                     if (e)
189                     {
190                         gui_space(md);
191                         time_n[j++] = gui_label(md, s, GUI_SML, 0, gui_yel, gui_wht);
192                     }
193                 }
194
195                 if ((md = gui_vstack(ld)))
196                 {
197                     for (j = 0; j < NSCORE - 1; j++)
198                         time_c[j] = gui_count(md, 1000, GUI_SML, 0);
199
200                     time_c[j++] = gui_count(md, 1000, GUI_SML, GUI_SW);
201
202                     if (e)
203                     {
204                         gui_space(md);
205                         time_c[j++] = gui_count(md, 1000, GUI_SML, GUI_LFT);
206                     }
207                 }
208             }
209         }
210         gui_filler(jd);
211     }
212 }
213
214 /* Set the Best Times top three list values for level i. */
215
216 void set_best_times(const struct score *s, int hilight, int goal)
217 {
218     int j, spe;
219     const char *name;
220
221     if (goal)
222         gui_set_label(time_l, _("Unlock Goal"));
223     else
224         gui_set_label(time_l, _("Best Times"));
225
226     if (s == NULL)
227     {
228         for (j = 0; j < NSCORE + time_extrarow ; j++)
229         {
230             gui_set_clock(time_t2[j], -1);
231             gui_set_label(time_n[j], "");
232             gui_set_count(time_c[j], -1);
233         }
234     }
235     else
236     {
237         for (j = 0; j < NSCORE + time_extrarow; j++)
238         {
239             name = s->player[j];
240             spe = is_special_name(name);
241
242             if (spe)
243                 gui_set_color(time_n[j], 0, 0);
244             else if (j != hilight)
245                 gui_set_color(time_n[j], gui_yel, gui_wht);
246             else if (j>= NSCORE)
247                 gui_set_color(time_n[j], gui_red, gui_red);
248             else
249                 gui_set_color(time_n[j], gui_grn, gui_grn);
250
251             gui_set_clock(time_t2[j], s->timer[j]);
252             gui_set_label(time_n[j], spe ? _(name) : name);
253             gui_set_count(time_c[j], s->coins[j]);
254         }
255     }
256 }
257
258 /*---------------------------------------------------------------------------*/
259
260 static int lock = 1;
261 static int keyd[127];
262
263 static void gui_fill(int id, char *line)
264 {
265     char l[2];
266     l[1] = '\0';
267
268     while(*line)
269     {
270         *l = *(line++);
271         keyd[(int)*l] = gui_state(id, l, GUI_SML, *l, 0);
272     }
273 }
274
275 void gui_keyboard(int id)
276 {
277     int jd, kd, ld;
278
279     lock = 1;
280
281     if ((jd = gui_hstack(id)))
282     {
283         gui_filler(jd);
284
285         if ((kd = gui_vstack(jd)))
286         {
287             if ((ld = gui_harray(kd)))
288             {
289                 gui_filler(ld);
290                 gui_fill(ld, "9876543210");
291                 gui_filler(ld);
292             }
293             if ((ld = gui_harray(kd)))
294             {
295                 gui_filler(ld);
296                 gui_fill(ld, "JIHGFEDCBA");
297                 gui_filler(ld);
298             }
299             if ((ld = gui_harray(kd)))
300             {
301                 gui_filler(ld);
302                 gui_fill(ld, "TSRQPONMLK");
303                 gui_filler(ld);
304             }
305             if ((ld = gui_harray(kd)))
306             {
307                 gui_filler(ld);
308                 gui_fill(ld, "!.-_ZYXWVU");
309                 gui_filler(ld);
310             }
311             if ((ld = gui_harray(kd)))
312             {
313                 gui_filler(ld);
314                 gui_fill(ld, "jihgfedcba");
315                 gui_filler(ld);
316             }
317             if ((ld = gui_harray(kd)))
318             {
319                 gui_filler(ld);
320                 gui_fill(ld, "tsrqponmlk");
321                 gui_filler(ld);
322             }
323             if ((ld = gui_hstack(kd)))
324             {
325                 gui_filler(ld);
326                 gui_state(ld, _("del"), GUI_SML, GUI_BS, 0);
327                 gui_fill(ld, "zyxwvu");
328                 gui_filler(ld);
329             }
330         }
331         gui_filler(jd);
332     }
333 }
334
335 /*---------------------------------------------------------------------------*/
336
337 int gui_back_prev_next(int id, int prev, int next)
338 {
339     int jd;
340     if ((jd = gui_hstack(id)))
341     {
342         if (next || prev)
343         {
344             gui_maybe(jd, _("Next"), GUI_NEXT, next);
345             gui_maybe(jd, _("Prev"), GUI_PREV, prev);
346         }
347
348         gui_start(jd, _("Back"),  GUI_SML, GUI_BACK, 0);
349     }
350     return jd;
351 }
352
353 int gui_maybe(int id, const char *label, int token, int enabled)
354 {
355     int bd;
356     if (enabled)
357         bd = gui_state(id, label, GUI_SML, token,    0);
358     else
359     {
360         bd = gui_state(id, label, GUI_SML, GUI_NULL, 0);
361         gui_set_color(bd, gui_gry, gui_gry);
362     }
363     return bd;
364 }
365
366 /*---------------------------------------------------------------------------*/