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