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