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], "-flip") == 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)
1909 main_info.pob_backbuf[0] = malloc(screen_pitch*screen_height*bytes_per_pixel);
1910 main_info.pob_backbuf[1] = malloc(screen_pitch*screen_height*bytes_per_pixel);
1912 for (c1 = 0; c1 < 7; c1++) {
1913 player_anims[c1].num_frames = player_anim_data[c1 * 10];
1914 player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
1915 for (c2 = 0; c2 < 4; c2++) {
1916 player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
1917 player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
1921 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
1922 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1925 if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
1926 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1931 if ((handle = dat_open("rabbit.gob", datfile_name, "rb")) == 0) {
1932 strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
1935 if (register_gob(handle, &rabbit_gobs, dat_filelen("rabbit.gob", datfile_name))) {
1942 if ((handle = dat_open("objects.gob", datfile_name, "rb")) == 0) {
1943 strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
1946 if (register_gob(handle, &object_gobs, dat_filelen("objects.gob", datfile_name))) {
1953 if ((handle = dat_open("font.gob", datfile_name, "rb")) == 0) {
1954 strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
1957 if (register_gob(handle, &font_gobs, dat_filelen("font.gob", datfile_name))) {
1964 if ((handle = dat_open("numbers.gob", datfile_name, "rb")) == 0) {
1965 strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
1968 if (register_gob(handle, &number_gobs, dat_filelen("numbers.gob", datfile_name))) {
1975 if (read_level() != 0) {
1976 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
1983 if (main_info.no_sound == 0) {
1985 dj_set_mixing_freq(20000);
1989 dj_set_num_sfx_channels(5);
1990 dj_set_sfx_volume(64);
1994 if ((handle = dat_open("jump.mod", datfile_name, "rb")) == 0) {
1995 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
1998 if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
1999 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2004 if ((handle = dat_open("bump.mod", datfile_name, "rb")) == 0) {
2005 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2008 if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
2009 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2014 if ((handle = dat_open("scores.mod", datfile_name, "rb")) == 0) {
2015 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2018 if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
2019 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2024 if ((handle = dat_open("jump.smp", datfile_name, "rb")) == 0) {
2025 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2028 if (dj_load_sfx(handle, 0, dat_filelen("jump.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
2029 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2034 if ((handle = dat_open("death.smp", datfile_name, "rb")) == 0) {
2035 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2038 if (dj_load_sfx(handle, 0, dat_filelen("death.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
2039 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2044 if ((handle = dat_open("spring.smp", datfile_name, "rb")) == 0) {
2045 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2048 if (dj_load_sfx(handle, 0, dat_filelen("spring.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
2049 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2054 if ((handle = dat_open("splash.smp", datfile_name, "rb")) == 0) {
2055 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2058 if (dj_load_sfx(handle, 0, dat_filelen("splash.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
2059 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2064 if ((handle = dat_open("fly.smp", datfile_name, "rb")) == 0) {
2065 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2068 if (dj_load_sfx(handle, 0, dat_filelen("fly.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
2069 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2074 dj_get_sfx_settings(SFX_FLY, &fly);
2076 fly.default_freq = SFX_FLY_FREQ;
2079 fly.loop_length = fly.length;
2080 dj_set_sfx_settings(SFX_FLY, &fly);
2083 if ((background_pic = malloc(102400)) == NULL)
2085 if ((mask_pic = malloc(102400)) == NULL)
2087 memset(mask_pic, 0, 102400);
2088 register_mask(mask_pic);
2090 setpalette(0, 256, pal);
2094 recalculate_gob(&font_gobs, pal);
2096 if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
2098 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2099 put_text(0, 200, 100, "Move the joystick to the", 2);
2100 put_text(0, 200, 115, "UPPER LEFT", 2);
2101 put_text(0, 200, 130, "and press button A", 2);
2102 put_text(0, 200, 200, "Or press ESC to use", 2);
2103 put_text(0, 200, 215, "previous settings", 2);
2104 if (calib_joy(0) != 0)
2107 register_background(NULL, NULL);
2109 main_info.view_page = 1;
2114 put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
2115 put_text(1, 200, 100, "Move the joystick to the", 2);
2116 put_text(1, 200, 115, "LOWER RIGHT", 2);
2117 put_text(1, 200, 130, "and press button A", 2);
2118 put_text(1, 200, 200, "Or press ESC to use", 2);
2119 put_text(1, 200, 215, "previous settings", 2);
2120 if (calib_joy(1) != 0)
2123 register_background(NULL, NULL);
2128 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2129 put_text(0, 200, 100, "Move the joystick to the", 2);
2130 put_text(0, 200, 115, "CENTER", 2);
2131 put_text(0, 200, 130, "and press button A", 2);
2132 put_text(0, 200, 200, "Or press ESC to use", 2);
2133 put_text(0, 200, 215, "previous settings", 2);
2134 if (calib_joy(2) != 0)
2137 if (joy.calib_data.x1 == joy.calib_data.x2)
2138 joy.calib_data.x1 -= 10;
2139 if (joy.calib_data.x3 == joy.calib_data.x2)
2140 joy.calib_data.x3 += 10;
2141 if (joy.calib_data.y1 == joy.calib_data.y2)
2142 joy.calib_data.y1 -= 10;
2143 if (joy.calib_data.y3 == joy.calib_data.y2)
2144 joy.calib_data.y3 += 10;
2149 if (load_flag == 1) {
2150 if ((handle = dat_open("calib.dat", datfile_name, "rb")) == 0) {
2151 strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
2154 joy.calib_data.x1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2155 joy.calib_data.x2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2156 joy.calib_data.x3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2157 joy.calib_data.y1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2158 joy.calib_data.y2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2159 joy.calib_data.y3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2168 void deinit_program(void)
2175 dj_free_mod(MOD_MENU);
2176 dj_free_mod(MOD_GAME);
2177 dj_free_sfx(SFX_DEATH);
2178 dj_free_sfx(SFX_SPRING);
2179 dj_free_sfx(SFX_SPLASH);
2182 if (background_pic != 0)
2183 free(background_pic);
2187 remove_keyb_handler();
2191 __dpmi_int(0x10, ®s);
2194 if (main_info.error_str[0] != 0) {
2195 printf(main_info.error_str);
2197 MessageBox(0, main_info.error_str, "Jump'n'Bump", 0);
2206 unsigned short rnd(unsigned short max)
2208 return (rand() % max);
2212 int read_level(void)
2218 if ((handle = dat_open("levelmap.txt", datfile_name, "rb")) == 0) {
2219 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2223 for (c1 = 0; c1 < 16; c1++) {
2224 for (c2 = 0; c2 < 22; c2++) {
2226 chr = fgetc(handle);
2231 if (chr >= '0' && chr <= '4')
2235 ban_map[c1][21-c2] = chr - '0';
2237 ban_map[c1][c2] = chr - '0';
2241 for (c2 = 0; c2 < 22; c2++)
2242 ban_map[16][c2] = BAN_SOLID;
2250 FILE *dat_open(char *file_name, char *dat_name, char *mode)
2258 handle = fopen(dat_name, mode);
2262 memset(name, 0, sizeof(name));
2264 num = fgetc(handle);
2265 num+= (fgetc(handle) << 8);
2266 num+= (fgetc(handle) << 16);
2267 num+= (fgetc(handle) << 24);
2269 for (c1 = 0; c1 < num; c1++) {
2270 if (!fread(name, 1, 12, handle)) {
2274 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2275 ofs = fgetc(handle);
2276 ofs += (fgetc(handle) << 8);
2277 ofs += (fgetc(handle) << 16);
2278 ofs += (fgetc(handle) << 24);
2279 fseek(handle, ofs, SEEK_SET);
2282 fseek(handle, 8, SEEK_CUR);
2291 int dat_filelen(char *file_name, char *dat_name)
2299 handle = fopen(dat_name, "rb");
2303 memset(name, 0, sizeof(name));
2305 num = fgetc(handle);
2306 num+= (fgetc(handle) << 8);
2307 num+= (fgetc(handle) << 16);
2308 num+= (fgetc(handle) << 24);
2310 for (c1 = 0; c1 < num; c1++) {
2311 if (!fread(name, 1, 12, handle)) {
2315 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2316 fseek(handle, 4, SEEK_CUR);
2317 len = fgetc(handle);
2318 len += (fgetc(handle) << 8);
2319 len += (fgetc(handle) << 16);
2320 len += (fgetc(handle) << 24);
2325 fseek(handle, 8, SEEK_CUR);
2334 int filelength(int handle)
2338 if (fstat(handle, &buf) == -1) {
2339 perror("filelength");
2348 void write_calib_data(void)
2356 if ((handle = fopen(datfile_name, "rb")) == NULL)
2358 len = filelength(fileno(handle));
2359 if ((mem = malloc(len)) == NULL)
2361 fread(mem, 1, len, handle);
2365 num = *(int *) (&mem[0]);
2366 for (c1 = 0; c1 < num; c1++) {
2367 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
2368 ofs = *(int *) (&mem[ofs + 12]);
2374 mem[ofs] = joy.calib_data.x1 & 0xff;
2375 mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
2376 mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
2377 mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
2378 mem[ofs + 4] = joy.calib_data.x2 & 0xff;
2379 mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
2380 mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
2381 mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
2382 mem[ofs + 8] = joy.calib_data.x3 & 0xff;
2383 mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
2384 mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
2385 mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
2386 mem[ofs + 12] = joy.calib_data.y1 & 0xff;
2387 mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
2388 mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
2389 mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
2390 mem[ofs + 16] = joy.calib_data.y2 & 0xff;
2391 mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
2392 mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
2393 mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
2394 mem[ofs + 20] = joy.calib_data.y3 & 0xff;
2395 mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
2396 mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
2397 mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
2399 if ((handle = fopen(datfile_name, "wb")) == NULL)
2401 fwrite(mem, 1, len, handle);