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