More cleanups. Added get_pixel and set_pixel functions.
[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] == BAN_VOID)
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] != BAN_VOID)
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] != BAN_VOID)
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] == BAN_ICE) {
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] != BAN_SOLID && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_ICE) || (ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_ICE && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] != BAN_SOLID)) {
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] == BAN_SOLID)
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] == BAN_ICE) {
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] != BAN_SOLID && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_ICE) || (ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_ICE && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] != BAN_SOLID)) {
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] == BAN_SOLID)
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] == BAN_ICE) {
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] != BAN_SOLID && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_ICE) || (ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_ICE && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] != BAN_SOLID)) {
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] == BAN_SOLID)
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] == BAN_ICE) {
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] != BAN_SOLID && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_ICE) || (ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_ICE && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] != BAN_SOLID)) {
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] == BAN_SOLID)
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] == BAN_SOLID || ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SPRING || (((ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_SOLID || ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_SPRING) && ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] != BAN_ICE) || (ban_map[(s2 + 16) >> 4][s1 >> 4] != BAN_ICE && (ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_SPRING)))) {
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] == BAN_SOLID)
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] == BAN_SOLID || ban_map[(s2 + 16) >> 4][s1 >> 4] == BAN_ICE || ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[(s2 + 16) >> 4][(s1 + 15) >> 4] == BAN_ICE) {
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] == BAN_VOID || ban_map[(s2 + 7) >> 4][(s1 + 15) >> 4] == BAN_VOID) && (ban_map[(s2 + 8) >> 4][s1 >> 4] == BAN_WATER || ban_map[(s2 + 8) >> 4][(s1 + 15) >> 4] == BAN_WATER)) {
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] == BAN_VOID || ban_map[(s2 + 7) >> 4][(s1 + 15) >> 4] == BAN_VOID) && (ban_map[(s2 + 8) >> 4][s1 >> 4] == BAN_WATER || ban_map[(s2 + 8) >> 4][(s1 + 15) >> 4] == BAN_WATER))
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] == BAN_SOLID || ban_map[s2 >> 4][s1 >> 4] == BAN_ICE || ban_map[s2 >> 4][s1 >> 4] == BAN_SPRING || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
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] == BAN_SOLID || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_SPRING || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
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] == BAN_SOLID || ban_map[s2 >> 4][s1 >> 4] == BAN_ICE || ban_map[s2 >> 4][s1 >> 4] == BAN_SPRING || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
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] == BAN_SOLID || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_SPRING || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
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] == BAN_SPRING || ((ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING && ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] != BAN_SOLID) || (ban_map[(s2 + 15) >> 4][s1 >> 4] != BAN_SOLID && ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING))) {
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 < NUM_OBJECTS; c2++) {
1020                                                 if (objects[c2].used == 1 && objects[c2].type == OBJ_SPRING) {
1021                                                         if (ban_map[(s2 + 15) >> 4][(s1 + 8) >> 4] == BAN_SPRING) {
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] == BAN_SPRING) {
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] == BAN_SPRING) {
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] == BAN_SOLID || ban_map[s2 >> 4][s1 >> 4] == BAN_ICE || ban_map[s2 >> 4][s1 >> 4] == BAN_SPRING || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[s2 >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
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] == BAN_WATER) {
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] == BAN_SOLID || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_ICE) {
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] == BAN_SOLID || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SOLID || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_ICE || ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
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] == BAN_VOID && (ban_map[s2 + 1][s1] == BAN_SOLID || ban_map[s2 + 1][s1] == BAN_ICE))
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         int c2;
1564
1565         for (c2 = 0; c2 < NUM_FLIES; c2++) {
1566                 flies[c2].back[main_info.draw_page] = get_pixel(main_info.draw_page, flies[c2].x, flies[c2].y);
1567                 flies[c2].back_defined[main_info.draw_page] = 1;
1568                 if (mask_pic[(flies[c2].y * JNB_WIDTH) + flies[c2].x] == 0)
1569                         set_pixel(main_info.draw_page, flies[c2].x, flies[c2].y, 0);
1570         }
1571 }
1572
1573 void draw_pobs(int page)
1574 {
1575         int c1;
1576         int back_buf_ofs;
1577
1578         back_buf_ofs = 0;
1579
1580         for (c1 = main_info.page_info[page].num_pobs - 1; c1 >= 0; c1--) {
1581                 main_info.page_info[page].pobs[c1].back_buf_ofs = back_buf_ofs;
1582                 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));
1583                 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);
1584                 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);
1585         }
1586
1587 }
1588
1589
1590 void redraw_flies_background(int page)
1591 {
1592         int c2;
1593
1594         for (c2 = NUM_FLIES - 1; c2 >= 0; c2--) {
1595                 if (flies[c2].back_defined[page] == 1)
1596                         set_pixel(page, flies[c2].old_x, flies[c2].old_y, flies[c2].back[page]);
1597         }
1598 }
1599
1600
1601 void redraw_pob_backgrounds(int page)
1602 {
1603         int c1;
1604
1605         for (c1 = 0; c1 < main_info.page_info[page].num_pobs; c1++)
1606                 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));
1607
1608 }
1609
1610
1611 int add_leftovers(int page, int x, int y, int image, char *pob_data)
1612 {
1613
1614         if (leftovers.page[page].num_pobs >= NUM_LEFTOVERS)
1615                 return 1;
1616
1617         leftovers.page[page].pobs[leftovers.page[page].num_pobs].x = x;
1618         leftovers.page[page].pobs[leftovers.page[page].num_pobs].y = y;
1619         leftovers.page[page].pobs[leftovers.page[page].num_pobs].image = image;
1620         leftovers.page[page].pobs[leftovers.page[page].num_pobs].pob_data = pob_data;
1621         leftovers.page[page].num_pobs++;
1622
1623         return 0;
1624
1625 }
1626
1627
1628 void draw_leftovers(int page)
1629 {
1630         int c1;
1631
1632         for (c1 = leftovers.page[page].num_pobs - 1; c1 >= 0; c1--)
1633                 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);
1634
1635         leftovers.page[page].num_pobs = 0;
1636
1637 }
1638
1639
1640 int init_level(int level, char *pal)
1641 {
1642         FILE *handle;
1643         int c1, c2;
1644         int s1, s2;
1645
1646         if ((handle = dat_open("level.pcx", datfile_name, "rb")) == 0) {
1647                 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
1648                 return 1;
1649         }
1650         if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
1651                 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
1652                 return 1;
1653         }
1654         fclose(handle);
1655         if ((handle = dat_open("mask.pcx", datfile_name, "rb")) == 0) {
1656                 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
1657                 return 1;
1658         }
1659         if (read_pcx(handle, mask_pic, 102400L, 0) != 0) {
1660                 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
1661                 return 1;
1662         }
1663         fclose(handle);
1664
1665         for (c1 = 0; c1 < 4; c1++) {
1666                 if (player[c1].enabled == 1) {
1667                         player[c1].bumps = 0;
1668                         player[c1].bumped[0] = 0;
1669                         player[c1].bumped[1] = 0;
1670                         player[c1].bumped[2] = 0;
1671                         player[c1].bumped[3] = 0;
1672                         position_player(c1);
1673                 }
1674         }
1675
1676         for (c1 = 0; c1 < NUM_OBJECTS; c1++)
1677                 objects[c1].used = 0;
1678
1679         for (c1 = 0; c1 < 16; c1++) {
1680                 for (c2 = 0; c2 < 22; c2++) {
1681                         if (ban_map[c1][c2] == BAN_SPRING)
1682                                 add_object(OBJ_SPRING, c2 << 4, c1 << 4, 0, 0, OBJ_ANIM_SPRING, 5);
1683                 }
1684         }
1685
1686         while (1) {
1687                 s1 = rnd(22);
1688                 s2 = rnd(16);
1689                 if (ban_map[s2][s1] == BAN_VOID) {
1690                         add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1691                         break;
1692                 }
1693         }
1694         while (1) {
1695                 s1 = rnd(22);
1696                 s2 = rnd(16);
1697                 if (ban_map[s2][s1] == BAN_VOID) {
1698                         add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1699                         break;
1700                 }
1701         }
1702         while (1) {
1703                 s1 = rnd(22);
1704                 s2 = rnd(16);
1705                 if (ban_map[s2][s1] == BAN_VOID) {
1706                         add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1707                         break;
1708                 }
1709         }
1710         while (1) {
1711                 s1 = rnd(22);
1712                 s2 = rnd(16);
1713                 if (ban_map[s2][s1] == BAN_VOID) {
1714                         add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1715                         break;
1716                 }
1717         }
1718
1719         return 0;
1720
1721 }
1722
1723
1724 void deinit_level(void)
1725 {
1726         dj_set_nosound(1);
1727         dj_stop_mod();
1728 }
1729
1730
1731 int init_program(int argc, char *argv[], char *pal)
1732 {
1733         FILE *handle = (FILE *) NULL;
1734         int c1 = 0, c2 = 0;
1735         char load_flag = 0;
1736         char force2, force3;
1737         sfx_data fly;
1738         int player_anim_data[] = {
1739                 1, 0, 0, 0x7fff, 0, 0, 0, 0, 0, 0,
1740                 4, 0, 0, 4, 1, 4, 2, 4, 3, 4,
1741                 1, 0, 4, 0x7fff, 0, 0, 0, 0, 0, 0,
1742                 4, 2, 5, 8, 6, 10, 7, 3, 6, 3,
1743                 1, 0, 6, 0x7fff, 0, 0, 0, 0, 0, 0,
1744                 2, 1, 5, 8, 4, 0x7fff, 0, 0, 0, 0,
1745                 1, 0, 8, 5, 0, 0, 0, 0, 0, 0
1746         };
1747
1748 #ifdef DOS
1749         if (__djgpp_nearptr_enable() == 0)
1750                 return 1;
1751 #endif
1752
1753         srand(time(NULL));
1754
1755         if (hook_keyb_handler() != 0)
1756                 return 1;
1757
1758         memset(&main_info, 0, sizeof(main_info));
1759
1760         strcpy(datfile_name, "data/jumpbump.dat");
1761
1762         force2 = force3 = 0;
1763
1764         if (argc > 1) {
1765                 for (c1 = 1; c1 < argc; c1++) {
1766                         if (stricmp(argv[c1], "-nosound") == 0)
1767                                 main_info.no_sound = 1;
1768                         else if (stricmp(argv[c1], "-nogore") == 0)
1769                                 main_info.no_gore = 1;
1770                         else if (stricmp(argv[c1], "-nojoy") == 0)
1771                                 main_info.joy_enabled = 0;
1772                         else if (stricmp(argv[c1], "-fireworks") == 0)
1773                                 main_info.fireworks = 1;
1774 #ifdef USE_SDL
1775                         else if (stricmp(argv[c1], "-fullscreen") == 0)
1776                                 fs_toggle();
1777 #endif
1778                         else if (stricmp(argv[c1], "-dat") == 0) {
1779                                 if (c1 < (argc - 1)) {
1780                                         if ((handle = fopen(argv[c1 + 1], "rb")) != NULL) {
1781                                                 fclose(handle);
1782                                                 strcpy(datfile_name, argv[c1 + 1]);
1783                                         }
1784                                 }
1785                         } else if (stricmp(argv[c1], "-mouse") == 0) {
1786                                 if (c1 < (argc - 1)) {
1787                                         if (stricmp(argv[c1 + 1], "2") == 0)
1788                                                 force2 = 1;
1789                                         if (stricmp(argv[c1 + 1], "3") == 0)
1790                                                 force3 = 1;
1791                                 }
1792                         }
1793                 }
1794         }
1795
1796         for (c1 = 0; c1 < 7; c1++) {
1797                 player_anims[c1].num_frames = player_anim_data[c1 * 10];
1798                 player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
1799                 for (c2 = 0; c2 < 4; c2++) {
1800                         player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
1801                         player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
1802                 }
1803         }
1804
1805         if ((background_pic = malloc(102400)) == NULL)
1806                 return 1;
1807         if ((mask_pic = malloc(102400)) == NULL)
1808                 return 1;
1809         memset(mask_pic, 0, 102400);
1810
1811         main_info.pob_backbuf[0] = malloc(65535);
1812         main_info.pob_backbuf[1] = malloc(65535);
1813         if (main_info.pob_backbuf[0] == 0 || main_info.pob_backbuf[1] == 0)
1814                 return 1;
1815
1816         if ((handle = dat_open("rabbit.gob", datfile_name, "rb")) == 0) {
1817                 strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
1818                 return 1;
1819         }
1820         if ((rabbit_gobs = malloc(dat_filelen("rabbit.gob", datfile_name))) == 0) {
1821                 strcpy(main_info.error_str, "Not enough memory, aborting...\n");
1822                 fclose(handle);
1823                 return 1;
1824         }
1825         fread(rabbit_gobs, 1, dat_filelen("rabbit.gob", datfile_name), handle);
1826         fclose(handle);
1827
1828         if ((handle = dat_open("objects.gob", datfile_name, "rb")) == 0) {
1829                 strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
1830                 return 1;
1831         }
1832         if ((object_gobs = malloc(dat_filelen("objects.gob", datfile_name))) == 0) {
1833                 strcpy(main_info.error_str, "Not enough memory, aborting...\n");
1834                 fclose(handle);
1835                 return 1;
1836         }
1837         fread(object_gobs, 1, dat_filelen("objects.gob", datfile_name), handle);
1838         fclose(handle);
1839
1840         if ((handle = dat_open("font.gob", datfile_name, "rb")) == 0) {
1841                 strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
1842                 return 1;
1843         }
1844         if ((font_gobs = malloc(dat_filelen("font.gob", datfile_name))) == 0) {
1845                 strcpy(main_info.error_str, "Not enough memory, aborting...\n");
1846                 fclose(handle);
1847                 return 1;
1848         }
1849         fread(font_gobs, 1, dat_filelen("font.gob", datfile_name), handle);
1850         fclose(handle);
1851
1852         if ((handle = dat_open("numbers.gob", datfile_name, "rb")) == 0) {
1853                 strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
1854                 return 1;
1855         }
1856         if ((number_gobs = malloc(dat_filelen("numbers.gob", datfile_name))) == 0) {
1857                 strcpy(main_info.error_str, "Not enough memory, aborting...\n");
1858                 fclose(handle);
1859                 return 1;
1860         }
1861         fread(number_gobs, 1, dat_filelen("numbers.gob", datfile_name), handle);
1862         fclose(handle);
1863
1864         if (read_level() != 0) {
1865                 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
1866                 fclose(handle);
1867                 return 1;
1868         }
1869
1870         dj_init();
1871         if (main_info.no_sound == 0) {
1872                 dj_autodetect_sd();
1873                 dj_set_mixing_freq(20000);
1874                 dj_set_stereo(0);
1875                 dj_set_auto_mix(0);
1876                 dj_set_dma_time(8);
1877                 dj_set_num_sfx_channels(5);
1878                 dj_set_sfx_volume(64);
1879                 dj_set_nosound(1);
1880                 dj_start();
1881
1882                 if ((handle = dat_open("jump.mod", datfile_name, "rb")) == 0) {
1883                         strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
1884                         return 1;
1885                 }
1886                 if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
1887                         strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
1888                         return 1;
1889                 }
1890                 fclose(handle);
1891
1892                 if ((handle = dat_open("bump.mod", datfile_name, "rb")) == 0) {
1893                         strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
1894                         return 1;
1895                 }
1896                 if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
1897                         strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
1898                         return 1;
1899                 }
1900                 fclose(handle);
1901
1902                 if ((handle = dat_open("scores.mod", datfile_name, "rb")) == 0) {
1903                         strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
1904                         return 1;
1905                 }
1906                 if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
1907                         strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
1908                         return 1;
1909                 }
1910                 fclose(handle);
1911
1912                 if ((handle = dat_open("jump.smp", datfile_name, "rb")) == 0) {
1913                         strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
1914                         return 1;
1915                 }
1916                 if (dj_load_sfx(handle, 0, dat_filelen("jump.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
1917                         strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
1918                         return 1;
1919                 }
1920                 fclose(handle);
1921
1922                 if ((handle = dat_open("death.smp", datfile_name, "rb")) == 0) {
1923                         strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
1924                         return 1;
1925                 }
1926                 if (dj_load_sfx(handle, 0, dat_filelen("death.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
1927                         strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
1928                         return 1;
1929                 }
1930                 fclose(handle);
1931
1932                 if ((handle = dat_open("spring.smp", datfile_name, "rb")) == 0) {
1933                         strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
1934                         return 1;
1935                 }
1936                 if (dj_load_sfx(handle, 0, dat_filelen("spring.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
1937                         strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
1938                         return 1;
1939                 }
1940                 fclose(handle);
1941
1942                 if ((handle = dat_open("splash.smp", datfile_name, "rb")) == 0) {
1943                         strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
1944                         return 1;
1945                 }
1946                 if (dj_load_sfx(handle, 0, dat_filelen("splash.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
1947                         strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
1948                         return 1;
1949                 }
1950                 fclose(handle);
1951
1952                 if ((handle = dat_open("fly.smp", datfile_name, "rb")) == 0) {
1953                         strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
1954                         return 1;
1955                 }
1956                 if (dj_load_sfx(handle, 0, dat_filelen("fly.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
1957                         strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
1958                         return 1;
1959                 }
1960                 fclose(handle);
1961
1962                 dj_get_sfx_settings(SFX_FLY, &fly);
1963                 fly.priority = 10;
1964                 fly.default_freq = SFX_FLY_FREQ;
1965                 fly.loop = 1;
1966                 fly.loop_start = 0;
1967                 fly.loop_length = fly.length;
1968                 dj_set_sfx_settings(SFX_FLY, &fly);
1969         }
1970
1971         if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
1972                 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1973                 return 1;
1974         }
1975         if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
1976                 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1977                 return 1;
1978         }
1979         fclose(handle);
1980
1981         setpalette(0, 256, pal);
1982
1983         init_inputs();
1984
1985         if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
1986                 load_flag = 0;
1987                 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
1988                 put_text(0, 200, 100, "Move the joystick to the", 2);
1989                 put_text(0, 200, 115, "UPPER LEFT", 2);
1990                 put_text(0, 200, 130, "and press button A", 2);
1991                 put_text(0, 200, 200, "Or press ESC to use", 2);
1992                 put_text(0, 200, 215, "previous settings", 2);
1993                 if (calib_joy(0) != 0)
1994                         load_flag = 1;
1995                 else {
1996                         clear_page(1, 0);
1997
1998                         main_info.view_page = 1;
1999                         flippage(1);
2000
2001                         wait_vrt(0);
2002
2003                         put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
2004                         put_text(1, 200, 100, "Move the joystick to the", 2);
2005                         put_text(1, 200, 115, "LOWER RIGHT", 2);
2006                         put_text(1, 200, 130, "and press button A", 2);
2007                         put_text(1, 200, 200, "Or press ESC to use", 2);
2008                         put_text(1, 200, 215, "previous settings", 2);
2009                         if (calib_joy(1) != 0)
2010                                 load_flag = 1;
2011                         else {
2012                                 clear_page(0, 0);
2013                                 flippage(0);
2014
2015                                 wait_vrt(0);
2016
2017                                 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2018                                 put_text(0, 200, 100, "Move the joystick to the", 2);
2019                                 put_text(0, 200, 115, "CENTER", 2);
2020                                 put_text(0, 200, 130, "and press button A", 2);
2021                                 put_text(0, 200, 200, "Or press ESC to use", 2);
2022                                 put_text(0, 200, 215, "previous settings", 2);
2023                                 if (calib_joy(2) != 0)
2024                                         load_flag = 1;
2025                                 else {
2026                                         if (joy.calib_data.x1 == joy.calib_data.x2)
2027                                                 joy.calib_data.x1 -= 10;
2028                                         if (joy.calib_data.x3 == joy.calib_data.x2)
2029                                                 joy.calib_data.x3 += 10;
2030                                         if (joy.calib_data.y1 == joy.calib_data.y2)
2031                                                 joy.calib_data.y1 -= 10;
2032                                         if (joy.calib_data.y3 == joy.calib_data.y2)
2033                                                 joy.calib_data.y3 += 10;
2034                                         write_calib_data();
2035                                 }
2036                         }
2037                 }
2038                 if (load_flag == 1) {
2039                         if ((handle = dat_open("calib.dat", datfile_name, "rb")) == 0) {
2040                                 strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
2041                                 return 1;
2042                         }
2043                         joy.calib_data.x1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2044                         joy.calib_data.x2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2045                         joy.calib_data.x3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2046                         joy.calib_data.y1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2047                         joy.calib_data.y2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2048                         joy.calib_data.y3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2049                         fclose(handle);
2050                 }
2051         }
2052
2053         return 0;
2054
2055 }
2056
2057
2058 void deinit_program(void)
2059 {
2060 #ifdef DOS
2061         __dpmi_regs regs;
2062 #endif
2063
2064         dj_stop();
2065         dj_free_mod(MOD_MENU);
2066         dj_free_mod(MOD_GAME);
2067         dj_free_sfx(SFX_DEATH);
2068         dj_free_sfx(SFX_SPRING);
2069         dj_free_sfx(SFX_SPLASH);
2070         dj_deinit();
2071
2072         if (rabbit_gobs != 0)
2073                 free(rabbit_gobs);
2074         if (object_gobs != 0)
2075                 free(object_gobs);
2076         if (number_gobs != 0)
2077                 free(number_gobs);
2078
2079         if (main_info.pob_backbuf[0] != 0)
2080                 free(main_info.pob_backbuf[0]);
2081         if (main_info.pob_backbuf[1] != 0)
2082                 free(main_info.pob_backbuf[1]);
2083
2084         if (background_pic != 0)
2085                 free(background_pic);
2086         if (mask_pic != 0)
2087                 free(mask_pic);
2088
2089         remove_keyb_handler();
2090
2091 #ifdef DOS
2092         regs.x.ax = 0x3;
2093         __dpmi_int(0x10, &regs);
2094 #endif
2095
2096         if (main_info.error_str[0] != 0) {
2097                 printf(main_info.error_str);
2098                 exit(1);
2099         } else
2100                 exit(0);
2101
2102 }
2103
2104
2105 unsigned short rnd(unsigned short max)
2106 {
2107         return (rand() % max);
2108 }
2109
2110
2111 int read_level(void)
2112 {
2113         FILE *handle;
2114         int c1, c2;
2115         int chr;
2116
2117         if ((handle = dat_open("levelmap.txt", datfile_name, "rb")) == 0) {
2118                 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2119                 return 1;
2120         }
2121
2122         for (c1 = 0; c1 < 16; c1++) {
2123                 for (c2 = 0; c2 < 22; c2++) {
2124                         while (1) {
2125                                 chr = fgetc(handle);
2126                                 if (chr == EOF) {
2127                                         fclose(handle);
2128                                         return 1;
2129                                 }
2130                                 if (chr >= '0' && chr <= '4')
2131                                         break;
2132                         }
2133                         ban_map[c1][c2] = chr - '0';
2134                 }
2135         }
2136
2137         for (c2 = 0; c2 < 22; c2++)
2138                 ban_map[16][c2] = BAN_SOLID;
2139
2140         fclose(handle);
2141         return 0;
2142
2143 }
2144
2145
2146 FILE *dat_open(char *file_name, char *dat_name, char *mode)
2147 {
2148         FILE *handle;
2149         int num;
2150         int c1;
2151         char name[21];
2152         int ofs;
2153
2154         handle = fopen(dat_name, mode);
2155         if (!handle)
2156                 return 0;
2157
2158         memset(name, 0, sizeof(name));
2159
2160         num = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2161         
2162         for (c1 = 0; c1 < num; c1++) {
2163                 if (!fread(name, 1, 12, handle)) {
2164                         fclose(handle);
2165                         return 0;
2166                 }
2167                 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2168                         ofs = fgetc(handle);
2169                         ofs += (fgetc(handle) << 8);
2170                         ofs += (fgetc(handle) << 16);
2171                         ofs += (fgetc(handle) << 24);
2172                         fseek(handle, ofs, SEEK_SET);
2173                         return handle;
2174                 }
2175                 fseek(handle, 8, SEEK_CUR);
2176         }
2177
2178         fclose(handle);
2179
2180         return 0;
2181 }
2182
2183
2184 int dat_filelen(char *file_name, char *dat_name)
2185 {
2186         FILE *handle;
2187         int num;
2188         int c1;
2189         char name[21];
2190         int len;
2191
2192         handle = fopen(dat_name, "rb");
2193         if (!handle)
2194                 return 0;
2195
2196         memset(name, 0, sizeof(name));
2197         
2198         num = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2199
2200         for (c1 = 0; c1 < num; c1++) {
2201                 if (!fread(name, 1, 12, handle)) {
2202                         fclose(handle);
2203                         return 0;
2204                 }
2205                 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2206                         fseek(handle, 4, SEEK_CUR);
2207                         len = fgetc(handle);
2208                         len += (fgetc(handle) << 8);
2209                         len += (fgetc(handle) << 16);
2210                         len += (fgetc(handle) << 24);
2211
2212                         fclose(handle);
2213                         return len;
2214                 }
2215                 fseek(handle, 8, SEEK_CUR);
2216         }
2217
2218         fclose(handle);
2219         return 0;
2220 }
2221
2222 void write_calib_data(void)
2223 {
2224         FILE *handle;
2225         int c1;
2226         int len, num;
2227         char *mem;
2228         int ofs;
2229
2230         if ((handle = fopen(datfile_name, "rb")) == NULL)
2231                 return;
2232         len = filelength(fileno(handle));
2233         if ((mem = malloc(len)) == NULL)
2234                 return;
2235         fread(mem, 1, len, handle);
2236         fclose(handle);
2237
2238         ofs = 4;
2239         num = *(int *) (&mem[0]);
2240         for (c1 = 0; c1 < num; c1++) {
2241                 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
2242                         ofs = *(int *) (&mem[ofs + 12]);
2243                         break;
2244                 }
2245                 ofs += 20;
2246         }
2247
2248         mem[ofs] = joy.calib_data.x1 & 0xff;
2249         mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
2250         mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
2251         mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
2252         mem[ofs + 4] = joy.calib_data.x2 & 0xff;
2253         mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
2254         mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
2255         mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
2256         mem[ofs + 8] = joy.calib_data.x3 & 0xff;
2257         mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
2258         mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
2259         mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
2260         mem[ofs + 12] = joy.calib_data.y1 & 0xff;
2261         mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
2262         mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
2263         mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
2264         mem[ofs + 16] = joy.calib_data.y2 & 0xff;
2265         mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
2266         mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
2267         mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
2268         mem[ofs + 20] = joy.calib_data.y3 & 0xff;
2269         mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
2270         mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
2271         mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
2272
2273         if ((handle = fopen(datfile_name, "wb")) == NULL)
2274                 return;
2275         fwrite(mem, 1, len, handle);
2276         fclose(handle);
2277
2278 }