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