3 * Copyright (C) 1998 Brainchild Design - http://brainchilddesign.com/
5 * Copyright (C) 2001 Chuck Mason <cemason@users.sourceforge.net>
7 * Copyright (C) 2002 Florian Schulze <crow@icculus.org>
9 * Portions of this code are from the MPEG software simulation group
10 * idct implementation. This code will be replaced with a new
11 * implementation soon.
13 * This file is part of Jump'n'Bump.
15 * Jump'n'Bump is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * Jump'n'Bump is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #define M_PI 3.14159265358979323846
36 gob_t rabbit_gobs = { 0 };
37 gob_t font_gobs = { 0 };
38 gob_t object_gobs = { 0 };
39 gob_t number_gobs = { 0 };
41 main_info_t main_info;
43 player_anim_t player_anims[7];
44 object_t objects[NUM_OBJECTS];
48 char datfile_name[2048];
54 unsigned int ban_map[17][22] = {
55 {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
56 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0},
57 {1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
58 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1},
59 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
60 {1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
61 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1},
62 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
63 {1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
64 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1},
65 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1},
66 {1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1},
67 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
68 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
69 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 1, 3, 3, 3, 1, 1, 1},
70 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
71 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
200 int old_draw_x, old_draw_y;
212 } pobs[NUM_LEFTOVERS];
216 int pogostick, bunnies_in_space, jetpack, lord_of_the_flies, blood_is_thicker_than_water;
218 static flip_pixels(unsigned char *pixels)
224 for (y = 0; y < JNB_HEIGHT; y++) {
225 for (x = 0; x < (352/2); x++) {
226 temp = pixels[y*JNB_WIDTH+x];
227 pixels[y*JNB_WIDTH+x] = pixels[y*JNB_WIDTH+(352-x)];
228 pixels[y*JNB_WIDTH+(352-x)] = temp;
233 int main(int argc, char *argv[])
236 int c1, c2 = 0, c3, c4;
239 int closest_player = 0, dist, cur_dist;
240 int end_loop_flag, fade_flag;
241 int mod_vol, sfx_vol, mod_fade_direction;
247 if (init_program(argc, argv, pal) != 0)
250 if (main_info.fireworks == 1) {
260 if (key_pressed(1) == 1) {
263 if (init_level(0, pal) != 0) {
268 memset(cur_pal, 0, 768);
269 setpalette(0, 256, cur_pal);
271 recalculate_gob(&rabbit_gobs, pal);
272 //recalculate_gob(&font_gobs, pal);
273 recalculate_gob(&object_gobs, pal);
274 recalculate_gob(&number_gobs, pal);
277 register_background(background_pic, pal);
282 for (c1 = 0; c1 < NUM_FLIES; c1++) {
284 flies[c1].x = s1 + rnd(101) - 50;
285 flies[c1].y = s2 + rnd(101) - 50;
286 if (ban_map[flies[c1].y >> 4][flies[c1].x >> 4] == BAN_VOID)
289 flies[c1].back_defined[0] = 0;
290 flies[c1].back_defined[1] = 0;
293 mod_vol = sfx_vol = 10;
294 mod_fade_direction = 1;
295 dj_ready_mod(MOD_GAME);
296 dj_set_mod_volume((char)mod_vol);
297 dj_set_sfx_volume((char)mod_vol);
299 dj_play_sfx(SFX_FLY, SFX_FLY_FREQ, 0, 0, 0, 4);
302 lord_of_the_flies = bunnies_in_space = jetpack = pogostick = blood_is_thicker_than_water = 0;
304 main_info.page_info[0].num_pobs = 0;
305 main_info.page_info[1].num_pobs = 0;
306 main_info.view_page = 0;
307 main_info.draw_page = 1;
312 while (update_count) {
314 if (key_pressed(1) == 1) {
317 mod_fade_direction = 0;
320 if (strncmp(last_keys, "kcitsogop", strlen("kcitsogop")) == 0) {
324 if (strncmp(last_keys, "ecapsniseinnub", strlen("ecapsniseinnub")) == 0) {
325 bunnies_in_space ^= 1;
328 if (strncmp(last_keys, "kcaptej", strlen("kcaptej")) == 0) {
332 if (strncmp(last_keys, "seilfehtfodrol", strlen("seilfehtfodrol")) == 0) {
333 lord_of_the_flies ^= 1;
336 if (strncmp(last_keys, "retawnahtrekcihtsidoolb", strlen("retawnahtrekcihtsidoolb")) == 0) {
337 blood_is_thicker_than_water ^= 1;
338 if (blood_is_thicker_than_water == 1) {
389 register_background(background_pic, pal);
390 recalculate_gob(&object_gobs, pal);
398 for (c3 = 0; c3 < 6; c3++) {
402 } else if (c3 == 1) {
405 } else if (c3 == 2) {
408 } else if (c3 == 3) {
411 } else if (c3 == 4) {
414 } else if (c3 == 5) {
418 if (player[c1].enabled == 1 && player[c2].enabled == 1) {
419 if (labs(player[c1].x - player[c2].x) < (12L << 16) && labs(player[c1].y - player[c2].y) < (12L << 16)) {
420 if ((labs(player[c1].y - player[c2].y) >> 16) > 5) {
421 if (player[c1].y < player[c2].y) {
422 if (player[c1].y_add >= 0) {
423 player[c1].y_add = -player[c1].y_add;
424 if (player[c1].y_add > -262144L)
425 player[c1].y_add = -262144L;
426 player[c1].jump_abort = 1;
427 player[c2].dead_flag = 1;
428 if (player[c2].anim != 6) {
430 player[c2].frame = 0;
431 player[c2].frame_tick = 0;
432 player[c2].image = player_anims[player[c2].anim].frame[player[c2].frame].image + player[c2].direction * 9;
433 if (main_info.no_gore == 0) {
434 for (c4 = 0; c4 < 6; c4++)
435 add_object(OBJ_FUR, (player[c2].x >> 16) + 6 + rnd(5), (player[c2].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 44 + c2 * 8);
436 for (c4 = 0; c4 < 6; c4++)
437 add_object(OBJ_FLESH, (player[c2].x >> 16) + 6 + rnd(5), (player[c2].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 76);
438 for (c4 = 0; c4 < 6; c4++)
439 add_object(OBJ_FLESH, (player[c2].x >> 16) + 6 + rnd(5), (player[c2].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 77);
440 for (c4 = 0; c4 < 8; c4++)
441 add_object(OBJ_FLESH, (player[c2].x >> 16) + 6 + rnd(5), (player[c2].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 78);
442 for (c4 = 0; c4 < 10; c4++)
443 add_object(OBJ_FLESH, (player[c2].x >> 16) + 6 + rnd(5), (player[c2].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 79);
445 dj_play_sfx(SFX_DEATH, (unsigned short)(SFX_DEATH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
447 player[c1].bumped[c2]++;
448 s1 = player[c1].bumps % 100;
449 add_leftovers(0, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
450 add_leftovers(1, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
451 add_leftovers(0, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
452 add_leftovers(1, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
455 if (player[c2].y_add < 0)
456 player[c2].y_add = 0;
459 if (player[c2].y_add >= 0) {
460 player[c2].y_add = -player[c2].y_add;
461 if (player[c2].y_add > -262144L)
462 player[c2].y_add = -262144L;
463 player[c2].jump_abort = 1;
464 player[c1].dead_flag = 1;
465 if (player[c1].anim != 6) {
467 player[c1].frame = 0;
468 player[c1].frame_tick = 0;
469 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
470 if (main_info.no_gore == 0) {
471 for (c4 = 0; c4 < 6; c4++)
472 add_object(OBJ_FUR, (player[c1].x >> 16) + 6 + rnd(5), (player[c1].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 44 + c1 * 8);
473 for (c4 = 0; c4 < 6; c4++)
474 add_object(OBJ_FLESH, (player[c1].x >> 16) + 6 + rnd(5), (player[c1].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 76);
475 for (c4 = 0; c4 < 7; c4++)
476 add_object(OBJ_FLESH, (player[c1].x >> 16) + 6 + rnd(5), (player[c1].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 77);
477 for (c4 = 0; c4 < 8; c4++)
478 add_object(OBJ_FLESH, (player[c1].x >> 16) + 6 + rnd(5), (player[c1].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 78);
479 for (c4 = 0; c4 < 10; c4++)
480 add_object(OBJ_FLESH, (player[c1].x >> 16) + 6 + rnd(5), (player[c1].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 79);
482 dj_play_sfx(SFX_DEATH, (unsigned short)(SFX_DEATH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
484 player[c2].bumped[c1]++;
485 s1 = player[c2].bumps % 100;
486 add_leftovers(0, 360, 34 + c2 * 64, s1 / 10, &number_gobs);
487 add_leftovers(1, 360, 34 + c2 * 64, s1 / 10, &number_gobs);
488 add_leftovers(0, 376, 34 + c2 * 64, s1 - (s1 / 10) * 10, &number_gobs);
489 add_leftovers(1, 376, 34 + c2 * 64, s1 - (s1 / 10) * 10, &number_gobs);
492 if (player[c1].y_add < 0)
493 player[c1].y_add = 0;
497 if (player[c1].x < player[c2].x) {
498 if (player[c1].x_add > 0)
499 player[c1].x = player[c2].x - (12L << 16);
500 else if (player[c2].x_add < 0)
501 player[c2].x = player[c1].x + (12L << 16);
503 player[c1].x -= player[c1].x_add;
504 player[c2].x -= player[c2].x_add;
506 l1 = player[c2].x_add;
507 player[c2].x_add = player[c1].x_add;
508 player[c1].x_add = l1;
509 if (player[c1].x_add > 0)
510 player[c1].x_add = -player[c1].x_add;
511 if (player[c2].x_add < 0)
512 player[c2].x_add = -player[c2].x_add;
514 if (player[c1].x_add > 0)
515 player[c2].x = player[c1].x - (12L << 16);
516 else if (player[c2].x_add < 0)
517 player[c1].x = player[c2].x + (12L << 16);
519 player[c1].x -= player[c1].x_add;
520 player[c2].x -= player[c2].x_add;
522 l1 = player[c2].x_add;
523 player[c2].x_add = player[c1].x_add;
524 player[c1].x_add = l1;
525 if (player[c1].x_add < 0)
526 player[c1].x_add = -player[c1].x_add;
527 if (player[c2].x_add > 0)
528 player[c2].x_add = -player[c2].x_add;
537 main_info.page_info[main_info.draw_page].num_pobs = 0;
538 for (c1 = 0; c1 < 4; c1++) {
539 if (player[c1].enabled == 1)
540 main_info.page_info[main_info.draw_page].num_pobs++;
547 /* get center of fly swarm */
549 for (c1 = 0; c1 < NUM_FLIES; c1++) {
556 if (update_count == 1) {
557 /* get closest player to fly swarm */
559 for (c1 = 0; c1 < 4; c1++) {
560 if (player[c1].enabled == 1) {
561 cur_dist = (int)sqrt((s1 - ((player[c1].x >> 16) + 8)) * (s1 - ((player[c1].x >> 16) + 8)) + (s2 - ((player[c1].y >> 16) + 8)) * (s2 - ((player[c1].y >> 16) + 8)));
562 if (cur_dist < dist) {
568 /* update fly swarm sound */
572 dj_set_sfx_channel_volume(4, (char)(s3));
575 for (c1 = 0; c1 < NUM_FLIES; c1++) {
576 /* get closest player to fly */
578 for (c2 = 0; c2 < 4; c2++) {
579 if (player[c2].enabled == 1) {
580 cur_dist = (int)sqrt((flies[c1].x - ((player[c2].x >> 16) + 8)) * (flies[c1].x - ((player[c2].x >> 16) + 8)) + (flies[c1].y - ((player[c2].y >> 16) + 8)) * (flies[c1].y - ((player[c2].y >> 16) + 8)));
581 if (cur_dist < dist) {
587 flies[c1].old_x = flies[c1].x;
588 flies[c1].old_y = flies[c1].y;
590 if ((s1 - flies[c1].x) > 30)
592 else if ((s1 - flies[c1].x) < -30)
595 if (((player[closest_player].x >> 16) + 8) > flies[c1].x) {
596 if (lord_of_the_flies == 0)
601 if (lord_of_the_flies == 0)
607 s4 = rnd(3) - 1 + s3;
608 if ((flies[c1].x + s4) < 16)
610 if ((flies[c1].x + s4) > 351)
612 if (ban_map[flies[c1].y >> 4][(flies[c1].x + s4) >> 4] != BAN_VOID)
616 if ((s2 - flies[c1].y) > 30)
618 else if ((s2 - flies[c1].y) < -30)
621 if (((player[closest_player].y >> 16) + 8) > flies[c1].y) {
622 if (lord_of_the_flies == 0)
627 if (lord_of_the_flies == 0)
633 s4 = rnd(3) - 1 + s3;
634 if ((flies[c1].y + s4) < 0)
636 if ((flies[c1].y + s4) > 239)
638 if (ban_map[(flies[c1].y + s4) >> 4][flies[c1].x >> 4] != BAN_VOID)
646 for (c1 = 0; c1 < 4; c1++) {
647 if (player[c1].enabled == 1) {
648 main_info.page_info[main_info.draw_page].pobs[s1].x = player[c1].x >> 16;
649 main_info.page_info[main_info.draw_page].pobs[s1].y = player[c1].y >> 16;
650 main_info.page_info[main_info.draw_page].pobs[s1].image = player[c1].image + c1 * 18;
651 main_info.page_info[main_info.draw_page].pobs[s1].pob_data = &rabbit_gobs;
656 if (update_count == 1) {
659 draw_pobs(main_info.draw_page);
663 draw_flies(main_info.draw_page);
668 if (mod_fade_direction == 1) {
671 dj_set_mod_volume((char)mod_vol);
676 dj_set_mod_volume((char)mod_vol);
680 if (mod_fade_direction == 1) {
683 dj_set_sfx_volume((char)sfx_vol);
688 dj_set_sfx_volume((char)sfx_vol);
693 for (c1 = 0; c1 < 768; c1++) {
694 if (cur_pal[c1] < pal[c1]) {
697 } else if (cur_pal[c1] > pal[c1]) {
702 if (fade_flag == 0 && end_loop_flag == 1)
705 if (update_count == 1) {
706 main_info.draw_page ^= 1;
707 main_info.view_page ^= 1;
709 flippage(main_info.view_page);
715 setpalette(0, 256, cur_pal);
717 if (update_count == 1) {
720 redraw_flies_background(main_info.draw_page);
722 redraw_pob_backgrounds(main_info.draw_page);
724 draw_leftovers(main_info.draw_page);
732 update_count = intr_sysupdate();
734 if (fade_flag == 0 && end_loop_flag == 1)
738 main_info.view_page = 0;
739 main_info.draw_page = 1;
741 dj_stop_sfx_channel(4);
745 memset(mask_pic, 0, 102400L);
746 register_mask(mask_pic);
748 //recalculate_gob(&font_gobs, pal);
749 register_background(NULL, NULL);
753 put_text(main_info.view_page, 100, 50, "DOTT", 2);
754 put_text(main_info.view_page, 160, 50, "JIFFY", 2);
755 put_text(main_info.view_page, 220, 50, "FIZZ", 2);
756 put_text(main_info.view_page, 280, 50, "MIJJI", 2);
757 put_text(main_info.view_page, 40, 80, "DOTT", 2);
758 put_text(main_info.view_page, 40, 110, "JIFFY", 2);
759 put_text(main_info.view_page, 40, 140, "FIZZ", 2);
760 put_text(main_info.view_page, 40, 170, "MIJJI", 2);
762 for (c1 = 0; c1 < 4; c1++) {
763 for (c2 = 0; c2 < 4; c2++) {
765 sprintf(str1, "%d", player[c1].bumped[c2]);
766 put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, str1, 2);
768 put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, "-", 2);
770 sprintf(str1, "%d", player[c1].bumps);
771 put_text(main_info.view_page, 350, 80 + c1 * 30, str1, 2);
774 put_text(main_info.view_page, 200, 230, "Press ESC to continue", 2);
778 flippage(main_info.view_page);
780 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
781 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
784 if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
785 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
790 memset(cur_pal, 0, 768);
792 setpalette(0, 256, cur_pal);
795 dj_ready_mod(MOD_SCORES);
796 dj_set_mod_volume((char)mod_vol);
800 while (key_pressed(1) == 0) {
803 dj_set_mod_volume((char)mod_vol);
804 for (c1 = 0; c1 < 768; c1++) {
805 if (cur_pal[c1] < pal[c1])
811 setpalette(0, 256, cur_pal);
812 flippage(main_info.view_page);
814 while (key_pressed(1) == 1) {
821 while (mod_vol > 0) {
823 dj_set_mod_volume((char)mod_vol);
824 for (c1 = 0; c1 < 768; c1++) {
825 if (cur_pal[c1] > pal[c1])
830 setpalette(0, 256, cur_pal);
831 flippage(main_info.view_page);
834 fillpalette(0, 0, 0);
847 void steer_players(void)
852 update_player_actions();
854 for (c1 = 0; c1 < 4; c1++) {
856 if (player[c1].enabled == 1) {
858 if (player[c1].dead_flag == 0) {
860 if (player[c1].action_left && player[c1].action_right) {
861 if (player[c1].direction == 0) {
862 if (player[c1].action_right) {
863 s1 = (player[c1].x >> 16);
864 s2 = (player[c1].y >> 16);
865 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
866 if (player[c1].x_add < 0)
867 player[c1].x_add += 1024;
869 player[c1].x_add += 768;
870 } else if ((ban_map[(s2 + 16) >> 4][s1 >> 4] != BAN_SOLID && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_ICE) || (ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_ICE && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] != BAN_SOLID)) {
871 if (player[c1].x_add > 0)
872 player[c1].x_add += 1024;
874 player[c1].x_add += 768;
876 if (player[c1].x_add < 0) {
877 player[c1].x_add += 16384;
878 if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
879 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);
881 player[c1].x_add += 12288;
883 if (player[c1].x_add > 98304L)
884 player[c1].x_add = 98304L;
885 player[c1].direction = 0;
886 if (player[c1].anim == 0) {
888 player[c1].frame = 0;
889 player[c1].frame_tick = 0;
890 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
894 if (player[c1].action_left) {
895 s1 = (player[c1].x >> 16);
896 s2 = (player[c1].y >> 16);
897 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
898 if (player[c1].x_add > 0)
899 player[c1].x_add -= 1024;
901 player[c1].x_add -= 768;
902 } else if ((ban_map[(s2 + 16) >> 4][s1 >> 4] != BAN_SOLID && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_ICE) || (ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_ICE && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] != BAN_SOLID)) {
903 if (player[c1].x_add > 0)
904 player[c1].x_add -= 1024;
906 player[c1].x_add -= 768;
908 if (player[c1].x_add > 0) {
909 player[c1].x_add -= 16384;
910 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
911 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);
913 player[c1].x_add -= 12288;
915 if (player[c1].x_add < -98304L)
916 player[c1].x_add = -98304L;
917 player[c1].direction = 1;
918 if (player[c1].anim == 0) {
920 player[c1].frame = 0;
921 player[c1].frame_tick = 0;
922 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
926 } else if (player[c1].action_left) {
927 s1 = (player[c1].x >> 16);
928 s2 = (player[c1].y >> 16);
929 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
930 if (player[c1].x_add > 0)
931 player[c1].x_add -= 1024;
933 player[c1].x_add -= 768;
934 } else if ((ban_map[(s2 + 16) >> 4][s1 >> 4] != BAN_SOLID && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_ICE) || (ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_ICE && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] != BAN_SOLID)) {
935 if (player[c1].x_add > 0)
936 player[c1].x_add -= 1024;
938 player[c1].x_add -= 768;
940 if (player[c1].x_add > 0) {
941 player[c1].x_add -= 16384;
942 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
943 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 player[c1].x_add -= 12288;
947 if (player[c1].x_add < -98304L)
948 player[c1].x_add = -98304L;
949 player[c1].direction = 1;
950 if (player[c1].anim == 0) {
952 player[c1].frame = 0;
953 player[c1].frame_tick = 0;
954 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
956 } else if (player[c1].action_right) {
957 s1 = (player[c1].x >> 16);
958 s2 = (player[c1].y >> 16);
959 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
960 if (player[c1].x_add < 0)
961 player[c1].x_add += 1024;
963 player[c1].x_add += 768;
964 } else if ((ban_map[(s2 + 16) >> 4][s1 >> 4] != BAN_SOLID && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_ICE) || (ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_ICE && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] != BAN_SOLID)) {
965 if (player[c1].x_add > 0)
966 player[c1].x_add += 1024;
968 player[c1].x_add += 768;
970 if (player[c1].x_add < 0) {
971 player[c1].x_add += 16384;
972 if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
973 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);
975 player[c1].x_add += 12288;
977 if (player[c1].x_add > 98304L)
978 player[c1].x_add = 98304L;
979 player[c1].direction = 0;
980 if (player[c1].anim == 0) {
982 player[c1].frame = 0;
983 player[c1].frame_tick = 0;
984 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
986 } else if ((!player[c1].action_left) && (!player[c1].action_right)) {
987 s1 = (player[c1].x >> 16);
988 s2 = (player[c1].y >> 16);
989 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID || ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SPRING || (((ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_SOLID || ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_SPRING) && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] != BAN_ICE) || (ban_map[(s2 + 16) >> 4][s1 >> 4] != BAN_ICE && (ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_SPRING)))) {
990 if (player[c1].x_add < 0) {
991 player[c1].x_add += 16384;
992 if (player[c1].x_add > 0)
993 player[c1].x_add = 0;
995 player[c1].x_add -= 16384;
996 if (player[c1].x_add < 0)
997 player[c1].x_add = 0;
999 if (player[c1].x_add != 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1000 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);
1002 if (player[c1].anim == 1) {
1003 player[c1].anim = 0;
1004 player[c1].frame = 0;
1005 player[c1].frame_tick = 0;
1006 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1010 if (pogostick == 1 || (player[c1].jump_ready == 1 && player[c1].action_up)) {
1011 s1 = (player[c1].x >> 16);
1012 s2 = (player[c1].y >> 16);
1015 if (ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_SOLID || ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_ICE || ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_ICE) {
1016 player[c1].y_add = -280000L;
1017 player[c1].anim = 2;
1018 player[c1].frame = 0;
1019 player[c1].frame_tick = 0;
1020 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1021 player[c1].jump_ready = 0;
1022 player[c1].jump_abort = 1;
1024 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1026 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1028 if ((ban_map[(s2 + 7) >> 4][s1 >> 4] == BAN_VOID || ban_map[(s2 + 7) >> 4][(s1 + 15) >> 4] == BAN_VOID) && (ban_map[(s2 + 8) >> 4][s1 >> 4] == BAN_WATER || ban_map[(s2 + 8) >> 4][(s1 + 15) >> 4] == BAN_WATER)) {
1029 player[c1].y_add = -196608L;
1030 player[c1].in_water = 0;
1031 player[c1].anim = 2;
1032 player[c1].frame = 0;
1033 player[c1].frame_tick = 0;
1034 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1035 player[c1].jump_ready = 0;
1036 player[c1].jump_abort = 1;
1038 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1040 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1043 if (pogostick == 0 && (!player[c1].action_up)) {
1044 player[c1].jump_ready = 1;
1045 if (player[c1].in_water == 0 && player[c1].y_add < 0 && player[c1].jump_abort == 1) {
1046 if (bunnies_in_space == 0)
1047 player[c1].y_add += 32768;
1049 player[c1].y_add += 16384;
1050 if (player[c1].y_add > 0)
1051 player[c1].y_add = 0;
1056 if (player[c1].action_up) {
1057 player[c1].y_add -= 16384;
1058 if (player[c1].y_add < -400000L)
1059 player[c1].y_add = -400000L;
1060 if ((ban_map[(s2 + 7) >> 4][s1 >> 4] == BAN_VOID || ban_map[(s2 + 7) >> 4][(s1 + 15) >> 4] == BAN_VOID) && (ban_map[(s2 + 8) >> 4][s1 >> 4] == BAN_WATER || ban_map[(s2 + 8) >> 4][(s1 + 15) >> 4] == BAN_WATER))
1061 player[c1].in_water = 0;
1063 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);
1068 player[c1].x += player[c1].x_add;
1069 if ((player[c1].x >> 16) < 0) {
1071 player[c1].x_add = 0;
1073 if ((player[c1].x >> 16) + 15 > 351) {
1074 player[c1].x = 336L << 16;
1075 player[c1].x_add = 0;
1077 if (player[c1].y > 0) {
1078 s1 = (player[c1].x >> 16);
1079 s2 = (player[c1].y >> 16);
1080 if (ban_map[s2 >> 4][s1 >> 4] == BAN_SOLID || ban_map[s2 >> 4][s1 >> 4] == BAN_ICE || ban_map[s2 >> 4][s1 >> 4] == BAN_SPRING || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
1081 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1082 player[c1].x_add = 0;
1084 s1 = (player[c1].x >> 16);
1085 s2 = (player[c1].y >> 16);
1086 if (ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_SPRING || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1087 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1088 player[c1].x_add = 0;
1091 s1 = (player[c1].x >> 16);
1093 if (ban_map[s2 >> 4][s1 >> 4] == BAN_SOLID || ban_map[s2 >> 4][s1 >> 4] == BAN_ICE || ban_map[s2 >> 4][s1 >> 4] == BAN_SPRING || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
1094 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1095 player[c1].x_add = 0;
1097 s1 = (player[c1].x >> 16);
1099 if (ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_SPRING || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1100 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1101 player[c1].x_add = 0;
1105 player[c1].y += player[c1].y_add;
1107 s1 = (player[c1].x >> 16);
1108 s2 = (player[c1].y >> 16);
1109 if (ban_map[(s2 + 15) >> 4][(s1 + 8) >> 4] == BAN_SPRING || ((ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING && ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] != BAN_SOLID) || (ban_map[(s2 + 15) >> 4][s1 >> 4] != BAN_SOLID && ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING))) {
1110 player[c1].y = ((player[c1].y >> 16) & 0xfff0) << 16;
1111 player[c1].y_add = -400000L;
1112 player[c1].anim = 2;
1113 player[c1].frame = 0;
1114 player[c1].frame_tick = 0;
1115 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1116 player[c1].jump_ready = 0;
1117 player[c1].jump_abort = 0;
1118 for (c2 = 0; c2 < NUM_OBJECTS; c2++) {
1119 if (objects[c2].used == 1 && objects[c2].type == OBJ_SPRING) {
1120 if (ban_map[(s2 + 15) >> 4][(s1 + 8) >> 4] == BAN_SPRING) {
1121 if ((objects[c2].x >> 20) == ((s1 + 8) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1122 objects[c2].frame = 0;
1123 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1124 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1128 if (ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
1129 if ((objects[c2].x >> 20) == (s1 >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1130 objects[c2].frame = 0;
1131 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1132 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1135 } else if (ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1136 if ((objects[c2].x >> 20) == ((s1 + 15) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1137 objects[c2].frame = 0;
1138 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1139 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1146 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1148 s1 = (player[c1].x >> 16);
1149 s2 = (player[c1].y >> 16);
1152 if (ban_map[s2 >> 4][s1 >> 4] == BAN_SOLID || ban_map[s2 >> 4][s1 >> 4] == BAN_ICE || ban_map[s2 >> 4][s1 >> 4] == BAN_SPRING || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1153 player[c1].y = (((s2 + 16) & 0xfff0)) << 16;
1154 player[c1].y_add = 0;
1155 player[c1].anim = 0;
1156 player[c1].frame = 0;
1157 player[c1].frame_tick = 0;
1158 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1160 s1 = (player[c1].x >> 16);
1161 s2 = (player[c1].y >> 16);
1164 if (ban_map[(s2 + 8) >> 4][(s1 + 8) >> 4] == BAN_WATER) {
1165 if (player[c1].in_water == 0) {
1166 player[c1].in_water = 1;
1167 player[c1].anim = 4;
1168 player[c1].frame = 0;
1169 player[c1].frame_tick = 0;
1170 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1171 if (player[c1].y_add >= 32768) {
1172 add_object(OBJ_SPLASH, (player[c1].x >> 16) + 8, ((player[c1].y >> 16) & 0xfff0) + 15, 0, 0, OBJ_ANIM_SPLASH, 0);
1173 if (blood_is_thicker_than_water == 0)
1174 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1176 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 5000), 64, 0, 0, -1);
1179 player[c1].y_add -= 1536;
1180 if (player[c1].y_add < 0 && player[c1].anim != 5) {
1181 player[c1].anim = 5;
1182 player[c1].frame = 0;
1183 player[c1].frame_tick = 0;
1184 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1186 if (player[c1].y_add < -65536L)
1187 player[c1].y_add = -65536L;
1188 if (player[c1].y_add > 65535L)
1189 player[c1].y_add = 65535L;
1190 if (ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_ICE) {
1191 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1192 player[c1].y_add = 0;
1194 } else if (ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1195 player[c1].in_water = 0;
1196 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1197 player[c1].y_add = 0;
1198 if (player[c1].anim != 0 && player[c1].anim != 1) {
1199 player[c1].anim = 0;
1200 player[c1].frame = 0;
1201 player[c1].frame_tick = 0;
1202 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1205 if (player[c1].in_water == 0) {
1206 if (bunnies_in_space == 0)
1207 player[c1].y_add += 12288;
1209 player[c1].y_add += 6144;
1210 if (player[c1].y_add > 327680L)
1211 player[c1].y_add = 327680L;
1213 player[c1].y = (player[c1].y & 0xffff0000) + 0x10000;
1214 player[c1].y_add = 0;
1216 player[c1].in_water = 0;
1218 if (player[c1].y_add > 36864 && player[c1].anim != 3 && player[c1].in_water == 0) {
1219 player[c1].anim = 3;
1220 player[c1].frame = 0;
1221 player[c1].frame_tick = 0;
1222 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1227 player[c1].frame_tick++;
1228 if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
1230 if (player[c1].frame >= player_anims[player[c1].anim].num_frames) {
1231 if (player[c1].anim != 6)
1232 player[c1].frame = player_anims[player[c1].anim].restart_frame;
1234 position_player(c1);
1236 player[c1].frame_tick = 0;
1238 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1247 void position_player(int player_num)
1256 if (ban_map[s2][s1] == BAN_VOID && (ban_map[s2 + 1][s1] == BAN_SOLID || ban_map[s2 + 1][s1] == BAN_ICE))
1259 for (c1 = 0; c1 < 4; c1++) {
1260 if (c1 != player_num && player[c1].enabled == 1) {
1261 if (abs((s1 << 4) - (player[c1].x >> 16)) < 32 && abs((s2 << 4) - (player[c1].y >> 16)) < 32)
1266 player[player_num].dead_flag = 0;
1267 player[player_num].x = (long) s1 << 20;
1268 player[player_num].y = (long) s2 << 20;
1269 player[player_num].x_add = player[player_num].y_add = 0;
1270 player[player_num].direction = 0;
1271 player[player_num].jump_ready = 1;
1272 player[player_num].in_water = 0;
1273 player[player_num].anim = 0;
1274 player[player_num].frame = 0;
1275 player[player_num].frame_tick = 0;
1276 player[player_num].image = player_anims[player[player_num].anim].frame[player[player_num].frame].image;
1284 void add_object(int type, int x, int y, int x_add, int y_add, int anim, int frame)
1288 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
1289 if (objects[c1].used == 0) {
1290 objects[c1].used = 1;
1291 objects[c1].type = type;
1292 objects[c1].x = (long) x << 16;
1293 objects[c1].y = (long) y << 16;
1294 objects[c1].x_add = x_add;
1295 objects[c1].y_add = y_add;
1296 objects[c1].x_acc = 0;
1297 objects[c1].y_acc = 0;
1298 objects[c1].anim = anim;
1299 objects[c1].frame = frame;
1300 objects[c1].ticks = object_anims[anim].frame[frame].ticks;
1301 objects[c1].image = object_anims[anim].frame[frame].image;
1309 void update_objects(void)
1314 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
1315 if (objects[c1].used == 1) {
1316 switch (objects[c1].type) {
1318 objects[c1].ticks--;
1319 if (objects[c1].ticks <= 0) {
1320 objects[c1].frame++;
1321 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames) {
1322 objects[c1].frame--;
1323 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1325 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1326 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1329 if (objects[c1].used == 1)
1330 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1333 objects[c1].ticks--;
1334 if (objects[c1].ticks <= 0) {
1335 objects[c1].frame++;
1336 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1337 objects[c1].used = 0;
1339 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1340 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1343 if (objects[c1].used == 1)
1344 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1347 objects[c1].x += objects[c1].x_add;
1348 objects[c1].y += objects[c1].y_add;
1349 objects[c1].ticks--;
1350 if (objects[c1].ticks <= 0) {
1351 objects[c1].frame++;
1352 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1353 objects[c1].used = 0;
1355 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1356 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1359 if (objects[c1].used == 1)
1360 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1362 case OBJ_YEL_BUTFLY:
1363 case OBJ_PINK_BUTFLY:
1364 objects[c1].x_acc += rnd(128) - 64;
1365 if (objects[c1].x_acc < -1024)
1366 objects[c1].x_acc = -1024;
1367 if (objects[c1].x_acc > 1024)
1368 objects[c1].x_acc = 1024;
1369 objects[c1].x_add += objects[c1].x_acc;
1370 if (objects[c1].x_add < -32768)
1371 objects[c1].x_add = -32768;
1372 if (objects[c1].x_add > 32768)
1373 objects[c1].x_add = 32768;
1374 objects[c1].x += objects[c1].x_add;
1375 if ((objects[c1].x >> 16) < 16) {
1376 objects[c1].x = 16 << 16;
1377 objects[c1].x_add = -objects[c1].x_add >> 2;
1378 objects[c1].x_acc = 0;
1379 } else if ((objects[c1].x >> 16) > 350) {
1380 objects[c1].x = 350 << 16;
1381 objects[c1].x_add = -objects[c1].x_add >> 2;
1382 objects[c1].x_acc = 0;
1384 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
1385 if (objects[c1].x_add < 0) {
1386 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
1388 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
1390 objects[c1].x_add = -objects[c1].x_add >> 2;
1391 objects[c1].x_acc = 0;
1393 objects[c1].y_acc += rnd(64) - 32;
1394 if (objects[c1].y_acc < -1024)
1395 objects[c1].y_acc = -1024;
1396 if (objects[c1].y_acc > 1024)
1397 objects[c1].y_acc = 1024;
1398 objects[c1].y_add += objects[c1].y_acc;
1399 if (objects[c1].y_add < -32768)
1400 objects[c1].y_add = -32768;
1401 if (objects[c1].y_add > 32768)
1402 objects[c1].y_add = 32768;
1403 objects[c1].y += objects[c1].y_add;
1404 if ((objects[c1].y >> 16) < 0) {
1406 objects[c1].y_add = -objects[c1].y_add >> 2;
1407 objects[c1].y_acc = 0;
1408 } else if ((objects[c1].y >> 16) > 255) {
1409 objects[c1].y = 255 << 16;
1410 objects[c1].y_add = -objects[c1].y_add >> 2;
1411 objects[c1].y_acc = 0;
1413 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
1414 if (objects[c1].y_add < 0) {
1415 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
1417 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1419 objects[c1].y_add = -objects[c1].y_add >> 2;
1420 objects[c1].y_acc = 0;
1422 if (objects[c1].type == OBJ_YEL_BUTFLY) {
1423 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_LEFT) {
1424 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_LEFT;
1425 objects[c1].frame = 0;
1426 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1427 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1428 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_RIGHT) {
1429 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_RIGHT;
1430 objects[c1].frame = 0;
1431 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1432 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1435 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_LEFT) {
1436 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_LEFT;
1437 objects[c1].frame = 0;
1438 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1439 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1440 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_RIGHT) {
1441 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_RIGHT;
1442 objects[c1].frame = 0;
1443 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1444 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1447 objects[c1].ticks--;
1448 if (objects[c1].ticks <= 0) {
1449 objects[c1].frame++;
1450 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1451 objects[c1].frame = object_anims[objects[c1].anim].restart_frame;
1453 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1454 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1457 if (objects[c1].used == 1)
1458 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1462 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 0);
1463 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
1464 objects[c1].y_add += 3072;
1465 if (objects[c1].y_add > 196608L)
1466 objects[c1].y_add = 196608L;
1467 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
1468 if (objects[c1].x_add < 0) {
1469 if (objects[c1].x_add < -65536L)
1470 objects[c1].x_add = -65536L;
1471 objects[c1].x_add += 1024;
1472 if (objects[c1].x_add > 0)
1473 objects[c1].x_add = 0;
1475 if (objects[c1].x_add > 65536L)
1476 objects[c1].x_add = 65536L;
1477 objects[c1].x_add -= 1024;
1478 if (objects[c1].x_add < 0)
1479 objects[c1].x_add = 0;
1481 objects[c1].y_add += 1024;
1482 if (objects[c1].y_add < -65536L)
1483 objects[c1].y_add = -65536L;
1484 if (objects[c1].y_add > 65536L)
1485 objects[c1].y_add = 65536L;
1487 objects[c1].x += objects[c1].x_add;
1488 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)) {
1489 if (objects[c1].x_add < 0) {
1490 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
1491 objects[c1].x_add = -objects[c1].x_add >> 2;
1493 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
1494 objects[c1].x_add = -objects[c1].x_add >> 2;
1497 objects[c1].y += objects[c1].y_add;
1498 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
1499 objects[c1].used = 0;
1500 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
1501 if (objects[c1].y_add < 0) {
1502 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
1503 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
1504 objects[c1].x_add >>= 2;
1505 objects[c1].y_add = -objects[c1].y_add >> 2;
1508 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
1509 if (objects[c1].y_add > 131072L) {
1510 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1511 objects[c1].x_add >>= 2;
1512 objects[c1].y_add = -objects[c1].y_add >> 2;
1514 objects[c1].used = 0;
1515 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
1516 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1517 if (objects[c1].y_add > 131072L)
1518 objects[c1].y_add = -objects[c1].y_add >> 2;
1520 objects[c1].y_add = 0;
1524 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
1525 objects[c1].x_add = -16384;
1526 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
1527 objects[c1].x_add = 16384;
1528 if (objects[c1].used == 1) {
1529 s1 = (int)(atan2(objects[c1].y_add, objects[c1].x_add) * 4 / M_PI);
1536 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame + s1, &object_gobs);
1540 if (rnd(100) < 30) {
1541 if (objects[c1].frame == 76)
1542 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 1);
1543 else if (objects[c1].frame == 77)
1544 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 2);
1545 else if (objects[c1].frame == 78)
1546 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 3);
1548 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
1549 objects[c1].y_add += 3072;
1550 if (objects[c1].y_add > 196608L)
1551 objects[c1].y_add = 196608L;
1552 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
1553 if (objects[c1].x_add < 0) {
1554 if (objects[c1].x_add < -65536L)
1555 objects[c1].x_add = -65536L;
1556 objects[c1].x_add += 1024;
1557 if (objects[c1].x_add > 0)
1558 objects[c1].x_add = 0;
1560 if (objects[c1].x_add > 65536L)
1561 objects[c1].x_add = 65536L;
1562 objects[c1].x_add -= 1024;
1563 if (objects[c1].x_add < 0)
1564 objects[c1].x_add = 0;
1566 objects[c1].y_add += 1024;
1567 if (objects[c1].y_add < -65536L)
1568 objects[c1].y_add = -65536L;
1569 if (objects[c1].y_add > 65536L)
1570 objects[c1].y_add = 65536L;
1572 objects[c1].x += objects[c1].x_add;
1573 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)) {
1574 if (objects[c1].x_add < 0) {
1575 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
1576 objects[c1].x_add = -objects[c1].x_add >> 2;
1578 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
1579 objects[c1].x_add = -objects[c1].x_add >> 2;
1582 objects[c1].y += objects[c1].y_add;
1583 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
1584 objects[c1].used = 0;
1585 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
1586 if (objects[c1].y_add < 0) {
1587 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
1588 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
1589 objects[c1].x_add >>= 2;
1590 objects[c1].y_add = -objects[c1].y_add >> 2;
1593 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
1594 if (objects[c1].y_add > 131072L) {
1595 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1596 objects[c1].x_add >>= 2;
1597 objects[c1].y_add = -objects[c1].y_add >> 2;
1599 if (rnd(100) < 10) {
1601 add_leftovers(0, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
1602 add_leftovers(1, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
1604 objects[c1].used = 0;
1606 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
1607 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1608 if (objects[c1].y_add > 131072L)
1609 objects[c1].y_add = -objects[c1].y_add >> 2;
1611 objects[c1].y_add = 0;
1615 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
1616 objects[c1].x_add = -16384;
1617 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
1618 objects[c1].x_add = 16384;
1619 if (objects[c1].used == 1)
1620 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame, &object_gobs);
1622 case OBJ_FLESH_TRACE:
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;
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;
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);
1643 int add_pob(int page, int x, int y, int image, gob_t *pob_data)
1646 if (main_info.page_info[page].num_pobs >= NUM_POBS)
1649 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].x = x;
1650 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].y = y;
1651 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].image = image;
1652 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].pob_data = pob_data;
1653 main_info.page_info[page].num_pobs++;
1660 void draw_flies(int page)
1664 for (c2 = 0; c2 < NUM_FLIES; c2++) {
1665 flies[c2].back[main_info.draw_page] = get_pixel(main_info.draw_page, flies[c2].x, flies[c2].y);
1666 flies[c2].back_defined[main_info.draw_page] = 1;
1667 if (mask_pic[(flies[c2].y * JNB_WIDTH) + flies[c2].x] == 0)
1668 set_pixel(main_info.draw_page, flies[c2].x, flies[c2].y, 0);
1672 void draw_pobs(int page)
1679 for (c1 = main_info.page_info[page].num_pobs - 1; c1 >= 0; c1--) {
1680 main_info.page_info[page].pobs[c1].back_buf_ofs = back_buf_ofs;
1681 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);
1683 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 * bytes_per_pixel;
1685 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) * bytes_per_pixel;
1686 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);
1692 void redraw_flies_background(int page)
1696 for (c2 = NUM_FLIES - 1; c2 >= 0; c2--) {
1697 if (flies[c2].back_defined[page] == 1)
1698 set_pixel(page, flies[c2].old_draw_x, flies[c2].old_draw_y, flies[c2].back[page]);
1699 flies[c2].old_draw_x = flies[c2].x;
1700 flies[c2].old_draw_y = flies[c2].y;
1705 void redraw_pob_backgrounds(int page)
1709 for (c1 = 0; c1 < main_info.page_info[page].num_pobs; c1++)
1710 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);
1715 int add_leftovers(int page, int x, int y, int image, gob_t *pob_data)
1718 if (leftovers.page[page].num_pobs >= NUM_LEFTOVERS)
1721 leftovers.page[page].pobs[leftovers.page[page].num_pobs].x = x;
1722 leftovers.page[page].pobs[leftovers.page[page].num_pobs].y = y;
1723 leftovers.page[page].pobs[leftovers.page[page].num_pobs].image = image;
1724 leftovers.page[page].pobs[leftovers.page[page].num_pobs].pob_data = pob_data;
1725 leftovers.page[page].num_pobs++;
1732 void draw_leftovers(int page)
1736 for (c1 = leftovers.page[page].num_pobs - 1; c1 >= 0; c1--)
1737 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);
1739 leftovers.page[page].num_pobs = 0;
1744 int init_level(int level, char *pal)
1750 if ((handle = dat_open("level.pcx", datfile_name, "rb")) == 0) {
1751 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
1754 if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
1755 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
1760 flip_pixels(background_pic);
1761 if ((handle = dat_open("mask.pcx", datfile_name, "rb")) == 0) {
1762 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
1765 if (read_pcx(handle, mask_pic, 102400L, 0) != 0) {
1766 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
1771 flip_pixels(mask_pic);
1772 register_mask(mask_pic);
1774 for (c1 = 0; c1 < 4; c1++) {
1775 if (player[c1].enabled == 1) {
1776 player[c1].bumps = 0;
1777 player[c1].bumped[0] = 0;
1778 player[c1].bumped[1] = 0;
1779 player[c1].bumped[2] = 0;
1780 player[c1].bumped[3] = 0;
1781 position_player(c1);
1785 for (c1 = 0; c1 < NUM_OBJECTS; c1++)
1786 objects[c1].used = 0;
1788 for (c1 = 0; c1 < 16; c1++) {
1789 for (c2 = 0; c2 < 22; c2++) {
1790 if (ban_map[c1][c2] == BAN_SPRING)
1791 add_object(OBJ_SPRING, c2 << 4, c1 << 4, 0, 0, OBJ_ANIM_SPRING, 5);
1798 if (ban_map[s2][s1] == BAN_VOID) {
1799 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1806 if (ban_map[s2][s1] == BAN_VOID) {
1807 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1814 if (ban_map[s2][s1] == BAN_VOID) {
1815 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1822 if (ban_map[s2][s1] == BAN_VOID) {
1823 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1833 void deinit_level(void)
1840 int init_program(int argc, char *argv[], char *pal)
1842 FILE *handle = (FILE *) NULL;
1847 int player_anim_data[] = {
1848 1, 0, 0, 0x7fff, 0, 0, 0, 0, 0, 0,
1849 4, 0, 0, 4, 1, 4, 2, 4, 3, 4,
1850 1, 0, 4, 0x7fff, 0, 0, 0, 0, 0, 0,
1851 4, 2, 5, 8, 6, 10, 7, 3, 6, 3,
1852 1, 0, 6, 0x7fff, 0, 0, 0, 0, 0, 0,
1853 2, 1, 5, 8, 4, 0x7fff, 0, 0, 0, 0,
1854 1, 0, 8, 5, 0, 0, 0, 0, 0, 0
1858 if (__djgpp_nearptr_enable() == 0)
1864 if (hook_keyb_handler() != 0)
1867 memset(&main_info, 0, sizeof(main_info));
1869 strcpy(datfile_name, DATA_PATH);
1871 force2 = force3 = 0;
1874 for (c1 = 1; c1 < argc; c1++) {
1875 if (stricmp(argv[c1], "-nosound") == 0)
1876 main_info.no_sound = 1;
1877 else if (stricmp(argv[c1], "-nogore") == 0)
1878 main_info.no_gore = 1;
1879 else if (stricmp(argv[c1], "-nojoy") == 0)
1880 main_info.joy_enabled = 0;
1881 else if (stricmp(argv[c1], "-fireworks") == 0)
1882 main_info.fireworks = 1;
1884 else if (stricmp(argv[c1], "-fullscreen") == 0)
1887 else if (stricmp(argv[c1], "-scaleup") == 0)
1889 else if (stricmp(argv[c1], "-mirror") == 0)
1891 else if (stricmp(argv[c1], "-dat") == 0) {
1892 if (c1 < (argc - 1)) {
1893 if ((handle = fopen(argv[c1 + 1], "rb")) != NULL) {
1895 strcpy(datfile_name, argv[c1 + 1]);
1898 } else if (stricmp(argv[c1], "-mouse") == 0) {
1899 if (c1 < (argc - 1)) {
1900 if (stricmp(argv[c1 + 1], "2") == 0)
1902 if (stricmp(argv[c1 + 1], "3") == 0)
1906 else if (strstr(argv[1],"-v")) {
1907 printf("jumpnbump %s compiled %s at %s with",JB_VERSION,__DATE__,__TIME__);
1911 printf(" network support.\n");
1914 else if (strstr(argv[1],"-h")) {
1915 printf("Usage: jumpnbump [OPTION]...\n");
1917 printf(" -h this help\n");
1918 printf(" -v print version\n");
1919 printf(" -dat level.dat play a different level\n");
1920 printf(" -port port define listen port\n");
1921 printf(" -net player host rport define network players\n");
1922 printf(" -fireworks screensaver mode\n");
1923 printf(" -fullscreen run in fullscreen mode\n");
1924 printf(" -nosound play without sound\n");
1925 printf(" -nogore play without blood\n");
1926 printf(" -mirror play with mirrored level\n");
1933 main_info.pob_backbuf[0] = malloc(screen_pitch*screen_height*bytes_per_pixel);
1934 main_info.pob_backbuf[1] = malloc(screen_pitch*screen_height*bytes_per_pixel);
1936 for (c1 = 0; c1 < 7; c1++) {
1937 player_anims[c1].num_frames = player_anim_data[c1 * 10];
1938 player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
1939 for (c2 = 0; c2 < 4; c2++) {
1940 player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
1941 player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
1945 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
1946 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1949 if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
1950 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1955 if ((handle = dat_open("rabbit.gob", datfile_name, "rb")) == 0) {
1956 strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
1959 if (register_gob(handle, &rabbit_gobs, dat_filelen("rabbit.gob", datfile_name))) {
1966 if ((handle = dat_open("objects.gob", datfile_name, "rb")) == 0) {
1967 strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
1970 if (register_gob(handle, &object_gobs, dat_filelen("objects.gob", datfile_name))) {
1977 if ((handle = dat_open("font.gob", datfile_name, "rb")) == 0) {
1978 strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
1981 if (register_gob(handle, &font_gobs, dat_filelen("font.gob", datfile_name))) {
1988 if ((handle = dat_open("numbers.gob", datfile_name, "rb")) == 0) {
1989 strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
1992 if (register_gob(handle, &number_gobs, dat_filelen("numbers.gob", datfile_name))) {
1999 if (read_level() != 0) {
2000 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2007 if (main_info.no_sound == 0) {
2009 dj_set_mixing_freq(20000);
2013 dj_set_num_sfx_channels(5);
2014 dj_set_sfx_volume(64);
2018 if ((handle = dat_open("jump.mod", datfile_name, "rb")) == 0) {
2019 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2022 if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
2023 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2028 if ((handle = dat_open("bump.mod", datfile_name, "rb")) == 0) {
2029 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2032 if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
2033 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2038 if ((handle = dat_open("scores.mod", datfile_name, "rb")) == 0) {
2039 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2042 if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
2043 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2048 if ((handle = dat_open("jump.smp", datfile_name, "rb")) == 0) {
2049 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2052 if (dj_load_sfx(handle, 0, dat_filelen("jump.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
2053 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2058 if ((handle = dat_open("death.smp", datfile_name, "rb")) == 0) {
2059 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2062 if (dj_load_sfx(handle, 0, dat_filelen("death.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
2063 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2068 if ((handle = dat_open("spring.smp", datfile_name, "rb")) == 0) {
2069 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2072 if (dj_load_sfx(handle, 0, dat_filelen("spring.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
2073 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2078 if ((handle = dat_open("splash.smp", datfile_name, "rb")) == 0) {
2079 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2082 if (dj_load_sfx(handle, 0, dat_filelen("splash.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
2083 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2088 if ((handle = dat_open("fly.smp", datfile_name, "rb")) == 0) {
2089 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2092 if (dj_load_sfx(handle, 0, dat_filelen("fly.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
2093 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2098 dj_get_sfx_settings(SFX_FLY, &fly);
2100 fly.default_freq = SFX_FLY_FREQ;
2103 fly.loop_length = fly.length;
2104 dj_set_sfx_settings(SFX_FLY, &fly);
2107 if ((background_pic = malloc(102400)) == NULL)
2109 if ((mask_pic = malloc(102400)) == NULL)
2111 memset(mask_pic, 0, 102400);
2112 register_mask(mask_pic);
2114 setpalette(0, 256, pal);
2118 recalculate_gob(&font_gobs, pal);
2120 if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
2122 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2123 put_text(0, 200, 100, "Move the joystick to the", 2);
2124 put_text(0, 200, 115, "UPPER LEFT", 2);
2125 put_text(0, 200, 130, "and press button A", 2);
2126 put_text(0, 200, 200, "Or press ESC to use", 2);
2127 put_text(0, 200, 215, "previous settings", 2);
2128 if (calib_joy(0) != 0)
2131 register_background(NULL, NULL);
2133 main_info.view_page = 1;
2138 put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
2139 put_text(1, 200, 100, "Move the joystick to the", 2);
2140 put_text(1, 200, 115, "LOWER RIGHT", 2);
2141 put_text(1, 200, 130, "and press button A", 2);
2142 put_text(1, 200, 200, "Or press ESC to use", 2);
2143 put_text(1, 200, 215, "previous settings", 2);
2144 if (calib_joy(1) != 0)
2147 register_background(NULL, NULL);
2152 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2153 put_text(0, 200, 100, "Move the joystick to the", 2);
2154 put_text(0, 200, 115, "CENTER", 2);
2155 put_text(0, 200, 130, "and press button A", 2);
2156 put_text(0, 200, 200, "Or press ESC to use", 2);
2157 put_text(0, 200, 215, "previous settings", 2);
2158 if (calib_joy(2) != 0)
2161 if (joy.calib_data.x1 == joy.calib_data.x2)
2162 joy.calib_data.x1 -= 10;
2163 if (joy.calib_data.x3 == joy.calib_data.x2)
2164 joy.calib_data.x3 += 10;
2165 if (joy.calib_data.y1 == joy.calib_data.y2)
2166 joy.calib_data.y1 -= 10;
2167 if (joy.calib_data.y3 == joy.calib_data.y2)
2168 joy.calib_data.y3 += 10;
2173 if (load_flag == 1) {
2174 if ((handle = dat_open("calib.dat", datfile_name, "rb")) == 0) {
2175 strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
2178 joy.calib_data.x1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2179 joy.calib_data.x2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2180 joy.calib_data.x3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2181 joy.calib_data.y1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2182 joy.calib_data.y2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2183 joy.calib_data.y3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2192 void deinit_program(void)
2199 dj_free_mod(MOD_MENU);
2200 dj_free_mod(MOD_GAME);
2201 dj_free_sfx(SFX_DEATH);
2202 dj_free_sfx(SFX_SPRING);
2203 dj_free_sfx(SFX_SPLASH);
2206 if (background_pic != 0)
2207 free(background_pic);
2211 remove_keyb_handler();
2215 __dpmi_int(0x10, ®s);
2218 if (main_info.error_str[0] != 0) {
2219 printf(main_info.error_str);
2221 MessageBox(0, main_info.error_str, "Jump'n'Bump", 0);
2230 unsigned short rnd(unsigned short max)
2232 return (rand() % max);
2236 int read_level(void)
2242 if ((handle = dat_open("levelmap.txt", datfile_name, "rb")) == 0) {
2243 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2247 for (c1 = 0; c1 < 16; c1++) {
2248 for (c2 = 0; c2 < 22; c2++) {
2250 chr = fgetc(handle);
2255 if (chr >= '0' && chr <= '4')
2259 ban_map[c1][21-c2] = chr - '0';
2261 ban_map[c1][c2] = chr - '0';
2265 for (c2 = 0; c2 < 22; c2++)
2266 ban_map[16][c2] = BAN_SOLID;
2274 FILE *dat_open(char *file_name, char *dat_name, char *mode)
2282 handle = fopen(dat_name, mode);
2286 memset(name, 0, sizeof(name));
2288 num = fgetc(handle);
2289 num+= (fgetc(handle) << 8);
2290 num+= (fgetc(handle) << 16);
2291 num+= (fgetc(handle) << 24);
2293 for (c1 = 0; c1 < num; c1++) {
2294 if (!fread(name, 1, 12, handle)) {
2298 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2299 ofs = fgetc(handle);
2300 ofs += (fgetc(handle) << 8);
2301 ofs += (fgetc(handle) << 16);
2302 ofs += (fgetc(handle) << 24);
2303 fseek(handle, ofs, SEEK_SET);
2306 fseek(handle, 8, SEEK_CUR);
2315 int dat_filelen(char *file_name, char *dat_name)
2323 handle = fopen(dat_name, "rb");
2327 memset(name, 0, sizeof(name));
2329 num = fgetc(handle);
2330 num+= (fgetc(handle) << 8);
2331 num+= (fgetc(handle) << 16);
2332 num+= (fgetc(handle) << 24);
2334 for (c1 = 0; c1 < num; c1++) {
2335 if (!fread(name, 1, 12, handle)) {
2339 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2340 fseek(handle, 4, SEEK_CUR);
2341 len = fgetc(handle);
2342 len += (fgetc(handle) << 8);
2343 len += (fgetc(handle) << 16);
2344 len += (fgetc(handle) << 24);
2349 fseek(handle, 8, SEEK_CUR);
2358 int filelength(int handle)
2362 if (fstat(handle, &buf) == -1) {
2363 perror("filelength");
2372 void write_calib_data(void)
2380 if ((handle = fopen(datfile_name, "rb")) == NULL)
2382 len = filelength(fileno(handle));
2383 if ((mem = malloc(len)) == NULL)
2385 fread(mem, 1, len, handle);
2389 num = *(int *) (&mem[0]);
2390 for (c1 = 0; c1 < num; c1++) {
2391 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
2392 ofs = *(int *) (&mem[ofs + 12]);
2398 mem[ofs] = joy.calib_data.x1 & 0xff;
2399 mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
2400 mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
2401 mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
2402 mem[ofs + 4] = joy.calib_data.x2 & 0xff;
2403 mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
2404 mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
2405 mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
2406 mem[ofs + 8] = joy.calib_data.x3 & 0xff;
2407 mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
2408 mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
2409 mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
2410 mem[ofs + 12] = joy.calib_data.y1 & 0xff;
2411 mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
2412 mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
2413 mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
2414 mem[ofs + 16] = joy.calib_data.y2 & 0xff;
2415 mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
2416 mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
2417 mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
2418 mem[ofs + 20] = joy.calib_data.y3 & 0xff;
2419 mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
2420 mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
2421 mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
2423 if ((handle = fopen(datfile_name, "wb")) == NULL)
2425 fwrite(mem, 1, len, handle);