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];
53 unsigned int ban_map[17][22] = {
54 {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
55 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0},
56 {1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
57 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1},
58 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
59 {1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
60 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1},
61 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
62 {1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
63 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1},
64 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1},
65 {1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1},
66 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
67 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
68 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 1, 3, 3, 3, 1, 1, 1},
69 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
70 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
199 int old_draw_x, old_draw_y;
211 } pobs[NUM_LEFTOVERS];
215 int pogostick, bunnies_in_space, jetpack, lord_of_the_flies, blood_is_thicker_than_water;
217 int main(int argc, char *argv[])
220 int c1, c2 = 0, c3, c4;
223 int closest_player = 0, dist, cur_dist;
224 int end_loop_flag, fade_flag;
225 int mod_vol, sfx_vol, mod_fade_direction;
231 if (init_program(argc, argv, pal) != 0)
234 if (main_info.fireworks == 1) {
244 if (key_pressed(1) == 1) {
247 if (init_level(0, pal) != 0) {
252 memset(cur_pal, 0, 768);
253 setpalette(0, 256, cur_pal);
255 recalculate_gob(&rabbit_gobs, pal);
256 //recalculate_gob(&font_gobs, pal);
257 recalculate_gob(&object_gobs, pal);
258 recalculate_gob(&number_gobs, pal);
261 register_background(background_pic, pal);
266 for (c1 = 0; c1 < NUM_FLIES; c1++) {
268 flies[c1].x = s1 + rnd(101) - 50;
269 flies[c1].y = s2 + rnd(101) - 50;
270 if (ban_map[flies[c1].y >> 4][flies[c1].x >> 4] == BAN_VOID)
273 flies[c1].back_defined[0] = 0;
274 flies[c1].back_defined[1] = 0;
277 mod_vol = sfx_vol = 10;
278 mod_fade_direction = 1;
279 dj_ready_mod(MOD_GAME);
280 dj_set_mod_volume((char)mod_vol);
281 dj_set_sfx_volume((char)mod_vol);
283 dj_play_sfx(SFX_FLY, SFX_FLY_FREQ, 0, 0, 0, 4);
286 lord_of_the_flies = bunnies_in_space = jetpack = pogostick = blood_is_thicker_than_water = 0;
288 main_info.page_info[0].num_pobs = 0;
289 main_info.page_info[1].num_pobs = 0;
290 main_info.view_page = 0;
291 main_info.draw_page = 1;
296 while (update_count) {
298 if (key_pressed(1) == 1) {
301 mod_fade_direction = 0;
304 if (strncmp(last_keys, "kcitsogop", strlen("kcitsogop")) == 0) {
308 if (strncmp(last_keys, "ecapsniseinnub", strlen("ecapsniseinnub")) == 0) {
309 bunnies_in_space ^= 1;
312 if (strncmp(last_keys, "kcaptej", strlen("kcaptej")) == 0) {
316 if (strncmp(last_keys, "seilfehtfodrol", strlen("seilfehtfodrol")) == 0) {
317 lord_of_the_flies ^= 1;
320 if (strncmp(last_keys, "retawnahtrekcihtsidoolb", strlen("retawnahtrekcihtsidoolb")) == 0) {
321 blood_is_thicker_than_water ^= 1;
322 if (blood_is_thicker_than_water == 1) {
373 register_background(background_pic, pal);
374 recalculate_gob(&object_gobs, pal);
382 for (c3 = 0; c3 < 6; c3++) {
386 } else if (c3 == 1) {
389 } else if (c3 == 2) {
392 } else if (c3 == 3) {
395 } else if (c3 == 4) {
398 } else if (c3 == 5) {
402 if (player[c1].enabled == 1 && player[c2].enabled == 1) {
403 if (labs(player[c1].x - player[c2].x) < (12L << 16) && labs(player[c1].y - player[c2].y) < (12L << 16)) {
404 if ((labs(player[c1].y - player[c2].y) >> 16) > 5) {
405 if (player[c1].y < player[c2].y) {
406 if (player[c1].y_add >= 0) {
407 player[c1].y_add = -player[c1].y_add;
408 if (player[c1].y_add > -262144L)
409 player[c1].y_add = -262144L;
410 player[c1].jump_abort = 1;
411 player[c2].dead_flag = 1;
412 if (player[c2].anim != 6) {
414 player[c2].frame = 0;
415 player[c2].frame_tick = 0;
416 player[c2].image = player_anims[player[c2].anim].frame[player[c2].frame].image + player[c2].direction * 9;
417 if (main_info.no_gore == 0) {
418 for (c4 = 0; c4 < 6; c4++)
419 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);
420 for (c4 = 0; c4 < 6; c4++)
421 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);
422 for (c4 = 0; c4 < 6; c4++)
423 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);
424 for (c4 = 0; c4 < 8; c4++)
425 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);
426 for (c4 = 0; c4 < 10; c4++)
427 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);
429 dj_play_sfx(SFX_DEATH, (unsigned short)(SFX_DEATH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
431 player[c1].bumped[c2]++;
432 s1 = player[c1].bumps % 100;
433 add_leftovers(0, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
434 add_leftovers(1, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
435 add_leftovers(0, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
436 add_leftovers(1, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
439 if (player[c2].y_add < 0)
440 player[c2].y_add = 0;
443 if (player[c2].y_add >= 0) {
444 player[c2].y_add = -player[c2].y_add;
445 if (player[c2].y_add > -262144L)
446 player[c2].y_add = -262144L;
447 player[c2].jump_abort = 1;
448 player[c1].dead_flag = 1;
449 if (player[c1].anim != 6) {
451 player[c1].frame = 0;
452 player[c1].frame_tick = 0;
453 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
454 if (main_info.no_gore == 0) {
455 for (c4 = 0; c4 < 6; c4++)
456 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);
457 for (c4 = 0; c4 < 6; c4++)
458 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);
459 for (c4 = 0; c4 < 7; c4++)
460 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);
461 for (c4 = 0; c4 < 8; c4++)
462 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);
463 for (c4 = 0; c4 < 10; c4++)
464 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);
466 dj_play_sfx(SFX_DEATH, (unsigned short)(SFX_DEATH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
468 player[c2].bumped[c1]++;
469 s1 = player[c2].bumps % 100;
470 add_leftovers(0, 360, 34 + c2 * 64, s1 / 10, &number_gobs);
471 add_leftovers(1, 360, 34 + c2 * 64, s1 / 10, &number_gobs);
472 add_leftovers(0, 376, 34 + c2 * 64, s1 - (s1 / 10) * 10, &number_gobs);
473 add_leftovers(1, 376, 34 + c2 * 64, s1 - (s1 / 10) * 10, &number_gobs);
476 if (player[c1].y_add < 0)
477 player[c1].y_add = 0;
481 if (player[c1].x < player[c2].x) {
482 if (player[c1].x_add > 0)
483 player[c1].x = player[c2].x - (12L << 16);
484 else if (player[c2].x_add < 0)
485 player[c2].x = player[c1].x + (12L << 16);
487 player[c1].x -= player[c1].x_add;
488 player[c2].x -= player[c2].x_add;
490 l1 = player[c2].x_add;
491 player[c2].x_add = player[c1].x_add;
492 player[c1].x_add = l1;
493 if (player[c1].x_add > 0)
494 player[c1].x_add = -player[c1].x_add;
495 if (player[c2].x_add < 0)
496 player[c2].x_add = -player[c2].x_add;
498 if (player[c1].x_add > 0)
499 player[c2].x = player[c1].x - (12L << 16);
500 else if (player[c2].x_add < 0)
501 player[c1].x = player[c2].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;
521 main_info.page_info[main_info.draw_page].num_pobs = 0;
522 for (c1 = 0; c1 < 4; c1++) {
523 if (player[c1].enabled == 1)
524 main_info.page_info[main_info.draw_page].num_pobs++;
531 /* get center of fly swarm */
533 for (c1 = 0; c1 < NUM_FLIES; c1++) {
540 if (update_count == 1) {
541 /* get closest player to fly swarm */
543 for (c1 = 0; c1 < 4; c1++) {
544 if (player[c1].enabled == 1) {
545 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)));
546 if (cur_dist < dist) {
552 /* update fly swarm sound */
556 dj_set_sfx_channel_volume(4, (char)(s3));
559 for (c1 = 0; c1 < NUM_FLIES; c1++) {
560 /* get closest player to fly */
562 for (c2 = 0; c2 < 4; c2++) {
563 if (player[c2].enabled == 1) {
564 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)));
565 if (cur_dist < dist) {
571 flies[c1].old_x = flies[c1].x;
572 flies[c1].old_y = flies[c1].y;
574 if ((s1 - flies[c1].x) > 30)
576 else if ((s1 - flies[c1].x) < -30)
579 if (((player[closest_player].x >> 16) + 8) > flies[c1].x) {
580 if (lord_of_the_flies == 0)
585 if (lord_of_the_flies == 0)
591 s4 = rnd(3) - 1 + s3;
592 if ((flies[c1].x + s4) < 16)
594 if ((flies[c1].x + s4) > 351)
596 if (ban_map[flies[c1].y >> 4][(flies[c1].x + s4) >> 4] != BAN_VOID)
600 if ((s2 - flies[c1].y) > 30)
602 else if ((s2 - flies[c1].y) < -30)
605 if (((player[closest_player].y >> 16) + 8) > flies[c1].y) {
606 if (lord_of_the_flies == 0)
611 if (lord_of_the_flies == 0)
617 s4 = rnd(3) - 1 + s3;
618 if ((flies[c1].y + s4) < 0)
620 if ((flies[c1].y + s4) > 239)
622 if (ban_map[(flies[c1].y + s4) >> 4][flies[c1].x >> 4] != BAN_VOID)
630 for (c1 = 0; c1 < 4; c1++) {
631 if (player[c1].enabled == 1) {
632 main_info.page_info[main_info.draw_page].pobs[s1].x = player[c1].x >> 16;
633 main_info.page_info[main_info.draw_page].pobs[s1].y = player[c1].y >> 16;
634 main_info.page_info[main_info.draw_page].pobs[s1].image = player[c1].image + c1 * 18;
635 main_info.page_info[main_info.draw_page].pobs[s1].pob_data = &rabbit_gobs;
640 if (update_count == 1) {
643 draw_pobs(main_info.draw_page);
647 draw_flies(main_info.draw_page);
652 if (mod_fade_direction == 1) {
655 dj_set_mod_volume((char)mod_vol);
660 dj_set_mod_volume((char)mod_vol);
664 if (mod_fade_direction == 1) {
667 dj_set_sfx_volume((char)sfx_vol);
672 dj_set_sfx_volume((char)sfx_vol);
677 for (c1 = 0; c1 < 768; c1++) {
678 if (cur_pal[c1] < pal[c1]) {
681 } else if (cur_pal[c1] > pal[c1]) {
686 if (fade_flag == 0 && end_loop_flag == 1)
689 if (update_count == 1) {
690 main_info.draw_page ^= 1;
691 main_info.view_page ^= 1;
693 flippage(main_info.view_page);
699 setpalette(0, 256, cur_pal);
701 if (update_count == 1) {
704 redraw_flies_background(main_info.draw_page);
706 redraw_pob_backgrounds(main_info.draw_page);
708 draw_leftovers(main_info.draw_page);
716 update_count = intr_sysupdate();
718 if (fade_flag == 0 && end_loop_flag == 1)
722 main_info.view_page = 0;
723 main_info.draw_page = 1;
725 dj_stop_sfx_channel(4);
729 memset(mask_pic, 0, 102400L);
730 register_mask(mask_pic);
732 //recalculate_gob(&font_gobs, pal);
733 register_background(NULL, NULL);
737 put_text(main_info.view_page, 100, 50, "DOTT", 2);
738 put_text(main_info.view_page, 160, 50, "JIFFY", 2);
739 put_text(main_info.view_page, 220, 50, "FIZZ", 2);
740 put_text(main_info.view_page, 280, 50, "MIJJI", 2);
741 put_text(main_info.view_page, 40, 80, "DOTT", 2);
742 put_text(main_info.view_page, 40, 110, "JIFFY", 2);
743 put_text(main_info.view_page, 40, 140, "FIZZ", 2);
744 put_text(main_info.view_page, 40, 170, "MIJJI", 2);
746 for (c1 = 0; c1 < 4; c1++) {
747 for (c2 = 0; c2 < 4; c2++) {
749 sprintf(str1, "%d", player[c1].bumped[c2]);
750 put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, str1, 2);
752 put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, "-", 2);
754 sprintf(str1, "%d", player[c1].bumps);
755 put_text(main_info.view_page, 350, 80 + c1 * 30, str1, 2);
758 put_text(main_info.view_page, 200, 230, "Press ESC to continue", 2);
762 flippage(main_info.view_page);
764 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
765 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
768 if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
769 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
774 memset(cur_pal, 0, 768);
776 setpalette(0, 256, cur_pal);
779 dj_ready_mod(MOD_SCORES);
780 dj_set_mod_volume((char)mod_vol);
784 while (key_pressed(1) == 0) {
787 dj_set_mod_volume((char)mod_vol);
788 for (c1 = 0; c1 < 768; c1++) {
789 if (cur_pal[c1] < pal[c1])
795 setpalette(0, 256, cur_pal);
796 flippage(main_info.view_page);
798 while (key_pressed(1) == 1) {
805 while (mod_vol > 0) {
807 dj_set_mod_volume((char)mod_vol);
808 for (c1 = 0; c1 < 768; c1++) {
809 if (cur_pal[c1] > pal[c1])
814 setpalette(0, 256, cur_pal);
815 flippage(main_info.view_page);
818 fillpalette(0, 0, 0);
831 void steer_players(void)
836 update_player_actions();
838 for (c1 = 0; c1 < 4; c1++) {
840 if (player[c1].enabled == 1) {
842 if (player[c1].dead_flag == 0) {
844 if (player[c1].action_left && player[c1].action_right) {
845 if (player[c1].direction == 0) {
846 if (player[c1].action_right) {
847 s1 = (player[c1].x >> 16);
848 s2 = (player[c1].y >> 16);
849 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
850 if (player[c1].x_add < 0)
851 player[c1].x_add += 1024;
853 player[c1].x_add += 768;
854 } 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)) {
855 if (player[c1].x_add > 0)
856 player[c1].x_add += 1024;
858 player[c1].x_add += 768;
860 if (player[c1].x_add < 0) {
861 player[c1].x_add += 16384;
862 if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
863 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);
865 player[c1].x_add += 12288;
867 if (player[c1].x_add > 98304L)
868 player[c1].x_add = 98304L;
869 player[c1].direction = 0;
870 if (player[c1].anim == 0) {
872 player[c1].frame = 0;
873 player[c1].frame_tick = 0;
874 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
878 if (player[c1].action_left) {
879 s1 = (player[c1].x >> 16);
880 s2 = (player[c1].y >> 16);
881 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
882 if (player[c1].x_add > 0)
883 player[c1].x_add -= 1024;
885 player[c1].x_add -= 768;
886 } 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)) {
887 if (player[c1].x_add > 0)
888 player[c1].x_add -= 1024;
890 player[c1].x_add -= 768;
892 if (player[c1].x_add > 0) {
893 player[c1].x_add -= 16384;
894 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
895 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);
897 player[c1].x_add -= 12288;
899 if (player[c1].x_add < -98304L)
900 player[c1].x_add = -98304L;
901 player[c1].direction = 1;
902 if (player[c1].anim == 0) {
904 player[c1].frame = 0;
905 player[c1].frame_tick = 0;
906 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
910 } else if (player[c1].action_left) {
911 s1 = (player[c1].x >> 16);
912 s2 = (player[c1].y >> 16);
913 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
914 if (player[c1].x_add > 0)
915 player[c1].x_add -= 1024;
917 player[c1].x_add -= 768;
918 } 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)) {
919 if (player[c1].x_add > 0)
920 player[c1].x_add -= 1024;
922 player[c1].x_add -= 768;
924 if (player[c1].x_add > 0) {
925 player[c1].x_add -= 16384;
926 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
927 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);
929 player[c1].x_add -= 12288;
931 if (player[c1].x_add < -98304L)
932 player[c1].x_add = -98304L;
933 player[c1].direction = 1;
934 if (player[c1].anim == 0) {
936 player[c1].frame = 0;
937 player[c1].frame_tick = 0;
938 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
940 } else if (player[c1].action_right) {
941 s1 = (player[c1].x >> 16);
942 s2 = (player[c1].y >> 16);
943 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
944 if (player[c1].x_add < 0)
945 player[c1].x_add += 1024;
947 player[c1].x_add += 768;
948 } 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)) {
949 if (player[c1].x_add > 0)
950 player[c1].x_add += 1024;
952 player[c1].x_add += 768;
954 if (player[c1].x_add < 0) {
955 player[c1].x_add += 16384;
956 if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
957 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);
959 player[c1].x_add += 12288;
961 if (player[c1].x_add > 98304L)
962 player[c1].x_add = 98304L;
963 player[c1].direction = 0;
964 if (player[c1].anim == 0) {
966 player[c1].frame = 0;
967 player[c1].frame_tick = 0;
968 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
970 } else if ((!player[c1].action_left) && (!player[c1].action_right)) {
971 s1 = (player[c1].x >> 16);
972 s2 = (player[c1].y >> 16);
973 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)))) {
974 if (player[c1].x_add < 0) {
975 player[c1].x_add += 16384;
976 if (player[c1].x_add > 0)
977 player[c1].x_add = 0;
979 player[c1].x_add -= 16384;
980 if (player[c1].x_add < 0)
981 player[c1].x_add = 0;
983 if (player[c1].x_add != 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
984 add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
986 if (player[c1].anim == 1) {
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;
994 if (pogostick == 1 || (player[c1].jump_ready == 1 && player[c1].action_up)) {
995 s1 = (player[c1].x >> 16);
996 s2 = (player[c1].y >> 16);
999 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) {
1000 player[c1].y_add = -280000L;
1001 player[c1].anim = 2;
1002 player[c1].frame = 0;
1003 player[c1].frame_tick = 0;
1004 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1005 player[c1].jump_ready = 0;
1006 player[c1].jump_abort = 1;
1008 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1010 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1012 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)) {
1013 player[c1].y_add = -196608L;
1014 player[c1].in_water = 0;
1015 player[c1].anim = 2;
1016 player[c1].frame = 0;
1017 player[c1].frame_tick = 0;
1018 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1019 player[c1].jump_ready = 0;
1020 player[c1].jump_abort = 1;
1022 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1024 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1027 if (pogostick == 0 && (!player[c1].action_up)) {
1028 player[c1].jump_ready = 1;
1029 if (player[c1].in_water == 0 && player[c1].y_add < 0 && player[c1].jump_abort == 1) {
1030 if (bunnies_in_space == 0)
1031 player[c1].y_add += 32768;
1033 player[c1].y_add += 16384;
1034 if (player[c1].y_add > 0)
1035 player[c1].y_add = 0;
1040 if (player[c1].action_up) {
1041 player[c1].y_add -= 16384;
1042 if (player[c1].y_add < -400000L)
1043 player[c1].y_add = -400000L;
1044 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))
1045 player[c1].in_water = 0;
1047 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);
1052 player[c1].x += player[c1].x_add;
1053 if ((player[c1].x >> 16) < 0) {
1055 player[c1].x_add = 0;
1057 if ((player[c1].x >> 16) + 15 > 351) {
1058 player[c1].x = 336L << 16;
1059 player[c1].x_add = 0;
1061 if (player[c1].y > 0) {
1062 s1 = (player[c1].x >> 16);
1063 s2 = (player[c1].y >> 16);
1064 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) {
1065 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1066 player[c1].x_add = 0;
1068 s1 = (player[c1].x >> 16);
1069 s2 = (player[c1].y >> 16);
1070 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) {
1071 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1072 player[c1].x_add = 0;
1075 s1 = (player[c1].x >> 16);
1077 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) {
1078 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1079 player[c1].x_add = 0;
1081 s1 = (player[c1].x >> 16);
1083 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) {
1084 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1085 player[c1].x_add = 0;
1089 player[c1].y += player[c1].y_add;
1091 s1 = (player[c1].x >> 16);
1092 s2 = (player[c1].y >> 16);
1093 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))) {
1094 player[c1].y = ((player[c1].y >> 16) & 0xfff0) << 16;
1095 player[c1].y_add = -400000L;
1096 player[c1].anim = 2;
1097 player[c1].frame = 0;
1098 player[c1].frame_tick = 0;
1099 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1100 player[c1].jump_ready = 0;
1101 player[c1].jump_abort = 0;
1102 for (c2 = 0; c2 < NUM_OBJECTS; c2++) {
1103 if (objects[c2].used == 1 && objects[c2].type == OBJ_SPRING) {
1104 if (ban_map[(s2 + 15) >> 4][(s1 + 8) >> 4] == BAN_SPRING) {
1105 if ((objects[c2].x >> 20) == ((s1 + 8) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1106 objects[c2].frame = 0;
1107 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1108 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1112 if (ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
1113 if ((objects[c2].x >> 20) == (s1 >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1114 objects[c2].frame = 0;
1115 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1116 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1119 } else if (ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1120 if ((objects[c2].x >> 20) == ((s1 + 15) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1121 objects[c2].frame = 0;
1122 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1123 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1130 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1132 s1 = (player[c1].x >> 16);
1133 s2 = (player[c1].y >> 16);
1136 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) {
1137 player[c1].y = (((s2 + 16) & 0xfff0)) << 16;
1138 player[c1].y_add = 0;
1139 player[c1].anim = 0;
1140 player[c1].frame = 0;
1141 player[c1].frame_tick = 0;
1142 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1144 s1 = (player[c1].x >> 16);
1145 s2 = (player[c1].y >> 16);
1148 if (ban_map[(s2 + 8) >> 4][(s1 + 8) >> 4] == BAN_WATER) {
1149 if (player[c1].in_water == 0) {
1150 player[c1].in_water = 1;
1151 player[c1].anim = 4;
1152 player[c1].frame = 0;
1153 player[c1].frame_tick = 0;
1154 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1155 if (player[c1].y_add >= 32768) {
1156 add_object(OBJ_SPLASH, (player[c1].x >> 16) + 8, ((player[c1].y >> 16) & 0xfff0) + 15, 0, 0, OBJ_ANIM_SPLASH, 0);
1157 if (blood_is_thicker_than_water == 0)
1158 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1160 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 5000), 64, 0, 0, -1);
1163 player[c1].y_add -= 1536;
1164 if (player[c1].y_add < 0 && player[c1].anim != 5) {
1165 player[c1].anim = 5;
1166 player[c1].frame = 0;
1167 player[c1].frame_tick = 0;
1168 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1170 if (player[c1].y_add < -65536L)
1171 player[c1].y_add = -65536L;
1172 if (player[c1].y_add > 65535L)
1173 player[c1].y_add = 65535L;
1174 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) {
1175 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1176 player[c1].y_add = 0;
1178 } 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) {
1179 player[c1].in_water = 0;
1180 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1181 player[c1].y_add = 0;
1182 if (player[c1].anim != 0 && player[c1].anim != 1) {
1183 player[c1].anim = 0;
1184 player[c1].frame = 0;
1185 player[c1].frame_tick = 0;
1186 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1189 if (player[c1].in_water == 0) {
1190 if (bunnies_in_space == 0)
1191 player[c1].y_add += 12288;
1193 player[c1].y_add += 6144;
1194 if (player[c1].y_add > 327680L)
1195 player[c1].y_add = 327680L;
1197 player[c1].y = (player[c1].y & 0xffff0000) + 0x10000;
1198 player[c1].y_add = 0;
1200 player[c1].in_water = 0;
1202 if (player[c1].y_add > 36864 && player[c1].anim != 3 && player[c1].in_water == 0) {
1203 player[c1].anim = 3;
1204 player[c1].frame = 0;
1205 player[c1].frame_tick = 0;
1206 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1211 player[c1].frame_tick++;
1212 if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
1214 if (player[c1].frame >= player_anims[player[c1].anim].num_frames) {
1215 if (player[c1].anim != 6)
1216 player[c1].frame = player_anims[player[c1].anim].restart_frame;
1218 position_player(c1);
1220 player[c1].frame_tick = 0;
1222 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1231 void position_player(int player_num)
1240 if (ban_map[s2][s1] == BAN_VOID && (ban_map[s2 + 1][s1] == BAN_SOLID || ban_map[s2 + 1][s1] == BAN_ICE))
1243 for (c1 = 0; c1 < 4; c1++) {
1244 if (c1 != player_num && player[c1].enabled == 1) {
1245 if (abs((s1 << 4) - (player[c1].x >> 16)) < 32 && abs((s2 << 4) - (player[c1].y >> 16)) < 32)
1250 player[player_num].dead_flag = 0;
1251 player[player_num].x = (long) s1 << 20;
1252 player[player_num].y = (long) s2 << 20;
1253 player[player_num].x_add = player[player_num].y_add = 0;
1254 player[player_num].direction = 0;
1255 player[player_num].jump_ready = 1;
1256 player[player_num].in_water = 0;
1257 player[player_num].anim = 0;
1258 player[player_num].frame = 0;
1259 player[player_num].frame_tick = 0;
1260 player[player_num].image = player_anims[player[player_num].anim].frame[player[player_num].frame].image;
1268 void add_object(int type, int x, int y, int x_add, int y_add, int anim, int frame)
1272 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
1273 if (objects[c1].used == 0) {
1274 objects[c1].used = 1;
1275 objects[c1].type = type;
1276 objects[c1].x = (long) x << 16;
1277 objects[c1].y = (long) y << 16;
1278 objects[c1].x_add = x_add;
1279 objects[c1].y_add = y_add;
1280 objects[c1].x_acc = 0;
1281 objects[c1].y_acc = 0;
1282 objects[c1].anim = anim;
1283 objects[c1].frame = frame;
1284 objects[c1].ticks = object_anims[anim].frame[frame].ticks;
1285 objects[c1].image = object_anims[anim].frame[frame].image;
1293 void update_objects(void)
1298 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
1299 if (objects[c1].used == 1) {
1300 switch (objects[c1].type) {
1302 objects[c1].ticks--;
1303 if (objects[c1].ticks <= 0) {
1304 objects[c1].frame++;
1305 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames) {
1306 objects[c1].frame--;
1307 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1309 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1310 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1313 if (objects[c1].used == 1)
1314 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1317 objects[c1].ticks--;
1318 if (objects[c1].ticks <= 0) {
1319 objects[c1].frame++;
1320 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1321 objects[c1].used = 0;
1323 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1324 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1327 if (objects[c1].used == 1)
1328 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1331 objects[c1].x += objects[c1].x_add;
1332 objects[c1].y += objects[c1].y_add;
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);
1346 case OBJ_YEL_BUTFLY:
1347 case OBJ_PINK_BUTFLY:
1348 objects[c1].x_acc += rnd(128) - 64;
1349 if (objects[c1].x_acc < -1024)
1350 objects[c1].x_acc = -1024;
1351 if (objects[c1].x_acc > 1024)
1352 objects[c1].x_acc = 1024;
1353 objects[c1].x_add += objects[c1].x_acc;
1354 if (objects[c1].x_add < -32768)
1355 objects[c1].x_add = -32768;
1356 if (objects[c1].x_add > 32768)
1357 objects[c1].x_add = 32768;
1358 objects[c1].x += objects[c1].x_add;
1359 if ((objects[c1].x >> 16) < 16) {
1360 objects[c1].x = 16 << 16;
1361 objects[c1].x_add = -objects[c1].x_add >> 2;
1362 objects[c1].x_acc = 0;
1363 } else if ((objects[c1].x >> 16) > 350) {
1364 objects[c1].x = 350 << 16;
1365 objects[c1].x_add = -objects[c1].x_add >> 2;
1366 objects[c1].x_acc = 0;
1368 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
1369 if (objects[c1].x_add < 0) {
1370 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
1372 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
1374 objects[c1].x_add = -objects[c1].x_add >> 2;
1375 objects[c1].x_acc = 0;
1377 objects[c1].y_acc += rnd(64) - 32;
1378 if (objects[c1].y_acc < -1024)
1379 objects[c1].y_acc = -1024;
1380 if (objects[c1].y_acc > 1024)
1381 objects[c1].y_acc = 1024;
1382 objects[c1].y_add += objects[c1].y_acc;
1383 if (objects[c1].y_add < -32768)
1384 objects[c1].y_add = -32768;
1385 if (objects[c1].y_add > 32768)
1386 objects[c1].y_add = 32768;
1387 objects[c1].y += objects[c1].y_add;
1388 if ((objects[c1].y >> 16) < 0) {
1390 objects[c1].y_add = -objects[c1].y_add >> 2;
1391 objects[c1].y_acc = 0;
1392 } else if ((objects[c1].y >> 16) > 255) {
1393 objects[c1].y = 255 << 16;
1394 objects[c1].y_add = -objects[c1].y_add >> 2;
1395 objects[c1].y_acc = 0;
1397 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
1398 if (objects[c1].y_add < 0) {
1399 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
1401 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1403 objects[c1].y_add = -objects[c1].y_add >> 2;
1404 objects[c1].y_acc = 0;
1406 if (objects[c1].type == OBJ_YEL_BUTFLY) {
1407 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_LEFT) {
1408 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_LEFT;
1409 objects[c1].frame = 0;
1410 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1411 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1412 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_RIGHT) {
1413 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_RIGHT;
1414 objects[c1].frame = 0;
1415 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1416 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1419 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_LEFT) {
1420 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_LEFT;
1421 objects[c1].frame = 0;
1422 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1423 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1424 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_RIGHT) {
1425 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_RIGHT;
1426 objects[c1].frame = 0;
1427 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1428 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1431 objects[c1].ticks--;
1432 if (objects[c1].ticks <= 0) {
1433 objects[c1].frame++;
1434 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1435 objects[c1].frame = object_anims[objects[c1].anim].restart_frame;
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].used == 1)
1442 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1446 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 0);
1447 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
1448 objects[c1].y_add += 3072;
1449 if (objects[c1].y_add > 196608L)
1450 objects[c1].y_add = 196608L;
1451 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
1452 if (objects[c1].x_add < 0) {
1453 if (objects[c1].x_add < -65536L)
1454 objects[c1].x_add = -65536L;
1455 objects[c1].x_add += 1024;
1456 if (objects[c1].x_add > 0)
1457 objects[c1].x_add = 0;
1459 if (objects[c1].x_add > 65536L)
1460 objects[c1].x_add = 65536L;
1461 objects[c1].x_add -= 1024;
1462 if (objects[c1].x_add < 0)
1463 objects[c1].x_add = 0;
1465 objects[c1].y_add += 1024;
1466 if (objects[c1].y_add < -65536L)
1467 objects[c1].y_add = -65536L;
1468 if (objects[c1].y_add > 65536L)
1469 objects[c1].y_add = 65536L;
1471 objects[c1].x += objects[c1].x_add;
1472 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)) {
1473 if (objects[c1].x_add < 0) {
1474 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
1475 objects[c1].x_add = -objects[c1].x_add >> 2;
1477 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
1478 objects[c1].x_add = -objects[c1].x_add >> 2;
1481 objects[c1].y += objects[c1].y_add;
1482 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
1483 objects[c1].used = 0;
1484 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
1485 if (objects[c1].y_add < 0) {
1486 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
1487 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
1488 objects[c1].x_add >>= 2;
1489 objects[c1].y_add = -objects[c1].y_add >> 2;
1492 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
1493 if (objects[c1].y_add > 131072L) {
1494 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1495 objects[c1].x_add >>= 2;
1496 objects[c1].y_add = -objects[c1].y_add >> 2;
1498 objects[c1].used = 0;
1499 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
1500 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1501 if (objects[c1].y_add > 131072L)
1502 objects[c1].y_add = -objects[c1].y_add >> 2;
1504 objects[c1].y_add = 0;
1508 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
1509 objects[c1].x_add = -16384;
1510 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
1511 objects[c1].x_add = 16384;
1512 if (objects[c1].used == 1) {
1513 s1 = (int)(atan2(objects[c1].y_add, objects[c1].x_add) * 4 / M_PI);
1520 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame + s1, &object_gobs);
1524 if (rnd(100) < 30) {
1525 if (objects[c1].frame == 76)
1526 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 1);
1527 else if (objects[c1].frame == 77)
1528 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 2);
1529 else if (objects[c1].frame == 78)
1530 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 3);
1532 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
1533 objects[c1].y_add += 3072;
1534 if (objects[c1].y_add > 196608L)
1535 objects[c1].y_add = 196608L;
1536 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
1537 if (objects[c1].x_add < 0) {
1538 if (objects[c1].x_add < -65536L)
1539 objects[c1].x_add = -65536L;
1540 objects[c1].x_add += 1024;
1541 if (objects[c1].x_add > 0)
1542 objects[c1].x_add = 0;
1544 if (objects[c1].x_add > 65536L)
1545 objects[c1].x_add = 65536L;
1546 objects[c1].x_add -= 1024;
1547 if (objects[c1].x_add < 0)
1548 objects[c1].x_add = 0;
1550 objects[c1].y_add += 1024;
1551 if (objects[c1].y_add < -65536L)
1552 objects[c1].y_add = -65536L;
1553 if (objects[c1].y_add > 65536L)
1554 objects[c1].y_add = 65536L;
1556 objects[c1].x += objects[c1].x_add;
1557 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)) {
1558 if (objects[c1].x_add < 0) {
1559 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
1560 objects[c1].x_add = -objects[c1].x_add >> 2;
1562 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
1563 objects[c1].x_add = -objects[c1].x_add >> 2;
1566 objects[c1].y += objects[c1].y_add;
1567 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
1568 objects[c1].used = 0;
1569 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
1570 if (objects[c1].y_add < 0) {
1571 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
1572 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
1573 objects[c1].x_add >>= 2;
1574 objects[c1].y_add = -objects[c1].y_add >> 2;
1577 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
1578 if (objects[c1].y_add > 131072L) {
1579 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1580 objects[c1].x_add >>= 2;
1581 objects[c1].y_add = -objects[c1].y_add >> 2;
1583 if (rnd(100) < 10) {
1585 add_leftovers(0, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
1586 add_leftovers(1, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
1588 objects[c1].used = 0;
1590 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
1591 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1592 if (objects[c1].y_add > 131072L)
1593 objects[c1].y_add = -objects[c1].y_add >> 2;
1595 objects[c1].y_add = 0;
1599 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
1600 objects[c1].x_add = -16384;
1601 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
1602 objects[c1].x_add = 16384;
1603 if (objects[c1].used == 1)
1604 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame, &object_gobs);
1606 case OBJ_FLESH_TRACE:
1607 objects[c1].ticks--;
1608 if (objects[c1].ticks <= 0) {
1609 objects[c1].frame++;
1610 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1611 objects[c1].used = 0;
1613 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1614 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1617 if (objects[c1].used == 1)
1618 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1627 int add_pob(int page, int x, int y, int image, gob_t *pob_data)
1630 if (main_info.page_info[page].num_pobs >= NUM_POBS)
1633 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].x = x;
1634 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].y = y;
1635 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].image = image;
1636 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].pob_data = pob_data;
1637 main_info.page_info[page].num_pobs++;
1644 void draw_flies(int page)
1648 for (c2 = 0; c2 < NUM_FLIES; c2++) {
1649 flies[c2].back[main_info.draw_page] = get_pixel(main_info.draw_page, flies[c2].x, flies[c2].y);
1650 flies[c2].back_defined[main_info.draw_page] = 1;
1651 if (mask_pic[(flies[c2].y * JNB_WIDTH) + flies[c2].x] == 0)
1652 set_pixel(main_info.draw_page, flies[c2].x, flies[c2].y, 0);
1656 void draw_pobs(int page)
1663 for (c1 = main_info.page_info[page].num_pobs - 1; c1 >= 0; c1--) {
1664 main_info.page_info[page].pobs[c1].back_buf_ofs = back_buf_ofs;
1665 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);
1667 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;
1669 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;
1670 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);
1676 void redraw_flies_background(int page)
1680 for (c2 = NUM_FLIES - 1; c2 >= 0; c2--) {
1681 if (flies[c2].back_defined[page] == 1)
1682 set_pixel(page, flies[c2].old_draw_x, flies[c2].old_draw_y, flies[c2].back[page]);
1683 flies[c2].old_draw_x = flies[c2].x;
1684 flies[c2].old_draw_y = flies[c2].y;
1689 void redraw_pob_backgrounds(int page)
1693 for (c1 = 0; c1 < main_info.page_info[page].num_pobs; c1++)
1694 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);
1699 int add_leftovers(int page, int x, int y, int image, gob_t *pob_data)
1702 if (leftovers.page[page].num_pobs >= NUM_LEFTOVERS)
1705 leftovers.page[page].pobs[leftovers.page[page].num_pobs].x = x;
1706 leftovers.page[page].pobs[leftovers.page[page].num_pobs].y = y;
1707 leftovers.page[page].pobs[leftovers.page[page].num_pobs].image = image;
1708 leftovers.page[page].pobs[leftovers.page[page].num_pobs].pob_data = pob_data;
1709 leftovers.page[page].num_pobs++;
1716 void draw_leftovers(int page)
1720 for (c1 = leftovers.page[page].num_pobs - 1; c1 >= 0; c1--)
1721 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);
1723 leftovers.page[page].num_pobs = 0;
1728 int init_level(int level, char *pal)
1734 if ((handle = dat_open("level.pcx", datfile_name, "rb")) == 0) {
1735 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
1738 if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
1739 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
1743 if ((handle = dat_open("mask.pcx", datfile_name, "rb")) == 0) {
1744 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
1747 if (read_pcx(handle, mask_pic, 102400L, 0) != 0) {
1748 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
1752 register_mask(mask_pic);
1754 for (c1 = 0; c1 < 4; c1++) {
1755 if (player[c1].enabled == 1) {
1756 player[c1].bumps = 0;
1757 player[c1].bumped[0] = 0;
1758 player[c1].bumped[1] = 0;
1759 player[c1].bumped[2] = 0;
1760 player[c1].bumped[3] = 0;
1761 position_player(c1);
1765 for (c1 = 0; c1 < NUM_OBJECTS; c1++)
1766 objects[c1].used = 0;
1768 for (c1 = 0; c1 < 16; c1++) {
1769 for (c2 = 0; c2 < 22; c2++) {
1770 if (ban_map[c1][c2] == BAN_SPRING)
1771 add_object(OBJ_SPRING, c2 << 4, c1 << 4, 0, 0, OBJ_ANIM_SPRING, 5);
1778 if (ban_map[s2][s1] == BAN_VOID) {
1779 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1786 if (ban_map[s2][s1] == BAN_VOID) {
1787 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1794 if (ban_map[s2][s1] == BAN_VOID) {
1795 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1802 if (ban_map[s2][s1] == BAN_VOID) {
1803 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1813 void deinit_level(void)
1820 int init_program(int argc, char *argv[], char *pal)
1822 FILE *handle = (FILE *) NULL;
1827 int player_anim_data[] = {
1828 1, 0, 0, 0x7fff, 0, 0, 0, 0, 0, 0,
1829 4, 0, 0, 4, 1, 4, 2, 4, 3, 4,
1830 1, 0, 4, 0x7fff, 0, 0, 0, 0, 0, 0,
1831 4, 2, 5, 8, 6, 10, 7, 3, 6, 3,
1832 1, 0, 6, 0x7fff, 0, 0, 0, 0, 0, 0,
1833 2, 1, 5, 8, 4, 0x7fff, 0, 0, 0, 0,
1834 1, 0, 8, 5, 0, 0, 0, 0, 0, 0
1838 if (__djgpp_nearptr_enable() == 0)
1844 if (hook_keyb_handler() != 0)
1847 memset(&main_info, 0, sizeof(main_info));
1849 strcpy(datfile_name, DATA_PATH);
1851 force2 = force3 = 0;
1854 for (c1 = 1; c1 < argc; c1++) {
1855 if (stricmp(argv[c1], "-nosound") == 0)
1856 main_info.no_sound = 1;
1857 else if (stricmp(argv[c1], "-nogore") == 0)
1858 main_info.no_gore = 1;
1859 else if (stricmp(argv[c1], "-nojoy") == 0)
1860 main_info.joy_enabled = 0;
1861 else if (stricmp(argv[c1], "-fireworks") == 0)
1862 main_info.fireworks = 1;
1864 else if (stricmp(argv[c1], "-fullscreen") == 0)
1867 else if (stricmp(argv[c1], "-scaleup") == 0)
1869 else if (stricmp(argv[c1], "-dat") == 0) {
1870 if (c1 < (argc - 1)) {
1871 if ((handle = fopen(argv[c1 + 1], "rb")) != NULL) {
1873 strcpy(datfile_name, argv[c1 + 1]);
1876 } else if (stricmp(argv[c1], "-mouse") == 0) {
1877 if (c1 < (argc - 1)) {
1878 if (stricmp(argv[c1 + 1], "2") == 0)
1880 if (stricmp(argv[c1 + 1], "3") == 0)
1887 main_info.pob_backbuf[0] = malloc(screen_pitch*screen_height*bytes_per_pixel);
1888 main_info.pob_backbuf[1] = malloc(screen_pitch*screen_height*bytes_per_pixel);
1890 for (c1 = 0; c1 < 7; c1++) {
1891 player_anims[c1].num_frames = player_anim_data[c1 * 10];
1892 player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
1893 for (c2 = 0; c2 < 4; c2++) {
1894 player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
1895 player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
1899 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
1900 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1903 if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
1904 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1909 if ((handle = dat_open("rabbit.gob", datfile_name, "rb")) == 0) {
1910 strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
1913 if (register_gob(handle, &rabbit_gobs, dat_filelen("rabbit.gob", datfile_name))) {
1920 if ((handle = dat_open("objects.gob", datfile_name, "rb")) == 0) {
1921 strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
1924 if (register_gob(handle, &object_gobs, dat_filelen("objects.gob", datfile_name))) {
1931 if ((handle = dat_open("font.gob", datfile_name, "rb")) == 0) {
1932 strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
1935 if (register_gob(handle, &font_gobs, dat_filelen("font.gob", datfile_name))) {
1942 if ((handle = dat_open("numbers.gob", datfile_name, "rb")) == 0) {
1943 strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
1946 if (register_gob(handle, &number_gobs, dat_filelen("numbers.gob", datfile_name))) {
1953 if (read_level() != 0) {
1954 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
1961 if (main_info.no_sound == 0) {
1963 dj_set_mixing_freq(20000);
1967 dj_set_num_sfx_channels(5);
1968 dj_set_sfx_volume(64);
1972 if ((handle = dat_open("jump.mod", datfile_name, "rb")) == 0) {
1973 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
1976 if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
1977 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
1982 if ((handle = dat_open("bump.mod", datfile_name, "rb")) == 0) {
1983 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
1986 if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
1987 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
1992 if ((handle = dat_open("scores.mod", datfile_name, "rb")) == 0) {
1993 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
1996 if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
1997 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2002 if ((handle = dat_open("jump.smp", datfile_name, "rb")) == 0) {
2003 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2006 if (dj_load_sfx(handle, 0, dat_filelen("jump.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
2007 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2012 if ((handle = dat_open("death.smp", datfile_name, "rb")) == 0) {
2013 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2016 if (dj_load_sfx(handle, 0, dat_filelen("death.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
2017 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2022 if ((handle = dat_open("spring.smp", datfile_name, "rb")) == 0) {
2023 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2026 if (dj_load_sfx(handle, 0, dat_filelen("spring.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
2027 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2032 if ((handle = dat_open("splash.smp", datfile_name, "rb")) == 0) {
2033 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2036 if (dj_load_sfx(handle, 0, dat_filelen("splash.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
2037 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2042 if ((handle = dat_open("fly.smp", datfile_name, "rb")) == 0) {
2043 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2046 if (dj_load_sfx(handle, 0, dat_filelen("fly.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
2047 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2052 dj_get_sfx_settings(SFX_FLY, &fly);
2054 fly.default_freq = SFX_FLY_FREQ;
2057 fly.loop_length = fly.length;
2058 dj_set_sfx_settings(SFX_FLY, &fly);
2061 if ((background_pic = malloc(102400)) == NULL)
2063 if ((mask_pic = malloc(102400)) == NULL)
2065 memset(mask_pic, 0, 102400);
2066 register_mask(mask_pic);
2068 setpalette(0, 256, pal);
2072 recalculate_gob(&font_gobs, pal);
2074 if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
2076 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2077 put_text(0, 200, 100, "Move the joystick to the", 2);
2078 put_text(0, 200, 115, "UPPER LEFT", 2);
2079 put_text(0, 200, 130, "and press button A", 2);
2080 put_text(0, 200, 200, "Or press ESC to use", 2);
2081 put_text(0, 200, 215, "previous settings", 2);
2082 if (calib_joy(0) != 0)
2085 register_background(NULL, NULL);
2087 main_info.view_page = 1;
2092 put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
2093 put_text(1, 200, 100, "Move the joystick to the", 2);
2094 put_text(1, 200, 115, "LOWER RIGHT", 2);
2095 put_text(1, 200, 130, "and press button A", 2);
2096 put_text(1, 200, 200, "Or press ESC to use", 2);
2097 put_text(1, 200, 215, "previous settings", 2);
2098 if (calib_joy(1) != 0)
2101 register_background(NULL, NULL);
2106 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2107 put_text(0, 200, 100, "Move the joystick to the", 2);
2108 put_text(0, 200, 115, "CENTER", 2);
2109 put_text(0, 200, 130, "and press button A", 2);
2110 put_text(0, 200, 200, "Or press ESC to use", 2);
2111 put_text(0, 200, 215, "previous settings", 2);
2112 if (calib_joy(2) != 0)
2115 if (joy.calib_data.x1 == joy.calib_data.x2)
2116 joy.calib_data.x1 -= 10;
2117 if (joy.calib_data.x3 == joy.calib_data.x2)
2118 joy.calib_data.x3 += 10;
2119 if (joy.calib_data.y1 == joy.calib_data.y2)
2120 joy.calib_data.y1 -= 10;
2121 if (joy.calib_data.y3 == joy.calib_data.y2)
2122 joy.calib_data.y3 += 10;
2127 if (load_flag == 1) {
2128 if ((handle = dat_open("calib.dat", datfile_name, "rb")) == 0) {
2129 strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
2132 joy.calib_data.x1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2133 joy.calib_data.x2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2134 joy.calib_data.x3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2135 joy.calib_data.y1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2136 joy.calib_data.y2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2137 joy.calib_data.y3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2146 void deinit_program(void)
2153 dj_free_mod(MOD_MENU);
2154 dj_free_mod(MOD_GAME);
2155 dj_free_sfx(SFX_DEATH);
2156 dj_free_sfx(SFX_SPRING);
2157 dj_free_sfx(SFX_SPLASH);
2160 if (background_pic != 0)
2161 free(background_pic);
2165 remove_keyb_handler();
2169 __dpmi_int(0x10, ®s);
2172 if (main_info.error_str[0] != 0) {
2173 printf(main_info.error_str);
2175 MessageBox(0, main_info.error_str, "Jump'n'Bump", 0);
2184 unsigned short rnd(unsigned short max)
2186 return (rand() % max);
2190 int read_level(void)
2196 if ((handle = dat_open("levelmap.txt", datfile_name, "rb")) == 0) {
2197 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2201 for (c1 = 0; c1 < 16; c1++) {
2202 for (c2 = 0; c2 < 22; c2++) {
2204 chr = fgetc(handle);
2209 if (chr >= '0' && chr <= '4')
2212 ban_map[c1][c2] = chr - '0';
2216 for (c2 = 0; c2 < 22; c2++)
2217 ban_map[16][c2] = BAN_SOLID;
2225 FILE *dat_open(char *file_name, char *dat_name, char *mode)
2233 handle = fopen(dat_name, mode);
2237 memset(name, 0, sizeof(name));
2239 num = fgetc(handle);
2240 num+= (fgetc(handle) << 8);
2241 num+= (fgetc(handle) << 16);
2242 num+= (fgetc(handle) << 24);
2244 for (c1 = 0; c1 < num; c1++) {
2245 if (!fread(name, 1, 12, handle)) {
2249 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2250 ofs = fgetc(handle);
2251 ofs += (fgetc(handle) << 8);
2252 ofs += (fgetc(handle) << 16);
2253 ofs += (fgetc(handle) << 24);
2254 fseek(handle, ofs, SEEK_SET);
2257 fseek(handle, 8, SEEK_CUR);
2266 int dat_filelen(char *file_name, char *dat_name)
2274 handle = fopen(dat_name, "rb");
2278 memset(name, 0, sizeof(name));
2280 num = fgetc(handle);
2281 num+= (fgetc(handle) << 8);
2282 num+= (fgetc(handle) << 16);
2283 num+= (fgetc(handle) << 24);
2285 for (c1 = 0; c1 < num; c1++) {
2286 if (!fread(name, 1, 12, handle)) {
2290 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2291 fseek(handle, 4, SEEK_CUR);
2292 len = fgetc(handle);
2293 len += (fgetc(handle) << 8);
2294 len += (fgetc(handle) << 16);
2295 len += (fgetc(handle) << 24);
2300 fseek(handle, 8, SEEK_CUR);
2309 int filelength(int handle)
2313 if (fstat(handle, &buf) == -1) {
2314 perror("filelength");
2323 void write_calib_data(void)
2331 if ((handle = fopen(datfile_name, "rb")) == NULL)
2333 len = filelength(fileno(handle));
2334 if ((mem = malloc(len)) == NULL)
2336 fread(mem, 1, len, handle);
2340 num = *(int *) (&mem[0]);
2341 for (c1 = 0; c1 < num; c1++) {
2342 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
2343 ofs = *(int *) (&mem[ofs + 12]);
2349 mem[ofs] = joy.calib_data.x1 & 0xff;
2350 mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
2351 mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
2352 mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
2353 mem[ofs + 4] = joy.calib_data.x2 & 0xff;
2354 mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
2355 mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
2356 mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
2357 mem[ofs + 8] = joy.calib_data.x3 & 0xff;
2358 mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
2359 mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
2360 mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
2361 mem[ofs + 12] = joy.calib_data.y1 & 0xff;
2362 mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
2363 mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
2364 mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
2365 mem[ofs + 16] = joy.calib_data.y2 & 0xff;
2366 mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
2367 mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
2368 mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
2369 mem[ofs + 20] = joy.calib_data.y3 & 0xff;
2370 mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
2371 mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
2372 mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
2374 if ((handle = fopen(datfile_name, "wb")) == NULL)
2376 fwrite(mem, 1, len, handle);