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
38 #define M_PI 3.14159265358979323846
41 gob_t rabbit_gobs = { 0 };
42 gob_t font_gobs = { 0 };
43 gob_t object_gobs = { 0 };
44 gob_t number_gobs = { 0 };
46 main_info_t main_info;
47 player_t player[JNB_MAX_PLAYERS];
48 player_anim_t player_anims[7];
49 object_t objects[NUM_OBJECTS];
53 char datfile_name[2048];
59 unsigned int ban_map[17][22] = {
60 {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
61 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0},
62 {1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
63 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1},
64 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
65 {1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
66 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1},
67 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
68 {1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
69 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1},
70 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1},
71 {1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1},
72 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
73 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
74 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 1, 3, 3, 3, 1, 1, 1},
75 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
76 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
202 int flies_enabled = 1;
207 int old_draw_x, old_draw_y;
219 } pobs[NUM_LEFTOVERS];
223 int pogostick, bunnies_in_space, jetpack, lord_of_the_flies, blood_is_thicker_than_water;
227 int filelength(int handle)
231 if (fstat(handle, &buf) == -1) {
232 perror("filelength");
241 /* networking shite. */
243 int client_player_num = -1;
248 TCPsocket sock = NULL;
249 SDLNet_SocketSet socketset = NULL;
255 SDLNet_SocketSet socketset;
258 NetInfo net_info[JNB_MAX_PLAYERS];
270 #define NETPKTBUFSIZE (4 + 4 + 4 + 4 + 4)
272 #define NETCMD_NACK (0xF00DF00D + 0)
273 #define NETCMD_ACK (0xF00DF00D + 1)
274 #define NETCMD_HELLO (0xF00DF00D + 2)
275 #define NETCMD_GREENLIGHT (0xF00DF00D + 3)
276 #define NETCMD_MOVE (0xF00DF00D + 4)
277 #define NETCMD_BYE (0xF00DF00D + 5)
278 #define NETCMD_POSITION (0xF00DF00D + 6)
279 #define NETCMD_ALIVE (0xF00DF00D + 7)
280 #define NETCMD_KILL (0xF00DF00D + 8)
284 void bufToPacket(const char *buf, NetPacket *pkt)
286 SDLNet_Write32(*((unsigned long *) (buf + 0)), &pkt->cmd);
287 SDLNet_Write32(*((unsigned long *) (buf + 4)), &pkt->arg);
288 SDLNet_Write32(*((unsigned long *) (buf + 8)), &pkt->arg2);
289 SDLNet_Write32(*((unsigned long *) (buf + 12)), &pkt->arg3);
290 SDLNet_Write32(*((unsigned long *) (buf + 16)), &pkt->arg4);
292 pkt->cmd = ntohl(*((unsigned long *) (buf + 0)));
293 pkt->arg = (long) ntohl(*((unsigned long *) (buf + 4)));
294 pkt->arg2 = (long) ntohl(*((unsigned long *) (buf + 8)));
295 pkt->arg3 = (long) ntohl(*((unsigned long *) (buf + 12)));
296 pkt->arg4 = (long) ntohl(*((unsigned long *) (buf + 16)));
301 void packetToBuf(const NetPacket *pkt, char *buf)
303 *((unsigned long *) (buf + 0)) = SDLNet_Read32(&pkt->cmd);
304 *((unsigned long *) (buf + 4)) = SDLNet_Read32(&pkt->arg);
305 *((unsigned long *) (buf + 8)) = SDLNet_Read32(&pkt->arg2);
306 *((unsigned long *) (buf + 12)) = SDLNet_Read32(&pkt->arg3);
307 *((unsigned long *) (buf + 16)) = SDLNet_Read32(&pkt->arg4);
309 *((unsigned long *) (buf + 0)) = htonl(pkt->cmd);
310 *((unsigned long *) (buf + 4)) = htonl((unsigned long) pkt->arg);
311 *((unsigned long *) (buf + 8)) = htonl((unsigned long) pkt->arg2);
312 *((unsigned long *) (buf + 12)) = htonl((unsigned long) pkt->arg3);
313 *((unsigned long *) (buf + 16)) = htonl((unsigned long) pkt->arg4);
318 void sendPacketToSock(TCPsocket s, NetPacket *pkt)
320 int bytes_left = NETPKTBUFSIZE;
322 char buf[NETPKTBUFSIZE];
325 packetToBuf(pkt, buf);
326 while (bytes_left > 0) {
327 bw = SDLNet_TCP_Send(s, ptr, bytes_left);
329 fprintf(stderr, "SERVER: SDLNet_TCP_Send(): %s\n", SDLNet_GetError());
332 } else if (bw == 0) {
342 void sendPacket(int playerid, NetPacket *pkt)
344 if ( playerid < JNB_MAX_PLAYERS ) {
345 if ((player[playerid].enabled) && (playerid != client_player_num)) {
346 sendPacketToSock(net_info[playerid].sock, pkt);
352 void sendPacketToAll(NetPacket *pkt)
356 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
362 int grabPacket(TCPsocket s, SDLNet_SocketSet ss, NetPacket *pkt)
364 static char buf[NETPKTBUFSIZE];
365 static int buf_count = 0;
369 if (SDLNet_CheckSockets(ss, 0) > 0) {
370 rc = SDLNet_TCP_Recv(s, &buf[buf_count], NETPKTBUFSIZE - buf_count);
371 if (rc <= 0) { /* closed connection? */
373 } else if (rc != NETPKTBUFSIZE) {
377 bufToPacket(buf, pkt);
386 int serverRecvPacket(NetPacket *pkt)
393 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
394 TCPsocket s = net_info[i].sock;
396 if ((i == client_player_num) || (!player[i].enabled))
399 rc = grabPacket(s, net_info[i].socketset, pkt);
403 player[i].enabled = 0;
405 pkt.cmd = NETCMD_BYE;
410 sendPacketToAll(&pkt);
412 return(i); /* it's all good. */
416 return(-1); /* no packets available currently. */
420 void wait_for_greenlight(void)
425 printf("CLIENT: Waiting for greenlight...\n");
429 while ((rc = grabPacket(sock, socketset, &pkt)) == 0) {
430 SDL_Delay(100); /* nap and then try again. */
434 printf("CLIENT: Lost connection.\n");
435 SDLNet_TCP_Close(sock);
438 } while (pkt.cmd != NETCMD_GREENLIGHT);
440 printf("CLIENT: Got greenlight.\n");
442 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
443 if (pkt.arg & (1 << i)) {
444 printf("CLIENT: There is a player #%d.\n", i);
445 player[i].enabled = 1;
451 static int buggered_off = 0;
454 void tellServerGoodbye(void)
460 pkt.cmd = NETCMD_BYE;
461 pkt.arg = client_player_num;
465 sendPacketToSock(sock, &pkt);
471 void processMovePacket(NetPacket *pkt)
473 int playerid = pkt->arg;
474 int movetype = ((pkt->arg2 >> 16) & 0xFF);
475 int newval = ((pkt->arg2 >> 0) & 0xFF);
477 if (movetype == MOVEMENT_LEFT) {
478 player[playerid].action_left = newval;
479 } else if (movetype == MOVEMENT_RIGHT) {
480 player[playerid].action_right = newval;
481 } else if (movetype == MOVEMENT_UP) {
482 player[playerid].action_up = newval;
484 printf("bogus MOVE packet!\n");
487 player[playerid].x = pkt->arg3;
488 player[playerid].y = pkt->arg4;
492 void tellServerPlayerMoved(int playerid, int movement_type, int newval)
496 pkt.cmd = NETCMD_MOVE;
498 pkt.arg2 = ( ((movement_type & 0xFF) << 16) | ((newval & 0xFF) << 0) );
499 pkt.arg3 = player[playerid].x;
500 pkt.arg4 = player[playerid].y;
503 processMovePacket(&pkt);
506 sendPacketToAll(&pkt);
508 sendPacketToSock(sock, &pkt);
515 void tellServerNewPosition(void)
518 pkt.cmd = NETCMD_POSITION;
519 pkt.arg = client_player_num;
520 pkt.arg2 = player[client_player_num].x;
521 pkt.arg3 = player[client_player_num].y;
524 sendPacketToAll(&pkt);
526 sendPacketToSock(sock, &pkt);
532 void processKillPacket(NetPacket *pkt)
541 player[c1].y_add = -player[c1].y_add;
542 if (player[c1].y_add > -262144L)
543 player[c1].y_add = -262144L;
544 player[c1].jump_abort = 1;
545 player[c2].dead_flag = 1;
546 if (player[c2].anim != 6) {
548 player[c2].frame = 0;
549 player[c2].frame_tick = 0;
550 player[c2].image = player_anims[player[c2].anim].frame[player[c2].frame].image + player[c2].direction * 9;
551 if (main_info.no_gore == 0) {
552 for (c4 = 0; c4 < 6; c4++) {
553 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);
554 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 76);
555 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 77);
556 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 78);
557 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 79);
560 dj_play_sfx(SFX_DEATH, (unsigned short)(SFX_DEATH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
562 player[c1].bumped[c2]++;
563 s1 = player[c1].bumps % 100;
564 add_leftovers(0, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
565 add_leftovers(1, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
566 add_leftovers(0, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
567 add_leftovers(1, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
573 void processPositionPacket(NetPacket *pkt)
575 int playerid = pkt->arg;
577 player[playerid].x = pkt->arg2;
578 player[playerid].y = pkt->arg3;
582 void processAlivePacket(NetPacket *pkt)
584 int playerid = pkt->arg;
586 player[playerid].dead_flag = 0;
587 player[playerid].x = pkt->arg2;
588 player[playerid].y = pkt->arg3;
592 void serverTellEveryoneGoodbye(void)
598 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
599 if (player[i].enabled) {
602 pkt.cmd = NETCMD_BYE;
607 sendPacketToAll(&pkt);
614 int server_said_bye = 0;
617 int update_players_from_server(void)
624 while ((rc = grabPacket(sock, socketset, &pkt)) != 0) {
626 printf("CLIENT: Lost connection.\n");
627 pkt.cmd = NETCMD_BYE;
628 pkt.arg = client_player_num;
631 if (pkt.cmd == NETCMD_BYE) {
632 if (pkt.arg == client_player_num) {
633 SDLNet_FreeSocketSet(socketset);
634 SDLNet_TCP_Close(sock);
639 player[pkt.arg].enabled = 0;
641 } else if (pkt.cmd == NETCMD_MOVE) {
642 processMovePacket(&pkt);
643 } else if (pkt.cmd == NETCMD_ALIVE) {
644 processAlivePacket(&pkt);
645 } else if (pkt.cmd == NETCMD_POSITION) {
646 processPositionPacket(&pkt);
647 } else if (pkt.cmd == NETCMD_KILL) {
648 processKillPacket(&pkt);
650 printf("CLIENT: Got an unknown packet: 0x%lX.\n", pkt.cmd);
658 void serverSendAlive(int playerid)
663 pkt.cmd = NETCMD_ALIVE;
665 pkt.arg2 = player[playerid].x;
666 pkt.arg3 = player[playerid].y;
667 sendPacketToAll(&pkt);
672 void serverSendKillPacket(int killer, int victim)
677 pkt.cmd = NETCMD_KILL;
680 pkt.arg3 = player[victim].x;
681 pkt.arg4 = player[victim].y;
682 processKillPacket(&pkt);
685 sendPacketToAll(&pkt);
691 void update_players_from_clients(void)
699 while ((playerid = serverRecvPacket(&pkt)) >= 0) {
700 if (pkt.cmd == NETCMD_BYE) {
701 pkt.arg = playerid; /* just in case. */
702 sendPacketToAll(&pkt);
703 player[playerid].enabled = 0;
704 SDLNet_FreeSocketSet(net_info[playerid].socketset);
705 SDLNet_TCP_Close(net_info[playerid].sock);
706 } else if (pkt.cmd == NETCMD_POSITION) {
707 pkt.arg = playerid; /* just in case. */
708 processPositionPacket(&pkt);
709 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
714 } else if (pkt.cmd == NETCMD_MOVE) {
715 pkt.arg = playerid; /* just in case. */
717 pkt.arg3 = player[playerid].x;
718 pkt.arg4 = player[playerid].y;
720 processMovePacket(&pkt);
721 sendPacketToAll(&pkt);
723 printf("SERVER: Got unknown packet (0x%lX).\n", pkt.cmd);
729 void init_server(const char *netarg)
734 int wait_for_clients = ((netarg == NULL) ? 0 : atoi(netarg));
737 if ((wait_for_clients > (JNB_MAX_PLAYERS - 1)) || (wait_for_clients < 0)) {
738 printf("SERVER: Waiting for bogus client count (%d).\n", wait_for_clients);
742 if (SDLNet_Init() < 0) {
747 SDLNet_ResolveHost(&addr, NULL, JNB_INETPORT);
748 ipstr = SDLNet_ResolveIP(&addr);
749 SDLNet_ResolveHost(&addr, ipstr, JNB_INETPORT);
750 printf("SERVER: we are %s (%i.%i.%i.%i:%i).\n", ipstr, (addr.host >> 0) & 0xff, (addr.host >> 8) & 0xff, (addr.host >> 16) & 0xff, (addr.host >> 24) & 0xff, addr.port);
751 net_info[client_player_num].addr = addr;
753 addr.host = INADDR_ANY;
754 sock = SDLNet_TCP_Open(&addr);
756 fprintf(stderr, "SERVER: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
760 player[client_player_num].enabled = 1;
762 printf("SERVER: waiting for (%d) clients...\n", wait_for_clients);
764 socketset = SDLNet_AllocSocketSet(JNB_MAX_PLAYERS + 1);
765 SDLNet_TCP_AddSocket(socketset, sock);
767 while (wait_for_clients > 0)
769 char buf[NETPKTBUFSIZE];
775 /* Wait for events */
776 SDLNet_CheckSockets(socketset, ~0);
777 if ( SDLNet_SocketReady(sock) ) {
778 s = SDLNet_TCP_Accept(sock);
782 fprintf(stderr, "SERVER: SDLNet_TCP_Accept(): %s", SDLNet_GetError());
783 SDLNet_TCP_Close(sock);
789 br = SDLNet_TCP_Recv(s, buf, NETPKTBUFSIZE);
791 fprintf(stderr, "SERVER: SDLNet_TCP_Recv(): %s\n", SDLNet_GetError());
793 SDLNet_TCP_Close(sock);
797 from = SDLNet_TCP_GetPeerAddress(s);
798 ipstr = SDLNet_ResolveIP(from);
799 printf("SERVER: Got data from %s (%i.%i.%i.%i:%i).\n", ipstr, (from->host >> 0) & 0xff, (from->host >> 8) & 0xff, (from->host >> 16) & 0xff, (from->host >> 24) & 0xff, from->port);
801 if (br != NETPKTBUFSIZE) {
802 printf("SERVER: Bogus packet.\n");
806 bufToPacket(buf, &pkt);
807 if (pkt.cmd != NETCMD_HELLO) {
808 printf("SERVER: Bogus packet.\n");
812 printf("SERVER: Client claims to be player #%ld.\n", pkt.arg);
814 if (pkt.arg > JNB_MAX_PLAYERS) {
815 printf("SERVER: (that's an invalid player number.)\n");
817 if (player[pkt.arg].enabled) {
818 printf("SERVER: (that player number is already taken.)\n");
825 printf("SERVER: Forbidding connection.\n");
826 pkt.cmd = NETCMD_NACK;
827 sendPacketToSock(s, &pkt);
830 player[pkt.arg].enabled = 1;
831 net_info[pkt.arg].sock = s;
832 net_info[pkt.arg].addr = *from;
833 net_info[pkt.arg].socketset = SDLNet_AllocSocketSet(1);
834 SDLNet_TCP_AddSocket(net_info[pkt.arg].socketset, net_info[pkt.arg].sock);
836 printf("SERVER: Granting connection. (%d) to go.\n", wait_for_clients);
837 pkt.cmd = NETCMD_ACK;
838 sendPacket(pkt.arg, &pkt);
842 SDLNet_TCP_Close(sock); /* done with the listen socket. */
843 SDLNet_FreeSocketSet(socketset);
847 printf("SERVER: Got all our connections. Greenlighting clients...\n");
849 pkt.cmd = NETCMD_GREENLIGHT;
851 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
852 if (player[i].enabled) {
856 sendPacketToAll(&pkt);
860 void connect_to_server(char *netarg)
863 char buf[NETPKTBUFSIZE];
869 if (netarg == NULL) {
870 printf("CLIENT: Need to specify host to connect to.\n");
874 if (SDLNet_Init() < 0) {
879 player[client_player_num].enabled = 1;
881 SDLNet_ResolveHost(&addr, NULL, JNB_INETPORT);
882 ipstr = SDLNet_ResolveIP(&addr);
883 SDLNet_ResolveHost(&addr, ipstr, JNB_INETPORT);
884 printf("CLIENT: we are %s (%i.%i.%i.%i:%i).\n", ipstr, (addr.host >> 0) & 0xff, (addr.host >> 8) & 0xff, (addr.host >> 16) & 0xff, (addr.host >> 24) & 0xff, addr.port);
885 net_info[client_player_num].addr = addr;
887 if (SDLNet_ResolveHost(&hent, netarg, JNB_INETPORT) < 0) {
888 fprintf(stderr, "CLIENT: couldn't find host: %s\n", SDLNet_GetError());
892 sock = SDLNet_TCP_Open(&hent);
894 fprintf(stderr, "CLIENT: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
898 socketset = SDLNet_AllocSocketSet(1);
899 SDLNet_TCP_AddSocket(socketset, sock);
901 printf("CLIENT: connected to %s...\n", SDLNet_ResolveIP(&hent));
903 printf("CLIENT: Sending HELLO packet...\n");
904 pkt.cmd = NETCMD_HELLO;
905 pkt.arg = client_player_num;
906 sendPacketToSock(sock, &pkt);
908 printf("CLIENT: Waiting for ACK from server...\n");
910 br = SDLNet_TCP_Recv(sock, buf, NETPKTBUFSIZE);
912 fprintf(stderr, "CLIENT: recv(): %s\n", SDLNet_GetError());
913 SDLNet_FreeSocketSet(socketset);
914 SDLNet_TCP_Close(sock);
918 if (br != NETPKTBUFSIZE) {
919 printf("CLIENT: Bogus packet size (%d of %d). FIXME.\n", br, NETPKTBUFSIZE);
920 SDLNet_FreeSocketSet(socketset);
921 SDLNet_TCP_Close(sock);
925 bufToPacket(buf, &pkt);
927 if (pkt.cmd == NETCMD_NACK) {
928 printf("CLIENT: Server forbid us from playing.\n");
929 SDLNet_FreeSocketSet(socketset);
930 SDLNet_TCP_Close(sock);
934 if (pkt.cmd != NETCMD_ACK) {
935 printf("CLIENT: Unexpected packet (cmd=0x%lX).\n", pkt.cmd);
936 SDLNet_FreeSocketSet(socketset);
937 SDLNet_TCP_Close(sock);
941 printf("CLIENT: Server accepted our connection.\n");
943 wait_for_greenlight();
948 static void flip_pixels(unsigned char *pixels)
954 for (y = 0; y < JNB_HEIGHT; y++) {
955 for (x = 0; x < (352/2); x++) {
956 temp = pixels[y*JNB_WIDTH+x];
957 pixels[y*JNB_WIDTH+x] = pixels[y*JNB_WIDTH+(352-x)-1];
958 pixels[y*JNB_WIDTH+(352-x)-1] = temp;
964 int main(int argc, char *argv[])
966 unsigned char *handle;
967 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
970 int closest_player = 0, dist, cur_dist = 0;
971 int end_loop_flag = 0, fade_flag = 0;
972 int mod_vol, sfx_vol, mod_fade_direction;
978 if (init_program(argc, argv, pal) != 0)
981 if (main_info.fireworks == 1) {
992 if (key_pressed(1) == 1) {
995 if (init_level(0, pal) != 0) {
1000 memset(cur_pal, 0, 768);
1001 setpalette(0, 256, cur_pal);
1003 recalculate_gob(&rabbit_gobs, pal);
1004 recalculate_gob(&object_gobs, pal);
1005 recalculate_gob(&number_gobs, pal);
1008 register_background(background_pic, pal);
1011 if (flies_enabled) {
1015 for (c1 = 0; c1 < NUM_FLIES; c1++) {
1017 flies[c1].x = s1 + rnd(101) - 50;
1018 flies[c1].y = s2 + rnd(101) - 50;
1019 if (ban_map[flies[c1].y >> 4][flies[c1].x >> 4] == BAN_VOID)
1022 flies[c1].back_defined[0] = 0;
1023 flies[c1].back_defined[1] = 0;
1027 mod_vol = sfx_vol = 10;
1028 mod_fade_direction = 1;
1029 dj_ready_mod(MOD_GAME);
1030 dj_set_mod_volume((char)mod_vol);
1031 dj_set_sfx_volume((char)mod_vol);
1035 dj_play_sfx(SFX_FLY, SFX_FLY_FREQ, 0, 0, 0, 4);
1039 lord_of_the_flies = bunnies_in_space = jetpack = pogostick = blood_is_thicker_than_water = 0;
1041 main_info.page_info[0].num_pobs = 0;
1042 main_info.page_info[1].num_pobs = 0;
1043 main_info.view_page = 0;
1044 main_info.draw_page = 1;
1048 while (update_count) {
1050 if (key_pressed(1) == 1) {
1054 serverTellEveryoneGoodbye();
1056 tellServerGoodbye();
1061 memset(pal, 0, 768);
1062 mod_fade_direction = 0;
1065 if (strncmp(last_keys, "kcitsogop", strlen("kcitsogop")) == 0) {
1069 if (strncmp(last_keys, "ecapsniseinnub", strlen("ecapsniseinnub")) == 0) {
1070 bunnies_in_space ^= 1;
1073 if (strncmp(last_keys, "kcaptej", strlen("kcaptej")) == 0) {
1077 if (strncmp(last_keys, "seilfehtfodrol", strlen("seilfehtfodrol")) == 0) {
1078 lord_of_the_flies ^= 1;
1081 if (strncmp(last_keys, "retawnahtrekcihtsidoolb", strlen("retawnahtrekcihtsidoolb")) == 0) {
1082 blood_is_thicker_than_water ^= 1;
1083 if (blood_is_thicker_than_water == 1) {
1134 register_background(background_pic, pal);
1135 recalculate_gob(&object_gobs, pal);
1142 update_players_from_clients();
1144 if (!update_players_from_server()) {
1145 break; /* got a BYE packet */
1155 for (c3 = 0; c3 < 6; c3++) {
1159 } else if (c3 == 1) {
1162 } else if (c3 == 2) {
1165 } else if (c3 == 3) {
1168 } else if (c3 == 4) {
1171 } else if (c3 == 5) {
1175 if (player[c1].enabled == 1 && player[c2].enabled == 1) {
1176 if (labs(player[c1].x - player[c2].x) < (12L << 16) && labs(player[c1].y - player[c2].y) < (12L << 16)) {
1177 if ((labs(player[c1].y - player[c2].y) >> 16) > 5) {
1178 if (player[c1].y < player[c2].y) {
1179 if (player[c1].y_add >= 0) {
1181 serverSendKillPacket(c1, c2);
1183 if (player[c2].y_add < 0)
1184 player[c2].y_add = 0;
1187 if (player[c2].y_add >= 0) {
1189 serverSendKillPacket(c2, c1);
1191 if (player[c1].y_add < 0)
1192 player[c1].y_add = 0;
1196 if (player[c1].x < player[c2].x) {
1197 if (player[c1].x_add > 0)
1198 player[c1].x = player[c2].x - (12L << 16);
1199 else if (player[c2].x_add < 0)
1200 player[c2].x = player[c1].x + (12L << 16);
1202 player[c1].x -= player[c1].x_add;
1203 player[c2].x -= player[c2].x_add;
1205 l1 = player[c2].x_add;
1206 player[c2].x_add = player[c1].x_add;
1207 player[c1].x_add = l1;
1208 if (player[c1].x_add > 0)
1209 player[c1].x_add = -player[c1].x_add;
1210 if (player[c2].x_add < 0)
1211 player[c2].x_add = -player[c2].x_add;
1213 if (player[c1].x_add > 0)
1214 player[c2].x = player[c1].x - (12L << 16);
1215 else if (player[c2].x_add < 0)
1216 player[c1].x = player[c2].x + (12L << 16);
1218 player[c1].x -= player[c1].x_add;
1219 player[c2].x -= player[c2].x_add;
1221 l1 = player[c2].x_add;
1222 player[c2].x_add = player[c1].x_add;
1223 player[c1].x_add = l1;
1224 if (player[c1].x_add < 0)
1225 player[c1].x_add = -player[c1].x_add;
1226 if (player[c2].x_add > 0)
1227 player[c2].x_add = -player[c2].x_add;
1236 main_info.page_info[main_info.draw_page].num_pobs = 0;
1237 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1238 if (player[c1].enabled == 1)
1239 main_info.page_info[main_info.draw_page].num_pobs++;
1246 if (flies_enabled) {
1247 /* get center of fly swarm */
1249 for (c1 = 0; c1 < NUM_FLIES; c1++) {
1256 if (update_count == 1) {
1257 /* get closest player to fly swarm */
1259 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1260 if (player[c1].enabled == 1) {
1261 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)));
1262 if (cur_dist < dist) {
1263 closest_player = c1;
1268 /* update fly swarm sound */
1272 dj_set_sfx_channel_volume(4, (char)(s3));
1275 for (c1 = 0; c1 < NUM_FLIES; c1++) {
1276 /* get closest player to fly */
1278 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
1279 if (player[c2].enabled == 1) {
1280 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)));
1281 if (cur_dist < dist) {
1282 closest_player = c2;
1287 flies[c1].old_x = flies[c1].x;
1288 flies[c1].old_y = flies[c1].y;
1290 if ((s1 - flies[c1].x) > 30)
1292 else if ((s1 - flies[c1].x) < -30)
1295 if (((player[closest_player].x >> 16) + 8) > flies[c1].x) {
1296 if (lord_of_the_flies == 0)
1301 if (lord_of_the_flies == 0)
1307 s4 = rnd(3) - 1 + s3;
1308 if ((flies[c1].x + s4) < 16)
1310 if ((flies[c1].x + s4) > 351)
1312 if (ban_map[flies[c1].y >> 4][(flies[c1].x + s4) >> 4] != BAN_VOID)
1316 if ((s2 - flies[c1].y) > 30)
1318 else if ((s2 - flies[c1].y) < -30)
1321 if (((player[closest_player].y >> 16) + 8) > flies[c1].y) {
1322 if (lord_of_the_flies == 0)
1327 if (lord_of_the_flies == 0)
1333 s4 = rnd(3) - 1 + s3;
1334 if ((flies[c1].y + s4) < 0)
1336 if ((flies[c1].y + s4) > 239)
1338 if (ban_map[(flies[c1].y + s4) >> 4][flies[c1].x >> 4] != BAN_VOID)
1347 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1348 if (player[c1].enabled == 1) {
1349 main_info.page_info[main_info.draw_page].pobs[s1].x = player[c1].x >> 16;
1350 main_info.page_info[main_info.draw_page].pobs[s1].y = player[c1].y >> 16;
1351 main_info.page_info[main_info.draw_page].pobs[s1].image = player[c1].image + c1 * 18;
1352 main_info.page_info[main_info.draw_page].pobs[s1].pob_data = &rabbit_gobs;
1357 if (update_count == 1) {
1360 draw_pobs(main_info.draw_page);
1365 draw_flies(main_info.draw_page);
1370 if (mod_fade_direction == 1) {
1373 dj_set_mod_volume((char)mod_vol);
1378 dj_set_mod_volume((char)mod_vol);
1382 if (mod_fade_direction == 1) {
1385 dj_set_sfx_volume((char)sfx_vol);
1390 dj_set_sfx_volume((char)sfx_vol);
1395 for (c1 = 0; c1 < 768; c1++) {
1396 if (cur_pal[c1] < pal[c1]) {
1399 } else if (cur_pal[c1] > pal[c1]) {
1404 if (fade_flag == 0 && end_loop_flag == 1)
1407 if (update_count == 1) {
1408 main_info.draw_page ^= 1;
1409 main_info.view_page ^= 1;
1411 flippage(main_info.view_page);
1417 setpalette(0, 256, cur_pal);
1419 if (update_count == 1) {
1423 redraw_flies_background(main_info.draw_page);
1425 redraw_pob_backgrounds(main_info.draw_page);
1427 draw_leftovers(main_info.draw_page);
1437 if ( (player[client_player_num].dead_flag == 0) &&
1439 (player[client_player_num].action_left) ||
1440 (player[client_player_num].action_right) ||
1441 (player[client_player_num].action_up) ||
1442 (player[client_player_num].jump_ready == 0)
1445 tellServerNewPosition();
1450 update_count = intr_sysupdate();
1454 if ((server_said_bye) || ((fade_flag == 0) && (end_loop_flag == 1)))
1458 if ((fade_flag == 0) && (end_loop_flag == 1))
1465 serverTellEveryoneGoodbye();
1466 SDLNet_TCP_Close(sock);
1469 if (!server_said_bye) {
1470 tellServerGoodbye();
1473 SDLNet_TCP_Close(sock);
1479 main_info.view_page = 0;
1480 main_info.draw_page = 1;
1482 dj_stop_sfx_channel(4);
1486 memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
1487 register_mask(mask_pic);
1489 register_background(NULL, NULL);
1493 put_text(main_info.view_page, 100, 50, "DOTT", 2);
1494 put_text(main_info.view_page, 160, 50, "JIFFY", 2);
1495 put_text(main_info.view_page, 220, 50, "FIZZ", 2);
1496 put_text(main_info.view_page, 280, 50, "MIJJI", 2);
1497 put_text(main_info.view_page, 40, 80, "DOTT", 2);
1498 put_text(main_info.view_page, 40, 110, "JIFFY", 2);
1499 put_text(main_info.view_page, 40, 140, "FIZZ", 2);
1500 put_text(main_info.view_page, 40, 170, "MIJJI", 2);
1502 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1503 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
1505 sprintf(str1, "%d", player[c1].bumped[c2]);
1506 put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, str1, 2);
1508 put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, "-", 2);
1510 sprintf(str1, "%d", player[c1].bumps);
1511 put_text(main_info.view_page, 350, 80 + c1 * 30, str1, 2);
1514 put_text(main_info.view_page, 200, 230, "Press ESC to continue", 2);
1518 flippage(main_info.view_page);
1520 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
1521 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1524 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
1525 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1530 for (c1 = 0; c1 < 16; c1++) {
1531 pal[(240 + c1) * 3 + 0] = c1 << 2;
1532 pal[(240 + c1) * 3 + 1] = c1 << 2;
1533 pal[(240 + c1) * 3 + 2] = c1 << 2;
1536 memset(cur_pal, 0, 768);
1538 setpalette(0, 256, cur_pal);
1541 dj_ready_mod(MOD_SCORES);
1542 dj_set_mod_volume((char)mod_vol);
1546 while (key_pressed(1) == 0) {
1549 dj_set_mod_volume((char)mod_vol);
1550 for (c1 = 0; c1 < 768; c1++) {
1551 if (cur_pal[c1] < pal[c1])
1557 setpalette(0, 256, cur_pal);
1558 flippage(main_info.view_page);
1560 while (key_pressed(1) == 1) {
1565 memset(pal, 0, 768);
1567 while (mod_vol > 0) {
1569 dj_set_mod_volume((char)mod_vol);
1570 for (c1 = 0; c1 < 768; c1++) {
1571 if (cur_pal[c1] > pal[c1])
1576 setpalette(0, 256, cur_pal);
1577 flippage(main_info.view_page);
1580 fillpalette(0, 0, 0);
1586 break; /* don't go back to menu if in net game. */
1595 void steer_players(void)
1600 update_player_actions();
1602 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1604 if (player[c1].enabled == 1) {
1606 if (player[c1].dead_flag == 0) {
1608 if (player[c1].action_left && player[c1].action_right) {
1609 if (player[c1].direction == 0) {
1610 if (player[c1].action_right) {
1611 s1 = (player[c1].x >> 16);
1612 s2 = (player[c1].y >> 16);
1613 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1614 if (player[c1].x_add < 0)
1615 player[c1].x_add += 1024;
1617 player[c1].x_add += 768;
1618 } 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)) {
1619 if (player[c1].x_add > 0)
1620 player[c1].x_add += 1024;
1622 player[c1].x_add += 768;
1624 if (player[c1].x_add < 0) {
1625 player[c1].x_add += 16384;
1626 if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1627 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);
1629 player[c1].x_add += 12288;
1631 if (player[c1].x_add > 98304L)
1632 player[c1].x_add = 98304L;
1633 player[c1].direction = 0;
1634 if (player[c1].anim == 0) {
1635 player[c1].anim = 1;
1636 player[c1].frame = 0;
1637 player[c1].frame_tick = 0;
1638 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1642 if (player[c1].action_left) {
1643 s1 = (player[c1].x >> 16);
1644 s2 = (player[c1].y >> 16);
1645 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1646 if (player[c1].x_add > 0)
1647 player[c1].x_add -= 1024;
1649 player[c1].x_add -= 768;
1650 } 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)) {
1651 if (player[c1].x_add > 0)
1652 player[c1].x_add -= 1024;
1654 player[c1].x_add -= 768;
1656 if (player[c1].x_add > 0) {
1657 player[c1].x_add -= 16384;
1658 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1659 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);
1661 player[c1].x_add -= 12288;
1663 if (player[c1].x_add < -98304L)
1664 player[c1].x_add = -98304L;
1665 player[c1].direction = 1;
1666 if (player[c1].anim == 0) {
1667 player[c1].anim = 1;
1668 player[c1].frame = 0;
1669 player[c1].frame_tick = 0;
1670 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1674 } else if (player[c1].action_left) {
1675 s1 = (player[c1].x >> 16);
1676 s2 = (player[c1].y >> 16);
1677 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1678 if (player[c1].x_add > 0)
1679 player[c1].x_add -= 1024;
1681 player[c1].x_add -= 768;
1682 } 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)) {
1683 if (player[c1].x_add > 0)
1684 player[c1].x_add -= 1024;
1686 player[c1].x_add -= 768;
1688 if (player[c1].x_add > 0) {
1689 player[c1].x_add -= 16384;
1690 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1691 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);
1693 player[c1].x_add -= 12288;
1695 if (player[c1].x_add < -98304L)
1696 player[c1].x_add = -98304L;
1697 player[c1].direction = 1;
1698 if (player[c1].anim == 0) {
1699 player[c1].anim = 1;
1700 player[c1].frame = 0;
1701 player[c1].frame_tick = 0;
1702 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1704 } else if (player[c1].action_right) {
1705 s1 = (player[c1].x >> 16);
1706 s2 = (player[c1].y >> 16);
1707 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1708 if (player[c1].x_add < 0)
1709 player[c1].x_add += 1024;
1711 player[c1].x_add += 768;
1712 } 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)) {
1713 if (player[c1].x_add > 0)
1714 player[c1].x_add += 1024;
1716 player[c1].x_add += 768;
1718 if (player[c1].x_add < 0) {
1719 player[c1].x_add += 16384;
1720 if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1721 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);
1723 player[c1].x_add += 12288;
1725 if (player[c1].x_add > 98304L)
1726 player[c1].x_add = 98304L;
1727 player[c1].direction = 0;
1728 if (player[c1].anim == 0) {
1729 player[c1].anim = 1;
1730 player[c1].frame = 0;
1731 player[c1].frame_tick = 0;
1732 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1734 } else if ((!player[c1].action_left) && (!player[c1].action_right)) {
1735 s1 = (player[c1].x >> 16);
1736 s2 = (player[c1].y >> 16);
1737 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)))) {
1738 if (player[c1].x_add < 0) {
1739 player[c1].x_add += 16384;
1740 if (player[c1].x_add > 0)
1741 player[c1].x_add = 0;
1743 player[c1].x_add -= 16384;
1744 if (player[c1].x_add < 0)
1745 player[c1].x_add = 0;
1747 if (player[c1].x_add != 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1748 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);
1750 if (player[c1].anim == 1) {
1751 player[c1].anim = 0;
1752 player[c1].frame = 0;
1753 player[c1].frame_tick = 0;
1754 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1758 if (pogostick == 1 || (player[c1].jump_ready == 1 && player[c1].action_up)) {
1759 s1 = (player[c1].x >> 16);
1760 s2 = (player[c1].y >> 16);
1763 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) {
1764 player[c1].y_add = -280000L;
1765 player[c1].anim = 2;
1766 player[c1].frame = 0;
1767 player[c1].frame_tick = 0;
1768 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1769 player[c1].jump_ready = 0;
1770 player[c1].jump_abort = 1;
1772 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1774 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1776 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)) {
1777 player[c1].y_add = -196608L;
1778 player[c1].in_water = 0;
1779 player[c1].anim = 2;
1780 player[c1].frame = 0;
1781 player[c1].frame_tick = 0;
1782 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1783 player[c1].jump_ready = 0;
1784 player[c1].jump_abort = 1;
1786 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1788 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1791 if (pogostick == 0 && (!player[c1].action_up)) {
1792 player[c1].jump_ready = 1;
1793 if (player[c1].in_water == 0 && player[c1].y_add < 0 && player[c1].jump_abort == 1) {
1794 if (bunnies_in_space == 0)
1795 player[c1].y_add += 32768;
1797 player[c1].y_add += 16384;
1798 if (player[c1].y_add > 0)
1799 player[c1].y_add = 0;
1804 if (player[c1].action_up) {
1805 player[c1].y_add -= 16384;
1806 if (player[c1].y_add < -400000L)
1807 player[c1].y_add = -400000L;
1808 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))
1809 player[c1].in_water = 0;
1811 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);
1816 player[c1].x += player[c1].x_add;
1817 if ((player[c1].x >> 16) < 0) {
1819 player[c1].x_add = 0;
1821 if ((player[c1].x >> 16) + 15 > 351) {
1822 player[c1].x = 336L << 16;
1823 player[c1].x_add = 0;
1825 if (player[c1].y > 0) {
1826 s1 = (player[c1].x >> 16);
1827 s2 = (player[c1].y >> 16);
1828 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) {
1829 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1830 player[c1].x_add = 0;
1832 s1 = (player[c1].x >> 16);
1833 s2 = (player[c1].y >> 16);
1834 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) {
1835 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1836 player[c1].x_add = 0;
1839 s1 = (player[c1].x >> 16);
1841 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) {
1842 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1843 player[c1].x_add = 0;
1845 s1 = (player[c1].x >> 16);
1847 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) {
1848 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1849 player[c1].x_add = 0;
1853 player[c1].y += player[c1].y_add;
1855 s1 = (player[c1].x >> 16);
1856 s2 = (player[c1].y >> 16);
1857 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))) {
1858 player[c1].y = ((player[c1].y >> 16) & 0xfff0) << 16;
1859 player[c1].y_add = -400000L;
1860 player[c1].anim = 2;
1861 player[c1].frame = 0;
1862 player[c1].frame_tick = 0;
1863 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1864 player[c1].jump_ready = 0;
1865 player[c1].jump_abort = 0;
1866 for (c2 = 0; c2 < NUM_OBJECTS; c2++) {
1867 if (objects[c2].used == 1 && objects[c2].type == OBJ_SPRING) {
1868 if (ban_map[(s2 + 15) >> 4][(s1 + 8) >> 4] == BAN_SPRING) {
1869 if ((objects[c2].x >> 20) == ((s1 + 8) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1870 objects[c2].frame = 0;
1871 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1872 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1876 if (ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
1877 if ((objects[c2].x >> 20) == (s1 >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1878 objects[c2].frame = 0;
1879 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1880 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1883 } else if (ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1884 if ((objects[c2].x >> 20) == ((s1 + 15) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1885 objects[c2].frame = 0;
1886 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1887 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1894 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1896 s1 = (player[c1].x >> 16);
1897 s2 = (player[c1].y >> 16);
1900 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) {
1901 player[c1].y = (((s2 + 16) & 0xfff0)) << 16;
1902 player[c1].y_add = 0;
1903 player[c1].anim = 0;
1904 player[c1].frame = 0;
1905 player[c1].frame_tick = 0;
1906 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1908 s1 = (player[c1].x >> 16);
1909 s2 = (player[c1].y >> 16);
1912 if (ban_map[(s2 + 8) >> 4][(s1 + 8) >> 4] == BAN_WATER) {
1913 if (player[c1].in_water == 0) {
1914 player[c1].in_water = 1;
1915 player[c1].anim = 4;
1916 player[c1].frame = 0;
1917 player[c1].frame_tick = 0;
1918 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1919 if (player[c1].y_add >= 32768) {
1920 add_object(OBJ_SPLASH, (player[c1].x >> 16) + 8, ((player[c1].y >> 16) & 0xfff0) + 15, 0, 0, OBJ_ANIM_SPLASH, 0);
1921 if (blood_is_thicker_than_water == 0)
1922 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1924 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 5000), 64, 0, 0, -1);
1927 player[c1].y_add -= 1536;
1928 if (player[c1].y_add < 0 && player[c1].anim != 5) {
1929 player[c1].anim = 5;
1930 player[c1].frame = 0;
1931 player[c1].frame_tick = 0;
1932 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1934 if (player[c1].y_add < -65536L)
1935 player[c1].y_add = -65536L;
1936 if (player[c1].y_add > 65535L)
1937 player[c1].y_add = 65535L;
1938 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) {
1939 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1940 player[c1].y_add = 0;
1942 } 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) {
1943 player[c1].in_water = 0;
1944 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1945 player[c1].y_add = 0;
1946 if (player[c1].anim != 0 && player[c1].anim != 1) {
1947 player[c1].anim = 0;
1948 player[c1].frame = 0;
1949 player[c1].frame_tick = 0;
1950 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1953 if (player[c1].in_water == 0) {
1954 if (bunnies_in_space == 0)
1955 player[c1].y_add += 12288;
1957 player[c1].y_add += 6144;
1958 if (player[c1].y_add > 327680L)
1959 player[c1].y_add = 327680L;
1961 player[c1].y = (player[c1].y & 0xffff0000) + 0x10000;
1962 player[c1].y_add = 0;
1964 player[c1].in_water = 0;
1966 if (player[c1].y_add > 36864 && player[c1].anim != 3 && player[c1].in_water == 0) {
1967 player[c1].anim = 3;
1968 player[c1].frame = 0;
1969 player[c1].frame_tick = 0;
1970 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1975 player[c1].frame_tick++;
1976 if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
1978 if (player[c1].frame >= player_anims[player[c1].anim].num_frames) {
1979 if (player[c1].anim != 6)
1980 player[c1].frame = player_anims[player[c1].anim].restart_frame;
1982 position_player(c1);
1984 player[c1].frame_tick = 0;
1986 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1995 void position_player(int player_num)
2004 if (ban_map[s2][s1] == BAN_VOID && (ban_map[s2 + 1][s1] == BAN_SOLID || ban_map[s2 + 1][s1] == BAN_ICE))
2007 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
2008 if (c1 != player_num && player[c1].enabled == 1) {
2009 if (abs((s1 << 4) - (player[c1].x >> 16)) < 32 && abs((s2 << 4) - (player[c1].y >> 16)) < 32)
2013 if (c1 == JNB_MAX_PLAYERS) {
2014 player[player_num].x = (long) s1 << 20;
2015 player[player_num].y = (long) s2 << 20;
2016 player[player_num].x_add = player[player_num].y_add = 0;
2017 player[player_num].direction = 0;
2018 player[player_num].jump_ready = 1;
2019 player[player_num].in_water = 0;
2020 player[player_num].anim = 0;
2021 player[player_num].frame = 0;
2022 player[player_num].frame_tick = 0;
2023 player[player_num].image = player_anims[player[player_num].anim].frame[player[player_num].frame].image;
2028 serverSendAlive(player_num);
2030 player[player_num].dead_flag = 0;
2040 void add_object(int type, int x, int y, int x_add, int y_add, int anim, int frame)
2044 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
2045 if (objects[c1].used == 0) {
2046 objects[c1].used = 1;
2047 objects[c1].type = type;
2048 objects[c1].x = (long) x << 16;
2049 objects[c1].y = (long) y << 16;
2050 objects[c1].x_add = x_add;
2051 objects[c1].y_add = y_add;
2052 objects[c1].x_acc = 0;
2053 objects[c1].y_acc = 0;
2054 objects[c1].anim = anim;
2055 objects[c1].frame = frame;
2056 objects[c1].ticks = object_anims[anim].frame[frame].ticks;
2057 objects[c1].image = object_anims[anim].frame[frame].image;
2065 void update_objects(void)
2070 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
2071 if (objects[c1].used == 1) {
2072 switch (objects[c1].type) {
2074 objects[c1].ticks--;
2075 if (objects[c1].ticks <= 0) {
2076 objects[c1].frame++;
2077 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames) {
2078 objects[c1].frame--;
2079 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2081 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2082 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2085 if (objects[c1].used == 1)
2086 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2089 objects[c1].ticks--;
2090 if (objects[c1].ticks <= 0) {
2091 objects[c1].frame++;
2092 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2093 objects[c1].used = 0;
2095 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2096 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2099 if (objects[c1].used == 1)
2100 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2103 objects[c1].x += objects[c1].x_add;
2104 objects[c1].y += objects[c1].y_add;
2105 objects[c1].ticks--;
2106 if (objects[c1].ticks <= 0) {
2107 objects[c1].frame++;
2108 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2109 objects[c1].used = 0;
2111 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2112 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2115 if (objects[c1].used == 1)
2116 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2118 case OBJ_YEL_BUTFLY:
2119 case OBJ_PINK_BUTFLY:
2120 objects[c1].x_acc += rnd(128) - 64;
2121 if (objects[c1].x_acc < -1024)
2122 objects[c1].x_acc = -1024;
2123 if (objects[c1].x_acc > 1024)
2124 objects[c1].x_acc = 1024;
2125 objects[c1].x_add += objects[c1].x_acc;
2126 if (objects[c1].x_add < -32768)
2127 objects[c1].x_add = -32768;
2128 if (objects[c1].x_add > 32768)
2129 objects[c1].x_add = 32768;
2130 objects[c1].x += objects[c1].x_add;
2131 if ((objects[c1].x >> 16) < 16) {
2132 objects[c1].x = 16 << 16;
2133 objects[c1].x_add = -objects[c1].x_add >> 2;
2134 objects[c1].x_acc = 0;
2135 } else if ((objects[c1].x >> 16) > 350) {
2136 objects[c1].x = 350 << 16;
2137 objects[c1].x_add = -objects[c1].x_add >> 2;
2138 objects[c1].x_acc = 0;
2140 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
2141 if (objects[c1].x_add < 0) {
2142 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2144 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2146 objects[c1].x_add = -objects[c1].x_add >> 2;
2147 objects[c1].x_acc = 0;
2149 objects[c1].y_acc += rnd(64) - 32;
2150 if (objects[c1].y_acc < -1024)
2151 objects[c1].y_acc = -1024;
2152 if (objects[c1].y_acc > 1024)
2153 objects[c1].y_acc = 1024;
2154 objects[c1].y_add += objects[c1].y_acc;
2155 if (objects[c1].y_add < -32768)
2156 objects[c1].y_add = -32768;
2157 if (objects[c1].y_add > 32768)
2158 objects[c1].y_add = 32768;
2159 objects[c1].y += objects[c1].y_add;
2160 if ((objects[c1].y >> 16) < 0) {
2162 objects[c1].y_add = -objects[c1].y_add >> 2;
2163 objects[c1].y_acc = 0;
2164 } else if ((objects[c1].y >> 16) > 255) {
2165 objects[c1].y = 255 << 16;
2166 objects[c1].y_add = -objects[c1].y_add >> 2;
2167 objects[c1].y_acc = 0;
2169 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
2170 if (objects[c1].y_add < 0) {
2171 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2173 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2175 objects[c1].y_add = -objects[c1].y_add >> 2;
2176 objects[c1].y_acc = 0;
2178 if (objects[c1].type == OBJ_YEL_BUTFLY) {
2179 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_LEFT) {
2180 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_LEFT;
2181 objects[c1].frame = 0;
2182 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2183 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2184 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_RIGHT) {
2185 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_RIGHT;
2186 objects[c1].frame = 0;
2187 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2188 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2191 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_LEFT) {
2192 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_LEFT;
2193 objects[c1].frame = 0;
2194 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2195 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2196 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_RIGHT) {
2197 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_RIGHT;
2198 objects[c1].frame = 0;
2199 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2200 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2203 objects[c1].ticks--;
2204 if (objects[c1].ticks <= 0) {
2205 objects[c1].frame++;
2206 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2207 objects[c1].frame = object_anims[objects[c1].anim].restart_frame;
2209 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2210 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2213 if (objects[c1].used == 1)
2214 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2218 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 0);
2219 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
2220 objects[c1].y_add += 3072;
2221 if (objects[c1].y_add > 196608L)
2222 objects[c1].y_add = 196608L;
2223 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
2224 if (objects[c1].x_add < 0) {
2225 if (objects[c1].x_add < -65536L)
2226 objects[c1].x_add = -65536L;
2227 objects[c1].x_add += 1024;
2228 if (objects[c1].x_add > 0)
2229 objects[c1].x_add = 0;
2231 if (objects[c1].x_add > 65536L)
2232 objects[c1].x_add = 65536L;
2233 objects[c1].x_add -= 1024;
2234 if (objects[c1].x_add < 0)
2235 objects[c1].x_add = 0;
2237 objects[c1].y_add += 1024;
2238 if (objects[c1].y_add < -65536L)
2239 objects[c1].y_add = -65536L;
2240 if (objects[c1].y_add > 65536L)
2241 objects[c1].y_add = 65536L;
2243 objects[c1].x += objects[c1].x_add;
2244 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)) {
2245 if (objects[c1].x_add < 0) {
2246 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2247 objects[c1].x_add = -objects[c1].x_add >> 2;
2249 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2250 objects[c1].x_add = -objects[c1].x_add >> 2;
2253 objects[c1].y += objects[c1].y_add;
2254 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
2255 objects[c1].used = 0;
2256 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
2257 if (objects[c1].y_add < 0) {
2258 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
2259 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2260 objects[c1].x_add >>= 2;
2261 objects[c1].y_add = -objects[c1].y_add >> 2;
2264 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
2265 if (objects[c1].y_add > 131072L) {
2266 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2267 objects[c1].x_add >>= 2;
2268 objects[c1].y_add = -objects[c1].y_add >> 2;
2270 objects[c1].used = 0;
2271 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
2272 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2273 if (objects[c1].y_add > 131072L)
2274 objects[c1].y_add = -objects[c1].y_add >> 2;
2276 objects[c1].y_add = 0;
2280 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
2281 objects[c1].x_add = -16384;
2282 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
2283 objects[c1].x_add = 16384;
2284 if (objects[c1].used == 1) {
2285 s1 = (int)(atan2(objects[c1].y_add, objects[c1].x_add) * 4 / M_PI);
2292 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame + s1, &object_gobs);
2296 if (rnd(100) < 30) {
2297 if (objects[c1].frame == 76)
2298 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 1);
2299 else if (objects[c1].frame == 77)
2300 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 2);
2301 else if (objects[c1].frame == 78)
2302 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 3);
2304 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
2305 objects[c1].y_add += 3072;
2306 if (objects[c1].y_add > 196608L)
2307 objects[c1].y_add = 196608L;
2308 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
2309 if (objects[c1].x_add < 0) {
2310 if (objects[c1].x_add < -65536L)
2311 objects[c1].x_add = -65536L;
2312 objects[c1].x_add += 1024;
2313 if (objects[c1].x_add > 0)
2314 objects[c1].x_add = 0;
2316 if (objects[c1].x_add > 65536L)
2317 objects[c1].x_add = 65536L;
2318 objects[c1].x_add -= 1024;
2319 if (objects[c1].x_add < 0)
2320 objects[c1].x_add = 0;
2322 objects[c1].y_add += 1024;
2323 if (objects[c1].y_add < -65536L)
2324 objects[c1].y_add = -65536L;
2325 if (objects[c1].y_add > 65536L)
2326 objects[c1].y_add = 65536L;
2328 objects[c1].x += objects[c1].x_add;
2329 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)) {
2330 if (objects[c1].x_add < 0) {
2331 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2332 objects[c1].x_add = -objects[c1].x_add >> 2;
2334 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2335 objects[c1].x_add = -objects[c1].x_add >> 2;
2338 objects[c1].y += objects[c1].y_add;
2339 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
2340 objects[c1].used = 0;
2341 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
2342 if (objects[c1].y_add < 0) {
2343 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
2344 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2345 objects[c1].x_add >>= 2;
2346 objects[c1].y_add = -objects[c1].y_add >> 2;
2349 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
2350 if (objects[c1].y_add > 131072L) {
2351 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2352 objects[c1].x_add >>= 2;
2353 objects[c1].y_add = -objects[c1].y_add >> 2;
2355 if (rnd(100) < 10) {
2357 add_leftovers(0, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
2358 add_leftovers(1, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
2360 objects[c1].used = 0;
2362 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
2363 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2364 if (objects[c1].y_add > 131072L)
2365 objects[c1].y_add = -objects[c1].y_add >> 2;
2367 objects[c1].y_add = 0;
2371 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
2372 objects[c1].x_add = -16384;
2373 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
2374 objects[c1].x_add = 16384;
2375 if (objects[c1].used == 1)
2376 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame, &object_gobs);
2378 case OBJ_FLESH_TRACE:
2379 objects[c1].ticks--;
2380 if (objects[c1].ticks <= 0) {
2381 objects[c1].frame++;
2382 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2383 objects[c1].used = 0;
2385 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2386 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2389 if (objects[c1].used == 1)
2390 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2399 int add_pob(int page, int x, int y, int image, gob_t *pob_data)
2402 if (main_info.page_info[page].num_pobs >= NUM_POBS)
2405 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].x = x;
2406 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].y = y;
2407 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].image = image;
2408 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].pob_data = pob_data;
2409 main_info.page_info[page].num_pobs++;
2416 void draw_flies(int page)
2420 for (c2 = 0; c2 < NUM_FLIES; c2++) {
2421 flies[c2].back[main_info.draw_page] = get_pixel(main_info.draw_page, flies[c2].x, flies[c2].y);
2422 flies[c2].back_defined[main_info.draw_page] = 1;
2423 if (mask_pic[(flies[c2].y * JNB_WIDTH) + flies[c2].x] == 0)
2424 set_pixel(main_info.draw_page, flies[c2].x, flies[c2].y, 0);
2428 void draw_pobs(int page)
2435 for (c1 = main_info.page_info[page].num_pobs - 1; c1 >= 0; c1--) {
2436 main_info.page_info[page].pobs[c1].back_buf_ofs = back_buf_ofs;
2437 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);
2439 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;
2441 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;
2442 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);
2448 void redraw_flies_background(int page)
2452 for (c2 = NUM_FLIES - 1; c2 >= 0; c2--) {
2453 if (flies[c2].back_defined[page] == 1)
2454 set_pixel(page, flies[c2].old_draw_x, flies[c2].old_draw_y, flies[c2].back[page]);
2455 flies[c2].old_draw_x = flies[c2].x;
2456 flies[c2].old_draw_y = flies[c2].y;
2461 void redraw_pob_backgrounds(int page)
2465 for (c1 = 0; c1 < main_info.page_info[page].num_pobs; c1++)
2466 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);
2471 int add_leftovers(int page, int x, int y, int image, gob_t *pob_data)
2474 if (leftovers.page[page].num_pobs >= NUM_LEFTOVERS)
2477 leftovers.page[page].pobs[leftovers.page[page].num_pobs].x = x;
2478 leftovers.page[page].pobs[leftovers.page[page].num_pobs].y = y;
2479 leftovers.page[page].pobs[leftovers.page[page].num_pobs].image = image;
2480 leftovers.page[page].pobs[leftovers.page[page].num_pobs].pob_data = pob_data;
2481 leftovers.page[page].num_pobs++;
2488 void draw_leftovers(int page)
2492 for (c1 = leftovers.page[page].num_pobs - 1; c1 >= 0; c1--)
2493 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);
2495 leftovers.page[page].num_pobs = 0;
2500 int init_level(int level, char *pal)
2502 unsigned char *handle;
2506 if ((handle = dat_open("level.pcx", datfile_name, "rb")) == 0) {
2507 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2510 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
2511 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2515 flip_pixels(background_pic);
2516 if ((handle = dat_open("mask.pcx", datfile_name, "rb")) == 0) {
2517 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2520 if (read_pcx(handle, mask_pic, JNB_WIDTH*JNB_HEIGHT, 0) != 0) {
2521 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2525 flip_pixels(mask_pic);
2526 register_mask(mask_pic);
2528 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
2529 if (player[c1].enabled == 1) {
2530 player[c1].bumps = 0;
2531 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++)
2532 player[c1].bumped[c2] = 0;
2533 position_player(c1);
2537 for (c1 = 0; c1 < NUM_OBJECTS; c1++)
2538 objects[c1].used = 0;
2540 for (c1 = 0; c1 < 16; c1++) {
2541 for (c2 = 0; c2 < 22; c2++) {
2542 if (ban_map[c1][c2] == BAN_SPRING)
2543 add_object(OBJ_SPRING, c2 << 4, c1 << 4, 0, 0, OBJ_ANIM_SPRING, 5);
2550 if (ban_map[s2][s1] == BAN_VOID) {
2551 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2558 if (ban_map[s2][s1] == BAN_VOID) {
2559 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2566 if (ban_map[s2][s1] == BAN_VOID) {
2567 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2574 if (ban_map[s2][s1] == BAN_VOID) {
2575 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2585 void deinit_level(void)
2593 #define PATH_MAX 1024
2599 unsigned char *datafile_buffer = NULL;
2601 static void preread_datafile(const char *fname)
2607 char *gzfilename = alloca(strlen(fname) + 4);
2612 strcpy(gzfilename, fname);
2613 strcat(gzfilename, ".gz");
2615 gzf = gzopen(gzfilename, "rb");
2620 if (bufpos >= bufsize) {
2621 bufsize += 1024 * 1024;
2622 datafile_buffer = (unsigned char *) realloc(datafile_buffer, bufsize);
2623 if (datafile_buffer == NULL) {
2624 perror("realloc()");
2629 br = gzread(gzf, datafile_buffer + bufpos, bufsize - bufpos);
2631 fprintf(stderr, "gzread failed.\n");
2636 } while (!gzeof(gzf));
2638 /* try to shrink buffer... */
2639 ptr = (unsigned char *) realloc(datafile_buffer, bufpos);
2641 datafile_buffer = ptr;
2647 /* drop through and try for an uncompressed datafile... */
2650 fd = open(fname, O_RDONLY | O_BINARY);
2652 fprintf(stderr, "can't open %s:", fname);
2657 len = filelength(fd);
2658 datafile_buffer = (unsigned char *) malloc(len);
2659 if (datafile_buffer == NULL) {
2665 if (read(fd, datafile_buffer, len) != len) {
2675 int init_program(int argc, char *argv[], char *pal)
2677 char *netarg = NULL;
2678 unsigned char *handle = (unsigned char *) NULL;
2683 int player_anim_data[] = {
2684 1, 0, 0, 0x7fff, 0, 0, 0, 0, 0, 0,
2685 4, 0, 0, 4, 1, 4, 2, 4, 3, 4,
2686 1, 0, 4, 0x7fff, 0, 0, 0, 0, 0, 0,
2687 4, 2, 5, 8, 6, 10, 7, 3, 6, 3,
2688 1, 0, 6, 0x7fff, 0, 0, 0, 0, 0, 0,
2689 2, 1, 5, 8, 4, 0x7fff, 0, 0, 0, 0,
2690 1, 0, 8, 5, 0, 0, 0, 0, 0, 0
2694 memset(&net_info, 0, sizeof(net_info));
2698 if (__djgpp_nearptr_enable() == 0)
2704 if (hook_keyb_handler() != 0)
2707 memset(&main_info, 0, sizeof(main_info));
2709 strcpy(datfile_name, DATA_PATH);
2711 force2 = force3 = 0;
2714 for (c1 = 1; c1 < argc; c1++) {
2715 if (stricmp(argv[c1], "-nosound") == 0)
2716 main_info.no_sound = 1;
2717 else if (stricmp(argv[c1], "-musicnosound") == 0)
2718 main_info.music_no_sound = 1;
2719 else if (stricmp(argv[c1], "-nogore") == 0)
2720 main_info.no_gore = 1;
2721 else if (stricmp(argv[c1], "-noflies") == 0)
2723 else if (stricmp(argv[c1], "-nojoy") == 0)
2724 main_info.joy_enabled = 0;
2725 else if (stricmp(argv[c1], "-fireworks") == 0)
2726 main_info.fireworks = 1;
2728 else if (stricmp(argv[c1], "-fullscreen") == 0)
2731 else if (stricmp(argv[c1], "-scaleup") == 0)
2733 else if (stricmp(argv[c1], "-mirror") == 0)
2735 else if (stricmp(argv[c1], "-dat") == 0) {
2736 if (c1 < (argc - 1)) {
2739 if ((f = fopen(argv[c1 + 1], "rb")) != NULL) {
2741 strcpy(datfile_name, argv[c1 + 1]);
2744 } else if (stricmp(argv[c1], "-player") == 0) {
2745 if (c1 < (argc - 1)) {
2746 if (client_player_num < 0)
2747 client_player_num = atoi(argv[c1 + 1]);
2750 } else if (stricmp(argv[c1], "-server") == 0) {
2751 if (c1 < (argc - 1)) {
2754 netarg = argv[c1 + 1];
2756 } else if (stricmp(argv[c1], "-connect") == 0) {
2757 if (c1 < (argc - 1)) {
2760 netarg = argv[c1 + 1];
2763 } else if (stricmp(argv[c1], "-mouse") == 0) {
2764 if (c1 < (argc - 1)) {
2765 if (stricmp(argv[c1 + 1], "2") == 0)
2767 if (stricmp(argv[c1 + 1], "3") == 0)
2771 else if (strstr(argv[1],"-v")) {
2772 printf("jumpnbump %s compiled %s at %s with",JNB_VERSION,__DATE__,__TIME__);
2776 printf(" network support.\n");
2779 else if (strstr(argv[1],"-h")) {
2780 printf("Usage: jumpnbump [OPTION]...\n");
2782 printf(" -h this help\n");
2783 printf(" -v print version\n");
2784 printf(" -dat level.dat play a different level\n");
2786 printf(" -server playercount start as server waiting for players\n");
2787 printf(" -connect host connect to server\n");
2789 printf(" -player num set main player to num (0-3). Needed for networking\n");
2790 printf(" -fireworks screensaver mode\n");
2791 printf(" -fullscreen run in fullscreen mode\n");
2792 printf(" -nosound play without sound\n");
2793 printf(" -nogore play without blood\n");
2794 printf(" -noflies disable flies\n");
2795 printf(" -mirror play with mirrored level\n");
2796 printf(" -scaleup play with doubled resolution (800x512)\n");
2797 printf(" -musicnosound play with music but without sound\n");
2804 preread_datafile(datfile_name);
2807 if (client_player_num < 0)
2808 client_player_num = 0;
2809 player[client_player_num].enabled = 1;
2812 main_info.pob_backbuf[0] = malloc(screen_pitch*screen_height*bytes_per_pixel);
2813 main_info.pob_backbuf[1] = malloc(screen_pitch*screen_height*bytes_per_pixel);
2815 for (c1 = 0; c1 < 7; c1++) {
2816 player_anims[c1].num_frames = player_anim_data[c1 * 10];
2817 player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
2818 for (c2 = 0; c2 < 4; c2++) {
2819 player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
2820 player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
2824 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
2825 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2828 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
2829 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2833 if ((handle = dat_open("rabbit.gob", datfile_name, "rb")) == 0) {
2834 strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
2837 if (register_gob(handle, &rabbit_gobs, dat_filelen("rabbit.gob", datfile_name))) {
2842 if ((handle = dat_open("objects.gob", datfile_name, "rb")) == 0) {
2843 strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
2846 if (register_gob(handle, &object_gobs, dat_filelen("objects.gob", datfile_name))) {
2851 if ((handle = dat_open("font.gob", datfile_name, "rb")) == 0) {
2852 strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
2855 if (register_gob(handle, &font_gobs, dat_filelen("font.gob", datfile_name))) {
2860 if ((handle = dat_open("numbers.gob", datfile_name, "rb")) == 0) {
2861 strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
2864 if (register_gob(handle, &number_gobs, dat_filelen("numbers.gob", datfile_name))) {
2869 if (read_level() != 0) {
2870 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2876 if (main_info.no_sound == 0) {
2878 dj_set_mixing_freq(20000);
2882 dj_set_num_sfx_channels(5);
2883 dj_set_sfx_volume(64);
2887 if ((handle = dat_open("jump.mod", datfile_name, "rb")) == 0) {
2888 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2891 if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
2892 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2896 if ((handle = dat_open("bump.mod", datfile_name, "rb")) == 0) {
2897 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2900 if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
2901 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2905 if ((handle = dat_open("scores.mod", datfile_name, "rb")) == 0) {
2906 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2909 if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
2910 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2914 if ((handle = dat_open("jump.smp", datfile_name, "rb")) == 0) {
2915 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2918 if (dj_load_sfx(handle, 0, dat_filelen("jump.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
2919 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2923 if ((handle = dat_open("death.smp", datfile_name, "rb")) == 0) {
2924 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2927 if (dj_load_sfx(handle, 0, dat_filelen("death.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
2928 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2932 if ((handle = dat_open("spring.smp", datfile_name, "rb")) == 0) {
2933 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2936 if (dj_load_sfx(handle, 0, dat_filelen("spring.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
2937 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2941 if ((handle = dat_open("splash.smp", datfile_name, "rb")) == 0) {
2942 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2945 if (dj_load_sfx(handle, 0, dat_filelen("splash.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
2946 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2950 if ((handle = dat_open("fly.smp", datfile_name, "rb")) == 0) {
2951 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2954 if (dj_load_sfx(handle, 0, dat_filelen("fly.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
2955 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2959 dj_get_sfx_settings(SFX_FLY, &fly);
2961 fly.default_freq = SFX_FLY_FREQ;
2964 fly.loop_length = fly.length;
2965 dj_set_sfx_settings(SFX_FLY, &fly);
2968 if ((background_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
2970 if ((mask_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
2972 memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
2973 register_mask(mask_pic);
2976 for (c1 = 0; c1 < 16; c1++) {
2977 pal[(240 + c1) * 3 + 0] = c1 << 2;
2978 pal[(240 + c1) * 3 + 1] = c1 << 2;
2979 pal[(240 + c1) * 3 + 2] = c1 << 2;
2982 setpalette(0, 256, pal);
2986 recalculate_gob(&font_gobs, pal);
2988 if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
2990 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2991 put_text(0, 200, 100, "Move the joystick to the", 2);
2992 put_text(0, 200, 115, "UPPER LEFT", 2);
2993 put_text(0, 200, 130, "and press button A", 2);
2994 put_text(0, 200, 200, "Or press ESC to use", 2);
2995 put_text(0, 200, 215, "previous settings", 2);
2996 if (calib_joy(0) != 0)
2999 register_background(NULL, NULL);
3001 main_info.view_page = 1;
3006 put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
3007 put_text(1, 200, 100, "Move the joystick to the", 2);
3008 put_text(1, 200, 115, "LOWER RIGHT", 2);
3009 put_text(1, 200, 130, "and press button A", 2);
3010 put_text(1, 200, 200, "Or press ESC to use", 2);
3011 put_text(1, 200, 215, "previous settings", 2);
3012 if (calib_joy(1) != 0)
3015 register_background(NULL, NULL);
3020 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
3021 put_text(0, 200, 100, "Move the joystick to the", 2);
3022 put_text(0, 200, 115, "CENTER", 2);
3023 put_text(0, 200, 130, "and press button A", 2);
3024 put_text(0, 200, 200, "Or press ESC to use", 2);
3025 put_text(0, 200, 215, "previous settings", 2);
3026 if (calib_joy(2) != 0)
3029 if (joy.calib_data.x1 == joy.calib_data.x2)
3030 joy.calib_data.x1 -= 10;
3031 if (joy.calib_data.x3 == joy.calib_data.x2)
3032 joy.calib_data.x3 += 10;
3033 if (joy.calib_data.y1 == joy.calib_data.y2)
3034 joy.calib_data.y1 -= 10;
3035 if (joy.calib_data.y3 == joy.calib_data.y2)
3036 joy.calib_data.y3 += 10;
3041 if (load_flag == 1) {
3042 if ((handle = dat_open("calib.dat", datfile_name, "rb")) == 0) {
3043 strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
3046 joy.calib_data.x1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3047 joy.calib_data.x2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3048 joy.calib_data.x3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3049 joy.calib_data.y1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3050 joy.calib_data.y2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3051 joy.calib_data.y3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3058 init_server(netarg);
3060 connect_to_server(netarg);
3069 void deinit_program(void)
3076 dj_free_mod(MOD_MENU);
3077 dj_free_mod(MOD_GAME);
3078 dj_free_sfx(SFX_DEATH);
3079 dj_free_sfx(SFX_SPRING);
3080 dj_free_sfx(SFX_SPLASH);
3083 if (background_pic != 0)
3084 free(background_pic);
3088 remove_keyb_handler();
3092 __dpmi_int(0x10, ®s);
3095 if (main_info.error_str[0] != 0) {
3096 printf(main_info.error_str);
3098 MessageBox(0, main_info.error_str, "Jump'n'Bump", 0);
3107 unsigned short rnd(unsigned short max)
3109 #if (RAND_MAX < 0x7fff)
3110 #error "rand returns too small values"
3111 #elif (RAND_MAX == 0x7fff)
3112 return (unsigned short)((rand()*2) % (int)max);
3114 return (unsigned short)(rand() % (int)max);
3119 int read_level(void)
3121 unsigned char *handle;
3125 if ((handle = dat_open("levelmap.txt", datfile_name, "rb")) == 0) {
3126 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
3130 for (c1 = 0; c1 < 16; c1++) {
3131 for (c2 = 0; c2 < 22; c2++) {
3133 chr = (int) *(handle++);
3134 if (chr >= '0' && chr <= '4')
3138 ban_map[c1][21-c2] = chr - '0';
3140 ban_map[c1][c2] = chr - '0';
3144 for (c2 = 0; c2 < 22; c2++)
3145 ban_map[16][c2] = BAN_SOLID;
3152 unsigned char *dat_open(char *file_name, char *dat_name, char *mode)
3160 if (datafile_buffer == NULL)
3163 memset(name, 0, sizeof(name));
3165 num = ( (datafile_buffer[0] << 0) +
3166 (datafile_buffer[1] << 8) +
3167 (datafile_buffer[2] << 16) +
3168 (datafile_buffer[3] << 24) );
3170 ptr = datafile_buffer + 4;
3172 for (c1 = 0; c1 < num; c1++) {
3174 memcpy(name, ptr, 12);
3177 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
3178 ofs = ( (ptr[0] << 0) +
3183 return (datafile_buffer + ofs);
3192 int dat_filelen(char *file_name, char *dat_name)
3200 memset(name, 0, sizeof(name));
3202 num = ( (datafile_buffer[0] << 0) +
3203 (datafile_buffer[1] << 8) +
3204 (datafile_buffer[2] << 16) +
3205 (datafile_buffer[3] << 24) );
3207 ptr = datafile_buffer + 4;
3209 for (c1 = 0; c1 < num; c1++) {
3211 memcpy(name, ptr, 12);
3214 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
3217 len = ( (ptr[0] << 0) +
3231 void write_calib_data(void)
3239 if ((handle = fopen(datfile_name, "rb")) == NULL)
3241 len = filelength(fileno(handle));
3242 if ((mem = malloc(len)) == NULL)
3244 fread(mem, 1, len, handle);
3248 num = *(int *) (&mem[0]);
3249 for (c1 = 0; c1 < num; c1++) {
3250 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
3251 ofs = *(int *) (&mem[ofs + 12]);
3257 mem[ofs] = joy.calib_data.x1 & 0xff;
3258 mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
3259 mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
3260 mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
3261 mem[ofs + 4] = joy.calib_data.x2 & 0xff;
3262 mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
3263 mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
3264 mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
3265 mem[ofs + 8] = joy.calib_data.x3 & 0xff;
3266 mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
3267 mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
3268 mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
3269 mem[ofs + 12] = joy.calib_data.y1 & 0xff;
3270 mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
3271 mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
3272 mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
3273 mem[ofs + 16] = joy.calib_data.y2 & 0xff;
3274 mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
3275 mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
3276 mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
3277 mem[ofs + 20] = joy.calib_data.y3 & 0xff;
3278 mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
3279 mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
3280 mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
3282 if ((handle = fopen(datfile_name, "wb")) == NULL)
3284 fwrite(mem, 1, len, handle);