3 * Copyright (C) 1998 Brainchild Design - http://brainchilddesign.com/
5 * Copyright (C) 2001 Chuck Mason <cemason@users.sourceforge.net>
7 * Copyright (C) 2002 Florian Schulze <crow@icculus.org>
9 * Portions of this code are from the MPEG software simulation group
10 * idct implementation. This code will be replaced with a new
11 * implementation soon.
13 * This file is part of Jump'n'Bump.
15 * Jump'n'Bump is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * Jump'n'Bump is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
41 #define M_PI 3.14159265358979323846
44 gob_t rabbit_gobs = { 0 };
45 gob_t font_gobs = { 0 };
46 gob_t object_gobs = { 0 };
47 gob_t number_gobs = { 0 };
49 main_info_t main_info;
50 player_t player[JNB_MAX_PLAYERS];
51 player_anim_t player_anims[7];
52 object_t objects[NUM_OBJECTS];
56 char datfile_name[2048];
62 unsigned int ban_map[17][22] = {
63 {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
64 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0},
65 {1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
66 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1},
67 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
68 {1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
69 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1},
70 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
71 {1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
72 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1},
73 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1},
74 {1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1},
75 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
76 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
77 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 1, 3, 3, 3, 1, 1, 1},
78 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
79 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
205 int flies_enabled = 1;
210 int old_draw_x, old_draw_y;
222 } pobs[NUM_LEFTOVERS];
226 int pogostick, bunnies_in_space, jetpack, lord_of_the_flies, blood_is_thicker_than_water;
230 int filelength(int handle)
234 if (fstat(handle, &buf) == -1) {
235 perror("filelength");
244 /* networking shite. */
246 int client_player_num = -1;
251 TCPsocket sock = NULL;
252 SDLNet_SocketSet socketset = NULL;
258 SDLNet_SocketSet socketset;
261 NetInfo net_info[JNB_MAX_PLAYERS];
273 #define NETPKTBUFSIZE (4 + 4 + 4 + 4 + 4)
275 #define NETCMD_NACK (0xF00DF00D + 0)
276 #define NETCMD_ACK (0xF00DF00D + 1)
277 #define NETCMD_HELLO (0xF00DF00D + 2)
278 #define NETCMD_GREENLIGHT (0xF00DF00D + 3)
279 #define NETCMD_MOVE (0xF00DF00D + 4)
280 #define NETCMD_BYE (0xF00DF00D + 5)
281 #define NETCMD_POSITION (0xF00DF00D + 6)
282 #define NETCMD_ALIVE (0xF00DF00D + 7)
283 #define NETCMD_KILL (0xF00DF00D + 8)
287 void bufToPacket(const char *buf, NetPacket *pkt)
289 SDLNet_Write32(*((Uint32*) (buf + 0)), &pkt->cmd);
290 SDLNet_Write32(*((Uint32*) (buf + 4)), &pkt->arg);
291 SDLNet_Write32(*((Uint32*) (buf + 8)), &pkt->arg2);
292 SDLNet_Write32(*((Uint32*) (buf + 12)), &pkt->arg3);
293 SDLNet_Write32(*((Uint32*) (buf + 16)), &pkt->arg4);
295 pkt->cmd = ntohl(*((unsigned long *) (buf + 0)));
296 pkt->arg = (long) ntohl(*((unsigned long *) (buf + 4)));
297 pkt->arg2 = (long) ntohl(*((unsigned long *) (buf + 8)));
298 pkt->arg3 = (long) ntohl(*((unsigned long *) (buf + 12)));
299 pkt->arg4 = (long) ntohl(*((unsigned long *) (buf + 16)));
304 void packetToBuf(const NetPacket *pkt, char *buf)
306 *((Uint32*) (buf + 0)) = SDLNet_Read32(&pkt->cmd);
307 *((Uint32*) (buf + 4)) = SDLNet_Read32(&pkt->arg);
308 *((Uint32*) (buf + 8)) = SDLNet_Read32(&pkt->arg2);
309 *((Uint32*) (buf + 12)) = SDLNet_Read32(&pkt->arg3);
310 *((Uint32*) (buf + 16)) = SDLNet_Read32(&pkt->arg4);
312 *((unsigned long *) (buf + 0)) = htonl(pkt->cmd);
313 *((unsigned long *) (buf + 4)) = htonl((unsigned long) pkt->arg);
314 *((unsigned long *) (buf + 8)) = htonl((unsigned long) pkt->arg2);
315 *((unsigned long *) (buf + 12)) = htonl((unsigned long) pkt->arg3);
316 *((unsigned long *) (buf + 16)) = htonl((unsigned long) pkt->arg4);
321 void sendPacketToSock(TCPsocket s, NetPacket *pkt)
323 int bytes_left = NETPKTBUFSIZE;
325 char buf[NETPKTBUFSIZE];
328 packetToBuf(pkt, buf);
329 while (bytes_left > 0) {
330 bw = SDLNet_TCP_Send(s, ptr, bytes_left);
332 fprintf(stderr, "SERVER: SDLNet_TCP_Send(): %s\n", SDLNet_GetError());
335 } else if (bw == 0) {
345 void sendPacket(int playerid, NetPacket *pkt)
347 if ( (playerid < JNB_MAX_PLAYERS) && (playerid >= 0)) {
348 if ((player[playerid].enabled) && (playerid != client_player_num)) {
349 sendPacketToSock(net_info[playerid].sock, pkt);
355 void sendPacketToAll(NetPacket *pkt)
359 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
364 /** read a packet from the given TCPsocket
365 Returns -1 if some error occured, 0 if there was no data available and 1 if a
366 packet was successfully read.
367 Note: the socket has to be in the supplied socketset.
368 TODO: this function will bomb if a packet arrives in pieces, there is no
369 inherent guarantee that the next call will be made on the same socket. */
370 int grabPacket(TCPsocket s, SDLNet_SocketSet ss, NetPacket *pkt)
372 static char buf[NETPKTBUFSIZE];
373 static int buf_count = 0;
376 if (SDLNet_CheckSockets(ss, 0) <= 0)
379 if(!SDLNet_SocketReady(s))
382 rc = SDLNet_TCP_Recv(s, &buf[buf_count], NETPKTBUFSIZE - buf_count);
384 /* closed connection? */
386 } else if (rc != NETPKTBUFSIZE) {
387 /* we got a partial packet. Store what we got in the static buffer and
388 return so that the next call can read the rest. Hopefully. */
393 bufToPacket(buf, pkt);
399 int serverRecvPacket(NetPacket *pkt)
406 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
407 TCPsocket s = net_info[i].sock;
409 if ((i == client_player_num) || (!player[i].enabled))
412 rc = grabPacket(s, net_info[i].socketset, pkt);
416 player[i].enabled = 0;
418 pkt.cmd = NETCMD_BYE;
423 sendPacketToAll(&pkt);
425 return(i); /* it's all good. */
429 return(-1); /* no packets available currently. */
433 void wait_for_greenlight(void)
438 printf("CLIENT: Waiting for greenlight...\n");
442 while ((rc = grabPacket(sock, socketset, &pkt)) == 0) {
443 SDL_Delay(100); /* nap and then try again. */
447 printf("CLIENT: Lost connection.\n");
448 SDLNet_TCP_Close(sock);
451 } while (pkt.cmd != NETCMD_GREENLIGHT);
453 printf("CLIENT: Got greenlight.\n");
455 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
456 if (pkt.arg & (1 << i)) {
457 printf("CLIENT: There is a player #%d.\n", i);
458 player[i].enabled = 1;
464 static int buggered_off = 0;
467 void tellServerGoodbye(void)
473 pkt.cmd = NETCMD_BYE;
474 pkt.arg = client_player_num;
478 sendPacketToSock(sock, &pkt);
484 void processMovePacket(NetPacket *pkt)
486 int playerid = pkt->arg;
487 int movetype = ((pkt->arg2 >> 16) & 0xFF);
488 int newval = ((pkt->arg2 >> 0) & 0xFF);
490 if (movetype == MOVEMENT_LEFT) {
491 player[playerid].action_left = newval;
492 } else if (movetype == MOVEMENT_RIGHT) {
493 player[playerid].action_right = newval;
494 } else if (movetype == MOVEMENT_UP) {
495 player[playerid].action_up = newval;
497 printf("bogus MOVE packet!\n");
500 player[playerid].x = pkt->arg3;
501 player[playerid].y = pkt->arg4;
505 void tellServerPlayerMoved(int playerid, int movement_type, int newval)
509 pkt.cmd = NETCMD_MOVE;
511 pkt.arg2 = ( ((movement_type & 0xFF) << 16) | ((newval & 0xFF) << 0) );
512 pkt.arg3 = player[playerid].x;
513 pkt.arg4 = player[playerid].y;
516 processMovePacket(&pkt);
519 sendPacketToAll(&pkt);
521 sendPacketToSock(sock, &pkt);
528 void tellServerNewPosition(void)
531 pkt.cmd = NETCMD_POSITION;
532 pkt.arg = client_player_num;
533 pkt.arg2 = player[client_player_num].x;
534 pkt.arg3 = player[client_player_num].y;
537 sendPacketToAll(&pkt);
539 sendPacketToSock(sock, &pkt);
545 void processKillPacket(NetPacket *pkt)
554 player[c1].y_add = -player[c1].y_add;
555 if (player[c1].y_add > -262144L)
556 player[c1].y_add = -262144L;
557 player[c1].jump_abort = 1;
558 player[c2].dead_flag = 1;
559 if (player[c2].anim != 6) {
561 player[c2].frame = 0;
562 player[c2].frame_tick = 0;
563 player[c2].image = player_anims[player[c2].anim].frame[player[c2].frame].image + player[c2].direction * 9;
564 if (main_info.no_gore == 0) {
565 for (c4 = 0; c4 < 6; c4++)
566 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);
567 for (c4 = 0; c4 < 6; c4++)
568 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 76);
569 for (c4 = 0; c4 < 6; c4++)
570 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 77);
571 for (c4 = 0; c4 < 8; c4++)
572 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 78);
573 for (c4 = 0; c4 < 10; c4++)
574 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 79);
576 dj_play_sfx(SFX_DEATH, (unsigned short)(SFX_DEATH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
578 player[c1].bumped[c2]++;
579 s1 = player[c1].bumps % 100;
580 add_leftovers(0, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
581 add_leftovers(1, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
582 add_leftovers(0, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
583 add_leftovers(1, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
589 void processPositionPacket(NetPacket *pkt)
591 int playerid = pkt->arg;
593 player[playerid].x = pkt->arg2;
594 player[playerid].y = pkt->arg3;
598 void processAlivePacket(NetPacket *pkt)
600 int playerid = pkt->arg;
602 player[playerid].dead_flag = 0;
603 player[playerid].x = pkt->arg2;
604 player[playerid].y = pkt->arg3;
608 void serverTellEveryoneGoodbye(void)
614 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
615 if (player[i].enabled) {
618 pkt.cmd = NETCMD_BYE;
623 sendPacketToAll(&pkt);
630 int server_said_bye = 0;
633 int update_players_from_server(void)
640 while ((rc = grabPacket(sock, socketset, &pkt)) != 0) {
642 printf("CLIENT: Lost connection.\n");
643 pkt.cmd = NETCMD_BYE;
644 pkt.arg = client_player_num;
647 if (pkt.cmd == NETCMD_BYE) {
648 if (pkt.arg == client_player_num) {
649 SDLNet_FreeSocketSet(socketset);
650 SDLNet_TCP_Close(sock);
655 player[pkt.arg].enabled = 0;
657 } else if (pkt.cmd == NETCMD_MOVE) {
658 processMovePacket(&pkt);
659 } else if (pkt.cmd == NETCMD_ALIVE) {
660 processAlivePacket(&pkt);
661 } else if (pkt.cmd == NETCMD_POSITION) {
662 processPositionPacket(&pkt);
663 } else if (pkt.cmd == NETCMD_KILL) {
664 processKillPacket(&pkt);
666 printf("CLIENT: Got an unknown packet: 0x%lX.\n", pkt.cmd);
674 void serverSendAlive(int playerid)
679 pkt.cmd = NETCMD_ALIVE;
681 pkt.arg2 = player[playerid].x;
682 pkt.arg3 = player[playerid].y;
683 sendPacketToAll(&pkt);
688 void serverSendKillPacket(int killer, int victim)
693 pkt.cmd = NETCMD_KILL;
696 pkt.arg3 = player[victim].x;
697 pkt.arg4 = player[victim].y;
698 processKillPacket(&pkt);
701 sendPacketToAll(&pkt);
707 void update_players_from_clients(void)
715 while ((playerid = serverRecvPacket(&pkt)) >= 0) {
716 if (pkt.cmd == NETCMD_BYE) {
717 pkt.arg = playerid; /* just in case. */
718 sendPacketToAll(&pkt);
719 player[playerid].enabled = 0;
720 SDLNet_FreeSocketSet(net_info[playerid].socketset);
721 SDLNet_TCP_Close(net_info[playerid].sock);
722 } else if (pkt.cmd == NETCMD_POSITION) {
723 pkt.arg = playerid; /* just in case. */
724 processPositionPacket(&pkt);
725 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
730 } else if (pkt.cmd == NETCMD_MOVE) {
731 pkt.arg = playerid; /* just in case. */
733 pkt.arg3 = player[playerid].x;
734 pkt.arg4 = player[playerid].y;
736 processMovePacket(&pkt);
737 sendPacketToAll(&pkt);
739 printf("SERVER: Got unknown packet (0x%lX).\n", pkt.cmd);
745 void init_server(const char *netarg)
750 int wait_for_clients = ((netarg == NULL) ? 0 : atoi(netarg));
753 /** assign player number zero as default for the server */
754 if(-1 == client_player_num)
755 client_player_num = 0;
757 if ((wait_for_clients >= JNB_MAX_PLAYERS) || (wait_for_clients < 0)) {
758 printf("SERVER: Waiting for bogus client count (%d).\n", wait_for_clients);
762 if (SDLNet_Init() < 0) {
767 SDLNet_ResolveHost(&addr, NULL, JNB_INETPORT);
768 ipstr = SDLNet_ResolveIP(&addr);
769 SDLNet_ResolveHost(&addr, ipstr, JNB_INETPORT);
770 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);
771 net_info[client_player_num].addr = addr;
773 addr.host = INADDR_ANY;
774 sock = SDLNet_TCP_Open(&addr);
776 fprintf(stderr, "SERVER: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
780 player[client_player_num].enabled = 1;
782 printf("SERVER: waiting for (%d) clients...\n", wait_for_clients);
784 socketset = SDLNet_AllocSocketSet(JNB_MAX_PLAYERS + 1);
785 SDLNet_TCP_AddSocket(socketset, sock);
787 while (wait_for_clients > 0)
789 char buf[NETPKTBUFSIZE];
795 /* Wait for events */
796 SDLNet_CheckSockets(socketset, ~0);
797 if ( SDLNet_SocketReady(sock) ) {
798 s = SDLNet_TCP_Accept(sock);
802 fprintf(stderr, "SERVER: SDLNet_TCP_Accept(): %s", SDLNet_GetError());
803 SDLNet_TCP_Close(sock);
809 br = SDLNet_TCP_Recv(s, buf, NETPKTBUFSIZE);
811 fprintf(stderr, "SERVER: SDLNet_TCP_Recv(): %s\n", SDLNet_GetError());
813 SDLNet_TCP_Close(sock);
817 from = SDLNet_TCP_GetPeerAddress(s);
818 ipstr = SDLNet_ResolveIP(from);
819 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);
821 if (br != NETPKTBUFSIZE) {
822 printf("SERVER: Bogus packet.\n");
826 bufToPacket(buf, &pkt);
827 if (pkt.cmd != NETCMD_HELLO) {
828 printf("SERVER: Bogus packet.\n");
832 printf("SERVER: Client claims to be player #%ld.\n", pkt.arg);
836 for(i=0; i!=JNB_MAX_PLAYERS; ++i) {
837 if(!player[i].enabled) {
838 printf("SERVER: assigning %d as player number\n", i);
845 if ((pkt.arg>=JNB_MAX_PLAYERS)||(pkt.arg<0)) {
846 printf("SERVER: (that's an invalid player number.)\n");
847 } else if (player[pkt.arg].enabled) {
848 printf("SERVER: (that player number is already taken.)\n");
854 printf("SERVER: Forbidding connection.\n");
855 pkt.cmd = NETCMD_NACK;
856 sendPacketToSock(s, &pkt);
859 player[pkt.arg].enabled = 1;
860 net_info[pkt.arg].sock = s;
861 net_info[pkt.arg].addr = *from;
862 net_info[pkt.arg].socketset = SDLNet_AllocSocketSet(1);
863 SDLNet_TCP_AddSocket(net_info[pkt.arg].socketset, net_info[pkt.arg].sock);
865 printf("SERVER: Granting connection. (%d) to go.\n", wait_for_clients);
866 pkt.cmd = NETCMD_ACK;
867 sendPacket(pkt.arg, &pkt);
871 SDLNet_TCP_Close(sock); /* done with the listen socket. */
872 SDLNet_FreeSocketSet(socketset);
876 printf("SERVER: Got all our connections. Greenlighting clients...\n");
878 pkt.cmd = NETCMD_GREENLIGHT;
880 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
881 if (player[i].enabled) {
885 sendPacketToAll(&pkt);
889 void connect_to_server(char *netarg)
892 char buf[NETPKTBUFSIZE];
898 if (netarg == NULL) {
899 printf("CLIENT: Need to specify host to connect to.\n");
903 if (SDLNet_Init() < 0) {
908 SDLNet_ResolveHost(&addr, NULL, JNB_INETPORT);
909 ipstr = SDLNet_ResolveIP(&addr);
910 SDLNet_ResolveHost(&addr, ipstr, JNB_INETPORT);
911 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);
913 if (SDLNet_ResolveHost(&hent, netarg, JNB_INETPORT) < 0) {
914 fprintf(stderr, "CLIENT: couldn't find host: %s\n", SDLNet_GetError());
918 sock = SDLNet_TCP_Open(&hent);
920 fprintf(stderr, "CLIENT: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
924 socketset = SDLNet_AllocSocketSet(1);
925 SDLNet_TCP_AddSocket(socketset, sock);
927 printf("CLIENT: connected to %s...\n", SDLNet_ResolveIP(&hent));
929 printf("CLIENT: Sending HELLO packet...\n");
930 pkt.cmd = NETCMD_HELLO;
931 pkt.arg = client_player_num;
932 sendPacketToSock(sock, &pkt);
934 printf("CLIENT: Waiting for ACK from server...\n");
936 br = SDLNet_TCP_Recv(sock, buf, NETPKTBUFSIZE);
938 fprintf(stderr, "CLIENT: recv(): %s\n", SDLNet_GetError());
939 SDLNet_FreeSocketSet(socketset);
940 SDLNet_TCP_Close(sock);
944 if (br != NETPKTBUFSIZE) {
945 printf("CLIENT: Bogus packet size (%d of %d). FIXME.\n", br, NETPKTBUFSIZE);
946 SDLNet_FreeSocketSet(socketset);
947 SDLNet_TCP_Close(sock);
951 bufToPacket(buf, &pkt);
953 if (pkt.cmd == NETCMD_NACK) {
954 printf("CLIENT: Server forbid us from playing.\n");
955 SDLNet_FreeSocketSet(socketset);
956 SDLNet_TCP_Close(sock);
960 if (pkt.cmd != NETCMD_ACK) {
961 printf("CLIENT: Unexpected packet (cmd=0x%lX).\n", pkt.cmd);
962 SDLNet_FreeSocketSet(socketset);
963 SDLNet_TCP_Close(sock);
967 client_player_num = pkt.arg;
968 player[client_player_num].enabled = 1;
969 net_info[client_player_num].addr = addr;
970 printf("CLIENT: Server accepted our connection.\n");
972 wait_for_greenlight();
977 static void flip_pixels(unsigned char *pixels)
983 for (y = 0; y < JNB_HEIGHT; y++) {
984 for (x = 0; x < (352/2); x++) {
985 temp = pixels[y*JNB_WIDTH+x];
986 pixels[y*JNB_WIDTH+x] = pixels[y*JNB_WIDTH+(352-x)-1];
987 pixels[y*JNB_WIDTH+(352-x)-1] = temp;
993 int main(int argc, char *argv[])
995 unsigned char *handle;
996 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
999 int closest_player = 0, dist, cur_dist = 0;
1000 int end_loop_flag = 0, fade_flag = 0;
1001 int mod_vol, sfx_vol, mod_fade_direction;
1007 if (init_program(argc, argv, pal) != 0)
1010 if (main_info.fireworks == 1) {
1021 if (key_pressed(1) == 1) {
1024 if (init_level(0, pal) != 0) {
1029 memset(cur_pal, 0, 768);
1030 setpalette(0, 256, cur_pal);
1032 recalculate_gob(&rabbit_gobs, pal);
1033 recalculate_gob(&object_gobs, pal);
1034 recalculate_gob(&number_gobs, pal);
1037 register_background(background_pic, pal);
1040 if (flies_enabled) {
1044 for (c1 = 0; c1 < NUM_FLIES; c1++) {
1046 flies[c1].x = s1 + rnd(101) - 50;
1047 flies[c1].y = s2 + rnd(101) - 50;
1048 if (ban_map[flies[c1].y >> 4][flies[c1].x >> 4] == BAN_VOID)
1051 flies[c1].back_defined[0] = 0;
1052 flies[c1].back_defined[1] = 0;
1056 mod_vol = sfx_vol = 10;
1057 mod_fade_direction = 1;
1058 dj_ready_mod(MOD_GAME);
1059 dj_set_mod_volume((char)mod_vol);
1060 dj_set_sfx_volume((char)mod_vol);
1064 dj_play_sfx(SFX_FLY, SFX_FLY_FREQ, 0, 0, 0, 4);
1068 lord_of_the_flies = bunnies_in_space = jetpack = pogostick = blood_is_thicker_than_water = 0;
1070 main_info.page_info[0].num_pobs = 0;
1071 main_info.page_info[1].num_pobs = 0;
1072 main_info.view_page = 0;
1073 main_info.draw_page = 1;
1077 while (update_count) {
1079 if (key_pressed(1) == 1) {
1083 serverTellEveryoneGoodbye();
1085 tellServerGoodbye();
1090 memset(pal, 0, 768);
1091 mod_fade_direction = 0;
1094 if (strncmp(last_keys, "kcitsogop", strlen("kcitsogop")) == 0) {
1098 if (strncmp(last_keys, "ecapsniseinnub", strlen("ecapsniseinnub")) == 0) {
1099 bunnies_in_space ^= 1;
1102 if (strncmp(last_keys, "kcaptej", strlen("kcaptej")) == 0) {
1106 if (strncmp(last_keys, "seilfehtfodrol", strlen("seilfehtfodrol")) == 0) {
1107 lord_of_the_flies ^= 1;
1110 if (strncmp(last_keys, "retawnahtrekcihtsidoolb", strlen("retawnahtrekcihtsidoolb")) == 0) {
1111 blood_is_thicker_than_water ^= 1;
1112 if (blood_is_thicker_than_water == 1) {
1163 register_background(background_pic, pal);
1164 recalculate_gob(&object_gobs, pal);
1171 update_players_from_clients();
1173 if (!update_players_from_server()) {
1174 break; /* got a BYE packet */
1184 for (c3 = 0; c3 < 6; c3++) {
1188 } else if (c3 == 1) {
1191 } else if (c3 == 2) {
1194 } else if (c3 == 3) {
1197 } else if (c3 == 4) {
1200 } else if (c3 == 5) {
1204 if (player[c1].enabled == 1 && player[c2].enabled == 1) {
1205 if (labs(player[c1].x - player[c2].x) < (12L << 16) && labs(player[c1].y - player[c2].y) < (12L << 16)) {
1206 if ((labs(player[c1].y - player[c2].y) >> 16) > 5) {
1207 if (player[c1].y < player[c2].y) {
1208 if (player[c1].y_add >= 0) {
1210 serverSendKillPacket(c1, c2);
1212 if (player[c2].y_add < 0)
1213 player[c2].y_add = 0;
1216 if (player[c2].y_add >= 0) {
1218 serverSendKillPacket(c2, c1);
1220 if (player[c1].y_add < 0)
1221 player[c1].y_add = 0;
1225 if (player[c1].x < player[c2].x) {
1226 if (player[c1].x_add > 0)
1227 player[c1].x = player[c2].x - (12L << 16);
1228 else if (player[c2].x_add < 0)
1229 player[c2].x = player[c1].x + (12L << 16);
1231 player[c1].x -= player[c1].x_add;
1232 player[c2].x -= player[c2].x_add;
1234 l1 = player[c2].x_add;
1235 player[c2].x_add = player[c1].x_add;
1236 player[c1].x_add = l1;
1237 if (player[c1].x_add > 0)
1238 player[c1].x_add = -player[c1].x_add;
1239 if (player[c2].x_add < 0)
1240 player[c2].x_add = -player[c2].x_add;
1242 if (player[c1].x_add > 0)
1243 player[c2].x = player[c1].x - (12L << 16);
1244 else if (player[c2].x_add < 0)
1245 player[c1].x = player[c2].x + (12L << 16);
1247 player[c1].x -= player[c1].x_add;
1248 player[c2].x -= player[c2].x_add;
1250 l1 = player[c2].x_add;
1251 player[c2].x_add = player[c1].x_add;
1252 player[c1].x_add = l1;
1253 if (player[c1].x_add < 0)
1254 player[c1].x_add = -player[c1].x_add;
1255 if (player[c2].x_add > 0)
1256 player[c2].x_add = -player[c2].x_add;
1265 main_info.page_info[main_info.draw_page].num_pobs = 0;
1266 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1267 if (player[c1].enabled == 1)
1268 main_info.page_info[main_info.draw_page].num_pobs++;
1275 if (flies_enabled) {
1276 /* get center of fly swarm */
1278 for (c1 = 0; c1 < NUM_FLIES; c1++) {
1285 if (update_count == 1) {
1286 /* get closest player to fly swarm */
1288 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1289 if (player[c1].enabled == 1) {
1290 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)));
1291 if (cur_dist < dist) {
1292 closest_player = c1;
1297 /* update fly swarm sound */
1301 dj_set_sfx_channel_volume(4, (char)(s3));
1304 for (c1 = 0; c1 < NUM_FLIES; c1++) {
1305 /* get closest player to fly */
1307 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
1308 if (player[c2].enabled == 1) {
1309 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)));
1310 if (cur_dist < dist) {
1311 closest_player = c2;
1316 flies[c1].old_x = flies[c1].x;
1317 flies[c1].old_y = flies[c1].y;
1319 if ((s1 - flies[c1].x) > 30)
1321 else if ((s1 - flies[c1].x) < -30)
1324 if (((player[closest_player].x >> 16) + 8) > flies[c1].x) {
1325 if (lord_of_the_flies == 0)
1330 if (lord_of_the_flies == 0)
1336 s4 = rnd(3) - 1 + s3;
1337 if ((flies[c1].x + s4) < 16)
1339 if ((flies[c1].x + s4) > 351)
1341 if (ban_map[flies[c1].y >> 4][(flies[c1].x + s4) >> 4] != BAN_VOID)
1345 if ((s2 - flies[c1].y) > 30)
1347 else if ((s2 - flies[c1].y) < -30)
1350 if (((player[closest_player].y >> 16) + 8) > flies[c1].y) {
1351 if (lord_of_the_flies == 0)
1356 if (lord_of_the_flies == 0)
1362 s4 = rnd(3) - 1 + s3;
1363 if ((flies[c1].y + s4) < 0)
1365 if ((flies[c1].y + s4) > 239)
1367 if (ban_map[(flies[c1].y + s4) >> 4][flies[c1].x >> 4] != BAN_VOID)
1376 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1377 if (player[c1].enabled == 1) {
1378 main_info.page_info[main_info.draw_page].pobs[s1].x = player[c1].x >> 16;
1379 main_info.page_info[main_info.draw_page].pobs[s1].y = player[c1].y >> 16;
1380 main_info.page_info[main_info.draw_page].pobs[s1].image = player[c1].image + c1 * 18;
1381 main_info.page_info[main_info.draw_page].pobs[s1].pob_data = &rabbit_gobs;
1386 if (update_count == 1) {
1389 draw_pobs(main_info.draw_page);
1394 draw_flies(main_info.draw_page);
1399 if (mod_fade_direction == 1) {
1402 dj_set_mod_volume((char)mod_vol);
1407 dj_set_mod_volume((char)mod_vol);
1411 if (mod_fade_direction == 1) {
1414 dj_set_sfx_volume((char)sfx_vol);
1419 dj_set_sfx_volume((char)sfx_vol);
1424 for (c1 = 0; c1 < 768; c1++) {
1425 if (cur_pal[c1] < pal[c1]) {
1428 } else if (cur_pal[c1] > pal[c1]) {
1433 if (fade_flag == 0 && end_loop_flag == 1)
1436 if (update_count == 1) {
1437 main_info.draw_page ^= 1;
1438 main_info.view_page ^= 1;
1440 flippage(main_info.view_page);
1446 setpalette(0, 256, cur_pal);
1448 if (update_count == 1) {
1452 redraw_flies_background(main_info.draw_page);
1454 redraw_pob_backgrounds(main_info.draw_page);
1456 draw_leftovers(main_info.draw_page);
1466 if ( (player[client_player_num].dead_flag == 0) &&
1468 (player[client_player_num].action_left) ||
1469 (player[client_player_num].action_right) ||
1470 (player[client_player_num].action_up) ||
1471 (player[client_player_num].jump_ready == 0)
1474 tellServerNewPosition();
1479 update_count = intr_sysupdate();
1483 if ((server_said_bye) || ((fade_flag == 0) && (end_loop_flag == 1)))
1487 if ((fade_flag == 0) && (end_loop_flag == 1))
1494 serverTellEveryoneGoodbye();
1495 SDLNet_TCP_Close(sock);
1498 if (!server_said_bye) {
1499 tellServerGoodbye();
1502 SDLNet_TCP_Close(sock);
1508 main_info.view_page = 0;
1509 main_info.draw_page = 1;
1511 dj_stop_sfx_channel(4);
1515 memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
1516 register_mask(mask_pic);
1518 register_background(NULL, NULL);
1522 put_text(main_info.view_page, 100, 50, "DOTT", 2);
1523 put_text(main_info.view_page, 160, 50, "JIFFY", 2);
1524 put_text(main_info.view_page, 220, 50, "FIZZ", 2);
1525 put_text(main_info.view_page, 280, 50, "MIJJI", 2);
1526 put_text(main_info.view_page, 40, 80, "DOTT", 2);
1527 put_text(main_info.view_page, 40, 110, "JIFFY", 2);
1528 put_text(main_info.view_page, 40, 140, "FIZZ", 2);
1529 put_text(main_info.view_page, 40, 170, "MIJJI", 2);
1531 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1532 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
1534 sprintf(str1, "%d", player[c1].bumped[c2]);
1535 put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, str1, 2);
1537 put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, "-", 2);
1539 sprintf(str1, "%d", player[c1].bumps);
1540 put_text(main_info.view_page, 350, 80 + c1 * 30, str1, 2);
1543 put_text(main_info.view_page, 200, 230, "Press ESC to continue", 2);
1547 flippage(main_info.view_page);
1549 if ((handle = dat_open("menu.pcx")) == 0) {
1550 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1553 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
1554 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1559 for (c1 = 0; c1 < 16; c1++) {
1560 pal[(240 + c1) * 3 + 0] = c1 << 2;
1561 pal[(240 + c1) * 3 + 1] = c1 << 2;
1562 pal[(240 + c1) * 3 + 2] = c1 << 2;
1565 memset(cur_pal, 0, 768);
1567 setpalette(0, 256, cur_pal);
1570 dj_ready_mod(MOD_SCORES);
1571 dj_set_mod_volume((char)mod_vol);
1575 while (key_pressed(1) == 0) {
1578 dj_set_mod_volume((char)mod_vol);
1579 for (c1 = 0; c1 < 768; c1++) {
1580 if (cur_pal[c1] < pal[c1])
1586 setpalette(0, 256, cur_pal);
1587 flippage(main_info.view_page);
1589 while (key_pressed(1) == 1) {
1594 memset(pal, 0, 768);
1596 while (mod_vol > 0) {
1598 dj_set_mod_volume((char)mod_vol);
1599 for (c1 = 0; c1 < 768; c1++) {
1600 if (cur_pal[c1] > pal[c1])
1605 setpalette(0, 256, cur_pal);
1606 flippage(main_info.view_page);
1609 fillpalette(0, 0, 0);
1615 break; /* don't go back to menu if in net game. */
1624 void steer_players(void)
1629 update_player_actions();
1631 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1633 if (player[c1].enabled == 1) {
1635 if (player[c1].dead_flag == 0) {
1637 if (player[c1].action_left && player[c1].action_right) {
1638 if (player[c1].direction == 0) {
1639 if (player[c1].action_right) {
1640 s1 = (player[c1].x >> 16);
1641 s2 = (player[c1].y >> 16);
1642 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1643 if (player[c1].x_add < 0)
1644 player[c1].x_add += 1024;
1646 player[c1].x_add += 768;
1647 } 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)) {
1648 if (player[c1].x_add > 0)
1649 player[c1].x_add += 1024;
1651 player[c1].x_add += 768;
1653 if (player[c1].x_add < 0) {
1654 player[c1].x_add += 16384;
1655 if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1656 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);
1658 player[c1].x_add += 12288;
1660 if (player[c1].x_add > 98304L)
1661 player[c1].x_add = 98304L;
1662 player[c1].direction = 0;
1663 if (player[c1].anim == 0) {
1664 player[c1].anim = 1;
1665 player[c1].frame = 0;
1666 player[c1].frame_tick = 0;
1667 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1671 if (player[c1].action_left) {
1672 s1 = (player[c1].x >> 16);
1673 s2 = (player[c1].y >> 16);
1674 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1675 if (player[c1].x_add > 0)
1676 player[c1].x_add -= 1024;
1678 player[c1].x_add -= 768;
1679 } 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)) {
1680 if (player[c1].x_add > 0)
1681 player[c1].x_add -= 1024;
1683 player[c1].x_add -= 768;
1685 if (player[c1].x_add > 0) {
1686 player[c1].x_add -= 16384;
1687 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1688 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);
1690 player[c1].x_add -= 12288;
1692 if (player[c1].x_add < -98304L)
1693 player[c1].x_add = -98304L;
1694 player[c1].direction = 1;
1695 if (player[c1].anim == 0) {
1696 player[c1].anim = 1;
1697 player[c1].frame = 0;
1698 player[c1].frame_tick = 0;
1699 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1703 } else if (player[c1].action_left) {
1704 s1 = (player[c1].x >> 16);
1705 s2 = (player[c1].y >> 16);
1706 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1707 if (player[c1].x_add > 0)
1708 player[c1].x_add -= 1024;
1710 player[c1].x_add -= 768;
1711 } 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)) {
1712 if (player[c1].x_add > 0)
1713 player[c1].x_add -= 1024;
1715 player[c1].x_add -= 768;
1717 if (player[c1].x_add > 0) {
1718 player[c1].x_add -= 16384;
1719 if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1720 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);
1722 player[c1].x_add -= 12288;
1724 if (player[c1].x_add < -98304L)
1725 player[c1].x_add = -98304L;
1726 player[c1].direction = 1;
1727 if (player[c1].anim == 0) {
1728 player[c1].anim = 1;
1729 player[c1].frame = 0;
1730 player[c1].frame_tick = 0;
1731 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1733 } else if (player[c1].action_right) {
1734 s1 = (player[c1].x >> 16);
1735 s2 = (player[c1].y >> 16);
1736 if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1737 if (player[c1].x_add < 0)
1738 player[c1].x_add += 1024;
1740 player[c1].x_add += 768;
1741 } 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)) {
1742 if (player[c1].x_add > 0)
1743 player[c1].x_add += 1024;
1745 player[c1].x_add += 768;
1747 if (player[c1].x_add < 0) {
1748 player[c1].x_add += 16384;
1749 if (player[c1].x_add < 98304L && player[c1].in_water == 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 player[c1].x_add += 12288;
1754 if (player[c1].x_add > 98304L)
1755 player[c1].x_add = 98304L;
1756 player[c1].direction = 0;
1757 if (player[c1].anim == 0) {
1758 player[c1].anim = 1;
1759 player[c1].frame = 0;
1760 player[c1].frame_tick = 0;
1761 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1763 } else if ((!player[c1].action_left) && (!player[c1].action_right)) {
1764 s1 = (player[c1].x >> 16);
1765 s2 = (player[c1].y >> 16);
1766 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)))) {
1767 if (player[c1].x_add < 0) {
1768 player[c1].x_add += 16384;
1769 if (player[c1].x_add > 0)
1770 player[c1].x_add = 0;
1772 player[c1].x_add -= 16384;
1773 if (player[c1].x_add < 0)
1774 player[c1].x_add = 0;
1776 if (player[c1].x_add != 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1777 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);
1779 if (player[c1].anim == 1) {
1780 player[c1].anim = 0;
1781 player[c1].frame = 0;
1782 player[c1].frame_tick = 0;
1783 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1787 if (pogostick == 1 || (player[c1].jump_ready == 1 && player[c1].action_up)) {
1788 s1 = (player[c1].x >> 16);
1789 s2 = (player[c1].y >> 16);
1792 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) {
1793 player[c1].y_add = -280000L;
1794 player[c1].anim = 2;
1795 player[c1].frame = 0;
1796 player[c1].frame_tick = 0;
1797 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1798 player[c1].jump_ready = 0;
1799 player[c1].jump_abort = 1;
1801 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1803 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1805 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)) {
1806 player[c1].y_add = -196608L;
1807 player[c1].in_water = 0;
1808 player[c1].anim = 2;
1809 player[c1].frame = 0;
1810 player[c1].frame_tick = 0;
1811 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1812 player[c1].jump_ready = 0;
1813 player[c1].jump_abort = 1;
1815 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1817 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1820 if (pogostick == 0 && (!player[c1].action_up)) {
1821 player[c1].jump_ready = 1;
1822 if (player[c1].in_water == 0 && player[c1].y_add < 0 && player[c1].jump_abort == 1) {
1823 if (bunnies_in_space == 0)
1824 player[c1].y_add += 32768;
1826 player[c1].y_add += 16384;
1827 if (player[c1].y_add > 0)
1828 player[c1].y_add = 0;
1833 if (player[c1].action_up) {
1834 player[c1].y_add -= 16384;
1835 if (player[c1].y_add < -400000L)
1836 player[c1].y_add = -400000L;
1837 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))
1838 player[c1].in_water = 0;
1840 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);
1845 player[c1].x += player[c1].x_add;
1846 if ((player[c1].x >> 16) < 0) {
1848 player[c1].x_add = 0;
1850 if ((player[c1].x >> 16) + 15 > 351) {
1851 player[c1].x = 336L << 16;
1852 player[c1].x_add = 0;
1854 if (player[c1].y > 0) {
1855 s1 = (player[c1].x >> 16);
1856 s2 = (player[c1].y >> 16);
1857 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) {
1858 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1859 player[c1].x_add = 0;
1861 s1 = (player[c1].x >> 16);
1862 s2 = (player[c1].y >> 16);
1863 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) {
1864 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1865 player[c1].x_add = 0;
1868 s1 = (player[c1].x >> 16);
1870 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) {
1871 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1872 player[c1].x_add = 0;
1874 s1 = (player[c1].x >> 16);
1876 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) {
1877 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1878 player[c1].x_add = 0;
1882 player[c1].y += player[c1].y_add;
1884 s1 = (player[c1].x >> 16);
1885 s2 = (player[c1].y >> 16);
1886 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))) {
1887 player[c1].y = ((player[c1].y >> 16) & 0xfff0) << 16;
1888 player[c1].y_add = -400000L;
1889 player[c1].anim = 2;
1890 player[c1].frame = 0;
1891 player[c1].frame_tick = 0;
1892 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1893 player[c1].jump_ready = 0;
1894 player[c1].jump_abort = 0;
1895 for (c2 = 0; c2 < NUM_OBJECTS; c2++) {
1896 if (objects[c2].used == 1 && objects[c2].type == OBJ_SPRING) {
1897 if (ban_map[(s2 + 15) >> 4][(s1 + 8) >> 4] == BAN_SPRING) {
1898 if ((objects[c2].x >> 20) == ((s1 + 8) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1899 objects[c2].frame = 0;
1900 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1901 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1905 if (ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
1906 if ((objects[c2].x >> 20) == (s1 >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1907 objects[c2].frame = 0;
1908 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1909 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1912 } else if (ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1913 if ((objects[c2].x >> 20) == ((s1 + 15) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1914 objects[c2].frame = 0;
1915 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1916 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1923 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1925 s1 = (player[c1].x >> 16);
1926 s2 = (player[c1].y >> 16);
1929 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) {
1930 player[c1].y = (((s2 + 16) & 0xfff0)) << 16;
1931 player[c1].y_add = 0;
1932 player[c1].anim = 0;
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 s1 = (player[c1].x >> 16);
1938 s2 = (player[c1].y >> 16);
1941 if (ban_map[(s2 + 8) >> 4][(s1 + 8) >> 4] == BAN_WATER) {
1942 if (player[c1].in_water == 0) {
1943 player[c1].in_water = 1;
1944 player[c1].anim = 4;
1945 player[c1].frame = 0;
1946 player[c1].frame_tick = 0;
1947 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1948 if (player[c1].y_add >= 32768) {
1949 add_object(OBJ_SPLASH, (player[c1].x >> 16) + 8, ((player[c1].y >> 16) & 0xfff0) + 15, 0, 0, OBJ_ANIM_SPLASH, 0);
1950 if (blood_is_thicker_than_water == 0)
1951 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1953 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 5000), 64, 0, 0, -1);
1956 player[c1].y_add -= 1536;
1957 if (player[c1].y_add < 0 && player[c1].anim != 5) {
1958 player[c1].anim = 5;
1959 player[c1].frame = 0;
1960 player[c1].frame_tick = 0;
1961 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1963 if (player[c1].y_add < -65536L)
1964 player[c1].y_add = -65536L;
1965 if (player[c1].y_add > 65535L)
1966 player[c1].y_add = 65535L;
1967 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) {
1968 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1969 player[c1].y_add = 0;
1971 } 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) {
1972 player[c1].in_water = 0;
1973 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1974 player[c1].y_add = 0;
1975 if (player[c1].anim != 0 && player[c1].anim != 1) {
1976 player[c1].anim = 0;
1977 player[c1].frame = 0;
1978 player[c1].frame_tick = 0;
1979 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1982 if (player[c1].in_water == 0) {
1983 if (bunnies_in_space == 0)
1984 player[c1].y_add += 12288;
1986 player[c1].y_add += 6144;
1987 if (player[c1].y_add > 327680L)
1988 player[c1].y_add = 327680L;
1990 player[c1].y = (player[c1].y & 0xffff0000) + 0x10000;
1991 player[c1].y_add = 0;
1993 player[c1].in_water = 0;
1995 if (player[c1].y_add > 36864 && player[c1].anim != 3 && player[c1].in_water == 0) {
1996 player[c1].anim = 3;
1997 player[c1].frame = 0;
1998 player[c1].frame_tick = 0;
1999 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
2004 player[c1].frame_tick++;
2005 if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
2007 if (player[c1].frame >= player_anims[player[c1].anim].num_frames) {
2008 if (player[c1].anim != 6)
2009 player[c1].frame = player_anims[player[c1].anim].restart_frame;
2011 position_player(c1);
2013 player[c1].frame_tick = 0;
2015 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
2024 void position_player(int player_num)
2033 if (ban_map[s2][s1] == BAN_VOID && (ban_map[s2 + 1][s1] == BAN_SOLID || ban_map[s2 + 1][s1] == BAN_ICE))
2036 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
2037 if (c1 != player_num && player[c1].enabled == 1) {
2038 if (abs((s1 << 4) - (player[c1].x >> 16)) < 32 && abs((s2 << 4) - (player[c1].y >> 16)) < 32)
2042 if (c1 == JNB_MAX_PLAYERS) {
2043 player[player_num].x = (long) s1 << 20;
2044 player[player_num].y = (long) s2 << 20;
2045 player[player_num].x_add = player[player_num].y_add = 0;
2046 player[player_num].direction = 0;
2047 player[player_num].jump_ready = 1;
2048 player[player_num].in_water = 0;
2049 player[player_num].anim = 0;
2050 player[player_num].frame = 0;
2051 player[player_num].frame_tick = 0;
2052 player[player_num].image = player_anims[player[player_num].anim].frame[player[player_num].frame].image;
2057 serverSendAlive(player_num);
2059 player[player_num].dead_flag = 0;
2069 void add_object(int type, int x, int y, int x_add, int y_add, int anim, int frame)
2073 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
2074 if (objects[c1].used == 0) {
2075 objects[c1].used = 1;
2076 objects[c1].type = type;
2077 objects[c1].x = (long) x << 16;
2078 objects[c1].y = (long) y << 16;
2079 objects[c1].x_add = x_add;
2080 objects[c1].y_add = y_add;
2081 objects[c1].x_acc = 0;
2082 objects[c1].y_acc = 0;
2083 objects[c1].anim = anim;
2084 objects[c1].frame = frame;
2085 objects[c1].ticks = object_anims[anim].frame[frame].ticks;
2086 objects[c1].image = object_anims[anim].frame[frame].image;
2094 void update_objects(void)
2099 for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
2100 if (objects[c1].used == 1) {
2101 switch (objects[c1].type) {
2103 objects[c1].ticks--;
2104 if (objects[c1].ticks <= 0) {
2105 objects[c1].frame++;
2106 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames) {
2107 objects[c1].frame--;
2108 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2110 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2111 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2114 if (objects[c1].used == 1)
2115 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2118 objects[c1].ticks--;
2119 if (objects[c1].ticks <= 0) {
2120 objects[c1].frame++;
2121 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2122 objects[c1].used = 0;
2124 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2125 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2128 if (objects[c1].used == 1)
2129 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2132 objects[c1].x += objects[c1].x_add;
2133 objects[c1].y += objects[c1].y_add;
2134 objects[c1].ticks--;
2135 if (objects[c1].ticks <= 0) {
2136 objects[c1].frame++;
2137 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2138 objects[c1].used = 0;
2140 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2141 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2144 if (objects[c1].used == 1)
2145 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2147 case OBJ_YEL_BUTFLY:
2148 case OBJ_PINK_BUTFLY:
2149 objects[c1].x_acc += rnd(128) - 64;
2150 if (objects[c1].x_acc < -1024)
2151 objects[c1].x_acc = -1024;
2152 if (objects[c1].x_acc > 1024)
2153 objects[c1].x_acc = 1024;
2154 objects[c1].x_add += objects[c1].x_acc;
2155 if (objects[c1].x_add < -32768)
2156 objects[c1].x_add = -32768;
2157 if (objects[c1].x_add > 32768)
2158 objects[c1].x_add = 32768;
2159 objects[c1].x += objects[c1].x_add;
2160 if ((objects[c1].x >> 16) < 16) {
2161 objects[c1].x = 16 << 16;
2162 objects[c1].x_add = -objects[c1].x_add >> 2;
2163 objects[c1].x_acc = 0;
2164 } else if ((objects[c1].x >> 16) > 350) {
2165 objects[c1].x = 350 << 16;
2166 objects[c1].x_add = -objects[c1].x_add >> 2;
2167 objects[c1].x_acc = 0;
2169 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
2170 if (objects[c1].x_add < 0) {
2171 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2173 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2175 objects[c1].x_add = -objects[c1].x_add >> 2;
2176 objects[c1].x_acc = 0;
2178 objects[c1].y_acc += rnd(64) - 32;
2179 if (objects[c1].y_acc < -1024)
2180 objects[c1].y_acc = -1024;
2181 if (objects[c1].y_acc > 1024)
2182 objects[c1].y_acc = 1024;
2183 objects[c1].y_add += objects[c1].y_acc;
2184 if (objects[c1].y_add < -32768)
2185 objects[c1].y_add = -32768;
2186 if (objects[c1].y_add > 32768)
2187 objects[c1].y_add = 32768;
2188 objects[c1].y += objects[c1].y_add;
2189 if ((objects[c1].y >> 16) < 0) {
2191 objects[c1].y_add = -objects[c1].y_add >> 2;
2192 objects[c1].y_acc = 0;
2193 } else if ((objects[c1].y >> 16) > 255) {
2194 objects[c1].y = 255 << 16;
2195 objects[c1].y_add = -objects[c1].y_add >> 2;
2196 objects[c1].y_acc = 0;
2198 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
2199 if (objects[c1].y_add < 0) {
2200 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2202 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2204 objects[c1].y_add = -objects[c1].y_add >> 2;
2205 objects[c1].y_acc = 0;
2207 if (objects[c1].type == OBJ_YEL_BUTFLY) {
2208 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_LEFT) {
2209 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_LEFT;
2210 objects[c1].frame = 0;
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;
2213 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_RIGHT) {
2214 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_RIGHT;
2215 objects[c1].frame = 0;
2216 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2217 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2220 if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_LEFT) {
2221 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_LEFT;
2222 objects[c1].frame = 0;
2223 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2224 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2225 } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_RIGHT) {
2226 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_RIGHT;
2227 objects[c1].frame = 0;
2228 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2229 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2232 objects[c1].ticks--;
2233 if (objects[c1].ticks <= 0) {
2234 objects[c1].frame++;
2235 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2236 objects[c1].frame = object_anims[objects[c1].anim].restart_frame;
2238 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2239 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2242 if (objects[c1].used == 1)
2243 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2247 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 0);
2248 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
2249 objects[c1].y_add += 3072;
2250 if (objects[c1].y_add > 196608L)
2251 objects[c1].y_add = 196608L;
2252 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
2253 if (objects[c1].x_add < 0) {
2254 if (objects[c1].x_add < -65536L)
2255 objects[c1].x_add = -65536L;
2256 objects[c1].x_add += 1024;
2257 if (objects[c1].x_add > 0)
2258 objects[c1].x_add = 0;
2260 if (objects[c1].x_add > 65536L)
2261 objects[c1].x_add = 65536L;
2262 objects[c1].x_add -= 1024;
2263 if (objects[c1].x_add < 0)
2264 objects[c1].x_add = 0;
2266 objects[c1].y_add += 1024;
2267 if (objects[c1].y_add < -65536L)
2268 objects[c1].y_add = -65536L;
2269 if (objects[c1].y_add > 65536L)
2270 objects[c1].y_add = 65536L;
2272 objects[c1].x += objects[c1].x_add;
2273 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)) {
2274 if (objects[c1].x_add < 0) {
2275 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2276 objects[c1].x_add = -objects[c1].x_add >> 2;
2278 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2279 objects[c1].x_add = -objects[c1].x_add >> 2;
2282 objects[c1].y += objects[c1].y_add;
2283 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
2284 objects[c1].used = 0;
2285 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
2286 if (objects[c1].y_add < 0) {
2287 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
2288 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2289 objects[c1].x_add >>= 2;
2290 objects[c1].y_add = -objects[c1].y_add >> 2;
2293 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
2294 if (objects[c1].y_add > 131072L) {
2295 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2296 objects[c1].x_add >>= 2;
2297 objects[c1].y_add = -objects[c1].y_add >> 2;
2299 objects[c1].used = 0;
2300 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
2301 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2302 if (objects[c1].y_add > 131072L)
2303 objects[c1].y_add = -objects[c1].y_add >> 2;
2305 objects[c1].y_add = 0;
2309 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
2310 objects[c1].x_add = -16384;
2311 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
2312 objects[c1].x_add = 16384;
2313 if (objects[c1].used == 1) {
2314 s1 = (int)(atan2(objects[c1].y_add, objects[c1].x_add) * 4 / M_PI);
2321 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame + s1, &object_gobs);
2325 if (rnd(100) < 30) {
2326 if (objects[c1].frame == 76)
2327 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 1);
2328 else if (objects[c1].frame == 77)
2329 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 2);
2330 else if (objects[c1].frame == 78)
2331 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 3);
2333 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
2334 objects[c1].y_add += 3072;
2335 if (objects[c1].y_add > 196608L)
2336 objects[c1].y_add = 196608L;
2337 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
2338 if (objects[c1].x_add < 0) {
2339 if (objects[c1].x_add < -65536L)
2340 objects[c1].x_add = -65536L;
2341 objects[c1].x_add += 1024;
2342 if (objects[c1].x_add > 0)
2343 objects[c1].x_add = 0;
2345 if (objects[c1].x_add > 65536L)
2346 objects[c1].x_add = 65536L;
2347 objects[c1].x_add -= 1024;
2348 if (objects[c1].x_add < 0)
2349 objects[c1].x_add = 0;
2351 objects[c1].y_add += 1024;
2352 if (objects[c1].y_add < -65536L)
2353 objects[c1].y_add = -65536L;
2354 if (objects[c1].y_add > 65536L)
2355 objects[c1].y_add = 65536L;
2357 objects[c1].x += objects[c1].x_add;
2358 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)) {
2359 if (objects[c1].x_add < 0) {
2360 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2361 objects[c1].x_add = -objects[c1].x_add >> 2;
2363 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2364 objects[c1].x_add = -objects[c1].x_add >> 2;
2367 objects[c1].y += objects[c1].y_add;
2368 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
2369 objects[c1].used = 0;
2370 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
2371 if (objects[c1].y_add < 0) {
2372 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
2373 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2374 objects[c1].x_add >>= 2;
2375 objects[c1].y_add = -objects[c1].y_add >> 2;
2378 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
2379 if (objects[c1].y_add > 131072L) {
2380 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2381 objects[c1].x_add >>= 2;
2382 objects[c1].y_add = -objects[c1].y_add >> 2;
2384 if (rnd(100) < 10) {
2386 add_leftovers(0, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
2387 add_leftovers(1, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
2389 objects[c1].used = 0;
2391 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
2392 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2393 if (objects[c1].y_add > 131072L)
2394 objects[c1].y_add = -objects[c1].y_add >> 2;
2396 objects[c1].y_add = 0;
2400 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
2401 objects[c1].x_add = -16384;
2402 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
2403 objects[c1].x_add = 16384;
2404 if (objects[c1].used == 1)
2405 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame, &object_gobs);
2407 case OBJ_FLESH_TRACE:
2408 objects[c1].ticks--;
2409 if (objects[c1].ticks <= 0) {
2410 objects[c1].frame++;
2411 if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2412 objects[c1].used = 0;
2414 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2415 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2418 if (objects[c1].used == 1)
2419 add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2428 int add_pob(int page, int x, int y, int image, gob_t *pob_data)
2431 if (main_info.page_info[page].num_pobs >= NUM_POBS)
2434 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].x = x;
2435 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].y = y;
2436 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].image = image;
2437 main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].pob_data = pob_data;
2438 main_info.page_info[page].num_pobs++;
2445 void draw_flies(int page)
2449 for (c2 = 0; c2 < NUM_FLIES; c2++) {
2450 flies[c2].back[main_info.draw_page] = get_pixel(main_info.draw_page, flies[c2].x, flies[c2].y);
2451 flies[c2].back_defined[main_info.draw_page] = 1;
2452 if (mask_pic[(flies[c2].y * JNB_WIDTH) + flies[c2].x] == 0)
2453 set_pixel(main_info.draw_page, flies[c2].x, flies[c2].y, 0);
2457 void draw_pobs(int page)
2464 for (c1 = main_info.page_info[page].num_pobs - 1; c1 >= 0; c1--) {
2465 main_info.page_info[page].pobs[c1].back_buf_ofs = back_buf_ofs;
2466 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);
2468 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;
2470 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;
2471 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);
2477 void redraw_flies_background(int page)
2481 for (c2 = NUM_FLIES - 1; c2 >= 0; c2--) {
2482 if (flies[c2].back_defined[page] == 1)
2483 set_pixel(page, flies[c2].old_draw_x, flies[c2].old_draw_y, flies[c2].back[page]);
2484 flies[c2].old_draw_x = flies[c2].x;
2485 flies[c2].old_draw_y = flies[c2].y;
2490 void redraw_pob_backgrounds(int page)
2494 for (c1 = 0; c1 < main_info.page_info[page].num_pobs; c1++)
2495 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);
2500 int add_leftovers(int page, int x, int y, int image, gob_t *pob_data)
2503 if (leftovers.page[page].num_pobs >= NUM_LEFTOVERS)
2506 leftovers.page[page].pobs[leftovers.page[page].num_pobs].x = x;
2507 leftovers.page[page].pobs[leftovers.page[page].num_pobs].y = y;
2508 leftovers.page[page].pobs[leftovers.page[page].num_pobs].image = image;
2509 leftovers.page[page].pobs[leftovers.page[page].num_pobs].pob_data = pob_data;
2510 leftovers.page[page].num_pobs++;
2517 void draw_leftovers(int page)
2521 for (c1 = leftovers.page[page].num_pobs - 1; c1 >= 0; c1--)
2522 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);
2524 leftovers.page[page].num_pobs = 0;
2529 int init_level(int level, char *pal)
2531 unsigned char *handle;
2535 if ((handle = dat_open("level.pcx")) == 0) {
2536 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2539 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
2540 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2544 flip_pixels(background_pic);
2545 if ((handle = dat_open("mask.pcx")) == 0) {
2546 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2549 if (read_pcx(handle, mask_pic, JNB_WIDTH*JNB_HEIGHT, 0) != 0) {
2550 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2554 flip_pixels(mask_pic);
2555 register_mask(mask_pic);
2557 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
2558 if (player[c1].enabled == 1) {
2559 player[c1].bumps = 0;
2560 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++)
2561 player[c1].bumped[c2] = 0;
2562 position_player(c1);
2566 for (c1 = 0; c1 < NUM_OBJECTS; c1++)
2567 objects[c1].used = 0;
2569 for (c1 = 0; c1 < 16; c1++) {
2570 for (c2 = 0; c2 < 22; c2++) {
2571 if (ban_map[c1][c2] == BAN_SPRING)
2572 add_object(OBJ_SPRING, c2 << 4, c1 << 4, 0, 0, OBJ_ANIM_SPRING, 5);
2579 if (ban_map[s2][s1] == BAN_VOID) {
2580 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2587 if (ban_map[s2][s1] == BAN_VOID) {
2588 add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2595 if (ban_map[s2][s1] == BAN_VOID) {
2596 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2603 if (ban_map[s2][s1] == BAN_VOID) {
2604 add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2614 void deinit_level(void)
2622 #define PATH_MAX 1024
2628 unsigned char *datafile_buffer = NULL;
2630 static void preread_datafile(const char *fname)
2636 char *gzfilename = alloca(strlen(fname) + 4);
2641 strcpy(gzfilename, fname);
2642 strcat(gzfilename, ".gz");
2644 gzf = gzopen(gzfilename, "rb");
2649 if (bufpos >= bufsize) {
2650 bufsize += 1024 * 1024;
2651 datafile_buffer = (unsigned char *) realloc(datafile_buffer, bufsize);
2652 if (datafile_buffer == NULL) {
2653 perror("realloc()");
2658 br = gzread(gzf, datafile_buffer + bufpos, bufsize - bufpos);
2660 fprintf(stderr, "gzread failed.\n");
2665 } while (!gzeof(gzf));
2667 /* try to shrink buffer... */
2668 ptr = (unsigned char *) realloc(datafile_buffer, bufpos);
2670 datafile_buffer = ptr;
2676 /* drop through and try for an uncompressed datafile... */
2679 fd = open(fname, O_RDONLY | O_BINARY);
2681 fprintf(stderr, "can't open %s:", fname);
2686 len = filelength(fd);
2687 datafile_buffer = (unsigned char *) malloc(len);
2688 if (datafile_buffer == NULL) {
2694 if (read(fd, datafile_buffer, len) != len) {
2704 int init_program(int argc, char *argv[], char *pal)
2706 char *netarg = NULL;
2707 unsigned char *handle = (unsigned char *) NULL;
2712 int player_anim_data[] = {
2713 1, 0, 0, 0x7fff, 0, 0, 0, 0, 0, 0,
2714 4, 0, 0, 4, 1, 4, 2, 4, 3, 4,
2715 1, 0, 4, 0x7fff, 0, 0, 0, 0, 0, 0,
2716 4, 2, 5, 8, 6, 10, 7, 3, 6, 3,
2717 1, 0, 6, 0x7fff, 0, 0, 0, 0, 0, 0,
2718 2, 1, 5, 8, 4, 0x7fff, 0, 0, 0, 0,
2719 1, 0, 8, 5, 0, 0, 0, 0, 0, 0
2723 memset(&net_info, 0, sizeof(net_info));
2727 if (__djgpp_nearptr_enable() == 0)
2733 if (hook_keyb_handler() != 0)
2736 memset(&main_info, 0, sizeof(main_info));
2738 strcpy(datfile_name, DATA_PATH);
2740 force2 = force3 = 0;
2743 for (c1 = 1; c1 < argc; c1++) {
2744 if (stricmp(argv[c1], "-nosound") == 0)
2745 main_info.no_sound = 1;
2746 else if (stricmp(argv[c1], "-musicnosound") == 0)
2747 main_info.music_no_sound = 1;
2748 else if (stricmp(argv[c1], "-nogore") == 0)
2749 main_info.no_gore = 1;
2750 else if (stricmp(argv[c1], "-noflies") == 0)
2752 else if (stricmp(argv[c1], "-nojoy") == 0)
2753 main_info.joy_enabled = 0;
2754 else if (stricmp(argv[c1], "-fireworks") == 0)
2755 main_info.fireworks = 1;
2757 else if (stricmp(argv[c1], "-fullscreen") == 0)
2760 else if (stricmp(argv[c1], "-scaleup") == 0)
2762 else if (stricmp(argv[c1], "-mirror") == 0)
2764 else if (stricmp(argv[c1], "-dat") == 0) {
2765 if (c1 < (argc - 1)) {
2768 if ((f = fopen(argv[c1 + 1], "rb")) != NULL) {
2770 strcpy(datfile_name, argv[c1 + 1]);
2773 } else if (stricmp(argv[c1], "-player") == 0) {
2774 if (c1 < (argc - 1)) {
2775 if (client_player_num < 0)
2776 client_player_num = atoi(argv[c1 + 1]);
2779 } else if (stricmp(argv[c1], "-server") == 0) {
2780 if (c1 < (argc - 1)) {
2783 netarg = argv[c1 + 1];
2785 } else if (stricmp(argv[c1], "-connect") == 0) {
2786 if (c1 < (argc - 1)) {
2789 netarg = argv[c1 + 1];
2792 } else if (stricmp(argv[c1], "-mouse") == 0) {
2793 if (c1 < (argc - 1)) {
2794 if (stricmp(argv[c1 + 1], "2") == 0)
2796 if (stricmp(argv[c1 + 1], "3") == 0)
2800 else if (strstr(argv[1],"-v")) {
2801 printf("jumpnbump %s compiled %s at %s with",JNB_VERSION,__DATE__,__TIME__);
2805 printf(" network support.\n");
2808 else if (strstr(argv[1],"-h")) {
2809 printf("Usage: jumpnbump [OPTION]...\n");
2811 printf(" -h this help\n");
2812 printf(" -v print version\n");
2813 printf(" -dat level.dat play a different level\n");
2815 printf(" -server playercount start as server waiting for players\n");
2816 printf(" -connect host connect to server\n");
2818 printf(" -player num set main player to num (0-3). Needed for networking\n");
2819 printf(" -fireworks screensaver mode\n");
2820 printf(" -fullscreen run in fullscreen mode\n");
2821 printf(" -nosound play without sound\n");
2822 printf(" -nogore play without blood\n");
2823 printf(" -noflies disable flies\n");
2824 printf(" -mirror play with mirrored level\n");
2825 printf(" -scaleup play with doubled resolution (800x512)\n");
2826 printf(" -musicnosound play with music but without sound\n");
2833 preread_datafile(datfile_name);
2836 /** It should not be necessary to assign a default player number here. The
2837 server assigns one in init_server, the client gets one assigned by the server,
2838 all provided the user didn't choose one on the commandline. */
2840 if (client_player_num < 0)
2841 client_player_num = 0;
2842 player[client_player_num].enabled = 1;
2846 main_info.pob_backbuf[0] = malloc(screen_pitch*screen_height*bytes_per_pixel);
2847 main_info.pob_backbuf[1] = malloc(screen_pitch*screen_height*bytes_per_pixel);
2849 for (c1 = 0; c1 < 7; c1++) {
2850 player_anims[c1].num_frames = player_anim_data[c1 * 10];
2851 player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
2852 for (c2 = 0; c2 < 4; c2++) {
2853 player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
2854 player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
2858 if ((handle = dat_open("menu.pcx")) == 0) {
2859 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2862 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
2863 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2867 if ((handle = dat_open("rabbit.gob")) == 0) {
2868 strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
2871 if (register_gob(handle, &rabbit_gobs, dat_filelen("rabbit.gob"))) {
2876 if ((handle = dat_open("objects.gob")) == 0) {
2877 strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
2880 if (register_gob(handle, &object_gobs, dat_filelen("objects.gob"))) {
2885 if ((handle = dat_open("font.gob")) == 0) {
2886 strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
2889 if (register_gob(handle, &font_gobs, dat_filelen("font.gob"))) {
2894 if ((handle = dat_open("numbers.gob")) == 0) {
2895 strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
2898 if (register_gob(handle, &number_gobs, dat_filelen("numbers.gob"))) {
2903 if (read_level() != 0) {
2904 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2910 if (main_info.no_sound == 0) {
2912 dj_set_mixing_freq(20000);
2916 dj_set_num_sfx_channels(5);
2917 dj_set_sfx_volume(64);
2921 if ((handle = dat_open("jump.mod")) == 0) {
2922 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2925 if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
2926 strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2930 if ((handle = dat_open("bump.mod")) == 0) {
2931 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2934 if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
2935 strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2939 if ((handle = dat_open("scores.mod")) == 0) {
2940 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2943 if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
2944 strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2948 if ((handle = dat_open("jump.smp")) == 0) {
2949 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2952 if (dj_load_sfx(handle, 0, dat_filelen("jump.smp"), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
2953 strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2957 if ((handle = dat_open("death.smp")) == 0) {
2958 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2961 if (dj_load_sfx(handle, 0, dat_filelen("death.smp"), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
2962 strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2966 if ((handle = dat_open("spring.smp")) == 0) {
2967 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2970 if (dj_load_sfx(handle, 0, dat_filelen("spring.smp"), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
2971 strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2975 if ((handle = dat_open("splash.smp")) == 0) {
2976 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2979 if (dj_load_sfx(handle, 0, dat_filelen("splash.smp"), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
2980 strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2984 if ((handle = dat_open("fly.smp")) == 0) {
2985 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2988 if (dj_load_sfx(handle, 0, dat_filelen("fly.smp"), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
2989 strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2993 dj_get_sfx_settings(SFX_FLY, &fly);
2995 fly.default_freq = SFX_FLY_FREQ;
2998 fly.loop_length = fly.length;
2999 dj_set_sfx_settings(SFX_FLY, &fly);
3002 if ((background_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
3004 if ((mask_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
3006 memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
3007 register_mask(mask_pic);
3010 for (c1 = 0; c1 < 16; c1++) {
3011 pal[(240 + c1) * 3 + 0] = c1 << 2;
3012 pal[(240 + c1) * 3 + 1] = c1 << 2;
3013 pal[(240 + c1) * 3 + 2] = c1 << 2;
3016 setpalette(0, 256, pal);
3020 recalculate_gob(&font_gobs, pal);
3022 if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
3024 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
3025 put_text(0, 200, 100, "Move the joystick to the", 2);
3026 put_text(0, 200, 115, "UPPER LEFT", 2);
3027 put_text(0, 200, 130, "and press button A", 2);
3028 put_text(0, 200, 200, "Or press ESC to use", 2);
3029 put_text(0, 200, 215, "previous settings", 2);
3030 if (calib_joy(0) != 0)
3033 register_background(NULL, NULL);
3035 main_info.view_page = 1;
3040 put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
3041 put_text(1, 200, 100, "Move the joystick to the", 2);
3042 put_text(1, 200, 115, "LOWER RIGHT", 2);
3043 put_text(1, 200, 130, "and press button A", 2);
3044 put_text(1, 200, 200, "Or press ESC to use", 2);
3045 put_text(1, 200, 215, "previous settings", 2);
3046 if (calib_joy(1) != 0)
3049 register_background(NULL, NULL);
3054 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
3055 put_text(0, 200, 100, "Move the joystick to the", 2);
3056 put_text(0, 200, 115, "CENTER", 2);
3057 put_text(0, 200, 130, "and press button A", 2);
3058 put_text(0, 200, 200, "Or press ESC to use", 2);
3059 put_text(0, 200, 215, "previous settings", 2);
3060 if (calib_joy(2) != 0)
3063 if (joy.calib_data.x1 == joy.calib_data.x2)
3064 joy.calib_data.x1 -= 10;
3065 if (joy.calib_data.x3 == joy.calib_data.x2)
3066 joy.calib_data.x3 += 10;
3067 if (joy.calib_data.y1 == joy.calib_data.y2)
3068 joy.calib_data.y1 -= 10;
3069 if (joy.calib_data.y3 == joy.calib_data.y2)
3070 joy.calib_data.y3 += 10;
3075 if (load_flag == 1) {
3076 if ((handle = dat_open("calib.dat")) == 0) {
3077 strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
3080 joy.calib_data.x1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3081 joy.calib_data.x2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3082 joy.calib_data.x3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3083 joy.calib_data.y1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3084 joy.calib_data.y2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3085 joy.calib_data.y3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3092 init_server(netarg);
3094 connect_to_server(netarg);
3103 void deinit_program(void)
3110 dj_free_mod(MOD_MENU);
3111 dj_free_mod(MOD_GAME);
3112 dj_free_sfx(SFX_DEATH);
3113 dj_free_sfx(SFX_SPRING);
3114 dj_free_sfx(SFX_SPLASH);
3117 if (background_pic != 0)
3118 free(background_pic);
3122 remove_keyb_handler();
3126 __dpmi_int(0x10, ®s);
3129 if (main_info.error_str[0] != 0) {
3130 printf(main_info.error_str);
3132 MessageBox(0, main_info.error_str, "Jump'n'Bump", 0);
3141 unsigned short rnd(unsigned short max)
3143 #if (RAND_MAX < 0x7fff)
3144 #error "rand returns too small values"
3145 #elif (RAND_MAX == 0x7fff)
3146 return (unsigned short)((rand()*2) % (int)max);
3148 return (unsigned short)(rand() % (int)max);
3153 int read_level(void)
3155 unsigned char *handle;
3159 if ((handle = dat_open("levelmap.txt")) == 0) {
3160 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
3164 for (c1 = 0; c1 < 16; c1++) {
3165 for (c2 = 0; c2 < 22; c2++) {
3167 chr = (int) *(handle++);
3168 if (chr >= '0' && chr <= '4')
3172 ban_map[c1][21-c2] = chr - '0';
3174 ban_map[c1][c2] = chr - '0';
3178 for (c2 = 0; c2 < 22; c2++)
3179 ban_map[16][c2] = BAN_SOLID;
3186 unsigned char *dat_open(char *file_name)
3194 if (datafile_buffer == NULL)
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) {
3212 ofs = ( (ptr[0] << 0) +
3217 return (datafile_buffer + ofs);
3226 int dat_filelen(char *file_name)
3234 memset(name, 0, sizeof(name));
3236 num = ( (datafile_buffer[0] << 0) +
3237 (datafile_buffer[1] << 8) +
3238 (datafile_buffer[2] << 16) +
3239 (datafile_buffer[3] << 24) );
3241 ptr = datafile_buffer + 4;
3243 for (c1 = 0; c1 < num; c1++) {
3245 memcpy(name, ptr, 12);
3248 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
3251 len = ( (ptr[0] << 0) +
3265 void write_calib_data(void)
3273 if ((handle = fopen(datfile_name, "rb")) == NULL)
3275 len = filelength(fileno(handle));
3276 if ((mem = malloc(len)) == NULL)
3278 fread(mem, 1, len, handle);
3282 num = *(int *) (&mem[0]);
3283 for (c1 = 0; c1 < num; c1++) {
3284 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
3285 ofs = *(int *) (&mem[ofs + 12]);
3291 mem[ofs] = joy.calib_data.x1 & 0xff;
3292 mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
3293 mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
3294 mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
3295 mem[ofs + 4] = joy.calib_data.x2 & 0xff;
3296 mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
3297 mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
3298 mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
3299 mem[ofs + 8] = joy.calib_data.x3 & 0xff;
3300 mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
3301 mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
3302 mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
3303 mem[ofs + 12] = joy.calib_data.y1 & 0xff;
3304 mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
3305 mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
3306 mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
3307 mem[ofs + 16] = joy.calib_data.y2 & 0xff;
3308 mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
3309 mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
3310 mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
3311 mem[ofs + 20] = joy.calib_data.y3 & 0xff;
3312 mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
3313 mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
3314 mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
3316 if ((handle = fopen(datfile_name, "wb")) == NULL)
3318 fwrite(mem, 1, len, handle);