Merge branch 'gles'
[neverball] / ball / hud.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 <SDL.h>
16 #include <math.h>
17 #include <string.h>
18
19 #include "glext.h"
20 #include "hud.h"
21 #include "gui.h"
22 #include "progress.h"
23 #include "config.h"
24 #include "video.h"
25 #include "audio.h"
26 #include "speed.h"
27
28 #include "game_common.h"
29 #include "game_client.h"
30
31 /*---------------------------------------------------------------------------*/
32
33 static int Lhud_id;
34 static int Rhud_id;
35 static int time_id;
36
37 static int coin_id;
38 static int ball_id;
39 static int scor_id;
40 static int goal_id;
41 static int view_id;
42 static int fps_id;
43
44 static int speed_id;
45 static int speed_ids[SPEED_MAX];
46
47 static const char *speed_labels[SPEED_MAX] = {
48     "", "8", "4", "2", "1", "2", "4", "8"
49 };
50
51 static float view_timer;
52 static float speed_timer;
53
54 static void hud_fps(void)
55 {
56     gui_set_count(fps_id, video_perf());
57 }
58
59 void hud_init(void)
60 {
61     int id;
62     const char *str_view;
63     int v;
64
65     if ((Rhud_id = gui_hstack(0)))
66     {
67         if ((id = gui_vstack(Rhud_id)))
68         {
69             gui_label(id, _("Coins"), GUI_SML, 0, gui_wht, gui_wht);
70             gui_label(id, _("Goal"),  GUI_SML, 0, gui_wht, gui_wht);
71         }
72         if ((id = gui_vstack(Rhud_id)))
73         {
74             coin_id = gui_count(id, 100, GUI_SML, GUI_NW);
75             goal_id = gui_count(id, 10,  GUI_SML, 0);
76         }
77         gui_layout(Rhud_id, +1, -1);
78     }
79
80     if ((Lhud_id = gui_hstack(0)))
81     {
82         if ((id = gui_vstack(Lhud_id)))
83         {
84             ball_id = gui_count(id, 10,   GUI_SML, GUI_NE);
85             scor_id = gui_count(id, 1000, GUI_SML, 0);
86         }
87         if ((id = gui_vstack(Lhud_id)))
88         {
89             gui_label(id, _("Balls"), GUI_SML, 0, gui_wht, gui_wht);
90             gui_label(id, _("Score"), GUI_SML, 0, gui_wht, gui_wht);
91         }
92         gui_layout(Lhud_id, -1, -1);
93     }
94
95     if ((time_id = gui_clock(0, 59999, GUI_MED, GUI_TOP)))
96         gui_layout(time_id, 0, -1);
97
98
99     /* Find the longest view name. */
100
101     for (str_view = "", v = VIEW_NONE + 1; v < VIEW_MAX; v++)
102         if (strlen(view_to_str(v)) > strlen(str_view))
103             str_view = view_to_str(v);
104
105     if ((view_id = gui_label(0, str_view, GUI_SML, GUI_SW, gui_wht, gui_wht)))
106         gui_layout(view_id, 1, 1);
107
108     if ((fps_id = gui_count(0, 1000, GUI_SML, GUI_SE)))
109         gui_layout(fps_id, -1, 1);
110
111     if ((speed_id = gui_varray(0)))
112     {
113         int i;
114
115         for (i = SPEED_MAX - 1; i > SPEED_NONE; i--)
116         {
117             int rect = 0;
118
119             if (i == SPEED_MAX - 1)
120                 rect = GUI_NW;
121             if (i == SPEED_NONE + 1)
122                 rect = GUI_SW;
123
124             speed_ids[i] = gui_label(speed_id, speed_labels[i],
125                                      GUI_SML, rect, 0, 0);
126         }
127
128         gui_layout(speed_id, +1, 0);
129     }
130 }
131
132 void hud_free(void)
133 {
134     gui_delete(Rhud_id);
135     gui_delete(Lhud_id);
136     gui_delete(time_id);
137     gui_delete(view_id);
138     gui_delete(fps_id);
139 }
140
141 void hud_paint(void)
142 {
143     if (curr_mode() == MODE_CHALLENGE)
144         gui_paint(Lhud_id);
145
146     gui_paint(Rhud_id);
147     gui_paint(time_id);
148
149     if (config_get_d(CONFIG_FPS))
150         gui_paint(fps_id);
151
152     hud_view_paint();
153     hud_speed_paint();
154 }
155
156 void hud_update(int pulse)
157 {
158     int clock = curr_clock();
159     int coins = curr_coins();
160     int goal  = curr_goal();
161     int balls = curr_balls();
162     int score = curr_score();
163
164     int c_id;
165     int last;
166
167     if (!pulse)
168     {
169         /* reset the hud */
170
171         gui_pulse(ball_id, 0.f);
172         gui_pulse(time_id, 0.f);
173         gui_pulse(coin_id, 0.f);
174
175         speed_timer = 0.0f;
176     }
177
178     /* time and tick-tock */
179
180     if (clock != (last = gui_value(time_id)))
181     {
182         gui_set_clock(time_id, clock);
183
184         if (last > clock && pulse)
185         {
186             if (clock <= 1000 && (last / 100) > (clock / 100))
187             {
188                 audio_play(AUD_TICK, 1.f);
189                 gui_pulse(time_id, 1.50);
190             }
191             else if (clock < 500 && (last / 50) > (clock / 50))
192             {
193                 audio_play(AUD_TOCK, 1.f);
194                 gui_pulse(time_id, 1.25);
195             }
196         }
197     }
198
199     /* balls and score + select coin widget */
200
201     switch (curr_mode())
202     {
203     case MODE_CHALLENGE:
204         if (gui_value(ball_id) != balls) gui_set_count(ball_id, balls);
205         if (gui_value(scor_id) != score) gui_set_count(scor_id, score);
206
207         c_id = coin_id;
208         break;
209
210     default:
211         c_id = coin_id;
212         break;
213     }
214
215
216     /* coins and pulse */
217
218     if (coins != (last = gui_value(c_id)))
219     {
220         last = coins - last;
221
222         gui_set_count(c_id, coins);
223
224         if (pulse && last > 0)
225         {
226             if      (last >= 10) gui_pulse(coin_id, 2.00f);
227             else if (last >=  5) gui_pulse(coin_id, 1.50f);
228             else                 gui_pulse(coin_id, 1.25f);
229
230             if (goal > 0)
231             {
232                 if      (last >= 10) gui_pulse(goal_id, 2.00f);
233                 else if (last >=  5) gui_pulse(goal_id, 1.50f);
234                 else                 gui_pulse(goal_id, 1.25f);
235             }
236         }
237     }
238
239     /* goal and pulse */
240
241     if (goal != (last = gui_value(goal_id)))
242     {
243         gui_set_count(goal_id, goal);
244
245         if (pulse && goal == 0 && last > 0)
246             gui_pulse(goal_id, 2.00f);
247     }
248
249     if (config_get_d(CONFIG_FPS))
250         hud_fps();
251 }
252
253 void hud_timer(float dt)
254 {
255     hud_update(1);
256
257     gui_timer(Rhud_id, dt);
258     gui_timer(Lhud_id, dt);
259     gui_timer(time_id, dt);
260
261     hud_view_timer(dt);
262     hud_speed_timer(dt);
263 }
264
265 /*---------------------------------------------------------------------------*/
266
267 void hud_view_pulse(int c)
268 {
269     gui_set_label(view_id, view_to_str(c));
270     gui_pulse(view_id, 1.2f);
271     view_timer = 2.0f;
272 }
273
274 void hud_view_timer(float dt)
275 {
276     view_timer -= dt;
277     gui_timer(view_id, dt);
278 }
279
280 void hud_view_paint(void)
281 {
282     if (view_timer > 0.0f)
283         gui_paint(view_id);
284 }
285
286 /*---------------------------------------------------------------------------*/
287
288 void hud_speed_pulse(int speed)
289 {
290     int i;
291
292     for (i = SPEED_NONE + 1; i < SPEED_MAX; i++)
293     {
294         const GLubyte *c = gui_gry;
295
296         if (speed != SPEED_NONE)
297         {
298             if      (i > SPEED_NORMAL && i <= speed)
299                 c = gui_grn;
300             else if (i < SPEED_NORMAL && i >= speed)
301                 c = gui_red;
302             else if (i == SPEED_NORMAL)
303                 c = gui_wht;
304         }
305
306         gui_set_color(speed_ids[i], c, c);
307
308         if (i == speed)
309             gui_pulse(speed_ids[i], 1.2f);
310     }
311
312     speed_timer = 2.0f;
313 }
314
315 void hud_speed_timer(float dt)
316 {
317     speed_timer -= dt;
318     gui_timer(speed_id, dt);
319 }
320
321 void hud_speed_paint(void)
322 {
323     if (speed_timer > 0.0f)
324         gui_paint(speed_id);
325 }
326
327 /*---------------------------------------------------------------------------*/