2 * Copyright (C) 2003 Robert Kooima
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.
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.
26 #include "game_common.h"
27 #include "game_server.h"
28 #include "game_client.h"
29 #include "game_proxy.h"
37 #include "st_shared.h"
39 /*---------------------------------------------------------------------------*/
41 static int init_title_level(void)
43 if (game_client_init("map-medium/title.sol"))
47 cmd.type = CMD_GOAL_OPEN;
49 game_client_sync(NULL);
51 game_client_fly(1.0f);
58 static const char *pick_demo(Array items)
60 struct dir_item *item;
61 return (item = array_rnd(items)) ? item->path : NULL;
64 /*---------------------------------------------------------------------------*/
66 static float real_time = 0.0f;
71 static int play_id = 0;
79 static int title_action(int i)
81 static const char keyphrase[] = "CHEAT";
82 static char queue[sizeof (keyphrase)] = "";
84 size_t queue_len = strlen(queue);
86 audio_play(AUD_MENU, 1.0f);
91 if (strlen(config_get_s(CONFIG_PLAYER)) == 0)
92 return goto_name(&st_set, &st_title, 0);
94 return goto_state(&st_set);
98 case TITLE_HELP: return goto_state(&st_help); break;
99 case TITLE_DEMO: return goto_state(&st_demo); break;
100 case TITLE_CONF: return goto_state(&st_conf); break;
101 case TITLE_EXIT: return 0; break;
105 /* Let the queue fill up. */
107 if (queue_len < sizeof (queue) - 1)
109 queue[queue_len] = (char) i;
110 queue[queue_len + 1] = '\0';
113 /* Advance the queue before adding the new element. */
119 for (k = 1; k < queue_len; k++)
120 queue[k - 1] = queue[k];
122 queue[queue_len - 1] = (char) i;
125 if (strcmp(queue, keyphrase) == 0)
128 gui_set_label(play_id, sgettext("menu^Cheat"));
129 gui_pulse(play_id, 1.2f);
131 else if (config_cheat())
134 gui_set_label(play_id, sgettext("menu^Play"));
135 gui_pulse(play_id, 1.2f);
143 static int title_gui(void)
147 /* Build the title GUI. */
149 if ((id = gui_vstack(0)))
151 gui_label(id, "Neverball", GUI_LRG, GUI_ALL, 0, 0);
155 if ((jd = gui_harray(id)))
159 if ((kd = gui_varray(jd)))
162 play_id = gui_start(kd, sgettext("menu^Cheat"),
163 GUI_MED, TITLE_PLAY, 1);
165 play_id = gui_start(kd, sgettext("menu^Play"),
166 GUI_MED, TITLE_PLAY, 1);
168 gui_state(kd, sgettext("menu^Replay"), GUI_MED, TITLE_DEMO, 0);
169 gui_state(kd, sgettext("menu^Help"), GUI_MED, TITLE_HELP, 0);
170 gui_state(kd, sgettext("menu^Options"), GUI_MED, TITLE_CONF, 0);
171 gui_state(kd, sgettext("menu^Exit"), GUI_MED, TITLE_EXIT, 0);
176 gui_layout(id, 0, 0);
182 static int title_enter(struct state *st, struct state *prev)
184 /* Start the title screen music. */
186 audio_music_fade_to(0.5f, "bgm/title.ogg");
188 /* Initialize the title level for display. */
195 SDL_EnableUNICODE(1);
200 static void title_leave(struct state *st, struct state *next, int id)
204 demo_dir_free(items);
208 SDL_EnableUNICODE(0);
213 static void title_timer(int id, float dt)
215 static const char *demo = NULL;
221 case 0: /* Mode 0: Pan across title level. */
223 if (real_time <= 20.0f)
225 game_client_fly(fcosf(V_PI * real_time / 20.0f));
235 case 1: /* Mode 1: Fade out. Load demo level. */
237 if (real_time > 1.0f)
240 items = demo_dir_scan();
242 if ((demo = pick_demo(items)))
244 demo_replay_init(demo, NULL, NULL, NULL, NULL, NULL);
245 game_client_fly(0.0f);
258 case 2: /* Mode 2: Run demo. */
260 if (!demo_replay_step(dt))
268 game_client_blend(demo_replay_blend());
272 case 3: /* Mode 3: Fade out. Load title level. */
274 if (real_time > 1.0f)
288 static int title_keybd(int c, int d)
290 if (d && (c & 0xFF80) == 0 && c > ' ')
291 return title_action(c);
295 static int title_buttn(int b, int d)
299 if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
300 return title_action(gui_token(gui_click()));
301 if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
307 /*---------------------------------------------------------------------------*/
309 struct state st_title = {