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