bonus ball for bonus levels. Fix #56
[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, sgettext("menu^Play"),    GUI_MED, TITLE_PLAY, 1);
183                 gui_state(kd, sgettext("menu^Options"), GUI_MED, TITLE_CONF, 0);
184                 gui_state(kd, sgettext("menu^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 static int shot_id;
239
240 static int course_action(int i)
241 {
242     if (course_exists(i))
243     {
244         course_goto(i);
245         goto_state(&st_party);
246     }
247     if (i < 0)
248         goto_state(&st_title);
249
250     return 1;
251 }
252
253 static int course_enter(void)
254 {
255     int w = config_get_d(CONFIG_WIDTH);
256     int h = config_get_d(CONFIG_HEIGHT);
257
258     int id, jd, kd, ld, i = 0, j, n = course_count();
259     int m = (int)(sqrt(n/2.0)*2);
260
261     if ((id = gui_vstack(0)))
262     {
263         gui_label(id, _("Select Course"), GUI_MED, GUI_ALL, 0, 0);
264         gui_space(id);
265
266         if ((jd = gui_hstack(id)))
267         {
268             shot_id = gui_image(jd, course_shot(0), w / 3, h / 3);
269             gui_filler(jd);
270             if ((kd = gui_varray(jd)))
271             {
272                 for(i = 0; i < n; i += m)
273                 {
274                     if ((ld = gui_harray(kd)))
275                     {
276                         for (j = (m-1); j >= 0; j--)
277                         {
278                             if (i+j < n)
279                                 gui_active(gui_image(ld, course_shot(i+j), w / 3 / m, h / 3 / m), i+j, 0);
280                             else
281                                 gui_space(ld);
282                         }
283                     }
284                 }
285             }
286         }
287
288         gui_space(id);
289         desc_id = gui_multi(id, _(course_desc(0)), GUI_SML, GUI_ALL, gui_yel, gui_wht);
290         gui_space(id);
291
292         if ((jd = gui_hstack(id)))
293         {
294             gui_filler(jd);
295             gui_state(jd, _("Back"), GUI_SML, -1, 0);
296         }
297
298         gui_layout(id, 0, 0);
299     }
300
301     audio_music_fade_to(0.5f, "bgm/inter.ogg");
302
303     return id;
304 }
305
306 static void course_leave(int id)
307 {
308     gui_delete(id);
309 }
310
311 static void course_paint(int id, float st)
312 {
313     game_draw(0);
314     gui_paint(id);
315 }
316
317 static void course_timer(int id, float dt)
318 {
319     gui_timer(id, dt);
320     audio_timer(dt);
321 }
322
323 static void course_point(int id, int x, int y, int dx, int dy)
324 {
325     int jd;
326
327     if ((jd = gui_point(id, x, y)))
328     {
329         int i = gui_token(jd);
330         if (course_exists(i))
331         {
332             gui_set_image(shot_id, course_shot(i));
333             gui_set_multi(desc_id, _(course_desc(i)));
334         }
335         gui_pulse(jd, 1.2f);
336     }
337 }
338
339 static int course_click(int b, int d)
340 {
341     return (d && b < 0) ? course_action(gui_token(gui_click())) : 1;
342 }
343
344 static int course_keybd(int c, int d)
345 {
346     return (d && c == SDLK_ESCAPE) ? goto_state(&st_title) : 1;
347 }
348
349 /*---------------------------------------------------------------------------*/
350
351 #define PARTY_T 0
352 #define PARTY_1 1
353 #define PARTY_2 2
354 #define PARTY_3 3
355 #define PARTY_4 4
356 #define PARTY_B 5
357
358 static int party_action(int i)
359 {
360     switch (i)
361     {
362     case PARTY_1:
363         audio_play(AUD_MENU, 1.f);
364         hole_goto(1, 1);
365         goto_state(&st_next);
366         break;
367     case PARTY_2:
368         audio_play(AUD_MENU, 1.f);
369         hole_goto(1, 2);
370         goto_state(&st_next);
371         break;
372     case PARTY_3:
373         audio_play(AUD_MENU, 1.f);
374         hole_goto(1, 3);
375         goto_state(&st_next);
376         break;
377     case PARTY_4:
378         audio_play(AUD_MENU, 1.f);
379         hole_goto(1, 4);
380         goto_state(&st_next);
381         break;
382     case PARTY_B:
383         audio_play(AUD_MENU, 1.f);
384         goto_state(&st_course);
385         break;
386     }
387     return 1;
388 }
389
390 static int party_enter(void)
391 {
392     int id, jd;
393
394     if ((id = gui_vstack(0)))
395     {
396         gui_label(id, _("Players?"), GUI_MED, GUI_ALL, 0, 0);
397         gui_space(id);
398
399         if ((jd = gui_harray(id)))
400         {
401             int p4 = gui_state(jd, "4", GUI_LRG, PARTY_4, 0);
402             int p3 = gui_state(jd, "3", GUI_LRG, PARTY_3, 0);
403             int p2 = gui_state(jd, "2", GUI_LRG, PARTY_2, 0);
404             int p1 = gui_state(jd, "1", GUI_LRG, PARTY_1, 0);
405
406             gui_set_color(p1, gui_red, gui_wht);
407             gui_set_color(p2, gui_grn, gui_wht);
408             gui_set_color(p3, gui_blu, gui_wht);
409             gui_set_color(p4, gui_yel, gui_wht);
410         }
411
412         gui_space(id);
413
414         if ((jd = gui_hstack(id)))
415         {
416             gui_filler(jd);
417             gui_state(jd, _("Back"), GUI_SML, PARTY_B, 0);
418         }
419
420         gui_layout(id, 0, 0);
421     }
422
423     return id;
424 }
425
426 static void party_leave(int id)
427 {
428     gui_delete(id);
429 }
430
431 static void party_paint(int id, float st)
432 {
433     game_draw(0);
434     gui_paint(id);
435 }
436
437 static void party_timer(int id, float dt)
438 {
439     gui_timer(id, dt);
440     audio_timer(dt);
441 }
442
443 static void party_point(int id, int x, int y, int dx, int dy)
444 {
445     gui_pulse(gui_point(id, x, y), 1.2f);
446 }
447
448 static int party_click(int b, int d)
449 {
450     return (d && b < 0) ? party_action(gui_token(gui_click())) : 1;
451 }
452
453 static int party_keybd(int c, int d)
454 {
455     return (d && c == SDLK_ESCAPE) ? goto_state(&st_course) : 1;
456 }
457
458 /*---------------------------------------------------------------------------*/
459
460 static int num = 0;
461
462 static int next_enter(void)
463 {
464     int id;
465     char str[MAXSTR];
466
467     sprintf(str, _("Hole %02d"), curr_hole());
468
469     if ((id = gui_vstack(0)))
470     {
471         gui_label(id, str, GUI_MED, GUI_ALL, 0, 0);
472         gui_space(id);
473
474         gui_label(id, _("Player"), GUI_SML, GUI_TOP, 0, 0);
475
476         switch (curr_player())
477         {
478         case 1:
479             gui_label(id, "1", GUI_LRG, GUI_BOT, gui_red, gui_wht);
480             if (curr_party() > 1) audio_play(AUD_PLAYER1, 1.f);
481             break;
482         case 2:
483             gui_label(id, "2", GUI_LRG, GUI_BOT, gui_grn, gui_wht);
484             if (curr_party() > 1) audio_play(AUD_PLAYER2, 1.f);
485             break;
486         case 3:
487             gui_label(id, "3", GUI_LRG, GUI_BOT, gui_blu, gui_wht);
488             if (curr_party() > 1) audio_play(AUD_PLAYER3, 1.f);
489             break;
490         case 4:
491             gui_label(id, "4", GUI_LRG, GUI_BOT, gui_yel, gui_wht);
492             if (curr_party() > 1) audio_play(AUD_PLAYER4, 1.f);
493             break;
494         }
495         gui_layout(id, 0, 0);
496     }
497
498     hud_init();
499     game_set_fly(1.f);
500
501     return id;
502 }
503
504 static void next_leave(int id)
505 {
506     hud_free();
507     gui_delete(id);
508 }
509
510 static void next_paint(int id, float st)
511 {
512     game_draw(0);
513     hud_paint();
514     gui_paint(id);
515 }
516
517 static void next_timer(int id, float dt)
518 {
519     gui_timer(id, dt);
520     audio_timer(dt);
521 }
522
523 static void next_point(int id, int x, int y, int dx, int dy)
524 {
525     gui_pulse(gui_point(id, x, y), 1.2f);
526 }
527
528 static int next_click(int b, int d)
529 {
530     return (d && b < 0) ? goto_state(&st_flyby) : 1;
531 }
532
533 static int next_keybd(int c, int d)
534 {
535     if (d)
536     {
537         if (c == SDLK_F12)
538             return goto_state(&st_poser);
539         if (c == SDLK_ESCAPE)
540             return goto_state(&st_over);
541         if (c == SDLK_RETURN)
542         {
543             hole_goto(num, -1);
544             num = 0;
545             return goto_state(&st_next);
546         }
547         if ('0' <= c && c <= '9')
548             num = num * 10 + c - '0';
549     }
550     return 1;
551 }
552
553 /*---------------------------------------------------------------------------*/
554
555 static int poser_enter(void)
556 {
557     game_set_fly(-1.f);
558     return 0;
559 }
560
561 static void poser_paint(int id, float st)
562 {
563     game_draw(1);
564 }
565
566 static int poser_keybd(int c, int d)
567 {
568     return (d && c == SDLK_ESCAPE) ? goto_state(&st_next) : 1;
569 }
570
571 /*---------------------------------------------------------------------------*/
572
573 static int flyby_enter(void)
574 {
575     hud_init();
576     return 0;
577 }
578
579 static void flyby_leave(int id)
580 {
581     hud_free();
582 }
583
584 static void flyby_paint(int id, float st)
585 {
586     game_draw(0);
587     hud_paint();
588 }
589
590 static void flyby_timer(int id, float dt)
591 {
592     float t = time_state();
593
594     if (dt > 0.f && t > 1.f)
595         goto_state(&st_stroke);
596     else
597         game_set_fly(1.f - t);
598
599     gui_timer(id, dt);
600     audio_timer(dt);
601 }
602
603 static int flyby_click(int b, int d)
604 {
605     if (d && b < 0)
606     {
607         game_set_fly(0.f);
608         return goto_state(&st_stroke);
609     }
610     return 1;
611 }
612
613 static int flyby_keybd(int c, int d)
614 {
615     return (d && c == SDLK_ESCAPE) ? goto_state(&st_over) : 1;
616 }
617
618 /*---------------------------------------------------------------------------*/
619
620 static int stroke_enter(void)
621 {
622     hud_init();
623     game_clr_mag();
624     config_set_d(CONFIG_CAMERA, 2);
625     config_set_grab();
626     return 0;
627 }
628
629 static void stroke_leave(int id)
630 {
631     hud_free();
632     config_clr_grab();
633     config_set_d(CONFIG_CAMERA, 0);
634 }
635
636 static void stroke_paint(int id, float st)
637 {
638     game_draw(0);
639     hud_paint();
640 }
641
642 static void stroke_timer(int id, float dt)
643 {
644     float g[3] = { 0.f, 0.f, 0.f };
645
646     game_update_view(dt);
647     game_step(g, dt);
648     audio_timer(dt);
649 }
650
651 static void stroke_point(int id, int x, int y, int dx, int dy)
652 {
653     game_set_rot(dx);
654     game_set_mag(dy);
655 }
656
657 static int stroke_click(int b, int d)
658 {
659     return (d && b < 0) ? goto_state(&st_roll) : 1;
660 }
661
662 static int stroke_keybd(int c, int d)
663 {
664     return (d && c == SDLK_ESCAPE) ? goto_state(&st_over) : 1;
665 }
666
667 /*---------------------------------------------------------------------------*/
668
669 static int roll_enter(void)
670 {
671     hud_init();
672     game_putt();
673     return 0;
674 }
675
676 static void roll_leave(int id)
677 {
678     hud_free();
679 }
680
681 static void roll_paint(int id, float st)
682 {
683     game_draw(0);
684     hud_paint();
685 }
686
687 static void roll_timer(int id, float dt)
688 {
689     float g[3] = { 0.0f, -9.8f, 0.0f };
690
691     switch (game_step(g, dt))
692     {
693     case GAME_STOP: goto_state(&st_stop); break;
694     case GAME_GOAL: goto_state(&st_goal); break;
695     case GAME_FALL: goto_state(&st_fall); break;
696     }
697     audio_timer(dt);
698 }
699
700 static int roll_keybd(int c, int d)
701 {
702     return (d && c == SDLK_ESCAPE) ? goto_state(&st_over) : 1;
703 }
704
705 /*---------------------------------------------------------------------------*/
706
707 static int goal_enter(void)
708 {
709     int id;
710     
711     if ((id = gui_label(0, _("It's In!"), GUI_MED, GUI_ALL, gui_grn, gui_grn)))
712         gui_layout(id, 0, 0);
713
714     hole_goal();
715     hud_init();
716
717     return id;
718 }
719
720 static void goal_leave(int id)
721 {
722     gui_delete(id);
723     hud_free();
724 }
725
726 static void goal_paint(int id, float st)
727 {
728     game_draw(0);
729     gui_paint(id);
730     hud_paint();
731 }
732
733 static void goal_timer(int id, float dt)
734 {
735     if (time_state() > 3)
736     {
737         if (hole_next())
738             goto_state(&st_next);
739         else
740             goto_state(&st_score);
741     }
742     audio_timer(dt);
743 }
744
745 static int goal_click(int b, int d)
746 {
747     if (b < 0 && d == 1)
748     {
749         if (hole_next())
750             goto_state(&st_next);
751         else
752             goto_state(&st_score);
753     }
754     return 1;
755 }
756
757 static int goal_keybd(int c, int d)
758 {
759     return (d && c == SDLK_ESCAPE) ? goto_state(&st_over) : 1;
760 }
761
762 /*---------------------------------------------------------------------------*/
763
764 static int stop_enter(void)
765 {
766     hole_stop();
767     hud_init();
768     return 0;
769 }
770
771 static void stop_leave(int id)
772 {
773     hud_free();
774 }
775
776 static void stop_paint(int id, float st)
777 {
778     game_draw(0);
779     hud_paint();
780 }
781
782 static void stop_timer(int id, float dt)
783 {
784     float g[3] = { 0.f, 0.f, 0.f };
785
786     game_update_view(dt);
787     game_step(g, dt);
788     audio_timer(dt);
789
790     if (time_state() > 1)
791     {
792         if (hole_next())
793             goto_state(&st_next);
794         else
795             goto_state(&st_score);
796     }
797 }
798
799 static int stop_click(int b, int d)
800 {
801     if (b < 0 && d == 1)
802     {
803         if (hole_next())
804             goto_state(&st_next);
805         else
806             goto_state(&st_score);
807     }
808     return 1;
809 }
810
811 static int stop_keybd(int c, int d)
812 {
813     return (d && c == SDLK_ESCAPE) ? goto_state(&st_over) : 1;
814 }
815
816 /*---------------------------------------------------------------------------*/
817
818 static int fall_enter(void)
819 {
820     int id;
821     
822     if ((id = gui_label(0, _("1 Stroke Penalty"), GUI_MED, GUI_ALL, gui_blk, gui_red)))
823         gui_layout(id, 0, 0);
824
825     hole_fall();
826     hud_init();
827
828     return id;
829 }
830
831 static void fall_leave(int id)
832 {
833     gui_delete(id);
834     hud_free();
835 }
836
837 static void fall_paint(int id, float st)
838 {
839     game_draw(0);
840     gui_paint(id);
841     hud_paint();
842 }
843
844 static void fall_timer(int id, float dt)
845 {
846     if (time_state() > 3)
847     {
848         if (hole_next())
849             goto_state(&st_next);
850         else
851             goto_state(&st_score);
852     }
853     audio_timer(dt);
854 }
855
856 static int fall_click(int b, int d)
857 {
858     if (b < 0 && d == 1)
859     {
860         if (hole_next())
861             goto_state(&st_next);
862         else
863             goto_state(&st_score);
864     }
865     return 1;
866 }
867
868 static int fall_keybd(int c, int d)
869 {
870     return (d && c == SDLK_ESCAPE) ? goto_state(&st_over) : 1;
871 }
872
873 /*---------------------------------------------------------------------------*/
874
875 static int score_enter(void)
876 {
877     audio_music_fade_out(2.f);
878     return score_card(_("Scores"), gui_yel, gui_red);
879 }
880
881 static void score_leave(int id)
882 {
883     gui_delete(id);
884 }
885
886 static void score_paint(int id, float st)
887 {
888     game_draw(0);
889     gui_paint(id);
890 }
891
892 static void score_timer(int id, float dt)
893 {
894     gui_timer(id, dt);
895     audio_timer(dt);
896 }
897
898 static int score_click(int b, int d)
899 {
900     if (b < 0 && d == 1)
901     {
902         if (hole_move())
903             return goto_state(&st_next);
904         else
905             return goto_state(&st_title);
906     }
907     return 1;
908 }
909
910 static int score_keybd(int c, int d)
911 {
912     return (d && c == SDLK_ESCAPE) ? goto_state(&st_title) : 1;
913 }
914
915 /*---------------------------------------------------------------------------*/
916
917 static int over_enter(void)
918 {
919     audio_music_fade_out(2.f);
920     return score_card(_("Final Scores"), gui_yel, gui_red);
921 }
922
923 static void over_leave(int id)
924 {
925     gui_delete(id);
926 }
927
928 static void over_paint(int id, float st)
929 {
930     game_draw(0);
931     gui_paint(id);
932 }
933
934 static void over_timer(int id, float dt)
935 {
936     gui_timer(id, dt);
937     audio_timer(dt);
938 }
939
940 static int over_click(int b, int d)
941 {
942     return (d && b < 0) ? goto_state(&st_title) : 1;
943 }
944
945 static int over_keybd(int c, int d)
946 {
947     return (d && c == SDLK_ESCAPE) ? goto_state(&st_title) : 1;
948 }
949
950 /*---------------------------------------------------------------------------*/
951
952 struct state st_title = {
953     title_enter,
954     title_leave,
955     title_paint,
956     title_timer,
957     title_point,
958     NULL,
959     title_click,
960     title_keybd,
961     NULL,
962     1, 0
963 };
964
965 struct state st_course = {
966     course_enter,
967     course_leave,
968     course_paint,
969     course_timer,
970     course_point,
971     NULL,
972     course_click,
973     course_keybd,
974     NULL,
975     1, 0
976 };
977
978 struct state st_party = {
979     party_enter,
980     party_leave,
981     party_paint,
982     party_timer,
983     party_point,
984     NULL,
985     party_click,
986     party_keybd,
987     NULL,
988     1, 0
989 };
990
991 struct state st_next = {
992     next_enter,
993     next_leave,
994     next_paint,
995     next_timer,
996     next_point,
997     NULL,
998     next_click,
999     next_keybd,
1000     NULL,
1001     1, 0
1002 };
1003
1004 struct state st_poser = {
1005     poser_enter,
1006     NULL,
1007     poser_paint,
1008     NULL,
1009     NULL,
1010     NULL,
1011     NULL,
1012     poser_keybd,
1013     NULL,
1014     1, 0
1015 };
1016
1017 struct state st_flyby = {
1018     flyby_enter,
1019     flyby_leave,
1020     flyby_paint,
1021     flyby_timer,
1022     NULL,
1023     NULL,
1024     flyby_click,
1025     flyby_keybd,
1026     NULL,
1027     1, 0
1028 };
1029
1030 struct state st_stroke = {
1031     stroke_enter,
1032     stroke_leave,
1033     stroke_paint,
1034     stroke_timer,
1035     stroke_point,
1036     NULL,
1037     stroke_click,
1038     stroke_keybd,
1039     NULL,
1040     0, 0
1041 };
1042
1043 struct state st_roll = {
1044     roll_enter,
1045     roll_leave,
1046     roll_paint,
1047     roll_timer,
1048     NULL,
1049     NULL,
1050     NULL,
1051     roll_keybd,
1052     NULL,
1053     0, 0
1054 };
1055
1056 struct state st_goal = {
1057     goal_enter,
1058     goal_leave,
1059     goal_paint,
1060     goal_timer,
1061     NULL,
1062     NULL,
1063     goal_click,
1064     goal_keybd,
1065     NULL,
1066     0, 0
1067 };
1068
1069 struct state st_stop = {
1070     stop_enter,
1071     stop_leave,
1072     stop_paint,
1073     stop_timer,
1074     NULL,
1075     NULL,
1076     stop_click,
1077     stop_keybd,
1078     NULL,
1079     0, 0
1080 };
1081
1082 struct state st_fall = {
1083     fall_enter,
1084     fall_leave,
1085     fall_paint,
1086     fall_timer,
1087     NULL,
1088     NULL,
1089     fall_click,
1090     fall_keybd,
1091     NULL,
1092     0, 0
1093 };
1094
1095 struct state st_score = {
1096     score_enter,
1097     score_leave,
1098     score_paint,
1099     score_timer,
1100     NULL,
1101     NULL,
1102     score_click,
1103     score_keybd,
1104     NULL,
1105     0, 0
1106 };
1107
1108 struct state st_over = {
1109     over_enter,
1110     over_leave,
1111     over_paint,
1112     over_timer,
1113     NULL,
1114     NULL,
1115     over_click,
1116     over_keybd,
1117     NULL,
1118     1, 0
1119 };