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