6106086380e3d6d2254e2518d5479efc0579234d
[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 struct state st_help_demo;
28
29 /*---------------------------------------------------------------------------*/
30
31 #define HELP_BACK   0
32 #define HELP_RULE   1
33 #define HELP_CONT   2
34 #define HELP_MODE   3
35 #define HELP_TECH   4
36 #define HELP_DEMO_1 6
37 #define HELP_DEMO_2 7
38
39 static int tab = HELP_RULE;
40
41 /*---------------------------------------------------------------------------*/
42
43 static int help_action(int t)
44 {
45     audio_play(AUD_MENU, 1.0f);
46
47     switch (t)
48     {
49     case HELP_BACK:
50         tab = HELP_RULE;
51         return goto_state(&st_title);
52         break;
53
54     case HELP_DEMO_1:
55         demo_replay_init(config_data("gui/demo1.nbr"), NULL);
56         return goto_state(&st_help_demo);
57         break;
58
59     case HELP_DEMO_2:
60         demo_replay_init(config_data("gui/demo2.nbr"), NULL);
61         return goto_state(&st_help_demo);
62         break;
63
64     default:
65         tab = t;
66         return goto_state(&st_help);
67         break;
68     }
69     return 0;
70 }
71
72 /* -------------------------------------------------------------------------- */
73
74 static int help_button(int id, const char *text, int token)
75 {
76     int jd = gui_state(id, text, GUI_SML, token, (token == tab));
77
78     if (token == tab)
79         gui_focus(jd);
80
81     return jd;
82 }
83
84 static int help_menu(int id)
85 {
86     int jd;
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     const char *sD = _("Toggle Fullscreen");
175
176     const char *k0 = _("Spacebar");
177     const char *k1 = _("Escape");
178     const char *k2 = SDL_GetKeyName(config_get_d(CONFIG_KEY_CAMERA_1));
179     const char *k3 = SDL_GetKeyName(config_get_d(CONFIG_KEY_CAMERA_2));
180     const char *k4 = SDL_GetKeyName(config_get_d(CONFIG_KEY_CAMERA_3));
181     const char *k6 = SDL_GetKeyName(SDLK_F10);
182     const char *k7 = SDL_GetKeyName(SDLK_F11);
183
184     int jd;
185
186     gui_space(id);
187
188     if ((jd = gui_harray(id)))
189     {
190         gui_label(jd, s6, GUI_SML, GUI_NE, gui_wht, gui_wht);
191         gui_label(jd, k0, GUI_SML, GUI_NW, gui_yel, gui_yel);
192     }
193     if ((jd = gui_harray(id)))
194     {
195         gui_label(jd, s7, GUI_SML, 0,      gui_wht, gui_wht);
196         gui_label(jd, k1, GUI_SML, 0,      gui_yel, gui_yel);
197     }
198     if ((jd = gui_harray(id)))
199     {
200         gui_label(jd, s8, GUI_SML, 0,      gui_wht, gui_wht);
201         gui_label(jd, k2, GUI_SML, 0,      gui_yel, gui_yel);
202     }
203     if ((jd = gui_harray(id)))
204     {
205         gui_label(jd, s9, GUI_SML, 0,      gui_wht, gui_wht);
206         gui_label(jd, k3, GUI_SML, 0,      gui_yel, gui_yel);
207     }
208     if ((jd = gui_harray(id)))
209     {
210         gui_label(jd, sA, GUI_SML, 0,      gui_wht, gui_wht);
211         gui_label(jd, k4, GUI_SML, 0,      gui_yel, gui_yel);
212     }
213     if ((jd = gui_harray(id)))
214     {
215         gui_label(jd, sC, GUI_SML, 0,      gui_wht, gui_wht);
216         gui_label(jd, k6, GUI_SML, 0,      gui_yel, gui_yel);
217     }
218     if ((jd = gui_harray(id)))
219     {
220         gui_label(jd, sD, GUI_SML, GUI_SE, gui_wht, gui_wht);
221         gui_label(jd, k7, GUI_SML, GUI_SW, gui_yel, gui_yel);
222     }
223
224     gui_space(id);
225
226     gui_label(id, s4, GUI_SML, GUI_TOP, gui_wht, gui_wht);
227     gui_label(id, s5, GUI_SML, GUI_BOT, gui_wht, gui_wht);
228
229     return id;
230 }
231
232 static int help_modes(int id)
233 {
234     int jd, kd;
235
236     gui_space(id);
237
238     if ((jd = gui_hstack(id)))
239     {
240         gui_filler(jd);
241
242         if ((kd = gui_vstack(jd)))
243         {
244             gui_label(kd, _("Normal Mode"), GUI_SML, GUI_TOP, 0, 0);
245             gui_multi(kd,
246                       _("Finish a level before the time runs out.\\"
247                         "You need to collect coins in order to open the goal."),
248                       GUI_SML, GUI_BOT, gui_wht, gui_wht);
249
250             gui_space(kd);
251
252             gui_label(kd, _("Practice Mode"), GUI_SML, GUI_TOP, 0, 0);
253             gui_multi(kd,
254                       _("Play without time limit or coin constraint.\\"
255                         "Levels cannot be unlocked in this mode."),
256                       GUI_SML, GUI_BOT, gui_wht, gui_wht);
257
258             gui_space(kd);
259
260             gui_label(kd, _("Challenge Mode"), GUI_SML, GUI_TOP, 0, 0);
261             gui_multi(kd,
262                       _("Start playing from the first level of the set.\\"
263                         "You start with only four balls, do not lose them.\\"
264                         "Earn an extra ball for each 100 coins collected."),
265                       GUI_SML, GUI_BOT, gui_wht, gui_wht);
266         }
267
268         gui_filler(jd);
269     }
270     return id;
271 }
272
273 static int help_techniques(int id)
274 {
275     const char *s0 = _(
276         "Corners can be used to jump.\\"
277         "Get rolling and take aim\\"
278         "at the angle. You may be able\\"
279         "to reach new places.\\");
280     const char *s1 = _(
281         "Tilting in 2 directions increases\\"
282         "the slope. Use the manual view\\"
283         "and turn the camera by 45\\"
284         "degrees for best results.\\");
285
286     int w = config_get_d(CONFIG_WIDTH);
287     int h = config_get_d(CONFIG_HEIGHT);
288
289     int jd, kd, ld;
290
291     if ((jd = gui_hstack(id)))
292     {
293         gui_filler(jd);
294
295         if ((kd = gui_varray(jd)))
296         {
297             if ((ld = gui_vstack(kd)))
298             {
299                 gui_space(ld);
300                 gui_multi(ld, s0, GUI_SML, GUI_ALL, gui_wht, gui_wht);
301                 gui_filler(ld);
302             }
303
304             if ((ld = gui_vstack(kd)))
305             {
306                 gui_space(ld);
307                 gui_multi(ld, s1, GUI_SML, GUI_ALL, gui_wht, gui_wht);
308                 gui_filler(ld);
309             }
310         }
311
312         gui_space(jd);
313
314         if ((kd = gui_varray(jd)))
315         {
316             if ((ld = gui_vstack(kd)))
317             {
318                 gui_space(ld);
319                 gui_image(ld, "gui/help3.jpg", w / 4, h / 4);
320                 gui_state(ld, _("Watch demo"), GUI_SML, 0, 0);
321                 gui_filler(ld);
322
323                 gui_active(ld, HELP_DEMO_1, 0);
324             }
325
326             if ((ld = gui_vstack(kd)))
327             {
328                 gui_space(ld);
329                 gui_image(ld, "gui/help4.jpg", w / 4, h / 4);
330                 gui_state(ld, _("Watch demo"), GUI_SML, 0, 0);
331                 gui_filler(ld);
332
333                 gui_active(ld, HELP_DEMO_2, 0);
334             }
335         }
336         
337         gui_filler(jd);
338     }
339     return id;
340 }
341
342 /* -------------------------------------------------------------------------- */
343
344 static int help_enter(void)
345 {
346     int id;
347
348     if ((id = gui_vstack(0)))
349     {
350         help_menu(id);
351
352         switch (tab)
353         {
354         case HELP_RULE:
355             help_rules(id);
356             break;
357
358         case HELP_CONT:
359             help_controls(id);
360             break;
361
362         case HELP_MODE:
363             help_modes(id);
364             break;
365
366         case HELP_TECH:
367             help_techniques(id);
368             break;
369
370         default:
371             break;
372         }
373         gui_layout(id, 0, +1);
374     }
375     return id;
376 }
377
378 static int help_buttn(int b, int d)
379 {
380     if (d)
381     {
382         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
383             return help_action(gui_token(gui_click()));
384         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
385             return help_action(HELP_BACK);
386     }
387     return 1;
388 }
389
390 /*---------------------------------------------------------------------------*/
391
392 static float real_time;
393 static float demo_time;
394
395 static int help_demo_enter(void)
396 {
397     real_time = -1.f;
398     demo_time =  0.f;
399
400     game_set_fly(0.f);
401
402     return 0;
403 }
404
405 static void help_demo_leave(int id)
406 {
407     demo_replay_stop(0);
408 }
409
410 static void help_demo_paint(int id, float st)
411 {
412     game_draw(0, st);
413 }
414
415 static void help_demo_timer(int id, float dt)
416 {
417     float t;
418
419     real_time += dt;
420
421     game_step_fade(dt);
422
423     while (demo_time < real_time)
424         if (demo_replay_step(&t))
425             demo_time += t;
426         else
427         {
428             goto_state(&st_help);
429             break;
430         }
431 }
432
433 static int help_demo_buttn(int b, int d)
434 {
435     if (d)
436     {
437         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
438             return goto_state(&st_help);
439     }
440     return 1;
441 }
442 /*---------------------------------------------------------------------------*/
443
444 struct state st_help = {
445     help_enter,
446     shared_leave,
447     shared_paint,
448     shared_timer,
449     shared_point,
450     shared_stick,
451     shared_click,
452     NULL,
453     help_buttn,
454     1, 0
455 };
456
457 struct state st_help_demo = {
458     help_demo_enter,
459     help_demo_leave,
460     help_demo_paint,
461     help_demo_timer,
462     NULL,
463     NULL,
464     NULL,
465     NULL,
466     help_demo_buttn,
467     1, 0
468 };