2 * Copyright (C) 2003 Robert Kooima
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.
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.
31 /*---------------------------------------------------------------------------*/
33 static char *number(int i)
35 static char str[MAXSTR];
37 sprintf(str, "%02d", i);
42 static int score_card(const char *title,
48 int p1 = (curr_party() >= 1) ? 1 : 0, l1 = (curr_party() == 1) ? 1 : 0;
49 int p2 = (curr_party() >= 2) ? 1 : 0, l2 = (curr_party() == 2) ? 1 : 0;
50 int p3 = (curr_party() >= 3) ? 1 : 0, l3 = (curr_party() == 3) ? 1 : 0;
51 int p4 = (curr_party() >= 4) ? 1 : 0, l4 = (curr_party() == 4) ? 1 : 0;
54 int n = curr_count() - 1;
55 int m = curr_count() / 2;
57 if ((id = gui_vstack(0)))
59 gui_label(id, title, GUI_MED, GUI_ALL, c0, c1);
62 if ((jd = gui_hstack(id)))
64 if ((kd = gui_varray(jd)))
66 if (p1) gui_label(kd, _("O"), 0, GUI_NE, 0, 0);
67 if (p1) gui_label(kd, hole_out(0), 0, 0, gui_wht, gui_wht);
68 if (p1) gui_label(kd, hole_out(1), 0, GUI_SE * l1, gui_red, gui_wht);
69 if (p2) gui_label(kd, hole_out(2), 0, GUI_SE * l2, gui_grn, gui_wht);
70 if (p3) gui_label(kd, hole_out(3), 0, GUI_SE * l3, gui_blu, gui_wht);
71 if (p4) gui_label(kd, hole_out(4), 0, GUI_SE * l4, gui_yel, gui_wht);
74 if ((kd = gui_harray(jd)))
75 for (i = m; i > 0; i--)
76 if ((ld = gui_varray(kd)))
78 if (p1) gui_label(ld, number(i), 0, (i == 1) ? GUI_NW : 0, 0, 0);
79 if (p1) gui_label(ld, hole_score(i, 0), 0, 0, gui_wht, gui_wht);
80 if (p1) gui_label(ld, hole_score(i, 1), 0, 0, gui_red, gui_wht);
81 if (p2) gui_label(ld, hole_score(i, 2), 0, 0, gui_grn, gui_wht);
82 if (p3) gui_label(ld, hole_score(i, 3), 0, 0, gui_blu, gui_wht);
83 if (p4) gui_label(ld, hole_score(i, 4), 0, 0, gui_yel, gui_wht);
85 if ((kd = gui_varray(jd)))
88 if (p1) gui_label(kd, _("Par"), 0, GUI_NW, gui_wht, gui_wht);
89 if (p1) gui_label(kd, _("P1"), 0, GUI_SW * l1, gui_red, gui_wht);
90 if (p2) gui_label(kd, _("P2"), 0, GUI_SW * l2, gui_grn, gui_wht);
91 if (p3) gui_label(kd, _("P3"), 0, GUI_SW * l3, gui_blu, gui_wht);
92 if (p4) gui_label(kd, _("P4"), 0, GUI_SW * l4, gui_yel, gui_wht);
98 if ((jd = gui_hstack(id)))
100 if ((kd = gui_varray(jd)))
102 if (p1) gui_label(kd, _("Tot"), 0, GUI_TOP, 0, 0);
103 if (p1) gui_label(kd, hole_tot(0), 0, 0, gui_wht, gui_wht);
104 if (p1) gui_label(kd, hole_tot(1), 0, GUI_BOT * l1, gui_red, gui_wht);
105 if (p2) gui_label(kd, hole_tot(2), 0, GUI_BOT * l2, gui_grn, gui_wht);
106 if (p3) gui_label(kd, hole_tot(3), 0, GUI_BOT * l3, gui_blu, gui_wht);
107 if (p4) gui_label(kd, hole_tot(4), 0, GUI_BOT * l4, gui_yel, gui_wht);
109 if ((kd = gui_varray(jd)))
111 if (p1) gui_label(kd, _("I"), 0, GUI_NE, 0, 0);
112 if (p1) gui_label(kd, hole_in(0), 0, 0, gui_wht, gui_wht);
113 if (p1) gui_label(kd, hole_in(1), 0, GUI_SE * l1, gui_red, gui_wht);
114 if (p2) gui_label(kd, hole_in(2), 0, GUI_SE * l2, gui_grn, gui_wht);
115 if (p3) gui_label(kd, hole_in(3), 0, GUI_SE * l3, gui_blu, gui_wht);
116 if (p4) gui_label(kd, hole_in(4), 0, GUI_SE * l4, gui_yel, gui_wht);
118 if ((kd = gui_harray(jd)))
119 for (i = n; i > m; i--)
120 if ((ld = gui_varray(kd)))
122 if (p1) gui_label(ld, number(i), 0, (i == m+1) ? GUI_NW : 0, 0, 0);
123 if (p1) gui_label(ld, hole_score(i, 0), 0, 0, gui_wht, gui_wht);
124 if (p1) gui_label(ld, hole_score(i, 1), 0, 0, gui_red, gui_wht);
125 if (p2) gui_label(ld, hole_score(i, 2), 0, 0, gui_grn, gui_wht);
126 if (p3) gui_label(ld, hole_score(i, 3), 0, 0, gui_blu, gui_wht);
127 if (p4) gui_label(ld, hole_score(i, 4), 0, 0, gui_yel, gui_wht);
129 if ((kd = gui_varray(jd)))
132 if (p1) gui_label(kd, _("Par"), 0, GUI_NW, gui_wht, gui_wht);
133 if (p1) gui_label(kd, _("P1"), 0, GUI_SW * l1, gui_red, gui_wht);
134 if (p2) gui_label(kd, _("P2"), 0, GUI_SW * l2, gui_grn, gui_wht);
135 if (p3) gui_label(kd, _("P3"), 0, GUI_SW * l3, gui_blu, gui_wht);
136 if (p4) gui_label(kd, _("P4"), 0, GUI_SW * l4, gui_yel, gui_wht);
140 gui_layout(id, 0, 0);
146 /*---------------------------------------------------------------------------*/
152 static int title_action(int i)
154 audio_play(AUD_MENU, 1.0f);
158 case TITLE_PLAY: return goto_state(&st_course);
159 case TITLE_CONF: return goto_state(&st_conf);
160 case TITLE_EXIT: return 0;
165 static int title_enter(void)
169 /* Build the title GUI. */
171 if ((id = gui_vstack(0)))
173 gui_label(id, "Neverputt", GUI_LRG, GUI_ALL, 0, 0);
176 if ((jd = gui_harray(id)))
180 if ((kd = gui_varray(jd)))
182 gui_start(kd, sgettext("menu^Play"), GUI_MED, TITLE_PLAY, 1);
183 gui_state(kd, sgettext("menu^Options"), GUI_MED, TITLE_CONF, 0);
184 gui_state(kd, sgettext("menu^Exit"), GUI_MED, TITLE_EXIT, 0);
189 gui_layout(id, 0, 0);
198 static void title_leave(int id)
203 static void title_paint(int id, float st)
209 static void title_timer(int id, float dt)
211 float g[3] = { 0.f, 0.f, 0.f };
214 game_set_fly(fcosf(time_state() / 10.f));
220 static void title_point(int id, int x, int y, int dx, int dy)
222 gui_pulse(gui_point(id, x, y), 1.2f);
225 static int title_click(int b, int d)
227 return (d && b < 0) ? title_action(gui_token(gui_click())) : 1;
230 static int title_keybd(int c, int d)
232 return (d && c == SDLK_ESCAPE) ? 0 : 1;
235 /*---------------------------------------------------------------------------*/
240 static int course_action(int i)
242 if (course_exists(i))
245 goto_state(&st_party);
248 goto_state(&st_title);
253 static int course_enter(void)
255 int w = config_get_d(CONFIG_WIDTH);
256 int h = config_get_d(CONFIG_HEIGHT);
258 int id, jd, kd, ld, i = 0, j, n = course_count();
259 int m = (int)(sqrt(n/2.0)*2);
261 if ((id = gui_vstack(0)))
263 gui_label(id, _("Select Course"), GUI_MED, GUI_ALL, 0, 0);
266 if ((jd = gui_hstack(id)))
268 shot_id = gui_image(jd, course_shot(0), w / 3, h / 3);
270 if ((kd = gui_varray(jd)))
272 for(i = 0; i < n; i += m)
274 if ((ld = gui_harray(kd)))
276 for (j = (m - 1); j >= 0; j--)
279 gui_active(gui_image(ld, course_shot(i + j),
280 w / 3 / m, h / 3 / m),
291 desc_id = gui_multi(id, _(course_desc(0)), GUI_SML, GUI_ALL, gui_yel, gui_wht);
294 if ((jd = gui_hstack(id)))
297 gui_state(jd, _("Back"), GUI_SML, -1, 0);
300 gui_layout(id, 0, 0);
303 audio_music_fade_to(0.5f, "bgm/inter.ogg");
308 static void course_leave(int id)
313 static void course_paint(int id, float st)
319 static void course_timer(int id, float dt)
325 static void course_point(int id, int x, int y, int dx, int dy)
329 if ((jd = gui_point(id, x, y)))
331 int i = gui_token(jd);
332 if (course_exists(i))
334 gui_set_image(shot_id, course_shot(i));
335 gui_set_multi(desc_id, _(course_desc(i)));
341 static int course_click(int b, int d)
343 return (d && b < 0) ? course_action(gui_token(gui_click())) : 1;
346 static int course_keybd(int c, int d)
348 return (d && c == SDLK_ESCAPE) ? goto_state(&st_title) : 1;
351 /*---------------------------------------------------------------------------*/
360 static int party_action(int i)
365 audio_play(AUD_MENU, 1.f);
367 goto_state(&st_next);
370 audio_play(AUD_MENU, 1.f);
372 goto_state(&st_next);
375 audio_play(AUD_MENU, 1.f);
377 goto_state(&st_next);
380 audio_play(AUD_MENU, 1.f);
382 goto_state(&st_next);
385 audio_play(AUD_MENU, 1.f);
386 goto_state(&st_course);
392 static int party_enter(void)
396 if ((id = gui_vstack(0)))
398 gui_label(id, _("Players?"), GUI_MED, GUI_ALL, 0, 0);
401 if ((jd = gui_harray(id)))
403 int p4 = gui_state(jd, "4", GUI_LRG, PARTY_4, 0);
404 int p3 = gui_state(jd, "3", GUI_LRG, PARTY_3, 0);
405 int p2 = gui_state(jd, "2", GUI_LRG, PARTY_2, 0);
406 int p1 = gui_state(jd, "1", GUI_LRG, PARTY_1, 0);
408 gui_set_color(p1, gui_red, gui_wht);
409 gui_set_color(p2, gui_grn, gui_wht);
410 gui_set_color(p3, gui_blu, gui_wht);
411 gui_set_color(p4, gui_yel, gui_wht);
416 if ((jd = gui_hstack(id)))
419 gui_state(jd, _("Back"), GUI_SML, PARTY_B, 0);
422 gui_layout(id, 0, 0);
428 static void party_leave(int id)
433 static void party_paint(int id, float st)
439 static void party_timer(int id, float dt)
445 static void party_point(int id, int x, int y, int dx, int dy)
447 gui_pulse(gui_point(id, x, y), 1.2f);
450 static int party_click(int b, int d)
452 return (d && b < 0) ? party_action(gui_token(gui_click())) : 1;
455 static int party_keybd(int c, int d)
457 return (d && c == SDLK_ESCAPE) ? goto_state(&st_course) : 1;
460 /*---------------------------------------------------------------------------*/
462 static int paused = 0;
464 static struct state *st_continue;
465 static struct state *st_quit;
467 #define PAUSE_CONTINUE 1
470 int goto_pause(struct state *s, int e)
472 if (e && (SDL_GetModState() & (KMOD_SHIFT | KMOD_CTRL | KMOD_ALT | KMOD_META)))
473 return goto_state(s);
474 st_continue = curr_state();
477 return goto_state(&st_pause);
480 static int pause_action(int i)
482 audio_play(AUD_MENU, 1.0f);
487 return goto_state(st_continue ? st_continue : &st_title);
490 return goto_state(st_quit);
495 static int pause_enter(void)
499 audio_music_fade_out(0.2f);
501 if ((id = gui_vstack(0)))
503 td = gui_label(id, _("Paused"), GUI_LRG, GUI_ALL, 0, 0);
506 if ((jd = gui_harray(id)))
508 gui_state(jd, _("Quit"), GUI_SML, PAUSE_QUIT, 0);
509 gui_start(jd, _("Continue"), GUI_SML, PAUSE_CONTINUE, 1);
513 gui_layout(id, 0, 0);
520 static void pause_leave(int id)
524 audio_music_fade_in(0.5f);
527 static void pause_paint(int id, float st)
534 static void pause_timer(int id, float dt)
540 static void pause_point(int id, int x, int y, int dx, int dy)
542 gui_pulse(gui_point(id, x, y), 1.2f);
545 static int pause_click(int b, int d)
547 return (d && b < 0) ? pause_action(gui_token(gui_click())) : 1;
550 static int pause_keybd(int c, int d)
552 if (d && (c == SDLK_ESCAPE || config_tst_d(CONFIG_KEY_PAUSE, c)))
553 return pause_action(PAUSE_CONTINUE);
557 /*---------------------------------------------------------------------------*/
559 static int shared_keybd(int c, int d)
563 if (c == SDLK_ESCAPE)
564 return goto_pause(&st_over, 1);
565 if (config_tst_d(CONFIG_KEY_PAUSE, c))
566 return goto_pause(&st_over, 0);
571 /*---------------------------------------------------------------------------*/
575 static int next_enter(void)
580 sprintf(str, _("Hole %02d"), curr_hole());
582 if ((id = gui_vstack(0)))
584 gui_label(id, str, GUI_MED, GUI_ALL, 0, 0);
587 gui_label(id, _("Player"), GUI_SML, GUI_TOP, 0, 0);
589 switch (curr_player())
592 gui_label(id, "1", GUI_LRG, GUI_BOT, gui_red, gui_wht);
593 if (curr_party() > 1) audio_play(AUD_PLAYER1, 1.f);
596 gui_label(id, "2", GUI_LRG, GUI_BOT, gui_grn, gui_wht);
597 if (curr_party() > 1) audio_play(AUD_PLAYER2, 1.f);
600 gui_label(id, "3", GUI_LRG, GUI_BOT, gui_blu, gui_wht);
601 if (curr_party() > 1) audio_play(AUD_PLAYER3, 1.f);
604 gui_label(id, "4", GUI_LRG, GUI_BOT, gui_yel, gui_wht);
605 if (curr_party() > 1) audio_play(AUD_PLAYER4, 1.f);
608 gui_layout(id, 0, 0);
620 static void next_leave(int id)
626 static void next_paint(int id, float st)
633 static void next_timer(int id, float dt)
639 static void next_point(int id, int x, int y, int dx, int dy)
641 gui_pulse(gui_point(id, x, y), 1.2f);
644 static int next_click(int b, int d)
646 return (d && b < 0) ? goto_state(&st_flyby) : 1;
649 static int next_keybd(int c, int d)
654 return goto_state(&st_poser);
655 if (c == SDLK_ESCAPE)
656 return goto_pause(&st_over, 1);
657 if (config_tst_d(CONFIG_KEY_PAUSE, c))
658 return goto_pause(&st_over, 0);
659 if (c == SDLK_RETURN)
663 return goto_state(&st_next);
665 if ('0' <= c && c <= '9')
666 num = num * 10 + c - '0';
671 /*---------------------------------------------------------------------------*/
673 static int poser_enter(void)
679 static void poser_paint(int id, float st)
684 static int poser_keybd(int c, int d)
686 return (d && c == SDLK_ESCAPE) ? goto_state(&st_next) : 1;
689 /*---------------------------------------------------------------------------*/
691 static int flyby_enter(void)
701 static void flyby_leave(int id)
706 static void flyby_paint(int id, float st)
712 static void flyby_timer(int id, float dt)
714 float t = time_state();
716 if (dt > 0.f && t > 1.f)
717 goto_state(&st_stroke);
719 game_set_fly(1.f - t);
725 static int flyby_click(int b, int d)
730 return goto_state(&st_stroke);
735 /*---------------------------------------------------------------------------*/
737 static int stroke_enter(void)
741 config_set_d(CONFIG_CAMERA, 2);
742 config_set_grab(!paused);
750 static void stroke_leave(int id)
754 config_set_d(CONFIG_CAMERA, 0);
757 static void stroke_paint(int id, float st)
763 static void stroke_timer(int id, float dt)
765 float g[3] = { 0.f, 0.f, 0.f };
767 game_update_view(dt);
772 static void stroke_point(int id, int x, int y, int dx, int dy)
778 static int stroke_click(int b, int d)
780 return (d && b < 0) ? goto_state(&st_roll) : 1;
783 /*---------------------------------------------------------------------------*/
785 static int roll_enter(void)
797 static void roll_leave(int id)
802 static void roll_paint(int id, float st)
808 static void roll_timer(int id, float dt)
810 float g[3] = { 0.0f, -9.8f, 0.0f };
812 switch (game_step(g, dt))
814 case GAME_STOP: goto_state(&st_stop); break;
815 case GAME_GOAL: goto_state(&st_goal); break;
816 case GAME_FALL: goto_state(&st_fall); break;
821 /*---------------------------------------------------------------------------*/
823 static int goal_enter(void)
827 if ((id = gui_label(0, _("It's In!"), GUI_MED, GUI_ALL, gui_grn, gui_grn)))
828 gui_layout(id, 0, 0);
840 static void goal_leave(int id)
846 static void goal_paint(int id, float st)
853 static void goal_timer(int id, float dt)
855 if (time_state() > 3)
858 goto_state(&st_next);
860 goto_state(&st_score);
865 static int goal_click(int b, int d)
870 goto_state(&st_next);
872 goto_state(&st_score);
877 /*---------------------------------------------------------------------------*/
879 static int stop_enter(void)
891 static void stop_leave(int id)
896 static void stop_paint(int id, float st)
902 static void stop_timer(int id, float dt)
904 float g[3] = { 0.f, 0.f, 0.f };
906 game_update_view(dt);
910 if (time_state() > 1)
913 goto_state(&st_next);
915 goto_state(&st_score);
919 static int stop_click(int b, int d)
924 goto_state(&st_next);
926 goto_state(&st_score);
931 /*---------------------------------------------------------------------------*/
933 static int fall_enter(void)
937 if ((id = gui_label(0, _("1 Stroke Penalty"), GUI_MED, GUI_ALL, gui_blk, gui_red)))
938 gui_layout(id, 0, 0);
945 game_draw(0); /*TODO: is this call ok? */
953 static void fall_leave(int id)
959 static void fall_paint(int id, float st)
966 static void fall_timer(int id, float dt)
968 if (time_state() > 3)
971 goto_state(&st_next);
973 goto_state(&st_score);
978 static int fall_click(int b, int d)
983 goto_state(&st_next);
985 goto_state(&st_score);
990 /*---------------------------------------------------------------------------*/
992 static int score_enter(void)
994 audio_music_fade_out(2.f);
999 return score_card(_("Scores"), gui_yel, gui_red);
1002 static void score_leave(int id)
1007 static void score_paint(int id, float st)
1013 static void score_timer(int id, float dt)
1019 static int score_click(int b, int d)
1021 if (b < 0 && d == 1)
1024 return goto_state(&st_next);
1026 return goto_state(&st_title);
1031 static int score_keybd(int c, int d)
1035 if (c == SDLK_ESCAPE)
1036 return goto_pause(&st_title, 1);
1037 if (config_tst_d(CONFIG_KEY_PAUSE, c))
1038 return goto_pause(&st_title, 0);
1043 /*---------------------------------------------------------------------------*/
1045 static int over_enter(void)
1047 audio_music_fade_out(2.f);
1048 return score_card(_("Final Scores"), gui_yel, gui_red);
1051 static void over_leave(int id)
1056 static void over_paint(int id, float st)
1062 static void over_timer(int id, float dt)
1068 static int over_click(int b, int d)
1070 return (d && b < 0) ? goto_state(&st_title) : 1;
1073 static int over_keybd(int c, int d)
1075 return (d && c == SDLK_ESCAPE) ? goto_state(&st_title) : 1;
1078 /*---------------------------------------------------------------------------*/
1080 struct state st_title = {
1093 struct state st_course = {
1106 struct state st_party = {
1119 struct state st_next = {
1132 struct state st_poser = {
1145 struct state st_flyby = {
1158 struct state st_stroke = {
1171 struct state st_roll = {
1184 struct state st_goal = {
1197 struct state st_stop = {
1210 struct state st_fall = {
1223 struct state st_score = {
1236 struct state st_over = {
1249 struct state st_pause = {