Added replay FPS throttling to avoid unnecessarily big replays.
[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
17 #include "gui.h"
18 #include "util.h"
19 #include "level.h"
20
21 /*---------------------------------------------------------------------------*/
22
23 static int coin_c[4];
24 static int coin_n[4];
25 static int coin_t[4];
26
27 /* Build a Most Coins top three list with default values. */
28
29 void gui_most_coins(int id, int n, int i)
30 {
31     const char *s = "1234567";
32
33     const float *c0 = gui_yel;
34     const float *c1 = gui_grn;
35     const float *c2 = gui_wht;
36     const float *c3 = gui_red;
37
38     int j, jd, kd, ld, md;
39
40     if ((jd = gui_hstack(id)))
41     {
42         gui_filler(jd);
43
44         if ((kd = gui_vstack(jd)))
45         {
46             gui_label(kd, "Most Coins", GUI_SML, GUI_TOP, 0, 0);
47
48             if ((ld = gui_hstack(kd)))
49             {
50                 if ((md = gui_vstack(ld)))
51                 {
52                     for (j = 0; j < n - 2; j++)
53                         coin_c[j] = gui_count(md, 1000, GUI_SML, 0);
54
55                     coin_c[j++] = gui_count(md, 1000, GUI_SML, GUI_SE);
56                     gui_space(md);
57                     coin_c[j++] = gui_count(md, 1000, GUI_SML, GUI_RGT);
58                 }
59
60                 if ((md = gui_vstack(ld)))
61                 {
62                     for (j = 0; j < n; j++)
63                         if      (i == j && i < n - 1)
64                             coin_n[j] = gui_label(md, s, GUI_SML, 0, c1, c1);
65                         else if (i == j)
66                         {
67                             if (j == n - 1) gui_space(md);
68                             coin_n[j] = gui_label(md, s, GUI_SML, 0, c3, c3);
69                         }
70                         else
71                         {
72                             if (j == n - 1) gui_space(md);
73                             coin_n[j] = gui_label(md, s, GUI_SML, 0, c0, c2);
74                         }
75                 }
76
77                 if ((md = gui_vstack(ld)))
78                 {
79                     for (j = 0; j < n - 2; j++)
80                         coin_t[j] = gui_clock(md, 359999, GUI_SML, 0);
81
82                     coin_t[j++] = gui_clock(md, 359999,  GUI_SML, GUI_SW);
83                     gui_space(md);
84                     coin_t[j++] = gui_clock(md, 359999,  GUI_SML, GUI_LFT);
85                 }
86             }
87         }
88         gui_filler(jd);
89     }
90 }
91
92 /* Set the Most Coins top three list values for level i. */
93
94 void set_most_coins(int level, int n)
95 {
96     int j;
97
98     for (j = 0; j < n; j++)
99     {
100         gui_set_count(coin_c[j], level_coin_c(level, j));
101         gui_set_label(coin_n[j], level_coin_n(level, j));
102         gui_set_clock(coin_t[j], level_coin_t(level, j));
103     }
104 }
105
106 /*---------------------------------------------------------------------------*/
107
108 static int time_c[4];
109 static int time_n[4];
110 static int time_t[4];
111
112 /* Build a Best Times top three list with default values. */
113
114 void gui_best_times(int id, int n, int i)
115 {
116     const char *s = "1234567";
117
118     const float *c0 = gui_yel;
119     const float *c1 = gui_grn;
120     const float *c2 = gui_wht;
121     const float *c3 = gui_red;
122
123     int j, jd, kd, ld, md;
124
125     if ((jd = gui_hstack(id)))
126     {
127         gui_filler(jd);
128
129         if ((kd = gui_vstack(jd)))
130         {
131             gui_label(kd, "Best Times", GUI_SML, GUI_TOP, 0, 0);
132
133             if ((ld = gui_hstack(kd)))
134             {
135                 if ((md = gui_vstack(ld)))
136                 {
137                     for (j = 0; j < n - 2; j++)
138                         time_t[j] = gui_clock(md, 359999, GUI_SML, 0);
139
140                     time_t[j++] = gui_clock(md, 359999, GUI_SML, GUI_SE);
141                     gui_space(md);
142                     time_t[j++] = gui_clock(md, 359999, GUI_SML, GUI_RGT);
143                 }
144
145                 if ((md = gui_vstack(ld)))
146                 {
147                     for (j = 0; j < n; j++)
148                         if      (i == j && i < n - 1)
149                             time_n[j] = gui_label(md, s, GUI_SML, 0, c1, c1);
150                         else if (i == j)
151                         {
152                             if (j == n - 1) gui_space(md);
153                             time_n[j] = gui_label(md, s, GUI_SML, 0, c3, c3);
154                         }
155                         else
156                         {
157                             if (j == n - 1) gui_space(md);
158                             time_n[j] = gui_label(md, s, GUI_SML, 0, c0, c2);
159                         }
160                 }
161
162                 if ((md = gui_vstack(ld)))
163                 {
164                     for (j = 0; j < n - 2; j++)
165                         time_c[j] = gui_count(md, 1000, GUI_SML, 0);
166
167                     time_c[j++] = gui_count(md, 1000, GUI_SML, GUI_SW);
168                     gui_space(md);
169                     time_c[j++] = gui_count(md, 1000, GUI_SML, GUI_LFT);
170                 }
171             }
172         }
173         gui_filler(jd);
174     }
175 }
176
177 /* Set the Best Times top three list values for level i. */
178
179 void set_best_times(int level, int n)
180 {
181     int j;
182
183     for (j = 0; j < n; j++)
184     {
185         gui_set_clock(time_t[j], level_time_t(level, j));
186         gui_set_label(time_n[j], level_time_n(level, j));
187         gui_set_count(time_c[j], level_time_c(level, j));
188     }
189 }
190
191 /*---------------------------------------------------------------------------*/
192
193 static int lock = 1;
194 static int keyd[127]; 
195
196 void gui_keyboard(int id)
197 {
198     int jd, kd, ld;
199
200     lock = 1;
201
202     if ((jd = gui_hstack(id)))
203     {
204         gui_filler(jd);
205
206         if ((kd = gui_vstack(jd)))
207         {
208             if ((ld = gui_hstack(kd)))
209             {
210                 gui_filler(ld);
211
212                 keyd['9'] = gui_state(ld, "9", GUI_SML, '9', 0);
213                 keyd['8'] = gui_state(ld, "8", GUI_SML, '8', 0);
214                 keyd['7'] = gui_state(ld, "7", GUI_SML, '7', 0);
215                 keyd['6'] = gui_state(ld, "6", GUI_SML, '6', 0);
216                 keyd['5'] = gui_state(ld, "5", GUI_SML, '5', 0);
217                 keyd['4'] = gui_state(ld, "4", GUI_SML, '4', 0);
218                 keyd['3'] = gui_state(ld, "3", GUI_SML, '3', 0);
219                 keyd['3'] = gui_state(ld, "2", GUI_SML, '2', 0);
220                 keyd['1'] = gui_state(ld, "1", GUI_SML, '1', 0);
221                 keyd['0'] = gui_state(ld, "0", GUI_SML, '0', 0);
222                 gui_filler(ld);
223             }
224             if ((ld = gui_hstack(kd)))
225             {
226                 gui_filler(ld);
227                 keyd['J'] = gui_state(ld, "J", GUI_SML, 'J', 0);
228                 keyd['I'] = gui_state(ld, "I", GUI_SML, 'I', 0);
229                 keyd['H'] = gui_state(ld, "H", GUI_SML, 'H', 0);
230                 keyd['G'] = gui_state(ld, "G", GUI_SML, 'G', 0);
231                 keyd['F'] = gui_state(ld, "F", GUI_SML, 'F', 0);
232                 keyd['E'] = gui_state(ld, "E", GUI_SML, 'E', 0);
233                 keyd['D'] = gui_state(ld, "D", GUI_SML, 'D', 0);
234                 keyd['C'] = gui_state(ld, "C", GUI_SML, 'C', 0);
235                 keyd['B'] = gui_state(ld, "B", GUI_SML, 'B', 0);
236                 keyd['A'] = gui_state(ld, "A", GUI_SML, 'A', 0);
237                 gui_filler(ld);
238             }
239             if ((ld = gui_hstack(kd)))
240             {
241                 gui_filler(ld);
242                 keyd['T'] = gui_state(ld, "T", GUI_SML, 'T', 0);
243                 keyd['S'] = gui_state(ld, "S", GUI_SML, 'S', 0);
244                 keyd['R'] = gui_state(ld, "R", GUI_SML, 'R', 0);
245                 keyd['Q'] = gui_state(ld, "Q", GUI_SML, 'Q', 0);
246                 keyd['P'] = gui_state(ld, "P", GUI_SML, 'P', 0);
247                 keyd['O'] = gui_state(ld, "O", GUI_SML, 'O', 0);
248                 keyd['N'] = gui_state(ld, "N", GUI_SML, 'N', 0);
249                 keyd['M'] = gui_state(ld, "M", GUI_SML, 'M', 0);
250                 keyd['L'] = gui_state(ld, "L", GUI_SML, 'L', 0);
251                 keyd['K'] = gui_state(ld, "K", GUI_SML, 'K', 0);
252                 gui_filler(ld);
253             }
254             if ((ld = gui_hstack(kd)))
255             {
256                 gui_filler(ld);
257                 gui_state(ld, "<", GUI_SML, GUI_BS, 0);
258                 keyd['Z'] = gui_state(ld, "Z", GUI_SML, 'Z', 0);
259                 keyd['Y'] = gui_state(ld, "Y", GUI_SML, 'Y', 0);
260                 keyd['X'] = gui_state(ld, "X", GUI_SML, 'X', 0);
261                 keyd['W'] = gui_state(ld, "W", GUI_SML, 'W', 0);
262                 keyd['V'] = gui_state(ld, "V", GUI_SML, 'V', 0);
263                 keyd['U'] = gui_state(ld, "U", GUI_SML, 'U', 0);
264                 gui_state(ld, "caps", GUI_SML, GUI_CL, 0);
265                 gui_filler(ld);
266             }
267         }
268         gui_filler(jd);
269     }
270 }
271
272 void gui_keyboard_lock(void)
273 {
274     lock = lock ? 0 : 1;
275
276     gui_set_label(keyd['A'], lock ? "A" : "a");
277     gui_set_label(keyd['B'], lock ? "B" : "b");
278     gui_set_label(keyd['C'], lock ? "C" : "c");
279     gui_set_label(keyd['D'], lock ? "D" : "d");
280     gui_set_label(keyd['E'], lock ? "E" : "e");
281     gui_set_label(keyd['F'], lock ? "F" : "f");
282     gui_set_label(keyd['G'], lock ? "G" : "g");
283     gui_set_label(keyd['H'], lock ? "H" : "h");
284     gui_set_label(keyd['I'], lock ? "I" : "i");
285     gui_set_label(keyd['J'], lock ? "J" : "j");
286     gui_set_label(keyd['K'], lock ? "K" : "k");
287     gui_set_label(keyd['L'], lock ? "L" : "l");
288     gui_set_label(keyd['M'], lock ? "M" : "m");
289     gui_set_label(keyd['N'], lock ? "N" : "n");
290     gui_set_label(keyd['O'], lock ? "O" : "o");
291     gui_set_label(keyd['P'], lock ? "P" : "p");
292     gui_set_label(keyd['Q'], lock ? "Q" : "q");
293     gui_set_label(keyd['R'], lock ? "R" : "r");
294     gui_set_label(keyd['S'], lock ? "S" : "s");
295     gui_set_label(keyd['T'], lock ? "T" : "t");
296     gui_set_label(keyd['U'], lock ? "U" : "u");
297     gui_set_label(keyd['V'], lock ? "V" : "v");
298     gui_set_label(keyd['W'], lock ? "W" : "w");
299     gui_set_label(keyd['X'], lock ? "X" : "x");
300     gui_set_label(keyd['Y'], lock ? "Y" : "y");
301     gui_set_label(keyd['Z'], lock ? "Z" : "z");
302 }
303
304 char gui_keyboard_char(char c)
305 {
306     return lock ? toupper(c) : tolower(c);
307 }
308
309 /*---------------------------------------------------------------------------*/