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