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