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