1 /*
2  * main.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 #include <fcntl.h>
30 #ifndef _WIN32
31 #include <unistd.h>
32 #endif
33 
34 #ifdef BZLIB_SUPPORT
35 #include "bzlib.h"
36 #endif
37 
38 #ifdef ZLIB_SUPPORT
39 #include "zlib.h"
40 #endif
41 
42 #include "network.h"
43 
44 #ifndef M_PI
45 #define M_PI		3.14159265358979323846
46 #endif
47 
48 gob_t rabbit_gobs = { 0 };
49 gob_t font_gobs = { 0 };
50 gob_t object_gobs = { 0 };
51 gob_t number_gobs = { 0 };
52 
53 main_info_t main_info;
54 player_t player[JNB_MAX_PLAYERS];
55 player_anim_t player_anims[7];
56 object_t objects[NUM_OBJECTS];
57 joy_t joy;
58 mouse_t mouse;
59 
60 char datfile_name[2048];
61 
62 unsigned char *background_pic;
63 unsigned char *mask_pic;
64 int flip = 0;
65 char pal[768];
66 char cur_pal[768];
67 
68 int ai[JNB_MAX_PLAYERS];
69 
70 int endscore_reached = 0;
71 
72 unsigned int ban_map[17][22] = {
73 	{1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
74 	{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0},
75 	{1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
76 	{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1},
77 	{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
78 	{1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
79 	{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1},
80 	{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
81 	{1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
82 	{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1},
83 	{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1},
84 	{1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1},
85 	{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
86 	{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
87 	{2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 1, 3, 3, 3, 1, 1, 1},
88 	{2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
89 	{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
90 };
91 
92 #define GET_BAN_MAP_XY(x,y) ban_map[(y) >> 4][(x) >> 4]
93 
94 struct {
95 	int num_frames;
96 	int restart_frame;
97 	struct {
98 		int image;
99 		int ticks;
100 	} frame[10];
101 } object_anims[8] = {
102 	{
103 		6, 0,
104 		{
105 			{0, 3},
106 			{1, 3},
107 			{2, 3},
108 			{3, 3},
109 			{4, 3},
110 			{5, 3},
111 			{0, 0},
112 			{0, 0},
113 			{0, 0},
114 			{0, 0}
115 		}
116 	}, {
117 		9, 0,
118 		{
119 			{6, 2},
120 			{7, 2},
121 			{8, 2},
122 			{9, 2},
123 			{10, 2},
124 			{11, 2},
125 			{12, 2},
126 			{13, 2},
127 			{14, 2},
128 			{0, 0}
129 		}
130 	}, {
131 		5, 0,
132 		{
133 			{15, 3},
134 			{16, 3},
135 			{16, 3},
136 			{17, 3},
137 			{18, 3},
138 			{19, 3},
139 			{0, 0},
140 			{0, 0},
141 			{0, 0},
142 			{0, 0}
143 		}
144 	}, {
145 		10, 0,
146 		{
147 			{20, 2},
148 			{21, 2},
149 			{22, 2},
150 			{23, 2},
151 			{24, 2},
152 			{25, 2},
153 			{24, 2},
154 			{23, 2},
155 			{22, 2},
156 			{21, 2}
157 		}
158 	}, {
159 		10, 0,
160 		{
161 			{26, 2},
162 			{27, 2},
163 			{28, 2},
164 			{29, 2},
165 			{30, 2},
166 			{31, 2},
167 			{30, 2},
168 			{29, 2},
169 			{28, 2},
170 			{27, 2}
171 		}
172 	}, {
173 		10, 0,
174 		{
175 			{32, 2},
176 			{33, 2},
177 			{34, 2},
178 			{35, 2},
179 			{36, 2},
180 			{37, 2},
181 			{36, 2},
182 			{35, 2},
183 			{34, 2},
184 			{33, 2}
185 		}
186 	}, {
187 		10, 0,
188 		{
189 			{38, 2},
190 			{39, 2},
191 			{40, 2},
192 			{41, 2},
193 			{42, 2},
194 			{43, 2},
195 			{42, 2},
196 			{41, 2},
197 			{40, 2},
198 			{39, 2}
199 		}
200 	}, {
201 		4, 0,
202 		{
203 			{76, 4},
204 			{77, 4},
205 			{78, 4},
206 			{79, 4},
207 			{0, 0},
208 			{0, 0},
209 			{0, 0},
210 			{0, 0},
211 			{0, 0},
212 			{0, 0}
213 		}
214 	}
215 };
216 
217 int flies_enabled = 1;
218 
219 struct {
220 	int x, y;
221 	int old_x, old_y;
222 	int old_draw_x, old_draw_y;
223 	int back[2];
224 	int back_defined[2];
225 } flies[NUM_FLIES];
226 
227 struct {
228 	struct {
229 		short num_pobs;
230 		struct {
231 			int x, y;
232 			int image;
233 			gob_t *pob_data;
234 		} pobs[NUM_LEFTOVERS];
235 	} page[2];
236 } leftovers;
237 
238 int pogostick, bunnies_in_space, jetpack, lord_of_the_flies, blood_is_thicker_than_water;
239 
240 int client_player_num = -1;
241 
242 #ifndef _WIN32
filelength(int handle)243 int filelength(int handle)
244 {
245 	struct stat buf;
246 
247 	if (fstat(handle, &buf) == -1) {
248 		perror("filelength");
249 		exit(EXIT_FAILURE);
250 	}
251 
252 	return buf.st_size;
253 }
254 #endif
255 
256 
flip_pixels(unsigned char * pixels)257 static void flip_pixels(unsigned char *pixels)
258 {
259 	int x,y;
260 	unsigned char temp;
261 
262 	assert(pixels);
263 	for (y = 0; y < JNB_HEIGHT; y++) {
264 		for (x = 0; x < (352/2); x++) {
265 			temp = pixels[y*JNB_WIDTH+x];
266 			pixels[y*JNB_WIDTH+x] = pixels[y*JNB_WIDTH+(352-x)-1];
267 			pixels[y*JNB_WIDTH+(352-x)-1] = temp;
268 		}
269 	}
270 }
271 
272 
get_closest_player_to_point(int x,int y,int * dist,int * closest_player)273 void get_closest_player_to_point(int x,int y,int *dist,int *closest_player)
274 {
275 	int c1;
276 	int cur_dist = 0;
277 
278 	*dist = 0x7fff;
279 	for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
280 		if (player[c1].enabled == 1) {
281 			cur_dist = (int)sqrt((x - ((player[c1].x >> 16) + 8)) * (x - ((player[c1].x >> 16) + 8)) + (y - ((player[c1].y >> 16) + 8)) * (y - ((player[c1].y >> 16) + 8)));
282 			if (cur_dist < *dist) {
283 				*closest_player = c1;
284 				*dist = cur_dist;
285 			}
286 		}
287 	}
288 }
289 
290 
update_flies(int update_count)291 static void update_flies(int update_count)
292 {
293 	int c1;
294 	int closest_player = 0, dist;
295 	int s1, s2, s3, s4;
296 
297 	/* get center of fly swarm */
298 	s1 = s2 = 0;
299 	for (c1 = 0; c1 < NUM_FLIES; c1++) {
300 		s1 += flies[c1].x;
301 		s2 += flies[c1].y;
302 	}
303 	s1 /= NUM_FLIES;
304 	s2 /= NUM_FLIES;
305 
306 	if (update_count == 1) {
307 		/* get closest player to fly swarm */
308 		get_closest_player_to_point(s1, s2, &dist, &closest_player);
309 		/* update fly swarm sound */
310 		s3 = 32 - dist / 3;
311 		if (s3 < 0)
312 			s3 = 0;
313 		dj_set_sfx_channel_volume(4, (char)(s3));
314 	}
315 
316 	for (c1 = 0; c1 < NUM_FLIES; c1++) {
317 		/* get closest player to fly */
318 		get_closest_player_to_point(flies[c1].x, flies[c1].y, &dist, &closest_player);
319 		flies[c1].old_x = flies[c1].x;
320 		flies[c1].old_y = flies[c1].y;
321 		s3 = 0;
322 		if ((s1 - flies[c1].x) > 30)
323 			s3 += 1;
324 		else if ((s1 - flies[c1].x) < -30)
325 			s3 -= 1;
326 		if (dist < 30) {
327 			if (((player[closest_player].x >> 16) + 8) > flies[c1].x) {
328 				if (lord_of_the_flies == 0)
329 					s3 -= 1;
330 				else
331 					s3 += 1;
332 			} else {
333 				if (lord_of_the_flies == 0)
334 					s3 += 1;
335 				else
336 					s3 -= 1;
337 			}
338 		}
339 		s4 = rnd(3) - 1 + s3;
340 		if ((flies[c1].x + s4) < 16)
341 			s4 = 0;
342 		if ((flies[c1].x + s4) > 351)
343 			s4 = 0;
344 		if (GET_BAN_MAP_XY(flies[c1].x + s4, flies[c1].y) != BAN_VOID)
345 			s4 = 0;
346 		flies[c1].x += s4;
347 		s3 = 0;
348 		if ((s2 - flies[c1].y) > 30)
349 			s3 += 1;
350 		else if ((s2 - flies[c1].y) < -30)
351 			s3 -= 1;
352 		if (dist < 30) {
353 			if (((player[closest_player].y >> 16) + 8) > flies[c1].y) {
354 				if (lord_of_the_flies == 0)
355 					s3 -= 1;
356 				else
357 					s3 += 1;
358 			} else {
359 				if (lord_of_the_flies == 0)
360 					s3 += 1;
361 				else
362 					s3 -= 1;
363 			}
364 		}
365 		s4 = rnd(3) - 1 + s3;
366 		if ((flies[c1].y + s4) < 0)
367 			s4 = 0;
368 		if ((flies[c1].y + s4) > 239)
369 			s4 = 0;
370 		if (GET_BAN_MAP_XY(flies[c1].x, flies[c1].y + s4) != BAN_VOID)
371 			s4 = 0;
372 		flies[c1].y += s4;
373 	}
374 }
375 
376 
player_kill(int c1,int c2)377 static void player_kill(int c1, int c2)
378 {
379 	if (player[c1].y_add >= 0) {
380 		if (is_server)
381 			serverSendKillPacket(c1, c2);
382 	} else {
383 		if (player[c2].y_add < 0)
384 			player[c2].y_add = 0;
385 	}
386 }
387 
388 
check_cheats(void)389 static void check_cheats(void)
390 {
391 	if (strncmp(last_keys, "kcitsogop", strlen("kcitsogop")) == 0) {
392 		pogostick ^= 1;
393 		last_keys[0] = 0;
394 	}
395 	if (strncmp(last_keys, "ecapsniseinnub", strlen("ecapsniseinnub")) == 0) {
396 		bunnies_in_space ^= 1;
397 		last_keys[0] = 0;
398 	}
399 	if (strncmp(last_keys, "kcaptej", strlen("kcaptej")) == 0) {
400 		jetpack ^= 1;
401 		last_keys[0] = 0;
402 	}
403 	if (strncmp(last_keys, "seilfehtfodrol", strlen("seilfehtfodrol")) == 0) {
404 		lord_of_the_flies ^= 1;
405 		last_keys[0] = 0;
406 	}
407 	if (strncmp(last_keys, "retawnahtrekcihtsidoolb", strlen("retawnahtrekcihtsidoolb")) == 0) {
408 		char blood[32] = {
409 			63,32,32,53,17,17,42, 7,
410 			 7,28, 0, 0,24, 0, 0,19,
411 			 0, 0,12, 0, 0, 7, 0, 0
412 		};
413 		char water[32] = {
414 			63,63,63,40,53,62,19,42,
415 			60, 0,33,60, 3,32,46, 3,
416 			26,33, 3,19,21, 1, 8, 8
417 		};
418 		int i;
419 
420 		blood_is_thicker_than_water ^= 1;
421 		if (blood_is_thicker_than_water == 1) {
422 			for (i=0; i<32; i++)
423 				pal[432+i] = blood[i];
424 		} else {
425 			for (i=0; i<32; i++)
426 				pal[432+i] = water[i];
427 		}
428 		register_background(background_pic, pal);
429 		recalculate_gob(&object_gobs, pal);
430 		last_keys[0] = 0;
431 	}
432 }
433 
434 
collision_check(void)435 static void collision_check(void)
436 {
437 	int c1 = 0, c2 = 0, c3 = 0;
438 	int l1;
439 
440 	/* collision check */
441 	for (c3 = 0; c3 < 6; c3++) {
442 		if (c3 == 0) {
443 			c1 = 0;
444 			c2 = 1;
445 		} else if (c3 == 1) {
446 			c1 = 0;
447 			c2 = 2;
448 		} else if (c3 == 2) {
449 			c1 = 0;
450 			c2 = 3;
451 		} else if (c3 == 3) {
452 			c1 = 1;
453 			c2 = 2;
454 		} else if (c3 == 4) {
455 			c1 = 1;
456 			c2 = 3;
457 		} else if (c3 == 5) {
458 			c1 = 2;
459 			c2 = 3;
460 		}
461 		if (player[c1].enabled == 1 && player[c2].enabled == 1) {
462 			if (labs(player[c1].x - player[c2].x) < (12L << 16) && labs(player[c1].y - player[c2].y) < (12L << 16)) {
463 				if ((labs(player[c1].y - player[c2].y) >> 16) > 5) {
464 					if (player[c1].y < player[c2].y) {
465 						player_kill(c1,c2);
466 					} else {
467 						player_kill(c2,c1);
468 					}
469 				} else {
470 					if (player[c1].x < player[c2].x) {
471 						if (player[c1].x_add > 0)
472 							player[c1].x = player[c2].x - (12L << 16);
473 						else if (player[c2].x_add < 0)
474 							player[c2].x = player[c1].x + (12L << 16);
475 						else {
476 							player[c1].x -= player[c1].x_add;
477 							player[c2].x -= player[c2].x_add;
478 						}
479 						l1 = player[c2].x_add;
480 						player[c2].x_add = player[c1].x_add;
481 						player[c1].x_add = l1;
482 						if (player[c1].x_add > 0)
483 							player[c1].x_add = -player[c1].x_add;
484 						if (player[c2].x_add < 0)
485 							player[c2].x_add = -player[c2].x_add;
486 					} else {
487 						if (player[c1].x_add > 0)
488 							player[c2].x = player[c1].x - (12L << 16);
489 						else if (player[c2].x_add < 0)
490 							player[c1].x = player[c2].x + (12L << 16);
491 						else {
492 							player[c1].x -= player[c1].x_add;
493 							player[c2].x -= player[c2].x_add;
494 						}
495 						l1 = player[c2].x_add;
496 						player[c2].x_add = player[c1].x_add;
497 						player[c1].x_add = l1;
498 						if (player[c1].x_add < 0)
499 							player[c1].x_add = -player[c1].x_add;
500 						if (player[c2].x_add > 0)
501 							player[c2].x_add = -player[c2].x_add;
502 					}
503 				}
504 			}
505 		}
506 	}
507 }
508 
game_loop(void)509 static void game_loop(void) {
510 	int mod_vol, sfx_vol;
511 	int update_count = 1;
512 	int end_loop_flag = 0;
513 	int fade_flag = 0;
514 	int update_palette = 0;
515 	int mod_fade_direction;
516 	int i;
517 
518 	mod_vol = sfx_vol = 0;
519 	mod_fade_direction = 1;
520 	dj_ready_mod(MOD_GAME);
521 	dj_set_mod_volume((char)mod_vol);
522 	dj_set_sfx_volume((char)mod_vol);
523 	dj_start_mod();
524 
525 	intr_sysupdate();
526 
527 	endscore_reached = 0;
528 	while (1) {
529 		while (update_count) {
530 
531 			if (endscore_reached || (key_pressed(1) == 1)) {
532 #ifdef USE_NET
533 				if (is_net) {
534 					if (is_server) {
535 						serverTellEveryoneGoodbye();
536 					} else {
537 						tellServerGoodbye();
538 					}
539 				}
540 #endif
541 				end_loop_flag = 1;
542 				memset(pal, 0, 768);
543 				mod_fade_direction = 0;
544 			}
545 
546 			check_cheats();
547 
548 #ifdef USE_NET
549 			if (is_net) {
550 				if (is_server) {
551 					update_players_from_clients();
552 				} else {
553 					if (!update_players_from_server()) {
554 						break;  /* got a BYE packet */
555 					}
556 				}
557 			}
558 #endif
559 
560 			steer_players();
561 
562 			dj_mix();
563 
564 			collision_check();
565 
566 			dj_mix();
567 
568 			main_info.page_info[main_info.draw_page].num_pobs = 0;
569 			for (i = 0; i < JNB_MAX_PLAYERS; i++) {
570 				if (player[i].enabled == 1)
571 					main_info.page_info[main_info.draw_page].num_pobs++;
572 			}
573 
574 			update_objects();
575 
576 			dj_mix();
577 
578 			if (flies_enabled) {
579 				update_flies(update_count);
580 			}
581 
582 			dj_mix();
583 
584 			if (update_count == 1) {
585 				int c2;
586 
587 				for (i = 0, c2 = 0; i < JNB_MAX_PLAYERS; i++) {
588 					if (player[i].enabled == 1) {
589 						main_info.page_info[main_info.draw_page].pobs[c2].x = player[i].x >> 16;
590 						main_info.page_info[main_info.draw_page].pobs[c2].y = player[i].y >> 16;
591 						main_info.page_info[main_info.draw_page].pobs[c2].image = player[i].image + i * 18;
592 						main_info.page_info[main_info.draw_page].pobs[c2].pob_data = &rabbit_gobs;
593 						c2++;
594 					}
595 				}
596 
597 				draw_begin();
598 
599 				draw_pobs(main_info.draw_page);
600 
601 				dj_mix();
602 
603 				if (flies_enabled)
604 					draw_flies(main_info.draw_page);
605 
606 				draw_end();
607 			}
608 
609 			if (mod_fade_direction == 1) {
610 				if (mod_vol < 30) {
611 					mod_vol++;
612 					dj_set_mod_volume((char)mod_vol);
613 				}
614 				if (sfx_vol < 64) {
615 					sfx_vol++;
616 					dj_set_sfx_volume((char)sfx_vol);
617 				}
618 			} else {
619 				if (mod_vol > 0) {
620 					mod_vol--;
621 					dj_set_mod_volume((char)mod_vol);
622 				}
623 				if (sfx_vol > 0) {
624 					sfx_vol--;
625 					dj_set_sfx_volume((char)sfx_vol);
626 				}
627 			}
628 
629 			fade_flag = 0;
630 			for (i = 0; i < 768; i++) {
631 				if (cur_pal[i] < pal[i]) {
632 					cur_pal[i]++;
633 					fade_flag = 1;
634 				} else if (cur_pal[i] > pal[i]) {
635 					cur_pal[i]--;
636 					fade_flag = 1;
637 				}
638 			}
639 			if (fade_flag == 1)
640 				update_palette = 1;
641 			if (fade_flag == 0 && end_loop_flag == 1)
642 				break;
643 
644 			if (update_count == 1) {
645 				if (update_palette == 1) {
646 					setpalette(0, 256, cur_pal);
647 					update_palette = 0;
648 				}
649 
650 				main_info.draw_page ^= 1;
651 				main_info.view_page ^= 1;
652 
653 				flippage(main_info.view_page);
654 
655 				wait_vrt(1);
656 
657 				draw_begin();
658 
659 				if (flies_enabled)
660 					redraw_flies_background(main_info.draw_page);
661 
662 				redraw_pob_backgrounds(main_info.draw_page);
663 
664 				draw_leftovers(main_info.draw_page);
665 
666 				draw_end();
667 			}
668 
669 			update_count--;
670 		}
671 
672 #ifdef USE_NET
673 		if (is_net) {
674 			if ( (player[client_player_num].dead_flag == 0) &&
675 				(
676 				 (player[client_player_num].action_left) ||
677 				 (player[client_player_num].action_right) ||
678 				 (player[client_player_num].action_up) ||
679 				 (player[client_player_num].jump_ready == 0)
680 				)
681 			   ) {
682 				tellServerNewPosition();
683 			}
684 		}
685 #endif
686 
687 		update_count = intr_sysupdate();
688 
689 #ifdef USE_NET
690 		if (is_net) {
691 			if ((server_said_bye) || ((fade_flag == 0) && (end_loop_flag == 1)))
692 				break;
693 		} else
694 #endif
695 		if ((fade_flag == 0) && (end_loop_flag == 1))
696 			break;
697 	}
698 }
699 
700 
menu_loop(void)701 static int menu_loop(void)
702 {
703 	unsigned char *handle;
704 	int mod_vol;
705 	int c1, c2;
706 	int s1, s2;
707 
708 	for(c1 = 0; c1 < JNB_MAX_PLAYERS; c1++)		// reset player values
709         {
710 		ai[c1] = 0;
711         }
712 
713 	while (1) {
714 
715 		if (!is_net)
716 			if (menu() != 0)
717 				deinit_program();
718 
719 		if (key_pressed(1) == 1) {
720 			return 0;
721 		}
722 		if (init_level(0, pal) != 0) {
723 			deinit_level();
724 			deinit_program();
725 		}
726 
727 		memset(cur_pal, 0, 768);
728 		setpalette(0, 256, cur_pal);
729 
730 		recalculate_gob(&rabbit_gobs, pal);
731 		recalculate_gob(&object_gobs, pal);
732 		recalculate_gob(&number_gobs, pal);
733 
734 		flippage(1);
735 		register_background(background_pic, pal);
736 		flippage(0);
737 
738 		if (flies_enabled) {
739 			s1 = rnd(250) + 50;
740 			s2 = rnd(150) + 50;
741 
742 			for (c1 = 0; c1 < NUM_FLIES; c1++) {
743 				while (1) {
744 					flies[c1].x = s1 + rnd(101) - 50;
745 					flies[c1].y = s2 + rnd(101) - 50;
746 					if (GET_BAN_MAP_XY(flies[c1].x, flies[c1].y) == BAN_VOID)
747 						break;
748 				}
749 				flies[c1].back_defined[0] = 0;
750 				flies[c1].back_defined[1] = 0;
751 			}
752 		}
753 
754 		if (flies_enabled)
755 			dj_play_sfx(SFX_FLY, SFX_FLY_FREQ, 0, 0, 0, 4);
756 
757 		dj_set_nosound(0);
758 
759 		lord_of_the_flies = bunnies_in_space = jetpack = pogostick = blood_is_thicker_than_water = 0;
760 		main_info.page_info[0].num_pobs = 0;
761 		main_info.page_info[1].num_pobs = 0;
762 		main_info.view_page = 0;
763 		main_info.draw_page = 1;
764 
765 		game_loop();
766 
767 #ifdef USE_NET
768 		if (is_net) {
769 			if (is_server) {
770 				serverTellEveryoneGoodbye();
771 				SDLNet_TCP_Close(sock);
772 				sock = NULL;
773 			} else {
774 				if (!server_said_bye) {
775 					tellServerGoodbye();
776 				}
777 
778 				SDLNet_TCP_Close(sock);
779 				sock = NULL;
780 			}
781 		}
782 #endif
783 
784 		main_info.view_page = 0;
785 		main_info.draw_page = 1;
786 
787 		dj_stop_sfx_channel(4);
788 
789 		deinit_level();
790 
791 		memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
792 		register_mask(mask_pic);
793 
794 		register_background(NULL, NULL);
795 
796 		draw_begin();
797 
798 		put_text(main_info.view_page, 100, 50, "DOTT", 2);
799 		put_text(main_info.view_page, 160, 50, "JIFFY", 2);
800 		put_text(main_info.view_page, 220, 50, "FIZZ", 2);
801 		put_text(main_info.view_page, 280, 50, "MIJJI", 2);
802 		put_text(main_info.view_page, 40, 80, "DOTT", 2);
803 		put_text(main_info.view_page, 40, 110, "JIFFY", 2);
804 		put_text(main_info.view_page, 40, 140, "FIZZ", 2);
805 		put_text(main_info.view_page, 40, 170, "MIJJI", 2);
806 
807 		for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
808 			if (!player[c1].enabled) {
809 				continue;
810 			}
811 			char str1[100];
812 
813 			for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
814 				if (!player[c2].enabled) {
815 					continue;
816 				}
817 				if (c2 != c1) {
818 					sprintf(str1, "%d", player[c1].bumped[c2]);
819 					put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, str1, 2);
820 				} else
821 					put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, "-", 2);
822 			}
823 			sprintf(str1, "%d", player[c1].bumps);
824 			put_text(main_info.view_page, 350, 80 + c1 * 30, str1, 2);
825 		}
826 
827 		put_text(main_info.view_page, 200, 230, "Press ESC to continue", 2);
828 
829 		draw_end();
830 
831 		flippage(main_info.view_page);
832 
833 		if ((handle = dat_open("menu.pcx")) == 0) {
834 			strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
835 			return 1;
836 		}
837 		if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
838 			strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
839 			return 1;
840 		}
841 
842 		/* fix dark font */
843 		for (c1 = 0; c1 < 16; c1++) {
844 			pal[(240 + c1) * 3 + 0] = c1 << 2;
845 			pal[(240 + c1) * 3 + 1] = c1 << 2;
846 			pal[(240 + c1) * 3 + 2] = c1 << 2;
847 		}
848 
849 		memset(cur_pal, 0, 768);
850 
851 		setpalette(0, 256, cur_pal);
852 
853 		mod_vol = 0;
854 		dj_ready_mod(MOD_SCORES);
855 		dj_set_mod_volume((char)mod_vol);
856 		dj_start_mod();
857 		dj_set_nosound(0);
858 
859 		while (key_pressed(1) == 0) {
860 			if (mod_vol < 35)
861 				mod_vol++;
862 			dj_set_mod_volume((char)mod_vol);
863 			for (c1 = 0; c1 < 768; c1++) {
864 				if (cur_pal[c1] < pal[c1])
865 					cur_pal[c1]++;
866 			}
867 			dj_mix();
868 			intr_sysupdate();
869 			wait_vrt(0);
870 			setpalette(0, 256, cur_pal);
871 			flippage(main_info.view_page);
872 		}
873 		while (key_pressed(1) == 1) {
874 			dj_mix();
875 			intr_sysupdate();
876 		}
877 
878 		memset(pal, 0, 768);
879 
880 		while (mod_vol > 0) {
881 			mod_vol--;
882 			dj_set_mod_volume((char)mod_vol);
883 			for (c1 = 0; c1 < 768; c1++) {
884 				if (cur_pal[c1] > pal[c1])
885 					cur_pal[c1]--;
886 			}
887 			dj_mix();
888 			wait_vrt(0);
889 			setpalette(0, 256, cur_pal);
890 			flippage(main_info.view_page);
891 		}
892 
893 		fillpalette(0, 0, 0);
894 
895 		dj_set_nosound(1);
896 		dj_stop_mod();
897 
898 		if (is_net)
899 			return 0; /* don't go back to menu if in net game. */
900 	}
901 }
902 
903 
main(int argc,char * argv[])904 int main(int argc, char *argv[])
905 {
906 	int result;
907 
908 	if (init_program(argc, argv, pal) != 0)
909 		deinit_program();
910 
911 	result = menu_loop();
912 
913 	deinit_program();
914 
915 	return result;
916 }
917 
918 
player_action_left(int c1)919 static void player_action_left(int c1)
920 {
921 	int s1 = 0, s2 = 0;
922 	int below_left, below, below_right;
923 
924     s1 = (player[c1].x >> 16);
925     s2 = (player[c1].y >> 16);
926 	below_left = GET_BAN_MAP_XY(s1, s2 + 16);
927 	below = GET_BAN_MAP_XY(s1 + 8, s2 + 16);
928 	below_right = GET_BAN_MAP_XY(s1 + 15, s2 + 16);
929 
930     if (below == BAN_ICE) {
931         if (player[c1].x_add > 0)
932             player[c1].x_add -= 1024;
933         else
934             player[c1].x_add -= 768;
935     } else if ((below_left != BAN_SOLID && below_right == BAN_ICE) || (below_left == BAN_ICE && below_right != BAN_SOLID)) {
936         if (player[c1].x_add > 0)
937             player[c1].x_add -= 1024;
938         else
939             player[c1].x_add -= 768;
940     } else {
941         if (player[c1].x_add > 0) {
942             player[c1].x_add -= 16384;
943             if (player[c1].x_add > -98304L && player[c1].in_water == 0 && below == BAN_SOLID)
944                 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);
945         } else
946             player[c1].x_add -= 12288;
947     }
948     if (player[c1].x_add < -98304L)
949         player[c1].x_add = -98304L;
950     player[c1].direction = 1;
951     if (player[c1].anim == 0) {
952         player[c1].anim = 1;
953         player[c1].frame = 0;
954         player[c1].frame_tick = 0;
955         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
956     }
957 }
958 
959 
player_action_right(int c1)960 static void player_action_right(int c1)
961 {
962 	int s1 = 0, s2 = 0;
963 	int below_left, below, below_right;
964 
965     s1 = (player[c1].x >> 16);
966     s2 = (player[c1].y >> 16);
967 	below_left = GET_BAN_MAP_XY(s1, s2 + 16);
968 	below = GET_BAN_MAP_XY(s1 + 8, s2 + 16);
969 	below_right = GET_BAN_MAP_XY(s1 + 15, s2 + 16);
970 
971     if (below == BAN_ICE) {
972         if (player[c1].x_add < 0)
973             player[c1].x_add += 1024;
974         else
975             player[c1].x_add += 768;
976     } else if ((below_left != BAN_SOLID && below_right == BAN_ICE) || (below_left == BAN_ICE && below_right != BAN_SOLID)) {
977         if (player[c1].x_add > 0)
978             player[c1].x_add += 1024;
979         else
980             player[c1].x_add += 768;
981     } else {
982         if (player[c1].x_add < 0) {
983             player[c1].x_add += 16384;
984             if (player[c1].x_add < 98304L && player[c1].in_water == 0 && below == BAN_SOLID)
985                 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);
986         } else
987             player[c1].x_add += 12288;
988     }
989     if (player[c1].x_add > 98304L)
990         player[c1].x_add = 98304L;
991     player[c1].direction = 0;
992     if (player[c1].anim == 0) {
993         player[c1].anim = 1;
994         player[c1].frame = 0;
995         player[c1].frame_tick = 0;
996         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
997     }
998 }
999 
map_tile(int pos_x,int pos_y)1000 int map_tile(int pos_x, int pos_y)
1001 {
1002 int tile;
1003 
1004 pos_x = pos_x >> 4;
1005 pos_y = pos_y >> 4;
1006 
1007 if(pos_x < 0 || pos_x >= 17 || pos_y < 0 || pos_y >= 22)
1008   return BAN_VOID;
1009 
1010 tile = ban_map[pos_y][pos_x];
1011 return tile;
1012 }
1013 
cpu_move(void)1014 void cpu_move(void)
1015 {
1016 	int lm, rm, jm;
1017 	int i, j;
1018 	int cur_posx, cur_posy, tar_posx, tar_posy;
1019 	int players_distance;
1020 	player_t* target = NULL;
1021 	int nearest_distance = -1;
1022 
1023 	for (i = 0; i < JNB_MAX_PLAYERS; i++)
1024 		{
1025 	  nearest_distance = -1;
1026 		if(ai[i] && player[i].enabled)		// this player is a computer
1027 			{		// get nearest target
1028 			for (j = 0; j < JNB_MAX_PLAYERS; j++)
1029 				{
1030 				int deltax, deltay;
1031 
1032 				if(i == j || !player[j].enabled)
1033 					continue;
1034 
1035 				deltax = player[j].x - player[i].x;
1036 				deltay = player[j].y - player[i].y;
1037 				players_distance = deltax*deltax + deltay*deltay;
1038 
1039 				if (players_distance < nearest_distance || nearest_distance == -1)
1040 					{
1041 					target = &player[j];
1042 					nearest_distance = players_distance;
1043 					}
1044 				}
1045 
1046 			if(target == NULL)
1047 				continue;
1048 
1049 			cur_posx = player[i].x >> 16;
1050 			cur_posy = player[i].y >> 16;
1051 			tar_posx = target->x >> 16;
1052 			tar_posy = target->y >> 16;
1053 
1054 			/** nearest player found, get him */
1055 			/* here goes the artificial intelligence code */
1056 
1057 			/* X-axis movement */
1058 			if(tar_posx > cur_posx)       // if true target is on the right side
1059 				{    // go after him
1060 				lm=0;
1061 				rm=1;
1062 				}
1063 			else    // target on the left side
1064 				{
1065 				lm=1;
1066 				rm=0;
1067 				}
1068 
1069 			if(cur_posy - tar_posy < 32 && cur_posy - tar_posy > 0 &&
1070               tar_posx - cur_posx < 32+8 && tar_posx - cur_posx > -32)
1071 				{
1072 				lm = !lm;
1073 				rm = !rm;
1074 				}
1075 			else if(tar_posx - cur_posx < 4+8 && tar_posx - cur_posx > -4)
1076 				{      // makes the bunnies less "nervous"
1077 				lm=0;
1078 				lm=0;
1079 				}
1080 
1081 			/* Y-axis movement */
1082 			if(map_tile(cur_posx, cur_posy+16) != BAN_VOID &&
1083 				((i == 0 && key_pressed(KEY_PL1_JUMP)) ||
1084 				(i == 1 && key_pressed(KEY_PL2_JUMP)) ||
1085 				(i == 2 && key_pressed(KEY_PL3_JUMP)) ||
1086 				(i == 3 && key_pressed(KEY_PL4_JUMP))))
1087 					jm=0;   // if we are on ground and jump key is being pressed,
1088 									//first we have to release it or else we won't be able to jump more than once
1089 
1090 			else if(map_tile(cur_posx, cur_posy-8) != BAN_VOID &&
1091 				map_tile(cur_posx, cur_posy-8) != BAN_WATER)
1092 					jm=0;   // don't jump if there is something over it
1093 
1094 			else if(map_tile(cur_posx-(lm*8)+(rm*16), cur_posy) != BAN_VOID &&
1095 				map_tile(cur_posx-(lm*8)+(rm*16), cur_posy) != BAN_WATER &&
1096 				cur_posx > 16 && cur_posx < 352-16-8)  // obstacle, jump
1097 					jm=1;   // if there is something on the way, jump over it
1098 
1099 			else if(((i == 0 && key_pressed(KEY_PL1_JUMP)) ||
1100 							(i == 1 && key_pressed(KEY_PL2_JUMP)) ||
1101 							(i == 2 && key_pressed(KEY_PL3_JUMP)) ||
1102 							(i == 3 && key_pressed(KEY_PL4_JUMP))) &&
1103 							(map_tile(cur_posx-(lm*8)+(rm*16), cur_posy+8) != BAN_VOID &&
1104 							map_tile(cur_posx-(lm*8)+(rm*16), cur_posy+8) != BAN_WATER))
1105 					jm=1;   // this makes it possible to jump over 2 tiles
1106 
1107 			else if(cur_posy - tar_posy < 32 && cur_posy - tar_posy > 0 &&
1108               tar_posx - cur_posx < 32+8 && tar_posx - cur_posx > -32)  // don't jump - running away
1109 				jm=0;
1110 
1111 			else if(tar_posy <= cur_posy)   // target on the upper side
1112 				jm=1;
1113 			else   // target below
1114 				jm=0;
1115 
1116 			/** Artificial intelligence done, now apply movements */
1117 			if(lm)
1118 				{
1119 				SDL_Scancode key;
1120 				if(i == 0)
1121 					key = KEY_PL1_LEFT;
1122 				else if(i == 1)
1123 					key = KEY_PL2_LEFT;
1124 				else if(i == 2)
1125 					key = KEY_PL3_LEFT;
1126 				else
1127 					key = KEY_PL4_LEFT;
1128 
1129 				key &= 0x7fff;
1130 				addkey(key);
1131 				}
1132 			else
1133 				{
1134 				SDL_Scancode key;
1135 				if(i == 0)
1136 					key = KEY_PL1_LEFT;
1137 				else if(i == 1)
1138 					key = KEY_PL2_LEFT;
1139 				else if(i == 2)
1140 					key = KEY_PL3_LEFT;
1141 				else
1142 					key = KEY_PL4_LEFT;
1143 
1144 				key &= 0x7fff;
1145 				addkey(key | 0x8000);
1146 				}
1147 
1148 			if(rm)
1149 				{
1150 				SDL_Scancode key;
1151 				if(i == 0)
1152 					key = KEY_PL1_RIGHT;
1153 				else if(i == 1)
1154 					key = KEY_PL2_RIGHT;
1155 				else if(i == 2)
1156 					key = KEY_PL3_RIGHT;
1157 				else
1158 					key = KEY_PL4_RIGHT;
1159 
1160 				key &= 0x7fff;
1161 				addkey(key);
1162 				}
1163 			else
1164 				{
1165 				SDL_Scancode key;
1166 				if(i == 0)
1167 					key = KEY_PL1_RIGHT;
1168 				else if(i == 1)
1169 					key = KEY_PL2_RIGHT;
1170 				else if(i == 2)
1171 					key = KEY_PL3_RIGHT;
1172 				else
1173 					key = KEY_PL4_RIGHT;
1174 
1175 				key &= 0x7fff;
1176 				addkey(key | 0x8000);
1177 				}
1178 
1179 			if(jm)
1180 				{
1181 				SDL_Scancode key;
1182 				if(i == 0)
1183 					key = KEY_PL1_JUMP;
1184 				else if(i == 1)
1185 					key = KEY_PL2_JUMP;
1186 				else if(i == 2)
1187 					key = KEY_PL3_JUMP;
1188 				else
1189 					key = KEY_PL4_JUMP;
1190 
1191 				key &= 0x7fff;
1192 				addkey(key);
1193 				}
1194 			else
1195 				{
1196 				SDL_Scancode key;
1197 				if(i == 0)
1198 					key = KEY_PL1_JUMP;
1199 				else if(i == 1)
1200 					key = KEY_PL2_JUMP;
1201 				else if(i == 2)
1202 					key = KEY_PL3_JUMP;
1203 				else
1204 					key = KEY_PL4_JUMP;
1205 
1206 				key &= 0x7fff;
1207 				addkey(key | 0x8000);
1208 				}
1209 			}
1210 		}
1211 }
1212 
1213 
1214 #define GET_BAN_MAP_IN_WATER(s1, s2) (GET_BAN_MAP_XY((s1), ((s2) + 7)) == BAN_VOID || GET_BAN_MAP_XY(((s1) + 15), ((s2) + 7)) == BAN_VOID) && (GET_BAN_MAP_XY((s1), ((s2) + 8)) == BAN_WATER || GET_BAN_MAP_XY(((s1) + 15), ((s2) + 8)) == BAN_WATER)
1215 
1216 
steer_players(void)1217 void steer_players(void)
1218 {
1219 	int c1, c2;
1220 	int s1 = 0, s2 = 0;
1221 
1222 	cpu_move();
1223 	update_player_actions();
1224 
1225 	for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1226 
1227 		if (player[c1].enabled == 1) {
1228 
1229 			if (player[c1].dead_flag == 0) {
1230 
1231 				if (player[c1].action_left && player[c1].action_right) {
1232 					if (player[c1].direction == 0) {
1233 						if (player[c1].action_right) {
1234 							player_action_right(c1);
1235 						}
1236 					} else {
1237 						if (player[c1].action_left) {
1238 							player_action_left(c1);
1239 						}
1240 					}
1241 				} else if (player[c1].action_left) {
1242 					player_action_left(c1);
1243 				} else if (player[c1].action_right) {
1244 					player_action_right(c1);
1245 				} else if ((!player[c1].action_left) && (!player[c1].action_right)) {
1246 					int below_left, below, below_right;
1247 
1248 					s1 = (player[c1].x >> 16);
1249 					s2 = (player[c1].y >> 16);
1250 					below_left = GET_BAN_MAP_XY(s1, s2 + 16);
1251 					below = GET_BAN_MAP_XY(s1 + 8, s2 + 16);
1252 					below_right = GET_BAN_MAP_XY(s1 + 15, s2 + 16);
1253 					if (below == BAN_SOLID || below == BAN_SPRING || (((below_left == BAN_SOLID || below_left == BAN_SPRING) && below_right != BAN_ICE) || (below_left != BAN_ICE && (below_right == BAN_SOLID || below_right == BAN_SPRING)))) {
1254 						if (player[c1].x_add < 0) {
1255 							player[c1].x_add += 16384;
1256 							if (player[c1].x_add > 0)
1257 								player[c1].x_add = 0;
1258 						} else {
1259 							player[c1].x_add -= 16384;
1260 							if (player[c1].x_add < 0)
1261 								player[c1].x_add = 0;
1262 						}
1263 						if (player[c1].x_add != 0 && GET_BAN_MAP_XY((s1 + 8), (s2 + 16)) == BAN_SOLID)
1264 							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);
1265 					}
1266 					if (player[c1].anim == 1) {
1267 						player[c1].anim = 0;
1268 						player[c1].frame = 0;
1269 						player[c1].frame_tick = 0;
1270 						player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1271 					}
1272 				}
1273 				if (jetpack == 0) {
1274 					/* no jetpack */
1275 					if (pogostick == 1 || (player[c1].jump_ready == 1 && player[c1].action_up)) {
1276 						s1 = (player[c1].x >> 16);
1277 						s2 = (player[c1].y >> 16);
1278 						if (s2 < -16)
1279 							s2 = -16;
1280 						/* jump */
1281 						if (GET_BAN_MAP_XY(s1, (s2 + 16)) == BAN_SOLID || GET_BAN_MAP_XY(s1, (s2 + 16)) == BAN_ICE || GET_BAN_MAP_XY((s1 + 15), (s2 + 16)) == BAN_SOLID || GET_BAN_MAP_XY((s1 + 15), (s2 + 16)) == BAN_ICE) {
1282 							player[c1].y_add = -280000L;
1283 							player[c1].anim = 2;
1284 							player[c1].frame = 0;
1285 							player[c1].frame_tick = 0;
1286 							player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1287 							player[c1].jump_ready = 0;
1288 							player[c1].jump_abort = 1;
1289 							if (pogostick == 0)
1290 								dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1291 							else
1292 								dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1293 						}
1294 						/* jump out of water */
1295 						if (GET_BAN_MAP_IN_WATER(s1, s2)) {
1296 							player[c1].y_add = -196608L;
1297 							player[c1].in_water = 0;
1298 							player[c1].anim = 2;
1299 							player[c1].frame = 0;
1300 							player[c1].frame_tick = 0;
1301 							player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1302 							player[c1].jump_ready = 0;
1303 							player[c1].jump_abort = 1;
1304 							if (pogostick == 0)
1305 								dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1306 							else
1307 								dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1308 						}
1309 					}
1310 					/* fall down by gravity */
1311 					if (pogostick == 0 && (!player[c1].action_up)) {
1312 						player[c1].jump_ready = 1;
1313 						if (player[c1].in_water == 0 && player[c1].y_add < 0 && player[c1].jump_abort == 1) {
1314 							if (bunnies_in_space == 0)
1315 								/* normal gravity */
1316 								player[c1].y_add += 32768;
1317 							else
1318 								/* light gravity */
1319 								player[c1].y_add += 16384;
1320 							if (player[c1].y_add > 0)
1321 								player[c1].y_add = 0;
1322 						}
1323 					}
1324 				} else {
1325 					/* with jetpack */
1326 					if (player[c1].action_up) {
1327 						player[c1].y_add -= 16384;
1328 						if (player[c1].y_add < -400000L)
1329 							player[c1].y_add = -400000L;
1330 						if (GET_BAN_MAP_IN_WATER(s1, s2))
1331 							player[c1].in_water = 0;
1332 						if (rnd(100) < 50)
1333 							add_object(OBJ_SMOKE, (player[c1].x >> 16) + 6 + rnd(5), (player[c1].y >> 16) + 10 + rnd(5), 0, 16384 + rnd(8192), OBJ_ANIM_SMOKE, 0);
1334 					}
1335 				}
1336 
1337 				player[c1].x += player[c1].x_add;
1338 				if ((player[c1].x >> 16) < 0) {
1339 					player[c1].x = 0;
1340 					player[c1].x_add = 0;
1341 				}
1342 				if ((player[c1].x >> 16) + 15 > 351) {
1343 					player[c1].x = 336L << 16;
1344 					player[c1].x_add = 0;
1345 				}
1346 				{
1347 					if (player[c1].y > 0) {
1348 						s2 = (player[c1].y >> 16);
1349 					} else {
1350 						/* check top line only */
1351 						s2 = 0;
1352 					}
1353 
1354 					s1 = (player[c1].x >> 16);
1355 					if (GET_BAN_MAP_XY(s1, s2) == BAN_SOLID || GET_BAN_MAP_XY(s1, s2) == BAN_ICE || GET_BAN_MAP_XY(s1, s2) == BAN_SPRING || GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_SOLID || GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_ICE || GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_SPRING) {
1356 						player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1357 						player[c1].x_add = 0;
1358 					}
1359 
1360 					s1 = (player[c1].x >> 16);
1361 					if (GET_BAN_MAP_XY((s1 + 15), s2) == BAN_SOLID || GET_BAN_MAP_XY((s1 + 15), s2) == BAN_ICE || GET_BAN_MAP_XY((s1 + 15), s2) == BAN_SPRING || GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_SOLID || GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_ICE || GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_SPRING) {
1362 						player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1363 						player[c1].x_add = 0;
1364 					}
1365 				}
1366 
1367 				player[c1].y += player[c1].y_add;
1368 
1369 				s1 = (player[c1].x >> 16);
1370 				s2 = (player[c1].y >> 16);
1371 				if (s2 < 0)
1372 					s2 = 0;
1373 				if (GET_BAN_MAP_XY((s1 + 8), (s2 + 15)) == BAN_SPRING || ((GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_SPRING && GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) != BAN_SOLID) || (GET_BAN_MAP_XY(s1, (s2 + 15)) != BAN_SOLID && GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_SPRING))) {
1374 					player[c1].y = ((player[c1].y >> 16) & 0xfff0) << 16;
1375 					player[c1].y_add = -400000L;
1376 					player[c1].anim = 2;
1377 					player[c1].frame = 0;
1378 					player[c1].frame_tick = 0;
1379 					player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1380 					player[c1].jump_ready = 0;
1381 					player[c1].jump_abort = 0;
1382 					for (c2 = 0; c2 < NUM_OBJECTS; c2++) {
1383 						if (objects[c2].used == 1 && objects[c2].type == OBJ_SPRING) {
1384 							if (GET_BAN_MAP_XY((s1 + 8), (s2 + 15)) == BAN_SPRING) {
1385 								if ((objects[c2].x >> 20) == ((s1 + 8) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1386 									objects[c2].frame = 0;
1387 									objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1388 									objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1389 									break;
1390 								}
1391 							} else {
1392 								if (GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_SPRING) {
1393 									if ((objects[c2].x >> 20) == (s1 >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1394 										objects[c2].frame = 0;
1395 										objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1396 										objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1397 										break;
1398 									}
1399 								} else if (GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_SPRING) {
1400 									if ((objects[c2].x >> 20) == ((s1 + 15) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1401 										objects[c2].frame = 0;
1402 										objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1403 										objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1404 										break;
1405 									}
1406 								}
1407 							}
1408 						}
1409 					}
1410 					dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1411 				}
1412 				s1 = (player[c1].x >> 16);
1413 				s2 = (player[c1].y >> 16);
1414 				if (s2 < 0)
1415 					s2 = 0;
1416 				if (GET_BAN_MAP_XY(s1, s2) == BAN_SOLID || GET_BAN_MAP_XY(s1, s2) == BAN_ICE || GET_BAN_MAP_XY(s1, s2) == BAN_SPRING || GET_BAN_MAP_XY((s1 + 15), s2) == BAN_SOLID || GET_BAN_MAP_XY((s1 + 15), s2) == BAN_ICE || GET_BAN_MAP_XY((s1 + 15), s2) == BAN_SPRING) {
1417 					player[c1].y = (((s2 + 16) & 0xfff0)) << 16;
1418 					player[c1].y_add = 0;
1419 					player[c1].anim = 0;
1420 					player[c1].frame = 0;
1421 					player[c1].frame_tick = 0;
1422 					player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1423 				}
1424 				s1 = (player[c1].x >> 16);
1425 				s2 = (player[c1].y >> 16);
1426 				if (s2 < 0)
1427 					s2 = 0;
1428 				if (GET_BAN_MAP_XY((s1 + 8), (s2 + 8)) == BAN_WATER) {
1429 					if (player[c1].in_water == 0) {
1430 						/* falling into water */
1431 						player[c1].in_water = 1;
1432 						player[c1].anim = 4;
1433 						player[c1].frame = 0;
1434 						player[c1].frame_tick = 0;
1435 						player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1436 						if (player[c1].y_add >= 32768) {
1437 							add_object(OBJ_SPLASH, (player[c1].x >> 16) + 8, ((player[c1].y >> 16) & 0xfff0) + 15, 0, 0, OBJ_ANIM_SPLASH, 0);
1438 							if (blood_is_thicker_than_water == 0)
1439 								dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1440 							else
1441 								dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 5000), 64, 0, 0, -1);
1442 						}
1443 					}
1444 					/* slowly move up to water surface */
1445 					player[c1].y_add -= 1536;
1446 					if (player[c1].y_add < 0 && player[c1].anim != 5) {
1447 						player[c1].anim = 5;
1448 						player[c1].frame = 0;
1449 						player[c1].frame_tick = 0;
1450 						player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1451 					}
1452 					if (player[c1].y_add < -65536L)
1453 						player[c1].y_add = -65536L;
1454 					if (player[c1].y_add > 65535L)
1455 						player[c1].y_add = 65535L;
1456 					if (GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_SOLID || GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_ICE || GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_SOLID || GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_ICE) {
1457 						player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1458 						player[c1].y_add = 0;
1459 					}
1460 				} else if (GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_SOLID || GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_ICE || GET_BAN_MAP_XY(s1, (s2 + 15)) == BAN_SPRING || GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_SOLID || GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_ICE || GET_BAN_MAP_XY((s1 + 15), (s2 + 15)) == BAN_SPRING) {
1461 					player[c1].in_water = 0;
1462 					player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1463 					player[c1].y_add = 0;
1464 					if (player[c1].anim != 0 && player[c1].anim != 1) {
1465 						player[c1].anim = 0;
1466 						player[c1].frame = 0;
1467 						player[c1].frame_tick = 0;
1468 						player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1469 					}
1470 				} else {
1471 					if (player[c1].in_water == 0) {
1472 						if (bunnies_in_space == 0)
1473 							player[c1].y_add += 12288;
1474 						else
1475 							player[c1].y_add += 6144;
1476 						if (player[c1].y_add > 327680L)
1477 							player[c1].y_add = 327680L;
1478 					} else {
1479 						player[c1].y = (player[c1].y & 0xffff0000) + 0x10000;
1480 						player[c1].y_add = 0;
1481 					}
1482 					player[c1].in_water = 0;
1483 				}
1484 				if (player[c1].y_add > 36864 && player[c1].anim != 3 && player[c1].in_water == 0) {
1485 					player[c1].anim = 3;
1486 					player[c1].frame = 0;
1487 					player[c1].frame_tick = 0;
1488 					player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1489 				}
1490 
1491 			}
1492 
1493 			player[c1].frame_tick++;
1494 			if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
1495 				player[c1].frame++;
1496 				if (player[c1].frame >= player_anims[player[c1].anim].num_frames) {
1497 					if (player[c1].anim != 6)
1498 						player[c1].frame = player_anims[player[c1].anim].restart_frame;
1499 					else
1500 						position_player(c1);
1501 				}
1502 				player[c1].frame_tick = 0;
1503 			}
1504 			player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1505 
1506 		}
1507 
1508 	}
1509 
1510 }
1511 
1512 
position_player(int player_num)1513 void position_player(int player_num)
1514 {
1515 	int c1;
1516 	int s1, s2;
1517 
1518 	while (1) {
1519 		while (1) {
1520 			s1 = rnd(22);
1521 			s2 = rnd(16);
1522 			if (ban_map[s2][s1] == BAN_VOID && (ban_map[s2 + 1][s1] == BAN_SOLID || ban_map[s2 + 1][s1] == BAN_ICE))
1523 				break;
1524 		}
1525 		for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1526 			if (c1 != player_num && player[c1].enabled == 1) {
1527 				if (abs((s1 << 4) - (player[c1].x >> 16)) < 32 && abs((s2 << 4) - (player[c1].y >> 16)) < 32)
1528 					break;
1529 			}
1530 		}
1531 		if (c1 == JNB_MAX_PLAYERS) {
1532 			player[player_num].x = (long) s1 << 20;
1533 			player[player_num].y = (long) s2 << 20;
1534 			player[player_num].x_add = player[player_num].y_add = 0;
1535 			player[player_num].direction = 0;
1536 			player[player_num].jump_ready = 1;
1537 			player[player_num].in_water = 0;
1538 			player[player_num].anim = 0;
1539 			player[player_num].frame = 0;
1540 			player[player_num].frame_tick = 0;
1541 			player[player_num].image = player_anims[player[player_num].anim].frame[player[player_num].frame].image;
1542 
1543 			if (is_server) {
1544 #ifdef USE_NET
1545 				if (is_net)
1546 					serverSendAlive(player_num);
1547 #endif
1548 				player[player_num].dead_flag = 0;
1549 			}
1550 
1551 			break;
1552 		}
1553 	}
1554 
1555 }
1556 
1557 
add_object(int type,int x,int y,int x_add,int y_add,int anim,int frame)1558 void add_object(int type, int x, int y, int x_add, int y_add, int anim, int frame)
1559 {
1560 	int c1;
1561 
1562 	for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
1563 		if (objects[c1].used == 0) {
1564 			objects[c1].used = 1;
1565 			objects[c1].type = type;
1566 			objects[c1].x = (long) x << 16;
1567 			objects[c1].y = (long) y << 16;
1568 			objects[c1].x_add = x_add;
1569 			objects[c1].y_add = y_add;
1570 			objects[c1].x_acc = 0;
1571 			objects[c1].y_acc = 0;
1572 			objects[c1].anim = anim;
1573 			objects[c1].frame = frame;
1574 			objects[c1].ticks = object_anims[anim].frame[frame].ticks;
1575 			objects[c1].image = object_anims[anim].frame[frame].image;
1576 			break;
1577 		}
1578 	}
1579 
1580 }
1581 
1582 
update_objects(void)1583 void update_objects(void)
1584 {
1585 	int c1;
1586 	int s1 = 0;
1587 
1588 	for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
1589 		if (objects[c1].used == 1) {
1590 			switch (objects[c1].type) {
1591 			case OBJ_SPRING:
1592 				objects[c1].ticks--;
1593 				if (objects[c1].ticks <= 0) {
1594 					objects[c1].frame++;
1595 					if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames) {
1596 						objects[c1].frame--;
1597 						objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1598 					} else {
1599 						objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1600 						objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1601 					}
1602 				}
1603 				if (objects[c1].used == 1)
1604 					add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1605 				break;
1606 			case OBJ_SPLASH:
1607 				objects[c1].ticks--;
1608 				if (objects[c1].ticks <= 0) {
1609 					objects[c1].frame++;
1610 					if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1611 						objects[c1].used = 0;
1612 					else {
1613 						objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1614 						objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1615 					}
1616 				}
1617 				if (objects[c1].used == 1)
1618 					add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1619 				break;
1620 			case OBJ_SMOKE:
1621 				objects[c1].x += objects[c1].x_add;
1622 				objects[c1].y += objects[c1].y_add;
1623 				objects[c1].ticks--;
1624 				if (objects[c1].ticks <= 0) {
1625 					objects[c1].frame++;
1626 					if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1627 						objects[c1].used = 0;
1628 					else {
1629 						objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1630 						objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1631 					}
1632 				}
1633 				if (objects[c1].used == 1)
1634 					add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1635 				break;
1636 			case OBJ_YEL_BUTFLY:
1637 			case OBJ_PINK_BUTFLY:
1638 				objects[c1].x_acc += rnd(128) - 64;
1639 				if (objects[c1].x_acc < -1024)
1640 					objects[c1].x_acc = -1024;
1641 				if (objects[c1].x_acc > 1024)
1642 					objects[c1].x_acc = 1024;
1643 				objects[c1].x_add += objects[c1].x_acc;
1644 				if (objects[c1].x_add < -32768)
1645 					objects[c1].x_add = -32768;
1646 				if (objects[c1].x_add > 32768)
1647 					objects[c1].x_add = 32768;
1648 				objects[c1].x += objects[c1].x_add;
1649 				if ((objects[c1].x >> 16) < 16) {
1650 					objects[c1].x = 16 << 16;
1651 					objects[c1].x_add = -objects[c1].x_add >> 2;
1652 					objects[c1].x_acc = 0;
1653 				} else if ((objects[c1].x >> 16) > 350) {
1654 					objects[c1].x = 350 << 16;
1655 					objects[c1].x_add = -objects[c1].x_add >> 2;
1656 					objects[c1].x_acc = 0;
1657 				}
1658 				if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
1659 					if (objects[c1].x_add < 0) {
1660 						objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
1661 					} else {
1662 						objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
1663 					}
1664 					objects[c1].x_add = -objects[c1].x_add >> 2;
1665 					objects[c1].x_acc = 0;
1666 				}
1667 				objects[c1].y_acc += rnd(64) - 32;
1668 				if (objects[c1].y_acc < -1024)
1669 					objects[c1].y_acc = -1024;
1670 				if (objects[c1].y_acc > 1024)
1671 					objects[c1].y_acc = 1024;
1672 				objects[c1].y_add += objects[c1].y_acc;
1673 				if (objects[c1].y_add < -32768)
1674 					objects[c1].y_add = -32768;
1675 				if (objects[c1].y_add > 32768)
1676 					objects[c1].y_add = 32768;
1677 				objects[c1].y += objects[c1].y_add;
1678 				if ((objects[c1].y >> 16) < 0) {
1679 					objects[c1].y = 0;
1680 					objects[c1].y_add = -objects[c1].y_add >> 2;
1681 					objects[c1].y_acc = 0;
1682 				} else if ((objects[c1].y >> 16) > 255) {
1683 					objects[c1].y = 255 << 16;
1684 					objects[c1].y_add = -objects[c1].y_add >> 2;
1685 					objects[c1].y_acc = 0;
1686 				}
1687 				if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
1688 					if (objects[c1].y_add < 0) {
1689 						objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
1690 					} else {
1691 						objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1692 					}
1693 					objects[c1].y_add = -objects[c1].y_add >> 2;
1694 					objects[c1].y_acc = 0;
1695 				}
1696 				if (objects[c1].type == OBJ_YEL_BUTFLY) {
1697 					if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_LEFT) {
1698 						objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_LEFT;
1699 						objects[c1].frame = 0;
1700 						objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1701 						objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1702 					} else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_RIGHT) {
1703 						objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_RIGHT;
1704 						objects[c1].frame = 0;
1705 						objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1706 						objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1707 					}
1708 				} else {
1709 					if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_LEFT) {
1710 						objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_LEFT;
1711 						objects[c1].frame = 0;
1712 						objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1713 						objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1714 					} else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_RIGHT) {
1715 						objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_RIGHT;
1716 						objects[c1].frame = 0;
1717 						objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1718 						objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1719 					}
1720 				}
1721 				objects[c1].ticks--;
1722 				if (objects[c1].ticks <= 0) {
1723 					objects[c1].frame++;
1724 					if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1725 						objects[c1].frame = object_anims[objects[c1].anim].restart_frame;
1726 					else {
1727 						objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1728 						objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1729 					}
1730 				}
1731 				if (objects[c1].used == 1)
1732 					add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1733 				break;
1734 			case OBJ_FUR:
1735 				if (rnd(100) < 30)
1736 					add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 0);
1737 				if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
1738 					objects[c1].y_add += 3072;
1739 					if (objects[c1].y_add > 196608L)
1740 						objects[c1].y_add = 196608L;
1741 				} else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
1742 					if (objects[c1].x_add < 0) {
1743 						if (objects[c1].x_add < -65536L)
1744 							objects[c1].x_add = -65536L;
1745 						objects[c1].x_add += 1024;
1746 						if (objects[c1].x_add > 0)
1747 							objects[c1].x_add = 0;
1748 					} else {
1749 						if (objects[c1].x_add > 65536L)
1750 							objects[c1].x_add = 65536L;
1751 						objects[c1].x_add -= 1024;
1752 						if (objects[c1].x_add < 0)
1753 							objects[c1].x_add = 0;
1754 					}
1755 					objects[c1].y_add += 1024;
1756 					if (objects[c1].y_add < -65536L)
1757 						objects[c1].y_add = -65536L;
1758 					if (objects[c1].y_add > 65536L)
1759 						objects[c1].y_add = 65536L;
1760 				}
1761 				objects[c1].x += objects[c1].x_add;
1762 				if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1 || ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3)) {
1763 					if (objects[c1].x_add < 0) {
1764 						objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
1765 						objects[c1].x_add = -objects[c1].x_add >> 2;
1766 					} else {
1767 						objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
1768 						objects[c1].x_add = -objects[c1].x_add >> 2;
1769 					}
1770 				}
1771 				objects[c1].y += objects[c1].y_add;
1772 				if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
1773 					objects[c1].used = 0;
1774 				if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
1775 					if (objects[c1].y_add < 0) {
1776 						if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
1777 							objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
1778 							objects[c1].x_add >>= 2;
1779 							objects[c1].y_add = -objects[c1].y_add >> 2;
1780 						}
1781 					} else {
1782 						if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
1783 							if (objects[c1].y_add > 131072L) {
1784 								objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1785 								objects[c1].x_add >>= 2;
1786 								objects[c1].y_add = -objects[c1].y_add >> 2;
1787 							} else
1788 								objects[c1].used = 0;
1789 						} else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
1790 							objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1791 							if (objects[c1].y_add > 131072L)
1792 								objects[c1].y_add = -objects[c1].y_add >> 2;
1793 							else
1794 								objects[c1].y_add = 0;
1795 						}
1796 					}
1797 				}
1798 				if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
1799 					objects[c1].x_add = -16384;
1800 				if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
1801 					objects[c1].x_add = 16384;
1802 				if (objects[c1].used == 1) {
1803 					s1 = (int)(atan2(objects[c1].y_add, objects[c1].x_add) * 4 / M_PI);
1804 					if (s1 < 0)
1805 						s1 += 8;
1806 					if (s1 < 0)
1807 						s1 = 0;
1808 					if (s1 > 7)
1809 						s1 = 7;
1810 					add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame + s1, &object_gobs);
1811 				}
1812 				break;
1813 			case OBJ_FLESH:
1814 				if (rnd(100) < 30) {
1815 					if (objects[c1].frame == 76)
1816 						add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 1);
1817 					else if (objects[c1].frame == 77)
1818 						add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 2);
1819 					else if (objects[c1].frame == 78)
1820 						add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 3);
1821 				}
1822 				if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
1823 					objects[c1].y_add += 3072;
1824 					if (objects[c1].y_add > 196608L)
1825 						objects[c1].y_add = 196608L;
1826 				} else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
1827 					if (objects[c1].x_add < 0) {
1828 						if (objects[c1].x_add < -65536L)
1829 							objects[c1].x_add = -65536L;
1830 						objects[c1].x_add += 1024;
1831 						if (objects[c1].x_add > 0)
1832 							objects[c1].x_add = 0;
1833 					} else {
1834 						if (objects[c1].x_add > 65536L)
1835 							objects[c1].x_add = 65536L;
1836 						objects[c1].x_add -= 1024;
1837 						if (objects[c1].x_add < 0)
1838 							objects[c1].x_add = 0;
1839 					}
1840 					objects[c1].y_add += 1024;
1841 					if (objects[c1].y_add < -65536L)
1842 						objects[c1].y_add = -65536L;
1843 					if (objects[c1].y_add > 65536L)
1844 						objects[c1].y_add = 65536L;
1845 				}
1846 				objects[c1].x += objects[c1].x_add;
1847 				if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1 || ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3)) {
1848 					if (objects[c1].x_add < 0) {
1849 						objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
1850 						objects[c1].x_add = -objects[c1].x_add >> 2;
1851 					} else {
1852 						objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
1853 						objects[c1].x_add = -objects[c1].x_add >> 2;
1854 					}
1855 				}
1856 				objects[c1].y += objects[c1].y_add;
1857 				if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
1858 					objects[c1].used = 0;
1859 				if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
1860 					if (objects[c1].y_add < 0) {
1861 						if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
1862 							objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
1863 							objects[c1].x_add >>= 2;
1864 							objects[c1].y_add = -objects[c1].y_add >> 2;
1865 						}
1866 					} else {
1867 						if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
1868 							if (objects[c1].y_add > 131072L) {
1869 								objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1870 								objects[c1].x_add >>= 2;
1871 								objects[c1].y_add = -objects[c1].y_add >> 2;
1872 							} else {
1873 								if (rnd(100) < 10) {
1874 									s1 = rnd(4) - 2;
1875 									add_leftovers(0, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
1876 									add_leftovers(1, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
1877 								}
1878 								objects[c1].used = 0;
1879 							}
1880 						} else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
1881 							objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1882 							if (objects[c1].y_add > 131072L)
1883 								objects[c1].y_add = -objects[c1].y_add >> 2;
1884 							else
1885 								objects[c1].y_add = 0;
1886 						}
1887 					}
1888 				}
1889 				if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
1890 					objects[c1].x_add = -16384;
1891 				if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
1892 					objects[c1].x_add = 16384;
1893 				if (objects[c1].used == 1)
1894 					add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame, &object_gobs);
1895 				break;
1896 			case OBJ_FLESH_TRACE:
1897 				objects[c1].ticks--;
1898 				if (objects[c1].ticks <= 0) {
1899 					objects[c1].frame++;
1900 					if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1901 						objects[c1].used = 0;
1902 					else {
1903 						objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1904 						objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1905 					}
1906 				}
1907 				if (objects[c1].used == 1)
1908 					add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1909 				break;
1910 			}
1911 		}
1912 	}
1913 
1914 }
1915 
1916 
add_pob(int page,int x,int y,int image,gob_t * pob_data)1917 int add_pob(int page, int x, int y, int image, gob_t *pob_data)
1918 {
1919 
1920 	if (main_info.page_info[page].num_pobs >= NUM_POBS)
1921 		return 1;
1922 
1923 	main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].x = x;
1924 	main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].y = y;
1925 	main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].image = image;
1926 	main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].pob_data = pob_data;
1927 	main_info.page_info[page].num_pobs++;
1928 
1929 	return 0;
1930 
1931 }
1932 
1933 
draw_flies(int page)1934 void draw_flies(int page)
1935 {
1936 	int c2;
1937 
1938 	for (c2 = 0; c2 < NUM_FLIES; c2++) {
1939 		flies[c2].back[main_info.draw_page] = get_pixel(main_info.draw_page, flies[c2].x, flies[c2].y);
1940 		flies[c2].back_defined[main_info.draw_page] = 1;
1941 		if (mask_pic[(flies[c2].y * JNB_WIDTH) + flies[c2].x] == 0)
1942 			set_pixel(main_info.draw_page, flies[c2].x, flies[c2].y, 0);
1943 	}
1944 }
1945 
draw_pobs(int page)1946 void draw_pobs(int page)
1947 {
1948 	int c1;
1949 	int back_buf_ofs;
1950 
1951 	back_buf_ofs = 0;
1952 
1953 	for (c1 = main_info.page_info[page].num_pobs - 1; c1 >= 0; c1--) {
1954 		main_info.page_info[page].pobs[c1].back_buf_ofs = back_buf_ofs;
1955 		get_block(page, main_info.page_info[page].pobs[c1].x - pob_hs_x(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), main_info.page_info[page].pobs[c1].y - pob_hs_y(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), pob_width(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), pob_height(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), (unsigned char *)main_info.pob_backbuf[page] + back_buf_ofs);
1956 		if (scale_up)
1957 			back_buf_ofs += pob_width(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data) * pob_height(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data) * 4;
1958 		else
1959 			back_buf_ofs += pob_width(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data) * pob_height(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data);
1960 		put_pob(page, main_info.page_info[page].pobs[c1].x, main_info.page_info[page].pobs[c1].y, main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data, 1, mask_pic);
1961 	}
1962 
1963 }
1964 
1965 
redraw_flies_background(int page)1966 void redraw_flies_background(int page)
1967 {
1968 	int c2;
1969 
1970 	for (c2 = NUM_FLIES - 1; c2 >= 0; c2--) {
1971 		if (flies[c2].back_defined[page] == 1)
1972 			set_pixel(page, flies[c2].old_draw_x, flies[c2].old_draw_y, flies[c2].back[page]);
1973 		flies[c2].old_draw_x = flies[c2].x;
1974 		flies[c2].old_draw_y = flies[c2].y;
1975 	}
1976 }
1977 
1978 
redraw_pob_backgrounds(int page)1979 void redraw_pob_backgrounds(int page)
1980 {
1981 	int c1;
1982 
1983 	for (c1 = 0; c1 < main_info.page_info[page].num_pobs; c1++)
1984 		put_block(page, main_info.page_info[page].pobs[c1].x - pob_hs_x(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), main_info.page_info[page].pobs[c1].y - pob_hs_y(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), pob_width(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), pob_height(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), (unsigned char *)main_info.pob_backbuf[page] + main_info.page_info[page].pobs[c1].back_buf_ofs);
1985 
1986 }
1987 
1988 
add_leftovers(int page,int x,int y,int image,gob_t * pob_data)1989 int add_leftovers(int page, int x, int y, int image, gob_t *pob_data)
1990 {
1991 
1992 	if (leftovers.page[page].num_pobs >= NUM_LEFTOVERS)
1993 		return 1;
1994 
1995 	leftovers.page[page].pobs[leftovers.page[page].num_pobs].x = x;
1996 	leftovers.page[page].pobs[leftovers.page[page].num_pobs].y = y;
1997 	leftovers.page[page].pobs[leftovers.page[page].num_pobs].image = image;
1998 	leftovers.page[page].pobs[leftovers.page[page].num_pobs].pob_data = pob_data;
1999 	leftovers.page[page].num_pobs++;
2000 
2001 	return 0;
2002 
2003 }
2004 
2005 
draw_leftovers(int page)2006 void draw_leftovers(int page)
2007 {
2008 	int c1;
2009 
2010 	for (c1 = leftovers.page[page].num_pobs - 1; c1 >= 0; c1--)
2011 		put_pob(page, leftovers.page[page].pobs[c1].x, leftovers.page[page].pobs[c1].y, leftovers.page[page].pobs[c1].image, leftovers.page[page].pobs[c1].pob_data, 1, mask_pic);
2012 
2013 	leftovers.page[page].num_pobs = 0;
2014 
2015 }
2016 
2017 
init_level(int level,char * pal)2018 int init_level(int level, char *pal)
2019 {
2020 	unsigned char *handle;
2021 	int c1, c2;
2022 	int s1, s2;
2023 
2024 	if ((handle = dat_open("level.pcx")) == 0) {
2025 		strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2026 		return 1;
2027 	}
2028 	if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
2029 		strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2030 		return 1;
2031 	}
2032 	if (flip)
2033 		flip_pixels(background_pic);
2034 	if ((handle = dat_open("mask.pcx")) == 0) {
2035 		strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2036 		return 1;
2037 	}
2038 	if (read_pcx(handle, mask_pic, JNB_WIDTH*JNB_HEIGHT, 0) != 0) {
2039 		strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2040 		return 1;
2041 	}
2042 	if (flip)
2043 		flip_pixels(mask_pic);
2044 	register_mask(mask_pic);
2045 
2046 	for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
2047 		if (player[c1].enabled == 1) {
2048 			player[c1].bumps = 0;
2049 			for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++)
2050 				player[c1].bumped[c2] = 0;
2051 			position_player(c1);
2052 			add_leftovers(0, 360, 34 + c1 * 64, 0, &number_gobs);
2053 			add_leftovers(1, 360, 34 + c1 * 64, 0, &number_gobs);
2054 			add_leftovers(0, 376, 34 + c1 * 64, 0, &number_gobs);
2055 			add_leftovers(1, 376, 34 + c1 * 64, 0, &number_gobs);
2056 		}
2057 	}
2058 
2059 	for (c1 = 0; c1 < NUM_OBJECTS; c1++)
2060 		objects[c1].used = 0;
2061 
2062 	for (c1 = 0; c1 < 16; c1++) {
2063 		for (c2 = 0; c2 < 22; c2++) {
2064 			if (ban_map[c1][c2] == BAN_SPRING)
2065 				add_object(OBJ_SPRING, c2 << 4, c1 << 4, 0, 0, OBJ_ANIM_SPRING, 5);
2066 		}
2067 	}
2068 
2069 	while (1) {
2070 		s1 = rnd(22);
2071 		s2 = rnd(16);
2072 		if (ban_map[s2][s1] == BAN_VOID) {
2073 			add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2074 			break;
2075 		}
2076 	}
2077 	while (1) {
2078 		s1 = rnd(22);
2079 		s2 = rnd(16);
2080 		if (ban_map[s2][s1] == BAN_VOID) {
2081 			add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2082 			break;
2083 		}
2084 	}
2085 	while (1) {
2086 		s1 = rnd(22);
2087 		s2 = rnd(16);
2088 		if (ban_map[s2][s1] == BAN_VOID) {
2089 			add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2090 			break;
2091 		}
2092 	}
2093 	while (1) {
2094 		s1 = rnd(22);
2095 		s2 = rnd(16);
2096 		if (ban_map[s2][s1] == BAN_VOID) {
2097 			add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2098 			break;
2099 		}
2100 	}
2101 
2102 	return 0;
2103 
2104 }
2105 
2106 
deinit_level(void)2107 void deinit_level(void)
2108 {
2109 	dj_set_nosound(1);
2110 	dj_stop_mod();
2111 }
2112 
2113 
2114 #ifndef PATH_MAX
2115 #define PATH_MAX 1024
2116 #endif
2117 #ifndef O_BINARY
2118 #define O_BINARY 0
2119 #endif
2120 
2121 unsigned char *datafile_buffer = NULL;
2122 
preread_datafile(const char * fname)2123 static void preread_datafile(const char *fname)
2124 {
2125     int fd = 0;
2126     int len;
2127 
2128 #ifdef ZLIB_SUPPORT
2129     char *gzfilename;
2130     gzFile gzf;
2131 #endif
2132 
2133 #ifdef BZLIB_SUPPORT
2134     char *bzfilename;
2135     BZFILE *bzf;
2136 #endif
2137 
2138 #ifdef BZLIB_SUPPORT
2139     bzfilename = malloc(strlen(fname) + 5);
2140     strcpy(bzfilename, fname);
2141     strcat(bzfilename, ".bz2");
2142     bzf = BZ2_bzopen(bzfilename, "rb");
2143     free(bzfilename);
2144     bzfilename = NULL;
2145 
2146     if (bzf != NULL) {
2147         int bufsize = 0;
2148         int bufpos = 0;
2149         int br;
2150         unsigned char *ptr;
2151         do {
2152             if (bufpos >= bufsize) {
2153                 bufsize += 1024 * 1024;
2154                 datafile_buffer = (unsigned char *) realloc(datafile_buffer, bufsize);
2155                 if (datafile_buffer == NULL) {
2156                     perror("realloc()");
2157                     exit(42);
2158                 }
2159             }
2160 
2161             br = BZ2_bzread(bzf, datafile_buffer + bufpos, bufsize - bufpos);
2162             if (br == -1) {
2163                 fprintf(stderr, "gzread failed.\n");
2164                 exit(42);
2165             }
2166 
2167             bufpos += br;
2168         } while (br>0);
2169 
2170         /* try to shrink buffer... */
2171         ptr = (unsigned char *) realloc(datafile_buffer, bufpos);
2172         if (ptr != NULL)
2173             datafile_buffer = ptr;
2174 
2175         BZ2_bzclose(bzf);
2176         return;
2177     }
2178 
2179     /* drop through and try for an gzip compressed or uncompressed datafile... */
2180 #endif
2181 
2182 #ifdef ZLIB_SUPPORT
2183     gzfilename = malloc(strlen(fname) + 4);
2184     strcpy(gzfilename, fname);
2185     strcat(gzfilename, ".gz");
2186     gzf = gzopen(gzfilename, "rb");
2187     free(gzfilename);
2188     gzfilename = NULL;
2189 
2190     if (gzf != NULL) {
2191         int bufsize = 0;
2192         int bufpos = 0;
2193         unsigned char *ptr;
2194         do {
2195             int br;
2196             if (bufpos >= bufsize) {
2197                 bufsize += 1024 * 1024;
2198                 datafile_buffer = (unsigned char *) realloc(datafile_buffer, bufsize);
2199                 if (datafile_buffer == NULL) {
2200                     perror("realloc()");
2201                     exit(42);
2202                 }
2203             }
2204 
2205             br = gzread(gzf, datafile_buffer + bufpos, bufsize - bufpos);
2206             if (br == -1) {
2207                 fprintf(stderr, "gzread failed.\n");
2208                 exit(42);
2209             }
2210 
2211             bufpos += br;
2212         } while (!gzeof(gzf));
2213 
2214         /* try to shrink buffer... */
2215         ptr = (unsigned char *) realloc(datafile_buffer, bufpos);
2216         if (ptr != NULL)
2217             datafile_buffer = ptr;
2218 
2219         gzclose(gzf);
2220         return;
2221     }
2222 
2223     /* drop through and try for an uncompressed datafile... */
2224 #endif
2225 
2226     fd = open(fname, O_RDONLY | O_BINARY);
2227     if (fd == -1) {
2228         fprintf(stderr, "can't open %s:", fname);
2229 	perror("");
2230         exit(42);
2231     }
2232 
2233     len = filelength(fd);
2234     datafile_buffer = (unsigned char *) malloc(len);
2235     if (datafile_buffer == NULL) {
2236         perror("malloc()");
2237         close(fd);
2238         exit(42);
2239     }
2240 
2241     if (read(fd, datafile_buffer, len) != len) {
2242         perror("read()");
2243         close(fd);
2244         exit(42);
2245     }
2246 
2247     close(fd);
2248 }
2249 
2250 
init_program(int argc,char * argv[],char * pal)2251 int init_program(int argc, char *argv[], char *pal)
2252 {
2253 	char *netarg = NULL;
2254 	unsigned char *handle = (unsigned char *) NULL;
2255 	int c1 = 0, c2 = 0;
2256 	int load_flag = 0;
2257 	sfx_data fly;
2258 	int player_anim_data[] = {
2259 		1, 0, 0, 0x7fff, 0, 0, 0, 0, 0, 0,
2260 		4, 0, 0, 4, 1, 4, 2, 4, 3, 4,
2261 		1, 0, 4, 0x7fff, 0, 0, 0, 0, 0, 0,
2262 		4, 2, 5, 8, 6, 10, 7, 3, 6, 3,
2263 		1, 0, 6, 0x7fff, 0, 0, 0, 0, 0, 0,
2264 		2, 1, 5, 8, 4, 0x7fff, 0, 0, 0, 0,
2265 		1, 0, 8, 5, 0, 0, 0, 0, 0, 0
2266 	};
2267 
2268 #ifdef USE_NET
2269 	memset(&net_info, 0, sizeof(net_info));
2270 #endif
2271 
2272 #ifdef DOS
2273 	if (__djgpp_nearptr_enable() == 0)
2274 		return 1;
2275 #endif
2276 
2277 	srand(time(NULL));
2278 
2279 	if (hook_keyb_handler() != 0)
2280 		return 1;
2281 
2282 	memset(&main_info, 0, sizeof(main_info));
2283 
2284 	strcpy(datfile_name, DATA_PATH);
2285 
2286 	if (argc > 1) {
2287 		for (c1 = 1; c1 < argc; c1++) {
2288 			if (stricmp(argv[c1], "-nosound") == 0)
2289 				main_info.no_sound = 1;
2290 			else if (stricmp(argv[c1], "-musicnosound") == 0)
2291 				main_info.music_no_sound = 1;
2292 			else if (stricmp(argv[c1], "-nogore") == 0)
2293 				main_info.no_gore = 1;
2294 			else if (stricmp(argv[c1], "-noflies") == 0)
2295 				flies_enabled = 0;
2296 			else if (stricmp(argv[c1], "-nojoy") == 0)
2297 				main_info.joy_enabled = 0;
2298 #ifdef USE_SDL
2299 			else if (stricmp(argv[c1], "-fullscreen") == 0)
2300 				fs_toggle();
2301 #endif
2302 			else if (stricmp(argv[c1], "-scaleup") == 0)
2303 				set_scaling(1);
2304 			else if (stricmp(argv[c1], "-mirror") == 0)
2305 				flip = 1;
2306 			else if (stricmp(argv[c1], "-dat") == 0) {
2307 				if (c1 < (argc - 1)) {
2308 					FILE *f;
2309 
2310 					if ((f = fopen(argv[c1 + 1], "rb")) != NULL) {
2311 						fclose(f);
2312 						strcpy(datfile_name, argv[c1 + 1]);
2313 					}
2314 				}
2315 			} else if (stricmp(argv[c1], "-player") == 0) {
2316 				if (c1 < (argc - 1)) {
2317 					if (client_player_num < 0)
2318 						client_player_num = atoi(argv[c1 + 1]);
2319 				}
2320 #ifdef USE_NET
2321 			} else if (stricmp(argv[c1], "-server") == 0) {
2322 				if (c1 < (argc - 1)) {
2323 					is_server = 1;
2324 					is_net = 1;
2325 					netarg = argv[c1 + 1];
2326 				}
2327 			} else if (stricmp(argv[c1], "-connect") == 0) {
2328 				if (c1 < (argc - 1)) {
2329 					is_server = 0;
2330 					is_net = 1;
2331 					netarg = argv[c1 + 1];
2332 				}
2333 #endif
2334 			}
2335 			else if (strstr(argv[1],"-v")) {
2336 				printf("jumpnbump %s compiled with", JNB_VERSION);
2337 #ifndef USE_NET
2338 				printf("out");
2339 #endif
2340 				printf(" network support.\n");
2341 				return 1;
2342 			}
2343 			else if (strstr(argv[1],"-h")) {
2344 				printf("Usage: jumpnbump [OPTION]...\n");
2345 				printf("\n");
2346 				printf("  -h                       this help\n");
2347 				printf("  -v                       print version\n");
2348 				printf("  -dat level.dat           play a different level\n");
2349 #ifdef USE_NET
2350 				printf("  -server playercount      start as server waiting for players\n");
2351 				printf("  -connect host            connect to server\n");
2352 #endif
2353 				printf("  -player num              set main player to num (0-3). Needed for networking\n");
2354 				printf("  -fullscreen              run in fullscreen mode\n");
2355 				printf("  -nosound                 play without sound\n");
2356 				printf("  -nogore                  play without blood\n");
2357 				printf("  -noflies                 disable flies\n");
2358 				printf("  -mirror                  play with mirrored level\n");
2359 				printf("  -scaleup                 play with doubled resolution (800x512)\n");
2360 				printf("  -musicnosound            play with music but without sound\n");
2361 				printf("\n");
2362 				return 1;
2363 			}
2364 		}
2365 	}
2366 
2367 	preread_datafile(datfile_name);
2368 
2369 #if 0
2370 /** It should not be necessary to assign a default player number here. The
2371 server assigns one in init_server, the client gets one assigned by the server,
2372 all provided the user didn't choose one on the commandline. */
2373 	if (is_net) {
2374 		if (client_player_num < 0)
2375 		        client_player_num = 0;
2376 		player[client_player_num].enabled = 1;
2377 	}
2378 #endif
2379 
2380 	main_info.pob_backbuf[0] = malloc(screen_pitch*screen_height);
2381 	main_info.pob_backbuf[1] = malloc(screen_pitch*screen_height);
2382 
2383 	for (c1 = 0; c1 < 7; c1++) {
2384 		player_anims[c1].num_frames = player_anim_data[c1 * 10];
2385 		player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
2386 		for (c2 = 0; c2 < 4; c2++) {
2387 			player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
2388 			player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
2389 		}
2390 	}
2391 
2392 	if ((handle = dat_open("menu.pcx")) == 0) {
2393 		strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2394 		return 1;
2395 	}
2396 	if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
2397 		strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2398 		return 1;
2399 	}
2400 
2401 	if ((handle = dat_open("rabbit.gob")) == 0) {
2402 		strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
2403 		return 1;
2404 	}
2405 	if (register_gob(handle, &rabbit_gobs, dat_filelen("rabbit.gob"))) {
2406 		/* error */
2407 		return 1;
2408 	}
2409 
2410 	if ((handle = dat_open("objects.gob")) == 0) {
2411 		strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
2412 		return 1;
2413 	}
2414 	if (register_gob(handle, &object_gobs, dat_filelen("objects.gob"))) {
2415 		/* error */
2416 		return 1;
2417 	}
2418 
2419 	if ((handle = dat_open("font.gob")) == 0) {
2420 		strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
2421 		return 1;
2422 	}
2423 	if (register_gob(handle, &font_gobs, dat_filelen("font.gob"))) {
2424 		/* error */
2425 		return 1;
2426 	}
2427 
2428 	if ((handle = dat_open("numbers.gob")) == 0) {
2429 		strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
2430 		return 1;
2431 	}
2432 	if (register_gob(handle, &number_gobs, dat_filelen("numbers.gob"))) {
2433 		/* error */
2434 		return 1;
2435 	}
2436 
2437 	if (read_level() != 0) {
2438 		strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2439 		return 1;
2440 	}
2441 
2442 	dj_init();
2443 
2444 	if (main_info.no_sound == 0) {
2445 		dj_autodetect_sd();
2446 		dj_set_mixing_freq(20000);
2447 		dj_set_stereo(0);
2448 		dj_set_auto_mix(0);
2449 		dj_set_dma_time(8);
2450 		dj_set_num_sfx_channels(5);
2451 		dj_set_sfx_volume(64);
2452 		dj_set_nosound(1);
2453 		dj_start();
2454 
2455 		if ((handle = dat_open("jump.mod")) == 0) {
2456 			strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2457 			return 1;
2458 		}
2459 		if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
2460 			strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2461 			return 1;
2462 		}
2463 
2464 		if ((handle = dat_open("bump.mod")) == 0) {
2465 			strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2466 			return 1;
2467 		}
2468 		if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
2469 			strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2470 			return 1;
2471 		}
2472 
2473 		if ((handle = dat_open("scores.mod")) == 0) {
2474 			strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2475 			return 1;
2476 		}
2477 		if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
2478 			strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2479 			return 1;
2480 		}
2481 
2482 		if ((handle = dat_open("jump.smp")) == 0) {
2483 			strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2484 			return 1;
2485 		}
2486 		if (dj_load_sfx(handle, 0, dat_filelen("jump.smp"), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
2487 			strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2488 			return 1;
2489 		}
2490 
2491 		if ((handle = dat_open("death.smp")) == 0) {
2492 			strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2493 			return 1;
2494 		}
2495 		if (dj_load_sfx(handle, 0, dat_filelen("death.smp"), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
2496 			strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2497 			return 1;
2498 		}
2499 
2500 		if ((handle = dat_open("spring.smp")) == 0) {
2501 			strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2502 			return 1;
2503 		}
2504 		if (dj_load_sfx(handle, 0, dat_filelen("spring.smp"), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
2505 			strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2506 			return 1;
2507 		}
2508 
2509 		if ((handle = dat_open("splash.smp")) == 0) {
2510 			strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2511 			return 1;
2512 		}
2513 		if (dj_load_sfx(handle, 0, dat_filelen("splash.smp"), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
2514 			strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2515 			return 1;
2516 		}
2517 
2518 		if ((handle = dat_open("fly.smp")) == 0) {
2519 			strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2520 			return 1;
2521 		}
2522 		if (dj_load_sfx(handle, 0, dat_filelen("fly.smp"), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
2523 			strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2524 			return 1;
2525 		}
2526 
2527 		dj_get_sfx_settings(SFX_FLY, &fly);
2528 		fly.priority = 10;
2529 		fly.default_freq = SFX_FLY_FREQ;
2530 		fly.loop = 1;
2531 		fly.loop_start = 0;
2532 		fly.loop_length = fly.length;
2533 		dj_set_sfx_settings(SFX_FLY, &fly);
2534 	}
2535 
2536 	if ((background_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
2537 		return 1;
2538 	if ((mask_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
2539 		return 1;
2540 	memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
2541 	register_mask(mask_pic);
2542 
2543 	/* fix dark font */
2544 	for (c1 = 0; c1 < 16; c1++) {
2545 		pal[(240 + c1) * 3 + 0] = c1 << 2;
2546 		pal[(240 + c1) * 3 + 1] = c1 << 2;
2547 		pal[(240 + c1) * 3 + 2] = c1 << 2;
2548 	}
2549 
2550 	setpalette(0, 256, pal);
2551 
2552 	init_inputs();
2553 
2554 	recalculate_gob(&font_gobs, pal);
2555 
2556 	if (main_info.joy_enabled == 1) {
2557 		load_flag = 0;
2558 		put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2559 		put_text(0, 200, 100, "Move the joystick to the", 2);
2560 		put_text(0, 200, 115, "UPPER LEFT", 2);
2561 		put_text(0, 200, 130, "and press button A", 2);
2562 		put_text(0, 200, 200, "Or press ESC to use", 2);
2563 		put_text(0, 200, 215, "previous settings", 2);
2564 		if (calib_joy(0) != 0)
2565 			load_flag = 1;
2566 		else {
2567 			register_background(NULL, NULL);
2568 
2569 			main_info.view_page = 1;
2570 			flippage(1);
2571 
2572 			wait_vrt(0);
2573 
2574 			put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
2575 			put_text(1, 200, 100, "Move the joystick to the", 2);
2576 			put_text(1, 200, 115, "LOWER RIGHT", 2);
2577 			put_text(1, 200, 130, "and press button A", 2);
2578 			put_text(1, 200, 200, "Or press ESC to use", 2);
2579 			put_text(1, 200, 215, "previous settings", 2);
2580 			if (calib_joy(1) != 0)
2581 				load_flag = 1;
2582 			else {
2583 				register_background(NULL, NULL);
2584 				flippage(0);
2585 
2586 				wait_vrt(0);
2587 
2588 				put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2589 				put_text(0, 200, 100, "Move the joystick to the", 2);
2590 				put_text(0, 200, 115, "CENTER", 2);
2591 				put_text(0, 200, 130, "and press button A", 2);
2592 				put_text(0, 200, 200, "Or press ESC to use", 2);
2593 				put_text(0, 200, 215, "previous settings", 2);
2594 				if (calib_joy(2) != 0)
2595 					load_flag = 1;
2596 				else {
2597 					if (joy.calib_data.x1 == joy.calib_data.x2)
2598 						joy.calib_data.x1 -= 10;
2599 					if (joy.calib_data.x3 == joy.calib_data.x2)
2600 						joy.calib_data.x3 += 10;
2601 					if (joy.calib_data.y1 == joy.calib_data.y2)
2602 						joy.calib_data.y1 -= 10;
2603 					if (joy.calib_data.y3 == joy.calib_data.y2)
2604 						joy.calib_data.y3 += 10;
2605 					write_calib_data();
2606 				}
2607 			}
2608 		}
2609 		if (load_flag == 1) {
2610 			if ((handle = dat_open("calib.dat")) == 0) {
2611 				strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
2612 				return 1;
2613 			}
2614 			joy.calib_data.x1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
2615 			joy.calib_data.x2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
2616 			joy.calib_data.x3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
2617 			joy.calib_data.y1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
2618 			joy.calib_data.y2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
2619 			joy.calib_data.y3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
2620 		}
2621 	}
2622 
2623 #ifdef USE_NET
2624 	if (is_net) {
2625 		if (is_server) {
2626 			init_server(netarg);
2627 		} else {
2628 			connect_to_server(netarg);
2629 		}
2630 	}
2631 #endif
2632 
2633 	return 0;
2634 
2635 }
2636 
deinit_program(void)2637 void deinit_program(void)
2638 {
2639 #ifdef DOS
2640 	__dpmi_regs regs;
2641 #endif
2642 
2643 	dj_stop();
2644 	dj_free_mod(MOD_MENU);
2645 	dj_free_mod(MOD_GAME);
2646 	dj_free_sfx(SFX_DEATH);
2647 	dj_free_sfx(SFX_SPRING);
2648 	dj_free_sfx(SFX_SPLASH);
2649 	dj_deinit();
2650 
2651 	if (background_pic != 0)
2652 		free(background_pic);
2653 	if (mask_pic != 0)
2654 		free(mask_pic);
2655 
2656 	remove_keyb_handler();
2657 
2658 #ifdef DOS
2659 	regs.x.ax = 0x3;
2660 	__dpmi_int(0x10, &regs);
2661 #endif
2662 
2663 	if (main_info.error_str[0] != 0) {
2664 		printf("%s", main_info.error_str);
2665 #ifdef _WIN32
2666 		MessageBox(0, main_info.error_str, "Jump 'n Bump", 0);
2667 #endif
2668 		exit(1);
2669 	} else
2670 		exit(0);
2671 
2672 }
2673 
2674 
rnd(unsigned short max)2675 unsigned short rnd(unsigned short max)
2676 {
2677 #if (RAND_MAX < 0x7fff)
2678 #error "rand returns too small values"
2679 #elif (RAND_MAX == 0x7fff)
2680 	return (unsigned short)((rand()*2) % (int)max);
2681 #else
2682 	return (unsigned short)(rand() % (int)max);
2683 #endif
2684 }
2685 
2686 
read_level(void)2687 int read_level(void)
2688 {
2689 	unsigned char *handle;
2690 	int c1, c2;
2691 	int chr;
2692 
2693 	if ((handle = dat_open("levelmap.txt")) == 0) {
2694 		strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2695 		return 1;
2696 	}
2697 
2698 	for (c1 = 0; c1 < 16; c1++) {
2699 		for (c2 = 0; c2 < 22; c2++) {
2700 			while (1) {
2701 				chr = (int) *(handle++);
2702 				if (chr >= '0' && chr <= '4')
2703 					break;
2704 			}
2705 			if (flip)
2706 				ban_map[c1][21-c2] = chr - '0';
2707 			else
2708 				ban_map[c1][c2] = chr - '0';
2709 		}
2710 	}
2711 
2712 	for (c2 = 0; c2 < 22; c2++)
2713 		ban_map[16][c2] = BAN_SOLID;
2714 
2715 	return 0;
2716 
2717 }
2718 
2719 
dat_open(char * file_name)2720 unsigned char *dat_open(char *file_name)
2721 {
2722 	int num;
2723 	int c1;
2724 	char name[21];
2725 	int ofs;
2726 	unsigned char *ptr;
2727 
2728 	if (datafile_buffer == NULL)
2729 		return 0;
2730 
2731 	memset(name, 0, sizeof(name));
2732 
2733 	num = ( (datafile_buffer[0] <<  0) +
2734 	        (datafile_buffer[1] <<  8) +
2735 	        (datafile_buffer[2] << 16) +
2736 	        (datafile_buffer[3] << 24) );
2737 
2738 	ptr = datafile_buffer + 4;
2739 
2740 	for (c1 = 0; c1 < num; c1++) {
2741 
2742 		memcpy(name, ptr, 12);
2743 		ptr += 12;
2744 
2745 		if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2746 			ofs = ( (ptr[0] <<  0) +
2747 				(ptr[1] <<  8) +
2748 				(ptr[2] << 16) +
2749 				(ptr[3] << 24) );
2750 
2751 			return (datafile_buffer + ofs);
2752 		}
2753 		ptr += 8;
2754 	}
2755 
2756 	return 0;
2757 }
2758 
2759 
dat_filelen(char * file_name)2760 int dat_filelen(char *file_name)
2761 {
2762 	unsigned char *ptr;
2763 	int num;
2764 	int c1;
2765 	char name[21];
2766 	int len;
2767 
2768 	memset(name, 0, sizeof(name));
2769 
2770 	num = ( (datafile_buffer[0] <<  0) +
2771 	        (datafile_buffer[1] <<  8) +
2772 	        (datafile_buffer[2] << 16) +
2773 	        (datafile_buffer[3] << 24) );
2774 
2775 	ptr = datafile_buffer + 4;
2776 
2777 	for (c1 = 0; c1 < num; c1++) {
2778 
2779 	        memcpy(name, ptr, 12);
2780 		ptr += 12;
2781 
2782 		if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2783 
2784 			ptr += 4;
2785 			len = ( (ptr[0] <<  0) +
2786 				(ptr[1] <<  8) +
2787 				(ptr[2] << 16) +
2788 				(ptr[3] << 24) );
2789 
2790 			return len;
2791 		}
2792 		ptr += 8;
2793 	}
2794 
2795 	return 0;
2796 }
2797 
2798 
write_calib_data(void)2799 void write_calib_data(void)
2800 {
2801 	FILE *handle;
2802 	int c1;
2803 	int len, num;
2804 	char *mem;
2805 	int ofs;
2806 
2807 	if ((handle = fopen(datfile_name, "rb")) == NULL)
2808 		return;
2809 	len = filelength(fileno(handle));
2810 	if ((mem = malloc(len)) == NULL)
2811 		return;
2812 	fread(mem, 1, len, handle);
2813 	fclose(handle);
2814 
2815 	ofs = 4;
2816 	num = *(int *) (&mem[0]);
2817 	for (c1 = 0; c1 < num; c1++) {
2818 		if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
2819 			ofs = *(int *) (&mem[ofs + 12]);
2820 			break;
2821 		}
2822 		ofs += 20;
2823 	}
2824 
2825 	mem[ofs] = joy.calib_data.x1 & 0xff;
2826 	mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
2827 	mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
2828 	mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
2829 	mem[ofs + 4] = joy.calib_data.x2 & 0xff;
2830 	mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
2831 	mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
2832 	mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
2833 	mem[ofs + 8] = joy.calib_data.x3 & 0xff;
2834 	mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
2835 	mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
2836 	mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
2837 	mem[ofs + 12] = joy.calib_data.y1 & 0xff;
2838 	mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
2839 	mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
2840 	mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
2841 	mem[ofs + 16] = joy.calib_data.y2 & 0xff;
2842 	mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
2843 	mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
2844 	mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
2845 	mem[ofs + 20] = joy.calib_data.y3 & 0xff;
2846 	mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
2847 	mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
2848 	mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
2849 
2850 	if ((handle = fopen(datfile_name, "wb")) == NULL)
2851 		return;
2852 	fwrite(mem, 1, len, handle);
2853 	fclose(handle);
2854 
2855 }
2856