1 /*
2  * menu.c
3  * Copyright (C) 1998 Brainchild Design - http://brainchilddesign.com/
4  *
5  * Copyright (C) 2001 Chuck Mason <cemason@users.sourceforge.net>
6  *
7  * Copyright (C) 2002 Florian Schulze <crow@icculus.org>
8  *
9  * Copyright (C) 2015 Côme Chilliet <come@chilliet.eu>
10  *
11  * This file is part of Jump 'n Bump.
12  *
13  * Jump 'n Bump is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * Jump 'n Bump is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
26  */
27 
28 #include "globals.h"
29 
30 char *menu_background;
31 
32 char menu_pal[768];
33 char menu_cur_pal[768];
34 
35 char *message[] = {
36 	"Jump 'n Bump "JNB_VERSION,
37 	"by Brainchild Design in 1998.",
38 	"Code by Mattias Brynervall.",
39 	"Graphics by Martin Magnusson",
40 	"and Andreas Brynervall.",
41 	"Music by Anders Nilsson.",
42 	"Linux port by Chuck Mason.",
43 	"SDL port by Florian Schulze.",
44 	"SDL2 port by Come Chilliet.",
45 	"Maintained by the Libre Games community.",
46 	"Visit our homepage at:",
47 	"libregames.gitlab.io/jumpnbump",
48 	"Jump 'n Bump is free software",
49 	"licensed under GPL 2.0 or later.",
50 	""
51 };
52 
53 #define NUM_MESSAGES (sizeof(message)/sizeof(char *))
54 
menu(void)55 int menu(void)
56 {
57 	int c1;
58 	int esc_pressed;
59 	int end_loop_flag, new_game_flag, fade_flag;
60 	int mod_vol = 0, mod_fade_direction = 0;
61 	int cur_message;
62 	int fade_dir, fade_count;
63 	char fade_pal[48];
64 	int update_count;
65 
66 	if (menu_init() != 0)
67 		return 1;
68 
69 	/* After a game, we have to release the keys, cause AI player
70 	 * can still be using them */
71 	addkey((KEY_PL1_LEFT & 0x7fff) | 0x8000);
72 	addkey((KEY_PL2_LEFT & 0x7fff) | 0x8000);
73 	addkey((KEY_PL3_LEFT & 0x7fff) | 0x8000);
74 	addkey((KEY_PL4_LEFT & 0x7fff) | 0x8000);
75 
76 	addkey((KEY_PL1_RIGHT & 0x7fff) | 0x8000);
77 	addkey((KEY_PL2_RIGHT & 0x7fff) | 0x8000);
78 	addkey((KEY_PL3_RIGHT & 0x7fff) | 0x8000);
79 	addkey((KEY_PL4_RIGHT & 0x7fff) | 0x8000);
80 
81 	addkey((KEY_PL1_JUMP & 0x7fff) | 0x8000);
82 	addkey((KEY_PL2_JUMP & 0x7fff) | 0x8000);
83 	addkey((KEY_PL3_JUMP & 0x7fff) | 0x8000);
84 	addkey((KEY_PL4_JUMP & 0x7fff) | 0x8000);
85 
86 	mod_vol = 0;
87 	mod_fade_direction = 1;
88 	dj_ready_mod(MOD_MENU);
89 	dj_set_mod_volume((char)mod_vol);
90 	dj_set_sfx_volume(64);
91 	dj_start_mod();
92 	dj_set_nosound(0);
93 
94 	memset(fade_pal, 0, 48);
95 	setpalette(240, 16, fade_pal);
96 
97 	fade_dir = 0;
98 	fade_count = 0;
99 	cur_message = NUM_MESSAGES - 1;
100 
101 	main_info.page_info[0].num_pobs = 0;
102 	main_info.page_info[1].num_pobs = 0;
103 	main_info.view_page = 0;
104 	main_info.draw_page = 1;
105 
106 	esc_pressed = key_pressed(1);
107 	end_loop_flag = new_game_flag = 0;
108 
109 	update_count = 1;
110 	while (1) {
111 
112 		dj_mix();
113 
114 		for(c1 = 0; c1 < JNB_MAX_PLAYERS; c1++)		// set AI to false
115 			ai[c1] = 0;
116 
117 		while (update_count) {
118 
119 			if (key_pressed(1) == 1 && esc_pressed == 0) {
120 				end_loop_flag = 1;
121 				new_game_flag = 0;
122 				memset(menu_pal, 0, 768);
123 				mod_fade_direction = 0;
124 			} else if (key_pressed(1) == 0)
125 				esc_pressed = 0;
126 
127 			update_player_actions();
128 			for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
129 				if (end_loop_flag == 1 && new_game_flag == 1) {
130 					if ((player[c1].x >> 16) > (165 + c1 * 2)) {
131 						if (player[c1].x_add < 0)
132 							player[c1].x_add += 16384;
133 						else
134 							player[c1].x_add += 12288;
135 						if (player[c1].x_add > 98304L)
136 							player[c1].x_add = 98304L;
137 						player[c1].direction = 0;
138 						if (player[c1].anim == 0) {
139 							player[c1].anim = 1;
140 							player[c1].frame = 0;
141 							player[c1].frame_tick = 0;
142 							player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
143 						}
144 						player[c1].enabled = 1;
145 					}
146 					if (!player[c1].action_up) {
147 						if (player[c1].y_add < 0) {
148 							player[c1].y_add += 32768;
149 							if (player[c1].y_add > 0)
150 								player[c1].y_add = 0;
151 						}
152 					}
153 					player[c1].y_add += 12288;
154 					if (player[c1].y_add > 36864 && player[c1].anim != 3) {
155 						player[c1].anim = 3;
156 						player[c1].frame = 0;
157 						player[c1].frame_tick = 0;
158 						player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
159 					}
160 					player[c1].y += player[c1].y_add;
161 					if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
162 						if ((player[c1].y >> 16) > (160 + c1 * 2)) {
163 							player[c1].y = (160L + c1 * 2) << 16;
164 							player[c1].y_add = 0;
165 							if (player[c1].anim != 0 && player[c1].anim != 1) {
166 								player[c1].anim = 0;
167 								player[c1].frame = 0;
168 								player[c1].frame_tick = 0;
169 								player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
170 							}
171 						}
172 					} else {
173 						if ((player[c1].y >> 16) > (138 + c1 * 2)) {
174 							player[c1].y = (138L + c1 * 2) << 16;
175 							player[c1].y_add = 0;
176 							if (player[c1].anim != 0 && player[c1].anim != 1) {
177 								player[c1].anim = 0;
178 								player[c1].frame = 0;
179 								player[c1].frame_tick = 0;
180 								player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
181 							}
182 							if (!player[c1].action_up)
183 								player[c1].jump_ready = 1;
184 						}
185 					}
186 					player[c1].x += player[c1].x_add;
187 					if ((player[c1].y >> 16) > (138 + c1 * 2)) {
188 						if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (190 + c1 * 2)) {
189 							player[c1].x = (165L + c1 * 2) << 16;
190 							player[c1].x_add = 0;
191 						}
192 						if ((player[c1].x >> 16) > (190 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
193 							player[c1].x = (208L + c1 * 2) << 16;
194 							player[c1].x_add = 0;
195 						}
196 					}
197 				} else {
198 					if (player[c1].action_left && player[c1].action_right) {
199 						if (player[c1].direction == 1) {
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) >= (160 + 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);
205 								} else
206 									player[c1].x_add -= 12288;
207 							}
208 							if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
209 								if (player[c1].x_add > 0) {
210 									player[c1].x_add -= 16384;
211 									if ((player[c1].y >> 16) >= (138 + c1 * 2))
212 										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);
213 								} else
214 									player[c1].x_add -= 12288;
215 							}
216 							if (player[c1].x_add < -98304L)
217 								player[c1].x_add = -98304L;
218 							player[c1].direction = 1;
219 							if (player[c1].anim == 0) {
220 								player[c1].anim = 1;
221 								player[c1].frame = 0;
222 								player[c1].frame_tick = 0;
223 								player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
224 							}
225 						} else {
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) >= (160 + 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);
231 								} else
232 									player[c1].x_add += 12288;
233 							}
234 							if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
235 								if (player[c1].x_add < 0) {
236 									player[c1].x_add += 16384;
237 									if ((player[c1].y >> 16) >= (138 + c1 * 2))
238 										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);
239 								} else
240 									player[c1].x_add += 12288;
241 							}
242 							if (player[c1].x_add > 98304L)
243 								player[c1].x_add = 98304L;
244 							player[c1].direction = 0;
245 							if (player[c1].anim == 0) {
246 								player[c1].anim = 1;
247 								player[c1].frame = 0;
248 								player[c1].frame_tick = 0;
249 								player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
250 							}
251 						}
252 					} else if (player[c1].action_left) {
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) >= (160 + 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);
258 							} else
259 								player[c1].x_add -= 12288;
260 						}
261 						if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
262 							if (player[c1].x_add > 0) {
263 								player[c1].x_add -= 16384;
264 								if ((player[c1].y >> 16) >= (138 + c1 * 2))
265 									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);
266 							} else
267 								player[c1].x_add -= 12288;
268 						}
269 						if (player[c1].x_add < -98304L)
270 							player[c1].x_add = -98304L;
271 						player[c1].direction = 1;
272 						if (player[c1].anim == 0) {
273 							player[c1].anim = 1;
274 							player[c1].frame = 0;
275 							player[c1].frame_tick = 0;
276 							player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
277 						}
278 					} else if (player[c1].action_right) {
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) >= (160 + 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);
284 							} else
285 								player[c1].x_add += 12288;
286 						}
287 						if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
288 							if (player[c1].x_add < 0) {
289 								player[c1].x_add += 16384;
290 								if ((player[c1].y >> 16) >= (138 + c1 * 2))
291 									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);
292 							} else
293 								player[c1].x_add += 12288;
294 						}
295 						if (player[c1].x_add > 98304L)
296 							player[c1].x_add = 98304L;
297 						player[c1].direction = 0;
298 						if (player[c1].anim == 0) {
299 							player[c1].anim = 1;
300 							player[c1].frame = 0;
301 							player[c1].frame_tick = 0;
302 							player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
303 						}
304 					} else {
305 						if (((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) && (player[c1].y >> 16) >= (160 + c1 * 2)) {
306 							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);
311 							} else 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 							}
317 						}
318 						if ((((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) && (player[c1].y >> 16) >= (138 + c1 * 2))) {
319 							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);
324 							} else if (player[c1].x_add > 0) {
325 								player[c1].x_add -= 16384;
326 								if (player[c1].x_add < 0)
327 									player[c1].x_add = 0;
328 								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);
329 							}
330 						}
331 						if (player[c1].anim == 1) {
332 							player[c1].anim = 0;
333 							player[c1].frame = 0;
334 							player[c1].frame_tick = 0;
335 							player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
336 						}
337 					}
338 					if ((player[c1].jump_ready == 1) && player[c1].action_up) {
339 						if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
340 							if ((player[c1].y >> 16) >= (160 + c1 * 2)) {
341 								player[c1].y_add = -280000L;
342 								player[c1].anim = 2;
343 								player[c1].frame = 0;
344 								player[c1].frame_tick = 0;
345 								player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
346 								player[c1].jump_ready = 0;
347 								dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
348 							}
349 						} else {
350 							if ((player[c1].y >> 16) >= (138 + c1 * 2)) {
351 								player[c1].y_add = -280000L;
352 								player[c1].anim = 2;
353 								player[c1].frame = 0;
354 								player[c1].frame_tick = 0;
355 								player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
356 								player[c1].jump_ready = 0;
357 								dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
358 							}
359 						}
360 					}
361 					if (!player[c1].action_up) {
362 						if (player[c1].y_add < 0) {
363 							player[c1].y_add += 32768;
364 							if (player[c1].y_add > 0)
365 								player[c1].y_add = 0;
366 						}
367 					}
368 					if (!player[c1].action_up)
369 						player[c1].jump_ready = 1;
370 					player[c1].y_add += 12288;
371 					if (player[c1].y_add > 36864 && player[c1].anim != 3) {
372 						player[c1].anim = 3;
373 						player[c1].frame = 0;
374 						player[c1].frame_tick = 0;
375 						player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
376 					}
377 					player[c1].y += player[c1].y_add;
378 					if ((player[c1].x >> 16) <= (165 + c1 * 2) || (player[c1].x >> 16) >= (208 + c1 * 2)) {
379 						if ((player[c1].y >> 16) > (160 + c1 * 2)) {
380 							player[c1].y = (160L + c1 * 2) << 16;
381 							player[c1].y_add = 0;
382 							if (player[c1].anim != 0 && player[c1].anim != 1) {
383 								player[c1].anim = 0;
384 								player[c1].frame = 0;
385 								player[c1].frame_tick = 0;
386 								player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
387 							}
388 						}
389 					} else {
390 						if ((player[c1].y >> 16) > (138 + c1 * 2)) {
391 							player[c1].y = (138L + c1 * 2) << 16;
392 							player[c1].y_add = 0;
393 							if (player[c1].anim != 0 && player[c1].anim != 1) {
394 								player[c1].anim = 0;
395 								player[c1].frame = 0;
396 								player[c1].frame_tick = 0;
397 								player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
398 							}
399 						}
400 					}
401 					player[c1].x += player[c1].x_add;
402 					if ((player[c1].x >> 16) < 0) {
403 						player[c1].x = 0;
404 						player[c1].x_add = 0;
405 					}
406 					if ((player[c1].x >> 16) > JNB_WIDTH) {
407 						end_loop_flag = 1;
408 						new_game_flag = 1;
409 						memset(menu_pal, 0, 768);
410 						mod_fade_direction = 0;
411 					}
412 					if ((player[c1].y >> 16) > (138 + c1 * 2)) {
413 						if ((player[c1].x >> 16) > (165 + c1 * 2) && (player[c1].x >> 16) < (190 + c1 * 2)) {
414 							player[c1].x = (165L + c1 * 2) << 16;
415 							player[c1].x_add = 0;
416 						}
417 						if ((player[c1].x >> 16) > (190 + c1 * 2) && (player[c1].x >> 16) < (208 + c1 * 2)) {
418 							player[c1].x = (208L + c1 * 2) << 16;
419 							player[c1].x_add = 0;
420 						}
421 					}
422 				}
423 				player[c1].frame_tick++;
424 				if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
425 					player[c1].frame++;
426 					if (player[c1].frame >= player_anims[player[c1].anim].num_frames)
427 						player[c1].frame = player_anims[player[c1].anim].restart_frame;
428 					player[c1].frame_tick = 0;
429 				}
430 				player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
431 			}
432 
433 			dj_mix();
434 
435 			main_info.page_info[main_info.draw_page].num_pobs = 0;
436 
437 			for (c1 = 3; c1 >= 0; c1--)
438 				add_pob(main_info.draw_page, player[c1].x >> 16, player[c1].y >> 16, player[c1].image + c1 * 18, &rabbit_gobs);
439 
440 			update_objects();
441 
442 			if (update_count == 1) {
443 				draw_begin();
444 				draw_pobs(main_info.draw_page);
445 				draw_end();
446 
447 				dj_mix();
448 
449 				if (mod_fade_direction == 1) {
450 					if (mod_vol < 35) {
451 						mod_vol++;
452 						dj_set_mod_volume((char)mod_vol);
453 					}
454 				} else {
455 					if (mod_vol > 0) {
456 						mod_vol--;
457 						dj_set_mod_volume((char)mod_vol);
458 					}
459 				}
460 			}
461 
462 			fade_flag = 0;
463 			for (c1 = 0; c1 < 720; c1++) {
464 				if (menu_cur_pal[c1] < menu_pal[c1]) {
465 					menu_cur_pal[c1]++;
466 					fade_flag = 1;
467 				} else if (menu_cur_pal[c1] > menu_pal[c1]) {
468 					menu_cur_pal[c1]--;
469 					fade_flag = 2;
470 				}
471 			}
472 			if (fade_flag == 0 && end_loop_flag == 1) {
473 				menu_deinit();
474 				if (new_game_flag == 1)
475 					return 0;
476 				else
477 					return 1;
478 			}
479 			switch (fade_dir) {
480 			case 0:
481 				if (fade_count < 30) {
482 					for (c1 = 0; c1 < 48; c1++) {
483 						if (fade_pal[c1] > 0)
484 							fade_pal[c1]--;
485 					}
486 					fade_count++;
487 				} else {
488 					draw_begin();
489 					clear_lines(0, 220, 20, 0);
490 					clear_lines(1, 220, 20, 0);
491 
492 					cur_message++;
493 					if (cur_message >= NUM_MESSAGES)
494 						cur_message -= NUM_MESSAGES;
495 					put_text(0, 200, 220, message[cur_message], 2);
496 					put_text(1, 200, 220, message[cur_message], 2);
497 					fade_dir = 1;
498 					fade_count = 0;
499 					draw_end();
500 				}
501 				break;
502 			case 1:
503 				if (fade_count < 100) {
504 					for (c1 = 0; c1 < 48; c1++) {
505 						if (fade_pal[c1] < menu_pal[c1 + 720])
506 							fade_pal[c1]++;
507 					}
508 					fade_count++;
509 				} else {
510 					fade_dir = 0;
511 					fade_count = 0;
512 				}
513 				break;
514 			}
515 
516 			for (c1 = 0; c1 < 48; c1++) {
517 				if (fade_pal[c1] > menu_pal[c1 + 720])
518 					fade_pal[c1]--;
519 			}
520 
521 			if (update_count == 1) {
522 				main_info.draw_page ^= 1;
523 				main_info.view_page ^= 1;
524 
525 				flippage(main_info.view_page);
526 
527 				wait_vrt(1);
528 			}
529 
530 			if (fade_flag != 0) {
531 				setpalette(0, 240, menu_cur_pal);
532 			}
533 
534 			if (update_count == 1) {
535 				setpalette(240, 16, fade_pal);
536 
537 				dj_mix();
538 
539 				draw_begin();
540 				redraw_pob_backgrounds(main_info.draw_page);
541 				draw_end();
542 			}
543 
544 			update_count--;
545 		}
546 
547 		update_count = intr_sysupdate();
548 
549 	}
550 
551 	menu_deinit();
552 	return 0;
553 
554 }
555 
556 
menu_init(void)557 int menu_init(void)
558 {
559 	unsigned char *handle;
560 	int c1;
561 
562 	fillpalette(0, 0, 0);
563 
564 	if ((handle = dat_open("menu.pcx")) == 0) {
565 		strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
566 		return 1;
567 	}
568 	if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, menu_pal) != 0) {
569 		strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
570 		return 1;
571 	}
572 	if ((handle = dat_open("menumask.pcx")) == 0) {
573 		strcpy(main_info.error_str, "Error loading 'menumask.pcx', aborting...\n");
574 		return 1;
575 	}
576 	if (read_pcx(handle, mask_pic, JNB_WIDTH*JNB_HEIGHT, 0) != 0) {
577 		strcpy(main_info.error_str, "Error loading 'menumask.pcx', aborting...\n");
578 		return 1;
579 	}
580 	memset(menu_cur_pal, 0, 768);
581 
582 	/* fix dark font */
583 	for (c1 = 0; c1 < 16; c1++) {
584 		menu_pal[(240 + c1) * 3 + 0] = c1 << 2;
585 		menu_pal[(240 + c1) * 3 + 1] = c1 << 2;
586 		menu_pal[(240 + c1) * 3 + 2] = c1 << 2;
587 	}
588 
589 	recalculate_gob(&rabbit_gobs, menu_pal);
590 	recalculate_gob(&font_gobs, menu_pal);
591 	recalculate_gob(&object_gobs, menu_pal);
592 	register_background(background_pic, menu_pal);
593 	register_mask(mask_pic);
594 
595 	for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
596 		player[c1].enabled = 0;
597 		player[c1].x = (long) rnd(150) << 16;
598 		player[c1].y = (160L + c1 * 2) << 16;
599 		player[c1].x_add = 0;
600 		player[c1].y_add = 0;
601 		player[c1].direction = rnd(2);
602 		player[c1].jump_ready = 1;
603 		player[c1].anim = 0;
604 		player[c1].frame = 0;
605 		player[c1].frame_tick = 0;
606 		player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image;
607 	}
608 
609 	for (c1 = 0; c1 < NUM_OBJECTS; c1++)
610 		objects[c1].used = 0;
611 
612 	main_info.page_info[0].num_pobs = 0;
613 	main_info.page_info[1].num_pobs = 0;
614 
615 	return 0;
616 
617 }
618 
619 
menu_deinit(void)620 void menu_deinit(void)
621 {
622 	dj_set_nosound(1);
623 }
624