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