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