Merge branch 'gles'
[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 "geom.h"
19 #include "gui.h"
20 #include "vec3.h"
21 #include "game.h"
22 #include "hole.h"
23 #include "audio.h"
24 #include "course.h"
25 #include "config.h"
26 #include "video.h"
27
28 #include "st_all.h"
29 #include "st_conf.h"
30
31 /*---------------------------------------------------------------------------*/
32
33 static SDL_Joystick *joystick = NULL;
34
35 void set_joystick(SDL_Joystick *j)
36 {
37     joystick = j;
38 }
39
40 /*---------------------------------------------------------------------------*/
41
42 static char *number(int i)
43 {
44     static char str[MAXSTR];
45
46     sprintf(str, "%02d", i);
47
48     return str;
49 }
50
51 static int score_card(const char  *title,
52                       const GLubyte *c0,
53                       const GLubyte *c1)
54 {
55     int id, jd, kd, ld;
56
57     int p1 = (curr_party() >= 1) ? 1 : 0, l1 = (curr_party() == 1) ? 1 : 0;
58     int p2 = (curr_party() >= 2) ? 1 : 0, l2 = (curr_party() == 2) ? 1 : 0;
59     int p3 = (curr_party() >= 3) ? 1 : 0, l3 = (curr_party() == 3) ? 1 : 0;
60     int p4 = (curr_party() >= 4) ? 1 : 0, l4 = (curr_party() == 4) ? 1 : 0;
61
62     int i;
63     int n = curr_count() - 1;
64     int m = curr_count() / 2;
65
66     if ((id = gui_vstack(0)))
67     {
68         gui_label(id, title, GUI_MED, GUI_ALL, c0, c1);
69         gui_space(id);
70
71         if ((jd = gui_hstack(id)))
72         {
73             if ((kd = gui_varray(jd)))
74             {
75                 if (p1) gui_label(kd, _("O"),         0, GUI_NE, 0, 0);
76                 if (p1) gui_label(kd, hole_out(0), 0, 0,           gui_wht, gui_wht);
77                 if (p1) gui_label(kd, hole_out(1), 0, GUI_SE * l1, gui_red, gui_wht);
78                 if (p2) gui_label(kd, hole_out(2), 0, GUI_SE * l2, gui_grn, gui_wht);
79                 if (p3) gui_label(kd, hole_out(3), 0, GUI_SE * l3, gui_blu, gui_wht);
80                 if (p4) gui_label(kd, hole_out(4), 0, GUI_SE * l4, gui_yel, gui_wht);
81             }
82
83             if ((kd = gui_harray(jd)))
84                 for (i = m; i > 0; i--)
85                     if ((ld = gui_varray(kd)))
86                     {
87                         if (p1) gui_label(ld, number(i), 0, (i == 1) ? GUI_NW : 0, 0, 0);
88                         if (p1) gui_label(ld, hole_score(i, 0), 0, 0, gui_wht, gui_wht);
89                         if (p1) gui_label(ld, hole_score(i, 1), 0, 0, gui_red, gui_wht);
90                         if (p2) gui_label(ld, hole_score(i, 2), 0, 0, gui_grn, gui_wht);
91                         if (p3) gui_label(ld, hole_score(i, 3), 0, 0, gui_blu, gui_wht);
92                         if (p4) gui_label(ld, hole_score(i, 4), 0, 0, gui_yel, gui_wht);
93                     }
94             if ((kd = gui_varray(jd)))
95             {
96                 gui_filler(kd);
97                 if (p1) gui_label(kd, _("Par"), 0, GUI_NW,      gui_wht, gui_wht);
98                 if (p1) gui_label(kd, _("P1"),  0, GUI_SW * l1, gui_red, gui_wht);
99                 if (p2) gui_label(kd, _("P2"),  0, GUI_SW * l2, gui_grn, gui_wht);
100                 if (p3) gui_label(kd, _("P3"),  0, GUI_SW * l3, gui_blu, gui_wht);
101                 if (p4) gui_label(kd, _("P4"),  0, GUI_SW * l4, gui_yel, gui_wht);
102             }
103         }
104
105         gui_space(id);
106
107         if ((jd = gui_hstack(id)))
108         {
109             if ((kd = gui_varray(jd)))
110             {
111                 if (p1) gui_label(kd, _("Tot"),    0, GUI_TOP, 0, 0);
112                 if (p1) gui_label(kd, hole_tot(0), 0, 0,           gui_wht, gui_wht);
113                 if (p1) gui_label(kd, hole_tot(1), 0, GUI_BOT * l1, gui_red, gui_wht);
114                 if (p2) gui_label(kd, hole_tot(2), 0, GUI_BOT * l2, gui_grn, gui_wht);
115                 if (p3) gui_label(kd, hole_tot(3), 0, GUI_BOT * l3, gui_blu, gui_wht);
116                 if (p4) gui_label(kd, hole_tot(4), 0, GUI_BOT * l4, gui_yel, gui_wht);
117             }
118             if ((kd = gui_varray(jd)))
119             {
120                 if (p1) gui_label(kd, _("I"),     0, GUI_NE, 0, 0);
121                 if (p1) gui_label(kd, hole_in(0), 0, 0,           gui_wht, gui_wht);
122                 if (p1) gui_label(kd, hole_in(1), 0, GUI_SE * l1, gui_red, gui_wht);
123                 if (p2) gui_label(kd, hole_in(2), 0, GUI_SE * l2, gui_grn, gui_wht);
124                 if (p3) gui_label(kd, hole_in(3), 0, GUI_SE * l3, gui_blu, gui_wht);
125                 if (p4) gui_label(kd, hole_in(4), 0, GUI_SE * l4, gui_yel, gui_wht);
126             }
127             if ((kd = gui_harray(jd)))
128                 for (i = n; i > m; i--)
129                     if ((ld = gui_varray(kd)))
130                     {
131                         if (p1) gui_label(ld, number(i), 0, (i == m+1) ? GUI_NW : 0, 0, 0);
132                         if (p1) gui_label(ld, hole_score(i, 0), 0, 0, gui_wht, gui_wht);
133                         if (p1) gui_label(ld, hole_score(i, 1), 0, 0, gui_red, gui_wht);
134                         if (p2) gui_label(ld, hole_score(i, 2), 0, 0, gui_grn, gui_wht);
135                         if (p3) gui_label(ld, hole_score(i, 3), 0, 0, gui_blu, gui_wht);
136                         if (p4) gui_label(ld, hole_score(i, 4), 0, 0, gui_yel, gui_wht);
137                     }
138             if ((kd = gui_varray(jd)))
139             {
140                 gui_filler(kd);
141                 if (p1) gui_label(kd, _("Par"), 0, GUI_NW,      gui_wht, gui_wht);
142                 if (p1) gui_label(kd, _("P1"),  0, GUI_SW * l1, gui_red, gui_wht);
143                 if (p2) gui_label(kd, _("P2"),  0, GUI_SW * l2, gui_grn, gui_wht);
144                 if (p3) gui_label(kd, _("P3"),  0, GUI_SW * l3, gui_blu, gui_wht);
145                 if (p4) gui_label(kd, _("P4"),  0, GUI_SW * l4, gui_yel, gui_wht);
146             }
147         }
148
149         gui_layout(id, 0, 0);
150     }
151
152     return id;
153 }
154
155 /*---------------------------------------------------------------------------*/
156
157 static int shared_stick_basic(int id, int a, float v, int bump)
158 {
159     int jd;
160
161     if ((jd = gui_stick(id, a, v, bump)))
162         gui_pulse(jd, 1.2f);
163
164     return jd;
165 }
166
167 static void shared_stick(int id, int a, float v, int bump)
168 {
169     shared_stick_basic(id, a, v, bump);
170 }
171
172 /*---------------------------------------------------------------------------*/
173
174 #define TITLE_PLAY 1
175 #define TITLE_CONF 2
176 #define TITLE_EXIT 3
177
178 static int title_action(int i)
179 {
180     audio_play(AUD_MENU, 1.0f);
181
182     switch (i)
183     {
184     case TITLE_PLAY: return goto_state(&st_course);
185     case TITLE_CONF: return goto_state(&st_conf);
186     case TITLE_EXIT: return 0;
187     }
188     return 1;
189 }
190
191 static int title_enter(struct state *st, struct state *prev)
192 {
193     int id, jd, kd;
194
195     /* Build the title GUI. */
196
197     if ((id = gui_vstack(0)))
198     {
199         gui_label(id, "Neverputt", GUI_LRG, GUI_ALL, 0, 0);
200         gui_space(id);
201
202         if ((jd = gui_harray(id)))
203         {
204             gui_filler(jd);
205
206             if ((kd = gui_varray(jd)))
207             {
208                 gui_start(kd, sgettext("menu^Play"),    GUI_MED, TITLE_PLAY, 1);
209                 gui_state(kd, sgettext("menu^Options"), GUI_MED, TITLE_CONF, 0);
210                 gui_state(kd, sgettext("menu^Exit"),    GUI_MED, TITLE_EXIT, 0);
211             }
212
213             gui_filler(jd);
214         }
215         gui_layout(id, 0, 0);
216     }
217
218     course_init();
219     course_rand();
220
221     return id;
222 }
223
224 static void title_leave(struct state *st, struct state *next, int id)
225 {
226     gui_delete(id);
227 }
228
229 static void title_paint(int id, float t)
230 {
231     game_draw(0, t);
232     gui_paint(id);
233 }
234
235 static void title_timer(int id, float dt)
236 {
237     float g[3] = { 0.f, 0.f, 0.f };
238
239     game_step(g, dt);
240     game_set_fly(fcosf(time_state() / 10.f));
241
242     gui_timer(id, dt);
243 }
244
245 static void title_point(int id, int x, int y, int dx, int dy)
246 {
247     gui_pulse(gui_point(id, x, y), 1.2f);
248 }
249
250 static int title_click(int b, int d)
251 {
252     return d && b == SDL_BUTTON_LEFT ? title_action(gui_token(gui_click())) : 1;
253 }
254
255 static int title_buttn(int b, int d)
256 {
257     if (d)
258     {
259         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
260             return title_action(gui_token(gui_click()));
261         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
262             return title_action(TITLE_EXIT);
263     }
264     return 1;
265 }
266
267 /*---------------------------------------------------------------------------*/
268
269 static int desc_id;
270 static int shot_id;
271
272 #define COURSE_BACK -1
273
274 static int course_action(int i)
275 {
276     if (course_exists(i))
277     {
278         course_goto(i);
279         goto_state(&st_party);
280     }
281     if (i == COURSE_BACK)
282         goto_state(&st_title);
283
284     return 1;
285 }
286
287 static int comp_size(int n, int s)
288 {
289     return n <= s * s ? s : comp_size(n, s + 1);
290 }
291
292 static int comp_cols(int n)
293 {
294     return comp_size(n, 1);
295 }
296
297 static int comp_rows(int n)
298 {
299     int s = comp_size(n, 1);
300
301     return n <= s * (s - 1) ? s - 1 : s;
302 }
303
304 static int course_enter(struct state *st, struct state *prev)
305 {
306     int w = config_get_d(CONFIG_WIDTH);
307     int h = config_get_d(CONFIG_HEIGHT);
308
309     int id, jd, kd, ld, md;
310
311     int i, j, r, c, n;
312
313     n = course_count();
314
315     r = comp_rows(n);
316     c = comp_cols(n);
317
318     if ((id = gui_vstack(0)))
319     {
320         gui_label(id, _("Select Course"), GUI_MED, GUI_ALL, 0, 0);
321         gui_space(id);
322
323         if ((jd = gui_hstack(id)))
324         {
325             shot_id = gui_image(jd, course_shot(0), w / 3, h / 3);
326
327             gui_filler(jd);
328
329             if ((kd = gui_varray(jd)))
330             {
331                 for(i = 0; i < r; i++)
332                 {
333                     if ((ld = gui_harray(kd)))
334                     {
335                         for (j = c - 1; j >= 0; j--)
336                         {
337                             int k = i * c + j;
338
339                             if (k < n)
340                             {
341                                 md = gui_image(ld, course_shot(k),
342                                                w / 3 / c, h / 3 / r);
343                                 gui_active(md, k, 0);
344
345                                 if (k == 0)
346                                     gui_focus(md);
347                             }
348                             else
349                                 gui_space(ld);
350                         }
351                     }
352                 }
353             }
354         }
355
356         gui_space(id);
357         desc_id = gui_multi(id, _(course_desc(0)), GUI_SML, GUI_ALL, gui_yel, gui_wht);
358         gui_space(id);
359
360         if ((jd = gui_hstack(id)))
361         {
362             gui_filler(jd);
363             gui_state(jd, _("Back"), GUI_SML, COURSE_BACK, 0);
364         }
365
366         gui_layout(id, 0, 0);
367     }
368
369     audio_music_fade_to(0.5f, "bgm/inter.ogg");
370
371     return id;
372 }
373
374 static void course_leave(struct state *st, struct state *next, int id)
375 {
376     gui_delete(id);
377 }
378
379 static void course_paint(int id, float t)
380 {
381     game_draw(0, t);
382     gui_paint(id);
383 }
384
385 static void course_timer(int id, float dt)
386 {
387     gui_timer(id, dt);
388 }
389
390 static void course_point(int id, int x, int y, int dx, int dy)
391 {
392     int jd;
393
394     if ((jd = gui_point(id, x, y)))
395     {
396         int i = gui_token(jd);
397
398         if (course_exists(i))
399         {
400             gui_set_image(shot_id, course_shot(i));
401             gui_set_multi(desc_id, _(course_desc(i)));
402         }
403         gui_pulse(jd, 1.2f);
404     }
405 }
406
407 static void course_stick(int id, int a, float v, int bump)
408 {
409     int jd;
410
411     if ((jd = shared_stick_basic(id, a, v, bump)))
412     {
413         int i = gui_token(jd);
414
415         if (course_exists(i))
416         {
417             gui_set_image(shot_id, course_shot(i));
418             gui_set_multi(desc_id, _(course_desc(i)));
419         }
420         gui_pulse(jd, 1.2f);
421     }
422 }
423
424 static int course_click(int b, int d)
425 {
426     return d && b == SDL_BUTTON_LEFT ? course_action(gui_token(gui_click())) : 1;
427 }
428
429 static int course_buttn(int b, int d)
430 {
431     if (d)
432     {
433         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
434             return course_action(gui_token(gui_click()));
435         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
436             return course_action(COURSE_BACK);
437     }
438     return 1;
439 }
440
441 /*---------------------------------------------------------------------------*/
442
443 #define PARTY_T 0
444 #define PARTY_1 1
445 #define PARTY_2 2
446 #define PARTY_3 3
447 #define PARTY_4 4
448 #define PARTY_B 5
449
450 static int party_action(int i)
451 {
452     switch (i)
453     {
454     case PARTY_1:
455         audio_play(AUD_MENU, 1.f);
456         if (hole_goto(1, 1))
457             goto_state(&st_next);
458         break;
459     case PARTY_2:
460         audio_play(AUD_MENU, 1.f);
461         if (hole_goto(1, 2))
462             goto_state(&st_next);
463         break;
464     case PARTY_3:
465         audio_play(AUD_MENU, 1.f);
466         if (hole_goto(1, 3))
467             goto_state(&st_next);
468         break;
469     case PARTY_4:
470         audio_play(AUD_MENU, 1.f);
471         if (hole_goto(1, 4))
472             goto_state(&st_next);
473         break;
474     case PARTY_B:
475         audio_play(AUD_MENU, 1.f);
476         goto_state(&st_course);
477         break;
478     }
479     return 1;
480 }
481
482 static int party_enter(struct state *st, struct state *prev)
483 {
484     int id, jd;
485
486     if ((id = gui_vstack(0)))
487     {
488         gui_label(id, _("Players?"), GUI_MED, GUI_ALL, 0, 0);
489         gui_space(id);
490
491         if ((jd = gui_harray(id)))
492         {
493             int p4 = gui_state(jd, "4", GUI_LRG, PARTY_4, 0);
494             int p3 = gui_state(jd, "3", GUI_LRG, PARTY_3, 0);
495             int p2 = gui_state(jd, "2", GUI_LRG, PARTY_2, 0);
496             int p1 = gui_state(jd, "1", GUI_LRG, PARTY_1, 0);
497
498             gui_set_color(p1, gui_red, gui_wht);
499             gui_set_color(p2, gui_grn, gui_wht);
500             gui_set_color(p3, gui_blu, gui_wht);
501             gui_set_color(p4, gui_yel, gui_wht);
502
503             gui_focus(p1);
504         }
505
506         gui_space(id);
507
508         if ((jd = gui_hstack(id)))
509         {
510             gui_filler(jd);
511             gui_state(jd, _("Back"), GUI_SML, PARTY_B, 0);
512         }
513
514         gui_layout(id, 0, 0);
515     }
516
517     return id;
518 }
519
520 static void party_leave(struct state *st, struct state *next, int id)
521 {
522     gui_delete(id);
523 }
524
525 static void party_paint(int id, float t)
526 {
527     game_draw(0, t);
528     gui_paint(id);
529 }
530
531 static void party_timer(int id, float dt)
532 {
533     gui_timer(id, dt);
534 }
535
536 static void party_point(int id, int x, int y, int dx, int dy)
537 {
538     gui_pulse(gui_point(id, x, y), 1.2f);
539 }
540
541 static int party_click(int b, int d)
542 {
543     return d && b == SDL_BUTTON_LEFT ? party_action(gui_token(gui_click())) : 1;
544 }
545
546 static int party_buttn(int b, int d)
547 {
548     if (d)
549     {
550         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
551             return party_action(gui_token(gui_click()));
552         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
553             return party_action(PARTY_B);
554     }
555     return 1;
556 }
557
558 /*---------------------------------------------------------------------------*/
559
560 static int paused = 0;
561
562 static struct state *st_continue;
563 static struct state *st_quit;
564
565 #define PAUSE_CONTINUE 1
566 #define PAUSE_QUIT     2
567
568 int goto_pause(struct state *s, int e)
569 {
570     if (curr_state() == &st_pause)
571         return 1;
572
573     if (e && !config_tst_d(CONFIG_KEY_PAUSE, SDLK_ESCAPE))
574         return goto_state(s);
575
576     st_continue = curr_state();
577     st_quit = s;
578     paused = 1;
579
580     return goto_state(&st_pause);
581 }
582
583 static int pause_action(int i)
584 {
585     audio_play(AUD_MENU, 1.0f);
586
587     switch(i)
588     {
589     case PAUSE_CONTINUE:
590         return goto_state(st_continue ? st_continue : &st_title);
591
592     case PAUSE_QUIT:
593         return goto_state(st_quit);
594     }
595     return 1;
596 }
597
598 static int pause_enter(struct state *st, struct state *prev)
599 {
600     int id, jd, td;
601
602     audio_music_fade_out(0.2f);
603
604     if ((id = gui_vstack(0)))
605     {
606         td = gui_label(id, _("Paused"), GUI_LRG, GUI_ALL, 0, 0);
607         gui_space(id);
608
609         if ((jd = gui_harray(id)))
610         {
611             gui_state(jd, _("Quit"), GUI_SML, PAUSE_QUIT, 0);
612             gui_start(jd, _("Continue"), GUI_SML, PAUSE_CONTINUE, 1);
613         }
614
615         gui_pulse(td, 1.2f);
616         gui_layout(id, 0, 0);
617     }
618
619     hud_init();
620     return id;
621 }
622
623 static void pause_leave(struct state *st, struct state *next, int id)
624 {
625     gui_delete(id);
626     hud_free();
627     audio_music_fade_in(0.5f);
628 }
629
630 static void pause_paint(int id, float t)
631 {
632     game_draw(0, t);
633     gui_paint(id);
634     hud_paint();
635 }
636
637 static void pause_timer(int id, float dt)
638 {
639     gui_timer(id, dt);
640 }
641
642 static void pause_point(int id, int x, int y, int dx, int dy)
643 {
644     gui_pulse(gui_point(id, x, y), 1.2f);
645 }
646
647 static int pause_click(int b, int d)
648 {
649     return d && b == SDL_BUTTON_LEFT ? pause_action(gui_token(gui_click())) : 1;
650 }
651
652 static int pause_keybd(int c, int d)
653 {
654     if (d && config_tst_d(CONFIG_KEY_PAUSE, c))
655         return pause_action(PAUSE_CONTINUE);
656     return 1;
657 }
658
659 static int pause_buttn(int b, int d)
660 {
661     if (d)
662     {
663         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
664             return pause_action(gui_token(gui_click()));
665         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
666             return pause_action(PAUSE_CONTINUE);
667     }
668     return 1;
669 }
670
671 /*---------------------------------------------------------------------------*/
672
673 static int shared_keybd(int c, int d)
674 {
675     if (d)
676     {
677         if (config_tst_d(CONFIG_KEY_PAUSE, c))
678             return goto_pause(&st_over, 0);
679     }
680     return 1;
681 }
682
683 /*---------------------------------------------------------------------------*/
684
685 static int num = 0;
686
687 static int next_enter(struct state *st, struct state *prev)
688 {
689     int id;
690     char str[MAXSTR];
691
692     sprintf(str, _("Hole %02d"), curr_hole());
693
694     if ((id = gui_vstack(0)))
695     {
696         gui_label(id, str, GUI_MED, GUI_ALL, 0, 0);
697         gui_space(id);
698
699         gui_label(id, _("Player"), GUI_SML, GUI_TOP, 0, 0);
700
701         switch (curr_player())
702         {
703         case 1:
704             gui_label(id, "1", GUI_LRG, GUI_BOT, gui_red, gui_wht);
705             if (curr_party() > 1) audio_play(AUD_PLAYER1, 1.f);
706             break;
707         case 2:
708             gui_label(id, "2", GUI_LRG, GUI_BOT, gui_grn, gui_wht);
709             if (curr_party() > 1) audio_play(AUD_PLAYER2, 1.f);
710             break;
711         case 3:
712             gui_label(id, "3", GUI_LRG, GUI_BOT, gui_blu, gui_wht);
713             if (curr_party() > 1) audio_play(AUD_PLAYER3, 1.f);
714             break;
715         case 4:
716             gui_label(id, "4", GUI_LRG, GUI_BOT, gui_yel, gui_wht);
717             if (curr_party() > 1) audio_play(AUD_PLAYER4, 1.f);
718             break;
719         }
720         gui_layout(id, 0, 0);
721     }
722
723     hud_init();
724     game_set_fly(1.f);
725
726     if (paused)
727         paused = 0;
728
729     return id;
730 }
731
732 static void next_leave(struct state *st, struct state *next, int id)
733 {
734     hud_free();
735     gui_delete(id);
736 }
737
738 static void next_paint(int id, float t)
739 {
740     game_draw(0, t);
741     hud_paint();
742     gui_paint(id);
743 }
744
745 static void next_timer(int id, float dt)
746 {
747     gui_timer(id, dt);
748 }
749
750 static void next_point(int id, int x, int y, int dx, int dy)
751 {
752     gui_pulse(gui_point(id, x, y), 1.2f);
753 }
754
755 static int next_click(int b, int d)
756 {
757     return (d && b == SDL_BUTTON_LEFT) ? goto_state(&st_flyby) : 1;
758 }
759
760 static int next_keybd(int c, int d)
761 {
762     if (d)
763     {
764         if (c == SDLK_F12)
765             return goto_state(&st_poser);
766         if (config_tst_d(CONFIG_KEY_PAUSE, c))
767             return goto_pause(&st_over, 0);
768         if ('0' <= c && c <= '9')
769             num = num * 10 + c - '0';
770     }
771     return 1;
772 }
773
774 static int next_buttn(int b, int d)
775 {
776     if (d)
777     {
778         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
779         {
780             if (num > 0 && hole_goto(num, -1))
781             {
782                 num = 0;
783                 return goto_state(&st_next);
784             }
785             return goto_state(&st_flyby);
786         }
787         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
788             return goto_pause(&st_over, 1);
789     }
790     return 1;
791 }
792
793 /*---------------------------------------------------------------------------*/
794
795 static int poser_enter(struct state *st, struct state *prev)
796 {
797     game_set_fly(-1.f);
798     return 0;
799 }
800
801 static void poser_paint(int id, float t)
802 {
803     game_draw(1, t);
804 }
805
806 static int poser_buttn(int b, int d)
807 {
808     if (d)
809     {
810         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
811             return goto_state(&st_next);
812         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
813             return goto_state(&st_next);
814     }
815     return 1;
816 }
817
818 /*---------------------------------------------------------------------------*/
819
820 static int flyby_enter(struct state *st, struct state *prev)
821 {
822     if (paused)
823         paused = 0;
824     else
825         hud_init();
826
827     return 0;
828 }
829
830 static void flyby_leave(struct state *st, struct state *next, int id)
831 {
832     hud_free();
833 }
834
835 static void flyby_paint(int id, float t)
836 {
837     game_draw(0, t);
838     hud_paint();
839 }
840
841 static void flyby_timer(int id, float dt)
842 {
843     float t = time_state();
844
845     if (dt > 0.f && t > 1.f)
846         goto_state(&st_stroke);
847     else
848         game_set_fly(1.f - t);
849
850     gui_timer(id, dt);
851 }
852
853 static int flyby_click(int b, int d)
854 {
855     if (d && b == SDL_BUTTON_LEFT)
856     {
857         game_set_fly(0.f);
858         return goto_state(&st_stroke);
859     }
860     return 1;
861 }
862
863 static int flyby_buttn(int b, int d)
864 {
865     if (d)
866     {
867         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
868         {
869             game_set_fly(0.f);
870             return goto_state(&st_stroke);
871         }
872         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
873             return goto_pause(&st_over, 1);
874     }
875     return 1;
876 }
877
878 /*---------------------------------------------------------------------------*/
879
880 static int stroke_rotate = 0;
881 static int stroke_mag    = 0;
882
883 static int stroke_enter(struct state *st, struct state *prev)
884 {
885     hud_init();
886     game_clr_mag();
887     config_set_d(CONFIG_CAMERA, 2);
888     video_set_grab(!paused);
889
890     if (paused)
891         paused = 0;
892
893     return 0;
894 }
895
896 static void stroke_leave(struct state *st, struct state *next, int id)
897 {
898     hud_free();
899     video_clr_grab();
900     config_set_d(CONFIG_CAMERA, 0);
901 }
902
903 static void stroke_paint(int id, float t)
904 {
905     game_draw(0, t);
906     hud_paint();
907 }
908
909 static void stroke_timer(int id, float dt)
910 {
911     float g[3] = { 0.f, 0.f, 0.f };
912
913     float k;
914
915     if (SDL_GetModState() & KMOD_SHIFT ||
916         (joystick && SDL_JoystickGetButton(joystick,
917                                            config_get_d(CONFIG_JOYSTICK_BUTTON_B))))
918         k = 0.25;
919     else
920         k = 1.0;
921
922     game_set_rot(stroke_rotate * k);
923     game_set_mag(stroke_mag * k);
924
925     game_update_view(dt);
926     game_step(g, dt);
927 }
928
929 static void stroke_point(int id, int x, int y, int dx, int dy)
930 {
931     game_set_rot(dx);
932     game_set_mag(dy);
933 }
934
935 static void stroke_stick(int id, int a, float v, int bump)
936 {
937     if (config_tst_d(CONFIG_JOYSTICK_AXIS_X, a))
938         stroke_rotate = 6 * v;
939     else if (config_tst_d(CONFIG_JOYSTICK_AXIS_Y, a))
940         stroke_mag = -6 * v;
941 }
942
943 static int stroke_click(int b, int d)
944 {
945     return (d && b == SDL_BUTTON_LEFT) ? goto_state(&st_roll) : 1;
946 }
947
948 static int stroke_buttn(int b, int d)
949 {
950     if (d)
951     {
952         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
953             return goto_state(&st_roll);
954         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
955             return goto_pause(&st_over, 1);
956     }
957     return 1;
958 }
959
960 /*---------------------------------------------------------------------------*/
961
962 static int roll_enter(struct state *st, struct state *prev)
963 {
964     hud_init();
965
966     if (paused)
967         paused = 0;
968     else
969         game_putt();
970
971     return 0;
972 }
973
974 static void roll_leave(struct state *st, struct state *next, int id)
975 {
976     hud_free();
977 }
978
979 static void roll_paint(int id, float t)
980 {
981     game_draw(0, t);
982     hud_paint();
983 }
984
985 static void roll_timer(int id, float dt)
986 {
987     float g[3] = { 0.0f, -9.8f, 0.0f };
988
989     switch (game_step(g, dt))
990     {
991     case GAME_STOP: goto_state(&st_stop); break;
992     case GAME_GOAL: goto_state(&st_goal); break;
993     case GAME_FALL: goto_state(&st_fall); break;
994     }
995 }
996
997 static int roll_buttn(int b, int d)
998 {
999     if (d)
1000     {
1001         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
1002             return goto_pause(&st_over, 1);
1003     }
1004     return 1;
1005 }
1006
1007 /*---------------------------------------------------------------------------*/
1008
1009 static int goal_enter(struct state *st, struct state *prev)
1010 {
1011     int id;
1012
1013     if ((id = gui_label(0, _("It's In!"), GUI_MED, GUI_ALL, gui_grn, gui_grn)))
1014         gui_layout(id, 0, 0);
1015
1016     if (paused)
1017         paused = 0;
1018     else
1019         hole_goal();
1020
1021     hud_init();
1022
1023     return id;
1024 }
1025
1026 static void goal_leave(struct state *st, struct state *next, int id)
1027 {
1028     gui_delete(id);
1029     hud_free();
1030 }
1031
1032 static void goal_paint(int id, float t)
1033 {
1034     game_draw(0, t);
1035     gui_paint(id);
1036     hud_paint();
1037 }
1038
1039 static void goal_timer(int id, float dt)
1040 {
1041     if (time_state() > 3)
1042     {
1043         if (hole_next())
1044             goto_state(&st_next);
1045         else
1046             goto_state(&st_score);
1047     }
1048 }
1049
1050 static int goal_click(int b, int d)
1051 {
1052     if (b == SDL_BUTTON_LEFT && d == 1)
1053     {
1054         if (hole_next())
1055             goto_state(&st_next);
1056         else
1057             goto_state(&st_score);
1058     }
1059     return 1;
1060 }
1061
1062 static int goal_buttn(int b, int d)
1063 {
1064     if (d)
1065     {
1066         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
1067         {
1068             if (hole_next())
1069                 goto_state(&st_next);
1070             else
1071                 goto_state(&st_score);
1072         }
1073         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
1074             return goto_pause(&st_over, 1);
1075     }
1076     return 1;
1077 }
1078
1079 /*---------------------------------------------------------------------------*/
1080
1081 static int stop_enter(struct state *st, struct state *prev)
1082 {
1083     if (paused)
1084         paused = 0;
1085     else
1086         hole_stop();
1087
1088     hud_init();
1089
1090     return 0;
1091 }
1092
1093 static void stop_leave(struct state *st, struct state *next, int id)
1094 {
1095     hud_free();
1096 }
1097
1098 static void stop_paint(int id, float t)
1099 {
1100     game_draw(0, t);
1101     hud_paint();
1102 }
1103
1104 static void stop_timer(int id, float dt)
1105 {
1106     float g[3] = { 0.f, 0.f, 0.f };
1107
1108     game_update_view(dt);
1109     game_step(g, dt);
1110
1111     if (time_state() > 1)
1112     {
1113         if (hole_next())
1114             goto_state(&st_next);
1115         else
1116             goto_state(&st_score);
1117     }
1118 }
1119
1120 static int stop_click(int b, int d)
1121 {
1122     if (b == SDL_BUTTON_LEFT && d == 1)
1123     {
1124         if (hole_next())
1125             goto_state(&st_next);
1126         else
1127             goto_state(&st_score);
1128     }
1129     return 1;
1130 }
1131
1132 static int stop_buttn(int b, int d)
1133 {
1134     if (d)
1135     {
1136         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
1137         {
1138             if (hole_next())
1139                 goto_state(&st_next);
1140             else
1141                 goto_state(&st_score);
1142         }
1143         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
1144             return goto_pause(&st_over, 1);
1145     }
1146     return 1;
1147 }
1148
1149 /*---------------------------------------------------------------------------*/
1150
1151 static int fall_enter(struct state *st, struct state *prev)
1152 {
1153     int id;
1154
1155     if ((id = gui_label(0, _("1 Stroke Penalty"), GUI_MED, GUI_ALL, gui_blk, gui_red)))
1156         gui_layout(id, 0, 0);
1157
1158     if (paused)
1159         paused = 0;
1160     else
1161     {
1162         hole_fall();
1163 /*        game_draw(0);*/ /*TODO: is this call ok? */  /* No, it's not. */
1164     }
1165
1166     hud_init();
1167
1168     return id;
1169 }
1170
1171 static void fall_leave(struct state *st, struct state *next, int id)
1172 {
1173     gui_delete(id);
1174     hud_free();
1175 }
1176
1177 static void fall_paint(int id, float t)
1178 {
1179     game_draw(0, t);
1180     gui_paint(id);
1181     hud_paint();
1182 }
1183
1184 static void fall_timer(int id, float dt)
1185 {
1186     if (time_state() > 3)
1187     {
1188         if (hole_next())
1189             goto_state(&st_next);
1190         else
1191             goto_state(&st_score);
1192     }
1193 }
1194
1195 static int fall_click(int b, int d)
1196 {
1197     if (b == SDL_BUTTON_LEFT && d == 1)
1198     {
1199         if (hole_next())
1200             goto_state(&st_next);
1201         else
1202             goto_state(&st_score);
1203     }
1204     return 1;
1205 }
1206
1207 static int fall_buttn(int b, int d)
1208 {
1209     if (d)
1210     {
1211         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
1212         {
1213             if (hole_next())
1214                 goto_state(&st_next);
1215             else
1216                 goto_state(&st_score);
1217         }
1218         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
1219             return goto_pause(&st_over, 1);
1220     }
1221     return 1;
1222 }
1223
1224 /*---------------------------------------------------------------------------*/
1225
1226 static int score_enter(struct state *st, struct state *prev)
1227 {
1228     audio_music_fade_out(2.f);
1229
1230     if (paused)
1231         paused = 0;
1232
1233     return score_card(_("Scores"), gui_yel, gui_red);
1234 }
1235
1236 static void score_leave(struct state *st, struct state *next, int id)
1237 {
1238     gui_delete(id);
1239 }
1240
1241 static void score_paint(int id, float t)
1242 {
1243     game_draw(0, t);
1244     gui_paint(id);
1245 }
1246
1247 static void score_timer(int id, float dt)
1248 {
1249     gui_timer(id, dt);
1250 }
1251
1252 static int score_click(int b, int d)
1253 {
1254     if (b == SDL_BUTTON_LEFT && d == 1)
1255     {
1256         if (hole_move())
1257             return goto_state(&st_next);
1258         else
1259             return goto_state(&st_title);
1260     }
1261     return 1;
1262 }
1263
1264 static int score_buttn(int b, int d)
1265 {
1266     if (d)
1267     {
1268         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
1269         {
1270             if (hole_move())
1271                 goto_state(&st_next);
1272             else
1273                 goto_state(&st_score);
1274         }
1275         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
1276             return goto_pause(&st_over, 1);
1277     }
1278     return 1;
1279 }
1280
1281 /*---------------------------------------------------------------------------*/
1282
1283 static int over_enter(struct state *st, struct state *prev)
1284 {
1285     audio_music_fade_out(2.f);
1286     return score_card(_("Final Scores"), gui_yel, gui_red);
1287 }
1288
1289 static void over_leave(struct state *st, struct state *next, int id)
1290 {
1291     gui_delete(id);
1292 }
1293
1294 static void over_paint(int id, float t)
1295 {
1296     game_draw(0, t);
1297     gui_paint(id);
1298 }
1299
1300 static void over_timer(int id, float dt)
1301 {
1302     gui_timer(id, dt);
1303 }
1304
1305 static int over_click(int b, int d)
1306 {
1307     return (d && b == SDL_BUTTON_LEFT) ? goto_state(&st_title) : 1;
1308 }
1309
1310 static int over_buttn(int b, int d)
1311 {
1312     if (d)
1313     {
1314         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
1315             return goto_state(&st_title);
1316         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
1317             return goto_state(&st_title);
1318     }
1319     return 1;
1320 }
1321
1322 /*---------------------------------------------------------------------------*/
1323
1324 struct state st_title = {
1325     title_enter,
1326     title_leave,
1327     title_paint,
1328     title_timer,
1329     title_point,
1330     shared_stick,
1331     NULL,
1332     title_click,
1333     NULL,
1334     title_buttn
1335 };
1336
1337 struct state st_course = {
1338     course_enter,
1339     course_leave,
1340     course_paint,
1341     course_timer,
1342     course_point,
1343     course_stick,
1344     NULL,
1345     course_click,
1346     NULL,
1347     course_buttn
1348 };
1349
1350 struct state st_party = {
1351     party_enter,
1352     party_leave,
1353     party_paint,
1354     party_timer,
1355     party_point,
1356     shared_stick,
1357     NULL,
1358     party_click,
1359     NULL,
1360     party_buttn
1361 };
1362
1363 struct state st_next = {
1364     next_enter,
1365     next_leave,
1366     next_paint,
1367     next_timer,
1368     next_point,
1369     shared_stick,
1370     NULL,
1371     next_click,
1372     next_keybd,
1373     next_buttn
1374 };
1375
1376 struct state st_poser = {
1377     poser_enter,
1378     NULL,
1379     poser_paint,
1380     NULL,
1381     NULL,
1382     NULL,
1383     NULL,
1384     NULL,
1385     NULL,
1386     poser_buttn
1387 };
1388
1389 struct state st_flyby = {
1390     flyby_enter,
1391     flyby_leave,
1392     flyby_paint,
1393     flyby_timer,
1394     NULL,
1395     NULL,
1396     NULL,
1397     flyby_click,
1398     shared_keybd,
1399     flyby_buttn
1400 };
1401
1402 struct state st_stroke = {
1403     stroke_enter,
1404     stroke_leave,
1405     stroke_paint,
1406     stroke_timer,
1407     stroke_point,
1408     stroke_stick,
1409     NULL,
1410     stroke_click,
1411     shared_keybd,
1412     stroke_buttn
1413 };
1414
1415 struct state st_roll = {
1416     roll_enter,
1417     roll_leave,
1418     roll_paint,
1419     roll_timer,
1420     NULL,
1421     NULL,
1422     NULL,
1423     NULL,
1424     shared_keybd,
1425     roll_buttn
1426 };
1427
1428 struct state st_goal = {
1429     goal_enter,
1430     goal_leave,
1431     goal_paint,
1432     goal_timer,
1433     NULL,
1434     NULL,
1435     NULL,
1436     goal_click,
1437     shared_keybd,
1438     goal_buttn
1439 };
1440
1441 struct state st_stop = {
1442     stop_enter,
1443     stop_leave,
1444     stop_paint,
1445     stop_timer,
1446     NULL,
1447     NULL,
1448     NULL,
1449     stop_click,
1450     shared_keybd,
1451     stop_buttn
1452 };
1453
1454 struct state st_fall = {
1455     fall_enter,
1456     fall_leave,
1457     fall_paint,
1458     fall_timer,
1459     NULL,
1460     NULL,
1461     NULL,
1462     fall_click,
1463     shared_keybd,
1464     fall_buttn
1465 };
1466
1467 struct state st_score = {
1468     score_enter,
1469     score_leave,
1470     score_paint,
1471     score_timer,
1472     NULL,
1473     NULL,
1474     NULL,
1475     score_click,
1476     shared_keybd,
1477     score_buttn
1478 };
1479
1480 struct state st_over = {
1481     over_enter,
1482     over_leave,
1483     over_paint,
1484     over_timer,
1485     NULL,
1486     NULL,
1487     NULL,
1488     over_click,
1489     NULL,
1490     over_buttn
1491 };
1492
1493 struct state st_pause = {
1494     pause_enter,
1495     pause_leave,
1496     pause_paint,
1497     pause_timer,
1498     pause_point,
1499     shared_stick,
1500     NULL,
1501     pause_click,
1502     pause_keybd,
1503     pause_buttn
1504 };