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