]> icculus.org git repositories - crow/jumpnbump.git/blob - main.c
ba4567ee44e2bbb90f06e45cd3ef3ce7dbb8adc0
[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("\n");
1937                                 return 1;
1938                         }
1939                 }
1940         }
1941
1942         main_info.pob_backbuf[0] = malloc(screen_pitch*screen_height*bytes_per_pixel);
1943         main_info.pob_backbuf[1] = malloc(screen_pitch*screen_height*bytes_per_pixel);
1944
1945         for (c1 = 0; c1 < 7; c1++) {
1946                 player_anims[c1].num_frames = player_anim_data[c1 * 10];
1947                 player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
1948                 for (c2 = 0; c2 < 4; c2++) {
1949                         player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
1950                         player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
1951                 }
1952         }
1953
1954         if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
1955                 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1956                 return 1;
1957         }
1958         if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
1959                 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1960                 return 1;
1961         }
1962         fclose(handle);
1963
1964         if ((handle = dat_open("rabbit.gob", datfile_name, "rb")) == 0) {
1965                 strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
1966                 return 1;
1967         }
1968         if (register_gob(handle, &rabbit_gobs, dat_filelen("rabbit.gob", datfile_name))) {
1969                 /* error */
1970                 fclose(handle);
1971                 return 1;
1972         }
1973         fclose(handle);
1974
1975         if ((handle = dat_open("objects.gob", datfile_name, "rb")) == 0) {
1976                 strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
1977                 return 1;
1978         }
1979         if (register_gob(handle, &object_gobs, dat_filelen("objects.gob", datfile_name))) {
1980                 /* error */
1981                 fclose(handle);
1982                 return 1;
1983         }
1984         fclose(handle);
1985
1986         if ((handle = dat_open("font.gob", datfile_name, "rb")) == 0) {
1987                 strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
1988                 return 1;
1989         }
1990         if (register_gob(handle, &font_gobs, dat_filelen("font.gob", datfile_name))) {
1991                 /* error */
1992                 fclose(handle);
1993                 return 1;
1994         }
1995         fclose(handle);
1996
1997         if ((handle = dat_open("numbers.gob", datfile_name, "rb")) == 0) {
1998                 strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
1999                 return 1;
2000         }
2001         if (register_gob(handle, &number_gobs, dat_filelen("numbers.gob", datfile_name))) {
2002                 /* error */
2003                 fclose(handle);
2004                 return 1;
2005         }
2006         fclose(handle);
2007
2008         if (read_level() != 0) {
2009                 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2010                 fclose(handle);
2011                 return 1;
2012         }
2013
2014         dj_init();
2015
2016         if (main_info.no_sound == 0) {
2017                 dj_autodetect_sd();
2018                 dj_set_mixing_freq(20000);
2019                 dj_set_stereo(0);
2020                 dj_set_auto_mix(0);
2021                 dj_set_dma_time(8);
2022                 dj_set_num_sfx_channels(5);
2023                 dj_set_sfx_volume(64);
2024                 dj_set_nosound(1);
2025                 dj_start();
2026
2027                 if ((handle = dat_open("jump.mod", datfile_name, "rb")) == 0) {
2028                         strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2029                         return 1;
2030                 }
2031                 if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
2032                         strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2033                         return 1;
2034                 }
2035                 fclose(handle);
2036
2037                 if ((handle = dat_open("bump.mod", datfile_name, "rb")) == 0) {
2038                         strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2039                         return 1;
2040                 }
2041                 if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
2042                         strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2043                         return 1;
2044                 }
2045                 fclose(handle);
2046
2047                 if ((handle = dat_open("scores.mod", datfile_name, "rb")) == 0) {
2048                         strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2049                         return 1;
2050                 }
2051                 if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
2052                         strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2053                         return 1;
2054                 }
2055                 fclose(handle);
2056
2057                 if ((handle = dat_open("jump.smp", datfile_name, "rb")) == 0) {
2058                         strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2059                         return 1;
2060                 }
2061                 if (dj_load_sfx(handle, 0, dat_filelen("jump.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
2062                         strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2063                         return 1;
2064                 }
2065                 fclose(handle);
2066
2067                 if ((handle = dat_open("death.smp", datfile_name, "rb")) == 0) {
2068                         strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2069                         return 1;
2070                 }
2071                 if (dj_load_sfx(handle, 0, dat_filelen("death.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
2072                         strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2073                         return 1;
2074                 }
2075                 fclose(handle);
2076
2077                 if ((handle = dat_open("spring.smp", datfile_name, "rb")) == 0) {
2078                         strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2079                         return 1;
2080                 }
2081                 if (dj_load_sfx(handle, 0, dat_filelen("spring.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
2082                         strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2083                         return 1;
2084                 }
2085                 fclose(handle);
2086
2087                 if ((handle = dat_open("splash.smp", datfile_name, "rb")) == 0) {
2088                         strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2089                         return 1;
2090                 }
2091                 if (dj_load_sfx(handle, 0, dat_filelen("splash.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
2092                         strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2093                         return 1;
2094                 }
2095                 fclose(handle);
2096
2097                 if ((handle = dat_open("fly.smp", datfile_name, "rb")) == 0) {
2098                         strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2099                         return 1;
2100                 }
2101                 if (dj_load_sfx(handle, 0, dat_filelen("fly.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
2102                         strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2103                         return 1;
2104                 }
2105                 fclose(handle);
2106
2107                 dj_get_sfx_settings(SFX_FLY, &fly);
2108                 fly.priority = 10;
2109                 fly.default_freq = SFX_FLY_FREQ;
2110                 fly.loop = 1;
2111                 fly.loop_start = 0;
2112                 fly.loop_length = fly.length;
2113                 dj_set_sfx_settings(SFX_FLY, &fly);
2114         }
2115
2116         if ((background_pic = malloc(102400)) == NULL)
2117                 return 1;
2118         if ((mask_pic = malloc(102400)) == NULL)
2119                 return 1;
2120         memset(mask_pic, 0, 102400);
2121         register_mask(mask_pic);
2122
2123         for (c1 = 0; c1 < 16; c1++) { // fix dark font
2124                 pal[(240 + c1) * 3 + 0] = c1 << 2;
2125                 pal[(240 + c1) * 3 + 1] = c1 << 2;
2126                 pal[(240 + c1) * 3 + 2] = c1 << 2;
2127         }
2128
2129         setpalette(0, 256, pal);
2130
2131         init_inputs();
2132
2133         recalculate_gob(&font_gobs, pal);
2134
2135         if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
2136                 load_flag = 0;
2137                 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2138                 put_text(0, 200, 100, "Move the joystick to the", 2);
2139                 put_text(0, 200, 115, "UPPER LEFT", 2);
2140                 put_text(0, 200, 130, "and press button A", 2);
2141                 put_text(0, 200, 200, "Or press ESC to use", 2);
2142                 put_text(0, 200, 215, "previous settings", 2);
2143                 if (calib_joy(0) != 0)
2144                         load_flag = 1;
2145                 else {
2146                         register_background(NULL, NULL);
2147
2148                         main_info.view_page = 1;
2149                         flippage(1);
2150
2151                         wait_vrt(0);
2152
2153                         put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
2154                         put_text(1, 200, 100, "Move the joystick to the", 2);
2155                         put_text(1, 200, 115, "LOWER RIGHT", 2);
2156                         put_text(1, 200, 130, "and press button A", 2);
2157                         put_text(1, 200, 200, "Or press ESC to use", 2);
2158                         put_text(1, 200, 215, "previous settings", 2);
2159                         if (calib_joy(1) != 0)
2160                                 load_flag = 1;
2161                         else {
2162                                 register_background(NULL, NULL);
2163                                 flippage(0);
2164
2165                                 wait_vrt(0);
2166
2167                                 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2168                                 put_text(0, 200, 100, "Move the joystick to the", 2);
2169                                 put_text(0, 200, 115, "CENTER", 2);
2170                                 put_text(0, 200, 130, "and press button A", 2);
2171                                 put_text(0, 200, 200, "Or press ESC to use", 2);
2172                                 put_text(0, 200, 215, "previous settings", 2);
2173                                 if (calib_joy(2) != 0)
2174                                         load_flag = 1;
2175                                 else {
2176                                         if (joy.calib_data.x1 == joy.calib_data.x2)
2177                                                 joy.calib_data.x1 -= 10;
2178                                         if (joy.calib_data.x3 == joy.calib_data.x2)
2179                                                 joy.calib_data.x3 += 10;
2180                                         if (joy.calib_data.y1 == joy.calib_data.y2)
2181                                                 joy.calib_data.y1 -= 10;
2182                                         if (joy.calib_data.y3 == joy.calib_data.y2)
2183                                                 joy.calib_data.y3 += 10;
2184                                         write_calib_data();
2185                                 }
2186                         }
2187                 }
2188                 if (load_flag == 1) {
2189                         if ((handle = dat_open("calib.dat", datfile_name, "rb")) == 0) {
2190                                 strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
2191                                 return 1;
2192                         }
2193                         joy.calib_data.x1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2194                         joy.calib_data.x2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2195                         joy.calib_data.x3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2196                         joy.calib_data.y1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2197                         joy.calib_data.y2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2198                         joy.calib_data.y3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2199                         fclose(handle);
2200                 }
2201         }
2202
2203         return 0;
2204
2205 }
2206
2207 void deinit_program(void)
2208 {
2209 #ifdef DOS
2210         __dpmi_regs regs;
2211 #endif
2212
2213         dj_stop();
2214         dj_free_mod(MOD_MENU);
2215         dj_free_mod(MOD_GAME);
2216         dj_free_sfx(SFX_DEATH);
2217         dj_free_sfx(SFX_SPRING);
2218         dj_free_sfx(SFX_SPLASH);
2219         dj_deinit();
2220
2221         if (background_pic != 0)
2222                 free(background_pic);
2223         if (mask_pic != 0)
2224                 free(mask_pic);
2225
2226         remove_keyb_handler();
2227
2228 #ifdef DOS
2229         regs.x.ax = 0x3;
2230         __dpmi_int(0x10, &regs);
2231 #endif
2232
2233         if (main_info.error_str[0] != 0) {
2234                 printf(main_info.error_str);
2235 #ifdef _MSC_VER
2236                 MessageBox(0, main_info.error_str, "Jump'n'Bump", 0);
2237 #endif
2238                 exit(1);
2239         } else
2240                 exit(0);
2241
2242 }
2243
2244
2245 unsigned short rnd(unsigned short max)
2246 {
2247         return (rand() % max);
2248 }
2249
2250
2251 int read_level(void)
2252 {
2253         FILE *handle;
2254         int c1, c2;
2255         int chr;
2256
2257         if ((handle = dat_open("levelmap.txt", datfile_name, "rb")) == 0) {
2258                 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2259                 return 1;
2260         }
2261
2262         for (c1 = 0; c1 < 16; c1++) {
2263                 for (c2 = 0; c2 < 22; c2++) {
2264                         while (1) {
2265                                 chr = fgetc(handle);
2266                                 if (chr == EOF) {
2267                                         fclose(handle);
2268                                         return 1;
2269                                 }
2270                                 if (chr >= '0' && chr <= '4')
2271                                         break;
2272                         }
2273                         if (flip)
2274                                 ban_map[c1][21-c2] = chr - '0';
2275                         else
2276                                 ban_map[c1][c2] = chr - '0';
2277                 }
2278         }
2279
2280         for (c2 = 0; c2 < 22; c2++)
2281                 ban_map[16][c2] = BAN_SOLID;
2282
2283         fclose(handle);
2284         return 0;
2285
2286 }
2287
2288
2289 FILE *dat_open(char *file_name, char *dat_name, char *mode)
2290 {
2291         FILE *handle;
2292         int num;
2293         int c1;
2294         char name[21];
2295         int ofs;
2296
2297         handle = fopen(dat_name, mode);
2298         if (!handle)
2299                 return 0;
2300
2301         memset(name, 0, sizeof(name));
2302
2303         num = fgetc(handle);
2304         num+= (fgetc(handle) << 8);
2305         num+= (fgetc(handle) << 16);
2306         num+= (fgetc(handle) << 24);
2307         
2308         for (c1 = 0; c1 < num; c1++) {
2309                 if (!fread(name, 1, 12, handle)) {
2310                         fclose(handle);
2311                         return 0;
2312                 }
2313                 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2314                         ofs = fgetc(handle);
2315                         ofs += (fgetc(handle) << 8);
2316                         ofs += (fgetc(handle) << 16);
2317                         ofs += (fgetc(handle) << 24);
2318                         fseek(handle, ofs, SEEK_SET);
2319                         return handle;
2320                 }
2321                 fseek(handle, 8, SEEK_CUR);
2322         }
2323
2324         fclose(handle);
2325
2326         return 0;
2327 }
2328
2329
2330 int dat_filelen(char *file_name, char *dat_name)
2331 {
2332         FILE *handle;
2333         int num;
2334         int c1;
2335         char name[21];
2336         int len;
2337
2338         handle = fopen(dat_name, "rb");
2339         if (!handle)
2340                 return 0;
2341
2342         memset(name, 0, sizeof(name));
2343         
2344         num = fgetc(handle);
2345         num+= (fgetc(handle) << 8);
2346         num+= (fgetc(handle) << 16);
2347         num+= (fgetc(handle) << 24);
2348
2349         for (c1 = 0; c1 < num; c1++) {
2350                 if (!fread(name, 1, 12, handle)) {
2351                         fclose(handle);
2352                         return 0;
2353                 }
2354                 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2355                         fseek(handle, 4, SEEK_CUR);
2356                         len = fgetc(handle);
2357                         len += (fgetc(handle) << 8);
2358                         len += (fgetc(handle) << 16);
2359                         len += (fgetc(handle) << 24);
2360
2361                         fclose(handle);
2362                         return len;
2363                 }
2364                 fseek(handle, 8, SEEK_CUR);
2365         }
2366
2367         fclose(handle);
2368         return 0;
2369 }
2370
2371
2372 #ifndef _MSC_VER
2373 int filelength(int handle)
2374 {
2375         struct stat buf;
2376
2377         if (fstat(handle, &buf) == -1) {
2378                 perror("filelength");
2379                 exit(EXIT_FAILURE);
2380         }
2381
2382         return buf.st_size;
2383 }
2384 #endif
2385
2386
2387 void write_calib_data(void)
2388 {
2389         FILE *handle;
2390         int c1;
2391         int len, num;
2392         char *mem;
2393         int ofs;
2394
2395         if ((handle = fopen(datfile_name, "rb")) == NULL)
2396                 return;
2397         len = filelength(fileno(handle));
2398         if ((mem = malloc(len)) == NULL)
2399                 return;
2400         fread(mem, 1, len, handle);
2401         fclose(handle);
2402
2403         ofs = 4;
2404         num = *(int *) (&mem[0]);
2405         for (c1 = 0; c1 < num; c1++) {
2406                 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
2407                         ofs = *(int *) (&mem[ofs + 12]);
2408                         break;
2409                 }
2410                 ofs += 20;
2411         }
2412
2413         mem[ofs] = joy.calib_data.x1 & 0xff;
2414         mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
2415         mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
2416         mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
2417         mem[ofs + 4] = joy.calib_data.x2 & 0xff;
2418         mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
2419         mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
2420         mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
2421         mem[ofs + 8] = joy.calib_data.x3 & 0xff;
2422         mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
2423         mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
2424         mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
2425         mem[ofs + 12] = joy.calib_data.y1 & 0xff;
2426         mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
2427         mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
2428         mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
2429         mem[ofs + 16] = joy.calib_data.y2 & 0xff;
2430         mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
2431         mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
2432         mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
2433         mem[ofs + 20] = joy.calib_data.y3 & 0xff;
2434         mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
2435         mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
2436         mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
2437
2438         if ((handle = fopen(datfile_name, "wb")) == NULL)
2439                 return;
2440         fwrite(mem, 1, len, handle);
2441         fclose(handle);
2442
2443 }