Fix double numbername translation (cf. http://shinobufan.intuxication.org/neverforum...
[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     level_load(config_data("map-rlk/title.sol"), &title_level);
102     game_init(&title_level, 0, 0);
103
104     real_time = 0.0f;
105     demo_time = 0.0f;
106     mode = 0;
107
108     return id;
109 }
110
111 static void title_leave(int id)
112 {
113     demo_replay_stop(0);
114     gui_delete(id);
115 }
116
117 static void title_timer(int id, float dt)
118 {
119     static const char *demo = NULL;
120     float t;
121
122     real_time += dt;
123
124     switch (mode)
125     {
126     case 0: /* Mode 0: Pan across title level. */
127
128         if (real_time <= 20.0f)
129             game_set_fly(fcosf(V_PI * real_time / 20.0f));
130         else
131         {
132             game_fade(+1.0f);
133             real_time = 0.0f;
134             mode = 1;
135         }
136         break;
137
138     case 1: /* Mode 1: Fade out.  Load demo level. */
139
140         if (real_time > 1.0f)
141         {
142             if ((demo = demo_pick()))
143             {
144                 demo_replay_init(demo, NULL);
145                 demo_time = 0.0f;
146                 real_time = 0.0f;
147                 mode = 2;
148             }
149             else
150             {
151                 game_fade(-1.0f);
152                 real_time = 0.0f;
153                 mode = 0;
154             }
155         }
156         break;
157
158     case 2: /* Mode 2: Run demo. */
159
160         while (demo_time < real_time)
161             if (demo_replay_step(&t))
162                 demo_time += t;
163             else
164             { 
165                 demo_replay_stop(0);
166                 game_fade(+1.0f);
167                 real_time = 0.0f;
168                 mode = 3;
169             }
170         break;
171
172     case 3: /* Mode 3: Fade out.  Load title level. */
173
174         if (real_time > 1.0f)
175         {
176             game_init(&title_level, 0, 0);
177             real_time = 0.0f;
178             mode = 0;
179         }
180         break;
181     }
182
183     gui_timer(id, dt);
184     audio_timer(dt);
185     game_step_fade(dt);
186 }
187
188 static int title_keybd(int c, int d)
189 {
190     if (d && c == SDLK_c && ALLOW_CHEAT)
191         config_tgl_d(CONFIG_CHEAT);
192     return 1; 
193 }
194         
195 static int title_buttn(int b, int d)
196 {
197     if (d)
198     {
199         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
200             return title_action(gui_token(gui_click()));
201         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
202             return 0;
203     }
204     return 1;
205 }
206
207 /*---------------------------------------------------------------------------*/
208
209 static int help_enter(void)
210 {
211     const char *s0 =
212         _("Move the mouse or joystick to tilt the floor\\"
213         "causing the ball to roll.  Roll over coins to\\"
214         "collect them.  Collect coins to unlock the goal\\"
215         "and finish the level.  Earn an extra ball for\\"
216         "each 100 coins collected.\\");
217
218     const char *s4 = _("Left and right mouse buttons rotate the view.");
219     const char *s5 = _("Hold Shift for faster view rotation.");
220     const char *s6 = _("Pause / Release Pointer");
221     const char *s7 = _("Exit / Cancel Menu");
222     const char *s8 = _("Chase View");
223     const char *s9 = _("Lazy View");
224     const char *sA = _("Manual View");
225     const char *sB = _("Comments?  Problems?  robert.kooima@gmail.com");
226
227     const char *k0 = _("Spacebar");
228     const char *k1 = _("Escape");
229     const char *k2 = SDL_GetKeyName(config_get_d(CONFIG_KEY_CAMERA_1));
230     const char *k3 = SDL_GetKeyName(config_get_d(CONFIG_KEY_CAMERA_2));
231     const char *k4 = SDL_GetKeyName(config_get_d(CONFIG_KEY_CAMERA_3));
232
233     int id, jd;
234
235     if ((id = gui_vstack(0)))
236     {
237         gui_multi(id, s0, GUI_SML, GUI_ALL, gui_wht, gui_wht);
238         gui_space(id);
239
240         if ((jd = gui_harray(id)))
241         {
242             gui_label(jd, s6, GUI_SML, GUI_NE, gui_wht, gui_wht);
243             gui_label(jd, k0, GUI_SML, GUI_NW, gui_yel, gui_yel);
244         }
245         if ((jd = gui_harray(id)))
246         {
247             gui_label(jd, s7, GUI_SML, 0,      gui_wht, gui_wht);
248             gui_label(jd, k1, GUI_SML, 0,      gui_yel, gui_yel);
249         }
250         if ((jd = gui_harray(id)))
251         {
252             gui_label(jd, s8, GUI_SML, 0,      gui_wht, gui_wht);
253             gui_label(jd, k2, GUI_SML, 0,      gui_yel, gui_yel);
254         }
255         if ((jd = gui_harray(id)))
256         {
257             gui_label(jd, s9, GUI_SML, 0,      gui_wht, gui_wht);
258             gui_label(jd, k3, GUI_SML, 0,      gui_yel, gui_yel);
259         }
260         if ((jd = gui_harray(id)))
261         {
262             gui_label(jd, sA, GUI_SML, GUI_SE, gui_wht, gui_wht);
263             gui_label(jd, k4, GUI_SML, GUI_SW, gui_yel, gui_yel);
264         }
265
266         gui_space(id);
267         gui_label(id, s4, GUI_SML, GUI_TOP, gui_wht, gui_wht);
268         gui_label(id, s5, GUI_SML, GUI_BOT, gui_wht, gui_wht);
269         gui_space(id);
270         gui_label(id, sB, GUI_SML, GUI_ALL, gui_wht, gui_wht);
271
272         gui_layout(id, 0, 0);
273     }
274     return id;
275 }
276
277 static int help_click(int b, int d)
278 {
279     return d ? goto_state(&st_title) : 1;
280 }
281
282 static int help_keybd(int c, int d)
283 {
284     return d ? goto_state(&st_title) : 1;
285 }
286
287 static int help_buttn(int b, int d)
288 {
289     return d ? goto_state(&st_title) : 1;
290 }
291
292 /*---------------------------------------------------------------------------*/
293
294 struct state st_title = {
295     title_enter,
296     title_leave,
297     shared_paint,
298     title_timer,
299     shared_point,
300     shared_stick,
301     shared_click,
302     title_keybd,
303     title_buttn,
304     1, 0
305 };
306
307 struct state st_help = {
308     help_enter,
309     shared_leave,
310     shared_paint,
311     shared_timer,
312     NULL,
313     NULL,
314     help_click,
315     help_keybd,
316     help_buttn,
317     1, 0
318 };