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