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];
38 "Jump 'n Bump "JNB_VERSION,
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 //"Ryan C. Gordon made networking possible again!",
48 "Visit our homepage at:",
49 "http://www.algonet.se/~mattiasb",
50 "Jump 'n Bump is e-mailware.",
51 "That means you're supposed to send us an e-mail!",
52 "Write for example where you're from",
53 "and what you thought about this game.",
54 "If you do that, you will greatly encourage us",
55 "to make more games for you!",
56 "Send your e-mail to: matbr656@student.liu.se",
57 "Oh, and by the way, there're a lot of secrets!",
58 "If you can't find them, you'd better ask us...",
59 "If you'd like to contact a specific member of BCD,",
60 "these are their e-mail addresses:",
61 "Andreas Brynervall: andreasb@acc.umu.se",
62 "Mattias Brynervall: matbr656@student.liu.se",
63 "Martin Magnusson: marma102@student.liu.se",
64 "Anders Nilsson: equel@swipnet.se",
68 #define NUM_MESSAGES (sizeof(message)/sizeof(char *))
74 int end_loop_flag, new_game_flag, fade_flag;
75 int mod_vol = 0, mod_fade_direction = 0;
77 int fade_dir, fade_count, fade_tick;
85 mod_fade_direction = 1;
86 dj_ready_mod(MOD_MENU);
87 dj_set_mod_volume((char)mod_vol);
88 dj_set_sfx_volume(64);
92 memset(fade_pal, 0, 48);
93 setpalette(240, 16, fade_pal);
98 cur_message = NUM_MESSAGES - 1;
100 main_info.page_info[0].num_pobs = 0;
101 main_info.page_info[1].num_pobs = 0;
102 main_info.view_page = 0;
103 main_info.draw_page = 1;
105 esc_pressed = key_pressed(1);
106 end_loop_flag = new_game_flag = 0;
113 while (update_count) {
115 if (key_pressed(1) == 1 && esc_pressed == 0) {
118 memset(menu_pal, 0, 768);
119 mod_fade_direction = 0;
120 } else if (key_pressed(1) == 0)
123 update_player_actions();
124 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
125 if (end_loop_flag == 1 && new_game_flag == 1) {
126 if ((player[c1].x >> 16) > (165 + c1 * 2)) {
127 if (player[c1].x_add < 0)
128 player[c1].x_add += 16384;
130 player[c1].x_add += 12288;
131 if (player[c1].x_add > 98304L)
132 player[c1].x_add = 98304L;
133 player[c1].direction = 0;
134 if (player[c1].anim == 0) {
136 player[c1].frame = 0;
137 player[c1].frame_tick = 0;
138 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
140 player[c1].enabled = 1;
142 if (!player[c1].action_up) {
143 if (player[c1].y_add < 0) {
144 player[c1].y_add += 32768;
145 if (player[c1].y_add > 0)
146 player[c1].y_add = 0;
149 player[c1].y_add += 12288;
150 if (player[c1].y_add > 36864 && player[c1].anim != 3) {
152 player[c1].frame = 0;
153 player[c1].frame_tick = 0;
154 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
156 player[c1].y += player[c1].y_add;
157 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
158 if ((player[c1].y >> 16) > (160 + c1 * 2)) {
159 player[c1].y = (160L + c1 * 2) << 16;
160 player[c1].y_add = 0;
161 if (player[c1].anim != 0 && player[c1].anim != 1) {
163 player[c1].frame = 0;
164 player[c1].frame_tick = 0;
165 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
169 if ((player[c1].y >> 16) > (138 + c1 * 2)) {
170 player[c1].y = (138L + c1 * 2) << 16;
171 player[c1].y_add = 0;
172 if (player[c1].anim != 0 && player[c1].anim != 1) {
174 player[c1].frame = 0;
175 player[c1].frame_tick = 0;
176 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
178 if (!player[c1].action_up)
179 player[c1].jump_ready = 1;
182 player[c1].x += player[c1].x_add;
183 if ((player[c1].y >> 16) > (138 + c1 * 2)) {
184 if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (190 + c1 * 2)) {
185 player[c1].x = (165L + c1 * 2) << 16;
186 player[c1].x_add = 0;
188 if ((player[c1].x >> 16) > (190 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
189 player[c1].x = (208L + c1 * 2) << 16;
190 player[c1].x_add = 0;
194 if (player[c1].action_left && player[c1].action_right) {
195 if (player[c1].direction == 1) {
196 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
197 if (player[c1].x_add > 0) {
198 player[c1].x_add -= 16384;
199 if ((player[c1].y >> 16) >= (160 + c1 * 2))
200 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);
202 player[c1].x_add -= 12288;
204 if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
205 if (player[c1].x_add > 0) {
206 player[c1].x_add -= 16384;
207 if ((player[c1].y >> 16) >= (138 + c1 * 2))
208 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);
210 player[c1].x_add -= 12288;
212 if (player[c1].x_add < -98304L)
213 player[c1].x_add = -98304L;
214 player[c1].direction = 1;
215 if (player[c1].anim == 0) {
217 player[c1].frame = 0;
218 player[c1].frame_tick = 0;
219 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
222 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
223 if (player[c1].x_add < 0) {
224 player[c1].x_add += 16384;
225 if ((player[c1].y >> 16) >= (160 + c1 * 2))
226 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);
228 player[c1].x_add += 12288;
230 if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
231 if (player[c1].x_add < 0) {
232 player[c1].x_add += 16384;
233 if ((player[c1].y >> 16) >= (138 + c1 * 2))
234 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);
236 player[c1].x_add += 12288;
238 if (player[c1].x_add > 98304L)
239 player[c1].x_add = 98304L;
240 player[c1].direction = 0;
241 if (player[c1].anim == 0) {
243 player[c1].frame = 0;
244 player[c1].frame_tick = 0;
245 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
248 } else if (player[c1].action_left) {
249 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
250 if (player[c1].x_add > 0) {
251 player[c1].x_add -= 16384;
252 if ((player[c1].y >> 16) >= (160 + c1 * 2))
253 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);
255 player[c1].x_add -= 12288;
257 if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
258 if (player[c1].x_add > 0) {
259 player[c1].x_add -= 16384;
260 if ((player[c1].y >> 16) >= (138 + c1 * 2))
261 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);
263 player[c1].x_add -= 12288;
265 if (player[c1].x_add < -98304L)
266 player[c1].x_add = -98304L;
267 player[c1].direction = 1;
268 if (player[c1].anim == 0) {
270 player[c1].frame = 0;
271 player[c1].frame_tick = 0;
272 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
274 } else if (player[c1].action_right) {
275 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
276 if (player[c1].x_add < 0) {
277 player[c1].x_add += 16384;
278 if ((player[c1].y >> 16) >= (160 + c1 * 2))
279 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);
281 player[c1].x_add += 12288;
283 if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
284 if (player[c1].x_add < 0) {
285 player[c1].x_add += 16384;
286 if ((player[c1].y >> 16) >= (138 + c1 * 2))
287 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);
289 player[c1].x_add += 12288;
291 if (player[c1].x_add > 98304L)
292 player[c1].x_add = 98304L;
293 player[c1].direction = 0;
294 if (player[c1].anim == 0) {
296 player[c1].frame = 0;
297 player[c1].frame_tick = 0;
298 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
301 if (((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) && (player[c1].y >> 16) >= (160 + c1 * 2)) {
302 if (player[c1].x_add < 0) {
303 player[c1].x_add += 16384;
304 if (player[c1].x_add > 0)
305 player[c1].x_add = 0;
306 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);
307 } else if (player[c1].x_add > 0) {
308 player[c1].x_add -= 16384;
309 if (player[c1].x_add < 0)
310 player[c1].x_add = 0;
311 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);
314 if ((((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) && (player[c1].y >> 16) >= (138 + c1 * 2))) {
315 if (player[c1].x_add < 0) {
316 player[c1].x_add += 16384;
317 if (player[c1].x_add > 0)
318 player[c1].x_add = 0;
319 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);
320 } else if (player[c1].x_add > 0) {
321 player[c1].x_add -= 16384;
322 if (player[c1].x_add < 0)
323 player[c1].x_add = 0;
324 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);
327 if (player[c1].anim == 1) {
329 player[c1].frame = 0;
330 player[c1].frame_tick = 0;
331 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
334 if ((player[c1].jump_ready == 1) && player[c1].action_up) {
335 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
336 if ((player[c1].y >> 16) >= (160 + c1 * 2)) {
337 player[c1].y_add = -280000L;
339 player[c1].frame = 0;
340 player[c1].frame_tick = 0;
341 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
342 player[c1].jump_ready = 0;
343 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
346 if ((player[c1].y >> 16) >= (138 + c1 * 2)) {
347 player[c1].y_add = -280000L;
349 player[c1].frame = 0;
350 player[c1].frame_tick = 0;
351 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
352 player[c1].jump_ready = 0;
353 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
357 if (!player[c1].action_up) {
358 if (player[c1].y_add < 0) {
359 player[c1].y_add += 32768;
360 if (player[c1].y_add > 0)
361 player[c1].y_add = 0;
364 if (!player[c1].action_up)
365 player[c1].jump_ready = 1;
366 player[c1].y_add += 12288;
367 if (player[c1].y_add > 36864 && player[c1].anim != 3) {
369 player[c1].frame = 0;
370 player[c1].frame_tick = 0;
371 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
373 player[c1].y += player[c1].y_add;
374 if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
375 if ((player[c1].y >> 16) > (160 + c1 * 2)) {
376 player[c1].y = (160L + c1 * 2) << 16;
377 player[c1].y_add = 0;
378 if (player[c1].anim != 0 && player[c1].anim != 1) {
380 player[c1].frame = 0;
381 player[c1].frame_tick = 0;
382 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
386 if ((player[c1].y >> 16) > (138 + c1 * 2)) {
387 player[c1].y = (138L + c1 * 2) << 16;
388 player[c1].y_add = 0;
389 if (player[c1].anim != 0 && player[c1].anim != 1) {
391 player[c1].frame = 0;
392 player[c1].frame_tick = 0;
393 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
397 player[c1].x += player[c1].x_add;
398 if ((player[c1].x >> 16) < 0) {
400 player[c1].x_add = 0;
402 if ((player[c1].x >> 16) > JNB_WIDTH) {
405 memset(menu_pal, 0, 768);
406 mod_fade_direction = 0;
408 if ((player[c1].y >> 16) > (138 + c1 * 2)) {
409 if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (190 + c1 * 2)) {
410 player[c1].x = (165L + c1 * 2) << 16;
411 player[c1].x_add = 0;
413 if ((player[c1].x >> 16) > (190 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
414 player[c1].x = (208L + c1 * 2) << 16;
415 player[c1].x_add = 0;
419 player[c1].frame_tick++;
420 if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
422 if (player[c1].frame >= player_anims[player[c1].anim].num_frames)
423 player[c1].frame = player_anims[player[c1].anim].restart_frame;
424 player[c1].frame_tick = 0;
426 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
431 main_info.page_info[main_info.draw_page].num_pobs = 0;
433 for (c1 = 3; c1 >= 0; c1--)
434 add_pob(main_info.draw_page, player[c1].x >> 16, player[c1].y >> 16, player[c1].image + c1 * 18, &rabbit_gobs);
438 if (update_count == 1) {
440 draw_pobs(main_info.draw_page);
445 if (mod_fade_direction == 1) {
448 dj_set_mod_volume((char)mod_vol);
453 dj_set_mod_volume((char)mod_vol);
459 for (c1 = 0; c1 < 720; c1++) {
460 if (menu_cur_pal[c1] < menu_pal[c1]) {
463 } else if (menu_cur_pal[c1] > menu_pal[c1]) {
468 if (fade_flag == 0 && end_loop_flag == 1) {
470 if (new_game_flag == 1)
477 if (fade_count < 30) {
478 for (c1 = 0; c1 < 48; c1++) {
479 if (fade_pal[c1] > 0)
485 clear_lines(0, 220, 20, 0);
486 clear_lines(1, 220, 20, 0);
489 if (cur_message >= NUM_MESSAGES)
490 cur_message -= NUM_MESSAGES;
491 put_text(0, 200, 220, message[cur_message], 2);
492 put_text(1, 200, 220, message[cur_message], 2);
500 if (fade_count < 100) {
501 for (c1 = 0; c1 < 48; c1++) {
502 if (fade_pal[c1] < menu_pal[c1 + 720])
514 for (c1 = 0; c1 < 48; c1++) {
515 if (fade_pal[c1] > menu_pal[c1 + 720])
519 if (update_count == 1) {
520 main_info.draw_page ^= 1;
521 main_info.view_page ^= 1;
523 flippage(main_info.view_page);
528 if (fade_flag != 0) {
529 setpalette(0, 240, menu_cur_pal);
532 if (update_count == 1) {
533 setpalette(240, 16, fade_pal);
538 redraw_pob_backgrounds(main_info.draw_page);
545 update_count = intr_sysupdate();
560 fillpalette(0, 0, 0);
562 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
563 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
566 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, menu_pal) != 0) {
567 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, JNB_WIDTH*JNB_HEIGHT, 0) != 0) {
575 strcpy(main_info.error_str, "Error loading 'menumask.pcx', aborting...\n");
578 memset(menu_cur_pal, 0, 768);
580 for (c1 = 0; c1 < 16; c1++) { // fix dark font
581 menu_pal[(240 + c1) * 3 + 0] = c1 << 2;
582 menu_pal[(240 + c1) * 3 + 1] = c1 << 2;
583 menu_pal[(240 + c1) * 3 + 2] = c1 << 2;
586 recalculate_gob(&rabbit_gobs, menu_pal);
587 recalculate_gob(&font_gobs, menu_pal);
588 recalculate_gob(&object_gobs, menu_pal);
589 register_background(background_pic, menu_pal);
590 register_mask(mask_pic);
592 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
593 player[c1].enabled = 0;
594 player[c1].x = (long) rnd(150) << 16;
595 player[c1].y = (160L + c1 * 2) << 16;
596 player[c1].x_add = 0;
597 player[c1].y_add = 0;
598 player[c1].direction = rnd(2);
599 player[c1].jump_ready = 1;
601 player[c1].frame = 0;
602 player[c1].frame_tick = 0;
603 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image;
606 for (c1 = 0; c1 < NUM_OBJECTS; c1++)
607 objects[c1].used = 0;
609 main_info.page_info[0].num_pobs = 0;
610 main_info.page_info[1].num_pobs = 0;
617 void menu_deinit(void)