update hard path to title.sol
[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 1;
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_image(ld, "gui/help3.jpg", w / 4, h / 4);
301                 gui_state(ld, _("Watch demo"), GUI_SML, 0, 0);
302                 gui_filler(ld);
303
304                 gui_active(ld, HELP_DEMO_1, 0);
305             }
306
307             if ((ld = gui_vstack(kd)))
308             {
309                 gui_space(ld);
310                 gui_image(ld, "gui/help4.jpg", w / 4, h / 4);
311                 gui_state(ld, _("Watch demo"), GUI_SML, 0, 0);
312                 gui_filler(ld);
313
314                 gui_active(ld, HELP_DEMO_2, 0);
315             }
316         }
317
318         gui_space(jd);
319
320         if ((kd = gui_varray(jd)))
321         {
322             if ((ld = gui_vstack(kd)))
323             {
324                 gui_space(ld);
325                 gui_multi(ld, s0, GUI_SML, GUI_ALL, gui_wht, gui_wht);
326                 gui_filler(ld);
327             }
328
329             if ((ld = gui_vstack(kd)))
330             {
331                 gui_space(ld);
332                 gui_multi(ld, s1, GUI_SML, GUI_ALL, gui_wht, gui_wht);
333                 gui_filler(ld);
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         gui_space(id);
351
352         help_menu(id);
353
354         switch (tab)
355         {
356         case HELP_RULE:
357             help_rules(id);
358             break;
359
360         case HELP_CONT:
361             help_controls(id);
362             break;
363
364         case HELP_MODE:
365             help_modes(id);
366             break;
367
368         case HELP_TECH:
369             help_techniques(id);
370             break;
371
372         default:
373             break;
374         }
375         gui_layout(id, 0, +1);
376     }
377     return id;
378 }
379
380 static int help_buttn(int b, int d)
381 {
382     if (d)
383     {
384         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
385             return help_action(gui_token(gui_click()));
386         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
387             return help_action(HELP_BACK);
388     }
389     return 1;
390 }
391
392 /*---------------------------------------------------------------------------*/
393
394 static float real_time;
395 static float demo_time;
396
397 static int help_demo_enter(void)
398 {
399     real_time = -1.f;
400     demo_time =  0.f;
401
402     game_set_fly(0.f);
403
404     return 0;
405 }
406
407 static void help_demo_leave(int id)
408 {
409     demo_replay_stop(0);
410 }
411
412 static void help_demo_paint(int id, float st)
413 {
414     game_draw(0, st);
415 }
416
417 static void help_demo_timer(int id, float dt)
418 {
419     float t;
420
421     real_time += dt;
422
423     game_step_fade(dt);
424
425     while (demo_time < real_time)
426         if (demo_replay_step(&t))
427             demo_time += t;
428         else
429         {
430             goto_state(&st_help);
431             break;
432         }
433 }
434
435 static int help_demo_buttn(int b, int d)
436 {
437     if (d)
438     {
439         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
440             return goto_state(&st_help);
441     }
442     return 1;
443 }
444 /*---------------------------------------------------------------------------*/
445
446 struct state st_help = {
447     help_enter,
448     shared_leave,
449     shared_paint,
450     shared_timer,
451     shared_point,
452     shared_stick,
453     shared_click,
454     NULL,
455     help_buttn,
456     1, 0
457 };
458
459 struct state st_help_demo = {
460     help_demo_enter,
461     help_demo_leave,
462     help_demo_paint,
463     help_demo_timer,
464     NULL,
465     NULL,
466     NULL,
467     NULL,
468     help_demo_buttn,
469     1, 0
470 };