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