I18N
[neverball] / putt / st_all.c
1 /*   
2  * Copyright (C) 2003 Robert Kooima
3  *
4  * NEVERPUTT 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 <math.h>
16
17 #include "hud.h"
18 #include "back.h"
19 #include "geom.h"
20 #include "gui.h"
21 #include "vec3.h"
22 #include "game.h"
23 #include "hole.h"
24 #include "audio.h"
25 #include "course.h"
26 #include "config.h"
27
28 #include "st_all.h"
29 #include "st_conf.h"
30
31 /*---------------------------------------------------------------------------*/
32
33 static char *number(int i)
34 {
35     static char str[MAXSTR];
36
37     sprintf(str, "%02d", i);
38
39     return str;
40 }
41
42 static int score_card(const char  *title,
43                       const float *c0,
44                       const float *c1)
45 {
46     int id, jd, kd, ld;
47
48     int p1 = (curr_party() >= 1) ? 1 : 0, l1 = (curr_party() == 1) ? 1 : 0;
49     int p2 = (curr_party() >= 2) ? 1 : 0, l2 = (curr_party() == 2) ? 1 : 0;
50     int p3 = (curr_party() >= 3) ? 1 : 0, l3 = (curr_party() == 3) ? 1 : 0;
51     int p4 = (curr_party() >= 4) ? 1 : 0, l4 = (curr_party() == 4) ? 1 : 0;
52
53     int i;
54     int n = curr_count() - 1;
55     int m = curr_count() / 2;
56
57     if ((id = gui_vstack(0)))
58     {
59         gui_label(id, title, GUI_MED, GUI_ALL, c0, c1);
60         gui_space(id);
61
62         if ((jd = gui_hstack(id)))
63         {
64             if ((kd = gui_varray(jd)))
65             { 
66                 if (p1) gui_label(kd, _("O"),         0, GUI_NE, 0, 0);
67                 if (p1) gui_label(kd, hole_out(0), 0, 0,           gui_wht, gui_wht);
68                 if (p1) gui_label(kd, hole_out(1), 0, GUI_SE * l1, gui_red, gui_wht);
69                 if (p2) gui_label(kd, hole_out(2), 0, GUI_SE * l2, gui_grn, gui_wht);
70                 if (p3) gui_label(kd, hole_out(3), 0, GUI_SE * l3, gui_blu, gui_wht);
71                 if (p4) gui_label(kd, hole_out(4), 0, GUI_SE * l4, gui_yel, gui_wht);
72             }
73
74             if ((kd = gui_harray(jd)))
75                 for (i = m; i > 0; i--)
76                     if ((ld = gui_varray(kd)))
77                     {
78                         if (p1) gui_label(ld, number(i), 0, (i == 1) ? GUI_NW : 0, 0, 0);
79                         if (p1) gui_label(ld, hole_score(i, 0), 0, 0, gui_wht, gui_wht);
80                         if (p1) gui_label(ld, hole_score(i, 1), 0, 0, gui_red, gui_wht);
81                         if (p2) gui_label(ld, hole_score(i, 2), 0, 0, gui_grn, gui_wht);
82                         if (p3) gui_label(ld, hole_score(i, 3), 0, 0, gui_blu, gui_wht);
83                         if (p4) gui_label(ld, hole_score(i, 4), 0, 0, gui_yel, gui_wht);
84                     }
85             if ((kd = gui_varray(jd)))
86             {
87                 gui_filler(kd);
88                 if (p1) gui_label(kd, _("Par"), 0, GUI_NW,      gui_wht, gui_wht);
89                 if (p1) gui_label(kd, _("P1"),  0, GUI_SW * l1, gui_red, gui_wht);
90                 if (p2) gui_label(kd, _("P2"),  0, GUI_SW * l2, gui_grn, gui_wht);
91                 if (p3) gui_label(kd, _("P3"),  0, GUI_SW * l3, gui_blu, gui_wht);
92                 if (p4) gui_label(kd, _("P4"),  0, GUI_SW * l4, gui_yel, gui_wht);
93             }
94         }
95
96         gui_space(id);
97
98         if ((jd = gui_hstack(id)))
99         {
100             if ((kd = gui_varray(jd)))
101             {
102                 if (p1) gui_label(kd, _("Tot"),    0, GUI_TOP, 0, 0);
103                 if (p1) gui_label(kd, hole_tot(0), 0, 0,           gui_wht, gui_wht);
104                 if (p1) gui_label(kd, hole_tot(1), 0, GUI_BOT * l1, gui_red, gui_wht);
105                 if (p2) gui_label(kd, hole_tot(2), 0, GUI_BOT * l2, gui_grn, gui_wht);
106                 if (p3) gui_label(kd, hole_tot(3), 0, GUI_BOT * l3, gui_blu, gui_wht);
107                 if (p4) gui_label(kd, hole_tot(4), 0, GUI_BOT * l4, gui_yel, gui_wht);
108             }
109             if ((kd = gui_varray(jd)))
110             {
111                 if (p1) gui_label(kd, _("I"),     0, GUI_NE, 0, 0);
112                 if (p1) gui_label(kd, hole_in(0), 0, 0,           gui_wht, gui_wht);
113                 if (p1) gui_label(kd, hole_in(1), 0, GUI_SE * l1, gui_red, gui_wht);
114                 if (p2) gui_label(kd, hole_in(2), 0, GUI_SE * l2, gui_grn, gui_wht);
115                 if (p3) gui_label(kd, hole_in(3), 0, GUI_SE * l3, gui_blu, gui_wht);
116                 if (p4) gui_label(kd, hole_in(4), 0, GUI_SE * l4, gui_yel, gui_wht);
117             }
118             if ((kd = gui_harray(jd)))
119                 for (i = n; i > m; i--)
120                     if ((ld = gui_varray(kd)))
121                     {
122                         if (p1) gui_label(ld, number(i), 0, (i == m+1) ? GUI_NW : 0, 0, 0);
123                         if (p1) gui_label(ld, hole_score(i, 0), 0, 0, gui_wht, gui_wht);
124                         if (p1) gui_label(ld, hole_score(i, 1), 0, 0, gui_red, gui_wht);
125                         if (p2) gui_label(ld, hole_score(i, 2), 0, 0, gui_grn, gui_wht);
126                         if (p3) gui_label(ld, hole_score(i, 3), 0, 0, gui_blu, gui_wht);
127                         if (p4) gui_label(ld, hole_score(i, 4), 0, 0, gui_yel, gui_wht);
128                     }
129             if ((kd = gui_varray(jd)))
130             {
131                 gui_filler(kd);
132                 if (p1) gui_label(kd, _("Par"), 0, GUI_NW,      gui_wht, gui_wht);
133                 if (p1) gui_label(kd, _("P1"),  0, GUI_SW * l1, gui_red, gui_wht);
134                 if (p2) gui_label(kd, _("P2"),  0, GUI_SW * l2, gui_grn, gui_wht);
135                 if (p3) gui_label(kd, _("P3"),  0, GUI_SW * l3, gui_blu, gui_wht);
136                 if (p4) gui_label(kd, _("P4"),  0, GUI_SW * l4, gui_yel, gui_wht);
137             }
138         }
139
140         gui_layout(id, 0, 0);
141     }
142
143     return id;
144 }
145
146 /*---------------------------------------------------------------------------*/
147
148 #define TITLE_PLAY 1
149 #define TITLE_CONF 2
150 #define TITLE_EXIT 3
151
152 static int title_action(int i)
153 {
154     audio_play(AUD_MENU, 1.0f);
155
156     switch (i)
157     {
158     case TITLE_PLAY: return goto_state(&st_course);
159     case TITLE_CONF: return goto_state(&st_conf);
160     case TITLE_EXIT: return 0;
161     }
162     return 1;
163 }
164
165 static int title_enter(void)
166 {
167     int id, jd, kd;
168
169     /* Build the title GUI. */
170
171     if ((id = gui_vstack(0)))
172     {
173         gui_label(id, _("Neverputt"), GUI_LRG, GUI_ALL, 0, 0);
174         gui_space(id);
175
176         if ((jd = gui_harray(id)))
177         {
178             gui_filler(jd);
179
180             if ((kd = gui_varray(jd)))
181             {
182                 gui_start(kd, _("Play"),    GUI_MED, TITLE_PLAY, 1);
183                 gui_state(kd, _("Options"), GUI_MED, TITLE_CONF, 0);
184                 gui_state(kd, _("Exit"),    GUI_MED, TITLE_EXIT, 0);
185             }
186
187             gui_filler(jd);
188         }
189         gui_layout(id, 0, 0);
190     }
191
192     course_init();
193     course_rand();
194
195     return id;
196 }
197
198 static void title_leave(int id)
199 {
200     gui_delete(id);
201 }
202
203 static void title_paint(int id, float st)
204 {
205     game_draw(0);
206     gui_paint(id);
207 }
208
209 static void title_timer(int id, float dt)
210 {
211     float g[3] = { 0.f, 0.f, 0.f };
212
213     game_step(g, dt);
214     game_set_fly(fcosf(time_state() / 10.f));
215
216     gui_timer(id, dt);
217     audio_timer(dt);
218 }
219
220 static void title_point(int id, int x, int y, int dx, int dy)
221 {
222     gui_pulse(gui_point(id, x, y), 1.2f);
223 }
224
225 static int title_click(int b, int d)
226 {
227     return (d && b < 0) ? title_action(gui_token(gui_click())) : 1;
228 }
229
230 static int title_keybd(int c, int d)
231 {
232     return (d && c == SDLK_ESCAPE) ? 0 : 1;
233 }
234
235 /*---------------------------------------------------------------------------*/
236
237 static int desc_id;
238
239 static int course_action(int i)
240 {
241     if (course_exists(i))
242     {
243         course_goto(i);
244         goto_state(&st_party);
245     }
246     if (i < 0)
247         goto_state(&st_title);
248
249     return 1;
250 }
251
252 static int course_enter(void)
253 {
254     int w = config_get_d(CONFIG_WIDTH);
255     int h = config_get_d(CONFIG_HEIGHT);
256
257     int id, jd, i, n = course_count(), m = n + 2;
258
259     if ((id = gui_vstack(0)))
260     {
261         gui_label(id, _("Select Course"), GUI_MED, GUI_ALL, 0, 0);
262         gui_space(id);
263
264         if ((jd = gui_hstack(id)))
265         {
266             gui_filler(jd);
267             for (i = n - 1; i >= 0; i--)
268                 gui_active(gui_image(jd, course_shot(i), w / m, h / m), i, 0);
269             gui_filler(jd);
270         }
271
272         gui_space(id);
273         desc_id = gui_multi(id, _(course_desc(0)), GUI_SML, GUI_ALL, gui_yel, gui_wht);
274         gui_space(id);
275
276         if ((jd = gui_hstack(id)))
277         {
278             gui_filler(jd);
279             gui_state(jd, _("Back"), GUI_SML, -1, 0);
280         }
281
282         gui_layout(id, 0, 0);
283     }
284
285     audio_music_fade_to(0.5f, "bgm/inter.ogg");
286
287     return id;
288 }
289
290 static void course_leave(int id)
291 {
292     gui_delete(id);
293 }
294
295 static void course_paint(int id, float st)
296 {
297     game_draw(0);
298     gui_paint(id);
299 }
300
301 static void course_timer(int id, float dt)
302 {
303     gui_timer(id, dt);
304     audio_timer(dt);
305 }
306
307 static void course_point(int id, int x, int y, int dx, int dy)
308 {
309     int jd;
310
311     if ((jd = gui_point(id, x, y)))
312     {
313         int i = gui_token(jd);
314         if (course_exists(i))
315             gui_set_multi(desc_id, _(course_desc(i)));
316         gui_pulse(jd, 1.2f);
317     }
318 }
319
320 static int course_click(int b, int d)
321 {
322     return (d && b < 0) ? course_action(gui_token(gui_click())) : 1;
323 }
324
325 static int course_keybd(int c, int d)
326 {
327     return (d && c == SDLK_ESCAPE) ? goto_state(&st_title) : 1;
328 }
329
330 /*---------------------------------------------------------------------------*/
331
332 #define PARTY_T 0
333 #define PARTY_1 1
334 #define PARTY_2 2
335 #define PARTY_3 3
336 #define PARTY_4 4
337 #define PARTY_B 5
338
339 static int party_action(int i)
340 {
341     switch (i)
342     {
343     case PARTY_1:
344         audio_play(AUD_MENU, 1.f);
345         hole_goto(1, 1);
346         goto_state(&st_next);
347         break;
348     case PARTY_2:
349         audio_play(AUD_MENU, 1.f);
350         hole_goto(1, 2);
351         goto_state(&st_next);
352         break;
353     case PARTY_3:
354         audio_play(AUD_MENU, 1.f);
355         hole_goto(1, 3);
356         goto_state(&st_next);
357         break;
358     case PARTY_4:
359         audio_play(AUD_MENU, 1.f);
360         hole_goto(1, 4);
361         goto_state(&st_next);
362         break;
363     case PARTY_B:
364         audio_play(AUD_MENU, 1.f);
365         goto_state(&st_course);
366         break;
367     }
368     return 1;
369 }
370
371 static int party_enter(void)
372 {
373     int id, jd;
374
375     if ((id = gui_vstack(0)))
376     {
377         gui_label(id, _("Players?"), GUI_MED, GUI_ALL, 0, 0);
378         gui_space(id);
379
380         if ((jd = gui_harray(id)))
381         {
382             int p4 = gui_state(jd, "4", GUI_LRG, PARTY_4, 0);
383             int p3 = gui_state(jd, "3", GUI_LRG, PARTY_3, 0);
384             int p2 = gui_state(jd, "2", GUI_LRG, PARTY_2, 0);
385             int p1 = gui_state(jd, "1", GUI_LRG, PARTY_1, 0);
386
387             gui_set_color(p1, gui_red, gui_wht);
388             gui_set_color(p2, gui_grn, gui_wht);
389             gui_set_color(p3, gui_blu, gui_wht);
390             gui_set_color(p4, gui_yel, gui_wht);
391         }
392
393         gui_space(id);
394
395         if ((jd = gui_hstack(id)))
396         {
397             gui_filler(jd);
398             gui_state(jd, _("Back"), GUI_SML, PARTY_B, 0);
399         }
400
401         gui_layout(id, 0, 0);
402     }
403
404     return id;
405 }
406
407 static void party_leave(int id)
408 {
409     gui_delete(id);
410 }
411
412 static void party_paint(int id, float st)
413 {
414     game_draw(0);
415     gui_paint(id);
416 }
417
418 static void party_timer(int id, float dt)
419 {
420     gui_timer(id, dt);
421     audio_timer(dt);
422 }
423
424 static void party_point(int id, int x, int y, int dx, int dy)
425 {
426     gui_pulse(gui_point(id, x, y), 1.2f);
427 }
428
429 static int party_click(int b, int d)
430 {
431     return (d && b < 0) ? party_action(gui_token(gui_click())) : 1;
432 }
433
434 static int party_keybd(int c, int d)
435 {
436     return (d && c == SDLK_ESCAPE) ? goto_state(&st_course) : 1;
437 }
438
439 /*---------------------------------------------------------------------------*/
440
441 static int num = 0;
442
443 static int next_enter(void)
444 {
445     int id;
446     char str[MAXSTR];
447
448     sprintf(str, _("Hole %02d"), curr_hole());
449
450     if ((id = gui_vstack(0)))
451     {
452         gui_label(id, str, GUI_MED, GUI_ALL, 0, 0);
453         gui_space(id);
454
455         gui_label(id, _("Player"), GUI_SML, GUI_TOP, 0, 0);
456
457         switch (curr_player())
458         {
459         case 1:
460             gui_label(id, "1", GUI_LRG, GUI_BOT, gui_red, gui_wht);
461             if (curr_party() > 1) audio_play(AUD_PLAYER1, 1.f);
462             break;
463         case 2:
464             gui_label(id, "2", GUI_LRG, GUI_BOT, gui_grn, gui_wht);
465             if (curr_party() > 1) audio_play(AUD_PLAYER2, 1.f);
466             break;
467         case 3:
468             gui_label(id, "3", GUI_LRG, GUI_BOT, gui_blu, gui_wht);
469             if (curr_party() > 1) audio_play(AUD_PLAYER3, 1.f);
470             break;
471         case 4:
472             gui_label(id, "4", GUI_LRG, GUI_BOT, gui_yel, gui_wht);
473             if (curr_party() > 1) audio_play(AUD_PLAYER4, 1.f);
474             break;
475         }
476         gui_layout(id, 0, 0);
477     }
478
479     hud_init();
480     game_set_fly(1.f);
481
482     return id;
483 }
484
485 static void next_leave(int id)
486 {
487     hud_free();
488     gui_delete(id);
489 }
490
491 static void next_paint(int id, float st)
492 {
493     game_draw(0);
494     hud_paint();
495     gui_paint(id);
496 }
497
498 static void next_timer(int id, float dt)
499 {
500     gui_timer(id, dt);
501     audio_timer(dt);
502 }
503
504 static void next_point(int id, int x, int y, int dx, int dy)
505 {
506     gui_pulse(gui_point(id, x, y), 1.2f);
507 }
508
509 static int next_click(int b, int d)
510 {
511     return (d && b < 0) ? goto_state(&st_flyby) : 1;
512 }
513
514 static int next_keybd(int c, int d)
515 {
516     if (d)
517     {
518         if (c == SDLK_F12)
519             return goto_state(&st_poser);
520         if (c == SDLK_ESCAPE)
521             return goto_state(&st_over);
522         if (c == SDLK_RETURN)
523         {
524             hole_goto(num, -1);
525             num = 0;
526             return goto_state(&st_next);
527         }
528         if ('0' <= c && c <= '9')
529             num = num * 10 + c - '0';
530     }
531     return 1;
532 }
533
534 /*---------------------------------------------------------------------------*/
535
536 static int poser_enter(void)
537 {
538     game_set_fly(-1.f);
539     return 0;
540 }
541
542 static void poser_paint(int id, float st)
543 {
544     game_draw(1);
545 }
546
547 static int poser_keybd(int c, int d)
548 {
549     return (d && c == SDLK_ESCAPE) ? goto_state(&st_next) : 1;
550 }
551
552 /*---------------------------------------------------------------------------*/
553
554 static int flyby_enter(void)
555 {
556     hud_init();
557     return 0;
558 }
559
560 static void flyby_leave(int id)
561 {
562     hud_free();
563 }
564
565 static void flyby_paint(int id, float st)
566 {
567     game_draw(0);
568     hud_paint();
569 }
570
571 static void flyby_timer(int id, float dt)
572 {
573     float t = time_state();
574
575     if (dt > 0.f && t > 1.f)
576         goto_state(&st_stroke);
577     else
578         game_set_fly(1.f - t);
579
580     gui_timer(id, dt);
581     audio_timer(dt);
582 }
583
584 static int flyby_click(int b, int d)
585 {
586     if (d && b < 0)
587     {
588         game_set_fly(0.f);
589         return goto_state(&st_stroke);
590     }
591     return 1;
592 }
593
594 static int flyby_keybd(int c, int d)
595 {
596     return (d && c == SDLK_ESCAPE) ? goto_state(&st_over) : 1;
597 }
598
599 /*---------------------------------------------------------------------------*/
600
601 static int stroke_enter(void)
602 {
603     hud_init();
604     game_clr_mag();
605     config_set_d(CONFIG_CAMERA, 2);
606     config_set_grab();
607     return 0;
608 }
609
610 static void stroke_leave(int id)
611 {
612     hud_free();
613     config_clr_grab();
614     config_set_d(CONFIG_CAMERA, 0);
615 }
616
617 static void stroke_paint(int id, float st)
618 {
619     game_draw(0);
620     hud_paint();
621 }
622
623 static void stroke_timer(int id, float dt)
624 {
625     float g[3] = { 0.f, 0.f, 0.f };
626
627     game_update_view(dt);
628     game_step(g, dt);
629     audio_timer(dt);
630 }
631
632 static void stroke_point(int id, int x, int y, int dx, int dy)
633 {
634     game_set_rot(dx);
635     game_set_mag(dy);
636 }
637
638 static int stroke_click(int b, int d)
639 {
640     return (d && b < 0) ? goto_state(&st_roll) : 1;
641 }
642
643 static int stroke_keybd(int c, int d)
644 {
645     return (d && c == SDLK_ESCAPE) ? goto_state(&st_over) : 1;
646 }
647
648 /*---------------------------------------------------------------------------*/
649
650 static int roll_enter(void)
651 {
652     hud_init();
653     game_putt();
654     return 0;
655 }
656
657 static void roll_leave(int id)
658 {
659     hud_free();
660 }
661
662 static void roll_paint(int id, float st)
663 {
664     game_draw(0);
665     hud_paint();
666 }
667
668 static void roll_timer(int id, float dt)
669 {
670     float g[3] = { 0.0f, -9.8f, 0.0f };
671
672     switch (game_step(g, dt))
673     {
674     case GAME_STOP: goto_state(&st_stop); break;
675     case GAME_GOAL: goto_state(&st_goal); break;
676     case GAME_FALL: goto_state(&st_fall); break;
677     }
678     audio_timer(dt);
679 }
680
681 static int roll_keybd(int c, int d)
682 {
683     return (d && c == SDLK_ESCAPE) ? goto_state(&st_over) : 1;
684 }
685
686 /*---------------------------------------------------------------------------*/
687
688 static int goal_enter(void)
689 {
690     int id;
691     
692     if ((id = gui_label(0, _("It's In!"), GUI_MED, GUI_ALL, gui_grn, gui_grn)))
693         gui_layout(id, 0, 0);
694
695     hole_goal();
696     hud_init();
697
698     return id;
699 }
700
701 static void goal_leave(int id)
702 {
703     gui_delete(id);
704     hud_free();
705 }
706
707 static void goal_paint(int id, float st)
708 {
709     game_draw(0);
710     gui_paint(id);
711     hud_paint();
712 }
713
714 static void goal_timer(int id, float dt)
715 {
716     if (time_state() > 3)
717     {
718         if (hole_next())
719             goto_state(&st_next);
720         else
721             goto_state(&st_score);
722     }
723     audio_timer(dt);
724 }
725
726 static int goal_click(int b, int d)
727 {
728     if (b < 0 && d == 1)
729     {
730         if (hole_next())
731             goto_state(&st_next);
732         else
733             goto_state(&st_score);
734     }
735     return 1;
736 }
737
738 static int goal_keybd(int c, int d)
739 {
740     return (d && c == SDLK_ESCAPE) ? goto_state(&st_over) : 1;
741 }
742
743 /*---------------------------------------------------------------------------*/
744
745 static int stop_enter(void)
746 {
747     hole_stop();
748     hud_init();
749     return 0;
750 }
751
752 static void stop_leave(int id)
753 {
754     hud_free();
755 }
756
757 static void stop_paint(int id, float st)
758 {
759     game_draw(0);
760     hud_paint();
761 }
762
763 static void stop_timer(int id, float dt)
764 {
765     float g[3] = { 0.f, 0.f, 0.f };
766
767     game_update_view(dt);
768     game_step(g, dt);
769     audio_timer(dt);
770
771     if (time_state() > 1)
772     {
773         if (hole_next())
774             goto_state(&st_next);
775         else
776             goto_state(&st_score);
777     }
778 }
779
780 static int stop_click(int b, int d)
781 {
782     if (b < 0 && d == 1)
783     {
784         if (hole_next())
785             goto_state(&st_next);
786         else
787             goto_state(&st_score);
788     }
789     return 1;
790 }
791
792 static int stop_keybd(int c, int d)
793 {
794     return (d && c == SDLK_ESCAPE) ? goto_state(&st_over) : 1;
795 }
796
797 /*---------------------------------------------------------------------------*/
798
799 static int fall_enter(void)
800 {
801     int id;
802     
803     if ((id = gui_label(0, _("1 Stroke Penalty"), GUI_MED, GUI_ALL, gui_blk, gui_red)))
804         gui_layout(id, 0, 0);
805
806     hole_fall();
807     hud_init();
808
809     return id;
810 }
811
812 static void fall_leave(int id)
813 {
814     gui_delete(id);
815     hud_free();
816 }
817
818 static void fall_paint(int id, float st)
819 {
820     game_draw(0);
821     gui_paint(id);
822     hud_paint();
823 }
824
825 static void fall_timer(int id, float dt)
826 {
827     if (time_state() > 3)
828     {
829         if (hole_next())
830             goto_state(&st_next);
831         else
832             goto_state(&st_score);
833     }
834     audio_timer(dt);
835 }
836
837 static int fall_click(int b, int d)
838 {
839     if (b < 0 && d == 1)
840     {
841         if (hole_next())
842             goto_state(&st_next);
843         else
844             goto_state(&st_score);
845     }
846     return 1;
847 }
848
849 static int fall_keybd(int c, int d)
850 {
851     return (d && c == SDLK_ESCAPE) ? goto_state(&st_over) : 1;
852 }
853
854 /*---------------------------------------------------------------------------*/
855
856 static int score_enter(void)
857 {
858     audio_music_fade_out(2.f);
859     return score_card(_("Scores"), gui_yel, gui_red);
860 }
861
862 static void score_leave(int id)
863 {
864     gui_delete(id);
865 }
866
867 static void score_paint(int id, float st)
868 {
869     game_draw(0);
870     gui_paint(id);
871 }
872
873 static void score_timer(int id, float dt)
874 {
875     gui_timer(id, dt);
876     audio_timer(dt);
877 }
878
879 static int score_click(int b, int d)
880 {
881     if (b < 0 && d == 1)
882     {
883         if (hole_move())
884             return goto_state(&st_next);
885         else
886             return goto_state(&st_title);
887     }
888     return 1;
889 }
890
891 static int score_keybd(int c, int d)
892 {
893     return (d && c == SDLK_ESCAPE) ? goto_state(&st_title) : 1;
894 }
895
896 /*---------------------------------------------------------------------------*/
897
898 static int over_enter(void)
899 {
900     audio_music_fade_out(2.f);
901     return score_card(_("Final Scores"), gui_yel, gui_red);
902 }
903
904 static void over_leave(int id)
905 {
906     gui_delete(id);
907 }
908
909 static void over_paint(int id, float st)
910 {
911     game_draw(0);
912     gui_paint(id);
913 }
914
915 static void over_timer(int id, float dt)
916 {
917     gui_timer(id, dt);
918     audio_timer(dt);
919 }
920
921 static int over_click(int b, int d)
922 {
923     return (d && b < 0) ? goto_state(&st_title) : 1;
924 }
925
926 static int over_keybd(int c, int d)
927 {
928     return (d && c == SDLK_ESCAPE) ? goto_state(&st_title) : 1;
929 }
930
931 /*---------------------------------------------------------------------------*/
932
933 struct state st_title = {
934     title_enter,
935     title_leave,
936     title_paint,
937     title_timer,
938     title_point,
939     NULL,
940     title_click,
941     title_keybd,
942     NULL,
943     1, 0
944 };
945
946 struct state st_course = {
947     course_enter,
948     course_leave,
949     course_paint,
950     course_timer,
951     course_point,
952     NULL,
953     course_click,
954     course_keybd,
955     NULL,
956     1, 0
957 };
958
959 struct state st_party = {
960     party_enter,
961     party_leave,
962     party_paint,
963     party_timer,
964     party_point,
965     NULL,
966     party_click,
967     party_keybd,
968     NULL,
969     1, 0
970 };
971
972 struct state st_next = {
973     next_enter,
974     next_leave,
975     next_paint,
976     next_timer,
977     next_point,
978     NULL,
979     next_click,
980     next_keybd,
981     NULL,
982     1, 0
983 };
984
985 struct state st_poser = {
986     poser_enter,
987     NULL,
988     poser_paint,
989     NULL,
990     NULL,
991     NULL,
992     NULL,
993     poser_keybd,
994     NULL,
995     1, 0
996 };
997
998 struct state st_flyby = {
999     flyby_enter,
1000     flyby_leave,
1001     flyby_paint,
1002     flyby_timer,
1003     NULL,
1004     NULL,
1005     flyby_click,
1006     flyby_keybd,
1007     NULL,
1008     1, 0
1009 };
1010
1011 struct state st_stroke = {
1012     stroke_enter,
1013     stroke_leave,
1014     stroke_paint,
1015     stroke_timer,
1016     stroke_point,
1017     NULL,
1018     stroke_click,
1019     stroke_keybd,
1020     NULL,
1021     0, 0
1022 };
1023
1024 struct state st_roll = {
1025     roll_enter,
1026     roll_leave,
1027     roll_paint,
1028     roll_timer,
1029     NULL,
1030     NULL,
1031     NULL,
1032     roll_keybd,
1033     NULL,
1034     0, 0
1035 };
1036
1037 struct state st_goal = {
1038     goal_enter,
1039     goal_leave,
1040     goal_paint,
1041     goal_timer,
1042     NULL,
1043     NULL,
1044     goal_click,
1045     goal_keybd,
1046     NULL,
1047     0, 0
1048 };
1049
1050 struct state st_stop = {
1051     stop_enter,
1052     stop_leave,
1053     stop_paint,
1054     stop_timer,
1055     NULL,
1056     NULL,
1057     stop_click,
1058     stop_keybd,
1059     NULL,
1060     0, 0
1061 };
1062
1063 struct state st_fall = {
1064     fall_enter,
1065     fall_leave,
1066     fall_paint,
1067     fall_timer,
1068     NULL,
1069     NULL,
1070     fall_click,
1071     fall_keybd,
1072     NULL,
1073     0, 0
1074 };
1075
1076 struct state st_score = {
1077     score_enter,
1078     score_leave,
1079     score_paint,
1080     score_timer,
1081     NULL,
1082     NULL,
1083     score_click,
1084     score_keybd,
1085     NULL,
1086     0, 0
1087 };
1088
1089 struct state st_over = {
1090     over_enter,
1091     over_leave,
1092     over_paint,
1093     over_timer,
1094     NULL,
1095     NULL,
1096     over_click,
1097     over_keybd,
1098     NULL,
1099     1, 0
1100 };