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
34 #define M_PI 3.14159265358979323846
37 gob_t rabbit_gobs = { 0 };
38 gob_t font_gobs = { 0 };
39 gob_t object_gobs = { 0 };
40 gob_t number_gobs = { 0 };
42 main_info_t main_info;
43 player_t player[JNB_MAX_PLAYERS];
44 player_anim_t player_anims[7];
45 object_t objects[NUM_OBJECTS];
49 char datfile_name[2048];
55 unsigned int ban_map[17][22] = {
56 {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
57 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0},
58 {1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
59 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1},
60 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
61 {1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
62 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1},
63 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
64 {1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
65 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1},
66 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1},
67 {1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1},
68 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
69 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
70 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 1, 3, 3, 3, 1, 1, 1},
71 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
72 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
198 int flies_enabled = 1;
203 int old_draw_x, old_draw_y;
215 } pobs[NUM_LEFTOVERS];
219 int pogostick, bunnies_in_space, jetpack, lord_of_the_flies, blood_is_thicker_than_water;
223 int filelength(int handle)
227 if (fstat(handle, &buf) == -1) {
228 perror("filelength");
237 /* networking shite. */
239 int client_player_num = -1;
248 /*struct timeval last_timestamp;*/
249 struct sockaddr *addr;
254 NetInfo net_info[JNB_MAX_PLAYERS];
265 #define NETPKTBUFSIZE (4 + 4 + 4 + 4 + 4)
267 #define NETCMD_NACK (0xF00DF00D + 0)
268 #define NETCMD_ACK (0xF00DF00D + 1)
269 #define NETCMD_HELLO (0xF00DF00D + 2)
270 #define NETCMD_GREENLIGHT (0xF00DF00D + 3)
271 #define NETCMD_MOVE (0xF00DF00D + 4)
272 #define NETCMD_BYE (0xF00DF00D + 5)
273 #define NETCMD_POSITION (0xF00DF00D + 6)
274 #define NETCMD_ALIVE (0xF00DF00D + 7)
275 #define NETCMD_KILL (0xF00DF00D + 8)
279 void bufToPacket(const char *buf, NetPacket *pkt)
281 SDLNet_Write32(*((unsigned long *) (buf + 0)), pkt->cmd);
282 SDLNet_Write32(*((unsigned long *) (buf + 4)), pkt->arg);
283 SDLNet_Write32(*((unsigned long *) (buf + 8)), pkt->arg2);
284 SDLNet_Write32(*((unsigned long *) (buf + 12)), pkt->arg3);
285 SDLNet_Write32(*((unsigned long *) (buf + 16)), pkt->arg4);
289 void packetToBuf(const NetPacket *pkt, char *buf)
291 *((unsigned long *) (buf + 0)) = SDLNet_Read32(pkt->cmd);
292 *((unsigned long *) (buf + 4)) = SDLNet_Read32((unsigned long) pkt->arg);
293 *((unsigned long *) (buf + 8)) = SDLNet_Read32((unsigned long) pkt->arg2);
294 *((unsigned long *) (buf + 12)) = SDLNet_Read32((unsigned long) pkt->arg3);
295 *((unsigned long *) (buf + 16)) = SDLNet_Read32((unsigned long) pkt->arg4);
299 void sendPacketToSock(int s, NetPacket *pkt)
302 int bytes_left = NETPKTBUFSIZE;
304 char buf[NETPKTBUFSIZE];
309 packetToBuf(pkt, buf);
310 while (bytes_left > 0) {
311 bw = write(s, ptr, bytes_left); /* this might block. For now, we'll deal. */
313 if (errno != EAGAIN) {
314 perror("SERVER: write()");
318 } else if (bw == 0) {
329 void sendPacket(int playerid, NetPacket *pkt)
331 if ( playerid < JNB_MAX_PLAYERS ) {
332 if ((player[playerid].enabled) && (playerid != client_player_num)) {
333 sendPacketToSock(net_info[playerid].sock, pkt);
339 void sendPacketToAll(NetPacket *pkt)
343 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
349 int grabPacket(int s, NetPacket *pkt)
352 char buf[NETPKTBUFSIZE];
360 tv.tv_sec = tv.tv_usec = 0; /* don't block. */
361 if (select(s + 1, &rfds, NULL, NULL, &tv)) {
362 rc = read(s, buf, NETPKTBUFSIZE);
363 if (rc <= 0) { /* closed connection? */
365 } else if (rc != NETPKTBUFSIZE) { // !!! FIXME: buffer these?
366 printf("NETWORK: -BUG- ... dropped a packet! (had %d of %d bytes).\b",
369 bufToPacket(buf, pkt);
381 int serverRecvPacket(NetPacket *pkt)
388 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
389 int s = net_info[i].sock;
391 if ((i == client_player_num) || (!player[i].enabled))
394 rc = grabPacket(s, pkt);
398 player[i].enabled = 0;
400 pkt.cmd = NETCMD_BYE;
405 sendPacketToAll(&pkt);
407 return(i); /* it's all good. */
411 return(-1); /* no packets available currently. */
415 void wait_for_greenlight(void)
420 printf("CLIENT: Waiting for greenlight...\n");
424 while ((rc = grabPacket(sock, &pkt)) == 0) {
425 SDL_Delay(100); /* nap and then try again. */
429 printf("CLIENT: Lost connection.\n");
433 } while (pkt.cmd != NETCMD_GREENLIGHT);
435 printf("CLIENT: Got greenlight.\n");
437 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
438 if (pkt.arg & (1 << i)) {
439 printf("CLIENT: There is a player #%d.\n", i);
440 player[i].enabled = 1;
446 static int buggered_off = 0;
449 void tellServerGoodbye(void)
455 pkt.cmd = NETCMD_BYE;
456 pkt.arg = client_player_num;
460 sendPacketToSock(sock, &pkt);
465 void processMovePacket(NetPacket *pkt)
467 int playerid = pkt->arg;
468 int movetype = ((pkt->arg2 >> 16) & 0xFF);
469 int newval = ((pkt->arg2 >> 0) & 0xFF);
471 if (movetype == MOVEMENT_LEFT) {
472 player[playerid].action_left = newval;
473 } else if (movetype == MOVEMENT_RIGHT) {
474 player[playerid].action_right = newval;
475 } else if (movetype == MOVEMENT_UP) {
476 player[playerid].action_up = newval;
478 printf("bogus MOVE packet!\n");
481 player[playerid].x = pkt->arg3;
482 player[playerid].y = pkt->arg4;
486 void tellServerPlayerMoved(int playerid, int movement_type, int newval)
490 pkt.cmd = NETCMD_MOVE;
492 pkt.arg2 = ( ((movement_type & 0xFF) << 16) | ((newval & 0xFF) << 0) );
493 pkt.arg3 = player[playerid].x;
494 pkt.arg4 = player[playerid].y;
497 processMovePacket(&pkt);
498 sendPacketToAll(&pkt);
500 sendPacketToSock(sock, &pkt);
505 void tellServerNewPosition(void)
508 pkt.cmd = NETCMD_POSITION;
509 pkt.arg = client_player_num;
510 pkt.arg2 = player[client_player_num].x;
511 pkt.arg3 = player[client_player_num].y;
514 sendPacketToAll(&pkt);
516 sendPacketToSock(sock, &pkt);
521 void processKillPacket(NetPacket *pkt)
530 player[c1].y_add = -player[c1].y_add;
531 if (player[c1].y_add > -262144L)
532 player[c1].y_add = -262144L;
533 player[c1].jump_abort = 1;
534 player[c2].dead_flag = 1;
535 if (player[c2].anim != 6) {
537 player[c2].frame = 0;
538 player[c2].frame_tick = 0;
539 player[c2].image = player_anims[player[c2].anim].frame[player[c2].frame].image + player[c2].direction * 9;
540 if (main_info.no_gore == 0) {
541 for (c4 = 0; c4 < 6; c4++)
542 add_object(OBJ_FUR, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 44 + c2 * 8);
543 for (c4 = 0; c4 < 6; c4++)
544 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 76);
545 for (c4 = 0; c4 < 6; c4++)
546 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 77);
547 for (c4 = 0; c4 < 8; c4++)
548 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 78);
549 for (c4 = 0; c4 < 10; c4++)
550 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 79);
552 dj_play_sfx(SFX_DEATH, (unsigned short)(SFX_DEATH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
554 player[c1].bumped[c2]++;
555 s1 = player[c1].bumps % 100;
556 add_leftovers(0, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
557 add_leftovers(1, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
558 add_leftovers(0, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
559 add_leftovers(1, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
564 void processPositionPacket(NetPacket *pkt)
566 int playerid = pkt->arg;
568 player[playerid].x = pkt->arg2;
569 player[playerid].y = pkt->arg3;
573 void processAlivePacket(NetPacket *pkt)
575 int playerid = pkt->arg;
577 player[playerid].dead_flag = 0;
578 player[playerid].x = pkt->arg2;
579 player[playerid].y = pkt->arg3;
583 void serverTellEveryoneGoodbye(void)
589 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
590 if (player[i].enabled) {
593 pkt.cmd = NETCMD_BYE;
598 sendPacketToAll(&pkt);
605 int server_said_bye = 0;
608 int update_players_from_server(void)
615 while ((rc = grabPacket(sock, &pkt)) != 0) {
617 printf("CLIENT: Lost connection.\n");
618 pkt.cmd = NETCMD_BYE;
619 pkt.arg = client_player_num;
622 if (pkt.cmd == NETCMD_BYE) {
623 if (pkt.arg == client_player_num) {
629 player[pkt.arg].enabled = 0;
631 } else if (pkt.cmd == NETCMD_MOVE) {
632 processMovePacket(&pkt);
633 } else if (pkt.cmd == NETCMD_ALIVE) {
634 processAlivePacket(&pkt);
635 } else if (pkt.cmd == NETCMD_POSITION) {
636 processPositionPacket(&pkt);
637 } else if (pkt.cmd == NETCMD_KILL) {
638 processKillPacket(&pkt);
640 printf("CLIENT: Got an unknown packet: 0x%lX.\n", pkt.cmd);
648 void serverSendAlive(int playerid)
653 pkt.cmd = NETCMD_ALIVE;
655 pkt.arg2 = player[playerid].x;
656 pkt.arg3 = player[playerid].y;
657 sendPacketToAll(&pkt);
661 void serverSendKillPacket(int killer, int victim)
666 pkt.cmd = NETCMD_KILL;
669 pkt.arg3 = player[victim].x;
670 pkt.arg4 = player[victim].y;
671 processKillPacket(&pkt);
672 sendPacketToAll(&pkt);
676 void update_players_from_clients(void)
687 while ((playerid = serverRecvPacket(&pkt)) >= 0) {
688 if (pkt.cmd == NETCMD_BYE) {
689 pkt.arg = playerid; /* just in case. */
690 sendPacketToAll(&pkt);
691 player[playerid].enabled = 0;
692 close(net_info[playerid].sock);
693 } else if (pkt.cmd == NETCMD_POSITION) {
694 pkt.arg = playerid; /* just in case. */
695 processPositionPacket(&pkt);
696 for (i = 0; i < (sizeof (net_info) / sizeof (net_info[0])); i++) {
701 } else if (pkt.cmd == NETCMD_MOVE) {
702 pkt.arg = playerid; /* just in case. */
703 //pkt.arg3 = player[playerid].x;
704 //pkt.arg4 = player[playerid].y;
705 processMovePacket(&pkt);
706 sendPacketToAll(&pkt);
708 printf("SERVER: Got unknown packet (0x%lX).\n", pkt.cmd);
715 void init_server(const char *netarg)
720 struct hostent *hent;
721 struct sockaddr_in addr;
722 struct in_addr inaddr;
724 int wait_for_clients = ((netarg == NULL) ? 0 : atoi(netarg));
726 if ((wait_for_clients > 3) || (wait_for_clients < 0)) {
727 printf("SERVER: Waiting for bogus client count (%d).\n", wait_for_clients);
731 sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
733 perror("SERVER: socket()");
737 memset(&addr, '\0', sizeof (addr));
738 addr.sin_family = AF_INET;
739 addr.sin_port = htons(JNB_INETPORT);
740 addr.sin_addr.s_addr = INADDR_ANY;
741 if (bind(sock, (struct sockaddr *) &addr,
742 (socklen_t) sizeof (addr)) == -1) {
743 perror("SERVER: bind()");
748 if (listen(sock, wait_for_clients) == -1) {
749 perror("SERVER: listen()");
754 player[client_player_num].enabled = 1;
756 gethostname(ipstr, sizeof (ipstr));
757 hent = gethostbyname(ipstr);
759 memcpy(&inaddr, hent->h_addr, hent->h_length);
760 strncpy(ipstr, inet_ntoa(inaddr), sizeof (ipstr));
763 printf("SERVER: we are [%s].\n", ipstr);
765 addr.sin_addr.s_addr = inaddr.s_addr;
766 addr.sin_family = AF_INET;
767 addr.sin_port = htons(JNB_INETPORT);
768 net_info[client_player_num].addr = malloc(sizeof (addr));
769 memcpy(net_info[client_player_num].addr, &addr, sizeof (addr));
770 net_info[client_player_num].addrlen = sizeof (addr);
771 /*gettimeofday(&net_info[client_player_num].last_timestamp, NULL);*/
773 printf("SERVER: waiting for (%d) clients...\n", wait_for_clients);
775 while (wait_for_clients > 0)
777 char buf[NETPKTBUFSIZE];
778 struct sockaddr_in from;
779 socklen_t fromlen = sizeof (from);
784 s = accept(sock, (struct sockaddr *) &from, &fromlen);
787 perror("SERVER: accept()");
792 br = read(s, buf, NETPKTBUFSIZE);
794 perror("SERVER: read()");
800 strncpy(ipstr, inet_ntoa(from.sin_addr), sizeof (ipstr));
801 printf("SERVER: Got data from [%s].\n", ipstr);
803 if (br != NETPKTBUFSIZE) {
804 printf("SERVER: Bogus packet.\n");
808 bufToPacket(buf, &pkt);
809 if (pkt.cmd != NETCMD_HELLO) {
810 printf("SERVER: Bogus packet.\n");
814 printf("SERVER: Client claims to be player #%ld.\n", pkt.arg);
816 if (pkt.arg > (sizeof (player) / sizeof (player[0]))) {
817 printf("SERVER: (that's an invalid player number.)\n");
819 if (player[pkt.arg].enabled) {
820 printf("SERVER: (that player number is already taken.)\n");
827 printf("SERVER: Forbidding connection.\n");
828 pkt.cmd = NETCMD_NACK;
829 sendPacketToSock(s, &pkt);
832 player[pkt.arg].enabled = 1;
833 net_info[pkt.arg].sock = s;
834 net_info[pkt.arg].addr = malloc(fromlen);
835 memcpy(net_info[pkt.arg].addr, &from, fromlen);
836 net_info[pkt.arg].addrlen = fromlen;
837 /*memcpy(&net_info[pkt.arg].last_timestamp, &pkt.timestamp, sizeof (pkt.timestamp));*/
839 printf("SERVER: Granting connection. (%d) to go.\n", wait_for_clients);
840 pkt.cmd = NETCMD_ACK;
841 sendPacket(pkt.arg, &pkt);
845 close(sock); /* done with the listen socket. */
848 printf("SERVER: Got all our connections. Greenlighting clients...\n");
850 pkt.cmd = NETCMD_GREENLIGHT;
852 for (i = 0; i < (sizeof (net_info) / sizeof (net_info[0])); i++) {
853 if (player[i].enabled) {
857 sendPacketToAll(&pkt);
862 void connect_to_server(char *netarg)
866 char buf[NETPKTBUFSIZE];
868 struct hostent *hent;
869 struct sockaddr_in addr;
870 struct in_addr inaddr;
874 if (netarg == NULL) {
875 printf("CLIENT: Need to specify host to connect to.\n");
879 player[client_player_num].enabled = 1;
880 gethostname(ipstr, sizeof (ipstr));
881 hent = gethostbyname(ipstr);
883 net_info[client_player_num].addr = malloc(hent->h_length);
884 memcpy(&net_info[client_player_num].addr, &hent->h_addr, hent->h_length);
885 net_info[client_player_num].addrlen = hent->h_length;
886 memcpy(&inaddr, hent->h_addr, hent->h_length);
887 strncpy(ipstr, inet_ntoa(inaddr), sizeof (ipstr));
889 printf("CLIENT: we are [%s].\n", ipstr);
891 /*gettimeofday(&net_info[client_player_num].last_timestamp, NULL);*/
893 hent = gethostbyname(netarg);
895 herror("CLIENT: couldn't find host");
899 sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
901 perror("CLIENT: socket()");
905 memcpy(&inaddr, hent->h_addr, hent->h_length);
906 printf("CLIENT: connecting to [%s]...\n", inet_ntoa(inaddr));
908 addr.sin_family = AF_INET;
909 addr.sin_port = htons(JNB_INETPORT);
910 memcpy(&addr.sin_addr.s_addr, hent->h_addr, hent->h_length);
911 if (connect(sock, (struct sockaddr *) &addr, sizeof (addr)) == -1) {
912 perror("CLIENT: connect()");
916 printf("CLIENT: Got socket. Sending HELLO packet...\n");
917 pkt.cmd = NETCMD_HELLO;
918 pkt.arg = client_player_num;
919 sendPacketToSock(sock, &pkt);
921 printf("CLIENT: Waiting for ACK from server...\n");
923 addrlen = sizeof (addr);
924 br = read(sock, buf, NETPKTBUFSIZE);
926 perror("CLIENT: read()");
931 if (br != NETPKTBUFSIZE) {
932 printf("CLIENT: Bogus packet size (%d of %d). FIXME.\n",
938 bufToPacket(buf, &pkt);
940 if (pkt.cmd == NETCMD_NACK) {
941 printf("CLIENT: Server forbid us from playing.\n");
946 if (pkt.cmd != NETCMD_ACK) {
947 printf("CLIENT: Unexpected packet (cmd=0x%lX).\n", pkt.cmd);
952 printf("CLIENT: Server accepted our connection.\n");
954 wait_for_greenlight();
959 static flip_pixels(unsigned char *pixels)
965 for (y = 0; y < JNB_HEIGHT; y++) {
966 for (x = 0; x < (352/2); x++) {
967 temp = pixels[y*JNB_WIDTH+x];
968 pixels[y*JNB_WIDTH+x] = pixels[y*JNB_WIDTH+(352-x)-1];
969 pixels[y*JNB_WIDTH+(352-x)-1] = temp;
975 int main(int argc, char *argv[])
977 unsigned char *handle;
978 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
981 int closest_player = 0, dist, cur_dist = 0;
982 int end_loop_flag = 0, fade_flag;
983 int mod_vol, sfx_vol, mod_fade_direction;
989 if (init_program(argc, argv, pal) != 0)
992 if (main_info.fireworks == 1) {
1003 if (key_pressed(1) == 1) {
1006 if (init_level(0, pal) != 0) {
1011 memset(cur_pal, 0, 768);
1012 setpalette(0, 256, cur_pal);
1014 recalculate_gob(&rabbit_gobs, pal);
1015 //recalculate_gob(&font_gobs, pal);
1016 recalculate_gob(&object_gobs, pal);
1017 recalculate_gob(&number_gobs, pal);
1020 register_background(background_pic, pal);
1023 if (flies_enabled) {
1027 for (c1 = 0; c1 < NUM_FLIES; c1++) {
1029 flies[c1].x = s1 + rnd(101) - 50;
1030 flies[c1].y = s2 + rnd(101) - 50;
1031 if (ban_map[flies[c1].y >> 4][flies[c1].x >> 4] == BAN_VOID)
1034 flies[c1].back_defined[0] = 0;
1035 flies[c1].back_defined[1] = 0;
1039 mod_vol = sfx_vol = 10;
1040 mod_fade_direction = 1;
1041 dj_ready_mod(MOD_GAME);
1042 dj_set_mod_volume((char)mod_vol);
1043 dj_set_sfx_volume((char)mod_vol);
1047 dj_play_sfx(SFX_FLY, SFX_FLY_FREQ, 0, 0, 0, 4);
1051 lord_of_the_flies = bunnies_in_space = jetpack = pogostick = blood_is_thicker_than_water = 0;
1053 main_info.page_info[0].num_pobs = 0;
1054 main_info.page_info[1].num_pobs = 0;
1055 main_info.view_page = 0;
1056 main_info.draw_page = 1;
1060 while (update_count) {
1062 if (key_pressed(1) == 1) {
1064 serverTellEveryoneGoodbye();
1066 tellServerGoodbye();
1069 memset(pal, 0, 768);
1070 mod_fade_direction = 0;
1073 if (strncmp(last_keys, "kcitsogop", strlen("kcitsogop")) == 0) {
1077 if (strncmp(last_keys, "ecapsniseinnub", strlen("ecapsniseinnub")) == 0) {
1078 bunnies_in_space ^= 1;
1081 if (strncmp(last_keys, "kcaptej", strlen("kcaptej")) == 0) {
1085 if (strncmp(last_keys, "seilfehtfodrol", strlen("seilfehtfodrol")) == 0) {
1086 lord_of_the_flies ^= 1;
1089 if (strncmp(last_keys, "retawnahtrekcihtsidoolb", strlen("retawnahtrekcihtsidoolb")) == 0) {
1090 blood_is_thicker_than_water ^= 1;
1091 if (blood_is_thicker_than_water == 1) {
1142 register_background(background_pic, pal);
1143 recalculate_gob(&object_gobs, pal);
1148 update_players_from_clients();
1150 if (!update_players_from_server()) {
1151 break; /* got a BYE packet */
1159 for (c3 = 0; c3 < 6; c3++) {
1163 } else if (c3 == 1) {
1166 } else if (c3 == 2) {
1169 } else if (c3 == 3) {
1172 } else if (c3 == 4) {
1175 } else if (c3 == 5) {
1179 if (player[c1].enabled == 1 && player[c2].enabled == 1) {
1180 if (labs(player[c1].x - player[c2].x) < (12L << 16) && labs(player[c1].y - player[c2].y) < (12L << 16)) {
1181 if ((labs(player[c1].y - player[c2].y) >> 16) > 5) {
1182 if (player[c1].y < player[c2].y) {
1183 if (player[c1].y_add >= 0) {
1185 serverSendKillPacket(c1, c2);
1187 if (player[c2].y_add < 0)
1188 player[c2].y_add = 0;
1191 if (player[c2].y_add >= 0) {
1193 serverSendKillPacket(c2, c1);
1195 if (player[c1].y_add < 0)
1196 player[c1].y_add = 0;
1200 if (player[c1].x < player[c2].x) {
1201 if (player[c1].x_add > 0)
1202 player[c1].x = player[c2].x - (12L << 16);
1203 else if (player[c2].x_add < 0)
1204 player[c2].x = player[c1].x + (12L << 16);
1206 player[c1].x -= player[c1].x_add;
1207 player[c2].x -= player[c2].x_add;
1209 l1 = player[c2].x_add;
1210 player[c2].x_add = player[c1].x_add;
1211 player[c1].x_add = l1;
1212 if (player[c1].x_add > 0)
1213 player[c1].x_add = -player[c1].x_add;
1214 if (player[c2].x_add < 0)
1215 player[c2].x_add = -player[c2].x_add;
1217 if (player[c1].x_add > 0)
1218 player[c2].x = player[c1].x - (12L << 16);
1219 else if (player[c2].x_add < 0)
1220 player[c1].x = player[c2].x + (12L << 16);
1222 player[c1].x -= player[c1].x_add;
1223 player[c2].x -= player[c2].x_add;
1225 l1 = player[c2].x_add;
1226 player[c2].x_add = player[c1].x_add;
1227 player[c1].x_add = l1;
1228 if (player[c1].x_add < 0)
1229 player[c1].x_add = -player[c1].x_add;
1230 if (player[c2].x_add > 0)
1231 player[c2].x_add = -player[c2].x_add;
1240 main_info.page_info[main_info.draw_page].num_pobs = 0;
1241 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1242 if (player[c1].enabled == 1)
1243 main_info.page_info[main_info.draw_page].num_pobs++;
1250 if (flies_enabled) {
1251 /* get center of fly swarm */
1253 for (c1 = 0; c1 < NUM_FLIES; c1++) {
1260 if (update_count == 1) {
1261 /* get closest player to fly swarm */
1263 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1264 if (player[c1].enabled == 1) {
1265 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)));
1266 if (cur_dist < dist) {
1267 closest_player = c1;
1272 /* update fly swarm sound */
1276 dj_set_sfx_channel_volume(4, (char)(s3));
1279 for (c1 = 0; c1 < NUM_FLIES; c1++) {
1280 /* get closest player to fly */
1282 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
1283 if (player[c2].enabled == 1) {
1284 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)));
1285 if (cur_dist < dist) {
1286 closest_player = c2;
1291 flies[c1].old_x = flies[c1].x;
1292 flies[c1].old_y = flies[c1].y;
1294 if ((s1 - flies[c1].x) > 30)
1296 else if ((s1 - flies[c1].x) < -30)
1299 if (((player[closest_player].x >> 16) + 8) > flies[c1].x) {
1300 if (lord_of_the_flies == 0)
1305 if (lord_of_the_flies == 0)
1311 s4 = rnd(3) - 1 + s3;
1312 if ((flies[c1].x + s4) < 16)
1314 if ((flies[c1].x + s4) > 351)
1316 if (ban_map[flies[c1].y >> 4][(flies[c1].x + s4) >> 4] != BAN_VOID)
1320 if ((s2 - flies[c1].y) > 30)
1322 else if ((s2 - flies[c1].y) < -30)
1325 if (((player[closest_player].y >> 16) + 8) > flies[c1].y) {
1326 if (lord_of_the_flies == 0)
1331 if (lord_of_the_flies == 0)
1337 s4 = rnd(3) - 1 + s3;
1338 if ((flies[c1].y + s4) < 0)
1340 if ((flies[c1].y + s4) > 239)
1342 if (ban_map[(flies[c1].y + s4) >> 4][flies[c1].x >> 4] != BAN_VOID)
1351 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1352 if (player[c1].enabled == 1) {
1353 main_info.page_info[main_info.draw_page].pobs[s1].x = player[c1].x >> 16;
1354 main_info.page_info[main_info.draw_page].pobs[s1].y = player[c1].y >> 16;
1355 main_info.page_info[main_info.draw_page].pobs[s1].image = player[c1].image + c1 * 18;
1356 main_info.page_info[main_info.draw_page].pobs[s1].pob_data = &rabbit_gobs;
1361 if (update_count == 1) {
1364 draw_pobs(main_info.draw_page);
1369 draw_flies(main_info.draw_page);
1374 if (mod_fade_direction == 1) {
1377 dj_set_mod_volume((char)mod_vol);
1382 dj_set_mod_volume((char)mod_vol);
1386 if (mod_fade_direction == 1) {
1389 dj_set_sfx_volume((char)sfx_vol);
1394 dj_set_sfx_volume((char)sfx_vol);
1399 for (c1 = 0; c1 < 768; c1++) {
1400 if (cur_pal[c1] < pal[c1]) {
1403 } else if (cur_pal[c1] > pal[c1]) {
1408 if (fade_flag == 0 && end_loop_flag == 1)
1411 if (update_count == 1) {
1412 main_info.draw_page ^= 1;
1413 main_info.view_page ^= 1;
1415 flippage(main_info.view_page);
1421 setpalette(0, 256, cur_pal);
1423 if (update_count == 1) {
1427 redraw_flies_background(main_info.draw_page);
1429 redraw_pob_backgrounds(main_info.draw_page);
1431 draw_leftovers(main_info.draw_page);
1439 if ( (player[client_player_num].dead_flag == 0) &&
1441 (player[client_player_num].action_left) ||
1442 (player[client_player_num].action_right) ||
1443 (player[client_player_num].action_up) ||
1444 (player[client_player_num].jump_ready == 0)
1447 tellServerNewPosition();
1450 update_count = intr_sysupdate();
1452 if ((server_said_bye) || ((fade_flag == 0) && (end_loop_flag == 1)))
1457 serverTellEveryoneGoodbye();
1461 if (!server_said_bye) {
1462 tellServerGoodbye();
1469 main_info.view_page = 0;
1470 main_info.draw_page = 1;
1472 dj_stop_sfx_channel(4);
1476 memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
1477 register_mask(mask_pic);
1479 //recalculate_gob(&font_gobs, pal);
1480 register_background(NULL, NULL);
1484 put_text(main_info.view_page, 100, 50, "DOTT", 2);
1485 put_text(main_info.view_page, 160, 50, "JIFFY", 2);
1486 put_text(main_info.view_page, 220, 50, "FIZZ", 2);
1487 put_text(main_info.view_page, 280, 50, "MIJJI", 2);
1488 put_text(main_info.view_page, 40, 80, "DOTT", 2);
1489 put_text(main_info.view_page, 40, 110, "JIFFY", 2);
1490 put_text(main_info.view_page, 40, 140, "FIZZ", 2);
1491 put_text(main_info.view_page, 40, 170, "MIJJI", 2);
1493 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1494 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
1496 sprintf(str1, "%d", player[c1].bumped[c2]);
1497 put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, str1, 2);
1499 put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, "-", 2);
1501 sprintf(str1, "%d", player[c1].bumps);
1502 put_text(main_info.view_page, 350, 80 + c1 * 30, str1, 2);
1505 put_text(main_info.view_page, 200, 230, "Press ESC to continue", 2);
1509 flippage(main_info.view_page);
1511 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
1512 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1515 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
1516 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1520 for (c1 = 0; c1 < 16; c1++) { // fix dark font
1521 pal[(240 + c1) * 3 + 0] = c1 << 2;
1522 pal[(240 + c1) * 3 + 1] = c1 << 2;
1523 pal[(240 + c1) * 3 + 2] = c1 << 2;
1526 memset(cur_pal, 0, 768);
1528 setpalette(0, 256, cur_pal);
1531 dj_ready_mod(MOD_SCORES);
1532 dj_set_mod_volume((char)mod_vol);
1536 while (key_pressed(1) == 0) {
1539 dj_set_mod_volume((char)mod_vol);
1540 for (c1 = 0; c1 < 768; c1++) {
1541 if (cur_pal[c1] < pal[c1])
1547 setpalette(0, 256, cur_pal);
1548 flippage(main_info.view_page);
1550 while (key_pressed(1) == 1) {
1555 memset(pal, 0, 768);
1557 while (mod_vol > 0) {
1559 dj_set_mod_volume((char)mod_vol);
1560 for (c1 = 0; c1 < 768; c1++) {
1561 if (cur_pal[c1] > pal[c1])
1566 setpalette(0, 256, cur_pal);
1567 flippage(main_info.view_page);
1570 fillpalette(0, 0, 0);
1576 break; /* don't go back to menu if in net game. */
1585 void steer_players(void)
1590 update_player_actions();
1592 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1594 if (player[c1].enabled == 1) {
1596 if (player[c1].dead_flag == 0) {
1598 if (player[c1].action_left && player[c1].action_right) {
1599 if (player[c1].direction == 0) {
1600 if (player[c1].action_right) {
1601 s1 = (player[c1].x >> 16);
1602 s2 = (player[c1].y >> 16);
1603 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1604 if (player[c1].x_add < 0)
1605 player[c1].x_add += 1024;
1607 player[c1].x_add += 768;
1608 } 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)) {
1609 if (player[c1].x_add > 0)
1610 player[c1].x_add += 1024;
1612 player[c1].x_add += 768;
1614 if (player[c1].x_add < 0) {
1615 player[c1].x_add += 16384;
1616 if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1617 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);
1619 player[c1].x_add += 12288;
1621 if (player[c1].x_add > 98304L)
1622 player[c1].x_add = 98304L;
1623 player[c1].direction = 0;
1624 if (player[c1].anim == 0) {
1625 player[c1].anim = 1;
1626 player[c1].frame = 0;
1627 player[c1].frame_tick = 0;
1628 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1632 if (player[c1].action_left) {
1633 s1 = (player[c1].x >> 16);
1634 s2 = (player[c1].y >> 16);
1635 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1636 if (player[c1].x_add > 0)
1637 player[c1].x_add -= 1024;
1639 player[c1].x_add -= 768;
1640 } 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)) {
1641 if (player[c1].x_add > 0)
1642 player[c1].x_add -= 1024;
1644 player[c1].x_add -= 768;
1646 if (player[c1].x_add > 0) {
1647 player[c1].x_add -= 16384;
1648 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1649 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);
1651 player[c1].x_add -= 12288;
1653 if (player[c1].x_add < -98304L)
1654 player[c1].x_add = -98304L;
1655 player[c1].direction = 1;
1656 if (player[c1].anim == 0) {
1657 player[c1].anim = 1;
1658 player[c1].frame = 0;
1659 player[c1].frame_tick = 0;
1660 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1664 } else if (player[c1].action_left) {
1665 s1 = (player[c1].x >> 16);
1666 s2 = (player[c1].y >> 16);
1667 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1668 if (player[c1].x_add > 0)
1669 player[c1].x_add -= 1024;
1671 player[c1].x_add -= 768;
1672 } 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)) {
1673 if (player[c1].x_add > 0)
1674 player[c1].x_add -= 1024;
1676 player[c1].x_add -= 768;
1678 if (player[c1].x_add > 0) {
1679 player[c1].x_add -= 16384;
1680 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1681 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);
1683 player[c1].x_add -= 12288;
1685 if (player[c1].x_add < -98304L)
1686 player[c1].x_add = -98304L;
1687 player[c1].direction = 1;
1688 if (player[c1].anim == 0) {
1689 player[c1].anim = 1;
1690 player[c1].frame = 0;
1691 player[c1].frame_tick = 0;
1692 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1694 } else if (player[c1].action_right) {
1695 s1 = (player[c1].x >> 16);
1696 s2 = (player[c1].y >> 16);
1697 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1698 if (player[c1].x_add < 0)
1699 player[c1].x_add += 1024;
1701 player[c1].x_add += 768;
1702 } 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)) {
1703 if (player[c1].x_add > 0)
1704 player[c1].x_add += 1024;
1706 player[c1].x_add += 768;
1708 if (player[c1].x_add < 0) {
1709 player[c1].x_add += 16384;
1710 if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1711 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);
1713 player[c1].x_add += 12288;
1715 if (player[c1].x_add > 98304L)
1716 player[c1].x_add = 98304L;
1717 player[c1].direction = 0;
1718 if (player[c1].anim == 0) {
1719 player[c1].anim = 1;
1720 player[c1].frame = 0;
1721 player[c1].frame_tick = 0;
1722 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1724 } else if ((!player[c1].action_left) && (!player[c1].action_right)) {
1725 s1 = (player[c1].x >> 16);
1726 s2 = (player[c1].y >> 16);
1727 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)))) {
1728 if (player[c1].x_add < 0) {
1729 player[c1].x_add += 16384;
1730 if (player[c1].x_add > 0)
1731 player[c1].x_add = 0;
1733 player[c1].x_add -= 16384;
1734 if (player[c1].x_add < 0)
1735 player[c1].x_add = 0;
1737 if (player[c1].x_add != 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1738 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);
1740 if (player[c1].anim == 1) {
1741 player[c1].anim = 0;
1742 player[c1].frame = 0;
1743 player[c1].frame_tick = 0;
1744 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1748 if (pogostick == 1 || (player[c1].jump_ready == 1 && player[c1].action_up)) {
1749 s1 = (player[c1].x >> 16);
1750 s2 = (player[c1].y >> 16);
1753 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) {
1754 player[c1].y_add = -280000L;
1755 player[c1].anim = 2;
1756 player[c1].frame = 0;
1757 player[c1].frame_tick = 0;
1758 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1759 player[c1].jump_ready = 0;
1760 player[c1].jump_abort = 1;
1762 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1764 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1766 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)) {
1767 player[c1].y_add = -196608L;
1768 player[c1].in_water = 0;
1769 player[c1].anim = 2;
1770 player[c1].frame = 0;
1771 player[c1].frame_tick = 0;
1772 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1773 player[c1].jump_ready = 0;
1774 player[c1].jump_abort = 1;
1776 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1778 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1781 if (pogostick == 0 && (!player[c1].action_up)) {
1782 player[c1].jump_ready = 1;
1783 if (player[c1].in_water == 0 && player[c1].y_add < 0 && player[c1].jump_abort == 1) {
1784 if (bunnies_in_space == 0)
1785 player[c1].y_add += 32768;
1787 player[c1].y_add += 16384;
1788 if (player[c1].y_add > 0)
1789 player[c1].y_add = 0;
1794 if (player[c1].action_up) {
1795 player[c1].y_add -= 16384;
1796 if (player[c1].y_add < -400000L)
1797 player[c1].y_add = -400000L;
1798 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))
1799 player[c1].in_water = 0;
1801 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);
1806 player[c1].x += player[c1].x_add;
1807 if ((player[c1].x >> 16) < 0) {
1809 player[c1].x_add = 0;
1811 if ((player[c1].x >> 16) + 15 > 351) {
1812 player[c1].x = 336L << 16;
1813 player[c1].x_add = 0;
1815 if (player[c1].y > 0) {
1816 s1 = (player[c1].x >> 16);
1817 s2 = (player[c1].y >> 16);
1818 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) {
1819 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1820 player[c1].x_add = 0;
1822 s1 = (player[c1].x >> 16);
1823 s2 = (player[c1].y >> 16);
1824 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) {
1825 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1826 player[c1].x_add = 0;
1829 s1 = (player[c1].x >> 16);
1831 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) {
1832 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1833 player[c1].x_add = 0;
1835 s1 = (player[c1].x >> 16);
1837 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) {
1838 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1839 player[c1].x_add = 0;
1843 player[c1].y += player[c1].y_add;
1845 s1 = (player[c1].x >> 16);
1846 s2 = (player[c1].y >> 16);
1847 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))) {
1848 player[c1].y = ((player[c1].y >> 16) & 0xfff0) << 16;
1849 player[c1].y_add = -400000L;
1850 player[c1].anim = 2;
1851 player[c1].frame = 0;
1852 player[c1].frame_tick = 0;
1853 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1854 player[c1].jump_ready = 0;
1855 player[c1].jump_abort = 0;
1856 for (c2 = 0; c2 < NUM_OBJECTS; c2++) {
1857 if (objects[c2].used == 1 && objects[c2].type == OBJ_SPRING) {
1858 if (ban_map[(s2 + 15) >> 4][(s1 + 8) >> 4] == BAN_SPRING) {
1859 if ((objects[c2].x >> 20) == ((s1 + 8) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1860 objects[c2].frame = 0;
1861 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1862 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1866 if (ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
1867 if ((objects[c2].x >> 20) == (s1 >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1868 objects[c2].frame = 0;
1869 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1870 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1873 } else if (ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1874 if ((objects[c2].x >> 20) == ((s1 + 15) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1875 objects[c2].frame = 0;
1876 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1877 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1884 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1886 s1 = (player[c1].x >> 16);
1887 s2 = (player[c1].y >> 16);
1890 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) {
1891 player[c1].y = (((s2 + 16) & 0xfff0)) << 16;
1892 player[c1].y_add = 0;
1893 player[c1].anim = 0;
1894 player[c1].frame = 0;
1895 player[c1].frame_tick = 0;
1896 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1898 s1 = (player[c1].x >> 16);
1899 s2 = (player[c1].y >> 16);
1902 if (ban_map[(s2 + 8) >> 4][(s1 + 8) >> 4] == BAN_WATER) {
1903 if (player[c1].in_water == 0) {
1904 player[c1].in_water = 1;
1905 player[c1].anim = 4;
1906 player[c1].frame = 0;
1907 player[c1].frame_tick = 0;
1908 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1909 if (player[c1].y_add >= 32768) {
1910 add_object(OBJ_SPLASH, (player[c1].x >> 16) + 8, ((player[c1].y >> 16) & 0xfff0) + 15, 0, 0, OBJ_ANIM_SPLASH, 0);
1911 if (blood_is_thicker_than_water == 0)
1912 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1914 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 5000), 64, 0, 0, -1);
1917 player[c1].y_add -= 1536;
1918 if (player[c1].y_add < 0 && player[c1].anim != 5) {
1919 player[c1].anim = 5;
1920 player[c1].frame = 0;
1921 player[c1].frame_tick = 0;
1922 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1924 if (player[c1].y_add < -65536L)
1925 player[c1].y_add = -65536L;
1926 if (player[c1].y_add > 65535L)
1927 player[c1].y_add = 65535L;
1928 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) {
1929 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1930 player[c1].y_add = 0;
1932 } 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) {
1933 player[c1].in_water = 0;
1934 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1935 player[c1].y_add = 0;
1936 if (player[c1].anim != 0 && player[c1].anim != 1) {
1937 player[c1].anim = 0;
1938 player[c1].frame = 0;
1939 player[c1].frame_tick = 0;
1940 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1943 if (player[c1].in_water == 0) {
1944 if (bunnies_in_space == 0)
1945 player[c1].y_add += 12288;
1947 player[c1].y_add += 6144;
1948 if (player[c1].y_add > 327680L)
1949 player[c1].y_add = 327680L;
1951 player[c1].y = (player[c1].y & 0xffff0000) + 0x10000;
1952 player[c1].y_add = 0;
1954 player[c1].in_water = 0;
1956 if (player[c1].y_add > 36864 && player[c1].anim != 3 && player[c1].in_water == 0) {
1957 player[c1].anim = 3;
1958 player[c1].frame = 0;
1959 player[c1].frame_tick = 0;
1960 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1965 player[c1].frame_tick++;
1966 if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
1968 if (player[c1].frame >= player_anims[player[c1].anim].num_frames) {
1969 if (player[c1].anim != 6)
1970 player[c1].frame = player_anims[player[c1].anim].restart_frame;
1972 position_player(c1);
1974 player[c1].frame_tick = 0;
1976 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1985 void position_player(int player_num)
1994 if (ban_map[s2][s1] == BAN_VOID && (ban_map[s2 + 1][s1] == BAN_SOLID || ban_map[s2 + 1][s1] == BAN_ICE))
1997 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1998 if (c1 != player_num && player[c1].enabled == 1) {
1999 if (abs((s1 << 4) - (player[c1].x >> 16)) < 32 && abs((s2 << 4) - (player[c1].y >> 16)) < 32)
2003 if (c1 == JNB_MAX_PLAYERS) {
2004 player[player_num].x = (long) s1 << 20;
2005 player[player_num].y = (long) s2 << 20;
2006 player[player_num].x_add = player[player_num].y_add = 0;
2007 player[player_num].direction = 0;
2008 player[player_num].jump_ready = 1;
2009 player[player_num].in_water = 0;
2010 player[player_num].anim = 0;
2011 player[player_num].frame = 0;
2012 player[player_num].frame_tick = 0;
2013 player[player_num].image = player_anims[player[player_num].anim].frame[player[player_num].frame].image;
2016 serverSendAlive(player_num);
2017 player[player_num].dead_flag = 0;
2027 void add_object(int type, int x, int y, int x_add, int y_add, int anim, int frame)
2031 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
2032 if (objects[c1].used == 0) {
2033 objects[c1].used = 1;
2034 objects[c1].type = type;
2035 objects[c1].x = (long) x << 16;
2036 objects[c1].y = (long) y << 16;
2037 objects[c1].x_add = x_add;
2038 objects[c1].y_add = y_add;
2039 objects[c1].x_acc = 0;
2040 objects[c1].y_acc = 0;
2041 objects[c1].anim = anim;
2042 objects[c1].frame = frame;
2043 objects[c1].ticks = object_anims[anim].frame[frame].ticks;
2044 objects[c1].image = object_anims[anim].frame[frame].image;
2052 void update_objects(void)
2057 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
2058 if (objects[c1].used == 1) {
2059 switch (objects[c1].type) {
2061 objects[c1].ticks--;
2062 if (objects[c1].ticks <= 0) {
2063 objects[c1].frame++;
2064 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames) {
2065 objects[c1].frame--;
2066 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2068 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2069 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2072 if (objects[c1].used == 1)
2073 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2076 objects[c1].ticks--;
2077 if (objects[c1].ticks <= 0) {
2078 objects[c1].frame++;
2079 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2080 objects[c1].used = 0;
2082 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2083 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2086 if (objects[c1].used == 1)
2087 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2090 objects[c1].x += objects[c1].x_add;
2091 objects[c1].y += objects[c1].y_add;
2092 objects[c1].ticks--;
2093 if (objects[c1].ticks <= 0) {
2094 objects[c1].frame++;
2095 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2096 objects[c1].used = 0;
2098 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2099 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2102 if (objects[c1].used == 1)
2103 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2105 case OBJ_YEL_BUTFLY:
2106 case OBJ_PINK_BUTFLY:
2107 objects[c1].x_acc += rnd(128) - 64;
2108 if (objects[c1].x_acc < -1024)
2109 objects[c1].x_acc = -1024;
2110 if (objects[c1].x_acc > 1024)
2111 objects[c1].x_acc = 1024;
2112 objects[c1].x_add += objects[c1].x_acc;
2113 if (objects[c1].x_add < -32768)
2114 objects[c1].x_add = -32768;
2115 if (objects[c1].x_add > 32768)
2116 objects[c1].x_add = 32768;
2117 objects[c1].x += objects[c1].x_add;
2118 if ((objects[c1].x >> 16) < 16) {
2119 objects[c1].x = 16 << 16;
2120 objects[c1].x_add = -objects[c1].x_add >> 2;
2121 objects[c1].x_acc = 0;
2122 } else if ((objects[c1].x >> 16) > 350) {
2123 objects[c1].x = 350 << 16;
2124 objects[c1].x_add = -objects[c1].x_add >> 2;
2125 objects[c1].x_acc = 0;
2127 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
2128 if (objects[c1].x_add < 0) {
2129 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2131 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2133 objects[c1].x_add = -objects[c1].x_add >> 2;
2134 objects[c1].x_acc = 0;
2136 objects[c1].y_acc += rnd(64) - 32;
2137 if (objects[c1].y_acc < -1024)
2138 objects[c1].y_acc = -1024;
2139 if (objects[c1].y_acc > 1024)
2140 objects[c1].y_acc = 1024;
2141 objects[c1].y_add += objects[c1].y_acc;
2142 if (objects[c1].y_add < -32768)
2143 objects[c1].y_add = -32768;
2144 if (objects[c1].y_add > 32768)
2145 objects[c1].y_add = 32768;
2146 objects[c1].y += objects[c1].y_add;
2147 if ((objects[c1].y >> 16) < 0) {
2149 objects[c1].y_add = -objects[c1].y_add >> 2;
2150 objects[c1].y_acc = 0;
2151 } else if ((objects[c1].y >> 16) > 255) {
2152 objects[c1].y = 255 << 16;
2153 objects[c1].y_add = -objects[c1].y_add >> 2;
2154 objects[c1].y_acc = 0;
2156 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
2157 if (objects[c1].y_add < 0) {
2158 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2160 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2162 objects[c1].y_add = -objects[c1].y_add >> 2;
2163 objects[c1].y_acc = 0;
2165 if (objects[c1].type == OBJ_YEL_BUTFLY) {
2166 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_LEFT) {
2167 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_LEFT;
2168 objects[c1].frame = 0;
2169 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2170 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2171 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_RIGHT) {
2172 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_RIGHT;
2173 objects[c1].frame = 0;
2174 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2175 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2178 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_LEFT) {
2179 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_LEFT;
2180 objects[c1].frame = 0;
2181 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2182 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2183 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_RIGHT) {
2184 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_RIGHT;
2185 objects[c1].frame = 0;
2186 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2187 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2190 objects[c1].ticks--;
2191 if (objects[c1].ticks <= 0) {
2192 objects[c1].frame++;
2193 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2194 objects[c1].frame = object_anims[objects[c1].anim].restart_frame;
2196 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2197 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2200 if (objects[c1].used == 1)
2201 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2205 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 0);
2206 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
2207 objects[c1].y_add += 3072;
2208 if (objects[c1].y_add > 196608L)
2209 objects[c1].y_add = 196608L;
2210 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
2211 if (objects[c1].x_add < 0) {
2212 if (objects[c1].x_add < -65536L)
2213 objects[c1].x_add = -65536L;
2214 objects[c1].x_add += 1024;
2215 if (objects[c1].x_add > 0)
2216 objects[c1].x_add = 0;
2218 if (objects[c1].x_add > 65536L)
2219 objects[c1].x_add = 65536L;
2220 objects[c1].x_add -= 1024;
2221 if (objects[c1].x_add < 0)
2222 objects[c1].x_add = 0;
2224 objects[c1].y_add += 1024;
2225 if (objects[c1].y_add < -65536L)
2226 objects[c1].y_add = -65536L;
2227 if (objects[c1].y_add > 65536L)
2228 objects[c1].y_add = 65536L;
2230 objects[c1].x += objects[c1].x_add;
2231 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)) {
2232 if (objects[c1].x_add < 0) {
2233 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2234 objects[c1].x_add = -objects[c1].x_add >> 2;
2236 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2237 objects[c1].x_add = -objects[c1].x_add >> 2;
2240 objects[c1].y += objects[c1].y_add;
2241 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
2242 objects[c1].used = 0;
2243 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
2244 if (objects[c1].y_add < 0) {
2245 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
2246 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2247 objects[c1].x_add >>= 2;
2248 objects[c1].y_add = -objects[c1].y_add >> 2;
2251 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
2252 if (objects[c1].y_add > 131072L) {
2253 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2254 objects[c1].x_add >>= 2;
2255 objects[c1].y_add = -objects[c1].y_add >> 2;
2257 objects[c1].used = 0;
2258 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
2259 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2260 if (objects[c1].y_add > 131072L)
2261 objects[c1].y_add = -objects[c1].y_add >> 2;
2263 objects[c1].y_add = 0;
2267 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
2268 objects[c1].x_add = -16384;
2269 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
2270 objects[c1].x_add = 16384;
2271 if (objects[c1].used == 1) {
2272 s1 = (int)(atan2(objects[c1].y_add, objects[c1].x_add) * 4 / M_PI);
2279 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame + s1, &object_gobs);
2283 if (rnd(100) < 30) {
2284 if (objects[c1].frame == 76)
2285 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 1);
2286 else if (objects[c1].frame == 77)
2287 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 2);
2288 else if (objects[c1].frame == 78)
2289 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 3);
2291 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
2292 objects[c1].y_add += 3072;
2293 if (objects[c1].y_add > 196608L)
2294 objects[c1].y_add = 196608L;
2295 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
2296 if (objects[c1].x_add < 0) {
2297 if (objects[c1].x_add < -65536L)
2298 objects[c1].x_add = -65536L;
2299 objects[c1].x_add += 1024;
2300 if (objects[c1].x_add > 0)
2301 objects[c1].x_add = 0;
2303 if (objects[c1].x_add > 65536L)
2304 objects[c1].x_add = 65536L;
2305 objects[c1].x_add -= 1024;
2306 if (objects[c1].x_add < 0)
2307 objects[c1].x_add = 0;
2309 objects[c1].y_add += 1024;
2310 if (objects[c1].y_add < -65536L)
2311 objects[c1].y_add = -65536L;
2312 if (objects[c1].y_add > 65536L)
2313 objects[c1].y_add = 65536L;
2315 objects[c1].x += objects[c1].x_add;
2316 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)) {
2317 if (objects[c1].x_add < 0) {
2318 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2319 objects[c1].x_add = -objects[c1].x_add >> 2;
2321 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2322 objects[c1].x_add = -objects[c1].x_add >> 2;
2325 objects[c1].y += objects[c1].y_add;
2326 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
2327 objects[c1].used = 0;
2328 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
2329 if (objects[c1].y_add < 0) {
2330 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
2331 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2332 objects[c1].x_add >>= 2;
2333 objects[c1].y_add = -objects[c1].y_add >> 2;
2336 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
2337 if (objects[c1].y_add > 131072L) {
2338 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2339 objects[c1].x_add >>= 2;
2340 objects[c1].y_add = -objects[c1].y_add >> 2;
2342 if (rnd(100) < 10) {
2344 add_leftovers(0, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
2345 add_leftovers(1, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
2347 objects[c1].used = 0;
2349 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
2350 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2351 if (objects[c1].y_add > 131072L)
2352 objects[c1].y_add = -objects[c1].y_add >> 2;
2354 objects[c1].y_add = 0;
2358 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
2359 objects[c1].x_add = -16384;
2360 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
2361 objects[c1].x_add = 16384;
2362 if (objects[c1].used == 1)
2363 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame, &object_gobs);
2365 case OBJ_FLESH_TRACE:
2366 objects[c1].ticks--;
2367 if (objects[c1].ticks <= 0) {
2368 objects[c1].frame++;
2369 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2370 objects[c1].used = 0;
2372 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2373 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2376 if (objects[c1].used == 1)
2377 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2386 int add_pob(int page, int x, int y, int image, gob_t *pob_data)
2389 if (main_info.page_info[page].num_pobs >= NUM_POBS)
2392 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].x = x;
2393 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].y = y;
2394 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].image = image;
2395 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].pob_data = pob_data;
2396 main_info.page_info[page].num_pobs++;
2403 void draw_flies(int page)
2407 for (c2 = 0; c2 < NUM_FLIES; c2++) {
2408 flies[c2].back[main_info.draw_page] = get_pixel(main_info.draw_page, flies[c2].x, flies[c2].y);
2409 flies[c2].back_defined[main_info.draw_page] = 1;
2410 if (mask_pic[(flies[c2].y * JNB_WIDTH) + flies[c2].x] == 0)
2411 set_pixel(main_info.draw_page, flies[c2].x, flies[c2].y, 0);
2415 void draw_pobs(int page)
2422 for (c1 = main_info.page_info[page].num_pobs - 1; c1 >= 0; c1--) {
2423 main_info.page_info[page].pobs[c1].back_buf_ofs = back_buf_ofs;
2424 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);
2426 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;
2428 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;
2429 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);
2435 void redraw_flies_background(int page)
2439 for (c2 = NUM_FLIES - 1; c2 >= 0; c2--) {
2440 if (flies[c2].back_defined[page] == 1)
2441 set_pixel(page, flies[c2].old_draw_x, flies[c2].old_draw_y, flies[c2].back[page]);
2442 flies[c2].old_draw_x = flies[c2].x;
2443 flies[c2].old_draw_y = flies[c2].y;
2448 void redraw_pob_backgrounds(int page)
2452 for (c1 = 0; c1 < main_info.page_info[page].num_pobs; c1++)
2453 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);
2458 int add_leftovers(int page, int x, int y, int image, gob_t *pob_data)
2461 if (leftovers.page[page].num_pobs >= NUM_LEFTOVERS)
2464 leftovers.page[page].pobs[leftovers.page[page].num_pobs].x = x;
2465 leftovers.page[page].pobs[leftovers.page[page].num_pobs].y = y;
2466 leftovers.page[page].pobs[leftovers.page[page].num_pobs].image = image;
2467 leftovers.page[page].pobs[leftovers.page[page].num_pobs].pob_data = pob_data;
2468 leftovers.page[page].num_pobs++;
2475 void draw_leftovers(int page)
2479 for (c1 = leftovers.page[page].num_pobs - 1; c1 >= 0; c1--)
2480 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);
2482 leftovers.page[page].num_pobs = 0;
2487 int init_level(int level, char *pal)
2489 unsigned char *handle;
2493 if ((handle = dat_open("level.pcx", datfile_name, "rb")) == 0) {
2494 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2497 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
2498 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2502 flip_pixels(background_pic);
2503 if ((handle = dat_open("mask.pcx", datfile_name, "rb")) == 0) {
2504 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2507 if (read_pcx(handle, mask_pic, JNB_WIDTH*JNB_HEIGHT, 0) != 0) {
2508 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2512 flip_pixels(mask_pic);
2513 register_mask(mask_pic);
2515 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
2516 if (player[c1].enabled == 1) {
2517 player[c1].bumps = 0;
2518 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++)
2519 player[c1].bumped[c2] = 0;
2520 position_player(c1);
2524 for (c1 = 0; c1 < NUM_OBJECTS; c1++)
2525 objects[c1].used = 0;
2527 for (c1 = 0; c1 < 16; c1++) {
2528 for (c2 = 0; c2 < 22; c2++) {
2529 if (ban_map[c1][c2] == BAN_SPRING)
2530 add_object(OBJ_SPRING, c2 << 4, c1 << 4, 0, 0, OBJ_ANIM_SPRING, 5);
2537 if (ban_map[s2][s1] == BAN_VOID) {
2538 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2545 if (ban_map[s2][s1] == BAN_VOID) {
2546 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2553 if (ban_map[s2][s1] == BAN_VOID) {
2554 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2561 if (ban_map[s2][s1] == BAN_VOID) {
2562 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2572 void deinit_level(void)
2580 #define PATH_MAX 1024
2583 unsigned char *datafile_buffer = NULL;
2585 static void preread_datafile(const char *fname)
2591 char *gzfilename = alloca(strlen(fname) + 4);
2596 strcpy(gzfilename, fname);
2597 strcat(gzfilename, ".gz");
2599 gzf = gzopen(gzfilename, "rb");
2604 if (bufpos >= bufsize) {
2605 bufsize += 1024 * 1024;
2606 datafile_buffer = (unsigned char *) realloc(datafile_buffer, bufsize);
2607 if (datafile_buffer == NULL) {
2608 perror("realloc()");
2613 br = gzread(gzf, datafile_buffer + bufpos, bufsize - bufpos);
2615 fprintf(stderr, "gzread failed.\n");
2620 } while (!gzeof(gzf));
2622 /* try to shrink buffer... */
2623 ptr = (unsigned char *) realloc(datafile_buffer, bufpos);
2625 datafile_buffer = ptr;
2631 /* drop through and try for an uncompressed datafile... */
2634 fd = open(fname, O_RDONLY | O_BINARY);
2636 fprintf(stderr, "can't open %s: %s\n", fname, strerror(errno));
2640 len = filelength(fd);
2641 datafile_buffer = (unsigned char *) malloc(len);
2642 if (datafile_buffer == NULL) {
2648 if (read(fd, datafile_buffer, len) != len) {
2658 int init_program(int argc, char *argv[], char *pal)
2660 char *netarg = NULL;
2661 unsigned char *handle = (unsigned char *) NULL;
2666 int player_anim_data[] = {
2667 1, 0, 0, 0x7fff, 0, 0, 0, 0, 0, 0,
2668 4, 0, 0, 4, 1, 4, 2, 4, 3, 4,
2669 1, 0, 4, 0x7fff, 0, 0, 0, 0, 0, 0,
2670 4, 2, 5, 8, 6, 10, 7, 3, 6, 3,
2671 1, 0, 6, 0x7fff, 0, 0, 0, 0, 0, 0,
2672 2, 1, 5, 8, 4, 0x7fff, 0, 0, 0, 0,
2673 1, 0, 8, 5, 0, 0, 0, 0, 0, 0
2676 memset(&net_info, 0, sizeof(net_info));
2679 if (__djgpp_nearptr_enable() == 0)
2685 if (hook_keyb_handler() != 0)
2688 memset(&main_info, 0, sizeof(main_info));
2690 strcpy(datfile_name, DATA_PATH);
2692 force2 = force3 = 0;
2695 for (c1 = 1; c1 < argc; c1++) {
2696 if (stricmp(argv[c1], "-nosound") == 0)
2697 main_info.no_sound = 1;
2698 else if (stricmp(argv[c1], "-musicnosound") == 0)
2699 main_info.music_no_sound = 1;
2700 else if (stricmp(argv[c1], "-nogore") == 0)
2701 main_info.no_gore = 1;
2702 else if (stricmp(argv[c1], "-noflies") == 0)
2704 else if (stricmp(argv[c1], "-nojoy") == 0)
2705 main_info.joy_enabled = 0;
2706 else if (stricmp(argv[c1], "-fireworks") == 0)
2707 main_info.fireworks = 1;
2709 else if (stricmp(argv[c1], "-fullscreen") == 0)
2712 else if (stricmp(argv[c1], "-scaleup") == 0)
2714 else if (stricmp(argv[c1], "-mirror") == 0)
2716 else if (stricmp(argv[c1], "-dat") == 0) {
2717 if (c1 < (argc - 1)) {
2720 if ((f = fopen(argv[c1 + 1], "rb")) != NULL) {
2722 strcpy(datfile_name, argv[c1 + 1]);
2725 } else if (stricmp(argv[c1], "-player") == 0) {
2726 if (c1 < (argc - 1)) {
2727 if (client_player_num < 0)
2728 client_player_num = atoi(argv[c1 + 1]);
2730 } else if (stricmp(argv[c1], "-server") == 0) {
2731 if (c1 < (argc - 1)) {
2734 netarg = argv[c1 + 1];
2736 } else if (stricmp(argv[c1], "-connect") == 0) {
2737 if (c1 < (argc - 1)) {
2740 netarg = argv[c1 + 1];
2742 } else if (stricmp(argv[c1], "-mouse") == 0) {
2743 if (c1 < (argc - 1)) {
2744 if (stricmp(argv[c1 + 1], "2") == 0)
2746 if (stricmp(argv[c1 + 1], "3") == 0)
2750 else if (strstr(argv[1],"-v")) {
2751 printf("jumpnbump %s compiled %s at %s with",JNB_VERSION,__DATE__,__TIME__);
2755 printf(" network support.\n");
2758 else if (strstr(argv[1],"-h")) {
2759 printf("Usage: jumpnbump [OPTION]...\n");
2761 printf(" -h this help\n");
2762 printf(" -v print version\n");
2763 printf(" -dat level.dat play a different level\n");
2764 printf(" -port port define listen port\n");
2765 printf(" -net player host rport define network players\n");
2766 printf(" -fireworks screensaver mode\n");
2767 printf(" -fullscreen run in fullscreen mode\n");
2768 printf(" -nosound play without sound\n");
2769 printf(" -nogore play without blood\n");
2770 printf(" -noflies disable flies\n");
2771 printf(" -mirror play with mirrored level\n");
2772 printf(" -scaleup play with doubled resolution (800x512)\n");
2773 printf(" -musicnosound play with music but without sound\n");
2780 preread_datafile(datfile_name);
2783 if (client_player_num < 0)
2784 client_player_num = 0;
2785 player[client_player_num].enabled = 1;
2788 main_info.pob_backbuf[0] = malloc(screen_pitch*screen_height*bytes_per_pixel);
2789 main_info.pob_backbuf[1] = malloc(screen_pitch*screen_height*bytes_per_pixel);
2791 for (c1 = 0; c1 < 7; c1++) {
2792 player_anims[c1].num_frames = player_anim_data[c1 * 10];
2793 player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
2794 for (c2 = 0; c2 < 4; c2++) {
2795 player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
2796 player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
2800 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
2801 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2804 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
2805 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2809 if ((handle = dat_open("rabbit.gob", datfile_name, "rb")) == 0) {
2810 strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
2813 if (register_gob(handle, &rabbit_gobs, dat_filelen("rabbit.gob", datfile_name))) {
2818 if ((handle = dat_open("objects.gob", datfile_name, "rb")) == 0) {
2819 strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
2822 if (register_gob(handle, &object_gobs, dat_filelen("objects.gob", datfile_name))) {
2827 if ((handle = dat_open("font.gob", datfile_name, "rb")) == 0) {
2828 strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
2831 if (register_gob(handle, &font_gobs, dat_filelen("font.gob", datfile_name))) {
2836 if ((handle = dat_open("numbers.gob", datfile_name, "rb")) == 0) {
2837 strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
2840 if (register_gob(handle, &number_gobs, dat_filelen("numbers.gob", datfile_name))) {
2845 if (read_level() != 0) {
2846 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2852 if (main_info.no_sound == 0) {
2854 dj_set_mixing_freq(20000);
2858 dj_set_num_sfx_channels(5);
2859 dj_set_sfx_volume(64);
2863 if ((handle = dat_open("jump.mod", datfile_name, "rb")) == 0) {
2864 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2867 if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
2868 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2872 if ((handle = dat_open("bump.mod", datfile_name, "rb")) == 0) {
2873 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2876 if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
2877 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2881 if ((handle = dat_open("scores.mod", datfile_name, "rb")) == 0) {
2882 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2885 if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
2886 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2890 if ((handle = dat_open("jump.smp", datfile_name, "rb")) == 0) {
2891 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2894 if (dj_load_sfx(handle, 0, dat_filelen("jump.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
2895 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2899 if ((handle = dat_open("death.smp", datfile_name, "rb")) == 0) {
2900 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2903 if (dj_load_sfx(handle, 0, dat_filelen("death.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
2904 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2908 if ((handle = dat_open("spring.smp", datfile_name, "rb")) == 0) {
2909 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2912 if (dj_load_sfx(handle, 0, dat_filelen("spring.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
2913 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2917 if ((handle = dat_open("splash.smp", datfile_name, "rb")) == 0) {
2918 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2921 if (dj_load_sfx(handle, 0, dat_filelen("splash.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
2922 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2926 if ((handle = dat_open("fly.smp", datfile_name, "rb")) == 0) {
2927 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2930 if (dj_load_sfx(handle, 0, dat_filelen("fly.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
2931 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2935 dj_get_sfx_settings(SFX_FLY, &fly);
2937 fly.default_freq = SFX_FLY_FREQ;
2940 fly.loop_length = fly.length;
2941 dj_set_sfx_settings(SFX_FLY, &fly);
2944 if ((background_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
2946 if ((mask_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
2948 memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
2949 register_mask(mask_pic);
2951 for (c1 = 0; c1 < 16; c1++) { // fix dark font
2952 pal[(240 + c1) * 3 + 0] = c1 << 2;
2953 pal[(240 + c1) * 3 + 1] = c1 << 2;
2954 pal[(240 + c1) * 3 + 2] = c1 << 2;
2957 setpalette(0, 256, pal);
2961 recalculate_gob(&font_gobs, pal);
2963 if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
2965 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2966 put_text(0, 200, 100, "Move the joystick to the", 2);
2967 put_text(0, 200, 115, "UPPER LEFT", 2);
2968 put_text(0, 200, 130, "and press button A", 2);
2969 put_text(0, 200, 200, "Or press ESC to use", 2);
2970 put_text(0, 200, 215, "previous settings", 2);
2971 if (calib_joy(0) != 0)
2974 register_background(NULL, NULL);
2976 main_info.view_page = 1;
2981 put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
2982 put_text(1, 200, 100, "Move the joystick to the", 2);
2983 put_text(1, 200, 115, "LOWER RIGHT", 2);
2984 put_text(1, 200, 130, "and press button A", 2);
2985 put_text(1, 200, 200, "Or press ESC to use", 2);
2986 put_text(1, 200, 215, "previous settings", 2);
2987 if (calib_joy(1) != 0)
2990 register_background(NULL, NULL);
2995 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2996 put_text(0, 200, 100, "Move the joystick to the", 2);
2997 put_text(0, 200, 115, "CENTER", 2);
2998 put_text(0, 200, 130, "and press button A", 2);
2999 put_text(0, 200, 200, "Or press ESC to use", 2);
3000 put_text(0, 200, 215, "previous settings", 2);
3001 if (calib_joy(2) != 0)
3004 if (joy.calib_data.x1 == joy.calib_data.x2)
3005 joy.calib_data.x1 -= 10;
3006 if (joy.calib_data.x3 == joy.calib_data.x2)
3007 joy.calib_data.x3 += 10;
3008 if (joy.calib_data.y1 == joy.calib_data.y2)
3009 joy.calib_data.y1 -= 10;
3010 if (joy.calib_data.y3 == joy.calib_data.y2)
3011 joy.calib_data.y3 += 10;
3016 if (load_flag == 1) {
3017 if ((handle = dat_open("calib.dat", datfile_name, "rb")) == 0) {
3018 strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
3021 joy.calib_data.x1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3022 joy.calib_data.x2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3023 joy.calib_data.x3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3024 joy.calib_data.y1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3025 joy.calib_data.y2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3026 joy.calib_data.y3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3031 init_server(netarg);
3033 connect_to_server(netarg);
3040 void deinit_program(void)
3047 dj_free_mod(MOD_MENU);
3048 dj_free_mod(MOD_GAME);
3049 dj_free_sfx(SFX_DEATH);
3050 dj_free_sfx(SFX_SPRING);
3051 dj_free_sfx(SFX_SPLASH);
3054 if (background_pic != 0)
3055 free(background_pic);
3059 remove_keyb_handler();
3063 __dpmi_int(0x10, ®s);
3066 if (main_info.error_str[0] != 0) {
3067 printf(main_info.error_str);
3069 MessageBox(0, main_info.error_str, "Jump'n'Bump", 0);
3078 unsigned short rnd(unsigned short max)
3080 return (rand() % max);
3084 int read_level(void)
3086 unsigned char *handle;
3090 if ((handle = dat_open("levelmap.txt", datfile_name, "rb")) == 0) {
3091 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
3095 for (c1 = 0; c1 < 16; c1++) {
3096 for (c2 = 0; c2 < 22; c2++) {
3098 chr = (int) *(handle++);
3099 if (chr >= '0' && chr <= '4')
3103 ban_map[c1][21-c2] = chr - '0';
3105 ban_map[c1][c2] = chr - '0';
3109 for (c2 = 0; c2 < 22; c2++)
3110 ban_map[16][c2] = BAN_SOLID;
3117 unsigned char *dat_open(char *file_name, char *dat_name, char *mode)
3125 if (datafile_buffer == NULL)
3128 memset(name, 0, sizeof(name));
3130 num = ( (datafile_buffer[0] << 0) +
3131 (datafile_buffer[1] << 8) +
3132 (datafile_buffer[2] << 16) +
3133 (datafile_buffer[3] << 24) );
3135 ptr = datafile_buffer + 4;
3137 for (c1 = 0; c1 < num; c1++) {
3139 memcpy(name, ptr, 12);
3142 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
3143 ofs = ( (ptr[0] << 0) +
3148 return (datafile_buffer + ofs);
3157 int dat_filelen(char *file_name, char *dat_name)
3165 memset(name, 0, sizeof(name));
3167 num = ( (datafile_buffer[0] << 0) +
3168 (datafile_buffer[1] << 8) +
3169 (datafile_buffer[2] << 16) +
3170 (datafile_buffer[3] << 24) );
3172 ptr = datafile_buffer + 4;
3174 for (c1 = 0; c1 < num; c1++) {
3176 memcpy(name, ptr, 12);
3179 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
3182 len = ( (ptr[0] << 0) +
3196 void write_calib_data(void)
3204 if ((handle = fopen(datfile_name, "rb")) == NULL)
3206 len = filelength(fileno(handle));
3207 if ((mem = malloc(len)) == NULL)
3209 fread(mem, 1, len, handle);
3213 num = *(int *) (&mem[0]);
3214 for (c1 = 0; c1 < num; c1++) {
3215 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
3216 ofs = *(int *) (&mem[ofs + 12]);
3222 mem[ofs] = joy.calib_data.x1 & 0xff;
3223 mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
3224 mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
3225 mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
3226 mem[ofs + 4] = joy.calib_data.x2 & 0xff;
3227 mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
3228 mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
3229 mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
3230 mem[ofs + 8] = joy.calib_data.x3 & 0xff;
3231 mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
3232 mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
3233 mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
3234 mem[ofs + 12] = joy.calib_data.y1 & 0xff;
3235 mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
3236 mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
3237 mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
3238 mem[ofs + 16] = joy.calib_data.y2 & 0xff;
3239 mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
3240 mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
3241 mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
3242 mem[ofs + 20] = joy.calib_data.y3 & 0xff;
3243 mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
3244 mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
3245 mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
3247 if ((handle = fopen(datfile_name, "wb")) == NULL)
3249 fwrite(mem, 1, len, handle);