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