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