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