e6234295e307b12685b058c9b8afba29f2395ea9
[neverball] / ball / st_help.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 "game.h"
17 #include "audio.h"
18 #include "config.h"
19 #include "demo.h"
20
21 #include "st_shared.h"
22 #include "st_title.h"
23 #include "st_help.h"
24
25 /*---------------------------------------------------------------------------*/
26
27 #define HELP_BACK   0
28 #define HELP_RULE   1
29 #define HELP_CONT   2
30 #define HELP_MODE   3
31 #define HELP_TECH   4
32 #define HELP_DEMO_1 6
33 #define HELP_DEMO_2 7
34
35 static int tab = HELP_RULE;
36
37 /*---------------------------------------------------------------------------*/
38
39 static int help_action(int t)
40 {
41     audio_play(AUD_MENU, 1.0f);
42
43     switch (t)
44     {
45     case HELP_BACK:
46         tab = HELP_RULE;
47         return goto_state(&st_title);
48         break;
49
50     case HELP_DEMO_1:
51         if (demo_replay_init(config_data("gui/demo1.nbr"),
52                              NULL, NULL, NULL, NULL, NULL))
53             return goto_state(&st_help_demo);
54         break;
55
56     case HELP_DEMO_2:
57         if (demo_replay_init(config_data("gui/demo2.nbr"),
58                              NULL, NULL, NULL, NULL, NULL))
59             return goto_state(&st_help_demo);
60         break;
61
62     default:
63         tab = t;
64         return goto_state(&st_help);
65         break;
66     }
67     return 1;
68 }
69
70 /* -------------------------------------------------------------------------- */
71
72 static int help_button(int id, const char *text, int token)
73 {
74     int jd = gui_state(id, text, GUI_SML, token, (token == tab));
75
76     if (token == tab)
77         gui_focus(jd);
78
79     return jd;
80 }
81
82 static int help_menu(int id)
83 {
84     int jd;
85
86     gui_space(id);
87
88     if ((jd = gui_harray(id)))
89     {
90         help_button(jd, _("Techniques"), HELP_TECH);
91         help_button(jd, _("Modes"),      HELP_MODE);
92         help_button(jd, _("Controls"),   HELP_CONT);
93         help_button(jd, _("Rules"),      HELP_RULE);
94         help_button(jd, _("Back"),       HELP_BACK);
95     }
96     return jd;
97 }
98
99 /* -------------------------------------------------------------------------- */
100
101 static int help_rules(int id)
102 {
103     const char *s0 = _(
104         "Move the mouse or joystick\\"
105         "or use keyboard arrows to\\"
106         "tilt the floor causing the\\"
107         "ball to roll.\\");
108     const char *s1 = _(
109         "Roll over coins to collect\\"
110         "them.  Collect coins to\\"
111         "unlock the goal and finish\\"
112         "the level.\\");
113
114     int w = config_get_d(CONFIG_WIDTH);
115     int h = config_get_d(CONFIG_HEIGHT);
116
117     int jd, kd, ld;
118
119     if ((jd = gui_hstack(id)))
120     {
121         gui_filler(jd);
122
123         if ((kd = gui_varray(jd)))
124         {
125             if ((ld = gui_vstack(kd)))
126             {
127                 gui_space(ld);
128                 gui_multi(ld, s0, GUI_SML, GUI_ALL, gui_wht, gui_wht);
129                 gui_filler(ld);
130             }
131
132             if ((ld = gui_vstack(kd)))
133             {
134                 gui_space(ld);
135                 gui_multi(ld, s1, GUI_SML, GUI_ALL, gui_wht, gui_wht);
136                 gui_filler(ld);
137             }
138         }
139
140         gui_space(jd);
141
142         if ((kd = gui_varray(jd)))
143         {
144             if ((ld = gui_vstack(kd)))
145             {
146                 gui_space(ld);
147                 gui_image(ld, "gui/help1.jpg", 5 * w / 16, 5 * h / 16);
148                 gui_filler(ld);
149             }
150
151             if ((ld = gui_vstack(kd)))
152             {
153                 gui_space(ld);
154                 gui_image(ld, "gui/help2.jpg", 5 * w / 16, 5 * h / 16);
155                 gui_filler(ld);
156             }
157         }
158
159         gui_filler(jd);
160     }
161     return id;
162 }
163
164 static int help_controls(int id)
165 {
166     const char *s4 = _("Left and right mouse buttons rotate the view.");
167     const char *s5 = _("Hold Shift for faster view rotation.");
168     const char *s6 = _("Pause / Release Pointer");
169     const char *s7 = _("Exit / Cancel Menu");
170     const char *s8 = _("Chase View");
171     const char *s9 = _("Lazy View");
172     const char *sA = _("Manual View");
173     const char *sC = _("Screenshot");
174     
175     const char *k0 = _(SDL_GetKeyName((SDLKey) config_get_d(CONFIG_KEY_PAUSE)));
176     const char *k1 = _("Escape");
177     const char *k2 = SDL_GetKeyName((SDLKey) config_get_d(CONFIG_KEY_CAMERA_1));
178     const char *k3 = SDL_GetKeyName((SDLKey) config_get_d(CONFIG_KEY_CAMERA_2));
179     const char *k4 = SDL_GetKeyName((SDLKey) config_get_d(CONFIG_KEY_CAMERA_3));
180     const char *k6 = SDL_GetKeyName(SDLK_F10);
181
182     int jd;
183
184     gui_space(id);
185
186     if ((jd = gui_harray(id)))
187     {
188         gui_label(jd, s6, GUI_SML, GUI_NE, gui_wht, gui_wht);
189         gui_label(jd, k0, GUI_SML, GUI_NW, gui_yel, gui_yel);
190     }
191     if ((jd = gui_harray(id)))
192     {
193         gui_label(jd, s7, GUI_SML, 0,      gui_wht, gui_wht);
194         gui_label(jd, k1, GUI_SML, 0,      gui_yel, gui_yel);
195     }
196     if ((jd = gui_harray(id)))
197     {
198         gui_label(jd, s8, GUI_SML, 0,      gui_wht, gui_wht);
199         gui_label(jd, k2, GUI_SML, 0,      gui_yel, gui_yel);
200     }
201     if ((jd = gui_harray(id)))
202     {
203         gui_label(jd, s9, GUI_SML, 0,      gui_wht, gui_wht);
204         gui_label(jd, k3, GUI_SML, 0,      gui_yel, gui_yel);
205     }
206     if ((jd = gui_harray(id)))
207     {
208         gui_label(jd, sA, GUI_SML, 0,      gui_wht, gui_wht);
209         gui_label(jd, k4, GUI_SML, 0,      gui_yel, gui_yel);
210     }
211     if ((jd = gui_harray(id)))
212     {
213         gui_label(jd, sC, GUI_SML, 0,      gui_wht, gui_wht);
214         gui_label(jd, k6, GUI_SML, 0,      gui_yel, gui_yel);
215     }
216
217     gui_space(id);
218
219     gui_label(id, s4, GUI_SML, GUI_TOP, gui_wht, gui_wht);
220     gui_label(id, s5, GUI_SML, GUI_BOT, gui_wht, gui_wht);
221
222     return id;
223 }
224
225 static int help_modes(int id)
226 {
227     int jd, kd;
228
229     gui_space(id);
230
231     if ((jd = gui_hstack(id)))
232     {
233         gui_filler(jd);
234
235         if ((kd = gui_vstack(jd)))
236         {
237             gui_label(kd, _("Normal Mode"), GUI_SML, GUI_TOP, 0, 0);
238             gui_multi(kd,
239                       _("Finish a level before the time runs out.\\"
240                         "You need to collect coins in order to open the goal."),
241                       GUI_SML, GUI_BOT, gui_wht, gui_wht);
242
243             gui_space(kd);
244
245             gui_label(kd, _("Challenge Mode"), GUI_SML, GUI_TOP, 0, 0);
246             gui_multi(kd,
247                       _("Start playing from the first level of the set.\\"
248                         "You start with only four balls, do not lose them.\\"
249                         "Earn an extra ball for each 100 coins collected."),
250                       GUI_SML, GUI_BOT, gui_wht, gui_wht);
251         }
252
253         gui_filler(jd);
254     }
255     return id;
256 }
257
258 static int help_techniques(int id)
259 {
260     const char *s0 = _(
261         "Corners can be used to jump.\\"
262         "Get rolling and take aim\\"
263         "at the angle. You may be able\\"
264         "to reach new places.\\");
265     const char *s1 = _(
266         "Tilting in 2 directions increases\\"
267         "the slope. Use the manual view\\"
268         "and turn the camera by 45\\"
269         "degrees for best results.\\");
270
271     int w = config_get_d(CONFIG_WIDTH);
272     int h = config_get_d(CONFIG_HEIGHT);
273
274     int jd, kd, ld;
275
276     if ((jd = gui_hstack(id)))
277     {
278         gui_filler(jd);
279
280         if ((kd = gui_varray(jd)))
281         {
282             if ((ld = gui_vstack(kd)))
283             {
284                 gui_space(ld);
285                 gui_image(ld, "gui/help3.jpg", w / 4, h / 4);
286                 gui_state(ld, _("Watch demo"), GUI_SML, 0, 0);
287                 gui_filler(ld);
288
289                 gui_active(ld, HELP_DEMO_1, 0);
290             }
291
292             if ((ld = gui_vstack(kd)))
293             {
294                 gui_space(ld);
295                 gui_image(ld, "gui/help4.jpg", w / 4, h / 4);
296                 gui_state(ld, _("Watch demo"), GUI_SML, 0, 0);
297                 gui_filler(ld);
298
299                 gui_active(ld, HELP_DEMO_2, 0);
300             }
301         }
302
303         gui_space(jd);
304
305         if ((kd = gui_varray(jd)))
306         {
307             if ((ld = gui_vstack(kd)))
308             {
309                 gui_space(ld);
310                 gui_multi(ld, s0, GUI_SML, GUI_ALL, gui_wht, gui_wht);
311                 gui_filler(ld);
312             }
313
314             if ((ld = gui_vstack(kd)))
315             {
316                 gui_space(ld);
317                 gui_multi(ld, s1, GUI_SML, GUI_ALL, gui_wht, gui_wht);
318                 gui_filler(ld);
319             }
320         }
321
322         gui_filler(jd);
323     }
324     return id;
325 }
326
327 /* -------------------------------------------------------------------------- */
328
329 static int help_enter(void)
330 {
331     int id;
332
333     if ((id = gui_vstack(0)))
334     {
335         help_menu(id);
336
337         switch (tab)
338         {
339         case HELP_RULE: help_rules(id);      break;
340         case HELP_CONT: help_controls(id);   break;
341         case HELP_MODE: help_modes(id);      break;
342         case HELP_TECH: help_techniques(id); break;
343
344         default:
345             break;
346         }
347
348         gui_layout(id, 0, +1);
349     }
350     return id;
351 }
352
353 static int help_buttn(int b, int d)
354 {
355     if (d)
356     {
357         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
358             return help_action(gui_token(gui_click()));
359         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
360             return help_action(HELP_BACK);
361     }
362     return 1;
363 }
364
365 /*---------------------------------------------------------------------------*/
366
367 static int help_demo_enter(void)
368 {
369     game_set_fly(0.f);
370
371     return 0;
372 }
373
374 static void help_demo_leave(int id)
375 {
376     demo_replay_stop(0);
377 }
378
379 static void help_demo_paint(int id, float t)
380 {
381     game_draw(0, t);
382 }
383
384 static void help_demo_timer(int id, float dt)
385 {
386     game_step_fade(dt);
387
388     if (!demo_replay_step(dt))
389         goto_state(&st_help);
390 }
391
392 static int help_demo_buttn(int b, int d)
393 {
394     if (d)
395     {
396         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
397             return goto_state(&st_help);
398     }
399     return 1;
400 }
401 /*---------------------------------------------------------------------------*/
402
403 struct state st_help = {
404     help_enter,
405     shared_leave,
406     shared_paint,
407     shared_timer,
408     shared_point,
409     shared_stick,
410     shared_angle,
411     shared_click,
412     NULL,
413     help_buttn,
414     1, 0
415 };
416
417 struct state st_help_demo = {
418     help_demo_enter,
419     help_demo_leave,
420     help_demo_paint,
421     help_demo_timer,
422     NULL,
423     NULL,
424     NULL,
425     NULL,
426     NULL,
427     help_demo_buttn,
428     1, 0
429 };