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 for (c1 = 0; c1 < 16; c1++) { // fix dark font
791 pal[(240 + c1) * 3 + 0] = c1 << 2;
792 pal[(240 + c1) * 3 + 1] = c1 << 2;
793 pal[(240 + c1) * 3 + 2] = c1 << 2;
796 memset(cur_pal, 0, 768);
798 setpalette(0, 256, cur_pal);
801 dj_ready_mod(MOD_SCORES);
802 dj_set_mod_volume((char)mod_vol);
806 while (key_pressed(1) == 0) {
809 dj_set_mod_volume((char)mod_vol);
810 for (c1 = 0; c1 < 768; c1++) {
811 if (cur_pal[c1] < pal[c1])
817 setpalette(0, 256, cur_pal);
818 flippage(main_info.view_page);
820 while (key_pressed(1) == 1) {
827 while (mod_vol > 0) {
829 dj_set_mod_volume((char)mod_vol);
830 for (c1 = 0; c1 < 768; c1++) {
831 if (cur_pal[c1] > pal[c1])
836 setpalette(0, 256, cur_pal);
837 flippage(main_info.view_page);
840 fillpalette(0, 0, 0);
853 void steer_players(void)
858 update_player_actions();
860 for (c1 = 0; c1 < 4; c1++) {
862 if (player[c1].enabled == 1) {
864 if (player[c1].dead_flag == 0) {
866 if (player[c1].action_left && player[c1].action_right) {
867 if (player[c1].direction == 0) {
868 if (player[c1].action_right) {
869 s1 = (player[c1].x >> 16);
870 s2 = (player[c1].y >> 16);
871 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
872 if (player[c1].x_add < 0)
873 player[c1].x_add += 1024;
875 player[c1].x_add += 768;
876 } 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)) {
877 if (player[c1].x_add > 0)
878 player[c1].x_add += 1024;
880 player[c1].x_add += 768;
882 if (player[c1].x_add < 0) {
883 player[c1].x_add += 16384;
884 if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
885 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);
887 player[c1].x_add += 12288;
889 if (player[c1].x_add > 98304L)
890 player[c1].x_add = 98304L;
891 player[c1].direction = 0;
892 if (player[c1].anim == 0) {
894 player[c1].frame = 0;
895 player[c1].frame_tick = 0;
896 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
900 if (player[c1].action_left) {
901 s1 = (player[c1].x >> 16);
902 s2 = (player[c1].y >> 16);
903 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
904 if (player[c1].x_add > 0)
905 player[c1].x_add -= 1024;
907 player[c1].x_add -= 768;
908 } 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)) {
909 if (player[c1].x_add > 0)
910 player[c1].x_add -= 1024;
912 player[c1].x_add -= 768;
914 if (player[c1].x_add > 0) {
915 player[c1].x_add -= 16384;
916 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
917 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);
919 player[c1].x_add -= 12288;
921 if (player[c1].x_add < -98304L)
922 player[c1].x_add = -98304L;
923 player[c1].direction = 1;
924 if (player[c1].anim == 0) {
926 player[c1].frame = 0;
927 player[c1].frame_tick = 0;
928 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
932 } else if (player[c1].action_left) {
933 s1 = (player[c1].x >> 16);
934 s2 = (player[c1].y >> 16);
935 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
936 if (player[c1].x_add > 0)
937 player[c1].x_add -= 1024;
939 player[c1].x_add -= 768;
940 } 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)) {
941 if (player[c1].x_add > 0)
942 player[c1].x_add -= 1024;
944 player[c1].x_add -= 768;
946 if (player[c1].x_add > 0) {
947 player[c1].x_add -= 16384;
948 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
949 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);
951 player[c1].x_add -= 12288;
953 if (player[c1].x_add < -98304L)
954 player[c1].x_add = -98304L;
955 player[c1].direction = 1;
956 if (player[c1].anim == 0) {
958 player[c1].frame = 0;
959 player[c1].frame_tick = 0;
960 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
962 } else if (player[c1].action_right) {
963 s1 = (player[c1].x >> 16);
964 s2 = (player[c1].y >> 16);
965 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
966 if (player[c1].x_add < 0)
967 player[c1].x_add += 1024;
969 player[c1].x_add += 768;
970 } 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)) {
971 if (player[c1].x_add > 0)
972 player[c1].x_add += 1024;
974 player[c1].x_add += 768;
976 if (player[c1].x_add < 0) {
977 player[c1].x_add += 16384;
978 if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
979 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);
981 player[c1].x_add += 12288;
983 if (player[c1].x_add > 98304L)
984 player[c1].x_add = 98304L;
985 player[c1].direction = 0;
986 if (player[c1].anim == 0) {
988 player[c1].frame = 0;
989 player[c1].frame_tick = 0;
990 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
992 } else if ((!player[c1].action_left) && (!player[c1].action_right)) {
993 s1 = (player[c1].x >> 16);
994 s2 = (player[c1].y >> 16);
995 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)))) {
996 if (player[c1].x_add < 0) {
997 player[c1].x_add += 16384;
998 if (player[c1].x_add > 0)
999 player[c1].x_add = 0;
1001 player[c1].x_add -= 16384;
1002 if (player[c1].x_add < 0)
1003 player[c1].x_add = 0;
1005 if (player[c1].x_add != 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1006 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);
1008 if (player[c1].anim == 1) {
1009 player[c1].anim = 0;
1010 player[c1].frame = 0;
1011 player[c1].frame_tick = 0;
1012 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1016 if (pogostick == 1 || (player[c1].jump_ready == 1 && player[c1].action_up)) {
1017 s1 = (player[c1].x >> 16);
1018 s2 = (player[c1].y >> 16);
1021 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) {
1022 player[c1].y_add = -280000L;
1023 player[c1].anim = 2;
1024 player[c1].frame = 0;
1025 player[c1].frame_tick = 0;
1026 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1027 player[c1].jump_ready = 0;
1028 player[c1].jump_abort = 1;
1030 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1032 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1034 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)) {
1035 player[c1].y_add = -196608L;
1036 player[c1].in_water = 0;
1037 player[c1].anim = 2;
1038 player[c1].frame = 0;
1039 player[c1].frame_tick = 0;
1040 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1041 player[c1].jump_ready = 0;
1042 player[c1].jump_abort = 1;
1044 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1046 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1049 if (pogostick == 0 && (!player[c1].action_up)) {
1050 player[c1].jump_ready = 1;
1051 if (player[c1].in_water == 0 && player[c1].y_add < 0 && player[c1].jump_abort == 1) {
1052 if (bunnies_in_space == 0)
1053 player[c1].y_add += 32768;
1055 player[c1].y_add += 16384;
1056 if (player[c1].y_add > 0)
1057 player[c1].y_add = 0;
1062 if (player[c1].action_up) {
1063 player[c1].y_add -= 16384;
1064 if (player[c1].y_add < -400000L)
1065 player[c1].y_add = -400000L;
1066 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))
1067 player[c1].in_water = 0;
1069 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);
1074 player[c1].x += player[c1].x_add;
1075 if ((player[c1].x >> 16) < 0) {
1077 player[c1].x_add = 0;
1079 if ((player[c1].x >> 16) + 15 > 351) {
1080 player[c1].x = 336L << 16;
1081 player[c1].x_add = 0;
1083 if (player[c1].y > 0) {
1084 s1 = (player[c1].x >> 16);
1085 s2 = (player[c1].y >> 16);
1086 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) {
1087 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1088 player[c1].x_add = 0;
1090 s1 = (player[c1].x >> 16);
1091 s2 = (player[c1].y >> 16);
1092 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) {
1093 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1094 player[c1].x_add = 0;
1097 s1 = (player[c1].x >> 16);
1099 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) {
1100 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1101 player[c1].x_add = 0;
1103 s1 = (player[c1].x >> 16);
1105 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) {
1106 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1107 player[c1].x_add = 0;
1111 player[c1].y += player[c1].y_add;
1113 s1 = (player[c1].x >> 16);
1114 s2 = (player[c1].y >> 16);
1115 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))) {
1116 player[c1].y = ((player[c1].y >> 16) & 0xfff0) << 16;
1117 player[c1].y_add = -400000L;
1118 player[c1].anim = 2;
1119 player[c1].frame = 0;
1120 player[c1].frame_tick = 0;
1121 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1122 player[c1].jump_ready = 0;
1123 player[c1].jump_abort = 0;
1124 for (c2 = 0; c2 < NUM_OBJECTS; c2++) {
1125 if (objects[c2].used == 1 && objects[c2].type == OBJ_SPRING) {
1126 if (ban_map[(s2 + 15) >> 4][(s1 + 8) >> 4] == BAN_SPRING) {
1127 if ((objects[c2].x >> 20) == ((s1 + 8) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1128 objects[c2].frame = 0;
1129 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1130 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1134 if (ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
1135 if ((objects[c2].x >> 20) == (s1 >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1136 objects[c2].frame = 0;
1137 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1138 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1141 } else if (ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1142 if ((objects[c2].x >> 20) == ((s1 + 15) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1143 objects[c2].frame = 0;
1144 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1145 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1152 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1154 s1 = (player[c1].x >> 16);
1155 s2 = (player[c1].y >> 16);
1158 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) {
1159 player[c1].y = (((s2 + 16) & 0xfff0)) << 16;
1160 player[c1].y_add = 0;
1161 player[c1].anim = 0;
1162 player[c1].frame = 0;
1163 player[c1].frame_tick = 0;
1164 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1166 s1 = (player[c1].x >> 16);
1167 s2 = (player[c1].y >> 16);
1170 if (ban_map[(s2 + 8) >> 4][(s1 + 8) >> 4] == BAN_WATER) {
1171 if (player[c1].in_water == 0) {
1172 player[c1].in_water = 1;
1173 player[c1].anim = 4;
1174 player[c1].frame = 0;
1175 player[c1].frame_tick = 0;
1176 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1177 if (player[c1].y_add >= 32768) {
1178 add_object(OBJ_SPLASH, (player[c1].x >> 16) + 8, ((player[c1].y >> 16) & 0xfff0) + 15, 0, 0, OBJ_ANIM_SPLASH, 0);
1179 if (blood_is_thicker_than_water == 0)
1180 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1182 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 5000), 64, 0, 0, -1);
1185 player[c1].y_add -= 1536;
1186 if (player[c1].y_add < 0 && player[c1].anim != 5) {
1187 player[c1].anim = 5;
1188 player[c1].frame = 0;
1189 player[c1].frame_tick = 0;
1190 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1192 if (player[c1].y_add < -65536L)
1193 player[c1].y_add = -65536L;
1194 if (player[c1].y_add > 65535L)
1195 player[c1].y_add = 65535L;
1196 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) {
1197 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1198 player[c1].y_add = 0;
1200 } 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) {
1201 player[c1].in_water = 0;
1202 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1203 player[c1].y_add = 0;
1204 if (player[c1].anim != 0 && player[c1].anim != 1) {
1205 player[c1].anim = 0;
1206 player[c1].frame = 0;
1207 player[c1].frame_tick = 0;
1208 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1211 if (player[c1].in_water == 0) {
1212 if (bunnies_in_space == 0)
1213 player[c1].y_add += 12288;
1215 player[c1].y_add += 6144;
1216 if (player[c1].y_add > 327680L)
1217 player[c1].y_add = 327680L;
1219 player[c1].y = (player[c1].y & 0xffff0000) + 0x10000;
1220 player[c1].y_add = 0;
1222 player[c1].in_water = 0;
1224 if (player[c1].y_add > 36864 && player[c1].anim != 3 && player[c1].in_water == 0) {
1225 player[c1].anim = 3;
1226 player[c1].frame = 0;
1227 player[c1].frame_tick = 0;
1228 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1233 player[c1].frame_tick++;
1234 if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
1236 if (player[c1].frame >= player_anims[player[c1].anim].num_frames) {
1237 if (player[c1].anim != 6)
1238 player[c1].frame = player_anims[player[c1].anim].restart_frame;
1240 position_player(c1);
1242 player[c1].frame_tick = 0;
1244 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1253 void position_player(int player_num)
1262 if (ban_map[s2][s1] == BAN_VOID && (ban_map[s2 + 1][s1] == BAN_SOLID || ban_map[s2 + 1][s1] == BAN_ICE))
1265 for (c1 = 0; c1 < 4; c1++) {
1266 if (c1 != player_num && player[c1].enabled == 1) {
1267 if (abs((s1 << 4) - (player[c1].x >> 16)) < 32 && abs((s2 << 4) - (player[c1].y >> 16)) < 32)
1272 player[player_num].dead_flag = 0;
1273 player[player_num].x = (long) s1 << 20;
1274 player[player_num].y = (long) s2 << 20;
1275 player[player_num].x_add = player[player_num].y_add = 0;
1276 player[player_num].direction = 0;
1277 player[player_num].jump_ready = 1;
1278 player[player_num].in_water = 0;
1279 player[player_num].anim = 0;
1280 player[player_num].frame = 0;
1281 player[player_num].frame_tick = 0;
1282 player[player_num].image = player_anims[player[player_num].anim].frame[player[player_num].frame].image;
1290 void add_object(int type, int x, int y, int x_add, int y_add, int anim, int frame)
1294 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
1295 if (objects[c1].used == 0) {
1296 objects[c1].used = 1;
1297 objects[c1].type = type;
1298 objects[c1].x = (long) x << 16;
1299 objects[c1].y = (long) y << 16;
1300 objects[c1].x_add = x_add;
1301 objects[c1].y_add = y_add;
1302 objects[c1].x_acc = 0;
1303 objects[c1].y_acc = 0;
1304 objects[c1].anim = anim;
1305 objects[c1].frame = frame;
1306 objects[c1].ticks = object_anims[anim].frame[frame].ticks;
1307 objects[c1].image = object_anims[anim].frame[frame].image;
1315 void update_objects(void)
1320 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
1321 if (objects[c1].used == 1) {
1322 switch (objects[c1].type) {
1324 objects[c1].ticks--;
1325 if (objects[c1].ticks <= 0) {
1326 objects[c1].frame++;
1327 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames) {
1328 objects[c1].frame--;
1329 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1331 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1332 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1335 if (objects[c1].used == 1)
1336 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1339 objects[c1].ticks--;
1340 if (objects[c1].ticks <= 0) {
1341 objects[c1].frame++;
1342 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1343 objects[c1].used = 0;
1345 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1346 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1349 if (objects[c1].used == 1)
1350 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1353 objects[c1].x += objects[c1].x_add;
1354 objects[c1].y += objects[c1].y_add;
1355 objects[c1].ticks--;
1356 if (objects[c1].ticks <= 0) {
1357 objects[c1].frame++;
1358 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1359 objects[c1].used = 0;
1361 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1362 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1365 if (objects[c1].used == 1)
1366 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1368 case OBJ_YEL_BUTFLY:
1369 case OBJ_PINK_BUTFLY:
1370 objects[c1].x_acc += rnd(128) - 64;
1371 if (objects[c1].x_acc < -1024)
1372 objects[c1].x_acc = -1024;
1373 if (objects[c1].x_acc > 1024)
1374 objects[c1].x_acc = 1024;
1375 objects[c1].x_add += objects[c1].x_acc;
1376 if (objects[c1].x_add < -32768)
1377 objects[c1].x_add = -32768;
1378 if (objects[c1].x_add > 32768)
1379 objects[c1].x_add = 32768;
1380 objects[c1].x += objects[c1].x_add;
1381 if ((objects[c1].x >> 16) < 16) {
1382 objects[c1].x = 16 << 16;
1383 objects[c1].x_add = -objects[c1].x_add >> 2;
1384 objects[c1].x_acc = 0;
1385 } else if ((objects[c1].x >> 16) > 350) {
1386 objects[c1].x = 350 << 16;
1387 objects[c1].x_add = -objects[c1].x_add >> 2;
1388 objects[c1].x_acc = 0;
1390 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
1391 if (objects[c1].x_add < 0) {
1392 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
1394 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
1396 objects[c1].x_add = -objects[c1].x_add >> 2;
1397 objects[c1].x_acc = 0;
1399 objects[c1].y_acc += rnd(64) - 32;
1400 if (objects[c1].y_acc < -1024)
1401 objects[c1].y_acc = -1024;
1402 if (objects[c1].y_acc > 1024)
1403 objects[c1].y_acc = 1024;
1404 objects[c1].y_add += objects[c1].y_acc;
1405 if (objects[c1].y_add < -32768)
1406 objects[c1].y_add = -32768;
1407 if (objects[c1].y_add > 32768)
1408 objects[c1].y_add = 32768;
1409 objects[c1].y += objects[c1].y_add;
1410 if ((objects[c1].y >> 16) < 0) {
1412 objects[c1].y_add = -objects[c1].y_add >> 2;
1413 objects[c1].y_acc = 0;
1414 } else if ((objects[c1].y >> 16) > 255) {
1415 objects[c1].y = 255 << 16;
1416 objects[c1].y_add = -objects[c1].y_add >> 2;
1417 objects[c1].y_acc = 0;
1419 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
1420 if (objects[c1].y_add < 0) {
1421 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
1423 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1425 objects[c1].y_add = -objects[c1].y_add >> 2;
1426 objects[c1].y_acc = 0;
1428 if (objects[c1].type == OBJ_YEL_BUTFLY) {
1429 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_LEFT) {
1430 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_LEFT;
1431 objects[c1].frame = 0;
1432 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1433 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1434 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_RIGHT) {
1435 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_RIGHT;
1436 objects[c1].frame = 0;
1437 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1438 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1441 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_LEFT) {
1442 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_LEFT;
1443 objects[c1].frame = 0;
1444 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1445 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1446 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_RIGHT) {
1447 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_RIGHT;
1448 objects[c1].frame = 0;
1449 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1450 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1453 objects[c1].ticks--;
1454 if (objects[c1].ticks <= 0) {
1455 objects[c1].frame++;
1456 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1457 objects[c1].frame = object_anims[objects[c1].anim].restart_frame;
1459 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1460 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1463 if (objects[c1].used == 1)
1464 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1468 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 0);
1469 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
1470 objects[c1].y_add += 3072;
1471 if (objects[c1].y_add > 196608L)
1472 objects[c1].y_add = 196608L;
1473 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
1474 if (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 if (objects[c1].x_add > 65536L)
1482 objects[c1].x_add = 65536L;
1483 objects[c1].x_add -= 1024;
1484 if (objects[c1].x_add < 0)
1485 objects[c1].x_add = 0;
1487 objects[c1].y_add += 1024;
1488 if (objects[c1].y_add < -65536L)
1489 objects[c1].y_add = -65536L;
1490 if (objects[c1].y_add > 65536L)
1491 objects[c1].y_add = 65536L;
1493 objects[c1].x += objects[c1].x_add;
1494 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)) {
1495 if (objects[c1].x_add < 0) {
1496 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
1497 objects[c1].x_add = -objects[c1].x_add >> 2;
1499 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
1500 objects[c1].x_add = -objects[c1].x_add >> 2;
1503 objects[c1].y += objects[c1].y_add;
1504 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
1505 objects[c1].used = 0;
1506 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
1507 if (objects[c1].y_add < 0) {
1508 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
1509 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
1510 objects[c1].x_add >>= 2;
1511 objects[c1].y_add = -objects[c1].y_add >> 2;
1514 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
1515 if (objects[c1].y_add > 131072L) {
1516 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1517 objects[c1].x_add >>= 2;
1518 objects[c1].y_add = -objects[c1].y_add >> 2;
1520 objects[c1].used = 0;
1521 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
1522 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1523 if (objects[c1].y_add > 131072L)
1524 objects[c1].y_add = -objects[c1].y_add >> 2;
1526 objects[c1].y_add = 0;
1530 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
1531 objects[c1].x_add = -16384;
1532 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
1533 objects[c1].x_add = 16384;
1534 if (objects[c1].used == 1) {
1535 s1 = (int)(atan2(objects[c1].y_add, objects[c1].x_add) * 4 / M_PI);
1542 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame + s1, &object_gobs);
1546 if (rnd(100) < 30) {
1547 if (objects[c1].frame == 76)
1548 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 1);
1549 else if (objects[c1].frame == 77)
1550 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 2);
1551 else if (objects[c1].frame == 78)
1552 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 3);
1554 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
1555 objects[c1].y_add += 3072;
1556 if (objects[c1].y_add > 196608L)
1557 objects[c1].y_add = 196608L;
1558 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
1559 if (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 if (objects[c1].x_add > 65536L)
1567 objects[c1].x_add = 65536L;
1568 objects[c1].x_add -= 1024;
1569 if (objects[c1].x_add < 0)
1570 objects[c1].x_add = 0;
1572 objects[c1].y_add += 1024;
1573 if (objects[c1].y_add < -65536L)
1574 objects[c1].y_add = -65536L;
1575 if (objects[c1].y_add > 65536L)
1576 objects[c1].y_add = 65536L;
1578 objects[c1].x += objects[c1].x_add;
1579 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)) {
1580 if (objects[c1].x_add < 0) {
1581 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
1582 objects[c1].x_add = -objects[c1].x_add >> 2;
1584 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
1585 objects[c1].x_add = -objects[c1].x_add >> 2;
1588 objects[c1].y += objects[c1].y_add;
1589 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
1590 objects[c1].used = 0;
1591 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
1592 if (objects[c1].y_add < 0) {
1593 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
1594 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
1595 objects[c1].x_add >>= 2;
1596 objects[c1].y_add = -objects[c1].y_add >> 2;
1599 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
1600 if (objects[c1].y_add > 131072L) {
1601 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1602 objects[c1].x_add >>= 2;
1603 objects[c1].y_add = -objects[c1].y_add >> 2;
1605 if (rnd(100) < 10) {
1607 add_leftovers(0, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
1608 add_leftovers(1, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
1610 objects[c1].used = 0;
1612 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
1613 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1614 if (objects[c1].y_add > 131072L)
1615 objects[c1].y_add = -objects[c1].y_add >> 2;
1617 objects[c1].y_add = 0;
1621 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
1622 objects[c1].x_add = -16384;
1623 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
1624 objects[c1].x_add = 16384;
1625 if (objects[c1].used == 1)
1626 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame, &object_gobs);
1628 case OBJ_FLESH_TRACE:
1629 objects[c1].ticks--;
1630 if (objects[c1].ticks <= 0) {
1631 objects[c1].frame++;
1632 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1633 objects[c1].used = 0;
1635 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1636 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1639 if (objects[c1].used == 1)
1640 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1649 int add_pob(int page, int x, int y, int image, gob_t *pob_data)
1652 if (main_info.page_info[page].num_pobs >= NUM_POBS)
1655 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].x = x;
1656 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].y = y;
1657 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].image = image;
1658 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].pob_data = pob_data;
1659 main_info.page_info[page].num_pobs++;
1666 void draw_flies(int page)
1670 for (c2 = 0; c2 < NUM_FLIES; c2++) {
1671 flies[c2].back[main_info.draw_page] = get_pixel(main_info.draw_page, flies[c2].x, flies[c2].y);
1672 flies[c2].back_defined[main_info.draw_page] = 1;
1673 if (mask_pic[(flies[c2].y * JNB_WIDTH) + flies[c2].x] == 0)
1674 set_pixel(main_info.draw_page, flies[c2].x, flies[c2].y, 0);
1678 void draw_pobs(int page)
1685 for (c1 = main_info.page_info[page].num_pobs - 1; c1 >= 0; c1--) {
1686 main_info.page_info[page].pobs[c1].back_buf_ofs = back_buf_ofs;
1687 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);
1689 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;
1691 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;
1692 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);
1698 void redraw_flies_background(int page)
1702 for (c2 = NUM_FLIES - 1; c2 >= 0; c2--) {
1703 if (flies[c2].back_defined[page] == 1)
1704 set_pixel(page, flies[c2].old_draw_x, flies[c2].old_draw_y, flies[c2].back[page]);
1705 flies[c2].old_draw_x = flies[c2].x;
1706 flies[c2].old_draw_y = flies[c2].y;
1711 void redraw_pob_backgrounds(int page)
1715 for (c1 = 0; c1 < main_info.page_info[page].num_pobs; c1++)
1716 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);
1721 int add_leftovers(int page, int x, int y, int image, gob_t *pob_data)
1724 if (leftovers.page[page].num_pobs >= NUM_LEFTOVERS)
1727 leftovers.page[page].pobs[leftovers.page[page].num_pobs].x = x;
1728 leftovers.page[page].pobs[leftovers.page[page].num_pobs].y = y;
1729 leftovers.page[page].pobs[leftovers.page[page].num_pobs].image = image;
1730 leftovers.page[page].pobs[leftovers.page[page].num_pobs].pob_data = pob_data;
1731 leftovers.page[page].num_pobs++;
1738 void draw_leftovers(int page)
1742 for (c1 = leftovers.page[page].num_pobs - 1; c1 >= 0; c1--)
1743 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);
1745 leftovers.page[page].num_pobs = 0;
1750 int init_level(int level, char *pal)
1756 if ((handle = dat_open("level.pcx", datfile_name, "rb")) == 0) {
1757 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
1760 if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
1761 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
1766 flip_pixels(background_pic);
1767 if ((handle = dat_open("mask.pcx", datfile_name, "rb")) == 0) {
1768 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
1771 if (read_pcx(handle, mask_pic, 102400L, 0) != 0) {
1772 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
1777 flip_pixels(mask_pic);
1778 register_mask(mask_pic);
1780 for (c1 = 0; c1 < 4; c1++) {
1781 if (player[c1].enabled == 1) {
1782 player[c1].bumps = 0;
1783 player[c1].bumped[0] = 0;
1784 player[c1].bumped[1] = 0;
1785 player[c1].bumped[2] = 0;
1786 player[c1].bumped[3] = 0;
1787 position_player(c1);
1791 for (c1 = 0; c1 < NUM_OBJECTS; c1++)
1792 objects[c1].used = 0;
1794 for (c1 = 0; c1 < 16; c1++) {
1795 for (c2 = 0; c2 < 22; c2++) {
1796 if (ban_map[c1][c2] == BAN_SPRING)
1797 add_object(OBJ_SPRING, c2 << 4, c1 << 4, 0, 0, OBJ_ANIM_SPRING, 5);
1804 if (ban_map[s2][s1] == BAN_VOID) {
1805 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1812 if (ban_map[s2][s1] == BAN_VOID) {
1813 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1820 if (ban_map[s2][s1] == BAN_VOID) {
1821 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1828 if (ban_map[s2][s1] == BAN_VOID) {
1829 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1839 void deinit_level(void)
1846 int init_program(int argc, char *argv[], char *pal)
1848 FILE *handle = (FILE *) NULL;
1853 int player_anim_data[] = {
1854 1, 0, 0, 0x7fff, 0, 0, 0, 0, 0, 0,
1855 4, 0, 0, 4, 1, 4, 2, 4, 3, 4,
1856 1, 0, 4, 0x7fff, 0, 0, 0, 0, 0, 0,
1857 4, 2, 5, 8, 6, 10, 7, 3, 6, 3,
1858 1, 0, 6, 0x7fff, 0, 0, 0, 0, 0, 0,
1859 2, 1, 5, 8, 4, 0x7fff, 0, 0, 0, 0,
1860 1, 0, 8, 5, 0, 0, 0, 0, 0, 0
1864 if (__djgpp_nearptr_enable() == 0)
1870 if (hook_keyb_handler() != 0)
1873 memset(&main_info, 0, sizeof(main_info));
1875 strcpy(datfile_name, DATA_PATH);
1877 force2 = force3 = 0;
1880 for (c1 = 1; c1 < argc; c1++) {
1881 if (stricmp(argv[c1], "-nosound") == 0)
1882 main_info.no_sound = 1;
1883 else if (stricmp(argv[c1], "-musicnosound") == 0)
1884 main_info.music_no_sound = 1;
1885 else if (stricmp(argv[c1], "-nogore") == 0)
1886 main_info.no_gore = 1;
1887 else if (stricmp(argv[c1], "-nojoy") == 0)
1888 main_info.joy_enabled = 0;
1889 else if (stricmp(argv[c1], "-fireworks") == 0)
1890 main_info.fireworks = 1;
1892 else if (stricmp(argv[c1], "-fullscreen") == 0)
1895 else if (stricmp(argv[c1], "-scaleup") == 0)
1897 else if (stricmp(argv[c1], "-mirror") == 0)
1899 else if (stricmp(argv[c1], "-dat") == 0) {
1900 if (c1 < (argc - 1)) {
1901 if ((handle = fopen(argv[c1 + 1], "rb")) != NULL) {
1903 strcpy(datfile_name, argv[c1 + 1]);
1906 } else if (stricmp(argv[c1], "-mouse") == 0) {
1907 if (c1 < (argc - 1)) {
1908 if (stricmp(argv[c1 + 1], "2") == 0)
1910 if (stricmp(argv[c1 + 1], "3") == 0)
1914 else if (strstr(argv[1],"-v")) {
1915 printf("jumpnbump %s compiled %s at %s with",JNB_VERSION,__DATE__,__TIME__);
1919 printf(" network support.\n");
1922 else if (strstr(argv[1],"-h")) {
1923 printf("Usage: jumpnbump [OPTION]...\n");
1925 printf(" -h this help\n");
1926 printf(" -v print version\n");
1927 printf(" -dat level.dat play a different level\n");
1928 printf(" -port port define listen port\n");
1929 printf(" -net player host rport define network players\n");
1930 printf(" -fireworks screensaver mode\n");
1931 printf(" -fullscreen run in fullscreen mode\n");
1932 printf(" -nosound play without sound\n");
1933 printf(" -nogore play without blood\n");
1934 printf(" -mirror play with mirrored level\n");
1935 printf(" -scaleup play with doubled resolution (800x512)\n");
1942 main_info.pob_backbuf[0] = malloc(screen_pitch*screen_height*bytes_per_pixel);
1943 main_info.pob_backbuf[1] = malloc(screen_pitch*screen_height*bytes_per_pixel);
1945 for (c1 = 0; c1 < 7; c1++) {
1946 player_anims[c1].num_frames = player_anim_data[c1 * 10];
1947 player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
1948 for (c2 = 0; c2 < 4; c2++) {
1949 player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
1950 player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
1954 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
1955 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1958 if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
1959 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1964 if ((handle = dat_open("rabbit.gob", datfile_name, "rb")) == 0) {
1965 strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
1968 if (register_gob(handle, &rabbit_gobs, dat_filelen("rabbit.gob", datfile_name))) {
1975 if ((handle = dat_open("objects.gob", datfile_name, "rb")) == 0) {
1976 strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
1979 if (register_gob(handle, &object_gobs, dat_filelen("objects.gob", datfile_name))) {
1986 if ((handle = dat_open("font.gob", datfile_name, "rb")) == 0) {
1987 strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
1990 if (register_gob(handle, &font_gobs, dat_filelen("font.gob", datfile_name))) {
1997 if ((handle = dat_open("numbers.gob", datfile_name, "rb")) == 0) {
1998 strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
2001 if (register_gob(handle, &number_gobs, dat_filelen("numbers.gob", datfile_name))) {
2008 if (read_level() != 0) {
2009 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2016 if (main_info.no_sound == 0) {
2018 dj_set_mixing_freq(20000);
2022 dj_set_num_sfx_channels(5);
2023 dj_set_sfx_volume(64);
2027 if ((handle = dat_open("jump.mod", datfile_name, "rb")) == 0) {
2028 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2031 if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
2032 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2037 if ((handle = dat_open("bump.mod", datfile_name, "rb")) == 0) {
2038 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2041 if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
2042 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2047 if ((handle = dat_open("scores.mod", datfile_name, "rb")) == 0) {
2048 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2051 if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
2052 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2057 if ((handle = dat_open("jump.smp", datfile_name, "rb")) == 0) {
2058 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2061 if (dj_load_sfx(handle, 0, dat_filelen("jump.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
2062 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2067 if ((handle = dat_open("death.smp", datfile_name, "rb")) == 0) {
2068 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2071 if (dj_load_sfx(handle, 0, dat_filelen("death.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
2072 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2077 if ((handle = dat_open("spring.smp", datfile_name, "rb")) == 0) {
2078 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2081 if (dj_load_sfx(handle, 0, dat_filelen("spring.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
2082 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2087 if ((handle = dat_open("splash.smp", datfile_name, "rb")) == 0) {
2088 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2091 if (dj_load_sfx(handle, 0, dat_filelen("splash.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
2092 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2097 if ((handle = dat_open("fly.smp", datfile_name, "rb")) == 0) {
2098 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2101 if (dj_load_sfx(handle, 0, dat_filelen("fly.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
2102 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2107 dj_get_sfx_settings(SFX_FLY, &fly);
2109 fly.default_freq = SFX_FLY_FREQ;
2112 fly.loop_length = fly.length;
2113 dj_set_sfx_settings(SFX_FLY, &fly);
2116 if ((background_pic = malloc(102400)) == NULL)
2118 if ((mask_pic = malloc(102400)) == NULL)
2120 memset(mask_pic, 0, 102400);
2121 register_mask(mask_pic);
2123 for (c1 = 0; c1 < 16; c1++) { // fix dark font
2124 pal[(240 + c1) * 3 + 0] = c1 << 2;
2125 pal[(240 + c1) * 3 + 1] = c1 << 2;
2126 pal[(240 + c1) * 3 + 2] = c1 << 2;
2129 setpalette(0, 256, pal);
2133 recalculate_gob(&font_gobs, pal);
2135 if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
2137 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2138 put_text(0, 200, 100, "Move the joystick to the", 2);
2139 put_text(0, 200, 115, "UPPER LEFT", 2);
2140 put_text(0, 200, 130, "and press button A", 2);
2141 put_text(0, 200, 200, "Or press ESC to use", 2);
2142 put_text(0, 200, 215, "previous settings", 2);
2143 if (calib_joy(0) != 0)
2146 register_background(NULL, NULL);
2148 main_info.view_page = 1;
2153 put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
2154 put_text(1, 200, 100, "Move the joystick to the", 2);
2155 put_text(1, 200, 115, "LOWER RIGHT", 2);
2156 put_text(1, 200, 130, "and press button A", 2);
2157 put_text(1, 200, 200, "Or press ESC to use", 2);
2158 put_text(1, 200, 215, "previous settings", 2);
2159 if (calib_joy(1) != 0)
2162 register_background(NULL, NULL);
2167 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2168 put_text(0, 200, 100, "Move the joystick to the", 2);
2169 put_text(0, 200, 115, "CENTER", 2);
2170 put_text(0, 200, 130, "and press button A", 2);
2171 put_text(0, 200, 200, "Or press ESC to use", 2);
2172 put_text(0, 200, 215, "previous settings", 2);
2173 if (calib_joy(2) != 0)
2176 if (joy.calib_data.x1 == joy.calib_data.x2)
2177 joy.calib_data.x1 -= 10;
2178 if (joy.calib_data.x3 == joy.calib_data.x2)
2179 joy.calib_data.x3 += 10;
2180 if (joy.calib_data.y1 == joy.calib_data.y2)
2181 joy.calib_data.y1 -= 10;
2182 if (joy.calib_data.y3 == joy.calib_data.y2)
2183 joy.calib_data.y3 += 10;
2188 if (load_flag == 1) {
2189 if ((handle = dat_open("calib.dat", datfile_name, "rb")) == 0) {
2190 strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
2193 joy.calib_data.x1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2194 joy.calib_data.x2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2195 joy.calib_data.x3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2196 joy.calib_data.y1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2197 joy.calib_data.y2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2198 joy.calib_data.y3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2207 void deinit_program(void)
2214 dj_free_mod(MOD_MENU);
2215 dj_free_mod(MOD_GAME);
2216 dj_free_sfx(SFX_DEATH);
2217 dj_free_sfx(SFX_SPRING);
2218 dj_free_sfx(SFX_SPLASH);
2221 if (background_pic != 0)
2222 free(background_pic);
2226 remove_keyb_handler();
2230 __dpmi_int(0x10, ®s);
2233 if (main_info.error_str[0] != 0) {
2234 printf(main_info.error_str);
2236 MessageBox(0, main_info.error_str, "Jump'n'Bump", 0);
2245 unsigned short rnd(unsigned short max)
2247 return (rand() % max);
2251 int read_level(void)
2257 if ((handle = dat_open("levelmap.txt", datfile_name, "rb")) == 0) {
2258 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2262 for (c1 = 0; c1 < 16; c1++) {
2263 for (c2 = 0; c2 < 22; c2++) {
2265 chr = fgetc(handle);
2270 if (chr >= '0' && chr <= '4')
2274 ban_map[c1][21-c2] = chr - '0';
2276 ban_map[c1][c2] = chr - '0';
2280 for (c2 = 0; c2 < 22; c2++)
2281 ban_map[16][c2] = BAN_SOLID;
2289 FILE *dat_open(char *file_name, char *dat_name, char *mode)
2297 handle = fopen(dat_name, mode);
2301 memset(name, 0, sizeof(name));
2303 num = fgetc(handle);
2304 num+= (fgetc(handle) << 8);
2305 num+= (fgetc(handle) << 16);
2306 num+= (fgetc(handle) << 24);
2308 for (c1 = 0; c1 < num; c1++) {
2309 if (!fread(name, 1, 12, handle)) {
2313 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2314 ofs = fgetc(handle);
2315 ofs += (fgetc(handle) << 8);
2316 ofs += (fgetc(handle) << 16);
2317 ofs += (fgetc(handle) << 24);
2318 fseek(handle, ofs, SEEK_SET);
2321 fseek(handle, 8, SEEK_CUR);
2330 int dat_filelen(char *file_name, char *dat_name)
2338 handle = fopen(dat_name, "rb");
2342 memset(name, 0, sizeof(name));
2344 num = fgetc(handle);
2345 num+= (fgetc(handle) << 8);
2346 num+= (fgetc(handle) << 16);
2347 num+= (fgetc(handle) << 24);
2349 for (c1 = 0; c1 < num; c1++) {
2350 if (!fread(name, 1, 12, handle)) {
2354 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2355 fseek(handle, 4, SEEK_CUR);
2356 len = fgetc(handle);
2357 len += (fgetc(handle) << 8);
2358 len += (fgetc(handle) << 16);
2359 len += (fgetc(handle) << 24);
2364 fseek(handle, 8, SEEK_CUR);
2373 int filelength(int handle)
2377 if (fstat(handle, &buf) == -1) {
2378 perror("filelength");
2387 void write_calib_data(void)
2395 if ((handle = fopen(datfile_name, "rb")) == NULL)
2397 len = filelength(fileno(handle));
2398 if ((mem = malloc(len)) == NULL)
2400 fread(mem, 1, len, handle);
2404 num = *(int *) (&mem[0]);
2405 for (c1 = 0; c1 < num; c1++) {
2406 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
2407 ofs = *(int *) (&mem[ofs + 12]);
2413 mem[ofs] = joy.calib_data.x1 & 0xff;
2414 mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
2415 mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
2416 mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
2417 mem[ofs + 4] = joy.calib_data.x2 & 0xff;
2418 mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
2419 mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
2420 mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
2421 mem[ofs + 8] = joy.calib_data.x3 & 0xff;
2422 mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
2423 mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
2424 mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
2425 mem[ofs + 12] = joy.calib_data.y1 & 0xff;
2426 mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
2427 mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
2428 mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
2429 mem[ofs + 16] = joy.calib_data.y2 & 0xff;
2430 mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
2431 mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
2432 mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
2433 mem[ofs + 20] = joy.calib_data.y3 & 0xff;
2434 mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
2435 mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
2436 mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
2438 if ((handle = fopen(datfile_name, "wb")) == NULL)
2440 fwrite(mem, 1, len, handle);