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