no message
[crow/jumpnbump.git] / main.c
1 /*
2  * main.c
3  * Copyright (C) 1998 Brainchild Design - http://brainchilddesign.com/
4  * 
5  * Copyright (C) 2001 Chuck Mason <cemason@users.sourceforge.net>
6  *
7  * Copyright (C) 2002 Florian Schulze <crow@icculus.org>
8  *
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.
12  *
13  * This file is part of Jump'n'Bump.
14  *
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.
19  *
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.
24  *
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
28  */
29
30 #include "globals.h"
31 #include <fcntl.h>
32
33 #ifdef USE_NET
34 #include "SDL_net.h"
35 #endif /* USE_NET */
36
37 #ifndef M_PI
38 #define M_PI            3.14159265358979323846
39 #endif
40
41 gob_t rabbit_gobs = { 0 };
42 gob_t font_gobs = { 0 };
43 gob_t object_gobs = { 0 };
44 gob_t number_gobs = { 0 };
45
46 main_info_t main_info;
47 player_t player[JNB_MAX_PLAYERS];
48 player_anim_t player_anims[7];
49 object_t objects[NUM_OBJECTS];
50 joy_t joy;
51 mouse_t mouse;
52
53 char datfile_name[2048];
54
55 char *background_pic;
56 char *mask_pic;
57 int flip = 0;
58
59 unsigned int ban_map[17][22] = {
60         {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
61         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0},
62         {1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
63         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1},
64         {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
65         {1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
66         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1},
67         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
68         {1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
69         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1},
70         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1},
71         {1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1},
72         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
73         {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
74         {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 1, 3, 3, 3, 1, 1, 1},
75         {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
76         {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
77 };
78
79 struct {
80         int num_frames;
81         int restart_frame;
82         struct {
83                 int image;
84                 int ticks;
85         } frame[10];
86 } object_anims[8] = {
87         {
88                 6, 0, {
89                         {
90                         0, 3}, {
91                         1, 3}, {
92                         2, 3}, {
93                         3, 3}, {
94                         4, 3}, {
95                         5, 3}, {
96                         0, 0}, {
97                         0, 0}, {
98                         0, 0}, {
99                         0, 0}
100                 }
101         }, {
102                 9, 0, {
103                         {
104                         6, 2}, {
105                         7, 2}, {
106                         8, 2}, {
107                         9, 2}, {
108                         10, 2}, {
109                         11, 2}, {
110                         12, 2}, {
111                         13, 2}, {
112                         14, 2}, {
113                         0, 0}
114                 }
115         }, {
116                 5, 0, {
117                         {
118                         15, 3}, {
119                         16, 3}, {
120                         16, 3}, {
121                         17, 3}, {
122                         18, 3}, {
123                         19, 3}, {
124                         0, 0}, {
125                         0, 0}, {
126                         0, 0}, {
127                         0, 0}
128                 }
129         }, {
130                 10, 0, {
131                         {
132                         20, 2}, {
133                         21, 2}, {
134                         22, 2}, {
135                         23, 2}, {
136                         24, 2}, {
137                         25, 2}, {
138                         24, 2}, {
139                         23, 2}, {
140                         22, 2}, {
141                         21, 2}
142                 }
143         }, {
144                 10, 0, {
145                         {
146                         26, 2}, {
147                         27, 2}, {
148                         28, 2}, {
149                         29, 2}, {
150                         30, 2}, {
151                         31, 2}, {
152                         30, 2}, {
153                         29, 2}, {
154                         28, 2}, {
155                         27, 2}
156                 }
157         }, {
158                 10, 0, {
159                         {
160                         32, 2}, {
161                         33, 2}, {
162                         34, 2}, {
163                         35, 2}, {
164                         36, 2}, {
165                         37, 2}, {
166                         36, 2}, {
167                         35, 2}, {
168                         34, 2}, {
169                         33, 2}
170                 }
171         }, {
172                 10, 0, {
173                         {
174                         38, 2}, {
175                         39, 2}, {
176                         40, 2}, {
177                         41, 2}, {
178                         42, 2}, {
179                         43, 2}, {
180                         42, 2}, {
181                         41, 2}, {
182                         40, 2}, {
183                         39, 2}
184                 }
185         }, {
186                 4, 0, {
187                         {
188                         76, 4}, {
189                         77, 4}, {
190                         78, 4}, {
191                         79, 4}, {
192                         0, 0}, {
193                         0, 0}, {
194                         0, 0}, {
195                         0, 0}, {
196                         0, 0}, {
197                         0, 0}
198                 }
199         }
200 };
201
202 int flies_enabled = 1;
203
204 struct {
205         int x, y;
206         int old_x, old_y;
207         int old_draw_x, old_draw_y;
208         int back[2];
209         int back_defined[2];
210 } flies[NUM_FLIES];
211
212 struct {
213         struct {
214                 short num_pobs;
215                 struct {
216                         int x, y;
217                         int image;
218                         gob_t *pob_data;
219                 } pobs[NUM_LEFTOVERS];
220         } page[2];
221 } leftovers;
222
223 int pogostick, bunnies_in_space, jetpack, lord_of_the_flies, blood_is_thicker_than_water;
224
225
226 #ifndef _MSC_VER
227 int filelength(int handle)
228 {
229         struct stat buf;
230
231         if (fstat(handle, &buf) == -1) {
232                 perror("filelength");
233                 exit(EXIT_FAILURE);
234         }
235
236         return buf.st_size;
237 }
238 #endif
239
240
241 /* networking shite. */
242
243 int client_player_num = -1;
244 int is_server = 1;
245 int is_net = 0;
246
247 #ifdef USE_NET
248 TCPsocket sock = NULL;
249 SDLNet_SocketSet socketset = NULL;
250
251 typedef struct
252 {
253         TCPsocket sock;
254         IPaddress addr;
255         SDLNet_SocketSet socketset;
256 } NetInfo;
257
258 NetInfo net_info[JNB_MAX_PLAYERS];
259 #endif
260
261 typedef struct
262 {
263         unsigned long cmd;
264         long arg;
265         long arg2;
266         long arg3;
267         long arg4;
268 } NetPacket;
269
270 #define NETPKTBUFSIZE (4 + 4 + 4 + 4 + 4)
271
272 #define NETCMD_NACK         (0xF00DF00D + 0)
273 #define NETCMD_ACK          (0xF00DF00D + 1)
274 #define NETCMD_HELLO        (0xF00DF00D + 2)
275 #define NETCMD_GREENLIGHT   (0xF00DF00D + 3)
276 #define NETCMD_MOVE         (0xF00DF00D + 4)
277 #define NETCMD_BYE          (0xF00DF00D + 5)
278 #define NETCMD_POSITION     (0xF00DF00D + 6)
279 #define NETCMD_ALIVE        (0xF00DF00D + 7)
280 #define NETCMD_KILL         (0xF00DF00D + 8)
281
282
283 #ifdef USE_NET
284 void bufToPacket(const char *buf, NetPacket *pkt)
285 {
286         SDLNet_Write32(*((unsigned long *) (buf +  0)), &pkt->cmd);
287         SDLNet_Write32(*((unsigned long *) (buf +  4)), &pkt->arg);
288         SDLNet_Write32(*((unsigned long *) (buf +  8)), &pkt->arg2);
289         SDLNet_Write32(*((unsigned long *) (buf + 12)), &pkt->arg3);
290         SDLNet_Write32(*((unsigned long *) (buf + 16)), &pkt->arg4);
291 /*
292         pkt->cmd               =        ntohl(*((unsigned long *) (buf +  0)));
293         pkt->arg               = (long) ntohl(*((unsigned long *) (buf +  4)));
294         pkt->arg2              = (long) ntohl(*((unsigned long *) (buf +  8)));
295         pkt->arg3              = (long) ntohl(*((unsigned long *) (buf + 12)));
296         pkt->arg4              = (long) ntohl(*((unsigned long *) (buf + 16)));
297 */
298 }
299
300
301 void packetToBuf(const NetPacket *pkt, char *buf)
302 {
303         *((unsigned long *) (buf +  0)) = SDLNet_Read32(&pkt->cmd);
304         *((unsigned long *) (buf +  4)) = SDLNet_Read32(&pkt->arg);
305         *((unsigned long *) (buf +  8)) = SDLNet_Read32(&pkt->arg2);
306         *((unsigned long *) (buf + 12)) = SDLNet_Read32(&pkt->arg3);
307         *((unsigned long *) (buf + 16)) = SDLNet_Read32(&pkt->arg4);
308 /*
309         *((unsigned long *) (buf +  0)) = htonl(pkt->cmd);
310         *((unsigned long *) (buf +  4)) = htonl((unsigned long) pkt->arg);
311         *((unsigned long *) (buf +  8)) = htonl((unsigned long) pkt->arg2);
312         *((unsigned long *) (buf + 12)) = htonl((unsigned long) pkt->arg3);
313         *((unsigned long *) (buf + 16)) = htonl((unsigned long) pkt->arg4);
314 */
315 }
316
317
318 void sendPacketToSock(TCPsocket s, NetPacket *pkt)
319 {
320         int bytes_left = NETPKTBUFSIZE;
321         int bw;
322         char buf[NETPKTBUFSIZE];
323         char *ptr = buf;
324
325         packetToBuf(pkt, buf);
326         while (bytes_left > 0) {
327                 bw = SDLNet_TCP_Send(s, ptr, bytes_left);
328                 if (bw < 0) {
329                         fprintf(stderr, "SERVER: SDLNet_TCP_Send(): %s\n", SDLNet_GetError());
330                         SDLNet_TCP_Close(s);
331                         exit(42);
332                 } else if (bw == 0) {
333                         SDL_Delay(1);
334                 } else {
335                         bytes_left -= bw;
336                         ptr += bw;
337                 }
338         }
339 }
340
341
342 void sendPacket(int playerid, NetPacket *pkt)
343 {
344         if ( playerid < JNB_MAX_PLAYERS ) {
345                 if ((player[playerid].enabled) && (playerid != client_player_num)) {
346                         sendPacketToSock(net_info[playerid].sock, pkt);
347                 }
348         }
349 }
350
351
352 void sendPacketToAll(NetPacket *pkt)
353 {
354         int i;
355
356         for (i = 0; i < JNB_MAX_PLAYERS; i++) {
357                 sendPacket(i, pkt);
358         }
359 }
360
361
362 int grabPacket(TCPsocket s, SDLNet_SocketSet ss, NetPacket *pkt)
363 {
364         static char buf[NETPKTBUFSIZE];
365         static int buf_count = 0;
366         int rc;
367         int retval = 0;
368
369         if (SDLNet_CheckSockets(ss, 0) > 0) {
370                 rc = SDLNet_TCP_Recv(s, &buf[buf_count], NETPKTBUFSIZE - buf_count);
371                 if (rc <= 0) {  /* closed connection? */
372                         retval = -1;
373                 } else if (rc != NETPKTBUFSIZE) {
374                         buf_count = rc;
375                 } else {
376                         buf_count = 0;
377                         bufToPacket(buf, pkt);
378                         retval = 1;
379                 }
380         }
381
382         return(retval);
383 }
384
385
386 int serverRecvPacket(NetPacket *pkt)
387 {
388         int rc;
389         int i;
390
391         assert(is_server);
392
393         for (i = 0; i < JNB_MAX_PLAYERS; i++) {
394                 TCPsocket s = net_info[i].sock;
395
396                 if ((i == client_player_num) || (!player[i].enabled))
397                         continue;
398
399                 rc = grabPacket(s, net_info[i].socketset, pkt);
400                 if (rc < 0) {
401                         NetPacket pkt;
402
403                         player[i].enabled = 0;
404                         SDLNet_TCP_Close(s);
405                         pkt.cmd = NETCMD_BYE;
406                         pkt.arg = i;
407                         pkt.arg2 = 0;
408                         pkt.arg3 = 0;
409                         pkt.arg4 = 0;
410                         sendPacketToAll(&pkt);
411                 } else if (rc > 0) {
412                         return(i);  /* it's all good. */
413                 }
414         }
415
416         return(-1);  /* no packets available currently. */
417 }
418
419
420 void wait_for_greenlight(void)
421 {
422         NetPacket pkt;
423         int i;
424
425         printf("CLIENT: Waiting for greenlight...\n");
426
427         do {
428                 int rc;
429                 while ((rc = grabPacket(sock, socketset, &pkt)) == 0) {
430                         SDL_Delay(100);  /* nap and then try again. */
431                 }
432
433                 if (rc < 0) {
434                         printf("CLIENT: Lost connection.\n");
435                         SDLNet_TCP_Close(sock);
436                         exit(42);
437                 }
438         } while (pkt.cmd != NETCMD_GREENLIGHT);
439
440         printf("CLIENT: Got greenlight.\n");
441
442         for (i = 0; i < JNB_MAX_PLAYERS; i++) {
443                 if (pkt.arg & (1 << i)) {
444                         printf("CLIENT: There is a player #%d.\n", i);
445                         player[i].enabled = 1;
446                 }
447         }
448 }
449
450
451 static int buggered_off = 0;
452
453
454 void tellServerGoodbye(void)
455 {
456         NetPacket pkt;
457
458         if (!buggered_off) {
459                 buggered_off = 1;
460                 pkt.cmd = NETCMD_BYE;
461                 pkt.arg = client_player_num;
462                 pkt.arg2 = 0;
463                 pkt.arg3 = 0;
464                 pkt.arg4 = 0;
465                 sendPacketToSock(sock, &pkt);
466         }
467 }
468 #endif /* USE_NET */
469
470
471 void processMovePacket(NetPacket *pkt)
472 {
473         int playerid = pkt->arg;
474         int movetype = ((pkt->arg2 >> 16) & 0xFF);
475         int newval   = ((pkt->arg2 >>  0) & 0xFF);
476
477         if (movetype == MOVEMENT_LEFT) {
478                 player[playerid].action_left = newval;
479         } else if (movetype == MOVEMENT_RIGHT) {
480                 player[playerid].action_right = newval;
481         } else if (movetype == MOVEMENT_UP) {
482                 player[playerid].action_up = newval;
483         } else {
484                 printf("bogus MOVE packet!\n");
485         }
486
487         player[playerid].x = pkt->arg3;
488         player[playerid].y = pkt->arg4;
489 }
490
491
492 void tellServerPlayerMoved(int playerid, int movement_type, int newval)
493 {
494         NetPacket pkt;
495
496         pkt.cmd = NETCMD_MOVE;
497         pkt.arg = playerid;
498         pkt.arg2 = ( ((movement_type & 0xFF) << 16) | ((newval & 0xFF) << 0) );
499         pkt.arg3 = player[playerid].x;
500         pkt.arg4 = player[playerid].y;
501
502         if (is_server) {
503                 processMovePacket(&pkt);
504 #ifdef USE_NET
505                 if (is_net)
506                         sendPacketToAll(&pkt);
507         } else {
508                 sendPacketToSock(sock, &pkt);
509 #endif
510         }
511 }
512
513
514 #ifdef USE_NET
515 void tellServerNewPosition(void)
516 {
517         NetPacket pkt;
518         pkt.cmd = NETCMD_POSITION;
519         pkt.arg = client_player_num;
520         pkt.arg2 = player[client_player_num].x;
521         pkt.arg3 = player[client_player_num].y;
522
523         if (is_server) {
524                 sendPacketToAll(&pkt);
525         } else {
526                 sendPacketToSock(sock, &pkt);
527         }
528 }
529 #endif /* USE_NET */
530
531
532 void processKillPacket(NetPacket *pkt)
533 {
534         int c1 = pkt->arg;
535         int c2 = pkt->arg2;
536         int x = pkt->arg3;
537         int y = pkt->arg4;
538         int c4 = 0;
539         int s1 = 0;
540
541         player[c1].y_add = -player[c1].y_add;
542         if (player[c1].y_add > -262144L)
543                 player[c1].y_add = -262144L;
544         player[c1].jump_abort = 1;
545         player[c2].dead_flag = 1;
546         if (player[c2].anim != 6) {
547                 player[c2].anim = 6;
548                 player[c2].frame = 0;
549                 player[c2].frame_tick = 0;
550                 player[c2].image = player_anims[player[c2].anim].frame[player[c2].frame].image + player[c2].direction * 9;
551                 if (main_info.no_gore == 0) {
552                         for (c4 = 0; c4 < 6; c4++)
553                                 add_object(OBJ_FUR, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 44 + c2 * 8);
554                         for (c4 = 0; c4 < 6; c4++)
555                                 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 76);
556                         for (c4 = 0; c4 < 6; c4++)
557                                 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 77);
558                         for (c4 = 0; c4 < 8; c4++)
559                                 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 78);
560                         for (c4 = 0; c4 < 10; c4++)
561                                 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 79);
562                 }
563                 dj_play_sfx(SFX_DEATH, (unsigned short)(SFX_DEATH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
564                 player[c1].bumps++;
565                 player[c1].bumped[c2]++;
566                 s1 = player[c1].bumps % 100;
567                 add_leftovers(0, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
568                 add_leftovers(1, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
569                 add_leftovers(0, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
570                 add_leftovers(1, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
571         }
572 }
573
574
575 #ifdef USE_NET
576 void processPositionPacket(NetPacket *pkt)
577 {
578         int playerid = pkt->arg;
579
580         player[playerid].x = pkt->arg2;
581         player[playerid].y = pkt->arg3;
582 }
583
584
585 void processAlivePacket(NetPacket *pkt)
586 {
587         int playerid = pkt->arg;
588
589         player[playerid].dead_flag = 0;
590         player[playerid].x = pkt->arg2;
591         player[playerid].y = pkt->arg3;
592 }
593
594
595 void serverTellEveryoneGoodbye(void)
596 {
597         int i;
598
599         if (!buggered_off) {
600                 buggered_off = 1;
601                 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
602                         if (player[i].enabled) {
603                                 NetPacket pkt;
604
605                                 pkt.cmd = NETCMD_BYE;
606                                 pkt.arg = i;
607                                 pkt.arg2 = 0;
608                                 pkt.arg3 = 0;
609                                 pkt.arg4 = 0;
610                                 sendPacketToAll(&pkt);
611                         }
612                 }
613         }
614 }
615
616
617 int server_said_bye = 0;
618
619
620 int update_players_from_server(void)
621 {
622         NetPacket pkt;
623         int rc;
624
625         assert(!is_server);
626
627         while ((rc = grabPacket(sock, socketset, &pkt)) != 0) {
628                 if (rc < 0) {
629                         printf("CLIENT: Lost connection.\n");
630                         pkt.cmd = NETCMD_BYE;
631                         pkt.arg = client_player_num;
632                 }
633
634                 if (pkt.cmd == NETCMD_BYE) {
635                         if (pkt.arg == client_player_num) {
636                                 SDLNet_FreeSocketSet(socketset);
637                                 SDLNet_TCP_Close(sock);
638                                 sock = NULL;
639                                 server_said_bye = 1;
640                                 return(0);
641                         } else {
642                                 player[pkt.arg].enabled = 0;
643                         }
644                 } else if (pkt.cmd == NETCMD_MOVE) {
645                         processMovePacket(&pkt);
646                 } else if (pkt.cmd == NETCMD_ALIVE) {
647                         processAlivePacket(&pkt);
648                 } else if (pkt.cmd == NETCMD_POSITION) {
649                         processPositionPacket(&pkt);
650                 } else if (pkt.cmd == NETCMD_KILL) {
651                         processKillPacket(&pkt);
652                 } else {
653                         printf("CLIENT: Got an unknown packet: 0x%lX.\n", pkt.cmd);
654                 }
655         }
656
657         return(1);
658 }
659
660
661 void serverSendAlive(int playerid)
662 {
663         NetPacket pkt;
664
665         assert(is_server);
666         pkt.cmd = NETCMD_ALIVE;
667         pkt.arg = playerid;
668         pkt.arg2 = player[playerid].x;
669         pkt.arg3 = player[playerid].y;
670         sendPacketToAll(&pkt);
671 }
672 #endif /* USE_NET */
673
674
675 void serverSendKillPacket(int killer, int victim)
676 {
677         NetPacket pkt;
678
679         assert(is_server);
680         pkt.cmd = NETCMD_KILL;
681         pkt.arg = killer;
682         pkt.arg2 = victim;
683         pkt.arg3 = player[victim].x;
684         pkt.arg4 = player[victim].y;
685         processKillPacket(&pkt);
686 #ifdef USE_NET
687         if (is_net)
688                 sendPacketToAll(&pkt);
689 #endif
690 }
691
692
693 #ifdef USE_NET
694 void update_players_from_clients(void)
695 {
696         int i;
697         NetPacket pkt;
698         int playerid;
699
700         assert(is_server);
701
702         while ((playerid = serverRecvPacket(&pkt)) >= 0) {
703                 if (pkt.cmd == NETCMD_BYE) {
704                         pkt.arg = playerid;  /* just in case. */
705                         sendPacketToAll(&pkt);
706                         player[playerid].enabled = 0;
707                         SDLNet_FreeSocketSet(net_info[playerid].socketset);
708                         SDLNet_TCP_Close(net_info[playerid].sock);
709                 } else if (pkt.cmd == NETCMD_POSITION) {
710                         pkt.arg = playerid;  /* just in case. */
711                         processPositionPacket(&pkt);
712                         for (i = 0; i < JNB_MAX_PLAYERS; i++) {
713                                 if (i != playerid) {
714                                         sendPacket(i, &pkt);
715                                 }
716                         }
717                 } else if (pkt.cmd == NETCMD_MOVE) {
718                         pkt.arg = playerid;  /* just in case. */
719                         /*
720                         pkt.arg3 = player[playerid].x;
721                         pkt.arg4 = player[playerid].y;
722                         */
723                         processMovePacket(&pkt);
724                         sendPacketToAll(&pkt);
725                 } else {
726                         printf("SERVER: Got unknown packet (0x%lX).\n", pkt.cmd);
727                 }
728         }
729 }
730
731
732 void init_server(const char *netarg)
733 {
734         NetPacket pkt;
735         IPaddress addr;
736         int i;
737         int wait_for_clients = ((netarg == NULL) ? 0 : atoi(netarg));
738         char *ipstr;
739
740         if ((wait_for_clients > (JNB_MAX_PLAYERS - 1)) || (wait_for_clients < 0)) {
741                 printf("SERVER: Waiting for bogus client count (%d).\n", wait_for_clients);
742                 exit(42);
743         }
744
745         if (SDLNet_Init() < 0) {
746                 exit(42);
747         }
748         atexit(SDLNet_Quit);
749         
750         SDLNet_ResolveHost(&addr, NULL, JNB_INETPORT);
751         ipstr = SDLNet_ResolveIP(&addr);
752         SDLNet_ResolveHost(&addr, ipstr, JNB_INETPORT);
753         printf("SERVER: we are %s (%i.%i.%i.%i:%i).\n", ipstr, (addr.host >> 0) & 0xff, (addr.host >> 8) & 0xff, (addr.host >> 16) & 0xff, (addr.host >> 24) & 0xff, addr.port);
754         net_info[client_player_num].addr = addr;
755
756         addr.host = INADDR_ANY;
757         sock = SDLNet_TCP_Open(&addr);
758         if (sock == NULL) {
759                 fprintf(stderr, "SERVER: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
760                 exit(42);
761         }
762
763         player[client_player_num].enabled = 1;
764
765         printf("SERVER: waiting for (%d) clients...\n", wait_for_clients);
766
767         socketset = SDLNet_AllocSocketSet(JNB_MAX_PLAYERS + 1);
768         SDLNet_TCP_AddSocket(socketset, sock);
769
770         while (wait_for_clients > 0)
771         {
772                 char buf[NETPKTBUFSIZE];
773                 IPaddress *from;
774                 int negatory = 1;
775                 int br;
776                 TCPsocket s;
777
778                 /* Wait for events */
779                 SDLNet_CheckSockets(socketset, ~0);
780                 if ( SDLNet_SocketReady(sock) ) {
781                         s = SDLNet_TCP_Accept(sock);
782
783                         if (s == NULL)
784                         {
785                                 fprintf(stderr, "SERVER: SDLNet_TCP_Accept(): %s", SDLNet_GetError());
786                                 SDLNet_TCP_Close(sock);
787                                 exit(42);
788                         }
789                 } else
790                         continue;
791
792                 br = SDLNet_TCP_Recv(s, buf, NETPKTBUFSIZE);
793                 if (br < 0) {
794                         fprintf(stderr, "SERVER: SDLNet_TCP_Recv(): %s\n", SDLNet_GetError());
795                         SDLNet_TCP_Close(s);
796                         SDLNet_TCP_Close(sock);
797                         exit(42);
798                 }
799
800                 from = SDLNet_TCP_GetPeerAddress(s);
801                 ipstr = SDLNet_ResolveIP(from);
802                 printf("SERVER: Got data from %s (%i.%i.%i.%i:%i).\n", ipstr, (from->host >> 0) & 0xff, (from->host >> 8) & 0xff, (from->host >> 16) & 0xff, (from->host >> 24) & 0xff, from->port);
803
804                 if (br != NETPKTBUFSIZE) {
805                         printf("SERVER: Bogus packet.\n");
806                         continue;
807                 }
808
809                 bufToPacket(buf, &pkt);
810                 if (pkt.cmd != NETCMD_HELLO) {
811                         printf("SERVER: Bogus packet.\n");
812                         continue;
813                 }
814
815                 printf("SERVER: Client claims to be player #%ld.\n", pkt.arg);
816
817                 if (pkt.arg > JNB_MAX_PLAYERS) {
818                         printf("SERVER:  (that's an invalid player number.)\n");
819                 } else {
820                         if (player[pkt.arg].enabled) {
821                                 printf("SERVER:  (that player number is already taken.)\n");
822                         } else {
823                                 negatory = 0;
824                         }
825                 }
826
827                 if (negatory) {
828                         printf("SERVER: Forbidding connection.\n");
829                         pkt.cmd = NETCMD_NACK;
830                         sendPacketToSock(s, &pkt);
831                         SDLNet_TCP_Close(s);
832                 } else {
833                         player[pkt.arg].enabled = 1;
834                         net_info[pkt.arg].sock = s;
835                         net_info[pkt.arg].addr = *from;
836                         net_info[pkt.arg].socketset = SDLNet_AllocSocketSet(1);
837                         SDLNet_TCP_AddSocket(net_info[pkt.arg].socketset, net_info[pkt.arg].sock);
838                         wait_for_clients--;
839                         printf("SERVER: Granting connection. (%d) to go.\n", wait_for_clients);
840                         pkt.cmd = NETCMD_ACK;
841                         sendPacket(pkt.arg, &pkt);
842                 }
843         }
844
845         SDLNet_TCP_Close(sock);  /* done with the listen socket. */
846         SDLNet_FreeSocketSet(socketset);
847         sock = NULL;
848         socketset = NULL;
849
850         printf("SERVER: Got all our connections. Greenlighting clients...\n");
851
852         pkt.cmd = NETCMD_GREENLIGHT;
853         pkt.arg = 0;
854         for (i = 0; i < JNB_MAX_PLAYERS; i++) {
855                 if (player[i].enabled) {
856                         pkt.arg |= (1 << i);
857                 }
858         }
859         sendPacketToAll(&pkt);
860 }
861
862
863 void connect_to_server(char *netarg)
864 {
865         NetPacket pkt;
866         char buf[NETPKTBUFSIZE];
867         char *ipstr;
868         IPaddress hent;
869         IPaddress addr;
870         int br;
871
872         if (netarg == NULL) {
873                 printf("CLIENT: Need to specify host to connect to.\n");
874                 exit(42);
875         }
876
877         if (SDLNet_Init() < 0) {
878                 exit(42);
879         }
880         atexit(SDLNet_Quit);
881         
882         player[client_player_num].enabled = 1;
883
884         SDLNet_ResolveHost(&addr, NULL, JNB_INETPORT);
885         ipstr = SDLNet_ResolveIP(&addr);
886         SDLNet_ResolveHost(&addr, ipstr, JNB_INETPORT);
887         printf("CLIENT: we are %s (%i.%i.%i.%i:%i).\n", ipstr, (addr.host >> 0) & 0xff, (addr.host >> 8) & 0xff, (addr.host >> 16) & 0xff, (addr.host >> 24) & 0xff, addr.port);
888         net_info[client_player_num].addr = addr;
889
890         if (SDLNet_ResolveHost(&hent, netarg, JNB_INETPORT) < 0) {
891                 fprintf(stderr, "CLIENT: couldn't find host: %s\n", SDLNet_GetError());
892                 exit(42);
893         }
894
895         sock = SDLNet_TCP_Open(&hent);
896         if (sock == NULL) {
897                 fprintf(stderr, "CLIENT: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
898                 exit(42);
899         }
900
901         socketset = SDLNet_AllocSocketSet(1);
902         SDLNet_TCP_AddSocket(socketset, sock);
903
904         printf("CLIENT: connected to %s...\n", SDLNet_ResolveIP(&hent));
905
906         printf("CLIENT: Sending HELLO packet...\n");
907         pkt.cmd = NETCMD_HELLO;
908         pkt.arg = client_player_num;
909         sendPacketToSock(sock, &pkt);
910
911         printf("CLIENT: Waiting for ACK from server...\n");
912
913         br = SDLNet_TCP_Recv(sock, buf, NETPKTBUFSIZE);
914         if (br < 0) {
915                 fprintf(stderr, "CLIENT: recv(): %s\n", SDLNet_GetError());
916                 SDLNet_FreeSocketSet(socketset);
917                 SDLNet_TCP_Close(sock);
918                 exit(42);
919         }
920
921         if (br != NETPKTBUFSIZE) {
922                 printf("CLIENT: Bogus packet size (%d of %d). FIXME.\n", br, NETPKTBUFSIZE);
923                 SDLNet_FreeSocketSet(socketset);
924                 SDLNet_TCP_Close(sock);
925                 exit(42);
926         }
927
928         bufToPacket(buf, &pkt);
929
930         if (pkt.cmd == NETCMD_NACK) {
931                 printf("CLIENT: Server forbid us from playing.\n");
932                 SDLNet_FreeSocketSet(socketset);
933                 SDLNet_TCP_Close(sock);
934                 exit(42);
935         }
936
937         if (pkt.cmd != NETCMD_ACK) {
938                 printf("CLIENT: Unexpected packet (cmd=0x%lX).\n", pkt.cmd);
939                 SDLNet_FreeSocketSet(socketset);
940                 SDLNet_TCP_Close(sock);
941                 exit(42);
942         }
943
944         printf("CLIENT: Server accepted our connection.\n");
945
946         wait_for_greenlight();
947 }
948 #endif /* USE_NET */
949
950
951 static void flip_pixels(unsigned char *pixels)
952 {
953         int x,y;
954         unsigned char temp;
955
956         assert(pixels);
957         for (y = 0; y < JNB_HEIGHT; y++) {
958                 for (x = 0; x < (352/2); x++) {
959                         temp = pixels[y*JNB_WIDTH+x];
960                         pixels[y*JNB_WIDTH+x] = pixels[y*JNB_WIDTH+(352-x)-1];
961                         pixels[y*JNB_WIDTH+(352-x)-1] = temp;
962                 }
963         }
964 }
965
966
967 int main(int argc, char *argv[])
968 {
969         unsigned char *handle;
970         int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
971         int l1;
972         int s1, s2, s3, s4;
973         int closest_player = 0, dist, cur_dist = 0;
974         int end_loop_flag = 0, fade_flag = 0;
975         int mod_vol, sfx_vol, mod_fade_direction;
976         char str1[100];
977         char pal[768];
978         char cur_pal[768];
979         int update_count;
980
981         if (init_program(argc, argv, pal) != 0)
982                 deinit_program();
983
984         if (main_info.fireworks == 1) {
985                 fireworks();
986                 deinit_program();
987         }
988
989         while (1) {
990
991                 if (!is_net)
992                         if (menu() != 0)
993                                 deinit_program();
994
995                 if (key_pressed(1) == 1) {
996                         break;
997                 }
998                 if (init_level(0, pal) != 0) {
999                         deinit_level();
1000                         deinit_program();
1001                 }
1002
1003                 memset(cur_pal, 0, 768);
1004                 setpalette(0, 256, cur_pal);
1005
1006                 recalculate_gob(&rabbit_gobs, pal);
1007                 recalculate_gob(&object_gobs, pal);
1008                 recalculate_gob(&number_gobs, pal);
1009
1010                 flippage(1);
1011                 register_background(background_pic, pal);
1012                 flippage(0);
1013
1014                 if (flies_enabled) {
1015                         s1 = rnd(250) + 50;
1016                         s2 = rnd(150) + 50;
1017
1018                         for (c1 = 0; c1 < NUM_FLIES; c1++) {
1019                                 while (1) {
1020                                         flies[c1].x = s1 + rnd(101) - 50;
1021                                         flies[c1].y = s2 + rnd(101) - 50;
1022                                         if (ban_map[flies[c1].y >> 4][flies[c1].x >> 4] == BAN_VOID)
1023                                                 break;
1024                                 }
1025                                 flies[c1].back_defined[0] = 0;
1026                                 flies[c1].back_defined[1] = 0;
1027                         }
1028                 }
1029
1030                 mod_vol = sfx_vol = 10;
1031                 mod_fade_direction = 1;
1032                 dj_ready_mod(MOD_GAME);
1033                 dj_set_mod_volume((char)mod_vol);
1034                 dj_set_sfx_volume((char)mod_vol);
1035                 dj_start_mod();
1036
1037                 if (flies_enabled)
1038                         dj_play_sfx(SFX_FLY, SFX_FLY_FREQ, 0, 0, 0, 4);
1039
1040                 dj_set_nosound(0);
1041
1042                 lord_of_the_flies = bunnies_in_space = jetpack = pogostick = blood_is_thicker_than_water = 0;
1043                 end_loop_flag = 0;
1044                 main_info.page_info[0].num_pobs = 0;
1045                 main_info.page_info[1].num_pobs = 0;
1046                 main_info.view_page = 0;
1047                 main_info.draw_page = 1;
1048
1049                 update_count = 1;
1050                 while (1) {
1051                         while (update_count) {
1052
1053                                 if (key_pressed(1) == 1) {
1054 #ifdef USE_NET
1055                                         if (is_net) {
1056                                                 if (is_server) {
1057                                                         serverTellEveryoneGoodbye();
1058                                                 } else {
1059                                                         tellServerGoodbye();
1060                                                 }
1061                                         }
1062 #endif
1063                                         end_loop_flag = 1;
1064                                         memset(pal, 0, 768);
1065                                         mod_fade_direction = 0;
1066                                 }
1067
1068                                 if (strncmp(last_keys, "kcitsogop", strlen("kcitsogop")) == 0) {
1069                                         pogostick ^= 1;
1070                                         last_keys[0] = 0;
1071                                 }
1072                                 if (strncmp(last_keys, "ecapsniseinnub", strlen("ecapsniseinnub")) == 0) {
1073                                         bunnies_in_space ^= 1;
1074                                         last_keys[0] = 0;
1075                                 }
1076                                 if (strncmp(last_keys, "kcaptej", strlen("kcaptej")) == 0) {
1077                                         jetpack ^= 1;
1078                                         last_keys[0] = 0;
1079                                 }
1080                                 if (strncmp(last_keys, "seilfehtfodrol", strlen("seilfehtfodrol")) == 0) {
1081                                         lord_of_the_flies ^= 1;
1082                                         last_keys[0] = 0;
1083                                 }
1084                                 if (strncmp(last_keys, "retawnahtrekcihtsidoolb", strlen("retawnahtrekcihtsidoolb")) == 0) {
1085                                         blood_is_thicker_than_water ^= 1;
1086                                         if (blood_is_thicker_than_water == 1) {
1087                                                 pal[432] = 63;
1088                                                 pal[433] = 32;
1089                                                 pal[434] = 32;
1090                                                 pal[435] = 53;
1091                                                 pal[436] = 17;
1092                                                 pal[437] = 17;
1093                                                 pal[438] = 42;
1094                                                 pal[439] = 7;
1095                                                 pal[440] = 7;
1096                                                 pal[441] = 28;
1097                                                 pal[442] = 0;
1098                                                 pal[443] = 0;
1099                                                 pal[444] = 24;
1100                                                 pal[445] = 0;
1101                                                 pal[446] = 0;
1102                                                 pal[447] = 19;
1103                                                 pal[448] = 0;
1104                                                 pal[449] = 0;
1105                                                 pal[450] = 12;
1106                                                 pal[451] = 0;
1107                                                 pal[452] = 0;
1108                                                 pal[453] = 7;
1109                                                 pal[454] = 0;
1110                                                 pal[455] = 0;
1111                                         } else {
1112                                                 pal[432] = 63;
1113                                                 pal[433] = 63;
1114                                                 pal[434] = 63;
1115                                                 pal[435] = 40;
1116                                                 pal[436] = 53;
1117                                                 pal[437] = 62;
1118                                                 pal[438] = 19;
1119                                                 pal[439] = 42;
1120                                                 pal[440] = 60;
1121                                                 pal[441] = 0;
1122                                                 pal[442] = 33;
1123                                                 pal[443] = 60;
1124                                                 pal[444] = 3;
1125                                                 pal[445] = 32;
1126                                                 pal[446] = 46;
1127                                                 pal[447] = 3;
1128                                                 pal[448] = 26;
1129                                                 pal[449] = 33;
1130                                                 pal[450] = 3;
1131                                                 pal[451] = 19;
1132                                                 pal[452] = 21;
1133                                                 pal[453] = 1;
1134                                                 pal[454] = 8;
1135                                                 pal[455] = 8;
1136                                         }
1137                                         register_background(background_pic, pal);
1138                                         recalculate_gob(&object_gobs, pal);
1139                                         last_keys[0] = 0;
1140                                 }
1141
1142 #ifdef USE_NET
1143                                 if (is_net) {
1144                                         if (is_server) {
1145                                                 update_players_from_clients();
1146                                         } else {
1147                                                 if (!update_players_from_server()) {
1148                                                         break;  /* got a BYE packet */
1149                                                 }
1150                                         }
1151                                 }
1152 #endif
1153
1154                                 steer_players();
1155
1156                                 dj_mix();
1157
1158                                 for (c3 = 0; c3 < 6; c3++) {
1159                                         if (c3 == 0) {
1160                                                 c1 = 0;
1161                                                 c2 = 1;
1162                                         } else if (c3 == 1) {
1163                                                 c1 = 0;
1164                                                 c2 = 2;
1165                                         } else if (c3 == 2) {
1166                                                 c1 = 0;
1167                                                 c2 = 3;
1168                                         } else if (c3 == 3) {
1169                                                 c1 = 1;
1170                                                 c2 = 2;
1171                                         } else if (c3 == 4) {
1172                                                 c1 = 1;
1173                                                 c2 = 3;
1174                                         } else if (c3 == 5) {
1175                                                 c1 = 2;
1176                                                 c2 = 3;
1177                                         }
1178                                         if (player[c1].enabled == 1 && player[c2].enabled == 1) {
1179                                                 if (labs(player[c1].x - player[c2].x) < (12L << 16) && labs(player[c1].y - player[c2].y) < (12L << 16)) {
1180                                                         if ((labs(player[c1].y - player[c2].y) >> 16) > 5) {
1181                                                                 if (player[c1].y < player[c2].y) {
1182                                                                         if (player[c1].y_add >= 0) {
1183                                                                                 if (is_server)
1184                                                                                         serverSendKillPacket(c1, c2);
1185                                                                         } else {
1186                                                                                 if (player[c2].y_add < 0)
1187                                                                                         player[c2].y_add = 0;
1188                                                                         }
1189                                                                 } else {
1190                                                                         if (player[c2].y_add >= 0) {
1191                                                                                 if (is_server)
1192                                                                                         serverSendKillPacket(c2, c1);
1193                                                                         } else {
1194                                                                                 if (player[c1].y_add < 0)
1195                                                                                         player[c1].y_add = 0;
1196                                                                         }
1197                                                                 }
1198                                                         } else {
1199                                                                 if (player[c1].x < player[c2].x) {
1200                                                                         if (player[c1].x_add > 0)
1201                                                                                 player[c1].x = player[c2].x - (12L << 16);
1202                                                                         else if (player[c2].x_add < 0)
1203                                                                                 player[c2].x = player[c1].x + (12L << 16);
1204                                                                         else {
1205                                                                                 player[c1].x -= player[c1].x_add;
1206                                                                                 player[c2].x -= player[c2].x_add;
1207                                                                         }
1208                                                                         l1 = player[c2].x_add;
1209                                                                         player[c2].x_add = player[c1].x_add;
1210                                                                         player[c1].x_add = l1;
1211                                                                         if (player[c1].x_add > 0)
1212                                                                                 player[c1].x_add = -player[c1].x_add;
1213                                                                         if (player[c2].x_add < 0)
1214                                                                                 player[c2].x_add = -player[c2].x_add;
1215                                                                 } else {
1216                                                                         if (player[c1].x_add > 0)
1217                                                                                 player[c2].x = player[c1].x - (12L << 16);
1218                                                                         else if (player[c2].x_add < 0)
1219                                                                                 player[c1].x = player[c2].x + (12L << 16);
1220                                                                         else {
1221                                                                                 player[c1].x -= player[c1].x_add;
1222                                                                                 player[c2].x -= player[c2].x_add;
1223                                                                         }
1224                                                                         l1 = player[c2].x_add;
1225                                                                         player[c2].x_add = player[c1].x_add;
1226                                                                         player[c1].x_add = l1;
1227                                                                         if (player[c1].x_add < 0)
1228                                                                                 player[c1].x_add = -player[c1].x_add;
1229                                                                         if (player[c2].x_add > 0)
1230                                                                                 player[c2].x_add = -player[c2].x_add;
1231                                                                 }
1232                                                         }
1233                                                 }
1234                                         }
1235                                 }
1236
1237                                 dj_mix();
1238
1239                                 main_info.page_info[main_info.draw_page].num_pobs = 0;
1240                                 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1241                                         if (player[c1].enabled == 1)
1242                                                 main_info.page_info[main_info.draw_page].num_pobs++;
1243                                 }
1244
1245                                 update_objects();
1246
1247                                 dj_mix();
1248
1249                                 if (flies_enabled) {
1250                                         /* get center of fly swarm */
1251                                         s1 = s2 = 0;
1252                                         for (c1 = 0; c1 < NUM_FLIES; c1++) {
1253                                                 s1 += flies[c1].x;
1254                                                 s2 += flies[c1].y;
1255                                         }
1256                                         s1 /= NUM_FLIES;
1257                                         s2 /= NUM_FLIES;
1258
1259                                         if (update_count == 1) {
1260                                                 /* get closest player to fly swarm */
1261                                                 dist = 0x7fff;
1262                                                 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1263                                                         if (player[c1].enabled == 1) {
1264                                                                 cur_dist = (int)sqrt((s1 - ((player[c1].x >> 16) + 8)) * (s1 - ((player[c1].x >> 16) + 8)) + (s2 - ((player[c1].y >> 16) + 8)) * (s2 - ((player[c1].y >> 16) + 8)));
1265                                                                 if (cur_dist < dist) {
1266                                                                         closest_player = c1;
1267                                                                         dist = cur_dist;
1268                                                                 }
1269                                                         }
1270                                                 }
1271                                                 /* update fly swarm sound */
1272                                                 s3 = 32 - dist / 3;
1273                                                 if (s3 < 0)
1274                                                         s3 = 0;
1275                                                 dj_set_sfx_channel_volume(4, (char)(s3));
1276                                         }
1277
1278                                         for (c1 = 0; c1 < NUM_FLIES; c1++) {
1279                                                 /* get closest player to fly */
1280                                                 dist = 0x7fff;
1281                                                 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
1282                                                         if (player[c2].enabled == 1) {
1283                                                                 cur_dist = (int)sqrt((flies[c1].x - ((player[c2].x >> 16) + 8)) * (flies[c1].x - ((player[c2].x >> 16) + 8)) + (flies[c1].y - ((player[c2].y >> 16) + 8)) * (flies[c1].y - ((player[c2].y >> 16) + 8)));
1284                                                                 if (cur_dist < dist) {
1285                                                                         closest_player = c2;
1286                                                                         dist = cur_dist;
1287                                                                 }
1288                                                         }
1289                                                 }
1290                                                 flies[c1].old_x = flies[c1].x;
1291                                                 flies[c1].old_y = flies[c1].y;
1292                                                 s3 = 0;
1293                                                 if ((s1 - flies[c1].x) > 30)
1294                                                         s3 += 1;
1295                                                 else if ((s1 - flies[c1].x) < -30)
1296                                                         s3 -= 1;
1297                                                 if (dist < 30) {
1298                                                         if (((player[closest_player].x >> 16) + 8) > flies[c1].x) {
1299                                                                 if (lord_of_the_flies == 0)
1300                                                                         s3 -= 1;
1301                                                                 else
1302                                                                         s3 += 1;
1303                                                         } else {
1304                                                                 if (lord_of_the_flies == 0)
1305                                                                         s3 += 1;
1306                                                                 else
1307                                                                         s3 -= 1;
1308                                                         }
1309                                                 }
1310                                                 s4 = rnd(3) - 1 + s3;
1311                                                 if ((flies[c1].x + s4) < 16)
1312                                                         s4 = 0;
1313                                                 if ((flies[c1].x + s4) > 351)
1314                                                         s4 = 0;
1315                                                 if (ban_map[flies[c1].y >> 4][(flies[c1].x + s4) >> 4] != BAN_VOID)
1316                                                         s4 = 0;
1317                                                 flies[c1].x += s4;
1318                                                 s3 = 0;
1319                                                 if ((s2 - flies[c1].y) > 30)
1320                                                         s3 += 1;
1321                                                 else if ((s2 - flies[c1].y) < -30)
1322                                                         s3 -= 1;
1323                                                 if (dist < 30) {
1324                                                         if (((player[closest_player].y >> 16) + 8) > flies[c1].y) {
1325                                                                 if (lord_of_the_flies == 0)
1326                                                                         s3 -= 1;
1327                                                                 else
1328                                                                         s3 += 1;
1329                                                         } else {
1330                                                                 if (lord_of_the_flies == 0)
1331                                                                         s3 += 1;
1332                                                                 else
1333                                                                         s3 -= 1;
1334                                                         }
1335                                                 }
1336                                                 s4 = rnd(3) - 1 + s3;
1337                                                 if ((flies[c1].y + s4) < 0)
1338                                                         s4 = 0;
1339                                                 if ((flies[c1].y + s4) > 239)
1340                                                         s4 = 0;
1341                                                 if (ban_map[(flies[c1].y + s4) >> 4][flies[c1].x >> 4] != BAN_VOID)
1342                                                         s4 = 0;
1343                                                 flies[c1].y += s4;
1344                                         }
1345                                 }
1346
1347                                 dj_mix();
1348
1349                                 s1 = 0;
1350                                 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1351                                         if (player[c1].enabled == 1) {
1352                                                 main_info.page_info[main_info.draw_page].pobs[s1].x = player[c1].x >> 16;
1353                                                 main_info.page_info[main_info.draw_page].pobs[s1].y = player[c1].y >> 16;
1354                                                 main_info.page_info[main_info.draw_page].pobs[s1].image = player[c1].image + c1 * 18;
1355                                                 main_info.page_info[main_info.draw_page].pobs[s1].pob_data = &rabbit_gobs;
1356                                                 s1++;
1357                                         }
1358                                 }
1359
1360                                 if (update_count == 1) {
1361                                         draw_begin();
1362
1363                                         draw_pobs(main_info.draw_page);
1364
1365                                         dj_mix();
1366
1367                                         if (flies_enabled)
1368                                                 draw_flies(main_info.draw_page);
1369
1370                                         draw_end();
1371                                 }
1372
1373                                 if (mod_fade_direction == 1) {
1374                                         if (mod_vol < 30) {
1375                                                 mod_vol++;
1376                                                 dj_set_mod_volume((char)mod_vol);
1377                                         }
1378                                 } else {
1379                                         if (mod_vol > 0) {
1380                                                 mod_vol--;
1381                                                 dj_set_mod_volume((char)mod_vol);
1382                                         }
1383                                 }
1384
1385                                 if (mod_fade_direction == 1) {
1386                                         if (sfx_vol < 64) {
1387                                                 sfx_vol++;
1388                                                 dj_set_sfx_volume((char)sfx_vol);
1389                                         }
1390                                 } else {
1391                                         if (sfx_vol > 0) {
1392                                                 sfx_vol--;
1393                                                 dj_set_sfx_volume((char)sfx_vol);
1394                                         }
1395                                 }
1396
1397                                 fade_flag = 0;
1398                                 for (c1 = 0; c1 < 768; c1++) {
1399                                         if (cur_pal[c1] < pal[c1]) {
1400                                                 cur_pal[c1]++;
1401                                                 fade_flag = 1;
1402                                         } else if (cur_pal[c1] > pal[c1]) {
1403                                                 cur_pal[c1]--;
1404                                                 fade_flag = 1;
1405                                         }
1406                                 }
1407                                 if (fade_flag == 0 && end_loop_flag == 1)
1408                                         break;
1409
1410                                 if (update_count == 1) {
1411                                         main_info.draw_page ^= 1;
1412                                         main_info.view_page ^= 1;
1413
1414                                         flippage(main_info.view_page);
1415         
1416                                         wait_vrt(1);
1417                                 }
1418
1419                                 if (fade_flag == 1)
1420                                         setpalette(0, 256, cur_pal);
1421
1422                                 if (update_count == 1) {
1423                                         draw_begin();
1424
1425                                         if (flies_enabled)
1426                                                 redraw_flies_background(main_info.draw_page);
1427
1428                                         redraw_pob_backgrounds(main_info.draw_page);
1429
1430                                         draw_leftovers(main_info.draw_page);
1431
1432                                         draw_end();
1433                                 }
1434
1435                                 update_count--;
1436                         }
1437
1438 #ifdef USE_NET
1439                         if (is_net) {
1440                                 if ( (player[client_player_num].dead_flag == 0) &&
1441                                         (
1442                                          (player[client_player_num].action_left) ||
1443                                          (player[client_player_num].action_right) ||
1444                                          (player[client_player_num].action_up) ||
1445                                          (player[client_player_num].jump_ready == 0)
1446                                         )
1447                                    ) {
1448                                         tellServerNewPosition();
1449                                 }
1450                         }
1451 #endif
1452
1453                         update_count = intr_sysupdate();
1454
1455 #ifdef USE_NET
1456                         if (is_net) {
1457                                 if ((server_said_bye) || ((fade_flag == 0) && (end_loop_flag == 1)))
1458                                         break;
1459                         } else
1460 #endif
1461                         if ((fade_flag == 0) && (end_loop_flag == 1))
1462                                 break;
1463                 }
1464
1465 #ifdef USE_NET
1466                 if (is_net) {
1467                         if (is_server) {
1468                                 serverTellEveryoneGoodbye();
1469                                 SDLNet_TCP_Close(sock);
1470                                 sock = NULL;
1471                         } else {
1472                                 if (!server_said_bye) {
1473                                         tellServerGoodbye();
1474                                 }
1475
1476                                 SDLNet_TCP_Close(sock);
1477                                 sock = NULL;
1478                         }
1479                 }
1480 #endif
1481                 
1482                 main_info.view_page = 0;
1483                 main_info.draw_page = 1;
1484
1485                 dj_stop_sfx_channel(4);
1486
1487                 deinit_level();
1488
1489                 memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
1490                 register_mask(mask_pic);
1491
1492                 register_background(NULL, NULL);
1493
1494                 draw_begin();
1495
1496                 put_text(main_info.view_page, 100, 50, "DOTT", 2);
1497                 put_text(main_info.view_page, 160, 50, "JIFFY", 2);
1498                 put_text(main_info.view_page, 220, 50, "FIZZ", 2);
1499                 put_text(main_info.view_page, 280, 50, "MIJJI", 2);
1500                 put_text(main_info.view_page, 40, 80, "DOTT", 2);
1501                 put_text(main_info.view_page, 40, 110, "JIFFY", 2);
1502                 put_text(main_info.view_page, 40, 140, "FIZZ", 2);
1503                 put_text(main_info.view_page, 40, 170, "MIJJI", 2);
1504
1505                 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1506                         for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
1507                                 if (c2 != c1) {
1508                                         sprintf(str1, "%d", player[c1].bumped[c2]);
1509                                         put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, str1, 2);
1510                                 } else
1511                                         put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, "-", 2);
1512                         }
1513                         sprintf(str1, "%d", player[c1].bumps);
1514                         put_text(main_info.view_page, 350, 80 + c1 * 30, str1, 2);
1515                 }
1516
1517                 put_text(main_info.view_page, 200, 230, "Press ESC to continue", 2);
1518
1519                 draw_end();
1520
1521                 flippage(main_info.view_page);
1522
1523                 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
1524                         strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1525                         return 1;
1526                 }
1527                 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
1528                         strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1529                         return 1;
1530                 }
1531
1532                 /* fix dark font */
1533                 for (c1 = 0; c1 < 16; c1++) {
1534                         pal[(240 + c1) * 3 + 0] = c1 << 2;
1535                         pal[(240 + c1) * 3 + 1] = c1 << 2;
1536                         pal[(240 + c1) * 3 + 2] = c1 << 2;
1537                 }
1538
1539                 memset(cur_pal, 0, 768);
1540
1541                 setpalette(0, 256, cur_pal);
1542
1543                 mod_vol = 0;
1544                 dj_ready_mod(MOD_SCORES);
1545                 dj_set_mod_volume((char)mod_vol);
1546                 dj_start_mod();
1547                 dj_set_nosound(0);
1548
1549                 while (key_pressed(1) == 0) {
1550                         if (mod_vol < 35)
1551                                 mod_vol++;
1552                         dj_set_mod_volume((char)mod_vol);
1553                         for (c1 = 0; c1 < 768; c1++) {
1554                                 if (cur_pal[c1] < pal[c1])
1555                                         cur_pal[c1]++;
1556                         }
1557                         dj_mix();
1558                         intr_sysupdate();
1559                         wait_vrt(0);
1560                         setpalette(0, 256, cur_pal);
1561                         flippage(main_info.view_page);
1562                 }
1563                 while (key_pressed(1) == 1) {
1564                         dj_mix();
1565                         intr_sysupdate();
1566                 }
1567
1568                 memset(pal, 0, 768);
1569
1570                 while (mod_vol > 0) {
1571                         mod_vol--;
1572                         dj_set_mod_volume((char)mod_vol);
1573                         for (c1 = 0; c1 < 768; c1++) {
1574                                 if (cur_pal[c1] > pal[c1])
1575                                         cur_pal[c1]--;
1576                         }
1577                         dj_mix();
1578                         wait_vrt(0);
1579                         setpalette(0, 256, cur_pal);
1580                         flippage(main_info.view_page);
1581                 }
1582
1583                 fillpalette(0, 0, 0);
1584
1585                 dj_set_nosound(1);
1586                 dj_stop_mod();
1587
1588                 if (is_net)
1589                         break; /* don't go back to menu if in net game. */
1590         }
1591
1592         deinit_program();
1593
1594         return 0;
1595 }
1596
1597
1598 void steer_players(void)
1599 {
1600         int c1, c2;
1601         int s1 = 0, s2 = 0;
1602
1603         update_player_actions();
1604
1605         for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1606
1607                 if (player[c1].enabled == 1) {
1608
1609                         if (player[c1].dead_flag == 0) {
1610
1611                                 if (player[c1].action_left && player[c1].action_right) {
1612                                         if (player[c1].direction == 0) {
1613                                                 if (player[c1].action_right) {
1614                                                         s1 = (player[c1].x >> 16);
1615                                                         s2 = (player[c1].y >> 16);
1616                                                         if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1617                                                                 if (player[c1].x_add < 0)
1618                                                                         player[c1].x_add += 1024;
1619                                                                 else
1620                                                                         player[c1].x_add += 768;
1621                                                         } else if ((ban_map[(s2 + 16) >> 4][s1 >> 4] != BAN_SOLID && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_ICE) || (ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_ICE && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] != BAN_SOLID)) {
1622                                                                 if (player[c1].x_add > 0)
1623                                                                         player[c1].x_add += 1024;
1624                                                                 else
1625                                                                         player[c1].x_add += 768;
1626                                                         } else {
1627                                                                 if (player[c1].x_add < 0) {
1628                                                                         player[c1].x_add += 16384;
1629                                                                         if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1630                                                                                 add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
1631                                                                 } else
1632                                                                         player[c1].x_add += 12288;
1633                                                         }
1634                                                         if (player[c1].x_add > 98304L)
1635                                                                 player[c1].x_add = 98304L;
1636                                                         player[c1].direction = 0;
1637                                                         if (player[c1].anim == 0) {
1638                                                                 player[c1].anim = 1;
1639                                                                 player[c1].frame = 0;
1640                                                                 player[c1].frame_tick = 0;
1641                                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1642                                                         }
1643                                                 }
1644                                         } else {
1645                                                 if (player[c1].action_left) {
1646                                                         s1 = (player[c1].x >> 16);
1647                                                         s2 = (player[c1].y >> 16);
1648                                                         if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1649                                                                 if (player[c1].x_add > 0)
1650                                                                         player[c1].x_add -= 1024;
1651                                                                 else
1652                                                                         player[c1].x_add -= 768;
1653                                                         } else if ((ban_map[(s2 + 16) >> 4][s1 >> 4] != BAN_SOLID && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_ICE) || (ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_ICE && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] != BAN_SOLID)) {
1654                                                                 if (player[c1].x_add > 0)
1655                                                                         player[c1].x_add -= 1024;
1656                                                                 else
1657                                                                         player[c1].x_add -= 768;
1658                                                         } else {
1659                                                                 if (player[c1].x_add > 0) {
1660                                                                         player[c1].x_add -= 16384;
1661                                                                         if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1662                                                                                 add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
1663                                                                 } else
1664                                                                         player[c1].x_add -= 12288;
1665                                                         }
1666                                                         if (player[c1].x_add < -98304L)
1667                                                                 player[c1].x_add = -98304L;
1668                                                         player[c1].direction = 1;
1669                                                         if (player[c1].anim == 0) {
1670                                                                 player[c1].anim = 1;
1671                                                                 player[c1].frame = 0;
1672                                                                 player[c1].frame_tick = 0;
1673                                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1674                                                         }
1675                                                 }
1676                                         }
1677                                 } else if (player[c1].action_left) {
1678                                         s1 = (player[c1].x >> 16);
1679                                         s2 = (player[c1].y >> 16);
1680                                         if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1681                                                 if (player[c1].x_add > 0)
1682                                                         player[c1].x_add -= 1024;
1683                                                 else
1684                                                         player[c1].x_add -= 768;
1685                                         } else if ((ban_map[(s2 + 16) >> 4][s1 >> 4] != BAN_SOLID && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_ICE) || (ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_ICE && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] != BAN_SOLID)) {
1686                                                 if (player[c1].x_add > 0)
1687                                                         player[c1].x_add -= 1024;
1688                                                 else
1689                                                         player[c1].x_add -= 768;
1690                                         } else {
1691                                                 if (player[c1].x_add > 0) {
1692                                                         player[c1].x_add -= 16384;
1693                                                         if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1694                                                                 add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
1695                                                 } else
1696                                                         player[c1].x_add -= 12288;
1697                                         }
1698                                         if (player[c1].x_add < -98304L)
1699                                                 player[c1].x_add = -98304L;
1700                                         player[c1].direction = 1;
1701                                         if (player[c1].anim == 0) {
1702                                                 player[c1].anim = 1;
1703                                                 player[c1].frame = 0;
1704                                                 player[c1].frame_tick = 0;
1705                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1706                                         }
1707                                 } else if (player[c1].action_right) {
1708                                         s1 = (player[c1].x >> 16);
1709                                         s2 = (player[c1].y >> 16);
1710                                         if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1711                                                 if (player[c1].x_add < 0)
1712                                                         player[c1].x_add += 1024;
1713                                                 else
1714                                                         player[c1].x_add += 768;
1715                                         } else if ((ban_map[(s2 + 16) >> 4][s1 >> 4] != BAN_SOLID && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_ICE) || (ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_ICE && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] != BAN_SOLID)) {
1716                                                 if (player[c1].x_add > 0)
1717                                                         player[c1].x_add += 1024;
1718                                                 else
1719                                                         player[c1].x_add += 768;
1720                                         } else {
1721                                                 if (player[c1].x_add < 0) {
1722                                                         player[c1].x_add += 16384;
1723                                                         if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1724                                                                 add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
1725                                                 } else
1726                                                         player[c1].x_add += 12288;
1727                                         }
1728                                         if (player[c1].x_add > 98304L)
1729                                                 player[c1].x_add = 98304L;
1730                                         player[c1].direction = 0;
1731                                         if (player[c1].anim == 0) {
1732                                                 player[c1].anim = 1;
1733                                                 player[c1].frame = 0;
1734                                                 player[c1].frame_tick = 0;
1735                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1736                                         }
1737                                 } else if ((!player[c1].action_left) && (!player[c1].action_right)) {
1738                                         s1 = (player[c1].x >> 16);
1739                                         s2 = (player[c1].y >> 16);
1740                                         if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID || ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SPRING || (((ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_SOLID || ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_SPRING) && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] != BAN_ICE) || (ban_map[(s2 + 16) >> 4][s1 >> 4] != BAN_ICE && (ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_SPRING)))) {
1741                                                 if (player[c1].x_add < 0) {
1742                                                         player[c1].x_add += 16384;
1743                                                         if (player[c1].x_add > 0)
1744                                                                 player[c1].x_add = 0;
1745                                                 } else {
1746                                                         player[c1].x_add -= 16384;
1747                                                         if (player[c1].x_add < 0)
1748                                                                 player[c1].x_add = 0;
1749                                                 }
1750                                                 if (player[c1].x_add != 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1751                                                         add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
1752                                         }
1753                                         if (player[c1].anim == 1) {
1754                                                 player[c1].anim = 0;
1755                                                 player[c1].frame = 0;
1756                                                 player[c1].frame_tick = 0;
1757                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1758                                         }
1759                                 }
1760                                 if (jetpack == 0) {
1761                                         if (pogostick == 1 || (player[c1].jump_ready == 1 && player[c1].action_up)) {
1762                                                 s1 = (player[c1].x >> 16);
1763                                                 s2 = (player[c1].y >> 16);
1764                                                 if (s2 < -16)
1765                                                         s2 = -16;
1766                                                 if (ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_SOLID || ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_ICE || ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_ICE) {
1767                                                         player[c1].y_add = -280000L;
1768                                                         player[c1].anim = 2;
1769                                                         player[c1].frame = 0;
1770                                                         player[c1].frame_tick = 0;
1771                                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1772                                                         player[c1].jump_ready = 0;
1773                                                         player[c1].jump_abort = 1;
1774                                                         if (pogostick == 0)
1775                                                                 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1776                                                         else
1777                                                                 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1778                                                 }
1779                                                 if ((ban_map[(s2 + 7) >> 4][s1 >> 4] == BAN_VOID || ban_map[(s2 + 7) >> 4][(s1 + 15) >> 4] == BAN_VOID) && (ban_map[(s2 + 8) >> 4][s1 >> 4] == BAN_WATER || ban_map[(s2 + 8) >> 4][(s1 + 15) >> 4] == BAN_WATER)) {
1780                                                         player[c1].y_add = -196608L;
1781                                                         player[c1].in_water = 0;
1782                                                         player[c1].anim = 2;
1783                                                         player[c1].frame = 0;
1784                                                         player[c1].frame_tick = 0;
1785                                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1786                                                         player[c1].jump_ready = 0;
1787                                                         player[c1].jump_abort = 1;
1788                                                         if (pogostick == 0)
1789                                                                 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1790                                                         else
1791                                                                 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1792                                                 }
1793                                         }
1794                                         if (pogostick == 0 && (!player[c1].action_up)) {
1795                                                 player[c1].jump_ready = 1;
1796                                                 if (player[c1].in_water == 0 && player[c1].y_add < 0 && player[c1].jump_abort == 1) {
1797                                                         if (bunnies_in_space == 0)
1798                                                                 player[c1].y_add += 32768;
1799                                                         else
1800                                                                 player[c1].y_add += 16384;
1801                                                         if (player[c1].y_add > 0)
1802                                                                 player[c1].y_add = 0;
1803                                                 }
1804                                         }
1805                                 } else {
1806
1807                                         if (player[c1].action_up) {
1808                                                 player[c1].y_add -= 16384;
1809                                                 if (player[c1].y_add < -400000L)
1810                                                         player[c1].y_add = -400000L;
1811                                                 if ((ban_map[(s2 + 7) >> 4][s1 >> 4] == BAN_VOID || ban_map[(s2 + 7) >> 4][(s1 + 15) >> 4] == BAN_VOID) && (ban_map[(s2 + 8) >> 4][s1 >> 4] == BAN_WATER || ban_map[(s2 + 8) >> 4][(s1 + 15) >> 4] == BAN_WATER))
1812                                                         player[c1].in_water = 0;
1813                                                 if (rnd(100) < 50)
1814                                                         add_object(OBJ_SMOKE, (player[c1].x >> 16) + 6 + rnd(5), (player[c1].y >> 16) + 10 + rnd(5), 0, 16384 + rnd(8192), OBJ_ANIM_SMOKE, 0);
1815                                         }
1816
1817                                 }
1818
1819                                 player[c1].x += player[c1].x_add;
1820                                 if ((player[c1].x >> 16) < 0) {
1821                                         player[c1].x = 0;
1822                                         player[c1].x_add = 0;
1823                                 }
1824                                 if ((player[c1].x >> 16) + 15 > 351) {
1825                                         player[c1].x = 336L << 16;
1826                                         player[c1].x_add = 0;
1827                                 }
1828                                 if (player[c1].y > 0) {
1829                                         s1 = (player[c1].x >> 16);
1830                                         s2 = (player[c1].y >> 16);
1831                                         if (ban_map[s2 >> 4][s1 >> 4] == BAN_SOLID || ban_map[s2 >> 4][s1 >> 4] == BAN_ICE || ban_map[s2 >> 4][s1 >> 4] == BAN_SPRING || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
1832                                                 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1833                                                 player[c1].x_add = 0;
1834                                         }
1835                                         s1 = (player[c1].x >> 16);
1836                                         s2 = (player[c1].y >> 16);
1837                                         if (ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_SPRING || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1838                                                 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1839                                                 player[c1].x_add = 0;
1840                                         }
1841                                 } else {
1842                                         s1 = (player[c1].x >> 16);
1843                                         s2 = 0;
1844                                         if (ban_map[s2 >> 4][s1 >> 4] == BAN_SOLID || ban_map[s2 >> 4][s1 >> 4] == BAN_ICE || ban_map[s2 >> 4][s1 >> 4] == BAN_SPRING || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
1845                                                 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1846                                                 player[c1].x_add = 0;
1847                                         }
1848                                         s1 = (player[c1].x >> 16);
1849                                         s2 = 0;
1850                                         if (ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_SPRING || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1851                                                 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1852                                                 player[c1].x_add = 0;
1853                                         }
1854                                 }
1855
1856                                 player[c1].y += player[c1].y_add;
1857
1858                                 s1 = (player[c1].x >> 16);
1859                                 s2 = (player[c1].y >> 16);
1860                                 if (ban_map[(s2 + 15) >> 4][(s1 + 8) >> 4] == BAN_SPRING || ((ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING && ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] != BAN_SOLID) || (ban_map[(s2 + 15) >> 4][s1 >> 4] != BAN_SOLID && ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING))) {
1861                                         player[c1].y = ((player[c1].y >> 16) & 0xfff0) << 16;
1862                                         player[c1].y_add = -400000L;
1863                                         player[c1].anim = 2;
1864                                         player[c1].frame = 0;
1865                                         player[c1].frame_tick = 0;
1866                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1867                                         player[c1].jump_ready = 0;
1868                                         player[c1].jump_abort = 0;
1869                                         for (c2 = 0; c2 < NUM_OBJECTS; c2++) {
1870                                                 if (objects[c2].used == 1 && objects[c2].type == OBJ_SPRING) {
1871                                                         if (ban_map[(s2 + 15) >> 4][(s1 + 8) >> 4] == BAN_SPRING) {
1872                                                                 if ((objects[c2].x >> 20) == ((s1 + 8) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1873                                                                         objects[c2].frame = 0;
1874                                                                         objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1875                                                                         objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1876                                                                         break;
1877                                                                 }
1878                                                         } else {
1879                                                                 if (ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
1880                                                                         if ((objects[c2].x >> 20) == (s1 >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1881                                                                                 objects[c2].frame = 0;
1882                                                                                 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1883                                                                                 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1884                                                                                 break;
1885                                                                         }
1886                                                                 } else if (ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1887                                                                         if ((objects[c2].x >> 20) == ((s1 + 15) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1888                                                                                 objects[c2].frame = 0;
1889                                                                                 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1890                                                                                 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1891                                                                                 break;
1892                                                                         }
1893                                                                 }
1894                                                         }
1895                                                 }
1896                                         }
1897                                         dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1898                                 }
1899                                 s1 = (player[c1].x >> 16);
1900                                 s2 = (player[c1].y >> 16);
1901                                 if (s2 < 0)
1902                                         s2 = 0;
1903                                 if (ban_map[s2 >> 4][s1 >> 4] == BAN_SOLID || ban_map[s2 >> 4][s1 >> 4] == BAN_ICE || ban_map[s2 >> 4][s1 >> 4] == BAN_SPRING || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1904                                         player[c1].y = (((s2 + 16) & 0xfff0)) << 16;
1905                                         player[c1].y_add = 0;
1906                                         player[c1].anim = 0;
1907                                         player[c1].frame = 0;
1908                                         player[c1].frame_tick = 0;
1909                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1910                                 }
1911                                 s1 = (player[c1].x >> 16);
1912                                 s2 = (player[c1].y >> 16);
1913                                 if (s2 < 0)
1914                                         s2 = 0;
1915                                 if (ban_map[(s2 + 8) >> 4][(s1 + 8) >> 4] == BAN_WATER) {
1916                                         if (player[c1].in_water == 0) {
1917                                                 player[c1].in_water = 1;
1918                                                 player[c1].anim = 4;
1919                                                 player[c1].frame = 0;
1920                                                 player[c1].frame_tick = 0;
1921                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1922                                                 if (player[c1].y_add >= 32768) {
1923                                                         add_object(OBJ_SPLASH, (player[c1].x >> 16) + 8, ((player[c1].y >> 16) & 0xfff0) + 15, 0, 0, OBJ_ANIM_SPLASH, 0);
1924                                                         if (blood_is_thicker_than_water == 0)
1925                                                                 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1926                                                         else
1927                                                                 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 5000), 64, 0, 0, -1);
1928                                                 }
1929                                         }
1930                                         player[c1].y_add -= 1536;
1931                                         if (player[c1].y_add < 0 && player[c1].anim != 5) {
1932                                                 player[c1].anim = 5;
1933                                                 player[c1].frame = 0;
1934                                                 player[c1].frame_tick = 0;
1935                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1936                                         }
1937                                         if (player[c1].y_add < -65536L)
1938                                                 player[c1].y_add = -65536L;
1939                                         if (player[c1].y_add > 65535L)
1940                                                 player[c1].y_add = 65535L;
1941                                         if (ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_ICE) {
1942                                                 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1943                                                 player[c1].y_add = 0;
1944                                         }
1945                                 } else if (ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1946                                         player[c1].in_water = 0;
1947                                         player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1948                                         player[c1].y_add = 0;
1949                                         if (player[c1].anim != 0 && player[c1].anim != 1) {
1950                                                 player[c1].anim = 0;
1951                                                 player[c1].frame = 0;
1952                                                 player[c1].frame_tick = 0;
1953                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1954                                         }
1955                                 } else {
1956                                         if (player[c1].in_water == 0) {
1957                                                 if (bunnies_in_space == 0)
1958                                                         player[c1].y_add += 12288;
1959                                                 else
1960                                                         player[c1].y_add += 6144;
1961                                                 if (player[c1].y_add > 327680L)
1962                                                         player[c1].y_add = 327680L;
1963                                         } else {
1964                                                 player[c1].y = (player[c1].y & 0xffff0000) + 0x10000;
1965                                                 player[c1].y_add = 0;
1966                                         }
1967                                         player[c1].in_water = 0;
1968                                 }
1969                                 if (player[c1].y_add > 36864 && player[c1].anim != 3 && player[c1].in_water == 0) {
1970                                         player[c1].anim = 3;
1971                                         player[c1].frame = 0;
1972                                         player[c1].frame_tick = 0;
1973                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1974                                 }
1975
1976                         }
1977
1978                         player[c1].frame_tick++;
1979                         if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
1980                                 player[c1].frame++;
1981                                 if (player[c1].frame >= player_anims[player[c1].anim].num_frames) {
1982                                         if (player[c1].anim != 6)
1983                                                 player[c1].frame = player_anims[player[c1].anim].restart_frame;
1984                                         else
1985                                                 position_player(c1);
1986                                 }
1987                                 player[c1].frame_tick = 0;
1988                         }
1989                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1990
1991                 }
1992
1993         }
1994
1995 }
1996
1997
1998 void position_player(int player_num)
1999 {
2000         int c1;
2001         int s1, s2;
2002
2003         while (1) {
2004                 while (1) {
2005                         s1 = rnd(22);
2006                         s2 = rnd(16);
2007                         if (ban_map[s2][s1] == BAN_VOID && (ban_map[s2 + 1][s1] == BAN_SOLID || ban_map[s2 + 1][s1] == BAN_ICE))
2008                                 break;
2009                 }
2010                 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
2011                         if (c1 != player_num && player[c1].enabled == 1) {
2012                                 if (abs((s1 << 4) - (player[c1].x >> 16)) < 32 && abs((s2 << 4) - (player[c1].y >> 16)) < 32)
2013                                         break;
2014                         }
2015                 }
2016                 if (c1 == JNB_MAX_PLAYERS) {
2017                         player[player_num].x = (long) s1 << 20;
2018                         player[player_num].y = (long) s2 << 20;
2019                         player[player_num].x_add = player[player_num].y_add = 0;
2020                         player[player_num].direction = 0;
2021                         player[player_num].jump_ready = 1;
2022                         player[player_num].in_water = 0;
2023                         player[player_num].anim = 0;
2024                         player[player_num].frame = 0;
2025                         player[player_num].frame_tick = 0;
2026                         player[player_num].image = player_anims[player[player_num].anim].frame[player[player_num].frame].image;
2027
2028                         if (is_server) {
2029 #ifdef USE_NET
2030                                 if (is_net)
2031                                         serverSendAlive(player_num);
2032 #endif
2033                                 player[player_num].dead_flag = 0;
2034                         }
2035
2036                         break;
2037                 }
2038         }
2039
2040 }
2041
2042
2043 void add_object(int type, int x, int y, int x_add, int y_add, int anim, int frame)
2044 {
2045         int c1;
2046
2047         for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
2048                 if (objects[c1].used == 0) {
2049                         objects[c1].used = 1;
2050                         objects[c1].type = type;
2051                         objects[c1].x = (long) x << 16;
2052                         objects[c1].y = (long) y << 16;
2053                         objects[c1].x_add = x_add;
2054                         objects[c1].y_add = y_add;
2055                         objects[c1].x_acc = 0;
2056                         objects[c1].y_acc = 0;
2057                         objects[c1].anim = anim;
2058                         objects[c1].frame = frame;
2059                         objects[c1].ticks = object_anims[anim].frame[frame].ticks;
2060                         objects[c1].image = object_anims[anim].frame[frame].image;
2061                         break;
2062                 }
2063         }
2064
2065 }
2066
2067
2068 void update_objects(void)
2069 {
2070         int c1;
2071         int s1 = 0;
2072
2073         for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
2074                 if (objects[c1].used == 1) {
2075                         switch (objects[c1].type) {
2076                         case OBJ_SPRING:
2077                                 objects[c1].ticks--;
2078                                 if (objects[c1].ticks <= 0) {
2079                                         objects[c1].frame++;
2080                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames) {
2081                                                 objects[c1].frame--;
2082                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2083                                         } else {
2084                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2085                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2086                                         }
2087                                 }
2088                                 if (objects[c1].used == 1)
2089                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2090                                 break;
2091                         case OBJ_SPLASH:
2092                                 objects[c1].ticks--;
2093                                 if (objects[c1].ticks <= 0) {
2094                                         objects[c1].frame++;
2095                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2096                                                 objects[c1].used = 0;
2097                                         else {
2098                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2099                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2100                                         }
2101                                 }
2102                                 if (objects[c1].used == 1)
2103                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2104                                 break;
2105                         case OBJ_SMOKE:
2106                                 objects[c1].x += objects[c1].x_add;
2107                                 objects[c1].y += objects[c1].y_add;
2108                                 objects[c1].ticks--;
2109                                 if (objects[c1].ticks <= 0) {
2110                                         objects[c1].frame++;
2111                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2112                                                 objects[c1].used = 0;
2113                                         else {
2114                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2115                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2116                                         }
2117                                 }
2118                                 if (objects[c1].used == 1)
2119                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2120                                 break;
2121                         case OBJ_YEL_BUTFLY:
2122                         case OBJ_PINK_BUTFLY:
2123                                 objects[c1].x_acc += rnd(128) - 64;
2124                                 if (objects[c1].x_acc < -1024)
2125                                         objects[c1].x_acc = -1024;
2126                                 if (objects[c1].x_acc > 1024)
2127                                         objects[c1].x_acc = 1024;
2128                                 objects[c1].x_add += objects[c1].x_acc;
2129                                 if (objects[c1].x_add < -32768)
2130                                         objects[c1].x_add = -32768;
2131                                 if (objects[c1].x_add > 32768)
2132                                         objects[c1].x_add = 32768;
2133                                 objects[c1].x += objects[c1].x_add;
2134                                 if ((objects[c1].x >> 16) < 16) {
2135                                         objects[c1].x = 16 << 16;
2136                                         objects[c1].x_add = -objects[c1].x_add >> 2;
2137                                         objects[c1].x_acc = 0;
2138                                 } else if ((objects[c1].x >> 16) > 350) {
2139                                         objects[c1].x = 350 << 16;
2140                                         objects[c1].x_add = -objects[c1].x_add >> 2;
2141                                         objects[c1].x_acc = 0;
2142                                 }
2143                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
2144                                         if (objects[c1].x_add < 0) {
2145                                                 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2146                                         } else {
2147                                                 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2148                                         }
2149                                         objects[c1].x_add = -objects[c1].x_add >> 2;
2150                                         objects[c1].x_acc = 0;
2151                                 }
2152                                 objects[c1].y_acc += rnd(64) - 32;
2153                                 if (objects[c1].y_acc < -1024)
2154                                         objects[c1].y_acc = -1024;
2155                                 if (objects[c1].y_acc > 1024)
2156                                         objects[c1].y_acc = 1024;
2157                                 objects[c1].y_add += objects[c1].y_acc;
2158                                 if (objects[c1].y_add < -32768)
2159                                         objects[c1].y_add = -32768;
2160                                 if (objects[c1].y_add > 32768)
2161                                         objects[c1].y_add = 32768;
2162                                 objects[c1].y += objects[c1].y_add;
2163                                 if ((objects[c1].y >> 16) < 0) {
2164                                         objects[c1].y = 0;
2165                                         objects[c1].y_add = -objects[c1].y_add >> 2;
2166                                         objects[c1].y_acc = 0;
2167                                 } else if ((objects[c1].y >> 16) > 255) {
2168                                         objects[c1].y = 255 << 16;
2169                                         objects[c1].y_add = -objects[c1].y_add >> 2;
2170                                         objects[c1].y_acc = 0;
2171                                 }
2172                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
2173                                         if (objects[c1].y_add < 0) {
2174                                                 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2175                                         } else {
2176                                                 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2177                                         }
2178                                         objects[c1].y_add = -objects[c1].y_add >> 2;
2179                                         objects[c1].y_acc = 0;
2180                                 }
2181                                 if (objects[c1].type == OBJ_YEL_BUTFLY) {
2182                                         if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_LEFT) {
2183                                                 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_LEFT;
2184                                                 objects[c1].frame = 0;
2185                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2186                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2187                                         } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_RIGHT) {
2188                                                 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_RIGHT;
2189                                                 objects[c1].frame = 0;
2190                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2191                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2192                                         }
2193                                 } else {
2194                                         if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_LEFT) {
2195                                                 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_LEFT;
2196                                                 objects[c1].frame = 0;
2197                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2198                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2199                                         } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_RIGHT) {
2200                                                 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_RIGHT;
2201                                                 objects[c1].frame = 0;
2202                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2203                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2204                                         }
2205                                 }
2206                                 objects[c1].ticks--;
2207                                 if (objects[c1].ticks <= 0) {
2208                                         objects[c1].frame++;
2209                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2210                                                 objects[c1].frame = object_anims[objects[c1].anim].restart_frame;
2211                                         else {
2212                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2213                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2214                                         }
2215                                 }
2216                                 if (objects[c1].used == 1)
2217                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2218                                 break;
2219                         case OBJ_FUR:
2220                                 if (rnd(100) < 30)
2221                                         add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 0);
2222                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
2223                                         objects[c1].y_add += 3072;
2224                                         if (objects[c1].y_add > 196608L)
2225                                                 objects[c1].y_add = 196608L;
2226                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
2227                                         if (objects[c1].x_add < 0) {
2228                                                 if (objects[c1].x_add < -65536L)
2229                                                         objects[c1].x_add = -65536L;
2230                                                 objects[c1].x_add += 1024;
2231                                                 if (objects[c1].x_add > 0)
2232                                                         objects[c1].x_add = 0;
2233                                         } else {
2234                                                 if (objects[c1].x_add > 65536L)
2235                                                         objects[c1].x_add = 65536L;
2236                                                 objects[c1].x_add -= 1024;
2237                                                 if (objects[c1].x_add < 0)
2238                                                         objects[c1].x_add = 0;
2239                                         }
2240                                         objects[c1].y_add += 1024;
2241                                         if (objects[c1].y_add < -65536L)
2242                                                 objects[c1].y_add = -65536L;
2243                                         if (objects[c1].y_add > 65536L)
2244                                                 objects[c1].y_add = 65536L;
2245                                 }
2246                                 objects[c1].x += objects[c1].x_add;
2247                                 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1 || ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3)) {
2248                                         if (objects[c1].x_add < 0) {
2249                                                 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2250                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
2251                                         } else {
2252                                                 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2253                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
2254                                         }
2255                                 }
2256                                 objects[c1].y += objects[c1].y_add;
2257                                 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
2258                                         objects[c1].used = 0;
2259                                 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
2260                                         if (objects[c1].y_add < 0) {
2261                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
2262                                                         objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2263                                                         objects[c1].x_add >>= 2;
2264                                                         objects[c1].y_add = -objects[c1].y_add >> 2;
2265                                                 }
2266                                         } else {
2267                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
2268                                                         if (objects[c1].y_add > 131072L) {
2269                                                                 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2270                                                                 objects[c1].x_add >>= 2;
2271                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
2272                                                         } else
2273                                                                 objects[c1].used = 0;
2274                                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
2275                                                         objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2276                                                         if (objects[c1].y_add > 131072L)
2277                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
2278                                                         else
2279                                                                 objects[c1].y_add = 0;
2280                                                 }
2281                                         }
2282                                 }
2283                                 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
2284                                         objects[c1].x_add = -16384;
2285                                 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
2286                                         objects[c1].x_add = 16384;
2287                                 if (objects[c1].used == 1) {
2288                                         s1 = (int)(atan2(objects[c1].y_add, objects[c1].x_add) * 4 / M_PI);
2289                                         if (s1 < 0)
2290                                                 s1 += 8;
2291                                         if (s1 < 0)
2292                                                 s1 = 0;
2293                                         if (s1 > 7)
2294                                                 s1 = 7;
2295                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame + s1, &object_gobs);
2296                                 }
2297                                 break;
2298                         case OBJ_FLESH:
2299                                 if (rnd(100) < 30) {
2300                                         if (objects[c1].frame == 76)
2301                                                 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 1);
2302                                         else if (objects[c1].frame == 77)
2303                                                 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 2);
2304                                         else if (objects[c1].frame == 78)
2305                                                 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 3);
2306                                 }
2307                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
2308                                         objects[c1].y_add += 3072;
2309                                         if (objects[c1].y_add > 196608L)
2310                                                 objects[c1].y_add = 196608L;
2311                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
2312                                         if (objects[c1].x_add < 0) {
2313                                                 if (objects[c1].x_add < -65536L)
2314                                                         objects[c1].x_add = -65536L;
2315                                                 objects[c1].x_add += 1024;
2316                                                 if (objects[c1].x_add > 0)
2317                                                         objects[c1].x_add = 0;
2318                                         } else {
2319                                                 if (objects[c1].x_add > 65536L)
2320                                                         objects[c1].x_add = 65536L;
2321                                                 objects[c1].x_add -= 1024;
2322                                                 if (objects[c1].x_add < 0)
2323                                                         objects[c1].x_add = 0;
2324                                         }
2325                                         objects[c1].y_add += 1024;
2326                                         if (objects[c1].y_add < -65536L)
2327                                                 objects[c1].y_add = -65536L;
2328                                         if (objects[c1].y_add > 65536L)
2329                                                 objects[c1].y_add = 65536L;
2330                                 }
2331                                 objects[c1].x += objects[c1].x_add;
2332                                 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1 || ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3)) {
2333                                         if (objects[c1].x_add < 0) {
2334                                                 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2335                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
2336                                         } else {
2337                                                 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2338                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
2339                                         }
2340                                 }
2341                                 objects[c1].y += objects[c1].y_add;
2342                                 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
2343                                         objects[c1].used = 0;
2344                                 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
2345                                         if (objects[c1].y_add < 0) {
2346                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
2347                                                         objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2348                                                         objects[c1].x_add >>= 2;
2349                                                         objects[c1].y_add = -objects[c1].y_add >> 2;
2350                                                 }
2351                                         } else {
2352                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
2353                                                         if (objects[c1].y_add > 131072L) {
2354                                                                 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2355                                                                 objects[c1].x_add >>= 2;
2356                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
2357                                                         } else {
2358                                                                 if (rnd(100) < 10) {
2359                                                                         s1 = rnd(4) - 2;
2360                                                                         add_leftovers(0, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
2361                                                                         add_leftovers(1, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
2362                                                                 }
2363                                                                 objects[c1].used = 0;
2364                                                         }
2365                                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
2366                                                         objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2367                                                         if (objects[c1].y_add > 131072L)
2368                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
2369                                                         else
2370                                                                 objects[c1].y_add = 0;
2371                                                 }
2372                                         }
2373                                 }
2374                                 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
2375                                         objects[c1].x_add = -16384;
2376                                 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
2377                                         objects[c1].x_add = 16384;
2378                                 if (objects[c1].used == 1)
2379                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame, &object_gobs);
2380                                 break;
2381                         case OBJ_FLESH_TRACE:
2382                                 objects[c1].ticks--;
2383                                 if (objects[c1].ticks <= 0) {
2384                                         objects[c1].frame++;
2385                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2386                                                 objects[c1].used = 0;
2387                                         else {
2388                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2389                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2390                                         }
2391                                 }
2392                                 if (objects[c1].used == 1)
2393                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2394                                 break;
2395                         }
2396                 }
2397         }
2398
2399 }
2400
2401
2402 int add_pob(int page, int x, int y, int image, gob_t *pob_data)
2403 {
2404
2405         if (main_info.page_info[page].num_pobs >= NUM_POBS)
2406                 return 1;
2407
2408         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].x = x;
2409         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].y = y;
2410         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].image = image;
2411         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].pob_data = pob_data;
2412         main_info.page_info[page].num_pobs++;
2413
2414         return 0;
2415
2416 }
2417
2418
2419 void draw_flies(int page)
2420 {
2421         int c2;
2422
2423         for (c2 = 0; c2 < NUM_FLIES; c2++) {
2424                 flies[c2].back[main_info.draw_page] = get_pixel(main_info.draw_page, flies[c2].x, flies[c2].y);
2425                 flies[c2].back_defined[main_info.draw_page] = 1;
2426                 if (mask_pic[(flies[c2].y * JNB_WIDTH) + flies[c2].x] == 0)
2427                         set_pixel(main_info.draw_page, flies[c2].x, flies[c2].y, 0);
2428         }
2429 }
2430
2431 void draw_pobs(int page)
2432 {
2433         int c1;
2434         int back_buf_ofs;
2435
2436         back_buf_ofs = 0;
2437
2438         for (c1 = main_info.page_info[page].num_pobs - 1; c1 >= 0; c1--) {
2439                 main_info.page_info[page].pobs[c1].back_buf_ofs = back_buf_ofs;
2440                 get_block(page, main_info.page_info[page].pobs[c1].x - pob_hs_x(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), main_info.page_info[page].pobs[c1].y - pob_hs_y(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), pob_width(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), pob_height(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), (unsigned char *)main_info.pob_backbuf[page] + back_buf_ofs);
2441                 if (scale_up)
2442                         back_buf_ofs += pob_width(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data) * pob_height(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data) * 4 * bytes_per_pixel;
2443                 else
2444                         back_buf_ofs += pob_width(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data) * pob_height(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data) * bytes_per_pixel;
2445                 put_pob(page, main_info.page_info[page].pobs[c1].x, main_info.page_info[page].pobs[c1].y, main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data, 1, mask_pic);
2446         }
2447
2448 }
2449
2450
2451 void redraw_flies_background(int page)
2452 {
2453         int c2;
2454
2455         for (c2 = NUM_FLIES - 1; c2 >= 0; c2--) {
2456                 if (flies[c2].back_defined[page] == 1)
2457                         set_pixel(page, flies[c2].old_draw_x, flies[c2].old_draw_y, flies[c2].back[page]);
2458                 flies[c2].old_draw_x = flies[c2].x;
2459                 flies[c2].old_draw_y = flies[c2].y;
2460         }
2461 }
2462
2463
2464 void redraw_pob_backgrounds(int page)
2465 {
2466         int c1;
2467
2468         for (c1 = 0; c1 < main_info.page_info[page].num_pobs; c1++)
2469                 put_block(page, main_info.page_info[page].pobs[c1].x - pob_hs_x(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), main_info.page_info[page].pobs[c1].y - pob_hs_y(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), pob_width(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), pob_height(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data), (unsigned char *)main_info.pob_backbuf[page] + main_info.page_info[page].pobs[c1].back_buf_ofs);
2470
2471 }
2472
2473
2474 int add_leftovers(int page, int x, int y, int image, gob_t *pob_data)
2475 {
2476
2477         if (leftovers.page[page].num_pobs >= NUM_LEFTOVERS)
2478                 return 1;
2479
2480         leftovers.page[page].pobs[leftovers.page[page].num_pobs].x = x;
2481         leftovers.page[page].pobs[leftovers.page[page].num_pobs].y = y;
2482         leftovers.page[page].pobs[leftovers.page[page].num_pobs].image = image;
2483         leftovers.page[page].pobs[leftovers.page[page].num_pobs].pob_data = pob_data;
2484         leftovers.page[page].num_pobs++;
2485
2486         return 0;
2487
2488 }
2489
2490
2491 void draw_leftovers(int page)
2492 {
2493         int c1;
2494
2495         for (c1 = leftovers.page[page].num_pobs - 1; c1 >= 0; c1--)
2496                 put_pob(page, leftovers.page[page].pobs[c1].x, leftovers.page[page].pobs[c1].y, leftovers.page[page].pobs[c1].image, leftovers.page[page].pobs[c1].pob_data, 1, mask_pic);
2497
2498         leftovers.page[page].num_pobs = 0;
2499
2500 }
2501
2502
2503 int init_level(int level, char *pal)
2504 {
2505         unsigned char *handle;
2506         int c1, c2;
2507         int s1, s2;
2508
2509         if ((handle = dat_open("level.pcx", datfile_name, "rb")) == 0) {
2510                 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2511                 return 1;
2512         }
2513         if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
2514                 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2515                 return 1;
2516         }
2517         if (flip)
2518                 flip_pixels(background_pic);
2519         if ((handle = dat_open("mask.pcx", datfile_name, "rb")) == 0) {
2520                 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2521                 return 1;
2522         }
2523         if (read_pcx(handle, mask_pic, JNB_WIDTH*JNB_HEIGHT, 0) != 0) {
2524                 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2525                 return 1;
2526         }
2527         if (flip)
2528                 flip_pixels(mask_pic);
2529         register_mask(mask_pic);
2530
2531         for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
2532                 if (player[c1].enabled == 1) {
2533                         player[c1].bumps = 0;
2534                         for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++)
2535                                 player[c1].bumped[c2] = 0;
2536                         position_player(c1);
2537                 }
2538         }
2539
2540         for (c1 = 0; c1 < NUM_OBJECTS; c1++)
2541                 objects[c1].used = 0;
2542
2543         for (c1 = 0; c1 < 16; c1++) {
2544                 for (c2 = 0; c2 < 22; c2++) {
2545                         if (ban_map[c1][c2] == BAN_SPRING)
2546                                 add_object(OBJ_SPRING, c2 << 4, c1 << 4, 0, 0, OBJ_ANIM_SPRING, 5);
2547                 }
2548         }
2549
2550         while (1) {
2551                 s1 = rnd(22);
2552                 s2 = rnd(16);
2553                 if (ban_map[s2][s1] == BAN_VOID) {
2554                         add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2555                         break;
2556                 }
2557         }
2558         while (1) {
2559                 s1 = rnd(22);
2560                 s2 = rnd(16);
2561                 if (ban_map[s2][s1] == BAN_VOID) {
2562                         add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2563                         break;
2564                 }
2565         }
2566         while (1) {
2567                 s1 = rnd(22);
2568                 s2 = rnd(16);
2569                 if (ban_map[s2][s1] == BAN_VOID) {
2570                         add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2571                         break;
2572                 }
2573         }
2574         while (1) {
2575                 s1 = rnd(22);
2576                 s2 = rnd(16);
2577                 if (ban_map[s2][s1] == BAN_VOID) {
2578                         add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2579                         break;
2580                 }
2581         }
2582
2583         return 0;
2584
2585 }
2586
2587
2588 void deinit_level(void)
2589 {
2590         dj_set_nosound(1);
2591         dj_stop_mod();
2592 }
2593
2594
2595 #ifndef PATH_MAX
2596 #define PATH_MAX 1024
2597 #endif
2598 #ifndef O_BINARY
2599 #define O_BINARY 0
2600 #endif
2601
2602 unsigned char *datafile_buffer = NULL;
2603
2604 static void preread_datafile(const char *fname)
2605 {
2606     int fd = 0;
2607     int len;
2608
2609 #ifdef ZLIB_SUPPORT
2610     char *gzfilename = alloca(strlen(fname) + 4);
2611     int bufsize = 0;
2612     int bufpos = 0;
2613     gzFile gzf;
2614
2615     strcpy(gzfilename, fname);
2616     strcat(gzfilename, ".gz");
2617
2618     gzf = gzopen(gzfilename, "rb");
2619     if (gzf != NULL) {
2620         unsigned char *ptr;
2621         do {
2622             int br;
2623             if (bufpos >= bufsize) {
2624                 bufsize += 1024 * 1024;
2625                 datafile_buffer = (unsigned char *) realloc(datafile_buffer, bufsize);
2626                 if (datafile_buffer == NULL) {
2627                     perror("realloc()");
2628                     exit(42);
2629                 }
2630             }
2631
2632             br = gzread(gzf, datafile_buffer + bufpos, bufsize - bufpos);
2633             if (br == -1) {
2634                 fprintf(stderr, "gzread failed.\n");
2635                 exit(42);
2636             }
2637
2638             bufpos += br;
2639         } while (!gzeof(gzf));
2640
2641         /* try to shrink buffer... */
2642         ptr = (unsigned char *) realloc(datafile_buffer, bufpos);
2643         if (ptr != NULL)
2644             datafile_buffer = ptr;
2645
2646         gzclose(gzf);
2647         return;
2648     }
2649
2650     /* drop through and try for an uncompressed datafile... */
2651 #endif
2652
2653     fd = open(fname, O_RDONLY | O_BINARY);
2654     if (fd == -1) {
2655         fprintf(stderr, "can't open %s:", fname);
2656         perror("");
2657         exit(42);
2658     }
2659