]> icculus.org git repositories - crow/jumpnbump.git/blob - main.c
d8d8616b35ad4c0ca8d3c652847e3e4f62e94e46
[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                 if (is_net)
537                         sendPacketToAll(&pkt);
538         } else {
539                 sendPacketToSock(sock, &pkt);
540 #endif
541         }
542 }
543
544
545 #ifdef USE_NET
546 void tellServerNewPosition(void)
547 {
548         NetPacket pkt;
549         pkt.cmd = NETCMD_POSITION;
550         pkt.arg = client_player_num;
551         pkt.arg2 = player[client_player_num].x;
552         pkt.arg3 = player[client_player_num].y;
553
554         if (is_server) {
555                 sendPacketToAll(&pkt);
556         } else {
557                 sendPacketToSock(sock, &pkt);
558         }
559 }
560 #endif // USE_NET
561
562
563 void processKillPacket(NetPacket *pkt)
564 {
565         int c1 = pkt->arg;
566         int c2 = pkt->arg2;
567         int x = pkt->arg3;
568         int y = pkt->arg4;
569         int c4 = 0;
570         int s1 = 0;
571
572         player[c1].y_add = -player[c1].y_add;
573         if (player[c1].y_add > -262144L)
574                 player[c1].y_add = -262144L;
575         player[c1].jump_abort = 1;
576         player[c2].dead_flag = 1;
577         if (player[c2].anim != 6) {
578                 player[c2].anim = 6;
579                 player[c2].frame = 0;
580                 player[c2].frame_tick = 0;
581                 player[c2].image = player_anims[player[c2].anim].frame[player[c2].frame].image + player[c2].direction * 9;
582                 if (main_info.no_gore == 0) {
583                         for (c4 = 0; c4 < 6; c4++)
584                                 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);
585                         for (c4 = 0; c4 < 6; c4++)
586                                 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 76);
587                         for (c4 = 0; c4 < 6; c4++)
588                                 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 77);
589                         for (c4 = 0; c4 < 8; c4++)
590                                 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 78);
591                         for (c4 = 0; c4 < 10; c4++)
592                                 add_object(OBJ_FLESH, (x >> 16) + 6 + rnd(5), (y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 79);
593                 }
594                 dj_play_sfx(SFX_DEATH, (unsigned short)(SFX_DEATH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
595                 player[c1].bumps++;
596                 player[c1].bumped[c2]++;
597                 s1 = player[c1].bumps % 100;
598                 add_leftovers(0, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
599                 add_leftovers(1, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
600                 add_leftovers(0, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
601                 add_leftovers(1, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
602         }
603 }
604
605
606 #ifdef USE_NET
607 void processPositionPacket(NetPacket *pkt)
608 {
609         int playerid = pkt->arg;
610
611         player[playerid].x = pkt->arg2;
612         player[playerid].y = pkt->arg3;
613 }
614
615
616 void processAlivePacket(NetPacket *pkt)
617 {
618         int playerid = pkt->arg;
619
620         player[playerid].dead_flag = 0;
621         player[playerid].x = pkt->arg2;
622         player[playerid].y = pkt->arg3;
623 }
624
625
626 void serverTellEveryoneGoodbye(void)
627 {
628         int i;
629
630         if (!buggered_off) {
631                 buggered_off = 1;
632                 for (i = 0; i < JNB_MAX_PLAYERS; i++) {
633                         if (player[i].enabled) {
634                                 NetPacket pkt;
635
636                                 pkt.cmd = NETCMD_BYE;
637                                 pkt.arg = i;
638                                 pkt.arg2 = 0;
639                                 pkt.arg3 = 0;
640                                 pkt.arg4 = 0;
641                                 sendPacketToAll(&pkt);
642                         }
643                 }
644         }
645 }
646
647
648 int server_said_bye = 0;
649
650
651 int update_players_from_server(void)
652 {
653         NetPacket pkt;
654         int rc;
655
656         assert(!is_server);
657
658         while ((rc = grabPacket(sock, &pkt)) != 0) {
659                 if (rc < 0) {
660                         printf("CLIENT: Lost connection.\n");
661                         pkt.cmd = NETCMD_BYE;
662                         pkt.arg = client_player_num;
663                 }
664
665                 if (pkt.cmd == NETCMD_BYE) {
666                         if (pkt.arg == client_player_num) {
667                                 close(sock);
668                                 sock = -1;
669                                 server_said_bye = 1;
670                                 return(0);
671                         } else {
672                                 player[pkt.arg].enabled = 0;
673                         }
674                 } else if (pkt.cmd == NETCMD_MOVE) {
675                         processMovePacket(&pkt);
676                 } else if (pkt.cmd == NETCMD_ALIVE) {
677                         processAlivePacket(&pkt);
678                 } else if (pkt.cmd == NETCMD_POSITION) {
679                         processPositionPacket(&pkt);
680                 } else if (pkt.cmd == NETCMD_KILL) {
681                         processKillPacket(&pkt);
682                 } else {
683                         printf("CLIENT: Got an unknown packet: 0x%lX.\n", pkt.cmd);
684                 }
685         }
686
687         return(1);
688 }
689
690
691 void serverSendAlive(int playerid)
692 {
693         NetPacket pkt;
694
695         assert(is_server);
696         pkt.cmd = NETCMD_ALIVE;
697         pkt.arg = playerid;
698         pkt.arg2 = player[playerid].x;
699         pkt.arg3 = player[playerid].y;
700         sendPacketToAll(&pkt);
701 }
702 #endif // USE_NET
703
704
705 void serverSendKillPacket(int killer, int victim)
706 {
707         NetPacket pkt;
708
709         assert(is_server);
710         pkt.cmd = NETCMD_KILL;
711         pkt.arg = killer;
712         pkt.arg2 = victim;
713         pkt.arg3 = player[victim].x;
714         pkt.arg4 = player[victim].y;
715         processKillPacket(&pkt);
716 #ifdef USE_NET
717         if (is_net)
718                 sendPacketToAll(&pkt);
719 #endif
720 }
721
722
723 #ifdef USE_NET
724 void update_players_from_clients(void)
725 {
726 #ifdef USE_NET
727     int i;
728     NetPacket pkt;
729     int playerid;
730
731     assert(is_server);
732
733     while ((playerid = serverRecvPacket(&pkt)) >= 0) {
734         if (pkt.cmd == NETCMD_BYE) {
735             pkt.arg = playerid;  /* just in case. */
736             sendPacketToAll(&pkt);
737             player[playerid].enabled = 0;
738             close(net_info[playerid].sock);
739         } else if (pkt.cmd == NETCMD_POSITION) {
740             pkt.arg = playerid;  /* just in case. */
741             processPositionPacket(&pkt);
742             for (i = 0; i < (sizeof (net_info) / sizeof (net_info[0])); i++) {
743                 if (i != playerid) {
744                     sendPacket(i, &pkt);
745                 }
746             }
747         } else if (pkt.cmd == NETCMD_MOVE) {
748             pkt.arg = playerid;  /* just in case. */
749             //pkt.arg3 = player[playerid].x;
750             //pkt.arg4 = player[playerid].y;
751             processMovePacket(&pkt);
752             sendPacketToAll(&pkt);
753         } else {
754             printf("SERVER: Got unknown packet (0x%lX).\n", pkt.cmd);
755         }
756     }
757 #endif
758 }
759
760
761 void init_server(const char *netarg)
762 {
763 #ifdef USE_NET
764     NetPacket pkt;
765     char ipstr[128];
766     struct hostent *hent;
767     struct sockaddr_in addr;
768     struct in_addr inaddr;
769     int i;
770     int wait_for_clients = ((netarg == NULL) ? 0 : atoi(netarg));
771 #ifdef _MSC_VER
772 WORD wVersionRequested;
773 WSADATA wsaData;
774 int err;
775  
776 wVersionRequested = MAKEWORD( 2, 2 );
777  
778 err = WSAStartup( wVersionRequested, &wsaData );
779 if ( err != 0 ) {
780     /* Tell the user that we could not find a usable */
781     /* WinSock DLL.                                  */
782         fprintf(stderr, "SERVER: WSAStartup failed!");
783     return;
784 }
785 #endif
786
787     if ((wait_for_clients > (JNB_MAX_PLAYERS - 1)) || (wait_for_clients < 0)) {
788         printf("SERVER: Waiting for bogus client count (%d).\n", wait_for_clients);
789         exit(42);
790     }
791
792     sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
793     if (sock < 0) {
794         fprintf(stderr, "SERVER: socket(): %i", net_error);
795         //perror("SERVER: socket()");
796         exit(42);
797     }
798
799     memset(&addr, '\0', sizeof (addr));
800     addr.sin_family = AF_INET;
801     addr.sin_port = htons(JNB_INETPORT);
802     addr.sin_addr.s_addr = INADDR_ANY;
803     if (bind(sock, (struct sockaddr *) &addr,
804             sizeof (addr)) == -1) {
805                 fprintf(stderr, "SERVER: bind(): %i", net_error);
806         //perror("SERVER: bind()");
807         close(sock);
808         exit(42);
809     }
810
811     if (listen(sock, wait_for_clients) == -1) {
812                 fprintf(stderr, "SERVER: listen(): %i", net_error);
813         //perror("SERVER: listen()");
814         close(sock);
815         exit(42);
816     }
817
818     player[client_player_num].enabled = 1;
819
820     gethostname(ipstr, sizeof (ipstr));
821     hent = gethostbyname(ipstr);
822     if (hent != NULL) {
823         memcpy(&inaddr, hent->h_addr, hent->h_length);
824         strncpy(ipstr, inet_ntoa(inaddr), sizeof (ipstr));
825     }
826
827     printf("SERVER: we are [%s].\n", ipstr);
828
829     addr.sin_addr.s_addr = inaddr.s_addr;
830     addr.sin_family = AF_INET;
831     addr.sin_port = htons(JNB_INETPORT);
832     net_info[client_player_num].addr = malloc(sizeof (addr));
833     memcpy(net_info[client_player_num].addr, &addr, sizeof (addr));
834     net_info[client_player_num].addrlen = sizeof (addr);
835     /*gettimeofday(&net_info[client_player_num].last_timestamp, NULL);*/
836
837     printf("SERVER: waiting for (%d) clients...\n", wait_for_clients);
838
839     while (wait_for_clients > 0)
840     {
841         char buf[NETPKTBUFSIZE];
842         struct sockaddr_in from;
843         int fromlen = sizeof (from);
844         int negatory = 1;
845         int br;
846         int s;
847
848         s = accept(sock, (struct sockaddr *) &from, &fromlen);
849         if (s < 0)
850         {
851                 fprintf(stderr, "SERVER: accept(): %i", net_error);
852             //perror("SERVER: accept()");
853             close(sock);
854             exit(42);
855         } /* if */
856
857         br = recv(s, buf, NETPKTBUFSIZE, 0);
858         if (br < 0) {
859                 fprintf(stderr, "SERVER: recv(): %i", net_error);
860             close(s);
861             close(sock);
862             exit(42);
863         }
864
865         strncpy(ipstr, inet_ntoa(from.sin_addr), sizeof (ipstr));
866         printf("SERVER: Got data from [%s].\n", ipstr);
867
868         if (br != NETPKTBUFSIZE) {
869             printf("SERVER: Bogus packet.\n");
870             continue;
871         }
872
873         bufToPacket(buf, &pkt);
874         if (pkt.cmd != NETCMD_HELLO) {
875             printf("SERVER: Bogus packet.\n");
876             continue;
877         }
878
879         printf("SERVER: Client claims to be player #%ld.\n", pkt.arg);
880
881         if (pkt.arg > (sizeof (player) / sizeof (player[0]))) {
882             printf("SERVER:  (that's an invalid player number.)\n");
883         } else {
884             if (player[pkt.arg].enabled) {
885                 printf("SERVER:  (that player number is already taken.)\n");
886             } else {
887                 negatory = 0;
888             }
889         }
890
891         if (negatory) {
892             printf("SERVER: Forbidding connection.\n");
893             pkt.cmd = NETCMD_NACK;
894             sendPacketToSock(s, &pkt);
895             close(s);
896         } else {
897             player[pkt.arg].enabled = 1;
898             net_info[pkt.arg].sock = s;
899             net_info[pkt.arg].addr = malloc(fromlen);
900             memcpy(net_info[pkt.arg].addr, &from, fromlen);
901             net_info[pkt.arg].addrlen = fromlen;
902             /*memcpy(&net_info[pkt.arg].last_timestamp, &pkt.timestamp, sizeof (pkt.timestamp));*/
903             wait_for_clients--;
904             printf("SERVER: Granting connection. (%d) to go.\n", wait_for_clients);
905             pkt.cmd = NETCMD_ACK;
906             sendPacket(pkt.arg, &pkt);
907         }
908     }
909
910     close(sock);  /* done with the listen socket. */
911     sock = -1;
912
913     printf("SERVER: Got all our connections. Greenlighting clients...\n");
914
915     pkt.cmd = NETCMD_GREENLIGHT;
916     pkt.arg = 0;
917     for (i = 0; i < (sizeof (net_info) / sizeof (net_info[0])); i++) {
918         if (player[i].enabled) {
919             pkt.arg |= (1 << i);
920         }
921     }
922     sendPacketToAll(&pkt);
923 #endif
924 }
925
926
927 void connect_to_server(char *netarg)
928 {
929 #ifdef USE_NET
930     NetPacket pkt;
931     char buf[NETPKTBUFSIZE];
932     char ipstr[128];
933     struct hostent *hent;
934     struct sockaddr_in addr;
935     struct in_addr inaddr;
936     int addrlen;
937     int br;
938 #ifdef _MSC_VER
939 WORD wVersionRequested;
940 WSADATA wsaData;
941 int err;
942  
943 wVersionRequested = MAKEWORD( 2, 2 );
944  
945 err = WSAStartup( wVersionRequested, &wsaData );
946 if ( err != 0 ) {
947     /* Tell the user that we could not find a usable */
948     /* WinSock DLL.                                  */
949         fprintf(stderr, "SERVER: WSAStartup failed!");
950     return;
951 }
952 #endif
953
954     if (netarg == NULL) {
955         printf("CLIENT: Need to specify host to connect to.\n");
956         exit(42);
957     }
958
959     player[client_player_num].enabled = 1;
960     gethostname(ipstr, sizeof (ipstr));
961     hent = gethostbyname(ipstr);
962     if (hent != NULL) {
963         net_info[client_player_num].addr = malloc(hent->h_length);
964         memcpy(&net_info[client_player_num].addr, &hent->h_addr, hent->h_length);
965         net_info[client_player_num].addrlen = hent->h_length;
966         memcpy(&inaddr, hent->h_addr, hent->h_length);
967         strncpy(ipstr, inet_ntoa(inaddr), sizeof (ipstr));
968     }
969     printf("CLIENT: we are [%s].\n", ipstr);
970
971     /*gettimeofday(&net_info[client_player_num].last_timestamp, NULL);*/
972
973     hent = gethostbyname(netarg);
974     if (hent == NULL) {
975                 fprintf(stderr, "CLIENT: couldn't find host: %i", net_error);
976         //perror("CLIENT: couldn't find host");
977         exit(42);
978     }
979
980     sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
981     if (sock < 0) {
982                 fprintf(stderr, "CLIENT: socket(): %i", net_error);
983         //perror("CLIENT: socket()");
984         exit(42);
985     }
986
987     memcpy(&inaddr, hent->h_addr, hent->h_length);
988     printf("CLIENT: connecting to [%s]...\n", inet_ntoa(inaddr));
989
990     addr.sin_family = AF_INET;
991     addr.sin_port = htons(JNB_INETPORT);
992     memcpy(&addr.sin_addr.s_addr, hent->h_addr, hent->h_length);
993     if (connect(sock, (struct sockaddr *) &addr, sizeof (addr)) == -1) {
994                 fprintf(stderr, "CLIENT: connect(): %i", net_error);
995         //perror("CLIENT: connect()");
996         exit(42);
997     }
998
999     printf("CLIENT: Got socket. Sending HELLO packet...\n");
1000     pkt.cmd = NETCMD_HELLO;
1001     pkt.arg = client_player_num;
1002     sendPacketToSock(sock, &pkt);
1003
1004     printf("CLIENT: Waiting for ACK from server...\n");
1005     
1006     addrlen = sizeof (addr);
1007     br = recv(sock, buf, NETPKTBUFSIZE, 0);
1008     if (br < 0) {
1009                 fprintf(stderr, "CLIENT: recv(): %i", net_error);
1010         //perror("CLIENT: recv()");
1011         close(sock);
1012         exit(42);
1013     }
1014
1015     if (br != NETPKTBUFSIZE) {
1016         printf("CLIENT: Bogus packet size (%d of %d). FIXME.\n",
1017                 br, NETPKTBUFSIZE);
1018         close(sock);
1019         exit(42);
1020     }
1021
1022     bufToPacket(buf, &pkt);
1023
1024     if (pkt.cmd == NETCMD_NACK) {
1025         printf("CLIENT: Server forbid us from playing.\n");
1026         close(sock);
1027         exit(42);
1028     }
1029
1030     if (pkt.cmd != NETCMD_ACK) {
1031         printf("CLIENT: Unexpected packet (cmd=0x%lX).\n", pkt.cmd);
1032         close(sock);
1033         exit(42);
1034     }
1035
1036     printf("CLIENT: Server accepted our connection.\n");
1037
1038     wait_for_greenlight();
1039 #endif
1040 }
1041 #endif // USE_NET
1042
1043
1044 static flip_pixels(unsigned char *pixels)
1045 {
1046         int x,y;
1047         unsigned char temp;
1048
1049         assert(pixels);
1050         for (y = 0; y < JNB_HEIGHT; y++) {
1051                 for (x = 0; x < (352/2); x++) {
1052                         temp = pixels[y*JNB_WIDTH+x];
1053                         pixels[y*JNB_WIDTH+x] = pixels[y*JNB_WIDTH+(352-x)-1];
1054                         pixels[y*JNB_WIDTH+(352-x)-1] = temp;
1055                 }
1056         }
1057 }
1058
1059
1060 int main(int argc, char *argv[])
1061 {
1062         unsigned char *handle;
1063         int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
1064         int l1;
1065         int s1, s2, s3, s4;
1066         int closest_player = 0, dist, cur_dist = 0;
1067         int end_loop_flag = 0, fade_flag;
1068         int mod_vol, sfx_vol, mod_fade_direction;
1069         char str1[100];
1070         char pal[768];
1071         char cur_pal[768];
1072         int update_count;
1073
1074         if (init_program(argc, argv, pal) != 0)
1075                 deinit_program();
1076
1077         if (main_info.fireworks == 1) {
1078                 fireworks();
1079                 deinit_program();
1080         }
1081
1082         while (1) {
1083
1084                 if (!is_net)
1085                         if (menu() != 0)
1086                                 deinit_program();
1087
1088                 if (key_pressed(1) == 1) {
1089                         break;
1090                 }
1091                 if (init_level(0, pal) != 0) {
1092                         deinit_level();
1093                         deinit_program();
1094                 }
1095
1096                 memset(cur_pal, 0, 768);
1097                 setpalette(0, 256, cur_pal);
1098
1099                 recalculate_gob(&rabbit_gobs, pal);
1100                 //recalculate_gob(&font_gobs, pal);
1101                 recalculate_gob(&object_gobs, pal);
1102                 recalculate_gob(&number_gobs, pal);
1103
1104                 flippage(1);
1105                 register_background(background_pic, pal);
1106                 flippage(0);
1107
1108                 if (flies_enabled) {
1109                         s1 = rnd(250) + 50;
1110                         s2 = rnd(150) + 50;
1111
1112                         for (c1 = 0; c1 < NUM_FLIES; c1++) {
1113                                 while (1) {
1114                                         flies[c1].x = s1 + rnd(101) - 50;
1115                                         flies[c1].y = s2 + rnd(101) - 50;
1116                                         if (ban_map[flies[c1].y >> 4][flies[c1].x >> 4] == BAN_VOID)
1117                                                 break;
1118                                 }
1119                                 flies[c1].back_defined[0] = 0;
1120                                 flies[c1].back_defined[1] = 0;
1121                         }
1122                 }
1123
1124                 mod_vol = sfx_vol = 10;
1125                 mod_fade_direction = 1;
1126                 dj_ready_mod(MOD_GAME);
1127                 dj_set_mod_volume((char)mod_vol);
1128                 dj_set_sfx_volume((char)mod_vol);
1129                 dj_start_mod();
1130
1131                 if (flies_enabled)
1132                         dj_play_sfx(SFX_FLY, SFX_FLY_FREQ, 0, 0, 0, 4);
1133
1134                 dj_set_nosound(0);
1135
1136                 lord_of_the_flies = bunnies_in_space = jetpack = pogostick = blood_is_thicker_than_water = 0;
1137                 end_loop_flag = 0;
1138                 main_info.page_info[0].num_pobs = 0;
1139                 main_info.page_info[1].num_pobs = 0;
1140                 main_info.view_page = 0;
1141                 main_info.draw_page = 1;
1142
1143                 update_count = 1;
1144                 while (1) {
1145                         while (update_count) {
1146
1147                                 if (key_pressed(1) == 1) {
1148 #ifdef USE_NET
1149                                         if (is_net) {
1150                                                 if (is_server) {
1151                                                         serverTellEveryoneGoodbye();
1152                                                 } else {
1153                                                         tellServerGoodbye();
1154                                                 }
1155                                         }
1156 #endif
1157                                         end_loop_flag = 1;
1158                                         memset(pal, 0, 768);
1159                                         mod_fade_direction = 0;
1160                                 }
1161
1162                                 if (strncmp(last_keys, "kcitsogop", strlen("kcitsogop")) == 0) {
1163                                         pogostick ^= 1;
1164                                         last_keys[0] = 0;
1165                                 }
1166                                 if (strncmp(last_keys, "ecapsniseinnub", strlen("ecapsniseinnub")) == 0) {
1167                                         bunnies_in_space ^= 1;
1168                                         last_keys[0] = 0;
1169                                 }
1170                                 if (strncmp(last_keys, "kcaptej", strlen("kcaptej")) == 0) {
1171                                         jetpack ^= 1;
1172                                         last_keys[0] = 0;
1173                                 }
1174                                 if (strncmp(last_keys, "seilfehtfodrol", strlen("seilfehtfodrol")) == 0) {
1175                                         lord_of_the_flies ^= 1;
1176                                         last_keys[0] = 0;
1177                                 }
1178                                 if (strncmp(last_keys, "retawnahtrekcihtsidoolb", strlen("retawnahtrekcihtsidoolb")) == 0) {
1179                                         blood_is_thicker_than_water ^= 1;
1180                                         if (blood_is_thicker_than_water == 1) {
1181                                                 pal[432] = 63;
1182                                                 pal[433] = 32;
1183                                                 pal[434] = 32;
1184                                                 pal[435] = 53;
1185                                                 pal[436] = 17;
1186                                                 pal[437] = 17;
1187                                                 pal[438] = 42;
1188                                                 pal[439] = 7;
1189                                                 pal[440] = 7;
1190                                                 pal[441] = 28;
1191                                                 pal[442] = 0;
1192                                                 pal[443] = 0;
1193                                                 pal[444] = 24;
1194                                                 pal[445] = 0;
1195                                                 pal[446] = 0;
1196                                                 pal[447] = 19;
1197                                                 pal[448] = 0;
1198                                                 pal[449] = 0;
1199                                                 pal[450] = 12;
1200                                                 pal[451] = 0;
1201                                                 pal[452] = 0;
1202                                                 pal[453] = 7;
1203                                                 pal[454] = 0;
1204                                                 pal[455] = 0;
1205                                         } else {
1206                                                 pal[432] = 63;
1207                                                 pal[433] = 63;
1208                                                 pal[434] = 63;
1209                                                 pal[435] = 40;
1210                                                 pal[436] = 53;
1211                                                 pal[437] = 62;
1212                                                 pal[438] = 19;
1213                                                 pal[439] = 42;
1214                                                 pal[440] = 60;
1215                                                 pal[441] = 0;
1216                                                 pal[442] = 33;
1217                                                 pal[443] = 60;
1218                                                 pal[444] = 3;
1219                                                 pal[445] = 32;
1220                                                 pal[446] = 46;
1221                                                 pal[447] = 3;
1222                                                 pal[448] = 26;
1223                                                 pal[449] = 33;
1224                                                 pal[450] = 3;
1225                                                 pal[451] = 19;
1226                                                 pal[452] = 21;
1227                                                 pal[453] = 1;
1228                                                 pal[454] = 8;
1229                                                 pal[455] = 8;
1230                                         }
1231                                         register_background(background_pic, pal);
1232                                         recalculate_gob(&object_gobs, pal);
1233                                         last_keys[0] = 0;
1234                                 }
1235
1236 #ifdef USE_NET
1237                                 if (is_net) {
1238                                         if (is_server) {
1239                                                 update_players_from_clients();
1240                                         } else {
1241                                                 if (!update_players_from_server()) {
1242                                                         break;  /* got a BYE packet */
1243                                                 }
1244                                         }
1245                                 }
1246 #endif
1247
1248                                 steer_players();
1249
1250                                 dj_mix();
1251
1252                                 for (c3 = 0; c3 < 6; c3++) {
1253                                         if (c3 == 0) {
1254                                                 c1 = 0;
1255                                                 c2 = 1;
1256                                         } else if (c3 == 1) {
1257                                                 c1 = 0;
1258                                                 c2 = 2;
1259                                         } else if (c3 == 2) {
1260                                                 c1 = 0;
1261                                                 c2 = 3;
1262                                         } else if (c3 == 3) {
1263                                                 c1 = 1;
1264                                                 c2 = 2;
1265                                         } else if (c3 == 4) {
1266                                                 c1 = 1;
1267                                                 c2 = 3;
1268                                         } else if (c3 == 5) {
1269                                                 c1 = 2;
1270                                                 c2 = 3;
1271                                         }
1272                                         if (player[c1].enabled == 1 && player[c2].enabled == 1) {
1273                                                 if (labs(player[c1].x - player[c2].x) < (12L << 16) && labs(player[c1].y - player[c2].y) < (12L << 16)) {
1274                                                         if ((labs(player[c1].y - player[c2].y) >> 16) > 5) {
1275                                                                 if (player[c1].y < player[c2].y) {
1276                                                                         if (player[c1].y_add >= 0) {
1277                                                                                 if (is_server)
1278                                                                                         serverSendKillPacket(c1, c2);
1279                                                                         } else {
1280                                                                                 if (player[c2].y_add < 0)
1281                                                                                         player[c2].y_add = 0;
1282                                                                         }
1283                                                                 } else {
1284                                                                         if (player[c2].y_add >= 0) {
1285                                                                                 if (is_server)
1286                                                                                         serverSendKillPacket(c2, c1);
1287                                                                         } else {
1288                                                                                 if (player[c1].y_add < 0)
1289                                                                                         player[c1].y_add = 0;
1290                                                                         }
1291                                                                 }
1292                                                         } else {
1293                                                                 if (player[c1].x < player[c2].x) {
1294                                                                         if (player[c1].x_add > 0)
1295                                                                                 player[c1].x = player[c2].x - (12L << 16);
1296                                                                         else if (player[c2].x_add < 0)
1297                                                                                 player[c2].x = player[c1].x + (12L << 16);
1298                                                                         else {
1299                                                                                 player[c1].x -= player[c1].x_add;
1300                                                                                 player[c2].x -= player[c2].x_add;
1301                                                                         }
1302                                                                         l1 = player[c2].x_add;
1303                                                                         player[c2].x_add = player[c1].x_add;
1304                                                                         player[c1].x_add = l1;
1305                                                                         if (player[c1].x_add > 0)
1306                                                                                 player[c1].x_add = -player[c1].x_add;
1307                                                                         if (player[c2].x_add < 0)
1308                                                                                 player[c2].x_add = -player[c2].x_add;
1309                                                                 } else {
1310                                                                         if (player[c1].x_add > 0)
1311                                                                                 player[c2].x = player[c1].x - (12L << 16);
1312                                                                         else if (player[c2].x_add < 0)
1313                                                                                 player[c1].x = player[c2].x + (12L << 16);
1314                                                                         else {
1315                                                                                 player[c1].x -= player[c1].x_add;
1316                                                                                 player[c2].x -= player[c2].x_add;
1317                                                                         }
1318                                                                         l1 = player[c2].x_add;
1319                                                                         player[c2].x_add = player[c1].x_add;
1320                                                                         player[c1].x_add = l1;
1321                                                                         if (player[c1].x_add < 0)
1322                                                                                 player[c1].x_add = -player[c1].x_add;
1323                                                                         if (player[c2].x_add > 0)
1324                                                                                 player[c2].x_add = -player[c2].x_add;
1325                                                                 }
1326                                                         }
1327                                                 }
1328                                         }
1329                                 }
1330
1331                                 dj_mix();
1332
1333                                 main_info.page_info[main_info.draw_page].num_pobs = 0;
1334                                 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1335                                         if (player[c1].enabled == 1)
1336                                                 main_info.page_info[main_info.draw_page].num_pobs++;
1337                                 }
1338
1339                                 update_objects();
1340
1341                                 dj_mix();
1342
1343                                 if (flies_enabled) {
1344                                         /* get center of fly swarm */
1345                                         s1 = s2 = 0;
1346                                         for (c1 = 0; c1 < NUM_FLIES; c1++) {
1347                                                 s1 += flies[c1].x;
1348                                                 s2 += flies[c1].y;
1349                                         }
1350                                         s1 /= NUM_FLIES;
1351                                         s2 /= NUM_FLIES;
1352
1353                                         if (update_count == 1) {
1354                                                 /* get closest player to fly swarm */
1355                                                 dist = 0x7fff;
1356                                                 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1357                                                         if (player[c1].enabled == 1) {
1358                                                                 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)));
1359                                                                 if (cur_dist < dist) {
1360                                                                         closest_player = c1;
1361                                                                         dist = cur_dist;
1362                                                                 }
1363                                                         }
1364                                                 }
1365                                                 /* update fly swarm sound */
1366                                                 s3 = 32 - dist / 3;
1367                                                 if (s3 < 0)
1368                                                         s3 = 0;
1369                                                 dj_set_sfx_channel_volume(4, (char)(s3));
1370                                         }
1371
1372                                         for (c1 = 0; c1 < NUM_FLIES; c1++) {
1373                                                 /* get closest player to fly */
1374                                                 dist = 0x7fff;
1375                                                 for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
1376                                                         if (player[c2].enabled == 1) {
1377                                                                 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)));
1378                                                                 if (cur_dist < dist) {
1379                                                                         closest_player = c2;
1380                                                                         dist = cur_dist;
1381                                                                 }
1382                                                         }
1383                                                 }
1384                                                 flies[c1].old_x = flies[c1].x;
1385                                                 flies[c1].old_y = flies[c1].y;
1386                                                 s3 = 0;
1387                                                 if ((s1 - flies[c1].x) > 30)
1388                                                         s3 += 1;
1389                                                 else if ((s1 - flies[c1].x) < -30)
1390                                                         s3 -= 1;
1391                                                 if (dist < 30) {
1392                                                         if (((player[closest_player].x >> 16) + 8) > flies[c1].x) {
1393                                                                 if (lord_of_the_flies == 0)
1394                                                                         s3 -= 1;
1395                                                                 else
1396                                                                         s3 += 1;
1397                                                         } else {
1398                                                                 if (lord_of_the_flies == 0)
1399                                                                         s3 += 1;
1400                                                                 else
1401                                                                         s3 -= 1;
1402                                                         }
1403                                                 }
1404                                                 s4 = rnd(3) - 1 + s3;
1405                                                 if ((flies[c1].x + s4) < 16)
1406                                                         s4 = 0;
1407                                                 if ((flies[c1].x + s4) > 351)
1408                                                         s4 = 0;
1409                                                 if (ban_map[flies[c1].y >> 4][(flies[c1].x + s4) >> 4] != BAN_VOID)
1410                                                         s4 = 0;
1411                                                 flies[c1].x += s4;
1412                                                 s3 = 0;
1413                                                 if ((s2 - flies[c1].y) > 30)
1414                                                         s3 += 1;
1415                                                 else if ((s2 - flies[c1].y) < -30)
1416                                                         s3 -= 1;
1417                                                 if (dist < 30) {
1418                                                         if (((player[closest_player].y >> 16) + 8) > flies[c1].y) {
1419                                                                 if (lord_of_the_flies == 0)
1420                                                                         s3 -= 1;
1421                                                                 else
1422                                                                         s3 += 1;
1423                                                         } else {
1424                                                                 if (lord_of_the_flies == 0)
1425                                                                         s3 += 1;
1426                                                                 else
1427                                                                         s3 -= 1;
1428                                                         }
1429                                                 }
1430                                                 s4 = rnd(3) - 1 + s3;
1431                                                 if ((flies[c1].y + s4) < 0)
1432                                                         s4 = 0;
1433                                                 if ((flies[c1].y + s4) > 239)
1434                                                         s4 = 0;
1435                                                 if (ban_map[(flies[c1].y + s4) >> 4][flies[c1].x >> 4] != BAN_VOID)
1436                                                         s4 = 0;
1437                                                 flies[c1].y += s4;
1438                                         }
1439                                 }
1440
1441                                 dj_mix();
1442
1443                                 s1 = 0;
1444                                 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1445                                         if (player[c1].enabled == 1) {
1446                                                 main_info.page_info[main_info.draw_page].pobs[s1].x = player[c1].x >> 16;
1447                                                 main_info.page_info[main_info.draw_page].pobs[s1].y = player[c1].y >> 16;
1448                                                 main_info.page_info[main_info.draw_page].pobs[s1].image = player[c1].image + c1 * 18;
1449                                                 main_info.page_info[main_info.draw_page].pobs[s1].pob_data = &rabbit_gobs;
1450                                                 s1++;
1451                                         }
1452                                 }
1453
1454                                 if (update_count == 1) {
1455                                         draw_begin();
1456
1457                                         draw_pobs(main_info.draw_page);
1458
1459                                         dj_mix();
1460
1461                                         if (flies_enabled)
1462                                                 draw_flies(main_info.draw_page);
1463
1464                                         draw_end();
1465                                 }
1466
1467                                 if (mod_fade_direction == 1) {
1468                                         if (mod_vol < 30) {
1469                                                 mod_vol++;
1470                                                 dj_set_mod_volume((char)mod_vol);
1471                                         }
1472                                 } else {
1473                                         if (mod_vol > 0) {
1474                                                 mod_vol--;
1475                                                 dj_set_mod_volume((char)mod_vol);
1476                                         }
1477                                 }
1478
1479                                 if (mod_fade_direction == 1) {
1480                                         if (sfx_vol < 64) {
1481                                                 sfx_vol++;
1482                                                 dj_set_sfx_volume((char)sfx_vol);
1483                                         }
1484                                 } else {
1485                                         if (sfx_vol > 0) {
1486                                                 sfx_vol--;
1487                                                 dj_set_sfx_volume((char)sfx_vol);
1488                                         }
1489                                 }
1490
1491                                 fade_flag = 0;
1492                                 for (c1 = 0; c1 < 768; c1++) {
1493                                         if (cur_pal[c1] < pal[c1]) {
1494                                                 cur_pal[c1]++;
1495                                                 fade_flag = 1;
1496                                         } else if (cur_pal[c1] > pal[c1]) {
1497                                                 cur_pal[c1]--;
1498                                                 fade_flag = 1;
1499                                         }
1500                                 }
1501                                 if (fade_flag == 0 && end_loop_flag == 1)
1502                                         break;
1503
1504                                 if (update_count == 1) {
1505                                         main_info.draw_page ^= 1;
1506                                         main_info.view_page ^= 1;
1507
1508                                         flippage(main_info.view_page);
1509         
1510                                         wait_vrt(1);
1511                                 }
1512
1513                                 if (fade_flag == 1)
1514                                         setpalette(0, 256, cur_pal);
1515
1516                                 if (update_count == 1) {
1517                                         draw_begin();
1518
1519                                         if (flies_enabled)
1520                                                 redraw_flies_background(main_info.draw_page);
1521
1522                                         redraw_pob_backgrounds(main_info.draw_page);
1523
1524                                         draw_leftovers(main_info.draw_page);
1525
1526                                         draw_end();
1527                                 }
1528
1529                                 update_count--;
1530                         }
1531
1532 #ifdef USE_NET
1533                         if (is_net) {
1534                                 if ( (player[client_player_num].dead_flag == 0) &&
1535                                         (
1536                                          (player[client_player_num].action_left) ||
1537                                          (player[client_player_num].action_right) ||
1538                                          (player[client_player_num].action_up) ||
1539                                          (player[client_player_num].jump_ready == 0)
1540                                         )
1541                                    ) {
1542                                         tellServerNewPosition();
1543                                 }
1544                         }
1545 #endif
1546
1547                         update_count = intr_sysupdate();
1548
1549 #ifdef USE_NET
1550                         if (is_net) {
1551                                 if ((server_said_bye) || ((fade_flag == 0) && (end_loop_flag == 1)))
1552                                         break;
1553                         } else
1554 #endif
1555                         if ((fade_flag == 0) && (end_loop_flag == 1))
1556                                 break;
1557                 }
1558
1559 #ifdef USE_NET
1560                 if (is_net) {
1561                         if (is_server) {
1562                                 serverTellEveryoneGoodbye();
1563                                 close(sock);
1564                                 sock = -1;
1565                         } else {
1566                                 if (!server_said_bye) {
1567                                         tellServerGoodbye();
1568                                 }
1569
1570                                 close(sock);
1571                                 sock = -1;
1572                         }
1573                 }
1574 #endif
1575                 
1576                 main_info.view_page = 0;
1577                 main_info.draw_page = 1;
1578
1579                 dj_stop_sfx_channel(4);
1580
1581                 deinit_level();
1582
1583                 memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
1584                 register_mask(mask_pic);
1585
1586                 //recalculate_gob(&font_gobs, pal);
1587                 register_background(NULL, NULL);
1588
1589                 draw_begin();
1590
1591                 put_text(main_info.view_page, 100, 50, "DOTT", 2);
1592                 put_text(main_info.view_page, 160, 50, "JIFFY", 2);
1593                 put_text(main_info.view_page, 220, 50, "FIZZ", 2);
1594                 put_text(main_info.view_page, 280, 50, "MIJJI", 2);
1595                 put_text(main_info.view_page, 40, 80, "DOTT", 2);
1596                 put_text(main_info.view_page, 40, 110, "JIFFY", 2);
1597                 put_text(main_info.view_page, 40, 140, "FIZZ", 2);
1598                 put_text(main_info.view_page, 40, 170, "MIJJI", 2);
1599
1600                 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1601                         for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++) {
1602                                 if (c2 != c1) {
1603                                         sprintf(str1, "%d", player[c1].bumped[c2]);
1604                                         put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, str1, 2);
1605                                 } else
1606                                         put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, "-", 2);
1607                         }
1608                         sprintf(str1, "%d", player[c1].bumps);
1609                         put_text(main_info.view_page, 350, 80 + c1 * 30, str1, 2);
1610                 }
1611
1612                 put_text(main_info.view_page, 200, 230, "Press ESC to continue", 2);
1613
1614                 draw_end();
1615
1616                 flippage(main_info.view_page);
1617
1618                 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
1619                         strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1620                         return 1;
1621                 }
1622                 if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
1623                         strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1624                         return 1;
1625                 }
1626
1627                 for (c1 = 0; c1 < 16; c1++) { // fix dark font
1628                         pal[(240 + c1) * 3 + 0] = c1 << 2;
1629                         pal[(240 + c1) * 3 + 1] = c1 << 2;
1630                         pal[(240 + c1) * 3 + 2] = c1 << 2;
1631                 }
1632
1633                 memset(cur_pal, 0, 768);
1634
1635                 setpalette(0, 256, cur_pal);
1636
1637                 mod_vol = 0;
1638                 dj_ready_mod(MOD_SCORES);
1639                 dj_set_mod_volume((char)mod_vol);
1640                 dj_start_mod();
1641                 dj_set_nosound(0);
1642
1643                 while (key_pressed(1) == 0) {
1644                         if (mod_vol < 35)
1645                                 mod_vol++;
1646                         dj_set_mod_volume((char)mod_vol);
1647                         for (c1 = 0; c1 < 768; c1++) {
1648                                 if (cur_pal[c1] < pal[c1])
1649                                         cur_pal[c1]++;
1650                         }
1651                         dj_mix();
1652                         intr_sysupdate();
1653                         wait_vrt(0);
1654                         setpalette(0, 256, cur_pal);
1655                         flippage(main_info.view_page);
1656                 }
1657                 while (key_pressed(1) == 1) {
1658                         dj_mix();
1659                         intr_sysupdate();
1660                 }
1661
1662                 memset(pal, 0, 768);
1663
1664                 while (mod_vol > 0) {
1665                         mod_vol--;
1666                         dj_set_mod_volume((char)mod_vol);
1667                         for (c1 = 0; c1 < 768; c1++) {
1668                                 if (cur_pal[c1] > pal[c1])
1669                                         cur_pal[c1]--;
1670                         }
1671                         dj_mix();
1672                         wait_vrt(0);
1673                         setpalette(0, 256, cur_pal);
1674                         flippage(main_info.view_page);
1675                 }
1676
1677                 fillpalette(0, 0, 0);
1678
1679                 dj_set_nosound(1);
1680                 dj_stop_mod();
1681
1682                 if (is_net)
1683                         break; /* don't go back to menu if in net game. */
1684         }
1685
1686         deinit_program();
1687
1688         return 0;
1689 }
1690
1691
1692 void steer_players(void)
1693 {
1694         int c1, c2;
1695         int s1 = 0, s2 = 0;
1696
1697         update_player_actions();
1698
1699         for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
1700
1701                 if (player[c1].enabled == 1) {
1702
1703                         if (player[c1].dead_flag == 0) {
1704
1705                                 if (player[c1].action_left && player[c1].action_right) {
1706                                         if (player[c1].direction == 0) {
1707                                                 if (player[c1].action_right) {
1708                                                         s1 = (player[c1].x >> 16);
1709                                                         s2 = (player[c1].y >> 16);
1710                                                         if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1711                                                                 if (player[c1].x_add < 0)
1712                                                                         player[c1].x_add += 1024;
1713                                                                 else
1714                                                                         player[c1].x_add += 768;
1715                                                         } else if ((ban_map[(s2 + 16) >> 4][s1 >> 4] != BAN_SOLID && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_ICE) || (ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_ICE && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] != BAN_SOLID)) {
1716                                                                 if (player[c1].x_add > 0)
1717                                                                         player[c1].x_add += 1024;
1718                                                                 else
1719                                                                         player[c1].x_add += 768;
1720                                                         } else {
1721                                                                 if (player[c1].x_add < 0) {
1722                                                                         player[c1].x_add += 16384;
1723                                                                         if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1724                                                                                 add_object(OBJ_SMOKE, (player[c1].x >> 16) + 2 + rnd(9), (player[c1].y >> 16) + 13 + rnd(5), 0, -16384 - rnd(8192), OBJ_ANIM_SMOKE, 0);
1725                                                                 } else
1726                                                                         player[c1].x_add += 12288;
1727                                                         }
1728                                                         if (player[c1].x_add > 98304L)
1729                                                                 player[c1].x_add = 98304L;
1730                                                         player[c1].direction = 0;
1731                                                         if (player[c1].anim == 0) {
1732                                                                 player[c1].anim = 1;
1733                                                                 player[c1].frame = 0;
1734                                                                 player[c1].frame_tick = 0;
1735                                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1736                                                         }
1737                                                 }
1738                                         } else {
1739                                                 if (player[c1].action_left) {
1740                                                         s1 = (player[c1].x >> 16);
1741                                                         s2 = (player[c1].y >> 16);
1742                                                         if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1743                                                                 if (player[c1].x_add > 0)
1744                                                                         player[c1].x_add -= 1024;
1745                                                                 else
1746                                                                         player[c1].x_add -= 768;
1747                                                         } 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)) {
1748                                                                 if (player[c1].x_add > 0)
1749                                                                         player[c1].x_add -= 1024;
1750                                                                 else
1751                                                                         player[c1].x_add -= 768;
1752                                                         } else {
1753                                                                 if (player[c1].x_add > 0) {
1754                                                                         player[c1].x_add -= 16384;
1755                                                                         if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1756                                                                                 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);
1757                                                                 } else
1758                                                                         player[c1].x_add -= 12288;
1759                                                         }
1760                                                         if (player[c1].x_add < -98304L)
1761                                                                 player[c1].x_add = -98304L;
1762                                                         player[c1].direction = 1;
1763                                                         if (player[c1].anim == 0) {
1764                                                                 player[c1].anim = 1;
1765                                                                 player[c1].frame = 0;
1766                                                                 player[c1].frame_tick = 0;
1767                                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1768                                                         }
1769                                                 }
1770                                         }
1771                                 } else if (player[c1].action_left) {
1772                                         s1 = (player[c1].x >> 16);
1773                                         s2 = (player[c1].y >> 16);
1774                                         if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1775                                                 if (player[c1].x_add > 0)
1776                                                         player[c1].x_add -= 1024;
1777                                                 else
1778                                                         player[c1].x_add -= 768;
1779                                         } 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)) {
1780                                                 if (player[c1].x_add > 0)
1781                                                         player[c1].x_add -= 1024;
1782                                                 else
1783                                                         player[c1].x_add -= 768;
1784                                         } else {
1785                                                 if (player[c1].x_add > 0) {
1786                                                         player[c1].x_add -= 16384;
1787                                                         if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1788                                                                 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);
1789                                                 } else
1790                                                         player[c1].x_add -= 12288;
1791                                         }
1792                                         if (player[c1].x_add < -98304L)
1793                                                 player[c1].x_add = -98304L;
1794                                         player[c1].direction = 1;
1795                                         if (player[c1].anim == 0) {
1796                                                 player[c1].anim = 1;
1797                                                 player[c1].frame = 0;
1798                                                 player[c1].frame_tick = 0;
1799                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1800                                         }
1801                                 } else if (player[c1].action_right) {
1802                                         s1 = (player[c1].x >> 16);
1803                                         s2 = (player[c1].y >> 16);
1804                                         if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
1805                                                 if (player[c1].x_add < 0)
1806                                                         player[c1].x_add += 1024;
1807                                                 else
1808                                                         player[c1].x_add += 768;
1809                                         } 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)) {
1810                                                 if (player[c1].x_add > 0)
1811                                                         player[c1].x_add += 1024;
1812                                                 else
1813                                                         player[c1].x_add += 768;
1814                                         } else {
1815                                                 if (player[c1].x_add < 0) {
1816                                                         player[c1].x_add += 16384;
1817                                                         if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1818                                                                 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);
1819                                                 } else
1820                                                         player[c1].x_add += 12288;
1821                                         }
1822                                         if (player[c1].x_add > 98304L)
1823                                                 player[c1].x_add = 98304L;
1824                                         player[c1].direction = 0;
1825                                         if (player[c1].anim == 0) {
1826                                                 player[c1].anim = 1;
1827                                                 player[c1].frame = 0;
1828                                                 player[c1].frame_tick = 0;
1829                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1830                                         }
1831                                 } else if ((!player[c1].action_left) && (!player[c1].action_right)) {
1832                                         s1 = (player[c1].x >> 16);
1833                                         s2 = (player[c1].y >> 16);
1834                                         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)))) {
1835                                                 if (player[c1].x_add < 0) {
1836                                                         player[c1].x_add += 16384;
1837                                                         if (player[c1].x_add > 0)
1838                                                                 player[c1].x_add = 0;
1839                                                 } else {
1840                                                         player[c1].x_add -= 16384;
1841                                                         if (player[c1].x_add < 0)
1842                                                                 player[c1].x_add = 0;
1843                                                 }
1844                                                 if (player[c1].x_add != 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1845                                                         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);
1846                                         }
1847                                         if (player[c1].anim == 1) {
1848                                                 player[c1].anim = 0;
1849                                                 player[c1].frame = 0;
1850                                                 player[c1].frame_tick = 0;
1851                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1852                                         }
1853                                 }
1854                                 if (jetpack == 0) {
1855                                         if (pogostick == 1 || (player[c1].jump_ready == 1 && player[c1].action_up)) {
1856                                                 s1 = (player[c1].x >> 16);
1857                                                 s2 = (player[c1].y >> 16);
1858                                                 if (s2 < -16)
1859                                                         s2 = -16;
1860                                                 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) {
1861                                                         player[c1].y_add = -280000L;
1862                                                         player[c1].anim = 2;
1863                                                         player[c1].frame = 0;
1864                                                         player[c1].frame_tick = 0;
1865                                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1866                                                         player[c1].jump_ready = 0;
1867                                                         player[c1].jump_abort = 1;
1868                                                         if (pogostick == 0)
1869                                                                 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1870                                                         else
1871                                                                 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1872                                                 }
1873                                                 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)) {
1874                                                         player[c1].y_add = -196608L;
1875                                                         player[c1].in_water = 0;
1876                                                         player[c1].anim = 2;
1877                                                         player[c1].frame = 0;
1878                                                         player[c1].frame_tick = 0;
1879                                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1880                                                         player[c1].jump_ready = 0;
1881                                                         player[c1].jump_abort = 1;
1882                                                         if (pogostick == 0)
1883                                                                 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1884                                                         else
1885                                                                 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1886                                                 }
1887                                         }
1888                                         if (pogostick == 0 && (!player[c1].action_up)) {
1889                                                 player[c1].jump_ready = 1;
1890                                                 if (player[c1].in_water == 0 && player[c1].y_add < 0 && player[c1].jump_abort == 1) {
1891                                                         if (bunnies_in_space == 0)
1892                                                                 player[c1].y_add += 32768;
1893                                                         else
1894                                                                 player[c1].y_add += 16384;
1895                                                         if (player[c1].y_add > 0)
1896                                                                 player[c1].y_add = 0;
1897                                                 }
1898                                         }
1899                                 } else {
1900
1901                                         if (player[c1].action_up) {
1902                                                 player[c1].y_add -= 16384;
1903                                                 if (player[c1].y_add < -400000L)
1904                                                         player[c1].y_add = -400000L;
1905                                                 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))
1906                                                         player[c1].in_water = 0;
1907                                                 if (rnd(100) < 50)
1908                                                         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);
1909                                         }
1910
1911                                 }
1912
1913                                 player[c1].x += player[c1].x_add;
1914                                 if ((player[c1].x >> 16) < 0) {
1915                                         player[c1].x = 0;
1916                                         player[c1].x_add = 0;
1917                                 }
1918                                 if ((player[c1].x >> 16) + 15 > 351) {
1919                                         player[c1].x = 336L << 16;
1920                                         player[c1].x_add = 0;
1921                                 }
1922                                 if (player[c1].y > 0) {
1923                                         s1 = (player[c1].x >> 16);
1924                                         s2 = (player[c1].y >> 16);
1925                                         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) {
1926                                                 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1927                                                 player[c1].x_add = 0;
1928                                         }
1929                                         s1 = (player[c1].x >> 16);
1930                                         s2 = (player[c1].y >> 16);
1931                                         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) {
1932                                                 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1933                                                 player[c1].x_add = 0;
1934                                         }
1935                                 } else {
1936                                         s1 = (player[c1].x >> 16);
1937                                         s2 = 0;
1938                                         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) {
1939                                                 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1940                                                 player[c1].x_add = 0;
1941                                         }
1942                                         s1 = (player[c1].x >> 16);
1943                                         s2 = 0;
1944                                         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) {
1945                                                 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1946                                                 player[c1].x_add = 0;
1947                                         }
1948                                 }
1949
1950                                 player[c1].y += player[c1].y_add;
1951
1952                                 s1 = (player[c1].x >> 16);
1953                                 s2 = (player[c1].y >> 16);
1954                                 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))) {
1955                                         player[c1].y = ((player[c1].y >> 16) & 0xfff0) << 16;
1956                                         player[c1].y_add = -400000L;
1957                                         player[c1].anim = 2;
1958                                         player[c1].frame = 0;
1959                                         player[c1].frame_tick = 0;
1960                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1961                                         player[c1].jump_ready = 0;
1962                                         player[c1].jump_abort = 0;
1963                                         for (c2 = 0; c2 < NUM_OBJECTS; c2++) {
1964                                                 if (objects[c2].used == 1 && objects[c2].type == OBJ_SPRING) {
1965                                                         if (ban_map[(s2 + 15) >> 4][(s1 + 8) >> 4] == BAN_SPRING) {
1966                                                                 if ((objects[c2].x >> 20) == ((s1 + 8) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1967                                                                         objects[c2].frame = 0;
1968                                                                         objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1969                                                                         objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1970                                                                         break;
1971                                                                 }
1972                                                         } else {
1973                                                                 if (ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
1974                                                                         if ((objects[c2].x >> 20) == (s1 >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1975                                                                                 objects[c2].frame = 0;
1976                                                                                 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1977                                                                                 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1978                                                                                 break;
1979                                                                         }
1980                                                                 } else if (ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1981                                                                         if ((objects[c2].x >> 20) == ((s1 + 15) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1982                                                                                 objects[c2].frame = 0;
1983                                                                                 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1984                                                                                 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1985                                                                                 break;
1986                                                                         }
1987                                                                 }
1988                                                         }
1989                                                 }
1990                                         }
1991                                         dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1992                                 }
1993                                 s1 = (player[c1].x >> 16);
1994                                 s2 = (player[c1].y >> 16);
1995                                 if (s2 < 0)
1996                                         s2 = 0;
1997                                 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) {
1998                                         player[c1].y = (((s2 + 16) & 0xfff0)) << 16;
1999                                         player[c1].y_add = 0;
2000                                         player[c1].anim = 0;
2001                                         player[c1].frame = 0;
2002                                         player[c1].frame_tick = 0;
2003                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
2004                                 }
2005                                 s1 = (player[c1].x >> 16);
2006                                 s2 = (player[c1].y >> 16);
2007                                 if (s2 < 0)
2008                                         s2 = 0;
2009                                 if (ban_map[(s2 + 8) >> 4][(s1 + 8) >> 4] == BAN_WATER) {
2010                                         if (player[c1].in_water == 0) {
2011                                                 player[c1].in_water = 1;
2012                                                 player[c1].anim = 4;
2013                                                 player[c1].frame = 0;
2014                                                 player[c1].frame_tick = 0;
2015                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
2016                                                 if (player[c1].y_add >= 32768) {
2017                                                         add_object(OBJ_SPLASH, (player[c1].x >> 16) + 8, ((player[c1].y >> 16) & 0xfff0) + 15, 0, 0, OBJ_ANIM_SPLASH, 0);
2018                                                         if (blood_is_thicker_than_water == 0)
2019                                                                 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
2020                                                         else
2021                                                                 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 5000), 64, 0, 0, -1);
2022                                                 }
2023                                         }
2024                                         player[c1].y_add -= 1536;
2025                                         if (player[c1].y_add < 0 && player[c1].anim != 5) {
2026                                                 player[c1].anim = 5;
2027                                                 player[c1].frame = 0;
2028                                                 player[c1].frame_tick = 0;
2029                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
2030                                         }
2031                                         if (player[c1].y_add < -65536L)
2032                                                 player[c1].y_add = -65536L;
2033                                         if (player[c1].y_add > 65535L)
2034                                                 player[c1].y_add = 65535L;
2035                                         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) {
2036                                                 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
2037                                                 player[c1].y_add = 0;
2038                                         }
2039                                 } 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) {
2040                                         player[c1].in_water = 0;
2041                                         player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
2042                                         player[c1].y_add = 0;
2043                                         if (player[c1].anim != 0 && player[c1].anim != 1) {
2044                                                 player[c1].anim = 0;
2045                                                 player[c1].frame = 0;
2046                                                 player[c1].frame_tick = 0;
2047                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
2048                                         }
2049                                 } else {
2050                                         if (player[c1].in_water == 0) {
2051                                                 if (bunnies_in_space == 0)
2052                                                         player[c1].y_add += 12288;
2053                                                 else
2054                                                         player[c1].y_add += 6144;
2055                                                 if (player[c1].y_add > 327680L)
2056                                                         player[c1].y_add = 327680L;
2057                                         } else {
2058                                                 player[c1].y = (player[c1].y & 0xffff0000) + 0x10000;
2059                                                 player[c1].y_add = 0;
2060                                         }
2061                                         player[c1].in_water = 0;
2062                                 }
2063                                 if (player[c1].y_add > 36864 && player[c1].anim != 3 && player[c1].in_water == 0) {
2064                                         player[c1].anim = 3;
2065                                         player[c1].frame = 0;
2066                                         player[c1].frame_tick = 0;
2067                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
2068                                 }
2069
2070                         }
2071
2072                         player[c1].frame_tick++;
2073                         if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
2074                                 player[c1].frame++;
2075                                 if (player[c1].frame >= player_anims[player[c1].anim].num_frames) {
2076                                         if (player[c1].anim != 6)
2077                                                 player[c1].frame = player_anims[player[c1].anim].restart_frame;
2078                                         else
2079                                                 position_player(c1);
2080                                 }
2081                                 player[c1].frame_tick = 0;
2082                         }
2083                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
2084
2085                 }
2086
2087         }
2088
2089 }
2090
2091
2092 void position_player(int player_num)
2093 {
2094         int c1;
2095         int s1, s2;
2096
2097         while (1) {
2098                 while (1) {
2099                         s1 = rnd(22);
2100                         s2 = rnd(16);
2101                         if (ban_map[s2][s1] == BAN_VOID && (ban_map[s2 + 1][s1] == BAN_SOLID || ban_map[s2 + 1][s1] == BAN_ICE))
2102                                 break;
2103                 }
2104                 for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
2105                         if (c1 != player_num && player[c1].enabled == 1) {
2106                                 if (abs((s1 << 4) - (player[c1].x >> 16)) < 32 && abs((s2 << 4) - (player[c1].y >> 16)) < 32)
2107                                         break;
2108                         }
2109                 }
2110                 if (c1 == JNB_MAX_PLAYERS) {
2111                         player[player_num].x = (long) s1 << 20;
2112                         player[player_num].y = (long) s2 << 20;
2113                         player[player_num].x_add = player[player_num].y_add = 0;
2114                         player[player_num].direction = 0;
2115                         player[player_num].jump_ready = 1;
2116                         player[player_num].in_water = 0;
2117                         player[player_num].anim = 0;
2118                         player[player_num].frame = 0;
2119                         player[player_num].frame_tick = 0;
2120                         player[player_num].image = player_anims[player[player_num].anim].frame[player[player_num].frame].image;
2121
2122                         if (is_server) {
2123 #ifdef USE_NET
2124                                 if (is_net)
2125                                         serverSendAlive(player_num);
2126 #endif
2127                                 player[player_num].dead_flag = 0;
2128                         }
2129
2130                         break;
2131                 }
2132         }
2133
2134 }
2135
2136
2137 void add_object(int type, int x, int y, int x_add, int y_add, int anim, int frame)
2138 {
2139         int c1;
2140
2141         for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
2142                 if (objects[c1].used == 0) {
2143                         objects[c1].used = 1;
2144                         objects[c1].type = type;
2145                         objects[c1].x = (long) x << 16;
2146                         objects[c1].y = (long) y << 16;
2147                         objects[c1].x_add = x_add;
2148                         objects[c1].y_add = y_add;
2149                         objects[c1].x_acc = 0;
2150                         objects[c1].y_acc = 0;
2151                         objects[c1].anim = anim;
2152                         objects[c1].frame = frame;
2153                         objects[c1].ticks = object_anims[anim].frame[frame].ticks;
2154                         objects[c1].image = object_anims[anim].frame[frame].image;
2155                         break;
2156                 }
2157         }
2158
2159 }
2160
2161
2162 void update_objects(void)
2163 {
2164         int c1;
2165         int s1 = 0;
2166
2167         for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
2168                 if (objects[c1].used == 1) {
2169                         switch (objects[c1].type) {
2170                         case OBJ_SPRING:
2171                                 objects[c1].ticks--;
2172                                 if (objects[c1].ticks <= 0) {
2173                                         objects[c1].frame++;
2174                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames) {
2175                                                 objects[c1].frame--;
2176                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2177                                         } else {
2178                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2179                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2180                                         }
2181                                 }
2182                                 if (objects[c1].used == 1)
2183                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2184                                 break;
2185                         case OBJ_SPLASH:
2186                                 objects[c1].ticks--;
2187                                 if (objects[c1].ticks <= 0) {
2188                                         objects[c1].frame++;
2189                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2190                                                 objects[c1].used = 0;
2191                                         else {
2192                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2193                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2194                                         }
2195                                 }
2196                                 if (objects[c1].used == 1)
2197                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2198                                 break;
2199                         case OBJ_SMOKE:
2200                                 objects[c1].x += objects[c1].x_add;
2201                                 objects[c1].y += objects[c1].y_add;
2202                                 objects[c1].ticks--;
2203                                 if (objects[c1].ticks <= 0) {
2204                                         objects[c1].frame++;
2205                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2206                                                 objects[c1].used = 0;
2207                                         else {
2208                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2209                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2210                                         }
2211                                 }
2212                                 if (objects[c1].used == 1)
2213                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2214                                 break;
2215                         case OBJ_YEL_BUTFLY:
2216                         case OBJ_PINK_BUTFLY:
2217                                 objects[c1].x_acc += rnd(128) - 64;
2218                                 if (objects[c1].x_acc < -1024)
2219                                         objects[c1].x_acc = -1024;
2220                                 if (objects[c1].x_acc > 1024)
2221                                         objects[c1].x_acc = 1024;
2222                                 objects[c1].x_add += objects[c1].x_acc;
2223                                 if (objects[c1].x_add < -32768)
2224                                         objects[c1].x_add = -32768;
2225                                 if (objects[c1].x_add > 32768)
2226                                         objects[c1].x_add = 32768;
2227                                 objects[c1].x += objects[c1].x_add;
2228                                 if ((objects[c1].x >> 16) < 16) {
2229                                         objects[c1].x = 16 << 16;
2230                                         objects[c1].x_add = -objects[c1].x_add >> 2;
2231                                         objects[c1].x_acc = 0;
2232                                 } else if ((objects[c1].x >> 16) > 350) {
2233                                         objects[c1].x = 350 << 16;
2234                                         objects[c1].x_add = -objects[c1].x_add >> 2;
2235                                         objects[c1].x_acc = 0;
2236                                 }
2237                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
2238                                         if (objects[c1].x_add < 0) {
2239                                                 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2240                                         } else {
2241                                                 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2242                                         }
2243                                         objects[c1].x_add = -objects[c1].x_add >> 2;
2244                                         objects[c1].x_acc = 0;
2245                                 }
2246                                 objects[c1].y_acc += rnd(64) - 32;
2247                                 if (objects[c1].y_acc < -1024)
2248                                         objects[c1].y_acc = -1024;
2249                                 if (objects[c1].y_acc > 1024)
2250                                         objects[c1].y_acc = 1024;
2251                                 objects[c1].y_add += objects[c1].y_acc;
2252                                 if (objects[c1].y_add < -32768)
2253                                         objects[c1].y_add = -32768;
2254                                 if (objects[c1].y_add > 32768)
2255                                         objects[c1].y_add = 32768;
2256                                 objects[c1].y += objects[c1].y_add;
2257                                 if ((objects[c1].y >> 16) < 0) {
2258                                         objects[c1].y = 0;
2259                                         objects[c1].y_add = -objects[c1].y_add >> 2;
2260                                         objects[c1].y_acc = 0;
2261                                 } else if ((objects[c1].y >> 16) > 255) {
2262                                         objects[c1].y = 255 << 16;
2263                                         objects[c1].y_add = -objects[c1].y_add >> 2;
2264                                         objects[c1].y_acc = 0;
2265                                 }
2266                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
2267                                         if (objects[c1].y_add < 0) {
2268                                                 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2269                                         } else {
2270                                                 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2271                                         }
2272                                         objects[c1].y_add = -objects[c1].y_add >> 2;
2273                                         objects[c1].y_acc = 0;
2274                                 }
2275                                 if (objects[c1].type == OBJ_YEL_BUTFLY) {
2276                                         if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_LEFT) {
2277                                                 objects[c1].anim = OBJ_ANIM_YEL_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_YEL_BUTFLY_RIGHT) {
2282                                                 objects[c1].anim = OBJ_ANIM_YEL_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                                 } else {
2288                                         if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_LEFT) {
2289                                                 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_LEFT;
2290                                                 objects[c1].frame = 0;
2291                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2292                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2293                                         } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_RIGHT) {
2294                                                 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_RIGHT;
2295                                                 objects[c1].frame = 0;
2296                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2297                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2298                                         }
2299                                 }
2300                                 objects[c1].ticks--;
2301                                 if (objects[c1].ticks <= 0) {
2302                                         objects[c1].frame++;
2303                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2304                                                 objects[c1].frame = object_anims[objects[c1].anim].restart_frame;
2305                                         else {
2306                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2307                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2308                                         }
2309                                 }
2310                                 if (objects[c1].used == 1)
2311                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2312                                 break;
2313                         case OBJ_FUR:
2314                                 if (rnd(100) < 30)
2315                                         add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 0);
2316                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
2317                                         objects[c1].y_add += 3072;
2318                                         if (objects[c1].y_add > 196608L)
2319                                                 objects[c1].y_add = 196608L;
2320                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
2321                                         if (objects[c1].x_add < 0) {
2322                                                 if (objects[c1].x_add < -65536L)
2323                                                         objects[c1].x_add = -65536L;
2324                                                 objects[c1].x_add += 1024;
2325                                                 if (objects[c1].x_add > 0)
2326                                                         objects[c1].x_add = 0;
2327                                         } else {
2328                                                 if (objects[c1].x_add > 65536L)
2329                                                         objects[c1].x_add = 65536L;
2330                                                 objects[c1].x_add -= 1024;
2331                                                 if (objects[c1].x_add < 0)
2332                                                         objects[c1].x_add = 0;
2333                                         }
2334                                         objects[c1].y_add += 1024;
2335                                         if (objects[c1].y_add < -65536L)
2336                                                 objects[c1].y_add = -65536L;
2337                                         if (objects[c1].y_add > 65536L)
2338                                                 objects[c1].y_add = 65536L;
2339                                 }
2340                                 objects[c1].x += objects[c1].x_add;
2341                                 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)) {
2342                                         if (objects[c1].x_add < 0) {
2343                                                 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2344                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
2345                                         } else {
2346                                                 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2347                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
2348                                         }
2349                                 }
2350                                 objects[c1].y += objects[c1].y_add;
2351                                 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
2352                                         objects[c1].used = 0;
2353                                 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
2354                                         if (objects[c1].y_add < 0) {
2355                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
2356                                                         objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2357                                                         objects[c1].x_add >>= 2;
2358                                                         objects[c1].y_add = -objects[c1].y_add >> 2;
2359                                                 }
2360                                         } else {
2361                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
2362                                                         if (objects[c1].y_add > 131072L) {
2363                                                                 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2364                                                                 objects[c1].x_add >>= 2;
2365                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
2366                                                         } else
2367                                                                 objects[c1].used = 0;
2368                                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
2369                                                         objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2370                                                         if (objects[c1].y_add > 131072L)
2371                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
2372                                                         else
2373                                                                 objects[c1].y_add = 0;
2374                                                 }
2375                                         }
2376                                 }
2377                                 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
2378                                         objects[c1].x_add = -16384;
2379                                 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
2380                                         objects[c1].x_add = 16384;
2381                                 if (objects[c1].used == 1) {
2382                                         s1 = (int)(atan2(objects[c1].y_add, objects[c1].x_add) * 4 / M_PI);
2383                                         if (s1 < 0)
2384                                                 s1 += 8;
2385                                         if (s1 < 0)
2386                                                 s1 = 0;
2387                                         if (s1 > 7)
2388                                                 s1 = 7;
2389                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame + s1, &object_gobs);
2390                                 }
2391                                 break;
2392                         case OBJ_FLESH:
2393                                 if (rnd(100) < 30) {
2394                                         if (objects[c1].frame == 76)
2395                                                 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 1);
2396                                         else if (objects[c1].frame == 77)
2397                                                 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 2);
2398                                         else if (objects[c1].frame == 78)
2399                                                 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 3);
2400                                 }
2401                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
2402                                         objects[c1].y_add += 3072;
2403                                         if (objects[c1].y_add > 196608L)
2404                                                 objects[c1].y_add = 196608L;
2405                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
2406                                         if (objects[c1].x_add < 0) {
2407                                                 if (objects[c1].x_add < -65536L)
2408                                                         objects[c1].x_add = -65536L;
2409                                                 objects[c1].x_add += 1024;
2410                                                 if (objects[c1].x_add > 0)
2411                                                         objects[c1].x_add = 0;
2412                                         } else {
2413                                                 if (objects[c1].x_add > 65536L)
2414                                                         objects[c1].x_add = 65536L;
2415                                                 objects[c1].x_add -= 1024;
2416                                                 if (objects[c1].x_add < 0)
2417                                                         objects[c1].x_add = 0;
2418                                         }
2419                                         objects[c1].y_add += 1024;
2420                                         if (objects[c1].y_add < -65536L)
2421                                                 objects[c1].y_add = -65536L;
2422                                         if (objects[c1].y_add > 65536L)
2423                                                 objects[c1].y_add = 65536L;
2424                                 }
2425                                 objects[c1].x += objects[c1].x_add;
2426                                 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)) {
2427                                         if (objects[c1].x_add < 0) {
2428                                                 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
2429                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
2430                                         } else {
2431                                                 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
2432                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
2433                                         }
2434                                 }
2435                                 objects[c1].y += objects[c1].y_add;
2436                                 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
2437                                         objects[c1].used = 0;
2438                                 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
2439                                         if (objects[c1].y_add < 0) {
2440                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
2441                                                         objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
2442                                                         objects[c1].x_add >>= 2;
2443                                                         objects[c1].y_add = -objects[c1].y_add >> 2;
2444                                                 }
2445                                         } else {
2446                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
2447                                                         if (objects[c1].y_add > 131072L) {
2448                                                                 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2449                                                                 objects[c1].x_add >>= 2;
2450                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
2451                                                         } else {
2452                                                                 if (rnd(100) < 10) {
2453                                                                         s1 = rnd(4) - 2;
2454                                                                         add_leftovers(0, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
2455                                                                         add_leftovers(1, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
2456                                                                 }
2457                                                                 objects[c1].used = 0;
2458                                                         }
2459                                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
2460                                                         objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
2461                                                         if (objects[c1].y_add > 131072L)
2462                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
2463                                                         else
2464                                                                 objects[c1].y_add = 0;
2465                                                 }
2466                                         }
2467                                 }
2468                                 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
2469                                         objects[c1].x_add = -16384;
2470                                 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
2471                                         objects[c1].x_add = 16384;
2472                                 if (objects[c1].used == 1)
2473                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame, &object_gobs);
2474                                 break;
2475                         case OBJ_FLESH_TRACE:
2476                                 objects[c1].ticks--;
2477                                 if (objects[c1].ticks <= 0) {
2478                                         objects[c1].frame++;
2479                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
2480                                                 objects[c1].used = 0;
2481                                         else {
2482                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
2483                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
2484                                         }
2485                                 }
2486                                 if (objects[c1].used == 1)
2487                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
2488                                 break;
2489                         }
2490                 }
2491         }
2492
2493 }
2494
2495
2496 int add_pob(int page, int x, int y, int image, gob_t *pob_data)
2497 {
2498
2499         if (main_info.page_info[page].num_pobs >= NUM_POBS)
2500                 return 1;
2501
2502         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].x = x;
2503         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].y = y;
2504         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].image = image;
2505         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].pob_data = pob_data;
2506         main_info.page_info[page].num_pobs++;
2507
2508         return 0;
2509
2510 }
2511
2512
2513 void draw_flies(int page)
2514 {
2515         int c2;
2516
2517         for (c2 = 0; c2 < NUM_FLIES; c2++) {
2518                 flies[c2].back[main_info.draw_page] = get_pixel(main_info.draw_page, flies[c2].x, flies[c2].y);
2519                 flies[c2].back_defined[main_info.draw_page] = 1;
2520                 if (mask_pic[(flies[c2].y * JNB_WIDTH) + flies[c2].x] == 0)
2521                         set_pixel(main_info.draw_page, flies[c2].x, flies[c2].y, 0);
2522         }
2523 }
2524
2525 void draw_pobs(int page)
2526 {
2527         int c1;
2528         int back_buf_ofs;
2529
2530         back_buf_ofs = 0;
2531
2532         for (c1 = main_info.page_info[page].num_pobs - 1; c1 >= 0; c1--) {
2533                 main_info.page_info[page].pobs[c1].back_buf_ofs = back_buf_ofs;
2534                 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);
2535                 if (scale_up)
2536                         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;
2537                 else
2538                         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;
2539                 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);
2540         }
2541
2542 }
2543
2544
2545 void redraw_flies_background(int page)
2546 {
2547         int c2;
2548
2549         for (c2 = NUM_FLIES - 1; c2 >= 0; c2--) {
2550                 if (flies[c2].back_defined[page] == 1)
2551                         set_pixel(page, flies[c2].old_draw_x, flies[c2].old_draw_y, flies[c2].back[page]);
2552                 flies[c2].old_draw_x = flies[c2].x;
2553                 flies[c2].old_draw_y = flies[c2].y;
2554         }
2555 }
2556
2557
2558 void redraw_pob_backgrounds(int page)
2559 {
2560         int c1;
2561
2562         for (c1 = 0; c1 < main_info.page_info[page].num_pobs; c1++)
2563                 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);
2564
2565 }
2566
2567
2568 int add_leftovers(int page, int x, int y, int image, gob_t *pob_data)
2569 {
2570
2571         if (leftovers.page[page].num_pobs >= NUM_LEFTOVERS)
2572                 return 1;
2573
2574         leftovers.page[page].pobs[leftovers.page[page].num_pobs].x = x;
2575         leftovers.page[page].pobs[leftovers.page[page].num_pobs].y = y;
2576         leftovers.page[page].pobs[leftovers.page[page].num_pobs].image = image;
2577         leftovers.page[page].pobs[leftovers.page[page].num_pobs].pob_data = pob_data;
2578         leftovers.page[page].num_pobs++;
2579
2580         return 0;
2581
2582 }
2583
2584
2585 void draw_leftovers(int page)
2586 {
2587         int c1;
2588
2589         for (c1 = leftovers.page[page].num_pobs - 1; c1 >= 0; c1--)
2590                 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);
2591
2592         leftovers.page[page].num_pobs = 0;
2593
2594 }
2595
2596
2597 int init_level(int level, char *pal)
2598 {
2599         unsigned char *handle;
2600         int c1, c2;
2601         int s1, s2;
2602
2603         if ((handle = dat_open("level.pcx", datfile_name, "rb")) == 0) {
2604                 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2605                 return 1;
2606         }
2607         if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
2608                 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
2609                 return 1;
2610         }
2611         if (flip)
2612                 flip_pixels(background_pic);
2613         if ((handle = dat_open("mask.pcx", datfile_name, "rb")) == 0) {
2614                 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2615                 return 1;
2616         }
2617         if (read_pcx(handle, mask_pic, JNB_WIDTH*JNB_HEIGHT, 0) != 0) {
2618                 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
2619                 return 1;
2620         }
2621         if (flip)
2622                 flip_pixels(mask_pic);
2623         register_mask(mask_pic);
2624
2625         for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
2626                 if (player[c1].enabled == 1) {
2627                         player[c1].bumps = 0;
2628                         for (c2 = 0; c2 < JNB_MAX_PLAYERS; c2++)
2629                                 player[c1].bumped[c2] = 0;
2630                         position_player(c1);
2631                 }
2632         }
2633
2634         for (c1 = 0; c1 < NUM_OBJECTS; c1++)
2635                 objects[c1].used = 0;
2636
2637         for (c1 = 0; c1 < 16; c1++) {
2638                 for (c2 = 0; c2 < 22; c2++) {
2639                         if (ban_map[c1][c2] == BAN_SPRING)
2640                                 add_object(OBJ_SPRING, c2 << 4, c1 << 4, 0, 0, OBJ_ANIM_SPRING, 5);
2641                 }
2642         }
2643
2644         while (1) {
2645                 s1 = rnd(22);
2646                 s2 = rnd(16);
2647                 if (ban_map[s2][s1] == BAN_VOID) {
2648                         add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2649                         break;
2650                 }
2651         }
2652         while (1) {
2653                 s1 = rnd(22);
2654                 s2 = rnd(16);
2655                 if (ban_map[s2][s1] == BAN_VOID) {
2656                         add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2657                         break;
2658                 }
2659         }
2660         while (1) {
2661                 s1 = rnd(22);
2662                 s2 = rnd(16);
2663                 if (ban_map[s2][s1] == BAN_VOID) {
2664                         add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2665                         break;
2666                 }
2667         }
2668         while (1) {
2669                 s1 = rnd(22);
2670                 s2 = rnd(16);
2671                 if (ban_map[s2][s1] == BAN_VOID) {
2672                         add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
2673                         break;
2674                 }
2675         }
2676
2677         return 0;
2678
2679 }
2680
2681
2682 void deinit_level(void)
2683 {
2684         dj_set_nosound(1);
2685         dj_stop_mod();
2686 }
2687
2688
2689 #ifndef PATH_MAX
2690 #define PATH_MAX 1024
2691 #endif
2692
2693 unsigned char *datafile_buffer = NULL;
2694
2695 static void preread_datafile(const char *fname)
2696 {
2697     int fd = 0;
2698     int len;
2699
2700 #ifdef ZLIB_SUPPORT
2701     char *gzfilename = alloca(strlen(fname) + 4);
2702     int bufsize = 0;
2703     int bufpos = 0;
2704     gzFile gzf;
2705
2706     strcpy(gzfilename, fname);
2707     strcat(gzfilename, ".gz");
2708
2709     gzf = gzopen(gzfilename, "rb");
2710     if (gzf != NULL) {
2711         unsigned char *ptr;
2712         do {
2713             int br;
2714             if (bufpos >= bufsize) {
2715                 bufsize += 1024 * 1024;
2716                 datafile_buffer = (unsigned char *) realloc(datafile_buffer, bufsize);
2717                 if (datafile_buffer == NULL) {
2718                     perror("realloc()");
2719                     exit(42);
2720                 }
2721             }
2722
2723             br = gzread(gzf, datafile_buffer + bufpos, bufsize - bufpos);
2724             if (br == -1) {
2725                 fprintf(stderr, "gzread failed.\n");
2726                 exit(42);
2727             }
2728
2729             bufpos += br;
2730         } while (!gzeof(gzf));
2731
2732         /* try to shrink buffer... */
2733         ptr = (unsigned char *) realloc(datafile_buffer, bufpos);
2734         if (ptr != NULL)
2735             datafile_buffer = ptr;
2736
2737         gzclose(gzf);
2738         return;
2739     }
2740
2741     /* drop through and try for an uncompressed datafile... */
2742 #endif
2743
2744     fd = open(fname, O_RDONLY | O_BINARY);
2745     if (fd == -1) {
2746         fprintf(stderr, "can't open %s: %s\n", fname, strerror(errno));
2747         exit(42);
2748     }
2749
2750     len = filelength(fd);
2751     datafile_buffer = (unsigned char *) malloc(len);
2752     if (datafile_buffer == NULL) {
2753         perror("malloc()");
2754         close(fd);
2755         exit(42);
2756     }
2757
2758     if (read(fd, datafile_buffer, len) != len) {
2759         perror("read()");
2760         close(fd);
2761         exit(42);
2762     }
2763
2764     close(fd);
2765 }
2766
2767
2768 int init_program(int argc, char *argv[], char *pal)
2769 {
2770         char *netarg = NULL;
2771         unsigned char *handle = (unsigned char *) NULL;
2772         int c1 = 0, c2 = 0;
2773         int load_flag = 0;
2774         int force2, force3;
2775         sfx_data fly;
2776         int player_anim_data[] = {
2777                 1, 0, 0, 0x7fff, 0, 0, 0, 0, 0, 0,
2778                 4, 0, 0, 4, 1, 4, 2, 4, 3, 4,
2779                 1, 0, 4, 0x7fff, 0, 0, 0, 0, 0, 0,
2780                 4, 2, 5, 8, 6, 10, 7, 3, 6, 3,
2781                 1, 0, 6, 0x7fff, 0, 0, 0, 0, 0, 0,
2782                 2, 1, 5, 8, 4, 0x7fff, 0, 0, 0, 0,
2783                 1, 0, 8, 5, 0, 0, 0, 0, 0, 0
2784         };
2785
2786 #ifdef USE_NET
2787         memset(&net_info, 0, sizeof(net_info));
2788 #endif
2789
2790 #ifdef DOS
2791         if (__djgpp_nearptr_enable() == 0)
2792                 return 1;
2793 #endif
2794
2795         srand(time(NULL));
2796
2797         if (hook_keyb_handler() != 0)
2798                 return 1;
2799
2800         memset(&main_info, 0, sizeof(main_info));
2801
2802         strcpy(datfile_name, DATA_PATH);
2803
2804         force2 = force3 = 0;
2805
2806         if (argc > 1) {
2807                 for (c1 = 1; c1 < argc; c1++) {
2808                         if (stricmp(argv[c1], "-nosound") == 0)
2809                                 main_info.no_sound = 1;
2810                         else if (stricmp(argv[c1], "-musicnosound") == 0)
2811                                 main_info.music_no_sound = 1;
2812                         else if (stricmp(argv[c1], "-nogore") == 0)
2813                                 main_info.no_gore = 1;
2814                         else if (stricmp(argv[c1], "-noflies") == 0)
2815                                 flies_enabled = 0;
2816                         else if (stricmp(argv[c1], "-nojoy") == 0)
2817                                 main_info.joy_enabled = 0;
2818                         else if (stricmp(argv[c1], "-fireworks") == 0)
2819                                 main_info.fireworks = 1;
2820 #ifdef USE_SDL
2821                         else if (stricmp(argv[c1], "-fullscreen") == 0)
2822                                 fs_toggle();
2823 #endif
2824                         else if (stricmp(argv[c1], "-scaleup") == 0)
2825                                 set_scaling(1);
2826                         else if (stricmp(argv[c1], "-mirror") == 0)
2827                                 flip = 1;
2828                         else if (stricmp(argv[c1], "-dat") == 0) {
2829                                 if (c1 < (argc - 1)) {
2830                                         FILE *f;
2831
2832                                         if ((f = fopen(argv[c1 + 1], "rb")) != NULL) {
2833                                                 fclose(f);
2834                                                 strcpy(datfile_name, argv[c1 + 1]);
2835                                         }
2836                                 }
2837                         } else if (stricmp(argv[c1], "-player") == 0) {
2838                                 if (c1 < (argc - 1)) {
2839                                         if (client_player_num < 0)
2840                                                 client_player_num = atoi(argv[c1 + 1]);
2841                                 }
2842                         } else if (stricmp(argv[c1], "-server") == 0) {
2843                                 if (c1 < (argc - 1)) {
2844                                         is_server = 1;
2845                                         is_net = 1;
2846                                         netarg = argv[c1 + 1];
2847                                 }
2848                         } else if (stricmp(argv[c1], "-connect") == 0) {
2849                                 if (c1 < (argc - 1)) {
2850                                         is_server = 0;
2851                                         is_net = 1;
2852                                         netarg = argv[c1 + 1];
2853                                 }
2854                         } else if (stricmp(argv[c1], "-mouse") == 0) {
2855                                 if (c1 < (argc - 1)) {
2856                                         if (stricmp(argv[c1 + 1], "2") == 0)
2857                                                 force2 = 1;
2858                                         if (stricmp(argv[c1 + 1], "3") == 0)
2859                                                 force3 = 1;
2860                                 }
2861                         }
2862                         else if (strstr(argv[1],"-v")) {
2863                                 printf("jumpnbump %s compiled %s at %s with",JNB_VERSION,__DATE__,__TIME__);
2864 #ifndef _SDLnet_h
2865                                 printf("out");
2866 #endif
2867                                 printf(" network support.\n");
2868                                 return 1;
2869                         }
2870                         else if (strstr(argv[1],"-h")) {
2871                                 printf("Usage: jumpnbump [OPTION]...\n");
2872                                 printf("\n");
2873                                 printf("  -h                       this help\n");
2874                                 printf("  -v                       print version\n");
2875                                 printf("  -dat level.dat           play a different level\n");
2876                                 printf("  -port port               define listen port\n");
2877                                 printf("  -net player host rport   define network players\n");
2878                                 printf("  -fireworks               screensaver mode\n");
2879                                 printf("  -fullscreen              run in fullscreen mode\n");
2880                                 printf("  -nosound                 play without sound\n");
2881                                 printf("  -nogore                  play without blood\n");
2882                                 printf("  -noflies                 disable flies\n");
2883                                 printf("  -mirror                  play with mirrored level\n");
2884                                 printf("  -scaleup                 play with doubled resolution (800x512)\n");
2885                                 printf("  -musicnosound            play with music but without sound\n");
2886                                 printf("\n");
2887                                 return 1;
2888                         }
2889                 }
2890         }
2891
2892         preread_datafile(datfile_name);
2893
2894         if (is_net) {
2895                 if (client_player_num < 0)
2896                         client_player_num = 0;
2897                 player[client_player_num].enabled = 1;
2898         }
2899
2900         main_info.pob_backbuf[0] = malloc(screen_pitch*screen_height*bytes_per_pixel);
2901         main_info.pob_backbuf[1] = malloc(screen_pitch*screen_height*bytes_per_pixel);
2902
2903         for (c1 = 0; c1 < 7; c1++) {
2904                 player_anims[c1].num_frames = player_anim_data[c1 * 10];
2905                 player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
2906                 for (c2 = 0; c2 < 4; c2++) {
2907                         player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
2908                         player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
2909                 }
2910         }
2911
2912         if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
2913                 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2914                 return 1;
2915         }
2916         if (read_pcx(handle, background_pic, JNB_WIDTH*JNB_HEIGHT, pal) != 0) {
2917                 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2918                 return 1;
2919         }
2920
2921         if ((handle = dat_open("rabbit.gob", datfile_name, "rb")) == 0) {
2922                 strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
2923                 return 1;
2924         }
2925         if (register_gob(handle, &rabbit_gobs, dat_filelen("rabbit.gob", datfile_name))) {
2926                 /* error */
2927                 return 1;
2928         }
2929
2930         if ((handle = dat_open("objects.gob", datfile_name, "rb")) == 0) {
2931                 strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
2932                 return 1;
2933         }
2934         if (register_gob(handle, &object_gobs, dat_filelen("objects.gob", datfile_name))) {
2935                 /* error */
2936                 return 1;
2937         }
2938
2939         if ((handle = dat_open("font.gob", datfile_name, "rb")) == 0) {
2940                 strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
2941                 return 1;
2942         }
2943         if (register_gob(handle, &font_gobs, dat_filelen("font.gob", datfile_name))) {
2944                 /* error */
2945                 return 1;
2946         }
2947
2948         if ((handle = dat_open("numbers.gob", datfile_name, "rb")) == 0) {
2949                 strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
2950                 return 1;
2951         }
2952         if (register_gob(handle, &number_gobs, dat_filelen("numbers.gob", datfile_name))) {
2953                 /* error */
2954                 return 1;
2955         }
2956
2957         if (read_level() != 0) {
2958                 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2959                 return 1;
2960         }
2961
2962         dj_init();
2963
2964         if (main_info.no_sound == 0) {
2965                 dj_autodetect_sd();
2966                 dj_set_mixing_freq(20000);
2967                 dj_set_stereo(0);
2968                 dj_set_auto_mix(0);
2969                 dj_set_dma_time(8);
2970                 dj_set_num_sfx_channels(5);
2971                 dj_set_sfx_volume(64);
2972                 dj_set_nosound(1);
2973                 dj_start();
2974
2975                 if ((handle = dat_open("jump.mod", datfile_name, "rb")) == 0) {
2976                         strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2977                         return 1;
2978                 }
2979                 if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
2980                         strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2981                         return 1;
2982                 }
2983
2984                 if ((handle = dat_open("bump.mod", datfile_name, "rb")) == 0) {
2985                         strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2986                         return 1;
2987                 }
2988                 if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
2989                         strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2990                         return 1;
2991                 }
2992
2993                 if ((handle = dat_open("scores.mod", datfile_name, "rb")) == 0) {
2994                         strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2995                         return 1;
2996                 }
2997                 if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
2998                         strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2999                         return 1;
3000                 }
3001
3002                 if ((handle = dat_open("jump.smp", datfile_name, "rb")) == 0) {
3003                         strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
3004                         return 1;
3005                 }
3006                 if (dj_load_sfx(handle, 0, dat_filelen("jump.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
3007                         strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
3008                         return 1;
3009                 }
3010
3011                 if ((handle = dat_open("death.smp", datfile_name, "rb")) == 0) {
3012                         strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
3013                         return 1;
3014                 }
3015                 if (dj_load_sfx(handle, 0, dat_filelen("death.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
3016                         strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
3017                         return 1;
3018                 }
3019
3020                 if ((handle = dat_open("spring.smp", datfile_name, "rb")) == 0) {
3021                         strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
3022                         return 1;
3023                 }
3024                 if (dj_load_sfx(handle, 0, dat_filelen("spring.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
3025                         strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
3026                         return 1;
3027                 }
3028
3029                 if ((handle = dat_open("splash.smp", datfile_name, "rb")) == 0) {
3030                         strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
3031                         return 1;
3032                 }
3033                 if (dj_load_sfx(handle, 0, dat_filelen("splash.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
3034                         strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
3035                         return 1;
3036                 }
3037
3038                 if ((handle = dat_open("fly.smp", datfile_name, "rb")) == 0) {
3039                         strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
3040                         return 1;
3041                 }
3042                 if (dj_load_sfx(handle, 0, dat_filelen("fly.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
3043                         strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
3044                         return 1;
3045                 }
3046
3047                 dj_get_sfx_settings(SFX_FLY, &fly);
3048                 fly.priority = 10;
3049                 fly.default_freq = SFX_FLY_FREQ;
3050                 fly.loop = 1;
3051                 fly.loop_start = 0;
3052                 fly.loop_length = fly.length;
3053                 dj_set_sfx_settings(SFX_FLY, &fly);
3054         }
3055
3056         if ((background_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
3057                 return 1;
3058         if ((mask_pic = malloc(JNB_WIDTH*JNB_HEIGHT)) == NULL)
3059                 return 1;
3060         memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
3061         register_mask(mask_pic);
3062
3063         for (c1 = 0; c1 < 16; c1++) { // fix dark font
3064                 pal[(240 + c1) * 3 + 0] = c1 << 2;
3065                 pal[(240 + c1) * 3 + 1] = c1 << 2;
3066                 pal[(240 + c1) * 3 + 2] = c1 << 2;
3067         }
3068
3069         setpalette(0, 256, pal);
3070
3071         init_inputs();
3072
3073         recalculate_gob(&font_gobs, pal);
3074
3075         if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
3076                 load_flag = 0;
3077                 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
3078                 put_text(0, 200, 100, "Move the joystick to the", 2);
3079                 put_text(0, 200, 115, "UPPER LEFT", 2);
3080                 put_text(0, 200, 130, "and press button A", 2);
3081                 put_text(0, 200, 200, "Or press ESC to use", 2);
3082                 put_text(0, 200, 215, "previous settings", 2);
3083                 if (calib_joy(0) != 0)
3084                         load_flag = 1;
3085                 else {
3086                         register_background(NULL, NULL);
3087
3088                         main_info.view_page = 1;
3089                         flippage(1);
3090
3091                         wait_vrt(0);
3092
3093                         put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
3094                         put_text(1, 200, 100, "Move the joystick to the", 2);
3095                         put_text(1, 200, 115, "LOWER RIGHT", 2);
3096                         put_text(1, 200, 130, "and press button A", 2);
3097                         put_text(1, 200, 200, "Or press ESC to use", 2);
3098                         put_text(1, 200, 215, "previous settings", 2);
3099                         if (calib_joy(1) != 0)
3100                                 load_flag = 1;
3101                         else {
3102                                 register_background(NULL, NULL);
3103                                 flippage(0);
3104
3105                                 wait_vrt(0);
3106
3107                                 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
3108                                 put_text(0, 200, 100, "Move the joystick to the", 2);
3109                                 put_text(0, 200, 115, "CENTER", 2);
3110                                 put_text(0, 200, 130, "and press button A", 2);
3111                                 put_text(0, 200, 200, "Or press ESC to use", 2);
3112                                 put_text(0, 200, 215, "previous settings", 2);
3113                                 if (calib_joy(2) != 0)
3114                                         load_flag = 1;
3115                                 else {
3116                                         if (joy.calib_data.x1 == joy.calib_data.x2)
3117                                                 joy.calib_data.x1 -= 10;
3118                                         if (joy.calib_data.x3 == joy.calib_data.x2)
3119                                                 joy.calib_data.x3 += 10;
3120                                         if (joy.calib_data.y1 == joy.calib_data.y2)
3121                                                 joy.calib_data.y1 -= 10;
3122                                         if (joy.calib_data.y3 == joy.calib_data.y2)
3123                                                 joy.calib_data.y3 += 10;
3124                                         write_calib_data();
3125                                 }
3126                         }
3127                 }
3128                 if (load_flag == 1) {
3129                         if ((handle = dat_open("calib.dat", datfile_name, "rb")) == 0) {
3130                                 strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
3131                                 return 1;
3132                         }
3133                         joy.calib_data.x1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3134                         joy.calib_data.x2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3135                         joy.calib_data.x3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3136                         joy.calib_data.y1 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3137                         joy.calib_data.y2 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3138                         joy.calib_data.y3 = (handle[0]) + (handle[1] << 8) + (handle[2] << 16) + (handle[3] << 24); handle += 4;
3139                 }
3140         }
3141
3142 #ifdef USE_NET
3143         if (is_net) {
3144                 if (is_server) {
3145                         init_server(netarg);
3146                 } else {
3147                         connect_to_server(netarg);
3148                 }
3149         }
3150 #endif
3151
3152         return 0;
3153
3154 }
3155
3156 void deinit_program(void)
3157 {
3158 #ifdef DOS
3159         __dpmi_regs regs;
3160 #endif
3161
3162         dj_stop();
3163         dj_free_mod(MOD_MENU);
3164         dj_free_mod(MOD_GAME);
3165         dj_free_sfx(SFX_DEATH);
3166         dj_free_sfx(SFX_SPRING);
3167         dj_free_sfx(SFX_SPLASH);
3168         dj_deinit();
3169
3170         if (background_pic != 0)
3171                 free(background_pic);
3172         if (mask_pic != 0)
3173                 free(mask_pic);
3174
3175         remove_keyb_handler();
3176
3177 #ifdef DOS
3178         regs.x.ax = 0x3;
3179         __dpmi_int(0x10, &regs);
3180 #endif
3181
3182         if (main_info.error_str[0] != 0) {
3183                 printf(main_info.error_str);
3184 #ifdef _MSC_VER
3185                 MessageBox(0, main_info.error_str, "Jump'n'Bump", 0);
3186 #endif
3187                 exit(1);
3188         } else
3189                 exit(0);
3190
3191 }
3192
3193
3194 unsigned short rnd(unsigned short max)
3195 {
3196         return (rand() % max);
3197 }
3198
3199
3200 int read_level(void)
3201 {
3202         unsigned char *handle;
3203         int c1, c2;
3204         int chr;
3205
3206         if ((handle = dat_open("levelmap.txt", datfile_name, "rb")) == 0) {
3207                 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
3208                 return 1;
3209         }
3210
3211         for (c1 = 0; c1 < 16; c1++) {
3212                 for (c2 = 0; c2 < 22; c2++) {
3213                         while (1) {
3214                                 chr = (int) *(handle++);
3215                                 if (chr >= '0' && chr <= '4')
3216                                         break;
3217                         }
3218                         if (flip)
3219                                 ban_map[c1][21-c2] = chr - '0';
3220                         else
3221                                 ban_map[c1][c2] = chr - '0';
3222                 }
3223         }
3224
3225         for (c2 = 0; c2 < 22; c2++)
3226                 ban_map[16][c2] = BAN_SOLID;
3227
3228         return 0;
3229
3230 }
3231
3232
3233 unsigned char *dat_open(char *file_name, char *dat_name, char *mode)
3234 {
3235         int num;
3236         int c1;
3237         char name[21];
3238         int ofs;
3239         unsigned char *ptr;
3240
3241         if (datafile_buffer == NULL)
3242                 return 0;
3243
3244         memset(name, 0, sizeof(name));
3245
3246         num = ( (datafile_buffer[0] <<  0) +
3247                 (datafile_buffer[1] <<  8) +
3248                 (datafile_buffer[2] << 16) +
3249                 (datafile_buffer[3] << 24) );
3250
3251         ptr = datafile_buffer + 4;
3252
3253         for (c1 = 0; c1 < num; c1++) {
3254
3255                 memcpy(name, ptr, 12);
3256                 ptr += 12;
3257
3258                 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
3259                         ofs = ( (ptr[0] <<  0) +
3260                                 (ptr[1] <<  8) +
3261                                 (ptr[2] << 16) +
3262                                 (ptr[3] << 24) );
3263
3264                         return (datafile_buffer + ofs);
3265                 }
3266                 ptr += 8;
3267         }
3268
3269         return 0;
3270 }
3271
3272
3273 int dat_filelen(char *file_name, char *dat_name)
3274 {
3275         unsigned char *ptr;
3276         int num;
3277         int c1;
3278         char name[21];
3279         int len;
3280
3281         memset(name, 0, sizeof(name));
3282         
3283         num = ( (datafile_buffer[0] <<  0) +
3284                 (datafile_buffer[1] <<  8) +
3285                 (datafile_buffer[2] << 16) +
3286                 (datafile_buffer[3] << 24) );
3287
3288         ptr = datafile_buffer + 4;
3289
3290         for (c1 = 0; c1 < num; c1++) {
3291
3292                 memcpy(name, ptr, 12);
3293                 ptr += 12;
3294
3295                 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
3296
3297                         ptr += 4;
3298                         len = ( (ptr[0] <<  0) +
3299                                 (ptr[1] <<  8) +
3300                                 (ptr[2] << 16) +
3301                                 (ptr[3] << 24) );
3302
3303                         return len;
3304                 }
3305                 ptr += 8;
3306         }
3307
3308         return 0;
3309 }
3310
3311
3312 void write_calib_data(void)
3313 {
3314         FILE *handle;
3315         int c1;
3316         int len, num;
3317         char *mem;
3318         int ofs;
3319
3320         if ((handle = fopen(datfile_name, "rb")) == NULL)
3321                 return;
3322         len = filelength(fileno(handle));
3323         if ((mem = malloc(len)) == NULL)
3324                 return;
3325         fread(mem, 1, len, handle);
3326         fclose(handle);
3327
3328         ofs = 4;
3329         num = *(int *) (&mem[0]);
3330         for (c1 = 0; c1 < num; c1++) {
3331                 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
3332                         ofs = *(int *) (&mem[ofs + 12]);
3333                         break;
3334                 }
3335                 ofs += 20;
3336         }
3337
3338         mem[ofs] = joy.calib_data.x1 & 0xff;
3339         mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
3340         mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
3341         mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
3342         mem[ofs + 4] = joy.calib_data.x2 & 0xff;
3343         mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
3344         mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
3345         mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
3346         mem[ofs + 8] = joy.calib_data.x3 & 0xff;
3347         mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
3348         mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
3349         mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
3350         mem[ofs + 12] = joy.calib_data.y1 & 0xff;
3351         mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
3352         mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
3353         mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
3354         mem[ofs + 16] = joy.calib_data.y2 & 0xff;
3355         mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
3356         mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
3357         mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
3358         mem[ofs + 20] = joy.calib_data.y3 & 0xff;
3359         mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
3360         mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
3361         mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
3362
3363         if ((handle = fopen(datfile_name, "wb")) == NULL)
3364                 return;
3365         fwrite(mem, 1, len, handle);
3366         fclose(handle);
3367
3368 }