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