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