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)-1];
228 pixels[y*JNB_WIDTH+(352-x)-1] = 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], "-musicnosound") == 0)
1878 main_info.music_no_sound = 1;
1879 else if (stricmp(argv[c1], "-nogore") == 0)
1880 main_info.no_gore = 1;
1881 else if (stricmp(argv[c1], "-nojoy") == 0)
1882 main_info.joy_enabled = 0;
1883 else if (stricmp(argv[c1], "-fireworks") == 0)
1884 main_info.fireworks = 1;
1886 else if (stricmp(argv[c1], "-fullscreen") == 0)
1889 else if (stricmp(argv[c1], "-scaleup") == 0)
1891 else if (stricmp(argv[c1], "-mirror") == 0)
1893 else if (stricmp(argv[c1], "-dat") == 0) {
1894 if (c1 < (argc - 1)) {
1895 if ((handle = fopen(argv[c1 + 1], "rb")) != NULL) {
1897 strcpy(datfile_name, argv[c1 + 1]);
1900 } else if (stricmp(argv[c1], "-mouse") == 0) {
1901 if (c1 < (argc - 1)) {
1902 if (stricmp(argv[c1 + 1], "2") == 0)
1904 if (stricmp(argv[c1 + 1], "3") == 0)
1908 else if (strstr(argv[1],"-v")) {
1909 printf("jumpnbump %s compiled %s at %s with",JNB_VERSION,__DATE__,__TIME__);
1913 printf(" network support.\n");
1916 else if (strstr(argv[1],"-h")) {
1917 printf("Usage: jumpnbump [OPTION]...\n");
1919 printf(" -h this help\n");
1920 printf(" -v print version\n");
1921 printf(" -dat level.dat play a different level\n");
1922 printf(" -port port define listen port\n");
1923 printf(" -net player host rport define network players\n");
1924 printf(" -fireworks screensaver mode\n");
1925 printf(" -fullscreen run in fullscreen mode\n");
1926 printf(" -nosound play without sound\n");
1927 printf(" -nogore play without blood\n");
1928 printf(" -mirror play with mirrored level\n");
1929 printf(" -scaleup play with doubled resolution (800x512)\n");
1936 main_info.pob_backbuf[0] = malloc(screen_pitch*screen_height*bytes_per_pixel);
1937 main_info.pob_backbuf[1] = malloc(screen_pitch*screen_height*bytes_per_pixel);
1939 for (c1 = 0; c1 < 7; c1++) {
1940 player_anims[c1].num_frames = player_anim_data[c1 * 10];
1941 player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
1942 for (c2 = 0; c2 < 4; c2++) {
1943 player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
1944 player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
1948 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
1949 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1952 if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
1953 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1958 if ((handle = dat_open("rabbit.gob", datfile_name, "rb")) == 0) {
1959 strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
1962 if (register_gob(handle, &rabbit_gobs, dat_filelen("rabbit.gob", datfile_name))) {
1969 if ((handle = dat_open("objects.gob", datfile_name, "rb")) == 0) {
1970 strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
1973 if (register_gob(handle, &object_gobs, dat_filelen("objects.gob", datfile_name))) {
1980 if ((handle = dat_open("font.gob", datfile_name, "rb")) == 0) {
1981 strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
1984 if (register_gob(handle, &font_gobs, dat_filelen("font.gob", datfile_name))) {
1991 if ((handle = dat_open("numbers.gob", datfile_name, "rb")) == 0) {
1992 strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
1995 if (register_gob(handle, &number_gobs, dat_filelen("numbers.gob", datfile_name))) {
2002 if (read_level() != 0) {
2003 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2010 if (main_info.no_sound == 0) {
2012 dj_set_mixing_freq(20000);
2016 dj_set_num_sfx_channels(5);
2017 dj_set_sfx_volume(64);
2021 if ((handle = dat_open("jump.mod", datfile_name, "rb")) == 0) {
2022 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2025 if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
2026 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2031 if ((handle = dat_open("bump.mod", datfile_name, "rb")) == 0) {
2032 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2035 if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
2036 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2041 if ((handle = dat_open("scores.mod", datfile_name, "rb")) == 0) {
2042 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2045 if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
2046 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2051 if ((handle = dat_open("jump.smp", datfile_name, "rb")) == 0) {
2052 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2055 if (dj_load_sfx(handle, 0, dat_filelen("jump.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
2056 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2061 if ((handle = dat_open("death.smp", datfile_name, "rb")) == 0) {
2062 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2065 if (dj_load_sfx(handle, 0, dat_filelen("death.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
2066 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2071 if ((handle = dat_open("spring.smp", datfile_name, "rb")) == 0) {
2072 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2075 if (dj_load_sfx(handle, 0, dat_filelen("spring.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
2076 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2081 if ((handle = dat_open("splash.smp", datfile_name, "rb")) == 0) {
2082 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2085 if (dj_load_sfx(handle, 0, dat_filelen("splash.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
2086 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2091 if ((handle = dat_open("fly.smp", datfile_name, "rb")) == 0) {
2092 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2095 if (dj_load_sfx(handle, 0, dat_filelen("fly.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
2096 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2101 dj_get_sfx_settings(SFX_FLY, &fly);
2103 fly.default_freq = SFX_FLY_FREQ;
2106 fly.loop_length = fly.length;
2107 dj_set_sfx_settings(SFX_FLY, &fly);
2110 if ((background_pic = malloc(102400)) == NULL)
2112 if ((mask_pic = malloc(102400)) == NULL)
2114 memset(mask_pic, 0, 102400);
2115 register_mask(mask_pic);
2117 setpalette(0, 256, pal);
2121 recalculate_gob(&font_gobs, pal);
2123 if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
2125 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2126 put_text(0, 200, 100, "Move the joystick to the", 2);
2127 put_text(0, 200, 115, "UPPER LEFT", 2);
2128 put_text(0, 200, 130, "and press button A", 2);
2129 put_text(0, 200, 200, "Or press ESC to use", 2);
2130 put_text(0, 200, 215, "previous settings", 2);
2131 if (calib_joy(0) != 0)
2134 register_background(NULL, NULL);
2136 main_info.view_page = 1;
2141 put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
2142 put_text(1, 200, 100, "Move the joystick to the", 2);
2143 put_text(1, 200, 115, "LOWER RIGHT", 2);
2144 put_text(1, 200, 130, "and press button A", 2);
2145 put_text(1, 200, 200, "Or press ESC to use", 2);
2146 put_text(1, 200, 215, "previous settings", 2);
2147 if (calib_joy(1) != 0)
2150 register_background(NULL, NULL);
2155 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2156 put_text(0, 200, 100, "Move the joystick to the", 2);
2157 put_text(0, 200, 115, "CENTER", 2);
2158 put_text(0, 200, 130, "and press button A", 2);
2159 put_text(0, 200, 200, "Or press ESC to use", 2);
2160 put_text(0, 200, 215, "previous settings", 2);
2161 if (calib_joy(2) != 0)
2164 if (joy.calib_data.x1 == joy.calib_data.x2)
2165 joy.calib_data.x1 -= 10;
2166 if (joy.calib_data.x3 == joy.calib_data.x2)
2167 joy.calib_data.x3 += 10;
2168 if (joy.calib_data.y1 == joy.calib_data.y2)
2169 joy.calib_data.y1 -= 10;
2170 if (joy.calib_data.y3 == joy.calib_data.y2)
2171 joy.calib_data.y3 += 10;
2176 if (load_flag == 1) {
2177 if ((handle = dat_open("calib.dat", datfile_name, "rb")) == 0) {
2178 strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
2181 joy.calib_data.x1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2182 joy.calib_data.x2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2183 joy.calib_data.x3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2184 joy.calib_data.y1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2185 joy.calib_data.y2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2186 joy.calib_data.y3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2195 void deinit_program(void)
2202 dj_free_mod(MOD_MENU);
2203 dj_free_mod(MOD_GAME);
2204 dj_free_sfx(SFX_DEATH);
2205 dj_free_sfx(SFX_SPRING);
2206 dj_free_sfx(SFX_SPLASH);
2209 if (background_pic != 0)
2210 free(background_pic);
2214 remove_keyb_handler();
2218 __dpmi_int(0x10, ®s);
2221 if (main_info.error_str[0] != 0) {
2222 printf(main_info.error_str);
2224 MessageBox(0, main_info.error_str, "Jump'n'Bump", 0);
2233 unsigned short rnd(unsigned short max)
2235 return (rand() % max);
2239 int read_level(void)
2245 if ((handle = dat_open("levelmap.txt", datfile_name, "rb")) == 0) {
2246 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2250 for (c1 = 0; c1 < 16; c1++) {
2251 for (c2 = 0; c2 < 22; c2++) {
2253 chr = fgetc(handle);
2258 if (chr >= '0' && chr <= '4')
2262 ban_map[c1][21-c2] = chr - '0';
2264 ban_map[c1][c2] = chr - '0';
2268 for (c2 = 0; c2 < 22; c2++)
2269 ban_map[16][c2] = BAN_SOLID;
2277 FILE *dat_open(char *file_name, char *dat_name, char *mode)
2285 handle = fopen(dat_name, mode);
2289 memset(name, 0, sizeof(name));
2291 num = fgetc(handle);
2292 num+= (fgetc(handle) << 8);
2293 num+= (fgetc(handle) << 16);
2294 num+= (fgetc(handle) << 24);
2296 for (c1 = 0; c1 < num; c1++) {
2297 if (!fread(name, 1, 12, handle)) {
2301 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2302 ofs = fgetc(handle);
2303 ofs += (fgetc(handle) << 8);
2304 ofs += (fgetc(handle) << 16);
2305 ofs += (fgetc(handle) << 24);
2306 fseek(handle, ofs, SEEK_SET);
2309 fseek(handle, 8, SEEK_CUR);
2318 int dat_filelen(char *file_name, char *dat_name)
2326 handle = fopen(dat_name, "rb");
2330 memset(name, 0, sizeof(name));
2332 num = fgetc(handle);
2333 num+= (fgetc(handle) << 8);
2334 num+= (fgetc(handle) << 16);
2335 num+= (fgetc(handle) << 24);
2337 for (c1 = 0; c1 < num; c1++) {
2338 if (!fread(name, 1, 12, handle)) {
2342 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2343 fseek(handle, 4, SEEK_CUR);
2344 len = fgetc(handle);
2345 len += (fgetc(handle) << 8);
2346 len += (fgetc(handle) << 16);
2347 len += (fgetc(handle) << 24);
2352 fseek(handle, 8, SEEK_CUR);
2361 int filelength(int handle)
2365 if (fstat(handle, &buf) == -1) {
2366 perror("filelength");
2375 void write_calib_data(void)
2383 if ((handle = fopen(datfile_name, "rb")) == NULL)
2385 len = filelength(fileno(handle));
2386 if ((mem = malloc(len)) == NULL)
2388 fread(mem, 1, len, handle);
2392 num = *(int *) (&mem[0]);
2393 for (c1 = 0; c1 < num; c1++) {
2394 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
2395 ofs = *(int *) (&mem[ofs + 12]);
2401 mem[ofs] = joy.calib_data.x1 & 0xff;
2402 mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
2403 mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
2404 mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
2405 mem[ofs + 4] = joy.calib_data.x2 & 0xff;
2406 mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
2407 mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
2408 mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
2409 mem[ofs + 8] = joy.calib_data.x3 & 0xff;
2410 mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
2411 mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
2412 mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
2413 mem[ofs + 12] = joy.calib_data.y1 & 0xff;
2414 mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
2415 mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
2416 mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
2417 mem[ofs + 16] = joy.calib_data.y2 & 0xff;
2418 mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
2419 mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
2420 mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
2421 mem[ofs + 20] = joy.calib_data.y3 & 0xff;
2422 mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
2423 mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
2424 mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
2426 if ((handle = fopen(datfile_name, "wb")) == NULL)
2428 fwrite(mem, 1, len, handle);