some display fixes (st_start, hud)
[neverball] / ball / st_title.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 "gui.h"
16 #include "vec3.h"
17 #include "back.h"
18 #include "demo.h"
19 #include "game.h"
20 #include "audio.h"
21 #include "config.h"
22
23 #include "st_title.h"
24 #include "st_demo.h"
25 #include "st_conf.h"
26 #include "st_set.h"
27
28 /*---------------------------------------------------------------------------*/
29
30 static float real_time = 0.0f;
31 static float demo_time = 0.0f;
32 static int   mode      = 0;
33
34 #define TITLE_PLAY 1
35 #define TITLE_HELP 2
36 #define TITLE_DEMO 3
37 #define TITLE_CONF 4
38 #define TITLE_EXIT 5
39
40 static int title_action(int i)
41 {
42     audio_play(AUD_MENU, 1.0f);
43
44     switch (i)
45     {
46     case TITLE_PLAY: return goto_state(&st_set);
47     case TITLE_HELP: return goto_state(&st_help);
48     case TITLE_DEMO: return goto_state(&st_demo);
49     case TITLE_CONF: return goto_state(&st_conf);
50     case TITLE_EXIT: return 0;
51     }
52     return 1;
53 }
54
55 static int title_enter(void)
56 {
57     int id, jd, kd;
58
59     /* Build the title GUI. */
60
61     if ((id = gui_vstack(0)))
62     {
63         gui_label(id, _("Neverball"), GUI_LRG, GUI_ALL, 0, 0);
64         gui_space(id);
65
66         if ((jd = gui_harray(id)))
67         {
68             gui_filler(jd);
69
70             if ((kd = gui_varray(jd)))
71             {
72                 gui_start(kd, _("Play"),    GUI_MED, TITLE_PLAY, 1);
73                 gui_state(kd, _("Replay"),  GUI_MED, TITLE_DEMO, 0);
74                 gui_state(kd, _("Help"),    GUI_MED, TITLE_HELP, 0);
75                 gui_state(kd, _("Options"), GUI_MED, TITLE_CONF, 0);
76                 gui_state(kd, _("Exit"),    GUI_MED, TITLE_EXIT, 0);
77             }
78
79             gui_filler(jd);
80         }
81         gui_layout(id, 0, 0);
82     }
83
84     /* Start the title screen music. */
85
86     audio_music_fade_to(0.5f, "bgm/title.ogg");
87
88     /* Initialize the first level of the first set for display. */
89
90     game_init("map-rlk/title.sol",
91               "map-back/jupiter.sol", "png/space.png", 0, 1);
92
93     real_time = 0.0f;
94     demo_time = 0.0f;
95     mode = 0;
96
97     return id;
98 }
99
100 static void title_leave(int id)
101 {
102     demo_replay_stop(0);
103     gui_delete(id);
104 }
105
106 static void title_paint(int id, float st)
107 {
108     game_draw(0, st);
109     gui_paint(id);
110 }
111
112 static void title_timer(int id, float dt)
113 {
114     static const char *demo = NULL;
115     float t;
116
117     real_time += dt;
118
119     switch (mode)
120     {
121     case 0: /* Mode 0: Pan across title level. */
122
123         if (real_time <= 20.0f)
124             game_set_fly(fcosf(V_PI * real_time / 20.0f));
125         else
126         {
127             game_fade(+1.0f);
128             real_time = 0.0f;
129             mode = 1;
130         }
131         break;
132
133     case 1: /* Mode 1: Fade out.  Load demo level. */
134
135         if (real_time > 1.0f)
136         {
137             if ((demo = demo_pick()))
138             {
139                 demo_replay_init(demo, NULL, NULL, NULL, NULL);
140                 demo_time = 0.0f;
141                 real_time = 0.0f;
142                 mode = 2;
143             }
144             else
145             {
146                 game_fade(-1.0f);
147                 real_time = 0.0f;
148                 mode = 0;
149             }
150         }
151         break;
152
153     case 2: /* Mode 2: Run demo. */
154
155         while (demo_time < real_time)
156             if (demo_replay_step(&t))
157                 demo_time += t;
158             else
159             { 
160                 demo_replay_stop(0);
161                 game_fade(+1.0f);
162                 real_time = 0.0f;
163                 mode = 3;
164             }
165         break;
166
167     case 3: /* Mode 3: Fade out.  Load title level. */
168
169         if (real_time > 1.0f)
170         {
171             game_init("map-rlk/title.sol",
172                       "map-back/jupiter.sol", "png/space.png", 0, 1);
173             real_time = 0.0f;
174             mode = 0;
175         }
176         break;
177     }
178
179     gui_timer(id, dt);
180     audio_timer(dt);
181     game_step_fade(dt);
182 }
183
184 static void title_point(int id, int x, int y, int dx, int dy)
185 {
186     gui_pulse(gui_point(id, x, y), 1.2f);
187 }
188
189 static void title_stick(int id, int a, int v)
190 {
191     if (config_tst_d(CONFIG_JOYSTICK_AXIS_X, a))
192         gui_pulse(gui_stick(id, v, 0), 1.2f);
193     if (config_tst_d(CONFIG_JOYSTICK_AXIS_Y, a))
194         gui_pulse(gui_stick(id, 0, v), 1.2f);
195 }
196
197 static int title_click(int b, int d)
198 {
199     if (d && b < 0)
200         return title_action(gui_token(gui_click()));
201     return 1;
202 }
203
204 static int title_keybd(int c, int d)
205 {
206     return (d && c == SDLK_ESCAPE) ? 0 : 1;
207 }
208
209 static int title_buttn(int b, int d)
210 {
211     if (d)
212     {
213         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
214             return title_action(gui_token(gui_click()));
215         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
216             return 0;
217     }
218     return 1;
219 }
220
221 /*---------------------------------------------------------------------------*/
222
223 static int help_enter(void)
224 {
225     const char *s0 =
226         _("Move the mouse or joystick to tilt the floor\\"
227         "causing the ball to roll.  Roll over coins to\\"
228         "collect them.  Collect coins to unlock the goal\\"
229         "and finish the level.  Earn an extra ball for\\"
230         "each 100 coins collected.\\");
231
232     const char *s4 = _("Left and right mouse buttons rotate the view.");
233     const char *s5 = _("Hold Shift for faster view rotation.");
234     const char *s6 = _("Pause / Release Pointer");
235     const char *s7 = _("Exit / Cancel Menu");
236     const char *s8 = _("Chase View");
237     const char *s9 = _("Lazy View");
238     const char *sA = _("Manual View");
239     const char *sB = _("Comments?  Problems?  robert.kooima@gmail.com");
240
241     const char *k0 = _("Spacebar");
242     const char *k1 = _("Escape");
243     const char *k2 = SDL_GetKeyName(config_get_d(CONFIG_KEY_CAMERA_1));
244     const char *k3 = SDL_GetKeyName(config_get_d(CONFIG_KEY_CAMERA_2));
245     const char *k4 = SDL_GetKeyName(config_get_d(CONFIG_KEY_CAMERA_3));
246
247     int id, jd;
248
249     if ((id = gui_vstack(0)))
250     {
251         gui_multi(id, s0, GUI_SML, GUI_ALL, gui_wht, gui_wht);
252         gui_space(id);
253
254         if ((jd = gui_harray(id)))
255         {
256             gui_label(jd, s6, GUI_SML, GUI_NE, gui_wht, gui_wht);
257             gui_label(jd, k0, GUI_SML, GUI_NW, gui_yel, gui_yel);
258         }
259         if ((jd = gui_harray(id)))
260         {
261             gui_label(jd, s7, GUI_SML, 0,      gui_wht, gui_wht);
262             gui_label(jd, k1, GUI_SML, 0,      gui_yel, gui_yel);
263         }
264         if ((jd = gui_harray(id)))
265         {
266             gui_label(jd, s8, GUI_SML, 0,      gui_wht, gui_wht);
267             gui_label(jd, k2, GUI_SML, 0,      gui_yel, gui_yel);
268         }
269         if ((jd = gui_harray(id)))
270         {
271             gui_label(jd, s9, GUI_SML, 0,      gui_wht, gui_wht);
272             gui_label(jd, k3, GUI_SML, 0,      gui_yel, gui_yel);
273         }
274         if ((jd = gui_harray(id)))
275         {
276             gui_label(jd, sA, GUI_SML, GUI_SE, gui_wht, gui_wht);
277             gui_label(jd, k4, GUI_SML, GUI_SW, gui_yel, gui_yel);
278         }
279
280         gui_space(id);
281         gui_label(id, s4, GUI_SML, GUI_TOP, gui_wht, gui_wht);
282         gui_label(id, s5, GUI_SML, GUI_BOT, gui_wht, gui_wht);
283         gui_space(id);
284         gui_label(id, sB, GUI_SML, GUI_ALL, gui_wht, gui_wht);
285
286         gui_layout(id, 0, 0);
287     }
288     return id;
289 }
290
291 static void help_leave(int id)
292 {
293     gui_delete(id);
294 }
295
296 static void help_paint(int id, float st)
297 {
298     game_draw(0, st);
299     config_pop_matrix();
300     gui_paint(id);
301 }
302
303 static void help_timer(int id, float dt)
304 {
305     gui_timer(id, dt);
306     audio_timer(dt);
307 }
308
309 static int help_click(int b, int d)
310 {
311     return d ? goto_state(&st_title) : 1;
312 }
313
314 static int help_keybd(int c, int d)
315 {
316     return d ? goto_state(&st_title) : 1;
317 }
318
319 static int help_buttn(int b, int d)
320 {
321     return d ? goto_state(&st_title) : 1;
322 }
323
324 /*---------------------------------------------------------------------------*/
325
326 struct state st_title = {
327     title_enter,
328     title_leave,
329     title_paint,
330     title_timer,
331     title_point,
332     title_stick,
333     title_click,
334     title_keybd,
335     title_buttn,
336     1, 0
337 };
338
339 struct state st_help = {
340     help_enter,
341     help_leave,
342     help_paint,
343     help_timer,
344     NULL,
345     NULL,
346     help_click,
347     help_keybd,
348     help_buttn,
349     1, 0
350 };