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