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