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