Updated -h option.
[crow/jumpnbump.git] / main.c
1 /*
2  * main.c
3  * Copyright (C) 1998 Brainchild Design - http://brainchilddesign.com/
4  * 
5  * Copyright (C) 2001 Chuck Mason <cemason@users.sourceforge.net>
6  *
7  * Copyright (C) 2002 Florian Schulze <crow@icculus.org>
8  *
9  * Portions of this code are from the MPEG software simulation group
10  * idct implementation. This code will be replaced with a new
11  * implementation soon.
12  *
13  * This file is part of Jump'n'Bump.
14  *
15  * Jump'n'Bump is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2 of the License, or
18  * (at your option) any later version.
19  *
20  * Jump'n'Bump is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  */
29
30 #include "globals.h"
31
32 #ifndef M_PI
33 #define M_PI            3.14159265358979323846
34 #endif
35
36 gob_t rabbit_gobs = { 0 };
37 gob_t font_gobs = { 0 };
38 gob_t object_gobs = { 0 };
39 gob_t number_gobs = { 0 };
40
41 main_info_t main_info;
42 player_t player[4];
43 player_anim_t player_anims[7];
44 object_t objects[NUM_OBJECTS];
45 joy_t joy;
46 mouse_t mouse;
47
48 char datfile_name[2048];
49
50 char *background_pic;
51 char *mask_pic;
52 int flip = 0;
53
54 unsigned int ban_map[17][22] = {
55         {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
56         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0},
57         {1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
58         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1},
59         {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
60         {1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
61         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1},
62         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
63         {1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
64         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1},
65         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1},
66         {1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1},
67         {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
68         {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
69         {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 1, 3, 3, 3, 1, 1, 1},
70         {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
71         {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
72 };
73
74 struct {
75         int num_frames;
76         int restart_frame;
77         struct {
78                 int image;
79                 int ticks;
80         } frame[10];
81 } object_anims[8] = {
82         {
83                 6, 0, {
84                         {
85                         0, 3}, {
86                         1, 3}, {
87                         2, 3}, {
88                         3, 3}, {
89                         4, 3}, {
90                         5, 3}, {
91                         0, 0}, {
92                         0, 0}, {
93                         0, 0}, {
94                         0, 0}
95                 }
96         }, {
97                 9, 0, {
98                         {
99                         6, 2}, {
100                         7, 2}, {
101                         8, 2}, {
102                         9, 2}, {
103                         10, 2}, {
104                         11, 2}, {
105                         12, 2}, {
106                         13, 2}, {
107                         14, 2}, {
108                         0, 0}
109                 }
110         }, {
111                 5, 0, {
112                         {
113                         15, 3}, {
114                         16, 3}, {
115                         16, 3}, {
116                         17, 3}, {
117                         18, 3}, {
118                         19, 3}, {
119                         0, 0}, {
120                         0, 0}, {
121                         0, 0}, {
122                         0, 0}
123                 }
124         }, {
125                 10, 0, {
126                         {
127                         20, 2}, {
128                         21, 2}, {
129                         22, 2}, {
130                         23, 2}, {
131                         24, 2}, {
132                         25, 2}, {
133                         24, 2}, {
134                         23, 2}, {
135                         22, 2}, {
136                         21, 2}
137                 }
138         }, {
139                 10, 0, {
140                         {
141                         26, 2}, {
142                         27, 2}, {
143                         28, 2}, {
144                         29, 2}, {
145                         30, 2}, {
146                         31, 2}, {
147                         30, 2}, {
148                         29, 2}, {
149                         28, 2}, {
150                         27, 2}
151                 }
152         }, {
153                 10, 0, {
154                         {
155                         32, 2}, {
156                         33, 2}, {
157                         34, 2}, {
158                         35, 2}, {
159                         36, 2}, {
160                         37, 2}, {
161                         36, 2}, {
162                         35, 2}, {
163                         34, 2}, {
164                         33, 2}
165                 }
166         }, {
167                 10, 0, {
168                         {
169                         38, 2}, {
170                         39, 2}, {
171                         40, 2}, {
172                         41, 2}, {
173                         42, 2}, {
174                         43, 2}, {
175                         42, 2}, {
176                         41, 2}, {
177                         40, 2}, {
178                         39, 2}
179                 }
180         }, {
181                 4, 0, {
182                         {
183                         76, 4}, {
184                         77, 4}, {
185                         78, 4}, {
186                         79, 4}, {
187                         0, 0}, {
188                         0, 0}, {
189                         0, 0}, {
190                         0, 0}, {
191                         0, 0}, {
192                         0, 0}
193                 }
194         }
195 };
196
197 struct {
198         int x, y;
199         int old_x, old_y;
200         int old_draw_x, old_draw_y;
201         int back[2];
202         int back_defined[2];
203 } flies[NUM_FLIES];
204
205 struct {
206         struct {
207                 short num_pobs;
208                 struct {
209                         int x, y;
210                         int image;
211                         gob_t *pob_data;
212                 } pobs[NUM_LEFTOVERS];
213         } page[2];
214 } leftovers;
215
216 int pogostick, bunnies_in_space, jetpack, lord_of_the_flies, blood_is_thicker_than_water;
217
218 static flip_pixels(unsigned char *pixels)
219 {
220         int x,y;
221         unsigned char temp;
222
223         assert(pixels);
224         for (y = 0; y < JNB_HEIGHT; y++) {
225                 for (x = 0; x < (352/2); x++) {
226                         temp = pixels[y*JNB_WIDTH+x];
227                         pixels[y*JNB_WIDTH+x] = pixels[y*JNB_WIDTH+(352-x)];
228                         pixels[y*JNB_WIDTH+(352-x)] = temp;
229                 }
230         }
231 }
232
233 int main(int argc, char *argv[])
234 {
235         FILE *handle;
236         int c1, c2 = 0, c3, c4;
237         int l1;
238         int s1, s2, s3, s4;
239         int closest_player = 0, dist, cur_dist;
240         int end_loop_flag, fade_flag;
241         int mod_vol, sfx_vol, mod_fade_direction;
242         char str1[100];
243         char pal[768];
244         char cur_pal[768];
245         int update_count;
246
247         if (init_program(argc, argv, pal) != 0)
248                 deinit_program();
249
250         if (main_info.fireworks == 1) {
251                 fireworks();
252                 deinit_program();
253         }
254
255         while (1) {
256
257                 if (menu() != 0)
258                         deinit_program();
259
260                 if (key_pressed(1) == 1) {
261                         break;
262                 }
263                 if (init_level(0, pal) != 0) {
264                         deinit_level();
265                         deinit_program();
266                 }
267
268                 memset(cur_pal, 0, 768);
269                 setpalette(0, 256, cur_pal);
270
271                 recalculate_gob(&rabbit_gobs, pal);
272                 //recalculate_gob(&font_gobs, pal);
273                 recalculate_gob(&object_gobs, pal);
274                 recalculate_gob(&number_gobs, pal);
275
276                 flippage(1);
277                 register_background(background_pic, pal);
278                 flippage(0);
279
280                 s1 = rnd(250) + 50;
281                 s2 = rnd(150) + 50;
282                 for (c1 = 0; c1 < NUM_FLIES; c1++) {
283                         while (1) {
284                                 flies[c1].x = s1 + rnd(101) - 50;
285                                 flies[c1].y = s2 + rnd(101) - 50;
286                                 if (ban_map[flies[c1].y >> 4][flies[c1].x >> 4] == BAN_VOID)
287                                         break;
288                         }
289                         flies[c1].back_defined[0] = 0;
290                         flies[c1].back_defined[1] = 0;
291                 }
292
293                 mod_vol = sfx_vol = 10;
294                 mod_fade_direction = 1;
295                 dj_ready_mod(MOD_GAME);
296                 dj_set_mod_volume((char)mod_vol);
297                 dj_set_sfx_volume((char)mod_vol);
298                 dj_start_mod();
299                 dj_play_sfx(SFX_FLY, SFX_FLY_FREQ, 0, 0, 0, 4);
300                 dj_set_nosound(0);
301
302                 lord_of_the_flies = bunnies_in_space = jetpack = pogostick = blood_is_thicker_than_water = 0;
303                 end_loop_flag = 0;
304                 main_info.page_info[0].num_pobs = 0;
305                 main_info.page_info[1].num_pobs = 0;
306                 main_info.view_page = 0;
307                 main_info.draw_page = 1;
308
309                 update_count = 1;
310                 while (1) {
311
312                         while (update_count) {
313
314                                 if (key_pressed(1) == 1) {
315                                         end_loop_flag = 1;
316                                         memset(pal, 0, 768);
317                                         mod_fade_direction = 0;
318                                 }
319
320                                 if (strncmp(last_keys, "kcitsogop", strlen("kcitsogop")) == 0) {
321                                         pogostick ^= 1;
322                                         last_keys[0] = 0;
323                                 }
324                                 if (strncmp(last_keys, "ecapsniseinnub", strlen("ecapsniseinnub")) == 0) {
325                                         bunnies_in_space ^= 1;
326                                         last_keys[0] = 0;
327                                 }
328                                 if (strncmp(last_keys, "kcaptej", strlen("kcaptej")) == 0) {
329                                         jetpack ^= 1;
330                                         last_keys[0] = 0;
331                                 }
332                                 if (strncmp(last_keys, "seilfehtfodrol", strlen("seilfehtfodrol")) == 0) {
333                                         lord_of_the_flies ^= 1;
334                                         last_keys[0] = 0;
335                                 }
336                                 if (strncmp(last_keys, "retawnahtrekcihtsidoolb", strlen("retawnahtrekcihtsidoolb")) == 0) {
337                                         blood_is_thicker_than_water ^= 1;
338                                         if (blood_is_thicker_than_water == 1) {
339                                                 pal[432] = 63;
340                                                 pal[433] = 32;
341                                                 pal[434] = 32;
342                                                 pal[435] = 53;
343                                                 pal[436] = 17;
344                                                 pal[437] = 17;
345                                                 pal[438] = 42;
346                                                 pal[439] = 7;
347                                                 pal[440] = 7;
348                                                 pal[441] = 28;
349                                                 pal[442] = 0;
350                                                 pal[443] = 0;
351                                                 pal[444] = 24;
352                                                 pal[445] = 0;
353                                                 pal[446] = 0;
354                                                 pal[447] = 19;
355                                                 pal[448] = 0;
356                                                 pal[449] = 0;
357                                                 pal[450] = 12;
358                                                 pal[451] = 0;
359                                                 pal[452] = 0;
360                                                 pal[453] = 7;
361                                                 pal[454] = 0;
362                                                 pal[455] = 0;
363                                         } else {
364                                                 pal[432] = 63;
365                                                 pal[433] = 63;
366                                                 pal[434] = 63;
367                                                 pal[435] = 40;
368                                                 pal[436] = 53;
369                                                 pal[437] = 62;
370                                                 pal[438] = 19;
371                                                 pal[439] = 42;
372                                                 pal[440] = 60;
373                                                 pal[441] = 0;
374                                                 pal[442] = 33;
375                                                 pal[443] = 60;
376                                                 pal[444] = 3;
377                                                 pal[445] = 32;
378                                                 pal[446] = 46;
379                                                 pal[447] = 3;
380                                                 pal[448] = 26;
381                                                 pal[449] = 33;
382                                                 pal[450] = 3;
383                                                 pal[451] = 19;
384                                                 pal[452] = 21;
385                                                 pal[453] = 1;
386                                                 pal[454] = 8;
387                                                 pal[455] = 8;
388                                         }
389                                         register_background(background_pic, pal);
390                                         recalculate_gob(&object_gobs, pal);
391                                         last_keys[0] = 0;
392                                 }
393
394                                 steer_players();
395
396                                 dj_mix();
397
398                                 for (c3 = 0; c3 < 6; c3++) {
399                                         if (c3 == 0) {
400                                                 c1 = 0;
401                                                 c2 = 1;
402                                         } else if (c3 == 1) {
403                                                 c1 = 0;
404                                                 c2 = 2;
405                                         } else if (c3 == 2) {
406                                                 c1 = 0;
407                                                 c2 = 3;
408                                         } else if (c3 == 3) {
409                                                 c1 = 1;
410                                                 c2 = 2;
411                                         } else if (c3 == 4) {
412                                                 c1 = 1;
413                                                 c2 = 3;
414                                         } else if (c3 == 5) {
415                                                 c1 = 2;
416                                                 c2 = 3;
417                                         }
418                                         if (player[c1].enabled == 1 && player[c2].enabled == 1) {
419                                                 if (labs(player[c1].x - player[c2].x) < (12L << 16) && labs(player[c1].y - player[c2].y) < (12L << 16)) {
420                                                         if ((labs(player[c1].y - player[c2].y) >> 16) > 5) {
421                                                                 if (player[c1].y < player[c2].y) {
422                                                                         if (player[c1].y_add >= 0) {
423                                                                                 player[c1].y_add = -player[c1].y_add;
424                                                                                 if (player[c1].y_add > -262144L)
425                                                                                         player[c1].y_add = -262144L;
426                                                                                 player[c1].jump_abort = 1;
427                                                                                 player[c2].dead_flag = 1;
428                                                                                 if (player[c2].anim != 6) {
429                                                                                         player[c2].anim = 6;
430                                                                                         player[c2].frame = 0;
431                                                                                         player[c2].frame_tick = 0;
432                                                                                         player[c2].image = player_anims[player[c2].anim].frame[player[c2].frame].image + player[c2].direction * 9;
433                                                                                         if (main_info.no_gore == 0) {
434                                                                                                 for (c4 = 0; c4 < 6; c4++)
435                                                                                                         add_object(OBJ_FUR, (player[c2].x >> 16) + 6 + rnd(5), (player[c2].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 44 + c2 * 8);
436                                                                                                 for (c4 = 0; c4 < 6; c4++)
437                                                                                                         add_object(OBJ_FLESH, (player[c2].x >> 16) + 6 + rnd(5), (player[c2].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 76);
438                                                                                                 for (c4 = 0; c4 < 6; c4++)
439                                                                                                         add_object(OBJ_FLESH, (player[c2].x >> 16) + 6 + rnd(5), (player[c2].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 77);
440                                                                                                 for (c4 = 0; c4 < 8; c4++)
441                                                                                                         add_object(OBJ_FLESH, (player[c2].x >> 16) + 6 + rnd(5), (player[c2].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 78);
442                                                                                                 for (c4 = 0; c4 < 10; c4++)
443                                                                                                         add_object(OBJ_FLESH, (player[c2].x >> 16) + 6 + rnd(5), (player[c2].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 79);
444                                                                                         }
445                                                                                         dj_play_sfx(SFX_DEATH, (unsigned short)(SFX_DEATH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
446                                                                                         player[c1].bumps++;
447                                                                                         player[c1].bumped[c2]++;
448                                                                                         s1 = player[c1].bumps % 100;
449                                                                                         add_leftovers(0, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
450                                                                                         add_leftovers(1, 360, 34 + c1 * 64, s1 / 10, &number_gobs);
451                                                                                         add_leftovers(0, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
452                                                                                         add_leftovers(1, 376, 34 + c1 * 64, s1 - (s1 / 10) * 10, &number_gobs);
453                                                                                 }
454                                                                         } else {
455                                                                                 if (player[c2].y_add < 0)
456                                                                                         player[c2].y_add = 0;
457                                                                         }
458                                                                 } else {
459                                                                         if (player[c2].y_add >= 0) {
460                                                                                 player[c2].y_add = -player[c2].y_add;
461                                                                                 if (player[c2].y_add > -262144L)
462                                                                                         player[c2].y_add = -262144L;
463                                                                                 player[c2].jump_abort = 1;
464                                                                                 player[c1].dead_flag = 1;
465                                                                                 if (player[c1].anim != 6) {
466                                                                                         player[c1].anim = 6;
467                                                                                         player[c1].frame = 0;
468                                                                                         player[c1].frame_tick = 0;
469                                                                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
470                                                                                         if (main_info.no_gore == 0) {
471                                                                                                 for (c4 = 0; c4 < 6; c4++)
472                                                                                                         add_object(OBJ_FUR, (player[c1].x >> 16) + 6 + rnd(5), (player[c1].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 44 + c1 * 8);
473                                                                                                 for (c4 = 0; c4 < 6; c4++)
474                                                                                                         add_object(OBJ_FLESH, (player[c1].x >> 16) + 6 + rnd(5), (player[c1].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 76);
475                                                                                                 for (c4 = 0; c4 < 7; c4++)
476                                                                                                         add_object(OBJ_FLESH, (player[c1].x >> 16) + 6 + rnd(5), (player[c1].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 77);
477                                                                                                 for (c4 = 0; c4 < 8; c4++)
478                                                                                                         add_object(OBJ_FLESH, (player[c1].x >> 16) + 6 + rnd(5), (player[c1].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 78);
479                                                                                                 for (c4 = 0; c4 < 10; c4++)
480                                                                                                         add_object(OBJ_FLESH, (player[c1].x >> 16) + 6 + rnd(5), (player[c1].y >> 16) + 6 + rnd(5), (rnd(65535) - 32768) * 3, (rnd(65535) - 32768) * 3, 0, 79);
481                                                                                         }
482                                                                                         dj_play_sfx(SFX_DEATH, (unsigned short)(SFX_DEATH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
483                                                                                         player[c2].bumps++;
484                                                                                         player[c2].bumped[c1]++;
485                                                                                         s1 = player[c2].bumps % 100;
486                                                                                         add_leftovers(0, 360, 34 + c2 * 64, s1 / 10, &number_gobs);
487                                                                                         add_leftovers(1, 360, 34 + c2 * 64, s1 / 10, &number_gobs);
488                                                                                         add_leftovers(0, 376, 34 + c2 * 64, s1 - (s1 / 10) * 10, &number_gobs);
489                                                                                         add_leftovers(1, 376, 34 + c2 * 64, s1 - (s1 / 10) * 10, &number_gobs);
490                                                                                 }
491                                                                         } else {
492                                                                                 if (player[c1].y_add < 0)
493                                                                                         player[c1].y_add = 0;
494                                                                         }
495                                                                 }
496                                                         } else {
497                                                                 if (player[c1].x < player[c2].x) {
498                                                                         if (player[c1].x_add > 0)
499                                                                                 player[c1].x = player[c2].x - (12L << 16);
500                                                                         else if (player[c2].x_add < 0)
501                                                                                 player[c2].x = player[c1].x + (12L << 16);
502                                                                         else {
503                                                                                 player[c1].x -= player[c1].x_add;
504                                                                                 player[c2].x -= player[c2].x_add;
505                                                                         }
506                                                                         l1 = player[c2].x_add;
507                                                                         player[c2].x_add = player[c1].x_add;
508                                                                         player[c1].x_add = l1;
509                                                                         if (player[c1].x_add > 0)
510                                                                                 player[c1].x_add = -player[c1].x_add;
511                                                                         if (player[c2].x_add < 0)
512                                                                                 player[c2].x_add = -player[c2].x_add;
513                                                                 } else {
514                                                                         if (player[c1].x_add > 0)
515                                                                                 player[c2].x = player[c1].x - (12L << 16);
516                                                                         else if (player[c2].x_add < 0)
517                                                                                 player[c1].x = player[c2].x + (12L << 16);
518                                                                         else {
519                                                                                 player[c1].x -= player[c1].x_add;
520                                                                                 player[c2].x -= player[c2].x_add;
521                                                                         }
522                                                                         l1 = player[c2].x_add;
523                                                                         player[c2].x_add = player[c1].x_add;
524                                                                         player[c1].x_add = l1;
525                                                                         if (player[c1].x_add < 0)
526                                                                                 player[c1].x_add = -player[c1].x_add;
527                                                                         if (player[c2].x_add > 0)
528                                                                                 player[c2].x_add = -player[c2].x_add;
529                                                                 }
530                                                         }
531                                                 }
532                                         }
533                                 }
534
535                                 dj_mix();
536
537                                 main_info.page_info[main_info.draw_page].num_pobs = 0;
538                                 for (c1 = 0; c1 < 4; c1++) {
539                                         if (player[c1].enabled == 1)
540                                                 main_info.page_info[main_info.draw_page].num_pobs++;
541                                 }
542
543                                 update_objects();
544
545                                 dj_mix();
546
547                                 /* get center of fly swarm */
548                                 s1 = s2 = 0;
549                                 for (c1 = 0; c1 < NUM_FLIES; c1++) {
550                                         s1 += flies[c1].x;
551                                         s2 += flies[c1].y;
552                                 }
553                                 s1 /= NUM_FLIES;
554                                 s2 /= NUM_FLIES;
555
556                                 if (update_count == 1) {
557                                         /* get closest player to fly swarm */
558                                         dist = 0x7fff;
559                                         for (c1 = 0; c1 < 4; c1++) {
560                                                 if (player[c1].enabled == 1) {
561                                                         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)));
562                                                         if (cur_dist < dist) {
563                                                                 closest_player = c1;
564                                                                 dist = cur_dist;
565                                                         }
566                                                 }
567                                         }
568                                         /* update fly swarm sound */
569                                         s3 = 32 - dist / 3;
570                                         if (s3 < 0)
571                                                 s3 = 0;
572                                         dj_set_sfx_channel_volume(4, (char)(s3));
573                                 }
574
575                                 for (c1 = 0; c1 < NUM_FLIES; c1++) {
576                                         /* get closest player to fly */
577                                         dist = 0x7fff;
578                                         for (c2 = 0; c2 < 4; c2++) {
579                                                 if (player[c2].enabled == 1) {
580                                                         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)));
581                                                         if (cur_dist < dist) {
582                                                                 closest_player = c2;
583                                                                 dist = cur_dist;
584                                                         }
585                                                 }
586                                         }
587                                         flies[c1].old_x = flies[c1].x;
588                                         flies[c1].old_y = flies[c1].y;
589                                         s3 = 0;
590                                         if ((s1 - flies[c1].x) > 30)
591                                                 s3 += 1;
592                                         else if ((s1 - flies[c1].x) < -30)
593                                                 s3 -= 1;
594                                         if (dist < 30) {
595                                                 if (((player[closest_player].x >> 16) + 8) > flies[c1].x) {
596                                                         if (lord_of_the_flies == 0)
597                                                                 s3 -= 1;
598                                                         else
599                                                                 s3 += 1;
600                                                 } else {
601                                                         if (lord_of_the_flies == 0)
602                                                                 s3 += 1;
603                                                         else
604                                                                 s3 -= 1;
605                                                 }
606                                         }
607                                         s4 = rnd(3) - 1 + s3;
608                                         if ((flies[c1].x + s4) < 16)
609                                                 s4 = 0;
610                                         if ((flies[c1].x + s4) > 351)
611                                                 s4 = 0;
612                                         if (ban_map[flies[c1].y >> 4][(flies[c1].x + s4) >> 4] != BAN_VOID)
613                                                 s4 = 0;
614                                         flies[c1].x += s4;
615                                         s3 = 0;
616                                         if ((s2 - flies[c1].y) > 30)
617                                                 s3 += 1;
618                                         else if ((s2 - flies[c1].y) < -30)
619                                                 s3 -= 1;
620                                         if (dist < 30) {
621                                                 if (((player[closest_player].y >> 16) + 8) > flies[c1].y) {
622                                                         if (lord_of_the_flies == 0)
623                                                                 s3 -= 1;
624                                                         else
625                                                                 s3 += 1;
626                                                 } else {
627                                                         if (lord_of_the_flies == 0)
628                                                                 s3 += 1;
629                                                         else
630                                                                 s3 -= 1;
631                                                 }
632                                         }
633                                         s4 = rnd(3) - 1 + s3;
634                                         if ((flies[c1].y + s4) < 0)
635                                                 s4 = 0;
636                                         if ((flies[c1].y + s4) > 239)
637                                                 s4 = 0;
638                                         if (ban_map[(flies[c1].y + s4) >> 4][flies[c1].x >> 4] != BAN_VOID)
639                                                 s4 = 0;
640                                         flies[c1].y += s4;
641                                 }
642
643                                 dj_mix();
644
645                                 s1 = 0;
646                                 for (c1 = 0; c1 < 4; c1++) {
647                                         if (player[c1].enabled == 1) {
648                                                 main_info.page_info[main_info.draw_page].pobs[s1].x = player[c1].x >> 16;
649                                                 main_info.page_info[main_info.draw_page].pobs[s1].y = player[c1].y >> 16;
650                                                 main_info.page_info[main_info.draw_page].pobs[s1].image = player[c1].image + c1 * 18;
651                                                 main_info.page_info[main_info.draw_page].pobs[s1].pob_data = &rabbit_gobs;
652                                                 s1++;
653                                         }
654                                 }
655
656                                 if (update_count == 1) {
657                                         draw_begin();
658
659                                         draw_pobs(main_info.draw_page);
660
661                                         dj_mix();
662
663                                         draw_flies(main_info.draw_page);
664
665                                         draw_end();
666                                 }
667
668                                 if (mod_fade_direction == 1) {
669                                         if (mod_vol < 30) {
670                                                 mod_vol++;
671                                                 dj_set_mod_volume((char)mod_vol);
672                                         }
673                                 } else {
674                                         if (mod_vol > 0) {
675                                                 mod_vol--;
676                                                 dj_set_mod_volume((char)mod_vol);
677                                         }
678                                 }
679
680                                 if (mod_fade_direction == 1) {
681                                         if (sfx_vol < 64) {
682                                                 sfx_vol++;
683                                                 dj_set_sfx_volume((char)sfx_vol);
684                                         }
685                                 } else {
686                                         if (sfx_vol > 0) {
687                                                 sfx_vol--;
688                                                 dj_set_sfx_volume((char)sfx_vol);
689                                         }
690                                 }
691
692                                 fade_flag = 0;
693                                 for (c1 = 0; c1 < 768; c1++) {
694                                         if (cur_pal[c1] < pal[c1]) {
695                                                 cur_pal[c1]++;
696                                                 fade_flag = 1;
697                                         } else if (cur_pal[c1] > pal[c1]) {
698                                                 cur_pal[c1]--;
699                                                 fade_flag = 1;
700                                         }
701                                 }
702                                 if (fade_flag == 0 && end_loop_flag == 1)
703                                         break;
704
705                                 if (update_count == 1) {
706                                         main_info.draw_page ^= 1;
707                                         main_info.view_page ^= 1;
708
709                                         flippage(main_info.view_page);
710         
711                                         wait_vrt(1);
712                                 }
713
714                                 if (fade_flag == 1)
715                                         setpalette(0, 256, cur_pal);
716
717                                 if (update_count == 1) {
718                                         draw_begin();
719
720                                         redraw_flies_background(main_info.draw_page);
721
722                                         redraw_pob_backgrounds(main_info.draw_page);
723
724                                         draw_leftovers(main_info.draw_page);
725
726                                         draw_end();
727                                 }
728
729                                 update_count--;
730                         }
731
732                         update_count = intr_sysupdate();
733
734                         if (fade_flag == 0 && end_loop_flag == 1)
735                                 break;
736                 }
737
738                 main_info.view_page = 0;
739                 main_info.draw_page = 1;
740
741                 dj_stop_sfx_channel(4);
742
743                 deinit_level();
744
745                 memset(mask_pic, 0, 102400L);
746                 register_mask(mask_pic);
747
748                 //recalculate_gob(&font_gobs, pal);
749                 register_background(NULL, NULL);
750
751                 draw_begin();
752
753                 put_text(main_info.view_page, 100, 50, "DOTT", 2);
754                 put_text(main_info.view_page, 160, 50, "JIFFY", 2);
755                 put_text(main_info.view_page, 220, 50, "FIZZ", 2);
756                 put_text(main_info.view_page, 280, 50, "MIJJI", 2);
757                 put_text(main_info.view_page, 40, 80, "DOTT", 2);
758                 put_text(main_info.view_page, 40, 110, "JIFFY", 2);
759                 put_text(main_info.view_page, 40, 140, "FIZZ", 2);
760                 put_text(main_info.view_page, 40, 170, "MIJJI", 2);
761
762                 for (c1 = 0; c1 < 4; c1++) {
763                         for (c2 = 0; c2 < 4; c2++) {
764                                 if (c2 != c1) {
765                                         sprintf(str1, "%d", player[c1].bumped[c2]);
766                                         put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, str1, 2);
767                                 } else
768                                         put_text(main_info.view_page, 100 + c2 * 60, 80 + c1 * 30, "-", 2);
769                         }
770                         sprintf(str1, "%d", player[c1].bumps);
771                         put_text(main_info.view_page, 350, 80 + c1 * 30, str1, 2);
772                 }
773
774                 put_text(main_info.view_page, 200, 230, "Press ESC to continue", 2);
775
776                 draw_end();
777
778                 flippage(main_info.view_page);
779
780                 if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
781                         strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
782                         return 1;
783                 }
784                 if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
785                         strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
786                         return 1;
787                 }
788                 fclose(handle);
789
790                 memset(cur_pal, 0, 768);
791
792                 setpalette(0, 256, cur_pal);
793
794                 mod_vol = 0;
795                 dj_ready_mod(MOD_SCORES);
796                 dj_set_mod_volume((char)mod_vol);
797                 dj_start_mod();
798                 dj_set_nosound(0);
799
800                 while (key_pressed(1) == 0) {
801                         if (mod_vol < 35)
802                                 mod_vol++;
803                         dj_set_mod_volume((char)mod_vol);
804                         for (c1 = 0; c1 < 768; c1++) {
805                                 if (cur_pal[c1] < pal[c1])
806                                         cur_pal[c1]++;
807                         }
808                         dj_mix();
809                         intr_sysupdate();
810                         wait_vrt(0);
811                         setpalette(0, 256, cur_pal);
812                         flippage(main_info.view_page);
813                 }
814                 while (key_pressed(1) == 1) {
815                         dj_mix();
816                         intr_sysupdate();
817                 }
818
819                 memset(pal, 0, 768);
820
821                 while (mod_vol > 0) {
822                         mod_vol--;
823                         dj_set_mod_volume((char)mod_vol);
824                         for (c1 = 0; c1 < 768; c1++) {
825                                 if (cur_pal[c1] > pal[c1])
826                                         cur_pal[c1]--;
827                         }
828                         dj_mix();
829                         wait_vrt(0);
830                         setpalette(0, 256, cur_pal);
831                         flippage(main_info.view_page);
832                 }
833
834                 fillpalette(0, 0, 0);
835
836                 dj_set_nosound(1);
837                 dj_stop_mod();
838
839         }
840
841         deinit_program();
842
843         return 0;
844 }
845
846
847 void steer_players(void)
848 {
849         int c1, c2;
850         int s1 = 0, s2 = 0;
851
852         update_player_actions();
853
854         for (c1 = 0; c1 < 4; c1++) {
855
856                 if (player[c1].enabled == 1) {
857
858                         if (player[c1].dead_flag == 0) {
859
860                                 if (player[c1].action_left && player[c1].action_right) {
861                                         if (player[c1].direction == 0) {
862                                                 if (player[c1].action_right) {
863                                                         s1 = (player[c1].x >> 16);
864                                                         s2 = (player[c1].y >> 16);
865                                                         if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
866                                                                 if (player[c1].x_add < 0)
867                                                                         player[c1].x_add += 1024;
868                                                                 else
869                                                                         player[c1].x_add += 768;
870                                                         } 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)) {
871                                                                 if (player[c1].x_add > 0)
872                                                                         player[c1].x_add += 1024;
873                                                                 else
874                                                                         player[c1].x_add += 768;
875                                                         } else {
876                                                                 if (player[c1].x_add < 0) {
877                                                                         player[c1].x_add += 16384;
878                                                                         if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
879                                                                                 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);
880                                                                 } else
881                                                                         player[c1].x_add += 12288;
882                                                         }
883                                                         if (player[c1].x_add > 98304L)
884                                                                 player[c1].x_add = 98304L;
885                                                         player[c1].direction = 0;
886                                                         if (player[c1].anim == 0) {
887                                                                 player[c1].anim = 1;
888                                                                 player[c1].frame = 0;
889                                                                 player[c1].frame_tick = 0;
890                                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
891                                                         }
892                                                 }
893                                         } else {
894                                                 if (player[c1].action_left) {
895                                                         s1 = (player[c1].x >> 16);
896                                                         s2 = (player[c1].y >> 16);
897                                                         if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
898                                                                 if (player[c1].x_add > 0)
899                                                                         player[c1].x_add -= 1024;
900                                                                 else
901                                                                         player[c1].x_add -= 768;
902                                                         } 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)) {
903                                                                 if (player[c1].x_add > 0)
904                                                                         player[c1].x_add -= 1024;
905                                                                 else
906                                                                         player[c1].x_add -= 768;
907                                                         } else {
908                                                                 if (player[c1].x_add > 0) {
909                                                                         player[c1].x_add -= 16384;
910                                                                         if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
911                                                                                 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);
912                                                                 } else
913                                                                         player[c1].x_add -= 12288;
914                                                         }
915                                                         if (player[c1].x_add < -98304L)
916                                                                 player[c1].x_add = -98304L;
917                                                         player[c1].direction = 1;
918                                                         if (player[c1].anim == 0) {
919                                                                 player[c1].anim = 1;
920                                                                 player[c1].frame = 0;
921                                                                 player[c1].frame_tick = 0;
922                                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
923                                                         }
924                                                 }
925                                         }
926                                 } else if (player[c1].action_left) {
927                                         s1 = (player[c1].x >> 16);
928                                         s2 = (player[c1].y >> 16);
929                                         if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
930                                                 if (player[c1].x_add > 0)
931                                                         player[c1].x_add -= 1024;
932                                                 else
933                                                         player[c1].x_add -= 768;
934                                         } 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)) {
935                                                 if (player[c1].x_add > 0)
936                                                         player[c1].x_add -= 1024;
937                                                 else
938                                                         player[c1].x_add -= 768;
939                                         } else {
940                                                 if (player[c1].x_add > 0) {
941                                                         player[c1].x_add -= 16384;
942                                                         if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
943                                                                 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);
944                                                 } else
945                                                         player[c1].x_add -= 12288;
946                                         }
947                                         if (player[c1].x_add < -98304L)
948                                                 player[c1].x_add = -98304L;
949                                         player[c1].direction = 1;
950                                         if (player[c1].anim == 0) {
951                                                 player[c1].anim = 1;
952                                                 player[c1].frame = 0;
953                                                 player[c1].frame_tick = 0;
954                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
955                                         }
956                                 } else if (player[c1].action_right) {
957                                         s1 = (player[c1].x >> 16);
958                                         s2 = (player[c1].y >> 16);
959                                         if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
960                                                 if (player[c1].x_add < 0)
961                                                         player[c1].x_add += 1024;
962                                                 else
963                                                         player[c1].x_add += 768;
964                                         } 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)) {
965                                                 if (player[c1].x_add > 0)
966                                                         player[c1].x_add += 1024;
967                                                 else
968                                                         player[c1].x_add += 768;
969                                         } else {
970                                                 if (player[c1].x_add < 0) {
971                                                         player[c1].x_add += 16384;
972                                                         if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
973                                                                 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);
974                                                 } else
975                                                         player[c1].x_add += 12288;
976                                         }
977                                         if (player[c1].x_add > 98304L)
978                                                 player[c1].x_add = 98304L;
979                                         player[c1].direction = 0;
980                                         if (player[c1].anim == 0) {
981                                                 player[c1].anim = 1;
982                                                 player[c1].frame = 0;
983                                                 player[c1].frame_tick = 0;
984                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
985                                         }
986                                 } else if ((!player[c1].action_left) && (!player[c1].action_right)) {
987                                         s1 = (player[c1].x >> 16);
988                                         s2 = (player[c1].y >> 16);
989                                         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)))) {
990                                                 if (player[c1].x_add < 0) {
991                                                         player[c1].x_add += 16384;
992                                                         if (player[c1].x_add > 0)
993                                                                 player[c1].x_add = 0;
994                                                 } else {
995                                                         player[c1].x_add -= 16384;
996                                                         if (player[c1].x_add < 0)
997                                                                 player[c1].x_add = 0;
998                                                 }
999                                                 if (player[c1].x_add != 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1000                                                         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);
1001                                         }
1002                                         if (player[c1].anim == 1) {
1003                                                 player[c1].anim = 0;
1004                                                 player[c1].frame = 0;
1005                                                 player[c1].frame_tick = 0;
1006                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1007                                         }
1008                                 }
1009                                 if (jetpack == 0) {
1010                                         if (pogostick == 1 || (player[c1].jump_ready == 1 && player[c1].action_up)) {
1011                                                 s1 = (player[c1].x >> 16);
1012                                                 s2 = (player[c1].y >> 16);
1013                                                 if (s2 < -16)
1014                                                         s2 = -16;
1015                                                 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) {
1016                                                         player[c1].y_add = -280000L;
1017                                                         player[c1].anim = 2;
1018                                                         player[c1].frame = 0;
1019                                                         player[c1].frame_tick = 0;
1020                                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1021                                                         player[c1].jump_ready = 0;
1022                                                         player[c1].jump_abort = 1;
1023                                                         if (pogostick == 0)
1024                                                                 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1025                                                         else
1026                                                                 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1027                                                 }
1028                                                 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)) {
1029                                                         player[c1].y_add = -196608L;
1030                                                         player[c1].in_water = 0;
1031                                                         player[c1].anim = 2;
1032                                                         player[c1].frame = 0;
1033                                                         player[c1].frame_tick = 0;
1034                                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1035                                                         player[c1].jump_ready = 0;
1036                                                         player[c1].jump_abort = 1;
1037                                                         if (pogostick == 0)
1038                                                                 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1039                                                         else
1040                                                                 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1041                                                 }
1042                                         }
1043                                         if (pogostick == 0 && (!player[c1].action_up)) {
1044                                                 player[c1].jump_ready = 1;
1045                                                 if (player[c1].in_water == 0 && player[c1].y_add < 0 && player[c1].jump_abort == 1) {
1046                                                         if (bunnies_in_space == 0)
1047                                                                 player[c1].y_add += 32768;
1048                                                         else
1049                                                                 player[c1].y_add += 16384;
1050                                                         if (player[c1].y_add > 0)
1051                                                                 player[c1].y_add = 0;
1052                                                 }
1053                                         }
1054                                 } else {
1055
1056                                         if (player[c1].action_up) {
1057                                                 player[c1].y_add -= 16384;
1058                                                 if (player[c1].y_add < -400000L)
1059                                                         player[c1].y_add = -400000L;
1060                                                 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))
1061                                                         player[c1].in_water = 0;
1062                                                 if (rnd(100) < 50)
1063                                                         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);
1064                                         }
1065
1066                                 }
1067
1068                                 player[c1].x += player[c1].x_add;
1069                                 if ((player[c1].x >> 16) < 0) {
1070                                         player[c1].x = 0;
1071                                         player[c1].x_add = 0;
1072                                 }
1073                                 if ((player[c1].x >> 16) + 15 > 351) {
1074                                         player[c1].x = 336L << 16;
1075                                         player[c1].x_add = 0;
1076                                 }
1077                                 if (player[c1].y > 0) {
1078                                         s1 = (player[c1].x >> 16);
1079                                         s2 = (player[c1].y >> 16);
1080                                         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) {
1081                                                 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1082                                                 player[c1].x_add = 0;
1083                                         }
1084                                         s1 = (player[c1].x >> 16);
1085                                         s2 = (player[c1].y >> 16);
1086                                         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) {
1087                                                 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1088                                                 player[c1].x_add = 0;
1089                                         }
1090                                 } else {
1091                                         s1 = (player[c1].x >> 16);
1092                                         s2 = 0;
1093                                         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) {
1094                                                 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1095                                                 player[c1].x_add = 0;
1096                                         }
1097                                         s1 = (player[c1].x >> 16);
1098                                         s2 = 0;
1099                                         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) {
1100                                                 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1101                                                 player[c1].x_add = 0;
1102                                         }
1103                                 }
1104
1105                                 player[c1].y += player[c1].y_add;
1106
1107                                 s1 = (player[c1].x >> 16);
1108                                 s2 = (player[c1].y >> 16);
1109                                 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))) {
1110                                         player[c1].y = ((player[c1].y >> 16) & 0xfff0) << 16;
1111                                         player[c1].y_add = -400000L;
1112                                         player[c1].anim = 2;
1113                                         player[c1].frame = 0;
1114                                         player[c1].frame_tick = 0;
1115                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1116                                         player[c1].jump_ready = 0;
1117                                         player[c1].jump_abort = 0;
1118                                         for (c2 = 0; c2 < NUM_OBJECTS; c2++) {
1119                                                 if (objects[c2].used == 1 && objects[c2].type == OBJ_SPRING) {
1120                                                         if (ban_map[(s2 + 15) >> 4][(s1 + 8) >> 4] == BAN_SPRING) {
1121                                                                 if ((objects[c2].x >> 20) == ((s1 + 8) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1122                                                                         objects[c2].frame = 0;
1123                                                                         objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1124                                                                         objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1125                                                                         break;
1126                                                                 }
1127                                                         } else {
1128                                                                 if (ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
1129                                                                         if ((objects[c2].x >> 20) == (s1 >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1130                                                                                 objects[c2].frame = 0;
1131                                                                                 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1132                                                                                 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1133                                                                                 break;
1134                                                                         }
1135                                                                 } else if (ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1136                                                                         if ((objects[c2].x >> 20) == ((s1 + 15) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1137                                                                                 objects[c2].frame = 0;
1138                                                                                 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1139                                                                                 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1140                                                                                 break;
1141                                                                         }
1142                                                                 }
1143                                                         }
1144                                                 }
1145                                         }
1146                                         dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1147                                 }
1148                                 s1 = (player[c1].x >> 16);
1149                                 s2 = (player[c1].y >> 16);
1150                                 if (s2 < 0)
1151                                         s2 = 0;
1152                                 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) {
1153                                         player[c1].y = (((s2 + 16) & 0xfff0)) << 16;
1154                                         player[c1].y_add = 0;
1155                                         player[c1].anim = 0;
1156                                         player[c1].frame = 0;
1157                                         player[c1].frame_tick = 0;
1158                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1159                                 }
1160                                 s1 = (player[c1].x >> 16);
1161                                 s2 = (player[c1].y >> 16);
1162                                 if (s2 < 0)
1163                                         s2 = 0;
1164                                 if (ban_map[(s2 + 8) >> 4][(s1 + 8) >> 4] == BAN_WATER) {
1165                                         if (player[c1].in_water == 0) {
1166                                                 player[c1].in_water = 1;
1167                                                 player[c1].anim = 4;
1168                                                 player[c1].frame = 0;
1169                                                 player[c1].frame_tick = 0;
1170                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1171                                                 if (player[c1].y_add >= 32768) {
1172                                                         add_object(OBJ_SPLASH, (player[c1].x >> 16) + 8, ((player[c1].y >> 16) & 0xfff0) + 15, 0, 0, OBJ_ANIM_SPLASH, 0);
1173                                                         if (blood_is_thicker_than_water == 0)
1174                                                                 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1175                                                         else
1176                                                                 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 5000), 64, 0, 0, -1);
1177                                                 }
1178                                         }
1179                                         player[c1].y_add -= 1536;
1180                                         if (player[c1].y_add < 0 && player[c1].anim != 5) {
1181                                                 player[c1].anim = 5;
1182                                                 player[c1].frame = 0;
1183                                                 player[c1].frame_tick = 0;
1184                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1185                                         }
1186                                         if (player[c1].y_add < -65536L)
1187                                                 player[c1].y_add = -65536L;
1188                                         if (player[c1].y_add > 65535L)
1189                                                 player[c1].y_add = 65535L;
1190                                         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) {
1191                                                 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1192                                                 player[c1].y_add = 0;
1193                                         }
1194                                 } 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) {
1195                                         player[c1].in_water = 0;
1196                                         player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1197                                         player[c1].y_add = 0;
1198                                         if (player[c1].anim != 0 && player[c1].anim != 1) {
1199                                                 player[c1].anim = 0;
1200                                                 player[c1].frame = 0;
1201                                                 player[c1].frame_tick = 0;
1202                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1203                                         }
1204                                 } else {
1205                                         if (player[c1].in_water == 0) {
1206                                                 if (bunnies_in_space == 0)
1207                                                         player[c1].y_add += 12288;
1208                                                 else
1209                                                         player[c1].y_add += 6144;
1210                                                 if (player[c1].y_add > 327680L)
1211                                                         player[c1].y_add = 327680L;
1212                                         } else {
1213                                                 player[c1].y = (player[c1].y & 0xffff0000) + 0x10000;
1214                                                 player[c1].y_add = 0;
1215                                         }
1216                                         player[c1].in_water = 0;
1217                                 }
1218                                 if (player[c1].y_add > 36864 && player[c1].anim != 3 && player[c1].in_water == 0) {
1219                                         player[c1].anim = 3;
1220                                         player[c1].frame = 0;
1221                                         player[c1].frame_tick = 0;
1222                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1223                                 }
1224
1225                         }
1226
1227                         player[c1].frame_tick++;
1228                         if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
1229                                 player[c1].frame++;
1230                                 if (player[c1].frame >= player_anims[player[c1].anim].num_frames) {
1231                                         if (player[c1].anim != 6)
1232                                                 player[c1].frame = player_anims[player[c1].anim].restart_frame;
1233                                         else
1234                                                 position_player(c1);
1235                                 }
1236                                 player[c1].frame_tick = 0;
1237                         }
1238                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1239
1240                 }
1241
1242         }
1243
1244 }
1245
1246
1247 void position_player(int player_num)
1248 {
1249         int c1;
1250         int s1, s2;
1251
1252         while (1) {
1253                 while (1) {
1254                         s1 = rnd(22);
1255                         s2 = rnd(16);
1256                         if (ban_map[s2][s1] == BAN_VOID && (ban_map[s2 + 1][s1] == BAN_SOLID || ban_map[s2 + 1][s1] == BAN_ICE))
1257                                 break;
1258                 }
1259                 for (c1 = 0; c1 < 4; c1++) {
1260                         if (c1 != player_num && player[c1].enabled == 1) {
1261                                 if (abs((s1 << 4) - (player[c1].x >> 16)) < 32 && abs((s2 << 4) - (player[c1].y >> 16)) < 32)
1262                                         break;
1263                         }
1264                 }
1265                 if (c1 == 4) {
1266                         player[player_num].dead_flag = 0;
1267                         player[player_num].x = (long) s1 << 20;
1268                         player[player_num].y = (long) s2 << 20;
1269                         player[player_num].x_add = player[player_num].y_add = 0;
1270                         player[player_num].direction = 0;
1271                         player[player_num].jump_ready = 1;
1272                         player[player_num].in_water = 0;
1273                         player[player_num].anim = 0;
1274                         player[player_num].frame = 0;
1275                         player[player_num].frame_tick = 0;
1276                         player[player_num].image = player_anims[player[player_num].anim].frame[player[player_num].frame].image;
1277                         break;
1278                 }
1279         }
1280
1281 }
1282
1283
1284 void add_object(int type, int x, int y, int x_add, int y_add, int anim, int frame)
1285 {
1286         int c1;
1287
1288         for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
1289                 if (objects[c1].used == 0) {
1290                         objects[c1].used = 1;
1291                         objects[c1].type = type;
1292                         objects[c1].x = (long) x << 16;
1293                         objects[c1].y = (long) y << 16;
1294                         objects[c1].x_add = x_add;
1295                         objects[c1].y_add = y_add;
1296                         objects[c1].x_acc = 0;
1297                         objects[c1].y_acc = 0;
1298                         objects[c1].anim = anim;
1299                         objects[c1].frame = frame;
1300                         objects[c1].ticks = object_anims[anim].frame[frame].ticks;
1301                         objects[c1].image = object_anims[anim].frame[frame].image;
1302                         break;
1303                 }
1304         }
1305
1306 }
1307
1308
1309 void update_objects(void)
1310 {
1311         int c1;
1312         int s1 = 0;
1313
1314         for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
1315                 if (objects[c1].used == 1) {
1316                         switch (objects[c1].type) {
1317                         case OBJ_SPRING:
1318                                 objects[c1].ticks--;
1319                                 if (objects[c1].ticks <= 0) {
1320                                         objects[c1].frame++;
1321                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames) {
1322                                                 objects[c1].frame--;
1323                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1324                                         } else {
1325                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1326                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1327                                         }
1328                                 }
1329                                 if (objects[c1].used == 1)
1330                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1331                                 break;
1332                         case OBJ_SPLASH:
1333                                 objects[c1].ticks--;
1334                                 if (objects[c1].ticks <= 0) {
1335                                         objects[c1].frame++;
1336                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1337                                                 objects[c1].used = 0;
1338                                         else {
1339                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1340                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1341                                         }
1342                                 }
1343                                 if (objects[c1].used == 1)
1344                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1345                                 break;
1346                         case OBJ_SMOKE:
1347                                 objects[c1].x += objects[c1].x_add;
1348                                 objects[c1].y += objects[c1].y_add;
1349                                 objects[c1].ticks--;
1350                                 if (objects[c1].ticks <= 0) {
1351                                         objects[c1].frame++;
1352                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1353                                                 objects[c1].used = 0;
1354                                         else {
1355                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1356                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1357                                         }
1358                                 }
1359                                 if (objects[c1].used == 1)
1360                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1361                                 break;
1362                         case OBJ_YEL_BUTFLY:
1363                         case OBJ_PINK_BUTFLY:
1364                                 objects[c1].x_acc += rnd(128) - 64;
1365                                 if (objects[c1].x_acc < -1024)
1366                                         objects[c1].x_acc = -1024;
1367                                 if (objects[c1].x_acc > 1024)
1368                                         objects[c1].x_acc = 1024;
1369                                 objects[c1].x_add += objects[c1].x_acc;
1370                                 if (objects[c1].x_add < -32768)
1371                                         objects[c1].x_add = -32768;
1372                                 if (objects[c1].x_add > 32768)
1373                                         objects[c1].x_add = 32768;
1374                                 objects[c1].x += objects[c1].x_add;
1375                                 if ((objects[c1].x >> 16) < 16) {
1376                                         objects[c1].x = 16 << 16;
1377                                         objects[c1].x_add = -objects[c1].x_add >> 2;
1378                                         objects[c1].x_acc = 0;
1379                                 } else if ((objects[c1].x >> 16) > 350) {
1380                                         objects[c1].x = 350 << 16;
1381                                         objects[c1].x_add = -objects[c1].x_add >> 2;
1382                                         objects[c1].x_acc = 0;
1383                                 }
1384                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
1385                                         if (objects[c1].x_add < 0) {
1386                                                 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
1387                                         } else {
1388                                                 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
1389                                         }
1390                                         objects[c1].x_add = -objects[c1].x_add >> 2;
1391                                         objects[c1].x_acc = 0;
1392                                 }
1393                                 objects[c1].y_acc += rnd(64) - 32;
1394                                 if (objects[c1].y_acc < -1024)
1395                                         objects[c1].y_acc = -1024;
1396                                 if (objects[c1].y_acc > 1024)
1397                                         objects[c1].y_acc = 1024;
1398                                 objects[c1].y_add += objects[c1].y_acc;
1399                                 if (objects[c1].y_add < -32768)
1400                                         objects[c1].y_add = -32768;
1401                                 if (objects[c1].y_add > 32768)
1402                                         objects[c1].y_add = 32768;
1403                                 objects[c1].y += objects[c1].y_add;
1404                                 if ((objects[c1].y >> 16) < 0) {
1405                                         objects[c1].y = 0;
1406                                         objects[c1].y_add = -objects[c1].y_add >> 2;
1407                                         objects[c1].y_acc = 0;
1408                                 } else if ((objects[c1].y >> 16) > 255) {
1409                                         objects[c1].y = 255 << 16;
1410                                         objects[c1].y_add = -objects[c1].y_add >> 2;
1411                                         objects[c1].y_acc = 0;
1412                                 }
1413                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
1414                                         if (objects[c1].y_add < 0) {
1415                                                 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
1416                                         } else {
1417                                                 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1418                                         }
1419                                         objects[c1].y_add = -objects[c1].y_add >> 2;
1420                                         objects[c1].y_acc = 0;
1421                                 }
1422                                 if (objects[c1].type == OBJ_YEL_BUTFLY) {
1423                                         if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_LEFT) {
1424                                                 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_LEFT;
1425                                                 objects[c1].frame = 0;
1426                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1427                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1428                                         } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_RIGHT) {
1429                                                 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_RIGHT;
1430                                                 objects[c1].frame = 0;
1431                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1432                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1433                                         }
1434                                 } else {
1435                                         if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_LEFT) {
1436                                                 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_LEFT;
1437                                                 objects[c1].frame = 0;
1438                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1439                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1440                                         } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_RIGHT) {
1441                                                 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_RIGHT;
1442                                                 objects[c1].frame = 0;
1443                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1444                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1445                                         }
1446                                 }
1447                                 objects[c1].ticks--;
1448                                 if (objects[c1].ticks <= 0) {
1449                                         objects[c1].frame++;
1450                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1451                                                 objects[c1].frame = object_anims[objects[c1].anim].restart_frame;
1452                                         else {
1453                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1454                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1455                                         }
1456                                 }
1457                                 if (objects[c1].used == 1)
1458                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1459                                 break;
1460                         case OBJ_FUR:
1461                                 if (rnd(100) < 30)
1462                                         add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 0);
1463                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
1464                                         objects[c1].y_add += 3072;
1465                                         if (objects[c1].y_add > 196608L)
1466                                                 objects[c1].y_add = 196608L;
1467                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
1468                                         if (objects[c1].x_add < 0) {
1469                                                 if (objects[c1].x_add < -65536L)
1470                                                         objects[c1].x_add = -65536L;
1471                                                 objects[c1].x_add += 1024;
1472                                                 if (objects[c1].x_add > 0)
1473                                                         objects[c1].x_add = 0;
1474                                         } else {
1475                                                 if (objects[c1].x_add > 65536L)
1476                                                         objects[c1].x_add = 65536L;
1477                                                 objects[c1].x_add -= 1024;
1478                                                 if (objects[c1].x_add < 0)
1479                                                         objects[c1].x_add = 0;
1480                                         }
1481                                         objects[c1].y_add += 1024;
1482                                         if (objects[c1].y_add < -65536L)
1483                                                 objects[c1].y_add = -65536L;
1484                                         if (objects[c1].y_add > 65536L)
1485                                                 objects[c1].y_add = 65536L;
1486                                 }
1487                                 objects[c1].x += objects[c1].x_add;
1488                                 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)) {
1489                                         if (objects[c1].x_add < 0) {
1490                                                 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
1491                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
1492                                         } else {
1493                                                 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
1494                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
1495                                         }
1496                                 }
1497                                 objects[c1].y += objects[c1].y_add;
1498                                 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
1499                                         objects[c1].used = 0;
1500                                 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
1501                                         if (objects[c1].y_add < 0) {
1502                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
1503                                                         objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
1504                                                         objects[c1].x_add >>= 2;
1505                                                         objects[c1].y_add = -objects[c1].y_add >> 2;
1506                                                 }
1507                                         } else {
1508                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
1509                                                         if (objects[c1].y_add > 131072L) {
1510                                                                 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1511                                                                 objects[c1].x_add >>= 2;
1512                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
1513                                                         } else
1514                                                                 objects[c1].used = 0;
1515                                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
1516                                                         objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1517                                                         if (objects[c1].y_add > 131072L)
1518                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
1519                                                         else
1520                                                                 objects[c1].y_add = 0;
1521                                                 }
1522                                         }
1523                                 }
1524                                 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
1525                                         objects[c1].x_add = -16384;
1526                                 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
1527                                         objects[c1].x_add = 16384;
1528                                 if (objects[c1].used == 1) {
1529                                         s1 = (int)(atan2(objects[c1].y_add, objects[c1].x_add) * 4 / M_PI);
1530                                         if (s1 < 0)
1531                                                 s1 += 8;
1532                                         if (s1 < 0)
1533                                                 s1 = 0;
1534                                         if (s1 > 7)
1535                                                 s1 = 7;
1536                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame + s1, &object_gobs);
1537                                 }
1538                                 break;
1539                         case OBJ_FLESH:
1540                                 if (rnd(100) < 30) {
1541                                         if (objects[c1].frame == 76)
1542                                                 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 1);
1543                                         else if (objects[c1].frame == 77)
1544                                                 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 2);
1545                                         else if (objects[c1].frame == 78)
1546                                                 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 3);
1547                                 }
1548                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
1549                                         objects[c1].y_add += 3072;
1550                                         if (objects[c1].y_add > 196608L)
1551                                                 objects[c1].y_add = 196608L;
1552                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
1553                                         if (objects[c1].x_add < 0) {
1554                                                 if (objects[c1].x_add < -65536L)
1555                                                         objects[c1].x_add = -65536L;
1556                                                 objects[c1].x_add += 1024;
1557                                                 if (objects[c1].x_add > 0)
1558                                                         objects[c1].x_add = 0;
1559                                         } else {
1560                                                 if (objects[c1].x_add > 65536L)
1561                                                         objects[c1].x_add = 65536L;
1562                                                 objects[c1].x_add -= 1024;
1563                                                 if (objects[c1].x_add < 0)
1564                                                         objects[c1].x_add = 0;
1565                                         }
1566                                         objects[c1].y_add += 1024;
1567                                         if (objects[c1].y_add < -65536L)
1568                                                 objects[c1].y_add = -65536L;
1569                                         if (objects[c1].y_add > 65536L)
1570                                                 objects[c1].y_add = 65536L;
1571                                 }
1572                                 objects[c1].x += objects[c1].x_add;
1573                                 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)) {
1574                                         if (objects[c1].x_add < 0) {
1575                                                 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
1576                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
1577                                         } else {
1578                                                 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
1579                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
1580                                         }
1581                                 }
1582                                 objects[c1].y += objects[c1].y_add;
1583                                 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
1584                                         objects[c1].used = 0;
1585                                 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
1586                                         if (objects[c1].y_add < 0) {
1587                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
1588                                                         objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
1589                                                         objects[c1].x_add >>= 2;
1590                                                         objects[c1].y_add = -objects[c1].y_add >> 2;
1591                                                 }
1592                                         } else {
1593                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
1594                                                         if (objects[c1].y_add > 131072L) {
1595                                                                 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1596                                                                 objects[c1].x_add >>= 2;
1597                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
1598                                                         } else {
1599                                                                 if (rnd(100) < 10) {
1600                                                                         s1 = rnd(4) - 2;
1601                                                                         add_leftovers(0, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
1602                                                                         add_leftovers(1, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
1603                                                                 }
1604                                                                 objects[c1].used = 0;
1605                                                         }
1606                                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
1607                                                         objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1608                                                         if (objects[c1].y_add > 131072L)
1609                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
1610                                                         else
1611                                                                 objects[c1].y_add = 0;
1612                                                 }
1613                                         }
1614                                 }
1615                                 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
1616                                         objects[c1].x_add = -16384;
1617                                 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
1618                                         objects[c1].x_add = 16384;
1619                                 if (objects[c1].used == 1)
1620                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame, &object_gobs);
1621                                 break;
1622                         case OBJ_FLESH_TRACE:
1623                                 objects[c1].ticks--;
1624                                 if (objects[c1].ticks <= 0) {
1625                                         objects[c1].frame++;
1626                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1627                                                 objects[c1].used = 0;
1628                                         else {
1629                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1630                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1631                                         }
1632                                 }
1633                                 if (objects[c1].used == 1)
1634                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1635                                 break;
1636                         }
1637                 }
1638         }
1639
1640 }
1641
1642
1643 int add_pob(int page, int x, int y, int image, gob_t *pob_data)
1644 {
1645
1646         if (main_info.page_info[page].num_pobs >= NUM_POBS)
1647                 return 1;
1648
1649         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].x = x;
1650         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].y = y;
1651         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].image = image;
1652         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].pob_data = pob_data;
1653         main_info.page_info[page].num_pobs++;
1654
1655         return 0;
1656
1657 }
1658
1659
1660 void draw_flies(int page)
1661 {
1662         int c2;
1663
1664         for (c2 = 0; c2 < NUM_FLIES; c2++) {
1665                 flies[c2].back[main_info.draw_page] = get_pixel(main_info.draw_page, flies[c2].x, flies[c2].y);
1666                 flies[c2].back_defined[main_info.draw_page] = 1;
1667                 if (mask_pic[(flies[c2].y * JNB_WIDTH) + flies[c2].x] == 0)
1668                         set_pixel(main_info.draw_page, flies[c2].x, flies[c2].y, 0);
1669         }
1670 }
1671
1672 void draw_pobs(int page)
1673 {
1674         int c1;
1675         int back_buf_ofs;
1676
1677         back_buf_ofs = 0;
1678
1679         for (c1 = main_info.page_info[page].num_pobs - 1; c1 >= 0; c1--) {
1680                 main_info.page_info[page].pobs[c1].back_buf_ofs = back_buf_ofs;
1681                 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);
1682                 if (scale_up)
1683                         back_buf_ofs += pob_width(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data) * pob_height(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data) * 4 * bytes_per_pixel;
1684                 else
1685                         back_buf_ofs += pob_width(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data) * pob_height(main_info.page_info[page].pobs[c1].image, main_info.page_info[page].pobs[c1].pob_data) * bytes_per_pixel;
1686                 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);
1687         }
1688
1689 }
1690
1691
1692 void redraw_flies_background(int page)
1693 {
1694         int c2;
1695
1696         for (c2 = NUM_FLIES - 1; c2 >= 0; c2--) {
1697                 if (flies[c2].back_defined[page] == 1)
1698                         set_pixel(page, flies[c2].old_draw_x, flies[c2].old_draw_y, flies[c2].back[page]);
1699                 flies[c2].old_draw_x = flies[c2].x;
1700                 flies[c2].old_draw_y = flies[c2].y;
1701         }
1702 }
1703
1704
1705 void redraw_pob_backgrounds(int page)
1706 {
1707         int c1;
1708
1709         for (c1 = 0; c1 < main_info.page_info[page].num_pobs; c1++)
1710                 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);
1711
1712 }
1713
1714
1715 int add_leftovers(int page, int x, int y, int image, gob_t *pob_data)
1716 {
1717
1718         if (leftovers.page[page].num_pobs >= NUM_LEFTOVERS)
1719                 return 1;
1720
1721         leftovers.page[page].pobs[leftovers.page[page].num_pobs].x = x;
1722         leftovers.page[page].pobs[leftovers.page[page].num_pobs].y = y;
1723         leftovers.page[page].pobs[leftovers.page[page].num_pobs].image = image;
1724         leftovers.page[page].pobs[leftovers.page[page].num_pobs].pob_data = pob_data;
1725         leftovers.page[page].num_pobs++;
1726
1727         return 0;
1728
1729 }
1730
1731
1732 void draw_leftovers(int page)
1733 {
1734         int c1;
1735
1736         for (c1 = leftovers.page[page].num_pobs - 1; c1 >= 0; c1--)
1737                 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);
1738
1739         leftovers.page[page].num_pobs = 0;
1740
1741 }
1742
1743
1744 int init_level(int level, char *pal)
1745 {
1746         FILE *handle;
1747         int c1, c2;
1748         int s1, s2;
1749
1750         if ((handle = dat_open("level.pcx", datfile_name, "rb")) == 0) {
1751                 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
1752                 return 1;
1753         }
1754         if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
1755                 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
1756                 return 1;
1757         }
1758         fclose(handle);
1759         if (flip)
1760                 flip_pixels(background_pic);
1761         if ((handle = dat_open("mask.pcx", datfile_name, "rb")) == 0) {
1762                 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
1763                 return 1;
1764         }
1765         if (read_pcx(handle, mask_pic, 102400L, 0) != 0) {
1766                 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
1767                 return 1;
1768         }
1769         fclose(handle);
1770         if (flip)
1771                 flip_pixels(mask_pic);
1772         register_mask(mask_pic);
1773
1774         for (c1 = 0; c1 < 4; c1++) {
1775                 if (player[c1].enabled == 1) {
1776                         player[c1].bumps = 0;
1777                         player[c1].bumped[0] = 0;
1778                         player[c1].bumped[1] = 0;
1779                         player[c1].bumped[2] = 0;
1780                         player[c1].bumped[3] = 0;
1781                         position_player(c1);
1782                 }
1783         }
1784
1785         for (c1 = 0; c1 < NUM_OBJECTS; c1++)
1786                 objects[c1].used = 0;
1787
1788         for (c1 = 0; c1 < 16; c1++) {
1789                 for (c2 = 0; c2 < 22; c2++) {
1790                         if (ban_map[c1][c2] == BAN_SPRING)
1791                                 add_object(OBJ_SPRING, c2 << 4, c1 << 4, 0, 0, OBJ_ANIM_SPRING, 5);
1792                 }
1793         }
1794
1795         while (1) {
1796                 s1 = rnd(22);
1797                 s2 = rnd(16);
1798                 if (ban_map[s2][s1] == BAN_VOID) {
1799                         add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1800                         break;
1801                 }
1802         }
1803         while (1) {
1804                 s1 = rnd(22);
1805                 s2 = rnd(16);
1806                 if (ban_map[s2][s1] == BAN_VOID) {
1807                         add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1808                         break;
1809                 }
1810         }
1811         while (1) {
1812                 s1 = rnd(22);
1813                 s2 = rnd(16);
1814                 if (ban_map[s2][s1] == BAN_VOID) {
1815                         add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1816                         break;
1817                 }
1818         }
1819         while (1) {
1820                 s1 = rnd(22);
1821                 s2 = rnd(16);
1822                 if (ban_map[s2][s1] == BAN_VOID) {
1823                         add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1824                         break;
1825                 }
1826         }
1827
1828         return 0;
1829
1830 }
1831
1832
1833 void deinit_level(void)
1834 {
1835         dj_set_nosound(1);
1836         dj_stop_mod();
1837 }
1838
1839
1840 int init_program(int argc, char *argv[], char *pal)
1841 {
1842         FILE *handle = (FILE *) NULL;
1843         int c1 = 0, c2 = 0;
1844         int load_flag = 0;
1845         int force2, force3;
1846         sfx_data fly;
1847         int player_anim_data[] = {
1848                 1, 0, 0, 0x7fff, 0, 0, 0, 0, 0, 0,
1849                 4, 0, 0, 4, 1, 4, 2, 4, 3, 4,
1850                 1, 0, 4, 0x7fff, 0, 0, 0, 0, 0, 0,
1851                 4, 2, 5, 8, 6, 10, 7, 3, 6, 3,
1852                 1, 0, 6, 0x7fff, 0, 0, 0, 0, 0, 0,
1853                 2, 1, 5, 8, 4, 0x7fff, 0, 0, 0, 0,
1854                 1, 0, 8, 5, 0, 0, 0, 0, 0, 0
1855         };
1856
1857 #ifdef DOS
1858         if (__djgpp_nearptr_enable() == 0)
1859                 return 1;
1860 #endif
1861
1862         srand(time(NULL));
1863
1864         if (hook_keyb_handler() != 0)
1865                 return 1;
1866
1867         memset(&main_info, 0, sizeof(main_info));
1868
1869         strcpy(datfile_name, DATA_PATH);
1870
1871         force2 = force3 = 0;
1872
1873         if (argc > 1) {
1874                 for (c1 = 1; c1 < argc; c1++) {
1875                         if (stricmp(argv[c1], "-nosound") == 0)
1876                                 main_info.no_sound = 1;
1877                         else if (stricmp(argv[c1], "-nogore") == 0)
1878                                 main_info.no_gore = 1;
1879                         else if (stricmp(argv[c1], "-nojoy") == 0)
1880                                 main_info.joy_enabled = 0;
1881                         else if (stricmp(argv[c1], "-fireworks") == 0)
1882                                 main_info.fireworks = 1;
1883 #ifdef USE_SDL
1884                         else if (stricmp(argv[c1], "-fullscreen") == 0)
1885                                 fs_toggle();
1886 #endif
1887                         else if (stricmp(argv[c1], "-scaleup") == 0)
1888                                 set_scaling(1);
1889                         else if (stricmp(argv[c1], "-mirror") == 0)
1890                                 flip = 1;
1891                         else if (stricmp(argv[c1], "-dat") == 0) {
1892                                 if (c1 < (argc - 1)) {
1893                                         if ((handle = fopen(argv[c1 + 1], "rb")) != NULL) {
1894                                                 fclose(handle);
1895                                                 strcpy(datfile_name, argv[c1 + 1]);
1896                                         }
1897                                 }
1898                         } else if (stricmp(argv[c1], "-mouse") == 0) {
1899                                 if (c1 < (argc - 1)) {
1900                                         if (stricmp(argv[c1 + 1], "2") == 0)
1901                                                 force2 = 1;
1902                                         if (stricmp(argv[c1 + 1], "3") == 0)
1903                                                 force3 = 1;
1904                                 }
1905                         }
1906                         else if (strstr(argv[1],"-v")) {
1907                                 printf("jumpnbump %s compiled %s at %s with",JB_VERSION,__DATE__,__TIME__);
1908 #ifndef _SDLnet_h
1909                                 printf("out");
1910 #endif
1911                                 printf(" network support.\n");
1912                                 return 1;
1913                         }
1914                         else if (strstr(argv[1],"-h")) {
1915                                 printf("Usage: jumpnbump [OPTION]...\n");
1916                                 printf("\n");
1917                                 printf("  -h                       this help\n");
1918                                 printf("  -v                       print version\n");
1919                                 printf("  -dat level.dat           play a different level\n");
1920                                 printf("  -port port               define listen port\n");
1921                                 printf("  -net player host rport   define network players\n");
1922                                 printf("  -fireworks               screensaver mode\n");
1923                                 printf("  -fullscreen              run in fullscreen mode\n");
1924                                 printf("  -nosound                 play without sound\n");
1925                                 printf("  -nogore                  play without blood\n");
1926                                 printf("  -mirror                  play with mirrored level\n");
1927                                 printf("\n");
1928                                 return 1;
1929                         }
1930                 }
1931         }
1932
1933         main_info.pob_backbuf[0] = malloc(screen_pitch*screen_height*bytes_per_pixel);
1934         main_info.pob_backbuf[1] = malloc(screen_pitch*screen_height*bytes_per_pixel);
1935
1936         for (c1 = 0; c1 < 7; c1++) {
1937                 player_anims[c1].num_frames = player_anim_data[c1 * 10];
1938                 player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
1939                 for (c2 = 0; c2 < 4; c2++) {
1940                         player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
1941                         player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
1942                 }
1943         }
1944
1945         if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
1946                 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1947                 return 1;
1948         }
1949         if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
1950                 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1951                 return 1;
1952         }
1953         fclose(handle);
1954
1955         if ((handle = dat_open("rabbit.gob", datfile_name, "rb")) == 0) {
1956                 strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
1957                 return 1;
1958         }
1959         if (register_gob(handle, &rabbit_gobs, dat_filelen("rabbit.gob", datfile_name))) {
1960                 /* error */
1961                 fclose(handle);
1962                 return 1;
1963         }
1964         fclose(handle);
1965
1966         if ((handle = dat_open("objects.gob", datfile_name, "rb")) == 0) {
1967                 strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
1968                 return 1;
1969         }
1970         if (register_gob(handle, &object_gobs, dat_filelen("objects.gob", datfile_name))) {
1971                 /* error */
1972                 fclose(handle);
1973                 return 1;
1974         }
1975         fclose(handle);
1976
1977         if ((handle = dat_open("font.gob", datfile_name, "rb")) == 0) {
1978                 strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
1979                 return 1;
1980         }
1981         if (register_gob(handle, &font_gobs, dat_filelen("font.gob", datfile_name))) {
1982                 /* error */
1983                 fclose(handle);
1984                 return 1;
1985         }
1986         fclose(handle);
1987
1988         if ((handle = dat_open("numbers.gob", datfile_name, "rb")) == 0) {
1989                 strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
1990                 return 1;
1991         }
1992         if (register_gob(handle, &number_gobs, dat_filelen("numbers.gob", datfile_name))) {
1993                 /* error */
1994                 fclose(handle);
1995                 return 1;
1996         }
1997         fclose(handle);
1998
1999         if (read_level() != 0) {
2000                 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2001                 fclose(handle);
2002                 return 1;
2003         }
2004
2005         dj_init();
2006
2007         if (main_info.no_sound == 0) {
2008                 dj_autodetect_sd();
2009                 dj_set_mixing_freq(20000);
2010                 dj_set_stereo(0);
2011                 dj_set_auto_mix(0);
2012                 dj_set_dma_time(8);
2013                 dj_set_num_sfx_channels(5);
2014                 dj_set_sfx_volume(64);
2015                 dj_set_nosound(1);
2016                 dj_start();
2017
2018                 if ((handle = dat_open("jump.mod", datfile_name, "rb")) == 0) {
2019                         strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2020                         return 1;
2021                 }
2022                 if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
2023                         strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2024                         return 1;
2025                 }
2026                 fclose(handle);
2027
2028                 if ((handle = dat_open("bump.mod", datfile_name, "rb")) == 0) {
2029                         strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2030                         return 1;
2031                 }
2032                 if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
2033                         strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2034                         return 1;
2035                 }
2036                 fclose(handle);
2037
2038                 if ((handle = dat_open("scores.mod", datfile_name, "rb")) == 0) {
2039                         strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2040                         return 1;
2041                 }
2042                 if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
2043                         strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2044                         return 1;
2045                 }
2046                 fclose(handle);
2047
2048                 if ((handle = dat_open("jump.smp", datfile_name, "rb")) == 0) {
2049                         strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2050                         return 1;
2051                 }
2052                 if (dj_load_sfx(handle, 0, dat_filelen("jump.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
2053                         strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2054                         return 1;
2055                 }
2056                 fclose(handle);
2057
2058                 if ((handle = dat_open("death.smp", datfile_name, "rb")) == 0) {
2059                         strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2060                         return 1;
2061                 }
2062                 if (dj_load_sfx(handle, 0, dat_filelen("death.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
2063                         strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2064                         return 1;
2065                 }
2066                 fclose(handle);
2067
2068                 if ((handle = dat_open("spring.smp", datfile_name, "rb")) == 0) {
2069                         strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2070                         return 1;
2071                 }
2072                 if (dj_load_sfx(handle, 0, dat_filelen("spring.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
2073                         strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2074                         return 1;
2075                 }
2076                 fclose(handle);
2077
2078                 if ((handle = dat_open("splash.smp", datfile_name, "rb")) == 0) {
2079                         strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2080                         return 1;
2081                 }
2082                 if (dj_load_sfx(handle, 0, dat_filelen("splash.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
2083                         strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2084                         return 1;
2085                 }
2086                 fclose(handle);
2087
2088                 if ((handle = dat_open("fly.smp", datfile_name, "rb")) == 0) {
2089                         strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2090                         return 1;
2091                 }
2092                 if (dj_load_sfx(handle, 0, dat_filelen("fly.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
2093                         strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2094                         return 1;
2095                 }
2096                 fclose(handle);
2097
2098                 dj_get_sfx_settings(SFX_FLY, &fly);
2099                 fly.priority = 10;
2100                 fly.default_freq = SFX_FLY_FREQ;
2101                 fly.loop = 1;
2102                 fly.loop_start = 0;
2103                 fly.loop_length = fly.length;
2104                 dj_set_sfx_settings(SFX_FLY, &fly);
2105         }
2106
2107         if ((background_pic = malloc(102400)) == NULL)
2108                 return 1;
2109         if ((mask_pic = malloc(102400)) == NULL)
2110                 return 1;
2111         memset(mask_pic, 0, 102400);
2112         register_mask(mask_pic);
2113
2114         setpalette(0, 256, pal);
2115
2116         init_inputs();
2117
2118         recalculate_gob(&font_gobs, pal);
2119
2120         if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
2121                 load_flag = 0;
2122                 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2123                 put_text(0, 200, 100, "Move the joystick to the", 2);
2124                 put_text(0, 200, 115, "UPPER LEFT", 2);
2125                 put_text(0, 200, 130, "and press button A", 2);
2126                 put_text(0, 200, 200, "Or press ESC to use", 2);
2127                 put_text(0, 200, 215, "previous settings", 2);
2128                 if (calib_joy(0) != 0)
2129                         load_flag = 1;
2130                 else {
2131                         register_background(NULL, NULL);
2132
2133                         main_info.view_page = 1;
2134                         flippage(1);
2135
2136                         wait_vrt(0);
2137
2138                         put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
2139                         put_text(1, 200, 100, "Move the joystick to the", 2);
2140                         put_text(1, 200, 115, "LOWER RIGHT", 2);
2141                         put_text(1, 200, 130, "and press button A", 2);
2142                         put_text(1, 200, 200, "Or press ESC to use", 2);
2143                         put_text(1, 200, 215, "previous settings", 2);
2144                         if (calib_joy(1) != 0)
2145                                 load_flag = 1;
2146                         else {
2147                                 register_background(NULL, NULL);
2148                                 flippage(0);
2149
2150                                 wait_vrt(0);
2151
2152                                 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2153                                 put_text(0, 200, 100, "Move the joystick to the", 2);
2154                                 put_text(0, 200, 115, "CENTER", 2);
2155                                 put_text(0, 200, 130, "and press button A", 2);
2156                                 put_text(0, 200, 200, "Or press ESC to use", 2);
2157                                 put_text(0, 200, 215, "previous settings", 2);
2158                                 if (calib_joy(2) != 0)
2159                                         load_flag = 1;
2160                                 else {
2161                                         if (joy.calib_data.x1 == joy.calib_data.x2)
2162                                                 joy.calib_data.x1 -= 10;
2163                                         if (joy.calib_data.x3 == joy.calib_data.x2)
2164                                                 joy.calib_data.x3 += 10;
2165                                         if (joy.calib_data.y1 == joy.calib_data.y2)
2166                                                 joy.calib_data.y1 -= 10;
2167                                         if (joy.calib_data.y3 == joy.calib_data.y2)
2168                                                 joy.calib_data.y3 += 10;
2169                                         write_calib_data();
2170                                 }
2171                         }
2172                 }
2173                 if (load_flag == 1) {
2174                         if ((handle = dat_open("calib.dat", datfile_name, "rb")) == 0) {
2175                                 strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
2176                                 return 1;
2177                         }
2178                         joy.calib_data.x1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2179                         joy.calib_data.x2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2180                         joy.calib_data.x3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2181                         joy.calib_data.y1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2182                         joy.calib_data.y2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2183                         joy.calib_data.y3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2184                         fclose(handle);
2185                 }
2186         }
2187
2188         return 0;
2189
2190 }
2191
2192 void deinit_program(void)
2193 {
2194 #ifdef DOS
2195         __dpmi_regs regs;
2196 #endif
2197
2198         dj_stop();
2199         dj_free_mod(MOD_MENU);
2200         dj_free_mod(MOD_GAME);
2201         dj_free_sfx(SFX_DEATH);
2202         dj_free_sfx(SFX_SPRING);
2203         dj_free_sfx(SFX_SPLASH);
2204         dj_deinit();
2205
2206         if (background_pic != 0)
2207                 free(background_pic);
2208         if (mask_pic != 0)
2209                 free(mask_pic);
2210
2211         remove_keyb_handler();
2212
2213 #ifdef DOS
2214         regs.x.ax = 0x3;
2215         __dpmi_int(0x10, &regs);
2216 #endif
2217
2218         if (main_info.error_str[0] != 0) {
2219                 printf(main_info.error_str);
2220 #ifdef _MSC_VER
2221                 MessageBox(0, main_info.error_str, "Jump'n'Bump", 0);
2222 #endif
2223                 exit(1);
2224         } else
2225                 exit(0);
2226
2227 }
2228
2229
2230 unsigned short rnd(unsigned short max)
2231 {
2232         return (rand() % max);
2233 }
2234
2235
2236 int read_level(void)
2237 {
2238         FILE *handle;
2239         int c1, c2;
2240         int chr;
2241
2242         if ((handle = dat_open("levelmap.txt", datfile_name, "rb")) == 0) {
2243                 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2244                 return 1;
2245         }
2246
2247         for (c1 = 0; c1 < 16; c1++) {
2248                 for (c2 = 0; c2 < 22; c2++) {
2249                         while (1) {
2250                                 chr = fgetc(handle);
2251                                 if (chr == EOF) {
2252                                         fclose(handle);
2253                                         return 1;
2254                                 }
2255                                 if (chr >= '0' && chr <= '4')
2256                                         break;
2257                         }
2258                         if (flip)
2259                                 ban_map[c1][21-c2] = chr - '0';
2260                         else
2261                                 ban_map[c1][c2] = chr - '0';
2262                 }
2263         }
2264
2265         for (c2 = 0; c2 < 22; c2++)
2266                 ban_map[16][c2] = BAN_SOLID;
2267
2268         fclose(handle);
2269         return 0;
2270
2271 }
2272
2273
2274 FILE *dat_open(char *file_name, char *dat_name, char *mode)
2275 {
2276         FILE *handle;
2277         int num;
2278         int c1;
2279         char name[21];
2280         int ofs;
2281
2282         handle = fopen(dat_name, mode);
2283         if (!handle)
2284                 return 0;
2285
2286         memset(name, 0, sizeof(name));
2287
2288         num = fgetc(handle);
2289         num+= (fgetc(handle) << 8);
2290         num+= (fgetc(handle) << 16);
2291         num+= (fgetc(handle) << 24);
2292         
2293         for (c1 = 0; c1 < num; c1++) {
2294                 if (!fread(name, 1, 12, handle)) {
2295                         fclose(handle);
2296                         return 0;
2297                 }
2298                 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2299                         ofs = fgetc(handle);
2300                         ofs += (fgetc(handle) << 8);
2301                         ofs += (fgetc(handle) << 16);
2302                         ofs += (fgetc(handle) << 24);
2303                         fseek(handle, ofs, SEEK_SET);
2304                         return handle;
2305                 }
2306                 fseek(handle, 8, SEEK_CUR);
2307         }
2308
2309         fclose(handle);
2310
2311         return 0;
2312 }
2313
2314
2315 int dat_filelen(char *file_name, char *dat_name)
2316 {
2317         FILE *handle;
2318         int num;
2319         int c1;
2320         char name[21];
2321         int len;
2322
2323         handle = fopen(dat_name, "rb");
2324         if (!handle)
2325                 return 0;
2326
2327         memset(name, 0, sizeof(name));
2328         
2329         num = fgetc(handle);
2330         num+= (fgetc(handle) << 8);
2331         num+= (fgetc(handle) << 16);
2332         num+= (fgetc(handle) << 24);
2333
2334         for (c1 = 0; c1 < num; c1++) {
2335                 if (!fread(name, 1, 12, handle)) {
2336                         fclose(handle);
2337                         return 0;
2338                 }
2339                 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2340                         fseek(handle, 4, SEEK_CUR);
2341                         len = fgetc(handle);
2342                         len += (fgetc(handle) << 8);
2343                         len += (fgetc(handle) << 16);
2344                         len += (fgetc(handle) << 24);
2345
2346                         fclose(handle);
2347                         return len;
2348                 }
2349                 fseek(handle, 8, SEEK_CUR);
2350         }
2351
2352         fclose(handle);
2353         return 0;
2354 }
2355
2356
2357 #ifndef _MSC_VER
2358 int filelength(int handle)
2359 {
2360         struct stat buf;
2361
2362         if (fstat(handle, &buf) == -1) {
2363                 perror("filelength");
2364                 exit(EXIT_FAILURE);
2365         }
2366
2367         return buf.st_size;
2368 }
2369 #endif
2370
2371
2372 void write_calib_data(void)
2373 {
2374         FILE *handle;
2375         int c1;
2376         int len, num;
2377         char *mem;
2378         int ofs;
2379
2380         if ((handle = fopen(datfile_name, "rb")) == NULL)
2381                 return;
2382         len = filelength(fileno(handle));
2383         if ((mem = malloc(len)) == NULL)
2384                 return;
2385         fread(mem, 1, len, handle);
2386         fclose(handle);
2387
2388         ofs = 4;
2389         num = *(int *) (&mem[0]);
2390         for (c1 = 0; c1 < num; c1++) {
2391                 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
2392                         ofs = *(int *) (&mem[ofs + 12]);
2393                         break;
2394                 }
2395                 ofs += 20;
2396         }
2397
2398         mem[ofs] = joy.calib_data.x1 & 0xff;
2399         mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
2400         mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
2401         mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
2402         mem[ofs + 4] = joy.calib_data.x2 & 0xff;
2403         mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
2404         mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
2405         mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
2406         mem[ofs + 8] = joy.calib_data.x3 & 0xff;
2407         mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
2408         mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
2409         mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
2410         mem[ofs + 12] = joy.calib_data.y1 & 0xff;
2411         mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
2412         mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
2413         mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
2414         mem[ofs + 16] = joy.calib_data.y2 & 0xff;
2415         mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
2416         mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
2417         mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
2418         mem[ofs + 20] = joy.calib_data.y3 & 0xff;
2419         mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
2420         mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
2421         mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
2422
2423         if ((handle = fopen(datfile_name, "wb")) == NULL)
2424                 return;
2425         fwrite(mem, 1, len, handle);
2426         fclose(handle);
2427
2428 }