Merge 'progress' branch.
[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 "game.h"
23 #include "progress.h"
24 #include "config.h"
25 #include "audio.h"
26
27 /*---------------------------------------------------------------------------*/
28
29 static int Lhud_id;
30 static int Rhud_id;
31 static int time_id;
32
33 static int coin_id;
34 static int ball_id;
35 static int scor_id;
36 static int goal_id;
37 static int view_id;
38 static int fps_id;
39
40 static float view_timer;
41
42 static void hud_fps(void)
43 {
44     gui_set_count(fps_id, config_perf());
45 }
46
47 void hud_init(void)
48 {
49     int id;
50     char *str_view;
51
52     if ((Rhud_id = gui_hstack(0)))
53     {
54         if ((id = gui_vstack(Rhud_id)))
55         {
56             gui_label(id, _("Coins"), GUI_SML, 0, gui_wht, gui_wht);
57             gui_label(id, _("Goal"),  GUI_SML, 0, gui_wht, gui_wht);
58         }
59         if ((id = gui_vstack(Rhud_id)))
60         {
61             coin_id = gui_count(id, 100, GUI_SML, GUI_NW);
62             goal_id = gui_count(id, 10,  GUI_SML, 0);
63         }
64         gui_layout(Rhud_id, +1, -1);
65     }
66
67     if ((Lhud_id = gui_hstack(0)))
68     {
69         if ((id = gui_vstack(Lhud_id)))
70         {
71             ball_id = gui_count(id, 10,   GUI_SML, GUI_NE);
72             scor_id = gui_count(id, 1000, GUI_SML, 0);
73         }
74         if ((id = gui_vstack(Lhud_id)))
75         {
76             gui_label(id, _("Balls"), GUI_SML, 0, gui_wht, gui_wht);
77             gui_label(id, _("Score"), GUI_SML, 0, gui_wht, gui_wht);
78         }
79         gui_layout(Lhud_id, -1, -1);
80     }
81
82     if ((time_id = gui_clock(0, 59999, GUI_MED, GUI_TOP)))
83         gui_layout(time_id, 0, -1);
84
85     str_view = strlen(STR_VIEW0) > strlen(STR_VIEW1) ? STR_VIEW0 : STR_VIEW1;
86     if (strlen(str_view) < strlen(STR_VIEW2))
87         str_view = STR_VIEW2;
88     if ((view_id = gui_label(0, str_view, GUI_SML, GUI_SW, gui_wht, gui_wht)))
89         gui_layout(view_id, 1, 1);
90
91     if ((fps_id = gui_count(0, 1000, GUI_SML, GUI_SE)))
92         gui_layout(fps_id, -1, 1);
93 }
94
95 void hud_free(void)
96 {
97     gui_delete(Rhud_id);
98     gui_delete(Lhud_id);
99     gui_delete(time_id);
100     gui_delete(view_id);
101     gui_delete(fps_id);
102 }
103
104 void hud_paint(void)
105 {
106     if (curr_mode() == MODE_CHALLENGE)
107         gui_paint(Lhud_id);
108
109     gui_paint(Rhud_id);
110     gui_paint(time_id);
111
112     if (config_get_d(CONFIG_FPS))
113         gui_paint(fps_id);
114
115     if (view_timer > 0.0f)
116         gui_paint(view_id);
117 }
118
119 void hud_update(int pulse)
120 {
121     int clock = curr_clock();
122     int coins = curr_coins();
123     int goal  = curr_goal();
124     int balls = curr_balls();
125     int score = curr_score();
126
127     int c_id;
128     int last;
129
130     if (!pulse)
131     {
132         /* reset the hud */
133
134         gui_pulse(ball_id, 0.f);
135         gui_pulse(time_id, 0.f);
136         gui_pulse(coin_id, 0.f);
137     }
138
139     /* time and tick-tock */
140
141     if (clock != (last = gui_value(time_id)))
142     {
143         gui_set_clock(time_id, clock);
144
145         if (last > clock && pulse)
146         {
147             if (clock <= 1000 && (last / 100) > (clock / 100))
148             {
149                 audio_play(AUD_TICK, 1.f);
150                 gui_pulse(time_id, 1.50);
151             }
152             else if (clock < 500 && (last / 50) > (clock / 50))
153             {
154                 audio_play(AUD_TOCK, 1.f);
155                 gui_pulse(time_id, 1.25);
156             }
157         }
158     }
159
160     /* balls and score + select coin widget */
161
162     switch (curr_mode())
163     {
164     case MODE_CHALLENGE:
165         if (gui_value(ball_id) != balls) gui_set_count(ball_id, balls);
166         if (gui_value(scor_id) != score) gui_set_count(scor_id, score);
167
168         c_id = coin_id;
169         break;
170
171     default:
172         c_id = coin_id;
173         break;
174     }
175
176
177     /* coins and pulse */
178
179     if (coins != (last = gui_value(c_id)))
180     {
181         last = coins - last;
182
183         gui_set_count(c_id, coins);
184
185         if (pulse && last > 0)
186         {
187             if      (last >= 10) gui_pulse(coin_id, 2.00f);
188             else if (last >=  5) gui_pulse(coin_id, 1.50f);
189             else                 gui_pulse(coin_id, 1.25f);
190
191             if (goal > 0)
192             {
193                 if      (last >= 10) gui_pulse(goal_id, 2.00f);
194                 else if (last >=  5) gui_pulse(goal_id, 1.50f);
195                 else                 gui_pulse(goal_id, 1.25f);
196             }
197         }
198     }
199
200     /* goal and pulse */
201
202     if (goal != (last = gui_value(goal_id)))
203     {
204         gui_set_count(goal_id, goal);
205
206         if (pulse && goal == 0 && last > 0)
207             gui_pulse(goal_id, 2.00f);
208     }
209
210     if (config_get_d(CONFIG_FPS))
211         hud_fps();
212 }
213
214 void hud_timer(float dt)
215 {
216
217     hud_update(1);
218
219     view_timer -= dt;
220
221     gui_timer(Rhud_id, dt);
222     gui_timer(Lhud_id, dt);
223     gui_timer(time_id, dt);
224     gui_timer(view_id, dt);
225 }
226
227 void hud_view_pulse(int c)
228 {
229     switch (c)
230     {
231     case 0: gui_set_label(view_id, STR_VIEW0); break;
232     case 1: gui_set_label(view_id, STR_VIEW1); break;
233     case 2: gui_set_label(view_id, STR_VIEW2); break;
234     }
235
236     gui_pulse(view_id, 1.2f);
237     view_timer = 2.0f;
238 }
239
240 /*---------------------------------------------------------------------------*/