Used strlen instead of checking first byte for NUL and added some
[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 "demo.h"
18 #include "game.h"
19 #include "audio.h"
20 #include "config.h"
21 #include "st_shared.h"
22
23 #include "st_title.h"
24 #include "st_help.h"
25 #include "st_demo.h"
26 #include "st_conf.h"
27 #include "st_set.h"
28 #include "st_name.h"
29
30 /*---------------------------------------------------------------------------*/
31
32 static float real_time = 0.0f;
33 static float demo_time = 0.0f;
34 static int   mode      = 0;
35
36 #define TITLE_PLAY 1
37 #define TITLE_HELP 2
38 #define TITLE_DEMO 3
39 #define TITLE_CONF 4
40 #define TITLE_EXIT 5
41
42 static int title_action(int i)
43 {
44     char player[MAXNAM];
45     audio_play(AUD_MENU, 1.0f);
46
47     switch (i)
48     {
49     case TITLE_PLAY:
50         config_get_s(CONFIG_PLAYER, player, MAXNAM);
51
52         if (strlen(player) == 0)
53             return goto_name(&st_set, &st_title);
54         else
55             return goto_state(&st_set);
56
57         break;
58
59     case TITLE_HELP: return goto_state(&st_help); break;
60     case TITLE_DEMO: return goto_state(&st_demo); break;
61     case TITLE_CONF: return goto_state(&st_conf); break;
62     case TITLE_EXIT: return 0;                    break;
63     }
64     return 1;
65 }
66
67 static struct level title_level;
68
69 static int title_enter(void)
70 {
71     int id, jd, kd;
72
73     /* Build the title GUI. */
74
75     if ((id = gui_vstack(0)))
76     {
77         gui_label(id, "Neverball", GUI_LRG, GUI_ALL, 0, 0);
78         gui_space(id);
79
80         if ((jd = gui_harray(id)))
81         {
82             gui_filler(jd);
83
84             if ((kd = gui_varray(jd)))
85             {
86                 gui_start(kd, sgettext("menu^Play"),    GUI_MED, TITLE_PLAY, 1);
87                 gui_state(kd, sgettext("menu^Replay"),  GUI_MED, TITLE_DEMO, 0);
88                 gui_state(kd, sgettext("menu^Help"),    GUI_MED, TITLE_HELP, 0);
89                 gui_state(kd, sgettext("menu^Options"), GUI_MED, TITLE_CONF, 0);
90                 gui_state(kd, sgettext("menu^Exit"),    GUI_MED, TITLE_EXIT, 0);
91             }
92
93             gui_filler(jd);
94         }
95         gui_layout(id, 0, 0);
96     }
97
98     /* Start the title screen music. */
99
100     audio_music_fade_to(0.5f, "bgm/title.ogg");
101
102     /* Initialize the title level for display. */
103     level_load("map-medium/title.sol", &title_level);
104     game_init(&title_level, 0, 0);
105
106     real_time = 0.0f;
107     demo_time = 0.0f;
108     mode = 0;
109
110     return id;
111 }
112
113 static void title_leave(int id)
114 {
115     demo_replay_stop(0);
116     gui_delete(id);
117 }
118
119 static void title_timer(int id, float dt)
120 {
121     static const char *demo = NULL;
122     float t;
123
124     real_time += dt;
125
126     switch (mode)
127     {
128     case 0: /* Mode 0: Pan across title level. */
129
130         if (real_time <= 20.0f)
131             game_set_fly(fcosf(V_PI * real_time / 20.0f));
132         else
133         {
134             game_fade(+1.0f);
135             real_time = 0.0f;
136             mode = 1;
137         }
138         break;
139
140     case 1: /* Mode 1: Fade out.  Load demo level. */
141
142         if (real_time > 1.0f)
143         {
144             if ((demo = demo_pick()))
145             {
146                 demo_replay_init(demo, NULL);
147                 demo_time = 0.0f;
148                 real_time = 0.0f;
149                 mode = 2;
150             }
151             else
152             {
153                 game_fade(-1.0f);
154                 real_time = 0.0f;
155                 mode = 0;
156             }
157         }
158         break;
159
160     case 2: /* Mode 2: Run demo. */
161
162         while (demo_time < real_time)
163             if (demo_replay_step(&t))
164                 demo_time += t;
165             else
166             {
167                 demo_replay_stop(0);
168                 game_fade(+1.0f);
169                 real_time = 0.0f;
170                 mode = 3;
171             }
172         break;
173
174     case 3: /* Mode 3: Fade out.  Load title level. */
175
176         if (real_time > 1.0f)
177         {
178             game_init(&title_level, 0, 0);
179             real_time = 0.0f;
180             mode = 0;
181         }
182         break;
183     }
184
185     gui_timer(id, dt);
186     audio_timer(dt);
187     game_step_fade(dt);
188 }
189
190 static int title_keybd(int c, int d)
191 {
192     if (d && c == SDLK_c && ALLOW_CHEAT)
193         config_tgl_d(CONFIG_CHEAT);
194     return 1;
195 }
196
197 static int title_buttn(int b, int d)
198 {
199     if (d)
200     {
201         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
202             return title_action(gui_token(gui_click()));
203         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
204             return 0;
205     }
206     return 1;
207 }
208
209 /*---------------------------------------------------------------------------*/
210
211 struct state st_title = {
212     title_enter,
213     title_leave,
214     shared_paint,
215     title_timer,
216     shared_point,
217     shared_stick,
218     shared_click,
219     title_keybd,
220     title_buttn,
221     1, 0
222 };
223