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
40 #define M_PI 3.14159265358979323846
43 gob_t rabbit_gobs = { 0 };
44 gob_t font_gobs = { 0 };
45 gob_t object_gobs = { 0 };
46 gob_t number_gobs = { 0 };
48 main_info_t main_info;
49 player_t player[JNB_MAX_PLAYERS];
50 player_anim_t player_anims[7];
51 object_t objects[NUM_OBJECTS];
55 char datfile_name[2048];
61 unsigned int ban_map[17][22] = {
62 {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
63 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0},
64 {1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
65 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1},
66 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
67 {1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
68 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1},
69 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
70 {1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
71 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1},
72 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1},
73 {1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1},
74 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
75 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
76 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 1, 3, 3, 3, 1, 1, 1},
77 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
78 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
204 int flies_enabled = 1;
209 int old_draw_x, old_draw_y;
221 } pobs[NUM_LEFTOVERS];
225 int pogostick, bunnies_in_space, jetpack, lord_of_the_flies, blood_is_thicker_than_water;
229 int filelength(int handle)
233 if (fstat(handle, &buf) == -1) {
234 perror("filelength");
243 /* networking shite. */
245 int client_player_num = -1;
250 TCPsocket sock = NULL;
251 SDLNet_SocketSet socketset = NULL;
257 SDLNet_SocketSet socketset;
260 NetInfo net_info[JNB_MAX_PLAYERS];
272 #define NETPKTBUFSIZE (4 + 4 + 4 + 4 + 4)
274 #define NETCMD_NACK (0xF00DF00D + 0)
275 #define NETCMD_ACK (0xF00DF00D + 1)
276 #define NETCMD_HELLO (0xF00DF00D + 2)
277 #define NETCMD_GREENLIGHT (0xF00DF00D + 3)
278 #define NETCMD_MOVE (0xF00DF00D + 4)
279 #define NETCMD_BYE (0xF00DF00D + 5)
280 #define NETCMD_POSITION (0xF00DF00D + 6)
281 #define NETCMD_ALIVE (0xF00DF00D + 7)
282 #define NETCMD_KILL (0xF00DF00D + 8)
286 void bufToPacket(const char *buf, NetPacket *pkt)
288 SDLNet_Write32(*((unsigned long *) (buf + 0)), &pkt->cmd);
289 SDLNet_Write32(*((unsigned long *) (buf + 4)), &pkt->arg);
290 SDLNet_Write32(*((unsigned long *) (buf + 8)), &pkt->arg2);
291 SDLNet_Write32(*((unsigned long *) (buf + 12)), &pkt->arg3);
292 SDLNet_Write32(*((unsigned long *) (buf + 16)), &pkt->arg4);
294 pkt->cmd = ntohl(*((unsigned long *) (buf + 0)));
295 pkt->arg = (long) ntohl(*((unsigned long *) (buf + 4)));
296 pkt->arg2 = (long) ntohl(*((unsigned long *) (buf + 8)));
297 pkt->arg3 = (long) ntohl(*((unsigned long *) (buf + 12)));
298 pkt->arg4 = (long) ntohl(*((unsigned long *) (buf + 16)));
303 void packetToBuf(const NetPacket *pkt, char *buf)
305 *((unsigned long *) (buf + 0)) = SDLNet_Read32(&pkt->cmd);
306 *((unsigned long *) (buf + 4)) = SDLNet_Read32(&pkt->arg);
307 *((unsigned long *) (buf + 8)) = SDLNet_Read32(&pkt->arg2);
308 *((unsigned long *) (buf + 12)) = SDLNet_Read32(&pkt->arg3);
309 *((unsigned long *) (buf + 16)) = SDLNet_Read32(&pkt->arg4);
311 *((unsigned long *) (buf + 0)) = htonl(pkt->cmd);
312 *((unsigned long *) (buf + 4)) = htonl((unsigned long) pkt->arg);
313 *((unsigned long *) (buf + 8)) = htonl((unsigned long) pkt->arg2);
314 *((unsigned long *) (buf + 12)) = htonl((unsigned long) pkt->arg3);
315 *((unsigned long *) (buf + 16)) = htonl((unsigned long) pkt->arg4);
320 void sendPacketToSock(TCPsocket s, NetPacket *pkt)
322 int bytes_left = NETPKTBUFSIZE;
324 char buf[NETPKTBUFSIZE];
327 packetToBuf(pkt, buf);
328 while (bytes_left > 0) {
329 bw = SDLNet_TCP_Send(s, ptr, bytes_left);
331 fprintf(stderr, "SERVER: SDLNet_TCP_Send(): %s\n", SDLNet_GetError());
334 } else if (bw == 0) {
344 void sendPacket(int playerid, NetPacket *pkt)
346 if ( playerid < JNB_MAX_PLAYERS ) {
347 if ((player[playerid].enabled) && (playerid != client_player_num)) {
348 sendPacketToSock(net_info[playerid].sock, pkt);
354 void sendPacketToAll(NetPacket *pkt)
358 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
364 int grabPacket(TCPsocket s, SDLNet_SocketSet ss, NetPacket *pkt)
366 static char buf[NETPKTBUFSIZE];
367 static int buf_count = 0;
371 if (SDLNet_CheckSockets(ss, 0) > 0) {
372 rc = SDLNet_TCP_Recv(s, &buf[buf_count], NETPKTBUFSIZE - buf_count);
373 if (rc <= 0) { /* closed connection? */
375 } else if (rc != NETPKTBUFSIZE) { // !!! FIXME: buffer these?
379 bufToPacket(buf, pkt);
388 int serverRecvPacket(NetPacket *pkt)
395 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
396 TCPsocket s = net_info[i].sock;
398 if ((i == client_player_num) || (!player[i].enabled))
401 rc = grabPacket(s, net_info[i].socketset, pkt);
405 player[i].enabled = 0;
407 pkt.cmd = NETCMD_BYE;
412 sendPacketToAll(&pkt);
414 return(i); /* it's all good. */
418 return(-1); /* no packets available currently. */
422 void wait_for_greenlight(void)
427 printf("CLIENT: Waiting for greenlight...\n");
431 while ((rc = grabPacket(sock, socketset, &pkt)) == 0) {
432 SDL_Delay(100); /* nap and then try again. */
436 printf("CLIENT: Lost connection.\n");
437 SDLNet_TCP_Close(sock);
440 } while (pkt.cmd != NETCMD_GREENLIGHT);
442 printf("CLIENT: Got greenlight.\n");
444 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
445 if (pkt.arg & (1 << i)) {
446 printf("CLIENT: There is a player #%d.\n", i);
447 player[i].enabled = 1;
453 static int buggered_off = 0;
456 void tellServerGoodbye(void)
462 pkt.cmd = NETCMD_BYE;
463 pkt.arg = client_player_num;
467 sendPacketToSock(sock, &pkt);
473 void processMovePacket(NetPacket *pkt)
475 int playerid = pkt->arg;
476 int movetype = ((pkt->arg2 >> 16) & 0xFF);
477 int newval = ((pkt->arg2 >> 0) & 0xFF);
479 if (movetype == MOVEMENT_LEFT) {
480 player[playerid].action_left = newval;
481 } else if (movetype == MOVEMENT_RIGHT) {
482 player[playerid].action_right = newval;
483 } else if (movetype == MOVEMENT_UP) {
484 player[playerid].action_up = newval;
486 printf("bogus MOVE packet!\n");
489 player[playerid].x = pkt->arg3;
490 player[playerid].y = pkt->arg4;
494 void tellServerPlayerMoved(int playerid, int movement_type, int newval)
498 pkt.cmd = NETCMD_MOVE;
500 pkt.arg2 = ( ((movement_type & 0xFF) << 16) | ((newval & 0xFF) << 0) );
501 pkt.arg3 = player[playerid].x;
502 pkt.arg4 = player[playerid].y;
505 processMovePacket(&pkt);
508 sendPacketToAll(&pkt);
510 sendPacketToSock(sock, &pkt);
517 void tellServerNewPosition(void)
520 pkt.cmd = NETCMD_POSITION;
521 pkt.arg = client_player_num;
522 pkt.arg2 = player[client_player_num].x;
523 pkt.arg3 = player[client_player_num].y;
526 sendPacketToAll(&pkt);
528 sendPacketToSock(sock, &pkt);
534 void processKillPacket(NetPacket *pkt)
543 player[c1].y_add = -player[c1].y_add;
544 if (player[c1].y_add > -262144L)
545 player[c1].y_add = -262144L;
546 player[c1].jump_abort = 1;
547 player[c2].dead_flag = 1;
548 if (player[c2].anim != 6) {
550 player[c2].frame = 0;
551 player[c2].frame_tick = 0;
552 player[c2].image = player_anims[player[c2].anim].frame[player[c2].frame].image + player[c2].direction * 9;
553 if (main_info.no_gore == 0) {
554 for (c4 = 0; c4 < 6; c4++)
555 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);
556 for (c4 = 0; c4 < 6; c4++)
557 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 76);
558 for (c4 = 0; c4 < 6; c4++)
559 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 77);
560 for (c4 = 0; c4 < 8; c4++)
561 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 78);
562 for (c4 = 0; c4 < 10; c4++)
563 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 79);
565 dj_play_sfx(SFX_DEATH, (unsigned short)(SFX_DEATH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
567 player[c1].bumped[c2]++;
568 s1 = player[c1].bumps % 100;
569 add_leftovers(0, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
570 add_leftovers(1, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
571 add_leftovers(0, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
572 add_leftovers(1, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
578 void processPositionPacket(NetPacket *pkt)
580 int playerid = pkt->arg;
582 player[playerid].x = pkt->arg2;
583 player[playerid].y = pkt->arg3;
587 void processAlivePacket(NetPacket *pkt)
589 int playerid = pkt->arg;
591 player[playerid].dead_flag = 0;
592 player[playerid].x = pkt->arg2;
593 player[playerid].y = pkt->arg3;
597 void serverTellEveryoneGoodbye(void)
603 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
604 if (player[i].enabled) {
607 pkt.cmd = NETCMD_BYE;
612 sendPacketToAll(&pkt);
619 int server_said_bye = 0;
622 int update_players_from_server(void)
629 while ((rc = grabPacket(sock, socketset, &pkt)) != 0) {
631 printf("CLIENT: Lost connection.\n");
632 pkt.cmd = NETCMD_BYE;
633 pkt.arg = client_player_num;
636 if (pkt.cmd == NETCMD_BYE) {
637 if (pkt.arg == client_player_num) {
638 SDLNet_FreeSocketSet(socketset);
639 SDLNet_TCP_Close(sock);
644 player[pkt.arg].enabled = 0;
646 } else if (pkt.cmd == NETCMD_MOVE) {
647 processMovePacket(&pkt);
648 } else if (pkt.cmd == NETCMD_ALIVE) {
649 processAlivePacket(&pkt);
650 } else if (pkt.cmd == NETCMD_POSITION) {
651 processPositionPacket(&pkt);
652 } else if (pkt.cmd == NETCMD_KILL) {
653 processKillPacket(&pkt);
655 printf("CLIENT: Got an unknown packet: 0x%lX.\n", pkt.cmd);
663 void serverSendAlive(int playerid)
668 pkt.cmd = NETCMD_ALIVE;
670 pkt.arg2 = player[playerid].x;
671 pkt.arg3 = player[playerid].y;
672 sendPacketToAll(&pkt);
677 void serverSendKillPacket(int killer, int victim)
682 pkt.cmd = NETCMD_KILL;
685 pkt.arg3 = player[victim].x;
686 pkt.arg4 = player[victim].y;
687 processKillPacket(&pkt);
690 sendPacketToAll(&pkt);
696 void update_players_from_clients(void)
704 while ((playerid = serverRecvPacket(&pkt)) >= 0) {
705 if (pkt.cmd == NETCMD_BYE) {
706 pkt.arg = playerid; /* just in case. */
707 sendPacketToAll(&pkt);
708 player[playerid].enabled = 0;
709 SDLNet_FreeSocketSet(net_info[playerid].socketset);
710 SDLNet_TCP_Close(net_info[playerid].sock);
711 } else if (pkt.cmd == NETCMD_POSITION) {
712 pkt.arg = playerid; /* just in case. */
713 processPositionPacket(&pkt);
714 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
719 } else if (pkt.cmd == NETCMD_MOVE) {
720 pkt.arg = playerid; /* just in case. */
721 //pkt.arg3 = player[playerid].x;
722 //pkt.arg4 = player[playerid].y;
723 processMovePacket(&pkt);
724 sendPacketToAll(&pkt);
726 printf("SERVER: Got unknown packet (0x%lX).\n", pkt.cmd);
732 void init_server(const char *netarg)
737 int wait_for_clients = ((netarg == NULL) ? 0 : atoi(netarg));
740 if ((wait_for_clients > (JNB_MAX_PLAYERS - 1)) || (wait_for_clients < 0)) {
741 printf("SERVER: Waiting for bogus client count (%d).\n", wait_for_clients);
745 if (SDLNet_Init() < 0) {
750 SDLNet_ResolveHost(&addr, NULL, JNB_INETPORT);
751 ipstr = SDLNet_ResolveIP(&addr);
752 SDLNet_ResolveHost(&addr, ipstr, JNB_INETPORT);
753 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);
754 net_info[client_player_num].addr = addr;
756 addr.host = INADDR_ANY;
757 sock = SDLNet_TCP_Open(&addr);
759 fprintf(stderr, "SERVER: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
763 player[client_player_num].enabled = 1;
765 printf("SERVER: waiting for (%d) clients...\n", wait_for_clients);
767 socketset = SDLNet_AllocSocketSet(JNB_MAX_PLAYERS + 1);
768 SDLNet_TCP_AddSocket(socketset, sock);
770 while (wait_for_clients > 0)
772 char buf[NETPKTBUFSIZE];
778 /* Wait for events */
779 SDLNet_CheckSockets(socketset, ~0);
780 if ( SDLNet_SocketReady(sock) ) {
781 s = SDLNet_TCP_Accept(sock);
785 fprintf(stderr, "SERVER: SDLNet_TCP_Accept(): %s", SDLNet_GetError());
786 SDLNet_TCP_Close(sock);
792 br = SDLNet_TCP_Recv(s, buf, NETPKTBUFSIZE);
794 fprintf(stderr, "SERVER: SDLNet_TCP_Recv(): %s\n", SDLNet_GetError());
796 SDLNet_TCP_Close(sock);
800 from = SDLNet_TCP_GetPeerAddress(s);
801 ipstr = SDLNet_ResolveIP(from);
802 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);
804 if (br != NETPKTBUFSIZE) {
805 printf("SERVER: Bogus packet.\n");
809 bufToPacket(buf, &pkt);
810 if (pkt.cmd != NETCMD_HELLO) {
811 printf("SERVER: Bogus packet.\n");
815 printf("SERVER: Client claims to be player #%ld.\n", pkt.arg);
817 if (pkt.arg > JNB_MAX_PLAYERS) {
818 printf("SERVER: (that's an invalid player number.)\n");
820 if (player[pkt.arg].enabled) {
821 printf("SERVER: (that player number is already taken.)\n");
828 printf("SERVER: Forbidding connection.\n");
829 pkt.cmd = NETCMD_NACK;
830 sendPacketToSock(s, &pkt);
833 player[pkt.arg].enabled = 1;
834 net_info[pkt.arg].sock = s;
835 net_info[pkt.arg].addr = *from;
836 net_info[pkt.arg].socketset = SDLNet_AllocSocketSet(1);
837 SDLNet_TCP_AddSocket(net_info[pkt.arg].socketset, net_info[pkt.arg].sock);
839 printf("SERVER: Granting connection. (%d) to go.\n", wait_for_clients);
840 pkt.cmd = NETCMD_ACK;
841 sendPacket(pkt.arg, &pkt);
845 SDLNet_TCP_Close(sock); /* done with the listen socket. */
846 SDLNet_FreeSocketSet(socketset);
850 printf("SERVER: Got all our connections. Greenlighting clients...\n");
852 pkt.cmd = NETCMD_GREENLIGHT;
854 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
855 if (player[i].enabled) {
859 sendPacketToAll(&pkt);
863 void connect_to_server(char *netarg)
866 char buf[NETPKTBUFSIZE];
872 if (netarg == NULL) {
873 printf("CLIENT: Need to specify host to connect to.\n");
877 if (SDLNet_Init() < 0) {
882 player[client_player_num].enabled = 1;
884 SDLNet_ResolveHost(&addr, NULL, JNB_INETPORT);
885 ipstr = SDLNet_ResolveIP(&addr);
886 SDLNet_ResolveHost(&addr, ipstr, JNB_INETPORT);
887 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);
888 net_info[client_player_num].addr = addr;
890 if (SDLNet_ResolveHost(&hent, netarg, JNB_INETPORT) < 0) {
891 fprintf(stderr, "CLIENT: couldn't find host: %s\n", SDLNet_GetError());
895 sock = SDLNet_TCP_Open(&hent);
897 fprintf(stderr, "CLIENT: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
901 socketset = SDLNet_AllocSocketSet(1);
902 SDLNet_TCP_AddSocket(socketset, sock);
904 printf("CLIENT: connected to %s...\n", SDLNet_ResolveIP(&hent));
906 printf("CLIENT: Sending HELLO packet...\n");
907 pkt.cmd = NETCMD_HELLO;
908 pkt.arg = client_player_num;
909 sendPacketToSock(sock, &pkt);
911 printf("CLIENT: Waiting for ACK from server...\n");
913 br = SDLNet_TCP_Recv(sock, buf, NETPKTBUFSIZE);
915 fprintf(stderr, "CLIENT: recv(): %s\n", SDLNet_GetError);
916 SDLNet_FreeSocketSet(socketset);
917 SDLNet_TCP_Close(sock);
921 if (br != NETPKTBUFSIZE) {
922 printf("CLIENT: Bogus packet size (%d of %d). FIXME.\n", br, NETPKTBUFSIZE);
923 SDLNet_FreeSocketSet(socketset);
924 SDLNet_TCP_Close(sock);
928 bufToPacket(buf, &pkt);
930 if (pkt.cmd == NETCMD_NACK) {
931 printf("CLIENT: Server forbid us from playing.\n");
932 SDLNet_FreeSocketSet(socketset);
933 SDLNet_TCP_Close(sock);
937 if (pkt.cmd != NETCMD_ACK) {
938 printf("CLIENT: Unexpected packet (cmd=0x%lX).\n", pkt.cmd);
939 SDLNet_FreeSocketSet(socketset);
940 SDLNet_TCP_Close(sock);
944 printf("CLIENT: Server accepted our connection.\n");
946 wait_for_greenlight();
951 static flip_pixels(unsigned char *pixels)
957 for (y = 0; y < JNB_HEIGHT; y++) {
958 for (x = 0; x < (352/2); x++) {
959 temp = pixels[y*JNB_WIDTH+x];
960 pixels[y*JNB_WIDTH+x] = pixels[y*JNB_WIDTH+(352-x)-1];
961 pixels[y*JNB_WIDTH+(352-x)-1] = temp;
967 int main(int argc, char *argv[])
969 unsigned char *handle;
970 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
973 int closest_player = 0, dist, cur_dist = 0;
974 int end_loop_flag = 0, fade_flag;
975 int mod_vol, sfx_vol, mod_fade_direction;
981 if (init_program(argc, argv, pal) != 0)
984 if (main_info.fireworks == 1) {
995 if (key_pressed(1) == 1) {
998 if (init_level(0, pal) != 0) {
1003 memset(cur_pal, 0, 768);
1004 setpalette(0, 256, cur_pal);
1006 recalculate_gob(&rabbit_gobs, pal);
1007 //recalculate_gob(&font_gobs, pal);
1008 recalculate_gob(&object_gobs, pal);
1009 recalculate_gob(&number_gobs, pal);
1012 register_background(background_pic, pal);
1015 if (flies_enabled) {
1019 for (c1 = 0; c1 < NUM_FLIES; c1++) {
1021 flies[c1].x = s1 + rnd(101) - 50;
1022 flies[c1].y = s2 + rnd(101) - 50;
1023 if (ban_map[flies[c1].y >> 4][flies[c1].x >> 4] == BAN_VOID)
1026 flies[c1].back_defined[0] = 0;
1027 flies[c1].back_defined[1] = 0;
1031 mod_vol = sfx_vol = 10;
1032 mod_fade_direction = 1;
1033 dj_ready_mod(MOD_GAME);
1034 dj_set_mod_volume((char)mod_vol);
1035 dj_set_sfx_volume((char)mod_vol);
1039 dj_play_sfx(SFX_FLY, SFX_FLY_FREQ, 0, 0, 0, 4);
1043 lord_of_the_flies = bunnies_in_space = jetpack = pogostick = blood_is_thicker_than_water = 0;
1045 main_info.page_info[0].num_pobs = 0;
1046 main_info.page_info[1].num_pobs = 0;
1047 main_info.view_page = 0;
1048 main_info.draw_page = 1;
1052 while (update_count) {
1054 if (key_pressed(1) == 1) {
1058 serverTellEveryoneGoodbye();
1060 tellServerGoodbye();
1065 memset(pal, 0, 768);
1066 mod_fade_direction = 0;
1069 if (strncmp(last_keys, "kcitsogop", strlen("kcitsogop")) == 0) {
1073 if (strncmp(last_keys, "ecapsniseinnub", strlen("ecapsniseinnub")) == 0) {
1074 bunnies_in_space ^= 1;
1077 if (strncmp(last_keys, "kcaptej", strlen("kcaptej")) == 0) {
1081 if (strncmp(last_keys, "seilfehtfodrol", strlen("seilfehtfodrol")) == 0) {
1082 lord_of_the_flies ^= 1;
1085 if (strncmp(last_keys, "retawnahtrekcihtsidoolb", strlen("retawnahtrekcihtsidoolb")) == 0) {
1086 blood_is_thicker_than_water ^= 1;
1087 if (blood_is_thicker_than_water == 1) {
1138 register_background(background_pic, pal);
1139 recalculate_gob(&object_gobs, pal);
1146 update_players_from_clients();
1148 if (!update_players_from_server()) {
1149 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);
1441 if ( (player[client_player_num].dead_flag == 0) &&
1443 (player[client_player_num].action_left) ||
1444 (player[client_player_num].action_right) ||
1445 (player[client_player_num].action_up) ||
1446 (player[client_player_num].jump_ready == 0)
1449 tellServerNewPosition();
1454 update_count = intr_sysupdate();
1458 if ((server_said_bye) || ((fade_flag == 0) && (end_loop_flag == 1)))
1462 if ((fade_flag == 0) && (end_loop_flag == 1))
1469 serverTellEveryoneGoodbye();
1470 SDLNet_TCP_Close(sock);
1473 if (!server_said_bye) {
1474 tellServerGoodbye();
1477 SDLNet_TCP_Close(sock);
1483 main_info.view_page = 0;
1484 main_info.draw_page = 1;
1486 dj_stop_sfx_channel(4);
1490 memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
1491 register_mask(mask_pic);
1493 //recalculate_gob(&font_gobs, pal);
1494 register_background(NULL, NULL);
1498 put_text(main_info.view_page, 100, 50, "DOTT", 2);
1499 put_text(main_info.view_page, 160, 50, "JIFFY", 2);
1500 put_text(main_info.view_page, 220, 50, "FIZZ", 2);
1501 put_text(main_info.view_page, 280, 50, "MIJJI", 2);
1502 put_text(main_info.view_page, 40, 80, "DOTT", 2);
1503 put_text(main_info.view_page, 40, 110, "JIFFY", 2);
1504 put_text(main_info.view_page, 40, 140, "FIZZ", 2);
1505 put_text(main_info.view_page, 40, 170, "MIJJI", 2);
1507 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1508 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
1510 sprintf(str1, "%d", player[c1].bumped[c2]);
1511 put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, str1, 2);
1513 put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, "-", 2);
1515 sprintf(str1, "%d", player[c1].bumps);
1516 put_text(main_info.view_page, 350, 80 + c1 * 30, str1, 2);
1519 put_text(main_info.view_page, 200, 230, "Press ESC to continue", 2);
1523 flippage(main_info.view_page);
1525 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
1526 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1529 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
1530 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1534 for (c1 = 0; c1 < 16; c1++) { // fix dark font
1535 pal[(240 + c1) * 3 + 0] = c1 << 2;
1536 pal[(240 + c1) * 3 + 1] = c1 << 2;
1537 pal[(240 + c1) * 3 + 2] = c1 << 2;
1540 memset(cur_pal, 0, 768);
1542 setpalette(0, 256, cur_pal);
1545 dj_ready_mod(MOD_SCORES);
1546 dj_set_mod_volume((char)mod_vol);
1550 while (key_pressed(1) == 0) {
1553 dj_set_mod_volume((char)mod_vol);
1554 for (c1 = 0; c1 < 768; c1++) {
1555 if (cur_pal[c1] < pal[c1])
1561 setpalette(0, 256, cur_pal);
1562 flippage(main_info.view_page);
1564 while (key_pressed(1) == 1) {
1569 memset(pal, 0, 768);
1571 while (mod_vol > 0) {
1573 dj_set_mod_volume((char)mod_vol);
1574 for (c1 = 0; c1 < 768; c1++) {
1575 if (cur_pal[c1] > pal[c1])
1580 setpalette(0, 256, cur_pal);
1581 flippage(main_info.view_page);
1584 fillpalette(0, 0, 0);
1590 break; /* don't go back to menu if in net game. */
1599 void steer_players(void)
1604 update_player_actions();
1606 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1608 if (player[c1].enabled == 1) {
1610 if (player[c1].dead_flag == 0) {
1612 if (player[c1].action_left && player[c1].action_right) {
1613 if (player[c1].direction == 0) {
1614 if (player[c1].action_right) {
1615 s1 = (player[c1].x >> 16);
1616 s2 = (player[c1].y >> 16);
1617 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1618 if (player[c1].x_add < 0)
1619 player[c1].x_add += 1024;
1621 player[c1].x_add += 768;
1622 } 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)) {
1623 if (player[c1].x_add > 0)
1624 player[c1].x_add += 1024;
1626 player[c1].x_add += 768;
1628 if (player[c1].x_add < 0) {
1629 player[c1].x_add += 16384;
1630 if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1631 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);
1633 player[c1].x_add += 12288;
1635 if (player[c1].x_add > 98304L)
1636 player[c1].x_add = 98304L;
1637 player[c1].direction = 0;
1638 if (player[c1].anim == 0) {
1639 player[c1].anim = 1;
1640 player[c1].frame = 0;
1641 player[c1].frame_tick = 0;
1642 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1646 if (player[c1].action_left) {
1647 s1 = (player[c1].x >> 16);
1648 s2 = (player[c1].y >> 16);
1649 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1650 if (player[c1].x_add > 0)
1651 player[c1].x_add -= 1024;
1653 player[c1].x_add -= 768;
1654 } 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)) {
1655 if (player[c1].x_add > 0)
1656 player[c1].x_add -= 1024;
1658 player[c1].x_add -= 768;
1660 if (player[c1].x_add > 0) {
1661 player[c1].x_add -= 16384;
1662 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1663 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);
1665 player[c1].x_add -= 12288;
1667 if (player[c1].x_add < -98304L)
1668 player[c1].x_add = -98304L;
1669 player[c1].direction = 1;
1670 if (player[c1].anim == 0) {
1671 player[c1].anim = 1;
1672 player[c1].frame = 0;
1673 player[c1].frame_tick = 0;
1674 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1678 } else if (player[c1].action_left) {
1679 s1 = (player[c1].x >> 16);
1680 s2 = (player[c1].y >> 16);
1681 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1682 if (player[c1].x_add > 0)
1683 player[c1].x_add -= 1024;
1685 player[c1].x_add -= 768;
1686 } 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)) {
1687 if (player[c1].x_add > 0)
1688 player[c1].x_add -= 1024;
1690 player[c1].x_add -= 768;
1692 if (player[c1].x_add > 0) {
1693 player[c1].x_add -= 16384;
1694 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1695 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);
1697 player[c1].x_add -= 12288;
1699 if (player[c1].x_add < -98304L)
1700 player[c1].x_add = -98304L;
1701 player[c1].direction = 1;
1702 if (player[c1].anim == 0) {
1703 player[c1].anim = 1;
1704 player[c1].frame = 0;
1705 player[c1].frame_tick = 0;
1706 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1708 } else if (player[c1].action_right) {
1709 s1 = (player[c1].x >> 16);
1710 s2 = (player[c1].y >> 16);
1711 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1712 if (player[c1].x_add < 0)
1713 player[c1].x_add += 1024;
1715 player[c1].x_add += 768;
1716 } 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)) {
1717 if (player[c1].x_add > 0)
1718 player[c1].x_add += 1024;
1720 player[c1].x_add += 768;
1722 if (player[c1].x_add < 0) {
1723 player[c1].x_add += 16384;
1724 if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1725 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);
1727 player[c1].x_add += 12288;
1729 if (player[c1].x_add > 98304L)
1730 player[c1].x_add = 98304L;
1731 player[c1].direction = 0;
1732 if (player[c1].anim == 0) {
1733 player[c1].anim = 1;
1734 player[c1].frame = 0;
1735 player[c1].frame_tick = 0;
1736 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1738 } else if ((!player[c1].action_left) && (!player[c1].action_right)) {
1739 s1 = (player[c1].x >> 16);
1740 s2 = (player[c1].y >> 16);
1741 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)))) {
1742 if (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 player[c1].x_add -= 16384;
1748 if (player[c1].x_add < 0)
1749 player[c1].x_add = 0;
1751 if (player[c1].x_add != 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1752 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);
1754 if (player[c1].anim == 1) {
1755 player[c1].anim = 0;
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;
1762 if (pogostick == 1 || (player[c1].jump_ready == 1 && player[c1].action_up)) {
1763 s1 = (player[c1].x >> 16);
1764 s2 = (player[c1].y >> 16);
1767 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) {
1768 player[c1].y_add = -280000L;
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);
1780 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)) {
1781 player[c1].y_add = -196608L;
1782 player[c1].in_water = 0;
1783 player[c1].anim = 2;
1784 player[c1].frame = 0;
1785 player[c1].frame_tick = 0;
1786 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1787 player[c1].jump_ready = 0;
1788 player[c1].jump_abort = 1;
1790 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1792 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1795 if (pogostick == 0 && (!player[c1].action_up)) {
1796 player[c1].jump_ready = 1;
1797 if (player[c1].in_water == 0 && player[c1].y_add < 0 && player[c1].jump_abort == 1) {
1798 if (bunnies_in_space == 0)
1799 player[c1].y_add += 32768;
1801 player[c1].y_add += 16384;
1802 if (player[c1].y_add > 0)
1803 player[c1].y_add = 0;
1808 if (player[c1].action_up) {
1809 player[c1].y_add -= 16384;
1810 if (player[c1].y_add < -400000L)
1811 player[c1].y_add = -400000L;
1812 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))
1813 player[c1].in_water = 0;
1815 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);
1820 player[c1].x += player[c1].x_add;
1821 if ((player[c1].x >> 16) < 0) {
1823 player[c1].x_add = 0;
1825 if ((player[c1].x >> 16) + 15 > 351) {
1826 player[c1].x = 336L << 16;
1827 player[c1].x_add = 0;
1829 if (player[c1].y > 0) {
1830 s1 = (player[c1].x >> 16);
1831 s2 = (player[c1].y >> 16);
1832 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) {
1833 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1834 player[c1].x_add = 0;
1836 s1 = (player[c1].x >> 16);
1837 s2 = (player[c1].y >> 16);
1838 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) {
1839 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1840 player[c1].x_add = 0;
1843 s1 = (player[c1].x >> 16);
1845 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) {
1846 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1847 player[c1].x_add = 0;
1849 s1 = (player[c1].x >> 16);
1851 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) {
1852 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1853 player[c1].x_add = 0;
1857 player[c1].y += player[c1].y_add;
1859 s1 = (player[c1].x >> 16);
1860 s2 = (player[c1].y >> 16);
1861 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))) {
1862 player[c1].y = ((player[c1].y >> 16) & 0xfff0) << 16;
1863 player[c1].y_add = -400000L;
1864 player[c1].anim = 2;
1865 player[c1].frame = 0;
1866 player[c1].frame_tick = 0;
1867 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1868 player[c1].jump_ready = 0;
1869 player[c1].jump_abort = 0;
1870 for (c2 = 0; c2 < NUM_OBJECTS; c2++) {
1871 if (objects[c2].used == 1 && objects[c2].type == OBJ_SPRING) {
1872 if (ban_map[(s2 + 15) >> 4][(s1 + 8) >> 4] == BAN_SPRING) {
1873 if ((objects[c2].x >> 20) == ((s1 + 8) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1874 objects[c2].frame = 0;
1875 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1876 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1880 if (ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
1881 if ((objects[c2].x >> 20) == (s1 >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1882 objects[c2].frame = 0;
1883 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1884 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1887 } else if (ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1888 if ((objects[c2].x >> 20) == ((s1 + 15) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1889 objects[c2].frame = 0;
1890 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1891 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1898 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1900 s1 = (player[c1].x >> 16);
1901 s2 = (player[c1].y >> 16);
1904 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) {
1905 player[c1].y = (((s2 + 16) & 0xfff0)) << 16;
1906 player[c1].y_add = 0;
1907 player[c1].anim = 0;
1908 player[c1].frame = 0;
1909 player[c1].frame_tick = 0;
1910 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1912 s1 = (player[c1].x >> 16);
1913 s2 = (player[c1].y >> 16);
1916 if (ban_map[(s2 + 8) >> 4][(s1 + 8) >> 4] == BAN_WATER) {
1917 if (player[c1].in_water == 0) {
1918 player[c1].in_water = 1;
1919 player[c1].anim = 4;
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;
1923 if (player[c1].y_add >= 32768) {
1924 add_object(OBJ_SPLASH, (player[c1].x >> 16) + 8, ((player[c1].y >> 16) & 0xfff0) + 15, 0, 0, OBJ_ANIM_SPLASH, 0);
1925 if (blood_is_thicker_than_water == 0)
1926 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1928 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 5000), 64, 0, 0, -1);
1931 player[c1].y_add -= 1536;
1932 if (player[c1].y_add < 0 && player[c1].anim != 5) {
1933 player[c1].anim = 5;
1934 player[c1].frame = 0;
1935 player[c1].frame_tick = 0;
1936 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1938 if (player[c1].y_add < -65536L)
1939 player[c1].y_add = -65536L;
1940 if (player[c1].y_add > 65535L)
1941 player[c1].y_add = 65535L;
1942 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) {
1943 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1944 player[c1].y_add = 0;
1946 } 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) {
1947 player[c1].in_water = 0;
1948 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1949 player[c1].y_add = 0;
1950 if (player[c1].anim != 0 && player[c1].anim != 1) {
1951 player[c1].anim = 0;
1952 player[c1].frame = 0;
1953 player[c1].frame_tick = 0;
1954 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1957 if (player[c1].in_water == 0) {
1958 if (bunnies_in_space == 0)
1959 player[c1].y_add += 12288;
1961 player[c1].y_add += 6144;
1962 if (player[c1].y_add > 327680L)
1963 player[c1].y_add = 327680L;
1965 player[c1].y = (player[c1].y & 0xffff0000) + 0x10000;
1966 player[c1].y_add = 0;
1968 player[c1].in_water = 0;
1970 if (player[c1].y_add > 36864 && player[c1].anim != 3 && player[c1].in_water == 0) {
1971 player[c1].anim = 3;
1972 player[c1].frame = 0;
1973 player[c1].frame_tick = 0;
1974 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1979 player[c1].frame_tick++;
1980 if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
1982 if (player[c1].frame >= player_anims[player[c1].anim].num_frames) {
1983 if (player[c1].anim != 6)
1984 player[c1].frame = player_anims[player[c1].anim].restart_frame;
1986 position_player(c1);
1988 player[c1].frame_tick = 0;
1990 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1999 void position_player(int player_num)
2008 if (ban_map[s2][s1] == BAN_VOID && (ban_map[s2 + 1][s1] == BAN_SOLID || ban_map[s2 + 1][s1] == BAN_ICE))
2011 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
2012 if (c1 != player_num && player[c1].enabled == 1) {
2013 if (abs((s1 << 4) - (player[c1].x >> 16)) < 32 && abs((s2 << 4) - (player[c1].y >> 16)) < 32)
2017 if (c1 == JNB_MAX_PLAYERS) {
2018 player[player_num].x = (long) s1 << 20;
2019 player[player_num].y = (long) s2 << 20;
2020 player[player_num].x_add = player[player_num].y_add = 0;
2021 player[player_num].direction = 0;
2022 player[player_num].jump_ready = 1;
2023 player[player_num].in_water = 0;
2024 player[player_num].anim = 0;
2025 player[player_num].frame = 0;
2026 player[player_num].frame_tick = 0;
2027 player[player_num].image = player_anims[player[player_num].anim].frame[player[player_num].frame].image;
2032 serverSendAlive(player_num);
2034 player[player_num].dead_flag = 0;
2044 void add_object(int type, int x, int y, int x_add, int y_add, int anim, int frame)
2048 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
2049 if (objects[c1].used == 0) {
2050 objects[c1].used = 1;
2051 objects[c1].type = type;
2052 objects[c1].x = (long) x << 16;
2053 objects[c1].y = (long) y << 16;
2054 objects[c1].x_add = x_add;
2055 objects[c1].y_add = y_add;
2056 objects[c1].x_acc = 0;
2057 objects[c1].y_acc = 0;
2058 objects[c1].anim = anim;
2059 objects[c1].frame = frame;
2060 objects[c1].ticks = object_anims[anim].frame[frame].ticks;
2061 objects[c1].image = object_anims[anim].frame[frame].image;
2069 void update_objects(void)
2074 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
2075 if (objects[c1].used == 1) {
2076 switch (objects[c1].type) {
2078 objects[c1].ticks--;
2079 if (objects[c1].ticks <= 0) {
2080 objects[c1].frame++;
2081 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames) {
2082 objects[c1].frame--;
2083 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2085 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2086 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2089 if (objects[c1].used == 1)
2090 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2093 objects[c1].ticks--;
2094 if (objects[c1].ticks <= 0) {
2095 objects[c1].frame++;
2096 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2097 objects[c1].used = 0;
2099 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2100 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2103 if (objects[c1].used == 1)
2104 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2107 objects[c1].x += objects[c1].x_add;
2108 objects[c1].y += objects[c1].y_add;
2109 objects[c1].ticks--;
2110 if (objects[c1].ticks <= 0) {
2111 objects[c1].frame++;
2112 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2113 objects[c1].used = 0;
2115 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2116 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2119 if (objects[c1].used == 1)
2120 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2122 case OBJ_YEL_BUTFLY:
2123 case OBJ_PINK_BUTFLY:
2124 objects[c1].x_acc += rnd(128) - 64;
2125 if (objects[c1].x_acc < -1024)
2126 objects[c1].x_acc = -1024;
2127 if (objects[c1].x_acc > 1024)
2128 objects[c1].x_acc = 1024;
2129 objects[c1].x_add += objects[c1].x_acc;
2130 if (objects[c1].x_add < -32768)
2131 objects[c1].x_add = -32768;
2132 if (objects[c1].x_add > 32768)
2133 objects[c1].x_add = 32768;
2134 objects[c1].x += objects[c1].x_add;
2135 if ((objects[c1].x >> 16) < 16) {
2136 objects[c1].x = 16 << 16;
2137 objects[c1].x_add = -objects[c1].x_add >> 2;
2138 objects[c1].x_acc = 0;
2139 } else if ((objects[c1].x >> 16) > 350) {
2140 objects[c1].x = 350 << 16;
2141 objects[c1].x_add = -objects[c1].x_add >> 2;
2142 objects[c1].x_acc = 0;
2144 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
2145 if (objects[c1].x_add < 0) {
2146 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2148 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2150 objects[c1].x_add = -objects[c1].x_add >> 2;
2151 objects[c1].x_acc = 0;
2153 objects[c1].y_acc += rnd(64) - 32;
2154 if (objects[c1].y_acc < -1024)
2155 objects[c1].y_acc = -1024;
2156 if (objects[c1].y_acc > 1024)
2157 objects[c1].y_acc = 1024;
2158 objects[c1].y_add += objects[c1].y_acc;
2159 if (objects[c1].y_add < -32768)
2160 objects[c1].y_add = -32768;
2161 if (objects[c1].y_add > 32768)
2162 objects[c1].y_add = 32768;
2163 objects[c1].y += objects[c1].y_add;
2164 if ((objects[c1].y >> 16) < 0) {
2166 objects[c1].y_add = -objects[c1].y_add >> 2;
2167 objects[c1].y_acc = 0;
2168 } else if ((objects[c1].y >> 16) > 255) {
2169 objects[c1].y = 255 << 16;
2170 objects[c1].y_add = -objects[c1].y_add >> 2;
2171 objects[c1].y_acc = 0;
2173 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
2174 if (objects[c1].y_add < 0) {
2175 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2177 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2179 objects[c1].y_add = -objects[c1].y_add >> 2;
2180 objects[c1].y_acc = 0;
2182 if (objects[c1].type == OBJ_YEL_BUTFLY) {
2183 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_LEFT) {
2184 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_LEFT;
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;
2188 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_RIGHT) {
2189 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_RIGHT;
2190 objects[c1].frame = 0;
2191 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2192 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2195 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_LEFT) {
2196 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_LEFT;
2197 objects[c1].frame = 0;
2198 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2199 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2200 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_RIGHT) {
2201 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_RIGHT;
2202 objects[c1].frame = 0;
2203 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2204 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2207 objects[c1].ticks--;
2208 if (objects[c1].ticks <= 0) {
2209 objects[c1].frame++;
2210 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2211 objects[c1].frame = object_anims[objects[c1].anim].restart_frame;
2213 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2214 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2217 if (objects[c1].used == 1)
2218 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2222 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 0);
2223 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
2224 objects[c1].y_add += 3072;
2225 if (objects[c1].y_add > 196608L)
2226 objects[c1].y_add = 196608L;
2227 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
2228 if (objects[c1].x_add < 0) {
2229 if (objects[c1].x_add < -65536L)
2230 objects[c1].x_add = -65536L;
2231 objects[c1].x_add += 1024;
2232 if (objects[c1].x_add > 0)
2233 objects[c1].x_add = 0;
2235 if (objects[c1].x_add > 65536L)
2236 objects[c1].x_add = 65536L;
2237 objects[c1].x_add -= 1024;
2238 if (objects[c1].x_add < 0)
2239 objects[c1].x_add = 0;
2241 objects[c1].y_add += 1024;
2242 if (objects[c1].y_add < -65536L)
2243 objects[c1].y_add = -65536L;
2244 if (objects[c1].y_add > 65536L)
2245 objects[c1].y_add = 65536L;
2247 objects[c1].x += objects[c1].x_add;
2248 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)) {
2249 if (objects[c1].x_add < 0) {
2250 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2251 objects[c1].x_add = -objects[c1].x_add >> 2;
2253 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2254 objects[c1].x_add = -objects[c1].x_add >> 2;
2257 objects[c1].y += objects[c1].y_add;
2258 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
2259 objects[c1].used = 0;
2260 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
2261 if (objects[c1].y_add < 0) {
2262 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
2263 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2264 objects[c1].x_add >>= 2;
2265 objects[c1].y_add = -objects[c1].y_add >> 2;
2268 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
2269 if (objects[c1].y_add > 131072L) {
2270 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2271 objects[c1].x_add >>= 2;
2272 objects[c1].y_add = -objects[c1].y_add >> 2;
2274 objects[c1].used = 0;
2275 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
2276 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2277 if (objects[c1].y_add > 131072L)
2278 objects[c1].y_add = -objects[c1].y_add >> 2;
2280 objects[c1].y_add = 0;
2284 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
2285 objects[c1].x_add = -16384;
2286 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
2287 objects[c1].x_add = 16384;
2288 if (objects[c1].used == 1) {
2289 s1 = (int)(atan2(objects[c1].y_add, objects[c1].x_add) * 4 / M_PI);
2296 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame + s1, &object_gobs);
2300 if (rnd(100) < 30) {
2301 if (objects[c1].frame == 76)
2302 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 1);
2303 else if (objects[c1].frame == 77)
2304 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 2);
2305 else if (objects[c1].frame == 78)
2306 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 3);
2308 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
2309 objects[c1].y_add += 3072;
2310 if (objects[c1].y_add > 196608L)
2311 objects[c1].y_add = 196608L;
2312 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
2313 if (objects[c1].x_add < 0) {
2314 if (objects[c1].x_add < -65536L)
2315 objects[c1].x_add = -65536L;
2316 objects[c1].x_add += 1024;
2317 if (objects[c1].x_add > 0)
2318 objects[c1].x_add = 0;
2320 if (objects[c1].x_add > 65536L)
2321 objects[c1].x_add = 65536L;
2322 objects[c1].x_add -= 1024;
2323 if (objects[c1].x_add < 0)
2324 objects[c1].x_add = 0;
2326 objects[c1].y_add += 1024;
2327 if (objects[c1].y_add < -65536L)
2328 objects[c1].y_add = -65536L;
2329 if (objects[c1].y_add > 65536L)
2330 objects[c1].y_add = 65536L;
2332 objects[c1].x += objects[c1].x_add;
2333 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)) {
2334 if (objects[c1].x_add < 0) {
2335 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2336 objects[c1].x_add = -objects[c1].x_add >> 2;
2338 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2339 objects[c1].x_add = -objects[c1].x_add >> 2;
2342 objects[c1].y += objects[c1].y_add;
2343 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
2344 objects[c1].used = 0;
2345 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
2346 if (objects[c1].y_add < 0) {
2347 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
2348 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2349 objects[c1].x_add >>= 2;
2350 objects[c1].y_add = -objects[c1].y_add >> 2;
2353 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
2354 if (objects[c1].y_add > 131072L) {
2355 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2356 objects[c1].x_add >>= 2;
2357 objects[c1].y_add = -objects[c1].y_add >> 2;
2359 if (rnd(100) < 10) {
2361 add_leftovers(0, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
2362 add_leftovers(1, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
2364 objects[c1].used = 0;
2366 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
2367 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2368 if (objects[c1].y_add > 131072L)
2369 objects[c1].y_add = -objects[c1].y_add >> 2;
2371 objects[c1].y_add = 0;
2375 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
2376 objects[c1].x_add = -16384;
2377 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
2378 objects[c1].x_add = 16384;
2379 if (objects[c1].used == 1)
2380 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame, &object_gobs);
2382 case OBJ_FLESH_TRACE:
2383 objects[c1].ticks--;
2384 if (objects[c1].ticks <= 0) {
2385 objects[c1].frame++;
2386 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2387 objects[c1].used = 0;
2389 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2390 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2393 if (objects[c1].used == 1)
2394 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2403 int add_pob(int page, int x, int y, int image, gob_t *pob_data)
2406 if (main_info.page_info[page].num_pobs >= NUM_POBS)
2409 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].x = x;
2410 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].y = y;
2411 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].image = image;
2412 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].pob_data = pob_data;
2413 main_info.page_info[page].num_pobs++;
2420 void draw_flies(int page)
2424 for (c2 = 0; c2 < NUM_FLIES; c2++) {
2425 flies[c2].back[main_info.draw_page] = get_pixel(main_info.draw_page, flies[c2].x, flies[c2].y);
2426 flies[c2].back_defined[main_info.draw_page] = 1;
2427 if (mask_pic[(flies[c2].y * JNB_WIDTH) + flies[c2].x] == 0)
2428 set_pixel(main_info.draw_page, flies[c2].x, flies[c2].y, 0);
2432 void draw_pobs(int page)
2439 for (c1 = main_info.page_info[page].num_pobs - 1; c1 >= 0; c1--) {
2440 main_info.page_info[page].pobs[c1].back_buf_ofs = back_buf_ofs;
2441 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);
2443 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;
2445 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;
2446 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);
2452 void redraw_flies_background(int page)
2456 for (c2 = NUM_FLIES - 1; c2 >= 0; c2--) {
2457 if (flies[c2].back_defined[page] == 1)
2458 set_pixel(page, flies[c2].old_draw_x, flies[c2].old_draw_y, flies[c2].back[page]);
2459 flies[c2].old_draw_x = flies[c2].x;
2460 flies[c2].old_draw_y = flies[c2].y;
2465 void redraw_pob_backgrounds(int page)
2469 for (c1 = 0; c1 < main_info.page_info[page].num_pobs; c1++)
2470 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);
2475 int add_leftovers(int page, int x, int y, int image, gob_t *pob_data)
2478 if (leftovers.page[page].num_pobs >= NUM_LEFTOVERS)
2481 leftovers.page[page].pobs[leftovers.page[page].num_pobs].x = x;
2482 leftovers.page[page].pobs[leftovers.page[page].num_pobs].y = y;
2483 leftovers.page[page].pobs[leftovers.page[page].num_pobs].image = image;
2484 leftovers.page[page].pobs[leftovers.page[page].num_pobs].pob_data = pob_data;
2485 leftovers.page[page].num_pobs++;
2492 void draw_leftovers(int page)
2496 for (c1 = leftovers.page[page].num_pobs - 1; c1 >= 0; c1--)
2497 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);
2499 leftovers.page[page].num_pobs = 0;
2504 int init_level(int level, char *pal)
2506 unsigned char *handle;
2510 if ((handle = dat_open("level.pcx", datfile_name, "rb")) == 0) {
2511 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2514 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
2515 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2519 flip_pixels(background_pic);
2520 if ((handle = dat_open("mask.pcx", datfile_name, "rb")) == 0) {
2521 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2524 if (read_pcx(handle, mask_pic, JNB_WIDTH*JNB_HEIGHT, 0) != 0) {
2525 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2529 flip_pixels(mask_pic);
2530 register_mask(mask_pic);
2532 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
2533 if (player[c1].enabled == 1) {
2534 player[c1].bumps = 0;
2535 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++)
2536 player[c1].bumped[c2] = 0;
2537 position_player(c1);
2541 for (c1 = 0; c1 < NUM_OBJECTS; c1++)
2542 objects[c1].used = 0;
2544 for (c1 = 0; c1 < 16; c1++) {
2545 for (c2 = 0; c2 < 22; c2++) {
2546 if (ban_map[c1][c2] == BAN_SPRING)
2547 add_object(OBJ_SPRING, c2 << 4, c1 << 4, 0, 0, OBJ_ANIM_SPRING, 5);
2554 if (ban_map[s2][s1] == BAN_VOID) {
2555 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2562 if (ban_map[s2][s1] == BAN_VOID) {
2563 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2570 if (ban_map[s2][s1] == BAN_VOID) {
2571 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2578 if (ban_map[s2][s1] == BAN_VOID) {
2579 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2589 void deinit_level(void)
2597 #define PATH_MAX 1024
2603 unsigned char *datafile_buffer = NULL;
2605 static void preread_datafile(const char *fname)
2611 char *gzfilename = alloca(strlen(fname) + 4);
2616 strcpy(gzfilename, fname);
2617 strcat(gzfilename, ".gz");
2619 gzf = gzopen(gzfilename, "rb");
2624 if (bufpos >= bufsize) {
2625 bufsize += 1024 * 1024;
2626 datafile_buffer = (unsigned char *) realloc(datafile_buffer, bufsize);
2627 if (datafile_buffer == NULL) {
2628 perror("realloc()");
2633 br = gzread(gzf, datafile_buffer + bufpos, bufsize - bufpos);
2635 fprintf(stderr, "gzread failed.\n");
2640 } while (!gzeof(gzf));
2642 /* try to shrink buffer... */
2643 ptr = (unsigned char *) realloc(datafile_buffer, bufpos);
2645 datafile_buffer = ptr;
2651 /* drop through and try for an uncompressed datafile... */
2654 fd = open(fname, O_RDONLY | O_BINARY);
2656 fprintf(stderr, "can't open %s:", fname);
2661 len = filelength(fd);
2662 datafile_buffer = (unsigned char *) malloc(len);
2663 if (datafile_buffer == NULL) {
2669 if (read(fd, datafile_buffer, len) != len) {
2679 int init_program(int argc, char *argv[], char *pal)
2681 char *netarg = NULL;
2682 unsigned char *handle = (unsigned char *) NULL;
2687 int player_anim_data[] = {
2688 1, 0, 0, 0x7fff, 0, 0, 0, 0, 0, 0,
2689 4, 0, 0, 4, 1, 4, 2, 4, 3, 4,
2690 1, 0, 4, 0x7fff, 0, 0, 0, 0, 0, 0,
2691 4, 2, 5, 8, 6, 10, 7, 3, 6, 3,
2692 1, 0, 6, 0x7fff, 0, 0, 0, 0, 0, 0,
2693 2, 1, 5, 8, 4, 0x7fff, 0, 0, 0, 0,
2694 1, 0, 8, 5, 0, 0, 0, 0, 0, 0
2698 memset(&net_info, 0, sizeof(net_info));
2702 if (__djgpp_nearptr_enable() == 0)
2708 if (hook_keyb_handler() != 0)
2711 memset(&main_info, 0, sizeof(main_info));
2713 strcpy(datfile_name, DATA_PATH);
2715 force2 = force3 = 0;
2718 for (c1 = 1; c1 < argc; c1++) {
2719 if (stricmp(argv[c1], "-nosound") == 0)
2720 main_info.no_sound = 1;
2721 else if (stricmp(argv[c1], "-musicnosound") == 0)
2722 main_info.music_no_sound = 1;
2723 else if (stricmp(argv[c1], "-nogore") == 0)
2724 main_info.no_gore = 1;
2725 else if (stricmp(argv[c1], "-noflies") == 0)
2727 else if (stricmp(argv[c1], "-nojoy") == 0)
2728 main_info.joy_enabled = 0;
2729 else if (stricmp(argv[c1], "-fireworks") == 0)
2730 main_info.fireworks = 1;
2732 else if (stricmp(argv[c1], "-fullscreen") == 0)
2735 else if (stricmp(argv[c1], "-scaleup") == 0)
2737 else if (stricmp(argv[c1], "-mirror") == 0)
2739 else if (stricmp(argv[c1], "-dat") == 0) {
2740 if (c1 < (argc - 1)) {
2743 if ((f = fopen(argv[c1 + 1], "rb")) != NULL) {
2745 strcpy(datfile_name, argv[c1 + 1]);
2748 } else if (stricmp(argv[c1], "-player") == 0) {
2749 if (c1 < (argc - 1)) {
2750 if (client_player_num < 0)
2751 client_player_num = atoi(argv[c1 + 1]);
2754 } else if (stricmp(argv[c1], "-server") == 0) {
2755 if (c1 < (argc - 1)) {
2758 netarg = argv[c1 + 1];
2760 } else if (stricmp(argv[c1], "-connect") == 0) {
2761 if (c1 < (argc - 1)) {
2764 netarg = argv[c1 + 1];
2767 } else if (stricmp(argv[c1], "-mouse") == 0) {
2768 if (c1 < (argc - 1)) {
2769 if (stricmp(argv[c1 + 1], "2") == 0)
2771 if (stricmp(argv[c1 + 1], "3") == 0)
2775 else if (strstr(argv[1],"-v")) {
2776 printf("jumpnbump %s compiled %s at %s with",JNB_VERSION,__DATE__,__TIME__);
2780 printf(" network support.\n");
2783 else if (strstr(argv[1],"-h")) {
2784 printf("Usage: jumpnbump [OPTION]...\n");
2786 printf(" -h this help\n");
2787 printf(" -v print version\n");
2788 printf(" -dat level.dat play a different level\n");
2790 //printf(" -port port define listen port\n");
2791 printf(" -server playercount start as server waiting for players\n");
2792 printf(" -connect host connect to server\n");
2794 printf(" -player num set main player to num (0-3). Needed for networking\n");
2795 printf(" -fireworks screensaver mode\n");
2796 printf(" -fullscreen run in fullscreen mode\n");
2797 printf(" -nosound play without sound\n");
2798 printf(" -nogore play without blood\n");
2799 printf(" -noflies disable flies\n");
2800 printf(" -mirror play with mirrored level\n");
2801 printf(" -scaleup play with doubled resolution (800x512)\n");
2802 printf(" -musicnosound play with music but without sound\n");
2809 preread_datafile(datfile_name);
2812 if (client_player_num < 0)
2813 client_player_num = 0;
2814 player[client_player_num].enabled = 1;
2817 main_info.pob_backbuf[0] = malloc(screen_pitch*screen_height*bytes_per_pixel);
2818 main_info.pob_backbuf[1] = malloc(screen_pitch*screen_height*bytes_per_pixel);
2820 for (c1 = 0; c1 < 7; c1++) {
2821 player_anims[c1].num_frames = player_anim_data[c1 * 10];
2822 player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
2823 for (c2 = 0; c2 < 4; c2++) {
2824 player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
2825 player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
2829 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
2830 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2833 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
2834 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2838 if ((handle = dat_open("rabbit.gob", datfile_name, "rb")) == 0) {
2839 strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
2842 if (register_gob(handle, &rabbit_gobs, dat_filelen("rabbit.gob", datfile_name))) {
2847 if ((handle = dat_open("objects.gob", datfile_name, "rb")) == 0) {
2848 strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
2851 if (register_gob(handle, &object_gobs, dat_filelen("objects.gob", datfile_name))) {
2856 if ((handle = dat_open("font.gob", datfile_name, "rb")) == 0) {
2857 strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
2860 if (register_gob(handle, &font_gobs, dat_filelen("font.gob", datfile_name))) {
2865 if ((handle = dat_open("numbers.gob", datfile_name, "rb")) == 0) {
2866 strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
2869 if (register_gob(handle, &number_gobs, dat_filelen("numbers.gob", datfile_name))) {
2874 if (read_level() != 0) {
2875 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2881 if (main_info.no_sound == 0) {
2883 dj_set_mixing_freq(20000);
2887 dj_set_num_sfx_channels(5);
2888 dj_set_sfx_volume(64);
2892 if ((handle = dat_open("jump.mod", datfile_name, "rb")) == 0) {
2893 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2896 if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
2897 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2901 if ((handle = dat_open("bump.mod", datfile_name, "rb")) == 0) {
2902 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2905 if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
2906 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2910 if ((handle = dat_open("scores.mod", datfile_name, "rb")) == 0) {
2911 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2914 if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
2915 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2919 if ((handle = dat_open("jump.smp", datfile_name, "rb")) == 0) {
2920 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2923 if (dj_load_sfx(handle, 0, dat_filelen("jump.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
2924 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2928 if ((handle = dat_open("death.smp", datfile_name, "rb")) == 0) {
2929 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2932 if (dj_load_sfx(handle, 0, dat_filelen("death.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
2933 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2937 if ((handle = dat_open("spring.smp", datfile_name, "rb")) == 0) {
2938 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2941 if (dj_load_sfx(handle, 0, dat_filelen("spring.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
2942 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2946 if ((handle = dat_open("splash.smp", datfile_name, "rb")) == 0) {
2947 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2950 if (dj_load_sfx(handle, 0, dat_filelen("splash.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
2951 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2955 if ((handle = dat_open("fly.smp", datfile_name, "rb")) == 0) {
2956 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2959 if (dj_load_sfx(handle, 0, dat_filelen("fly.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
2960 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2964 dj_get_sfx_settings(SFX_FLY, &fly);
2966 fly.default_freq = SFX_FLY_FREQ;
2969 fly.loop_length = fly.length;
2970 dj_set_sfx_settings(SFX_FLY, &fly);
2973 if ((background_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
2975 if ((mask_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
2977 memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
2978 register_mask(mask_pic);
2980 for (c1 = 0; c1 < 16; c1++) { // fix dark font
2981 pal[(240 + c1) * 3 + 0] = c1 << 2;
2982 pal[(240 + c1) * 3 + 1] = c1 << 2;
2983 pal[(240 + c1) * 3 + 2] = c1 << 2;
2986 setpalette(0, 256, pal);
2990 recalculate_gob(&font_gobs, pal);
2992 if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
2994 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2995 put_text(0, 200, 100, "Move the joystick to the", 2);
2996 put_text(0, 200, 115, "UPPER LEFT", 2);
2997 put_text(0, 200, 130, "and press button A", 2);
2998 put_text(0, 200, 200, "Or press ESC to use", 2);
2999 put_text(0, 200, 215, "previous settings", 2);
3000 if (calib_joy(0) != 0)
3003 register_background(NULL, NULL);
3005 main_info.view_page = 1;
3010 put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
3011 put_text(1, 200, 100, "Move the joystick to the", 2);
3012 put_text(1, 200, 115, "LOWER RIGHT", 2);
3013 put_text(1, 200, 130, "and press button A", 2);
3014 put_text(1, 200, 200, "Or press ESC to use", 2);
3015 put_text(1, 200, 215, "previous settings", 2);
3016 if (calib_joy(1) != 0)
3019 register_background(NULL, NULL);
3024 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
3025 put_text(0, 200, 100, "Move the joystick to the", 2);
3026 put_text(0, 200, 115, "CENTER", 2);
3027 put_text(0, 200, 130, "and press button A", 2);
3028 put_text(0, 200, 200, "Or press ESC to use", 2);
3029 put_text(0, 200, 215, "previous settings", 2);
3030 if (calib_joy(2) != 0)
3033 if (joy.calib_data.x1 == joy.calib_data.x2)
3034 joy.calib_data.x1 -= 10;
3035 if (joy.calib_data.x3 == joy.calib_data.x2)
3036 joy.calib_data.x3 += 10;
3037 if (joy.calib_data.y1 == joy.calib_data.y2)
3038 joy.calib_data.y1 -= 10;
3039 if (joy.calib_data.y3 == joy.calib_data.y2)
3040 joy.calib_data.y3 += 10;
3045 if (load_flag == 1) {
3046 if ((handle = dat_open("calib.dat", datfile_name, "rb")) == 0) {
3047 strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
3050 joy.calib_data.x1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3051 joy.calib_data.x2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3052 joy.calib_data.x3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3053 joy.calib_data.y1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3054 joy.calib_data.y2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3055 joy.calib_data.y3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3062 init_server(netarg);
3064 connect_to_server(netarg);
3073 void deinit_program(void)
3080 dj_free_mod(MOD_MENU);
3081 dj_free_mod(MOD_GAME);
3082 dj_free_sfx(SFX_DEATH);
3083 dj_free_sfx(SFX_SPRING);
3084 dj_free_sfx(SFX_SPLASH);
3087 if (background_pic != 0)
3088 free(background_pic);
3092 remove_keyb_handler();
3096 __dpmi_int(0x10, ®s);
3099 if (main_info.error_str[0] != 0) {
3100 printf(main_info.error_str);
3102 MessageBox(0, main_info.error_str, "Jump'n'Bump", 0);
3111 unsigned short rnd(unsigned short max)
3113 return (rand() % max);
3117 int read_level(void)
3119 unsigned char *handle;
3123 if ((handle = dat_open("levelmap.txt", datfile_name, "rb")) == 0) {
3124 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
3128 for (c1 = 0; c1 < 16; c1++) {
3129 for (c2 = 0; c2 < 22; c2++) {
3131 chr = (int) *(handle++);
3132 if (chr >= '0' && chr <= '4')
3136 ban_map[c1][21-c2] = chr - '0';
3138 ban_map[c1][c2] = chr - '0';
3142 for (c2 = 0; c2 < 22; c2++)
3143 ban_map[16][c2] = BAN_SOLID;
3150 unsigned char *dat_open(char *file_name, char *dat_name, char *mode)
3158 if (datafile_buffer == NULL)
3161 memset(name, 0, sizeof(name));
3163 num = ( (datafile_buffer[0] << 0) +
3164 (datafile_buffer[1] << 8) +
3165 (datafile_buffer[2] << 16) +
3166 (datafile_buffer[3] << 24) );
3168 ptr = datafile_buffer + 4;
3170 for (c1 = 0; c1 < num; c1++) {
3172 memcpy(name, ptr, 12);
3175 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
3176 ofs = ( (ptr[0] << 0) +
3181 return (datafile_buffer + ofs);
3190 int dat_filelen(char *file_name, char *dat_name)
3198 memset(name, 0, sizeof(name));
3200 num = ( (datafile_buffer[0] << 0) +
3201 (datafile_buffer[1] << 8) +
3202 (datafile_buffer[2] << 16) +
3203 (datafile_buffer[3] << 24) );
3205 ptr = datafile_buffer + 4;
3207 for (c1 = 0; c1 < num; c1++) {
3209 memcpy(name, ptr, 12);
3212 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
3215 len = ( (ptr[0] << 0) +
3229 void write_calib_data(void)
3237 if ((handle = fopen(datfile_name, "rb")) == NULL)
3239 len = filelength(fileno(handle));
3240 if ((mem = malloc(len)) == NULL)
3242 fread(mem, 1, len, handle);
3246 num = *(int *) (&mem[0]);
3247 for (c1 = 0; c1 < num; c1++) {
3248 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
3249 ofs = *(int *) (&mem[ofs + 12]);
3255 mem[ofs] = joy.calib_data.x1 & 0xff;
3256 mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
3257 mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
3258 mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
3259 mem[ofs + 4] = joy.calib_data.x2 & 0xff;
3260 mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
3261 mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
3262 mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
3263 mem[ofs + 8] = joy.calib_data.x3 & 0xff;
3264 mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
3265 mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
3266 mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
3267 mem[ofs + 12] = joy.calib_data.y1 & 0xff;
3268 mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
3269 mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
3270 mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
3271 mem[ofs + 16] = joy.calib_data.y2 & 0xff;
3272 mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
3273 mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
3274 mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
3275 mem[ofs + 20] = joy.calib_data.y3 & 0xff;
3276 mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
3277 mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
3278 mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
3280 if ((handle = fopen(datfile_name, "wb")) == NULL)
3282 fwrite(mem, 1, len, handle);