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 * This file is part of Jump'n'Bump.
11 * Jump'n'Bump is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * Jump'n'Bump is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 #define M_PI 3.14159265358979323846
40 gob_t rabbit_gobs
= { 0 };
41 gob_t font_gobs
= { 0 };
42 gob_t object_gobs
= { 0 };
43 gob_t number_gobs
= { 0 };
45 main_info_t main_info
;
46 player_t player
[JNB_MAX_PLAYERS
];
47 player_anim_t player_anims
[7];
48 object_t objects
[NUM_OBJECTS
];
52 char datfile_name
[2048];
58 int ai
[JNB_MAX_PLAYERS
];
60 unsigned int ban_map
[17][22] = {
61 {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
62 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0},
63 {1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
64 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1},
65 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
66 {1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
67 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1},
68 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
69 {1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
70 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1},
71 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1},
72 {1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1},
73 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
74 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
75 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 1, 3, 3, 3, 1, 1, 1},
76 {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
77 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
203 int flies_enabled
= 1;
208 int old_draw_x
, old_draw_y
;
220 } pobs
[NUM_LEFTOVERS
];
224 int pogostick
, bunnies_in_space
, jetpack
, lord_of_the_flies
, blood_is_thicker_than_water
;
228 int filelength(int handle
)
232 if (fstat(handle
, &buf
) == -1) {
233 perror("filelength");
242 /* networking shite. */
244 int client_player_num
= -1;
249 TCPsocket sock
= NULL
;
250 SDLNet_SocketSet socketset
= NULL
;
256 SDLNet_SocketSet socketset
;
259 NetInfo net_info
[JNB_MAX_PLAYERS
];
271 #define NETPKTBUFSIZE (4 + 4 + 4 + 4 + 4)
273 #define NETCMD_NACK (0xF00DF00D + 0)
274 #define NETCMD_ACK (0xF00DF00D + 1)
275 #define NETCMD_HELLO (0xF00DF00D + 2)
276 #define NETCMD_GREENLIGHT (0xF00DF00D + 3)
277 #define NETCMD_MOVE (0xF00DF00D + 4)
278 #define NETCMD_BYE (0xF00DF00D + 5)
279 #define NETCMD_POSITION (0xF00DF00D + 6)
280 #define NETCMD_ALIVE (0xF00DF00D + 7)
281 #define NETCMD_KILL (0xF00DF00D + 8)
285 void bufToPacket(const char *buf
, NetPacket
*pkt
)
287 SDLNet_Write32(*((Uint32
*) (buf
+ 0)), &pkt
->cmd
);
288 SDLNet_Write32(*((Uint32
*) (buf
+ 4)), &pkt
->arg
);
289 SDLNet_Write32(*((Uint32
*) (buf
+ 8)), &pkt
->arg2
);
290 SDLNet_Write32(*((Uint32
*) (buf
+ 12)), &pkt
->arg3
);
291 SDLNet_Write32(*((Uint32
*) (buf
+ 16)), &pkt
->arg4
);
293 pkt->cmd = ntohl(*((unsigned long *) (buf + 0)));
294 pkt->arg = (long) ntohl(*((unsigned long *) (buf + 4)));
295 pkt->arg2 = (long) ntohl(*((unsigned long *) (buf + 8)));
296 pkt->arg3 = (long) ntohl(*((unsigned long *) (buf + 12)));
297 pkt->arg4 = (long) ntohl(*((unsigned long *) (buf + 16)));
302 void packetToBuf(const NetPacket
*pkt
, char *buf
)
304 *((Uint32
*) (buf
+ 0)) = SDLNet_Read32(&pkt
->cmd
);
305 *((Uint32
*) (buf
+ 4)) = SDLNet_Read32(&pkt
->arg
);
306 *((Uint32
*) (buf
+ 8)) = SDLNet_Read32(&pkt
->arg2
);
307 *((Uint32
*) (buf
+ 12)) = SDLNet_Read32(&pkt
->arg3
);
308 *((Uint32
*) (buf
+ 16)) = SDLNet_Read32(&pkt
->arg4
);
310 *((unsigned long *) (buf + 0)) = htonl(pkt->cmd);
311 *((unsigned long *) (buf + 4)) = htonl((unsigned long) pkt->arg);
312 *((unsigned long *) (buf + 8)) = htonl((unsigned long) pkt->arg2);
313 *((unsigned long *) (buf + 12)) = htonl((unsigned long) pkt->arg3);
314 *((unsigned long *) (buf + 16)) = htonl((unsigned long) pkt->arg4);
319 void sendPacketToSock(TCPsocket s
, NetPacket
*pkt
)
321 int bytes_left
= NETPKTBUFSIZE
;
323 char buf
[NETPKTBUFSIZE
];
326 packetToBuf(pkt
, buf
);
327 while (bytes_left
> 0) {
328 bw
= SDLNet_TCP_Send(s
, ptr
, bytes_left
);
330 fprintf(stderr
, "SERVER: SDLNet_TCP_Send(): %s\n", SDLNet_GetError());
333 } else if (bw
== 0) {
343 void sendPacket(int playerid
, NetPacket
*pkt
)
345 if ( (playerid
< JNB_MAX_PLAYERS
) && (playerid
>= 0)) {
346 if ((player
[playerid
].enabled
) && (playerid
!= client_player_num
)) {
347 sendPacketToSock(net_info
[playerid
].sock
, pkt
);
353 void sendPacketToAll(NetPacket
*pkt
)
357 for (i
= 0; i
< JNB_MAX_PLAYERS
; i
++) {
362 /** read a packet from the given TCPsocket
363 Returns -1 if some error occured, 0 if there was no data available and 1 if a
364 packet was successfully read.
365 Note: the socket has to be in the supplied socketset.
366 TODO: this function will bomb if a packet arrives in pieces, there is no
367 inherent guarantee that the next call will be made on the same socket. */
368 int grabPacket(TCPsocket s
, SDLNet_SocketSet ss
, NetPacket
*pkt
)
370 static char buf
[NETPKTBUFSIZE
];
371 static int buf_count
= 0;
374 if (SDLNet_CheckSockets(ss
, 0) <= 0)
377 if(!SDLNet_SocketReady(s
))
380 rc
= SDLNet_TCP_Recv(s
, &buf
[buf_count
], NETPKTBUFSIZE
- buf_count
);
382 /* closed connection? */
384 } else if (rc
!= NETPKTBUFSIZE
) {
385 /* we got a partial packet. Store what we got in the static buffer and
386 return so that the next call can read the rest. Hopefully. */
391 bufToPacket(buf
, pkt
);
397 int serverRecvPacket(NetPacket
*pkt
)
404 for (i
= 0; i
< JNB_MAX_PLAYERS
; i
++) {
405 TCPsocket s
= net_info
[i
].sock
;
407 if ((i
== client_player_num
) || (!player
[i
].enabled
))
410 rc
= grabPacket(s
, net_info
[i
].socketset
, pkt
);
414 player
[i
].enabled
= 0;
416 pkt
.cmd
= NETCMD_BYE
;
421 sendPacketToAll(&pkt
);
423 return(i
); /* it's all good. */
427 return(-1); /* no packets available currently. */
431 void wait_for_greenlight(void)
436 printf("CLIENT: Waiting for greenlight...\n");
440 while ((rc
= grabPacket(sock
, socketset
, &pkt
)) == 0) {
441 SDL_Delay(100); /* nap and then try again. */
445 printf("CLIENT: Lost connection.\n");
446 SDLNet_TCP_Close(sock
);
449 } while (pkt
.cmd
!= NETCMD_GREENLIGHT
);
451 printf("CLIENT: Got greenlight.\n");
453 for (i
= 0; i
< JNB_MAX_PLAYERS
; i
++) {
454 if (pkt
.arg
& (1 << i
)) {
455 printf("CLIENT: There is a player #%d.\n", i
);
456 player
[i
].enabled
= 1;
462 static int buggered_off
= 0;
465 void tellServerGoodbye(void)
471 pkt
.cmd
= NETCMD_BYE
;
472 pkt
.arg
= client_player_num
;
476 sendPacketToSock(sock
, &pkt
);
482 void processMovePacket(NetPacket
*pkt
)
484 int playerid
= pkt
->arg
;
485 int movetype
= ((pkt
->arg2
>> 16) & 0xFF);
486 int newval
= ((pkt
->arg2
>> 0) & 0xFF);
488 if (movetype
== MOVEMENT_LEFT
) {
489 player
[playerid
].action_left
= newval
;
490 } else if (movetype
== MOVEMENT_RIGHT
) {
491 player
[playerid
].action_right
= newval
;
492 } else if (movetype
== MOVEMENT_UP
) {
493 player
[playerid
].action_up
= newval
;
495 printf("bogus MOVE packet!\n");
498 player
[playerid
].x
= pkt
->arg3
;
499 player
[playerid
].y
= pkt
->arg4
;
503 void tellServerPlayerMoved(int playerid
, int movement_type
, int newval
)
507 pkt
.cmd
= NETCMD_MOVE
;
509 pkt
.arg2
= ( ((movement_type
& 0xFF) << 16) | ((newval
& 0xFF) << 0) );
510 pkt
.arg3
= player
[playerid
].x
;
511 pkt
.arg4
= player
[playerid
].y
;
514 processMovePacket(&pkt
);
517 sendPacketToAll(&pkt
);
519 sendPacketToSock(sock
, &pkt
);
526 void tellServerNewPosition(void)
529 pkt
.cmd
= NETCMD_POSITION
;
530 pkt
.arg
= client_player_num
;
531 pkt
.arg2
= player
[client_player_num
].x
;
532 pkt
.arg3
= player
[client_player_num
].y
;
535 sendPacketToAll(&pkt
);
537 sendPacketToSock(sock
, &pkt
);
543 void processKillPacket(NetPacket
*pkt
)
552 player
[c1
].y_add
= -player
[c1
].y_add
;
553 if (player
[c1
].y_add
> -262144L)
554 player
[c1
].y_add
= -262144L;
555 player
[c1
].jump_abort
= 1;
556 player
[c2
].dead_flag
= 1;
557 if (player
[c2
].anim
!= 6) {
559 player
[c2
].frame
= 0;
560 player
[c2
].frame_tick
= 0;
561 player
[c2
].image
= player_anims
[player
[c2
].anim
].frame
[player
[c2
].frame
].image
+ player
[c2
].direction
* 9;
562 if (main_info
.no_gore
== 0) {
563 for (c4
= 0; c4
< 6; c4
++)
564 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);
565 for (c4
= 0; c4
< 6; c4
++)
566 add_object(OBJ_FLESH
, (x
>> 16) + 6 + rnd(5), (y
>> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 76);
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, 77);
569 for (c4
= 0; c4
< 8; 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, 78);
571 for (c4
= 0; c4
< 10; 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, 79);
574 dj_play_sfx(SFX_DEATH
, (unsigned short)(SFX_DEATH_FREQ
+ rnd(2000) - 1000), 64, 0, 0, -1);
576 player
[c1
].bumped
[c2
]++;
577 s1
= player
[c1
].bumps
% 100;
578 add_leftovers(0, 360, 34 + c1
* 64, s1
/ 10, &number_gobs
);
579 add_leftovers(1, 360, 34 + c1
* 64, s1
/ 10, &number_gobs
);
580 add_leftovers(0, 376, 34 + c1
* 64, s1
- (s1
/ 10) * 10, &number_gobs
);
581 add_leftovers(1, 376, 34 + c1
* 64, s1
- (s1
/ 10) * 10, &number_gobs
);
587 void processPositionPacket(NetPacket
*pkt
)
589 int playerid
= pkt
->arg
;
591 player
[playerid
].x
= pkt
->arg2
;
592 player
[playerid
].y
= pkt
->arg3
;
596 void processAlivePacket(NetPacket
*pkt
)
598 int playerid
= pkt
->arg
;
600 player
[playerid
].dead_flag
= 0;
601 player
[playerid
].x
= pkt
->arg2
;
602 player
[playerid
].y
= pkt
->arg3
;
606 void serverTellEveryoneGoodbye(void)
612 for (i
= 0; i
< JNB_MAX_PLAYERS
; i
++) {
613 if (player
[i
].enabled
) {
616 pkt
.cmd
= NETCMD_BYE
;
621 sendPacketToAll(&pkt
);
628 int server_said_bye
= 0;
631 int update_players_from_server(void)
638 while ((rc
= grabPacket(sock
, socketset
, &pkt
)) != 0) {
640 printf("CLIENT: Lost connection.\n");
641 pkt
.cmd
= NETCMD_BYE
;
642 pkt
.arg
= client_player_num
;
645 if (pkt
.cmd
== NETCMD_BYE
) {
646 if (pkt
.arg
== client_player_num
) {
647 SDLNet_FreeSocketSet(socketset
);
648 SDLNet_TCP_Close(sock
);
653 player
[pkt
.arg
].enabled
= 0;
655 } else if (pkt
.cmd
== NETCMD_MOVE
) {
656 processMovePacket(&pkt
);
657 } else if (pkt
.cmd
== NETCMD_ALIVE
) {
658 processAlivePacket(&pkt
);
659 } else if (pkt
.cmd
== NETCMD_POSITION
) {
660 processPositionPacket(&pkt
);
661 } else if (pkt
.cmd
== NETCMD_KILL
) {
662 processKillPacket(&pkt
);
664 printf("CLIENT: Got an unknown packet: 0x%lX.\n", pkt
.cmd
);
672 void serverSendAlive(int playerid
)
677 pkt
.cmd
= NETCMD_ALIVE
;
679 pkt
.arg2
= player
[playerid
].x
;
680 pkt
.arg3
= player
[playerid
].y
;
681 sendPacketToAll(&pkt
);
686 void serverSendKillPacket(int killer
, int victim
)
691 pkt
.cmd
= NETCMD_KILL
;
694 pkt
.arg3
= player
[victim
].x
;
695 pkt
.arg4
= player
[victim
].y
;
696 processKillPacket(&pkt
);
699 sendPacketToAll(&pkt
);
705 void update_players_from_clients(void)
713 while ((playerid
= serverRecvPacket(&pkt
)) >= 0) {
714 if (pkt
.cmd
== NETCMD_BYE
) {
715 pkt
.arg
= playerid
; /* just in case. */
716 sendPacketToAll(&pkt
);
717 player
[playerid
].enabled
= 0;
718 SDLNet_FreeSocketSet(net_info
[playerid
].socketset
);
719 SDLNet_TCP_Close(net_info
[playerid
].sock
);
720 } else if (pkt
.cmd
== NETCMD_POSITION
) {
721 pkt
.arg
= playerid
; /* just in case. */
722 processPositionPacket(&pkt
);
723 for (i
= 0; i
< JNB_MAX_PLAYERS
; i
++) {
728 } else if (pkt
.cmd
== NETCMD_MOVE
) {
729 pkt
.arg
= playerid
; /* just in case. */
731 pkt.arg3 = player[playerid].x;
732 pkt.arg4 = player[playerid].y;
734 processMovePacket(&pkt
);
735 sendPacketToAll(&pkt
);
737 printf("SERVER: Got unknown packet (0x%lX).\n", pkt
.cmd
);
743 void init_server(const char *netarg
)
748 int wait_for_clients
= ((netarg
== NULL
) ? 0 : atoi(netarg
));
751 /** assign player number zero as default for the server */
752 if(-1 == client_player_num
)
753 client_player_num
= 0;
755 if ((wait_for_clients
>= JNB_MAX_PLAYERS
) || (wait_for_clients
< 0)) {
756 printf("SERVER: Waiting for bogus client count (%d).\n", wait_for_clients
);
760 if (SDLNet_Init() < 0) {
765 SDLNet_ResolveHost(&addr
, NULL
, JNB_INETPORT
);
766 ipstr
= SDLNet_ResolveIP(&addr
);
767 SDLNet_ResolveHost(&addr
, ipstr
, JNB_INETPORT
);
768 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
);
769 net_info
[client_player_num
].addr
= addr
;
771 addr
.host
= INADDR_ANY
;
772 sock
= SDLNet_TCP_Open(&addr
);
774 fprintf(stderr
, "SERVER: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
778 player
[client_player_num
].enabled
= 1;
780 printf("SERVER: waiting for (%d) clients...\n", wait_for_clients
);
782 socketset
= SDLNet_AllocSocketSet(JNB_MAX_PLAYERS
+ 1);
783 SDLNet_TCP_AddSocket(socketset
, sock
);
785 while (wait_for_clients
> 0)
787 char buf
[NETPKTBUFSIZE
];
793 /* Wait for events */
794 SDLNet_CheckSockets(socketset
, ~0);
795 if ( SDLNet_SocketReady(sock
) ) {
796 s
= SDLNet_TCP_Accept(sock
);
800 fprintf(stderr
, "SERVER: SDLNet_TCP_Accept(): %s", SDLNet_GetError());
801 SDLNet_TCP_Close(sock
);
807 br
= SDLNet_TCP_Recv(s
, buf
, NETPKTBUFSIZE
);
809 fprintf(stderr
, "SERVER: SDLNet_TCP_Recv(): %s\n", SDLNet_GetError());
811 SDLNet_TCP_Close(sock
);
815 from
= SDLNet_TCP_GetPeerAddress(s
);
816 ipstr
= SDLNet_ResolveIP(from
);
817 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
);
819 if (br
!= NETPKTBUFSIZE
) {
820 printf("SERVER: Bogus packet.\n");
824 bufToPacket(buf
, &pkt
);
825 if (pkt
.cmd
!= NETCMD_HELLO
) {
826 printf("SERVER: Bogus packet.\n");
830 printf("SERVER: Client claims to be player #%ld.\n", pkt
.arg
);
834 for(i
=0; i
!=JNB_MAX_PLAYERS
; ++i
) {
835 if(!player
[i
].enabled
) {
836 printf("SERVER: assigning %d as player number\n", i
);
843 if ((pkt
.arg
>=JNB_MAX_PLAYERS
)||(pkt
.arg
<0)) {
844 printf("SERVER: (that's an invalid player number.)\n");
845 } else if (player
[pkt
.arg
].enabled
) {
846 printf("SERVER: (that player number is already taken.)\n");
852 printf("SERVER: Forbidding connection.\n");
853 pkt
.cmd
= NETCMD_NACK
;
854 sendPacketToSock(s
, &pkt
);
857 player
[pkt
.arg
].enabled
= 1;
858 net_info
[pkt
.arg
].sock
= s
;
859 net_info
[pkt
.arg
].addr
= *from
;
860 net_info
[pkt
.arg
].socketset
= SDLNet_AllocSocketSet(1);
861 SDLNet_TCP_AddSocket(net_info
[pkt
.arg
].socketset
, net_info
[pkt
.arg
].sock
);
863 printf("SERVER: Granting connection. (%d) to go.\n", wait_for_clients
);
864 pkt
.cmd
= NETCMD_ACK
;
865 sendPacket(pkt
.arg
, &pkt
);
869 SDLNet_TCP_Close(sock
); /* done with the listen socket. */
870 SDLNet_FreeSocketSet(socketset
);
874 printf("SERVER: Got all our connections. Greenlighting clients...\n");
876 pkt
.cmd
= NETCMD_GREENLIGHT
;
878 for (i
= 0; i
< JNB_MAX_PLAYERS
; i
++) {
879 if (player
[i
].enabled
) {
883 sendPacketToAll(&pkt
);
887 void connect_to_server(char *netarg
)
890 char buf
[NETPKTBUFSIZE
];
896 if (netarg
== NULL
) {
897 printf("CLIENT: Need to specify host to connect to.\n");
901 if (SDLNet_Init() < 0) {
906 SDLNet_ResolveHost(&addr
, NULL
, JNB_INETPORT
);
907 ipstr
= SDLNet_ResolveIP(&addr
);
908 SDLNet_ResolveHost(&addr
, ipstr
, JNB_INETPORT
);
909 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
);
911 if (SDLNet_ResolveHost(&hent
, netarg
, JNB_INETPORT
) < 0) {
912 fprintf(stderr
, "CLIENT: couldn't find host: %s\n", SDLNet_GetError());
916 sock
= SDLNet_TCP_Open(&hent
);
918 fprintf(stderr
, "CLIENT: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
922 socketset
= SDLNet_AllocSocketSet(1);
923 SDLNet_TCP_AddSocket(socketset
, sock
);
925 printf("CLIENT: connected to %s...\n", SDLNet_ResolveIP(&hent
));
927 printf("CLIENT: Sending HELLO packet...\n");
928 pkt
.cmd
= NETCMD_HELLO
;
929 pkt
.arg
= client_player_num
;
930 sendPacketToSock(sock
, &pkt
);
932 printf("CLIENT: Waiting for ACK from server...\n");
934 br
= SDLNet_TCP_Recv(sock
, buf
, NETPKTBUFSIZE
);
936 fprintf(stderr
, "CLIENT: recv(): %s\n", SDLNet_GetError());
937 SDLNet_FreeSocketSet(socketset
);
938 SDLNet_TCP_Close(sock
);
942 if (br
!= NETPKTBUFSIZE
) {
943 printf("CLIENT: Bogus packet size (%d of %d). FIXME.\n", br
, NETPKTBUFSIZE
);
944 SDLNet_FreeSocketSet(socketset
);
945 SDLNet_TCP_Close(sock
);
949 bufToPacket(buf
, &pkt
);
951 if (pkt
.cmd
== NETCMD_NACK
) {
952 printf("CLIENT: Server forbid us from playing.\n");
953 SDLNet_FreeSocketSet(socketset
);
954 SDLNet_TCP_Close(sock
);
958 if (pkt
.cmd
!= NETCMD_ACK
) {
959 printf("CLIENT: Unexpected packet (cmd=0x%lX).\n", pkt
.cmd
);
960 SDLNet_FreeSocketSet(socketset
);
961 SDLNet_TCP_Close(sock
);
965 client_player_num
= pkt
.arg
;
966 player
[client_player_num
].enabled
= 1;
967 net_info
[client_player_num
].addr
= addr
;
968 printf("CLIENT: Server accepted our connection.\n");
970 wait_for_greenlight();
975 static void flip_pixels(unsigned char *pixels
)
981 for (y
= 0; y
< JNB_HEIGHT
; y
++) {
982 for (x
= 0; x
< (352/2); x
++) {
983 temp
= pixels
[y
*JNB_WIDTH
+x
];
984 pixels
[y
*JNB_WIDTH
+x
] = pixels
[y
*JNB_WIDTH
+(352-x
)-1];
985 pixels
[y
*JNB_WIDTH
+(352-x
)-1] = temp
;
991 int main(int argc
, char *argv
[])
993 unsigned char *handle
;
994 int c1
= 0, c2
= 0, c3
= 0, c4
= 0;
997 int closest_player
= 0, dist
, cur_dist
= 0;
998 int end_loop_flag
= 0, fade_flag
= 0;
999 int mod_vol
, sfx_vol
, mod_fade_direction
;
1006 if (init_program(argc
, argv
, pal
) != 0)
1009 if (main_info
.fireworks
== 1) {
1014 for(i
= 0; i
< JNB_MAX_PLAYERS
; i
++) // reset player values
1025 if (key_pressed(1) == 1) {
1028 if (init_level(0, pal
) != 0) {
1033 memset(cur_pal
, 0, 768);
1034 setpalette(0, 256, cur_pal
);
1036 recalculate_gob(&rabbit_gobs
, pal
);
1037 recalculate_gob(&object_gobs
, pal
);
1038 recalculate_gob(&number_gobs
, pal
);
1041 register_background(background_pic
, pal
);
1044 if (flies_enabled
) {
1048 for (c1
= 0; c1
< NUM_FLIES
; c1
++) {
1050 flies
[c1
].x
= s1
+ rnd(101) - 50;
1051 flies
[c1
].y
= s2
+ rnd(101) - 50;
1052 if (ban_map
[flies
[c1
].y
>> 4][flies
[c1
].x
>> 4] == BAN_VOID
)
1055 flies
[c1
].back_defined
[0] = 0;
1056 flies
[c1
].back_defined
[1] = 0;
1060 mod_vol
= sfx_vol
= 10;
1061 mod_fade_direction
= 1;
1062 dj_ready_mod(MOD_GAME
);
1063 dj_set_mod_volume((char)mod_vol
);
1064 dj_set_sfx_volume((char)mod_vol
);
1068 dj_play_sfx(SFX_FLY
, SFX_FLY_FREQ
, 0, 0, 0, 4);
1072 lord_of_the_flies
= bunnies_in_space
= jetpack
= pogostick
= blood_is_thicker_than_water
= 0;
1074 main_info
.page_info
[0].num_pobs
= 0;
1075 main_info
.page_info
[1].num_pobs
= 0;
1076 main_info
.view_page
= 0;
1077 main_info
.draw_page
= 1;
1081 while (update_count
) {
1083 if (key_pressed(1) == 1) {
1087 serverTellEveryoneGoodbye();
1089 tellServerGoodbye();
1094 memset(pal
, 0, 768);
1095 mod_fade_direction
= 0;
1098 if (strncmp(last_keys
, "kcitsogop", strlen("kcitsogop")) == 0) {
1102 if (strncmp(last_keys
, "ecapsniseinnub", strlen("ecapsniseinnub")) == 0) {
1103 bunnies_in_space
^= 1;
1106 if (strncmp(last_keys
, "kcaptej", strlen("kcaptej")) == 0) {
1110 if (strncmp(last_keys
, "seilfehtfodrol", strlen("seilfehtfodrol")) == 0) {
1111 lord_of_the_flies
^= 1;
1114 if (strncmp(last_keys
, "retawnahtrekcihtsidoolb", strlen("retawnahtrekcihtsidoolb")) == 0) {
1115 blood_is_thicker_than_water
^= 1;
1116 if (blood_is_thicker_than_water
== 1) {
1167 register_background(background_pic
, pal
);
1168 recalculate_gob(&object_gobs
, pal
);
1175 update_players_from_clients();
1177 if (!update_players_from_server()) {
1178 break; /* got a BYE packet */
1188 for (c3
= 0; c3
< 6; c3
++) {
1192 } else if (c3
== 1) {
1195 } else if (c3
== 2) {
1198 } else if (c3
== 3) {
1201 } else if (c3
== 4) {
1204 } else if (c3
== 5) {
1208 if (player
[c1
].enabled
== 1 && player
[c2
].enabled
== 1) {
1209 if (labs(player
[c1
].x
- player
[c2
].x
) < (12L << 16) && labs(player
[c1
].y
- player
[c2
].y
) < (12L << 16)) {
1210 if ((labs(player
[c1
].y
- player
[c2
].y
) >> 16) > 5) {
1211 if (player
[c1
].y
< player
[c2
].y
) {
1212 if (player
[c1
].y_add
>= 0) {
1214 serverSendKillPacket(c1
, c2
);
1216 if (player
[c2
].y_add
< 0)
1217 player
[c2
].y_add
= 0;
1220 if (player
[c2
].y_add
>= 0) {
1222 serverSendKillPacket(c2
, c1
);
1224 if (player
[c1
].y_add
< 0)
1225 player
[c1
].y_add
= 0;
1229 if (player
[c1
].x
< player
[c2
].x
) {
1230 if (player
[c1
].x_add
> 0)
1231 player
[c1
].x
= player
[c2
].x
- (12L << 16);
1232 else if (player
[c2
].x_add
< 0)
1233 player
[c2
].x
= player
[c1
].x
+ (12L << 16);
1235 player
[c1
].x
-= player
[c1
].x_add
;
1236 player
[c2
].x
-= player
[c2
].x_add
;
1238 l1
= player
[c2
].x_add
;
1239 player
[c2
].x_add
= player
[c1
].x_add
;
1240 player
[c1
].x_add
= l1
;
1241 if (player
[c1
].x_add
> 0)
1242 player
[c1
].x_add
= -player
[c1
].x_add
;
1243 if (player
[c2
].x_add
< 0)
1244 player
[c2
].x_add
= -player
[c2
].x_add
;
1246 if (player
[c1
].x_add
> 0)
1247 player
[c2
].x
= player
[c1
].x
- (12L << 16);
1248 else if (player
[c2
].x_add
< 0)
1249 player
[c1
].x
= player
[c2
].x
+ (12L << 16);
1251 player
[c1
].x
-= player
[c1
].x_add
;
1252 player
[c2
].x
-= player
[c2
].x_add
;
1254 l1
= player
[c2
].x_add
;
1255 player
[c2
].x_add
= player
[c1
].x_add
;
1256 player
[c1
].x_add
= l1
;
1257 if (player
[c1
].x_add
< 0)
1258 player
[c1
].x_add
= -player
[c1
].x_add
;
1259 if (player
[c2
].x_add
> 0)
1260 player
[c2
].x_add
= -player
[c2
].x_add
;
1269 main_info
.page_info
[main_info
.draw_page
].num_pobs
= 0;
1270 for (c1
= 0; c1
< JNB_MAX_PLAYERS
; c1
++) {
1271 if (player
[c1
].enabled
== 1)
1272 main_info
.page_info
[main_info
.draw_page
].num_pobs
++;
1279 if (flies_enabled
) {
1280 /* get center of fly swarm */
1282 for (c1
= 0; c1
< NUM_FLIES
; c1
++) {
1289 if (update_count
== 1) {
1290 /* get closest player to fly swarm */
1292 for (c1
= 0; c1
< JNB_MAX_PLAYERS
; c1
++) {
1293 if (player
[c1
].enabled
== 1) {
1294 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)));
1295 if (cur_dist
< dist
) {
1296 closest_player
= c1
;
1301 /* update fly swarm sound */
1305 dj_set_sfx_channel_volume(4, (char)(s3
));
1308 for (c1
= 0; c1
< NUM_FLIES
; c1
++) {
1309 /* get closest player to fly */
1311 for (c2
= 0; c2
< JNB_MAX_PLAYERS
; c2
++) {
1312 if (player
[c2
].enabled
== 1) {
1313 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)));
1314 if (cur_dist
< dist
) {
1315 closest_player
= c2
;
1320 flies
[c1
].old_x
= flies
[c1
].x
;
1321 flies
[c1
].old_y
= flies
[c1
].y
;
1323 if ((s1
- flies
[c1
].x
) > 30)
1325 else if ((s1
- flies
[c1
].x
) < -30)
1328 if (((player
[closest_player
].x
>> 16) + 8) > flies
[c1
].x
) {
1329 if (lord_of_the_flies
== 0)
1334 if (lord_of_the_flies
== 0)
1340 s4
= rnd(3) - 1 + s3
;
1341 if ((flies
[c1
].x
+ s4
) < 16)
1343 if ((flies
[c1
].x
+ s4
) > 351)
1345 if (ban_map
[flies
[c1
].y
>> 4][(flies
[c1
].x
+ s4
) >> 4] != BAN_VOID
)
1349 if ((s2
- flies
[c1
].y
) > 30)
1351 else if ((s2
- flies
[c1
].y
) < -30)
1354 if (((player
[closest_player
].y
>> 16) + 8) > flies
[c1
].y
) {
1355 if (lord_of_the_flies
== 0)
1360 if (lord_of_the_flies
== 0)
1366 s4
= rnd(3) - 1 + s3
;
1367 if ((flies
[c1
].y
+ s4
) < 0)
1369 if ((flies
[c1
].y
+ s4
) > 239)
1371 if (ban_map
[(flies
[c1
].y
+ s4
) >> 4][flies
[c1
].x
>> 4] != BAN_VOID
)
1380 for (c1
= 0; c1
< JNB_MAX_PLAYERS
; c1
++) {
1381 if (player
[c1
].enabled
== 1) {
1382 main_info
.page_info
[main_info
.draw_page
].pobs
[s1
].x
= player
[c1
].x
>> 16;
1383 main_info
.page_info
[main_info
.draw_page
].pobs
[s1
].y
= player
[c1
].y
>> 16;
1384 main_info
.page_info
[main_info
.draw_page
].pobs
[s1
].image
= player
[c1
].image
+ c1
* 18;
1385 main_info
.page_info
[main_info
.draw_page
].pobs
[s1
].pob_data
= &rabbit_gobs
;
1390 if (update_count
== 1) {
1393 draw_pobs(main_info
.draw_page
);
1398 draw_flies(main_info
.draw_page
);
1403 if (mod_fade_direction
== 1) {
1406 dj_set_mod_volume((char)mod_vol
);
1411 dj_set_mod_volume((char)mod_vol
);
1415 if (mod_fade_direction
== 1) {
1418 dj_set_sfx_volume((char)sfx_vol
);
1423 dj_set_sfx_volume((char)sfx_vol
);
1428 for (c1
= 0; c1
< 768; c1
++) {
1429 if (cur_pal
[c1
] < pal
[c1
]) {
1432 } else if (cur_pal
[c1
] > pal
[c1
]) {
1437 if (fade_flag
== 0 && end_loop_flag
== 1)
1440 if (update_count
== 1) {
1441 main_info
.draw_page
^= 1;
1442 main_info
.view_page
^= 1;
1444 flippage(main_info
.view_page
);
1450 setpalette(0, 256, cur_pal
);
1452 if (update_count
== 1) {
1456 redraw_flies_background(main_info
.draw_page
);
1458 redraw_pob_backgrounds(main_info
.draw_page
);
1460 draw_leftovers(main_info
.draw_page
);
1470 if ( (player
[client_player_num
].dead_flag
== 0) &&
1472 (player
[client_player_num
].action_left
) ||
1473 (player
[client_player_num
].action_right
) ||
1474 (player
[client_player_num
].action_up
) ||
1475 (player
[client_player_num
].jump_ready
== 0)
1478 tellServerNewPosition();
1483 update_count
= intr_sysupdate();
1487 if ((server_said_bye
) || ((fade_flag
== 0) && (end_loop_flag
== 1)))
1491 if ((fade_flag
== 0) && (end_loop_flag
== 1))
1498 serverTellEveryoneGoodbye();
1499 SDLNet_TCP_Close(sock
);
1502 if (!server_said_bye
) {
1503 tellServerGoodbye();
1506 SDLNet_TCP_Close(sock
);
1512 main_info
.view_page
= 0;
1513 main_info
.draw_page
= 1;
1515 dj_stop_sfx_channel(4);
1519 memset(mask_pic
, 0, JNB_WIDTH
*JNB_HEIGHT
);
1520 register_mask(mask_pic
);
1522 register_background(NULL
, NULL
);
1526 put_text(main_info
.view_page
, 100, 50, "DOTT", 2);
1527 put_text(main_info
.view_page
, 160, 50, "JIFFY", 2);
1528 put_text(main_info
.view_page
, 220, 50, "FIZZ", 2);
1529 put_text(main_info
.view_page
, 280, 50, "MIJJI", 2);
1530 put_text(main_info
.view_page
, 40, 80, "DOTT", 2);
1531 put_text(main_info
.view_page
, 40, 110, "JIFFY", 2);
1532 put_text(main_info
.view_page
, 40, 140, "FIZZ", 2);
1533 put_text(main_info
.view_page
, 40, 170, "MIJJI", 2);
1535 for (c1
= 0; c1
< JNB_MAX_PLAYERS
; c1
++) {
1536 for (c2
= 0; c2
< JNB_MAX_PLAYERS
; c2
++) {
1538 sprintf(str1
, "%d", player
[c1
].bumped
[c2
]);
1539 put_text(main_info
.view_page
, 100 + c2
* 60, 80 + c1
* 30, str1
, 2);
1541 put_text(main_info
.view_page
, 100 + c2
* 60, 80 + c1
* 30, "-", 2);
1543 sprintf(str1
, "%d", player
[c1
].bumps
);
1544 put_text(main_info
.view_page
, 350, 80 + c1
* 30, str1
, 2);
1547 put_text(main_info
.view_page
, 200, 230, "Press ESC to continue", 2);
1551 flippage(main_info
.view_page
);
1553 if ((handle
= dat_open("menu.pcx")) == 0) {
1554 strcpy(main_info
.error_str
, "Error loading 'menu.pcx', aborting...\n");
1557 if (read_pcx(handle
, background_pic
, JNB_WIDTH
*JNB_HEIGHT
, pal
) != 0) {
1558 strcpy(main_info
.error_str
, "Error loading 'menu.pcx', aborting...\n");
1563 for (c1
= 0; c1
< 16; c1
++) {
1564 pal
[(240 + c1
) * 3 + 0] = c1
<< 2;
1565 pal
[(240 + c1
) * 3 + 1] = c1
<< 2;
1566 pal
[(240 + c1
) * 3 + 2] = c1
<< 2;
1569 memset(cur_pal
, 0, 768);
1571 setpalette(0, 256, cur_pal
);
1574 dj_ready_mod(MOD_SCORES
);
1575 dj_set_mod_volume((char)mod_vol
);
1579 while (key_pressed(1) == 0) {
1582 dj_set_mod_volume((char)mod_vol
);
1583 for (c1
= 0; c1
< 768; c1
++) {
1584 if (cur_pal
[c1
] < pal
[c1
])
1590 setpalette(0, 256, cur_pal
);
1591 flippage(main_info
.view_page
);
1593 while (key_pressed(1) == 1) {
1598 memset(pal
, 0, 768);
1600 while (mod_vol
> 0) {
1602 dj_set_mod_volume((char)mod_vol
);
1603 for (c1
= 0; c1
< 768; c1
++) {
1604 if (cur_pal
[c1
] > pal
[c1
])
1609 setpalette(0, 256, cur_pal
);
1610 flippage(main_info
.view_page
);
1613 fillpalette(0, 0, 0);
1619 break; /* don't go back to menu if in net game. */
1627 int map_tile(int pos_x
, int pos_y
)
1634 if(pos_x
< 0 || pos_x
>= 17 || pos_y
< 0 || pos_y
>= 22)
1637 tile
= ban_map
[pos_y
][pos_x
];
1645 int cur_posx
, cur_posy
, tar_posx
, tar_posy
;
1646 int players_distance
;
1647 player_t
* target
= NULL
;
1648 int nearest_distance
= -1;
1650 for (i
= 0; i
< JNB_MAX_PLAYERS
; i
++)
1652 nearest_distance
= -1;
1653 if(ai
[i
] && player
[i
].enabled
) // this player is a computer
1654 { // get nearest target
1655 for (j
= 0; j
< JNB_MAX_PLAYERS
; j
++)
1659 if(i
== j
|| !player
[j
].enabled
)
1662 deltax
= player
[j
].x
- player
[i
].x
;
1663 deltay
= player
[j
].y
- player
[i
].y
;
1664 players_distance
= deltax
*deltax
+ deltay
*deltay
;
1666 if (players_distance
< nearest_distance
|| nearest_distance
== -1)
1668 target
= &player
[j
];
1669 nearest_distance
= players_distance
;
1676 cur_posx
= player
[i
].x
>> 16;
1677 cur_posy
= player
[i
].y
>> 16;
1678 tar_posx
= target
->x
>> 16;
1679 tar_posy
= target
->y
>> 16;
1681 /** nearest player found, get him */
1682 /* here goes the artificial intelligence code */
1684 /* X-axis movement */
1685 if(tar_posx
> cur_posx
) // if true target is on the right side
1690 else // target on the left side
1696 if(cur_posy
- tar_posy
< 32 && cur_posy
- tar_posy
> 0 &&
1697 tar_posx
- cur_posx
< 32+8 && tar_posx
- cur_posx
> -32)
1702 else if(tar_posx
- cur_posx
< 4+8 && tar_posx
- cur_posx
> -4)
1703 { // makes the bunnies less "nervous"
1708 /* Y-axis movement */
1709 if(map_tile(cur_posx
, cur_posy
+16) != BAN_VOID
&&
1710 ((i
== 0 && key_pressed(KEY_PL1_JUMP
)) ||
1711 (i
== 1 && key_pressed(KEY_PL2_JUMP
)) ||
1712 (i
== 2 && key_pressed(KEY_PL3_JUMP
)) ||
1713 (i
== 3 && key_pressed(KEY_PL4_JUMP
))))
1714 jm
=0; // if we are on ground and jump key is being pressed,
1715 //first we have to release it or else we won't be able to jump more than once
1717 else if(map_tile(cur_posx
, cur_posy
-8) != BAN_VOID
&&
1718 map_tile(cur_posx
, cur_posy
-8) != BAN_WATER
)
1719 jm
=0; // don't jump if there is something over it
1721 else if(map_tile(cur_posx
-(lm
*8)+(rm
*16), cur_posy
) != BAN_VOID
&&
1722 map_tile(cur_posx
-(lm
*8)+(rm
*16), cur_posy
) != BAN_WATER
&&
1723 cur_posx
> 16 && cur_posx
< 352-16-8) // obstacle, jump
1724 jm
=1; // if there is something on the way, jump over it
1726 else if(((i
== 0 && key_pressed(KEY_PL1_JUMP
)) ||
1727 (i
== 1 && key_pressed(KEY_PL2_JUMP
)) ||
1728 (i
== 2 && key_pressed(KEY_PL3_JUMP
)) ||
1729 (i
== 3 && key_pressed(KEY_PL4_JUMP
))) &&
1730 (map_tile(cur_posx
-(lm
*8)+(rm
*16), cur_posy
+8) != BAN_VOID
&&
1731 map_tile(cur_posx
-(lm
*8)+(rm
*16), cur_posy
+8) != BAN_WATER
))
1732 jm
=1; // this makes it possible to jump over 2 tiles
1734 else if(cur_posy
- tar_posy
< 32 && cur_posy
- tar_posy
> 0 &&
1735 tar_posx
- cur_posx
< 32+8 && tar_posx
- cur_posx
> -32) // don't jump - running away
1738 else if(tar_posy
<= cur_posy
) // target on the upper side
1740 else // target below
1743 /** Artificial intelligence done, now apply movements */
1772 addkey(key
| 0x8000);
1779 key
= KEY_PL1_RIGHT
;
1781 key
= KEY_PL2_RIGHT
;
1783 key
= KEY_PL3_RIGHT
;
1785 key
= KEY_PL4_RIGHT
;
1794 key
= KEY_PL1_RIGHT
;
1796 key
= KEY_PL2_RIGHT
;
1798 key
= KEY_PL3_RIGHT
;
1800 key
= KEY_PL4_RIGHT
;
1803 addkey(key
| 0x8000);
1834 addkey(key
| 0x8000);
1841 void steer_players(void)
1847 update_player_actions();
1849 for (c1
= 0; c1
< JNB_MAX_PLAYERS
; c1
++) {
1851 if (player
[c1
].enabled
== 1) {
1853 if (player
[c1
].dead_flag
== 0) {
1855 if (player
[c1
].action_left
&& player
[c1
].action_right
) {
1856 if (player
[c1
].direction
== 0) {
1857 if (player
[c1
].action_right
) {
1858 s1
= (player
[c1
].x
>> 16);
1859 s2
= (player
[c1
].y
>> 16);
1860 if (ban_map
[(s2
+ 16) >> 4][(s1
+ 8) >> 4] == BAN_ICE
) {
1861 if (player
[c1
].x_add
< 0)
1862 player
[c1
].x_add
+= 1024;
1864 player
[c1
].x_add
+= 768;
1865 } 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
)) {
1866 if (player
[c1
].x_add
> 0)
1867 player
[c1
].x_add
+= 1024;
1869 player
[c1
].x_add
+= 768;
1871 if (player
[c1
].x_add
< 0) {
1872 player
[c1
].x_add
+= 16384;
1873 if (player
[c1
].x_add
< 98304L && player
[c1
].in_water
== 0 && ban_map
[(s2
+ 16) >> 4][(s1
+ 8) >> 4] == BAN_SOLID
)
1874 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);
1876 player
[c1
].x_add
+= 12288;
1878 if (player
[c1
].x_add
> 98304L)
1879 player
[c1
].x_add
= 98304L;
1880 player
[c1
].direction
= 0;
1881 if (player
[c1
].anim
== 0) {
1882 player
[c1
].anim
= 1;
1883 player
[c1
].frame
= 0;
1884 player
[c1
].frame_tick
= 0;
1885 player
[c1
].image
= player_anims
[player
[c1
].anim
].frame
[player
[c1
].frame
].image
+ player
[c1
].direction
* 9;
1889 if (player
[c1
].action_left
) {
1890 s1
= (player
[c1
].x
>> 16);
1891 s2
= (player
[c1
].y
>> 16);
1892 if (ban_map
[(s2
+ 16) >> 4][(s1
+ 8) >> 4] == BAN_ICE
) {
1893 if (player
[c1
].x_add
> 0)
1894 player
[c1
].x_add
-= 1024;
1896 player
[c1
].x_add
-= 768;
1897 } 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
)) {
1898 if (player
[c1
].x_add
> 0)
1899 player
[c1
].x_add
-= 1024;
1901 player
[c1
].x_add
-= 768;
1903 if (player
[c1
].x_add
> 0) {
1904 player
[c1
].x_add
-= 16384;
1905 if (player
[c1
].x_add
> -98304L && player
[c1
].in_water
== 0 && ban_map
[(s2
+ 16) >> 4][(s1
+ 8) >> 4] == BAN_SOLID
)
1906 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);
1908 player
[c1
].x_add
-= 12288;
1910 if (player
[c1
].x_add
< -98304L)
1911 player
[c1
].x_add
= -98304L;
1912 player
[c1
].direction
= 1;
1913 if (player
[c1
].anim
== 0) {
1914 player
[c1
].anim
= 1;
1915 player
[c1
].frame
= 0;
1916 player
[c1
].frame_tick
= 0;
1917 player
[c1
].image
= player_anims
[player
[c1
].anim
].frame
[player
[c1
].frame
].image
+ player
[c1
].direction
* 9;
1921 } else if (player
[c1
].action_left
) {
1922 s1
= (player
[c1
].x
>> 16);
1923 s2
= (player
[c1
].y
>> 16);
1924 if (ban_map
[(s2
+ 16) >> 4][(s1
+ 8) >> 4] == BAN_ICE
) {
1925 if (player
[c1
].x_add
> 0)
1926 player
[c1
].x_add
-= 1024;
1928 player
[c1
].x_add
-= 768;
1929 } 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
)) {
1930 if (player
[c1
].x_add
> 0)
1931 player
[c1
].x_add
-= 1024;
1933 player
[c1
].x_add
-= 768;
1935 if (player
[c1
].x_add
> 0) {
1936 player
[c1
].x_add
-= 16384;
1937 if (player
[c1
].x_add
> -98304L && player
[c1
].in_water
== 0 && ban_map
[(s2
+ 16) >> 4][(s1
+ 8) >> 4] == BAN_SOLID
)
1938 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);
1940 player
[c1
].x_add
-= 12288;
1942 if (player
[c1
].x_add
< -98304L)
1943 player
[c1
].x_add
= -98304L;
1944 player
[c1
].direction
= 1;
1945 if (player
[c1
].anim
== 0) {
1946 player
[c1
].anim
= 1;
1947 player
[c1
].frame
= 0;
1948 player
[c1
].frame_tick
= 0;
1949 player
[c1
].image
= player_anims
[player
[c1
].anim
].frame
[player
[c1
].frame
].image
+ player
[c1
].direction
* 9;
1951 } else if (player
[c1
].action_right
) {
1952 s1
= (player
[c1
].x
>> 16);
1953 s2
= (player
[c1
].y
>> 16);
1954 if (ban_map
[(s2
+ 16) >> 4][(s1
+ 8) >> 4] == BAN_ICE
) {
1955 if (player
[c1
].x_add
< 0)
1956 player
[c1
].x_add
+= 1024;
1958 player
[c1
].x_add
+= 768;
1959 } 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
)) {
1960 if (player
[c1
].x_add
> 0)
1961 player
[c1
].x_add
+= 1024;
1963 player
[c1
].x_add
+= 768;
1965 if (player
[c1
].x_add
< 0) {
1966 player
[c1
].x_add
+= 16384;
1967 if (player
[c1
].x_add
< 98304L && player
[c1
].in_water
== 0 && ban_map
[(s2
+ 16) >> 4][(s1
+ 8) >> 4] == BAN_SOLID
)
1968 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);
1970 player
[c1
].x_add
+= 12288;
1972 if (player
[c1
].x_add
> 98304L)
1973 player
[c1
].x_add
= 98304L;
1974 player
[c1
].direction
= 0;
1975 if (player
[c1
].anim
== 0) {
1976 player
[c1
].anim
= 1;
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;
1981 } else if ((!player
[c1
].action_left
) && (!player
[c1
].action_right
)) {
1982 s1
= (player
[c1
].x
>> 16);
1983 s2
= (player
[c1
].y
>> 16);
1984 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
)))) {
1985 if (player
[c1
].x_add
< 0) {
1986 player
[c1
].x_add
+= 16384;
1987 if (player
[c1
].x_add
> 0)
1988 player
[c1
].x_add
= 0;
1990 player
[c1
].x_add
-= 16384;
1991 if (player
[c1
].x_add
< 0)
1992 player
[c1
].x_add
= 0;
1994 if (player
[c1
].x_add
!= 0 && ban_map
[(s2
+ 16) >> 4][(s1
+ 8) >> 4] == BAN_SOLID
)
1995 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);
1997 if (player
[c1
].anim
== 1) {
1998 player
[c1
].anim
= 0;
1999 player
[c1
].frame
= 0;
2000 player
[c1
].frame_tick
= 0;
2001 player
[c1
].image
= player_anims
[player
[c1
].anim
].frame
[player
[c1
].frame
].image
+ player
[c1
].direction
* 9;
2005 if (pogostick
== 1 || (player
[c1
].jump_ready
== 1 && player
[c1
].action_up
)) {
2006 s1
= (player
[c1
].x
>> 16);
2007 s2
= (player
[c1
].y
>> 16);
2010 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
) {
2011 player
[c1
].y_add
= -280000L;
2012 player
[c1
].anim
= 2;
2013 player
[c1
].frame
= 0;
2014 player
[c1
].frame_tick
= 0;
2015 player
[c1
].image
= player_anims
[player
[c1
].anim
].frame
[player
[c1
].frame
].image
+ player
[c1
].direction
* 9;
2016 player
[c1
].jump_ready
= 0;
2017 player
[c1
].jump_abort
= 1;
2019 dj_play_sfx(SFX_JUMP
, (unsigned short)(SFX_JUMP_FREQ
+ rnd(2000) - 1000), 64, 0, 0, -1);
2021 dj_play_sfx(SFX_SPRING
, (unsigned short)(SFX_SPRING_FREQ
+ rnd(2000) - 1000), 64, 0, 0, -1);
2023 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
)) {
2024 player
[c1
].y_add
= -196608L;
2025 player
[c1
].in_water
= 0;
2026 player
[c1
].anim
= 2;
2027 player
[c1
].frame
= 0;
2028 player
[c1
].frame_tick
= 0;
2029 player
[c1
].image
= player_anims
[player
[c1
].anim
].frame
[player
[c1
].frame
].image
+ player
[c1
].direction
* 9;
2030 player
[c1
].jump_ready
= 0;
2031 player
[c1
].jump_abort
= 1;
2033 dj_play_sfx(SFX_JUMP
, (unsigned short)(SFX_JUMP_FREQ
+ rnd(2000) - 1000), 64, 0, 0, -1);
2035 dj_play_sfx(SFX_SPRING
, (unsigned short)(SFX_SPRING_FREQ
+ rnd(2000) - 1000), 64, 0, 0, -1);
2038 if (pogostick
== 0 && (!player
[c1
].action_up
)) {
2039 player
[c1
].jump_ready
= 1;
2040 if (player
[c1
].in_water
== 0 && player
[c1
].y_add
< 0 && player
[c1
].jump_abort
== 1) {
2041 if (bunnies_in_space
== 0)
2042 player
[c1
].y_add
+= 32768;
2044 player
[c1
].y_add
+= 16384;
2045 if (player
[c1
].y_add
> 0)
2046 player
[c1
].y_add
= 0;
2051 if (player
[c1
].action_up
) {
2052 player
[c1
].y_add
-= 16384;
2053 if (player
[c1
].y_add
< -400000L)
2054 player
[c1
].y_add
= -400000L;
2055 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
))
2056 player
[c1
].in_water
= 0;
2058 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);
2063 player
[c1
].x
+= player
[c1
].x_add
;
2064 if ((player
[c1
].x
>> 16) < 0) {
2066 player
[c1
].x_add
= 0;
2068 if ((player
[c1
].x
>> 16) + 15 > 351) {
2069 player
[c1
].x
= 336L << 16;
2070 player
[c1
].x_add
= 0;
2072 if (player
[c1
].y
> 0) {
2073 s1
= (player
[c1
].x
>> 16);
2074 s2
= (player
[c1
].y
>> 16);
2075 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
) {
2076 player
[c1
].x
= (((s1
+ 16) & 0xfff0)) << 16;
2077 player
[c1
].x_add
= 0;
2079 s1
= (player
[c1
].x
>> 16);
2080 s2
= (player
[c1
].y
>> 16);
2081 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
) {
2082 player
[c1
].x
= (((s1
+ 16) & 0xfff0) - 16) << 16;
2083 player
[c1
].x_add
= 0;
2086 s1
= (player
[c1
].x
>> 16);
2088 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
) {
2089 player
[c1
].x
= (((s1
+ 16) & 0xfff0)) << 16;
2090 player
[c1
].x_add
= 0;
2092 s1
= (player
[c1
].x
>> 16);
2094 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
) {
2095 player
[c1
].x
= (((s1
+ 16) & 0xfff0) - 16) << 16;
2096 player
[c1
].x_add
= 0;
2100 player
[c1
].y
+= player
[c1
].y_add
;
2102 s1
= (player
[c1
].x
>> 16);
2103 s2
= (player
[c1
].y
>> 16);
2104 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
))) {
2105 player
[c1
].y
= ((player
[c1
].y
>> 16) & 0xfff0) << 16;
2106 player
[c1
].y_add
= -400000L;
2107 player
[c1
].anim
= 2;
2108 player
[c1
].frame
= 0;
2109 player
[c1
].frame_tick
= 0;
2110 player
[c1
].image
= player_anims
[player
[c1
].anim
].frame
[player
[c1
].frame
].image
+ player
[c1
].direction
* 9;
2111 player
[c1
].jump_ready
= 0;
2112 player
[c1
].jump_abort
= 0;
2113 for (c2
= 0; c2
< NUM_OBJECTS
; c2
++) {
2114 if (objects
[c2
].used
== 1 && objects
[c2
].type
== OBJ_SPRING
) {
2115 if (ban_map
[(s2
+ 15) >> 4][(s1
+ 8) >> 4] == BAN_SPRING
) {
2116 if ((objects
[c2
].x
>> 20) == ((s1
+ 8) >> 4) && (objects
[c2
].y
>> 20) == ((s2
+ 15) >> 4)) {
2117 objects
[c2
].frame
= 0;
2118 objects
[c2
].ticks
= object_anims
[objects
[c2
].anim
].frame
[objects
[c2
].frame
].ticks
;
2119 objects
[c2
].image
= object_anims
[objects
[c2
].anim
].frame
[objects
[c2
].frame
].image
;
2123 if (ban_map
[(s2
+ 15) >> 4][s1
>> 4] == BAN_SPRING
) {
2124 if ((objects
[c2
].x
>> 20) == (s1
>> 4) && (objects
[c2
].y
>> 20) == ((s2
+ 15) >> 4)) {
2125 objects
[c2
].frame
= 0;
2126 objects
[c2
].ticks
= object_anims
[objects
[c2
].anim
].frame
[objects
[c2
].frame
].ticks
;
2127 objects
[c2
].image
= object_anims
[objects
[c2
].anim
].frame
[objects
[c2
].frame
].image
;
2130 } else if (ban_map
[(s2
+ 15) >> 4][(s1
+ 15) >> 4] == BAN_SPRING
) {
2131 if ((objects
[c2
].x
>> 20) == ((s1
+ 15) >> 4) && (objects
[c2
].y
>> 20) == ((s2
+ 15) >> 4)) {
2132 objects
[c2
].frame
= 0;
2133 objects
[c2
].ticks
= object_anims
[objects
[c2
].anim
].frame
[objects
[c2
].frame
].ticks
;
2134 objects
[c2
].image
= object_anims
[objects
[c2
].anim
].frame
[objects
[c2
].frame
].image
;
2141 dj_play_sfx(SFX_SPRING
, (unsigned short)(SFX_SPRING_FREQ
+ rnd(2000) - 1000), 64, 0, 0, -1);
2143 s1
= (player
[c1
].x
>> 16);
2144 s2
= (player
[c1
].y
>> 16);
2147 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
) {
2148 player
[c1
].y
= (((s2
+ 16) & 0xfff0)) << 16;
2149 player
[c1
].y_add
= 0;
2150 player
[c1
].anim
= 0;
2151 player
[c1
].frame
= 0;
2152 player
[c1
].frame_tick
= 0;
2153 player
[c1
].image
= player_anims
[player
[c1
].anim
].frame
[player
[c1
].frame
].image
+ player
[c1
].direction
* 9;
2155 s1
= (player
[c1
].x
>> 16);
2156 s2
= (player
[c1
].y
>> 16);
2159 if (ban_map
[(s2
+ 8) >> 4][(s1
+ 8) >> 4] == BAN_WATER
) {
2160 if (player
[c1
].in_water
== 0) {
2161 player
[c1
].in_water
= 1;
2162 player
[c1
].anim
= 4;
2163 player
[c1
].frame
= 0;
2164 player
[c1
].frame_tick
= 0;
2165 player
[c1
].image
= player_anims
[player
[c1
].anim
].frame
[player
[c1
].frame
].image
+ player
[c1
].direction
* 9;
2166 if (player
[c1
].y_add
>= 32768) {
2167 add_object(OBJ_SPLASH
, (player
[c1
].x
>> 16) + 8, ((player
[c1
].y
>> 16) & 0xfff0) + 15, 0, 0, OBJ_ANIM_SPLASH
, 0);
2168 if (blood_is_thicker_than_water
== 0)
2169 dj_play_sfx(SFX_SPLASH
, (unsigned short)(SFX_SPLASH_FREQ
+ rnd(2000) - 1000), 64, 0, 0, -1);
2171 dj_play_sfx(SFX_SPLASH
, (unsigned short)(SFX_SPLASH_FREQ
+ rnd(2000) - 5000), 64, 0, 0, -1);
2174 player
[c1
].y_add
-= 1536;
2175 if (player
[c1
].y_add
< 0 && player
[c1
].anim
!= 5) {
2176 player
[c1
].anim
= 5;
2177 player
[c1
].frame
= 0;
2178 player
[c1
].frame_tick
= 0;
2179 player
[c1
].image
= player_anims
[player
[c1
].anim
].frame
[player
[c1
].frame
].image
+ player
[c1
].direction
* 9;
2181 if (player
[c1
].y_add
< -65536L)
2182 player
[c1
].y_add
= -65536L;
2183 if (player
[c1
].y_add
> 65535L)
2184 player
[c1
].y_add
= 65535L;
2185 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
) {
2186 player
[c1
].y
= (((s2
+ 16) & 0xfff0) - 16) << 16;
2187 player
[c1
].y_add
= 0;
2189 } 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
) {
2190 player
[c1
].in_water
= 0;
2191 player
[c1
].y
= (((s2
+ 16) & 0xfff0) - 16) << 16;
2192 player
[c1
].y_add
= 0;
2193 if (player
[c1
].anim
!= 0 && player
[c1
].anim
!= 1) {
2194 player
[c1
].anim
= 0;
2195 player
[c1
].frame
= 0;
2196 player
[c1
].frame_tick
= 0;
2197 player
[c1
].image
= player_anims
[player
[c1
].anim
].frame
[player
[c1
].frame
].image
+ player
[c1
].direction
* 9;
2200 if (player
[c1
].in_water
== 0) {
2201 if (bunnies_in_space
== 0)
2202 player
[c1
].y_add
+= 12288;
2204 player
[c1
].y_add
+= 6144;
2205 if (player
[c1
].y_add
> 327680L)
2206 player
[c1
].y_add
= 327680L;
2208 player
[c1
].y
= (player
[c1
].y
& 0xffff0000) + 0x10000;
2209 player
[c1
].y_add
= 0;
2211 player
[c1
].in_water
= 0;
2213 if (player
[c1
].y_add
> 36864 && player
[c1
].anim
!= 3 && player
[c1
].in_water
== 0) {
2214 player
[c1
].anim
= 3;
2215 player
[c1
].frame
= 0;
2216 player
[c1
].frame_tick
= 0;
2217 player
[c1
].image
= player_anims
[player
[c1
].anim
].frame
[player
[c1
].frame
].image
+ player
[c1
].direction
* 9;
2222 player
[c1
].frame_tick
++;
2223 if (player
[c1
].frame_tick
>= player_anims
[player
[c1
].anim
].frame
[player
[c1
].frame
].ticks
) {
2225 if (player
[c1
].frame
>= player_anims
[player
[c1
].anim
].num_frames
) {
2226 if (player
[c1
].anim
!= 6)
2227 player
[c1
].frame
= player_anims
[player
[c1
].anim
].restart_frame
;
2229 position_player(c1
);
2231 player
[c1
].frame_tick
= 0;
2233 player
[c1
].image
= player_anims
[player
[c1
].anim
].frame
[player
[c1
].frame
].image
+ player
[c1
].direction
* 9;
2242 void position_player(int player_num
)
2251 if (ban_map
[s2
][s1
] == BAN_VOID
&& (ban_map
[s2
+ 1][s1
] == BAN_SOLID
|| ban_map
[s2
+ 1][s1
] == BAN_ICE
))
2254 for (c1
= 0; c1
< JNB_MAX_PLAYERS
; c1
++) {
2255 if (c1
!= player_num
&& player
[c1
].enabled
== 1) {
2256 if (abs((s1
<< 4) - (player
[c1
].x
>> 16)) < 32 && abs((s2
<< 4) - (player
[c1
].y
>> 16)) < 32)
2260 if (c1
== JNB_MAX_PLAYERS
) {
2261 player
[player_num
].x
= (long) s1
<< 20;
2262 player
[player_num
].y
= (long) s2
<< 20;
2263 player
[player_num
].x_add
= player
[player_num
].y_add
= 0;
2264 player
[player_num
].direction
= 0;
2265 player
[player_num
].jump_ready
= 1;
2266 player
[player_num
].in_water
= 0;
2267 player
[player_num
].anim
= 0;
2268 player
[player_num
].frame
= 0;
2269 player
[player_num
].frame_tick
= 0;
2270 player
[player_num
].image
= player_anims
[player
[player_num
].anim
].frame
[player
[player_num
].frame
].image
;
2275 serverSendAlive(player_num
);
2277 player
[player_num
].dead_flag
= 0;
2287 void add_object(int type
, int x
, int y
, int x_add
, int y_add
, int anim
, int frame
)
2291 for (c1
= 0; c1
< NUM_OBJECTS
; c1
++) {
2292 if (objects
[c1
].used
== 0) {
2293 objects
[c1
].used
= 1;
2294 objects
[c1
].type
= type
;
2295 objects
[c1
].x
= (long) x
<< 16;
2296 objects
[c1
].y
= (long) y
<< 16;
2297 objects
[c1
].x_add
= x_add
;
2298 objects
[c1
].y_add
= y_add
;
2299 objects
[c1
].x_acc
= 0;
2300 objects
[c1
].y_acc
= 0;
2301 objects
[c1
].anim
= anim
;
2302 objects
[c1
].frame
= frame
;
2303 objects
[c1
].ticks
= object_anims
[anim
].frame
[frame
].ticks
;
2304 objects
[c1
].image
= object_anims
[anim
].frame
[frame
].image
;
2312 void update_objects(void)
2317 for (c1
= 0; c1
< NUM_OBJECTS
; c1
++) {
2318 if (objects
[c1
].used
== 1) {
2319 switch (objects
[c1
].type
) {
2321 objects
[c1
].ticks
--;
2322 if (objects
[c1
].ticks
<= 0) {
2323 objects
[c1
].frame
++;
2324 if (objects
[c1
].frame
>= object_anims
[objects
[c1
].anim
].num_frames
) {
2325 objects
[c1
].frame
--;
2326 objects
[c1
].ticks
= object_anims
[objects
[c1
].anim
].frame
[objects
[c1
].frame
].ticks
;
2328 objects
[c1
].ticks
= object_anims
[objects
[c1
].anim
].frame
[objects
[c1
].frame
].ticks
;
2329 objects
[c1
].image
= object_anims
[objects
[c1
].anim
].frame
[objects
[c1
].frame
].image
;
2332 if (objects
[c1
].used
== 1)
2333 add_pob(main_info
.draw_page
, objects
[c1
].x
>> 16, objects
[c1
].y
>> 16, objects
[c1
].image
, &object_gobs
);
2336 objects
[c1
].ticks
--;
2337 if (objects
[c1
].ticks
<= 0) {
2338 objects
[c1
].frame
++;
2339 if (objects
[c1
].frame
>= object_anims
[objects
[c1
].anim
].num_frames
)
2340 objects
[c1
].used
= 0;
2342 objects
[c1
].ticks
= object_anims
[objects
[c1
].anim
].frame
[objects
[c1
].frame
].ticks
;
2343 objects
[c1
].image
= object_anims
[objects
[c1
].anim
].frame
[objects
[c1
].frame
].image
;
2346 if (objects
[c1
].used
== 1)
2347 add_pob(main_info
.draw_page
, objects
[c1
].x
>> 16, objects
[c1
].y
>> 16, objects
[c1
].image
, &object_gobs
);
2350 objects
[c1
].x
+= objects
[c1
].x_add
;
2351 objects
[c1
].y
+= objects
[c1
].y_add
;
2352 objects
[c1
].ticks
--;
2353 if (objects
[c1
].ticks
<= 0) {
2354 objects
[c1
].frame
++;
2355 if (objects
[c1
].frame
>= object_anims
[objects
[c1
].anim
].num_frames
)
2356 objects
[c1
].used
= 0;
2358 objects
[c1
].ticks
= object_anims
[objects
[c1
].anim
].frame
[objects
[c1
].frame
].ticks
;
2359 objects
[c1
].image
= object_anims
[objects
[c1
].anim
].frame
[objects
[c1
].frame
].image
;
2362 if (objects
[c1
].used
== 1)
2363 add_pob(main_info
.draw_page
, objects
[c1
].x
>> 16, objects
[c1
].y
>> 16, objects
[c1
].image
, &object_gobs
);
2365 case OBJ_YEL_BUTFLY
:
2366 case OBJ_PINK_BUTFLY
:
2367 objects
[c1
].x_acc
+= rnd(128) - 64;
2368 if (objects
[c1
].x_acc
< -1024)
2369 objects
[c1
].x_acc
= -1024;
2370 if (objects
[c1
].x_acc
> 1024)
2371 objects
[c1
].x_acc
= 1024;
2372 objects
[c1
].x_add
+= objects
[c1
].x_acc
;
2373 if (objects
[c1
].x_add
< -32768)
2374 objects
[c1
].x_add
= -32768;
2375 if (objects
[c1
].x_add
> 32768)
2376 objects
[c1
].x_add
= 32768;
2377 objects
[c1
].x
+= objects
[c1
].x_add
;
2378 if ((objects
[c1
].x
>> 16) < 16) {
2379 objects
[c1
].x
= 16 << 16;
2380 objects
[c1
].x_add
= -objects
[c1
].x_add
>> 2;
2381 objects
[c1
].x_acc
= 0;
2382 } else if ((objects
[c1
].x
>> 16) > 350) {
2383 objects
[c1
].x
= 350 << 16;
2384 objects
[c1
].x_add
= -objects
[c1
].x_add
>> 2;
2385 objects
[c1
].x_acc
= 0;
2387 if (ban_map
[objects
[c1
].y
>> 20][objects
[c1
].x
>> 20] != 0) {
2388 if (objects
[c1
].x_add
< 0) {
2389 objects
[c1
].x
= (((objects
[c1
].x
>> 16) + 16) & 0xfff0) << 16;
2391 objects
[c1
].x
= ((((objects
[c1
].x
>> 16) - 16) & 0xfff0) + 15) << 16;
2393 objects
[c1
].x_add
= -objects
[c1
].x_add
>> 2;
2394 objects
[c1
].x_acc
= 0;
2396 objects
[c1
].y_acc
+= rnd(64) - 32;
2397 if (objects
[c1
].y_acc
< -1024)
2398 objects
[c1
].y_acc
= -1024;
2399 if (objects
[c1
].y_acc
> 1024)
2400 objects
[c1
].y_acc
= 1024;
2401 objects
[c1
].y_add
+= objects
[c1
].y_acc
;
2402 if (objects
[c1
].y_add
< -32768)
2403 objects
[c1
].y_add
= -32768;
2404 if (objects
[c1
].y_add
> 32768)
2405 objects
[c1
].y_add
= 32768;
2406 objects
[c1
].y
+= objects
[c1
].y_add
;
2407 if ((objects
[c1
].y
>> 16) < 0) {
2409 objects
[c1
].y_add
= -objects
[c1
].y_add
>> 2;
2410 objects
[c1
].y_acc
= 0;
2411 } else if ((objects
[c1
].y
>> 16) > 255) {
2412 objects
[c1
].y
= 255 << 16;
2413 objects
[c1
].y_add
= -objects
[c1
].y_add
>> 2;
2414 objects
[c1
].y_acc
= 0;
2416 if (ban_map
[objects
[c1
].y
>> 20][objects
[c1
].x
>> 20] != 0) {
2417 if (objects
[c1
].y_add
< 0) {
2418 objects
[c1
].y
= (((objects
[c1
].y
>> 16) + 16) & 0xfff0) << 16;
2420 objects
[c1
].y
= ((((objects
[c1
].y
>> 16) - 16) & 0xfff0) + 15) << 16;
2422 objects
[c1
].y_add
= -objects
[c1
].y_add
>> 2;
2423 objects
[c1
].y_acc
= 0;
2425 if (objects
[c1
].type
== OBJ_YEL_BUTFLY
) {
2426 if (objects
[c1
].x_add
< 0 && objects
[c1
].anim
!= OBJ_ANIM_YEL_BUTFLY_LEFT
) {
2427 objects
[c1
].anim
= OBJ_ANIM_YEL_BUTFLY_LEFT
;
2428 objects
[c1
].frame
= 0;
2429 objects
[c1
].ticks
= object_anims
[objects
[c1
].anim
].frame
[objects
[c1
].frame
].ticks
;
2430 objects
[c1
].image
= object_anims
[objects
[c1
].anim
].frame
[objects
[c1
].frame
].image
;
2431 } else if (objects
[c1
].x_add
> 0 && objects
[c1
].anim
!= OBJ_ANIM_YEL_BUTFLY_RIGHT
) {
2432 objects
[c1
].anim
= OBJ_ANIM_YEL_BUTFLY_RIGHT
;
2433 objects
[c1
].frame
= 0;
2434 objects
[c1
].ticks
= object_anims
[objects
[c1
].anim
].frame
[objects
[c1
].frame
].ticks
;
2435 objects
[c1
].image
= object_anims
[objects
[c1
].anim
].frame
[objects
[c1
].frame
].image
;
2438 if (objects
[c1
].x_add
< 0 && objects
[c1
].anim
!= OBJ_ANIM_PINK_BUTFLY_LEFT
) {
2439 objects
[c1
].anim
= OBJ_ANIM_PINK_BUTFLY_LEFT
;
2440 objects
[c1
].frame
= 0;
2441 objects
[c1
].ticks
= object_anims
[objects
[c1
].anim
].frame
[objects
[c1
].frame
].ticks
;
2442 objects
[c1
].image
= object_anims
[objects
[c1
].anim
].frame
[objects
[c1
].frame
].image
;
2443 } else if (objects
[c1
].x_add
> 0 && objects
[c1
].anim
!= OBJ_ANIM_PINK_BUTFLY_RIGHT
) {
2444 objects
[c1
].anim
= OBJ_ANIM_PINK_BUTFLY_RIGHT
;
2445 objects
[c1
].frame
= 0;
2446 objects
[c1
].ticks
= object_anims
[objects
[c1
].anim
].frame
[objects
[c1
].frame
].ticks
;
2447 objects
[c1
].image
= object_anims
[objects
[c1
].anim
].frame
[objects
[c1
].frame
].image
;
2450 objects
[c1
].ticks
--;
2451 if (objects
[c1
].ticks
<= 0) {
2452 objects
[c1
].frame
++;
2453 if (objects
[c1
].frame
>= object_anims
[objects
[c1
].anim
].num_frames
)
2454 objects
[c1
].frame
= object_anims
[objects
[c1
].anim
].restart_frame
;
2456 objects
[c1
].ticks
= object_anims
[objects
[c1
].anim
].frame
[objects
[c1
].frame
].ticks
;
2457 objects
[c1
].image
= object_anims
[objects
[c1
].anim
].frame
[objects
[c1
].frame
].image
;
2460 if (objects
[c1
].used
== 1)
2461 add_pob(main_info
.draw_page
, objects
[c1
].x
>> 16, objects
[c1
].y
>> 16, objects
[c1
].image
, &object_gobs
);
2465 add_object(OBJ_FLESH_TRACE
, objects
[c1
].x
>> 16, objects
[c1
].y
>> 16, 0, 0, OBJ_ANIM_FLESH_TRACE
, 0);
2466 if (ban_map
[objects
[c1
].y
>> 20][objects
[c1
].x
>> 20] == 0) {
2467 objects
[c1
].y_add
+= 3072;
2468 if (objects
[c1
].y_add
> 196608L)
2469 objects
[c1
].y_add
= 196608L;
2470 } else if (ban_map
[objects
[c1
].y
>> 20][objects
[c1
].x
>> 20] == 2) {
2471 if (objects
[c1
].x_add
< 0) {
2472 if (objects
[c1
].x_add
< -65536L)
2473 objects
[c1
].x_add
= -65536L;
2474 objects
[c1
].x_add
+= 1024;
2475 if (objects
[c1
].x_add
> 0)
2476 objects
[c1
].x_add
= 0;
2478 if (objects
[c1
].x_add
> 65536L)
2479 objects
[c1
].x_add
= 65536L;
2480 objects
[c1
].x_add
-= 1024;
2481 if (objects
[c1
].x_add
< 0)
2482 objects
[c1
].x_add
= 0;
2484 objects
[c1
].y_add
+= 1024;
2485 if (objects
[c1
].y_add
< -65536L)
2486 objects
[c1
].y_add
= -65536L;
2487 if (objects
[c1
].y_add
> 65536L)
2488 objects
[c1
].y_add
= 65536L;
2490 objects
[c1
].x
+= objects
[c1
].x_add
;
2491 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)) {
2492 if (objects
[c1
].x_add
< 0) {
2493 objects
[c1
].x
= (((objects
[c1
].x
>> 16) + 16) & 0xfff0) << 16;
2494 objects
[c1
].x_add
= -objects
[c1
].x_add
>> 2;
2496 objects
[c1
].x
= ((((objects
[c1
].x
>> 16) - 16) & 0xfff0) + 15) << 16;
2497 objects
[c1
].x_add
= -objects
[c1
].x_add
>> 2;
2500 objects
[c1
].y
+= objects
[c1
].y_add
;
2501 if ((objects
[c1
].x
>> 16) < -5 || (objects
[c1
].x
>> 16) > 405 || (objects
[c1
].y
>> 16) > 260)
2502 objects
[c1
].used
= 0;
2503 if ((objects
[c1
].y
>> 16) > 0 && (ban_map
[objects
[c1
].y
>> 20][objects
[c1
].x
>> 20] != 0)) {
2504 if (objects
[c1
].y_add
< 0) {
2505 if (ban_map
[objects
[c1
].y
>> 20][objects
[c1
].x
>> 20] != 2) {
2506 objects
[c1
].y
= (((objects
[c1
].y
>> 16) + 16) & 0xfff0) << 16;
2507 objects
[c1
].x_add
>>= 2;
2508 objects
[c1
].y_add
= -objects
[c1
].y_add
>> 2;
2511 if (ban_map
[objects
[c1
].y
>> 20][objects
[c1
].x
>> 20] == 1) {
2512 if (objects
[c1
].y_add
> 131072L) {
2513 objects
[c1
].y
= ((((objects
[c1
].y
>> 16) - 16) & 0xfff0) + 15) << 16;
2514 objects
[c1
].x_add
>>= 2;
2515 objects
[c1
].y_add
= -objects
[c1
].y_add
>> 2;
2517 objects
[c1
].used
= 0;
2518 } else if (ban_map
[objects
[c1
].y
>> 20][objects
[c1
].x
>> 20] == 3) {
2519 objects
[c1
].y
= ((((objects
[c1
].y
>> 16) - 16) & 0xfff0) + 15) << 16;
2520 if (objects
[c1
].y_add
> 131072L)
2521 objects
[c1
].y_add
= -objects
[c1
].y_add
>> 2;
2523 objects
[c1
].y_add
= 0;
2527 if (objects
[c1
].x_add
< 0 && objects
[c1
].x_add
> -16384)
2528 objects
[c1
].x_add
= -16384;
2529 if (objects
[c1
].x_add
> 0 && objects
[c1
].x_add
< 16384)
2530 objects
[c1
].x_add
= 16384;
2531 if (objects
[c1
].used
== 1) {
2532 s1
= (int)(atan2(objects
[c1
].y_add
, objects
[c1
].x_add
) * 4 / M_PI
);
2539 add_pob(main_info
.draw_page
, objects
[c1
].x
>> 16, objects
[c1
].y
>> 16, objects
[c1
].frame
+ s1
, &object_gobs
);
2543 if (rnd(100) < 30) {
2544 if (objects
[c1
].frame
== 76)
2545 add_object(OBJ_FLESH_TRACE
, objects
[c1
].x
>> 16, objects
[c1
].y
>> 16, 0, 0, OBJ_ANIM_FLESH_TRACE
, 1);
2546 else if (objects
[c1
].frame
== 77)
2547 add_object(OBJ_FLESH_TRACE
, objects
[c1
].x
>> 16, objects
[c1
].y
>> 16, 0, 0, OBJ_ANIM_FLESH_TRACE
, 2);
2548 else if (objects
[c1
].frame
== 78)
2549 add_object(OBJ_FLESH_TRACE
, objects
[c1
].x
>> 16, objects
[c1
].y
>> 16, 0, 0, OBJ_ANIM_FLESH_TRACE
, 3);
2551 if (ban_map
[objects
[c1
].y
>> 20][objects
[c1
].x
>> 20] == 0) {
2552 objects
[c1
].y_add
+= 3072;
2553 if (objects
[c1
].y_add
> 196608L)
2554 objects
[c1
].y_add
= 196608L;
2555 } else if (ban_map
[objects
[c1
].y
>> 20][objects
[c1
].x
>> 20] == 2) {
2556 if (objects
[c1
].x_add
< 0) {
2557 if (objects
[c1
].x_add
< -65536L)
2558 objects
[c1
].x_add
= -65536L;
2559 objects
[c1
].x_add
+= 1024;
2560 if (objects
[c1
].x_add
> 0)
2561 objects
[c1
].x_add
= 0;
2563 if (objects
[c1
].x_add
> 65536L)
2564 objects
[c1
].x_add
= 65536L;
2565 objects
[c1
].x_add
-= 1024;
2566 if (objects
[c1
].x_add
< 0)
2567 objects
[c1
].x_add
= 0;
2569 objects
[c1
].y_add
+= 1024;
2570 if (objects
[c1
].y_add
< -65536L)
2571 objects
[c1
].y_add
= -65536L;
2572 if (objects
[c1
].y_add
> 65536L)
2573 objects
[c1
].y_add
= 65536L;
2575 objects
[c1
].x
+= objects
[c1
].x_add
;
2576 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)) {
2577 if (objects
[c1
].x_add
< 0) {
2578 objects
[c1
].x
= (((objects
[c1
].x
>> 16) + 16) & 0xfff0) << 16;
2579 objects
[c1
].x_add
= -objects
[c1
].x_add
>> 2;
2581 objects
[c1
].x
= ((((objects
[c1
].x
>> 16) - 16) & 0xfff0) + 15) << 16;
2582 objects
[c1
].x_add
= -objects
[c1
].x_add
>> 2;
2585 objects
[c1
].y
+= objects
[c1
].y_add
;
2586 if ((objects
[c1
].x
>> 16) < -5 || (objects
[c1
].x
>> 16) > 405 || (objects
[c1
].y
>> 16) > 260)
2587 objects
[c1
].used
= 0;
2588 if ((objects
[c1
].y
>> 16) > 0 && (ban_map
[objects
[c1
].y
>> 20][objects
[c1
].x
>> 20] != 0)) {
2589 if (objects
[c1
].y_add
< 0) {
2590 if (ban_map
[objects
[c1
].y
>> 20][objects
[c1
].x
>> 20] != 2) {
2591 objects
[c1
].y
= (((objects
[c1
].y
>> 16) + 16) & 0xfff0) << 16;
2592 objects
[c1
].x_add
>>= 2;
2593 objects
[c1
].y_add
= -objects
[c1
].y_add
>> 2;
2596 if (ban_map
[objects
[c1
].y
>> 20][objects
[c1
].x
>> 20] == 1) {
2597 if (objects
[c1
].y_add
> 131072L) {
2598 objects
[c1
].y
= ((((objects
[c1
].y
>> 16) - 16) & 0xfff0) + 15) << 16;
2599 objects
[c1
].x_add
>>= 2;
2600 objects
[c1
].y_add
= -objects
[c1
].y_add
>> 2;
2602 if (rnd(100) < 10) {
2604 add_leftovers(0, objects
[c1
].x
>> 16, (objects
[c1
].y
>> 16) + s1
, objects
[c1
].frame
, &object_gobs
);
2605 add_leftovers(1, objects
[c1
].x
>> 16, (objects
[c1
].y
>> 16) + s1
, objects
[c1
].frame
, &object_gobs
);
2607 objects
[c1
].used
= 0;
2609 } else if (ban_map
[objects
[c1
].y
>> 20][objects
[c1
].x
>> 20] == 3) {
2610 objects
[c1
].y
= ((((objects
[c1
].y
>> 16) - 16) & 0xfff0) + 15) << 16;
2611 if (objects
[c1
].y_add
> 131072L)
2612 objects
[c1
].y_add
= -objects
[c1
].y_add
>> 2;
2614 objects
[c1
].y_add
= 0;
2618 if (objects
[c1
].x_add
< 0 && objects
[c1
].x_add
> -16384)
2619 objects
[c1
].x_add
= -16384;
2620 if (objects
[c1
].x_add
> 0 && objects
[c1
].x_add
< 16384)
2621 objects
[c1
].x_add
= 16384;
2622 if (objects
[c1
].used
== 1)
2623 add_pob(main_info
.draw_page
, objects
[c1
].x
>> 16, objects
[c1
].y
>> 16, objects
[c1
].frame
, &object_gobs
);
2625 case OBJ_FLESH_TRACE
:
2626 objects
[c1
].ticks
--;
2627 if (objects
[c1
].ticks
<= 0) {
2628 objects
[c1
].frame
++;
2629 if (objects
[c1
].frame
>= object_anims
[objects
[c1
].anim
].num_frames
)
2630 objects
[c1
].used
= 0;
2632 objects
[c1
].ticks
= object_anims
[objects
[c1
].anim
].frame
[objects
[c1
].frame
].ticks
;
2633 objects
[c1
].image
= object_anims
[objects
[c1
].anim
].frame
[objects
[c1
].frame
].image
;
2636 if (objects
[c1
].used
== 1)
2637 add_pob(main_info
.draw_page
, objects
[c1
].x
>> 16, objects
[c1
].y
>> 16, objects
[c1
].image
, &object_gobs
);
2646 int add_pob(int page
, int x
, int y
, int image
, gob_t
*pob_data
)
2649 if (main_info
.page_info
[page
].num_pobs
>= NUM_POBS
)
2652 main_info
.page_info
[page
].pobs
[main_info
.page_info
[page
].num_pobs
].x
= x
;
2653 main_info
.page_info
[page
].pobs
[main_info
.page_info
[page
].num_pobs
].y
= y
;
2654 main_info
.page_info
[page
].pobs
[main_info
.page_info
[page
].num_pobs
].image
= image
;
2655 main_info
.page_info
[page
].pobs
[main_info
.page_info
[page
].num_pobs
].pob_data
= pob_data
;
2656 main_info
.page_info
[page
].num_pobs
++;
2663 void draw_flies(int page
)
2667 for (c2
= 0; c2
< NUM_FLIES
; c2
++) {
2668 flies
[c2
].back
[main_info
.draw_page
] = get_pixel(main_info
.draw_page
, flies
[c2
].x
, flies
[c2
].y
);
2669 flies
[c2
].back_defined
[main_info
.draw_page
] = 1;
2670 if (mask_pic
[(flies
[c2
].y
* JNB_WIDTH
) + flies
[c2
].x
] == 0)
2671 set_pixel(main_info
.draw_page
, flies
[c2
].x
, flies
[c2
].y
, 0);
2675 void draw_pobs(int page
)
2682 for (c1
= main_info
.page_info
[page
].num_pobs
- 1; c1
>= 0; c1
--) {
2683 main_info
.page_info
[page
].pobs
[c1
].back_buf_ofs
= back_buf_ofs
;
2684 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
);
2686 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;
2688 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
);
2689 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
);
2695 void redraw_flies_background(int page
)
2699 for (c2
= NUM_FLIES
- 1; c2
>= 0; c2
--) {
2700 if (flies
[c2
].back_defined
[page
] == 1)
2701 set_pixel(page
, flies
[c2
].old_draw_x
, flies
[c2
].old_draw_y
, flies
[c2
].back
[page
]);
2702 flies
[c2
].old_draw_x
= flies
[c2
].x
;
2703 flies
[c2
].old_draw_y
= flies
[c2
].y
;
2708 void redraw_pob_backgrounds(int page
)
2712 for (c1
= 0; c1
< main_info
.page_info
[page
].num_pobs
; c1
++)
2713 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
);
2718 int add_leftovers(int page
, int x
, int y
, int image
, gob_t
*pob_data
)
2721 if (leftovers
.page
[page
].num_pobs
>= NUM_LEFTOVERS
)
2724 leftovers
.page
[page
].pobs
[leftovers
.page
[page
].num_pobs
].x
= x
;
2725 leftovers
.page
[page
].pobs
[leftovers
.page
[page
].num_pobs
].y
= y
;
2726 leftovers
.page
[page
].pobs
[leftovers
.page
[page
].num_pobs
].image
= image
;
2727 leftovers
.page
[page
].pobs
[leftovers
.page
[page
].num_pobs
].pob_data
= pob_data
;
2728 leftovers
.page
[page
].num_pobs
++;
2735 void draw_leftovers(int page
)
2739 for (c1
= leftovers
.page
[page
].num_pobs
- 1; c1
>= 0; c1
--)
2740 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
);
2742 leftovers
.page
[page
].num_pobs
= 0;
2747 int init_level(int level
, char *pal
)
2749 unsigned char *handle
;
2753 if ((handle
= dat_open("level.pcx")) == 0) {
2754 strcpy(main_info
.error_str
, "Error loading 'level.pcx', aborting...\n");
2757 if (read_pcx(handle
, background_pic
, JNB_WIDTH
*JNB_HEIGHT
, pal
) != 0) {
2758 strcpy(main_info
.error_str
, "Error loading 'level.pcx', aborting...\n");
2762 flip_pixels(background_pic
);
2763 if ((handle
= dat_open("mask.pcx")) == 0) {
2764 strcpy(main_info
.error_str
, "Error loading 'mask.pcx', aborting...\n");
2767 if (read_pcx(handle
, mask_pic
, JNB_WIDTH
*JNB_HEIGHT
, 0) != 0) {
2768 strcpy(main_info
.error_str
, "Error loading 'mask.pcx', aborting...\n");
2772 flip_pixels(mask_pic
);
2773 register_mask(mask_pic
);
2775 for (c1
= 0; c1
< JNB_MAX_PLAYERS
; c1
++) {
2776 if (player
[c1
].enabled
== 1) {
2777 player
[c1
].bumps
= 0;
2778 for (c2
= 0; c2
< JNB_MAX_PLAYERS
; c2
++)
2779 player
[c1
].bumped
[c2
] = 0;
2780 position_player(c1
);
2784 for (c1
= 0; c1
< NUM_OBJECTS
; c1
++)
2785 objects
[c1
].used
= 0;
2787 for (c1
= 0; c1
< 16; c1
++) {
2788 for (c2
= 0; c2
< 22; c2
++) {
2789 if (ban_map
[c1
][c2
] == BAN_SPRING
)
2790 add_object(OBJ_SPRING
, c2
<< 4, c1
<< 4, 0, 0, OBJ_ANIM_SPRING
, 5);
2797 if (ban_map
[s2
][s1
] == BAN_VOID
) {
2798 add_object(OBJ_YEL_BUTFLY
, (s1
<< 4) + 8, (s2
<< 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2805 if (ban_map
[s2
][s1
] == BAN_VOID
) {
2806 add_object(OBJ_YEL_BUTFLY
, (s1
<< 4) + 8, (s2
<< 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2813 if (ban_map
[s2
][s1
] == BAN_VOID
) {
2814 add_object(OBJ_PINK_BUTFLY
, (s1
<< 4) + 8, (s2
<< 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2821 if (ban_map
[s2
][s1
] == BAN_VOID
) {
2822 add_object(OBJ_PINK_BUTFLY
, (s1
<< 4) + 8, (s2
<< 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2832 void deinit_level(void)
2840 #define PATH_MAX 1024
2846 unsigned char *datafile_buffer
= NULL
;
2848 static void preread_datafile(const char *fname
)
2854 char *gzfilename
= alloca(strlen(fname
) + 4);
2859 strcpy(gzfilename
, fname
);
2860 strcat(gzfilename
, ".gz");
2862 gzf
= gzopen(gzfilename
, "rb");
2867 if (bufpos
>= bufsize
) {
2868 bufsize
+= 1024 * 1024;
2869 datafile_buffer
= (unsigned char *) realloc(datafile_buffer
, bufsize
);
2870 if (datafile_buffer
== NULL
) {
2871 perror("realloc()");
2876 br
= gzread(gzf
, datafile_buffer
+ bufpos
, bufsize
- bufpos
);
2878 fprintf(stderr
, "gzread failed.\n");
2883 } while (!gzeof(gzf
));
2885 /* try to shrink buffer... */
2886 ptr
= (unsigned char *) realloc(datafile_buffer
, bufpos
);
2888 datafile_buffer
= ptr
;
2894 /* drop through and try for an uncompressed datafile... */
2897 fd
= open(fname
, O_RDONLY
| O_BINARY
);
2899 fprintf(stderr
, "can't open %s:", fname
);
2904 len
= filelength(fd
);
2905 datafile_buffer
= (unsigned char *) malloc(len
);
2906 if (datafile_buffer
== NULL
) {
2912 if (read(fd
, datafile_buffer
, len
) != len
) {
2922 int init_program(int argc
, char *argv
[], char *pal
)
2924 char *netarg
= NULL
;
2925 unsigned char *handle
= (unsigned char *) NULL
;
2930 int player_anim_data
[] = {
2931 1, 0, 0, 0x7fff, 0, 0, 0, 0, 0, 0,
2932 4, 0, 0, 4, 1, 4, 2, 4, 3, 4,
2933 1, 0, 4, 0x7fff, 0, 0, 0, 0, 0, 0,
2934 4, 2, 5, 8, 6, 10, 7, 3, 6, 3,
2935 1, 0, 6, 0x7fff, 0, 0, 0, 0, 0, 0,
2936 2, 1, 5, 8, 4, 0x7fff, 0, 0, 0, 0,
2937 1, 0, 8, 5, 0, 0, 0, 0, 0, 0
2941 memset(&net_info
, 0, sizeof(net_info
));
2945 if (__djgpp_nearptr_enable() == 0)
2951 if (hook_keyb_handler() != 0)
2954 memset(&main_info
, 0, sizeof(main_info
));
2956 strcpy(datfile_name
, DATA_PATH
);
2958 force2
= force3
= 0;
2961 for (c1
= 1; c1
< argc
; c1
++) {
2962 if (stricmp(argv
[c1
], "-nosound") == 0)
2963 main_info
.no_sound
= 1;
2964 else if (stricmp(argv
[c1
], "-musicnosound") == 0)
2965 main_info
.music_no_sound
= 1;
2966 else if (stricmp(argv
[c1
], "-nogore") == 0)
2967 main_info
.no_gore
= 1;
2968 else if (stricmp(argv
[c1
], "-noflies") == 0)
2970 else if (stricmp(argv
[c1
], "-nojoy") == 0)
2971 main_info
.joy_enabled
= 0;
2972 else if (stricmp(argv
[c1
], "-fireworks") == 0)
2973 main_info
.fireworks
= 1;
2975 else if (stricmp(argv
[c1
], "-fullscreen") == 0)
2978 else if (stricmp(argv
[c1
], "-scaleup") == 0)
2980 else if (stricmp(argv
[c1
], "-mirror") == 0)
2982 else if (stricmp(argv
[c1
], "-dat") == 0) {
2983 if (c1
< (argc
- 1)) {
2986 if ((f
= fopen(argv
[c1
+ 1], "rb")) != NULL
) {
2988 strcpy(datfile_name
, argv
[c1
+ 1]);
2991 } else if (stricmp(argv
[c1
], "-player") == 0) {
2992 if (c1
< (argc
- 1)) {
2993 if (client_player_num
< 0)
2994 client_player_num
= atoi(argv
[c1
+ 1]);
2997 } else if (stricmp(argv
[c1
], "-server") == 0) {
2998 if (c1
< (argc
- 1)) {
3001 netarg
= argv
[c1
+ 1];
3003 } else if (stricmp(argv
[c1
], "-connect") == 0) {
3004 if (c1
< (argc
- 1)) {
3007 netarg
= argv
[c1
+ 1];
3010 } else if (stricmp(argv
[c1
], "-mouse") == 0) {
3011 if (c1
< (argc
- 1)) {
3012 if (stricmp(argv
[c1
+ 1], "2") == 0)
3014 if (stricmp(argv
[c1
+ 1], "3") == 0)
3018 else if (strstr(argv
[1],"-v")) {
3019 printf("jumpnbump %s compiled %s at %s with",JNB_VERSION
,__DATE__
,__TIME__
);
3023 printf(" network support.\n");
3026 else if (strstr(argv
[1],"-h")) {
3027 printf("Usage: jumpnbump [OPTION]...\n");
3029 printf(" -h this help\n");
3030 printf(" -v print version\n");
3031 printf(" -dat level.dat play a different level\n");
3033 printf(" -server playercount start as server waiting for players\n");
3034 printf(" -connect host connect to server\n");
3036 printf(" -player num set main player to num (0-3). Needed for networking\n");
3037 printf(" -fireworks screensaver mode\n");
3038 printf(" -fullscreen run in fullscreen mode\n");
3039 printf(" -nosound play without sound\n");
3040 printf(" -nogore play without blood\n");
3041 printf(" -noflies disable flies\n");
3042 printf(" -mirror play with mirrored level\n");
3043 printf(" -scaleup play with doubled resolution (800x512)\n");
3044 printf(" -musicnosound play with music but without sound\n");
3051 preread_datafile(datfile_name
);
3054 /** It should not be necessary to assign a default player number here. The
3055 server assigns one in init_server, the client gets one assigned by the server,
3056 all provided the user didn't choose one on the commandline. */
3058 if (client_player_num
< 0)
3059 client_player_num
= 0;
3060 player
[client_player_num
].enabled
= 1;
3064 main_info
.pob_backbuf
[0] = malloc(screen_pitch
*screen_height
);
3065 main_info
.pob_backbuf
[1] = malloc(screen_pitch
*screen_height
);
3067 for (c1
= 0; c1
< 7; c1
++) {
3068 player_anims
[c1
].num_frames
= player_anim_data
[c1
* 10];
3069 player_anims
[c1
].restart_frame
= player_anim_data
[c1
* 10 + 1];
3070 for (c2
= 0; c2
< 4; c2
++) {
3071 player_anims
[c1
].frame
[c2
].image
= player_anim_data
[c1
* 10 + c2
* 2 + 2];
3072 player_anims
[c1
].frame
[c2
].ticks
= player_anim_data
[c1
* 10 + c2
* 2 + 3];
3076 if ((handle
= dat_open("menu.pcx")) == 0) {
3077 strcpy(main_info
.error_str
, "Error loading 'menu.pcx', aborting...\n");
3080 if (read_pcx(handle
, background_pic
, JNB_WIDTH
*JNB_HEIGHT
, pal
) != 0) {
3081 strcpy(main_info
.error_str
, "Error loading 'menu.pcx', aborting...\n");
3085 if ((handle
= dat_open("rabbit.gob")) == 0) {
3086 strcpy(main_info
.error_str
, "Error loading 'rabbit.gob', aborting...\n");
3089 if (register_gob(handle
, &rabbit_gobs
, dat_filelen("rabbit.gob"))) {
3094 if ((handle
= dat_open("objects.gob")) == 0) {
3095 strcpy(main_info
.error_str
, "Error loading 'objects.gob', aborting...\n");
3098 if (register_gob(handle
, &object_gobs
, dat_filelen("objects.gob"))) {
3103 if ((handle
= dat_open("font.gob")) == 0) {
3104 strcpy(main_info
.error_str
, "Error loading 'font.gob', aborting...\n");
3107 if (register_gob(handle
, &font_gobs
, dat_filelen("font.gob"))) {
3112 if ((handle
= dat_open("numbers.gob")) == 0) {
3113 strcpy(main_info
.error_str
, "Error loading 'numbers.gob', aborting...\n");
3116 if (register_gob(handle
, &number_gobs
, dat_filelen("numbers.gob"))) {
3121 if (read_level() != 0) {
3122 strcpy(main_info
.error_str
, "Error loading 'levelmap.txt', aborting...\n");
3128 if (main_info
.no_sound
== 0) {
3130 dj_set_mixing_freq(20000);
3134 dj_set_num_sfx_channels(5);
3135 dj_set_sfx_volume(64);
3139 if ((handle
= dat_open("jump.mod")) == 0) {
3140 strcpy(main_info
.error_str
, "Error loading 'jump.mod', aborting...\n");
3143 if (dj_load_mod(handle
, 0, MOD_MENU
) != 0) {
3144 strcpy(main_info
.error_str
, "Error loading 'jump.mod', aborting...\n");
3148 if ((handle
= dat_open("bump.mod")) == 0) {
3149 strcpy(main_info
.error_str
, "Error loading 'bump.mod', aborting...\n");
3152 if (dj_load_mod(handle
, 0, MOD_GAME
) != 0) {
3153 strcpy(main_info
.error_str
, "Error loading 'bump.mod', aborting...\n");
3157 if ((handle
= dat_open("scores.mod")) == 0) {
3158 strcpy(main_info
.error_str
, "Error loading 'scores.mod', aborting...\n");
3161 if (dj_load_mod(handle
, 0, MOD_SCORES
) != 0) {
3162 strcpy(main_info
.error_str
, "Error loading 'scores.mod', aborting...\n");
3166 if ((handle
= dat_open("jump.smp")) == 0) {
3167 strcpy(main_info
.error_str
, "Error loading 'jump.smp', aborting...\n");
3170 if (dj_load_sfx(handle
, 0, dat_filelen("jump.smp"), DJ_SFX_TYPE_SMP
, SFX_JUMP
) != 0) {
3171 strcpy(main_info
.error_str
, "Error loading 'jump.smp', aborting...\n");
3175 if ((handle
= dat_open("death.smp")) == 0) {
3176 strcpy(main_info
.error_str
, "Error loading 'death.smp', aborting...\n");
3179 if (dj_load_sfx(handle
, 0, dat_filelen("death.smp"), DJ_SFX_TYPE_SMP
, SFX_DEATH
) != 0) {
3180 strcpy(main_info
.error_str
, "Error loading 'death.smp', aborting...\n");
3184 if ((handle
= dat_open("spring.smp")) == 0) {
3185 strcpy(main_info
.error_str
, "Error loading 'spring.smp', aborting...\n");
3188 if (dj_load_sfx(handle
, 0, dat_filelen("spring.smp"), DJ_SFX_TYPE_SMP
, SFX_SPRING
) != 0) {
3189 strcpy(main_info
.error_str
, "Error loading 'spring.smp', aborting...\n");
3193 if ((handle
= dat_open("splash.smp")) == 0) {
3194 strcpy(main_info
.error_str
, "Error loading 'splash.smp', aborting...\n");
3197 if (dj_load_sfx(handle
, 0, dat_filelen("splash.smp"), DJ_SFX_TYPE_SMP
, SFX_SPLASH
) != 0) {
3198 strcpy(main_info
.error_str
, "Error loading 'splash.smp', aborting...\n");
3202 if ((handle
= dat_open("fly.smp")) == 0) {
3203 strcpy(main_info
.error_str
, "Error loading 'fly.smp', aborting...\n");
3206 if (dj_load_sfx(handle
, 0, dat_filelen("fly.smp"), DJ_SFX_TYPE_SMP
, SFX_FLY
) != 0) {
3207 strcpy(main_info
.error_str
, "Error loading 'fly.smp', aborting...\n");
3211 dj_get_sfx_settings(SFX_FLY
, &fly
);
3213 fly
.default_freq
= SFX_FLY_FREQ
;
3216 fly
.loop_length
= fly
.length
;
3217 dj_set_sfx_settings(SFX_FLY
, &fly
);
3220 if ((background_pic
= malloc(JNB_WIDTH
*JNB_HEIGHT
)) == NULL
)
3222 if ((mask_pic
= malloc(JNB_WIDTH
*JNB_HEIGHT
)) == NULL
)
3224 memset(mask_pic
, 0, JNB_WIDTH
*JNB_HEIGHT
);
3225 register_mask(mask_pic
);
3228 for (c1
= 0; c1
< 16; c1
++) {
3229 pal
[(240 + c1
) * 3 + 0] = c1
<< 2;
3230 pal
[(240 + c1
) * 3 + 1] = c1
<< 2;
3231 pal
[(240 + c1
) * 3 + 2] = c1
<< 2;
3234 setpalette(0, 256, pal
);
3238 recalculate_gob(&font_gobs
, pal
);
3240 if (main_info
.joy_enabled
== 1 && main_info
.fireworks
== 0) {
3242 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
3243 put_text(0, 200, 100, "Move the joystick to the", 2);
3244 put_text(0, 200, 115, "UPPER LEFT", 2);
3245 put_text(0, 200, 130, "and press button A", 2);
3246 put_text(0, 200, 200, "Or press ESC to use", 2);
3247 put_text(0, 200, 215, "previous settings", 2);
3248 if (calib_joy(0) != 0)
3251 register_background(NULL
, NULL
);
3253 main_info
.view_page
= 1;
3258 put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
3259 put_text(1, 200, 100, "Move the joystick to the", 2);
3260 put_text(1, 200, 115, "LOWER RIGHT", 2);
3261 put_text(1, 200, 130, "and press button A", 2);
3262 put_text(1, 200, 200, "Or press ESC to use", 2);
3263 put_text(1, 200, 215, "previous settings", 2);
3264 if (calib_joy(1) != 0)
3267 register_background(NULL
, NULL
);
3272 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
3273 put_text(0, 200, 100, "Move the joystick to the", 2);
3274 put_text(0, 200, 115, "CENTER", 2);
3275 put_text(0, 200, 130, "and press button A", 2);
3276 put_text(0, 200, 200, "Or press ESC to use", 2);
3277 put_text(0, 200, 215, "previous settings", 2);
3278 if (calib_joy(2) != 0)
3281 if (joy
.calib_data
.x1
== joy
.calib_data
.x2
)
3282 joy
.calib_data
.x1
-= 10;
3283 if (joy
.calib_data
.x3
== joy
.calib_data
.x2
)
3284 joy
.calib_data
.x3
+= 10;
3285 if (joy
.calib_data
.y1
== joy
.calib_data
.y2
)
3286 joy
.calib_data
.y1
-= 10;
3287 if (joy
.calib_data
.y3
== joy
.calib_data
.y2
)
3288 joy
.calib_data
.y3
+= 10;
3293 if (load_flag
== 1) {
3294 if ((handle
= dat_open("calib.dat")) == 0) {
3295 strcpy(main_info
.error_str
, "Error loading 'calib.dat', aborting...\n");
3298 joy
.calib_data
.x1
= (handle
[0]) + (handle
[1] << 8) + (handle
[2] << 16) + (handle
[3] << 24); handle
+= 4;
3299 joy
.calib_data
.x2
= (handle
[0]) + (handle
[1] << 8) + (handle
[2] << 16) + (handle
[3] << 24); handle
+= 4;
3300 joy
.calib_data
.x3
= (handle
[0]) + (handle
[1] << 8) + (handle
[2] << 16) + (handle
[3] << 24); handle
+= 4;
3301 joy
.calib_data
.y1
= (handle
[0]) + (handle
[1] << 8) + (handle
[2] << 16) + (handle
[3] << 24); handle
+= 4;
3302 joy
.calib_data
.y2
= (handle
[0]) + (handle
[1] << 8) + (handle
[2] << 16) + (handle
[3] << 24); handle
+= 4;
3303 joy
.calib_data
.y3
= (handle
[0]) + (handle
[1] << 8) + (handle
[2] << 16) + (handle
[3] << 24); handle
+= 4;
3310 init_server(netarg
);
3312 connect_to_server(netarg
);
3321 void deinit_program(void)
3330 dj_free_mod(MOD_MENU
);
3331 dj_free_mod(MOD_GAME
);
3332 dj_free_sfx(SFX_DEATH
);
3333 dj_free_sfx(SFX_SPRING
);
3334 dj_free_sfx(SFX_SPLASH
);
3337 if (background_pic
!= 0)
3338 free(background_pic
);
3342 remove_keyb_handler();
3346 __dpmi_int(0x10, ®s
);
3349 if (main_info
.error_str
[0] != 0) {
3350 printf(main_info
.error_str
);
3352 MessageBox(0, main_info
.error_str
, "Jump'n'Bump", 0);
3361 unsigned short rnd(unsigned short max
)
3363 #if (RAND_MAX < 0x7fff)
3364 #error "rand returns too small values"
3365 #elif (RAND_MAX == 0x7fff)
3366 return (unsigned short)((rand()*2) % (int)max
);
3368 return (unsigned short)(rand() % (int)max
);
3373 int read_level(void)
3375 unsigned char *handle
;
3379 if ((handle
= dat_open("levelmap.txt")) == 0) {
3380 strcpy(main_info
.error_str
, "Error loading 'levelmap.txt', aborting...\n");
3384 for (c1
= 0; c1
< 16; c1
++) {
3385 for (c2
= 0; c2
< 22; c2
++) {
3387 chr
= (int) *(handle
++);
3388 if (chr
>= '0' && chr
<= '4')
3392 ban_map
[c1
][21-c2
] = chr
- '0';
3394 ban_map
[c1
][c2
] = chr
- '0';
3398 for (c2
= 0; c2
< 22; c2
++)
3399 ban_map
[16][c2
] = BAN_SOLID
;
3406 unsigned char *dat_open(char *file_name
)
3414 if (datafile_buffer
== NULL
)
3417 memset(name
, 0, sizeof(name
));
3419 num
= ( (datafile_buffer
[0] << 0) +
3420 (datafile_buffer
[1] << 8) +
3421 (datafile_buffer
[2] << 16) +
3422 (datafile_buffer
[3] << 24) );
3424 ptr
= datafile_buffer
+ 4;
3426 for (c1
= 0; c1
< num
; c1
++) {
3428 memcpy(name
, ptr
, 12);
3431 if (strnicmp(name
, file_name
, strlen(file_name
)) == 0) {
3432 ofs
= ( (ptr
[0] << 0) +
3437 return (datafile_buffer
+ ofs
);
3446 int dat_filelen(char *file_name
)
3454 memset(name
, 0, sizeof(name
));
3456 num
= ( (datafile_buffer
[0] << 0) +
3457 (datafile_buffer
[1] << 8) +
3458 (datafile_buffer
[2] << 16) +
3459 (datafile_buffer
[3] << 24) );
3461 ptr
= datafile_buffer
+ 4;
3463 for (c1
= 0; c1
< num
; c1
++) {
3465 memcpy(name
, ptr
, 12);
3468 if (strnicmp(name
, file_name
, strlen(file_name
)) == 0) {
3471 len
= ( (ptr
[0] << 0) +
3485 void write_calib_data(void)
3493 if ((handle
= fopen(datfile_name
, "rb")) == NULL
)
3495 len
= filelength(fileno(handle
));
3496 if ((mem
= malloc(len
)) == NULL
)
3498 fread(mem
, 1, len
, handle
);
3502 num
= *(int *) (&mem
[0]);
3503 for (c1
= 0; c1
< num
; c1
++) {
3504 if (strnicmp(&mem
[ofs
], "calib.dat", strlen("calib.dat")) == 0) {
3505 ofs
= *(int *) (&mem
[ofs
+ 12]);
3511 mem
[ofs
] = joy
.calib_data
.x1
& 0xff;
3512 mem
[ofs
+ 1] = (joy
.calib_data
.x1
>> 8) & 0xff;
3513 mem
[ofs
+ 2] = (joy
.calib_data
.x1
>> 16) & 0xff;
3514 mem
[ofs
+ 3] = (joy
.calib_data
.x1
>> 24) & 0xff;
3515 mem
[ofs
+ 4] = joy
.calib_data
.x2
& 0xff;
3516 mem
[ofs
+ 5] = (joy
.calib_data
.x2
>> 8) & 0xff;
3517 mem
[ofs
+ 6] = (joy
.calib_data
.x2
>> 16) & 0xff;
3518 mem
[ofs
+ 7] = (joy
.calib_data
.x2
>> 24) & 0xff;
3519 mem
[ofs
+ 8] = joy
.calib_data
.x3
& 0xff;
3520 mem
[ofs
+ 9] = (joy
.calib_data
.x3
>> 8) & 0xff;
3521 mem
[ofs
+ 10] = (joy
.calib_data
.x3
>> 16) & 0xff;
3522 mem
[ofs
+ 11] = (joy
.calib_data
.x3
>> 24) & 0xff;
3523 mem
[ofs
+ 12] = joy
.calib_data
.y1
& 0xff;
3524 mem
[ofs
+ 13] = (joy
.calib_data
.y1
>> 8) & 0xff;
3525 mem
[ofs
+ 14] = (joy
.calib_data
.y1
>> 16) & 0xff;
3526 mem
[ofs
+ 15] = (joy
.calib_data
.y1
>> 24) & 0xff;
3527 mem
[ofs
+ 16] = joy
.calib_data
.y2
& 0xff;
3528 mem
[ofs
+ 17] = (joy
.calib_data
.y2
>> 8) & 0xff;
3529 mem
[ofs
+ 18] = (joy
.calib_data
.y2
>> 16) & 0xff;
3530 mem
[ofs
+ 19] = (joy
.calib_data
.y2
>> 24) & 0xff;
3531 mem
[ofs
+ 20] = joy
.calib_data
.y3
& 0xff;
3532 mem
[ofs
+ 21] = (joy
.calib_data
.y3
>> 8) & 0xff;
3533 mem
[ofs
+ 22] = (joy
.calib_data
.y3
>> 16) & 0xff;
3534 mem
[ofs
+ 23] = (joy
.calib_data
.y3
>> 24) & 0xff;
3536 if ((handle
= fopen(datfile_name
, "wb")) == NULL
)
3538 fwrite(mem
, 1, len
, handle
);