9df97b73ddca1eecdb8619a7d125295ec021bd67
[neverball] / ball / st_start.c
1 /*   
2  * Copyright (C) 2003 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 "gui.h"
16 #include "set.h"
17 #include "util.h"
18 #include "game.h"
19 #include "level.h"
20 #include "audio.h"
21 #include "config.h"
22
23 #include "st_set.h"
24 #include "st_over.h"
25 #include "st_level.h"
26 #include "st_start.h"
27 #include "st_title.h"
28
29 /*---------------------------------------------------------------------------*/
30
31 #define START_BACK -1
32 #define START_PRACTICE -2
33 #define START_NORMAL -3
34 #define START_CHALLENGE 0
35
36 static int shot_id;
37
38 /*---------------------------------------------------------------------------*/
39
40 /* Create a level selector button based upon its existence and status. */
41
42 static void gui_level(int id, char *text, int i)
43 {
44     int m = config_get_d(CONFIG_MODE);
45     int o = level_opened(i) && (!m || !level_locked(i));
46     int e = level_exists(i);
47
48     if      (o) gui_state(id, text, GUI_SML, i, 0);
49     else if (e) gui_label(id, text, GUI_SML, GUI_ALL, gui_yel, gui_red);
50     else        gui_label(id, text, GUI_SML, GUI_ALL, gui_blk, gui_blk);
51 }
52
53 /*---------------------------------------------------------------------------*/
54
55 static int start_action(int i)
56 {
57     int mode = config_get_d(CONFIG_MODE) ? MODE_PRACTICE : MODE_NORMAL;
58     audio_play(AUD_MENU, 1.0f);
59
60     if (i == START_BACK)
61         return goto_state(&st_set);
62     else if (i == START_NORMAL)
63     {
64         config_set_d(CONFIG_MODE, 0);
65         goto_state(&st_start);
66     }
67     else if (i == START_PRACTICE)
68     {
69         config_set_d(CONFIG_MODE, 1);
70         goto_state(&st_start);
71     }
72     
73     if (i == START_CHALLENGE)
74     {
75         i = 1;
76         mode = MODE_CHALLENGE;
77     }
78
79     if (level_opened(i))
80     {
81         if (level_play(USER_REPLAY_FILE, i, mode))
82             return goto_state(&st_level);
83         else
84         {
85             set_free();
86             return goto_state(&st_title);
87         }
88     }
89     return 1;
90 }
91
92 static int start_enter(void)
93 {
94     int w = config_get_d(CONFIG_WIDTH);
95     int h = config_get_d(CONFIG_HEIGHT);
96     int m = config_get_d(CONFIG_MODE);
97
98     int id, jd, kd, ld;
99
100     if ((id = gui_vstack(0)))
101     {
102         if ((jd = gui_hstack(id)))
103         {
104             /*gui_label(jd, _("Level"), GUI_SML, GUI_ALL, gui_yel, gui_red);*/
105             gui_label(jd, _(set_name(set_curr())), GUI_SML, GUI_ALL, gui_yel, gui_red);
106             gui_filler(jd);
107             gui_start(jd, _("Back"),  GUI_SML, START_BACK, 0);
108         }
109
110         
111         if ((jd = gui_harray(id)))
112         {
113             shot_id = gui_image(jd, level_shot(0), 7 * w / 16, 7 * h / 16);
114
115             if ((kd = gui_varray(jd)))
116             {
117                 gui_state(kd, _("Challenge"), GUI_SML, START_CHALLENGE , 0);
118                 if ((ld = gui_harray(kd)))
119                 {
120                     gui_state(ld, _("Practice"), GUI_SML, START_PRACTICE, m == 1);
121                     gui_state(ld, _("Normal"),   GUI_SML, START_NORMAL,   m == 0);
122                 }
123                 if ((ld = gui_harray(kd)))
124                 {
125                     gui_level(ld, "05",  5);
126                     gui_level(ld, "04",  4);
127                     gui_level(ld, "03",  3);
128                     gui_level(ld, "02",  2);
129                     gui_level(ld, "01",  1);
130                 }
131                 if ((ld = gui_harray(kd)))
132                 {
133                     gui_level(ld, "10", 10);
134                     gui_level(ld, "09",  9);
135                     gui_level(ld, "08",  8);
136                     gui_level(ld, "07",  7);
137                     gui_level(ld, "06",  6);
138                 }
139                 if ((ld = gui_harray(kd)))
140                 {
141                     gui_level(ld, "15", 15);
142                     gui_level(ld, "14", 14);
143                     gui_level(ld, "13", 13);
144                     gui_level(ld, "12", 12);
145                     gui_level(ld, "11", 11);
146                 }
147                 if ((ld = gui_harray(kd)))
148                 {
149                     gui_level(ld, "20", 20);
150                     gui_level(ld, "19", 19);
151                     gui_level(ld, "18", 18);
152                     gui_level(ld, "17", 17);
153                     gui_level(ld, "16", 16);
154                 }
155                 if ((ld = gui_harray(kd)))
156                 {
157                     gui_level(ld, "25", 25);
158                     gui_level(ld, "24", 24);
159                     gui_level(ld, "23", 23);
160                     gui_level(ld, "22", 22);
161                     gui_level(ld, "21", 21);
162                 }
163             }
164         }
165         gui_space(id);
166
167         if ((jd = gui_harray(id)))
168         {
169             gui_most_coins(jd, 3, 0);
170             gui_best_times(jd, 3, 0);
171         }
172
173         gui_layout(id, 0, 0);
174         set_most_coins(0, -1);
175         set_best_times(0, -1);
176     }
177
178     return id;
179 }
180
181 static void start_leave(int id)
182 {
183     gui_delete(id);
184 }
185
186 static void start_paint(int id, float st)
187 {
188     game_draw(0, st);
189     config_pop_matrix();
190     gui_paint(id);
191 }
192
193 static void start_timer(int id, float dt)
194 {
195     gui_timer(id, dt);
196     audio_timer(dt);
197 }
198
199 static void start_point(int id, int x, int y, int dx, int dy)
200 {
201     int jd;
202
203     if ((jd = gui_point(id, x, y)))
204     {
205         int i = gui_token(jd);
206
207         if (i < 0)
208                 return;
209
210         gui_set_image(shot_id, level_shot(i));
211
212         set_most_coins(i, -1);
213         set_best_times(i, -1);
214
215         gui_pulse(jd, 1.2f);
216     }
217 }
218
219 static void start_stick(int id, int a, int v)
220 {
221     int jd;
222
223     int x = (config_tst_d(CONFIG_JOYSTICK_AXIS_X, a)) ? v : 0;
224     int y = (config_tst_d(CONFIG_JOYSTICK_AXIS_Y, a)) ? v : 0;
225
226     if ((jd = gui_stick(id, x, y)))
227     {
228         int i = gui_token(jd);
229
230         if (i < 0)
231                 return;
232
233         gui_set_image(shot_id, level_shot(i));
234
235         set_most_coins(i, -1);
236         set_best_times(i, -1);
237
238         gui_pulse(jd, 1.2f);
239     }
240 }
241
242 static int start_click(int b, int d)
243 {
244     if (d && b < 0)
245         return start_action(gui_token(gui_click()));
246     return 1;
247 }
248
249 static int start_keybd(int c, int d)
250 {
251     if (d && c == SDLK_ESCAPE)
252         return goto_state(&st_title);
253     
254     if (d && c == SDLK_c)
255     {
256         level_cheat();
257         return goto_state(&st_start);
258     }
259
260     if (d && c == SDLK_F12)
261     {
262         int n = curr_count();
263         int i;
264
265         /* Iterate over all levels, taking a screenshot of each. */
266
267         for (i = 1; i < n; i++)
268             if (level_exists(i))
269                 level_snap(i);
270     }
271
272     return 1;
273 }
274
275 static int start_buttn(int b, int d)
276 {
277     if (d)
278     {
279         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
280             return start_action(gui_token(gui_click()));
281         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_B, b))
282             return goto_state(&st_title);
283         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
284             return goto_state(&st_title);
285     }
286     return 1;
287 }
288
289 /*---------------------------------------------------------------------------*/
290
291 struct state st_start = {
292     start_enter,
293     start_leave,
294     start_paint,
295     start_timer,
296     start_point,
297     start_stick,
298     start_click,
299     start_keybd,
300     start_buttn,
301     1, 0
302 };