remove disable prec and next button since it break keyboard navigation
[neverball] / ball / st_demo.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 "hud.h"
17 #include "set.h"
18 #include "game.h"
19 #include "demo.h"
20 #include "level.h"
21 #include "audio.h"
22 #include "solid.h"
23 #include "config.h"
24
25 #include "st_demo.h"
26 #include "st_title.h"
27
28 /*---------------------------------------------------------------------------*/
29
30 #define DEMO_BACK -1
31 #define DEMO_NEXT -2
32 #define DEMO_PREV -3
33
34 #define DEMO_LINE 4
35 #define DEMO_STEP 8
36
37 static int first = 0;
38 static int total = 0;
39
40 static float replay_time;
41 static float global_time;
42
43 /*---------------------------------------------------------------------------*/
44
45 static int demo_action(int i)
46 {
47     audio_play(AUD_MENU, 1.0f);
48
49     switch (i)
50     {
51     case DEMO_BACK:
52         return goto_state(&st_title);
53
54     case DEMO_NEXT:
55         first += DEMO_STEP;
56         return goto_state(&st_demo);
57         break;
58
59     case DEMO_PREV:
60         first -= DEMO_STEP;
61         return goto_state(&st_demo);
62         break;
63
64     default:
65         if (level_replay(demo_name(i)))
66             return goto_state(&st_demo_play);
67     }
68     return 1;
69 }
70
71 static void demo_replay(int id, int i)
72 {
73     int w = config_get_d(CONFIG_WIDTH);
74     int h = config_get_d(CONFIG_HEIGHT);
75     int jd;
76
77     if ((jd = gui_vstack(id)))
78     {
79         gui_space(jd);
80
81         gui_image(jd, demo_shot(i), w / 6, h / 6);
82         gui_state(jd, demo_name(i), GUI_SML, i, 0);
83
84         gui_active(jd, i, 0);
85     }
86 }
87
88 static int name_id;
89 static int time_id;
90 static int coin_id;
91 static int date_id;
92 static int mode_id;
93 static int player_id;
94
95 static void demo_status(int i)
96 {
97     int m = demo_mode(i);
98     char * ms;
99     switch (m)
100     {
101         case MODE_CHALLENGE: ms = _("Challenge"); break;
102         case MODE_NORMAL:    ms = _("Normal");    break;
103         case MODE_PRACTICE:  ms = _("Practice");  break;
104         default: ms = "???";
105     }
106     gui_set_label(name_id,   demo_name(i));
107     gui_set_label(date_id,   demo_str_date(i));
108     gui_set_label(player_id, demo_player(i));
109     gui_set_label(mode_id,   ms);
110     gui_set_count(coin_id,   demo_coins(i));
111     gui_set_clock(time_id,   demo_clock(i));
112 }
113
114 static int demo_enter(void)
115 {
116     int i, j;
117     int id, jd, kd, ld;
118
119     total = demo_scan();
120
121     if ((id = gui_vstack(0)))
122     {
123         if (total == 0)
124         {
125             gui_label(id, _("No Replay"), GUI_MED, GUI_ALL, 0,0);
126             gui_filler(id);
127             gui_multi(id, _("You can save replay of you games.\\Currently, there is no replay saved."), GUI_SML, GUI_ALL, gui_wht, gui_wht);
128             gui_filler(id);
129             gui_start(id, _("Back"), GUI_SML, DEMO_BACK, 0);
130         }
131     else
132     {
133         if ((jd = gui_hstack(id)))
134         {
135
136             ld = gui_label(jd, _("Select Replay"), GUI_SML, GUI_ALL, 0,0);
137             gui_filler(jd);
138
139             
140             
141             if (first + DEMO_STEP < total)
142                 gui_state(jd, _("Next"), GUI_SML, DEMO_NEXT, 0);
143
144             if (first > 0)
145                 gui_state(jd, _("Prev"), GUI_SML, DEMO_PREV, 0);
146             
147             gui_start(jd, _("Back"), GUI_SML, DEMO_BACK, 0);
148         }
149         if ((jd = gui_varray(id)))
150             for (i = first; i < first + DEMO_STEP ; i += DEMO_LINE)
151                 if ((kd = gui_harray(jd)))
152                 {
153                     for (j = i + DEMO_LINE - 1; j >= i; j--)
154                         if (j < total)
155                             demo_replay(kd, j);
156                         else
157                             gui_space(kd);
158                 }
159         gui_filler(id);
160         if ((jd = gui_hstack(id)))
161         {
162             if((kd = gui_vstack(jd)))
163             {
164                 if ((ld = gui_harray(kd)))
165                 {
166                     coin_id = gui_count(ld, 100,          GUI_SML, GUI_RGT);
167                     gui_label(ld, _("Coins"),             GUI_SML, GUI_LFT, gui_wht, gui_wht);
168                     time_id = gui_clock(ld, 35000,        GUI_SML, GUI_RGT);
169                     gui_label(ld, _("Time"),              GUI_SML, GUI_LFT, gui_wht, gui_wht);
170                     name_id = gui_label(ld, demo_name(0), GUI_SML, GUI_RGT, 0, 0);
171                 }
172                 if ((ld = gui_harray(kd)))
173                 {
174                     mode_id = gui_label(ld, "..............", GUI_SML, GUI_RGT, 0, 0);
175                     gui_label(ld, _("Mode"),                  GUI_SML, GUI_LFT, gui_wht, gui_wht);
176                     player_id = gui_label(ld, demo_player(0), GUI_SML, GUI_RGT, 0, 0);
177                 }
178                 date_id = gui_label(kd, demo_str_date(0),     GUI_SML, GUI_RGT, 0, 0);
179             }
180             if((kd = gui_vstack(jd)))
181             {
182                 gui_label(kd, _("Name"), GUI_SML, GUI_LFT, gui_wht, gui_wht);
183                 gui_label(kd, _("Player"), GUI_SML, GUI_LFT, gui_wht, gui_wht);
184                 gui_label(kd, _("Date"), GUI_SML, GUI_LFT, gui_wht, gui_wht);
185             }
186         }
187         demo_status(0);
188     }
189
190         gui_layout(id, 0, 0);
191     }
192
193     audio_music_fade_to(0.5f, "bgm/inter.ogg");
194
195     return id;
196 }
197
198 static void demo_leave(int id)
199 {
200     gui_delete(id);
201 }
202
203 static void demo_paint(int id, float st)
204 {
205     game_draw(0, st);
206     config_pop_matrix();
207     gui_paint(id);
208 }
209
210 static void demo_timer(int id, float dt)
211 {
212     gui_timer(id, dt);
213     audio_timer(dt);
214 }
215
216 static void demo_point(int id, int x, int y, int dx, int dy)
217 {
218     int jd = gui_point(id, x, y);
219     int i  = gui_token(jd);
220     gui_pulse(jd, 1.2f);
221     if (jd && i>=0)
222         demo_status(i);
223 }
224
225 static void demo_stick(int id, int a, int v)
226 {
227     if (config_tst_d(CONFIG_JOYSTICK_AXIS_X, a))
228         gui_pulse(gui_stick(id, v, 0), 1.2f);
229     if (config_tst_d(CONFIG_JOYSTICK_AXIS_Y, a))
230         gui_pulse(gui_stick(id, 0, v), 1.2f);
231 }
232
233 static int demo_click(int b, int d)
234 {
235     if (b <= 0 && d == 1)
236         return demo_action(gui_token(gui_click()));
237     return 1;
238 }
239
240 static int demo_buttn(int b, int d)
241 {
242     if (d)
243     {
244         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
245             return demo_click(0, 1);
246         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
247             return demo_action(DEMO_BACK);
248     }
249     return 1;
250 }
251
252 /*---------------------------------------------------------------------------*/
253
254 static int demo_play_enter(void)
255 {
256     int id;
257
258     if ((id = gui_label(0, _("Replay"), GUI_LRG, GUI_ALL, gui_blu, gui_grn)))
259     {
260         gui_layout(id, 0, 0);
261         gui_pulse(id, 1.2f);
262     }
263
264     global_time = -1.f;
265     replay_time =  0.f;
266
267     game_set_fly(0.f);
268
269     return id;
270 }
271
272 static void demo_play_leave(int id)
273 {
274     gui_delete(id);
275 }
276
277 static void demo_play_paint(int id, float st)
278 {
279     game_draw(0, st);
280     hud_paint();
281
282     if (time_state() < 1.f)
283         gui_paint(id);
284 }
285
286 static void demo_play_timer(int id, float dt)
287 {
288     float t;
289
290     game_step_fade(dt);
291     gui_timer(id, dt);
292     audio_timer(dt);
293
294     global_time += dt;
295     hud_timer(dt);
296
297     /* Spin or skip depending on how fast the demo wants to run. */
298
299     while (replay_time < global_time)
300         if (demo_replay_step(&t))
301         {
302             replay_time += t;
303         }
304         else 
305         {
306             goto_state(&st_demo_end);
307             break;
308         }
309 }
310
311 static int demo_play_buttn(int b, int d)
312 {
313     if (d)
314     {
315         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
316             return goto_state(&st_demo_end);
317     }
318     return 1;
319 }
320
321 /*---------------------------------------------------------------------------*/
322
323 #define DEMO_KEEP 0
324 #define DEMO_DEL  1
325
326 static int demo_end_action(int i)
327 {
328     audio_play(AUD_MENU, 1.0f);
329
330     if (i == DEMO_DEL)
331         return goto_state(&st_demo_del);
332
333     else
334     {
335         demo_replay_stop(0);
336         return goto_state(&st_demo);
337     }
338 }
339
340 static int demo_end_enter(void)
341 {
342     int id, jd, kd;
343
344     if ((id = gui_vstack(0)))
345     {
346         kd = gui_label(id, _("Replay Ends"), GUI_MED, GUI_ALL, gui_gry, gui_red);
347
348         if ((jd = gui_harray(id)))
349         {
350             gui_state(jd, _("Delete"), GUI_SML, DEMO_DEL,  0);
351             gui_start(jd, _("Keep"),   GUI_SML, DEMO_KEEP, 1);
352         }
353
354         gui_pulse(kd, 1.2f);
355         gui_layout(id, 0, 0);
356     }
357     audio_music_fade_out(2.0f);
358
359     return id;
360 }
361
362 static void demo_end_leave(int id)
363 {
364     gui_delete(id);
365 }
366
367 static void demo_end_paint(int id, float st)
368 {
369     game_draw(0, st);
370     gui_paint(id);
371 }
372
373 static void demo_end_timer(int id, float dt)
374 {
375     float g[3] = { 0.0f, -9.8f, 0.0f };
376
377     if (time_state() < 2.f)
378         game_step(g, dt, 0);
379                 
380     gui_timer(id, dt);
381     audio_timer(dt);
382 }
383
384 static void demo_end_point(int id, int x, int y, int dx, int dy)
385 {
386     gui_pulse(gui_point(id, x, y), 1.2f);
387 }
388
389 static void demo_end_stick(int id, int a, int v)
390 {
391     if (config_tst_d(CONFIG_JOYSTICK_AXIS_X, a))
392         gui_pulse(gui_stick(id, v, 0), 1.2f);
393     if (config_tst_d(CONFIG_JOYSTICK_AXIS_Y, a))
394         gui_pulse(gui_stick(id, 0, v), 1.2f);
395 }
396
397 static int demo_end_click(int b, int d)
398 {
399     if (d && b < 0)
400         return demo_end_action(gui_token(gui_click()));
401     return 1;
402 }
403
404 static int demo_end_buttn(int b, int d)
405 {
406     if (d)
407     {
408         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
409             return demo_end_action(gui_token(gui_click()));
410         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
411             return demo_end_action(DEMO_KEEP);
412     }
413     return 1;
414 }
415
416 /*---------------------------------------------------------------------------*/
417
418 static int demo_del_action(int i)
419 {
420     audio_play(AUD_MENU, 1.0f);
421
422     demo_replay_stop(i == DEMO_DEL);
423     return goto_state(&st_demo);
424 }
425
426 static int demo_del_enter(void)
427 {
428     int id, jd, kd;
429
430     if ((id = gui_vstack(0)))
431     {
432         kd = gui_label(id, _("Delete Replay?"), GUI_MED, GUI_ALL, gui_red, gui_red);
433
434         if ((jd = gui_harray(id)))
435         {
436             gui_state(jd, _("Yes"), GUI_SML, DEMO_DEL,  0);
437             gui_start(jd, _("No"),  GUI_SML, DEMO_KEEP, 1);
438         }
439
440         gui_pulse(kd, 1.2f);
441         gui_layout(id, 0, 0);
442     }
443     audio_music_fade_out(2.0f);
444
445     return id;
446 }
447
448 static void demo_del_leave(int id)
449 {
450     gui_delete(id);
451 }
452
453 static void demo_del_paint(int id, float st)
454 {
455     game_draw(0, st);
456     gui_paint(id);
457 }
458
459 static void demo_del_timer(int id, float dt)
460 {
461     gui_timer(id, dt);
462     audio_timer(dt);
463 }
464
465 static void demo_del_point(int id, int x, int y, int dx, int dy)
466 {
467     gui_pulse(gui_point(id, x, y), 1.2f);
468 }
469
470 static void demo_del_stick(int id, int a, int v)
471 {
472     if (config_tst_d(CONFIG_JOYSTICK_AXIS_X, a))
473         gui_pulse(gui_stick(id, v, 0), 1.2f);
474     if (config_tst_d(CONFIG_JOYSTICK_AXIS_Y, a))
475         gui_pulse(gui_stick(id, 0, v), 1.2f);
476 }
477
478 static int demo_del_click(int b, int d)
479 {
480     if (d && b < 0)
481         return demo_del_action(gui_token(gui_click()));
482     return 1;
483 }
484
485 static int demo_del_buttn(int b, int d)
486 {
487     if (d)
488     {
489         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
490             return demo_del_action(gui_token(gui_click()));
491         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
492             return demo_del_action(DEMO_KEEP);
493     }
494     return 1;
495 }
496
497 /*---------------------------------------------------------------------------*/
498
499 struct state st_demo = {
500     demo_enter,
501     demo_leave,
502     demo_paint,
503     demo_timer,
504     demo_point,
505     demo_stick,
506     demo_click,
507     NULL,
508     demo_buttn,
509     0
510 };
511
512 struct state st_demo_play = {
513     demo_play_enter,
514     demo_play_leave,
515     demo_play_paint,
516     demo_play_timer,
517     NULL,
518     NULL,
519     NULL,
520     NULL,
521     demo_play_buttn,
522     0
523 };
524
525 struct state st_demo_end = {
526     demo_end_enter,
527     demo_end_leave,
528     demo_end_paint,
529     demo_end_timer,
530     demo_end_point,
531     demo_end_stick,
532     demo_end_click,
533     NULL,
534     demo_end_buttn,
535     1, 0
536 };
537
538 struct state st_demo_del = {
539     demo_del_enter,
540     demo_del_leave,
541     demo_del_paint,
542     demo_del_timer,
543     demo_del_point,
544     demo_del_stick,
545     demo_del_click,
546     NULL,
547     demo_del_buttn,
548     1, 0
549 };