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
41 #define M_PI 3.14159265358979323846
44 gob_t rabbit_gobs = { 0 };
45 gob_t font_gobs = { 0 };
46 gob_t object_gobs = { 0 };
47 gob_t number_gobs = { 0 };
49 main_info_t main_info;
50 player_t player[JNB_MAX_PLAYERS];
51 player_anim_t player_anims[7];
52 object_t objects[NUM_OBJECTS];
56 char datfile_name[2048];
62 unsigned int ban_map[17][22] = {
63 {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
64 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0},
65 {1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
66 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1},
67 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
68 {1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
69 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1},
70 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
71 {1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
72 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1},
73 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1},
74 {1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1},
75 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
76 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
77 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 1, 3, 3, 3, 1, 1, 1},
78 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
79 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
205 int flies_enabled = 1;
210 int old_draw_x, old_draw_y;
222 } pobs[NUM_LEFTOVERS];
226 int pogostick, bunnies_in_space, jetpack, lord_of_the_flies, blood_is_thicker_than_water;
230 int filelength(int handle)
234 if (fstat(handle, &buf) == -1) {
235 perror("filelength");
244 /* networking shite. */
246 int client_player_num = -1;
251 TCPsocket sock = NULL;
252 SDLNet_SocketSet socketset = NULL;
258 SDLNet_SocketSet socketset;
261 NetInfo net_info[JNB_MAX_PLAYERS];
273 #define NETPKTBUFSIZE (4 + 4 + 4 + 4 + 4)
275 #define NETCMD_NACK (0xF00DF00D + 0)
276 #define NETCMD_ACK (0xF00DF00D + 1)
277 #define NETCMD_HELLO (0xF00DF00D + 2)
278 #define NETCMD_GREENLIGHT (0xF00DF00D + 3)
279 #define NETCMD_MOVE (0xF00DF00D + 4)
280 #define NETCMD_BYE (0xF00DF00D + 5)
281 #define NETCMD_POSITION (0xF00DF00D + 6)
282 #define NETCMD_ALIVE (0xF00DF00D + 7)
283 #define NETCMD_KILL (0xF00DF00D + 8)
287 void bufToPacket(const char *buf, NetPacket *pkt)
289 SDLNet_Write32(*((unsigned long *) (buf + 0)), &pkt->cmd);
290 SDLNet_Write32(*((unsigned long *) (buf + 4)), &pkt->arg);
291 SDLNet_Write32(*((unsigned long *) (buf + 8)), &pkt->arg2);
292 SDLNet_Write32(*((unsigned long *) (buf + 12)), &pkt->arg3);
293 SDLNet_Write32(*((unsigned long *) (buf + 16)), &pkt->arg4);
295 pkt->cmd = ntohl(*((unsigned long *) (buf + 0)));
296 pkt->arg = (long) ntohl(*((unsigned long *) (buf + 4)));
297 pkt->arg2 = (long) ntohl(*((unsigned long *) (buf + 8)));
298 pkt->arg3 = (long) ntohl(*((unsigned long *) (buf + 12)));
299 pkt->arg4 = (long) ntohl(*((unsigned long *) (buf + 16)));
304 void packetToBuf(const NetPacket *pkt, char *buf)
306 *((unsigned long *) (buf + 0)) = SDLNet_Read32(&pkt->cmd);
307 *((unsigned long *) (buf + 4)) = SDLNet_Read32(&pkt->arg);
308 *((unsigned long *) (buf + 8)) = SDLNet_Read32(&pkt->arg2);
309 *((unsigned long *) (buf + 12)) = SDLNet_Read32(&pkt->arg3);
310 *((unsigned long *) (buf + 16)) = SDLNet_Read32(&pkt->arg4);
312 *((unsigned long *) (buf + 0)) = htonl(pkt->cmd);
313 *((unsigned long *) (buf + 4)) = htonl((unsigned long) pkt->arg);
314 *((unsigned long *) (buf + 8)) = htonl((unsigned long) pkt->arg2);
315 *((unsigned long *) (buf + 12)) = htonl((unsigned long) pkt->arg3);
316 *((unsigned long *) (buf + 16)) = htonl((unsigned long) pkt->arg4);
321 void sendPacketToSock(TCPsocket s, NetPacket *pkt)
323 int bytes_left = NETPKTBUFSIZE;
325 char buf[NETPKTBUFSIZE];
328 packetToBuf(pkt, buf);
329 while (bytes_left > 0) {
330 bw = SDLNet_TCP_Send(s, ptr, bytes_left);
332 fprintf(stderr, "SERVER: SDLNet_TCP_Send(): %s\n", SDLNet_GetError());
335 } else if (bw == 0) {
345 void sendPacket(int playerid, NetPacket *pkt)
347 if ( playerid < JNB_MAX_PLAYERS ) {
348 if ((player[playerid].enabled) && (playerid != client_player_num)) {
349 sendPacketToSock(net_info[playerid].sock, pkt);
355 void sendPacketToAll(NetPacket *pkt)
359 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
365 int grabPacket(TCPsocket s, SDLNet_SocketSet ss, NetPacket *pkt)
367 static char buf[NETPKTBUFSIZE];
368 static int buf_count = 0;
372 if (SDLNet_CheckSockets(ss, 0) > 0) {
373 rc = SDLNet_TCP_Recv(s, &buf[buf_count], NETPKTBUFSIZE - buf_count);
374 if (rc <= 0) { /* closed connection? */
376 } else if (rc != NETPKTBUFSIZE) {
380 bufToPacket(buf, pkt);
389 int serverRecvPacket(NetPacket *pkt)
396 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
397 TCPsocket s = net_info[i].sock;
399 if ((i == client_player_num) || (!player[i].enabled))
402 rc = grabPacket(s, net_info[i].socketset, pkt);
406 player[i].enabled = 0;
408 pkt.cmd = NETCMD_BYE;
413 sendPacketToAll(&pkt);
415 return(i); /* it's all good. */
419 return(-1); /* no packets available currently. */
423 void wait_for_greenlight(void)
428 printf("CLIENT: Waiting for greenlight...\n");
432 while ((rc = grabPacket(sock, socketset, &pkt)) == 0) {
433 SDL_Delay(100); /* nap and then try again. */
437 printf("CLIENT: Lost connection.\n");
438 SDLNet_TCP_Close(sock);
441 } while (pkt.cmd != NETCMD_GREENLIGHT);
443 printf("CLIENT: Got greenlight.\n");
445 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
446 if (pkt.arg & (1 << i)) {
447 printf("CLIENT: There is a player #%d.\n", i);
448 player[i].enabled = 1;
454 static int buggered_off = 0;
457 void tellServerGoodbye(void)
463 pkt.cmd = NETCMD_BYE;
464 pkt.arg = client_player_num;
468 sendPacketToSock(sock, &pkt);
474 void processMovePacket(NetPacket *pkt)
476 int playerid = pkt->arg;
477 int movetype = ((pkt->arg2 >> 16) & 0xFF);
478 int newval = ((pkt->arg2 >> 0) & 0xFF);
480 if (movetype == MOVEMENT_LEFT) {
481 player[playerid].action_left = newval;
482 } else if (movetype == MOVEMENT_RIGHT) {
483 player[playerid].action_right = newval;
484 } else if (movetype == MOVEMENT_UP) {
485 player[playerid].action_up = newval;
487 printf("bogus MOVE packet!\n");
490 player[playerid].x = pkt->arg3;
491 player[playerid].y = pkt->arg4;
495 void tellServerPlayerMoved(int playerid, int movement_type, int newval)
499 pkt.cmd = NETCMD_MOVE;
501 pkt.arg2 = ( ((movement_type & 0xFF) << 16) | ((newval & 0xFF) << 0) );
502 pkt.arg3 = player[playerid].x;
503 pkt.arg4 = player[playerid].y;
506 processMovePacket(&pkt);
509 sendPacketToAll(&pkt);
511 sendPacketToSock(sock, &pkt);
518 void tellServerNewPosition(void)
521 pkt.cmd = NETCMD_POSITION;
522 pkt.arg = client_player_num;
523 pkt.arg2 = player[client_player_num].x;
524 pkt.arg3 = player[client_player_num].y;
527 sendPacketToAll(&pkt);
529 sendPacketToSock(sock, &pkt);
535 void processKillPacket(NetPacket *pkt)
544 player[c1].y_add = -player[c1].y_add;
545 if (player[c1].y_add > -262144L)
546 player[c1].y_add = -262144L;
547 player[c1].jump_abort = 1;
548 player[c2].dead_flag = 1;
549 if (player[c2].anim != 6) {
551 player[c2].frame = 0;
552 player[c2].frame_tick = 0;
553 player[c2].image = player_anims[player[c2].anim].frame[player[c2].frame].image + player[c2].direction * 9;
554 if (main_info.no_gore == 0) {
555 for (c4 = 0; c4 < 6; c4++)
556 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);
557 for (c4 = 0; c4 < 6; c4++)
558 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 76);
559 for (c4 = 0; c4 < 6; c4++)
560 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 77);
561 for (c4 = 0; c4 < 8; c4++)
562 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 78);
563 for (c4 = 0; c4 < 10; c4++)
564 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 79);
566 dj_play_sfx(SFX_DEATH, (unsigned short)(SFX_DEATH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
568 player[c1].bumped[c2]++;
569 s1 = player[c1].bumps % 100;
570 add_leftovers(0, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
571 add_leftovers(1, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
572 add_leftovers(0, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
573 add_leftovers(1, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
579 void processPositionPacket(NetPacket *pkt)
581 int playerid = pkt->arg;
583 player[playerid].x = pkt->arg2;
584 player[playerid].y = pkt->arg3;
588 void processAlivePacket(NetPacket *pkt)
590 int playerid = pkt->arg;
592 player[playerid].dead_flag = 0;
593 player[playerid].x = pkt->arg2;
594 player[playerid].y = pkt->arg3;
598 void serverTellEveryoneGoodbye(void)
604 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
605 if (player[i].enabled) {
608 pkt.cmd = NETCMD_BYE;
613 sendPacketToAll(&pkt);
620 int server_said_bye = 0;
623 int update_players_from_server(void)
630 while ((rc = grabPacket(sock, socketset, &pkt)) != 0) {
632 printf("CLIENT: Lost connection.\n");
633 pkt.cmd = NETCMD_BYE;
634 pkt.arg = client_player_num;
637 if (pkt.cmd == NETCMD_BYE) {
638 if (pkt.arg == client_player_num) {
639 SDLNet_FreeSocketSet(socketset);
640 SDLNet_TCP_Close(sock);
645 player[pkt.arg].enabled = 0;
647 } else if (pkt.cmd == NETCMD_MOVE) {
648 processMovePacket(&pkt);
649 } else if (pkt.cmd == NETCMD_ALIVE) {
650 processAlivePacket(&pkt);
651 } else if (pkt.cmd == NETCMD_POSITION) {
652 processPositionPacket(&pkt);
653 } else if (pkt.cmd == NETCMD_KILL) {
654 processKillPacket(&pkt);
656 printf("CLIENT: Got an unknown packet: 0x%lX.\n", pkt.cmd);
664 void serverSendAlive(int playerid)
669 pkt.cmd = NETCMD_ALIVE;
671 pkt.arg2 = player[playerid].x;
672 pkt.arg3 = player[playerid].y;
673 sendPacketToAll(&pkt);
678 void serverSendKillPacket(int killer, int victim)
683 pkt.cmd = NETCMD_KILL;
686 pkt.arg3 = player[victim].x;
687 pkt.arg4 = player[victim].y;
688 processKillPacket(&pkt);
691 sendPacketToAll(&pkt);
697 void update_players_from_clients(void)
705 while ((playerid = serverRecvPacket(&pkt)) >= 0) {
706 if (pkt.cmd == NETCMD_BYE) {
707 pkt.arg = playerid; /* just in case. */
708 sendPacketToAll(&pkt);
709 player[playerid].enabled = 0;
710 SDLNet_FreeSocketSet(net_info[playerid].socketset);
711 SDLNet_TCP_Close(net_info[playerid].sock);
712 } else if (pkt.cmd == NETCMD_POSITION) {
713 pkt.arg = playerid; /* just in case. */
714 processPositionPacket(&pkt);
715 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
720 } else if (pkt.cmd == NETCMD_MOVE) {
721 pkt.arg = playerid; /* just in case. */
723 pkt.arg3 = player[playerid].x;
724 pkt.arg4 = player[playerid].y;
726 processMovePacket(&pkt);
727 sendPacketToAll(&pkt);
729 printf("SERVER: Got unknown packet (0x%lX).\n", pkt.cmd);
735 void init_server(const char *netarg)
740 int wait_for_clients = ((netarg == NULL) ? 0 : atoi(netarg));
743 if ((wait_for_clients > (JNB_MAX_PLAYERS - 1)) || (wait_for_clients < 0)) {
744 printf("SERVER: Waiting for bogus client count (%d).\n", wait_for_clients);
748 if (SDLNet_Init() < 0) {
753 SDLNet_ResolveHost(&addr, NULL, JNB_INETPORT);
754 ipstr = SDLNet_ResolveIP(&addr);
755 SDLNet_ResolveHost(&addr, ipstr, JNB_INETPORT);
756 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);
757 net_info[client_player_num].addr = addr;
759 addr.host = INADDR_ANY;
760 sock = SDLNet_TCP_Open(&addr);
762 fprintf(stderr, "SERVER: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
766 player[client_player_num].enabled = 1;
768 printf("SERVER: waiting for (%d) clients...\n", wait_for_clients);
770 socketset = SDLNet_AllocSocketSet(JNB_MAX_PLAYERS + 1);
771 SDLNet_TCP_AddSocket(socketset, sock);
773 while (wait_for_clients > 0)
775 char buf[NETPKTBUFSIZE];
781 /* Wait for events */
782 SDLNet_CheckSockets(socketset, ~0);
783 if ( SDLNet_SocketReady(sock) ) {
784 s = SDLNet_TCP_Accept(sock);
788 fprintf(stderr, "SERVER: SDLNet_TCP_Accept(): %s", SDLNet_GetError());
789 SDLNet_TCP_Close(sock);
795 br = SDLNet_TCP_Recv(s, buf, NETPKTBUFSIZE);
797 fprintf(stderr, "SERVER: SDLNet_TCP_Recv(): %s\n", SDLNet_GetError());
799 SDLNet_TCP_Close(sock);
803 from = SDLNet_TCP_GetPeerAddress(s);
804 ipstr = SDLNet_ResolveIP(from);
805 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);
807 if (br != NETPKTBUFSIZE) {
808 printf("SERVER: Bogus packet.\n");
812 bufToPacket(buf, &pkt);
813 if (pkt.cmd != NETCMD_HELLO) {
814 printf("SERVER: Bogus packet.\n");
818 printf("SERVER: Client claims to be player #%ld.\n", pkt.arg);
820 if (pkt.arg > JNB_MAX_PLAYERS) {
821 printf("SERVER: (that's an invalid player number.)\n");
823 if (player[pkt.arg].enabled) {
824 printf("SERVER: (that player number is already taken.)\n");
831 printf("SERVER: Forbidding connection.\n");
832 pkt.cmd = NETCMD_NACK;
833 sendPacketToSock(s, &pkt);
836 player[pkt.arg].enabled = 1;
837 net_info[pkt.arg].sock = s;
838 net_info[pkt.arg].addr = *from;
839 net_info[pkt.arg].socketset = SDLNet_AllocSocketSet(1);
840 SDLNet_TCP_AddSocket(net_info[pkt.arg].socketset, net_info[pkt.arg].sock);
842 printf("SERVER: Granting connection. (%d) to go.\n", wait_for_clients);
843 pkt.cmd = NETCMD_ACK;
844 sendPacket(pkt.arg, &pkt);
848 SDLNet_TCP_Close(sock); /* done with the listen socket. */
849 SDLNet_FreeSocketSet(socketset);
853 printf("SERVER: Got all our connections. Greenlighting clients...\n");
855 pkt.cmd = NETCMD_GREENLIGHT;
857 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
858 if (player[i].enabled) {
862 sendPacketToAll(&pkt);
866 void connect_to_server(char *netarg)
869 char buf[NETPKTBUFSIZE];
875 if (netarg == NULL) {
876 printf("CLIENT: Need to specify host to connect to.\n");
880 if (SDLNet_Init() < 0) {
885 player[client_player_num].enabled = 1;
887 SDLNet_ResolveHost(&addr, NULL, JNB_INETPORT);
888 ipstr = SDLNet_ResolveIP(&addr);
889 SDLNet_ResolveHost(&addr, ipstr, JNB_INETPORT);
890 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);
891 net_info[client_player_num].addr = addr;
893 if (SDLNet_ResolveHost(&hent, netarg, JNB_INETPORT) < 0) {
894 fprintf(stderr, "CLIENT: couldn't find host: %s\n", SDLNet_GetError());
898 sock = SDLNet_TCP_Open(&hent);
900 fprintf(stderr, "CLIENT: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
904 socketset = SDLNet_AllocSocketSet(1);
905 SDLNet_TCP_AddSocket(socketset, sock);
907 printf("CLIENT: connected to %s...\n", SDLNet_ResolveIP(&hent));
909 printf("CLIENT: Sending HELLO packet...\n");
910 pkt.cmd = NETCMD_HELLO;
911 pkt.arg = client_player_num;
912 sendPacketToSock(sock, &pkt);
914 printf("CLIENT: Waiting for ACK from server...\n");
916 br = SDLNet_TCP_Recv(sock, buf, NETPKTBUFSIZE);
918 fprintf(stderr, "CLIENT: recv(): %s\n", SDLNet_GetError());
919 SDLNet_FreeSocketSet(socketset);
920 SDLNet_TCP_Close(sock);
924 if (br != NETPKTBUFSIZE) {
925 printf("CLIENT: Bogus packet size (%d of %d). FIXME.\n", br, NETPKTBUFSIZE);
926 SDLNet_FreeSocketSet(socketset);
927 SDLNet_TCP_Close(sock);
931 bufToPacket(buf, &pkt);
933 if (pkt.cmd == NETCMD_NACK) {
934 printf("CLIENT: Server forbid us from playing.\n");
935 SDLNet_FreeSocketSet(socketset);
936 SDLNet_TCP_Close(sock);
940 if (pkt.cmd != NETCMD_ACK) {
941 printf("CLIENT: Unexpected packet (cmd=0x%lX).\n", pkt.cmd);
942 SDLNet_FreeSocketSet(socketset);
943 SDLNet_TCP_Close(sock);
947 printf("CLIENT: Server accepted our connection.\n");
949 wait_for_greenlight();
954 static void flip_pixels(unsigned char *pixels)
960 for (y = 0; y < JNB_HEIGHT; y++) {
961 for (x = 0; x < (352/2); x++) {
962 temp = pixels[y*JNB_WIDTH+x];
963 pixels[y*JNB_WIDTH+x] = pixels[y*JNB_WIDTH+(352-x)-1];
964 pixels[y*JNB_WIDTH+(352-x)-1] = temp;
970 int main(int argc, char *argv[])
972 unsigned char *handle;
973 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
976 int closest_player = 0, dist, cur_dist = 0;
977 int end_loop_flag = 0, fade_flag = 0;
978 int mod_vol, sfx_vol, mod_fade_direction;
984 if (init_program(argc, argv, pal) != 0)
987 if (main_info.fireworks == 1) {
998 if (key_pressed(1) == 1) {
1001 if (init_level(0, pal) != 0) {
1006 memset(cur_pal, 0, 768);
1007 setpalette(0, 256, cur_pal);
1009 recalculate_gob(&rabbit_gobs, pal);
1010 recalculate_gob(&object_gobs, pal);
1011 recalculate_gob(&number_gobs, pal);
1014 register_background(background_pic, pal);
1017 if (flies_enabled) {
1021 for (c1 = 0; c1 < NUM_FLIES; c1++) {
1023 flies[c1].x = s1 + rnd(101) - 50;
1024 flies[c1].y = s2 + rnd(101) - 50;
1025 if (ban_map[flies[c1].y >> 4][flies[c1].x >> 4] == BAN_VOID)
1028 flies[c1].back_defined[0] = 0;
1029 flies[c1].back_defined[1] = 0;
1033 mod_vol = sfx_vol = 10;
1034 mod_fade_direction = 1;
1035 dj_ready_mod(MOD_GAME);
1036 dj_set_mod_volume((char)mod_vol);
1037 dj_set_sfx_volume((char)mod_vol);
1041 dj_play_sfx(SFX_FLY, SFX_FLY_FREQ, 0, 0, 0, 4);
1045 lord_of_the_flies = bunnies_in_space = jetpack = pogostick = blood_is_thicker_than_water = 0;
1047 main_info.page_info[0].num_pobs = 0;
1048 main_info.page_info[1].num_pobs = 0;
1049 main_info.view_page = 0;
1050 main_info.draw_page = 1;
1054 while (update_count) {
1056 if (key_pressed(1) == 1) {
1060 serverTellEveryoneGoodbye();
1062 tellServerGoodbye();
1067 memset(pal, 0, 768);
1068 mod_fade_direction = 0;
1071 if (strncmp(last_keys, "kcitsogop", strlen("kcitsogop")) == 0) {
1075 if (strncmp(last_keys, "ecapsniseinnub", strlen("ecapsniseinnub")) == 0) {
1076 bunnies_in_space ^= 1;
1079 if (strncmp(last_keys, "kcaptej", strlen("kcaptej")) == 0) {
1083 if (strncmp(last_keys, "seilfehtfodrol", strlen("seilfehtfodrol")) == 0) {
1084 lord_of_the_flies ^= 1;
1087 if (strncmp(last_keys, "retawnahtrekcihtsidoolb", strlen("retawnahtrekcihtsidoolb")) == 0) {
1088 blood_is_thicker_than_water ^= 1;
1089 if (blood_is_thicker_than_water == 1) {
1140 register_background(background_pic, pal);
1141 recalculate_gob(&object_gobs, pal);
1148 update_players_from_clients();
1150 if (!update_players_from_server()) {
1151 break; /* got a BYE packet */
1161 for (c3 = 0; c3 < 6; c3++) {
1165 } else if (c3 == 1) {
1168 } else if (c3 == 2) {
1171 } else if (c3 == 3) {
1174 } else if (c3 == 4) {
1177 } else if (c3 == 5) {
1181 if (player[c1].enabled == 1 && player[c2].enabled == 1) {
1182 if (labs(player[c1].x - player[c2].x) < (12L << 16) && labs(player[c1].y - player[c2].y) < (12L << 16)) {
1183 if ((labs(player[c1].y - player[c2].y) >> 16) > 5) {
1184 if (player[c1].y < player[c2].y) {
1185 if (player[c1].y_add >= 0) {
1187 serverSendKillPacket(c1, c2);
1189 if (player[c2].y_add < 0)
1190 player[c2].y_add = 0;
1193 if (player[c2].y_add >= 0) {
1195 serverSendKillPacket(c2, c1);
1197 if (player[c1].y_add < 0)
1198 player[c1].y_add = 0;
1202 if (player[c1].x < player[c2].x) {
1203 if (player[c1].x_add > 0)
1204 player[c1].x = player[c2].x - (12L << 16);
1205 else if (player[c2].x_add < 0)
1206 player[c2].x = player[c1].x + (12L << 16);
1208 player[c1].x -= player[c1].x_add;
1209 player[c2].x -= player[c2].x_add;
1211 l1 = player[c2].x_add;
1212 player[c2].x_add = player[c1].x_add;
1213 player[c1].x_add = l1;
1214 if (player[c1].x_add > 0)
1215 player[c1].x_add = -player[c1].x_add;
1216 if (player[c2].x_add < 0)
1217 player[c2].x_add = -player[c2].x_add;
1219 if (player[c1].x_add > 0)
1220 player[c2].x = player[c1].x - (12L << 16);
1221 else if (player[c2].x_add < 0)
1222 player[c1].x = player[c2].x + (12L << 16);
1224 player[c1].x -= player[c1].x_add;
1225 player[c2].x -= player[c2].x_add;
1227 l1 = player[c2].x_add;
1228 player[c2].x_add = player[c1].x_add;
1229 player[c1].x_add = l1;
1230 if (player[c1].x_add < 0)
1231 player[c1].x_add = -player[c1].x_add;
1232 if (player[c2].x_add > 0)
1233 player[c2].x_add = -player[c2].x_add;
1242 main_info.page_info[main_info.draw_page].num_pobs = 0;
1243 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1244 if (player[c1].enabled == 1)
1245 main_info.page_info[main_info.draw_page].num_pobs++;
1252 if (flies_enabled) {
1253 /* get center of fly swarm */
1255 for (c1 = 0; c1 < NUM_FLIES; c1++) {
1262 if (update_count == 1) {
1263 /* get closest player to fly swarm */
1265 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1266 if (player[c1].enabled == 1) {
1267 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)));
1268 if (cur_dist < dist) {
1269 closest_player = c1;
1274 /* update fly swarm sound */
1278 dj_set_sfx_channel_volume(4, (char)(s3));
1281 for (c1 = 0; c1 < NUM_FLIES; c1++) {
1282 /* get closest player to fly */
1284 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
1285 if (player[c2].enabled == 1) {
1286 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)));
1287 if (cur_dist < dist) {
1288 closest_player = c2;
1293 flies[c1].old_x = flies[c1].x;
1294 flies[c1].old_y = flies[c1].y;
1296 if ((s1 - flies[c1].x) > 30)
1298 else if ((s1 - flies[c1].x) < -30)
1301 if (((player[closest_player].x >> 16) + 8) > flies[c1].x) {
1302 if (lord_of_the_flies == 0)
1307 if (lord_of_the_flies == 0)
1313 s4 = rnd(3) - 1 + s3;
1314 if ((flies[c1].x + s4) < 16)
1316 if ((flies[c1].x + s4) > 351)
1318 if (ban_map[flies[c1].y >> 4][(flies[c1].x + s4) >> 4] != BAN_VOID)
1322 if ((s2 - flies[c1].y) > 30)
1324 else if ((s2 - flies[c1].y) < -30)
1327 if (((player[closest_player].y >> 16) + 8) > flies[c1].y) {
1328 if (lord_of_the_flies == 0)
1333 if (lord_of_the_flies == 0)
1339 s4 = rnd(3) - 1 + s3;
1340 if ((flies[c1].y + s4) < 0)
1342 if ((flies[c1].y + s4) > 239)
1344 if (ban_map[(flies[c1].y + s4) >> 4][flies[c1].x >> 4] != BAN_VOID)
1353 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1354 if (player[c1].enabled == 1) {
1355 main_info.page_info[main_info.draw_page].pobs[s1].x = player[c1].x >> 16;
1356 main_info.page_info[main_info.draw_page].pobs[s1].y = player[c1].y >> 16;
1357 main_info.page_info[main_info.draw_page].pobs[s1].image = player[c1].image + c1 * 18;
1358 main_info.page_info[main_info.draw_page].pobs[s1].pob_data = &rabbit_gobs;
1363 if (update_count == 1) {
1366 draw_pobs(main_info.draw_page);
1371 draw_flies(main_info.draw_page);
1376 if (mod_fade_direction == 1) {
1379 dj_set_mod_volume((char)mod_vol);
1384 dj_set_mod_volume((char)mod_vol);
1388 if (mod_fade_direction == 1) {
1391 dj_set_sfx_volume((char)sfx_vol);
1396 dj_set_sfx_volume((char)sfx_vol);
1401 for (c1 = 0; c1 < 768; c1++) {
1402 if (cur_pal[c1] < pal[c1]) {
1405 } else if (cur_pal[c1] > pal[c1]) {
1410 if (fade_flag == 0 && end_loop_flag == 1)
1413 if (update_count == 1) {
1414 main_info.draw_page ^= 1;
1415 main_info.view_page ^= 1;
1417 flippage(main_info.view_page);
1423 setpalette(0, 256, cur_pal);
1425 if (update_count == 1) {
1429 redraw_flies_background(main_info.draw_page);
1431 redraw_pob_backgrounds(main_info.draw_page);
1433 draw_leftovers(main_info.draw_page);
1443 if ( (player[client_player_num].dead_flag == 0) &&
1445 (player[client_player_num].action_left) ||
1446 (player[client_player_num].action_right) ||
1447 (player[client_player_num].action_up) ||
1448 (player[client_player_num].jump_ready == 0)
1451 tellServerNewPosition();
1456 update_count = intr_sysupdate();
1460 if ((server_said_bye) || ((fade_flag == 0) && (end_loop_flag == 1)))
1464 if ((fade_flag == 0) && (end_loop_flag == 1))
1471 serverTellEveryoneGoodbye();
1472 SDLNet_TCP_Close(sock);
1475 if (!server_said_bye) {
1476 tellServerGoodbye();
1479 SDLNet_TCP_Close(sock);
1485 main_info.view_page = 0;
1486 main_info.draw_page = 1;
1488 dj_stop_sfx_channel(4);
1492 memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
1493 register_mask(mask_pic);
1495 register_background(NULL, NULL);
1499 put_text(main_info.view_page, 100, 50, "DOTT", 2);
1500 put_text(main_info.view_page, 160, 50, "JIFFY", 2);
1501 put_text(main_info.view_page, 220, 50, "FIZZ", 2);
1502 put_text(main_info.view_page, 280, 50, "MIJJI", 2);
1503 put_text(main_info.view_page, 40, 80, "DOTT", 2);
1504 put_text(main_info.view_page, 40, 110, "JIFFY", 2);
1505 put_text(main_info.view_page, 40, 140, "FIZZ", 2);
1506 put_text(main_info.view_page, 40, 170, "MIJJI", 2);
1508 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1509 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
1511 sprintf(str1, "%d", player[c1].bumped[c2]);
1512 put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, str1, 2);
1514 put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, "-", 2);
1516 sprintf(str1, "%d", player[c1].bumps);
1517 put_text(main_info.view_page, 350, 80 + c1 * 30, str1, 2);
1520 put_text(main_info.view_page, 200, 230, "Press ESC to continue", 2);
1524 flippage(main_info.view_page);
1526 if ((handle = dat_open("menu.pcx")) == 0) {
1527 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1530 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
1531 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1536 for (c1 = 0; c1 < 16; c1++) {
1537 pal[(240 + c1) * 3 + 0] = c1 << 2;
1538 pal[(240 + c1) * 3 + 1] = c1 << 2;
1539 pal[(240 + c1) * 3 + 2] = c1 << 2;
1542 memset(cur_pal, 0, 768);
1544 setpalette(0, 256, cur_pal);
1547 dj_ready_mod(MOD_SCORES);
1548 dj_set_mod_volume((char)mod_vol);
1552 while (key_pressed(1) == 0) {
1555 dj_set_mod_volume((char)mod_vol);
1556 for (c1 = 0; c1 < 768; c1++) {
1557 if (cur_pal[c1] < pal[c1])
1563 setpalette(0, 256, cur_pal);
1564 flippage(main_info.view_page);
1566 while (key_pressed(1) == 1) {
1571 memset(pal, 0, 768);
1573 while (mod_vol > 0) {
1575 dj_set_mod_volume((char)mod_vol);
1576 for (c1 = 0; c1 < 768; c1++) {
1577 if (cur_pal[c1] > pal[c1])
1582 setpalette(0, 256, cur_pal);
1583 flippage(main_info.view_page);
1586 fillpalette(0, 0, 0);
1592 break; /* don't go back to menu if in net game. */
1601 void steer_players(void)
1606 update_player_actions();
1608 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1610 if (player[c1].enabled == 1) {
1612 if (player[c1].dead_flag == 0) {
1614 if (player[c1].action_left && player[c1].action_right) {
1615 if (player[c1].direction == 0) {
1616 if (player[c1].action_right) {
1617 s1 = (player[c1].x >> 16);
1618 s2 = (player[c1].y >> 16);
1619 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1620 if (player[c1].x_add < 0)
1621 player[c1].x_add += 1024;
1623 player[c1].x_add += 768;
1624 } 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)) {
1625 if (player[c1].x_add > 0)
1626 player[c1].x_add += 1024;
1628 player[c1].x_add += 768;
1630 if (player[c1].x_add < 0) {
1631 player[c1].x_add += 16384;
1632 if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1633 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);
1635 player[c1].x_add += 12288;
1637 if (player[c1].x_add > 98304L)
1638 player[c1].x_add = 98304L;
1639 player[c1].direction = 0;
1640 if (player[c1].anim == 0) {
1641 player[c1].anim = 1;
1642 player[c1].frame = 0;
1643 player[c1].frame_tick = 0;
1644 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1648 if (player[c1].action_left) {
1649 s1 = (player[c1].x >> 16);
1650 s2 = (player[c1].y >> 16);
1651 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1652 if (player[c1].x_add > 0)
1653 player[c1].x_add -= 1024;
1655 player[c1].x_add -= 768;
1656 } 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)) {
1657 if (player[c1].x_add > 0)
1658 player[c1].x_add -= 1024;
1660 player[c1].x_add -= 768;
1662 if (player[c1].x_add > 0) {
1663 player[c1].x_add -= 16384;
1664 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1665 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);
1667 player[c1].x_add -= 12288;
1669 if (player[c1].x_add < -98304L)
1670 player[c1].x_add = -98304L;
1671 player[c1].direction = 1;
1672 if (player[c1].anim == 0) {
1673 player[c1].anim = 1;
1674 player[c1].frame = 0;
1675 player[c1].frame_tick = 0;
1676 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1680 } else if (player[c1].action_left) {
1681 s1 = (player[c1].x >> 16);
1682 s2 = (player[c1].y >> 16);
1683 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1684 if (player[c1].x_add > 0)
1685 player[c1].x_add -= 1024;
1687 player[c1].x_add -= 768;
1688 } 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)) {
1689 if (player[c1].x_add > 0)
1690 player[c1].x_add -= 1024;
1692 player[c1].x_add -= 768;
1694 if (player[c1].x_add > 0) {
1695 player[c1].x_add -= 16384;
1696 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1697 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);
1699 player[c1].x_add -= 12288;
1701 if (player[c1].x_add < -98304L)
1702 player[c1].x_add = -98304L;
1703 player[c1].direction = 1;
1704 if (player[c1].anim == 0) {
1705 player[c1].anim = 1;
1706 player[c1].frame = 0;
1707 player[c1].frame_tick = 0;
1708 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1710 } else if (player[c1].action_right) {
1711 s1 = (player[c1].x >> 16);
1712 s2 = (player[c1].y >> 16);
1713 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1714 if (player[c1].x_add < 0)
1715 player[c1].x_add += 1024;
1717 player[c1].x_add += 768;
1718 } 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)) {
1719 if (player[c1].x_add > 0)
1720 player[c1].x_add += 1024;
1722 player[c1].x_add += 768;
1724 if (player[c1].x_add < 0) {
1725 player[c1].x_add += 16384;
1726 if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1727 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);
1729 player[c1].x_add += 12288;
1731 if (player[c1].x_add > 98304L)
1732 player[c1].x_add = 98304L;
1733 player[c1].direction = 0;
1734 if (player[c1].anim == 0) {
1735 player[c1].anim = 1;
1736 player[c1].frame = 0;
1737 player[c1].frame_tick = 0;
1738 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1740 } else if ((!player[c1].action_left) && (!player[c1].action_right)) {
1741 s1 = (player[c1].x >> 16);
1742 s2 = (player[c1].y >> 16);
1743 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)))) {
1744 if (player[c1].x_add < 0) {
1745 player[c1].x_add += 16384;
1746 if (player[c1].x_add > 0)
1747 player[c1].x_add = 0;
1749 player[c1].x_add -= 16384;
1750 if (player[c1].x_add < 0)
1751 player[c1].x_add = 0;
1753 if (player[c1].x_add != 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1754 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);
1756 if (player[c1].anim == 1) {
1757 player[c1].anim = 0;
1758 player[c1].frame = 0;
1759 player[c1].frame_tick = 0;
1760 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1764 if (pogostick == 1 || (player[c1].jump_ready == 1 && player[c1].action_up)) {
1765 s1 = (player[c1].x >> 16);
1766 s2 = (player[c1].y >> 16);
1769 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) {
1770 player[c1].y_add = -280000L;
1771 player[c1].anim = 2;
1772 player[c1].frame = 0;
1773 player[c1].frame_tick = 0;
1774 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1775 player[c1].jump_ready = 0;
1776 player[c1].jump_abort = 1;
1778 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1780 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1782 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)) {
1783 player[c1].y_add = -196608L;
1784 player[c1].in_water = 0;
1785 player[c1].anim = 2;
1786 player[c1].frame = 0;
1787 player[c1].frame_tick = 0;
1788 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1789 player[c1].jump_ready = 0;
1790 player[c1].jump_abort = 1;
1792 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1794 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1797 if (pogostick == 0 && (!player[c1].action_up)) {
1798 player[c1].jump_ready = 1;
1799 if (player[c1].in_water == 0 && player[c1].y_add < 0 && player[c1].jump_abort == 1) {
1800 if (bunnies_in_space == 0)
1801 player[c1].y_add += 32768;
1803 player[c1].y_add += 16384;
1804 if (player[c1].y_add > 0)
1805 player[c1].y_add = 0;
1810 if (player[c1].action_up) {
1811 player[c1].y_add -= 16384;
1812 if (player[c1].y_add < -400000L)
1813 player[c1].y_add = -400000L;
1814 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))
1815 player[c1].in_water = 0;
1817 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);
1822 player[c1].x += player[c1].x_add;
1823 if ((player[c1].x >> 16) < 0) {
1825 player[c1].x_add = 0;
1827 if ((player[c1].x >> 16) + 15 > 351) {
1828 player[c1].x = 336L << 16;
1829 player[c1].x_add = 0;
1831 if (player[c1].y > 0) {
1832 s1 = (player[c1].x >> 16);
1833 s2 = (player[c1].y >> 16);
1834 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) {
1835 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1836 player[c1].x_add = 0;
1838 s1 = (player[c1].x >> 16);
1839 s2 = (player[c1].y >> 16);
1840 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) {
1841 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1842 player[c1].x_add = 0;
1845 s1 = (player[c1].x >> 16);
1847 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) {
1848 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1849 player[c1].x_add = 0;
1851 s1 = (player[c1].x >> 16);
1853 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) {
1854 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1855 player[c1].x_add = 0;
1859 player[c1].y += player[c1].y_add;
1861 s1 = (player[c1].x >> 16);
1862 s2 = (player[c1].y >> 16);
1863 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))) {
1864 player[c1].y = ((player[c1].y >> 16) & 0xfff0) << 16;
1865 player[c1].y_add = -400000L;
1866 player[c1].anim = 2;
1867 player[c1].frame = 0;
1868 player[c1].frame_tick = 0;
1869 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1870 player[c1].jump_ready = 0;
1871 player[c1].jump_abort = 0;
1872 for (c2 = 0; c2 < NUM_OBJECTS; c2++) {
1873 if (objects[c2].used == 1 && objects[c2].type == OBJ_SPRING) {
1874 if (ban_map[(s2 + 15) >> 4][(s1 + 8) >> 4] == BAN_SPRING) {
1875 if ((objects[c2].x >> 20) == ((s1 + 8) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1876 objects[c2].frame = 0;
1877 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1878 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1882 if (ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
1883 if ((objects[c2].x >> 20) == (s1 >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1884 objects[c2].frame = 0;
1885 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1886 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1889 } else if (ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1890 if ((objects[c2].x >> 20) == ((s1 + 15) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1891 objects[c2].frame = 0;
1892 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1893 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1900 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1902 s1 = (player[c1].x >> 16);
1903 s2 = (player[c1].y >> 16);
1906 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) {
1907 player[c1].y = (((s2 + 16) & 0xfff0)) << 16;
1908 player[c1].y_add = 0;
1909 player[c1].anim = 0;
1910 player[c1].frame = 0;
1911 player[c1].frame_tick = 0;
1912 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1914 s1 = (player[c1].x >> 16);
1915 s2 = (player[c1].y >> 16);
1918 if (ban_map[(s2 + 8) >> 4][(s1 + 8) >> 4] == BAN_WATER) {
1919 if (player[c1].in_water == 0) {
1920 player[c1].in_water = 1;
1921 player[c1].anim = 4;
1922 player[c1].frame = 0;
1923 player[c1].frame_tick = 0;
1924 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1925 if (player[c1].y_add >= 32768) {
1926 add_object(OBJ_SPLASH, (player[c1].x >> 16) + 8, ((player[c1].y >> 16) & 0xfff0) + 15, 0, 0, OBJ_ANIM_SPLASH, 0);
1927 if (blood_is_thicker_than_water == 0)
1928 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1930 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 5000), 64, 0, 0, -1);
1933 player[c1].y_add -= 1536;
1934 if (player[c1].y_add < 0 && player[c1].anim != 5) {
1935 player[c1].anim = 5;
1936 player[c1].frame = 0;
1937 player[c1].frame_tick = 0;
1938 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1940 if (player[c1].y_add < -65536L)
1941 player[c1].y_add = -65536L;
1942 if (player[c1].y_add > 65535L)
1943 player[c1].y_add = 65535L;
1944 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) {
1945 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1946 player[c1].y_add = 0;
1948 } 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) {
1949 player[c1].in_water = 0;
1950 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1951 player[c1].y_add = 0;
1952 if (player[c1].anim != 0 && player[c1].anim != 1) {
1953 player[c1].anim = 0;
1954 player[c1].frame = 0;
1955 player[c1].frame_tick = 0;
1956 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1959 if (player[c1].in_water == 0) {
1960 if (bunnies_in_space == 0)
1961 player[c1].y_add += 12288;
1963 player[c1].y_add += 6144;
1964 if (player[c1].y_add > 327680L)
1965 player[c1].y_add = 327680L;
1967 player[c1].y = (player[c1].y & 0xffff0000) + 0x10000;
1968 player[c1].y_add = 0;
1970 player[c1].in_water = 0;
1972 if (player[c1].y_add > 36864 && player[c1].anim != 3 && player[c1].in_water == 0) {
1973 player[c1].anim = 3;
1974 player[c1].frame = 0;
1975 player[c1].frame_tick = 0;
1976 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1981 player[c1].frame_tick++;
1982 if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
1984 if (player[c1].frame >= player_anims[player[c1].anim].num_frames) {
1985 if (player[c1].anim != 6)
1986 player[c1].frame = player_anims[player[c1].anim].restart_frame;
1988 position_player(c1);
1990 player[c1].frame_tick = 0;
1992 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
2001 void position_player(int player_num)
2010 if (ban_map[s2][s1] == BAN_VOID && (ban_map[s2 + 1][s1] == BAN_SOLID || ban_map[s2 + 1][s1] == BAN_ICE))
2013 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
2014 if (c1 != player_num && player[c1].enabled == 1) {
2015 if (abs((s1 << 4) - (player[c1].x >> 16)) < 32 && abs((s2 << 4) - (player[c1].y >> 16)) < 32)
2019 if (c1 == JNB_MAX_PLAYERS) {
2020 player[player_num].x = (long) s1 << 20;
2021 player[player_num].y = (long) s2 << 20;
2022 player[player_num].x_add = player[player_num].y_add = 0;
2023 player[player_num].direction = 0;
2024 player[player_num].jump_ready = 1;
2025 player[player_num].in_water = 0;
2026 player[player_num].anim = 0;
2027 player[player_num].frame = 0;
2028 player[player_num].frame_tick = 0;
2029 player[player_num].image = player_anims[player[player_num].anim].frame[player[player_num].frame].image;
2034 serverSendAlive(player_num);
2036 player[player_num].dead_flag = 0;
2046 void add_object(int type, int x, int y, int x_add, int y_add, int anim, int frame)
2050 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
2051 if (objects[c1].used == 0) {
2052 objects[c1].used = 1;
2053 objects[c1].type = type;
2054 objects[c1].x = (long) x << 16;
2055 objects[c1].y = (long) y << 16;
2056 objects[c1].x_add = x_add;
2057 objects[c1].y_add = y_add;
2058 objects[c1].x_acc = 0;
2059 objects[c1].y_acc = 0;
2060 objects[c1].anim = anim;
2061 objects[c1].frame = frame;
2062 objects[c1].ticks = object_anims[anim].frame[frame].ticks;
2063 objects[c1].image = object_anims[anim].frame[frame].image;
2071 void update_objects(void)
2076 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
2077 if (objects[c1].used == 1) {
2078 switch (objects[c1].type) {
2080 objects[c1].ticks--;
2081 if (objects[c1].ticks <= 0) {
2082 objects[c1].frame++;
2083 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames) {
2084 objects[c1].frame--;
2085 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2087 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2088 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2091 if (objects[c1].used == 1)
2092 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2095 objects[c1].ticks--;
2096 if (objects[c1].ticks <= 0) {
2097 objects[c1].frame++;
2098 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2099 objects[c1].used = 0;
2101 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2102 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2105 if (objects[c1].used == 1)
2106 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2109 objects[c1].x += objects[c1].x_add;
2110 objects[c1].y += objects[c1].y_add;
2111 objects[c1].ticks--;
2112 if (objects[c1].ticks <= 0) {
2113 objects[c1].frame++;
2114 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2115 objects[c1].used = 0;
2117 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2118 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2121 if (objects[c1].used == 1)
2122 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2124 case OBJ_YEL_BUTFLY:
2125 case OBJ_PINK_BUTFLY:
2126 objects[c1].x_acc += rnd(128) - 64;
2127 if (objects[c1].x_acc < -1024)
2128 objects[c1].x_acc = -1024;
2129 if (objects[c1].x_acc > 1024)
2130 objects[c1].x_acc = 1024;
2131 objects[c1].x_add += objects[c1].x_acc;
2132 if (objects[c1].x_add < -32768)
2133 objects[c1].x_add = -32768;
2134 if (objects[c1].x_add > 32768)
2135 objects[c1].x_add = 32768;
2136 objects[c1].x += objects[c1].x_add;
2137 if ((objects[c1].x >> 16) < 16) {
2138 objects[c1].x = 16 << 16;
2139 objects[c1].x_add = -objects[c1].x_add >> 2;
2140 objects[c1].x_acc = 0;
2141 } else if ((objects[c1].x >> 16) > 350) {
2142 objects[c1].x = 350 << 16;
2143 objects[c1].x_add = -objects[c1].x_add >> 2;
2144 objects[c1].x_acc = 0;
2146 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
2147 if (objects[c1].x_add < 0) {
2148 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2150 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2152 objects[c1].x_add = -objects[c1].x_add >> 2;
2153 objects[c1].x_acc = 0;
2155 objects[c1].y_acc += rnd(64) - 32;
2156 if (objects[c1].y_acc < -1024)
2157 objects[c1].y_acc = -1024;
2158 if (objects[c1].y_acc > 1024)
2159 objects[c1].y_acc = 1024;
2160 objects[c1].y_add += objects[c1].y_acc;
2161 if (objects[c1].y_add < -32768)
2162 objects[c1].y_add = -32768;
2163 if (objects[c1].y_add > 32768)
2164 objects[c1].y_add = 32768;
2165 objects[c1].y += objects[c1].y_add;
2166 if ((objects[c1].y >> 16) < 0) {
2168 objects[c1].y_add = -objects[c1].y_add >> 2;
2169 objects[c1].y_acc = 0;
2170 } else if ((objects[c1].y >> 16) > 255) {
2171 objects[c1].y = 255 << 16;
2172 objects[c1].y_add = -objects[c1].y_add >> 2;
2173 objects[c1].y_acc = 0;
2175 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
2176 if (objects[c1].y_add < 0) {
2177 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2179 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2181 objects[c1].y_add = -objects[c1].y_add >> 2;
2182 objects[c1].y_acc = 0;
2184 if (objects[c1].type == OBJ_YEL_BUTFLY) {
2185 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_LEFT) {
2186 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_LEFT;
2187 objects[c1].frame = 0;
2188 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2189 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2190 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_RIGHT) {
2191 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_RIGHT;
2192 objects[c1].frame = 0;
2193 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2194 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2197 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_LEFT) {
2198 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_LEFT;
2199 objects[c1].frame = 0;
2200 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2201 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2202 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_RIGHT) {
2203 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_RIGHT;
2204 objects[c1].frame = 0;
2205 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2206 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2209 objects[c1].ticks--;
2210 if (objects[c1].ticks <= 0) {
2211 objects[c1].frame++;
2212 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2213 objects[c1].frame = object_anims[objects[c1].anim].restart_frame;
2215 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2216 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2219 if (objects[c1].used == 1)
2220 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2224 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 0);
2225 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
2226 objects[c1].y_add += 3072;
2227 if (objects[c1].y_add > 196608L)
2228 objects[c1].y_add = 196608L;
2229 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
2230 if (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 if (objects[c1].x_add > 65536L)
2238 objects[c1].x_add = 65536L;
2239 objects[c1].x_add -= 1024;
2240 if (objects[c1].x_add < 0)
2241 objects[c1].x_add = 0;
2243 objects[c1].y_add += 1024;
2244 if (objects[c1].y_add < -65536L)
2245 objects[c1].y_add = -65536L;
2246 if (objects[c1].y_add > 65536L)
2247 objects[c1].y_add = 65536L;
2249 objects[c1].x += objects[c1].x_add;
2250 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)) {
2251 if (objects[c1].x_add < 0) {
2252 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2253 objects[c1].x_add = -objects[c1].x_add >> 2;
2255 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2256 objects[c1].x_add = -objects[c1].x_add >> 2;
2259 objects[c1].y += objects[c1].y_add;
2260 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
2261 objects[c1].used = 0;
2262 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
2263 if (objects[c1].y_add < 0) {
2264 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
2265 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2266 objects[c1].x_add >>= 2;
2267 objects[c1].y_add = -objects[c1].y_add >> 2;
2270 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
2271 if (objects[c1].y_add > 131072L) {
2272 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2273 objects[c1].x_add >>= 2;
2274 objects[c1].y_add = -objects[c1].y_add >> 2;
2276 objects[c1].used = 0;
2277 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
2278 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2279 if (objects[c1].y_add > 131072L)
2280 objects[c1].y_add = -objects[c1].y_add >> 2;
2282 objects[c1].y_add = 0;
2286 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
2287 objects[c1].x_add = -16384;
2288 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
2289 objects[c1].x_add = 16384;
2290 if (objects[c1].used == 1) {
2291 s1 = (int)(atan2(objects[c1].y_add, objects[c1].x_add) * 4 / M_PI);
2298 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame + s1, &object_gobs);
2302 if (rnd(100) < 30) {
2303 if (objects[c1].frame == 76)
2304 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 1);
2305 else if (objects[c1].frame == 77)
2306 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 2);
2307 else if (objects[c1].frame == 78)
2308 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 3);
2310 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
2311 objects[c1].y_add += 3072;
2312 if (objects[c1].y_add > 196608L)
2313 objects[c1].y_add = 196608L;
2314 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
2315 if (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 if (objects[c1].x_add > 65536L)
2323 objects[c1].x_add = 65536L;
2324 objects[c1].x_add -= 1024;
2325 if (objects[c1].x_add < 0)
2326 objects[c1].x_add = 0;
2328 objects[c1].y_add += 1024;
2329 if (objects[c1].y_add < -65536L)
2330 objects[c1].y_add = -65536L;
2331 if (objects[c1].y_add > 65536L)
2332 objects[c1].y_add = 65536L;
2334 objects[c1].x += objects[c1].x_add;
2335 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)) {
2336 if (objects[c1].x_add < 0) {
2337 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2338 objects[c1].x_add = -objects[c1].x_add >> 2;
2340 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2341 objects[c1].x_add = -objects[c1].x_add >> 2;
2344 objects[c1].y += objects[c1].y_add;
2345 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
2346 objects[c1].used = 0;
2347 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
2348 if (objects[c1].y_add < 0) {
2349 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
2350 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2351 objects[c1].x_add >>= 2;
2352 objects[c1].y_add = -objects[c1].y_add >> 2;
2355 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
2356 if (objects[c1].y_add > 131072L) {
2357 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2358 objects[c1].x_add >>= 2;
2359 objects[c1].y_add = -objects[c1].y_add >> 2;
2361 if (rnd(100) < 10) {
2363 add_leftovers(0, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
2364 add_leftovers(1, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
2366 objects[c1].used = 0;
2368 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
2369 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2370 if (objects[c1].y_add > 131072L)
2371 objects[c1].y_add = -objects[c1].y_add >> 2;
2373 objects[c1].y_add = 0;
2377 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
2378 objects[c1].x_add = -16384;
2379 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
2380 objects[c1].x_add = 16384;
2381 if (objects[c1].used == 1)
2382 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame, &object_gobs);
2384 case OBJ_FLESH_TRACE:
2385 objects[c1].ticks--;
2386 if (objects[c1].ticks <= 0) {
2387 objects[c1].frame++;
2388 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2389 objects[c1].used = 0;
2391 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2392 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2395 if (objects[c1].used == 1)
2396 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2405 int add_pob(int page, int x, int y, int image, gob_t *pob_data)
2408 if (main_info.page_info[page].num_pobs >= NUM_POBS)
2411 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].x = x;
2412 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].y = y;
2413 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].image = image;
2414 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].pob_data = pob_data;
2415 main_info.page_info[page].num_pobs++;
2422 void draw_flies(int page)
2426 for (c2 = 0; c2 < NUM_FLIES; c2++) {
2427 flies[c2].back[main_info.draw_page] = get_pixel(main_info.draw_page, flies[c2].x, flies[c2].y);
2428 flies[c2].back_defined[main_info.draw_page] = 1;
2429 if (mask_pic[(flies[c2].y * JNB_WIDTH) + flies[c2].x] == 0)
2430 set_pixel(main_info.draw_page, flies[c2].x, flies[c2].y, 0);
2434 void draw_pobs(int page)
2441 for (c1 = main_info.page_info[page].num_pobs - 1; c1 >= 0; c1--) {
2442 main_info.page_info[page].pobs[c1].back_buf_ofs = back_buf_ofs;
2443 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);
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) * 4 * bytes_per_pixel;
2447 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;
2448 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);
2454 void redraw_flies_background(int page)
2458 for (c2 = NUM_FLIES - 1; c2 >= 0; c2--) {
2459 if (flies[c2].back_defined[page] == 1)
2460 set_pixel(page, flies[c2].old_draw_x, flies[c2].old_draw_y, flies[c2].back[page]);
2461 flies[c2].old_draw_x = flies[c2].x;
2462 flies[c2].old_draw_y = flies[c2].y;
2467 void redraw_pob_backgrounds(int page)
2471 for (c1 = 0; c1 < main_info.page_info[page].num_pobs; c1++)
2472 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);
2477 int add_leftovers(int page, int x, int y, int image, gob_t *pob_data)
2480 if (leftovers.page[page].num_pobs >= NUM_LEFTOVERS)
2483 leftovers.page[page].pobs[leftovers.page[page].num_pobs].x = x;
2484 leftovers.page[page].pobs[leftovers.page[page].num_pobs].y = y;
2485 leftovers.page[page].pobs[leftovers.page[page].num_pobs].image = image;
2486 leftovers.page[page].pobs[leftovers.page[page].num_pobs].pob_data = pob_data;
2487 leftovers.page[page].num_pobs++;
2494 void draw_leftovers(int page)
2498 for (c1 = leftovers.page[page].num_pobs - 1; c1 >= 0; c1--)
2499 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);
2501 leftovers.page[page].num_pobs = 0;
2506 int init_level(int level, char *pal)
2508 unsigned char *handle;
2512 if ((handle = dat_open("level.pcx")) == 0) {
2513 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2516 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
2517 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2521 flip_pixels(background_pic);
2522 if ((handle = dat_open("mask.pcx")) == 0) {
2523 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2526 if (read_pcx(handle, mask_pic, JNB_WIDTH*JNB_HEIGHT, 0) != 0) {
2527 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2531 flip_pixels(mask_pic);
2532 register_mask(mask_pic);
2534 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
2535 if (player[c1].enabled == 1) {
2536 player[c1].bumps = 0;
2537 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++)
2538 player[c1].bumped[c2] = 0;
2539 position_player(c1);
2543 for (c1 = 0; c1 < NUM_OBJECTS; c1++)
2544 objects[c1].used = 0;
2546 for (c1 = 0; c1 < 16; c1++) {
2547 for (c2 = 0; c2 < 22; c2++) {
2548 if (ban_map[c1][c2] == BAN_SPRING)
2549 add_object(OBJ_SPRING, c2 << 4, c1 << 4, 0, 0, OBJ_ANIM_SPRING, 5);
2556 if (ban_map[s2][s1] == BAN_VOID) {
2557 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2564 if (ban_map[s2][s1] == BAN_VOID) {
2565 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2572 if (ban_map[s2][s1] == BAN_VOID) {
2573 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2580 if (ban_map[s2][s1] == BAN_VOID) {
2581 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2591 void deinit_level(void)
2599 #define PATH_MAX 1024
2605 unsigned char *datafile_buffer = NULL;
2607 static void preread_datafile(const char *fname)
2613 char *gzfilename = alloca(strlen(fname) + 4);
2618 strcpy(gzfilename, fname);
2619 strcat(gzfilename, ".gz");
2621 gzf = gzopen(gzfilename, "rb");
2626 if (bufpos >= bufsize) {
2627 bufsize += 1024 * 1024;
2628 datafile_buffer = (unsigned char *) realloc(datafile_buffer, bufsize);
2629 if (datafile_buffer == NULL) {
2630 perror("realloc()");
2635 br = gzread(gzf, datafile_buffer + bufpos, bufsize - bufpos);
2637 fprintf(stderr, "gzread failed.\n");
2642 } while (!gzeof(gzf));
2644 /* try to shrink buffer... */
2645 ptr = (unsigned char *) realloc(datafile_buffer, bufpos);
2647 datafile_buffer = ptr;
2653 /* drop through and try for an uncompressed datafile... */
2656 fd = open(fname, O_RDONLY | O_BINARY);
2658 fprintf(stderr, "can't open %s:", fname);
2663 len = filelength(fd);
2664 datafile_buffer = (unsigned char *) malloc(len);
2665 if (datafile_buffer == NULL) {
2671 if (read(fd, datafile_buffer, len) != len) {
2681 int init_program(int argc, char *argv[], char *pal)
2683 char *netarg = NULL;
2684 unsigned char *handle = (unsigned char *) NULL;
2689 int player_anim_data[] = {
2690 1, 0, 0, 0x7fff, 0, 0, 0, 0, 0, 0,
2691 4, 0, 0, 4, 1, 4, 2, 4, 3, 4,
2692 1, 0, 4, 0x7fff, 0, 0, 0, 0, 0, 0,
2693 4, 2, 5, 8, 6, 10, 7, 3, 6, 3,
2694 1, 0, 6, 0x7fff, 0, 0, 0, 0, 0, 0,
2695 2, 1, 5, 8, 4, 0x7fff, 0, 0, 0, 0,
2696 1, 0, 8, 5, 0, 0, 0, 0, 0, 0
2700 memset(&net_info, 0, sizeof(net_info));
2704 if (__djgpp_nearptr_enable() == 0)
2710 if (hook_keyb_handler() != 0)
2713 memset(&main_info, 0, sizeof(main_info));
2715 strcpy(datfile_name, DATA_PATH);
2717 force2 = force3 = 0;
2720 for (c1 = 1; c1 < argc; c1++) {
2721 if (stricmp(argv[c1], "-nosound") == 0)
2722 main_info.no_sound = 1;
2723 else if (stricmp(argv[c1], "-musicnosound") == 0)
2724 main_info.music_no_sound = 1;
2725 else if (stricmp(argv[c1], "-nogore") == 0)
2726 main_info.no_gore = 1;
2727 else if (stricmp(argv[c1], "-noflies") == 0)
2729 else if (stricmp(argv[c1], "-nojoy") == 0)
2730 main_info.joy_enabled = 0;
2731 else if (stricmp(argv[c1], "-fireworks") == 0)
2732 main_info.fireworks = 1;
2734 else if (stricmp(argv[c1], "-fullscreen") == 0)
2737 else if (stricmp(argv[c1], "-scaleup") == 0)
2739 else if (stricmp(argv[c1], "-mirror") == 0)
2741 else if (stricmp(argv[c1], "-dat") == 0) {
2742 if (c1 < (argc - 1)) {
2745 if ((f = fopen(argv[c1 + 1], "rb")) != NULL) {
2747 strcpy(datfile_name, argv[c1 + 1]);
2750 } else if (stricmp(argv[c1], "-player") == 0) {
2751 if (c1 < (argc - 1)) {
2752 if (client_player_num < 0)
2753 client_player_num = atoi(argv[c1 + 1]);
2756 } else if (stricmp(argv[c1], "-server") == 0) {
2757 if (c1 < (argc - 1)) {
2760 netarg = argv[c1 + 1];
2762 } else if (stricmp(argv[c1], "-connect") == 0) {
2763 if (c1 < (argc - 1)) {
2766 netarg = argv[c1 + 1];
2769 } else if (stricmp(argv[c1], "-mouse") == 0) {
2770 if (c1 < (argc - 1)) {
2771 if (stricmp(argv[c1 + 1], "2") == 0)
2773 if (stricmp(argv[c1 + 1], "3") == 0)
2777 else if (strstr(argv[1],"-v")) {
2778 printf("jumpnbump %s compiled %s at %s with",JNB_VERSION,__DATE__,__TIME__);
2782 printf(" network support.\n");
2785 else if (strstr(argv[1],"-h")) {
2786 printf("Usage: jumpnbump [OPTION]...\n");
2788 printf(" -h this help\n");
2789 printf(" -v print version\n");
2790 printf(" -dat level.dat play a different level\n");
2792 printf(" -server playercount start as server waiting for players\n");
2793 printf(" -connect host connect to server\n");
2795 printf(" -player num set main player to num (0-3). Needed for networking\n");
2796 printf(" -fireworks screensaver mode\n");
2797 printf(" -fullscreen run in fullscreen mode\n");
2798 printf(" -nosound play without sound\n");
2799 printf(" -nogore play without blood\n");
2800 printf(" -noflies disable flies\n");
2801 printf(" -mirror play with mirrored level\n");
2802 printf(" -scaleup play with doubled resolution (800x512)\n");
2803 printf(" -musicnosound play with music but without sound\n");
2810 preread_datafile(datfile_name);
2813 if (client_player_num < 0)
2814 client_player_num = 0;
2815 player[client_player_num].enabled = 1;
2818 main_info.pob_backbuf[0] = malloc(screen_pitch*screen_height*bytes_per_pixel);
2819 main_info.pob_backbuf[1] = malloc(screen_pitch*screen_height*bytes_per_pixel);
2821 for (c1 = 0; c1 < 7; c1++) {
2822 player_anims[c1].num_frames = player_anim_data[c1 * 10];
2823 player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
2824 for (c2 = 0; c2 < 4; c2++) {
2825 player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
2826 player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
2830 if ((handle = dat_open("menu.pcx")) == 0) {
2831 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2834 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
2835 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2839 if ((handle = dat_open("rabbit.gob")) == 0) {
2840 strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
2843 if (register_gob(handle, &rabbit_gobs, dat_filelen("rabbit.gob"))) {
2848 if ((handle = dat_open("objects.gob")) == 0) {
2849 strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
2852 if (register_gob(handle, &object_gobs, dat_filelen("objects.gob"))) {
2857 if ((handle = dat_open("font.gob")) == 0) {
2858 strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
2861 if (register_gob(handle, &font_gobs, dat_filelen("font.gob"))) {
2866 if ((handle = dat_open("numbers.gob")) == 0) {
2867 strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
2870 if (register_gob(handle, &number_gobs, dat_filelen("numbers.gob"))) {
2875 if (read_level() != 0) {
2876 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2882 if (main_info.no_sound == 0) {
2884 dj_set_mixing_freq(20000);
2888 dj_set_num_sfx_channels(5);
2889 dj_set_sfx_volume(64);
2893 if ((handle = dat_open("jump.mod")) == 0) {
2894 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2897 if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
2898 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2902 if ((handle = dat_open("bump.mod")) == 0) {
2903 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2906 if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
2907 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2911 if ((handle = dat_open("scores.mod")) == 0) {
2912 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2915 if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
2916 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2920 if ((handle = dat_open("jump.smp")) == 0) {
2921 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2924 if (dj_load_sfx(handle, 0, dat_filelen("jump.smp"), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
2925 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2929 if ((handle = dat_open("death.smp")) == 0) {
2930 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2933 if (dj_load_sfx(handle, 0, dat_filelen("death.smp"), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
2934 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2938 if ((handle = dat_open("spring.smp")) == 0) {
2939 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2942 if (dj_load_sfx(handle, 0, dat_filelen("spring.smp"), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
2943 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2947 if ((handle = dat_open("splash.smp")) == 0) {
2948 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2951 if (dj_load_sfx(handle, 0, dat_filelen("splash.smp"), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
2952 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2956 if ((handle = dat_open("fly.smp")) == 0) {
2957 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2960 if (dj_load_sfx(handle, 0, dat_filelen("fly.smp"), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
2961 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2965 dj_get_sfx_settings(SFX_FLY, &fly);
2967 fly.default_freq = SFX_FLY_FREQ;
2970 fly.loop_length = fly.length;
2971 dj_set_sfx_settings(SFX_FLY, &fly);
2974 if ((background_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
2976 if ((mask_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
2978 memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
2979 register_mask(mask_pic);
2982 for (c1 = 0; c1 < 16; c1++) {
2983 pal[(240 + c1) * 3 + 0] = c1 << 2;
2984 pal[(240 + c1) * 3 + 1] = c1 << 2;
2985 pal[(240 + c1) * 3 + 2] = c1 << 2;
2988 setpalette(0, 256, pal);
2992 recalculate_gob(&font_gobs, pal);
2994 if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
2996 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2997 put_text(0, 200, 100, "Move the joystick to the", 2);
2998 put_text(0, 200, 115, "UPPER LEFT", 2);
2999 put_text(0, 200, 130, "and press button A", 2);
3000 put_text(0, 200, 200, "Or press ESC to use", 2);
3001 put_text(0, 200, 215, "previous settings", 2);
3002 if (calib_joy(0) != 0)
3005 register_background(NULL, NULL);
3007 main_info.view_page = 1;
3012 put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
3013 put_text(1, 200, 100, "Move the joystick to the", 2);
3014 put_text(1, 200, 115, "LOWER RIGHT", 2);
3015 put_text(1, 200, 130, "and press button A", 2);
3016 put_text(1, 200, 200, "Or press ESC to use", 2);
3017 put_text(1, 200, 215, "previous settings", 2);
3018 if (calib_joy(1) != 0)
3021 register_background(NULL, NULL);
3026 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
3027 put_text(0, 200, 100, "Move the joystick to the", 2);
3028 put_text(0, 200, 115, "CENTER", 2);
3029 put_text(0, 200, 130, "and press button A", 2);
3030 put_text(0, 200, 200, "Or press ESC to use", 2);
3031 put_text(0, 200, 215, "previous settings", 2);
3032 if (calib_joy(2) != 0)
3035 if (joy.calib_data.x1 == joy.calib_data.x2)
3036 joy.calib_data.x1 -= 10;
3037 if (joy.calib_data.x3 == joy.calib_data.x2)
3038 joy.calib_data.x3 += 10;
3039 if (joy.calib_data.y1 == joy.calib_data.y2)
3040 joy.calib_data.y1 -= 10;
3041 if (joy.calib_data.y3 == joy.calib_data.y2)
3042 joy.calib_data.y3 += 10;
3047 if (load_flag == 1) {
3048 if ((handle = dat_open("calib.dat")) == 0) {
3049 strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
3052 joy.calib_data.x1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3053 joy.calib_data.x2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3054 joy.calib_data.x3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3055 joy.calib_data.y1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3056 joy.calib_data.y2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3057 joy.calib_data.y3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3064 init_server(netarg);
3066 connect_to_server(netarg);
3075 void deinit_program(void)
3082 dj_free_mod(MOD_MENU);
3083 dj_free_mod(MOD_GAME);
3084 dj_free_sfx(SFX_DEATH);
3085 dj_free_sfx(SFX_SPRING);
3086 dj_free_sfx(SFX_SPLASH);
3089 if (background_pic != 0)
3090 free(background_pic);
3094 remove_keyb_handler();
3098 __dpmi_int(0x10, ®s);
3101 if (main_info.error_str[0] != 0) {
3102 printf(main_info.error_str);
3104 MessageBox(0, main_info.error_str, "Jump'n'Bump", 0);
3113 unsigned short rnd(unsigned short max)
3115 #if (RAND_MAX < 0x7fff)
3116 #error "rand returns too small values"
3117 #elif (RAND_MAX == 0x7fff)
3118 return (unsigned short)((rand()*2) % (int)max);
3120 return (unsigned short)(rand() % (int)max);
3125 int read_level(void)
3127 unsigned char *handle;
3131 if ((handle = dat_open("levelmap.txt")) == 0) {
3132 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
3136 for (c1 = 0; c1 < 16; c1++) {
3137 for (c2 = 0; c2 < 22; c2++) {
3139 chr = (int) *(handle++);
3140 if (chr >= '0' && chr <= '4')
3144 ban_map[c1][21-c2] = chr - '0';
3146 ban_map[c1][c2] = chr - '0';
3150 for (c2 = 0; c2 < 22; c2++)
3151 ban_map[16][c2] = BAN_SOLID;
3158 unsigned char *dat_open(char *file_name)
3166 if (datafile_buffer == NULL)
3169 memset(name, 0, sizeof(name));
3171 num = ( (datafile_buffer[0] << 0) +
3172 (datafile_buffer[1] << 8) +
3173 (datafile_buffer[2] << 16) +
3174 (datafile_buffer[3] << 24) );
3176 ptr = datafile_buffer + 4;
3178 for (c1 = 0; c1 < num; c1++) {
3180 memcpy(name, ptr, 12);
3183 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
3184 ofs = ( (ptr[0] << 0) +
3189 return (datafile_buffer + ofs);
3198 int dat_filelen(char *file_name)
3206 memset(name, 0, sizeof(name));
3208 num = ( (datafile_buffer[0] << 0) +
3209 (datafile_buffer[1] << 8) +
3210 (datafile_buffer[2] << 16) +
3211 (datafile_buffer[3] << 24) );
3213 ptr = datafile_buffer + 4;
3215 for (c1 = 0; c1 < num; c1++) {
3217 memcpy(name, ptr, 12);
3220 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
3223 len = ( (ptr[0] << 0) +
3237 void write_calib_data(void)
3245 if ((handle = fopen(datfile_name, "rb")) == NULL)
3247 len = filelength(fileno(handle));
3248 if ((mem = malloc(len)) == NULL)
3250 fread(mem, 1, len, handle);
3254 num = *(int *) (&mem[0]);
3255 for (c1 = 0; c1 < num; c1++) {
3256 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
3257 ofs = *(int *) (&mem[ofs + 12]);
3263 mem[ofs] = joy.calib_data.x1 & 0xff;
3264 mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
3265 mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
3266 mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
3267 mem[ofs + 4] = joy.calib_data.x2 & 0xff;
3268 mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
3269 mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
3270 mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
3271 mem[ofs + 8] = joy.calib_data.x3 & 0xff;
3272 mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
3273 mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
3274 mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
3275 mem[ofs + 12] = joy.calib_data.y1 & 0xff;
3276 mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
3277 mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
3278 mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
3279 mem[ofs + 16] = joy.calib_data.y2 & 0xff;
3280 mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
3281 mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
3282 mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
3283 mem[ofs + 20] = joy.calib_data.y3 & 0xff;
3284 mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
3285 mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
3286 mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
3288 if ((handle = fopen(datfile_name, "wb")) == NULL)
3290 fwrite(mem, 1, len, handle);