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