Split SOL data structures into base, varying and rendering parts
[neverball] / ball / st_fail.c
1 /*
2  * Copyright (C) 2007 Robert Kooima
3  *
4  * NEVERBALL 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 "util.h"
16 #include "progress.h"
17 #include "demo.h"
18 #include "audio.h"
19 #include "gui.h"
20 #include "config.h"
21 #include "video.h"
22
23 #include "game_common.h"
24 #include "game_server.h"
25 #include "game_client.h"
26
27 #include "st_save.h"
28 #include "st_fail.h"
29 #include "st_level.h"
30 #include "st_play.h"
31 #include "st_shared.h"
32
33 /*---------------------------------------------------------------------------*/
34
35 #define FAIL_NEXT 1
36 #define FAIL_SAME 2
37 #define FAIL_SAVE 3
38 #define FAIL_BACK 4
39 #define FAIL_OVER 5
40
41 static int resume;
42 static int status;
43
44 static int fail_action(int i)
45 {
46     audio_play(AUD_MENU, 1.0f);
47
48     switch (i)
49     {
50     case FAIL_BACK:
51         /* Fall through. */
52
53     case FAIL_OVER:
54         progress_stop();
55         return goto_state(&st_exit);
56
57     case FAIL_SAVE:
58         progress_stop();
59         return goto_save(&st_fail, &st_fail);
60
61     case FAIL_NEXT:
62         if (progress_next())
63             return goto_state(&st_level);
64         break;
65
66     case FAIL_SAME:
67         if (progress_same())
68             return goto_state(&st_level);
69         break;
70     }
71
72     return 1;
73 }
74
75 static int fail_gui(void)
76 {
77     int id, jd, kd;
78
79     const char *label = "";
80
81     if (status == GAME_FALL)
82         label = _("Fall-out!");
83     else if (status == GAME_TIME)
84         label = _("Time's Up!");
85
86     if ((id = gui_vstack(0)))
87     {
88         kd = gui_label(id, label, GUI_LRG, GUI_ALL, gui_gry, gui_red);
89
90         gui_space(id);
91
92         if ((jd = gui_harray(id)))
93         {
94             if (progress_dead())
95                 gui_start(jd, _("Exit"), GUI_SML, FAIL_OVER, 0);
96
97             if (progress_next_avail())
98                 gui_start(jd, _("Next Level"),  GUI_SML, FAIL_NEXT, 0);
99
100             if (progress_same_avail())
101                 gui_start(jd, _("Retry Level"), GUI_SML, FAIL_SAME, 0);
102
103             if (demo_saved())
104                 gui_state(jd, _("Save Replay"), GUI_SML, FAIL_SAVE, 0);
105         }
106
107         gui_space(id);
108
109         gui_pulse(kd, 1.2f);
110         gui_layout(id, 0, 0);
111     }
112
113     return id;
114 }
115
116 static int fail_enter(struct state *st, struct state *prev)
117 {
118     audio_music_fade_out(2.0f);
119     video_clr_grab();
120
121     /* Check if we came from a known previous state. */
122
123     resume = (prev == &st_fail || prev == &st_save);
124
125     /* Note the current status if we got here from elsewhere. */
126
127     if (!resume)
128         status = curr_status();
129
130     return fail_gui();
131 }
132
133 static void fail_timer(int id, float dt)
134 {
135     if (status == GAME_FALL)
136     {
137         if (!resume && time_state() < 2.f)
138         {
139             game_server_step(dt);
140             game_client_sync(demo_fp);
141         }
142     }
143
144     gui_timer(id, dt);
145 }
146
147 static int fail_keybd(int c, int d)
148 {
149     if (d)
150     {
151         if (config_tst_d(CONFIG_KEY_RESTART, c) && progress_same_avail())
152         {
153             if (progress_same())
154                 goto_state(&st_play_ready);
155         }
156     }
157     return 1;
158 }
159
160 static int fail_buttn(int b, int d)
161 {
162     if (d)
163     {
164         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
165             return fail_action(gui_token(gui_click()));
166         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
167             return fail_action(FAIL_BACK);
168     }
169     return 1;
170 }
171
172 /*---------------------------------------------------------------------------*/
173
174 struct state st_fail = {
175     fail_enter,
176     shared_leave,
177     shared_paint,
178     fail_timer,
179     shared_point,
180     shared_stick,
181     shared_angle,
182     shared_click,
183     fail_keybd,
184     fail_buttn
185 };
186