3 * Copyright (C) 1998 Brainchild Design - http://brainchilddesign.com/
5 * Copyright (C) 2001 Chuck Mason <cemason@users.sourceforge.net>
7 * Copyright (C) 2002 Florian Schulze <crow@icculus.org>
9 * This file is part of Jump'n'Bump.
11 * Jump'n'Bump is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * Jump'n'Bump is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 char *menu_background;
31 char menu_cur_pal[768];
34 "Jump 'n Bump "JNB_VERSION,
35 "by Brainchild Design in 1998.",
36 "Code by Mattias Brynervall.",
37 "Graphics by Martin Magnusson",
38 "and Andreas Brynervall.",
39 "Music by Anders Nilsson.",
40 "Linux port by Chuck Mason.",
41 "New SDL port by Florian Schulze.",
42 "http://www.icculus.org/jumpnbump/",
43 "Ryan C. Gordon made networking possible again!",
44 "Visit our homepage at:",
45 "http://www.algonet.se/~mattiasb",
46 "Jump 'n Bump is e-mailware.",
47 "That means you're supposed to send us an e-mail!",
48 "Write for example where you're from",
49 "and what you thought about this game.",
50 "If you do that, you will greatly encourage us",
51 "to make more games for you!",
52 "Send your e-mail to: matbr656@student.liu.se",
53 "Oh, and by the way, there're a lot of secrets!",
54 "If you can't find them, you'd better ask us...",
55 "If you'd like to contact a specific member of BCD,",
56 "these are their e-mail addresses:",
57 "Andreas Brynervall: andreasb@acc.umu.se",
58 "Mattias Brynervall: matbr656@student.liu.se",
59 "Martin Magnusson: marma102@student.liu.se",
60 "Anders Nilsson: equel@swipnet.se",
64 #define NUM_MESSAGES (sizeof(message)/sizeof(char *))
70 int end_loop_flag, new_game_flag, fade_flag;
71 int mod_vol = 0, mod_fade_direction = 0;
73 int fade_dir, fade_count, fade_tick;
81 mod_fade_direction = 1;
82 dj_ready_mod(MOD_MENU);
83 dj_set_mod_volume((char)mod_vol);
84 dj_set_sfx_volume(64);
88 memset(fade_pal, 0, 48);
89 setpalette(240, 16, fade_pal);
94 cur_message = NUM_MESSAGES - 1;
96 main_info.page_info[0].num_pobs = 0;
97 main_info.page_info[1].num_pobs = 0;
98 main_info.view_page = 0;
99 main_info.draw_page = 1;
101 esc_pressed = key_pressed(1);
102 end_loop_flag = new_game_flag = 0;
109 while (update_count) {
111 if (key_pressed(1) == 1 && esc_pressed == 0) {
114 memset(menu_pal, 0, 768);
115 mod_fade_direction = 0;
116 } else if (key_pressed(1) == 0)
119 update_player_actions();
120 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
121 if (end_loop_flag == 1 && new_game_flag == 1) {
122 if ((player[c1].x >> 16) > (165 + c1 * 2)) {
123 if (player[c1].x_add < 0)
124 player[c1].x_add += 16384;
126 player[c1].x_add += 12288;
127 if (player[c1].x_add > 98304L)
128 player[c1].x_add = 98304L;
129 player[c1].direction = 0;
130 if (player[c1].anim == 0) {
132 player[c1].frame = 0;
133 player[c1].frame_tick = 0;
134 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
136 player[c1].enabled = 1;
138 if (!player[c1].action_up) {
139 if (player[c1].y_add < 0) {
140 player[c1].y_add += 32768;
141 if (player[c1].y_add > 0)
142 player[c1].y_add = 0;
145 player[c1].y_add += 12288;
146 if (player[c1].y_add > 36864 && player[c1].anim != 3) {
148 player[c1].frame = 0;
149 player[c1].frame_tick = 0;
150 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
152 player[c1].y += player[c1].y_add;
153 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
154 if ((player[c1].y >> 16) > (160 + c1 * 2)) {
155 player[c1].y = (160L + c1 * 2) << 16;
156 player[c1].y_add = 0;
157 if (player[c1].anim != 0 && player[c1].anim != 1) {
159 player[c1].frame = 0;
160 player[c1].frame_tick = 0;
161 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
165 if ((player[c1].y >> 16) > (138 + c1 * 2)) {
166 player[c1].y = (138L + c1 * 2) << 16;
167 player[c1].y_add = 0;
168 if (player[c1].anim != 0 && player[c1].anim != 1) {
170 player[c1].frame = 0;
171 player[c1].frame_tick = 0;
172 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
174 if (!player[c1].action_up)
175 player[c1].jump_ready = 1;
178 player[c1].x += player[c1].x_add;
179 if ((player[c1].y >> 16) > (138 + c1 * 2)) {
180 if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (190 + c1 * 2)) {
181 player[c1].x = (165L + c1 * 2) << 16;
182 player[c1].x_add = 0;
184 if ((player[c1].x >> 16) > (190 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
185 player[c1].x = (208L + c1 * 2) << 16;
186 player[c1].x_add = 0;
190 if (player[c1].action_left && player[c1].action_right) {
191 if (player[c1].direction == 1) {
192 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
193 if (player[c1].x_add > 0) {
194 player[c1].x_add -= 16384;
195 if ((player[c1].y >> 16) >= (160 + c1 * 2))
196 add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
198 player[c1].x_add -= 12288;
200 if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
201 if (player[c1].x_add > 0) {
202 player[c1].x_add -= 16384;
203 if ((player[c1].y >> 16) >= (138 + c1 * 2))
204 add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
206 player[c1].x_add -= 12288;
208 if (player[c1].x_add < -98304L)
209 player[c1].x_add = -98304L;
210 player[c1].direction = 1;
211 if (player[c1].anim == 0) {
213 player[c1].frame = 0;
214 player[c1].frame_tick = 0;
215 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
218 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
219 if (player[c1].x_add < 0) {
220 player[c1].x_add += 16384;
221 if ((player[c1].y >> 16) >= (160 + c1 * 2))
222 add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
224 player[c1].x_add += 12288;
226 if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
227 if (player[c1].x_add < 0) {
228 player[c1].x_add += 16384;
229 if ((player[c1].y >> 16) >= (138 + c1 * 2))
230 add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
232 player[c1].x_add += 12288;
234 if (player[c1].x_add > 98304L)
235 player[c1].x_add = 98304L;
236 player[c1].direction = 0;
237 if (player[c1].anim == 0) {
239 player[c1].frame = 0;
240 player[c1].frame_tick = 0;
241 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
244 } else if (player[c1].action_left) {
245 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
246 if (player[c1].x_add > 0) {
247 player[c1].x_add -= 16384;
248 if ((player[c1].y >> 16) >= (160 + c1 * 2))
249 add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
251 player[c1].x_add -= 12288;
253 if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
254 if (player[c1].x_add > 0) {
255 player[c1].x_add -= 16384;
256 if ((player[c1].y >> 16) >= (138 + c1 * 2))
257 add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
259 player[c1].x_add -= 12288;
261 if (player[c1].x_add < -98304L)
262 player[c1].x_add = -98304L;
263 player[c1].direction = 1;
264 if (player[c1].anim == 0) {
266 player[c1].frame = 0;
267 player[c1].frame_tick = 0;
268 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
270 } else if (player[c1].action_right) {
271 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
272 if (player[c1].x_add < 0) {
273 player[c1].x_add += 16384;
274 if ((player[c1].y >> 16) >= (160 + c1 * 2))
275 add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
277 player[c1].x_add += 12288;
279 if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
280 if (player[c1].x_add < 0) {
281 player[c1].x_add += 16384;
282 if ((player[c1].y >> 16) >= (138 + c1 * 2))
283 add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
285 player[c1].x_add += 12288;
287 if (player[c1].x_add > 98304L)
288 player[c1].x_add = 98304L;
289 player[c1].direction = 0;
290 if (player[c1].anim == 0) {
292 player[c1].frame = 0;
293 player[c1].frame_tick = 0;
294 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
297 if (((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) && (player[c1].y >> 16) >= (160 + c1 * 2)) {
298 if (player[c1].x_add < 0) {
299 player[c1].x_add += 16384;
300 if (player[c1].x_add > 0)
301 player[c1].x_add = 0;
302 add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
303 } else if (player[c1].x_add > 0) {
304 player[c1].x_add -= 16384;
305 if (player[c1].x_add < 0)
306 player[c1].x_add = 0;
307 add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
310 if ((((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) && (player[c1].y >> 16) >= (138 + c1 * 2))) {
311 if (player[c1].x_add < 0) {
312 player[c1].x_add += 16384;
313 if (player[c1].x_add > 0)
314 player[c1].x_add = 0;
315 add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
316 } else if (player[c1].x_add > 0) {
317 player[c1].x_add -= 16384;
318 if (player[c1].x_add < 0)
319 player[c1].x_add = 0;
320 add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
323 if (player[c1].anim == 1) {
325 player[c1].frame = 0;
326 player[c1].frame_tick = 0;
327 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
330 if ((player[c1].jump_ready == 1) && player[c1].action_up) {
331 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
332 if ((player[c1].y >> 16) >= (160 + c1 * 2)) {
333 player[c1].y_add = -280000L;
335 player[c1].frame = 0;
336 player[c1].frame_tick = 0;
337 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
338 player[c1].jump_ready = 0;
339 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
342 if ((player[c1].y >> 16) >= (138 + c1 * 2)) {
343 player[c1].y_add = -280000L;
345 player[c1].frame = 0;
346 player[c1].frame_tick = 0;
347 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
348 player[c1].jump_ready = 0;
349 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
353 if (!player[c1].action_up) {
354 if (player[c1].y_add < 0) {
355 player[c1].y_add += 32768;
356 if (player[c1].y_add > 0)
357 player[c1].y_add = 0;
360 if (!player[c1].action_up)
361 player[c1].jump_ready = 1;
362 player[c1].y_add += 12288;
363 if (player[c1].y_add > 36864 && player[c1].anim != 3) {
365 player[c1].frame = 0;
366 player[c1].frame_tick = 0;
367 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
369 player[c1].y += player[c1].y_add;
370 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
371 if ((player[c1].y >> 16) > (160 + c1 * 2)) {
372 player[c1].y = (160L + c1 * 2) << 16;
373 player[c1].y_add = 0;
374 if (player[c1].anim != 0 && player[c1].anim != 1) {
376 player[c1].frame = 0;
377 player[c1].frame_tick = 0;
378 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
382 if ((player[c1].y >> 16) > (138 + c1 * 2)) {
383 player[c1].y = (138L + c1 * 2) << 16;
384 player[c1].y_add = 0;
385 if (player[c1].anim != 0 && player[c1].anim != 1) {
387 player[c1].frame = 0;
388 player[c1].frame_tick = 0;
389 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
393 player[c1].x += player[c1].x_add;
394 if ((player[c1].x >> 16) < 0) {
396 player[c1].x_add = 0;
398 if ((player[c1].x >> 16) > JNB_WIDTH) {
401 memset(menu_pal, 0, 768);
402 mod_fade_direction = 0;
404 if ((player[c1].y >> 16) > (138 + c1 * 2)) {
405 if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (190 + c1 * 2)) {
406 player[c1].x = (165L + c1 * 2) << 16;
407 player[c1].x_add = 0;
409 if ((player[c1].x >> 16) > (190 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
410 player[c1].x = (208L + c1 * 2) << 16;
411 player[c1].x_add = 0;
415 player[c1].frame_tick++;
416 if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
418 if (player[c1].frame >= player_anims[player[c1].anim].num_frames)
419 player[c1].frame = player_anims[player[c1].anim].restart_frame;
420 player[c1].frame_tick = 0;
422 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
427 main_info.page_info[main_info.draw_page].num_pobs = 0;
429 for (c1 = 3; c1 >= 0; c1--)
430 add_pob(main_info.draw_page, player[c1].x >> 16, player[c1].y >> 16, player[c1].image + c1 * 18, &rabbit_gobs);
434 if (update_count == 1) {
436 draw_pobs(main_info.draw_page);
441 if (mod_fade_direction == 1) {
444 dj_set_mod_volume((char)mod_vol);
449 dj_set_mod_volume((char)mod_vol);
455 for (c1 = 0; c1 < 720; c1++) {
456 if (menu_cur_pal[c1] < menu_pal[c1]) {
459 } else if (menu_cur_pal[c1] > menu_pal[c1]) {
464 if (fade_flag == 0 && end_loop_flag == 1) {
466 if (new_game_flag == 1)
473 if (fade_count < 30) {
474 for (c1 = 0; c1 < 48; c1++) {
475 if (fade_pal[c1] > 0)
481 clear_lines(0, 220, 20, 0);
482 clear_lines(1, 220, 20, 0);
485 if (cur_message >= NUM_MESSAGES)
486 cur_message -= NUM_MESSAGES;
487 put_text(0, 200, 220, message[cur_message], 2);
488 put_text(1, 200, 220, message[cur_message], 2);
496 if (fade_count < 100) {
497 for (c1 = 0; c1 < 48; c1++) {
498 if (fade_pal[c1] < menu_pal[c1 + 720])
510 for (c1 = 0; c1 < 48; c1++) {
511 if (fade_pal[c1] > menu_pal[c1 + 720])
515 if (update_count == 1) {
516 main_info.draw_page ^= 1;
517 main_info.view_page ^= 1;
519 flippage(main_info.view_page);
524 if (fade_flag != 0) {
525 setpalette(0, 240, menu_cur_pal);
528 if (update_count == 1) {
529 setpalette(240, 16, fade_pal);
534 redraw_pob_backgrounds(main_info.draw_page);
541 update_count = intr_sysupdate();
556 fillpalette(0, 0, 0);
558 if ((handle = dat_open("menu.pcx")) == 0) {
559 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
562 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, menu_pal) != 0) {
563 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
566 if ((handle = dat_open("menumask.pcx")) == 0) {
567 strcpy(main_info.error_str, "Error loading 'menumask.pcx', aborting...\n");
570 if (read_pcx(handle, mask_pic, JNB_WIDTH*JNB_HEIGHT, 0) != 0) {
571 strcpy(main_info.error_str, "Error loading 'menumask.pcx', aborting...\n");
574 memset(menu_cur_pal, 0, 768);
577 for (c1 = 0; c1 < 16; c1++) {
578 menu_pal[(240 + c1) * 3 + 0] = c1 << 2;
579 menu_pal[(240 + c1) * 3 + 1] = c1 << 2;
580 menu_pal[(240 + c1) * 3 + 2] = c1 << 2;
583 recalculate_gob(&rabbit_gobs, menu_pal);
584 recalculate_gob(&font_gobs, menu_pal);
585 recalculate_gob(&object_gobs, menu_pal);
586 register_background(background_pic, menu_pal);
587 register_mask(mask_pic);
589 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
590 player[c1].enabled = 0;
591 player[c1].x = (long) rnd(150) << 16;
592 player[c1].y = (160L + c1 * 2) << 16;
593 player[c1].x_add = 0;
594 player[c1].y_add = 0;
595 player[c1].direction = rnd(2);
596 player[c1].jump_ready = 1;
598 player[c1].frame = 0;
599 player[c1].frame_tick = 0;
600 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image;
603 for (c1 = 0; c1 < NUM_OBJECTS; c1++)
604 objects[c1].used = 0;
606 main_info.page_info[0].num_pobs = 0;
607 main_info.page_info[1].num_pobs = 0;
614 void menu_deinit(void)