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