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 * Portions of this code are from the MPEG software simulation group
10 * idct implementation. This code will be replaced with a new
11 * implementation soon.
13 * This file is part of Jump'n'Bump.
15 * Jump'n'Bump is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * Jump'n'Bump is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 char *menu_background;
35 char menu_cur_pal[768];
39 "by Brainchild Design in 1998.",
40 "Code by Mattias Brynervall.",
41 "Graphics by Martin Magnusson",
42 "and Andreas Brynervall.",
43 "Music by Anders Nilsson.",
44 "Linux port by Chuck Mason.",
45 "New SDL port by Florian Schulze.",
46 "http://www.icculus.org/jumpnbump/",
47 "Visit our homepage at:",
48 "http://www.algonet.se/~mattiasb",
49 "Jump 'n Bump is e-mailware.",
50 "That means you're supposed to send us an e-mail!",
51 "Write for example where you're from",
52 "and what you thought about this game.",
53 "If you do that, you will greatly encourage us",
54 "to make more games for you!",
55 "Send your e-mail to: matbr656@student.liu.se",
56 "Oh, and by the way, there's a lot of secrets!",
57 "If you can't find them, you'd better ask us...",
58 "If you'd like to contact a specific member of BCD,",
59 "these are their e-mail addresses:",
60 "Andreas Brynervall: andreasb@acc.umu.se",
61 "Mattias Brynervall: matbr656@student.liu.se",
62 "Martin Magnusson: marma102@student.liu.se",
63 "Anders Nilsson: equel@swipnet.se",
67 #define NUM_MESSAGES (sizeof(message)/sizeof(char *))
73 int end_loop_flag, new_game_flag, fade_flag;
74 int mod_vol = 0, mod_fade_direction = 0;
76 int fade_dir, fade_count, fade_tick;
84 mod_fade_direction = 1;
85 dj_ready_mod(MOD_MENU);
86 dj_set_mod_volume((char)mod_vol);
87 dj_set_sfx_volume(64);
91 memset(fade_pal, 0, 48);
92 setpalette(240, 16, fade_pal);
97 cur_message = NUM_MESSAGES - 1;
99 main_info.page_info[0].num_pobs = 0;
100 main_info.page_info[1].num_pobs = 0;
101 main_info.view_page = 0;
102 main_info.draw_page = 1;
104 esc_pressed = key_pressed(1);
105 end_loop_flag = new_game_flag = 0;
112 while (update_count) {
114 if (key_pressed(1) == 1 && esc_pressed == 0) {
117 memset(menu_pal, 0, 768);
118 mod_fade_direction = 0;
119 } else if (key_pressed(1) == 0)
122 update_player_actions();
123 for (c1 = 0; c1 < 4; c1++) {
124 if (end_loop_flag == 1 && new_game_flag == 1) {
125 if ((player[c1].x >> 16) > (165 + c1 * 2)) {
126 if (player[c1].x_add < 0)
127 player[c1].x_add += 16384;
129 player[c1].x_add += 12288;
130 if (player[c1].x_add > 98304L)
131 player[c1].x_add = 98304L;
132 player[c1].direction = 0;
133 if (player[c1].anim == 0) {
135 player[c1].frame = 0;
136 player[c1].frame_tick = 0;
137 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
139 player[c1].enabled = 1;
141 if (!player[c1].action_up) {
142 if (player[c1].y_add < 0) {
143 player[c1].y_add += 32768;
144 if (player[c1].y_add > 0)
145 player[c1].y_add = 0;
148 player[c1].y_add += 12288;
149 if (player[c1].y_add > 36864 && player[c1].anim != 3) {
151 player[c1].frame = 0;
152 player[c1].frame_tick = 0;
153 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
155 player[c1].y += player[c1].y_add;
156 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
157 if ((player[c1].y >> 16) > (160 + c1 * 2)) {
158 player[c1].y = (160L + c1 * 2) << 16;
159 player[c1].y_add = 0;
160 if (player[c1].anim != 0 && player[c1].anim != 1) {
162 player[c1].frame = 0;
163 player[c1].frame_tick = 0;
164 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
168 if ((player[c1].y >> 16) > (138 + c1 * 2)) {
169 player[c1].y = (138L + c1 * 2) << 16;
170 player[c1].y_add = 0;
171 if (player[c1].anim != 0 && player[c1].anim != 1) {
173 player[c1].frame = 0;
174 player[c1].frame_tick = 0;
175 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
177 if (!player[c1].action_up)
178 player[c1].jump_ready = 1;
181 player[c1].x += player[c1].x_add;
182 if ((player[c1].y >> 16) > (138 + c1 * 2)) {
183 if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (190 + c1 * 2)) {
184 player[c1].x = (165L + c1 * 2) << 16;
185 player[c1].x_add = 0;
187 if ((player[c1].x >> 16) > (190 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
188 player[c1].x = (208L + c1 * 2) << 16;
189 player[c1].x_add = 0;
193 if (player[c1].action_left && player[c1].action_right) {
194 if (player[c1].direction == 1) {
195 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
196 if (player[c1].x_add > 0) {
197 player[c1].x_add -= 16384;
198 if ((player[c1].y >> 16) >= (160 + c1 * 2))
199 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);
201 player[c1].x_add -= 12288;
203 if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
204 if (player[c1].x_add > 0) {
205 player[c1].x_add -= 16384;
206 if ((player[c1].y >> 16) >= (138 + c1 * 2))
207 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);
209 player[c1].x_add -= 12288;
211 if (player[c1].x_add < -98304L)
212 player[c1].x_add = -98304L;
213 player[c1].direction = 1;
214 if (player[c1].anim == 0) {
216 player[c1].frame = 0;
217 player[c1].frame_tick = 0;
218 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
221 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
222 if (player[c1].x_add < 0) {
223 player[c1].x_add += 16384;
224 if ((player[c1].y >> 16) >= (160 + c1 * 2))
225 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);
227 player[c1].x_add += 12288;
229 if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
230 if (player[c1].x_add < 0) {
231 player[c1].x_add += 16384;
232 if ((player[c1].y >> 16) >= (138 + c1 * 2))
233 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);
235 player[c1].x_add += 12288;
237 if (player[c1].x_add > 98304L)
238 player[c1].x_add = 98304L;
239 player[c1].direction = 0;
240 if (player[c1].anim == 0) {
242 player[c1].frame = 0;
243 player[c1].frame_tick = 0;
244 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
247 } else if (player[c1].action_left) {
248 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
249 if (player[c1].x_add > 0) {
250 player[c1].x_add -= 16384;
251 if ((player[c1].y >> 16) >= (160 + c1 * 2))
252 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);
254 player[c1].x_add -= 12288;
256 if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
257 if (player[c1].x_add > 0) {
258 player[c1].x_add -= 16384;
259 if ((player[c1].y >> 16) >= (138 + c1 * 2))
260 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);
262 player[c1].x_add -= 12288;
264 if (player[c1].x_add < -98304L)
265 player[c1].x_add = -98304L;
266 player[c1].direction = 1;
267 if (player[c1].anim == 0) {
269 player[c1].frame = 0;
270 player[c1].frame_tick = 0;
271 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
273 } else if (player[c1].action_right) {
274 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
275 if (player[c1].x_add < 0) {
276 player[c1].x_add += 16384;
277 if ((player[c1].y >> 16) >= (160 + c1 * 2))
278 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);
280 player[c1].x_add += 12288;
282 if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
283 if (player[c1].x_add < 0) {
284 player[c1].x_add += 16384;
285 if ((player[c1].y >> 16) >= (138 + c1 * 2))
286 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);
288 player[c1].x_add += 12288;
290 if (player[c1].x_add > 98304L)
291 player[c1].x_add = 98304L;
292 player[c1].direction = 0;
293 if (player[c1].anim == 0) {
295 player[c1].frame = 0;
296 player[c1].frame_tick = 0;
297 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
300 if (((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) && (player[c1].y >> 16) >= (160 + c1 * 2)) {
301 if (player[c1].x_add < 0) {
302 player[c1].x_add += 16384;
303 if (player[c1].x_add > 0)
304 player[c1].x_add = 0;
305 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);
306 } else if (player[c1].x_add > 0) {
307 player[c1].x_add -= 16384;
308 if (player[c1].x_add < 0)
309 player[c1].x_add = 0;
310 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);
313 if ((((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) && (player[c1].y >> 16) >= (138 + c1 * 2))) {
314 if (player[c1].x_add < 0) {
315 player[c1].x_add += 16384;
316 if (player[c1].x_add > 0)
317 player[c1].x_add = 0;
318 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);
319 } else if (player[c1].x_add > 0) {
320 player[c1].x_add -= 16384;
321 if (player[c1].x_add < 0)
322 player[c1].x_add = 0;
323 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);
326 if (player[c1].anim == 1) {
328 player[c1].frame = 0;
329 player[c1].frame_tick = 0;
330 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
333 if ((player[c1].jump_ready == 1) && player[c1].action_up) {
334 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
335 if ((player[c1].y >> 16) >= (160 + c1 * 2)) {
336 player[c1].y_add = -280000L;
338 player[c1].frame = 0;
339 player[c1].frame_tick = 0;
340 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
341 player[c1].jump_ready = 0;
342 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
345 if ((player[c1].y >> 16) >= (138 + c1 * 2)) {
346 player[c1].y_add = -280000L;
348 player[c1].frame = 0;
349 player[c1].frame_tick = 0;
350 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
351 player[c1].jump_ready = 0;
352 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
356 if (!player[c1].action_up) {
357 if (player[c1].y_add < 0) {
358 player[c1].y_add += 32768;
359 if (player[c1].y_add > 0)
360 player[c1].y_add = 0;
363 if (!player[c1].action_up)
364 player[c1].jump_ready = 1;
365 player[c1].y_add += 12288;
366 if (player[c1].y_add > 36864 && player[c1].anim != 3) {
368 player[c1].frame = 0;
369 player[c1].frame_tick = 0;
370 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
372 player[c1].y += player[c1].y_add;
373 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
374 if ((player[c1].y >> 16) > (160 + c1 * 2)) {
375 player[c1].y = (160L + c1 * 2) << 16;
376 player[c1].y_add = 0;
377 if (player[c1].anim != 0 && player[c1].anim != 1) {
379 player[c1].frame = 0;
380 player[c1].frame_tick = 0;
381 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
385 if ((player[c1].y >> 16) > (138 + c1 * 2)) {
386 player[c1].y = (138L + c1 * 2) << 16;
387 player[c1].y_add = 0;
388 if (player[c1].anim != 0 && player[c1].anim != 1) {
390 player[c1].frame = 0;
391 player[c1].frame_tick = 0;
392 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
396 player[c1].x += player[c1].x_add;
397 if ((player[c1].x >> 16) < 0) {
399 player[c1].x_add = 0;
401 if ((player[c1].x >> 16) > 400) {
404 memset(menu_pal, 0, 768);
405 mod_fade_direction = 0;
407 if ((player[c1].y >> 16) > (138 + c1 * 2)) {
408 if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (190 + c1 * 2)) {
409 player[c1].x = (165L + c1 * 2) << 16;
410 player[c1].x_add = 0;
412 if ((player[c1].x >> 16) > (190 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
413 player[c1].x = (208L + c1 * 2) << 16;
414 player[c1].x_add = 0;
418 player[c1].frame_tick++;
419 if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
421 if (player[c1].frame >= player_anims[player[c1].anim].num_frames)
422 player[c1].frame = player_anims[player[c1].anim].restart_frame;
423 player[c1].frame_tick = 0;
425 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
430 main_info.page_info[main_info.draw_page].num_pobs = 0;
432 for (c1 = 3; c1 >= 0; c1--)
433 add_pob(main_info.draw_page, player[c1].x >> 16, player[c1].y >> 16, player[c1].image + c1 * 18, &rabbit_gobs);
437 if (update_count == 1) {
439 draw_pobs(main_info.draw_page);
444 if (mod_fade_direction == 1) {
447 dj_set_mod_volume((char)mod_vol);
452 dj_set_mod_volume((char)mod_vol);
458 for (c1 = 0; c1 < 720; c1++) {
459 if (menu_cur_pal[c1] < menu_pal[c1]) {
462 } else if (menu_cur_pal[c1] > menu_pal[c1]) {
467 if (fade_flag == 0 && end_loop_flag == 1) {
469 if (new_game_flag == 1)
476 if (fade_count < 30) {
477 for (c1 = 0; c1 < 48; c1++) {
478 if (fade_pal[c1] > 0)
484 clear_lines(0, 220, 20, 0);
485 clear_lines(1, 220, 20, 0);
488 if (cur_message >= NUM_MESSAGES)
489 cur_message -= NUM_MESSAGES;
490 put_text(0, 200, 220, message[cur_message], 2);
491 put_text(1, 200, 220, message[cur_message], 2);
499 if (fade_count < 100) {
500 for (c1 = 0; c1 < 48; c1++) {
501 if (fade_pal[c1] < menu_pal[c1 + 720])
513 for (c1 = 0; c1 < 48; c1++) {
514 if (fade_pal[c1] > menu_pal[c1 + 720])
518 if (update_count == 1) {
519 main_info.draw_page ^= 1;
520 main_info.view_page ^= 1;
522 flippage(main_info.view_page);
527 if (fade_flag != 0) {
528 setpalette(0, 240, menu_cur_pal);
531 if (update_count == 1) {
532 setpalette(240, 16, fade_pal);
537 redraw_pob_backgrounds(main_info.draw_page);
544 update_count = intr_sysupdate();
559 fillpalette(0, 0, 0);
561 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
562 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
565 if (read_pcx(handle, background_pic, 102400, menu_pal) != 0) {
566 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
570 if ((handle = dat_open("menumask.pcx", datfile_name, "rb")) == 0) {
571 strcpy(main_info.error_str, "Error loading 'menumask.pcx', aborting...\n");
574 if (read_pcx(handle, mask_pic, 102400, 0) != 0) {
575 strcpy(main_info.error_str, "Error loading 'menumask.pcx', aborting...\n");
579 memset(menu_cur_pal, 0, 768);
581 recalculate_gob(&rabbit_gobs, menu_pal);
582 recalculate_gob(&font_gobs, menu_pal);
583 recalculate_gob(&object_gobs, menu_pal);
584 register_background(background_pic, menu_pal);
585 register_mask(mask_pic);
587 for (c1 = 0; c1 < 4; c1++) {
588 player[c1].enabled = 0;
589 player[c1].x = (long) rnd(150) << 16;
590 player[c1].y = (160L + c1 * 2) << 16;
591 player[c1].x_add = 0;
592 player[c1].y_add = 0;
593 player[c1].direction = rnd(2);
594 player[c1].jump_ready = 1;
596 player[c1].frame = 0;
597 player[c1].frame_tick = 0;
598 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image;
601 for (c1 = 0; c1 < NUM_OBJECTS; c1++)
602 objects[c1].used = 0;
604 main_info.page_info[0].num_pobs = 0;
605 main_info.page_info[1].num_pobs = 0;
612 void menu_deinit(void)