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, ®s);
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