3 * Copyright (C) 1998 Brainchild Design - http://brainchilddesign.com/
5 * Copyright (C) 2001 Chuck Mason <cemason@users.sourceforge.net>
7 * Copyright (C) 2002 Florian Schulze <crow@icculus.org>
9 * Portions of this code are from the MPEG software simulation group
10 * idct implementation. This code will be replaced with a new
11 * implementation soon.
13 * This file is part of Jump'n'Bump.
15 * Jump'n'Bump is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * Jump'n'Bump is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
40 #define M_PI 3.14159265358979323846
43 gob_t rabbit_gobs = { 0 };
44 gob_t font_gobs = { 0 };
45 gob_t object_gobs = { 0 };
46 gob_t number_gobs = { 0 };
48 main_info_t main_info;
49 player_t player[JNB_MAX_PLAYERS];
50 player_anim_t player_anims[7];
51 object_t objects[NUM_OBJECTS];
55 char datfile_name[2048];
61 unsigned int ban_map[17][22] = {
62 {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
63 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0},
64 {1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
65 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1},
66 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
67 {1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
68 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1},
69 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
70 {1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
71 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1},
72 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1},
73 {1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1},
74 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
75 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
76 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 1, 3, 3, 3, 1, 1, 1},
77 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
78 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
204 int flies_enabled = 1;
209 int old_draw_x, old_draw_y;
221 } pobs[NUM_LEFTOVERS];
225 int pogostick, bunnies_in_space, jetpack, lord_of_the_flies, blood_is_thicker_than_water;
229 int filelength(int handle)
233 if (fstat(handle, &buf) == -1) {
234 perror("filelength");
243 /* networking shite. */
245 int client_player_num = -1;
250 TCPsocket sock = NULL;
251 SDLNet_SocketSet socketset = NULL;
257 SDLNet_SocketSet socketset;
260 NetInfo net_info[JNB_MAX_PLAYERS];
272 #define NETPKTBUFSIZE (4 + 4 + 4 + 4 + 4)
274 #define NETCMD_NACK (0xF00DF00D + 0)
275 #define NETCMD_ACK (0xF00DF00D + 1)
276 #define NETCMD_HELLO (0xF00DF00D + 2)
277 #define NETCMD_GREENLIGHT (0xF00DF00D + 3)
278 #define NETCMD_MOVE (0xF00DF00D + 4)
279 #define NETCMD_BYE (0xF00DF00D + 5)
280 #define NETCMD_POSITION (0xF00DF00D + 6)
281 #define NETCMD_ALIVE (0xF00DF00D + 7)
282 #define NETCMD_KILL (0xF00DF00D + 8)
286 void bufToPacket(const char *buf, NetPacket *pkt)
288 SDLNet_Write32(*((unsigned long *) (buf + 0)), &pkt->cmd);
289 SDLNet_Write32(*((unsigned long *) (buf + 4)), &pkt->arg);
290 SDLNet_Write32(*((unsigned long *) (buf + 8)), &pkt->arg2);
291 SDLNet_Write32(*((unsigned long *) (buf + 12)), &pkt->arg3);
292 SDLNet_Write32(*((unsigned long *) (buf + 16)), &pkt->arg4);
294 pkt->cmd = ntohl(*((unsigned long *) (buf + 0)));
295 pkt->arg = (long) ntohl(*((unsigned long *) (buf + 4)));
296 pkt->arg2 = (long) ntohl(*((unsigned long *) (buf + 8)));
297 pkt->arg3 = (long) ntohl(*((unsigned long *) (buf + 12)));
298 pkt->arg4 = (long) ntohl(*((unsigned long *) (buf + 16)));
303 void packetToBuf(const NetPacket *pkt, char *buf)
305 *((unsigned long *) (buf + 0)) = SDLNet_Read32(&pkt->cmd);
306 *((unsigned long *) (buf + 4)) = SDLNet_Read32(&pkt->arg);
307 *((unsigned long *) (buf + 8)) = SDLNet_Read32(&pkt->arg2);
308 *((unsigned long *) (buf + 12)) = SDLNet_Read32(&pkt->arg3);
309 *((unsigned long *) (buf + 16)) = SDLNet_Read32(&pkt->arg4);
311 *((unsigned long *) (buf + 0)) = htonl(pkt->cmd);
312 *((unsigned long *) (buf + 4)) = htonl((unsigned long) pkt->arg);
313 *((unsigned long *) (buf + 8)) = htonl((unsigned long) pkt->arg2);
314 *((unsigned long *) (buf + 12)) = htonl((unsigned long) pkt->arg3);
315 *((unsigned long *) (buf + 16)) = htonl((unsigned long) pkt->arg4);
320 void sendPacketToSock(TCPsocket s, NetPacket *pkt)
322 int bytes_left = NETPKTBUFSIZE;
324 char buf[NETPKTBUFSIZE];
327 packetToBuf(pkt, buf);
328 while (bytes_left > 0) {
329 bw = SDLNet_TCP_Send(s, ptr, bytes_left);
331 fprintf(stderr, "SERVER: SDLNet_TCP_Send(): %s\n", SDLNet_GetError());
334 } else if (bw == 0) {
344 void sendPacket(int playerid, NetPacket *pkt)
346 if ( playerid < JNB_MAX_PLAYERS ) {
347 if ((player[playerid].enabled) && (playerid != client_player_num)) {
348 sendPacketToSock(net_info[playerid].sock, pkt);
354 void sendPacketToAll(NetPacket *pkt)
358 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
364 int grabPacket(TCPsocket s, SDLNet_SocketSet ss, NetPacket *pkt)
366 char buf[NETPKTBUFSIZE];
370 if (SDLNet_CheckSockets(ss, 0) > 0) {
371 rc = SDLNet_TCP_Recv(s, buf, NETPKTBUFSIZE);
372 if (rc <= 0) { /* closed connection? */
374 } else if (rc != NETPKTBUFSIZE) { // !!! FIXME: buffer these?
375 printf("NETWORK: -BUG- ... dropped a packet! (had %d of %d bytes).\b", 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. */
719 //pkt.arg3 = player[playerid].x;
720 //pkt.arg4 = player[playerid].y;
721 processMovePacket(&pkt);
722 sendPacketToAll(&pkt);
724 printf("SERVER: Got unknown packet (0x%lX).\n", pkt.cmd);
730 void init_server(const char *netarg)
735 int wait_for_clients = ((netarg == NULL) ? 0 : atoi(netarg));
738 if ((wait_for_clients > (JNB_MAX_PLAYERS - 1)) || (wait_for_clients < 0)) {
739 printf("SERVER: Waiting for bogus client count (%d).\n", wait_for_clients);
743 if (SDLNet_Init() < 0) {
748 SDLNet_ResolveHost(&addr, NULL, JNB_INETPORT);
749 ipstr = SDLNet_ResolveIP(&addr);
750 SDLNet_ResolveHost(&addr, ipstr, JNB_INETPORT);
751 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);
752 net_info[client_player_num].addr = addr;
754 addr.host = INADDR_ANY;
755 sock = SDLNet_TCP_Open(&addr);
757 fprintf(stderr, "SERVER: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
761 player[client_player_num].enabled = 1;
763 printf("SERVER: waiting for (%d) clients...\n", wait_for_clients);
765 socketset = SDLNet_AllocSocketSet(JNB_MAX_PLAYERS + 1);
766 SDLNet_TCP_AddSocket(socketset, sock);
768 while (wait_for_clients > 0)
770 char buf[NETPKTBUFSIZE];
776 /* Wait for events */
777 SDLNet_CheckSockets(socketset, ~0);
778 if ( SDLNet_SocketReady(sock) ) {
779 s = SDLNet_TCP_Accept(sock);
783 fprintf(stderr, "SERVER: SDLNet_TCP_Accept(): %s", SDLNet_GetError());
784 SDLNet_TCP_Close(sock);
790 br = SDLNet_TCP_Recv(s, buf, NETPKTBUFSIZE);
792 fprintf(stderr, "SERVER: SDLNet_TCP_Recv(): %s\n", SDLNet_GetError());
794 SDLNet_TCP_Close(sock);
798 from = SDLNet_TCP_GetPeerAddress(s);
799 ipstr = SDLNet_ResolveIP(from);
800 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);
802 if (br != NETPKTBUFSIZE) {
803 printf("SERVER: Bogus packet.\n");
807 bufToPacket(buf, &pkt);
808 if (pkt.cmd != NETCMD_HELLO) {
809 printf("SERVER: Bogus packet.\n");
813 printf("SERVER: Client claims to be player #%ld.\n", pkt.arg);
815 if (pkt.arg > JNB_MAX_PLAYERS) {
816 printf("SERVER: (that's an invalid player number.)\n");
818 if (player[pkt.arg].enabled) {
819 printf("SERVER: (that player number is already taken.)\n");
826 printf("SERVER: Forbidding connection.\n");
827 pkt.cmd = NETCMD_NACK;
828 sendPacketToSock(s, &pkt);
831 player[pkt.arg].enabled = 1;
832 net_info[pkt.arg].sock = s;
833 net_info[pkt.arg].addr = *from;
834 net_info[pkt.arg].socketset = SDLNet_AllocSocketSet(1);
835 SDLNet_TCP_AddSocket(net_info[pkt.arg].socketset, net_info[pkt.arg].sock);
837 printf("SERVER: Granting connection. (%d) to go.\n", wait_for_clients);
838 pkt.cmd = NETCMD_ACK;
839 sendPacket(pkt.arg, &pkt);
843 SDLNet_TCP_Close(sock); /* done with the listen socket. */
844 SDLNet_FreeSocketSet(socketset);
848 printf("SERVER: Got all our connections. Greenlighting clients...\n");
850 pkt.cmd = NETCMD_GREENLIGHT;
852 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
853 if (player[i].enabled) {
857 sendPacketToAll(&pkt);
861 void connect_to_server(char *netarg)
864 char buf[NETPKTBUFSIZE];
870 if (netarg == NULL) {
871 printf("CLIENT: Need to specify host to connect to.\n");
875 if (SDLNet_Init() < 0) {
880 player[client_player_num].enabled = 1;
882 SDLNet_ResolveHost(&addr, NULL, JNB_INETPORT);
883 ipstr = SDLNet_ResolveIP(&addr);
884 SDLNet_ResolveHost(&addr, ipstr, JNB_INETPORT);
885 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);
886 net_info[client_player_num].addr = addr;
888 if (SDLNet_ResolveHost(&hent, netarg, JNB_INETPORT) < 0) {
889 fprintf(stderr, "CLIENT: couldn't find host: %s\n", SDLNet_GetError());
893 sock = SDLNet_TCP_Open(&hent);
895 fprintf(stderr, "CLIENT: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
899 socketset = SDLNet_AllocSocketSet(1);
900 SDLNet_TCP_AddSocket(socketset, sock);
902 printf("CLIENT: connected to %s...\n", SDLNet_ResolveIP(&hent));
904 printf("CLIENT: Sending HELLO packet...\n");
905 pkt.cmd = NETCMD_HELLO;
906 pkt.arg = client_player_num;
907 sendPacketToSock(sock, &pkt);
909 printf("CLIENT: Waiting for ACK from server...\n");
911 br = SDLNet_TCP_Recv(sock, buf, NETPKTBUFSIZE);
913 fprintf(stderr, "CLIENT: recv(): %s\n", SDLNet_GetError);
914 SDLNet_FreeSocketSet(socketset);
915 SDLNet_TCP_Close(sock);
919 if (br != NETPKTBUFSIZE) {
920 printf("CLIENT: Bogus packet size (%d of %d). FIXME.\n", br, NETPKTBUFSIZE);
921 SDLNet_FreeSocketSet(socketset);
922 SDLNet_TCP_Close(sock);
926 bufToPacket(buf, &pkt);
928 if (pkt.cmd == NETCMD_NACK) {
929 printf("CLIENT: Server forbid us from playing.\n");
930 SDLNet_FreeSocketSet(socketset);
931 SDLNet_TCP_Close(sock);
935 if (pkt.cmd != NETCMD_ACK) {
936 printf("CLIENT: Unexpected packet (cmd=0x%lX).\n", pkt.cmd);
937 SDLNet_FreeSocketSet(socketset);
938 SDLNet_TCP_Close(sock);
942 printf("CLIENT: Server accepted our connection.\n");
944 wait_for_greenlight();
949 static flip_pixels(unsigned char *pixels)
955 for (y = 0; y < JNB_HEIGHT; y++) {
956 for (x = 0; x < (352/2); x++) {
957 temp = pixels[y*JNB_WIDTH+x];
958 pixels[y*JNB_WIDTH+x] = pixels[y*JNB_WIDTH+(352-x)-1];
959 pixels[y*JNB_WIDTH+(352-x)-1] = temp;
965 int main(int argc, char *argv[])
967 unsigned char *handle;
968 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
971 int closest_player = 0, dist, cur_dist = 0;
972 int end_loop_flag = 0, fade_flag;
973 int mod_vol, sfx_vol, mod_fade_direction;
979 if (init_program(argc, argv, pal) != 0)
982 if (main_info.fireworks == 1) {
993 if (key_pressed(1) == 1) {
996 if (init_level(0, pal) != 0) {
1001 memset(cur_pal, 0, 768);
1002 setpalette(0, 256, cur_pal);
1004 recalculate_gob(&rabbit_gobs, pal);
1005 //recalculate_gob(&font_gobs, pal);
1006 recalculate_gob(&object_gobs, pal);
1007 recalculate_gob(&number_gobs, pal);
1010 register_background(background_pic, pal);
1013 if (flies_enabled) {
1017 for (c1 = 0; c1 < NUM_FLIES; c1++) {
1019 flies[c1].x = s1 + rnd(101) - 50;
1020 flies[c1].y = s2 + rnd(101) - 50;
1021 if (ban_map[flies[c1].y >> 4][flies[c1].x >> 4] == BAN_VOID)
1024 flies[c1].back_defined[0] = 0;
1025 flies[c1].back_defined[1] = 0;
1029 mod_vol = sfx_vol = 10;
1030 mod_fade_direction = 1;
1031 dj_ready_mod(MOD_GAME);
1032 dj_set_mod_volume((char)mod_vol);
1033 dj_set_sfx_volume((char)mod_vol);
1037 dj_play_sfx(SFX_FLY, SFX_FLY_FREQ, 0, 0, 0, 4);
1041 lord_of_the_flies = bunnies_in_space = jetpack = pogostick = blood_is_thicker_than_water = 0;
1043 main_info.page_info[0].num_pobs = 0;
1044 main_info.page_info[1].num_pobs = 0;
1045 main_info.view_page = 0;
1046 main_info.draw_page = 1;
1050 while (update_count) {
1052 if (key_pressed(1) == 1) {
1056 serverTellEveryoneGoodbye();
1058 tellServerGoodbye();
1063 memset(pal, 0, 768);
1064 mod_fade_direction = 0;
1067 if (strncmp(last_keys, "kcitsogop", strlen("kcitsogop")) == 0) {
1071 if (strncmp(last_keys, "ecapsniseinnub", strlen("ecapsniseinnub")) == 0) {
1072 bunnies_in_space ^= 1;
1075 if (strncmp(last_keys, "kcaptej", strlen("kcaptej")) == 0) {
1079 if (strncmp(last_keys, "seilfehtfodrol", strlen("seilfehtfodrol")) == 0) {
1080 lord_of_the_flies ^= 1;
1083 if (strncmp(last_keys, "retawnahtrekcihtsidoolb", strlen("retawnahtrekcihtsidoolb")) == 0) {
1084 blood_is_thicker_than_water ^= 1;
1085 if (blood_is_thicker_than_water == 1) {
1136 register_background(background_pic, pal);
1137 recalculate_gob(&object_gobs, pal);
1144 update_players_from_clients();
1146 if (!update_players_from_server()) {
1147 break; /* got a BYE packet */
1157 for (c3 = 0; c3 < 6; c3++) {
1161 } else if (c3 == 1) {
1164 } else if (c3 == 2) {
1167 } else if (c3 == 3) {
1170 } else if (c3 == 4) {
1173 } else if (c3 == 5) {
1177 if (player[c1].enabled == 1 && player[c2].enabled == 1) {
1178 if (labs(player[c1].x - player[c2].x) < (12L << 16) && labs(player[c1].y - player[c2].y) < (12L << 16)) {
1179 if ((labs(player[c1].y - player[c2].y) >> 16) > 5) {
1180 if (player[c1].y < player[c2].y) {
1181 if (player[c1].y_add >= 0) {
1183 serverSendKillPacket(c1, c2);
1185 if (player[c2].y_add < 0)
1186 player[c2].y_add = 0;
1189 if (player[c2].y_add >= 0) {
1191 serverSendKillPacket(c2, c1);
1193 if (player[c1].y_add < 0)
1194 player[c1].y_add = 0;
1198 if (player[c1].x < player[c2].x) {
1199 if (player[c1].x_add > 0)
1200 player[c1].x = player[c2].x - (12L << 16);
1201 else if (player[c2].x_add < 0)
1202 player[c2].x = player[c1].x + (12L << 16);
1204 player[c1].x -= player[c1].x_add;
1205 player[c2].x -= player[c2].x_add;
1207 l1 = player[c2].x_add;
1208 player[c2].x_add = player[c1].x_add;
1209 player[c1].x_add = l1;
1210 if (player[c1].x_add > 0)
1211 player[c1].x_add = -player[c1].x_add;
1212 if (player[c2].x_add < 0)
1213 player[c2].x_add = -player[c2].x_add;
1215 if (player[c1].x_add > 0)
1216 player[c2].x = player[c1].x - (12L << 16);
1217 else if (player[c2].x_add < 0)
1218 player[c1].x = player[c2].x + (12L << 16);
1220 player[c1].x -= player[c1].x_add;
1221 player[c2].x -= player[c2].x_add;
1223 l1 = player[c2].x_add;
1224 player[c2].x_add = player[c1].x_add;
1225 player[c1].x_add = l1;
1226 if (player[c1].x_add < 0)
1227 player[c1].x_add = -player[c1].x_add;
1228 if (player[c2].x_add > 0)
1229 player[c2].x_add = -player[c2].x_add;
1238 main_info.page_info[main_info.draw_page].num_pobs = 0;
1239 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1240 if (player[c1].enabled == 1)
1241 main_info.page_info[main_info.draw_page].num_pobs++;
1248 if (flies_enabled) {
1249 /* get center of fly swarm */
1251 for (c1 = 0; c1 < NUM_FLIES; c1++) {
1258 if (update_count == 1) {
1259 /* get closest player to fly swarm */
1261 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1262 if (player[c1].enabled == 1) {
1263 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)));
1264 if (cur_dist < dist) {
1265 closest_player = c1;
1270 /* update fly swarm sound */
1274 dj_set_sfx_channel_volume(4, (char)(s3));
1277 for (c1 = 0; c1 < NUM_FLIES; c1++) {
1278 /* get closest player to fly */
1280 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
1281 if (player[c2].enabled == 1) {
1282 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)));
1283 if (cur_dist < dist) {
1284 closest_player = c2;
1289 flies[c1].old_x = flies[c1].x;
1290 flies[c1].old_y = flies[c1].y;
1292 if ((s1 - flies[c1].x) > 30)
1294 else if ((s1 - flies[c1].x) < -30)
1297 if (((player[closest_player].x >> 16) + 8) > flies[c1].x) {
1298 if (lord_of_the_flies == 0)
1303 if (lord_of_the_flies == 0)
1309 s4 = rnd(3) - 1 + s3;
1310 if ((flies[c1].x + s4) < 16)
1312 if ((flies[c1].x + s4) > 351)
1314 if (ban_map[flies[c1].y >> 4][(flies[c1].x + s4) >> 4] != BAN_VOID)
1318 if ((s2 - flies[c1].y) > 30)
1320 else if ((s2 - flies[c1].y) < -30)
1323 if (((player[closest_player].y >> 16) + 8) > flies[c1].y) {
1324 if (lord_of_the_flies == 0)
1329 if (lord_of_the_flies == 0)
1335 s4 = rnd(3) - 1 + s3;
1336 if ((flies[c1].y + s4) < 0)
1338 if ((flies[c1].y + s4) > 239)
1340 if (ban_map[(flies[c1].y + s4) >> 4][flies[c1].x >> 4] != BAN_VOID)
1349 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1350 if (player[c1].enabled == 1) {
1351 main_info.page_info[main_info.draw_page].pobs[s1].x = player[c1].x >> 16;
1352 main_info.page_info[main_info.draw_page].pobs[s1].y = player[c1].y >> 16;
1353 main_info.page_info[main_info.draw_page].pobs[s1].image = player[c1].image + c1 * 18;
1354 main_info.page_info[main_info.draw_page].pobs[s1].pob_data = &rabbit_gobs;
1359 if (update_count == 1) {
1362 draw_pobs(main_info.draw_page);
1367 draw_flies(main_info.draw_page);
1372 if (mod_fade_direction == 1) {
1375 dj_set_mod_volume((char)mod_vol);
1380 dj_set_mod_volume((char)mod_vol);
1384 if (mod_fade_direction == 1) {
1387 dj_set_sfx_volume((char)sfx_vol);
1392 dj_set_sfx_volume((char)sfx_vol);
1397 for (c1 = 0; c1 < 768; c1++) {
1398 if (cur_pal[c1] < pal[c1]) {
1401 } else if (cur_pal[c1] > pal[c1]) {
1406 if (fade_flag == 0 && end_loop_flag == 1)
1409 if (update_count == 1) {
1410 main_info.draw_page ^= 1;
1411 main_info.view_page ^= 1;
1413 flippage(main_info.view_page);
1419 setpalette(0, 256, cur_pal);
1421 if (update_count == 1) {
1425 redraw_flies_background(main_info.draw_page);
1427 redraw_pob_backgrounds(main_info.draw_page);
1429 draw_leftovers(main_info.draw_page);
1439 if ( (player[client_player_num].dead_flag == 0) &&
1441 (player[client_player_num].action_left) ||
1442 (player[client_player_num].action_right) ||
1443 (player[client_player_num].action_up) ||
1444 (player[client_player_num].jump_ready == 0)
1447 tellServerNewPosition();
1452 update_count = intr_sysupdate();
1456 if ((server_said_bye) || ((fade_flag == 0) && (end_loop_flag == 1)))
1460 if ((fade_flag == 0) && (end_loop_flag == 1))
1467 serverTellEveryoneGoodbye();
1468 SDLNet_TCP_Close(sock);
1471 if (!server_said_bye) {
1472 tellServerGoodbye();
1475 SDLNet_TCP_Close(sock);
1481 main_info.view_page = 0;
1482 main_info.draw_page = 1;
1484 dj_stop_sfx_channel(4);
1488 memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
1489 register_mask(mask_pic);
1491 //recalculate_gob(&font_gobs, pal);
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");
1532 for (c1 = 0; c1 < 16; c1++) { // fix dark font
1533 pal[(240 + c1) * 3 + 0] = c1 << 2;
1534 pal[(240 + c1) * 3 + 1] = c1 << 2;
1535 pal[(240 + c1) * 3 + 2] = c1 << 2;
1538 memset(cur_pal, 0, 768);
1540 setpalette(0, 256, cur_pal);
1543 dj_ready_mod(MOD_SCORES);
1544 dj_set_mod_volume((char)mod_vol);
1548 while (key_pressed(1) == 0) {
1551 dj_set_mod_volume((char)mod_vol);
1552 for (c1 = 0; c1 < 768; c1++) {
1553 if (cur_pal[c1] < pal[c1])
1559 setpalette(0, 256, cur_pal);
1560 flippage(main_info.view_page);
1562 while (key_pressed(1) == 1) {
1567 memset(pal, 0, 768);
1569 while (mod_vol > 0) {
1571 dj_set_mod_volume((char)mod_vol);
1572 for (c1 = 0; c1 < 768; c1++) {
1573 if (cur_pal[c1] > pal[c1])
1578 setpalette(0, 256, cur_pal);
1579 flippage(main_info.view_page);
1582 fillpalette(0, 0, 0);
1588 break; /* don't go back to menu if in net game. */
1597 void steer_players(void)
1602 update_player_actions();
1604 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1606 if (player[c1].enabled == 1) {
1608 if (player[c1].dead_flag == 0) {
1610 if (player[c1].action_left && player[c1].action_right) {
1611 if (player[c1].direction == 0) {
1612 if (player[c1].action_right) {
1613 s1 = (player[c1].x >> 16);
1614 s2 = (player[c1].y >> 16);
1615 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1616 if (player[c1].x_add < 0)
1617 player[c1].x_add += 1024;
1619 player[c1].x_add += 768;
1620 } 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)) {
1621 if (player[c1].x_add > 0)
1622 player[c1].x_add += 1024;
1624 player[c1].x_add += 768;
1626 if (player[c1].x_add < 0) {
1627 player[c1].x_add += 16384;
1628 if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1629 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);
1631 player[c1].x_add += 12288;
1633 if (player[c1].x_add > 98304L)
1634 player[c1].x_add = 98304L;
1635 player[c1].direction = 0;
1636 if (player[c1].anim == 0) {
1637 player[c1].anim = 1;
1638 player[c1].frame = 0;
1639 player[c1].frame_tick = 0;
1640 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1644 if (player[c1].action_left) {
1645 s1 = (player[c1].x >> 16);
1646 s2 = (player[c1].y >> 16);
1647 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1648 if (player[c1].x_add > 0)
1649 player[c1].x_add -= 1024;
1651 player[c1].x_add -= 768;
1652 } 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)) {
1653 if (player[c1].x_add > 0)
1654 player[c1].x_add -= 1024;
1656 player[c1].x_add -= 768;
1658 if (player[c1].x_add > 0) {
1659 player[c1].x_add -= 16384;
1660 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1661 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);
1663 player[c1].x_add -= 12288;
1665 if (player[c1].x_add < -98304L)
1666 player[c1].x_add = -98304L;
1667 player[c1].direction = 1;
1668 if (player[c1].anim == 0) {
1669 player[c1].anim = 1;
1670 player[c1].frame = 0;
1671 player[c1].frame_tick = 0;
1672 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1676 } else if (player[c1].action_left) {
1677 s1 = (player[c1].x >> 16);
1678 s2 = (player[c1].y >> 16);
1679 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1680 if (player[c1].x_add > 0)
1681 player[c1].x_add -= 1024;
1683 player[c1].x_add -= 768;
1684 } 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)) {
1685 if (player[c1].x_add > 0)
1686 player[c1].x_add -= 1024;
1688 player[c1].x_add -= 768;
1690 if (player[c1].x_add > 0) {
1691 player[c1].x_add -= 16384;
1692 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1693 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);
1695 player[c1].x_add -= 12288;
1697 if (player[c1].x_add < -98304L)
1698 player[c1].x_add = -98304L;
1699 player[c1].direction = 1;
1700 if (player[c1].anim == 0) {
1701 player[c1].anim = 1;
1702 player[c1].frame = 0;
1703 player[c1].frame_tick = 0;
1704 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1706 } else if (player[c1].action_right) {
1707 s1 = (player[c1].x >> 16);
1708 s2 = (player[c1].y >> 16);
1709 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1710 if (player[c1].x_add < 0)
1711 player[c1].x_add += 1024;
1713 player[c1].x_add += 768;
1714 } 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)) {
1715 if (player[c1].x_add > 0)
1716 player[c1].x_add += 1024;
1718 player[c1].x_add += 768;
1720 if (player[c1].x_add < 0) {
1721 player[c1].x_add += 16384;
1722 if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1723 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);
1725 player[c1].x_add += 12288;
1727 if (player[c1].x_add > 98304L)
1728 player[c1].x_add = 98304L;
1729 player[c1].direction = 0;
1730 if (player[c1].anim == 0) {
1731 player[c1].anim = 1;
1732 player[c1].frame = 0;
1733 player[c1].frame_tick = 0;
1734 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1736 } else if ((!player[c1].action_left) && (!player[c1].action_right)) {
1737 s1 = (player[c1].x >> 16);
1738 s2 = (player[c1].y >> 16);
1739 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)))) {
1740 if (player[c1].x_add < 0) {
1741 player[c1].x_add += 16384;
1742 if (player[c1].x_add > 0)
1743 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 if (player[c1].x_add != 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1750 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);
1752 if (player[c1].anim == 1) {
1753 player[c1].anim = 0;
1754 player[c1].frame = 0;
1755 player[c1].frame_tick = 0;
1756 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1760 if (pogostick == 1 || (player[c1].jump_ready == 1 && player[c1].action_up)) {
1761 s1 = (player[c1].x >> 16);
1762 s2 = (player[c1].y >> 16);
1765 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) {
1766 player[c1].y_add = -280000L;
1767 player[c1].anim = 2;
1768 player[c1].frame = 0;
1769 player[c1].frame_tick = 0;
1770 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1771 player[c1].jump_ready = 0;
1772 player[c1].jump_abort = 1;
1774 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1776 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1778 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)) {
1779 player[c1].y_add = -196608L;
1780 player[c1].in_water = 0;
1781 player[c1].anim = 2;
1782 player[c1].frame = 0;
1783 player[c1].frame_tick = 0;
1784 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1785 player[c1].jump_ready = 0;
1786 player[c1].jump_abort = 1;
1788 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1790 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1793 if (pogostick == 0 && (!player[c1].action_up)) {
1794 player[c1].jump_ready = 1;
1795 if (player[c1].in_water == 0 && player[c1].y_add < 0 && player[c1].jump_abort == 1) {
1796 if (bunnies_in_space == 0)
1797 player[c1].y_add += 32768;
1799 player[c1].y_add += 16384;
1800 if (player[c1].y_add > 0)
1801 player[c1].y_add = 0;
1806 if (player[c1].action_up) {
1807 player[c1].y_add -= 16384;
1808 if (player[c1].y_add < -400000L)
1809 player[c1].y_add = -400000L;
1810 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))
1811 player[c1].in_water = 0;
1813 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);
1818 player[c1].x += player[c1].x_add;
1819 if ((player[c1].x >> 16) < 0) {
1821 player[c1].x_add = 0;
1823 if ((player[c1].x >> 16) + 15 > 351) {
1824 player[c1].x = 336L << 16;
1825 player[c1].x_add = 0;
1827 if (player[c1].y > 0) {
1828 s1 = (player[c1].x >> 16);
1829 s2 = (player[c1].y >> 16);
1830 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) {
1831 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1832 player[c1].x_add = 0;
1834 s1 = (player[c1].x >> 16);
1835 s2 = (player[c1].y >> 16);
1836 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) {
1837 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1838 player[c1].x_add = 0;
1841 s1 = (player[c1].x >> 16);
1843 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) {
1844 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1845 player[c1].x_add = 0;
1847 s1 = (player[c1].x >> 16);
1849 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) {
1850 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1851 player[c1].x_add = 0;
1855 player[c1].y += player[c1].y_add;
1857 s1 = (player[c1].x >> 16);
1858 s2 = (player[c1].y >> 16);
1859 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))) {
1860 player[c1].y = ((player[c1].y >> 16) & 0xfff0) << 16;
1861 player[c1].y_add = -400000L;
1862 player[c1].anim = 2;
1863 player[c1].frame = 0;
1864 player[c1].frame_tick = 0;
1865 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1866 player[c1].jump_ready = 0;
1867 player[c1].jump_abort = 0;
1868 for (c2 = 0; c2 < NUM_OBJECTS; c2++) {
1869 if (objects[c2].used == 1 && objects[c2].type == OBJ_SPRING) {
1870 if (ban_map[(s2 + 15) >> 4][(s1 + 8) >> 4] == BAN_SPRING) {
1871 if ((objects[c2].x >> 20) == ((s1 + 8) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1872 objects[c2].frame = 0;
1873 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1874 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1878 if (ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
1879 if ((objects[c2].x >> 20) == (s1 >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1880 objects[c2].frame = 0;
1881 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1882 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1885 } else if (ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1886 if ((objects[c2].x >> 20) == ((s1 + 15) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1887 objects[c2].frame = 0;
1888 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1889 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1896 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1898 s1 = (player[c1].x >> 16);
1899 s2 = (player[c1].y >> 16);
1902 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) {
1903 player[c1].y = (((s2 + 16) & 0xfff0)) << 16;
1904 player[c1].y_add = 0;
1905 player[c1].anim = 0;
1906 player[c1].frame = 0;
1907 player[c1].frame_tick = 0;
1908 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1910 s1 = (player[c1].x >> 16);
1911 s2 = (player[c1].y >> 16);
1914 if (ban_map[(s2 + 8) >> 4][(s1 + 8) >> 4] == BAN_WATER) {
1915 if (player[c1].in_water == 0) {
1916 player[c1].in_water = 1;
1917 player[c1].anim = 4;
1918 player[c1].frame = 0;
1919 player[c1].frame_tick = 0;
1920 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1921 if (player[c1].y_add >= 32768) {
1922 add_object(OBJ_SPLASH, (player[c1].x >> 16) + 8, ((player[c1].y >> 16) & 0xfff0) + 15, 0, 0, OBJ_ANIM_SPLASH, 0);
1923 if (blood_is_thicker_than_water == 0)
1924 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1926 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 5000), 64, 0, 0, -1);
1929 player[c1].y_add -= 1536;
1930 if (player[c1].y_add < 0 && player[c1].anim != 5) {
1931 player[c1].anim = 5;
1932 player[c1].frame = 0;
1933 player[c1].frame_tick = 0;
1934 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1936 if (player[c1].y_add < -65536L)
1937 player[c1].y_add = -65536L;
1938 if (player[c1].y_add > 65535L)
1939 player[c1].y_add = 65535L;
1940 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) {
1941 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1942 player[c1].y_add = 0;
1944 } 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) {
1945 player[c1].in_water = 0;
1946 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1947 player[c1].y_add = 0;
1948 if (player[c1].anim != 0 && player[c1].anim != 1) {
1949 player[c1].anim = 0;
1950 player[c1].frame = 0;
1951 player[c1].frame_tick = 0;
1952 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1955 if (player[c1].in_water == 0) {
1956 if (bunnies_in_space == 0)
1957 player[c1].y_add += 12288;
1959 player[c1].y_add += 6144;
1960 if (player[c1].y_add > 327680L)
1961 player[c1].y_add = 327680L;
1963 player[c1].y = (player[c1].y & 0xffff0000) + 0x10000;
1964 player[c1].y_add = 0;
1966 player[c1].in_water = 0;
1968 if (player[c1].y_add > 36864 && player[c1].anim != 3 && player[c1].in_water == 0) {
1969 player[c1].anim = 3;
1970 player[c1].frame = 0;
1971 player[c1].frame_tick = 0;
1972 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1977 player[c1].frame_tick++;
1978 if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
1980 if (player[c1].frame >= player_anims[player[c1].anim].num_frames) {
1981 if (player[c1].anim != 6)
1982 player[c1].frame = player_anims[player[c1].anim].restart_frame;
1984 position_player(c1);
1986 player[c1].frame_tick = 0;
1988 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1997 void position_player(int player_num)
2006 if (ban_map[s2][s1] == BAN_VOID && (ban_map[s2 + 1][s1] == BAN_SOLID || ban_map[s2 + 1][s1] == BAN_ICE))
2009 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
2010 if (c1 != player_num && player[c1].enabled == 1) {
2011 if (abs((s1 << 4) - (player[c1].x >> 16)) < 32 && abs((s2 << 4) - (player[c1].y >> 16)) < 32)
2015 if (c1 == JNB_MAX_PLAYERS) {
2016 player[player_num].x = (long) s1 << 20;
2017 player[player_num].y = (long) s2 << 20;
2018 player[player_num].x_add = player[player_num].y_add = 0;
2019 player[player_num].direction = 0;
2020 player[player_num].jump_ready = 1;
2021 player[player_num].in_water = 0;
2022 player[player_num].anim = 0;
2023 player[player_num].frame = 0;
2024 player[player_num].frame_tick = 0;
2025 player[player_num].image = player_anims[player[player_num].anim].frame[player[player_num].frame].image;
2030 serverSendAlive(player_num);
2032 player[player_num].dead_flag = 0;
2042 void add_object(int type, int x, int y, int x_add, int y_add, int anim, int frame)
2046 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
2047 if (objects[c1].used == 0) {
2048 objects[c1].used = 1;
2049 objects[c1].type = type;
2050 objects[c1].x = (long) x << 16;
2051 objects[c1].y = (long) y << 16;
2052 objects[c1].x_add = x_add;
2053 objects[c1].y_add = y_add;
2054 objects[c1].x_acc = 0;
2055 objects[c1].y_acc = 0;
2056 objects[c1].anim = anim;
2057 objects[c1].frame = frame;
2058 objects[c1].ticks = object_anims[anim].frame[frame].ticks;
2059 objects[c1].image = object_anims[anim].frame[frame].image;
2067 void update_objects(void)
2072 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
2073 if (objects[c1].used == 1) {
2074 switch (objects[c1].type) {
2076 objects[c1].ticks--;
2077 if (objects[c1].ticks <= 0) {
2078 objects[c1].frame++;
2079 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames) {
2080 objects[c1].frame--;
2081 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2083 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2084 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2087 if (objects[c1].used == 1)
2088 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2091 objects[c1].ticks--;
2092 if (objects[c1].ticks <= 0) {
2093 objects[c1].frame++;
2094 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2095 objects[c1].used = 0;
2097 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2098 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2101 if (objects[c1].used == 1)
2102 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2105 objects[c1].x += objects[c1].x_add;
2106 objects[c1].y += objects[c1].y_add;
2107 objects[c1].ticks--;
2108 if (objects[c1].ticks <= 0) {
2109 objects[c1].frame++;
2110 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2111 objects[c1].used = 0;
2113 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2114 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2117 if (objects[c1].used == 1)
2118 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2120 case OBJ_YEL_BUTFLY:
2121 case OBJ_PINK_BUTFLY:
2122 objects[c1].x_acc += rnd(128) - 64;
2123 if (objects[c1].x_acc < -1024)
2124 objects[c1].x_acc = -1024;
2125 if (objects[c1].x_acc > 1024)
2126 objects[c1].x_acc = 1024;
2127 objects[c1].x_add += objects[c1].x_acc;
2128 if (objects[c1].x_add < -32768)
2129 objects[c1].x_add = -32768;
2130 if (objects[c1].x_add > 32768)
2131 objects[c1].x_add = 32768;
2132 objects[c1].x += objects[c1].x_add;
2133 if ((objects[c1].x >> 16) < 16) {
2134 objects[c1].x = 16 << 16;
2135 objects[c1].x_add = -objects[c1].x_add >> 2;
2136 objects[c1].x_acc = 0;
2137 } else if ((objects[c1].x >> 16) > 350) {
2138 objects[c1].x = 350 << 16;
2139 objects[c1].x_add = -objects[c1].x_add >> 2;
2140 objects[c1].x_acc = 0;
2142 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
2143 if (objects[c1].x_add < 0) {
2144 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2146 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2148 objects[c1].x_add = -objects[c1].x_add >> 2;
2149 objects[c1].x_acc = 0;
2151 objects[c1].y_acc += rnd(64) - 32;
2152 if (objects[c1].y_acc < -1024)
2153 objects[c1].y_acc = -1024;
2154 if (objects[c1].y_acc > 1024)
2155 objects[c1].y_acc = 1024;
2156 objects[c1].y_add += objects[c1].y_acc;
2157 if (objects[c1].y_add < -32768)
2158 objects[c1].y_add = -32768;
2159 if (objects[c1].y_add > 32768)
2160 objects[c1].y_add = 32768;
2161 objects[c1].y += objects[c1].y_add;
2162 if ((objects[c1].y >> 16) < 0) {
2164 objects[c1].y_add = -objects[c1].y_add >> 2;
2165 objects[c1].y_acc = 0;
2166 } else if ((objects[c1].y >> 16) > 255) {
2167 objects[c1].y = 255 << 16;
2168 objects[c1].y_add = -objects[c1].y_add >> 2;
2169 objects[c1].y_acc = 0;
2171 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
2172 if (objects[c1].y_add < 0) {
2173 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2175 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2177 objects[c1].y_add = -objects[c1].y_add >> 2;
2178 objects[c1].y_acc = 0;
2180 if (objects[c1].type == OBJ_YEL_BUTFLY) {
2181 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_LEFT) {
2182 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_LEFT;
2183 objects[c1].frame = 0;
2184 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2185 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2186 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_RIGHT) {
2187 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_RIGHT;
2188 objects[c1].frame = 0;
2189 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2190 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2193 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_LEFT) {
2194 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_LEFT;
2195 objects[c1].frame = 0;
2196 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2197 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2198 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_RIGHT) {
2199 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_RIGHT;
2200 objects[c1].frame = 0;
2201 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2202 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2205 objects[c1].ticks--;
2206 if (objects[c1].ticks <= 0) {
2207 objects[c1].frame++;
2208 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2209 objects[c1].frame = object_anims[objects[c1].anim].restart_frame;
2211 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2212 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2215 if (objects[c1].used == 1)
2216 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2220 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 0);
2221 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
2222 objects[c1].y_add += 3072;
2223 if (objects[c1].y_add > 196608L)
2224 objects[c1].y_add = 196608L;
2225 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
2226 if (objects[c1].x_add < 0) {
2227 if (objects[c1].x_add < -65536L)
2228 objects[c1].x_add = -65536L;
2229 objects[c1].x_add += 1024;
2230 if (objects[c1].x_add > 0)
2231 objects[c1].x_add = 0;
2233 if (objects[c1].x_add > 65536L)
2234 objects[c1].x_add = 65536L;
2235 objects[c1].x_add -= 1024;
2236 if (objects[c1].x_add < 0)
2237 objects[c1].x_add = 0;
2239 objects[c1].y_add += 1024;
2240 if (objects[c1].y_add < -65536L)
2241 objects[c1].y_add = -65536L;
2242 if (objects[c1].y_add > 65536L)
2243 objects[c1].y_add = 65536L;
2245 objects[c1].x += objects[c1].x_add;
2246 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)) {
2247 if (objects[c1].x_add < 0) {
2248 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2249 objects[c1].x_add = -objects[c1].x_add >> 2;
2251 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2252 objects[c1].x_add = -objects[c1].x_add >> 2;
2255 objects[c1].y += objects[c1].y_add;
2256 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
2257 objects[c1].used = 0;
2258 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
2259 if (objects[c1].y_add < 0) {
2260 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
2261 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2262 objects[c1].x_add >>= 2;
2263 objects[c1].y_add = -objects[c1].y_add >> 2;
2266 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
2267 if (objects[c1].y_add > 131072L) {
2268 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2269 objects[c1].x_add >>= 2;
2270 objects[c1].y_add = -objects[c1].y_add >> 2;
2272 objects[c1].used = 0;
2273 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
2274 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2275 if (objects[c1].y_add > 131072L)
2276 objects[c1].y_add = -objects[c1].y_add >> 2;
2278 objects[c1].y_add = 0;
2282 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
2283 objects[c1].x_add = -16384;
2284 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
2285 objects[c1].x_add = 16384;
2286 if (objects[c1].used == 1) {
2287 s1 = (int)(atan2(objects[c1].y_add, objects[c1].x_add) * 4 / M_PI);
2294 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame + s1, &object_gobs);
2298 if (rnd(100) < 30) {
2299 if (objects[c1].frame == 76)
2300 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 1);
2301 else if (objects[c1].frame == 77)
2302 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 2);
2303 else if (objects[c1].frame == 78)
2304 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 3);
2306 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
2307 objects[c1].y_add += 3072;
2308 if (objects[c1].y_add > 196608L)
2309 objects[c1].y_add = 196608L;
2310 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
2311 if (objects[c1].x_add < 0) {
2312 if (objects[c1].x_add < -65536L)
2313 objects[c1].x_add = -65536L;
2314 objects[c1].x_add += 1024;
2315 if (objects[c1].x_add > 0)
2316 objects[c1].x_add = 0;
2318 if (objects[c1].x_add > 65536L)
2319 objects[c1].x_add = 65536L;
2320 objects[c1].x_add -= 1024;
2321 if (objects[c1].x_add < 0)
2322 objects[c1].x_add = 0;
2324 objects[c1].y_add += 1024;
2325 if (objects[c1].y_add < -65536L)
2326 objects[c1].y_add = -65536L;
2327 if (objects[c1].y_add > 65536L)
2328 objects[c1].y_add = 65536L;
2330 objects[c1].x += objects[c1].x_add;
2331 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)) {
2332 if (objects[c1].x_add < 0) {
2333 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2334 objects[c1].x_add = -objects[c1].x_add >> 2;
2336 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2337 objects[c1].x_add = -objects[c1].x_add >> 2;
2340 objects[c1].y += objects[c1].y_add;
2341 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
2342 objects[c1].used = 0;
2343 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
2344 if (objects[c1].y_add < 0) {
2345 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
2346 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2347 objects[c1].x_add >>= 2;
2348 objects[c1].y_add = -objects[c1].y_add >> 2;
2351 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
2352 if (objects[c1].y_add > 131072L) {
2353 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2354 objects[c1].x_add >>= 2;
2355 objects[c1].y_add = -objects[c1].y_add >> 2;
2357 if (rnd(100) < 10) {
2359 add_leftovers(0, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
2360 add_leftovers(1, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
2362 objects[c1].used = 0;
2364 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
2365 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2366 if (objects[c1].y_add > 131072L)
2367 objects[c1].y_add = -objects[c1].y_add >> 2;
2369 objects[c1].y_add = 0;
2373 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
2374 objects[c1].x_add = -16384;
2375 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
2376 objects[c1].x_add = 16384;
2377 if (objects[c1].used == 1)
2378 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame, &object_gobs);
2380 case OBJ_FLESH_TRACE:
2381 objects[c1].ticks--;
2382 if (objects[c1].ticks <= 0) {
2383 objects[c1].frame++;
2384 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2385 objects[c1].used = 0;
2387 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2388 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2391 if (objects[c1].used == 1)
2392 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2401 int add_pob(int page, int x, int y, int image, gob_t *pob_data)
2404 if (main_info.page_info[page].num_pobs >= NUM_POBS)
2407 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].x = x;
2408 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].y = y;
2409 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].image = image;
2410 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].pob_data = pob_data;
2411 main_info.page_info[page].num_pobs++;
2418 void draw_flies(int page)
2422 for (c2 = 0; c2 < NUM_FLIES; c2++) {
2423 flies[c2].back[main_info.draw_page] = get_pixel(main_info.draw_page, flies[c2].x, flies[c2].y);
2424 flies[c2].back_defined[main_info.draw_page] = 1;
2425 if (mask_pic[(flies[c2].y * JNB_WIDTH) + flies[c2].x] == 0)
2426 set_pixel(main_info.draw_page, flies[c2].x, flies[c2].y, 0);
2430 void draw_pobs(int page)
2437 for (c1 = main_info.page_info[page].num_pobs - 1; c1 >= 0; c1--) {
2438 main_info.page_info[page].pobs[c1].back_buf_ofs = back_buf_ofs;
2439 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);
2441 back_buf_ofs += pob_width(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data) * pob_height(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data) * 4 * bytes_per_pixel;
2443 back_buf_ofs += pob_width(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data) * pob_height(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data) * bytes_per_pixel;
2444 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);
2450 void redraw_flies_background(int page)
2454 for (c2 = NUM_FLIES - 1; c2 >= 0; c2--) {
2455 if (flies[c2].back_defined[page] == 1)
2456 set_pixel(page, flies[c2].old_draw_x, flies[c2].old_draw_y, flies[c2].back[page]);
2457 flies[c2].old_draw_x = flies[c2].x;
2458 flies[c2].old_draw_y = flies[c2].y;
2463 void redraw_pob_backgrounds(int page)
2467 for (c1 = 0; c1 < main_info.page_info[page].num_pobs; c1++)
2468 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);
2473 int add_leftovers(int page, int x, int y, int image, gob_t *pob_data)
2476 if (leftovers.page[page].num_pobs >= NUM_LEFTOVERS)
2479 leftovers.page[page].pobs[leftovers.page[page].num_pobs].x = x;
2480 leftovers.page[page].pobs[leftovers.page[page].num_pobs].y = y;
2481 leftovers.page[page].pobs[leftovers.page[page].num_pobs].image = image;
2482 leftovers.page[page].pobs[leftovers.page[page].num_pobs].pob_data = pob_data;
2483 leftovers.page[page].num_pobs++;
2490 void draw_leftovers(int page)
2494 for (c1 = leftovers.page[page].num_pobs - 1; c1 >= 0; c1--)
2495 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);
2497 leftovers.page[page].num_pobs = 0;
2502 int init_level(int level, char *pal)
2504 unsigned char *handle;
2508 if ((handle = dat_open("level.pcx", datfile_name, "rb")) == 0) {
2509 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2512 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
2513 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2517 flip_pixels(background_pic);
2518 if ((handle = dat_open("mask.pcx", datfile_name, "rb")) == 0) {
2519 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2522 if (read_pcx(handle, mask_pic, JNB_WIDTH*JNB_HEIGHT, 0) != 0) {
2523 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2527 flip_pixels(mask_pic);
2528 register_mask(mask_pic);
2530 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
2531 if (player[c1].enabled == 1) {
2532 player[c1].bumps = 0;
2533 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++)
2534 player[c1].bumped[c2] = 0;
2535 position_player(c1);
2539 for (c1 = 0; c1 < NUM_OBJECTS; c1++)
2540 objects[c1].used = 0;
2542 for (c1 = 0; c1 < 16; c1++) {
2543 for (c2 = 0; c2 < 22; c2++) {
2544 if (ban_map[c1][c2] == BAN_SPRING)
2545 add_object(OBJ_SPRING, c2 << 4, c1 << 4, 0, 0, OBJ_ANIM_SPRING, 5);
2552 if (ban_map[s2][s1] == BAN_VOID) {
2553 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2560 if (ban_map[s2][s1] == BAN_VOID) {
2561 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2568 if (ban_map[s2][s1] == BAN_VOID) {
2569 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2576 if (ban_map[s2][s1] == BAN_VOID) {
2577 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2587 void deinit_level(void)
2595 #define PATH_MAX 1024
2601 unsigned char *datafile_buffer = NULL;
2603 static void preread_datafile(const char *fname)
2609 char *gzfilename = alloca(strlen(fname) + 4);
2614 strcpy(gzfilename, fname);
2615 strcat(gzfilename, ".gz");
2617 gzf = gzopen(gzfilename, "rb");
2622 if (bufpos >= bufsize) {
2623 bufsize += 1024 * 1024;
2624 datafile_buffer = (unsigned char *) realloc(datafile_buffer, bufsize);
2625 if (datafile_buffer == NULL) {
2626 perror("realloc()");
2631 br = gzread(gzf, datafile_buffer + bufpos, bufsize - bufpos);
2633 fprintf(stderr, "gzread failed.\n");
2638 } while (!gzeof(gzf));
2640 /* try to shrink buffer... */
2641 ptr = (unsigned char *) realloc(datafile_buffer, bufpos);
2643 datafile_buffer = ptr;
2649 /* drop through and try for an uncompressed datafile... */
2652 fd = open(fname, O_RDONLY | O_BINARY);
2654 fprintf(stderr, "can't open %s:", fname);
2659 len = filelength(fd);
2660 datafile_buffer = (unsigned char *) malloc(len);
2661 if (datafile_buffer == NULL) {
2667 if (read(fd, datafile_buffer, len) != len) {
2677 int init_program(int argc, char *argv[], char *pal)
2679 char *netarg = NULL;
2680 unsigned char *handle = (unsigned char *) NULL;
2685 int player_anim_data[] = {
2686 1, 0, 0, 0x7fff, 0, 0, 0, 0, 0, 0,
2687 4, 0, 0, 4, 1, 4, 2, 4, 3, 4,
2688 1, 0, 4, 0x7fff, 0, 0, 0, 0, 0, 0,
2689 4, 2, 5, 8, 6, 10, 7, 3, 6, 3,
2690 1, 0, 6, 0x7fff, 0, 0, 0, 0, 0, 0,
2691 2, 1, 5, 8, 4, 0x7fff, 0, 0, 0, 0,
2692 1, 0, 8, 5, 0, 0, 0, 0, 0, 0
2696 memset(&net_info, 0, sizeof(net_info));
2700 if (__djgpp_nearptr_enable() == 0)
2706 if (hook_keyb_handler() != 0)
2709 memset(&main_info, 0, sizeof(main_info));
2711 strcpy(datfile_name, DATA_PATH);
2713 force2 = force3 = 0;
2716 for (c1 = 1; c1 < argc; c1++) {
2717 if (stricmp(argv[c1], "-nosound") == 0)
2718 main_info.no_sound = 1;
2719 else if (stricmp(argv[c1], "-musicnosound") == 0)
2720 main_info.music_no_sound = 1;
2721 else if (stricmp(argv[c1], "-nogore") == 0)
2722 main_info.no_gore = 1;
2723 else if (stricmp(argv[c1], "-noflies") == 0)
2725 else if (stricmp(argv[c1], "-nojoy") == 0)
2726 main_info.joy_enabled = 0;
2727 else if (stricmp(argv[c1], "-fireworks") == 0)
2728 main_info.fireworks = 1;
2730 else if (stricmp(argv[c1], "-fullscreen") == 0)
2733 else if (stricmp(argv[c1], "-scaleup") == 0)
2735 else if (stricmp(argv[c1], "-mirror") == 0)
2737 else if (stricmp(argv[c1], "-dat") == 0) {
2738 if (c1 < (argc - 1)) {
2741 if ((f = fopen(argv[c1 + 1], "rb")) != NULL) {
2743 strcpy(datfile_name, argv[c1 + 1]);
2746 } else if (stricmp(argv[c1], "-player") == 0) {
2747 if (c1 < (argc - 1)) {
2748 if (client_player_num < 0)
2749 client_player_num = atoi(argv[c1 + 1]);
2752 } else if (stricmp(argv[c1], "-server") == 0) {
2753 if (c1 < (argc - 1)) {
2756 netarg = argv[c1 + 1];
2758 } else if (stricmp(argv[c1], "-connect") == 0) {
2759 if (c1 < (argc - 1)) {
2762 netarg = argv[c1 + 1];
2765 } else if (stricmp(argv[c1], "-mouse") == 0) {
2766 if (c1 < (argc - 1)) {
2767 if (stricmp(argv[c1 + 1], "2") == 0)
2769 if (stricmp(argv[c1 + 1], "3") == 0)
2773 else if (strstr(argv[1],"-v")) {
2774 printf("jumpnbump %s compiled %s at %s with",JNB_VERSION,__DATE__,__TIME__);
2778 printf(" network support.\n");
2781 else if (strstr(argv[1],"-h")) {
2782 printf("Usage: jumpnbump [OPTION]...\n");
2784 printf(" -h this help\n");
2785 printf(" -v print version\n");
2786 printf(" -dat level.dat play a different level\n");
2788 //printf(" -port port define listen port\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);
2978 for (c1 = 0; c1 < 16; c1++) { // fix dark font
2979 pal[(240 + c1) * 3 + 0] = c1 << 2;
2980 pal[(240 + c1) * 3 + 1] = c1 << 2;
2981 pal[(240 + c1) * 3 + 2] = c1 << 2;
2984 setpalette(0, 256, pal);
2988 recalculate_gob(&font_gobs, pal);
2990 if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
2992 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2993 put_text(0, 200, 100, "Move the joystick to the", 2);
2994 put_text(0, 200, 115, "UPPER LEFT", 2);
2995 put_text(0, 200, 130, "and press button A", 2);
2996 put_text(0, 200, 200, "Or press ESC to use", 2);
2997 put_text(0, 200, 215, "previous settings", 2);
2998 if (calib_joy(0) != 0)
3001 register_background(NULL, NULL);
3003 main_info.view_page = 1;
3008 put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
3009 put_text(1, 200, 100, "Move the joystick to the", 2);
3010 put_text(1, 200, 115, "LOWER RIGHT", 2);
3011 put_text(1, 200, 130, "and press button A", 2);
3012 put_text(1, 200, 200, "Or press ESC to use", 2);
3013 put_text(1, 200, 215, "previous settings", 2);
3014 if (calib_joy(1) != 0)
3017 register_background(NULL, NULL);
3022 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
3023 put_text(0, 200, 100, "Move the joystick to the", 2);
3024 put_text(0, 200, 115, "CENTER", 2);
3025 put_text(0, 200, 130, "and press button A", 2);
3026 put_text(0, 200, 200, "Or press ESC to use", 2);
3027 put_text(0, 200, 215, "previous settings", 2);
3028 if (calib_joy(2) != 0)
3031 if (joy.calib_data.x1 == joy.calib_data.x2)
3032 joy.calib_data.x1 -= 10;
3033 if (joy.calib_data.x3 == joy.calib_data.x2)
3034 joy.calib_data.x3 += 10;
3035 if (joy.calib_data.y1 == joy.calib_data.y2)
3036 joy.calib_data.y1 -= 10;
3037 if (joy.calib_data.y3 == joy.calib_data.y2)
3038 joy.calib_data.y3 += 10;
3043 if (load_flag == 1) {
3044 if ((handle = dat_open("calib.dat", datfile_name, "rb")) == 0) {
3045 strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
3048 joy.calib_data.x1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3049 joy.calib_data.x2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3050 joy.calib_data.x3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3051 joy.calib_data.y1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3052 joy.calib_data.y2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3053 joy.calib_data.y3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3060 init_server(netarg);
3062 connect_to_server(netarg);
3071 void deinit_program(void)
3078 dj_free_mod(MOD_MENU);
3079 dj_free_mod(MOD_GAME);
3080 dj_free_sfx(SFX_DEATH);
3081 dj_free_sfx(SFX_SPRING);
3082 dj_free_sfx(SFX_SPLASH);
3085 if (background_pic != 0)
3086 free(background_pic);
3090 remove_keyb_handler();
3094 __dpmi_int(0x10, ®s);
3097 if (main_info.error_str[0] != 0) {
3098 printf(main_info.error_str);
3100 MessageBox(0, main_info.error_str, "Jump'n'Bump", 0);
3109 unsigned short rnd(unsigned short max)
3111 return (rand() % max);
3115 int read_level(void)
3117 unsigned char *handle;
3121 if ((handle = dat_open("levelmap.txt", datfile_name, "rb")) == 0) {
3122 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
3126 for (c1 = 0; c1 < 16; c1++) {
3127 for (c2 = 0; c2 < 22; c2++) {
3129 chr = (int) *(handle++);
3130 if (chr >= '0' && chr <= '4')
3134 ban_map[c1][21-c2] = chr - '0';
3136 ban_map[c1][c2] = chr - '0';
3140 for (c2 = 0; c2 < 22; c2++)
3141 ban_map[16][c2] = BAN_SOLID;
3148 unsigned char *dat_open(char *file_name, char *dat_name, char *mode)
3156 if (datafile_buffer == NULL)
3159 memset(name, 0, sizeof(name));
3161 num = ( (datafile_buffer[0] << 0) +
3162 (datafile_buffer[1] << 8) +
3163 (datafile_buffer[2] << 16) +
3164 (datafile_buffer[3] << 24) );
3166 ptr = datafile_buffer + 4;
3168 for (c1 = 0; c1 < num; c1++) {
3170 memcpy(name, ptr, 12);
3173 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
3174 ofs = ( (ptr[0] << 0) +
3179 return (datafile_buffer + ofs);
3188 int dat_filelen(char *file_name, char *dat_name)
3196 memset(name, 0, sizeof(name));
3198 num = ( (datafile_buffer[0] << 0) +
3199 (datafile_buffer[1] << 8) +
3200 (datafile_buffer[2] << 16) +
3201 (datafile_buffer[3] << 24) );
3203 ptr = datafile_buffer + 4;
3205 for (c1 = 0; c1 < num; c1++) {
3207 memcpy(name, ptr, 12);
3210 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
3213 len = ( (ptr[0] << 0) +
3227 void write_calib_data(void)
3235 if ((handle = fopen(datfile_name, "rb")) == NULL)
3237 len = filelength(fileno(handle));
3238 if ((mem = malloc(len)) == NULL)
3240 fread(mem, 1, len, handle);
3244 num = *(int *) (&mem[0]);
3245 for (c1 = 0; c1 < num; c1++) {
3246 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
3247 ofs = *(int *) (&mem[ofs + 12]);
3253 mem[ofs] = joy.calib_data.x1 & 0xff;
3254 mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
3255 mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
3256 mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
3257 mem[ofs + 4] = joy.calib_data.x2 & 0xff;
3258 mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
3259 mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
3260 mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
3261 mem[ofs + 8] = joy.calib_data.x3 & 0xff;
3262 mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
3263 mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
3264 mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
3265 mem[ofs + 12] = joy.calib_data.y1 & 0xff;
3266 mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
3267 mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
3268 mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
3269 mem[ofs + 16] = joy.calib_data.y2 & 0xff;
3270 mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
3271 mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
3272 mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
3273 mem[ofs + 20] = joy.calib_data.y3 & 0xff;
3274 mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
3275 mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
3276 mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
3278 if ((handle = fopen(datfile_name, "wb")) == NULL)
3280 fwrite(mem, 1, len, handle);