3 * Copyright (C) 1998 Brainchild Design - http://brainchilddesign.com/
5 * Copyright (C) 2001 Chuck Mason <cemason@users.sourceforge.net>
7 * Copyright (C) 2002 Florian Schulze <crow@icculus.org>
9 * Portions of this code are from the MPEG software simulation group
10 * idct implementation. This code will be replaced with a new
11 * implementation soon.
13 * This file is part of Jump'n'Bump.
15 * Jump'n'Bump is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * Jump'n'Bump is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
38 #define M_PI 3.14159265358979323846
41 gob_t rabbit_gobs = { 0 };
42 gob_t font_gobs = { 0 };
43 gob_t object_gobs = { 0 };
44 gob_t number_gobs = { 0 };
46 main_info_t main_info;
47 player_t player[JNB_MAX_PLAYERS];
48 player_anim_t player_anims[7];
49 object_t objects[NUM_OBJECTS];
53 char datfile_name[2048];
59 unsigned int ban_map[17][22] = {
60 {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
61 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0},
62 {1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
63 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1},
64 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
65 {1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
66 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1},
67 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
68 {1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
69 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1},
70 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1},
71 {1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1},
72 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
73 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
74 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 1, 3, 3, 3, 1, 1, 1},
75 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
76 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
202 int flies_enabled = 1;
207 int old_draw_x, old_draw_y;
219 } pobs[NUM_LEFTOVERS];
223 int pogostick, bunnies_in_space, jetpack, lord_of_the_flies, blood_is_thicker_than_water;
227 int filelength(int handle)
231 if (fstat(handle, &buf) == -1) {
232 perror("filelength");
241 /* networking shite. */
243 int client_player_num = -1;
248 TCPsocket sock = NULL;
249 SDLNet_SocketSet socketset = NULL;
255 SDLNet_SocketSet socketset;
258 NetInfo net_info[JNB_MAX_PLAYERS];
270 #define NETPKTBUFSIZE (4 + 4 + 4 + 4 + 4)
272 #define NETCMD_NACK (0xF00DF00D + 0)
273 #define NETCMD_ACK (0xF00DF00D + 1)
274 #define NETCMD_HELLO (0xF00DF00D + 2)
275 #define NETCMD_GREENLIGHT (0xF00DF00D + 3)
276 #define NETCMD_MOVE (0xF00DF00D + 4)
277 #define NETCMD_BYE (0xF00DF00D + 5)
278 #define NETCMD_POSITION (0xF00DF00D + 6)
279 #define NETCMD_ALIVE (0xF00DF00D + 7)
280 #define NETCMD_KILL (0xF00DF00D + 8)
284 void bufToPacket(const char *buf, NetPacket *pkt)
286 SDLNet_Write32(*((unsigned long *) (buf + 0)), &pkt->cmd);
287 SDLNet_Write32(*((unsigned long *) (buf + 4)), &pkt->arg);
288 SDLNet_Write32(*((unsigned long *) (buf + 8)), &pkt->arg2);
289 SDLNet_Write32(*((unsigned long *) (buf + 12)), &pkt->arg3);
290 SDLNet_Write32(*((unsigned long *) (buf + 16)), &pkt->arg4);
292 pkt->cmd = ntohl(*((unsigned long *) (buf + 0)));
293 pkt->arg = (long) ntohl(*((unsigned long *) (buf + 4)));
294 pkt->arg2 = (long) ntohl(*((unsigned long *) (buf + 8)));
295 pkt->arg3 = (long) ntohl(*((unsigned long *) (buf + 12)));
296 pkt->arg4 = (long) ntohl(*((unsigned long *) (buf + 16)));
301 void packetToBuf(const NetPacket *pkt, char *buf)
303 *((unsigned long *) (buf + 0)) = SDLNet_Read32(&pkt->cmd);
304 *((unsigned long *) (buf + 4)) = SDLNet_Read32(&pkt->arg);
305 *((unsigned long *) (buf + 8)) = SDLNet_Read32(&pkt->arg2);
306 *((unsigned long *) (buf + 12)) = SDLNet_Read32(&pkt->arg3);
307 *((unsigned long *) (buf + 16)) = SDLNet_Read32(&pkt->arg4);
309 *((unsigned long *) (buf + 0)) = htonl(pkt->cmd);
310 *((unsigned long *) (buf + 4)) = htonl((unsigned long) pkt->arg);
311 *((unsigned long *) (buf + 8)) = htonl((unsigned long) pkt->arg2);
312 *((unsigned long *) (buf + 12)) = htonl((unsigned long) pkt->arg3);
313 *((unsigned long *) (buf + 16)) = htonl((unsigned long) pkt->arg4);
318 void sendPacketToSock(TCPsocket s, NetPacket *pkt)
320 int bytes_left = NETPKTBUFSIZE;
322 char buf[NETPKTBUFSIZE];
325 packetToBuf(pkt, buf);
326 while (bytes_left > 0) {
327 bw = SDLNet_TCP_Send(s, ptr, bytes_left);
329 fprintf(stderr, "SERVER: SDLNet_TCP_Send(): %s\n", SDLNet_GetError());
332 } else if (bw == 0) {
342 void sendPacket(int playerid, NetPacket *pkt)
344 if ( playerid < JNB_MAX_PLAYERS ) {
345 if ((player[playerid].enabled) && (playerid != client_player_num)) {
346 sendPacketToSock(net_info[playerid].sock, pkt);
352 void sendPacketToAll(NetPacket *pkt)
356 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
362 int grabPacket(TCPsocket s, SDLNet_SocketSet ss, NetPacket *pkt)
364 static char buf[NETPKTBUFSIZE];
365 static int buf_count = 0;
369 if (SDLNet_CheckSockets(ss, 0) > 0) {
370 rc = SDLNet_TCP_Recv(s, &buf[buf_count], NETPKTBUFSIZE - buf_count);
371 if (rc <= 0) { /* closed connection? */
373 } else if (rc != NETPKTBUFSIZE) {
377 bufToPacket(buf, pkt);
386 int serverRecvPacket(NetPacket *pkt)
393 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
394 TCPsocket s = net_info[i].sock;
396 if ((i == client_player_num) || (!player[i].enabled))
399 rc = grabPacket(s, net_info[i].socketset, pkt);
403 player[i].enabled = 0;
405 pkt.cmd = NETCMD_BYE;
410 sendPacketToAll(&pkt);
412 return(i); /* it's all good. */
416 return(-1); /* no packets available currently. */
420 void wait_for_greenlight(void)
425 printf("CLIENT: Waiting for greenlight...\n");
429 while ((rc = grabPacket(sock, socketset, &pkt)) == 0) {
430 SDL_Delay(100); /* nap and then try again. */
434 printf("CLIENT: Lost connection.\n");
435 SDLNet_TCP_Close(sock);
438 } while (pkt.cmd != NETCMD_GREENLIGHT);
440 printf("CLIENT: Got greenlight.\n");
442 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
443 if (pkt.arg & (1 << i)) {
444 printf("CLIENT: There is a player #%d.\n", i);
445 player[i].enabled = 1;
451 static int buggered_off = 0;
454 void tellServerGoodbye(void)
460 pkt.cmd = NETCMD_BYE;
461 pkt.arg = client_player_num;
465 sendPacketToSock(sock, &pkt);
471 void processMovePacket(NetPacket *pkt)
473 int playerid = pkt->arg;
474 int movetype = ((pkt->arg2 >> 16) & 0xFF);
475 int newval = ((pkt->arg2 >> 0) & 0xFF);
477 if (movetype == MOVEMENT_LEFT) {
478 player[playerid].action_left = newval;
479 } else if (movetype == MOVEMENT_RIGHT) {
480 player[playerid].action_right = newval;
481 } else if (movetype == MOVEMENT_UP) {
482 player[playerid].action_up = newval;
484 printf("bogus MOVE packet!\n");
487 player[playerid].x = pkt->arg3;
488 player[playerid].y = pkt->arg4;
492 void tellServerPlayerMoved(int playerid, int movement_type, int newval)
496 pkt.cmd = NETCMD_MOVE;
498 pkt.arg2 = ( ((movement_type & 0xFF) << 16) | ((newval & 0xFF) << 0) );
499 pkt.arg3 = player[playerid].x;
500 pkt.arg4 = player[playerid].y;
503 processMovePacket(&pkt);
506 sendPacketToAll(&pkt);
508 sendPacketToSock(sock, &pkt);
515 void tellServerNewPosition(void)
518 pkt.cmd = NETCMD_POSITION;
519 pkt.arg = client_player_num;
520 pkt.arg2 = player[client_player_num].x;
521 pkt.arg3 = player[client_player_num].y;
524 sendPacketToAll(&pkt);
526 sendPacketToSock(sock, &pkt);
532 void processKillPacket(NetPacket *pkt)
541 player[c1].y_add = -player[c1].y_add;
542 if (player[c1].y_add > -262144L)
543 player[c1].y_add = -262144L;
544 player[c1].jump_abort = 1;
545 player[c2].dead_flag = 1;
546 if (player[c2].anim != 6) {
548 player[c2].frame = 0;
549 player[c2].frame_tick = 0;
550 player[c2].image = player_anims[player[c2].anim].frame[player[c2].frame].image + player[c2].direction * 9;
551 if (main_info.no_gore == 0) {
552 for (c4 = 0; c4 < 6; c4++)
553 add_object(OBJ_FUR, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 44 + c2 * 8);
554 for (c4 = 0; c4 < 6; c4++)
555 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 76);
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, 77);
558 for (c4 = 0; c4 < 8; 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, 78);
560 for (c4 = 0; c4 < 10; 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, 79);
563 dj_play_sfx(SFX_DEATH, (unsigned short)(SFX_DEATH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
565 player[c1].bumped[c2]++;
566 s1 = player[c1].bumps % 100;
567 add_leftovers(0, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
568 add_leftovers(1, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
569 add_leftovers(0, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
570 add_leftovers(1, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
576 void processPositionPacket(NetPacket *pkt)
578 int playerid = pkt->arg;
580 player[playerid].x = pkt->arg2;
581 player[playerid].y = pkt->arg3;
585 void processAlivePacket(NetPacket *pkt)
587 int playerid = pkt->arg;
589 player[playerid].dead_flag = 0;
590 player[playerid].x = pkt->arg2;
591 player[playerid].y = pkt->arg3;
595 void serverTellEveryoneGoodbye(void)
601 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
602 if (player[i].enabled) {
605 pkt.cmd = NETCMD_BYE;
610 sendPacketToAll(&pkt);
617 int server_said_bye = 0;
620 int update_players_from_server(void)
627 while ((rc = grabPacket(sock, socketset, &pkt)) != 0) {
629 printf("CLIENT: Lost connection.\n");
630 pkt.cmd = NETCMD_BYE;
631 pkt.arg = client_player_num;
634 if (pkt.cmd == NETCMD_BYE) {
635 if (pkt.arg == client_player_num) {
636 SDLNet_FreeSocketSet(socketset);
637 SDLNet_TCP_Close(sock);
642 player[pkt.arg].enabled = 0;
644 } else if (pkt.cmd == NETCMD_MOVE) {
645 processMovePacket(&pkt);
646 } else if (pkt.cmd == NETCMD_ALIVE) {
647 processAlivePacket(&pkt);
648 } else if (pkt.cmd == NETCMD_POSITION) {
649 processPositionPacket(&pkt);
650 } else if (pkt.cmd == NETCMD_KILL) {
651 processKillPacket(&pkt);
653 printf("CLIENT: Got an unknown packet: 0x%lX.\n", pkt.cmd);
661 void serverSendAlive(int playerid)
666 pkt.cmd = NETCMD_ALIVE;
668 pkt.arg2 = player[playerid].x;
669 pkt.arg3 = player[playerid].y;
670 sendPacketToAll(&pkt);
675 void serverSendKillPacket(int killer, int victim)
680 pkt.cmd = NETCMD_KILL;
683 pkt.arg3 = player[victim].x;
684 pkt.arg4 = player[victim].y;
685 processKillPacket(&pkt);
688 sendPacketToAll(&pkt);
694 void update_players_from_clients(void)
702 while ((playerid = serverRecvPacket(&pkt)) >= 0) {
703 if (pkt.cmd == NETCMD_BYE) {
704 pkt.arg = playerid; /* just in case. */
705 sendPacketToAll(&pkt);
706 player[playerid].enabled = 0;
707 SDLNet_FreeSocketSet(net_info[playerid].socketset);
708 SDLNet_TCP_Close(net_info[playerid].sock);
709 } else if (pkt.cmd == NETCMD_POSITION) {
710 pkt.arg = playerid; /* just in case. */
711 processPositionPacket(&pkt);
712 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
717 } else if (pkt.cmd == NETCMD_MOVE) {
718 pkt.arg = playerid; /* just in case. */
720 pkt.arg3 = player[playerid].x;
721 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 void 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 = 0;
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(&object_gobs, pal);
1008 recalculate_gob(&number_gobs, pal);
1011 register_background(background_pic, pal);
1014 if (flies_enabled) {
1018 for (c1 = 0; c1 < NUM_FLIES; c1++) {
1020 flies[c1].x = s1 + rnd(101) - 50;
1021 flies[c1].y = s2 + rnd(101) - 50;
1022 if (ban_map[flies[c1].y >> 4][flies[c1].x >> 4] == BAN_VOID)
1025 flies[c1].back_defined[0] = 0;
1026 flies[c1].back_defined[1] = 0;
1030 mod_vol = sfx_vol = 10;
1031 mod_fade_direction = 1;
1032 dj_ready_mod(MOD_GAME);
1033 dj_set_mod_volume((char)mod_vol);
1034 dj_set_sfx_volume((char)mod_vol);
1038 dj_play_sfx(SFX_FLY, SFX_FLY_FREQ, 0, 0, 0, 4);
1042 lord_of_the_flies = bunnies_in_space = jetpack = pogostick = blood_is_thicker_than_water = 0;
1044 main_info.page_info[0].num_pobs = 0;
1045 main_info.page_info[1].num_pobs = 0;
1046 main_info.view_page = 0;
1047 main_info.draw_page = 1;
1051 while (update_count) {
1053 if (key_pressed(1) == 1) {
1057 serverTellEveryoneGoodbye();
1059 tellServerGoodbye();
1064 memset(pal, 0, 768);
1065 mod_fade_direction = 0;
1068 if (strncmp(last_keys, "kcitsogop", strlen("kcitsogop")) == 0) {
1072 if (strncmp(last_keys, "ecapsniseinnub", strlen("ecapsniseinnub")) == 0) {
1073 bunnies_in_space ^= 1;
1076 if (strncmp(last_keys, "kcaptej", strlen("kcaptej")) == 0) {
1080 if (strncmp(last_keys, "seilfehtfodrol", strlen("seilfehtfodrol")) == 0) {
1081 lord_of_the_flies ^= 1;
1084 if (strncmp(last_keys, "retawnahtrekcihtsidoolb", strlen("retawnahtrekcihtsidoolb")) == 0) {
1085 blood_is_thicker_than_water ^= 1;
1086 if (blood_is_thicker_than_water == 1) {
1137 register_background(background_pic, pal);
1138 recalculate_gob(&object_gobs, pal);
1145 update_players_from_clients();
1147 if (!update_players_from_server()) {
1148 break; /* got a BYE packet */
1158 for (c3 = 0; c3 < 6; c3++) {
1162 } else if (c3 == 1) {
1165 } else if (c3 == 2) {
1168 } else if (c3 == 3) {
1171 } else if (c3 == 4) {
1174 } else if (c3 == 5) {
1178 if (player[c1].enabled == 1 && player[c2].enabled == 1) {
1179 if (labs(player[c1].x - player[c2].x) < (12L << 16) && labs(player[c1].y - player[c2].y) < (12L << 16)) {
1180 if ((labs(player[c1].y - player[c2].y) >> 16) > 5) {
1181 if (player[c1].y < player[c2].y) {
1182 if (player[c1].y_add >= 0) {
1184 serverSendKillPacket(c1, c2);
1186 if (player[c2].y_add < 0)
1187 player[c2].y_add = 0;
1190 if (player[c2].y_add >= 0) {
1192 serverSendKillPacket(c2, c1);
1194 if (player[c1].y_add < 0)
1195 player[c1].y_add = 0;
1199 if (player[c1].x < player[c2].x) {
1200 if (player[c1].x_add > 0)
1201 player[c1].x = player[c2].x - (12L << 16);
1202 else if (player[c2].x_add < 0)
1203 player[c2].x = player[c1].x + (12L << 16);
1205 player[c1].x -= player[c1].x_add;
1206 player[c2].x -= player[c2].x_add;
1208 l1 = player[c2].x_add;
1209 player[c2].x_add = player[c1].x_add;
1210 player[c1].x_add = l1;
1211 if (player[c1].x_add > 0)
1212 player[c1].x_add = -player[c1].x_add;
1213 if (player[c2].x_add < 0)
1214 player[c2].x_add = -player[c2].x_add;
1216 if (player[c1].x_add > 0)
1217 player[c2].x = player[c1].x - (12L << 16);
1218 else if (player[c2].x_add < 0)
1219 player[c1].x = player[c2].x + (12L << 16);
1221 player[c1].x -= player[c1].x_add;
1222 player[c2].x -= player[c2].x_add;
1224 l1 = player[c2].x_add;
1225 player[c2].x_add = player[c1].x_add;
1226 player[c1].x_add = l1;
1227 if (player[c1].x_add < 0)
1228 player[c1].x_add = -player[c1].x_add;
1229 if (player[c2].x_add > 0)
1230 player[c2].x_add = -player[c2].x_add;
1239 main_info.page_info[main_info.draw_page].num_pobs = 0;
1240 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1241 if (player[c1].enabled == 1)
1242 main_info.page_info[main_info.draw_page].num_pobs++;
1249 if (flies_enabled) {
1250 /* get center of fly swarm */
1252 for (c1 = 0; c1 < NUM_FLIES; c1++) {
1259 if (update_count == 1) {
1260 /* get closest player to fly swarm */
1262 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1263 if (player[c1].enabled == 1) {
1264 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)));
1265 if (cur_dist < dist) {
1266 closest_player = c1;
1271 /* update fly swarm sound */
1275 dj_set_sfx_channel_volume(4, (char)(s3));
1278 for (c1 = 0; c1 < NUM_FLIES; c1++) {
1279 /* get closest player to fly */
1281 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
1282 if (player[c2].enabled == 1) {
1283 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)));
1284 if (cur_dist < dist) {
1285 closest_player = c2;
1290 flies[c1].old_x = flies[c1].x;
1291 flies[c1].old_y = flies[c1].y;
1293 if ((s1 - flies[c1].x) > 30)
1295 else if ((s1 - flies[c1].x) < -30)
1298 if (((player[closest_player].x >> 16) + 8) > flies[c1].x) {
1299 if (lord_of_the_flies == 0)
1304 if (lord_of_the_flies == 0)
1310 s4 = rnd(3) - 1 + s3;
1311 if ((flies[c1].x + s4) < 16)
1313 if ((flies[c1].x + s4) > 351)
1315 if (ban_map[flies[c1].y >> 4][(flies[c1].x + s4) >> 4] != BAN_VOID)
1319 if ((s2 - flies[c1].y) > 30)
1321 else if ((s2 - flies[c1].y) < -30)
1324 if (((player[closest_player].y >> 16) + 8) > flies[c1].y) {
1325 if (lord_of_the_flies == 0)
1330 if (lord_of_the_flies == 0)
1336 s4 = rnd(3) - 1 + s3;
1337 if ((flies[c1].y + s4) < 0)
1339 if ((flies[c1].y + s4) > 239)
1341 if (ban_map[(flies[c1].y + s4) >> 4][flies[c1].x >> 4] != BAN_VOID)
1350 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1351 if (player[c1].enabled == 1) {
1352 main_info.page_info[main_info.draw_page].pobs[s1].x = player[c1].x >> 16;
1353 main_info.page_info[main_info.draw_page].pobs[s1].y = player[c1].y >> 16;
1354 main_info.page_info[main_info.draw_page].pobs[s1].image = player[c1].image + c1 * 18;
1355 main_info.page_info[main_info.draw_page].pobs[s1].pob_data = &rabbit_gobs;
1360 if (update_count == 1) {
1363 draw_pobs(main_info.draw_page);
1368 draw_flies(main_info.draw_page);
1373 if (mod_fade_direction == 1) {
1376 dj_set_mod_volume((char)mod_vol);
1381 dj_set_mod_volume((char)mod_vol);
1385 if (mod_fade_direction == 1) {
1388 dj_set_sfx_volume((char)sfx_vol);
1393 dj_set_sfx_volume((char)sfx_vol);
1398 for (c1 = 0; c1 < 768; c1++) {
1399 if (cur_pal[c1] < pal[c1]) {
1402 } else if (cur_pal[c1] > pal[c1]) {
1407 if (fade_flag == 0 && end_loop_flag == 1)
1410 if (update_count == 1) {
1411 main_info.draw_page ^= 1;
1412 main_info.view_page ^= 1;
1414 flippage(main_info.view_page);
1420 setpalette(0, 256, cur_pal);
1422 if (update_count == 1) {
1426 redraw_flies_background(main_info.draw_page);
1428 redraw_pob_backgrounds(main_info.draw_page);
1430 draw_leftovers(main_info.draw_page);
1440 if ( (player[client_player_num].dead_flag == 0) &&
1442 (player[client_player_num].action_left) ||
1443 (player[client_player_num].action_right) ||
1444 (player[client_player_num].action_up) ||
1445 (player[client_player_num].jump_ready == 0)
1448 tellServerNewPosition();
1453 update_count = intr_sysupdate();
1457 if ((server_said_bye) || ((fade_flag == 0) && (end_loop_flag == 1)))
1461 if ((fade_flag == 0) && (end_loop_flag == 1))
1468 serverTellEveryoneGoodbye();
1469 SDLNet_TCP_Close(sock);
1472 if (!server_said_bye) {
1473 tellServerGoodbye();
1476 SDLNet_TCP_Close(sock);
1482 main_info.view_page = 0;
1483 main_info.draw_page = 1;
1485 dj_stop_sfx_channel(4);
1489 memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
1490 register_mask(mask_pic);
1492 register_background(NULL, NULL);
1496 put_text(main_info.view_page, 100, 50, "DOTT", 2);
1497 put_text(main_info.view_page, 160, 50, "JIFFY", 2);
1498 put_text(main_info.view_page, 220, 50, "FIZZ", 2);
1499 put_text(main_info.view_page, 280, 50, "MIJJI", 2);
1500 put_text(main_info.view_page, 40, 80, "DOTT", 2);
1501 put_text(main_info.view_page, 40, 110, "JIFFY", 2);
1502 put_text(main_info.view_page, 40, 140, "FIZZ", 2);
1503 put_text(main_info.view_page, 40, 170, "MIJJI", 2);
1505 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1506 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
1508 sprintf(str1, "%d", player[c1].bumped[c2]);
1509 put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, str1, 2);
1511 put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, "-", 2);
1513 sprintf(str1, "%d", player[c1].bumps);
1514 put_text(main_info.view_page, 350, 80 + c1 * 30, str1, 2);
1517 put_text(main_info.view_page, 200, 230, "Press ESC to continue", 2);
1521 flippage(main_info.view_page);
1523 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
1524 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1527 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
1528 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1533 for (c1 = 0; c1 < 16; c1++) {
1534 pal[(240 + c1) * 3 + 0] = c1 << 2;
1535 pal[(240 + c1) * 3 + 1] = c1 << 2;
1536 pal[(240 + c1) * 3 + 2] = c1 << 2;
1539 memset(cur_pal, 0, 768);
1541 setpalette(0, 256, cur_pal);
1544 dj_ready_mod(MOD_SCORES);
1545 dj_set_mod_volume((char)mod_vol);
1549 while (key_pressed(1) == 0) {
1552 dj_set_mod_volume((char)mod_vol);
1553 for (c1 = 0; c1 < 768; c1++) {
1554 if (cur_pal[c1] < pal[c1])
1560 setpalette(0, 256, cur_pal);
1561 flippage(main_info.view_page);
1563 while (key_pressed(1) == 1) {
1568 memset(pal, 0, 768);
1570 while (mod_vol > 0) {
1572 dj_set_mod_volume((char)mod_vol);
1573 for (c1 = 0; c1 < 768; c1++) {
1574 if (cur_pal[c1] > pal[c1])
1579 setpalette(0, 256, cur_pal);
1580 flippage(main_info.view_page);
1583 fillpalette(0, 0, 0);
1589 break; /* don't go back to menu if in net game. */
1598 void steer_players(void)
1603 update_player_actions();
1605 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1607 if (player[c1].enabled == 1) {
1609 if (player[c1].dead_flag == 0) {
1611 if (player[c1].action_left && player[c1].action_right) {
1612 if (player[c1].direction == 0) {
1613 if (player[c1].action_right) {
1614 s1 = (player[c1].x >> 16);
1615 s2 = (player[c1].y >> 16);
1616 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1617 if (player[c1].x_add < 0)
1618 player[c1].x_add += 1024;
1620 player[c1].x_add += 768;
1621 } 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)) {
1622 if (player[c1].x_add > 0)
1623 player[c1].x_add += 1024;
1625 player[c1].x_add += 768;
1627 if (player[c1].x_add < 0) {
1628 player[c1].x_add += 16384;
1629 if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1630 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);
1632 player[c1].x_add += 12288;
1634 if (player[c1].x_add > 98304L)
1635 player[c1].x_add = 98304L;
1636 player[c1].direction = 0;
1637 if (player[c1].anim == 0) {
1638 player[c1].anim = 1;
1639 player[c1].frame = 0;
1640 player[c1].frame_tick = 0;
1641 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1645 if (player[c1].action_left) {
1646 s1 = (player[c1].x >> 16);
1647 s2 = (player[c1].y >> 16);
1648 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1649 if (player[c1].x_add > 0)
1650 player[c1].x_add -= 1024;
1652 player[c1].x_add -= 768;
1653 } 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)) {
1654 if (player[c1].x_add > 0)
1655 player[c1].x_add -= 1024;
1657 player[c1].x_add -= 768;
1659 if (player[c1].x_add > 0) {
1660 player[c1].x_add -= 16384;
1661 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1662 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);
1664 player[c1].x_add -= 12288;
1666 if (player[c1].x_add < -98304L)
1667 player[c1].x_add = -98304L;
1668 player[c1].direction = 1;
1669 if (player[c1].anim == 0) {
1670 player[c1].anim = 1;
1671 player[c1].frame = 0;
1672 player[c1].frame_tick = 0;
1673 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1677 } else if (player[c1].action_left) {
1678 s1 = (player[c1].x >> 16);
1679 s2 = (player[c1].y >> 16);
1680 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1681 if (player[c1].x_add > 0)
1682 player[c1].x_add -= 1024;
1684 player[c1].x_add -= 768;
1685 } 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)) {
1686 if (player[c1].x_add > 0)
1687 player[c1].x_add -= 1024;
1689 player[c1].x_add -= 768;
1691 if (player[c1].x_add > 0) {
1692 player[c1].x_add -= 16384;
1693 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1694 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);
1696 player[c1].x_add -= 12288;
1698 if (player[c1].x_add < -98304L)
1699 player[c1].x_add = -98304L;
1700 player[c1].direction = 1;
1701 if (player[c1].anim == 0) {
1702 player[c1].anim = 1;
1703 player[c1].frame = 0;
1704 player[c1].frame_tick = 0;
1705 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1707 } else if (player[c1].action_right) {
1708 s1 = (player[c1].x >> 16);
1709 s2 = (player[c1].y >> 16);
1710 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1711 if (player[c1].x_add < 0)
1712 player[c1].x_add += 1024;
1714 player[c1].x_add += 768;
1715 } 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)) {
1716 if (player[c1].x_add > 0)
1717 player[c1].x_add += 1024;
1719 player[c1].x_add += 768;
1721 if (player[c1].x_add < 0) {
1722 player[c1].x_add += 16384;
1723 if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1724 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);
1726 player[c1].x_add += 12288;
1728 if (player[c1].x_add > 98304L)
1729 player[c1].x_add = 98304L;
1730 player[c1].direction = 0;
1731 if (player[c1].anim == 0) {
1732 player[c1].anim = 1;
1733 player[c1].frame = 0;
1734 player[c1].frame_tick = 0;
1735 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1737 } else if ((!player[c1].action_left) && (!player[c1].action_right)) {
1738 s1 = (player[c1].x >> 16);
1739 s2 = (player[c1].y >> 16);
1740 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)))) {
1741 if (player[c1].x_add < 0) {
1742 player[c1].x_add += 16384;
1743 if (player[c1].x_add > 0)
1744 player[c1].x_add = 0;
1746 player[c1].x_add -= 16384;
1747 if (player[c1].x_add < 0)
1748 player[c1].x_add = 0;
1750 if (player[c1].x_add != 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1751 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);
1753 if (player[c1].anim == 1) {
1754 player[c1].anim = 0;
1755 player[c1].frame = 0;
1756 player[c1].frame_tick = 0;
1757 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1761 if (pogostick == 1 || (player[c1].jump_ready == 1 && player[c1].action_up)) {
1762 s1 = (player[c1].x >> 16);
1763 s2 = (player[c1].y >> 16);
1766 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) {
1767 player[c1].y_add = -280000L;
1768 player[c1].anim = 2;
1769 player[c1].frame = 0;
1770 player[c1].frame_tick = 0;
1771 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1772 player[c1].jump_ready = 0;
1773 player[c1].jump_abort = 1;
1775 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1777 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1779 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)) {
1780 player[c1].y_add = -196608L;
1781 player[c1].in_water = 0;
1782 player[c1].anim = 2;
1783 player[c1].frame = 0;
1784 player[c1].frame_tick = 0;
1785 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1786 player[c1].jump_ready = 0;
1787 player[c1].jump_abort = 1;
1789 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1791 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1794 if (pogostick == 0 && (!player[c1].action_up)) {
1795 player[c1].jump_ready = 1;
1796 if (player[c1].in_water == 0 && player[c1].y_add < 0 && player[c1].jump_abort == 1) {
1797 if (bunnies_in_space == 0)
1798 player[c1].y_add += 32768;
1800 player[c1].y_add += 16384;
1801 if (player[c1].y_add > 0)
1802 player[c1].y_add = 0;
1807 if (player[c1].action_up) {
1808 player[c1].y_add -= 16384;
1809 if (player[c1].y_add < -400000L)
1810 player[c1].y_add = -400000L;
1811 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))
1812 player[c1].in_water = 0;
1814 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);
1819 player[c1].x += player[c1].x_add;
1820 if ((player[c1].x >> 16) < 0) {
1822 player[c1].x_add = 0;
1824 if ((player[c1].x >> 16) + 15 > 351) {
1825 player[c1].x = 336L << 16;
1826 player[c1].x_add = 0;
1828 if (player[c1].y > 0) {
1829 s1 = (player[c1].x >> 16);
1830 s2 = (player[c1].y >> 16);
1831 if (ban_map[s2 >> 4][s1 >> 4] == BAN_SOLID || ban_map[s2 >> 4][s1 >> 4] == BAN_ICE || ban_map[s2 >> 4][s1 >> 4] == BAN_SPRING || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
1832 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1833 player[c1].x_add = 0;
1835 s1 = (player[c1].x >> 16);
1836 s2 = (player[c1].y >> 16);
1837 if (ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_SPRING || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1838 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1839 player[c1].x_add = 0;
1842 s1 = (player[c1].x >> 16);
1844 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) {
1845 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1846 player[c1].x_add = 0;
1848 s1 = (player[c1].x >> 16);
1850 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) {
1851 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1852 player[c1].x_add = 0;
1856 player[c1].y += player[c1].y_add;
1858 s1 = (player[c1].x >> 16);
1859 s2 = (player[c1].y >> 16);
1860 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))) {
1861 player[c1].y = ((player[c1].y >> 16) & 0xfff0) << 16;
1862 player[c1].y_add = -400000L;
1863 player[c1].anim = 2;
1864 player[c1].frame = 0;
1865 player[c1].frame_tick = 0;
1866 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1867 player[c1].jump_ready = 0;
1868 player[c1].jump_abort = 0;
1869 for (c2 = 0; c2 < NUM_OBJECTS; c2++) {
1870 if (objects[c2].used == 1 && objects[c2].type == OBJ_SPRING) {
1871 if (ban_map[(s2 + 15) >> 4][(s1 + 8) >> 4] == BAN_SPRING) {
1872 if ((objects[c2].x >> 20) == ((s1 + 8) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1873 objects[c2].frame = 0;
1874 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1875 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1879 if (ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
1880 if ((objects[c2].x >> 20) == (s1 >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1881 objects[c2].frame = 0;
1882 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1883 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1886 } else if (ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1887 if ((objects[c2].x >> 20) == ((s1 + 15) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1888 objects[c2].frame = 0;
1889 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1890 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1897 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1899 s1 = (player[c1].x >> 16);
1900 s2 = (player[c1].y >> 16);
1903 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) {
1904 player[c1].y = (((s2 + 16) & 0xfff0)) << 16;
1905 player[c1].y_add = 0;
1906 player[c1].anim = 0;
1907 player[c1].frame = 0;
1908 player[c1].frame_tick = 0;
1909 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1911 s1 = (player[c1].x >> 16);
1912 s2 = (player[c1].y >> 16);
1915 if (ban_map[(s2 + 8) >> 4][(s1 + 8) >> 4] == BAN_WATER) {
1916 if (player[c1].in_water == 0) {
1917 player[c1].in_water = 1;
1918 player[c1].anim = 4;
1919 player[c1].frame = 0;
1920 player[c1].frame_tick = 0;
1921 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1922 if (player[c1].y_add >= 32768) {
1923 add_object(OBJ_SPLASH, (player[c1].x >> 16) + 8, ((player[c1].y >> 16) & 0xfff0) + 15, 0, 0, OBJ_ANIM_SPLASH, 0);
1924 if (blood_is_thicker_than_water == 0)
1925 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1927 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 5000), 64, 0, 0, -1);
1930 player[c1].y_add -= 1536;
1931 if (player[c1].y_add < 0 && player[c1].anim != 5) {
1932 player[c1].anim = 5;
1933 player[c1].frame = 0;
1934 player[c1].frame_tick = 0;
1935 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1937 if (player[c1].y_add < -65536L)
1938 player[c1].y_add = -65536L;
1939 if (player[c1].y_add > 65535L)
1940 player[c1].y_add = 65535L;
1941 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) {
1942 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1943 player[c1].y_add = 0;
1945 } 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) {
1946 player[c1].in_water = 0;
1947 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1948 player[c1].y_add = 0;
1949 if (player[c1].anim != 0 && player[c1].anim != 1) {
1950 player[c1].anim = 0;
1951 player[c1].frame = 0;
1952 player[c1].frame_tick = 0;
1953 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1956 if (player[c1].in_water == 0) {
1957 if (bunnies_in_space == 0)
1958 player[c1].y_add += 12288;
1960 player[c1].y_add += 6144;
1961 if (player[c1].y_add > 327680L)
1962 player[c1].y_add = 327680L;
1964 player[c1].y = (player[c1].y & 0xffff0000) + 0x10000;
1965 player[c1].y_add = 0;
1967 player[c1].in_water = 0;
1969 if (player[c1].y_add > 36864 && player[c1].anim != 3 && player[c1].in_water == 0) {
1970 player[c1].anim = 3;
1971 player[c1].frame = 0;
1972 player[c1].frame_tick = 0;
1973 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1978 player[c1].frame_tick++;
1979 if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
1981 if (player[c1].frame >= player_anims[player[c1].anim].num_frames) {
1982 if (player[c1].anim != 6)
1983 player[c1].frame = player_anims[player[c1].anim].restart_frame;
1985 position_player(c1);
1987 player[c1].frame_tick = 0;
1989 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1998 void position_player(int player_num)
2007 if (ban_map[s2][s1] == BAN_VOID && (ban_map[s2 + 1][s1] == BAN_SOLID || ban_map[s2 + 1][s1] == BAN_ICE))
2010 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
2011 if (c1 != player_num && player[c1].enabled == 1) {
2012 if (abs((s1 << 4) - (player[c1].x >> 16)) < 32 && abs((s2 << 4) - (player[c1].y >> 16)) < 32)
2016 if (c1 == JNB_MAX_PLAYERS) {
2017 player[player_num].x = (long) s1 << 20;
2018 player[player_num].y = (long) s2 << 20;
2019 player[player_num].x_add = player[player_num].y_add = 0;
2020 player[player_num].direction = 0;
2021 player[player_num].jump_ready = 1;
2022 player[player_num].in_water = 0;
2023 player[player_num].anim = 0;
2024 player[player_num].frame = 0;
2025 player[player_num].frame_tick = 0;
2026 player[player_num].image = player_anims[player[player_num].anim].frame[player[player_num].frame].image;
2031 serverSendAlive(player_num);
2033 player[player_num].dead_flag = 0;
2043 void add_object(int type, int x, int y, int x_add, int y_add, int anim, int frame)
2047 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
2048 if (objects[c1].used == 0) {
2049 objects[c1].used = 1;
2050 objects[c1].type = type;
2051 objects[c1].x = (long) x << 16;
2052 objects[c1].y = (long) y << 16;
2053 objects[c1].x_add = x_add;
2054 objects[c1].y_add = y_add;
2055 objects[c1].x_acc = 0;
2056 objects[c1].y_acc = 0;
2057 objects[c1].anim = anim;
2058 objects[c1].frame = frame;
2059 objects[c1].ticks = object_anims[anim].frame[frame].ticks;
2060 objects[c1].image = object_anims[anim].frame[frame].image;
2068 void update_objects(void)
2073 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
2074 if (objects[c1].used == 1) {
2075 switch (objects[c1].type) {
2077 objects[c1].ticks--;
2078 if (objects[c1].ticks <= 0) {
2079 objects[c1].frame++;
2080 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames) {
2081 objects[c1].frame--;
2082 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2084 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2085 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2088 if (objects[c1].used == 1)
2089 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2092 objects[c1].ticks--;
2093 if (objects[c1].ticks <= 0) {
2094 objects[c1].frame++;
2095 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2096 objects[c1].used = 0;
2098 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2099 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2102 if (objects[c1].used == 1)
2103 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2106 objects[c1].x += objects[c1].x_add;
2107 objects[c1].y += objects[c1].y_add;
2108 objects[c1].ticks--;
2109 if (objects[c1].ticks <= 0) {
2110 objects[c1].frame++;
2111 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2112 objects[c1].used = 0;
2114 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2115 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2118 if (objects[c1].used == 1)
2119 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2121 case OBJ_YEL_BUTFLY:
2122 case OBJ_PINK_BUTFLY:
2123 objects[c1].x_acc += rnd(128) - 64;
2124 if (objects[c1].x_acc < -1024)
2125 objects[c1].x_acc = -1024;
2126 if (objects[c1].x_acc > 1024)
2127 objects[c1].x_acc = 1024;
2128 objects[c1].x_add += objects[c1].x_acc;
2129 if (objects[c1].x_add < -32768)
2130 objects[c1].x_add = -32768;
2131 if (objects[c1].x_add > 32768)
2132 objects[c1].x_add = 32768;
2133 objects[c1].x += objects[c1].x_add;
2134 if ((objects[c1].x >> 16) < 16) {
2135 objects[c1].x = 16 << 16;
2136 objects[c1].x_add = -objects[c1].x_add >> 2;
2137 objects[c1].x_acc = 0;
2138 } else if ((objects[c1].x >> 16) > 350) {
2139 objects[c1].x = 350 << 16;
2140 objects[c1].x_add = -objects[c1].x_add >> 2;
2141 objects[c1].x_acc = 0;
2143 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
2144 if (objects[c1].x_add < 0) {
2145 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2147 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2149 objects[c1].x_add = -objects[c1].x_add >> 2;
2150 objects[c1].x_acc = 0;
2152 objects[c1].y_acc += rnd(64) - 32;
2153 if (objects[c1].y_acc < -1024)
2154 objects[c1].y_acc = -1024;
2155 if (objects[c1].y_acc > 1024)
2156 objects[c1].y_acc = 1024;
2157 objects[c1].y_add += objects[c1].y_acc;
2158 if (objects[c1].y_add < -32768)
2159 objects[c1].y_add = -32768;
2160 if (objects[c1].y_add > 32768)
2161 objects[c1].y_add = 32768;
2162 objects[c1].y += objects[c1].y_add;
2163 if ((objects[c1].y >> 16) < 0) {
2165 objects[c1].y_add = -objects[c1].y_add >> 2;
2166 objects[c1].y_acc = 0;
2167 } else if ((objects[c1].y >> 16) > 255) {
2168 objects[c1].y = 255 << 16;
2169 objects[c1].y_add = -objects[c1].y_add >> 2;
2170 objects[c1].y_acc = 0;
2172 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
2173 if (objects[c1].y_add < 0) {
2174 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2176 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2178 objects[c1].y_add = -objects[c1].y_add >> 2;
2179 objects[c1].y_acc = 0;
2181 if (objects[c1].type == OBJ_YEL_BUTFLY) {
2182 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_LEFT) {
2183 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_LEFT;
2184 objects[c1].frame = 0;
2185 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2186 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2187 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_RIGHT) {
2188 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_RIGHT;
2189 objects[c1].frame = 0;
2190 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2191 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2194 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_LEFT) {
2195 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_LEFT;
2196 objects[c1].frame = 0;
2197 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2198 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2199 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_RIGHT) {
2200 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_RIGHT;
2201 objects[c1].frame = 0;
2202 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2203 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2206 objects[c1].ticks--;
2207 if (objects[c1].ticks <= 0) {
2208 objects[c1].frame++;
2209 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2210 objects[c1].frame = object_anims[objects[c1].anim].restart_frame;
2212 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2213 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2216 if (objects[c1].used == 1)
2217 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2221 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 0);
2222 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
2223 objects[c1].y_add += 3072;
2224 if (objects[c1].y_add > 196608L)
2225 objects[c1].y_add = 196608L;
2226 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
2227 if (objects[c1].x_add < 0) {
2228 if (objects[c1].x_add < -65536L)
2229 objects[c1].x_add = -65536L;
2230 objects[c1].x_add += 1024;
2231 if (objects[c1].x_add > 0)
2232 objects[c1].x_add = 0;
2234 if (objects[c1].x_add > 65536L)
2235 objects[c1].x_add = 65536L;
2236 objects[c1].x_add -= 1024;
2237 if (objects[c1].x_add < 0)
2238 objects[c1].x_add = 0;
2240 objects[c1].y_add += 1024;
2241 if (objects[c1].y_add < -65536L)
2242 objects[c1].y_add = -65536L;
2243 if (objects[c1].y_add > 65536L)
2244 objects[c1].y_add = 65536L;
2246 objects[c1].x += objects[c1].x_add;
2247 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)) {
2248 if (objects[c1].x_add < 0) {
2249 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2250 objects[c1].x_add = -objects[c1].x_add >> 2;
2252 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2253 objects[c1].x_add = -objects[c1].x_add >> 2;
2256 objects[c1].y += objects[c1].y_add;
2257 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
2258 objects[c1].used = 0;
2259 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
2260 if (objects[c1].y_add < 0) {
2261 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
2262 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2263 objects[c1].x_add >>= 2;
2264 objects[c1].y_add = -objects[c1].y_add >> 2;
2267 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
2268 if (objects[c1].y_add > 131072L) {
2269 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2270 objects[c1].x_add >>= 2;
2271 objects[c1].y_add = -objects[c1].y_add >> 2;
2273 objects[c1].used = 0;
2274 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
2275 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2276 if (objects[c1].y_add > 131072L)
2277 objects[c1].y_add = -objects[c1].y_add >> 2;
2279 objects[c1].y_add = 0;
2283 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
2284 objects[c1].x_add = -16384;
2285 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
2286 objects[c1].x_add = 16384;
2287 if (objects[c1].used == 1) {
2288 s1 = (int)(atan2(objects[c1].y_add, objects[c1].x_add) * 4 / M_PI);
2295 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame + s1, &object_gobs);
2299 if (rnd(100) < 30) {
2300 if (objects[c1].frame == 76)
2301 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 1);
2302 else if (objects[c1].frame == 77)
2303 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 2);
2304 else if (objects[c1].frame == 78)
2305 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 3);
2307 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
2308 objects[c1].y_add += 3072;
2309 if (objects[c1].y_add > 196608L)
2310 objects[c1].y_add = 196608L;
2311 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
2312 if (objects[c1].x_add < 0) {
2313 if (objects[c1].x_add < -65536L)
2314 objects[c1].x_add = -65536L;
2315 objects[c1].x_add += 1024;
2316 if (objects[c1].x_add > 0)
2317 objects[c1].x_add = 0;
2319 if (objects[c1].x_add > 65536L)
2320 objects[c1].x_add = 65536L;
2321 objects[c1].x_add -= 1024;
2322 if (objects[c1].x_add < 0)
2323 objects[c1].x_add = 0;
2325 objects[c1].y_add += 1024;
2326 if (objects[c1].y_add < -65536L)
2327 objects[c1].y_add = -65536L;
2328 if (objects[c1].y_add > 65536L)
2329 objects[c1].y_add = 65536L;
2331 objects[c1].x += objects[c1].x_add;
2332 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)) {
2333 if (objects[c1].x_add < 0) {
2334 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2335 objects[c1].x_add = -objects[c1].x_add >> 2;
2337 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2338 objects[c1].x_add = -objects[c1].x_add >> 2;
2341 objects[c1].y += objects[c1].y_add;
2342 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
2343 objects[c1].used = 0;
2344 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
2345 if (objects[c1].y_add < 0) {
2346 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
2347 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2348 objects[c1].x_add >>= 2;
2349 objects[c1].y_add = -objects[c1].y_add >> 2;
2352 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
2353 if (objects[c1].y_add > 131072L) {
2354 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2355 objects[c1].x_add >>= 2;
2356 objects[c1].y_add = -objects[c1].y_add >> 2;
2358 if (rnd(100) < 10) {
2360 add_leftovers(0, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
2361 add_leftovers(1, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
2363 objects[c1].used = 0;
2365 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
2366 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2367 if (objects[c1].y_add > 131072L)
2368 objects[c1].y_add = -objects[c1].y_add >> 2;
2370 objects[c1].y_add = 0;
2374 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
2375 objects[c1].x_add = -16384;
2376 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
2377 objects[c1].x_add = 16384;
2378 if (objects[c1].used == 1)
2379 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame, &object_gobs);
2381 case OBJ_FLESH_TRACE:
2382 objects[c1].ticks--;
2383 if (objects[c1].ticks <= 0) {
2384 objects[c1].frame++;
2385 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2386 objects[c1].used = 0;
2388 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2389 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2392 if (objects[c1].used == 1)
2393 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2402 int add_pob(int page, int x, int y, int image, gob_t *pob_data)
2405 if (main_info.page_info[page].num_pobs >= NUM_POBS)
2408 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].x = x;
2409 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].y = y;
2410 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].image = image;
2411 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].pob_data = pob_data;
2412 main_info.page_info[page].num_pobs++;
2419 void draw_flies(int page)
2423 for (c2 = 0; c2 < NUM_FLIES; c2++) {
2424 flies[c2].back[main_info.draw_page] = get_pixel(main_info.draw_page, flies[c2].x, flies[c2].y);
2425 flies[c2].back_defined[main_info.draw_page] = 1;
2426 if (mask_pic[(flies[c2].y * JNB_WIDTH) + flies[c2].x] == 0)
2427 set_pixel(main_info.draw_page, flies[c2].x, flies[c2].y, 0);
2431 void draw_pobs(int page)
2438 for (c1 = main_info.page_info[page].num_pobs - 1; c1 >= 0; c1--) {
2439 main_info.page_info[page].pobs[c1].back_buf_ofs = back_buf_ofs;
2440 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);
2442 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;
2444 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;
2445 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);
2451 void redraw_flies_background(int page)
2455 for (c2 = NUM_FLIES - 1; c2 >= 0; c2--) {
2456 if (flies[c2].back_defined[page] == 1)
2457 set_pixel(page, flies[c2].old_draw_x, flies[c2].old_draw_y, flies[c2].back[page]);
2458 flies[c2].old_draw_x = flies[c2].x;
2459 flies[c2].old_draw_y = flies[c2].y;
2464 void redraw_pob_backgrounds(int page)
2468 for (c1 = 0; c1 < main_info.page_info[page].num_pobs; c1++)
2469 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);
2474 int add_leftovers(int page, int x, int y, int image, gob_t *pob_data)
2477 if (leftovers.page[page].num_pobs >= NUM_LEFTOVERS)
2480 leftovers.page[page].pobs[leftovers.page[page].num_pobs].x = x;
2481 leftovers.page[page].pobs[leftovers.page[page].num_pobs].y = y;
2482 leftovers.page[page].pobs[leftovers.page[page].num_pobs].image = image;
2483 leftovers.page[page].pobs[leftovers.page[page].num_pobs].pob_data = pob_data;
2484 leftovers.page[page].num_pobs++;
2491 void draw_leftovers(int page)
2495 for (c1 = leftovers.page[page].num_pobs - 1; c1 >= 0; c1--)
2496 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);
2498 leftovers.page[page].num_pobs = 0;
2503 int init_level(int level, char *pal)
2505 unsigned char *handle;
2509 if ((handle = dat_open("level.pcx", datfile_name, "rb")) == 0) {
2510 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2513 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
2514 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2518 flip_pixels(background_pic);
2519 if ((handle = dat_open("mask.pcx", datfile_name, "rb")) == 0) {
2520 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2523 if (read_pcx(handle, mask_pic, JNB_WIDTH*JNB_HEIGHT, 0) != 0) {
2524 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2528 flip_pixels(mask_pic);
2529 register_mask(mask_pic);
2531 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
2532 if (player[c1].enabled == 1) {
2533 player[c1].bumps = 0;
2534 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++)
2535 player[c1].bumped[c2] = 0;
2536 position_player(c1);
2540 for (c1 = 0; c1 < NUM_OBJECTS; c1++)
2541 objects[c1].used = 0;
2543 for (c1 = 0; c1 < 16; c1++) {
2544 for (c2 = 0; c2 < 22; c2++) {
2545 if (ban_map[c1][c2] == BAN_SPRING)
2546 add_object(OBJ_SPRING, c2 << 4, c1 << 4, 0, 0, OBJ_ANIM_SPRING, 5);
2553 if (ban_map[s2][s1] == BAN_VOID) {
2554 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2561 if (ban_map[s2][s1] == BAN_VOID) {
2562 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2569 if (ban_map[s2][s1] == BAN_VOID) {
2570 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2577 if (ban_map[s2][s1] == BAN_VOID) {
2578 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2588 void deinit_level(void)
2596 #define PATH_MAX 1024
2602 unsigned char *datafile_buffer = NULL;
2604 static void preread_datafile(const char *fname)
2610 char *gzfilename = alloca(strlen(fname) + 4);
2615 strcpy(gzfilename, fname);
2616 strcat(gzfilename, ".gz");
2618 gzf = gzopen(gzfilename, "rb");
2623 if (bufpos >= bufsize) {
2624 bufsize += 1024 * 1024;
2625 datafile_buffer = (unsigned char *) realloc(datafile_buffer, bufsize);
2626 if (datafile_buffer == NULL) {
2627 perror("realloc()");
2632 br = gzread(gzf, datafile_buffer + bufpos, bufsize - bufpos);
2634 fprintf(stderr, "gzread failed.\n");
2639 } while (!gzeof(gzf));
2641 /* try to shrink buffer... */
2642 ptr = (unsigned char *) realloc(datafile_buffer, bufpos);
2644 datafile_buffer = ptr;
2650 /* drop through and try for an uncompressed datafile... */
2653 fd = open(fname, O_RDONLY | O_BINARY);
2655 fprintf(stderr, "can't open %s:", fname);
2660 len = filelength(fd);
2661 datafile_buffer = (unsigned char *) malloc(len);
2662 if (datafile_buffer == NULL) {
2668 if (read(fd, datafile_buffer, len) != len) {
2678 int init_program(int argc, char *argv[], char *pal)
2680 char *netarg = NULL;
2681 unsigned char *handle = (unsigned char *) NULL;
2686 int player_anim_data[] = {
2687 1, 0, 0, 0x7fff, 0, 0, 0, 0, 0, 0,
2688 4, 0, 0, 4, 1, 4, 2, 4, 3, 4,
2689 1, 0, 4, 0x7fff, 0, 0, 0, 0, 0, 0,
2690 4, 2, 5, 8, 6, 10, 7, 3, 6, 3,
2691 1, 0, 6, 0x7fff, 0, 0, 0, 0, 0, 0,
2692 2, 1, 5, 8, 4, 0x7fff, 0, 0, 0, 0,
2693 1, 0, 8, 5, 0, 0, 0, 0, 0, 0
2697 memset(&net_info, 0, sizeof(net_info));
2701 if (__djgpp_nearptr_enable() == 0)
2707 if (hook_keyb_handler() != 0)
2710 memset(&main_info, 0, sizeof(main_info));
2712 strcpy(datfile_name, DATA_PATH);
2714 force2 = force3 = 0;
2717 for (c1 = 1; c1 < argc; c1++) {
2718 if (stricmp(argv[c1], "-nosound") == 0)
2719 main_info.no_sound = 1;
2720 else if (stricmp(argv[c1], "-musicnosound") == 0)
2721 main_info.music_no_sound = 1;
2722 else if (stricmp(argv[c1], "-nogore") == 0)
2723 main_info.no_gore = 1;
2724 else if (stricmp(argv[c1], "-noflies") == 0)
2726 else if (stricmp(argv[c1], "-nojoy") == 0)
2727 main_info.joy_enabled = 0;
2728 else if (stricmp(argv[c1], "-fireworks") == 0)
2729 main_info.fireworks = 1;
2731 else if (stricmp(argv[c1], "-fullscreen") == 0)
2734 else if (stricmp(argv[c1], "-scaleup") == 0)
2736 else if (stricmp(argv[c1], "-mirror") == 0)
2738 else if (stricmp(argv[c1], "-dat") == 0) {
2739 if (c1 < (argc - 1)) {
2742 if ((f = fopen(argv[c1 + 1], "rb")) != NULL) {
2744 strcpy(datfile_name, argv[c1 + 1]);
2747 } else if (stricmp(argv[c1], "-player") == 0) {
2748 if (c1 < (argc - 1)) {
2749 if (client_player_num < 0)
2750 client_player_num = atoi(argv[c1 + 1]);
2753 } else if (stricmp(argv[c1], "-server") == 0) {
2754 if (c1 < (argc - 1)) {
2757 netarg = argv[c1 + 1];
2759 } else if (stricmp(argv[c1], "-connect") == 0) {
2760 if (c1 < (argc - 1)) {
2763 netarg = argv[c1 + 1];
2766 } else if (stricmp(argv[c1], "-mouse") == 0) {
2767 if (c1 < (argc - 1)) {
2768 if (stricmp(argv[c1 + 1], "2") == 0)
2770 if (stricmp(argv[c1 + 1], "3") == 0)
2774 else if (strstr(argv[1],"-v")) {
2775 printf("jumpnbump %s compiled %s at %s with",JNB_VERSION,__DATE__,__TIME__);
2779 printf(" network support.\n");
2782 else if (strstr(argv[1],"-h")) {
2783 printf("Usage: jumpnbump [OPTION]...\n");
2785 printf(" -h this help\n");
2786 printf(" -v print version\n");
2787 printf(" -dat level.dat play a different level\n");
2789 printf(" -server playercount start as server waiting for players\n");
2790 printf(" -connect host connect to server\n");
2792 printf(" -player num set main player to num (0-3). Needed for networking\n");
2793 printf(" -fireworks screensaver mode\n");
2794 printf(" -fullscreen run in fullscreen mode\n");
2795 printf(" -nosound play without sound\n");
2796 printf(" -nogore play without blood\n");
2797 printf(" -noflies disable flies\n");
2798 printf(" -mirror play with mirrored level\n");
2799 printf(" -scaleup play with doubled resolution (800x512)\n");
2800 printf(" -musicnosound play with music but without sound\n");
2807 preread_datafile(datfile_name);
2810 if (client_player_num < 0)
2811 client_player_num = 0;
2812 player[client_player_num].enabled = 1;
2815 main_info.pob_backbuf[0] = malloc(screen_pitch*screen_height*bytes_per_pixel);
2816 main_info.pob_backbuf[1] = malloc(screen_pitch*screen_height*bytes_per_pixel);
2818 for (c1 = 0; c1 < 7; c1++) {
2819 player_anims[c1].num_frames = player_anim_data[c1 * 10];
2820 player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
2821 for (c2 = 0; c2 < 4; c2++) {
2822 player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
2823 player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
2827 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
2828 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2831 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
2832 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2836 if ((handle = dat_open("rabbit.gob", datfile_name, "rb")) == 0) {
2837 strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
2840 if (register_gob(handle, &rabbit_gobs, dat_filelen("rabbit.gob", datfile_name))) {
2845 if ((handle = dat_open("objects.gob", datfile_name, "rb")) == 0) {
2846 strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
2849 if (register_gob(handle, &object_gobs, dat_filelen("objects.gob", datfile_name))) {
2854 if ((handle = dat_open("font.gob", datfile_name, "rb")) == 0) {
2855 strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
2858 if (register_gob(handle, &font_gobs, dat_filelen("font.gob", datfile_name))) {
2863 if ((handle = dat_open("numbers.gob", datfile_name, "rb")) == 0) {
2864 strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
2867 if (register_gob(handle, &number_gobs, dat_filelen("numbers.gob", datfile_name))) {
2872 if (read_level() != 0) {
2873 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2879 if (main_info.no_sound == 0) {
2881 dj_set_mixing_freq(20000);
2885 dj_set_num_sfx_channels(5);
2886 dj_set_sfx_volume(64);
2890 if ((handle = dat_open("jump.mod", datfile_name, "rb")) == 0) {
2891 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2894 if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
2895 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2899 if ((handle = dat_open("bump.mod", datfile_name, "rb")) == 0) {
2900 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2903 if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
2904 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2908 if ((handle = dat_open("scores.mod", datfile_name, "rb")) == 0) {
2909 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2912 if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
2913 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2917 if ((handle = dat_open("jump.smp", datfile_name, "rb")) == 0) {
2918 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2921 if (dj_load_sfx(handle, 0, dat_filelen("jump.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
2922 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2926 if ((handle = dat_open("death.smp", datfile_name, "rb")) == 0) {
2927 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2930 if (dj_load_sfx(handle, 0, dat_filelen("death.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
2931 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2935 if ((handle = dat_open("spring.smp", datfile_name, "rb")) == 0) {
2936 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2939 if (dj_load_sfx(handle, 0, dat_filelen("spring.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
2940 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2944 if ((handle = dat_open("splash.smp", datfile_name, "rb")) == 0) {
2945 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2948 if (dj_load_sfx(handle, 0, dat_filelen("splash.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
2949 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2953 if ((handle = dat_open("fly.smp", datfile_name, "rb")) == 0) {
2954 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2957 if (dj_load_sfx(handle, 0, dat_filelen("fly.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
2958 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2962 dj_get_sfx_settings(SFX_FLY, &fly);
2964 fly.default_freq = SFX_FLY_FREQ;
2967 fly.loop_length = fly.length;
2968 dj_set_sfx_settings(SFX_FLY, &fly);
2971 if ((background_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
2973 if ((mask_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
2975 memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
2976 register_mask(mask_pic);
2979 for (c1 = 0; c1 < 16; c1++) {
2980 pal[(240 + c1) * 3 + 0] = c1 << 2;
2981 pal[(240 + c1) * 3 + 1] = c1 << 2;
2982 pal[(240 + c1) * 3 + 2] = c1 << 2;
2985 setpalette(0, 256, pal);
2989 recalculate_gob(&font_gobs, pal);
2991 if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
2993 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2994 put_text(0, 200, 100, "Move the joystick to the", 2);
2995 put_text(0, 200, 115, "UPPER LEFT", 2);
2996 put_text(0, 200, 130, "and press button A", 2);
2997 put_text(0, 200, 200, "Or press ESC to use", 2);
2998 put_text(0, 200, 215, "previous settings", 2);
2999 if (calib_joy(0) != 0)
3002 register_background(NULL, NULL);
3004 main_info.view_page = 1;
3009 put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
3010 put_text(1, 200, 100, "Move the joystick to the", 2);
3011 put_text(1, 200, 115, "LOWER RIGHT", 2);
3012 put_text(1, 200, 130, "and press button A", 2);
3013 put_text(1, 200, 200, "Or press ESC to use", 2);
3014 put_text(1, 200, 215, "previous settings", 2);
3015 if (calib_joy(1) != 0)
3018 register_background(NULL, NULL);
3023 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
3024 put_text(0, 200, 100, "Move the joystick to the", 2);
3025 put_text(0, 200, 115, "CENTER", 2);
3026 put_text(0, 200, 130, "and press button A", 2);
3027 put_text(0, 200, 200, "Or press ESC to use", 2);
3028 put_text(0, 200, 215, "previous settings", 2);
3029 if (calib_joy(2) != 0)
3032 if (joy.calib_data.x1 == joy.calib_data.x2)
3033 joy.calib_data.x1 -= 10;
3034 if (joy.calib_data.x3 == joy.calib_data.x2)
3035 joy.calib_data.x3 += 10;
3036 if (joy.calib_data.y1 == joy.calib_data.y2)
3037 joy.calib_data.y1 -= 10;
3038 if (joy.calib_data.y3 == joy.calib_data.y2)
3039 joy.calib_data.y3 += 10;
3044 if (load_flag == 1) {
3045 if ((handle = dat_open("calib.dat", datfile_name, "rb")) == 0) {
3046 strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
3049 joy.calib_data.x1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3050 joy.calib_data.x2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3051 joy.calib_data.x3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3052 joy.calib_data.y1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3053 joy.calib_data.y2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3054 joy.calib_data.y3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3061 init_server(netarg);
3063 connect_to_server(netarg);
3072 void deinit_program(void)
3079 dj_free_mod(MOD_MENU);
3080 dj_free_mod(MOD_GAME);
3081 dj_free_sfx(SFX_DEATH);
3082 dj_free_sfx(SFX_SPRING);
3083 dj_free_sfx(SFX_SPLASH);
3086 if (background_pic != 0)
3087 free(background_pic);
3091 remove_keyb_handler();
3095 __dpmi_int(0x10, ®s);
3098 if (main_info.error_str[0] != 0) {
3099 printf(main_info.error_str);
3101 MessageBox(0, main_info.error_str, "Jump'n'Bump", 0);
3110 unsigned short rnd(unsigned short max)
3112 return (rand() % max);
3116 int read_level(void)
3118 unsigned char *handle;
3122 if ((handle = dat_open("levelmap.txt", datfile_name, "rb")) == 0) {
3123 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
3127 for (c1 = 0; c1 < 16; c1++) {
3128 for (c2 = 0; c2 < 22; c2++) {
3130 chr = (int) *(handle++);
3131 if (chr >= '0' && chr <= '4')
3135 ban_map[c1][21-c2] = chr - '0';
3137 ban_map[c1][c2] = chr - '0';
3141 for (c2 = 0; c2 < 22; c2++)
3142 ban_map[16][c2] = BAN_SOLID;
3149 unsigned char *dat_open(char *file_name, char *dat_name, char *mode)
3157 if (datafile_buffer == NULL)
3160 memset(name, 0, sizeof(name));
3162 num = ( (datafile_buffer[0] << 0) +
3163 (datafile_buffer[1] << 8) +
3164 (datafile_buffer[2] << 16) +
3165 (datafile_buffer[3] << 24) );
3167 ptr = datafile_buffer + 4;
3169 for (c1 = 0; c1 < num; c1++) {
3171 memcpy(name, ptr, 12);
3174 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
3175 ofs = ( (ptr[0] << 0) +
3180 return (datafile_buffer + ofs);
3189 int dat_filelen(char *file_name, char *dat_name)
3197 memset(name, 0, sizeof(name));
3199 num = ( (datafile_buffer[0] << 0) +
3200 (datafile_buffer[1] << 8) +
3201 (datafile_buffer[2] << 16) +
3202 (datafile_buffer[3] << 24) );
3204 ptr = datafile_buffer + 4;
3206 for (c1 = 0; c1 < num; c1++) {
3208 memcpy(name, ptr, 12);
3211 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
3214 len = ( (ptr[0] << 0) +
3228 void write_calib_data(void)
3236 if ((handle = fopen(datfile_name, "rb")) == NULL)
3238 len = filelength(fileno(handle));
3239 if ((mem = malloc(len)) == NULL)
3241 fread(mem, 1, len, handle);
3245 num = *(int *) (&mem[0]);
3246 for (c1 = 0; c1 < num; c1++) {
3247 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
3248 ofs = *(int *) (&mem[ofs + 12]);
3254 mem[ofs] = joy.calib_data.x1 & 0xff;
3255 mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
3256 mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
3257 mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
3258 mem[ofs + 4] = joy.calib_data.x2 & 0xff;
3259 mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
3260 mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
3261 mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
3262 mem[ofs + 8] = joy.calib_data.x3 & 0xff;
3263 mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
3264 mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
3265 mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
3266 mem[ofs + 12] = joy.calib_data.y1 & 0xff;
3267 mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
3268 mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
3269 mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
3270 mem[ofs + 16] = joy.calib_data.y2 & 0xff;
3271 mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
3272 mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
3273 mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
3274 mem[ofs + 20] = joy.calib_data.y3 & 0xff;
3275 mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
3276 mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
3277 mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
3279 if ((handle = fopen(datfile_name, "wb")) == NULL)
3281 fwrite(mem, 1, len, handle);